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