修复Direct2D资源未正确释放导致的内存泄漏问题

This commit is contained in:
Nomango 2018-07-24 00:24:29 +08:00
parent f5752252a2
commit 6617f7b7e0
9 changed files with 86 additions and 82 deletions

View File

@ -196,15 +196,14 @@ double e2d::Input::getMouseY()
e2d::Point e2d::Input::getMousePos()
{
HWND hWnd = Window::getInstance()->getHWnd();
POINT mousePos;
GetCursorPos(&mousePos);
ScreenToClient(Window::getInstance()->getHWnd(), &mousePos);
ScreenToClient(hWnd, &mousePos);
float dpiScaleX = 0.f, dpiScaleY = 0.f;
Renderer::getFactory()->GetDesktopDpi(&dpiScaleX, &dpiScaleY);
return Point(static_cast<double>(mousePos.x * 96.f / dpiScaleX),
static_cast<double>(mousePos.y * 96.f / dpiScaleX));
UINT ret = ::GetDpiForWindow(hWnd);
return Point(mousePos.x * 96.0 / ret, mousePos.y * 96.0 / ret);
}
double e2d::Input::getMouseDeltaX()

View File

@ -7,7 +7,6 @@ e2d::Renderer* e2d::Renderer::_instance = nullptr;
ID2D1Factory* e2d::Renderer::_d2dFactory = nullptr;
IWICImagingFactory* e2d::Renderer::_imagingFactory = nullptr;
IDWriteFactory* e2d::Renderer::_writeFactory = nullptr;
IDWriteTextFormat* e2d::Renderer::_textFormat = nullptr;
ID2D1StrokeStyle* e2d::Renderer::_miterStrokeStyle = nullptr;
ID2D1StrokeStyle* e2d::Renderer::_bevelStrokeStyle = nullptr;
ID2D1StrokeStyle* e2d::Renderer::_roundStrokeStyle = nullptr;
@ -28,11 +27,10 @@ void e2d::Renderer::destroyInstance()
delete _instance;
_instance = nullptr;
SafeRelease(_textFormat);
SafeRelease(_d2dFactory);
SafeRelease(_miterStrokeStyle);
SafeRelease(_bevelStrokeStyle);
SafeRelease(_roundStrokeStyle);
SafeRelease(_d2dFactory);
SafeRelease(_imagingFactory);
SafeRelease(_writeFactory);
}
@ -41,7 +39,8 @@ void e2d::Renderer::destroyInstance()
e2d::Renderer::Renderer()
: _renderTimes(0)
, _lastRenderTime(0)
, _fpsText()
, _fpsFormat(nullptr)
, _fpsLayout(nullptr)
, _renderTarget(nullptr)
, _solidBrush(nullptr)
, _textRenderer(nullptr)
@ -54,9 +53,11 @@ e2d::Renderer::Renderer()
e2d::Renderer::~Renderer()
{
SafeRelease(_renderTarget);
SafeRelease(_solidBrush);
SafeRelease(_fpsFormat);
SafeRelease(_fpsLayout);
SafeRelease(_textRenderer);
SafeRelease(_solidBrush);
SafeRelease(_renderTarget);
CoUninitialize();
}
@ -114,9 +115,6 @@ void e2d::Renderer::__discardDeviceResources()
SafeRelease(_renderTarget);
SafeRelease(_solidBrush);
SafeRelease(_textRenderer);
SafeRelease(_miterStrokeStyle);
SafeRelease(_bevelStrokeStyle);
SafeRelease(_roundStrokeStyle);
}
void e2d::Renderer::render()
@ -162,27 +160,45 @@ void e2d::Renderer::_renderFps()
++_renderTimes;
double duration = Game::getInstance()->getTotalDuration().seconds();
double fDelay = duration - _lastRenderTime;
if (fDelay >= 0.1)
double delay = duration - _lastRenderTime;
if (delay >= 0.1)
{
_fpsText = String::format(L"FPS: %.1lf", (1 / fDelay) * _renderTimes);
String fpsText = String::format(L"FPS: %.1lf", (1 / delay) * _renderTimes);
_lastRenderTime = duration;
_renderTimes = 0;
auto writeFactory = Renderer::getWriteFactory();
if (!_fpsFormat)
{
writeFactory->CreateTextFormat(
L"",
nullptr,
DWRITE_FONT_WEIGHT_NORMAL,
DWRITE_FONT_STYLE_NORMAL,
DWRITE_FONT_STRETCH_NORMAL,
20,
L"",
&_fpsFormat
);
}
if (_fpsFormat)
{
_fpsFormat->SetWordWrapping(DWRITE_WORD_WRAPPING_NO_WRAP);
SafeRelease(_fpsLayout);
writeFactory->CreateTextLayout(
(const WCHAR *)fpsText,
(UINT32)fpsText.getLength(),
_fpsFormat,
0,
0,
&_fpsLayout
);
}
}
IDWriteTextLayout * pTextLayout = nullptr;
IDWriteTextFormat * pTextFormat = Renderer::getFpsTextFormat();
HRESULT hr = _writeFactory->CreateTextLayout(
(const WCHAR *)_fpsText,
(UINT32)_fpsText.getLength(),
pTextFormat,
0,
0,
&pTextLayout
);
if (SUCCEEDED(hr))
if (_fpsLayout)
{
_renderTarget->SetTransform(D2D1::Matrix3x2F::Identity());
_solidBrush->SetOpacity(1.0f);
@ -196,9 +212,7 @@ void e2d::Renderer::_renderFps()
D2D1_LINE_JOIN_ROUND
);
pTextLayout->Draw(nullptr, textRenderer, 10, 0);
SafeRelease(pTextLayout);
_fpsLayout->Draw(nullptr, textRenderer, 10, 0);
}
}
@ -227,11 +241,17 @@ e2d::TextRenderer * e2d::Renderer::getTextRenderer()
if (!_textRenderer)
{
// 创建自定义的文字渲染器
_textRenderer = TextRenderer::Create(
HRESULT hr = TextRenderer::Create(
&_textRenderer,
Renderer::getFactory(),
this->getRenderTarget(),
this->getSolidColorBrush()
);
if (FAILED(hr))
{
throw SystemException(L"Create TextRenderer failed");
}
}
return _textRenderer;
}
@ -293,30 +313,6 @@ IDWriteFactory * e2d::Renderer::getWriteFactory()
return _writeFactory;
}
IDWriteTextFormat * e2d::Renderer::getFpsTextFormat()
{
if (!_textFormat)
{
// ´´½¨ FPS Îı¾¸ñʽ»¯¶ÔÏó
HRESULT hr = Renderer::getWriteFactory()->CreateTextFormat(
L"",
nullptr,
DWRITE_FONT_WEIGHT_NORMAL,
DWRITE_FONT_STYLE_NORMAL,
DWRITE_FONT_STRETCH_NORMAL,
20,
L"",
&_textFormat
);
if (SUCCEEDED(hr))
{
_textFormat->SetWordWrapping(DWRITE_WORD_WRAPPING_NO_WRAP);
}
}
return _textFormat;
}
ID2D1StrokeStyle * e2d::Renderer::getMiterStrokeStyle()
{
if (!_miterStrokeStyle)

View File

@ -426,9 +426,8 @@ LRESULT e2d::Window::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPar
if (wParam == SIZE_RESTORED)
{
float dpiScaleX = 0.f, dpiScaleY = 0.f;
Renderer::getFactory()->GetDesktopDpi(&dpiScaleX, &dpiScaleY);
_instance->_size = Size(width * 96.f / dpiScaleX, height * 96.f / dpiScaleY);
UINT ret = ::GetDpiForWindow(hWnd);
_instance->_size = Size(width * 96.0 / ret, height * 96.0 / ret);
}
// 如果程序接收到一个 WM_SIZE 消息,这个方法将调整渲染

View File

@ -35,12 +35,10 @@ void e2d::Scene::render()
void e2d::Scene::update()
{
// 执行 onUpdate 函数
if (_autoUpdate)
{
this->onUpdate();
}
// 更新根节点
_root->_update();
}

View File

@ -23,24 +23,27 @@ TextRenderer::~TextRenderer()
SafeRelease(pBrush_);
}
TextRenderer * TextRenderer::Create(
HRESULT TextRenderer::Create(
TextRenderer** ppTextRenderer,
ID2D1Factory* pD2DFactory,
ID2D1HwndRenderTarget* pRT,
ID2D1SolidColorBrush* pBrush
)
{
TextRenderer * pTextRenderer = new (std::nothrow) TextRenderer();
if (pTextRenderer)
*ppTextRenderer = new (std::nothrow) TextRenderer();
if (*ppTextRenderer)
{
pD2DFactory->AddRef();
pRT->AddRef();
pBrush->AddRef();
pTextRenderer->pD2DFactory_ = pD2DFactory;
pTextRenderer->pRT_ = pRT;
pTextRenderer->pBrush_ = pBrush;
(*ppTextRenderer)->pD2DFactory_ = pD2DFactory;
(*ppTextRenderer)->pRT_ = pRT;
(*ppTextRenderer)->pBrush_ = pBrush;
(*ppTextRenderer)->AddRef();
return S_OK;
}
return pTextRenderer;
return E_FAIL;
}
STDMETHODIMP_(void) TextRenderer::SetTextStyle(

View File

@ -184,7 +184,7 @@ void e2d::Node::_render()
void e2d::Node::_renderOutline()
{
if (_outline)
if (_outline && _visible)
{
auto renderer = Renderer::getInstance();
// 获取纯色画刷
@ -206,7 +206,10 @@ void e2d::Node::_renderOutline()
void e2d::Node::_renderCollider()
{
// 绘制自身的几何碰撞体
_collider.render();
if (_visible)
{
_collider.render();
}
// 绘制所有子节点的几何碰撞体
for (auto child : _children)

View File

@ -52,7 +52,15 @@ void e2d::Transition::_init(Scene * prev, Scene * next)
if (_inScene) _inScene->retain();
_windowSize = Window::getInstance()->getSize();
_outLayerParam = _inLayerParam = D2D1::LayerParameters();
_outLayerParam = _inLayerParam = D2D1::LayerParameters(
D2D1::InfiniteRect(),
nullptr,
D2D1_ANTIALIAS_MODE_PER_PRIMITIVE,
D2D1::Matrix3x2F::Identity(),
1.0,
renderer->getSolidColorBrush(),
D2D1_LAYER_OPTIONS_NONE
);
}
void e2d::Transition::_update()

View File

@ -309,9 +309,6 @@ public:
// »ñÈ¡ IDWriteFactory ¶ÔÏó
static IDWriteFactory * getWriteFactory();
// 获取 FPS 文本格式化对象
static IDWriteTextFormat * getFpsTextFormat();
// »ñÈ¡ Miter ÑùʽµÄ ID2D1StrokeStyle
static ID2D1StrokeStyle * getMiterStrokeStyle();
@ -340,16 +337,16 @@ private:
private:
int _renderTimes;
double _lastRenderTime;
String _fpsText;
D2D1_COLOR_F _clearColor;
ID2D1HwndRenderTarget* _renderTarget;
ID2D1SolidColorBrush* _solidBrush;
TextRenderer* _textRenderer;
IDWriteTextFormat* _fpsFormat;
IDWriteTextLayout* _fpsLayout;
ID2D1SolidColorBrush* _solidBrush;
ID2D1HwndRenderTarget* _renderTarget;
static ID2D1Factory* _d2dFactory;
static IWICImagingFactory* _imagingFactory;
static IDWriteFactory* _writeFactory;
static IDWriteTextFormat* _textFormat;
static ID2D1StrokeStyle* _miterStrokeStyle;
static ID2D1StrokeStyle* _bevelStrokeStyle;
static ID2D1StrokeStyle* _roundStrokeStyle;

View File

@ -77,7 +77,8 @@ private:
~TextRenderer();
public:
static TextRenderer * Create(
static HRESULT Create(
TextRenderer** ppTextRenderer,
ID2D1Factory* pD2DFactory,
ID2D1HwndRenderTarget* pRT,
ID2D1SolidColorBrush* pBrush