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