blob: 43d9b2602e5c0d8237d3c49f95dd2c9c7cc84aff [file] [log] [blame]
daniel@transgaming.come979ead2010-09-23 18:03:14 +00001//
Geoff Langcec35902014-04-16 10:52:36 -04002// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
daniel@transgaming.come979ead2010-09-23 18:03:14 +00003// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// Display.cpp: Implements the egl::Display class, representing the abstract
8// display on which graphics are drawn. Implements EGLDisplay.
9// [EGL 1.4] section 2.1.2 page 3.
10
11#include "libEGL/Display.h"
12
13#include <algorithm>
jbauman@chromium.org84d7cbc2011-07-14 22:53:19 +000014#include <map>
daniel@transgaming.come979ead2010-09-23 18:03:14 +000015#include <vector>
Geoff Lang2b5f3b32014-06-18 18:07:49 -040016#include <sstream>
daniel@transgaming.come979ead2010-09-23 18:03:14 +000017
18#include "common/debug.h"
shannonwoods@chromium.orga2ecfcc2013-05-30 00:11:59 +000019#include "common/mathutil.h"
daniel@transgaming.comcfa8efd2012-11-28 19:30:55 +000020#include "libGLESv2/main.h"
shannon.woods@transgaming.com486d9e92013-02-28 23:15:41 +000021#include "libGLESv2/Context.h"
shannon.woods%transgaming.com@gtempaccount.com8bce3f52013-04-13 03:35:32 +000022#include "libGLESv2/renderer/SwapChain.h"
daniel@transgaming.come979ead2010-09-23 18:03:14 +000023
24#include "libEGL/main.h"
shannon.woods@transgaming.com486d9e92013-02-28 23:15:41 +000025#include "libEGL/Surface.h"
daniel@transgaming.come979ead2010-09-23 18:03:14 +000026
daniel@transgaming.come979ead2010-09-23 18:03:14 +000027namespace egl
28{
Geoff Lang591e6af2014-06-18 18:08:57 -040029
30typedef std::map<EGLNativeDisplayType, Display*> DisplayMap;
31static DisplayMap *GetDisplayMap()
jbauman@chromium.org84d7cbc2011-07-14 22:53:19 +000032{
Geoff Lang591e6af2014-06-18 18:08:57 -040033 static DisplayMap displays;
34 return &displays;
jbauman@chromium.org84d7cbc2011-07-14 22:53:19 +000035}
36
Geoff Lang591e6af2014-06-18 18:08:57 -040037egl::Display *Display::getDisplay(EGLNativeDisplayType displayId, EGLint displayType)
jbauman@chromium.org84d7cbc2011-07-14 22:53:19 +000038{
Geoff Lang591e6af2014-06-18 18:08:57 -040039 DisplayMap *displays = GetDisplayMap();
40 DisplayMap::const_iterator iter = displays->find(displayId);
41 if (iter != displays->end())
jbauman@chromium.org84d7cbc2011-07-14 22:53:19 +000042 {
Geoff Lang591e6af2014-06-18 18:08:57 -040043 return iter->second;
jbauman@chromium.org84d7cbc2011-07-14 22:53:19 +000044 }
shannonwoods@chromium.orgeff3a122013-05-30 00:10:04 +000045
46 // FIXME: Check if displayId is a valid display device context
jbauman@chromium.org84d7cbc2011-07-14 22:53:19 +000047
Geoff Lang591e6af2014-06-18 18:08:57 -040048 egl::Display *display = new egl::Display(displayId, displayType);
49 displays->insert(std::make_pair(displayId, display));
jbauman@chromium.org84d7cbc2011-07-14 22:53:19 +000050
jbauman@chromium.org84d7cbc2011-07-14 22:53:19 +000051 return display;
52}
53
Geoff Lang591e6af2014-06-18 18:08:57 -040054Display::Display(EGLNativeDisplayType displayId, EGLint displayType)
55 : mDisplayId(displayId),
56 mRequestedDisplayType(displayType),
57 mRenderer(NULL)
daniel@transgaming.come979ead2010-09-23 18:03:14 +000058{
daniel@transgaming.come979ead2010-09-23 18:03:14 +000059}
60
61Display::~Display()
62{
63 terminate();
jbauman@chromium.org84d7cbc2011-07-14 22:53:19 +000064
Geoff Lang591e6af2014-06-18 18:08:57 -040065 DisplayMap *displays = GetDisplayMap();
66 DisplayMap::iterator iter = displays->find(mDisplayId);
67 if (iter != displays->end())
jbauman@chromium.org84d7cbc2011-07-14 22:53:19 +000068 {
Geoff Lang591e6af2014-06-18 18:08:57 -040069 displays->erase(iter);
jbauman@chromium.org84d7cbc2011-07-14 22:53:19 +000070 }
daniel@transgaming.come979ead2010-09-23 18:03:14 +000071}
72
73bool Display::initialize()
74{
75 if (isInitialized())
76 {
77 return true;
78 }
79
Geoff Lang591e6af2014-06-18 18:08:57 -040080 mRenderer = glCreateRenderer(this, mDisplayId, mRequestedDisplayType);
81
daniel@transgaming.comc1e26342012-11-28 19:31:16 +000082 if (!mRenderer)
daniel@transgaming.come979ead2010-09-23 18:03:14 +000083 {
daniel@transgaming.com621ce052012-10-31 17:52:29 +000084 terminate();
daniel@transgaming.comc1e26342012-11-28 19:31:16 +000085 return error(EGL_NOT_INITIALIZED, false);
daniel@transgaming.come979ead2010-09-23 18:03:14 +000086 }
daniel@transgaming.com621ce052012-10-31 17:52:29 +000087
daniel@transgaming.com114bd462012-10-31 18:42:47 +000088 EGLint minSwapInterval = mRenderer->getMinSwapInterval();
89 EGLint maxSwapInterval = mRenderer->getMaxSwapInterval();
Geoff Langc0b9ef42014-07-02 10:02:37 -040090 EGLint maxTextureSize = mRenderer->getRendererCaps().max2DTextureSize;
daniel@transgaming.com621ce052012-10-31 17:52:29 +000091
daniel@transgaming.com76d3e6e2012-10-31 19:55:33 +000092 rx::ConfigDesc *descList;
daniel@transgaming.com3281f972012-10-31 18:38:51 +000093 int numConfigs = mRenderer->generateConfigs(&descList);
daniel@transgaming.com621ce052012-10-31 17:52:29 +000094 ConfigSet configSet;
95
daniel@transgaming.com3281f972012-10-31 18:38:51 +000096 for (int i = 0; i < numConfigs; ++i)
Geoff Langaae65a42014-05-26 12:43:44 -040097 {
98 configSet.add(descList[i], minSwapInterval, maxSwapInterval, maxTextureSize, maxTextureSize);
99 }
daniel@transgaming.come979ead2010-09-23 18:03:14 +0000100
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000101 // Give the sorted configs a unique ID and store them internally
102 EGLint index = 1;
103 for (ConfigSet::Iterator config = configSet.mSet.begin(); config != configSet.mSet.end(); config++)
104 {
105 Config configuration = *config;
106 configuration.mConfigID = index;
107 index++;
daniel@transgaming.come979ead2010-09-23 18:03:14 +0000108
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000109 mConfigSet.mSet.insert(configuration);
daniel@transgaming.come979ead2010-09-23 18:03:14 +0000110 }
111
daniel@transgaming.com3281f972012-10-31 18:38:51 +0000112 mRenderer->deleteConfigs(descList);
113 descList = NULL;
114
daniel@transgaming.come979ead2010-09-23 18:03:14 +0000115 if (!isInitialized())
116 {
117 terminate();
daniel@transgaming.come979ead2010-09-23 18:03:14 +0000118 return false;
119 }
120
Geoff Lang2b5f3b32014-06-18 18:07:49 -0400121 initDisplayExtensionString();
shannonwoods@chromium.org6e4f2a62013-05-30 00:15:19 +0000122 initVendorString();
vladimirv@gmail.com721b7f22011-02-11 00:54:47 +0000123
daniel@transgaming.come979ead2010-09-23 18:03:14 +0000124 return true;
125}
126
127void Display::terminate()
128{
129 while (!mSurfaceSet.empty())
130 {
131 destroySurface(*mSurfaceSet.begin());
132 }
133
134 while (!mContextSet.empty())
135 {
136 destroyContext(*mContextSet.begin());
137 }
138
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000139 glDestroyRenderer(mRenderer);
140 mRenderer = NULL;
daniel@transgaming.come979ead2010-09-23 18:03:14 +0000141}
142
143bool Display::getConfigs(EGLConfig *configs, const EGLint *attribList, EGLint configSize, EGLint *numConfig)
144{
145 return mConfigSet.getConfigs(configs, attribList, configSize, numConfig);
146}
147
148bool Display::getConfigAttrib(EGLConfig config, EGLint attribute, EGLint *value)
149{
150 const egl::Config *configuration = mConfigSet.get(config);
151
152 switch (attribute)
153 {
154 case EGL_BUFFER_SIZE: *value = configuration->mBufferSize; break;
155 case EGL_ALPHA_SIZE: *value = configuration->mAlphaSize; break;
156 case EGL_BLUE_SIZE: *value = configuration->mBlueSize; break;
157 case EGL_GREEN_SIZE: *value = configuration->mGreenSize; break;
158 case EGL_RED_SIZE: *value = configuration->mRedSize; break;
159 case EGL_DEPTH_SIZE: *value = configuration->mDepthSize; break;
160 case EGL_STENCIL_SIZE: *value = configuration->mStencilSize; break;
161 case EGL_CONFIG_CAVEAT: *value = configuration->mConfigCaveat; break;
162 case EGL_CONFIG_ID: *value = configuration->mConfigID; break;
163 case EGL_LEVEL: *value = configuration->mLevel; break;
164 case EGL_NATIVE_RENDERABLE: *value = configuration->mNativeRenderable; break;
165 case EGL_NATIVE_VISUAL_TYPE: *value = configuration->mNativeVisualType; break;
166 case EGL_SAMPLES: *value = configuration->mSamples; break;
167 case EGL_SAMPLE_BUFFERS: *value = configuration->mSampleBuffers; break;
168 case EGL_SURFACE_TYPE: *value = configuration->mSurfaceType; break;
169 case EGL_TRANSPARENT_TYPE: *value = configuration->mTransparentType; break;
170 case EGL_TRANSPARENT_BLUE_VALUE: *value = configuration->mTransparentBlueValue; break;
171 case EGL_TRANSPARENT_GREEN_VALUE: *value = configuration->mTransparentGreenValue; break;
172 case EGL_TRANSPARENT_RED_VALUE: *value = configuration->mTransparentRedValue; break;
173 case EGL_BIND_TO_TEXTURE_RGB: *value = configuration->mBindToTextureRGB; break;
174 case EGL_BIND_TO_TEXTURE_RGBA: *value = configuration->mBindToTextureRGBA; break;
175 case EGL_MIN_SWAP_INTERVAL: *value = configuration->mMinSwapInterval; break;
176 case EGL_MAX_SWAP_INTERVAL: *value = configuration->mMaxSwapInterval; break;
177 case EGL_LUMINANCE_SIZE: *value = configuration->mLuminanceSize; break;
178 case EGL_ALPHA_MASK_SIZE: *value = configuration->mAlphaMaskSize; break;
179 case EGL_COLOR_BUFFER_TYPE: *value = configuration->mColorBufferType; break;
180 case EGL_RENDERABLE_TYPE: *value = configuration->mRenderableType; break;
181 case EGL_MATCH_NATIVE_PIXMAP: *value = false; UNIMPLEMENTED(); break;
182 case EGL_CONFORMANT: *value = configuration->mConformant; break;
vladimirv@gmail.com721b7f22011-02-11 00:54:47 +0000183 case EGL_MAX_PBUFFER_WIDTH: *value = configuration->mMaxPBufferWidth; break;
184 case EGL_MAX_PBUFFER_HEIGHT: *value = configuration->mMaxPBufferHeight; break;
185 case EGL_MAX_PBUFFER_PIXELS: *value = configuration->mMaxPBufferPixels; break;
daniel@transgaming.come979ead2010-09-23 18:03:14 +0000186 default:
187 return false;
188 }
189
190 return true;
191}
192
daniel@transgaming.come979ead2010-09-23 18:03:14 +0000193
daniel@transgaming.come979ead2010-09-23 18:03:14 +0000194
jbauman@chromium.org06d7a752011-04-30 01:02:52 +0000195EGLSurface Display::createWindowSurface(HWND window, EGLConfig config, const EGLint *attribList)
daniel@transgaming.come979ead2010-09-23 18:03:14 +0000196{
197 const Config *configuration = mConfigSet.get(config);
apatrick@chromium.orgf4490e22011-12-06 02:05:22 +0000198 EGLint postSubBufferSupported = EGL_FALSE;
daniel@transgaming.come979ead2010-09-23 18:03:14 +0000199
John Bauman3dc300a2014-01-28 15:30:35 -0800200 EGLint width = 0;
201 EGLint height = 0;
202 EGLint fixedSize = EGL_FALSE;
203
jbauman@chromium.org06d7a752011-04-30 01:02:52 +0000204 if (attribList)
205 {
206 while (*attribList != EGL_NONE)
207 {
208 switch (attribList[0])
209 {
210 case EGL_RENDER_BUFFER:
211 switch (attribList[1])
212 {
213 case EGL_BACK_BUFFER:
214 break;
215 case EGL_SINGLE_BUFFER:
216 return error(EGL_BAD_MATCH, EGL_NO_SURFACE); // Rendering directly to front buffer not supported
217 default:
218 return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
219 }
220 break;
apatrick@chromium.orgf4490e22011-12-06 02:05:22 +0000221 case EGL_POST_SUB_BUFFER_SUPPORTED_NV:
222 postSubBufferSupported = attribList[1];
223 break;
John Bauman3dc300a2014-01-28 15:30:35 -0800224 case EGL_WIDTH:
225 width = attribList[1];
226 break;
227 case EGL_HEIGHT:
228 height = attribList[1];
229 break;
230 case EGL_FIXED_SIZE_ANGLE:
231 fixedSize = attribList[1];
232 break;
jbauman@chromium.org06d7a752011-04-30 01:02:52 +0000233 case EGL_VG_COLORSPACE:
234 return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
235 case EGL_VG_ALPHA_FORMAT:
236 return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
237 default:
238 return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
239 }
240
241 attribList += 2;
242 }
243 }
244
John Bauman3dc300a2014-01-28 15:30:35 -0800245 if (width < 0 || height < 0)
246 {
247 return error(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
248 }
249
250 if (!fixedSize)
251 {
252 width = -1;
253 height = -1;
254 }
255
jbauman@chromium.org06d7a752011-04-30 01:02:52 +0000256 if (hasExistingWindowSurface(window))
257 {
258 return error(EGL_BAD_ALLOC, EGL_NO_SURFACE);
259 }
260
daniel@transgaming.comf688c0d2012-10-31 17:52:57 +0000261 if (mRenderer->testDeviceLost(false))
daniel@transgaming.comcf23c452011-11-09 17:47:26 +0000262 {
vangelis@google.com8c9c4522011-09-09 18:22:28 +0000263 if (!restoreLostDevice())
264 return EGL_NO_SURFACE;
265 }
266
John Bauman3dc300a2014-01-28 15:30:35 -0800267 Surface *surface = new Surface(this, configuration, window, fixedSize, width, height, postSubBufferSupported);
jbauman@chromium.org4e297702011-05-12 23:04:07 +0000268
269 if (!surface->initialize())
270 {
271 delete surface;
272 return EGL_NO_SURFACE;
273 }
274
daniel@transgaming.come979ead2010-09-23 18:03:14 +0000275 mSurfaceSet.insert(surface);
276
jbauman@chromium.org06d7a752011-04-30 01:02:52 +0000277 return success(surface);
daniel@transgaming.come979ead2010-09-23 18:03:14 +0000278}
279
jbauman@chromium.org4e297702011-05-12 23:04:07 +0000280EGLSurface Display::createOffscreenSurface(EGLConfig config, HANDLE shareHandle, const EGLint *attribList)
vladimirv@gmail.com721b7f22011-02-11 00:54:47 +0000281{
jbauman@chromium.org06d7a752011-04-30 01:02:52 +0000282 EGLint width = 0, height = 0;
283 EGLenum textureFormat = EGL_NO_TEXTURE;
284 EGLenum textureTarget = EGL_NO_TEXTURE;
vladimirv@gmail.com721b7f22011-02-11 00:54:47 +0000285 const Config *configuration = mConfigSet.get(config);
286
jbauman@chromium.org06d7a752011-04-30 01:02:52 +0000287 if (attribList)
288 {
289 while (*attribList != EGL_NONE)
290 {
291 switch (attribList[0])
292 {
293 case EGL_WIDTH:
294 width = attribList[1];
295 break;
296 case EGL_HEIGHT:
297 height = attribList[1];
298 break;
299 case EGL_LARGEST_PBUFFER:
300 if (attribList[1] != EGL_FALSE)
301 UNIMPLEMENTED(); // FIXME
302 break;
303 case EGL_TEXTURE_FORMAT:
304 switch (attribList[1])
305 {
306 case EGL_NO_TEXTURE:
307 case EGL_TEXTURE_RGB:
308 case EGL_TEXTURE_RGBA:
309 textureFormat = attribList[1];
310 break;
311 default:
312 return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
313 }
314 break;
315 case EGL_TEXTURE_TARGET:
316 switch (attribList[1])
317 {
318 case EGL_NO_TEXTURE:
319 case EGL_TEXTURE_2D:
320 textureTarget = attribList[1];
321 break;
322 default:
323 return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
324 }
325 break;
326 case EGL_MIPMAP_TEXTURE:
327 if (attribList[1] != EGL_FALSE)
328 return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
329 break;
330 case EGL_VG_COLORSPACE:
331 return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
332 case EGL_VG_ALPHA_FORMAT:
333 return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
334 default:
335 return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
336 }
337
338 attribList += 2;
339 }
340 }
341
342 if (width < 0 || height < 0)
343 {
344 return error(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
345 }
346
347 if (width == 0 || height == 0)
348 {
349 return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
350 }
351
Geoff Langc0b9ef42014-07-02 10:02:37 -0400352 if (textureFormat != EGL_NO_TEXTURE && !mRenderer->getRendererExtensions().textureNPOT && (!gl::isPow2(width) || !gl::isPow2(height)))
jbauman@chromium.org06d7a752011-04-30 01:02:52 +0000353 {
354 return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
355 }
356
357 if ((textureFormat != EGL_NO_TEXTURE && textureTarget == EGL_NO_TEXTURE) ||
358 (textureFormat == EGL_NO_TEXTURE && textureTarget != EGL_NO_TEXTURE))
359 {
360 return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
361 }
362
363 if (!(configuration->mSurfaceType & EGL_PBUFFER_BIT))
364 {
365 return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
366 }
367
368 if ((textureFormat == EGL_TEXTURE_RGB && configuration->mBindToTextureRGB != EGL_TRUE) ||
369 (textureFormat == EGL_TEXTURE_RGBA && configuration->mBindToTextureRGBA != EGL_TRUE))
370 {
371 return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
372 }
373
daniel@transgaming.comf688c0d2012-10-31 17:52:57 +0000374 if (mRenderer->testDeviceLost(false))
daniel@transgaming.comcf23c452011-11-09 17:47:26 +0000375 {
vangelis@google.com8c9c4522011-09-09 18:22:28 +0000376 if (!restoreLostDevice())
377 return EGL_NO_SURFACE;
378 }
379
jbauman@chromium.org4e297702011-05-12 23:04:07 +0000380 Surface *surface = new Surface(this, configuration, shareHandle, width, height, textureFormat, textureTarget);
381
382 if (!surface->initialize())
383 {
384 delete surface;
385 return EGL_NO_SURFACE;
386 }
387
vladimirv@gmail.com721b7f22011-02-11 00:54:47 +0000388 mSurfaceSet.insert(surface);
389
jbauman@chromium.org06d7a752011-04-30 01:02:52 +0000390 return success(surface);
vladimirv@gmail.com721b7f22011-02-11 00:54:47 +0000391}
392
shannon.woods%transgaming.com@gtempaccount.comdaea4b42013-04-13 03:28:54 +0000393EGLContext Display::createContext(EGLConfig configHandle, EGLint clientVersion, const gl::Context *shareContext, bool notifyResets, bool robustAccess)
daniel@transgaming.come979ead2010-09-23 18:03:14 +0000394{
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000395 if (!mRenderer)
daniel@transgaming.come979ead2010-09-23 18:03:14 +0000396 {
shannon.woods%transgaming.com@gtempaccount.com2104d932013-04-13 03:38:46 +0000397 return EGL_NO_CONTEXT;
daniel@transgaming.come979ead2010-09-23 18:03:14 +0000398 }
daniel@transgaming.comf688c0d2012-10-31 17:52:57 +0000399 else if (mRenderer->testDeviceLost(false)) // Lost device
daniel@transgaming.come979ead2010-09-23 18:03:14 +0000400 {
vangelis@google.com8c9c4522011-09-09 18:22:28 +0000401 if (!restoreLostDevice())
shannon.woods%transgaming.com@gtempaccount.com2104d932013-04-13 03:38:46 +0000402 {
403 return error(EGL_CONTEXT_LOST, EGL_NO_CONTEXT);
404 }
405 }
406
407 if (clientVersion > 2 && mRenderer->getMajorShaderModel() < 4)
408 {
409 return error(EGL_BAD_CONFIG, EGL_NO_CONTEXT);
daniel@transgaming.come979ead2010-09-23 18:03:14 +0000410 }
411
shannon.woods%transgaming.com@gtempaccount.comdaea4b42013-04-13 03:28:54 +0000412 gl::Context *context = glCreateContext(clientVersion, shareContext, mRenderer, notifyResets, robustAccess);
daniel@transgaming.come979ead2010-09-23 18:03:14 +0000413 mContextSet.insert(context);
414
shannon.woods%transgaming.com@gtempaccount.com2104d932013-04-13 03:38:46 +0000415 return success(context);
daniel@transgaming.come979ead2010-09-23 18:03:14 +0000416}
417
vangelis@google.com8c9c4522011-09-09 18:22:28 +0000418bool Display::restoreLostDevice()
419{
daniel@transgaming.comcf23c452011-11-09 17:47:26 +0000420 for (ContextSet::iterator ctx = mContextSet.begin(); ctx != mContextSet.end(); ctx++)
421 {
422 if ((*ctx)->isResetNotificationEnabled())
423 return false; // If reset notifications have been requested, application must delete all contexts first
424 }
425
vangelis@google.com8c9c4522011-09-09 18:22:28 +0000426 // Release surface resources to make the Reset() succeed
427 for (SurfaceSet::iterator surface = mSurfaceSet.begin(); surface != mSurfaceSet.end(); surface++)
428 {
429 (*surface)->release();
430 }
431
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000432 if (!mRenderer->resetDevice())
vangelis@google.com8c9c4522011-09-09 18:22:28 +0000433 {
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000434 return error(EGL_BAD_ALLOC, false);
vangelis@google.com8c9c4522011-09-09 18:22:28 +0000435 }
436
437 // Restore any surfaces that may have been lost
438 for (SurfaceSet::iterator surface = mSurfaceSet.begin(); surface != mSurfaceSet.end(); surface++)
439 {
440 (*surface)->resetSwapChain();
441 }
442
443 return true;
444}
445
446
daniel@transgaming.come979ead2010-09-23 18:03:14 +0000447void Display::destroySurface(egl::Surface *surface)
448{
daniel@transgaming.comc556fa52011-05-26 14:13:29 +0000449 delete surface;
450 mSurfaceSet.erase(surface);
daniel@transgaming.come979ead2010-09-23 18:03:14 +0000451}
452
453void Display::destroyContext(gl::Context *context)
454{
455 glDestroyContext(context);
456 mContextSet.erase(context);
daniel@transgaming.come979ead2010-09-23 18:03:14 +0000457}
458
daniel@transgaming.com09fcc9f2011-11-09 17:46:47 +0000459void Display::notifyDeviceLost()
460{
461 for (ContextSet::iterator context = mContextSet.begin(); context != mContextSet.end(); context++)
462 {
463 (*context)->markContextLost();
464 }
shannon.woods@transgaming.com779aa262013-02-28 23:04:58 +0000465 egl::error(EGL_CONTEXT_LOST);
daniel@transgaming.com09fcc9f2011-11-09 17:46:47 +0000466}
467
shannon.woods%transgaming.com@gtempaccount.com8bce3f52013-04-13 03:35:32 +0000468void Display::recreateSwapChains()
469{
470 for (SurfaceSet::iterator surface = mSurfaceSet.begin(); surface != mSurfaceSet.end(); surface++)
471 {
472 (*surface)->getSwapChain()->recreate();
473 }
474}
475
daniel@transgaming.com3b1703f2011-05-11 15:36:26 +0000476bool Display::isInitialized() const
daniel@transgaming.come979ead2010-09-23 18:03:14 +0000477{
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000478 return mRenderer != NULL && mConfigSet.size() > 0;
daniel@transgaming.come979ead2010-09-23 18:03:14 +0000479}
480
481bool Display::isValidConfig(EGLConfig config)
482{
483 return mConfigSet.get(config) != NULL;
484}
485
486bool Display::isValidContext(gl::Context *context)
487{
488 return mContextSet.find(context) != mContextSet.end();
489}
490
491bool Display::isValidSurface(egl::Surface *surface)
492{
daniel@transgaming.comc556fa52011-05-26 14:13:29 +0000493 return mSurfaceSet.find(surface) != mSurfaceSet.end();
daniel@transgaming.come979ead2010-09-23 18:03:14 +0000494}
495
496bool Display::hasExistingWindowSurface(HWND window)
497{
498 for (SurfaceSet::iterator surface = mSurfaceSet.begin(); surface != mSurfaceSet.end(); surface++)
499 {
500 if ((*surface)->getWindowHandle() == window)
501 {
502 return true;
503 }
504 }
505
506 return false;
507}
508
Geoff Lang2b5f3b32014-06-18 18:07:49 -0400509std::string Display::generateClientExtensionString()
vladimirv@gmail.com721b7f22011-02-11 00:54:47 +0000510{
Geoff Lang2b5f3b32014-06-18 18:07:49 -0400511 std::vector<std::string> extensions;
daniel@transgaming.com1a1fe242011-09-26 18:25:45 +0000512
Geoff Lang2b5f3b32014-06-18 18:07:49 -0400513 extensions.push_back("EGL_EXT_client_extensions");
514
Geoff Lang591e6af2014-06-18 18:08:57 -0400515 extensions.push_back("ANGLE_platform_angle");
516
517 if (supportsPlatformD3D())
518 {
519 extensions.push_back("ANGLE_platform_angle_d3d");
520 }
521
522 if (supportsPlatformOpenGL())
523 {
524 extensions.push_back("ANGLE_platform_angle_opengl");
525 }
526
Geoff Lang2b5f3b32014-06-18 18:07:49 -0400527 std::ostringstream stream;
528 std::copy(extensions.begin(), extensions.end(), std::ostream_iterator<std::string>(stream, " "));
529 return stream.str();
530}
531
532void Display::initDisplayExtensionString()
533{
534 std::vector<std::string> extensions;
daniel@transgaming.com1a1fe242011-09-26 18:25:45 +0000535
daniel@transgaming.com8747f182011-11-09 17:50:38 +0000536 // Multi-vendor (EXT) extensions
Geoff Lang2b5f3b32014-06-18 18:07:49 -0400537 extensions.push_back("EGL_EXT_create_context_robustness");
daniel@transgaming.com8747f182011-11-09 17:50:38 +0000538
539 // ANGLE-specific extensions
Geoff Lang2b5f3b32014-06-18 18:07:49 -0400540 if (mRenderer->getShareHandleSupport())
apatrick@chromium.orgf4490e22011-12-06 02:05:22 +0000541 {
Geoff Lang2b5f3b32014-06-18 18:07:49 -0400542 extensions.push_back("EGL_ANGLE_d3d_share_handle_client_buffer");
543 extensions.push_back("EGL_ANGLE_surface_d3d_texture_2d_share_handle");
daniel@transgaming.com1a1fe242011-09-26 18:25:45 +0000544 }
545
Geoff Lang2b5f3b32014-06-18 18:07:49 -0400546 extensions.push_back("EGL_ANGLE_query_surface_pointer");
547 extensions.push_back("EGL_ANGLE_window_fixed_size");
vladimirv@gmail.com721b7f22011-02-11 00:54:47 +0000548
shannon.woods@transgaming.com8d2f0862013-02-28 23:09:19 +0000549 if (mRenderer->getPostSubBufferSupport())
550 {
Geoff Lang2b5f3b32014-06-18 18:07:49 -0400551 extensions.push_back("EGL_NV_post_sub_buffer");
shannon.woods@transgaming.com8d2f0862013-02-28 23:09:19 +0000552 }
apatrick@chromium.orgf4490e22011-12-06 02:05:22 +0000553
shannonwoods@chromium.org7d9f7be2013-05-30 00:20:51 +0000554 // TODO: complete support for the EGL_KHR_create_context extension
Geoff Lang2b5f3b32014-06-18 18:07:49 -0400555 extensions.push_back("EGL_KHR_create_context");
shannonwoods@chromium.org7d9f7be2013-05-30 00:20:51 +0000556
Geoff Lang2b5f3b32014-06-18 18:07:49 -0400557 std::ostringstream stream;
558 std::copy(extensions.begin(), extensions.end(), std::ostream_iterator<std::string>(stream, " "));
559 mDisplayExtensionString = stream.str();
vladimirv@gmail.com721b7f22011-02-11 00:54:47 +0000560}
561
Geoff Lang2b5f3b32014-06-18 18:07:49 -0400562const char *Display::getExtensionString(egl::Display *display)
vladimirv@gmail.com721b7f22011-02-11 00:54:47 +0000563{
Geoff Lang2b5f3b32014-06-18 18:07:49 -0400564 if (display != EGL_NO_DISPLAY)
565 {
566 return display->mDisplayExtensionString.c_str();
567 }
568 else
569 {
570 static std::string clientExtensions = generateClientExtensionString();
571 return clientExtensions.c_str();
572 }
vladimirv@gmail.com721b7f22011-02-11 00:54:47 +0000573}
574
Geoff Lang591e6af2014-06-18 18:08:57 -0400575bool Display::supportsPlatformD3D()
576{
577#if defined(ANGLE_ENABLE_D3D9) || defined(ANGLE_ENABLE_D3D11)
578 return true;
579#else
580 return false;
581#endif
582}
583
584bool Display::supportsPlatformOpenGL()
585{
586 return false;
587}
588
shannonwoods@chromium.org6e4f2a62013-05-30 00:15:19 +0000589void Display::initVendorString()
590{
591 mVendorString = "Google Inc.";
592
593 LUID adapterLuid = {0};
594
595 if (mRenderer && mRenderer->getLUID(&adapterLuid))
596 {
597 char adapterLuidString[64];
598 sprintf_s(adapterLuidString, sizeof(adapterLuidString), " (adapter LUID: %08x%08x)", adapterLuid.HighPart, adapterLuid.LowPart);
599
600 mVendorString += adapterLuidString;
601 }
602}
603
604const char *Display::getVendorString() const
605{
606 return mVendorString.c_str();
607}
daniel@transgaming.comc6f7f9d2012-01-27 15:40:00 +0000608
vladimirv@gmail.com721b7f22011-02-11 00:54:47 +0000609}