Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1168)

Side by Side Diff: ui/gl/gl_surface_egl.cc

Issue 712343003: Infrastructure for temportarily relinquishing GPU resources. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
55 namespace gfx { 55 namespace gfx {
56 56
57 unsigned int NativeViewGLSurfaceEGL::current_swap_generation_ = 0; 57 unsigned int NativeViewGLSurfaceEGL::current_swap_generation_ = 0;
58 58
59 namespace { 59 namespace {
60 60
61 EGLConfig g_config; 61 EGLConfig g_config;
62 EGLDisplay g_display; 62 EGLDisplay g_display;
63 EGLNativeDisplayType g_native_display; 63 EGLNativeDisplayType g_native_display;
64 64
65 // In the Cast environment, we need to destroy the displayType
66 // returned by the GPU platform when we switch to an external app
67 // which will temporarily own all screen and GPU resources.
68 // Even though Chromium is still in the background.
69 // As such, it must be reinitialized each time we come back to the foreground.
70 bool g_initialized = false;
71 int g_num_surfaces = 0;
72
65 const char* g_egl_extensions = NULL; 73 const char* g_egl_extensions = NULL;
66 bool g_egl_create_context_robustness_supported = false; 74 bool g_egl_create_context_robustness_supported = false;
67 bool g_egl_sync_control_supported = false; 75 bool g_egl_sync_control_supported = false;
68 bool g_egl_window_fixed_size_supported = false; 76 bool g_egl_window_fixed_size_supported = false;
69 bool g_egl_surfaceless_context_supported = false; 77 bool g_egl_surfaceless_context_supported = false;
70 78
71 class EGLSyncControlVSyncProvider 79 class EGLSyncControlVSyncProvider
72 : public gfx::SyncControlVSyncProvider { 80 : public gfx::SyncControlVSyncProvider {
73 public: 81 public:
74 explicit EGLSyncControlVSyncProvider(EGLSurface surface) 82 explicit EGLSyncControlVSyncProvider(EGLSurface surface)
(...skipping 27 matching lines...) Expand all
102 EGLSurface surface_; 110 EGLSurface surface_;
103 111
104 DISALLOW_COPY_AND_ASSIGN(EGLSyncControlVSyncProvider); 112 DISALLOW_COPY_AND_ASSIGN(EGLSyncControlVSyncProvider);
105 }; 113 };
106 114
107 } // namespace 115 } // namespace
108 116
109 GLSurfaceEGL::GLSurfaceEGL() {} 117 GLSurfaceEGL::GLSurfaceEGL() {}
110 118
111 bool GLSurfaceEGL::InitializeOneOff() { 119 bool GLSurfaceEGL::InitializeOneOff() {
112 static bool initialized = false; 120 if (g_initialized)
113 if (initialized)
114 return true; 121 return true;
115 122
116 g_native_display = GetPlatformDefaultEGLNativeDisplay(); 123 g_native_display = GetPlatformDefaultEGLNativeDisplay();
117 124
118 #if defined(OS_WIN) 125 #if defined(OS_WIN)
119 g_display = GetPlatformDisplay(g_native_display); 126 g_display = GetPlatformDisplay(g_native_display);
120 #else 127 #else
121 g_display = eglGetDisplay(g_native_display); 128 g_display = eglGetDisplay(g_native_display);
122 #endif 129 #endif
123 130
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
179 } 186 }
180 187
181 g_egl_extensions = eglQueryString(g_display, EGL_EXTENSIONS); 188 g_egl_extensions = eglQueryString(g_display, EGL_EXTENSIONS);
182 g_egl_create_context_robustness_supported = 189 g_egl_create_context_robustness_supported =
183 HasEGLExtension("EGL_EXT_create_context_robustness"); 190 HasEGLExtension("EGL_EXT_create_context_robustness");
184 g_egl_sync_control_supported = 191 g_egl_sync_control_supported =
185 HasEGLExtension("EGL_CHROMIUM_sync_control"); 192 HasEGLExtension("EGL_CHROMIUM_sync_control");
186 g_egl_window_fixed_size_supported = 193 g_egl_window_fixed_size_supported =
187 HasEGLExtension("EGL_ANGLE_window_fixed_size"); 194 HasEGLExtension("EGL_ANGLE_window_fixed_size");
188 195
196 // We always succeed beyond this point so set g_initialized here to avoid
197 // infinite recursion through CreateGLContext and GetDisplay
198 // if g_egl_surfaceless_context_supported.
199 g_initialized = true;
200
189 // TODO(oetuaho@nvidia.com): Surfaceless is disabled on Android as a temporary 201 // TODO(oetuaho@nvidia.com): Surfaceless is disabled on Android as a temporary
190 // workaround, since code written for Android WebView takes different paths 202 // workaround, since code written for Android WebView takes different paths
191 // based on whether GL surface objects have underlying EGL surface handles, 203 // based on whether GL surface objects have underlying EGL surface handles,
192 // conflicting with the use of surfaceless. See https://crbug.com/382349 204 // conflicting with the use of surfaceless. See https://crbug.com/382349
193 #if defined(OS_ANDROID) 205 #if defined(OS_ANDROID)
194 DCHECK(!g_egl_surfaceless_context_supported); 206 DCHECK(!g_egl_surfaceless_context_supported);
195 #else 207 #else
196 // Check if SurfacelessEGL is supported. 208 // Check if SurfacelessEGL is supported.
197 g_egl_surfaceless_context_supported = 209 g_egl_surfaceless_context_supported =
198 HasEGLExtension("EGL_KHR_surfaceless_context"); 210 HasEGLExtension("EGL_KHR_surfaceless_context");
199 if (g_egl_surfaceless_context_supported) { 211 if (g_egl_surfaceless_context_supported) {
200 // EGL_KHR_surfaceless_context is supported but ensure 212 // EGL_KHR_surfaceless_context is supported but ensure
201 // GL_OES_surfaceless_context is also supported. We need a current context 213 // GL_OES_surfaceless_context is also supported. We need a current context
202 // to query for supported GL extensions. 214 // to query for supported GL extensions.
203 scoped_refptr<GLSurface> surface = new SurfacelessEGL(Size(1, 1)); 215 scoped_refptr<GLSurface> surface = new SurfacelessEGL(Size(1, 1));
204 scoped_refptr<GLContext> context = GLContext::CreateGLContext( 216 scoped_refptr<GLContext> context = GLContext::CreateGLContext(
205 NULL, surface.get(), PreferIntegratedGpu); 217 NULL, surface.get(), PreferIntegratedGpu);
206 if (!context->MakeCurrent(surface.get())) 218 if (!context->MakeCurrent(surface.get()))
207 g_egl_surfaceless_context_supported = false; 219 g_egl_surfaceless_context_supported = false;
208 220
209 // Ensure context supports GL_OES_surfaceless_context. 221 // Ensure context supports GL_OES_surfaceless_context.
210 if (g_egl_surfaceless_context_supported) { 222 if (g_egl_surfaceless_context_supported) {
211 g_egl_surfaceless_context_supported = context->HasExtension( 223 g_egl_surfaceless_context_supported = context->HasExtension(
212 "GL_OES_surfaceless_context"); 224 "GL_OES_surfaceless_context");
213 context->ReleaseCurrent(surface.get()); 225 context->ReleaseCurrent(surface.get());
214 } 226 }
215 } 227 }
216 #endif 228 #endif
217 229
218 initialized = true;
219
220 return true; 230 return true;
221 } 231 }
222 232
233 // static
234 void GLSurfaceEGL::Deinitialize() {
235 g_initialized = false;
236 }
237
223 EGLDisplay GLSurfaceEGL::GetDisplay() { 238 EGLDisplay GLSurfaceEGL::GetDisplay() {
239 if (!g_initialized) {
240 bool result = GLSurfaceEGL::InitializeOneOff();
241 DCHECK(result);
242 }
224 return g_display; 243 return g_display;
225 } 244 }
226 245
227 EGLDisplay GLSurfaceEGL::GetHardwareDisplay() { 246 EGLDisplay GLSurfaceEGL::GetHardwareDisplay() {
247 if (!g_initialized) {
248 bool result = GLSurfaceEGL::InitializeOneOff();
249 DCHECK(result);
250 }
228 return g_display; 251 return g_display;
229 } 252 }
230 253
231 EGLNativeDisplayType GLSurfaceEGL::GetNativeDisplay() { 254 EGLNativeDisplayType GLSurfaceEGL::GetNativeDisplay() {
255 if (!g_initialized) {
256 bool result = GLSurfaceEGL::InitializeOneOff();
257 DCHECK(result);
258 }
232 return g_native_display; 259 return g_native_display;
233 } 260 }
234 261
235 const char* GLSurfaceEGL::GetEGLExtensions() { 262 const char* GLSurfaceEGL::GetEGLExtensions() {
263 // No need for InitializeOneOff. Assume that extensions will not change
264 // after the first initialization.
236 return g_egl_extensions; 265 return g_egl_extensions;
237 } 266 }
238 267
239 bool GLSurfaceEGL::HasEGLExtension(const char* name) { 268 bool GLSurfaceEGL::HasEGLExtension(const char* name) {
240 return ExtensionsContain(GetEGLExtensions(), name); 269 return ExtensionsContain(GetEGLExtensions(), name);
241 } 270 }
242 271
243 bool GLSurfaceEGL::IsCreateContextRobustnessSupported() { 272 bool GLSurfaceEGL::IsCreateContextRobustnessSupported() {
244 return g_egl_create_context_robustness_supported; 273 return g_egl_create_context_robustness_supported;
245 } 274 }
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
348 EGLBoolean retVal = eglQuerySurface(GetDisplay(), 377 EGLBoolean retVal = eglQuerySurface(GetDisplay(),
349 surface_, 378 surface_,
350 EGL_POST_SUB_BUFFER_SUPPORTED_NV, 379 EGL_POST_SUB_BUFFER_SUPPORTED_NV,
351 &surfaceVal); 380 &surfaceVal);
352 supports_post_sub_buffer_ = (surfaceVal && retVal) == EGL_TRUE; 381 supports_post_sub_buffer_ = (surfaceVal && retVal) == EGL_TRUE;
353 382
354 if (sync_provider) 383 if (sync_provider)
355 vsync_provider_.reset(sync_provider.release()); 384 vsync_provider_.reset(sync_provider.release());
356 else if (g_egl_sync_control_supported) 385 else if (g_egl_sync_control_supported)
357 vsync_provider_.reset(new EGLSyncControlVSyncProvider(surface_)); 386 vsync_provider_.reset(new EGLSyncControlVSyncProvider(surface_));
387 ++g_num_surfaces;
358 return true; 388 return true;
359 } 389 }
360 390
361 void NativeViewGLSurfaceEGL::Destroy() { 391 void NativeViewGLSurfaceEGL::Destroy() {
362 if (surface_) { 392 if (surface_) {
363 if (!eglDestroySurface(GetDisplay(), surface_)) { 393 if (!eglDestroySurface(GetDisplay(), surface_)) {
364 LOG(ERROR) << "eglDestroySurface failed with error " 394 LOG(ERROR) << "eglDestroySurface failed with error "
365 << GetLastEGLErrorString(); 395 << GetLastEGLErrorString();
366 } 396 }
367 surface_ = NULL; 397 surface_ = NULL;
398 CHECK(g_num_surfaces > 0) << "Bad surface count";
jbauman 2014/11/12 01:47:28 DCHECK probably makes more sense here.
GusFernandez 2014/11/15 02:11:56 Done.
399 if (--g_num_surfaces == 0) {
400 GLSurfaceEGL::Deinitialize();
401 }
368 } 402 }
369 } 403 }
370 404
371 EGLConfig NativeViewGLSurfaceEGL::GetConfig() { 405 EGLConfig NativeViewGLSurfaceEGL::GetConfig() {
372 #if !defined(USE_X11) 406 #if !defined(USE_X11)
373 return g_config; 407 return g_config;
374 #else 408 #else
375 if (!config_) { 409 if (!config_) {
376 // Get a config compatible with the window 410 // Get a config compatible with the window
377 DCHECK(window_); 411 DCHECK(window_);
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after
601 635
602 EGLSurface new_surface = eglCreatePbufferSurface(display, 636 EGLSurface new_surface = eglCreatePbufferSurface(display,
603 GetConfig(), 637 GetConfig(),
604 pbuffer_attribs); 638 pbuffer_attribs);
605 if (!new_surface) { 639 if (!new_surface) {
606 LOG(ERROR) << "eglCreatePbufferSurface failed with error " 640 LOG(ERROR) << "eglCreatePbufferSurface failed with error "
607 << GetLastEGLErrorString(); 641 << GetLastEGLErrorString();
608 return false; 642 return false;
609 } 643 }
610 644
611 if (old_surface) 645 if (old_surface) {
612 eglDestroySurface(display, old_surface); 646 eglDestroySurface(display, old_surface);
647 } else {
648 ++g_num_surfaces;
649 }
613 650
614 surface_ = new_surface; 651 surface_ = new_surface;
615 return true; 652 return true;
616 } 653 }
617 654
618 void PbufferGLSurfaceEGL::Destroy() { 655 void PbufferGLSurfaceEGL::Destroy() {
619 if (surface_) { 656 if (surface_) {
620 if (!eglDestroySurface(GetDisplay(), surface_)) { 657 if (!eglDestroySurface(GetDisplay(), surface_)) {
621 LOG(ERROR) << "eglDestroySurface failed with error " 658 LOG(ERROR) << "eglDestroySurface failed with error "
622 << GetLastEGLErrorString(); 659 << GetLastEGLErrorString();
623 } 660 }
661 CHECK(g_num_surfaces > 0) << "Bad surface count";
662 if (--g_num_surfaces == 0) {
663 GLSurfaceEGL::Deinitialize();
664 }
624 surface_ = NULL; 665 surface_ = NULL;
625 } 666 }
626 } 667 }
627 668
628 EGLConfig PbufferGLSurfaceEGL::GetConfig() { 669 EGLConfig PbufferGLSurfaceEGL::GetConfig() {
629 return g_config; 670 return g_config;
630 } 671 }
631 672
632 bool PbufferGLSurfaceEGL::IsOffscreen() { 673 bool PbufferGLSurfaceEGL::IsOffscreen() {
633 return true; 674 return true;
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
738 } 779 }
739 780
740 void* SurfacelessEGL::GetShareHandle() { 781 void* SurfacelessEGL::GetShareHandle() {
741 return NULL; 782 return NULL;
742 } 783 }
743 784
744 SurfacelessEGL::~SurfacelessEGL() { 785 SurfacelessEGL::~SurfacelessEGL() {
745 } 786 }
746 787
747 } // namespace gfx 788 } // namespace gfx
OLDNEW
« content/common/gpu/gpu_channel_manager.cc ('K') | « ui/gl/gl_surface_egl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698