修复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() e2d::Point e2d::Input::getMousePos()
{ {
HWND hWnd = Window::getInstance()->getHWnd();
POINT mousePos; POINT mousePos;
GetCursorPos(&mousePos); GetCursorPos(&mousePos);
ScreenToClient(Window::getInstance()->getHWnd(), &mousePos); ScreenToClient(hWnd, &mousePos);
float dpiScaleX = 0.f, dpiScaleY = 0.f; UINT ret = ::GetDpiForWindow(hWnd);
Renderer::getFactory()->GetDesktopDpi(&dpiScaleX, &dpiScaleY); return Point(mousePos.x * 96.0 / ret, mousePos.y * 96.0 / ret);
return Point(static_cast<double>(mousePos.x * 96.f / dpiScaleX),
static_cast<double>(mousePos.y * 96.f / dpiScaleX));
} }
double e2d::Input::getMouseDeltaX() double e2d::Input::getMouseDeltaX()

View File

@ -7,7 +7,6 @@ e2d::Renderer* e2d::Renderer::_instance = nullptr;
ID2D1Factory* e2d::Renderer::_d2dFactory = nullptr; ID2D1Factory* e2d::Renderer::_d2dFactory = nullptr;
IWICImagingFactory* e2d::Renderer::_imagingFactory = nullptr; IWICImagingFactory* e2d::Renderer::_imagingFactory = nullptr;
IDWriteFactory* e2d::Renderer::_writeFactory = nullptr; IDWriteFactory* e2d::Renderer::_writeFactory = nullptr;
IDWriteTextFormat* e2d::Renderer::_textFormat = nullptr;
ID2D1StrokeStyle* e2d::Renderer::_miterStrokeStyle = nullptr; ID2D1StrokeStyle* e2d::Renderer::_miterStrokeStyle = nullptr;
ID2D1StrokeStyle* e2d::Renderer::_bevelStrokeStyle = nullptr; ID2D1StrokeStyle* e2d::Renderer::_bevelStrokeStyle = nullptr;
ID2D1StrokeStyle* e2d::Renderer::_roundStrokeStyle = nullptr; ID2D1StrokeStyle* e2d::Renderer::_roundStrokeStyle = nullptr;
@ -28,11 +27,10 @@ void e2d::Renderer::destroyInstance()
delete _instance; delete _instance;
_instance = nullptr; _instance = nullptr;
SafeRelease(_textFormat);
SafeRelease(_d2dFactory);
SafeRelease(_miterStrokeStyle); SafeRelease(_miterStrokeStyle);
SafeRelease(_bevelStrokeStyle); SafeRelease(_bevelStrokeStyle);
SafeRelease(_roundStrokeStyle); SafeRelease(_roundStrokeStyle);
SafeRelease(_d2dFactory);
SafeRelease(_imagingFactory); SafeRelease(_imagingFactory);
SafeRelease(_writeFactory); SafeRelease(_writeFactory);
} }
@ -41,7 +39,8 @@ void e2d::Renderer::destroyInstance()
e2d::Renderer::Renderer() e2d::Renderer::Renderer()
: _renderTimes(0) : _renderTimes(0)
, _lastRenderTime(0) , _lastRenderTime(0)
, _fpsText() , _fpsFormat(nullptr)
, _fpsLayout(nullptr)
, _renderTarget(nullptr) , _renderTarget(nullptr)
, _solidBrush(nullptr) , _solidBrush(nullptr)
, _textRenderer(nullptr) , _textRenderer(nullptr)
@ -54,9 +53,11 @@ e2d::Renderer::Renderer()
e2d::Renderer::~Renderer() e2d::Renderer::~Renderer()
{ {
SafeRelease(_renderTarget); SafeRelease(_fpsFormat);
SafeRelease(_solidBrush); SafeRelease(_fpsLayout);
SafeRelease(_textRenderer); SafeRelease(_textRenderer);
SafeRelease(_solidBrush);
SafeRelease(_renderTarget);
CoUninitialize(); CoUninitialize();
} }
@ -114,9 +115,6 @@ void e2d::Renderer::__discardDeviceResources()
SafeRelease(_renderTarget); SafeRelease(_renderTarget);
SafeRelease(_solidBrush); SafeRelease(_solidBrush);
SafeRelease(_textRenderer); SafeRelease(_textRenderer);
SafeRelease(_miterStrokeStyle);
SafeRelease(_bevelStrokeStyle);
SafeRelease(_roundStrokeStyle);
} }
void e2d::Renderer::render() void e2d::Renderer::render()
@ -162,27 +160,45 @@ void e2d::Renderer::_renderFps()
++_renderTimes; ++_renderTimes;
double duration = Game::getInstance()->getTotalDuration().seconds(); double duration = Game::getInstance()->getTotalDuration().seconds();
double fDelay = duration - _lastRenderTime; double delay = duration - _lastRenderTime;
if (fDelay >= 0.1) 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; _lastRenderTime = duration;
_renderTimes = 0; _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; if (_fpsLayout)
IDWriteTextFormat * pTextFormat = Renderer::getFpsTextFormat();
HRESULT hr = _writeFactory->CreateTextLayout(
(const WCHAR *)_fpsText,
(UINT32)_fpsText.getLength(),
pTextFormat,
0,
0,
&pTextLayout
);
if (SUCCEEDED(hr))
{ {
_renderTarget->SetTransform(D2D1::Matrix3x2F::Identity()); _renderTarget->SetTransform(D2D1::Matrix3x2F::Identity());
_solidBrush->SetOpacity(1.0f); _solidBrush->SetOpacity(1.0f);
@ -196,9 +212,7 @@ void e2d::Renderer::_renderFps()
D2D1_LINE_JOIN_ROUND D2D1_LINE_JOIN_ROUND
); );
pTextLayout->Draw(nullptr, textRenderer, 10, 0); _fpsLayout->Draw(nullptr, textRenderer, 10, 0);
SafeRelease(pTextLayout);
} }
} }
@ -227,11 +241,17 @@ e2d::TextRenderer * e2d::Renderer::getTextRenderer()
if (!_textRenderer) if (!_textRenderer)
{ {
// 创建自定义的文字渲染器 // 创建自定义的文字渲染器
_textRenderer = TextRenderer::Create( HRESULT hr = TextRenderer::Create(
&_textRenderer,
Renderer::getFactory(), Renderer::getFactory(),
this->getRenderTarget(), this->getRenderTarget(),
this->getSolidColorBrush() this->getSolidColorBrush()
); );
if (FAILED(hr))
{
throw SystemException(L"Create TextRenderer failed");
}
} }
return _textRenderer; return _textRenderer;
} }
@ -293,30 +313,6 @@ IDWriteFactory * e2d::Renderer::getWriteFactory()
return _writeFactory; 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() ID2D1StrokeStyle * e2d::Renderer::getMiterStrokeStyle()
{ {
if (!_miterStrokeStyle) if (!_miterStrokeStyle)

View File

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

View File

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

View File

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

View File

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

View File

@ -52,7 +52,15 @@ void e2d::Transition::_init(Scene * prev, Scene * next)
if (_inScene) _inScene->retain(); if (_inScene) _inScene->retain();
_windowSize = Window::getInstance()->getSize(); _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() void e2d::Transition::_update()

View File

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

View File

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