aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Brian Osman <brianosman@google.com>2017-02-21 16:58:08 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-02-22 13:32:56 +0000
commit60c774db3ec46f3eb85f6390ba31e38c8d29e2d4 (patch)
tree0fd26132415dc9843b98b4db2e90ba1f44b3c32c
parent22eb2f1aa09b0fb27c199c2cc96cd74b2098d502 (diff)
Support shared GL contexts in GrContextFactory
Mostly plumbing, plus some minimal testing to make sure that the platform APIs don't explode. I plan to add testing of SkCrossContextImageData using this, which should verify that textures are actually shared. Also found a factory and some related code in the CommandBuffer test context that was totally unused. BUG=skia: Change-Id: I05bbc22c4d1ef946b702a5cc7f67788785219c62 Reviewed-on: https://skia-review.googlesource.com/8808 Reviewed-by: Brian Salomon <bsalomon@google.com> Commit-Queue: Brian Osman <brianosman@google.com>
-rw-r--r--src/utils/win/SkWGL.h5
-rw-r--r--src/utils/win/SkWGL_win.cpp23
-rw-r--r--tests/GrContextFactoryTest.cpp52
-rw-r--r--tools/gpu/GrContextFactory.cpp64
-rw-r--r--tools/gpu/GrContextFactory.h11
-rw-r--r--tools/gpu/gl/angle/GLTestContext_angle.cpp14
-rw-r--r--tools/gpu/gl/angle/GLTestContext_angle.h3
-rw-r--r--tools/gpu/gl/command_buffer/GLTestContext_command_buffer.cpp47
-rw-r--r--tools/gpu/gl/command_buffer/GLTestContext_command_buffer.h22
-rw-r--r--tools/gpu/gl/debug/DebugGLTestContext.cpp5
-rw-r--r--tools/gpu/gl/debug/DebugGLTestContext.h2
-rw-r--r--tools/gpu/gl/egl/CreatePlatformGLTestContext_egl.cpp20
-rw-r--r--tools/gpu/gl/iOS/CreatePlatformGLTestContext_iOS.mm19
-rw-r--r--tools/gpu/gl/mac/CreatePlatformGLTestContext_mac.cpp14
-rw-r--r--tools/gpu/gl/mesa/GLTestContext_mesa.cpp16
-rw-r--r--tools/gpu/gl/mesa/GLTestContext_mesa.h2
-rw-r--r--tools/gpu/gl/null/NullGLTestContext.cpp5
-rw-r--r--tools/gpu/gl/null/NullGLTestContext.h2
-rw-r--r--tools/gpu/gl/win/CreatePlatformGLTestContext_win.cpp20
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;