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 #include <windows.ui.xaml.h> 22 #include <windows.ui.xaml.media.dxinterop.h> 23 #include <wrl.h> 24 #include <wrl/wrappers/corewrappers.h> 25 26 using namespace Microsoft::WRL; 27 using namespace Microsoft::WRL::Wrappers; 28 using namespace ABI::Windows::Foundation; 29 using namespace ABI::Windows::Foundation::Collections; 30 31 namespace rx 32 { 33 class InspectableNativeWindow 34 { 35 public: InspectableNativeWindow()36 InspectableNativeWindow() 37 : mSupportsSwapChainResize(true), 38 mSwapChainSizeSpecified(false), 39 mSwapChainScaleSpecified(false), 40 mSwapChainScale(1.0f), 41 mClientRectChanged(false), 42 mClientRect({0, 0, 0, 0}), 43 mNewClientRect({0, 0, 0, 0}) 44 { 45 mSizeChangedEventToken.value = 0; 46 } ~InspectableNativeWindow()47 virtual ~InspectableNativeWindow() {} 48 49 virtual bool initialize(EGLNativeWindowType window, IPropertySet *propertySet) = 0; 50 virtual HRESULT createSwapChain(ID3D11Device *device, 51 IDXGIFactory2 *factory, 52 DXGI_FORMAT format, 53 unsigned int width, 54 unsigned int height, 55 bool containsAlpha, 56 IDXGISwapChain1 **swapChain) = 0; 57 getClientRect(RECT * rect)58 bool getClientRect(RECT *rect) 59 { 60 if (mClientRectChanged) 61 { 62 mClientRect = mNewClientRect; 63 } 64 65 *rect = mClientRect; 66 67 return true; 68 } 69 70 // setNewClientSize is used by the WinRT size change handler. It isn't used by the rest of 71 // ANGLE. setNewClientSize(const Size & newWindowSize)72 void setNewClientSize(const Size &newWindowSize) 73 { 74 // If the client doesn't support swapchain resizing then we should have already unregistered 75 // from size change handler 76 ASSERT(mSupportsSwapChainResize); 77 78 if (mSupportsSwapChainResize) 79 { 80 // If the swapchain size was specified then we should ignore this call too 81 if (!mSwapChainSizeSpecified) 82 { 83 mNewClientRect = clientRect(newWindowSize); 84 mClientRectChanged = true; 85 86 // If a scale was specified, then now is the time to apply the scale matrix for the 87 // new swapchain size and window size 88 if (mSwapChainScaleSpecified) 89 { 90 scaleSwapChain(newWindowSize, mNewClientRect); 91 } 92 } 93 94 // Even if the swapchain size was fixed, the window might have changed size. 95 // In this case, we should recalculate the scale matrix to account for the new window 96 // size 97 if (mSwapChainSizeSpecified) 98 { 99 scaleSwapChain(newWindowSize, mClientRect); 100 } 101 } 102 } 103 104 protected: 105 virtual HRESULT scaleSwapChain(const Size &windowSize, const RECT &clientRect) = 0; 106 RECT clientRect(const Size &size); 107 108 bool mSupportsSwapChainResize; // Support for IDXGISwapChain::ResizeBuffers method 109 bool mSwapChainSizeSpecified; // If an EGLRenderSurfaceSizeProperty was specified 110 bool mSwapChainScaleSpecified; // If an EGLRenderResolutionScaleProperty was specified 111 float mSwapChainScale; // The scale value specified by the EGLRenderResolutionScaleProperty 112 // property 113 RECT mClientRect; 114 RECT mNewClientRect; 115 bool mClientRectChanged; 116 117 EventRegistrationToken mSizeChangedEventToken; 118 }; 119 120 bool IsCoreWindow(EGLNativeWindowType window, 121 ComPtr<ABI::Windows::UI::Core::ICoreWindow> *coreWindow = nullptr); 122 bool IsSwapChainPanel( 123 EGLNativeWindowType window, 124 ComPtr<ABI::Windows::UI::Xaml::Controls::ISwapChainPanel> *swapChainPanel = nullptr); 125 bool IsEGLConfiguredPropertySet( 126 EGLNativeWindowType window, 127 ABI::Windows::Foundation::Collections::IPropertySet **propertySet = nullptr, 128 IInspectable **inspectable = nullptr); 129 130 HRESULT GetOptionalPropertyValue( 131 const ComPtr<ABI::Windows::Foundation::Collections::IMap<HSTRING, IInspectable *>> &propertyMap, 132 const wchar_t *propertyName, 133 boolean *hasKey, 134 ComPtr<ABI::Windows::Foundation::IPropertyValue> &propertyValue); 135 136 HRESULT GetOptionalSizePropertyValue( 137 const ComPtr<ABI::Windows::Foundation::Collections::IMap<HSTRING, IInspectable *>> &propertyMap, 138 const wchar_t *propertyName, 139 SIZE *value, 140 bool *valueExists); 141 142 HRESULT GetOptionalSinglePropertyValue( 143 const ComPtr<ABI::Windows::Foundation::Collections::IMap<HSTRING, IInspectable *>> &propertyMap, 144 const wchar_t *propertyName, 145 float *value, 146 bool *valueExists); 147 } // namespace rx 148 149 #endif // LIBANGLE_RENDERER_D3D_D3D11_WINRT_INSPECTABLENATIVEWINDOW_H_ 150