1/*
2 * Copyright 2012 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#ifndef GrGLUtil_DEFINED
9#define GrGLUtil_DEFINED
10
11#include "gl/GrGLInterface.h"
12#include "GrGLDefines.h"
13
14class SkMatrix;
15
16////////////////////////////////////////////////////////////////////////////////
17
18typedef uint32_t GrGLVersion;
19typedef uint32_t GrGLSLVersion;
20
21#define GR_GL_VER(major, minor) ((static_cast<int>(major) << 16) | \
22                                 static_cast<int>(minor))
23#define GR_GLSL_VER(major, minor) ((static_cast<int>(major) << 16) | \
24                                   static_cast<int>(minor))
25
26#define GR_GL_INVALID_VER GR_GL_VER(0, 0)
27#define GR_GLSL_INVALID_VER GR_GL_VER(0, 0)
28
29/**
30 * The Vendor and Renderer enum values are lazily updated as required.
31 */
32enum GrGLVendor {
33    kARM_GrGLVendor,
34    kImagination_GrGLVendor,
35    kIntel_GrGLVendor,
36    kQualcomm_GrGLVendor,
37
38    kOther_GrGLVendor
39};
40
41enum GrGLRenderer {
42    kTegra2_GrGLRenderer,
43    kTegra3_GrGLRenderer,
44
45    kOther_GrGLRenderer
46};
47
48////////////////////////////////////////////////////////////////////////////////
49
50/**
51 *  Some drivers want the var-int arg to be zero-initialized on input.
52 */
53#define GR_GL_INIT_ZERO     0
54#define GR_GL_GetIntegerv(gl, e, p)                                            \
55    do {                                                                       \
56        *(p) = GR_GL_INIT_ZERO;                                                \
57        GR_GL_CALL(gl, GetIntegerv(e, p));                                     \
58    } while (0)
59
60#define GR_GL_GetFramebufferAttachmentParameteriv(gl, t, a, pname, p)          \
61    do {                                                                       \
62        *(p) = GR_GL_INIT_ZERO;                                                \
63        GR_GL_CALL(gl, GetFramebufferAttachmentParameteriv(t, a, pname, p));   \
64    } while (0)
65
66#define GR_GL_GetRenderbufferParameteriv(gl, t, pname, p)                      \
67    do {                                                                       \
68        *(p) = GR_GL_INIT_ZERO;                                                \
69        GR_GL_CALL(gl, GetRenderbufferParameteriv(t, pname, p));               \
70    } while (0)
71#define GR_GL_GetTexLevelParameteriv(gl, t, l, pname, p)                       \
72    do {                                                                       \
73        *(p) = GR_GL_INIT_ZERO;                                                \
74        GR_GL_CALL(gl, GetTexLevelParameteriv(t, l, pname, p));                \
75    } while (0)
76
77////////////////////////////////////////////////////////////////////////////////
78
79/**
80 * Helpers for glGetString()
81 */
82
83// these variants assume caller already has a string from glGetString()
84GrGLVersion GrGLGetVersionFromString(const char* versionString);
85GrGLStandard GrGLGetStandardInUseFromString(const char* versionString);
86GrGLSLVersion GrGLGetGLSLVersionFromString(const char* versionString);
87bool GrGLIsMesaFromVersionString(const char* versionString);
88GrGLVendor GrGLGetVendorFromString(const char* vendorString);
89GrGLRenderer GrGLGetRendererFromString(const char* rendererString);
90bool GrGLIsChromiumFromRendererString(const char* rendererString);
91
92// these variants call glGetString()
93GrGLVersion GrGLGetVersion(const GrGLInterface*);
94GrGLSLVersion GrGLGetGLSLVersion(const GrGLInterface*);
95GrGLVendor GrGLGetVendor(const GrGLInterface*);
96GrGLRenderer GrGLGetRenderer(const GrGLInterface*);
97
98
99/**
100 * Helpers for glGetError()
101 */
102
103void GrGLCheckErr(const GrGLInterface* gl,
104                  const char* location,
105                  const char* call);
106
107void GrGLClearErr(const GrGLInterface* gl);
108
109/**
110 * Helper for converting SkMatrix to a column-major GL float array
111 */
112template<int MatrixSize> void GrGLGetMatrix(GrGLfloat* dest, const SkMatrix& src);
113
114////////////////////////////////////////////////////////////////////////////////
115
116/**
117 * Macros for using GrGLInterface to make GL calls
118 */
119
120// internal macro to conditionally call glGetError based on compile-time and
121// run-time flags.
122#if GR_GL_CHECK_ERROR
123    extern bool gCheckErrorGL;
124    #define GR_GL_CHECK_ERROR_IMPL(IFACE, X)                    \
125        if (gCheckErrorGL)                                      \
126            GrGLCheckErr(IFACE, GR_FILE_AND_LINE_STR, #X)
127#else
128    #define GR_GL_CHECK_ERROR_IMPL(IFACE, X)
129#endif
130
131// internal macro to conditionally log the gl call using GrPrintf based on
132// compile-time and run-time flags.
133#if GR_GL_LOG_CALLS
134    extern bool gLogCallsGL;
135    #define GR_GL_LOG_CALLS_IMPL(X)                             \
136        if (gLogCallsGL)                                        \
137            GrPrintf(GR_FILE_AND_LINE_STR "GL: " #X "\n")
138#else
139    #define GR_GL_LOG_CALLS_IMPL(X)
140#endif
141
142// internal macro that does the per-GL-call callback (if necessary)
143#if GR_GL_PER_GL_FUNC_CALLBACK
144    #define GR_GL_CALLBACK_IMPL(IFACE) (IFACE)->fCallback(IFACE)
145#else
146    #define GR_GL_CALLBACK_IMPL(IFACE)
147#endif
148
149// makes a GL call on the interface and does any error checking and logging
150#define GR_GL_CALL(IFACE, X)                                    \
151    do {                                                        \
152        GR_GL_CALL_NOERRCHECK(IFACE, X);                        \
153        GR_GL_CHECK_ERROR_IMPL(IFACE, X);                       \
154    } while (false)
155
156// Variant of above that always skips the error check. This is useful when
157// the caller wants to do its own glGetError() call and examine the error value.
158#define GR_GL_CALL_NOERRCHECK(IFACE, X)                         \
159    do {                                                        \
160        GR_GL_CALLBACK_IMPL(IFACE);                             \
161        (IFACE)->fFunctions.f##X;                               \
162        GR_GL_LOG_CALLS_IMPL(X);                                \
163    } while (false)
164
165// same as GR_GL_CALL but stores the return value of the gl call in RET
166#define GR_GL_CALL_RET(IFACE, RET, X)                           \
167    do {                                                        \
168        GR_GL_CALL_RET_NOERRCHECK(IFACE, RET, X);               \
169        GR_GL_CHECK_ERROR_IMPL(IFACE, X);                       \
170    } while (false)
171
172// same as GR_GL_CALL_RET but always skips the error check.
173#define GR_GL_CALL_RET_NOERRCHECK(IFACE, RET, X)                \
174    do {                                                        \
175        GR_GL_CALLBACK_IMPL(IFACE);                             \
176        (RET) = (IFACE)->fFunctions.f##X;                       \
177        GR_GL_LOG_CALLS_IMPL(X);                                \
178    } while (false)
179
180// call glGetError without doing a redundant error check or logging.
181#define GR_GL_GET_ERROR(IFACE) (IFACE)->fFunctions.fGetError()
182
183#endif
184