From 45c2c8166bbd84a87e29fdd344b39e36e8a28a3f Mon Sep 17 00:00:00 2001 From: kkinnunen Date: Thu, 25 Feb 2016 02:03:43 -0800 Subject: Implement support for using GL ES 3.0 with command buffer Adds a new 'api': --config gpu(api=commandbuffer3) for dm/nanobench. BUG=skia:4943 GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1684413003 Review URL: https://codereview.chromium.org/1684413003 --- dm/DM.cpp | 3 +- dm/DMGpuSupport.h | 3 +- .../gl/command_buffer/SkCommandBufferGLContext.h | 22 ++++++-- include/views/SkOSWindow_Mac.h | 2 +- include/views/SkOSWindow_SDL.h | 2 +- include/views/SkOSWindow_Unix.h | 2 +- include/views/SkOSWindow_Win.h | 2 +- samplecode/SampleApp.cpp | 10 ++-- samplecode/SampleApp.h | 4 +- src/gpu/GrContextFactory.cpp | 7 ++- src/gpu/GrContextFactory.h | 8 ++- src/gpu/gl/GrGLCaps.cpp | 21 +++++-- src/gpu/gl/GrGLInterface.cpp | 49 +++++++++++------ .../gl/command_buffer/SkCommandBufferGLContext.cpp | 64 +++++++++++++--------- src/views/win/SkOSWindow_win.cpp | 6 +- tests/TestConfigParsing.cpp | 2 +- tools/flags/SkCommonFlagsConfig.cpp | 7 ++- 17 files changed, 141 insertions(+), 73 deletions(-) diff --git a/dm/DM.cpp b/dm/DM.cpp index f37fc8b7ff..91a92ea76b 100644 --- a/dm/DM.cpp +++ b/dm/DM.cpp @@ -1224,7 +1224,8 @@ void RunWithGPUTestContexts(T test, GPUTestContexts testContexts, Reporter* repo GrContextFactory::kANGLE_GL_GLContextType, #endif #if SK_COMMAND_BUFFER - GrContextFactory::kCommandBuffer_GLContextType, + GrContextFactory::kCommandBufferES2_GLContextType, + GrContextFactory::kCommandBufferES3_GLContextType, #endif #if SK_MESA GrContextFactory::kMESA_GLContextType, diff --git a/dm/DMGpuSupport.h b/dm/DMGpuSupport.h index 2cfdbdcc2c..4af4d1386f 100644 --- a/dm/DMGpuSupport.h +++ b/dm/DMGpuSupport.h @@ -68,7 +68,8 @@ public: static const GLContextType kANGLE_GLContextType = 0, kANGLE_GL_GLContextType = 0, - kCommandBuffer_GLContextType = 0, + kCommandBufferES2_GLContextType = 0, + kCommandBufferES3_GLContextType = 0, kDebug_GLContextType = 0, kMESA_GLContextType = 0, kNVPR_GLContextType = 0, diff --git a/include/gpu/gl/command_buffer/SkCommandBufferGLContext.h b/include/gpu/gl/command_buffer/SkCommandBufferGLContext.h index 47f3fd967a..cf16c2299c 100644 --- a/include/gpu/gl/command_buffer/SkCommandBufferGLContext.h +++ b/include/gpu/gl/command_buffer/SkCommandBufferGLContext.h @@ -16,8 +16,16 @@ class SkCommandBufferGLContext : public SkGLContext { public: ~SkCommandBufferGLContext() override; - static SkCommandBufferGLContext* Create() { - SkCommandBufferGLContext* ctx = new SkCommandBufferGLContext; + static SkCommandBufferGLContext* CreateES2() { + SkCommandBufferGLContext* ctx = new SkCommandBufferGLContext(kGLES2_ContextVersion); + if (!ctx->isValid()) { + delete ctx; + return nullptr; + } + return ctx; + } + static SkCommandBufferGLContext* CreateES3() { + SkCommandBufferGLContext* ctx = new SkCommandBufferGLContext(kGLES3_ContextVersion); if (!ctx->isValid()) { delete ctx; return nullptr; @@ -42,10 +50,14 @@ public: int getSampleCount(); private: - SkCommandBufferGLContext(); + enum ContextVersion { + kGLES2_ContextVersion, + kGLES3_ContextVersion + }; + SkCommandBufferGLContext(ContextVersion minContextVersion); SkCommandBufferGLContext(void* nativeWindow, int msaaSampleCount); - void initializeGLContext(void* nativeWindow, const int* configAttribs, - const int* surfaceAttribs); + void initializeGLContext(ContextVersion minContextVersion, void* nativeWindow, + const int* configAttribs, const int* surfaceAttribs); void destroyGLContext(); void onPlatformMakeCurrent() const override; diff --git a/include/views/SkOSWindow_Mac.h b/include/views/SkOSWindow_Mac.h index 6ce898321f..66f0cdfde7 100644 --- a/include/views/SkOSWindow_Mac.h +++ b/include/views/SkOSWindow_Mac.h @@ -28,7 +28,7 @@ public: kANGLE_BackEndType, #endif // SK_ANGLE #if SK_COMMAND_BUFFER - kCommandBuffer_BackEndType, + kCommandBufferES2_BackEndType, #endif // SK_COMMAND_BUFFER }; diff --git a/include/views/SkOSWindow_SDL.h b/include/views/SkOSWindow_SDL.h index e08108add4..65ef07eea0 100644 --- a/include/views/SkOSWindow_SDL.h +++ b/include/views/SkOSWindow_SDL.h @@ -24,7 +24,7 @@ public: kANGLE_BackEndType, #endif // SK_ANGLE #if SK_COMMAND_BUFFER - kCommandBuffer_BackEndType, + kCommandBufferES2_BackEndType, #endif // SK_COMMAND_BUFFER }; diff --git a/include/views/SkOSWindow_Unix.h b/include/views/SkOSWindow_Unix.h index ecd0a14521..3395ab9d09 100644 --- a/include/views/SkOSWindow_Unix.h +++ b/include/views/SkOSWindow_Unix.h @@ -40,7 +40,7 @@ public: kANGLE_BackEndType, #endif // SK_ANGLE #if SK_COMMAND_BUFFER - kCommandBuffer_BackEndType, + kCommandBufferES2_BackEndType, #endif // SK_COMMAND_BUFFER }; diff --git a/include/views/SkOSWindow_Win.h b/include/views/SkOSWindow_Win.h index c1a68c621e..9e771c2c6a 100644 --- a/include/views/SkOSWindow_Win.h +++ b/include/views/SkOSWindow_Win.h @@ -42,7 +42,7 @@ public: kANGLE_BackEndType, #endif // SK_ANGLE #if SK_COMMAND_BUFFER - kCommandBuffer_BackEndType, + kCommandBufferES2_BackEndType, #endif // SK_COMMAND_BUFFER #endif // SK_SUPPORT_GPU }; diff --git a/samplecode/SampleApp.cpp b/samplecode/SampleApp.cpp index 7ebac5f215..5b13310677 100644 --- a/samplecode/SampleApp.cpp +++ b/samplecode/SampleApp.cpp @@ -206,9 +206,9 @@ public: break; #endif // SK_ANGLE #if SK_COMMAND_BUFFER - case kCommandBuffer_DeviceType: + case kCommandBufferES2_DeviceType: // Command buffer is really the only other odd man out :D - fBackend = kCommandBuffer_BackEndType; + fBackend = kCommandBufferES2_BackEndType; break; #endif // SK_COMMAND_BUFFER default: @@ -237,7 +237,7 @@ public: break; #endif // SK_ANGLE #if SK_COMMAND_BUFFER - case kCommandBuffer_DeviceType: + case kCommandBufferES2_DeviceType: glInterface.reset(GrGLCreateCommandBufferInterface()); break; #endif // SK_COMMAND_BUFFER @@ -692,7 +692,7 @@ static inline SampleWindow::DeviceType cycle_devicetype(SampleWindow::DeviceType , SampleWindow::kANGLE_DeviceType #endif // SK_ANGLE #if SK_COMMAND_BUFFER - , SampleWindow::kCommandBuffer_DeviceType + , SampleWindow::kCommandBufferES2_DeviceType #endif // SK_COMMAND_BUFFER #endif // SK_SUPPORT_GPU }; @@ -859,7 +859,7 @@ SampleWindow::SampleWindow(void* hwnd, int argc, char** argv, DeviceManager* dev fDeviceType = kANGLE_DeviceType; #endif #if SK_COMMAND_BUFFER && DEFAULT_TO_COMMAND_BUFFER - fDeviceType = kCommandBuffer_DeviceType; + fDeviceType = kCommandBufferES2_DeviceType; #endif fUseClip = false; diff --git a/samplecode/SampleApp.h b/samplecode/SampleApp.h index d4157fa415..9bcb085efa 100644 --- a/samplecode/SampleApp.h +++ b/samplecode/SampleApp.h @@ -39,7 +39,7 @@ public: kANGLE_DeviceType, #endif // SK_ANGLE #if SK_COMMAND_BUFFER - kCommandBuffer_DeviceType, + kCommandBufferES2_DeviceType, #endif // SK_COMMAND_BUFFER #endif // SK_SUPPORT_GPU kDeviceTypeCnt @@ -53,7 +53,7 @@ public: case kANGLE_DeviceType: #endif // SK_ANGLE #if SK_COMMAND_BUFFER - case kCommandBuffer_DeviceType: + case kCommandBufferES2_DeviceType: #endif // SK_COMMAND_BUFFER return true; default: diff --git a/src/gpu/GrContextFactory.cpp b/src/gpu/GrContextFactory.cpp index b7e48254c8..3f7fd4abd9 100755 --- a/src/gpu/GrContextFactory.cpp +++ b/src/gpu/GrContextFactory.cpp @@ -95,8 +95,11 @@ GrContextFactory::ContextInfo GrContextFactory::getContextInfo(GLContextType typ break; #endif #if SK_COMMAND_BUFFER - case kCommandBuffer_GLContextType: - glCtx.reset(SkCommandBufferGLContext::Create()); + case kCommandBufferES2_GLContextType: + glCtx.reset(SkCommandBufferGLContext::CreateES2()); + break; + case kCommandBufferES3_GLContextType: + glCtx.reset(SkCommandBufferGLContext::CreateES3()); break; #endif #if SK_MESA diff --git a/src/gpu/GrContextFactory.h b/src/gpu/GrContextFactory.h index 7afa3108c6..ca4420e182 100644 --- a/src/gpu/GrContextFactory.h +++ b/src/gpu/GrContextFactory.h @@ -34,7 +34,9 @@ public: kANGLE_GL_GLContextType, //! ANGLE on OpenGL OpenGL ES context. #endif #if SK_COMMAND_BUFFER - kCommandBuffer_GLContextType, //! Chromium command buffer OpenGL ES context. + kCommandBufferES2_GLContextType, //! Chromium command buffer OpenGL ES 2.0 context. + kCommandBufferES3_GLContextType, //! Chromium command buffer OpenGL ES 3.0 context. + //! Not ready for production. #endif #if SK_MESA kMESA_GLContextType, //! MESA OpenGL context @@ -82,8 +84,10 @@ public: return "angle-gl"; #endif #if SK_COMMAND_BUFFER - case kCommandBuffer_GLContextType: + case kCommandBufferES2_GLContextType: return "commandbuffer"; + case kCommandBufferES3_GLContextType: + return "commandbuffer3"; #endif #if SK_MESA case kMESA_GLContextType: diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp index 546b0bf692..da7907be9f 100644 --- a/src/gpu/gl/GrGLCaps.cpp +++ b/src/gpu/gl/GrGLCaps.cpp @@ -114,7 +114,7 @@ void GrGLCaps::init(const GrContextOptions& contextOptions, } else { // Qualcomm Adreno drivers appear to have issues with texture storage. fTexStorageSupport = (version >= GR_GL_VER(3,0) && - kQualcomm_GrGLVendor != ctxInfo.vendor()) || + kQualcomm_GrGLVendor != ctxInfo.vendor()) && ctxInfo.hasExtension("GL_EXT_texture_storage"); } @@ -360,12 +360,12 @@ void GrGLCaps::init(const GrContextOptions& contextOptions, } else { // Unextended GLES2 doesn't have any buffer mapping. fMapBufferFlags = kNone_MapBufferType; - if (ctxInfo.hasExtension("GL_CHROMIUM_map_sub")) { - fMapBufferFlags = kCanMap_MapFlag | kSubset_MapFlag; - fMapBufferType = kChromium_MapBufferType; - } else if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_EXT_map_buffer_range")) { + if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_EXT_map_buffer_range")) { fMapBufferFlags = kCanMap_MapFlag | kSubset_MapFlag; fMapBufferType = kMapBufferRange_MapBufferType; + } else if (ctxInfo.hasExtension("GL_CHROMIUM_map_sub")) { + fMapBufferFlags = kCanMap_MapFlag | kSubset_MapFlag; + fMapBufferType = kChromium_MapBufferType; } else if (ctxInfo.hasExtension("GL_OES_mapbuffer")) { fMapBufferFlags = kCanMap_MapFlag; fMapBufferType = kMapBuffer_MapBufferType; @@ -520,6 +520,17 @@ void GrGLCaps::init(const GrContextOptions& contextOptions, fTextureSwizzleSupport = false; } + // TODO: remove after command buffer supports full ES 3.0. + if (kGLES_GrGLStandard == standard && version >= GR_GL_VER(3, 0) && + kChromium_GrGLDriver == ctxInfo.driver()) { + fTexStorageSupport = false; + fSupportsInstancedDraws = false; + fTextureSwizzleSupport = false; + SkASSERT(ctxInfo.hasExtension("GL_CHROMIUM_map_sub")); + fMapBufferFlags = kCanMap_MapFlag | kSubset_MapFlag; + fMapBufferType = kChromium_MapBufferType; + } + // Requires fTextureRedSupport, fTextureSwizzleSupport, msaa support, ES compatibility have // already been detected. this->initConfigTable(ctxInfo, gli, glslCaps); diff --git a/src/gpu/gl/GrGLInterface.cpp b/src/gpu/gl/GrGLInterface.cpp index c09efae2b8..53911bfcc9 100644 --- a/src/gpu/gl/GrGLInterface.cpp +++ b/src/gpu/gl/GrGLInterface.cpp @@ -216,6 +216,15 @@ bool GrGLInterface::validate() const { if (GR_GL_INVALID_VER == glVer) { RETURN_FALSE_INTERFACE } + // TODO: Remove this once command buffer implements full ES3. + bool ALLOW_MISSING_FUNCTIONS_FOR_INCOMPLETE_COMMAND_BUFFER_ES3 = false; + if (kGLES_GrGLStandard == fStandard && glVer >= GR_GL_VER(3,0)) { + const GrGLubyte* rendererUByte; + GR_GL_CALL_RET(this, rendererUByte, GetString(GR_GL_RENDERER)); + const char* renderer = reinterpret_cast(rendererUByte); + ALLOW_MISSING_FUNCTIONS_FOR_INCOMPLETE_COMMAND_BUFFER_ES3 = + 0 == strcmp(renderer, "Chromium"); + } // Now check that baseline ES/Desktop fns not covered above are present // and that we have fn pointers for any advertised fExtensions that we will @@ -306,8 +315,10 @@ bool GrGLInterface::validate() const { } } } else if (glVer >= GR_GL_VER(3,0) || fExtensions.has("GL_EXT_texture_storage")) { - if (nullptr == fFunctions.fTexStorage2D) { - RETURN_FALSE_INTERFACE + if (!ALLOW_MISSING_FUNCTIONS_FOR_INCOMPLETE_COMMAND_BUFFER_ES3) { + if (nullptr == fFunctions.fTexStorage2D) { + RETURN_FALSE_INTERFACE + } } } @@ -480,9 +491,11 @@ bool GrGLInterface::validate() const { if (glVer >= GR_GL_VER(3,0) || (kGLES_GrGLStandard == fStandard && fExtensions.has("GL_EXT_map_buffer_range")) || (kGL_GrGLStandard == fStandard && fExtensions.has("GL_ARB_map_buffer_range"))) { - if (nullptr == fFunctions.fMapBufferRange || - nullptr == fFunctions.fFlushMappedBufferRange) { - RETURN_FALSE_INTERFACE; + if (!ALLOW_MISSING_FUNCTIONS_FOR_INCOMPLETE_COMMAND_BUFFER_ES3) { + if (nullptr == fFunctions.fMapBufferRange || + nullptr == fFunctions.fFlushMappedBufferRange) { + RETURN_FALSE_INTERFACE; + } } } @@ -562,14 +575,16 @@ bool GrGLInterface::validate() const { nullptr == fFunctions.fDrawElementsInstanced) { RETURN_FALSE_INTERFACE } - } + } } else if (kGLES_GrGLStandard == fStandard) { - if (glVer >= GR_GL_VER(3,0) || fExtensions.has("GL_EXT_draw_instanced")) { - if (nullptr == fFunctions.fDrawArraysInstanced || - nullptr == fFunctions.fDrawElementsInstanced) { - RETURN_FALSE_INTERFACE + if (!ALLOW_MISSING_FUNCTIONS_FOR_INCOMPLETE_COMMAND_BUFFER_ES3) { + if (glVer >= GR_GL_VER(3,0) || fExtensions.has("GL_EXT_draw_instanced")) { + if (nullptr == fFunctions.fDrawArraysInstanced || + nullptr == fFunctions.fDrawElementsInstanced) { + RETURN_FALSE_INTERFACE + } } - } + } } if (kGL_GrGLStandard == fStandard) { @@ -577,13 +592,15 @@ bool GrGLInterface::validate() const { if (nullptr == fFunctions.fVertexAttribDivisor) { RETURN_FALSE_INTERFACE } - } + } } else if (kGLES_GrGLStandard == fStandard) { - if (glVer >= GR_GL_VER(3,0) || fExtensions.has("GL_EXT_instanced_arrays")) { - if (nullptr == fFunctions.fVertexAttribDivisor) { - RETURN_FALSE_INTERFACE + if (!ALLOW_MISSING_FUNCTIONS_FOR_INCOMPLETE_COMMAND_BUFFER_ES3) { + if (glVer >= GR_GL_VER(3,0) || fExtensions.has("GL_EXT_instanced_arrays")) { + if (nullptr == fFunctions.fVertexAttribDivisor) { + RETURN_FALSE_INTERFACE + } } - } + } } if ((kGL_GrGLStandard == fStandard && glVer >= GR_GL_VER(4,3)) || diff --git a/src/gpu/gl/command_buffer/SkCommandBufferGLContext.cpp b/src/gpu/gl/command_buffer/SkCommandBufferGLContext.cpp index cf9da9365b..946cd4af2c 100644 --- a/src/gpu/gl/command_buffer/SkCommandBufferGLContext.cpp +++ b/src/gpu/gl/command_buffer/SkCommandBufferGLContext.cpp @@ -33,6 +33,7 @@ typedef void (*__eglMustCastToProperFunctionPointerType)(void); #define EGL_DEFAULT_DISPLAY ((EGLNativeDisplayType)0) #define EGL_SURFACE_TYPE 0x3033 #define EGL_PBUFFER_BIT 0x0001 +#define EGL_WINDOW_BIT 0x0004 #define EGL_RENDERABLE_TYPE 0x3040 #define EGL_RED_SIZE 0x3024 #define EGL_GREEN_SIZE 0x3023 @@ -52,6 +53,11 @@ typedef void (*__eglMustCastToProperFunctionPointerType)(void); #endif +#ifndef EGL_OPENGL_ES3_BIT +// Part of EGL 1.5, typical headers are 1.4. +#define EGL_OPENGL_ES3_BIT 0x0040 +#endif + typedef EGLDisplay (*GetDisplayProc)(EGLNativeDisplayType display_id); typedef EGLBoolean (*InitializeProc)(EGLDisplay dpy, EGLint *major, EGLint *minor); typedef EGLBoolean (*TerminateProc)(EGLDisplay dpy); @@ -137,14 +143,15 @@ const GrGLInterface* GrGLCreateCommandBufferInterface() { return GrGLAssembleGLESInterface(gLibrary, command_buffer_get_gl_proc); } -SkCommandBufferGLContext::SkCommandBufferGLContext() +SkCommandBufferGLContext::SkCommandBufferGLContext(ContextVersion minContextVersion) : fContext(EGL_NO_CONTEXT) , fDisplay(EGL_NO_DISPLAY) , fSurface(EGL_NO_SURFACE) { static const EGLint configAttribs[] = { EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, - EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, + EGL_RENDERABLE_TYPE, minContextVersion == kGLES3_ContextVersion ? EGL_OPENGL_ES3_BIT + : EGL_OPENGL_ES2_BIT, EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, @@ -158,13 +165,15 @@ SkCommandBufferGLContext::SkCommandBufferGLContext() EGL_NONE }; - initializeGLContext(nullptr, configAttribs, surfaceAttribs); + initializeGLContext(minContextVersion, nullptr, configAttribs, surfaceAttribs); } SkCommandBufferGLContext::SkCommandBufferGLContext(void* nativeWindow, int msaaSampleCount) { static const EGLint surfaceAttribs[] = { EGL_NONE }; EGLint configAttribs[] = { + EGL_SURFACE_TYPE, EGL_WINDOW_BIT, + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, @@ -179,10 +188,11 @@ SkCommandBufferGLContext::SkCommandBufferGLContext(void* nativeWindow, int msaaS configAttribs[12] = EGL_NONE; } - initializeGLContext(nativeWindow, configAttribs, surfaceAttribs); + initializeGLContext(kGLES2_ContextVersion, nativeWindow, configAttribs, surfaceAttribs); } -void SkCommandBufferGLContext::initializeGLContext(void* nativeWindow, const int* configAttribs, +void SkCommandBufferGLContext::initializeGLContext(ContextVersion minContextVersion, + void* nativeWindow, const int* configAttribs, const int* surfaceAttribs) { LoadCommandBufferOnce(); if (!gfFunctionsLoadedSuccessfully) { @@ -191,16 +201,14 @@ void SkCommandBufferGLContext::initializeGLContext(void* nativeWindow, const int } // Make sure CHROMIUM_path_rendering is enabled for NVPR support. - sk_setenv("CHROME_COMMAND_BUFFER_GLES2_ARGS", "--enable-gl-path-rendering"); + sk_setenv("CHROME_COMMAND_BUFFER_GLES2_ARGS", "--enable-gl-path-rendering --enable-unsafe-es3-apis"); fDisplay = gfGetDisplay(EGL_DEFAULT_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)) { + if (!gfInitialize(fDisplay, nullptr, nullptr)) { SkDebugf("Command Buffer: Could not initialize EGL display.\n"); this->destroyGLContext(); return; @@ -208,7 +216,7 @@ void SkCommandBufferGLContext::initializeGLContext(void* nativeWindow, const int EGLint numConfigs; if (!gfChooseConfig(fDisplay, configAttribs, static_cast(&fConfig), 1, - &numConfigs) || numConfigs != 1) { + &numConfigs) || numConfigs < 1) { SkDebugf("Command Buffer: Could not choose EGL config.\n"); this->destroyGLContext(); return; @@ -231,7 +239,7 @@ void SkCommandBufferGLContext::initializeGLContext(void* nativeWindow, const int } static const EGLint contextAttribs[] = { - EGL_CONTEXT_CLIENT_VERSION, 2, + EGL_CONTEXT_CLIENT_VERSION, minContextVersion == kGLES3_ContextVersion ? 3 : 2, EGL_NONE }; fContext = gfCreateContext(fDisplay, static_cast(fConfig), nullptr, contextAttribs); @@ -271,22 +279,28 @@ void SkCommandBufferGLContext::destroyGLContext() { if (!gfFunctionsLoadedSuccessfully) { return; } - if (fDisplay) { - gfMakeCurrent(fDisplay, 0, 0, 0); - - if (fContext) { - gfDestroyContext(fDisplay, fContext); - fContext = EGL_NO_CONTEXT; - } - - if (fSurface) { - gfDestroySurface(fDisplay, fSurface); - fSurface = EGL_NO_SURFACE; - } + if (EGL_NO_DISPLAY == fDisplay) { + return; + } - gfTerminate(fDisplay); - fDisplay = EGL_NO_DISPLAY; + if (EGL_NO_CONTEXT != fContext) { + gfDestroyContext(fDisplay, fContext); + fContext = EGL_NO_CONTEXT; + } + // Call MakeCurrent after destroying the context, so that the EGL implementation knows + // that the context is not used anymore after it is released from being current. + // This way command buffer does not need to abandon the context before destruction, and no + // client-side errors are printed. + gfMakeCurrent(fDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + + if (EGL_NO_SURFACE != fSurface) { + gfDestroySurface(fDisplay, fSurface); + fSurface = EGL_NO_SURFACE; } + // The display is likely to be used again for another test, do not call gfTerminate. Also, + // terminating could imply terminating the "host" EGL inside command buffer. This would + // terminate also EGL that this thread might use outside of command buffer. + fDisplay = EGL_NO_DISPLAY; } void SkCommandBufferGLContext::onPlatformMakeCurrent() const { diff --git a/src/views/win/SkOSWindow_win.cpp b/src/views/win/SkOSWindow_win.cpp index c451708cef..3a2a5f6e47 100644 --- a/src/views/win/SkOSWindow_win.cpp +++ b/src/views/win/SkOSWindow_win.cpp @@ -618,7 +618,7 @@ bool SkOSWindow::attach(SkBackEndTypes attachType, int msaaSampleCount, Attachme break; #endif // SK_ANGLE #if SK_COMMAND_BUFFER - case kCommandBuffer_BackEndType: + case kCommandBufferES2_BackEndType: result = attachCommandBuffer(msaaSampleCount, info); break; #endif // SK_COMMAND_BUFFER @@ -651,7 +651,7 @@ void SkOSWindow::detach() { break; #endif // SK_ANGLE #if SK_COMMAND_BUFFER - case kCommandBuffer_BackEndType: + case kCommandBufferES2_BackEndType: detachCommandBuffer(); break; #endif // SK_COMMAND_BUFFER @@ -678,7 +678,7 @@ void SkOSWindow::present() { break; #endif // SK_ANGLE #if SK_COMMAND_BUFFER - case kCommandBuffer_BackEndType: + case kCommandBufferES2_BackEndType: presentCommandBuffer(); break; #endif // SK_COMMAND_BUFFER diff --git a/tests/TestConfigParsing.cpp b/tests/TestConfigParsing.cpp index 777d1fba66..f1f353edb2 100644 --- a/tests/TestConfigParsing.cpp +++ b/tests/TestConfigParsing.cpp @@ -169,7 +169,7 @@ DEF_TEST(ParseConfigs_ExtendedGpuConfigsCorrect, reporter) { #endif #if SK_COMMAND_BUFFER REPORTER_ASSERT(reporter, configs[4]->asConfigGpu()->getContextType() == - GrContextFactory::kCommandBuffer_GLContextType); + GrContextFactory::kCommandBufferES2_GLContextType); #else REPORTER_ASSERT(reporter, !configs[4]->asConfigGpu()); diff --git a/tools/flags/SkCommonFlagsConfig.cpp b/tools/flags/SkCommonFlagsConfig.cpp index e2aa3270f2..c82e8de003 100644 --- a/tools/flags/SkCommonFlagsConfig.cpp +++ b/tools/flags/SkCommonFlagsConfig.cpp @@ -64,6 +64,7 @@ static const char configExtendedHelp[] = #endif #if SK_COMMAND_BUFFER "\t\tcommandbuffer\t\tUse command buffer.\n" + "\t\tcommandbuffer3\t\tUse command buffer ES 3.0 (experimental).\n" #endif #if SK_MESA "\t\tmesa\t\t\tUse MESA.\n" @@ -214,7 +215,11 @@ static bool parse_option_gpu_api(const SkString& value, #endif #if SK_COMMAND_BUFFER if (value.equals("commandbuffer")) { - *outContextType = GrContextFactory::kCommandBuffer_GLContextType; + *outContextType = GrContextFactory::kCommandBufferES2_GLContextType; + return true; + } + if (value.equals("commandbuffer3")) { + *outContextType = GrContextFactory::kCommandBufferES3_GLContextType; return true; } #endif -- cgit v1.2.3