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