OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ui/gl/gl_surface_egl.h" | 5 #include "ui/gl/gl_surface_egl.h" |
6 | 6 |
7 #if defined(OS_ANDROID) | 7 #if defined(OS_ANDROID) |
8 #include <android/native_window_jni.h> | 8 #include <android/native_window_jni.h> |
9 #endif | 9 #endif |
10 | 10 |
(...skipping 23 matching lines...) Expand all Loading... |
34 #endif | 34 #endif |
35 | 35 |
36 #if !defined(EGL_FIXED_SIZE_ANGLE) | 36 #if !defined(EGL_FIXED_SIZE_ANGLE) |
37 #define EGL_FIXED_SIZE_ANGLE 0x3201 | 37 #define EGL_FIXED_SIZE_ANGLE 0x3201 |
38 #endif | 38 #endif |
39 | 39 |
40 #if !defined(EGL_OPENGL_ES3_BIT) | 40 #if !defined(EGL_OPENGL_ES3_BIT) |
41 #define EGL_OPENGL_ES3_BIT 0x00000040 | 41 #define EGL_OPENGL_ES3_BIT 0x00000040 |
42 #endif | 42 #endif |
43 | 43 |
44 #if defined(OS_WIN) | |
45 // From ANGLE's egl/eglext.h. | 44 // From ANGLE's egl/eglext.h. |
46 | 45 |
47 #ifndef EGL_ANGLE_platform_angle | 46 #ifndef EGL_ANGLE_platform_angle |
48 #define EGL_ANGLE_platform_angle 1 | 47 #define EGL_ANGLE_platform_angle 1 |
49 #define EGL_PLATFORM_ANGLE_ANGLE 0x3202 | 48 #define EGL_PLATFORM_ANGLE_ANGLE 0x3202 |
50 #define EGL_PLATFORM_ANGLE_TYPE_ANGLE 0x3203 | 49 #define EGL_PLATFORM_ANGLE_TYPE_ANGLE 0x3203 |
51 #define EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE 0x3204 | 50 #define EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE 0x3204 |
52 #define EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE 0x3205 | 51 #define EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE 0x3205 |
53 #define EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE 0x3206 | 52 #define EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE 0x3206 |
54 #endif /* EGL_ANGLE_platform_angle */ | 53 #endif /* EGL_ANGLE_platform_angle */ |
55 | 54 |
56 #ifndef EGL_ANGLE_platform_angle_d3d | 55 #ifndef EGL_ANGLE_platform_angle_d3d |
57 #define EGL_ANGLE_platform_angle_d3d 1 | 56 #define EGL_ANGLE_platform_angle_d3d 1 |
58 #define EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE 0x3207 | 57 #define EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE 0x3207 |
59 #define EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE 0x3208 | 58 #define EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE 0x3208 |
60 #define EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE 0x3209 | 59 #define EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE 0x3209 |
61 #define EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE 0x320A | 60 #define EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE 0x320A |
62 #define EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE 0x320B | 61 #define EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE 0x320B |
63 #define EGL_PLATFORM_ANGLE_DEVICE_TYPE_REFERENCE_ANGLE 0x320C | 62 #define EGL_PLATFORM_ANGLE_DEVICE_TYPE_REFERENCE_ANGLE 0x320C |
64 #endif /* EGL_ANGLE_platform_angle_d3d */ | 63 #endif /* EGL_ANGLE_platform_angle_d3d */ |
65 | 64 |
66 #endif // defined(OS_WIN) | |
67 | |
68 using ui::GetLastEGLErrorString; | 65 using ui::GetLastEGLErrorString; |
69 | 66 |
70 namespace gfx { | 67 namespace gfx { |
71 | 68 |
72 #if defined(OS_WIN) | 69 #if defined(OS_WIN) |
73 unsigned int NativeViewGLSurfaceEGL::current_swap_generation_ = 0; | 70 unsigned int NativeViewGLSurfaceEGL::current_swap_generation_ = 0; |
74 unsigned int NativeViewGLSurfaceEGL::swaps_this_generation_ = 0; | 71 unsigned int NativeViewGLSurfaceEGL::swaps_this_generation_ = 0; |
75 unsigned int NativeViewGLSurfaceEGL::last_multiswap_generation_ = 0; | 72 unsigned int NativeViewGLSurfaceEGL::last_multiswap_generation_ = 0; |
76 | 73 |
77 const unsigned int MULTISWAP_FRAME_VSYNC_THRESHOLD = 60; | 74 const unsigned int MULTISWAP_FRAME_VSYNC_THRESHOLD = 60; |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
134 DISALLOW_COPY_AND_ASSIGN(EGLSyncControlVSyncProvider); | 131 DISALLOW_COPY_AND_ASSIGN(EGLSyncControlVSyncProvider); |
135 }; | 132 }; |
136 | 133 |
137 void DeinitializeEgl() { | 134 void DeinitializeEgl() { |
138 if (g_initialized) { | 135 if (g_initialized) { |
139 g_initialized = false; | 136 g_initialized = false; |
140 eglTerminate(g_display); | 137 eglTerminate(g_display); |
141 } | 138 } |
142 } | 139 } |
143 | 140 |
| 141 EGLDisplay GetPlatformANGLEDisplay(EGLNativeDisplayType native_display, |
| 142 EGLenum platform_type, |
| 143 EGLenum device_type) { |
| 144 const EGLint display_attribs[] = {EGL_PLATFORM_ANGLE_TYPE_ANGLE, |
| 145 platform_type, |
| 146 EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, |
| 147 device_type, |
| 148 EGL_NONE}; |
| 149 return eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, |
| 150 reinterpret_cast<void*>(native_display), |
| 151 display_attribs); |
| 152 } |
| 153 |
| 154 enum DisplayType { DEFAULT, SWIFT_SHADER, ANGLE_WARP, ANGLE_D3D9, ANGLE_D3D11 }; |
| 155 |
| 156 EGLDisplay GetDisplayFromType(DisplayType display_type, |
| 157 EGLNativeDisplayType native_display) { |
| 158 switch (display_type) { |
| 159 case DEFAULT: |
| 160 case SWIFT_SHADER: |
| 161 return eglGetDisplay(native_display); |
| 162 case ANGLE_WARP: |
| 163 return GetPlatformANGLEDisplay(native_display, |
| 164 EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, |
| 165 EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE); |
| 166 case ANGLE_D3D9: |
| 167 return GetPlatformANGLEDisplay( |
| 168 native_display, EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE, |
| 169 EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE); |
| 170 case ANGLE_D3D11: |
| 171 return GetPlatformANGLEDisplay( |
| 172 native_display, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, |
| 173 EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE); |
| 174 default: |
| 175 NOTREACHED(); |
| 176 return EGL_NO_DISPLAY; |
| 177 } |
| 178 } |
| 179 |
| 180 const char* DisplayTypeString(DisplayType display_type) { |
| 181 switch (display_type) { |
| 182 case DEFAULT: |
| 183 return "Default"; |
| 184 case SWIFT_SHADER: |
| 185 return "SwiftShader"; |
| 186 case ANGLE_WARP: |
| 187 return "WARP"; |
| 188 case ANGLE_D3D9: |
| 189 return "D3D9"; |
| 190 case ANGLE_D3D11: |
| 191 return "D3D11"; |
| 192 default: |
| 193 NOTREACHED(); |
| 194 return "Err"; |
| 195 } |
| 196 } |
| 197 |
| 198 void GetInitDisplays(bool supports_angle_d3d, |
| 199 std::vector<DisplayType>* init_displays) { |
| 200 const base::CommandLine* command_line = |
| 201 base::CommandLine::ForCurrentProcess(); |
| 202 bool using_swift_shader = |
| 203 command_line->GetSwitchValueASCII(switches::kUseGL) == "swiftshader"; |
| 204 |
| 205 // SwiftShader does not use the platform extensions |
| 206 if (using_swift_shader) { |
| 207 init_displays->push_back(SWIFT_SHADER); |
| 208 return; |
| 209 } |
| 210 |
| 211 // If we're missing the ANGLE extensions, fall back to default. |
| 212 if (!supports_angle_d3d) { |
| 213 init_displays->push_back(DEFAULT); |
| 214 return; |
| 215 } |
| 216 |
| 217 if (command_line->HasSwitch(switches::kUseWarp)) { |
| 218 init_displays->push_back(ANGLE_WARP); |
| 219 return; |
| 220 } |
| 221 |
| 222 if (command_line->HasSwitch(switches::kDisableD3D11)) { |
| 223 init_displays->push_back(ANGLE_D3D9); |
| 224 return; |
| 225 } |
| 226 |
| 227 // Default mode for ANGLE - try D3D11, else try D3D9 |
| 228 init_displays->push_back(ANGLE_D3D11); |
| 229 init_displays->push_back(ANGLE_D3D9); |
| 230 } |
| 231 |
144 } // namespace | 232 } // namespace |
145 | 233 |
146 GLSurfaceEGL::GLSurfaceEGL() { | 234 GLSurfaceEGL::GLSurfaceEGL() { |
147 ++g_num_surfaces; | 235 ++g_num_surfaces; |
148 if (!g_initialized) { | 236 if (!g_initialized) { |
149 bool result = GLSurfaceEGL::InitializeOneOff(); | 237 bool result = GLSurfaceEGL::InitializeOneOff(); |
150 DCHECK(result); | 238 DCHECK(result); |
151 DCHECK(g_initialized); | 239 DCHECK(g_initialized); |
152 } | 240 } |
153 } | 241 } |
154 | 242 |
155 bool GLSurfaceEGL::InitializeOneOff() { | 243 bool GLSurfaceEGL::InitializeOneOff() { |
156 if (g_initialized) | 244 if (g_initialized) |
157 return true; | 245 return true; |
158 | 246 |
159 g_native_display_type = GetPlatformDefaultEGLNativeDisplay(); | 247 InitializeDisplay(); |
160 | 248 if (g_display == EGL_NO_DISPLAY) |
161 #if defined(OS_WIN) | |
162 g_display = GetPlatformDisplay(g_native_display_type); | |
163 #else | |
164 g_display = eglGetDisplay(g_native_display_type); | |
165 #endif | |
166 | |
167 if (!g_display) { | |
168 LOG(ERROR) << "eglGetDisplay failed with error " << GetLastEGLErrorString(); | |
169 return false; | 249 return false; |
170 } | |
171 | |
172 if (!eglInitialize(g_display, NULL, NULL)) { | |
173 LOG(ERROR) << "eglInitialize failed with error " << GetLastEGLErrorString(); | |
174 return false; | |
175 } | |
176 | 250 |
177 // Choose an EGL configuration. | 251 // Choose an EGL configuration. |
178 // On X this is only used for PBuffer surfaces. | 252 // On X this is only used for PBuffer surfaces. |
179 EGLint renderable_type = EGL_OPENGL_ES2_BIT; | 253 EGLint renderable_type = EGL_OPENGL_ES2_BIT; |
180 if (base::CommandLine::ForCurrentProcess()->HasSwitch( | 254 if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
181 switches::kEnableUnsafeES3APIs)) { | 255 switches::kEnableUnsafeES3APIs)) { |
182 renderable_type = EGL_OPENGL_ES3_BIT; | 256 renderable_type = EGL_OPENGL_ES3_BIT; |
183 } | 257 } |
184 const EGLint kConfigAttribs[] = { | 258 const EGLint kConfigAttribs[] = { |
185 EGL_BUFFER_SIZE, 32, | 259 EGL_BUFFER_SIZE, 32, |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
321 } | 395 } |
322 | 396 |
323 GLSurfaceEGL::~GLSurfaceEGL() { | 397 GLSurfaceEGL::~GLSurfaceEGL() { |
324 DCHECK_GT(g_num_surfaces, 0) << "Bad surface count"; | 398 DCHECK_GT(g_num_surfaces, 0) << "Bad surface count"; |
325 if (--g_num_surfaces == 0 && g_terminate_pending) { | 399 if (--g_num_surfaces == 0 && g_terminate_pending) { |
326 DeinitializeEgl(); | 400 DeinitializeEgl(); |
327 g_terminate_pending = false; | 401 g_terminate_pending = false; |
328 } | 402 } |
329 } | 403 } |
330 | 404 |
331 #if defined(OS_WIN) | 405 // InitializeDisplay is necessary because the static binding code |
332 static const EGLint kDisplayAttribsWarp[] { | 406 // needs a full Display init before it can query the Display extensions. |
333 EGL_PLATFORM_ANGLE_TYPE_ANGLE, | |
334 EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, | |
335 | |
336 EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, | |
337 EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE, | |
338 | |
339 EGL_NONE | |
340 }; | |
341 | |
342 // static | 407 // static |
343 EGLDisplay GLSurfaceEGL::GetPlatformDisplay( | 408 EGLDisplay GLSurfaceEGL::InitializeDisplay() { |
344 EGLNativeDisplayType native_display) { | 409 if (g_display != EGL_NO_DISPLAY) { |
345 if (base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kUseWarp)) { | 410 return g_display; |
346 // Check for availability of WARP via ANGLE extension. | |
347 bool supports_warp = false; | |
348 const char* no_display_extensions = eglQueryString(EGL_NO_DISPLAY, | |
349 EGL_EXTENSIONS); | |
350 // If EGL_EXT_client_extensions not supported this call to eglQueryString | |
351 // will return NULL. | |
352 if (no_display_extensions) | |
353 supports_warp = | |
354 ExtensionsContain(no_display_extensions, "ANGLE_platform_angle") && | |
355 ExtensionsContain(no_display_extensions, "ANGLE_platform_angle_d3d"); | |
356 | |
357 if (!supports_warp) | |
358 return NULL; | |
359 | |
360 return eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, native_display, | |
361 kDisplayAttribsWarp); | |
362 } | 411 } |
363 | 412 |
364 return eglGetDisplay(native_display); | 413 g_native_display_type = GetPlatformDefaultEGLNativeDisplay(); |
| 414 |
| 415 // If EGL_EXT_client_extensions not supported this call to eglQueryString |
| 416 // will return NULL. |
| 417 const char* client_extensions = |
| 418 eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS); |
| 419 |
| 420 bool supports_angle_d3d = false; |
| 421 // Check for availability of ANGLE extensions. |
| 422 if (client_extensions) { |
| 423 supports_angle_d3d = |
| 424 ExtensionsContain(client_extensions, "ANGLE_platform_angle") && |
| 425 ExtensionsContain(client_extensions, "ANGLE_platform_angle_d3d"); |
| 426 } |
| 427 |
| 428 std::vector<DisplayType> init_displays; |
| 429 GetInitDisplays(supports_angle_d3d, &init_displays); |
| 430 |
| 431 for (size_t disp_index = 0; disp_index < init_displays.size(); ++disp_index) { |
| 432 DisplayType display_type = init_displays[disp_index]; |
| 433 EGLDisplay display = |
| 434 GetDisplayFromType(display_type, g_native_display_type); |
| 435 if (display == EGL_NO_DISPLAY) { |
| 436 LOG(ERROR) << "EGL display query failed with error " |
| 437 << GetLastEGLErrorString(); |
| 438 } |
| 439 |
| 440 if (!eglInitialize(display, nullptr, nullptr)) { |
| 441 bool is_last = disp_index == init_displays.size() - 1; |
| 442 |
| 443 LOG(ERROR) << "eglInitialize " << DisplayTypeString(display_type) |
| 444 << " failed with error " << GetLastEGLErrorString() |
| 445 << (is_last ? "" : ", trying next display type"); |
| 446 } else { |
| 447 g_display = display; |
| 448 break; |
| 449 } |
| 450 } |
| 451 |
| 452 return g_display; |
365 } | 453 } |
366 #endif | |
367 | 454 |
368 NativeViewGLSurfaceEGL::NativeViewGLSurfaceEGL(EGLNativeWindowType window) | 455 NativeViewGLSurfaceEGL::NativeViewGLSurfaceEGL(EGLNativeWindowType window) |
369 : window_(window), | 456 : window_(window), |
370 surface_(NULL), | 457 surface_(NULL), |
371 supports_post_sub_buffer_(false), | 458 supports_post_sub_buffer_(false), |
372 config_(NULL), | 459 config_(NULL), |
373 size_(1, 1), | 460 size_(1, 1), |
374 swap_interval_(1) { | 461 swap_interval_(1) { |
375 #if defined(OS_ANDROID) | 462 #if defined(OS_ANDROID) |
376 if (window) | 463 if (window) |
(...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
831 } | 918 } |
832 | 919 |
833 void* SurfacelessEGL::GetShareHandle() { | 920 void* SurfacelessEGL::GetShareHandle() { |
834 return NULL; | 921 return NULL; |
835 } | 922 } |
836 | 923 |
837 SurfacelessEGL::~SurfacelessEGL() { | 924 SurfacelessEGL::~SurfacelessEGL() { |
838 } | 925 } |
839 | 926 |
840 } // namespace gfx | 927 } // namespace gfx |
OLD | NEW |