michael@0: michael@0: /* michael@0: * Copyright 2013 Google Inc. michael@0: * michael@0: * Use of this source code is governed by a BSD-style license that can be michael@0: * found in the LICENSE file. michael@0: */ michael@0: #ifndef SkGLContextHelper_DEFINED michael@0: #define SkGLContextHelper_DEFINED michael@0: michael@0: #include "GrGLInterface.h" michael@0: michael@0: /** michael@0: * Create an offscreen opengl context with an RGBA8 / 8bit stencil FBO. michael@0: * Provides a GrGLInterface struct of function pointers for the context. michael@0: */ michael@0: michael@0: class SK_API SkGLContextHelper : public SkRefCnt { michael@0: public: michael@0: SK_DECLARE_INST_COUNT(SkGLContextHelper) michael@0: michael@0: SkGLContextHelper(); michael@0: virtual ~SkGLContextHelper(); michael@0: michael@0: /** michael@0: * Initializes the context and makes it current. michael@0: */ michael@0: bool init(const int width, const int height); michael@0: michael@0: int getFBOID() const { return fFBO; } michael@0: michael@0: const GrGLInterface* gl() const { return fGL; } michael@0: michael@0: virtual void makeCurrent() const = 0; michael@0: michael@0: /** michael@0: * The primary purpose of this function it to provide a means of scheduling michael@0: * work on the GPU (since all of the subclasses create primary buffers for michael@0: * testing that are small and not meant to be rendered to the screen). michael@0: * michael@0: * If the drawing surface provided by the platform is double buffered this michael@0: * call will cause the platform to swap which buffer is currently being michael@0: * targeted. If the current surface does not include a back buffer, this michael@0: * call has no effect. michael@0: */ michael@0: virtual void swapBuffers() const = 0; michael@0: michael@0: bool hasExtension(const char* extensionName) const { michael@0: SkASSERT(NULL != fGL); michael@0: return fGL->hasExtension(extensionName); michael@0: } michael@0: michael@0: protected: michael@0: /** michael@0: * Subclass implements this to make a GL context. The returned GrGLInterface michael@0: * should be populated with functions compatible with the context. The michael@0: * format and size of backbuffers does not matter since an FBO will be michael@0: * created. michael@0: */ michael@0: virtual const GrGLInterface* createGLContext() = 0; michael@0: michael@0: /** michael@0: * Subclass should destroy the underlying GL context. michael@0: */ michael@0: virtual void destroyGLContext() = 0; michael@0: michael@0: private: michael@0: GrGLuint fFBO; michael@0: GrGLuint fColorBufferID; michael@0: GrGLuint fDepthStencilBufferID; michael@0: const GrGLInterface* fGL; michael@0: michael@0: typedef SkRefCnt INHERITED; michael@0: }; michael@0: michael@0: /** michael@0: * Helper macros for using the GL context through the GrGLInterface. Example: michael@0: * SK_GL(glCtx, GenTextures(1, &texID)); michael@0: */ michael@0: #define SK_GL(ctx, X) (ctx).gl()->fFunctions.f ## X; \ michael@0: SkASSERT(GR_GL_NO_ERROR == (ctx).gl()->fFunctions.fGetError()) michael@0: #define SK_GL_RET(ctx, RET, X) (RET) = (ctx).gl()->fFunctions.f ## X; \ michael@0: SkASSERT(GR_GL_NO_ERROR == (ctx).gl()->fFunctions.fGetError()) michael@0: #define SK_GL_NOERRCHECK(ctx, X) (ctx).gl()->fFunctions.f ## X michael@0: #define SK_GL_RET_NOERRCHECK(ctx, RET, X) (RET) = (ctx).gl()->fFunctions.f ## X michael@0: michael@0: #endif