修复Direct2D资源未正确释放导致的内存泄漏问题
This commit is contained in:
		
							parent
							
								
									f5752252a2
								
							
						
					
					
						commit
						6617f7b7e0
					
				|  | @ -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() | ||||||
|  |  | ||||||
|  | @ -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) | ||||||
|  |  | ||||||
|  | @ -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 消息,这个方法将调整渲染
 | ||||||
|  |  | ||||||
|  | @ -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(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -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( | ||||||
|  |  | ||||||
|  | @ -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) | ||||||
|  |  | ||||||
|  | @ -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() | ||||||
|  |  | ||||||
|  | @ -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; | ||||||
|  |  | ||||||
|  | @ -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 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue