diff options
author | 2014-10-15 23:03:54 -0700 | |
---|---|---|
committer | 2014-10-15 23:03:54 -0700 | |
commit | 30bc88ccd524c0372fd2f8f79190ea4b81685beb (patch) | |
tree | bc506a76edaa98c6285f6e2496c83585d1ada1cc /src | |
parent | de258cd6b402c4da78b66e88191ad02162d87916 (diff) |
Refactor SkGLContext to be actually extendable
Refactor SkGLContext to be actually extendable. Before, non-trivial subclass
would need to destroy the GL connection upon running the destructor. However,
the base class would run GL commands in its own destructor (with destroyed GL
connection)
Refactor so that SkGLContext subclass object creation is completely done by
the factory function. If the factory function returns a non-NULL ptr, it means the context
is usable.
The destruction is done with the destructor instead of virtual function called
upon destruction. Make the destructors not to call virtual functions, for
clarity.
Remove custom 1x1 FBO setup code from the base class. It appears not to be used
anymore.
BUG=skia:2992
Review URL: https://codereview.chromium.org/640283004
Diffstat (limited to 'src')
-rw-r--r-- | src/gpu/gl/SkGLContext.cpp | 124 | ||||
-rw-r--r-- | src/gpu/gl/SkNullGLContext.cpp | 14 | ||||
-rw-r--r-- | src/gpu/gl/angle/SkANGLEGLContext.cpp | 65 | ||||
-rw-r--r-- | src/gpu/gl/debug/SkDebugGLContext.cpp | 10 | ||||
-rw-r--r-- | src/gpu/gl/egl/SkCreatePlatformGLContext_egl.cpp | 87 | ||||
-rw-r--r-- | src/gpu/gl/glx/SkCreatePlatformGLContext_glx.cpp | 107 | ||||
-rw-r--r-- | src/gpu/gl/iOS/SkCreatePlatformGLContext_iOS.mm | 54 | ||||
-rw-r--r-- | src/gpu/gl/mac/SkCreatePlatformGLContext_mac.cpp | 66 | ||||
-rw-r--r-- | src/gpu/gl/mesa/SkMesaGLContext.cpp | 63 | ||||
-rw-r--r-- | src/gpu/gl/nacl/SkCreatePlatformGLContext_nacl.cpp | 48 | ||||
-rw-r--r-- | src/gpu/gl/win/SkCreatePlatformGLContext_win.cpp | 87 |
11 files changed, 286 insertions, 439 deletions
diff --git a/src/gpu/gl/SkGLContext.cpp b/src/gpu/gl/SkGLContext.cpp index 92f65cd924..7cc728d62e 100644 --- a/src/gpu/gl/SkGLContext.cpp +++ b/src/gpu/gl/SkGLContext.cpp @@ -8,131 +8,11 @@ #include "gl/SkGLContext.h" #include "GrGLUtil.h" -SkGLContext::SkGLContext() - : fFBO(0) - , fColorBufferID(0) - , fDepthStencilBufferID(0) - , fGL(NULL) { +SkGLContext::SkGLContext() { } SkGLContext::~SkGLContext() { - - if (fGL) { - // TODO: determine why DeleteFramebuffers is generating a GL error in tests - SK_GL_NOERRCHECK(*this, DeleteFramebuffers(1, &fFBO)); - SK_GL_NOERRCHECK(*this, DeleteRenderbuffers(1, &fColorBufferID)); - SK_GL_NOERRCHECK(*this, DeleteRenderbuffers(1, &fDepthStencilBufferID)); - } - - SkSafeUnref(fGL); -} - -bool SkGLContext::init(GrGLStandard forcedGpuAPI, int width, - int height) { - if (fGL) { - fGL->unref(); - this->destroyGLContext(); - } - - fGL = this->createGLContext(forcedGpuAPI); - if (fGL) { - const GrGLubyte* temp; - - if (!fGL->validate()) { - fGL = NULL; - this->destroyGLContext(); - return false; - } - - SK_GL_RET(*this, temp, GetString(GR_GL_VERSION)); - const char* versionStr = reinterpret_cast<const char*>(temp); - GrGLVersion version = GrGLGetVersionFromString(versionStr); - - // clear any existing GL erorrs - GrGLenum error; - do { - SK_GL_RET(*this, error, GetError()); - } while (GR_GL_NO_ERROR != error); - - SK_GL(*this, GenFramebuffers(1, &fFBO)); - SK_GL(*this, BindFramebuffer(GR_GL_FRAMEBUFFER, fFBO)); - SK_GL(*this, GenRenderbuffers(1, &fColorBufferID)); - SK_GL(*this, BindRenderbuffer(GR_GL_RENDERBUFFER, fColorBufferID)); - if (kGLES_GrGLStandard == this->gl()->fStandard) { - SK_GL(*this, RenderbufferStorage(GR_GL_RENDERBUFFER, - GR_GL_RGBA8, - width, height)); - } else { - SK_GL(*this, RenderbufferStorage(GR_GL_RENDERBUFFER, - GR_GL_RGBA, - width, height)); - } - SK_GL(*this, FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, - GR_GL_COLOR_ATTACHMENT0, - GR_GL_RENDERBUFFER, - fColorBufferID)); - SK_GL(*this, GenRenderbuffers(1, &fDepthStencilBufferID)); - SK_GL(*this, BindRenderbuffer(GR_GL_RENDERBUFFER, fDepthStencilBufferID)); - - // Some drivers that support packed depth stencil will only succeed - // in binding a packed format an FBO. However, we can't rely on packed - // depth stencil being available. - bool supportsPackedDepthStencil; - if (kGLES_GrGLStandard == this->gl()->fStandard) { - supportsPackedDepthStencil = version >= GR_GL_VER(3,0) || - this->hasExtension("GL_OES_packed_depth_stencil"); - } else { - supportsPackedDepthStencil = version >= GR_GL_VER(3,0) || - this->hasExtension("GL_EXT_packed_depth_stencil") || - this->hasExtension("GL_ARB_framebuffer_object"); - } - - if (supportsPackedDepthStencil) { - // ES2 requires sized internal formats for RenderbufferStorage - // On Desktop we let the driver decide. - GrGLenum format = kGLES_GrGLStandard == this->gl()->fStandard ? - GR_GL_DEPTH24_STENCIL8 : - GR_GL_DEPTH_STENCIL; - SK_GL(*this, RenderbufferStorage(GR_GL_RENDERBUFFER, - format, - width, height)); - SK_GL(*this, FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, - GR_GL_DEPTH_ATTACHMENT, - GR_GL_RENDERBUFFER, - fDepthStencilBufferID)); - } else { - GrGLenum format = kGLES_GrGLStandard == this->gl()->fStandard ? GR_GL_STENCIL_INDEX8 : - GR_GL_STENCIL_INDEX; - SK_GL(*this, RenderbufferStorage(GR_GL_RENDERBUFFER, - format, - width, height)); - } - SK_GL(*this, FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, - GR_GL_STENCIL_ATTACHMENT, - GR_GL_RENDERBUFFER, - fDepthStencilBufferID)); - SK_GL(*this, Viewport(0, 0, width, height)); - SK_GL(*this, ClearStencil(0)); - SK_GL(*this, Clear(GR_GL_STENCIL_BUFFER_BIT)); - - SK_GL_RET(*this, error, GetError()); - GrGLenum status; - SK_GL_RET(*this, status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); - - if (GR_GL_FRAMEBUFFER_COMPLETE != status || - GR_GL_NO_ERROR != error) { - fFBO = 0; - fColorBufferID = 0; - fDepthStencilBufferID = 0; - fGL->unref(); - fGL = NULL; - this->destroyGLContext(); - return false; - } else { - return true; - } - } - return false; + SkASSERT(NULL == fGL.get()); // Subclass should destroy the interface. } void SkGLContext::testAbandon() { diff --git a/src/gpu/gl/SkNullGLContext.cpp b/src/gpu/gl/SkNullGLContext.cpp index 576ee526f1..68807e7c57 100644 --- a/src/gpu/gl/SkNullGLContext.cpp +++ b/src/gpu/gl/SkNullGLContext.cpp @@ -8,9 +8,11 @@ #include "gl/SkNullGLContext.h" -const GrGLInterface* SkNullGLContext::createGLContext(GrGLStandard forcedGpuAPI) { - if (kGLES_GrGLStandard == forcedGpuAPI) { - return NULL; - } - return GrGLCreateNullInterface(); -}; +SkNullGLContext::SkNullGLContext() { + fGL.reset(GrGLCreateNullInterface()); +} + +SkNullGLContext::~SkNullGLContext() { + fGL.reset(NULL); +} + diff --git a/src/gpu/gl/angle/SkANGLEGLContext.cpp b/src/gpu/gl/angle/SkANGLEGLContext.cpp index 4914ba5533..232c866423 100644 --- a/src/gpu/gl/angle/SkANGLEGLContext.cpp +++ b/src/gpu/gl/angle/SkANGLEGLContext.cpp @@ -12,36 +12,6 @@ SkANGLEGLContext::SkANGLEGLContext() : fContext(EGL_NO_CONTEXT) , fDisplay(EGL_NO_DISPLAY) , fSurface(EGL_NO_SURFACE) { -} - -SkANGLEGLContext::~SkANGLEGLContext() { - this->destroyGLContext(); -} - -void SkANGLEGLContext::destroyGLContext() { - if (fDisplay) { - eglMakeCurrent(fDisplay, 0, 0, 0); - - if (fContext) { - eglDestroyContext(fDisplay, fContext); - fContext = EGL_NO_CONTEXT; - } - - if (fSurface) { - eglDestroySurface(fDisplay, fSurface); - fSurface = EGL_NO_SURFACE; - } - - //TODO should we close the display? - fDisplay = EGL_NO_DISPLAY; - } -} - -const GrGLInterface* SkANGLEGLContext::createGLContext(GrGLStandard forcedGpuAPI) { - if (kGL_GrGLStandard == forcedGpuAPI) { - return NULL; - } - fDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); EGLint majorVersion; @@ -78,14 +48,41 @@ const GrGLInterface* SkANGLEGLContext::createGLContext(GrGLStandard forcedGpuAPI eglMakeCurrent(fDisplay, fSurface, fSurface, fContext); - const GrGLInterface* interface = GrGLCreateANGLEInterface(); - if (NULL == interface) { + fGL.reset(GrGLCreateANGLEInterface()); + if (NULL == fGL.get()) { SkDebugf("Could not create ANGLE GL interface!\n"); this->destroyGLContext(); - return NULL; + return; + } + if (!fGL->validate()) { + SkDebugf("Could not validate ANGLE GL interface!\n"); + this->destroyGLContext(); + return; } +} - return interface; +SkANGLEGLContext::~SkANGLEGLContext() { + this->destroyGLContext(); +} + +void SkANGLEGLContext::destroyGLContext() { + fGL.reset(NULL); + if (fDisplay) { + eglMakeCurrent(fDisplay, 0, 0, 0); + + if (fContext) { + eglDestroyContext(fDisplay, fContext); + fContext = EGL_NO_CONTEXT; + } + + if (fSurface) { + eglDestroySurface(fDisplay, fSurface); + fSurface = EGL_NO_SURFACE; + } + + //TODO should we close the display? + fDisplay = EGL_NO_DISPLAY; + } } void SkANGLEGLContext::makeCurrent() const { diff --git a/src/gpu/gl/debug/SkDebugGLContext.cpp b/src/gpu/gl/debug/SkDebugGLContext.cpp index 8ea546699c..c021c7a7a8 100644 --- a/src/gpu/gl/debug/SkDebugGLContext.cpp +++ b/src/gpu/gl/debug/SkDebugGLContext.cpp @@ -8,10 +8,10 @@ #include "gl/SkDebugGLContext.h" -const GrGLInterface* SkDebugGLContext::createGLContext(GrGLStandard forcedGpuAPI) { - if (kGLES_GrGLStandard == forcedGpuAPI) { - return NULL; - } +SkDebugGLContext::SkDebugGLContext() { + fGL.reset(GrGLCreateDebugInterface()); +} - return GrGLCreateDebugInterface(); +SkDebugGLContext::~SkDebugGLContext() { + fGL.reset(NULL); } diff --git a/src/gpu/gl/egl/SkCreatePlatformGLContext_egl.cpp b/src/gpu/gl/egl/SkCreatePlatformGLContext_egl.cpp index f33e84abc4..6fc8f48373 100644 --- a/src/gpu/gl/egl/SkCreatePlatformGLContext_egl.cpp +++ b/src/gpu/gl/egl/SkCreatePlatformGLContext_egl.cpp @@ -14,52 +14,23 @@ namespace { class EGLGLContext : public SkGLContext { public: - EGLGLContext(); - - virtual ~EGLGLContext(); - + EGLGLContext(GrGLStandard forcedGpuAPI); + virtual ~EGLGLContext() SK_OVERRIDE; virtual void makeCurrent() const SK_OVERRIDE; virtual void swapBuffers() const SK_OVERRIDE; -protected: - virtual const GrGLInterface* createGLContext(GrGLStandard forcedGpuAPI) SK_OVERRIDE; - virtual void destroyGLContext() SK_OVERRIDE; private: + void destroyGLContext(); + EGLContext fContext; EGLDisplay fDisplay; EGLSurface fSurface; }; -EGLGLContext::EGLGLContext() +EGLGLContext::EGLGLContext(GrGLStandard forcedGpuAPI) : fContext(EGL_NO_CONTEXT) , fDisplay(EGL_NO_DISPLAY) , fSurface(EGL_NO_SURFACE) { -} - -EGLGLContext::~EGLGLContext() { - this->destroyGLContext(); -} - -void EGLGLContext::destroyGLContext() { - if (fDisplay) { - eglMakeCurrent(fDisplay, 0, 0, 0); - - if (fContext) { - eglDestroyContext(fDisplay, fContext); - fContext = EGL_NO_CONTEXT; - } - - if (fSurface) { - eglDestroySurface(fDisplay, fSurface); - fSurface = EGL_NO_SURFACE; - } - - //TODO should we close the display? - fDisplay = EGL_NO_DISPLAY; - } -} - -const GrGLInterface* EGLGLContext::createGLContext(GrGLStandard forcedGpuAPI) { static const EGLint kEGLContextAttribsForOpenGL[] = { EGL_NONE }; @@ -98,9 +69,7 @@ const GrGLInterface* EGLGLContext::createGLContext(GrGLStandard forcedGpuAPI) { } SkASSERT(forcedGpuAPI == kNone_GrGLStandard || kAPIs[api].fStandard == forcedGpuAPI); - const GrGLInterface* interface = NULL; - - for (; NULL == interface && api < apiLimit; ++api) { + for (; NULL == fGL.get() && api < apiLimit; ++api) { fDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); EGLint majorVersion; @@ -160,23 +129,46 @@ const GrGLInterface* EGLGLContext::createGLContext(GrGLStandard forcedGpuAPI) { continue; } - interface = GrGLCreateNativeInterface(); - if (NULL == interface) { + fGL.reset(GrGLCreateNativeInterface()); + if (NULL == fGL.get()) { SkDebugf("Failed to create gl interface.\n"); this->destroyGLContext(); continue; } - if (!interface->validate()) { - interface->unref(); - interface = NULL; + if (!fGL->validate()) { + SkDebugf("Failed to validate gl interface.\n"); this->destroyGLContext(); + continue; } } +} - return interface; +EGLGLContext::~EGLGLContext() { + this->destroyGLContext(); } +void EGLGLContext::destroyGLContext() { + fGL.reset(NULL); + if (fDisplay) { + eglMakeCurrent(fDisplay, 0, 0, 0); + + if (fContext) { + eglDestroyContext(fDisplay, fContext); + fContext = EGL_NO_CONTEXT; + } + + if (fSurface) { + eglDestroySurface(fDisplay, fSurface); + fSurface = EGL_NO_SURFACE; + } + + //TODO should we close the display? + fDisplay = EGL_NO_DISPLAY; + } +} + + void EGLGLContext::makeCurrent() const { if (!eglMakeCurrent(fDisplay, fSurface, fSurface, fContext)) { SkDebugf("Could not set the context.\n"); @@ -191,7 +183,12 @@ void EGLGLContext::swapBuffers() const { } // anonymous namespace -SkGLContext* SkCreatePlatformGLContext() { - return SkNEW(EGLGLContext); +SkGLContext* SkCreatePlatformGLContext(GrGLStandard forcedGpuAPI) { + EGLGLContext* ctx = SkNEW_ARGS(EGLGLContext, (forcedGpuAPI)); + if (!ctx->isValid()) { + SkDELETE(ctx); + return NULL; + } + return ctx; } diff --git a/src/gpu/gl/glx/SkCreatePlatformGLContext_glx.cpp b/src/gpu/gl/glx/SkCreatePlatformGLContext_glx.cpp index 794cdb6f03..f9977b2a46 100644 --- a/src/gpu/gl/glx/SkCreatePlatformGLContext_glx.cpp +++ b/src/gpu/gl/glx/SkCreatePlatformGLContext_glx.cpp @@ -46,65 +46,32 @@ static int ctxErrorHandler(Display *dpy, XErrorEvent *ev) { class GLXGLContext : public SkGLContext { public: - GLXGLContext(); - - virtual ~GLXGLContext(); - + GLXGLContext(GrGLStandard forcedGpuAPI); + virtual ~GLXGLContext() SK_OVERRIDE; virtual void makeCurrent() const SK_OVERRIDE; virtual void swapBuffers() const SK_OVERRIDE; -protected: - virtual const GrGLInterface* createGLContext(GrGLStandard forcedGpuAPI) SK_OVERRIDE; - virtual void destroyGLContext() SK_OVERRIDE; private: + void destroyGLContext(); + GLXContext fContext; Display* fDisplay; Pixmap fPixmap; GLXPixmap fGlxPixmap; }; -GLXGLContext::GLXGLContext() +GLXGLContext::GLXGLContext(GrGLStandard forcedGpuAPI) : fContext(NULL) , fDisplay(NULL) , fPixmap(0) , fGlxPixmap(0) { -} - -GLXGLContext::~GLXGLContext() { - this->destroyGLContext(); -} -void GLXGLContext::destroyGLContext() { - if (fDisplay) { - glXMakeCurrent(fDisplay, 0, 0); - - if (fContext) { - glXDestroyContext(fDisplay, fContext); - fContext = NULL; - } - - if (fGlxPixmap) { - glXDestroyGLXPixmap(fDisplay, fGlxPixmap); - fGlxPixmap = 0; - } - - if (fPixmap) { - XFreePixmap(fDisplay, fPixmap); - fPixmap = 0; - } - - XCloseDisplay(fDisplay); - fDisplay = NULL; - } -} - -const GrGLInterface* GLXGLContext::createGLContext(GrGLStandard forcedGpuAPI) { fDisplay = XOpenDisplay(0); if (!fDisplay) { SkDebugf("Failed to open X display.\n"); this->destroyGLContext(); - return NULL; + return; } // Get a matching FB config @@ -121,7 +88,7 @@ const GrGLInterface* GLXGLContext::createGLContext(GrGLStandard forcedGpuAPI) { ((glx_major == 1) && (glx_minor < 3)) || (glx_major < 1)) { SkDebugf("GLX version 1.3 or higher required.\n"); this->destroyGLContext(); - return NULL; + return; } //SkDebugf("Getting matching framebuffer configs.\n"); @@ -131,7 +98,7 @@ const GrGLInterface* GLXGLContext::createGLContext(GrGLStandard forcedGpuAPI) { if (!fbc) { SkDebugf("Failed to retrieve a framebuffer config.\n"); this->destroyGLContext(); - return NULL; + return; } //SkDebugf("Found %d matching FB configs.\n", fbcount); @@ -171,7 +138,7 @@ const GrGLInterface* GLXGLContext::createGLContext(GrGLStandard forcedGpuAPI) { if (!fPixmap) { SkDebugf("Failed to create pixmap.\n"); this->destroyGLContext(); - return NULL; + return; } fGlxPixmap = glXCreateGLXPixmap(fDisplay, vi, fPixmap); @@ -283,7 +250,7 @@ const GrGLInterface* GLXGLContext::createGLContext(GrGLStandard forcedGpuAPI) { if (ctxErrorOccurred || !fContext) { SkDebugf("Failed to create an OpenGL context.\n"); this->destroyGLContext(); - return NULL; + return; } // Verify that context is a direct context @@ -297,16 +264,51 @@ const GrGLInterface* GLXGLContext::createGLContext(GrGLStandard forcedGpuAPI) { if (!glXMakeCurrent(fDisplay, fGlxPixmap, fContext)) { SkDebugf("Could not set the context.\n"); this->destroyGLContext(); - return NULL; + return; } - const GrGLInterface* interface = GrGLCreateNativeInterface(); - if (!interface) { + fGL.reset(GrGLCreateNativeInterface()); + if (NULL == fGL.get()) { SkDebugf("Failed to create gl interface"); this->destroyGLContext(); - return NULL; + return; + } + + if (!fGL->validate()) { + SkDebugf("Failed to validate gl interface"); + this->destroyGLContext(); + return; + } +} + + +GLXGLContext::~GLXGLContext() { + this->destroyGLContext(); +} + +void GLXGLContext::destroyGLContext() { + fGL.reset(NULL); + if (fDisplay) { + glXMakeCurrent(fDisplay, 0, 0); + + if (fContext) { + glXDestroyContext(fDisplay, fContext); + fContext = NULL; + } + + if (fGlxPixmap) { + glXDestroyGLXPixmap(fDisplay, fGlxPixmap); + fGlxPixmap = 0; + } + + if (fPixmap) { + XFreePixmap(fDisplay, fPixmap); + fPixmap = 0; + } + + XCloseDisplay(fDisplay); + fDisplay = NULL; } - return interface; } void GLXGLContext::makeCurrent() const { @@ -321,6 +323,11 @@ void GLXGLContext::swapBuffers() const { } // anonymous namespace -SkGLContext* SkCreatePlatformGLContext() { - return SkNEW(GLXGLContext); +SkGLContext* SkCreatePlatformGLContext(GrGLStandard forcedGpuAPI) { + GLXGLContext* ctx = SkNEW_ARGS(GLXGLContext, (forcedGpuAPI)); + if (!ctx->isValid()) { + SkDELETE(ctx); + return NULL; + } + return ctx; } diff --git a/src/gpu/gl/iOS/SkCreatePlatformGLContext_iOS.mm b/src/gpu/gl/iOS/SkCreatePlatformGLContext_iOS.mm index 9989957ac9..423ef8cbdd 100644 --- a/src/gpu/gl/iOS/SkCreatePlatformGLContext_iOS.mm +++ b/src/gpu/gl/iOS/SkCreatePlatformGLContext_iOS.mm @@ -16,21 +16,33 @@ namespace { class IOSGLContext : public SkGLContext { public: IOSGLContext(); - - virtual ~IOSGLContext(); - + virtual ~IOSGLContext() SK_OVERRIDE; virtual void makeCurrent() const SK_OVERRIDE; virtual void swapBuffers() const SK_OVERRIDE; -protected: - virtual const GrGLInterface* createGLContext(GrGLStandard forcedGpuAPI) SK_OVERRIDE; - virtual void destroyGLContext() SK_OVERRIDE; private: + void destroyGLContext(); + void* fEAGLContext; }; IOSGLContext::IOSGLContext() : fEAGLContext(NULL) { + + fEAGLContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; + [EAGLContext setCurrentContext:EAGLCTX]; + + fGL.reset(GrGLCreateNativeInterface()); + if (NULL == fGL.get()) { + SkDebugf("Failed to create gl interface"); + this->destroyGLContext(); + return; + } + if (!fGL->validate()) { + SkDebugf("Failed to validate gl interface"); + this->destroyGLContext(); + return; + } } IOSGLContext::~IOSGLContext() { @@ -38,6 +50,7 @@ IOSGLContext::~IOSGLContext() { } void IOSGLContext::destroyGLContext() { + fGL.reset(NULL); if (fEAGLContext) { if ([EAGLContext currentContext] == EAGLCTX) { [EAGLContext setCurrentContext:nil]; @@ -47,22 +60,6 @@ void IOSGLContext::destroyGLContext() { } } -const GrGLInterface* IOSGLContext::createGLContext(GrGLStandard forcedGpuAPI) { - if (kGL_GrGLStandard == forcedGpuAPI) { - return NULL; - } - - fEAGLContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; - [EAGLContext setCurrentContext:EAGLCTX]; - - const GrGLInterface* interface = GrGLCreateNativeInterface(); - if (!interface) { - SkDebugf("Failed to create gl interface"); - this->destroyGLContext(); - return NULL; - } - return interface; -} void IOSGLContext::makeCurrent() const { if (![EAGLContext setCurrentContext:EAGLCTX]) { @@ -74,8 +71,15 @@ void IOSGLContext::swapBuffers() const { } } // anonymous namespace - -SkGLContext* SkCreatePlatformGLContext() { - return SkNEW(IOSGLContext); +SkGLContext* SkCreatePlatformGLContext(GrGLStandard forcedGpuAPI) { + if (kGL_GrGLStandard == forcedGpuAPI) { + return NULL; + } + IOSGLContext* ctx = SkNEW(IOSGLContext); + if (!ctx->isValid()) { + SkDELETE(ctx); + return NULL; + } + return ctx; } diff --git a/src/gpu/gl/mac/SkCreatePlatformGLContext_mac.cpp b/src/gpu/gl/mac/SkCreatePlatformGLContext_mac.cpp index 35ec276296..5ae1aeb3c7 100644 --- a/src/gpu/gl/mac/SkCreatePlatformGLContext_mac.cpp +++ b/src/gpu/gl/mac/SkCreatePlatformGLContext_mac.cpp @@ -14,39 +14,18 @@ namespace { class MacGLContext : public SkGLContext { public: MacGLContext(); - - virtual ~MacGLContext(); - + virtual ~MacGLContext() SK_OVERRIDE; virtual void makeCurrent() const SK_OVERRIDE; virtual void swapBuffers() const SK_OVERRIDE; -protected: - virtual const GrGLInterface* createGLContext(GrGLStandard forcedGpuAPI) SK_OVERRIDE; - virtual void destroyGLContext() SK_OVERRIDE; private: + void destroyGLContext(); + CGLContextObj fContext; }; MacGLContext::MacGLContext() : fContext(NULL) { -} - -MacGLContext::~MacGLContext() { - this->destroyGLContext(); -} - -void MacGLContext::destroyGLContext() { - if (fContext) { - CGLReleaseContext(fContext); - } -} - -const GrGLInterface* MacGLContext::createGLContext(GrGLStandard forcedGpuAPI) { - SkASSERT(NULL == fContext); - if (kGLES_GrGLStandard == forcedGpuAPI) { - return NULL; - } - CGLPixelFormatAttribute attributes[] = { #if MAC_OS_X_VERSION_10_7 kCGLPFAOpenGLProfile, (CGLPixelFormatAttribute) kCGLOGLPVersion_3_2_Core, @@ -61,7 +40,7 @@ const GrGLInterface* MacGLContext::createGLContext(GrGLStandard forcedGpuAPI) { if (NULL == pixFormat) { SkDebugf("CGLChoosePixelFormat failed."); - return NULL; + return; } CGLCreateContext(pixFormat, NULL, &fContext); @@ -69,19 +48,34 @@ const GrGLInterface* MacGLContext::createGLContext(GrGLStandard forcedGpuAPI) { if (NULL == fContext) { SkDebugf("CGLCreateContext failed."); - return NULL; + return; } CGLSetCurrentContext(fContext); - const GrGLInterface* interface = GrGLCreateNativeInterface(); - if (NULL == interface) { + fGL.reset(GrGLCreateNativeInterface()); + if (NULL == fGL.get()) { SkDebugf("Context could not create GL interface.\n"); this->destroyGLContext(); - return NULL; + return; + } + if (!fGL->validate()) { + SkDebugf("Context could not validate GL interface.\n"); + this->destroyGLContext(); + return; } +} - return interface; +MacGLContext::~MacGLContext() { + this->destroyGLContext(); +} + +void MacGLContext::destroyGLContext() { + fGL.reset(NULL); + if (fContext) { + CGLReleaseContext(fContext); + fContext = NULL; + } } void MacGLContext::makeCurrent() const { @@ -94,6 +88,14 @@ void MacGLContext::swapBuffers() const { } // anonymous namespace -SkGLContext* SkCreatePlatformGLContext() { - return SkNEW(MacGLContext); +SkGLContext* SkCreatePlatformGLContext(GrGLStandard forcedGpuAPI) { + if (kGLES_GrGLStandard == forcedGpuAPI) { + return NULL; + } + MacGLContext* ctx = SkNEW(MacGLContext); + if (!ctx->isValid()) { + SkDELETE(ctx); + return NULL; + } + return ctx; } diff --git a/src/gpu/gl/mesa/SkMesaGLContext.cpp b/src/gpu/gl/mesa/SkMesaGLContext.cpp index 8c339c7fac..3c5cc971a2 100644 --- a/src/gpu/gl/mesa/SkMesaGLContext.cpp +++ b/src/gpu/gl/mesa/SkMesaGLContext.cpp @@ -11,34 +11,12 @@ #include "gl/SkMesaGLContext.h" #include "gl/GrGLDefines.h" +static const GrGLint gBOGUS_SIZE = 16; + SkMesaGLContext::SkMesaGLContext() : fContext(static_cast<Context>(NULL)) , fImage(NULL) { GR_STATIC_ASSERT(sizeof(Context) == sizeof(OSMesaContext)); -} - -SkMesaGLContext::~SkMesaGLContext() { - this->destroyGLContext(); -} - -void SkMesaGLContext::destroyGLContext() { - if (fImage) { - sk_free(fImage); - fImage = NULL; - } - - if (fContext) { - OSMesaDestroyContext((OSMesaContext)fContext); - fContext = static_cast<Context>(NULL); - } -} - -static const GrGLint gBOGUS_SIZE = 16; - -const GrGLInterface* SkMesaGLContext::createGLContext(GrGLStandard forcedGpuAPI) { - if (kGLES_GrGLStandard == forcedGpuAPI) { - return NULL; - } /* Create an RGBA-mode context */ #if OSMESA_MAJOR_VERSION * 100 + OSMESA_MINOR_VERSION >= 305 @@ -50,7 +28,7 @@ const GrGLInterface* SkMesaGLContext::createGLContext(GrGLStandard forcedGpuAPI) if (!fContext) { SkDebugf("OSMesaCreateContext failed!\n"); this->destroyGLContext(); - return NULL; + return; } // Allocate the image buffer fImage = (GrGLubyte *) sk_malloc_throw(gBOGUS_SIZE * gBOGUS_SIZE * @@ -58,7 +36,7 @@ const GrGLInterface* SkMesaGLContext::createGLContext(GrGLStandard forcedGpuAPI) if (!fImage) { SkDebugf("Alloc image buffer failed!\n"); this->destroyGLContext(); - return NULL; + return; } // Bind the buffer to the context and make it current @@ -69,19 +47,42 @@ const GrGLInterface* SkMesaGLContext::createGLContext(GrGLStandard forcedGpuAPI) gBOGUS_SIZE)) { SkDebugf("OSMesaMakeCurrent failed!\n"); this->destroyGLContext(); - return NULL; + return; } - const GrGLInterface* interface = GrGLCreateMesaInterface(); - if (!interface) { + fGL.reset(GrGLCreateMesaInterface()); + if (NULL == fGL.get()) { SkDebugf("Could not create GL interface!\n"); this->destroyGLContext(); - return NULL; + return; } - return interface; + if (!fGL->validate()) { + SkDebugf("Could not validate GL interface!\n"); + this->destroyGLContext(); + return; + } } +SkMesaGLContext::~SkMesaGLContext() { + this->destroyGLContext(); +} + +void SkMesaGLContext::destroyGLContext() { + fGL.reset(NULL); + if (fImage) { + sk_free(fImage); + fImage = NULL; + } + + if (fContext) { + OSMesaDestroyContext((OSMesaContext)fContext); + fContext = static_cast<Context>(NULL); + } +} + + + void SkMesaGLContext::makeCurrent() const { if (fContext) { if (!OSMesaMakeCurrent((OSMesaContext)fContext, fImage, diff --git a/src/gpu/gl/nacl/SkCreatePlatformGLContext_nacl.cpp b/src/gpu/gl/nacl/SkCreatePlatformGLContext_nacl.cpp index 5e4b2e4917..5cb4423897 100644 --- a/src/gpu/gl/nacl/SkCreatePlatformGLContext_nacl.cpp +++ b/src/gpu/gl/nacl/SkCreatePlatformGLContext_nacl.cpp @@ -7,54 +7,8 @@ */ #include "gl/SkGLContext.h" -#include <GLES2/gl2.h> -#include <EGL/egl.h> - -namespace { -class NACLGLContext : public SkGLContext { -public: - SkGLContextEGL(); - - virtual ~NACLGLContext(); - - virtual void makeCurrent() const SK_OVERRIDE; - virtual void swapBuffers() const SK_OVERRIDE; -protected: - virtual const GrGLInterface* createGLContext(GrGLStandard forcedGpuAPI) SK_OVERRIDE; - virtual void destroyGLContext() SK_OVERRIDE; - -private: - EGLContext fContext; - EGLDisplay fDisplay; - EGLSurface fSurface; -}; - -NACLGLContext::NACLGLContext() - : fContext(NULL) - , fDisplay(NULL) -{ -} - -NACLGLContext::~NACLGLContext() { - this->destroyGLContext(); -} - -void NACLGLContext::destroyGLContext() { -} - -const GrGLInterface* NACLGLContext::createGLContext(GrGLStandard forcedGpuAPI) { +SkGLContext* SkCreatePlatformGLContext(GrGLStandard forcedGpuAPI) { return NULL; } -void NACLGLContext::makeCurrent() const { -} - -void NACLGLContext::swapBuffers() const { -} - -} // anonymous namespace - -NACLGLContext* SkCreatePlatformGLContext() { - return SkNEW(NACLGLContext); -} diff --git a/src/gpu/gl/win/SkCreatePlatformGLContext_win.cpp b/src/gpu/gl/win/SkCreatePlatformGLContext_win.cpp index d362556a4e..b53d46ced3 100644 --- a/src/gpu/gl/win/SkCreatePlatformGLContext_win.cpp +++ b/src/gpu/gl/win/SkCreatePlatformGLContext_win.cpp @@ -19,17 +19,14 @@ namespace { class WinGLContext : public SkGLContext { public: - WinGLContext(); - - virtual ~WinGLContext(); - + WinGLContext(GrGLStandard forcedGpuAPI); + virtual ~WinGLContext() SK_OVERRIDE; virtual void makeCurrent() const SK_OVERRIDE; virtual void swapBuffers() const SK_OVERRIDE; -protected: - virtual const GrGLInterface* createGLContext(GrGLStandard forcedGpuAPI) SK_OVERRIDE; - virtual void destroyGLContext() SK_OVERRIDE; private: + void destroyGLContext(); + HWND fWindow; HDC fDeviceContext; HGLRC fGlRenderContext; @@ -39,34 +36,11 @@ private: ATOM WinGLContext::gWC = 0; -WinGLContext::WinGLContext() +WinGLContext::WinGLContext(GrGLStandard forcedGpuAPI) : fWindow(NULL) , fDeviceContext(NULL) , fGlRenderContext(0) , fPbufferContext(NULL) { -} - -WinGLContext::~WinGLContext() { - this->destroyGLContext(); -} - -void WinGLContext::destroyGLContext() { - SkSafeSetNull(fPbufferContext); - if (fGlRenderContext) { - wglDeleteContext(fGlRenderContext); - fGlRenderContext = 0; - } - if (fWindow && fDeviceContext) { - ReleaseDC(fWindow, fDeviceContext); - fDeviceContext = 0; - } - if (fWindow) { - DestroyWindow(fWindow); - fWindow = 0; - } -} - -const GrGLInterface* WinGLContext::createGLContext(GrGLStandard forcedGpuAPI) { HINSTANCE hInstance = (HINSTANCE)GetModuleHandle(NULL); if (!gWC) { @@ -85,7 +59,7 @@ const GrGLInterface* WinGLContext::createGLContext(GrGLStandard forcedGpuAPI) { gWC = RegisterClass(&wc); if (!gWC) { SkDebugf("Could not register window class.\n"); - return NULL; + return; } } @@ -96,13 +70,13 @@ const GrGLInterface* WinGLContext::createGLContext(GrGLStandard forcedGpuAPI) { NULL, NULL, hInstance, NULL))) { SkDebugf("Could not create window.\n"); - return NULL; + return; } if (!(fDeviceContext = GetDC(fWindow))) { SkDebugf("Could not get device context.\n"); this->destroyGLContext(); - return NULL; + return; } // Requesting a Core profile would bar us from using NVPR. So we request // compatibility profile or GL ES. @@ -119,7 +93,7 @@ const GrGLInterface* WinGLContext::createGLContext(GrGLStandard forcedGpuAPI) { if (!(fGlRenderContext = SkCreateWGLContext(fDeviceContext, 0, contextType))) { SkDebugf("Could not create rendering context.\n"); this->destroyGLContext(); - return NULL; + return; } dc = fDeviceContext; glrc = fGlRenderContext; @@ -136,17 +110,41 @@ const GrGLInterface* WinGLContext::createGLContext(GrGLStandard forcedGpuAPI) { if (!(wglMakeCurrent(dc, glrc))) { SkDebugf("Could not set the context.\n"); this->destroyGLContext(); - return NULL; + return; } - const GrGLInterface* interface = GrGLCreateNativeInterface(); - if (NULL == interface) { + fGL.reset(GrGLCreateNativeInterface()); + if (NULL == fGL.get()) { SkDebugf("Could not create GL interface.\n"); this->destroyGLContext(); - return NULL; + return; } + if (!fGL->validate()) { + SkDebugf("Could not validate GL interface.\n"); + this->destroyGLContext(); + return; + } +} - return interface; +WinGLContext::~WinGLContext() { + this->destroyGLContext(); +} + +void WinGLContext::destroyGLContext() { + fGL.reset(NULL); + SkSafeSetNull(fPbufferContext); + if (fGlRenderContext) { + wglDeleteContext(fGlRenderContext); + fGlRenderContext = 0; + } + if (fWindow && fDeviceContext) { + ReleaseDC(fWindow, fDeviceContext); + fDeviceContext = 0; + } + if (fWindow) { + DestroyWindow(fWindow); + fWindow = 0; + } } void WinGLContext::makeCurrent() const { @@ -181,7 +179,12 @@ void WinGLContext::swapBuffers() const { } // anonymous namespace -SkGLContext* SkCreatePlatformGLContext() { - return SkNEW(WinGLContext); +SkGLContext* SkCreatePlatformGLContext(GrGLStandard forcedGpuAPI) { + WinGLContext* ctx = SkNEW_ARGS(WinGLContext, (forcedGpuAPI)); + if (!ctx->isValid()) { + SkDELETE(ctx); + return NULL; + } + return ctx; } |