xref: /aosp_15_r20/external/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.h (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1 //
2 // Copyright 2014 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 
7 // InspectableNativeWindow.h: Host specific implementation interface for
8 // managing IInspectable native window types.
9 
10 #ifndef LIBANGLE_RENDERER_D3D_D3D11_WINRT_INSPECTABLENATIVEWINDOW_H_
11 #define LIBANGLE_RENDERER_D3D_D3D11_WINRT_INSPECTABLENATIVEWINDOW_H_
12 
13 #include "common/debug.h"
14 #include "common/platform.h"
15 
16 #include "angle_windowsstore.h"
17 
18 #include <EGL/eglplatform.h>
19 
20 #include <windows.applicationmodel.core.h>
21 #undef GetCurrentTime
22 #if defined(ANGLE_ENABLE_WINDOWS_APP_SDK)
23 #    include <microsoft.ui.dispatching.h>
24 #    include <microsoft.ui.xaml.h>
25 #    include <microsoft.ui.xaml.media.dxinterop.h>
26 #else
27 #    include <windows.ui.xaml.h>
28 #    include <windows.ui.xaml.media.dxinterop.h>
29 #endif
30 #include <wrl.h>
31 #include <wrl/wrappers/corewrappers.h>
32 
33 using namespace Microsoft::WRL;
34 using namespace Microsoft::WRL::Wrappers;
35 using namespace ABI::Windows::Foundation;
36 using namespace ABI::Windows::Foundation::Collections;
37 
38 #if defined(ANGLE_ENABLE_WINDOWS_APP_SDK)
39 using ISwapChainPanel = ABI::Microsoft::UI::Xaml::Controls::ISwapChainPanel;
40 #else
41 using ISwapChainPanel = ABI::Windows::UI::Xaml::Controls::ISwapChainPanel;
42 #endif
43 
44 namespace rx
45 {
46 class InspectableNativeWindow
47 {
48   public:
InspectableNativeWindow()49     InspectableNativeWindow()
50         : mSupportsSwapChainResize(true),
51           mSwapChainSizeSpecified(false),
52           mSwapChainScaleSpecified(false),
53           mSwapChainScale(1.0f),
54           mClientRectChanged(false),
55           mClientRect({0, 0, 0, 0}),
56           mNewClientRect({0, 0, 0, 0})
57     {
58         mSizeChangedEventToken.value = 0;
59     }
~InspectableNativeWindow()60     virtual ~InspectableNativeWindow() {}
61 
62     virtual bool initialize(EGLNativeWindowType window, IPropertySet *propertySet) = 0;
63     virtual HRESULT createSwapChain(ID3D11Device *device,
64                                     IDXGIFactory2 *factory,
65                                     DXGI_FORMAT format,
66                                     unsigned int width,
67                                     unsigned int height,
68                                     bool containsAlpha,
69                                     IDXGISwapChain1 **swapChain)                   = 0;
70 
getClientRect(RECT * rect)71     bool getClientRect(RECT *rect)
72     {
73         if (mClientRectChanged)
74         {
75             mClientRect = mNewClientRect;
76         }
77 
78         *rect = mClientRect;
79 
80         return true;
81     }
82 
83     // setNewClientSize is used by the WinRT size change handler. It isn't used by the rest of
84     // ANGLE.
setNewClientSize(const Size & newWindowSize)85     void setNewClientSize(const Size &newWindowSize)
86     {
87         // If the client doesn't support swapchain resizing then we should have already unregistered
88         // from size change handler
89         ASSERT(mSupportsSwapChainResize);
90 
91         if (mSupportsSwapChainResize)
92         {
93             // If the swapchain size was specified then we should ignore this call too
94             if (!mSwapChainSizeSpecified)
95             {
96                 mNewClientRect     = clientRect(newWindowSize);
97                 mClientRectChanged = true;
98 
99                 // If a scale was specified, then now is the time to apply the scale matrix for the
100                 // new swapchain size and window size
101                 if (mSwapChainScaleSpecified)
102                 {
103                     scaleSwapChain(newWindowSize, mNewClientRect);
104                 }
105             }
106 
107             // Even if the swapchain size was fixed, the window might have changed size.
108             // In this case, we should recalculate the scale matrix to account for the new window
109             // size
110             if (mSwapChainSizeSpecified)
111             {
112                 scaleSwapChain(newWindowSize, mClientRect);
113             }
114         }
115     }
116 
117   protected:
118     virtual HRESULT scaleSwapChain(const Size &windowSize, const RECT &clientRect) = 0;
119     RECT clientRect(const Size &size);
120 
121     bool mSupportsSwapChainResize;  // Support for IDXGISwapChain::ResizeBuffers method
122     bool mSwapChainSizeSpecified;   // If an EGLRenderSurfaceSizeProperty was specified
123     bool mSwapChainScaleSpecified;  // If an EGLRenderResolutionScaleProperty was specified
124     float mSwapChainScale;  // The scale value specified by the EGLRenderResolutionScaleProperty
125                             // property
126     RECT mClientRect;
127     RECT mNewClientRect;
128     bool mClientRectChanged;
129 
130     EventRegistrationToken mSizeChangedEventToken;
131 };
132 
133 bool IsCoreWindow(EGLNativeWindowType window,
134                   ComPtr<ABI::Windows::UI::Core::ICoreWindow> *coreWindow = nullptr);
135 bool IsSwapChainPanel(EGLNativeWindowType window,
136                       ComPtr<ISwapChainPanel> *swapChainPanel = nullptr);
137 bool IsEGLConfiguredPropertySet(
138     EGLNativeWindowType window,
139     ABI::Windows::Foundation::Collections::IPropertySet **propertySet = nullptr,
140     IInspectable **inspectable                                        = nullptr);
141 
142 HRESULT GetOptionalPropertyValue(
143     const ComPtr<ABI::Windows::Foundation::Collections::IMap<HSTRING, IInspectable *>> &propertyMap,
144     const wchar_t *propertyName,
145     boolean *hasKey,
146     ComPtr<ABI::Windows::Foundation::IPropertyValue> &propertyValue);
147 
148 HRESULT GetOptionalSizePropertyValue(
149     const ComPtr<ABI::Windows::Foundation::Collections::IMap<HSTRING, IInspectable *>> &propertyMap,
150     const wchar_t *propertyName,
151     SIZE *value,
152     bool *valueExists);
153 
154 HRESULT GetOptionalSinglePropertyValue(
155     const ComPtr<ABI::Windows::Foundation::Collections::IMap<HSTRING, IInspectable *>> &propertyMap,
156     const wchar_t *propertyName,
157     float *value,
158     bool *valueExists);
159 }  // namespace rx
160 
161 #endif  // LIBANGLE_RENDERER_D3D_D3D11_WINRT_INSPECTABLENATIVEWINDOW_H_
162