diff options
19 files changed, 212 insertions, 134 deletions
diff --git a/src/utils/win/SkWGL.h b/src/utils/win/SkWGL.h index 3799377cc3..1fafd2fe52 100644 --- a/src/utils/win/SkWGL.h +++ b/src/utils/win/SkWGL.h @@ -133,7 +133,8 @@ enum SkWGLContextRequest { * (including non-MSAA) will be created. If preferCoreProfile is true but a core profile cannot be * created then a compatible profile context will be created. */ -HGLRC SkCreateWGLContext(HDC dc, int msaaSampleCount, bool deepColor, SkWGLContextRequest context); +HGLRC SkCreateWGLContext(HDC dc, int msaaSampleCount, bool deepColor, SkWGLContextRequest context, + HGLRC shareContext = nullptr); /** * Helper class for creating a pbuffer context and deleting all the handles when finished. This @@ -143,7 +144,7 @@ HGLRC SkCreateWGLContext(HDC dc, int msaaSampleCount, bool deepColor, SkWGLConte class SkWGLPbufferContext : public SkRefCnt { public: static SkWGLPbufferContext* Create(HDC parentDC, int msaaSampleCount, - SkWGLContextRequest contextType); + SkWGLContextRequest contextType, HGLRC shareContext); virtual ~SkWGLPbufferContext(); diff --git a/src/utils/win/SkWGL_win.cpp b/src/utils/win/SkWGL_win.cpp index dc1b4caf1a..d46123d1bf 100644 --- a/src/utils/win/SkWGL_win.cpp +++ b/src/utils/win/SkWGL_win.cpp @@ -334,7 +334,8 @@ static void get_pixel_formats_to_try(HDC dc, const SkWGLExtensions& extensions, extensions.choosePixelFormat(dc, iAttrs.begin(), fAttrs, 1, format, &num); } -static HGLRC create_gl_context(HDC dc, SkWGLExtensions extensions, SkWGLContextRequest contextType) { +static HGLRC create_gl_context(HDC dc, SkWGLExtensions extensions, SkWGLContextRequest contextType, + HGLRC shareContext) { HDC prevDC = wglGetCurrentDC(); HGLRC prevGLRC = wglGetCurrentContext(); @@ -350,7 +351,7 @@ static HGLRC create_gl_context(HDC dc, SkWGLExtensions extensions, SkWGLContextR SK_WGL_CONTEXT_PROFILE_MASK, SK_WGL_CONTEXT_ES2_PROFILE_BIT, 0, }; - glrc = extensions.createContextAttribs(dc, nullptr, glesAttribs); + glrc = extensions.createContextAttribs(dc, shareContext, glesAttribs); if (nullptr == glrc) { wglMakeCurrent(prevDC, prevGLRC); return nullptr; @@ -375,7 +376,7 @@ static HGLRC create_gl_context(HDC dc, SkWGLExtensions extensions, SkWGLContextR for (int v = 0; v < SK_ARRAY_COUNT(kCoreGLVersions) / 2; ++v) { coreProfileAttribs[1] = kCoreGLVersions[2 * v]; coreProfileAttribs[3] = kCoreGLVersions[2 * v + 1]; - glrc = extensions.createContextAttribs(dc, nullptr, coreProfileAttribs); + glrc = extensions.createContextAttribs(dc, shareContext, coreProfileAttribs); if (glrc) { break; } @@ -385,6 +386,12 @@ static HGLRC create_gl_context(HDC dc, SkWGLExtensions extensions, SkWGLContextR if (nullptr == glrc) { glrc = wglCreateContext(dc); + if (shareContext) { + if (!wglShareLists(shareContext, glrc)) { + wglDeleteContext(glrc); + return nullptr; + } + } } SkASSERT(glrc); @@ -398,7 +405,7 @@ static HGLRC create_gl_context(HDC dc, SkWGLExtensions extensions, SkWGLContextR } HGLRC SkCreateWGLContext(HDC dc, int msaaSampleCount, bool deepColor, - SkWGLContextRequest contextType) { + SkWGLContextRequest contextType, HGLRC shareContext) { SkWGLExtensions extensions; if (!extensions.hasExtension(dc, "WGL_ARB_pixel_format")) { return nullptr; @@ -420,10 +427,12 @@ HGLRC SkCreateWGLContext(HDC dc, int msaaSampleCount, bool deepColor, return nullptr; } - return create_gl_context(dc, extensions, contextType);} + return create_gl_context(dc, extensions, contextType, shareContext); +} SkWGLPbufferContext* SkWGLPbufferContext::Create(HDC parentDC, int msaaSampleCount, - SkWGLContextRequest contextType) { + SkWGLContextRequest contextType, + HGLRC shareContext) { SkWGLExtensions extensions; if (!extensions.hasExtension(parentDC, "WGL_ARB_pixel_format") || !extensions.hasExtension(parentDC, "WGL_ARB_pbuffer")) { @@ -440,7 +449,7 @@ SkWGLPbufferContext* SkWGLPbufferContext::Create(HDC parentDC, int msaaSampleCou if (0 != pbuf) { HDC dc = extensions.getPbufferDC(pbuf); if (dc) { - HGLRC glrc = create_gl_context(dc, extensions, contextType); + HGLRC glrc = create_gl_context(dc, extensions, contextType, shareContext); if (glrc) { return new SkWGLPbufferContext(pbuf, dc, glrc); } diff --git a/tests/GrContextFactoryTest.cpp b/tests/GrContextFactoryTest.cpp index f7ddf36d91..8e6a96410d 100644 --- a/tests/GrContextFactoryTest.cpp +++ b/tests/GrContextFactoryTest.cpp @@ -96,4 +96,56 @@ DEF_GPUTEST(GrContextFactory_abandon, reporter, /*factory*/) { } } +DEF_GPUTEST(GrContextFactory_sharedContexts, reporter, /*factory*/) { + GrContextFactory testFactory; + GrContextFactory::ContextOverrides noOverrides = GrContextFactory::ContextOverrides::kNone; + + for (int i = 0; i < GrContextFactory::kContextTypeCnt; ++i) { + GrContextFactory::ContextType ctxType = static_cast<GrContextFactory::ContextType>(i); + ContextInfo info1 = testFactory.getContextInfo(ctxType); + if (!info1.grContext()) { + continue; + } + + // Ref for passing in. The API does not explicitly say that this stays alive. + info1.grContext()->ref(); + testFactory.abandonContexts(); + + // Test that creating a context in a share group with an abandoned context fails. + ContextInfo info2 = testFactory.getContextInfo(ctxType, noOverrides, info1.grContext()); + REPORTER_ASSERT(reporter, !info2.grContext()); + info1.grContext()->unref(); + + // Create a new base context + ContextInfo info3 = testFactory.getContextInfo(ctxType); + + // Creating a context in a share group may fail, but should never crash. + ContextInfo info4 = testFactory.getContextInfo(ctxType, noOverrides, info3.grContext()); + if (!info4.grContext()) { + continue; + } + REPORTER_ASSERT(reporter, info3.grContext() != info4.grContext()); + REPORTER_ASSERT(reporter, info3.testContext() != info4.testContext()); + + // Passing a different index should create a new (unique) context. + ContextInfo info5 = testFactory.getContextInfo(ctxType, noOverrides, info3.grContext(), 1); + REPORTER_ASSERT(reporter, info5.grContext()); + REPORTER_ASSERT(reporter, info5.testContext()); + REPORTER_ASSERT(reporter, info5.grContext() != info4.grContext()); + REPORTER_ASSERT(reporter, info5.testContext() != info4.testContext()); + + // Creating a shared context with a different type should always fail. + for (int j = 0; j < GrContextFactory::kContextTypeCnt; ++j) { + if (i == j) { + continue; + } + GrContextFactory::ContextType differentCtxType = + static_cast<GrContextFactory::ContextType>(j); + ContextInfo info6 = testFactory.getContextInfo(differentCtxType, noOverrides, + info3.grContext()); + REPORTER_ASSERT(reporter, !info6.grContext()); + } + } +} + #endif diff --git a/tools/gpu/GrContextFactory.cpp b/tools/gpu/GrContextFactory.cpp index 401189a6a3..965e646e59 100644 --- a/tools/gpu/GrContextFactory.cpp +++ b/tools/gpu/GrContextFactory.cpp @@ -103,61 +103,90 @@ const GrContextFactory::ContextType GrContextFactory::kNativeGL_ContextType = GrContextFactory::kGLES_ContextType; #endif -ContextInfo GrContextFactory::getContextInfo(ContextType type, ContextOverrides overrides) { +ContextInfo GrContextFactory::getContextInfo(ContextType type, ContextOverrides overrides, + GrContext* shareContext, uint32_t shareIndex) { + // (shareIndex != 0) -> (shareContext != nullptr) + SkASSERT((shareIndex == 0) || (shareContext != nullptr)); + for (int i = 0; i < fContexts.count(); ++i) { Context& context = fContexts[i]; if (context.fType == type && context.fOverrides == overrides && + context.fShareContext == shareContext && + context.fShareIndex == shareIndex && !context.fAbandoned) { context.fTestContext->makeCurrent(); return ContextInfo(context.fBackend, context.fTestContext, context.fGrContext); } } + + // If we're trying to create a context in a share group, find the master context + Context* masterContext = nullptr; + if (shareContext) { + for (int i = 0; i < fContexts.count(); ++i) { + if (!fContexts[i].fAbandoned && fContexts[i].fGrContext == shareContext) { + masterContext = &fContexts[i]; + break; + } + } + + if (!masterContext || masterContext->fType != type) { + return ContextInfo(); + } + } + std::unique_ptr<TestContext> testCtx; - sk_sp<GrContext> grCtx; GrBackendContext backendContext = 0; sk_sp<const GrGLInterface> glInterface; GrBackend backend = ContextTypeBackend(type); switch (backend) { case kOpenGL_GrBackend: { + GLTestContext* glShareContext = masterContext + ? static_cast<GLTestContext*>(masterContext->fTestContext) : nullptr; GLTestContext* glCtx; switch (type) { case kGL_ContextType: - glCtx = CreatePlatformGLTestContext(kGL_GrGLStandard); + glCtx = CreatePlatformGLTestContext(kGL_GrGLStandard, glShareContext); break; case kGLES_ContextType: - glCtx = CreatePlatformGLTestContext(kGLES_GrGLStandard); + glCtx = CreatePlatformGLTestContext(kGLES_GrGLStandard, glShareContext); break; #if SK_ANGLE case kANGLE_D3D9_ES2_ContextType: - glCtx = MakeANGLETestContext(ANGLEBackend::kD3D9, ANGLEContextVersion::kES2).release(); + glCtx = MakeANGLETestContext(ANGLEBackend::kD3D9, ANGLEContextVersion::kES2, + glShareContext).release(); break; case kANGLE_D3D11_ES2_ContextType: - glCtx = MakeANGLETestContext(ANGLEBackend::kD3D11, ANGLEContextVersion::kES2).release(); + glCtx = MakeANGLETestContext(ANGLEBackend::kD3D11, ANGLEContextVersion::kES2, + glShareContext).release(); break; case kANGLE_D3D11_ES3_ContextType: - glCtx = MakeANGLETestContext(ANGLEBackend::kD3D11, ANGLEContextVersion::kES3).release(); + glCtx = MakeANGLETestContext(ANGLEBackend::kD3D11, ANGLEContextVersion::kES3, + glShareContext).release(); break; case kANGLE_GL_ES2_ContextType: - glCtx = MakeANGLETestContext(ANGLEBackend::kOpenGL, ANGLEContextVersion::kES2).release(); + glCtx = MakeANGLETestContext(ANGLEBackend::kOpenGL, ANGLEContextVersion::kES2, + glShareContext).release(); break; case kANGLE_GL_ES3_ContextType: - glCtx = MakeANGLETestContext(ANGLEBackend::kOpenGL, ANGLEContextVersion::kES3).release(); + glCtx = MakeANGLETestContext(ANGLEBackend::kOpenGL, ANGLEContextVersion::kES3, + glShareContext).release(); break; #endif case kCommandBuffer_ContextType: - glCtx = CommandBufferGLTestContext::Create(); + glCtx = CommandBufferGLTestContext::Create(glShareContext); break; #if SK_MESA case kMESA_ContextType: - glCtx = CreateMesaGLTestContext(); + glCtx = CreateMesaGLTestContext(glShareContext); break; #endif case kNullGL_ContextType: - glCtx = CreateNullGLTestContext(ContextOverrides::kRequireNVPRSupport & overrides); + glCtx = CreateNullGLTestContext( + ContextOverrides::kRequireNVPRSupport & overrides, glShareContext); break; case kDebugGL_ContextType: - glCtx = CreateDebugGLTestContext(); + glCtx = CreateDebugGLTestContext(glShareContext); break; default: return ContextInfo(); @@ -178,6 +207,10 @@ ContextInfo GrContextFactory::getContextInfo(ContextType type, ContextOverrides } #ifdef SK_VULKAN case kVulkan_GrBackend: + if (masterContext) { + // Shared contexts not supported yet + return ContextInfo(); + } SkASSERT(kVulkan_ContextType == type); if (ContextOverrides::kRequireNVPRSupport & overrides) { return ContextInfo(); @@ -211,7 +244,7 @@ ContextInfo GrContextFactory::getContextInfo(ContextType type, ContextOverrides if (ContextOverrides::kAllowSRGBWithoutDecodeControl & overrides) { grOptions.fRequireDecodeDisableForSRGB = false; } - grCtx.reset(GrContext::Create(backend, backendContext, grOptions)); + sk_sp<GrContext> grCtx(GrContext::Create(backend, backendContext, grOptions)); if (!grCtx.get()) { return ContextInfo(); } @@ -238,6 +271,9 @@ ContextInfo GrContextFactory::getContextInfo(ContextType type, ContextOverrides context.fType = type; context.fOverrides = overrides; context.fAbandoned = false; + context.fShareContext = shareContext; + context.fShareIndex = shareIndex; return ContextInfo(context.fBackend, context.fTestContext, context.fGrContext); } + } // namespace sk_gpu_test diff --git a/tools/gpu/GrContextFactory.h b/tools/gpu/GrContextFactory.h index 48b250d0ea..e42f34c944 100644 --- a/tools/gpu/GrContextFactory.h +++ b/tools/gpu/GrContextFactory.h @@ -144,9 +144,13 @@ public: /** * Get a context initialized with a type of GL context. It also makes the GL context current. + * If shareContextInfo is supplied, then a context is created or returned in the same share + * group (able to share resources). To get multiple contexts in a single share group, pass the + * same shareContextInfo, with different values for shareIndex. */ ContextInfo getContextInfo(ContextType type, - ContextOverrides overrides = ContextOverrides::kNone); + ContextOverrides overrides = ContextOverrides::kNone, + GrContext* shareContext = nullptr, uint32_t shareIndex = 0); /** * Get a GrContext initialized with a type of GL context. It also makes the GL context current. */ @@ -162,7 +166,10 @@ private: GrBackend fBackend; TestContext* fTestContext; GrContext* fGrContext; - bool fAbandoned; + GrContext* fShareContext; + uint32_t fShareIndex; + + bool fAbandoned; }; SkTArray<Context, true> fContexts; std::unique_ptr<GLTestContext> fSentinelGLContext; diff --git a/tools/gpu/gl/angle/GLTestContext_angle.cpp b/tools/gpu/gl/angle/GLTestContext_angle.cpp index c3ec431b7e..c0ea48595c 100644 --- a/tools/gpu/gl/angle/GLTestContext_angle.cpp +++ b/tools/gpu/gl/angle/GLTestContext_angle.cpp @@ -76,7 +76,7 @@ void* get_angle_egl_display(void* nativeDisplay, ANGLEBackend type) { class ANGLEGLContext : public sk_gpu_test::GLTestContext { public: - ANGLEGLContext(ANGLEBackend, ANGLEContextVersion); + ANGLEGLContext(ANGLEBackend, ANGLEContextVersion, ANGLEGLContext* shareContext); ~ANGLEGLContext() override; GrEGLImage texture2DToEGLImage(GrGLuint texID) const override; @@ -98,7 +98,8 @@ private: ANGLEContextVersion fVersion; }; -ANGLEGLContext::ANGLEGLContext(ANGLEBackend type, ANGLEContextVersion version) +ANGLEGLContext::ANGLEGLContext(ANGLEBackend type, ANGLEContextVersion version, + ANGLEGLContext* shareContext) : fContext(EGL_NO_CONTEXT) , fDisplay(EGL_NO_DISPLAY) , fSurface(EGL_NO_SURFACE) @@ -134,7 +135,8 @@ ANGLEGLContext::ANGLEGLContext(ANGLEBackend type, ANGLEContextVersion version) EGL_CONTEXT_CLIENT_VERSION, versionNum, EGL_NONE }; - fContext = eglCreateContext(fDisplay, surfaceConfig, nullptr, contextAttribs); + EGLContext eglShareContext = shareContext ? shareContext->fContext : nullptr; + fContext = eglCreateContext(fDisplay, surfaceConfig, eglShareContext, contextAttribs); static const EGLint surfaceAttribs[] = { @@ -287,8 +289,10 @@ const GrGLInterface* CreateANGLEGLInterface() { return GrGLAssembleGLESInterface(&gLibs, angle_get_gl_proc); } -std::unique_ptr<GLTestContext> MakeANGLETestContext(ANGLEBackend type, ANGLEContextVersion version){ - std::unique_ptr<GLTestContext> ctx(new ANGLEGLContext(type, version)); +std::unique_ptr<GLTestContext> MakeANGLETestContext(ANGLEBackend type, ANGLEContextVersion version, + GLTestContext* shareContext){ + ANGLEGLContext* angleShareContext = reinterpret_cast<ANGLEGLContext*>(shareContext); + std::unique_ptr<GLTestContext> ctx(new ANGLEGLContext(type, version, angleShareContext)); if (!ctx->isValid()) { return nullptr; } diff --git a/tools/gpu/gl/angle/GLTestContext_angle.h b/tools/gpu/gl/angle/GLTestContext_angle.h index 9314710276..5433ee0ffa 100644 --- a/tools/gpu/gl/angle/GLTestContext_angle.h +++ b/tools/gpu/gl/angle/GLTestContext_angle.h @@ -30,7 +30,8 @@ enum class ANGLEContextVersion { }; /** Creates a GLTestContext backed by ANGLE. */ -std::unique_ptr<GLTestContext> MakeANGLETestContext(ANGLEBackend, ANGLEContextVersion); +std::unique_ptr<GLTestContext> MakeANGLETestContext(ANGLEBackend, ANGLEContextVersion, + GLTestContext* shareContext = nullptr); } // namespace sk_gpu_test #endif diff --git a/tools/gpu/gl/command_buffer/GLTestContext_command_buffer.cpp b/tools/gpu/gl/command_buffer/GLTestContext_command_buffer.cpp index 888270e41b..56bc5da3d6 100644 --- a/tools/gpu/gl/command_buffer/GLTestContext_command_buffer.cpp +++ b/tools/gpu/gl/command_buffer/GLTestContext_command_buffer.cpp @@ -138,7 +138,7 @@ static const GrGLInterface* create_command_buffer_interface() { namespace sk_gpu_test { -CommandBufferGLTestContext::CommandBufferGLTestContext() +CommandBufferGLTestContext::CommandBufferGLTestContext(CommandBufferGLTestContext* shareContext) : fContext(EGL_NO_CONTEXT), fDisplay(EGL_NO_DISPLAY), fSurface(EGL_NO_SURFACE) { static const EGLint configAttribs[] = { @@ -157,32 +157,6 @@ CommandBufferGLTestContext::CommandBufferGLTestContext() EGL_NONE }; - initializeGLContext(nullptr, configAttribs, surfaceAttribs); -} - -CommandBufferGLTestContext::CommandBufferGLTestContext(void *nativeWindow, int msaaSampleCount) { - static const EGLint surfaceAttribs[] = {EGL_NONE}; - - EGLint configAttribs[] = { - EGL_RED_SIZE, 8, - EGL_GREEN_SIZE, 8, - EGL_BLUE_SIZE, 8, - EGL_ALPHA_SIZE, 8, - EGL_DEPTH_SIZE, 8, - EGL_STENCIL_SIZE, 8, - EGL_SAMPLE_BUFFERS, 1, - EGL_SAMPLES, msaaSampleCount, - EGL_NONE - }; - if (msaaSampleCount == 0) { - configAttribs[12] = EGL_NONE; - } - - initializeGLContext(nativeWindow, configAttribs, surfaceAttribs); -} - -void CommandBufferGLTestContext::initializeGLContext(void *nativeWindow, const int *configAttribs, - const int *surfaceAttribs) { load_command_buffer_once(); if (!gfFunctionsLoadedSuccessfully) { static SkOnce once; @@ -208,16 +182,10 @@ void CommandBufferGLTestContext::initializeGLContext(void *nativeWindow, const i return; } - if (nativeWindow) { - fSurface = gfCreateWindowSurface(fDisplay, - static_cast<EGLConfig>(fConfig), - (EGLNativeWindowType) nativeWindow, - surfaceAttribs); - } else { - fSurface = gfCreatePbufferSurface(fDisplay, - static_cast<EGLConfig>(fConfig), - surfaceAttribs); - } + fSurface = gfCreatePbufferSurface(fDisplay, + static_cast<EGLConfig>(fConfig), + surfaceAttribs); + if (EGL_NO_SURFACE == fSurface) { SkDebugf("Command Buffer: Could not create EGL surface.\n"); this->destroyGLContext(); @@ -228,7 +196,10 @@ void CommandBufferGLTestContext::initializeGLContext(void *nativeWindow, const i EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; - fContext = gfCreateContext(fDisplay, static_cast<EGLConfig>(fConfig), nullptr, contextAttribs); + EGLContext eglShareContext = shareContext + ? reinterpret_cast<EGLContext>(shareContext->fContext) : nullptr; + fContext = gfCreateContext(fDisplay, static_cast<EGLConfig>(fConfig), eglShareContext, + contextAttribs); if (EGL_NO_CONTEXT == fContext) { SkDebugf("Command Buffer: Could not create EGL context.\n"); this->destroyGLContext(); diff --git a/tools/gpu/gl/command_buffer/GLTestContext_command_buffer.h b/tools/gpu/gl/command_buffer/GLTestContext_command_buffer.h index 0994c98c8b..7582f16351 100644 --- a/tools/gpu/gl/command_buffer/GLTestContext_command_buffer.h +++ b/tools/gpu/gl/command_buffer/GLTestContext_command_buffer.h @@ -16,17 +16,10 @@ class CommandBufferGLTestContext : public GLTestContext { public: ~CommandBufferGLTestContext() override; - static CommandBufferGLTestContext *Create() { - CommandBufferGLTestContext *ctx = new CommandBufferGLTestContext; - if (!ctx->isValid()) { - delete ctx; - return nullptr; - } - return ctx; - } - - static CommandBufferGLTestContext *Create(void *nativeWindow, int msaaSampleCount) { - CommandBufferGLTestContext *ctx = new CommandBufferGLTestContext(nativeWindow, msaaSampleCount); + static CommandBufferGLTestContext *Create(GLTestContext* shareContext) { + CommandBufferGLTestContext* cbShareContext = + reinterpret_cast<CommandBufferGLTestContext*>(shareContext); + CommandBufferGLTestContext *ctx = new CommandBufferGLTestContext(cbShareContext); if (!ctx->isValid()) { delete ctx; return nullptr; @@ -43,12 +36,7 @@ public: int getSampleCount(); private: - CommandBufferGLTestContext(); - - CommandBufferGLTestContext(void *nativeWindow, int msaaSampleCount); - - void initializeGLContext(void *nativeWindow, const int *configAttribs, - const int *surfaceAttribs); + CommandBufferGLTestContext(CommandBufferGLTestContext* shareContext); void destroyGLContext(); diff --git a/tools/gpu/gl/debug/DebugGLTestContext.cpp b/tools/gpu/gl/debug/DebugGLTestContext.cpp index cf8a9e4240..e8eea8f78e 100644 --- a/tools/gpu/gl/debug/DebugGLTestContext.cpp +++ b/tools/gpu/gl/debug/DebugGLTestContext.cpp @@ -1208,7 +1208,10 @@ private: } // anonymous namespace namespace sk_gpu_test { -GLTestContext* CreateDebugGLTestContext() { +GLTestContext* CreateDebugGLTestContext(GLTestContext* shareContext) { + if (shareContext) { + return nullptr; + } GLTestContext* ctx = new DebugGLContext(); if (ctx->isValid()) { return ctx; diff --git a/tools/gpu/gl/debug/DebugGLTestContext.h b/tools/gpu/gl/debug/DebugGLTestContext.h index 3f2646bb8c..9b9abe5644 100644 --- a/tools/gpu/gl/debug/DebugGLTestContext.h +++ b/tools/gpu/gl/debug/DebugGLTestContext.h @@ -11,7 +11,7 @@ #include "gl/GLTestContext.h" namespace sk_gpu_test { -GLTestContext* CreateDebugGLTestContext(); +GLTestContext* CreateDebugGLTestContext(GLTestContext* shareContext = nullptr); } // namespace sk_gpu_test #endif diff --git a/tools/gpu/gl/egl/CreatePlatformGLTestContext_egl.cpp b/tools/gpu/gl/egl/CreatePlatformGLTestContext_egl.cpp index a281559a6d..d41adff4bb 100644 --- a/tools/gpu/gl/egl/CreatePlatformGLTestContext_egl.cpp +++ b/tools/gpu/gl/egl/CreatePlatformGLTestContext_egl.cpp @@ -38,7 +38,7 @@ private: class EGLGLTestContext : public sk_gpu_test::GLTestContext { public: - EGLGLTestContext(GrGLStandard forcedGpuAPI); + EGLGLTestContext(GrGLStandard forcedGpuAPI, EGLGLTestContext* shareContext); ~EGLGLTestContext() override; GrEGLImage texture2DToEGLImage(GrGLuint texID) const override; @@ -58,10 +58,13 @@ private: EGLSurface fSurface; }; -EGLGLTestContext::EGLGLTestContext(GrGLStandard forcedGpuAPI) +EGLGLTestContext::EGLGLTestContext(GrGLStandard forcedGpuAPI, EGLGLTestContext* shareContext) : fContext(EGL_NO_CONTEXT) , fDisplay(EGL_NO_DISPLAY) , fSurface(EGL_NO_SURFACE) { + + EGLContext eglShareContext = shareContext ? shareContext->fContext : nullptr; + static const EGLint kEGLContextAttribsForOpenGL[] = { EGL_NONE }; @@ -142,7 +145,8 @@ EGLGLTestContext::EGLGLTestContext(GrGLStandard forcedGpuAPI) continue; } - fContext = eglCreateContext(fDisplay, surfaceConfig, nullptr, kAPIs[api].fContextAttribs); + fContext = eglCreateContext(fDisplay, surfaceConfig, eglShareContext, + kAPIs[api].fContextAttribs); if (EGL_NO_CONTEXT == fContext) { SkDebugf("eglCreateContext failed. EGL Error: 0x%08x\n", eglGetError()); continue; @@ -256,7 +260,8 @@ GrGLuint EGLGLTestContext::eglImageToExternalTexture(GrEGLImage image) const { } std::unique_ptr<sk_gpu_test::GLTestContext> EGLGLTestContext::makeNew() const { - std::unique_ptr<sk_gpu_test::GLTestContext> ctx(new EGLGLTestContext(this->gl()->fStandard)); + std::unique_ptr<sk_gpu_test::GLTestContext> ctx(new EGLGLTestContext(this->gl()->fStandard, + nullptr)); if (ctx) { ctx->makeCurrent(); } @@ -327,11 +332,8 @@ GR_STATIC_ASSERT(sizeof(EGLSyncKHR) <= sizeof(sk_gpu_test::PlatformFence)); namespace sk_gpu_test { GLTestContext *CreatePlatformGLTestContext(GrGLStandard forcedGpuAPI, GLTestContext *shareContext) { - SkASSERT(!shareContext); - if (shareContext) { - return nullptr; - } - EGLGLTestContext *ctx = new EGLGLTestContext(forcedGpuAPI); + EGLGLTestContext* eglShareContext = reinterpret_cast<EGLGLTestContext*>(shareContext); + EGLGLTestContext *ctx = new EGLGLTestContext(forcedGpuAPI, eglShareContext); if (!ctx->isValid()) { delete ctx; return nullptr; diff --git a/tools/gpu/gl/iOS/CreatePlatformGLTestContext_iOS.mm b/tools/gpu/gl/iOS/CreatePlatformGLTestContext_iOS.mm index 4c1aa0119d..954e88e538 100644 --- a/tools/gpu/gl/iOS/CreatePlatformGLTestContext_iOS.mm +++ b/tools/gpu/gl/iOS/CreatePlatformGLTestContext_iOS.mm @@ -16,7 +16,7 @@ namespace { class IOSGLTestContext : public sk_gpu_test::GLTestContext { public: - IOSGLTestContext(); + IOSGLTestContext(IOSGLTestContext* shareContext); ~IOSGLTestContext() override; private: @@ -30,11 +30,17 @@ private: void* fGLLibrary; }; -IOSGLTestContext::IOSGLTestContext() +IOSGLTestContext::IOSGLTestContext(IOSGLTestContext* shareContext) : fEAGLContext(NULL) , fGLLibrary(RTLD_DEFAULT) { - fEAGLContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; + if (shareContext) { + EAGLContext* iosShareContext = (EAGLContext*)(shareContext->fEAGLContext); + fEAGLContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2 + sharegroup: [iosShareContext sharegroup]]; + } else { + fEAGLContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; + } [EAGLContext setCurrentContext:EAGLCTX]; sk_sp<const GrGLInterface> gl(GrGLCreateNativeInterface()); @@ -92,14 +98,11 @@ GrGLFuncPtr IOSGLTestContext::onPlatformGetProcAddress(const char* procName) con namespace sk_gpu_test { GLTestContext *CreatePlatformGLTestContext(GrGLStandard forcedGpuAPI, GLTestContext *shareContext) { - SkASSERT(!shareContext); - if (shareContext) { - return NULL; - } if (kGL_GrGLStandard == forcedGpuAPI) { return NULL; } - IOSGLTestContext *ctx = new IOSGLTestContext; + IOSGLTestContext* iosShareContext = reinterpret_cast<IOSGLTestContext*>(shareContext); + IOSGLTestContext *ctx = new IOSGLTestContext(iosShareContext); if (!ctx->isValid()) { delete ctx; return NULL; diff --git a/tools/gpu/gl/mac/CreatePlatformGLTestContext_mac.cpp b/tools/gpu/gl/mac/CreatePlatformGLTestContext_mac.cpp index 2a908f8625..8ce687d00d 100644 --- a/tools/gpu/gl/mac/CreatePlatformGLTestContext_mac.cpp +++ b/tools/gpu/gl/mac/CreatePlatformGLTestContext_mac.cpp @@ -16,7 +16,7 @@ namespace { class MacGLTestContext : public sk_gpu_test::GLTestContext { public: - MacGLTestContext(); + MacGLTestContext(MacGLTestContext* shareContext); ~MacGLTestContext() override; private: @@ -30,7 +30,7 @@ private: void* fGLLibrary; }; -MacGLTestContext::MacGLTestContext() +MacGLTestContext::MacGLTestContext(MacGLTestContext* shareContext) : fContext(nullptr) , fGLLibrary(RTLD_DEFAULT) { CGLPixelFormatAttribute attributes[] = { @@ -50,7 +50,7 @@ MacGLTestContext::MacGLTestContext() return; } - CGLCreateContext(pixFormat, nullptr, &fContext); + CGLCreateContext(pixFormat, shareContext ? shareContext->fContext : nullptr, &fContext); CGLReleasePixelFormat(pixFormat); if (nullptr == fContext) { @@ -111,15 +111,11 @@ GrGLFuncPtr MacGLTestContext::onPlatformGetProcAddress(const char* procName) con namespace sk_gpu_test { GLTestContext* CreatePlatformGLTestContext(GrGLStandard forcedGpuAPI, GLTestContext* shareContext) { - SkASSERT(!shareContext); - if (shareContext) { - return nullptr; - } - if (kGLES_GrGLStandard == forcedGpuAPI) { return nullptr; } - MacGLTestContext* ctx = new MacGLTestContext; + MacGLTestContext* macShareContext = reinterpret_cast<MacGLTestContext*>(shareContext); + MacGLTestContext* ctx = new MacGLTestContext(macShareContext); if (!ctx->isValid()) { delete ctx; return nullptr; diff --git a/tools/gpu/gl/mesa/GLTestContext_mesa.cpp b/tools/gpu/gl/mesa/GLTestContext_mesa.cpp index 1a1c79d27a..33be94cf47 100644 --- a/tools/gpu/gl/mesa/GLTestContext_mesa.cpp +++ b/tools/gpu/gl/mesa/GLTestContext_mesa.cpp @@ -37,7 +37,7 @@ private: typedef intptr_t Context; public: - MesaGLContext(); + MesaGLContext(MesaGLContext* shareContext); ~MesaGLContext() override; private: @@ -53,15 +53,18 @@ private: GrGLubyte *fImage; }; -MesaGLContext::MesaGLContext() : fContext(static_cast<Context>(0)), fImage(nullptr) { +MesaGLContext::MesaGLContext(MesaGLContext* shareContext) + : fContext(static_cast<Context>(0)) + , fImage(nullptr) { GR_STATIC_ASSERT(sizeof(Context) == sizeof(OSMesaContext)); + Context mesaShareContext = shareContext ? shareContext->fContext : nullptr; /* Create an RGBA-mode context */ #if OSMESA_MAJOR_VERSION * 100 + OSMESA_MINOR_VERSION >= 305 /* specify Z, stencil, accum sizes */ - fContext = (Context)OSMesaCreateContextExt(OSMESA_BGRA, 0, 0, 0, nullptr); + fContext = (Context)OSMesaCreateContextExt(OSMESA_BGRA, 0, 0, 0, mesaShareContext); #else - fContext = (Context) OSMesaCreateContext(OSMESA_BGRA, nullptr); + fContext = (Context) OSMesaCreateContext(OSMESA_BGRA, mesaShareContext); #endif if (!fContext) { SkDebugf("OSMesaCreateContext failed!\n"); @@ -140,8 +143,9 @@ GrGLFuncPtr MesaGLContext::onPlatformGetProcAddress(const char *procName) const namespace sk_gpu_test { -GLTestContext *CreateMesaGLTestContext() { - MesaGLContext *ctx = new MesaGLContext; +GLTestContext *CreateMesaGLTestContext(GLTestContext* shareContext) { + MesaGLContext* mesaShareContext = reinterpret_cast<MesaGLContext*>(shareContext); + MesaGLContext *ctx = new MesaGLContext(mesaShareContext); if (!ctx->isValid()) { delete ctx; return nullptr; diff --git a/tools/gpu/gl/mesa/GLTestContext_mesa.h b/tools/gpu/gl/mesa/GLTestContext_mesa.h index 17c072e679..40184aa7ea 100644 --- a/tools/gpu/gl/mesa/GLTestContext_mesa.h +++ b/tools/gpu/gl/mesa/GLTestContext_mesa.h @@ -11,7 +11,7 @@ #include "gl/GLTestContext.h" namespace sk_gpu_test { -GLTestContext* CreateMesaGLTestContext(); +GLTestContext* CreateMesaGLTestContext(GLTestContext* shareContext); } // namespace sk_gpu_test #endif diff --git a/tools/gpu/gl/null/NullGLTestContext.cpp b/tools/gpu/gl/null/NullGLTestContext.cpp index dcb6231bcb..894de0709a 100644 --- a/tools/gpu/gl/null/NullGLTestContext.cpp +++ b/tools/gpu/gl/null/NullGLTestContext.cpp @@ -29,7 +29,10 @@ private: } // anonymous namespace namespace sk_gpu_test { -GLTestContext* CreateNullGLTestContext(bool enableNVPR) { +GLTestContext* CreateNullGLTestContext(bool enableNVPR, GLTestContext* shareContext) { + if (shareContext) { + return nullptr; + } GLTestContext* ctx = new NullGLContext(enableNVPR); if (ctx->isValid()) { return ctx; diff --git a/tools/gpu/gl/null/NullGLTestContext.h b/tools/gpu/gl/null/NullGLTestContext.h index 909ec2e666..9062e88f19 100644 --- a/tools/gpu/gl/null/NullGLTestContext.h +++ b/tools/gpu/gl/null/NullGLTestContext.h @@ -11,7 +11,7 @@ #include "gl/GLTestContext.h" namespace sk_gpu_test { -GLTestContext* CreateNullGLTestContext(bool enableNVPR); +GLTestContext* CreateNullGLTestContext(bool enableNVPR, GLTestContext* shareContext); } // namespace sk_gpu_test #endif diff --git a/tools/gpu/gl/win/CreatePlatformGLTestContext_win.cpp b/tools/gpu/gl/win/CreatePlatformGLTestContext_win.cpp index a37413ef19..af35b7b6bc 100644 --- a/tools/gpu/gl/win/CreatePlatformGLTestContext_win.cpp +++ b/tools/gpu/gl/win/CreatePlatformGLTestContext_win.cpp @@ -18,8 +18,8 @@ namespace { class WinGLTestContext : public sk_gpu_test::GLTestContext { public: - WinGLTestContext(GrGLStandard forcedGpuAPI); - ~WinGLTestContext() override; + WinGLTestContext(GrGLStandard forcedGpuAPI, WinGLTestContext* shareContext); + ~WinGLTestContext() override; private: void destroyGLContext(); @@ -37,7 +37,7 @@ private: ATOM WinGLTestContext::gWC = 0; -WinGLTestContext::WinGLTestContext(GrGLStandard forcedGpuAPI) +WinGLTestContext::WinGLTestContext(GrGLStandard forcedGpuAPI, WinGLTestContext* shareContext) : fWindow(nullptr) , fDeviceContext(nullptr) , fGlRenderContext(0) @@ -85,13 +85,14 @@ WinGLTestContext::WinGLTestContext(GrGLStandard forcedGpuAPI) kGLES_GrGLStandard == forcedGpuAPI ? kGLES_SkWGLContextRequest : kGLPreferCompatibilityProfile_SkWGLContextRequest; - fPbufferContext = SkWGLPbufferContext::Create(fDeviceContext, 0, contextType); + HGLRC winShareContext = shareContext ? shareContext->fGlRenderContext : nullptr; + fPbufferContext = SkWGLPbufferContext::Create(fDeviceContext, 0, contextType, winShareContext); HDC dc; HGLRC glrc; - if (nullptr == fPbufferContext) { - if (!(fGlRenderContext = SkCreateWGLContext(fDeviceContext, 0, false, contextType))) { + if (!(fGlRenderContext = SkCreateWGLContext(fDeviceContext, 0, false, contextType, + winShareContext))) { SkDebugf("Could not create rendering context.\n"); this->destroyGLContext(); return; @@ -189,11 +190,8 @@ GrGLFuncPtr WinGLTestContext::onPlatformGetProcAddress(const char* name) const { namespace sk_gpu_test { GLTestContext* CreatePlatformGLTestContext(GrGLStandard forcedGpuAPI, GLTestContext *shareContext) { - SkASSERT(!shareContext); - if (shareContext) { - return nullptr; - } - WinGLTestContext *ctx = new WinGLTestContext(forcedGpuAPI); + WinGLTestContext* winShareContext = reinterpret_cast<WinGLTestContext*>(shareContext); + WinGLTestContext *ctx = new WinGLTestContext(forcedGpuAPI, winShareContext); if (!ctx->isValid()) { delete ctx; return nullptr; |