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

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: Make callback optional. Other changes suggested by jbauman and spang 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 if (g_initialized) {
236 g_initialized = false;
237 eglTerminate(g_display);
238 }
239 }
240
223 EGLDisplay GLSurfaceEGL::GetDisplay() { 241 EGLDisplay GLSurfaceEGL::GetDisplay() {
242 if (!g_initialized) {
243 bool result = GLSurfaceEGL::InitializeOneOff();
244 DCHECK(result);
245 }
224 return g_display; 246 return g_display;
225 } 247 }
226 248
227 EGLDisplay GLSurfaceEGL::GetHardwareDisplay() { 249 EGLDisplay GLSurfaceEGL::GetHardwareDisplay() {
250 if (!g_initialized) {
251 bool result = GLSurfaceEGL::InitializeOneOff();
252 DCHECK(result);
253 }
228 return g_display; 254 return g_display;
229 } 255 }
230 256
231 EGLNativeDisplayType GLSurfaceEGL::GetNativeDisplay() { 257 EGLNativeDisplayType GLSurfaceEGL::GetNativeDisplay() {
258 if (!g_initialized) {
259 bool result = GLSurfaceEGL::InitializeOneOff();
260 DCHECK(result);
261 }
232 return g_native_display; 262 return g_native_display;
233 } 263 }
234 264
235 const char* GLSurfaceEGL::GetEGLExtensions() { 265 const char* GLSurfaceEGL::GetEGLExtensions() {
266 // No need for InitializeOneOff. Assume that extensions will not change
267 // after the first initialization.
236 return g_egl_extensions; 268 return g_egl_extensions;
237 } 269 }
238 270
239 bool GLSurfaceEGL::HasEGLExtension(const char* name) { 271 bool GLSurfaceEGL::HasEGLExtension(const char* name) {
240 return ExtensionsContain(GetEGLExtensions(), name); 272 return ExtensionsContain(GetEGLExtensions(), name);
241 } 273 }
242 274
243 bool GLSurfaceEGL::IsCreateContextRobustnessSupported() { 275 bool GLSurfaceEGL::IsCreateContextRobustnessSupported() {
244 return g_egl_create_context_robustness_supported; 276 return g_egl_create_context_robustness_supported;
245 } 277 }
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
348 EGLBoolean retVal = eglQuerySurface(GetDisplay(), 380 EGLBoolean retVal = eglQuerySurface(GetDisplay(),
349 surface_, 381 surface_,
350 EGL_POST_SUB_BUFFER_SUPPORTED_NV, 382 EGL_POST_SUB_BUFFER_SUPPORTED_NV,
351 &surfaceVal); 383 &surfaceVal);
352 supports_post_sub_buffer_ = (surfaceVal && retVal) == EGL_TRUE; 384 supports_post_sub_buffer_ = (surfaceVal && retVal) == EGL_TRUE;
353 385
354 if (sync_provider) 386 if (sync_provider)
355 vsync_provider_.reset(sync_provider.release()); 387 vsync_provider_.reset(sync_provider.release());
356 else if (g_egl_sync_control_supported) 388 else if (g_egl_sync_control_supported)
357 vsync_provider_.reset(new EGLSyncControlVSyncProvider(surface_)); 389 vsync_provider_.reset(new EGLSyncControlVSyncProvider(surface_));
390 ++g_num_surfaces;
piman 2014/11/18 20:55:34 Could that tracking be done in the constructor/des
GusFernandez 2014/11/19 18:50:13 Good idea. This simplified the code somewhat.
358 return true; 391 return true;
359 } 392 }
360 393
361 void NativeViewGLSurfaceEGL::Destroy() { 394 void NativeViewGLSurfaceEGL::Destroy() {
362 if (surface_) { 395 if (surface_) {
363 if (!eglDestroySurface(GetDisplay(), surface_)) { 396 if (!eglDestroySurface(GetDisplay(), surface_)) {
364 LOG(ERROR) << "eglDestroySurface failed with error " 397 LOG(ERROR) << "eglDestroySurface failed with error "
365 << GetLastEGLErrorString(); 398 << GetLastEGLErrorString();
366 } 399 }
367 surface_ = NULL; 400 surface_ = NULL;
401 DCHECK_GT(g_num_surfaces, 0) << "Bad surface count";
402 if (--g_num_surfaces == 0) {
403 DVLOG(2) << "Destroyed last (native) EGL surface. Deinitializing.";
404 GLSurfaceEGL::Deinitialize();
405 }
368 } 406 }
369 } 407 }
370 408
371 EGLConfig NativeViewGLSurfaceEGL::GetConfig() { 409 EGLConfig NativeViewGLSurfaceEGL::GetConfig() {
372 #if !defined(USE_X11) 410 #if !defined(USE_X11)
373 return g_config; 411 return g_config;
374 #else 412 #else
375 if (!config_) { 413 if (!config_) {
376 // Get a config compatible with the window 414 // Get a config compatible with the window
377 DCHECK(window_); 415 DCHECK(window_);
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after
601 639
602 EGLSurface new_surface = eglCreatePbufferSurface(display, 640 EGLSurface new_surface = eglCreatePbufferSurface(display,
603 GetConfig(), 641 GetConfig(),
604 pbuffer_attribs); 642 pbuffer_attribs);
605 if (!new_surface) { 643 if (!new_surface) {
606 LOG(ERROR) << "eglCreatePbufferSurface failed with error " 644 LOG(ERROR) << "eglCreatePbufferSurface failed with error "
607 << GetLastEGLErrorString(); 645 << GetLastEGLErrorString();
608 return false; 646 return false;
609 } 647 }
610 648
611 if (old_surface) 649 if (old_surface) {
612 eglDestroySurface(display, old_surface); 650 eglDestroySurface(display, old_surface);
651 DVLOG(2) << "Reinitialized pbuffer surface. EGL surface count remains at "
652 << g_num_surfaces;
653 } else {
654 ++g_num_surfaces;
655 DVLOG(2) << "Initialized new pbuffer surface. EGL surface count now "
656 << g_num_surfaces;
657 }
613 658
614 surface_ = new_surface; 659 surface_ = new_surface;
615 return true; 660 return true;
616 } 661 }
617 662
618 void PbufferGLSurfaceEGL::Destroy() { 663 void PbufferGLSurfaceEGL::Destroy() {
619 if (surface_) { 664 if (surface_) {
620 if (!eglDestroySurface(GetDisplay(), surface_)) { 665 if (!eglDestroySurface(GetDisplay(), surface_)) {
621 LOG(ERROR) << "eglDestroySurface failed with error " 666 LOG(ERROR) << "eglDestroySurface failed with error "
622 << GetLastEGLErrorString(); 667 << GetLastEGLErrorString();
623 } 668 }
669 CHECK_GT(g_num_surfaces, 0) << "Bad surface count";
piman 2014/11/18 20:55:34 nit: DCHECK_GT
GusFernandez 2014/11/19 18:50:13 Irrelevant after the change above.
670 if (--g_num_surfaces == 0) {
671 DVLOG(2) << "Destroyed last (pbuffer) EGL surface. Deinitializing.";
672 GLSurfaceEGL::Deinitialize();
673 }
624 surface_ = NULL; 674 surface_ = NULL;
625 } 675 }
626 } 676 }
627 677
628 EGLConfig PbufferGLSurfaceEGL::GetConfig() { 678 EGLConfig PbufferGLSurfaceEGL::GetConfig() {
629 return g_config; 679 return g_config;
630 } 680 }
631 681
632 bool PbufferGLSurfaceEGL::IsOffscreen() { 682 bool PbufferGLSurfaceEGL::IsOffscreen() {
633 return true; 683 return true;
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
738 } 788 }
739 789
740 void* SurfacelessEGL::GetShareHandle() { 790 void* SurfacelessEGL::GetShareHandle() {
741 return NULL; 791 return NULL;
742 } 792 }
743 793
744 SurfacelessEGL::~SurfacelessEGL() { 794 SurfacelessEGL::~SurfacelessEGL() {
745 } 795 }
746 796
747 } // namespace gfx 797 } // namespace gfx
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698