diff --git a/Kiwano/2d/Canvas.cpp b/Kiwano/2d/Canvas.cpp index 4fd8c808..7bfd230b 100644 --- a/Kiwano/2d/Canvas.cpp +++ b/Kiwano/2d/Canvas.cpp @@ -30,7 +30,7 @@ namespace kiwano : cache_expired_(false) , stroke_width_(1.0f) { - auto ctx = Renderer::Instance().GetDeviceResources()->GetD2DDeviceContext(); + auto ctx = Renderer::Instance().GetD2DDeviceResources()->GetDeviceContext(); ThrowIfFailed( ctx->CreateCompatibleRenderTarget(&render_target_) @@ -123,7 +123,7 @@ namespace kiwano void Canvas::SetOutlineJoinStyle(StrokeStyle outline_join) { - outline_join_style_ = Renderer::Instance().GetDeviceResources()->GetStrokeStyle(outline_join); + outline_join_style_ = Renderer::Instance().GetD2DDeviceResources()->GetStrokeStyle(outline_join); } void Canvas::SetTextStyle(Font const& font, TextStyle const & text_style) @@ -136,7 +136,7 @@ namespace kiwano text_style_.outline, DX::ConvertToColorF(text_style_.outline_color), text_style_.outline_width, - Renderer::Instance().GetDeviceResources()->GetStrokeStyle(text_style_.outline_stroke) + Renderer::Instance().GetD2DDeviceResources()->GetStrokeStyle(text_style_.outline_stroke) ); // clear text format @@ -272,7 +272,7 @@ namespace kiwano if (!text_format_) { ThrowIfFailed( - Renderer::Instance().GetDeviceResources()->CreateTextFormat( + Renderer::Instance().GetD2DDeviceResources()->CreateTextFormat( text_format_, text_font_, text_style_ @@ -283,7 +283,7 @@ namespace kiwano ComPtr text_layout; Size layout_size; ThrowIfFailed( - Renderer::Instance().GetDeviceResources()->CreateTextLayout( + Renderer::Instance().GetD2DDeviceResources()->CreateTextLayout( text_layout, layout_size, text, @@ -392,7 +392,7 @@ namespace kiwano current_geometry_ = nullptr; ThrowIfFailed( - Renderer::Instance().GetDeviceResources()->GetD2DFactory()->CreatePathGeometry(¤t_geometry_) + Renderer::Instance().GetD2DDeviceResources()->GetFactory()->CreatePathGeometry(¤t_geometry_) ); ThrowIfFailed( diff --git a/Kiwano/2d/DebugNode.cpp b/Kiwano/2d/DebugNode.cpp index 7d7a9dc6..64870e76 100644 --- a/Kiwano/2d/DebugNode.cpp +++ b/Kiwano/2d/DebugNode.cpp @@ -54,7 +54,7 @@ namespace kiwano Renderer::Instance().SetTransform(Matrix{}); Renderer::Instance().GetSolidColorBrush()->SetColor(D2D1::ColorF(0.0f, 0.0f, 0.0f, 0.5f)); - Renderer::Instance().GetDeviceResources()->GetD2DDeviceContext()->FillRectangle( + Renderer::Instance().GetD2DDeviceResources()->GetDeviceContext()->FillRectangle( D2D1_RECT_F{ 10, 10, 30 + debug_text_->GetLayoutSize().x, 30 + debug_text_->GetLayoutSize().y }, Renderer::Instance().GetSolidColorBrush() ); diff --git a/Kiwano/2d/Geometry.cpp b/Kiwano/2d/Geometry.cpp index a87f242e..2c3d89b0 100644 --- a/Kiwano/2d/Geometry.cpp +++ b/Kiwano/2d/Geometry.cpp @@ -128,7 +128,7 @@ namespace kiwano ComPtr path_geo; ComPtr path_sink; - HRESULT hr = Renderer::Instance().GetDeviceResources()->GetD2DFactory()->CreatePathGeometry(&path_geo); + HRESULT hr = Renderer::Instance().GetD2DDeviceResources()->GetFactory()->CreatePathGeometry(&path_geo); if (SUCCEEDED(hr)) { @@ -185,7 +185,7 @@ namespace kiwano void RectangleGeometry::SetRect(Rect const & rect) { ComPtr geo; - auto factory = Renderer::Instance().GetDeviceResources()->GetD2DFactory(); + auto factory = Renderer::Instance().GetD2DDeviceResources()->GetFactory(); if (SUCCEEDED(factory->CreateRectangleGeometry(DX::ConvertToRectF(rect), &geo))) { @@ -226,7 +226,7 @@ namespace kiwano void CircleGeometry::SetCircle(Point const & center, float radius) { ComPtr geo; - auto factory = Renderer::Instance().GetDeviceResources()->GetD2DFactory(); + auto factory = Renderer::Instance().GetD2DDeviceResources()->GetFactory(); if (SUCCEEDED(factory->CreateEllipseGeometry( D2D1::Ellipse( @@ -274,7 +274,7 @@ namespace kiwano void EllipseGeometry::SetEllipse(Point const & center, float radius_x, float radius_y) { ComPtr geo; - auto factory = Renderer::Instance().GetDeviceResources()->GetD2DFactory(); + auto factory = Renderer::Instance().GetD2DDeviceResources()->GetFactory(); if (SUCCEEDED(factory->CreateEllipseGeometry( D2D1::Ellipse( @@ -306,7 +306,7 @@ namespace kiwano { current_geometry_ = nullptr; - auto factory = Renderer::Instance().GetDeviceResources()->GetD2DFactory(); + auto factory = Renderer::Instance().GetD2DDeviceResources()->GetFactory(); ThrowIfFailed( factory->CreatePathGeometry(¤t_geometry_) @@ -422,7 +422,7 @@ namespace kiwano void RoundedRectGeometry::SetRoundedRect(Rect const & rect, float radius_x, float radius_y) { ComPtr geo; - auto factory = Renderer::Instance().GetDeviceResources()->GetD2DFactory(); + auto factory = Renderer::Instance().GetD2DDeviceResources()->GetFactory(); if (SUCCEEDED(factory->CreateRoundedRectangleGeometry( D2D1::RoundedRect( diff --git a/Kiwano/2d/GifImage.cpp b/Kiwano/2d/GifImage.cpp index 5abb1a3a..cc1414cd 100644 --- a/Kiwano/2d/GifImage.cpp +++ b/Kiwano/2d/GifImage.cpp @@ -36,8 +36,8 @@ namespace kiwano , frame_position_{} , bg_color_{} { - factory_ = Renderer::Instance().GetDeviceResources()->GetWICImagingFactory(); - auto ctx = Renderer::Instance().GetDeviceResources()->GetD2DDeviceContext(); + factory_ = Renderer::Instance().GetD2DDeviceResources()->GetWICImagingFactory(); + auto ctx = Renderer::Instance().GetD2DDeviceResources()->GetDeviceContext(); ThrowIfFailed( ctx->CreateCompatibleRenderTarget(&frame_rt_) @@ -192,7 +192,7 @@ namespace kiwano if (SUCCEEDED(hr)) { - auto ctx = Renderer::Instance().GetDeviceResources()->GetD2DDeviceContext(); + auto ctx = Renderer::Instance().GetD2DDeviceResources()->GetDeviceContext(); // Create a D2DBitmap from IWICBitmapSource raw_frame_.Reset(); diff --git a/Kiwano/2d/Image.cpp b/Kiwano/2d/Image.cpp index ef6b2538..59c9449c 100644 --- a/Kiwano/2d/Image.cpp +++ b/Kiwano/2d/Image.cpp @@ -69,11 +69,11 @@ namespace kiwano return false; } #endif - hr = Renderer::Instance().GetDeviceResources()->CreateBitmapFromFile(bitmap, res.GetFileName()); + hr = Renderer::Instance().GetD2DDeviceResources()->CreateBitmapFromFile(bitmap, res.GetFileName()); } else { - hr = Renderer::Instance().GetDeviceResources()->CreateBitmapFromResource(bitmap, res); + hr = Renderer::Instance().GetD2DDeviceResources()->CreateBitmapFromResource(bitmap, res); } if (FAILED(hr)) diff --git a/Kiwano/2d/Text.cpp b/Kiwano/2d/Text.cpp index 357bf914..945f59b4 100644 --- a/Kiwano/2d/Text.cpp +++ b/Kiwano/2d/Text.cpp @@ -327,7 +327,7 @@ namespace kiwano return; ThrowIfFailed( - Renderer::Instance().GetDeviceResources()->CreateTextFormat( + Renderer::Instance().GetD2DDeviceResources()->CreateTextFormat( text_format_, font_, style_ @@ -335,7 +335,7 @@ namespace kiwano ); ThrowIfFailed( - Renderer::Instance().GetDeviceResources()->CreateTextLayout( + Renderer::Instance().GetD2DDeviceResources()->CreateTextLayout( text_layout_, layout_size_, text_, diff --git a/Kiwano/Kiwano.vcxproj b/Kiwano/Kiwano.vcxproj index 7d863634..744bb653 100644 --- a/Kiwano/Kiwano.vcxproj +++ b/Kiwano/Kiwano.vcxproj @@ -84,7 +84,7 @@ - + diff --git a/Kiwano/Kiwano.vcxproj.filters b/Kiwano/Kiwano.vcxproj.filters index dbf82b8b..cb5ffa7e 100644 --- a/Kiwano/Kiwano.vcxproj.filters +++ b/Kiwano/Kiwano.vcxproj.filters @@ -183,9 +183,6 @@ renderer - - renderer - renderer @@ -333,6 +330,9 @@ utils + + renderer + diff --git a/Kiwano/imgui/imgui_impl.hpp b/Kiwano/imgui/imgui_impl.hpp index e14c213d..b3e675aa 100644 --- a/Kiwano/imgui/imgui_impl.hpp +++ b/Kiwano/imgui/imgui_impl.hpp @@ -6,7 +6,7 @@ #include "imgui_impl_dx11.h" -inline bool ImGui_Impl_Init(::kiwano::Renderer& renderer) { return ImGui_ImplDX11_Init(renderer.GetDeviceResources()->GetD3DDevice(), renderer.GetDeviceResources()->GetD3DDeviceContext()); } +inline bool ImGui_Impl_Init(::kiwano::Renderer& renderer) { return ImGui_ImplDX11_Init(renderer.GetD3DDeviceResources()->GetDevice(), renderer.GetD3DDeviceResources()->GetDeviceContext()); } inline void ImGui_Impl_Shutdown() { ImGui_ImplDX11_Shutdown(); } inline void ImGui_Impl_NewFrame() { ImGui_ImplDX11_NewFrame(); } inline void ImGui_Impl_RenderDrawData(ImDrawData* draw_data) { ImGui_ImplDX11_RenderDrawData(draw_data); } @@ -18,7 +18,7 @@ inline bool ImGui_Impl_CreateDeviceObjects() { return ImGui_ImplDX11_Cre #include "imgui_impl_dx10.h" -inline bool ImGui_Impl_Init(::kiwano::Renderer& renderer) { return ImGui_ImplDX10_Init(renderer.GetDeviceResources()->GetD3DDeviceContext()); } +inline bool ImGui_Impl_Init(::kiwano::Renderer& renderer) { return ImGui_ImplDX10_Init(renderer.GetD3DDeviceResources()->GetDevice()); } inline void ImGui_Impl_Shutdown() { ImGui_ImplDX10_Shutdown(); } inline void ImGui_Impl_NewFrame() { ImGui_ImplDX10_NewFrame(); } inline void ImGui_Impl_RenderDrawData(ImDrawData* draw_data) { ImGui_ImplDX10_RenderDrawData(draw_data); } diff --git a/Kiwano/renderer/D2DDeviceResources.cpp b/Kiwano/renderer/D2DDeviceResources.cpp index f37f6f65..6a4b12e5 100644 --- a/Kiwano/renderer/D2DDeviceResources.cpp +++ b/Kiwano/renderer/D2DDeviceResources.cpp @@ -28,12 +28,109 @@ namespace kiwano { + struct D2DDeviceResources + : public ID2DDeviceResources + { + public: + D2DDeviceResources(); + + virtual ~D2DDeviceResources(); + + HRESULT CreateDeviceIndependentResources(); + + public: + HRESULT CreateBitmapFromFile( + _Out_ ComPtr& bitmap, + _In_ String const& file_path + ) override; + + HRESULT CreateBitmapFromResource( + _Out_ ComPtr& bitmap, + _In_ Resource const& res + ) override; + + HRESULT CreateTextFormat( + _Out_ ComPtr& text_format, + _In_ Font const& font, + _In_ TextStyle const& text_style + ) const override; + + HRESULT CreateTextLayout( + _Out_ ComPtr& text_layout, + _Out_ Size& layout_size, + _In_ String const& text, + _In_ ComPtr const& text_format, + _In_ TextStyle const& text_style + ) const override; + + void ClearImageCache() override; + + void DiscardResources() override; + + HRESULT SetD2DDevice( + _In_ ComPtr const& device + ) override; + + void SetTargetBitmap( + _In_ ComPtr const& target + ) override; + + ID2D1StrokeStyle* GetStrokeStyle(StrokeStyle stroke) const override; + + public: + unsigned long STDMETHODCALLTYPE AddRef(); + + unsigned long STDMETHODCALLTYPE Release(); + + HRESULT STDMETHODCALLTYPE QueryInterface( + IID const& riid, + void** ppvObject + ); + + protected: + unsigned long ref_count_; + float dpi_; + + using BitmapMap = UnorderedMap>; + BitmapMap bitmap_cache_; + + ComPtr d2d_miter_stroke_style_; + ComPtr d2d_bevel_stroke_style_; + ComPtr d2d_round_stroke_style_; + }; + + + HRESULT ID2DDeviceResources::Create(ID2DDeviceResources** device_resources) + { + HRESULT hr = E_FAIL; + if (device_resources) + { + D2DDeviceResources* res = new (std::nothrow) D2DDeviceResources; + if (res) + { + hr = res->CreateDeviceIndependentResources(); + } + + if (SUCCEEDED(hr)) + { + res->AddRef(); + + DX::SafeRelease(*device_resources); + (*device_resources) = res; + } + else + { + delete res; + res = nullptr; + } + } + return hr; + } D2DDeviceResources::D2DDeviceResources() : ref_count_(0) , dpi_(96.f) { - CreateDeviceIndependentResources(); } D2DDeviceResources::~D2DDeviceResources() @@ -59,11 +156,13 @@ namespace kiwano return newCount; } - STDMETHODIMP D2DDeviceResources::QueryInterface( - IID const& riid, - void** object) + STDMETHODIMP D2DDeviceResources::QueryInterface(IID const& riid, void** object) { - if (__uuidof(IUnknown) == riid) + if (__uuidof(ID2DDeviceResources) == riid) + { + *object = this; + } + else if (__uuidof(IUnknown) == riid) { *object = this; } @@ -82,10 +181,10 @@ namespace kiwano { ClearImageCache(); - d2d_factory_.Reset(); - d2d_device_.Reset(); - d2d_device_context_.Reset(); - d2d_target_bitmap_.Reset(); + factory_.Reset(); + device_.Reset(); + device_context_.Reset(); + target_bitmap_.Reset(); imaging_factory_.Reset(); dwrite_factory_.Reset(); @@ -118,7 +217,7 @@ namespace kiwano if (SUCCEEDED(hr)) { - d2d_factory_ = d2d_factory; + factory_ = d2d_factory; hr = CoCreateInstance( CLSID_WICImagingFactory, @@ -158,7 +257,7 @@ namespace kiwano 0.0f ); - hr = d2d_factory_->CreateStrokeStyle( + hr = factory_->CreateStrokeStyle( stroke_style, nullptr, 0, @@ -168,7 +267,7 @@ namespace kiwano if (SUCCEEDED(hr)) { stroke_style.lineJoin = D2D1_LINE_JOIN_BEVEL; - hr = d2d_factory_->CreateStrokeStyle( + hr = factory_->CreateStrokeStyle( stroke_style, nullptr, 0, @@ -179,7 +278,7 @@ namespace kiwano if (SUCCEEDED(hr)) { stroke_style.lineJoin = D2D1_LINE_JOIN_ROUND; - hr = d2d_factory_->CreateStrokeStyle( + hr = factory_->CreateStrokeStyle( stroke_style, nullptr, 0, @@ -209,9 +308,9 @@ namespace kiwano if (SUCCEEDED(hr)) { - d2d_device_ = device; - d2d_device_context_ = d2d_device_ctx; - d2d_device_context_->SetDpi(dpi_, dpi_); + device_ = device; + device_context_ = d2d_device_ctx; + device_context_->SetDpi(dpi_, dpi_); } return hr; @@ -219,14 +318,14 @@ namespace kiwano void D2DDeviceResources::SetTargetBitmap(ComPtr const& target) { - d2d_target_bitmap_ = target; - if (d2d_device_context_) - d2d_device_context_->SetTarget(d2d_target_bitmap_.Get()); + target_bitmap_ = target; + if (device_context_) + device_context_->SetTarget(target_bitmap_.Get()); } HRESULT D2DDeviceResources::CreateBitmapFromFile(ComPtr & bitmap, String const & file_path) { - if (!imaging_factory_ || !d2d_device_context_) + if (!imaging_factory_ || !device_context_) return E_UNEXPECTED; size_t hash_code = std::hash{}(file_path); @@ -275,7 +374,7 @@ namespace kiwano if (SUCCEEDED(hr)) { - hr = d2d_device_context_->CreateBitmapFromWicBitmap( + hr = device_context_->CreateBitmapFromWicBitmap( converter.Get(), nullptr, &bitmap_tmp @@ -293,7 +392,7 @@ namespace kiwano HRESULT D2DDeviceResources::CreateBitmapFromResource(ComPtr & bitmap, Resource const & res) { - if (!imaging_factory_ || !d2d_device_context_) + if (!imaging_factory_ || !device_context_) return E_UNEXPECTED; size_t hash_code = res.GetHashCode(); @@ -362,7 +461,7 @@ namespace kiwano if (SUCCEEDED(hr)) { - hr = d2d_device_context_->CreateBitmapFromWicBitmap( + hr = device_context_->CreateBitmapFromWicBitmap( converter.Get(), nullptr, &bitmap_tmp diff --git a/Kiwano/renderer/D2DDeviceResources.h b/Kiwano/renderer/D2DDeviceResources.h index a67e0515..18e785a3 100644 --- a/Kiwano/renderer/D2DDeviceResources.h +++ b/Kiwano/renderer/D2DDeviceResources.h @@ -29,90 +29,66 @@ namespace kiwano { - class KGE_API D2DDeviceResources + MIDL_INTERFACE("5706684a-bf6d-4b03-b627-094758a33032") + KGE_API ID2DDeviceResources : public IUnknown { public: - HRESULT CreateBitmapFromFile( + static HRESULT Create(ID2DDeviceResources** device_resources); + + virtual HRESULT CreateBitmapFromFile( _Out_ ComPtr& bitmap, _In_ String const& file_path - ); + ) = 0; - HRESULT CreateBitmapFromResource( + virtual HRESULT CreateBitmapFromResource( _Out_ ComPtr& bitmap, _In_ Resource const& res - ); + ) = 0; - HRESULT CreateTextFormat( + virtual HRESULT CreateTextFormat( _Out_ ComPtr& text_format, _In_ Font const& font, _In_ TextStyle const& text_style - ) const; + ) const = 0; - HRESULT CreateTextLayout( + virtual HRESULT CreateTextLayout( _Out_ ComPtr& text_layout, _Out_ Size& layout_size, _In_ String const& text, _In_ ComPtr const& text_format, _In_ TextStyle const& text_style - ) const; + ) const = 0; - void ClearImageCache(); + virtual ID2D1StrokeStyle* GetStrokeStyle(StrokeStyle stroke) const = 0; - void DiscardResources(); - - HRESULT SetD2DDevice( + virtual HRESULT SetD2DDevice( _In_ ComPtr const& device - ); + ) = 0; - void SetTargetBitmap( + virtual void SetTargetBitmap( _In_ ComPtr const& target - ); + ) = 0; - inline ID2D1Factory1* GetD2DFactory() const { KGE_ASSERT(d2d_factory_); return d2d_factory_.Get(); } + virtual void ClearImageCache() = 0; + + virtual void DiscardResources() = 0; + + inline ID2D1Factory1* GetFactory() const { KGE_ASSERT(factory_); return factory_.Get(); } inline IWICImagingFactory* GetWICImagingFactory() const { KGE_ASSERT(imaging_factory_); return imaging_factory_.Get(); } inline IDWriteFactory* GetDWriteFactory() const { KGE_ASSERT(dwrite_factory_); return dwrite_factory_.Get(); } - inline ID2D1Device* GetD2DDevice() const { KGE_ASSERT(d2d_device_); return d2d_device_.Get(); } - inline ID2D1DeviceContext* GetD2DDeviceContext() const { KGE_ASSERT(d2d_device_context_); return d2d_device_context_.Get(); } - inline ID2D1Bitmap1* GetD2DTargetBitmap() const { KGE_ASSERT(d2d_target_bitmap_); return d2d_target_bitmap_.Get(); } - - ID2D1StrokeStyle* GetStrokeStyle(StrokeStyle stroke) const; - - public: - unsigned long STDMETHODCALLTYPE AddRef(); - - unsigned long STDMETHODCALLTYPE Release(); - - HRESULT STDMETHODCALLTYPE QueryInterface( - IID const& riid, - void** ppvObject - ); + inline ID2D1Device* GetDevice() const { KGE_ASSERT(device_); return device_.Get(); } + inline ID2D1DeviceContext* GetDeviceContext() const { KGE_ASSERT(device_context_); return device_context_.Get(); } + inline ID2D1Bitmap1* GetTargetBitmap() const { KGE_ASSERT(target_bitmap_); return target_bitmap_.Get(); } protected: - D2DDeviceResources(); - - virtual ~D2DDeviceResources(); - - HRESULT CreateDeviceIndependentResources(); - - private: - unsigned long ref_count_; - float dpi_; - - using BitmapMap = UnorderedMap>; - BitmapMap bitmap_cache_; - - ComPtr d2d_factory_; - ComPtr d2d_device_; - ComPtr d2d_device_context_; - ComPtr d2d_target_bitmap_; + ComPtr factory_; + ComPtr device_; + ComPtr device_context_; + ComPtr target_bitmap_; ComPtr imaging_factory_; ComPtr dwrite_factory_; - - ComPtr d2d_miter_stroke_style_; - ComPtr d2d_bevel_stroke_style_; - ComPtr d2d_round_stroke_style_; }; } diff --git a/Kiwano/renderer/D3D10DeviceResources.cpp b/Kiwano/renderer/D3D10DeviceResources.cpp index 8b26085d..9db8e5bf 100644 --- a/Kiwano/renderer/D3D10DeviceResources.cpp +++ b/Kiwano/renderer/D3D10DeviceResources.cpp @@ -80,8 +80,55 @@ namespace kiwano } // namespace DX + struct D3D10DeviceResources + : public ID3D10DeviceResources + { + public: + HRESULT Present(bool vsync); + + HRESULT ClearRenderTarget(Color& clear_color); + + HRESULT HandleDeviceLost(); + + HRESULT SetLogicalSize(Size logical_size); + + HRESULT SetDpi(float dpi); + + void DiscardResources(); + + public: + unsigned long STDMETHODCALLTYPE AddRef(); + + unsigned long STDMETHODCALLTYPE Release(); + + HRESULT STDMETHODCALLTYPE QueryInterface( + IID const& riid, + void** ppvObject + ); + + public: + D3D10DeviceResources(); + + virtual ~D3D10DeviceResources(); + + HRESULT CreateDeviceResources(); + + HRESULT CreateWindowSizeDependentResources(); + + public: + HWND hwnd_; + float dpi_; + Size logical_size_; + Size output_size_; + unsigned long ref_count_; + + ComPtr d2d_res_; + }; + + D3D10DeviceResources::D3D10DeviceResources() - : hwnd_(nullptr) + : ref_count_(0) + , hwnd_(nullptr) { dpi_ = 96.f; // dpi_ = (float)GetDpiForWindow(hwnd); } @@ -91,28 +138,24 @@ namespace kiwano DiscardResources(); } - HRESULT D3D10DeviceResources::Create(D3D10DeviceResources** device_resources, HWND hwnd) + HRESULT ID3D10DeviceResources::Create(ID3D10DeviceResources** device_resources, ID2DDeviceResources* d2d_device_res, HWND hwnd) { HRESULT hr = E_FAIL; - if (device_resources) + if (device_resources && d2d_device_res) { D3D10DeviceResources* res = new (std::nothrow) D3D10DeviceResources; if (res) { - hr = res->CreateDeviceIndependentResources(); + RECT rc; + ::GetClientRect(hwnd, &rc); - if (SUCCEEDED(hr)) - { - RECT rc; - GetClientRect(hwnd, &rc); + res->hwnd_ = hwnd; + res->d2d_res_ = d2d_device_res; + res->logical_size_.x = float(rc.right - rc.left); + res->logical_size_.y = float(rc.bottom - rc.top); - res->hwnd_ = hwnd; - res->logical_size_.x = float(rc.right - rc.left); - res->logical_size_.y = float(rc.bottom - rc.top); - - hr = res->CreateDeviceResources(); - } + hr = res->CreateDeviceResources(); if (SUCCEEDED(hr)) { @@ -138,29 +181,28 @@ namespace kiwano HRESULT D3D10DeviceResources::Present(bool vsync) { + KGE_ASSERT(dxgi_swap_chain_ != nullptr); + // The first argument instructs DXGI to block until VSync. return dxgi_swap_chain_->Present(vsync ? 1 : 0, 0); } HRESULT D3D10DeviceResources::ClearRenderTarget(Color& clear_color) { - d3d_device_->OMSetRenderTargets( - 1, - &d3d_rt_view_, - d3d_ds_view_.Get() - ); - d3d_device_->ClearRenderTargetView( - d3d_rt_view_.Get(), - reinterpret_cast(&clear_color) - ); + KGE_ASSERT(device_ != nullptr && rt_view_ != nullptr && ds_view_ != nullptr); + + auto rt_view = rt_view_.Get(); + device_->OMSetRenderTargets(1, &rt_view, ds_view_.Get()); + device_->ClearRenderTargetView(rt_view, reinterpret_cast(&clear_color)); return S_OK; } void D3D10DeviceResources::DiscardResources() { - d3d_device_.Reset(); - d3d_rt_view_.Reset(); - d3d_ds_view_.Reset(); + d2d_res_.Reset(); + device_.Reset(); + rt_view_.Reset(); + ds_view_.Reset(); dxgi_swap_chain_.Reset(); dxgi_factory_.Reset(); @@ -192,7 +234,7 @@ namespace kiwano if (SUCCEEDED(hr)) { - d3d_device_ = device; + device_ = device; ComPtr dxgi_adapter; ComPtr dxgi_device; @@ -201,7 +243,7 @@ namespace kiwano if (SUCCEEDED(hr)) { - hr = d3d_device_->QueryInterface(IID_PPV_ARGS(&dxgi_device)); + hr = device_->QueryInterface(IID_PPV_ARGS(&dxgi_device)); } if (SUCCEEDED(hr)) @@ -222,12 +264,12 @@ namespace kiwano // Create the Direct2D device object and a corresponding context. if (SUCCEEDED(hr)) { - hr = GetD2DFactory()->CreateDevice(dxgi_device.Get(), &d2d_device); + hr = d2d_res_->GetFactory()->CreateDevice(dxgi_device.Get(), &d2d_device); } if (SUCCEEDED(hr)) { - hr = SetD2DDevice(d2d_device); + hr = d2d_res_->SetD2DDevice(d2d_device); } } @@ -253,7 +295,7 @@ namespace kiwano ComPtr dxgi_device; if (SUCCEEDED(hr)) { - hr = d3d_device_->QueryInterface(&dxgi_device); + hr = device_->QueryInterface(&dxgi_device); } ComPtr dxgi_adapter; @@ -271,7 +313,7 @@ namespace kiwano if (SUCCEEDED(hr)) { hr = dxgi_factory->CreateSwapChain( - d3d_device_.Get(), + device_.Get(), &swap_chain_desc, &dxgi_swap_chain_); } @@ -289,11 +331,11 @@ namespace kiwano // Clear the previous window size specific context. ID3D10RenderTargetView* null_views[] = { nullptr }; - d3d_device_->OMSetRenderTargets(ARRAYSIZE(null_views), null_views, nullptr); - SetTargetBitmap(nullptr); - d3d_rt_view_ = nullptr; - d3d_ds_view_ = nullptr; - d3d_device_->Flush(); + device_->OMSetRenderTargets(ARRAYSIZE(null_views), null_views, nullptr); + d2d_res_->SetTargetBitmap(nullptr); + rt_view_ = nullptr; + ds_view_ = nullptr; + device_->Flush(); // Calculate the necessary render target size in pixels. output_size_.x = DX::ConvertDipsToPixels(logical_size_.x, dpi_); @@ -327,8 +369,8 @@ namespace kiwano renderDesc.ViewDimension = D3D10_RTV_DIMENSION_TEXTURE2D; renderDesc.Texture2D.MipSlice = 0; - d3d_rt_view_ = nullptr; - hr = d3d_device_->CreateRenderTargetView(dxgi_back_buffer.Get(), &renderDesc, &d3d_rt_view_); + rt_view_ = nullptr; + hr = device_->CreateRenderTargetView(dxgi_back_buffer.Get(), &renderDesc, &rt_view_); } } @@ -349,7 +391,7 @@ namespace kiwano tex_desc.SampleDesc.Quality = 0; tex_desc.Usage = D3D10_USAGE_DEFAULT; - hr = d3d_device_->CreateTexture2D(&tex_desc, NULL, &depth_stencil); + hr = device_->CreateTexture2D(&tex_desc, NULL, &depth_stencil); if (SUCCEEDED(hr)) { @@ -358,14 +400,14 @@ namespace kiwano desc.ViewDimension = D3D10_DSV_DIMENSION_TEXTURE2D; desc.Texture2D.MipSlice = 0; - d3d_ds_view_.Reset(); - hr = d3d_device_->CreateDepthStencilView(depth_stencil.Get(), &desc, &d3d_ds_view_); + ds_view_.Reset(); + hr = device_->CreateDepthStencilView(depth_stencil.Get(), &desc, &ds_view_); } if (SUCCEEDED(hr)) { - ID3D10RenderTargetView* main_view = d3d_rt_view_.Get(); - d3d_device_->OMSetRenderTargets(1, &main_view, d3d_ds_view_.Get()); + ID3D10RenderTargetView* main_view = rt_view_.Get(); + device_->OMSetRenderTargets(1, &main_view, ds_view_.Get()); } } @@ -380,7 +422,7 @@ namespace kiwano viewport.MinDepth = 0; viewport.MaxDepth = 1; - d3d_device_->RSSetViewports(1, &viewport); + device_->RSSetViewports(1, &viewport); } // Create a Direct2D target bitmap associated with the @@ -393,7 +435,7 @@ namespace kiwano ComPtr target; if (SUCCEEDED(hr)) { - hr = GetD2DDeviceContext()->CreateBitmapFromDxgiSurface( + hr = d2d_res_->GetDeviceContext()->CreateBitmapFromDxgiSurface( dxgi_back_buffer.Get(), D2D1::BitmapProperties1( D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW, @@ -405,7 +447,7 @@ namespace kiwano if (SUCCEEDED(hr)) { - SetTargetBitmap(target); + d2d_res_->SetTargetBitmap(target); } } @@ -448,13 +490,56 @@ namespace kiwano logical_size_.x = float(rc.right - rc.left); logical_size_.y = float(rc.bottom - rc.top); - GetD2DDeviceContext()->SetDpi(dpi_, dpi_); + d2d_res_->GetDeviceContext()->SetDpi(dpi_, dpi_); return CreateWindowSizeDependentResources(); } return S_OK; } + STDMETHODIMP_(unsigned long) D3D10DeviceResources::AddRef() + { + return InterlockedIncrement(&ref_count_); + } + + STDMETHODIMP_(unsigned long) D3D10DeviceResources::Release() + { + unsigned long newCount = InterlockedDecrement(&ref_count_); + + if (newCount == 0) + { + delete this; + return 0; + } + + return newCount; + } + + STDMETHODIMP D3D10DeviceResources::QueryInterface(IID const& riid, void** object) + { + if (__uuidof(ID3D10DeviceResources) == riid) + { + *object = this; + } + else if (__uuidof(ID3DDeviceResourcesBase) == riid) + { + *object = this; + } + else if (__uuidof(IUnknown) == riid) + { + *object = this; + } + else + { + *object = nullptr; + return E_FAIL; + } + + AddRef(); + + return S_OK; + } + } #endif // !KGE_USE_DIRECTX10 diff --git a/Kiwano/renderer/D3D10DeviceResources.h b/Kiwano/renderer/D3D10DeviceResources.h index feb9f228..6d276fa0 100644 --- a/Kiwano/renderer/D3D10DeviceResources.h +++ b/Kiwano/renderer/D3D10DeviceResources.h @@ -25,69 +25,28 @@ #if defined(KGE_USE_DIRECTX10) #include "D2DDeviceResources.h" +#include "D3DDeviceResourcesBase.h" #include namespace kiwano { - class KGE_API D3D10DeviceResources - : public D2DDeviceResources + MIDL_INTERFACE("3a150b9d-cc23-4022-a463-7e95452a54c4") + KGE_API ID3D10DeviceResources + : public ID3DDeviceResourcesBase { public: - static HRESULT Create( - D3D10DeviceResources** device_resources, - HWND hwnd - ); + static HRESULT Create(ID3D10DeviceResources** device_resources, ID2DDeviceResources* d2d_device_res, HWND hwnd); - HRESULT Present( - bool vsync - ); - - HRESULT ClearRenderTarget( - Color& clear_color - ); - - HRESULT HandleDeviceLost(); - - HRESULT SetLogicalSize( - Size logical_size - ); - - HRESULT SetDpi( - float dpi - ); - - void DiscardResources(); - - inline ID3D10Device* GetD3DDevice() const { KGE_ASSERT(d3d_device_); return d3d_device_.Get(); } - inline ID3D10Device* GetD3DDeviceContext() const { KGE_ASSERT(d3d_device_); return d3d_device_.Get(); } - inline ID3D10RenderTargetView* GetD3DRenderTargetView() const { KGE_ASSERT(d3d_rt_view_); return d3d_rt_view_.Get(); } - inline ID3D10DepthStencilView* GetD3DDepthStencilView() const { KGE_ASSERT(d3d_ds_view_); return d3d_ds_view_.Get(); } + inline ID3D10Device* GetDevice() const { KGE_ASSERT(device_); return device_.Get(); } + inline ID3D10RenderTargetView* GetRenderTargetView() const { KGE_ASSERT(rt_view_); return rt_view_.Get(); } + inline ID3D10DepthStencilView* GetDepthStencilView() const { KGE_ASSERT(ds_view_); return ds_view_.Get(); } inline IDXGIFactory* GetDXGIFactory() const { KGE_ASSERT(dxgi_factory_); return dxgi_factory_.Get(); } inline IDXGISwapChain* GetDXGISwapChain() const { KGE_ASSERT(dxgi_swap_chain_); return dxgi_swap_chain_.Get(); } - inline Size const& GetLogicalSize() const { return logical_size_; } - inline Size const& GetOutputSize() const { return output_size_; } - inline float GetDpi() const { return dpi_; } - protected: - D3D10DeviceResources(); - - virtual ~D3D10DeviceResources(); - - protected: - HRESULT CreateDeviceResources(); - - HRESULT CreateWindowSizeDependentResources(); - - private: - HWND hwnd_; - float dpi_; - Size logical_size_; - Size output_size_; - - ComPtr d3d_device_; - ComPtr d3d_rt_view_; - ComPtr d3d_ds_view_; + ComPtr device_; + ComPtr rt_view_; + ComPtr ds_view_; ComPtr dxgi_swap_chain_; ComPtr dxgi_factory_; }; diff --git a/Kiwano/renderer/D3D11DeviceResources.cpp b/Kiwano/renderer/D3D11DeviceResources.cpp index 555d6d16..a4a7550d 100644 --- a/Kiwano/renderer/D3D11DeviceResources.cpp +++ b/Kiwano/renderer/D3D11DeviceResources.cpp @@ -52,8 +52,57 @@ namespace kiwano } #endif + + struct D3D11DeviceResources + : public ID3D11DeviceResources + { + public: + HRESULT Present(bool vsync) override; + + HRESULT ClearRenderTarget(Color& clear_color) override; + + HRESULT HandleDeviceLost() override; + + HRESULT SetLogicalSize(Size logical_size) override; + + HRESULT SetDpi(float dpi) override; + + void DiscardResources() override; + + public: + unsigned long STDMETHODCALLTYPE AddRef(); + + unsigned long STDMETHODCALLTYPE Release(); + + HRESULT STDMETHODCALLTYPE QueryInterface( + IID const& riid, + void** ppvObject + ); + + public: + D3D11DeviceResources(); + + virtual ~D3D11DeviceResources(); + + HRESULT CreateDeviceResources(); + + HRESULT CreateWindowSizeDependentResources(); + + public: + HWND hwnd_; + float dpi_; + Size logical_size_; + Size output_size_; + unsigned long ref_count_; + + D3D_FEATURE_LEVEL d3d_feature_level_; + ComPtr d2d_res_; + }; + + D3D11DeviceResources::D3D11DeviceResources() - : hwnd_(nullptr) + : ref_count_(0) + , hwnd_(nullptr) , d3d_feature_level_(D3D_FEATURE_LEVEL_9_1) { dpi_ = 96.f; // dpi_ = (float)GetDpiForWindow(hwnd); @@ -64,28 +113,24 @@ namespace kiwano DiscardResources(); } - HRESULT D3D11DeviceResources::Create(D3D11DeviceResources** device_resources, HWND hwnd) + HRESULT ID3D11DeviceResources::Create(ID3D11DeviceResources** device_resources, ID2DDeviceResources* d2d_device_res, HWND hwnd) { HRESULT hr = E_FAIL; - if (device_resources) + if (device_resources && d2d_device_res) { D3D11DeviceResources* res = new (std::nothrow) D3D11DeviceResources; if (res) { - hr = res->CreateDeviceIndependentResources(); + RECT rc; + ::GetClientRect(hwnd, &rc); - if (SUCCEEDED(hr)) - { - RECT rc; - GetClientRect(hwnd, &rc); + res->hwnd_ = hwnd; + res->d2d_res_ = d2d_device_res; + res->logical_size_.x = float(rc.right - rc.left); + res->logical_size_.y = float(rc.bottom - rc.top); - res->hwnd_ = hwnd; - res->logical_size_.x = float(rc.right - rc.left); - res->logical_size_.y = float(rc.bottom - rc.top); - - hr = res->CreateDeviceResources(); - } + hr = res->CreateDeviceResources(); if (SUCCEEDED(hr)) { @@ -111,30 +156,29 @@ namespace kiwano HRESULT D3D11DeviceResources::Present(bool vsync) { + KGE_ASSERT(dxgi_swap_chain_ != nullptr); + // The first argument instructs DXGI to block until VSync. return dxgi_swap_chain_->Present(vsync ? 1 : 0, 0); } HRESULT D3D11DeviceResources::ClearRenderTarget(Color& clear_color) { - d3d_device_context_->OMSetRenderTargets( - 1, - &d3d_rt_view_, - d3d_ds_view_.Get() - ); - d3d_device_context_->ClearRenderTargetView( - d3d_rt_view_.Get(), - reinterpret_cast(&clear_color) - ); + KGE_ASSERT(device_context_ != nullptr && rt_view_ != nullptr && ds_view_ != nullptr); + + auto rt_view = rt_view_.Get(); + device_context_->OMSetRenderTargets(1, &rt_view, ds_view_.Get()); + device_context_->ClearRenderTargetView(rt_view, reinterpret_cast(&clear_color)); return S_OK; } void D3D11DeviceResources::DiscardResources() { - d3d_device_.Reset(); - d3d_device_context_.Reset(); - d3d_rt_view_.Reset(); - d3d_ds_view_.Reset(); + d2d_res_.Reset(); + device_.Reset(); + device_context_.Reset(); + rt_view_.Reset(); + ds_view_.Reset(); dxgi_swap_chain_.Reset(); dxgi_factory_.Reset(); @@ -204,8 +248,8 @@ namespace kiwano if (SUCCEEDED(hr)) { - d3d_device_ = device; - d3d_device_context_ = context; + device_ = device; + device_context_ = context; ComPtr dxgi_adapter; ComPtr dxgi_device; @@ -214,7 +258,7 @@ namespace kiwano if (SUCCEEDED(hr)) { - hr = d3d_device_->QueryInterface(IID_PPV_ARGS(&dxgi_device)); + hr = device_->QueryInterface(IID_PPV_ARGS(&dxgi_device)); } if (SUCCEEDED(hr)) @@ -235,12 +279,12 @@ namespace kiwano // Create the Direct2D device object and a corresponding context. if (SUCCEEDED(hr)) { - hr = GetD2DFactory()->CreateDevice(dxgi_device.Get(), &d2d_device); + hr = d2d_res_->GetFactory()->CreateDevice(dxgi_device.Get(), &d2d_device); } if (SUCCEEDED(hr)) { - hr = SetD2DDevice(d2d_device); + hr = d2d_res_->SetD2DDevice(d2d_device); } } @@ -273,7 +317,7 @@ namespace kiwano ComPtr dxgi_device; if (SUCCEEDED(hr)) { - hr = d3d_device_->QueryInterface(&dxgi_device); + hr = device_->QueryInterface(&dxgi_device); } ComPtr dxgi_adapter; @@ -291,7 +335,7 @@ namespace kiwano if (SUCCEEDED(hr)) { hr = dxgi_factory->CreateSwapChain( - d3d_device_.Get(), + device_.Get(), &swap_chain_desc, &dxgi_swap_chain_); } @@ -309,11 +353,11 @@ namespace kiwano // Clear the previous window size specific context. ID3D11RenderTargetView* null_views[] = { nullptr }; - d3d_device_context_->OMSetRenderTargets(ARRAYSIZE(null_views), null_views, nullptr); - SetTargetBitmap(nullptr); - d3d_rt_view_ = nullptr; - d3d_ds_view_ = nullptr; - d3d_device_context_->Flush(); + device_context_->OMSetRenderTargets(ARRAYSIZE(null_views), null_views, nullptr); + d2d_res_->SetTargetBitmap(nullptr); + rt_view_ = nullptr; + ds_view_ = nullptr; + device_context_->Flush(); // Calculate the necessary render target size in pixels. output_size_.x = DX::ConvertDipsToPixels(logical_size_.x, dpi_); @@ -339,8 +383,8 @@ namespace kiwano if (SUCCEEDED(hr)) { - d3d_rt_view_ = nullptr; - hr = d3d_device_->CreateRenderTargetView(dxgi_back_buffer.Get(), nullptr, &d3d_rt_view_); + rt_view_ = nullptr; + hr = device_->CreateRenderTargetView(dxgi_back_buffer.Get(), nullptr, &rt_view_); } } @@ -357,20 +401,20 @@ namespace kiwano D3D11_BIND_DEPTH_STENCIL ); - hr = d3d_device_->CreateTexture2D(&tex_desc, nullptr, &depth_stencil); + hr = device_->CreateTexture2D(&tex_desc, nullptr, &depth_stencil); if (SUCCEEDED(hr)) { CD3D11_DEPTH_STENCIL_VIEW_DESC desc(D3D11_DSV_DIMENSION_TEXTURE2D); - d3d_ds_view_.Reset(); - hr = d3d_device_->CreateDepthStencilView(depth_stencil.Get(), &desc, &d3d_ds_view_); + ds_view_.Reset(); + hr = device_->CreateDepthStencilView(depth_stencil.Get(), &desc, &ds_view_); } if (SUCCEEDED(hr)) { - ID3D11RenderTargetView* main_view = d3d_rt_view_.Get(); - d3d_device_context_->OMSetRenderTargets(1, &main_view, d3d_ds_view_.Get()); + ID3D11RenderTargetView* main_view = rt_view_.Get(); + device_context_->OMSetRenderTargets(1, &main_view, ds_view_.Get()); } } @@ -383,7 +427,7 @@ namespace kiwano output_size_.x, output_size_.y); - d3d_device_context_->RSSetViewports(1, &screen_viewport); + device_context_->RSSetViewports(1, &screen_viewport); } // Create a Direct2D target bitmap associated with the @@ -396,7 +440,7 @@ namespace kiwano ComPtr target; if (SUCCEEDED(hr)) { - hr = GetD2DDeviceContext()->CreateBitmapFromDxgiSurface( + hr = d2d_res_->GetDeviceContext()->CreateBitmapFromDxgiSurface( dxgi_back_buffer.Get(), D2D1::BitmapProperties1( D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW, @@ -408,7 +452,7 @@ namespace kiwano if (SUCCEEDED(hr)) { - SetTargetBitmap(target); + d2d_res_->SetTargetBitmap(target); } } @@ -451,13 +495,56 @@ namespace kiwano logical_size_.x = float(rc.right - rc.left); logical_size_.y = float(rc.bottom - rc.top); - GetD2DDeviceContext()->SetDpi(dpi_, dpi_); + d2d_res_->GetDeviceContext()->SetDpi(dpi_, dpi_); return CreateWindowSizeDependentResources(); } return S_OK; } + STDMETHODIMP_(unsigned long) D3D11DeviceResources::AddRef() + { + return InterlockedIncrement(&ref_count_); + } + + STDMETHODIMP_(unsigned long) D3D11DeviceResources::Release() + { + unsigned long newCount = InterlockedDecrement(&ref_count_); + + if (newCount == 0) + { + delete this; + return 0; + } + + return newCount; + } + + STDMETHODIMP D3D11DeviceResources::QueryInterface(IID const& riid, void** object) + { + if (__uuidof(ID3D11DeviceResources) == riid) + { + *object = this; + } + else if (__uuidof(ID3DDeviceResourcesBase) == riid) + { + *object = this; + } + else if (__uuidof(IUnknown) == riid) + { + *object = this; + } + else + { + *object = nullptr; + return E_FAIL; + } + + AddRef(); + + return S_OK; + } + } #endif // !KGE_USE_DIRECTX10 diff --git a/Kiwano/renderer/D3D11DeviceResources.h b/Kiwano/renderer/D3D11DeviceResources.h index 3c9cba73..b7a702d6 100644 --- a/Kiwano/renderer/D3D11DeviceResources.h +++ b/Kiwano/renderer/D3D11DeviceResources.h @@ -25,73 +25,30 @@ #if !defined(KGE_USE_DIRECTX10) #include "D2DDeviceResources.h" +#include "D3DDeviceResourcesBase.h" #include namespace kiwano { - class KGE_API D3D11DeviceResources - : public D2DDeviceResources + MIDL_INTERFACE("3ede2b87-a202-4799-a39b-2308ad34cae8") + KGE_API ID3D11DeviceResources + : public ID3DDeviceResourcesBase { public: - static HRESULT Create( - D3D11DeviceResources** device_resources, - HWND hwnd - ); + static HRESULT Create(ID3D11DeviceResources** device_resources, ID2DDeviceResources* d2d_device_res, HWND hwnd); - HRESULT Present( - bool vsync - ); - - HRESULT ClearRenderTarget( - Color& clear_color - ); - - HRESULT HandleDeviceLost(); - - HRESULT SetLogicalSize( - Size logical_size - ); - - HRESULT SetDpi( - float dpi - ); - - void DiscardResources(); - - inline ID3D11Device* GetD3DDevice() const { KGE_ASSERT(d3d_device_); return d3d_device_.Get(); } - inline ID3D11DeviceContext* GetD3DDeviceContext() const { KGE_ASSERT(d3d_device_context_); return d3d_device_context_.Get(); } - inline ID3D11RenderTargetView* GetD3DRenderTargetView() const { KGE_ASSERT(d3d_rt_view_); return d3d_rt_view_.Get(); } - inline ID3D11DepthStencilView* GetD3DDepthStencilView() const { KGE_ASSERT(d3d_ds_view_); return d3d_ds_view_.Get(); } + inline ID3D11Device* GetDevice() const { KGE_ASSERT(device_); return device_.Get(); } + inline ID3D11DeviceContext* GetDeviceContext() const { KGE_ASSERT(device_context_); return device_context_.Get(); } + inline ID3D11RenderTargetView* GetRenderTargetView() const { KGE_ASSERT(rt_view_); return rt_view_.Get(); } + inline ID3D11DepthStencilView* GetDepthStencilView() const { KGE_ASSERT(ds_view_); return ds_view_.Get(); } inline IDXGIFactory* GetDXGIFactory() const { KGE_ASSERT(dxgi_factory_); return dxgi_factory_.Get(); } inline IDXGISwapChain* GetDXGISwapChain() const { KGE_ASSERT(dxgi_swap_chain_); return dxgi_swap_chain_.Get(); } - inline D3D_FEATURE_LEVEL GetDeviceFeatureLevel() const { return d3d_feature_level_; } - inline Size const& GetLogicalSize() const { return logical_size_; } - inline Size const& GetOutputSize() const { return output_size_; } - inline float GetDpi() const { return dpi_; } - protected: - D3D11DeviceResources(); - - virtual ~D3D11DeviceResources(); - - protected: - HRESULT CreateDeviceResources(); - - HRESULT CreateWindowSizeDependentResources(); - - private: - HWND hwnd_; - float dpi_; - Size logical_size_; - Size output_size_; - - D3D_FEATURE_LEVEL d3d_feature_level_; - - ComPtr d3d_device_; - ComPtr d3d_device_context_; - ComPtr d3d_rt_view_; - ComPtr d3d_ds_view_; + ComPtr device_; + ComPtr device_context_; + ComPtr rt_view_; + ComPtr ds_view_; ComPtr dxgi_swap_chain_; ComPtr dxgi_factory_; }; diff --git a/Kiwano/renderer/DeviceResources.h b/Kiwano/renderer/D3DDeviceResourcesBase.h similarity index 70% rename from Kiwano/renderer/DeviceResources.h rename to Kiwano/renderer/D3DDeviceResourcesBase.h index 7cb771d1..d742c41f 100644 --- a/Kiwano/renderer/DeviceResources.h +++ b/Kiwano/renderer/D3DDeviceResourcesBase.h @@ -20,20 +20,28 @@ #pragma once #include "../macros.h" - -#if defined(KGE_USE_DIRECTX10) -# include "D3D10DeviceResources.h" -#else -# include "D3D11DeviceResources.h" -#endif +#include "../math/helper.h" +#include "../2d/Color.h" +#include namespace kiwano { -#if defined(KGE_USE_DIRECTX10) - using DeviceResources = D3D10DeviceResources; -#else - using DeviceResources = D3D11DeviceResources; -#endif + MIDL_INTERFACE("fb99fa64-d9cf-4e0e-9c75-90514797b01d") + KGE_API ID3DDeviceResourcesBase : public IUnknown + { + public: + virtual HRESULT Present(bool vsync) = 0; + + virtual HRESULT ClearRenderTarget(Color& clear_color) = 0; + + virtual HRESULT HandleDeviceLost() = 0; + + virtual HRESULT SetLogicalSize(Size logical_size) = 0; + + virtual HRESULT SetDpi(float dpi) = 0; + + virtual void DiscardResources() = 0; + }; } diff --git a/Kiwano/renderer/TextRenderer.cpp b/Kiwano/renderer/TextRenderer.cpp index 31ad9bd7..bc0022cd 100644 --- a/Kiwano/renderer/TextRenderer.cpp +++ b/Kiwano/renderer/TextRenderer.cpp @@ -500,7 +500,11 @@ namespace kiwano IID const& riid, void** ppvObject) { - if (__uuidof(IDWriteTextRenderer) == riid) + if (__uuidof(ITextRenderer) == riid) + { + *ppvObject = this; + } + else if (__uuidof(IDWriteTextRenderer) == riid) { *ppvObject = this; } diff --git a/Kiwano/renderer/TextRenderer.h b/Kiwano/renderer/TextRenderer.h index 3807fe46..1a19cac6 100644 --- a/Kiwano/renderer/TextRenderer.h +++ b/Kiwano/renderer/TextRenderer.h @@ -24,7 +24,7 @@ namespace kiwano { - interface ITextRenderer + interface DWRITE_DECLARE_INTERFACE("b293e798-9916-4096-a3c1-e5d4039dfa64") ITextRenderer : public IDWriteTextRenderer { public: diff --git a/Kiwano/renderer/render.cpp b/Kiwano/renderer/render.cpp index 89dbafbd..aae78c66 100644 --- a/Kiwano/renderer/render.cpp +++ b/Kiwano/renderer/render.cpp @@ -49,21 +49,36 @@ namespace kiwano ThrowIfFailed(hwnd_ ? S_OK : E_FAIL); - device_resources_ = nullptr; + d2d_res_ = nullptr; + d3d_res_ = nullptr; drawing_state_block_ = nullptr; ThrowIfFailed( - DeviceResources::Create( - &device_resources_, - hwnd_ + ID2DDeviceResources::Create( + &d2d_res_ ) ); - factory_ = device_resources_->GetD2DFactory(); - device_context_ = device_resources_->GetD2DDeviceContext(); + ThrowIfFailed( +#if defined(KGE_USE_DIRECTX10) + ID3D10DeviceResources::Create( + &d3d_res_, + d2d_res_.Get(), + hwnd_ + ) +#else + ID3D11DeviceResources::Create( + &d3d_res_, + d2d_res_.Get(), + hwnd_ + ) +#endif + ); + + device_context_ = d2d_res_->GetDeviceContext(); ThrowIfFailed( - factory_->CreateDrawingStateBlock( + d2d_res_->GetFactory()->CreateDrawingStateBlock( &drawing_state_block_ ) ); @@ -80,11 +95,9 @@ namespace kiwano KGE_LOG(L"Destroying device resources"); drawing_state_block_.Reset(); - text_renderer_.Reset(); solid_color_brush_.Reset(); - device_context_.Reset(); - factory_.Reset(); - device_resources_.Reset(); + d2d_res_.Reset(); + d3d_res_.Reset(); } HRESULT Renderer::CreateDeviceResources() @@ -114,7 +127,7 @@ namespace kiwano HRESULT Renderer::HandleDeviceLost() { - HRESULT hr = device_resources_->HandleDeviceLost(); + HRESULT hr = d3d_res_->HandleDeviceLost(); if (SUCCEEDED(hr)) { @@ -151,12 +164,12 @@ namespace kiwano if (SUCCEEDED(hr)) { - hr = device_resources_->Present(vsync_); + hr = d3d_res_->Present(vsync_); } if (SUCCEEDED(hr)) { - hr = device_resources_->ClearRenderTarget(clear_color_); + hr = d3d_res_->ClearRenderTarget(clear_color_); } if (hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_DEVICE_RESET) @@ -197,7 +210,7 @@ namespace kiwano geometry.Get(), solid_color_brush_.Get(), stroke_width, - device_resources_->GetStrokeStyle(stroke) + d2d_res_->GetStrokeStyle(stroke) ); if (collecting_status_) @@ -332,9 +345,9 @@ namespace kiwano { output_size_.x = static_cast(width); output_size_.y = static_cast(height); - if (device_resources_) + if (d3d_res_) { - return device_resources_->SetLogicalSize(output_size_); + return d3d_res_->SetLogicalSize(output_size_); } return S_OK; } @@ -375,7 +388,7 @@ namespace kiwano StrokeStyle outline_stroke ) { - if (!text_renderer_ || !device_resources_) + if (!text_renderer_ || !d3d_res_) return E_UNEXPECTED; text_renderer_->SetTextStyle( @@ -383,7 +396,7 @@ namespace kiwano has_outline, DX::ConvertToColorF(outline_color), outline_width, - device_resources_->GetStrokeStyle(outline_stroke) + d2d_res_->GetStrokeStyle(outline_stroke) ); return S_OK; } diff --git a/Kiwano/renderer/render.h b/Kiwano/renderer/render.h index 0ae2e5f2..e90f6a02 100644 --- a/Kiwano/renderer/render.h +++ b/Kiwano/renderer/render.h @@ -26,17 +26,23 @@ #include "../2d/Font.hpp" #include "../2d/TextStyle.hpp" #include "helper.hpp" -#include "DeviceResources.h" #include "TextRenderer.h" +#include "D2DDeviceResources.h" + +#if defined(KGE_USE_DIRECTX10) +# include "D3D10DeviceResources.h" +#else +# include "D3D11DeviceResources.h" +#endif namespace kiwano { - struct RenderStatus - { - Time start; - Duration duration; - int primitives; - }; + +#if defined(KGE_USE_DIRECTX10) + typedef ID3D10DeviceResources ID3DDeviceResources; +#else + typedef ID3D11DeviceResources ID3DDeviceResources; +#endif class KGE_API Renderer : public Singleton @@ -137,23 +143,32 @@ namespace kiwano ); public: + struct Status + { + Time start; + Duration duration; + int primitives; + }; + void SetupComponent(Application*) override; void DestroyComponent() override; void SetCollectingStatus(bool collecting); - inline HWND GetTargetWindow() const { return hwnd_; } + inline HWND GetTargetWindow() const { return hwnd_; } - inline RenderStatus const& GetStatus() const { return status_; } + inline Status const& GetStatus() const { return status_; } - inline Size const& GetOutputSize() const { return output_size_; } + inline Size const& GetOutputSize() const { return output_size_; } - inline DeviceResources* GetDeviceResources() const { KGE_ASSERT(device_resources_); return device_resources_.Get(); } + inline ID2DDeviceResources* GetD2DDeviceResources() const { KGE_ASSERT(d2d_res_); return d2d_res_.Get(); } - inline ITextRenderer* GetTextRenderer() const { KGE_ASSERT(text_renderer_); return text_renderer_.Get(); } + inline ID3DDeviceResources* GetD3DDeviceResources() const { KGE_ASSERT(d3d_res_); return d3d_res_.Get(); } - inline ID2D1SolidColorBrush* GetSolidColorBrush() const { KGE_ASSERT(solid_color_brush_); return solid_color_brush_.Get(); } + inline ITextRenderer* GetTextRenderer() const { KGE_ASSERT(text_renderer_); return text_renderer_.Get(); } + + inline ID2D1SolidColorBrush* GetSolidColorBrush() const { KGE_ASSERT(solid_color_brush_); return solid_color_brush_.Get(); } private: Renderer(); @@ -176,10 +191,10 @@ namespace kiwano Size output_size_; Color clear_color_; TextAntialias text_antialias_; - RenderStatus status_; + Status status_; - ComPtr device_resources_; - ComPtr factory_; + ComPtr d2d_res_; + ComPtr d3d_res_; ComPtr device_context_; ComPtr drawing_state_block_; ComPtr text_renderer_;