michael@0: /* michael@0: * Copyright 2012 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 GrGLUtil_DEFINED michael@0: #define GrGLUtil_DEFINED michael@0: michael@0: #include "gl/GrGLInterface.h" michael@0: #include "GrGLDefines.h" michael@0: michael@0: class SkMatrix; michael@0: michael@0: //////////////////////////////////////////////////////////////////////////////// michael@0: michael@0: typedef uint32_t GrGLVersion; michael@0: typedef uint32_t GrGLSLVersion; michael@0: michael@0: /** michael@0: * The Vendor and Renderer enum values are lazily updated as required. michael@0: */ michael@0: enum GrGLVendor { michael@0: kARM_GrGLVendor, michael@0: kImagination_GrGLVendor, michael@0: kIntel_GrGLVendor, michael@0: kQualcomm_GrGLVendor, michael@0: michael@0: kOther_GrGLVendor michael@0: }; michael@0: michael@0: enum GrGLRenderer { michael@0: kTegra2_GrGLRenderer, michael@0: kTegra3_GrGLRenderer, michael@0: michael@0: kOther_GrGLRenderer michael@0: }; michael@0: michael@0: #define GR_GL_VER(major, minor) ((static_cast(major) << 16) | \ michael@0: static_cast(minor)) michael@0: #define GR_GLSL_VER(major, minor) ((static_cast(major) << 16) | \ michael@0: static_cast(minor)) michael@0: michael@0: //////////////////////////////////////////////////////////////////////////////// michael@0: michael@0: /** michael@0: * Some drivers want the var-int arg to be zero-initialized on input. michael@0: */ michael@0: #define GR_GL_INIT_ZERO 0 michael@0: #define GR_GL_GetIntegerv(gl, e, p) \ michael@0: do { \ michael@0: *(p) = GR_GL_INIT_ZERO; \ michael@0: GR_GL_CALL(gl, GetIntegerv(e, p)); \ michael@0: } while (0) michael@0: michael@0: #define GR_GL_GetFramebufferAttachmentParameteriv(gl, t, a, pname, p) \ michael@0: do { \ michael@0: *(p) = GR_GL_INIT_ZERO; \ michael@0: GR_GL_CALL(gl, GetFramebufferAttachmentParameteriv(t, a, pname, p)); \ michael@0: } while (0) michael@0: michael@0: #define GR_GL_GetRenderbufferParameteriv(gl, t, pname, p) \ michael@0: do { \ michael@0: *(p) = GR_GL_INIT_ZERO; \ michael@0: GR_GL_CALL(gl, GetRenderbufferParameteriv(t, pname, p)); \ michael@0: } while (0) michael@0: #define GR_GL_GetTexLevelParameteriv(gl, t, l, pname, p) \ michael@0: do { \ michael@0: *(p) = GR_GL_INIT_ZERO; \ michael@0: GR_GL_CALL(gl, GetTexLevelParameteriv(t, l, pname, p)); \ michael@0: } while (0) michael@0: michael@0: //////////////////////////////////////////////////////////////////////////////// michael@0: michael@0: /** michael@0: * Helpers for glGetString() michael@0: */ michael@0: michael@0: // these variants assume caller already has a string from glGetString() michael@0: GrGLVersion GrGLGetVersionFromString(const char* versionString); michael@0: GrGLStandard GrGLGetStandardInUseFromString(const char* versionString); michael@0: GrGLSLVersion GrGLGetGLSLVersionFromString(const char* versionString); michael@0: bool GrGLIsMesaFromVersionString(const char* versionString); michael@0: GrGLVendor GrGLGetVendorFromString(const char* vendorString); michael@0: GrGLRenderer GrGLGetRendererFromString(const char* rendererString); michael@0: bool GrGLIsChromiumFromRendererString(const char* rendererString); michael@0: michael@0: // these variants call glGetString() michael@0: GrGLVersion GrGLGetVersion(const GrGLInterface*); michael@0: GrGLSLVersion GrGLGetGLSLVersion(const GrGLInterface*); michael@0: GrGLVendor GrGLGetVendor(const GrGLInterface*); michael@0: GrGLRenderer GrGLGetRenderer(const GrGLInterface*); michael@0: michael@0: michael@0: /** michael@0: * Helpers for glGetError() michael@0: */ michael@0: michael@0: void GrGLCheckErr(const GrGLInterface* gl, michael@0: const char* location, michael@0: const char* call); michael@0: michael@0: void GrGLClearErr(const GrGLInterface* gl); michael@0: michael@0: /** michael@0: * Helper for converting SkMatrix to a column-major GL float array michael@0: */ michael@0: template void GrGLGetMatrix(GrGLfloat* dest, const SkMatrix& src); michael@0: michael@0: //////////////////////////////////////////////////////////////////////////////// michael@0: michael@0: /** michael@0: * Macros for using GrGLInterface to make GL calls michael@0: */ michael@0: michael@0: // internal macro to conditionally call glGetError based on compile-time and michael@0: // run-time flags. michael@0: #if GR_GL_CHECK_ERROR michael@0: extern bool gCheckErrorGL; michael@0: #define GR_GL_CHECK_ERROR_IMPL(IFACE, X) \ michael@0: if (gCheckErrorGL) \ michael@0: GrGLCheckErr(IFACE, GR_FILE_AND_LINE_STR, #X) michael@0: #else michael@0: #define GR_GL_CHECK_ERROR_IMPL(IFACE, X) michael@0: #endif michael@0: michael@0: // internal macro to conditionally log the gl call using GrPrintf based on michael@0: // compile-time and run-time flags. michael@0: #if GR_GL_LOG_CALLS michael@0: extern bool gLogCallsGL; michael@0: #define GR_GL_LOG_CALLS_IMPL(X) \ michael@0: if (gLogCallsGL) \ michael@0: GrPrintf(GR_FILE_AND_LINE_STR "GL: " #X "\n") michael@0: #else michael@0: #define GR_GL_LOG_CALLS_IMPL(X) michael@0: #endif michael@0: michael@0: // internal macro that does the per-GL-call callback (if necessary) michael@0: #if GR_GL_PER_GL_FUNC_CALLBACK michael@0: #define GR_GL_CALLBACK_IMPL(IFACE) (IFACE)->fCallback(IFACE) michael@0: #else michael@0: #define GR_GL_CALLBACK_IMPL(IFACE) michael@0: #endif michael@0: michael@0: // makes a GL call on the interface and does any error checking and logging michael@0: #define GR_GL_CALL(IFACE, X) \ michael@0: do { \ michael@0: GR_GL_CALL_NOERRCHECK(IFACE, X); \ michael@0: GR_GL_CHECK_ERROR_IMPL(IFACE, X); \ michael@0: } while (false) michael@0: michael@0: // Variant of above that always skips the error check. This is useful when michael@0: // the caller wants to do its own glGetError() call and examine the error value. michael@0: #define GR_GL_CALL_NOERRCHECK(IFACE, X) \ michael@0: do { \ michael@0: GR_GL_CALLBACK_IMPL(IFACE); \ michael@0: (IFACE)->fFunctions.f##X; \ michael@0: GR_GL_LOG_CALLS_IMPL(X); \ michael@0: } while (false) michael@0: michael@0: // same as GR_GL_CALL but stores the return value of the gl call in RET michael@0: #define GR_GL_CALL_RET(IFACE, RET, X) \ michael@0: do { \ michael@0: GR_GL_CALL_RET_NOERRCHECK(IFACE, RET, X); \ michael@0: GR_GL_CHECK_ERROR_IMPL(IFACE, X); \ michael@0: } while (false) michael@0: michael@0: // same as GR_GL_CALL_RET but always skips the error check. michael@0: #define GR_GL_CALL_RET_NOERRCHECK(IFACE, RET, X) \ michael@0: do { \ michael@0: GR_GL_CALLBACK_IMPL(IFACE); \ michael@0: (RET) = (IFACE)->fFunctions.f##X; \ michael@0: GR_GL_LOG_CALLS_IMPL(X); \ michael@0: } while (false) michael@0: michael@0: // call glGetError without doing a redundant error check or logging. michael@0: #define GR_GL_GET_ERROR(IFACE) (IFACE)->fFunctions.fGetError() michael@0: michael@0: #endif