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.cpp: NativeWindow base class for managing IInspectable native window
8 // types.
9
10 #include "libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.h"
11 #include "libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.h"
12
13 namespace rx
14 {
15
IsCoreWindow(EGLNativeWindowType window,ComPtr<ABI::Windows::UI::Core::ICoreWindow> * coreWindow)16 bool IsCoreWindow(EGLNativeWindowType window,
17 ComPtr<ABI::Windows::UI::Core::ICoreWindow> *coreWindow)
18 {
19 if (!window)
20 {
21 return false;
22 }
23
24 ComPtr<IInspectable> win = reinterpret_cast<IInspectable *>(window);
25 ComPtr<ABI::Windows::UI::Core::ICoreWindow> coreWin;
26 if (SUCCEEDED(win.As(&coreWin)))
27 {
28 if (coreWindow != nullptr)
29 {
30 *coreWindow = coreWin;
31 }
32 return true;
33 }
34
35 return false;
36 }
37
IsSwapChainPanel(EGLNativeWindowType window,ComPtr<ABI::Windows::UI::Xaml::Controls::ISwapChainPanel> * swapChainPanel)38 bool IsSwapChainPanel(EGLNativeWindowType window,
39 ComPtr<ABI::Windows::UI::Xaml::Controls::ISwapChainPanel> *swapChainPanel)
40 {
41 if (!window)
42 {
43 return false;
44 }
45
46 ComPtr<IInspectable> win = window;
47 ComPtr<ABI::Windows::UI::Xaml::Controls::ISwapChainPanel> panel;
48 if (SUCCEEDED(win.As(&panel)))
49 {
50 if (swapChainPanel != nullptr)
51 {
52 *swapChainPanel = panel;
53 }
54 return true;
55 }
56
57 return false;
58 }
59
IsEGLConfiguredPropertySet(EGLNativeWindowType window,ABI::Windows::Foundation::Collections::IPropertySet ** propertySet,IInspectable ** eglNativeWindow)60 bool IsEGLConfiguredPropertySet(EGLNativeWindowType window,
61 ABI::Windows::Foundation::Collections::IPropertySet **propertySet,
62 IInspectable **eglNativeWindow)
63 {
64 if (!window)
65 {
66 return false;
67 }
68
69 ComPtr<IInspectable> props = window;
70 ComPtr<IPropertySet> propSet;
71 ComPtr<IInspectable> nativeWindow;
72 ComPtr<ABI::Windows::Foundation::Collections::IMap<HSTRING, IInspectable *>> propMap;
73 boolean hasEglNativeWindowPropertyKey = false;
74
75 HRESULT result = props.As(&propSet);
76 if (SUCCEEDED(result))
77 {
78 result = propSet.As(&propMap);
79 }
80
81 // Look for the presence of the EGLNativeWindowType in the property set
82 if (SUCCEEDED(result))
83 {
84 result = propMap->HasKey(HStringReference(EGLNativeWindowTypeProperty).Get(),
85 &hasEglNativeWindowPropertyKey);
86 }
87
88 // If the IPropertySet does not contain the required EglNativeWindowType key, the property set
89 // is considered invalid.
90 if (SUCCEEDED(result) && !hasEglNativeWindowPropertyKey)
91 {
92 ERR() << "Could not find EGLNativeWindowTypeProperty in IPropertySet. Valid "
93 "EGLNativeWindowTypeProperty values include ICoreWindow";
94 return false;
95 }
96
97 // The EglNativeWindowType property exists, so retreive the IInspectable that represents the
98 // EGLNativeWindowType
99 if (SUCCEEDED(result) && hasEglNativeWindowPropertyKey)
100 {
101 result =
102 propMap->Lookup(HStringReference(EGLNativeWindowTypeProperty).Get(), &nativeWindow);
103 }
104
105 if (SUCCEEDED(result))
106 {
107 if (propertySet != nullptr)
108 {
109 result = propSet.CopyTo(propertySet);
110 }
111 }
112
113 if (SUCCEEDED(result))
114 {
115 if (eglNativeWindow != nullptr)
116 {
117 result = nativeWindow.CopyTo(eglNativeWindow);
118 }
119 }
120
121 if (SUCCEEDED(result))
122 {
123 return true;
124 }
125
126 return false;
127 }
128
129 // Retrieve an optional property from a property set
GetOptionalPropertyValue(const ComPtr<ABI::Windows::Foundation::Collections::IMap<HSTRING,IInspectable * >> & propertyMap,const wchar_t * propertyName,boolean * hasKey,ComPtr<ABI::Windows::Foundation::IPropertyValue> & propertyValue)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 if (!propertyMap || !hasKey)
137 {
138 return E_INVALIDARG;
139 }
140
141 // Assume that the value does not exist
142 *hasKey = false;
143
144 HRESULT result = propertyMap->HasKey(HStringReference(propertyName).Get(), hasKey);
145 if (SUCCEEDED(result) && !(*hasKey))
146 {
147 // Value does not exist, so return S_OK and set the exists parameter to false to indicate
148 // that a the optional property does not exist.
149 return S_OK;
150 }
151
152 if (SUCCEEDED(result))
153 {
154 result = propertyMap->Lookup(HStringReference(propertyName).Get(), &propertyValue);
155 }
156
157 return result;
158 }
159
160 // Attempts to read an optional SIZE property value that is assumed to be in the form of
161 // an ABI::Windows::Foundation::Size. This function validates the Size value before returning
162 // it to the caller.
163 //
164 // Possible return values are:
165 // S_OK, valueExists == true - optional SIZE value was successfully retrieved and validated
166 // S_OK, valueExists == false - optional SIZE value was not found
167 // E_INVALIDARG, valueExists = false - optional SIZE value was malformed in the property set.
168 // * Incorrect property type ( must be PropertyType_Size)
169 // * Invalid property value (width/height must be > 0)
170 // Additional errors may be returned from IMap or IPropertyValue
171 //
GetOptionalSizePropertyValue(const ComPtr<ABI::Windows::Foundation::Collections::IMap<HSTRING,IInspectable * >> & propertyMap,const wchar_t * propertyName,SIZE * value,bool * valueExists)172 HRESULT GetOptionalSizePropertyValue(
173 const ComPtr<ABI::Windows::Foundation::Collections::IMap<HSTRING, IInspectable *>> &propertyMap,
174 const wchar_t *propertyName,
175 SIZE *value,
176 bool *valueExists)
177 {
178 ComPtr<ABI::Windows::Foundation::IPropertyValue> propertyValue;
179 ABI::Windows::Foundation::PropertyType propertyType =
180 ABI::Windows::Foundation::PropertyType::PropertyType_Empty;
181 Size sizeValue = {0, 0};
182 boolean hasKey = false;
183
184 if (!propertyMap || !value || !valueExists)
185 {
186 return E_INVALIDARG;
187 }
188
189 // Assume that the value does not exist
190 *valueExists = false;
191 *value = {0, 0};
192
193 HRESULT result = GetOptionalPropertyValue(propertyMap, propertyName, &hasKey, propertyValue);
194 if (SUCCEEDED(result) && hasKey)
195 {
196 result = propertyValue->get_Type(&propertyType);
197
198 // Check if the expected Size property is of PropertyType_Size type.
199 if (SUCCEEDED(result) &&
200 propertyType == ABI::Windows::Foundation::PropertyType::PropertyType_Size)
201 {
202 if (SUCCEEDED(propertyValue->GetSize(&sizeValue)) &&
203 (sizeValue.Width > 0 && sizeValue.Height > 0))
204 {
205 // A valid property value exists
206 *value = {static_cast<long>(sizeValue.Width), static_cast<long>(sizeValue.Height)};
207 *valueExists = true;
208 result = S_OK;
209 }
210 else
211 {
212 // An invalid Size property was detected. Width/Height values must > 0
213 result = E_INVALIDARG;
214 }
215 }
216 else
217 {
218 // An invalid property type was detected. Size property must be of PropertyType_Size
219 result = E_INVALIDARG;
220 }
221 }
222
223 return result;
224 }
225
226 // Attempts to read an optional float property value that is assumed to be in the form of
227 // an ABI::Windows::Foundation::Single. This function validates the Single value before returning
228 // it to the caller.
229 //
230 // Possible return values are:
231 // S_OK, valueExists == true - optional Single value was successfully retrieved and validated
232 // S_OK, valueExists == false - optional Single value was not found
233 // E_INVALIDARG, valueExists = false - optional Single value was malformed in the property set.
234 // * Incorrect property type ( must be PropertyType_Single)
235 // * Invalid property value (must be > 0)
236 // Additional errors may be returned from IMap or IPropertyValue
237 //
GetOptionalSinglePropertyValue(const ComPtr<ABI::Windows::Foundation::Collections::IMap<HSTRING,IInspectable * >> & propertyMap,const wchar_t * propertyName,float * value,bool * valueExists)238 HRESULT GetOptionalSinglePropertyValue(
239 const ComPtr<ABI::Windows::Foundation::Collections::IMap<HSTRING, IInspectable *>> &propertyMap,
240 const wchar_t *propertyName,
241 float *value,
242 bool *valueExists)
243 {
244 ComPtr<ABI::Windows::Foundation::IPropertyValue> propertyValue;
245 ABI::Windows::Foundation::PropertyType propertyType =
246 ABI::Windows::Foundation::PropertyType::PropertyType_Empty;
247 float scaleValue = 0.0f;
248 boolean hasKey = false;
249
250 if (!propertyMap || !value || !valueExists)
251 {
252 return E_INVALIDARG;
253 }
254
255 // Assume that the value does not exist
256 *valueExists = false;
257 *value = 0.0f;
258
259 HRESULT result = GetOptionalPropertyValue(propertyMap, propertyName, &hasKey, propertyValue);
260 if (SUCCEEDED(result) && hasKey)
261 {
262 result = propertyValue->get_Type(&propertyType);
263
264 // Check if the expected Scale property is of PropertyType_Single type.
265 if (SUCCEEDED(result) &&
266 propertyType == ABI::Windows::Foundation::PropertyType::PropertyType_Single)
267 {
268 if (SUCCEEDED(propertyValue->GetSingle(&scaleValue)) && (scaleValue > 0.0f))
269 {
270 // A valid property value exists
271 *value = scaleValue;
272 *valueExists = true;
273 result = S_OK;
274 }
275 else
276 {
277 // An invalid scale was set
278 result = E_INVALIDARG;
279 }
280 }
281 else
282 {
283 // An invalid property type was detected. Size property must be of PropertyType_Single
284 result = E_INVALIDARG;
285 }
286 }
287
288 return result;
289 }
290
clientRect(const Size & size)291 RECT InspectableNativeWindow::clientRect(const Size &size)
292 {
293 // We don't have to check if a swapchain scale was specified here; the default value is 1.0f
294 // which will have no effect.
295 return {0, 0, lround(size.Width * mSwapChainScale), lround(size.Height * mSwapChainScale)};
296 }
297 } // namespace rx
298