michael@0: /* michael@0: * Copyright 2011 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: michael@0: #ifndef GrGLInterface_DEFINED michael@0: #define GrGLInterface_DEFINED michael@0: michael@0: #include "GrGLFunctions.h" michael@0: #include "GrGLExtensions.h" michael@0: #include "SkRefCnt.h" michael@0: michael@0: //////////////////////////////////////////////////////////////////////////////// michael@0: michael@0: /** michael@0: * Rather than depend on platform-specific GL headers and libraries, we require michael@0: * the client to provide a struct of GL function pointers. This struct can be michael@0: * specified per-GrContext as a parameter to GrContext::Create. If NULL is michael@0: * passed to Create then a "default" GL interface is created. If the default is michael@0: * also NULL GrContext creation will fail. michael@0: * michael@0: * The default interface is returned by GrGLDefaultInterface. This function's michael@0: * implementation is platform-specific. Several have been provided, along with michael@0: * an implementation that simply returns NULL. michael@0: * michael@0: * By defining GR_GL_PER_GL_CALL_IFACE_CALLBACK to 1 the client can specify a michael@0: * callback function that will be called prior to each GL function call. See michael@0: * comments in GrGLConfig.h michael@0: */ michael@0: michael@0: struct GrGLInterface; michael@0: michael@0: const GrGLInterface* GrGLDefaultInterface(); michael@0: michael@0: /** michael@0: * Creates a GrGLInterface for a "native" GL context (e.g. WGL on windows, michael@0: * GLX on linux, AGL on Mac). The interface is only valid for the GL context michael@0: * that is current when the interface is created. michael@0: */ michael@0: const GrGLInterface* GrGLCreateNativeInterface(); michael@0: michael@0: #if SK_MESA michael@0: /** michael@0: * Creates a GrGLInterface for an OSMesa context. michael@0: */ michael@0: const GrGLInterface* GrGLCreateMesaInterface(); michael@0: #endif michael@0: michael@0: #if SK_ANGLE michael@0: /** michael@0: * Creates a GrGLInterface for an ANGLE context. michael@0: */ michael@0: const GrGLInterface* GrGLCreateANGLEInterface(); michael@0: #endif michael@0: michael@0: /** michael@0: * Creates a null GrGLInterface that doesn't draw anything. Used for measuring michael@0: * CPU overhead. michael@0: */ michael@0: const SK_API GrGLInterface* GrGLCreateNullInterface(); michael@0: michael@0: /** michael@0: * Creates a debugging GrGLInterface that doesn't draw anything. Used for michael@0: * finding memory leaks and invalid memory accesses. michael@0: */ michael@0: const GrGLInterface* GrGLCreateDebugInterface(); michael@0: michael@0: #if GR_GL_PER_GL_FUNC_CALLBACK michael@0: typedef void (*GrGLInterfaceCallbackProc)(const GrGLInterface*); michael@0: typedef intptr_t GrGLInterfaceCallbackData; michael@0: #endif michael@0: michael@0: /** Function that returns a new interface identical to "interface" but without support for michael@0: GL_NV_path_rendering. */ michael@0: const GrGLInterface* GrGLInterfaceRemoveNVPR(const GrGLInterface*); michael@0: michael@0: /** Function that returns a new interface identical to "interface" but with support for michael@0: test version of GL_EXT_debug_marker. */ michael@0: const GrGLInterface* GrGLInterfaceAddTestDebugMarker(const GrGLInterface*, michael@0: GrGLInsertEventMarkerProc insertEventMarkerFn, michael@0: GrGLPushGroupMarkerProc pushGroupMarkerFn, michael@0: GrGLPopGroupMarkerProc popGroupMarkerFn); michael@0: michael@0: /** michael@0: * GrContext uses the following interface to make all calls into OpenGL. When a michael@0: * GrContext is created it is given a GrGLInterface. The interface's function michael@0: * pointers must be valid for the OpenGL context associated with the GrContext. michael@0: * On some platforms, such as Windows, function pointers for OpenGL extensions michael@0: * may vary between OpenGL contexts. So the caller must be careful to use a michael@0: * GrGLInterface initialized for the correct context. All functions that should michael@0: * be available based on the OpenGL's version and extension string must be michael@0: * non-NULL or GrContext creation will fail. This can be tested with the michael@0: * validate() method when the OpenGL context has been made current. michael@0: */ michael@0: struct SK_API GrGLInterface : public SkRefCnt { michael@0: private: michael@0: // simple wrapper class that exists only to initialize a pointer to NULL michael@0: template class GLPtr { michael@0: public: michael@0: GLPtr() : fPtr(NULL) {} michael@0: GLPtr operator=(FNPTR_TYPE ptr) { fPtr = ptr; return *this; } michael@0: operator FNPTR_TYPE() const { return fPtr; } michael@0: private: michael@0: FNPTR_TYPE fPtr; michael@0: }; michael@0: michael@0: // This is a temporary workaround to keep Chromium's GrGLInterface factories compiling until michael@0: // they're updated to use the Functions struct. michael@0: template class GLPtrAlias { michael@0: public: michael@0: GLPtrAlias(GLPtr* base) : fBase(base) {} michael@0: void operator=(FNPTR_TYPE ptr) { *fBase = ptr; } michael@0: private: michael@0: GLPtr* fBase; michael@0: }; michael@0: michael@0: typedef SkRefCnt INHERITED; michael@0: michael@0: public: michael@0: SK_DECLARE_INST_COUNT(GrGLInterface) michael@0: michael@0: GrGLInterface(); michael@0: michael@0: static GrGLInterface* NewClone(const GrGLInterface*); michael@0: michael@0: // Validates that the GrGLInterface supports its advertised standard. This means the necessary michael@0: // function pointers have been initialized for both the GL version and any advertised michael@0: // extensions. michael@0: bool validate() const; michael@0: michael@0: // Indicates the type of GL implementation michael@0: union { michael@0: GrGLStandard fStandard; michael@0: GrGLStandard fBindingsExported; // Legacy name, will be remove when Chromium is updated. michael@0: }; michael@0: michael@0: GrGLExtensions fExtensions; michael@0: michael@0: bool hasExtension(const char ext[]) const { return fExtensions.has(ext); } michael@0: michael@0: /** michael@0: * The function pointers are in a struct so that we can have a compiler generated assignment michael@0: * operator. michael@0: */ michael@0: struct Functions { michael@0: GLPtr fActiveTexture; michael@0: GLPtr fAttachShader; michael@0: GLPtr fBeginQuery; michael@0: GLPtr fBindAttribLocation; michael@0: GLPtr fBindBuffer; michael@0: GLPtr fBindFragDataLocation; michael@0: GLPtr fBindFragDataLocationIndexed; michael@0: GLPtr fBindFramebuffer; michael@0: GLPtr fBindRenderbuffer; michael@0: GLPtr fBindTexture; michael@0: GLPtr fBindVertexArray; michael@0: GLPtr fBlendColor; michael@0: GLPtr fBlendFunc; michael@0: GLPtr fBlitFramebuffer; michael@0: GLPtr fBufferData; michael@0: GLPtr fBufferSubData; michael@0: GLPtr fCheckFramebufferStatus; michael@0: GLPtr fClear; michael@0: GLPtr fClearColor; michael@0: GLPtr fClearStencil; michael@0: GLPtr fColorMask; michael@0: GLPtr fCompileShader; michael@0: GLPtr fCompressedTexImage2D; michael@0: GLPtr fCopyTexSubImage2D; michael@0: GLPtr fCreateProgram; michael@0: GLPtr fCreateShader; michael@0: GLPtr fCullFace; michael@0: GLPtr fDeleteBuffers; michael@0: GLPtr fDeleteFramebuffers; michael@0: GLPtr fDeleteProgram; michael@0: GLPtr fDeleteQueries; michael@0: GLPtr fDeleteRenderbuffers; michael@0: GLPtr fDeleteShader; michael@0: GLPtr fDeleteTextures; michael@0: GLPtr fDeleteVertexArrays; michael@0: GLPtr fDepthMask; michael@0: GLPtr fDisable; michael@0: GLPtr fDisableVertexAttribArray; michael@0: GLPtr fDrawArrays; michael@0: GLPtr fDrawBuffer; michael@0: GLPtr fDrawBuffers; michael@0: GLPtr fDrawElements; michael@0: GLPtr fEnable; michael@0: GLPtr fEnableVertexAttribArray; michael@0: GLPtr fEndQuery; michael@0: GLPtr fFinish; michael@0: GLPtr fFlush; michael@0: GLPtr fFramebufferRenderbuffer; michael@0: GLPtr fFramebufferTexture2D; michael@0: GLPtr fFramebufferTexture2DMultisample; michael@0: GLPtr fFrontFace; michael@0: GLPtr fGenBuffers; michael@0: GLPtr fGenFramebuffers; michael@0: GLPtr fGenerateMipmap; michael@0: GLPtr fGenQueries; michael@0: GLPtr fGenRenderbuffers; michael@0: GLPtr fGenTextures; michael@0: GLPtr fGenVertexArrays; michael@0: GLPtr fGetBufferParameteriv; michael@0: GLPtr fGetError; michael@0: GLPtr fGetFramebufferAttachmentParameteriv; michael@0: GLPtr fGetIntegerv; michael@0: GLPtr fGetQueryObjecti64v; michael@0: GLPtr fGetQueryObjectiv; michael@0: GLPtr fGetQueryObjectui64v; michael@0: GLPtr fGetQueryObjectuiv; michael@0: GLPtr fGetQueryiv; michael@0: GLPtr fGetProgramInfoLog; michael@0: GLPtr fGetProgramiv; michael@0: GLPtr fGetRenderbufferParameteriv; michael@0: GLPtr fGetShaderInfoLog; michael@0: GLPtr fGetShaderiv; michael@0: GLPtr fGetString; michael@0: GLPtr fGetStringi; michael@0: GLPtr fGetTexLevelParameteriv; michael@0: GLPtr fGetUniformLocation; michael@0: GLPtr fInsertEventMarker; michael@0: GLPtr fLineWidth; michael@0: GLPtr fLinkProgram; michael@0: GLPtr fLoadIdentity; michael@0: GLPtr fLoadMatrixf; michael@0: GLPtr fMapBuffer; michael@0: GLPtr fMatrixMode; michael@0: GLPtr fPixelStorei; michael@0: GLPtr fPopGroupMarker; michael@0: GLPtr fPushGroupMarker; michael@0: GLPtr fQueryCounter; michael@0: GLPtr fReadBuffer; michael@0: GLPtr fReadPixels; michael@0: GLPtr fRenderbufferStorage; michael@0: michael@0: // On OpenGL ES there are multiple incompatible extensions that add support for MSAA michael@0: // and ES3 adds MSAA support to the standard. On an ES3 driver we may still use the michael@0: // older extensions for performance reasons or due to ES3 driver bugs. We want the function michael@0: // that creates the GrGLInterface to provide all available functions and internally michael@0: // we will select among them. They all have a method called glRenderbufferStorageMultisample*. michael@0: // So we have separate function pointers for GL_IMG/EXT_multisampled_to_texture, michael@0: // GL_CHROMIUM/ANGLE_framebuffer_multisample/ES3, and GL_APPLE_framebuffer_multisample michael@0: // variations. michael@0: // michael@0: // If a driver supports multiple GL_ARB_framebuffer_multisample-style extensions then we will michael@0: // assume the function pointers for the standard (or equivalent GL_ARB) version have michael@0: // been preferred over GL_EXT, GL_CHROMIUM, or GL_ANGLE variations that have reduced michael@0: // functionality. michael@0: michael@0: // GL_EXT_multisampled_render_to_texture (preferred) or GL_IMG_multisampled_render_to_texture michael@0: GLPtr fRenderbufferStorageMultisampleES2EXT; michael@0: // GL_APPLE_framebuffer_multisample michael@0: GLPtr fRenderbufferStorageMultisampleES2APPLE; michael@0: michael@0: // This is used to store the pointer for GL_ARB/EXT/ANGLE/CHROMIUM_framebuffer_multisample or michael@0: // the standard function in ES3+ or GL 3.0+. michael@0: GLPtr fRenderbufferStorageMultisample; michael@0: michael@0: // Pointer to BindUniformLocationCHROMIUM from the GL_CHROMIUM_bind_uniform_location extension. michael@0: GLPtr fBindUniformLocation; michael@0: michael@0: GLPtr fResolveMultisampleFramebuffer; michael@0: GLPtr fScissor; michael@0: GLPtr fShaderSource; michael@0: GLPtr fStencilFunc; michael@0: GLPtr fStencilFuncSeparate; michael@0: GLPtr fStencilMask; michael@0: GLPtr fStencilMaskSeparate; michael@0: GLPtr fStencilOp; michael@0: GLPtr fStencilOpSeparate; michael@0: GLPtr fTexGenfv; michael@0: GLPtr fTexGeni; michael@0: GLPtr fTexImage2D; michael@0: GLPtr fTexParameteri; michael@0: GLPtr fTexParameteriv; michael@0: GLPtr fTexSubImage2D; michael@0: GLPtr fTexStorage2D; michael@0: GLPtr fDiscardFramebuffer; michael@0: GLPtr fUniform1f; michael@0: GLPtr fUniform1i; michael@0: GLPtr fUniform1fv; michael@0: GLPtr fUniform1iv; michael@0: GLPtr fUniform2f; michael@0: GLPtr fUniform2i; michael@0: GLPtr fUniform2fv; michael@0: GLPtr fUniform2iv; michael@0: GLPtr fUniform3f; michael@0: GLPtr fUniform3i; michael@0: GLPtr fUniform3fv; michael@0: GLPtr fUniform3iv; michael@0: GLPtr fUniform4f; michael@0: GLPtr fUniform4i; michael@0: GLPtr fUniform4fv; michael@0: GLPtr fUniform4iv; michael@0: GLPtr fUniformMatrix2fv; michael@0: GLPtr fUniformMatrix3fv; michael@0: GLPtr fUniformMatrix4fv; michael@0: GLPtr fUnmapBuffer; michael@0: GLPtr fUseProgram; michael@0: GLPtr fVertexAttrib4fv; michael@0: GLPtr fVertexAttribPointer; michael@0: GLPtr fViewport; michael@0: michael@0: // Experimental: Functions for GL_NV_path_rendering. These will be michael@0: // alphabetized with the above functions once this is fully supported michael@0: // (and functions we are unlikely to use will possibly be omitted). michael@0: GLPtr fPathCommands; michael@0: GLPtr fPathCoords; michael@0: GLPtr fPathSubCommands; michael@0: GLPtr fPathSubCoords; michael@0: GLPtr fPathString; michael@0: GLPtr fPathGlyphs; michael@0: GLPtr fPathGlyphRange; michael@0: GLPtr fWeightPaths; michael@0: GLPtr fCopyPath; michael@0: GLPtr fInterpolatePaths; michael@0: GLPtr fTransformPath; michael@0: GLPtr fPathParameteriv; michael@0: GLPtr fPathParameteri; michael@0: GLPtr fPathParameterfv; michael@0: GLPtr fPathParameterf; michael@0: GLPtr fPathDashArray; michael@0: GLPtr fGenPaths; michael@0: GLPtr fDeletePaths; michael@0: GLPtr fIsPath; michael@0: GLPtr fPathStencilFunc; michael@0: GLPtr fPathStencilDepthOffset; michael@0: GLPtr fStencilFillPath; michael@0: GLPtr fStencilStrokePath; michael@0: GLPtr fStencilFillPathInstanced; michael@0: GLPtr fStencilStrokePathInstanced; michael@0: GLPtr fPathCoverDepthFunc; michael@0: GLPtr fPathColorGen; michael@0: GLPtr fPathTexGen; michael@0: GLPtr fPathFogGen; michael@0: GLPtr fCoverFillPath; michael@0: GLPtr fCoverStrokePath; michael@0: GLPtr fCoverFillPathInstanced; michael@0: GLPtr fCoverStrokePathInstanced; michael@0: GLPtr fGetPathParameteriv; michael@0: GLPtr fGetPathParameterfv; michael@0: GLPtr fGetPathCommands; michael@0: GLPtr fGetPathCoords; michael@0: GLPtr fGetPathDashArray; michael@0: GLPtr fGetPathMetrics; michael@0: GLPtr fGetPathMetricRange; michael@0: GLPtr fGetPathSpacing; michael@0: GLPtr fGetPathColorGeniv; michael@0: GLPtr fGetPathColorGenfv; michael@0: GLPtr fGetPathTexGeniv; michael@0: GLPtr fGetPathTexGenfv; michael@0: GLPtr fIsPointInFillPath; michael@0: GLPtr fIsPointInStrokePath; michael@0: GLPtr fGetPathLength; michael@0: GLPtr fPointAlongPath; michael@0: } fFunctions; michael@0: michael@0: // Per-GL func callback michael@0: #if GR_GL_PER_GL_FUNC_CALLBACK michael@0: GrGLInterfaceCallbackProc fCallback; michael@0: GrGLInterfaceCallbackData fCallbackData; michael@0: #endif michael@0: }; michael@0: michael@0: #endif