From 3f21a2e9f3ea6e4f5ad8aca4bd260b4dba375732 Mon Sep 17 00:00:00 2001 From: bsalomon Date: Wed, 13 Apr 2016 15:03:59 -0700 Subject: Only eglTerminate command buffer displays when no displays are in use This is a workaround for crbug.com/603223 BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1878943008 Review URL: https://codereview.chromium.org/1878943008 --- .../GLTestContext_command_buffer.cpp | 48 +++++++++++++++++----- 1 file changed, 38 insertions(+), 10 deletions(-) (limited to 'tools') diff --git a/tools/gpu/gl/command_buffer/GLTestContext_command_buffer.cpp b/tools/gpu/gl/command_buffer/GLTestContext_command_buffer.cpp index 5985a2e31f..af0abc5853 100644 --- a/tools/gpu/gl/command_buffer/GLTestContext_command_buffer.cpp +++ b/tools/gpu/gl/command_buffer/GLTestContext_command_buffer.cpp @@ -6,6 +6,7 @@ * found in the LICENSE file. */ +#include "SkMutex.h" #include "SkOnce.h" #include "gl/GrGLInterface.h" #include "gl/GrGLAssembleInterface.h" @@ -139,6 +140,41 @@ static const GrGLInterface* create_command_buffer_interface() { return GrGLAssembleGLESInterface(gLibrary, command_buffer_get_gl_proc); } +// We use a poor man's garbage collector of EGLDisplays. They are only +// terminated when there are no more EGLDisplays in use. See crbug.com/603223 +SK_DECLARE_STATIC_MUTEX(gDisplayMutex); +static int gActiveDisplayCnt; +SkTArray gRetiredDisplays; + +static EGLDisplay get_and_init_display() { + SkAutoMutexAcquire am(gDisplayMutex); + EGLDisplay dsp = gfGetDisplay(EGL_DEFAULT_DISPLAY); + if (dsp == EGL_NO_DISPLAY) { + return EGL_NO_DISPLAY; + } + EGLint major, minor; + if (!gfInitialize(dsp, &major, &minor)) { + gRetiredDisplays.push_back(dsp); + return EGL_NO_DISPLAY; + } + ++gActiveDisplayCnt; + return dsp; +} + +static void retire_display(EGLDisplay dsp) { + if (dsp == EGL_NO_DISPLAY) { + return; + } + SkAutoMutexAcquire am(gDisplayMutex); + gRetiredDisplays.push_back(dsp); + --gActiveDisplayCnt; + if (!gActiveDisplayCnt) { + for (EGLDisplay d : gRetiredDisplays) { + gfTerminate(d); + } + gRetiredDisplays.reset(); + } +} } // anonymous namespace namespace sk_gpu_test { @@ -196,20 +232,12 @@ void CommandBufferGLTestContext::initializeGLContext(void *nativeWindow, const i // Make sure CHROMIUM_path_rendering is enabled for NVPR support. sk_setenv("CHROME_COMMAND_BUFFER_GLES2_ARGS", "--enable-gl-path-rendering"); - fDisplay = gfGetDisplay(EGL_DEFAULT_DISPLAY); + fDisplay = get_and_init_display(); if (EGL_NO_DISPLAY == fDisplay) { SkDebugf("Command Buffer: Could not create EGL display.\n"); return; } - EGLint majorVersion; - EGLint minorVersion; - if (!gfInitialize(fDisplay, &majorVersion, &minorVersion)) { - SkDebugf("Command Buffer: Could not initialize EGL display.\n"); - this->destroyGLContext(); - return; - } - EGLint numConfigs; if (!gfChooseConfig(fDisplay, configAttribs, static_cast(&fConfig), 1, &numConfigs) || numConfigs != 1) { @@ -288,7 +316,7 @@ void CommandBufferGLTestContext::destroyGLContext() { fSurface = EGL_NO_SURFACE; } - gfTerminate(fDisplay); + retire_display(fDisplay); fDisplay = EGL_NO_DISPLAY; } } -- cgit v1.2.3