| // |
| // Copyright 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.cpp: NativeWindow base class for managing IInspectable native window |
| // types. |
| |
| #include "libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.h" |
| #include "libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.h" |
| |
| namespace rx |
| { |
| |
| bool IsCoreWindow(EGLNativeWindowType window, |
| ComPtr<ABI::Windows::UI::Core::ICoreWindow> *coreWindow) |
| { |
| if (!window) |
| { |
| return false; |
| } |
| |
| ComPtr<IInspectable> win = static_cast<IInspectable *>(window); |
| ComPtr<ABI::Windows::UI::Core::ICoreWindow> coreWin; |
| if (SUCCEEDED(win.As(&coreWin))) |
| { |
| if (coreWindow != nullptr) |
| { |
| *coreWindow = coreWin; |
| } |
| return true; |
| } |
| |
| return false; |
| } |
| |
| bool IsSwapChainPanel(EGLNativeWindowType window, |
| ComPtr<ABI::Windows::UI::Xaml::Controls::ISwapChainPanel> *swapChainPanel) |
| { |
| if (!window) |
| { |
| return false; |
| } |
| |
| ComPtr<IInspectable> win = static_cast<IInspectable *>(window); |
| ComPtr<ABI::Windows::UI::Xaml::Controls::ISwapChainPanel> panel; |
| if (SUCCEEDED(win.As(&panel))) |
| { |
| if (swapChainPanel != nullptr) |
| { |
| *swapChainPanel = panel; |
| } |
| return true; |
| } |
| |
| return false; |
| } |
| |
| bool IsEGLConfiguredPropertySet(EGLNativeWindowType window, |
| ABI::Windows::Foundation::Collections::IPropertySet **propertySet, |
| IInspectable **eglNativeWindow) |
| { |
| if (!window) |
| { |
| return false; |
| } |
| |
| ComPtr<IInspectable> props = static_cast<IInspectable *>(window); |
| ComPtr<IPropertySet> propSet; |
| ComPtr<IInspectable> nativeWindow; |
| ComPtr<ABI::Windows::Foundation::Collections::IMap<HSTRING, IInspectable *>> propMap; |
| boolean hasEglNativeWindowPropertyKey = false; |
| |
| HRESULT result = props.As(&propSet); |
| if (SUCCEEDED(result)) |
| { |
| result = propSet.As(&propMap); |
| } |
| |
| // Look for the presence of the EGLNativeWindowType in the property set |
| if (SUCCEEDED(result)) |
| { |
| result = propMap->HasKey(HStringReference(EGLNativeWindowTypeProperty).Get(), |
| &hasEglNativeWindowPropertyKey); |
| } |
| |
| // If the IPropertySet does not contain the required EglNativeWindowType key, the property set |
| // is considered invalid. |
| if (SUCCEEDED(result) && !hasEglNativeWindowPropertyKey) |
| { |
| ERR() << "Could not find EGLNativeWindowTypeProperty in IPropertySet. Valid " |
| "EGLNativeWindowTypeProperty values include ICoreWindow"; |
| return false; |
| } |
| |
| // The EglNativeWindowType property exists, so retreive the IInspectable that represents the |
| // EGLNativeWindowType |
| if (SUCCEEDED(result) && hasEglNativeWindowPropertyKey) |
| { |
| result = |
| propMap->Lookup(HStringReference(EGLNativeWindowTypeProperty).Get(), &nativeWindow); |
| } |
| |
| if (SUCCEEDED(result)) |
| { |
| if (propertySet != nullptr) |
| { |
| result = propSet.CopyTo(propertySet); |
| } |
| } |
| |
| if (SUCCEEDED(result)) |
| { |
| if (eglNativeWindow != nullptr) |
| { |
| result = nativeWindow.CopyTo(eglNativeWindow); |
| } |
| } |
| |
| if (SUCCEEDED(result)) |
| { |
| return true; |
| } |
| |
| return false; |
| } |
| |
| // Retrieve an optional property from a property set |
| HRESULT GetOptionalPropertyValue( |
| const ComPtr<ABI::Windows::Foundation::Collections::IMap<HSTRING, IInspectable *>> &propertyMap, |
| const wchar_t *propertyName, |
| boolean *hasKey, |
| ComPtr<ABI::Windows::Foundation::IPropertyValue> &propertyValue) |
| { |
| if (!propertyMap || !hasKey) |
| { |
| return E_INVALIDARG; |
| } |
| |
| // Assume that the value does not exist |
| *hasKey = false; |
| |
| HRESULT result = propertyMap->HasKey(HStringReference(propertyName).Get(), hasKey); |
| if (SUCCEEDED(result) && !(*hasKey)) |
| { |
| // Value does not exist, so return S_OK and set the exists parameter to false to indicate |
| // that a the optional property does not exist. |
| return S_OK; |
| } |
| |
| if (SUCCEEDED(result)) |
| { |
| result = propertyMap->Lookup(HStringReference(propertyName).Get(), &propertyValue); |
| } |
| |
| return result; |
| } |
| |
| // Attempts to read an optional SIZE property value that is assumed to be in the form of |
| // an ABI::Windows::Foundation::Size. This function validates the Size value before returning |
| // it to the caller. |
| // |
| // Possible return values are: |
| // S_OK, valueExists == true - optional SIZE value was successfully retrieved and validated |
| // S_OK, valueExists == false - optional SIZE value was not found |
| // E_INVALIDARG, valueExists = false - optional SIZE value was malformed in the property set. |
| // * Incorrect property type ( must be PropertyType_Size) |
| // * Invalid property value (width/height must be > 0) |
| // Additional errors may be returned from IMap or IPropertyValue |
| // |
| HRESULT GetOptionalSizePropertyValue( |
| const ComPtr<ABI::Windows::Foundation::Collections::IMap<HSTRING, IInspectable *>> &propertyMap, |
| const wchar_t *propertyName, |
| SIZE *value, |
| bool *valueExists) |
| { |
| ComPtr<ABI::Windows::Foundation::IPropertyValue> propertyValue; |
| ABI::Windows::Foundation::PropertyType propertyType = |
| ABI::Windows::Foundation::PropertyType::PropertyType_Empty; |
| Size sizeValue = {0, 0}; |
| boolean hasKey = false; |
| |
| if (!propertyMap || !value || !valueExists) |
| { |
| return E_INVALIDARG; |
| } |
| |
| // Assume that the value does not exist |
| *valueExists = false; |
| *value = {0, 0}; |
| |
| HRESULT result = GetOptionalPropertyValue(propertyMap, propertyName, &hasKey, propertyValue); |
| if (SUCCEEDED(result) && hasKey) |
| { |
| result = propertyValue->get_Type(&propertyType); |
| |
| // Check if the expected Size property is of PropertyType_Size type. |
| if (SUCCEEDED(result) && |
| propertyType == ABI::Windows::Foundation::PropertyType::PropertyType_Size) |
| { |
| if (SUCCEEDED(propertyValue->GetSize(&sizeValue)) && |
| (sizeValue.Width > 0 && sizeValue.Height > 0)) |
| { |
| // A valid property value exists |
| *value = {static_cast<long>(sizeValue.Width), static_cast<long>(sizeValue.Height)}; |
| *valueExists = true; |
| result = S_OK; |
| } |
| else |
| { |
| // An invalid Size property was detected. Width/Height values must > 0 |
| result = E_INVALIDARG; |
| } |
| } |
| else |
| { |
| // An invalid property type was detected. Size property must be of PropertyType_Size |
| result = E_INVALIDARG; |
| } |
| } |
| |
| return result; |
| } |
| |
| // Attempts to read an optional float property value that is assumed to be in the form of |
| // an ABI::Windows::Foundation::Single. This function validates the Single value before returning |
| // it to the caller. |
| // |
| // Possible return values are: |
| // S_OK, valueExists == true - optional Single value was successfully retrieved and validated |
| // S_OK, valueExists == false - optional Single value was not found |
| // E_INVALIDARG, valueExists = false - optional Single value was malformed in the property set. |
| // * Incorrect property type ( must be PropertyType_Single) |
| // * Invalid property value (must be > 0) |
| // Additional errors may be returned from IMap or IPropertyValue |
| // |
| HRESULT GetOptionalSinglePropertyValue( |
| const ComPtr<ABI::Windows::Foundation::Collections::IMap<HSTRING, IInspectable *>> &propertyMap, |
| const wchar_t *propertyName, |
| float *value, |
| bool *valueExists) |
| { |
| ComPtr<ABI::Windows::Foundation::IPropertyValue> propertyValue; |
| ABI::Windows::Foundation::PropertyType propertyType = |
| ABI::Windows::Foundation::PropertyType::PropertyType_Empty; |
| float scaleValue = 0.0f; |
| boolean hasKey = false; |
| |
| if (!propertyMap || !value || !valueExists) |
| { |
| return E_INVALIDARG; |
| } |
| |
| // Assume that the value does not exist |
| *valueExists = false; |
| *value = 0.0f; |
| |
| HRESULT result = GetOptionalPropertyValue(propertyMap, propertyName, &hasKey, propertyValue); |
| if (SUCCEEDED(result) && hasKey) |
| { |
| result = propertyValue->get_Type(&propertyType); |
| |
| // Check if the expected Scale property is of PropertyType_Single type. |
| if (SUCCEEDED(result) && |
| propertyType == ABI::Windows::Foundation::PropertyType::PropertyType_Single) |
| { |
| if (SUCCEEDED(propertyValue->GetSingle(&scaleValue)) && (scaleValue > 0.0f)) |
| { |
| // A valid property value exists |
| *value = scaleValue; |
| *valueExists = true; |
| result = S_OK; |
| } |
| else |
| { |
| // An invalid scale was set |
| result = E_INVALIDARG; |
| } |
| } |
| else |
| { |
| // An invalid property type was detected. Size property must be of PropertyType_Single |
| result = E_INVALIDARG; |
| } |
| } |
| |
| return result; |
| } |
| |
| RECT InspectableNativeWindow::clientRect(const Size &size) |
| { |
| // We don't have to check if a swapchain scale was specified here; the default value is 1.0f |
| // which will have no effect. |
| return {0, 0, lround(size.Width * mSwapChainScale), lround(size.Height * mSwapChainScale)}; |
| } |
| } // namespace rx |