// // Copyright (c) 2014 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // // InspectableNativeWindow.h: Host specific implementation interface for // managing IInspectable native window types. #ifndef LIBANGLE_RENDERER_D3D_D3D11_WINRT_INSPECTABLENATIVEWINDOW_H_ #define LIBANGLE_RENDERER_D3D_D3D11_WINRT_INSPECTABLENATIVEWINDOW_H_ #include "common/debug.h" #include "common/platform.h" #include "angle_windowsstore.h" #include #include #include #include #include #include using namespace Microsoft::WRL; using namespace Microsoft::WRL::Wrappers; using namespace ABI::Windows::Foundation; using namespace ABI::Windows::Foundation::Collections; namespace rx { float ConvertDipsToPixels(float dips); float GetLogicalDpi(); class InspectableNativeWindow { public: InspectableNativeWindow() : mSupportsSwapChainResize(true), mSwapChainSizeSpecified(false), mSwapChainScaleSpecified(false), mClientRectChanged(false), mClientRect({0,0,0,0}), mNewClientRect({0,0,0,0}) { mSizeChangedEventToken.value = 0; mSwapChainScale = 96.0f / GetLogicalDpi(); if (mSwapChainScale != 1.0f) mSwapChainScaleSpecified = true; } virtual ~InspectableNativeWindow(){} virtual bool initialize(EGLNativeWindowType window, IPropertySet *propertySet) = 0; virtual HRESULT createSwapChain(ID3D11Device *device, IDXGIFactory2 *factory, DXGI_FORMAT format, unsigned int width, unsigned int height, bool containsAlpha, IDXGISwapChain1 **swapChain) = 0; bool getClientRect(RECT *rect) { if (mClientRectChanged) { mClientRect = mNewClientRect; } *rect = mClientRect; return true; } // setNewClientSize is used by the WinRT size change handler. It isn't used by the rest of ANGLE. void setNewClientSize(const Size &newWindowSize) { // If the client doesn't support swapchain resizing then we should have already unregistered from size change handler ASSERT(mSupportsSwapChainResize); if (mSupportsSwapChainResize) { // If the swapchain size was specified then we should ignore this call too if (!mSwapChainSizeSpecified) { mNewClientRect = clientRect(newWindowSize); mClientRectChanged = true; // If a scale was specified, then now is the time to apply the scale matrix for the new swapchain size and window size if (mSwapChainScaleSpecified) { scaleSwapChain(newWindowSize, mNewClientRect); } } // Even if the swapchain size was fixed, the window might have changed size. // In this case, we should recalculate the scale matrix to account for the new window size if (mSwapChainSizeSpecified) { scaleSwapChain(newWindowSize, mClientRect); } } } protected: virtual HRESULT scaleSwapChain(const Size &windowSize, const RECT &clientRect) = 0; RECT clientRect(const Size &size); bool mSupportsSwapChainResize; // Support for IDXGISwapChain::ResizeBuffers method bool mSwapChainSizeSpecified; // If an EGLRenderSurfaceSizeProperty was specified bool mSwapChainScaleSpecified; // If an EGLRenderResolutionScaleProperty was specified float mSwapChainScale; // The scale value specified by the EGLRenderResolutionScaleProperty property RECT mClientRect; RECT mNewClientRect; bool mClientRectChanged; EventRegistrationToken mSizeChangedEventToken; }; bool IsCoreWindow(EGLNativeWindowType window, ComPtr *coreWindow = nullptr); bool IsSwapChainPanel(EGLNativeWindowType window, ComPtr *swapChainPanel = nullptr); bool IsEGLConfiguredPropertySet(EGLNativeWindowType window, ABI::Windows::Foundation::Collections::IPropertySet **propertySet = nullptr, IInspectable **inspectable = nullptr); HRESULT GetOptionalPropertyValue(const ComPtr> &propertyMap, const wchar_t *propertyName, boolean *hasKey, ComPtr &propertyValue); HRESULT GetOptionalSizePropertyValue(const ComPtr> &propertyMap, const wchar_t *propertyName, SIZE *value, bool *valueExists); HRESULT GetOptionalSinglePropertyValue(const ComPtr> &propertyMap, const wchar_t *propertyName, float *value, bool *valueExists); } #endif // LIBANGLE_RENDERER_D3D_D3D11_WINRT_INSPECTABLENATIVEWINDOW_H_