GrGLInterface.cpp revision 096defe64d408e54474fe19f418c95bf1a554fc7
1/* 2 * Copyright 2011 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 9#include "gl/GrGLInterface.h" 10#include "gl/GrGLExtensions.h" 11#include "gl/GrGLUtil.h" 12 13#include <stdio.h> 14 15SK_DEFINE_INST_COUNT(GrGLInterface) 16 17#if GR_GL_PER_GL_FUNC_CALLBACK 18namespace { 19void GrGLDefaultInterfaceCallback(const GrGLInterface*) {} 20} 21#endif 22 23GrGLInterface::GrGLInterface() { 24 fBindingsExported = kNone_GrGLBinding; 25 26#if GR_GL_PER_GL_FUNC_CALLBACK 27 fCallback = GrGLDefaultInterfaceCallback; 28 fCallbackData = 0; 29#endif 30} 31 32bool GrGLInterface::validate(GrGLBinding binding) const { 33 34 // kNone must be 0 so that the check we're about to do can never succeed if 35 // binding == kNone. 36 GR_STATIC_ASSERT(kNone_GrGLBinding == 0); 37 38 if (0 == (binding & fBindingsExported)) { 39 return false; 40 } 41 42 GrGLExtensions extensions; 43 if (!extensions.init(binding, this)) { 44 return false; 45 } 46 47 // functions that are always required 48 if (NULL == fActiveTexture || 49 NULL == fAttachShader || 50 NULL == fBindAttribLocation || 51 NULL == fBindBuffer || 52 NULL == fBindTexture || 53 NULL == fBlendFunc || 54 NULL == fBlendColor || // -> GL >= 1.4, ES >= 2.0 or extension 55 NULL == fBufferData || 56 NULL == fBufferSubData || 57 NULL == fClear || 58 NULL == fClearColor || 59 NULL == fClearStencil || 60 NULL == fColorMask || 61 NULL == fCompileShader || 62 NULL == fCreateProgram || 63 NULL == fCreateShader || 64 NULL == fCullFace || 65 NULL == fDeleteBuffers || 66 NULL == fDeleteProgram || 67 NULL == fDeleteShader || 68 NULL == fDeleteTextures || 69 NULL == fDepthMask || 70 NULL == fDisable || 71 NULL == fDisableVertexAttribArray || 72 NULL == fDrawArrays || 73 NULL == fDrawElements || 74 NULL == fEnable || 75 NULL == fEnableVertexAttribArray || 76 NULL == fFrontFace || 77 NULL == fGenBuffers || 78 NULL == fGenTextures || 79 NULL == fGetBufferParameteriv || 80 NULL == fGetError || 81 NULL == fGetIntegerv || 82 NULL == fGetProgramInfoLog || 83 NULL == fGetProgramiv || 84 NULL == fGetShaderInfoLog || 85 NULL == fGetShaderiv || 86 NULL == fGetString || 87 NULL == fGetUniformLocation || 88 NULL == fLinkProgram || 89 NULL == fPixelStorei || 90 NULL == fReadPixels || 91 NULL == fScissor || 92 NULL == fShaderSource || 93 NULL == fStencilFunc || 94 NULL == fStencilMask || 95 NULL == fStencilOp || 96 NULL == fTexImage2D || 97 NULL == fTexParameteri || 98 NULL == fTexParameteriv || 99 NULL == fTexSubImage2D || 100 NULL == fUniform1f || 101 NULL == fUniform1i || 102 NULL == fUniform1fv || 103 NULL == fUniform1iv || 104 NULL == fUniform2f || 105 NULL == fUniform2i || 106 NULL == fUniform2fv || 107 NULL == fUniform2iv || 108 NULL == fUniform3f || 109 NULL == fUniform3i || 110 NULL == fUniform3fv || 111 NULL == fUniform3iv || 112 NULL == fUniform4f || 113 NULL == fUniform4i || 114 NULL == fUniform4fv || 115 NULL == fUniform4iv || 116 NULL == fUniformMatrix2fv || 117 NULL == fUniformMatrix3fv || 118 NULL == fUniformMatrix4fv || 119 NULL == fUseProgram || 120 NULL == fVertexAttrib4fv || 121 NULL == fVertexAttribPointer || 122 NULL == fViewport || 123 NULL == fBindFramebuffer || 124 NULL == fBindRenderbuffer || 125 NULL == fCheckFramebufferStatus || 126 NULL == fDeleteFramebuffers || 127 NULL == fDeleteRenderbuffers || 128 NULL == fFinish || 129 NULL == fFlush || 130 NULL == fFramebufferRenderbuffer || 131 NULL == fFramebufferTexture2D || 132 NULL == fGetFramebufferAttachmentParameteriv || 133 NULL == fGetRenderbufferParameteriv || 134 NULL == fGenFramebuffers || 135 NULL == fGenRenderbuffers || 136 NULL == fRenderbufferStorage) { 137 return false; 138 } 139 140 GrGLVersion glVer = GrGLGetVersion(this); 141 142 // Now check that baseline ES/Desktop fns not covered above are present 143 // and that we have fn pointers for any advertised extensions that we will 144 // try to use. 145 146 // these functions are part of ES2, we assume they are available 147 // On the desktop we assume they are available if the extension 148 // is present or GL version is high enough. 149 if (kES2_GrGLBinding == binding) { 150 if (NULL == fStencilFuncSeparate || 151 NULL == fStencilMaskSeparate || 152 NULL == fStencilOpSeparate) { 153 return false; 154 } 155 } else if (kDesktop_GrGLBinding == binding) { 156 157 if (glVer >= GR_GL_VER(2,0)) { 158 if (NULL == fStencilFuncSeparate || 159 NULL == fStencilMaskSeparate || 160 NULL == fStencilOpSeparate) { 161 return false; 162 } 163 } 164 if (glVer >= GR_GL_VER(3,0) && NULL == fBindFragDataLocation) { 165 return false; 166 } 167 if (glVer >= GR_GL_VER(2,0) || extensions.has("GL_ARB_draw_buffers")) { 168 if (NULL == fDrawBuffers) { 169 return false; 170 } 171 } 172 173 if (glVer >= GR_GL_VER(1,5) || extensions.has("GL_ARB_occlusion_query")) { 174 if (NULL == fGenQueries || 175 NULL == fDeleteQueries || 176 NULL == fBeginQuery || 177 NULL == fEndQuery || 178 NULL == fGetQueryiv || 179 NULL == fGetQueryObjectiv || 180 NULL == fGetQueryObjectuiv) { 181 return false; 182 } 183 } 184 if (glVer >= GR_GL_VER(3,3) || 185 extensions.has("GL_ARB_timer_query") || 186 extensions.has("GL_EXT_timer_query")) { 187 if (NULL == fGetQueryObjecti64v || 188 NULL == fGetQueryObjectui64v) { 189 return false; 190 } 191 } 192 if (glVer >= GR_GL_VER(3,3) || extensions.has("GL_ARB_timer_query")) { 193 if (NULL == fQueryCounter) { 194 return false; 195 } 196 } 197 // The below two blocks are checks for functions used with 198 // GL_NV_path_rendering. We're not enforcing that they be non-NULL 199 // because they aren't actually called at this time. 200 if (false && 201 (NULL == fMatrixMode || 202 NULL == fLoadIdentity || 203 NULL == fLoadMatrixf)) { 204 return false; 205 } 206 if (false && extensions.has("GL_NV_path_rendering")) { 207 if (NULL == fPathCommands || 208 NULL == fPathCoords || 209 NULL == fPathSubCommands || 210 NULL == fPathSubCoords || 211 NULL == fPathString || 212 NULL == fPathGlyphs || 213 NULL == fPathGlyphRange || 214 NULL == fWeightPaths || 215 NULL == fCopyPath || 216 NULL == fInterpolatePaths || 217 NULL == fTransformPath || 218 NULL == fPathParameteriv || 219 NULL == fPathParameteri || 220 NULL == fPathParameterfv || 221 NULL == fPathParameterf || 222 NULL == fPathDashArray || 223 NULL == fGenPaths || 224 NULL == fDeletePaths || 225 NULL == fIsPath || 226 NULL == fPathStencilFunc || 227 NULL == fPathStencilDepthOffset || 228 NULL == fStencilFillPath || 229 NULL == fStencilStrokePath || 230 NULL == fStencilFillPathInstanced || 231 NULL == fStencilStrokePathInstanced || 232 NULL == fPathCoverDepthFunc || 233 NULL == fPathColorGen || 234 NULL == fPathTexGen || 235 NULL == fPathFogGen || 236 NULL == fCoverFillPath || 237 NULL == fCoverStrokePath || 238 NULL == fCoverFillPathInstanced || 239 NULL == fCoverStrokePathInstanced || 240 NULL == fGetPathParameteriv || 241 NULL == fGetPathParameterfv || 242 NULL == fGetPathCommands || 243 NULL == fGetPathCoords || 244 NULL == fGetPathDashArray || 245 NULL == fGetPathMetrics || 246 NULL == fGetPathMetricRange || 247 NULL == fGetPathSpacing || 248 NULL == fGetPathColorGeniv || 249 NULL == fGetPathColorGenfv || 250 NULL == fGetPathTexGeniv || 251 NULL == fGetPathTexGenfv || 252 NULL == fIsPointInFillPath || 253 NULL == fIsPointInStrokePath || 254 NULL == fGetPathLength || 255 NULL == fPointAlongPath) { 256 return false; 257 } 258 } 259 } 260 261 // optional function on desktop before 1.3 262 if (kDesktop_GrGLBinding != binding || 263 (glVer >= GR_GL_VER(1,3)) || 264 extensions.has("GL_ARB_texture_compression")) { 265 if (NULL == fCompressedTexImage2D) { 266 return false; 267 } 268 } 269 270 // part of desktop GL, but not ES 271 if (kDesktop_GrGLBinding == binding && 272 (NULL == fLineWidth || 273 NULL == fGetTexLevelParameteriv || 274 NULL == fDrawBuffer || 275 NULL == fReadBuffer)) { 276 return false; 277 } 278 279 // GL_EXT_texture_storage is part of desktop 4.2 280 // There is a desktop ARB extension and an ES+desktop EXT extension 281 if (kDesktop_GrGLBinding == binding) { 282 if (glVer >= GR_GL_VER(4,2) || 283 extensions.has("GL_ARB_texture_storage") || 284 extensions.has("GL_EXT_texture_storage")) { 285 if (NULL == fTexStorage2D) { 286 return false; 287 } 288 } 289 } else if (extensions.has("GL_EXT_texture_storage")) { 290 if (NULL == fTexStorage2D) { 291 return false; 292 } 293 } 294 295 // FBO MSAA 296 if (kDesktop_GrGLBinding == binding) { 297 // GL 3.0 and the ARB extension have multisample + blit 298 if (glVer >= GR_GL_VER(3,0) || extensions.has("GL_ARB_framebuffer_object")) { 299 if (NULL == fRenderbufferStorageMultisample || 300 NULL == fBlitFramebuffer) { 301 return false; 302 } 303 } else { 304 if (extensions.has("GL_EXT_framebuffer_blit") && 305 NULL == fBlitFramebuffer) { 306 return false; 307 } 308 if (extensions.has("GL_EXT_framebuffer_multisample") && 309 NULL == fRenderbufferStorageMultisample) { 310 return false; 311 } 312 } 313 } else { 314 if (extensions.has("GL_CHROMIUM_framebuffer_multisample")) { 315 if (NULL == fRenderbufferStorageMultisample || 316 NULL == fBlitFramebuffer) { 317 return false; 318 } 319 } 320 if (extensions.has("GL_APPLE_framebuffer_multisample")) { 321 if (NULL == fRenderbufferStorageMultisample || 322 NULL == fResolveMultisampleFramebuffer) { 323 return false; 324 } 325 } 326 if (extensions.has("GL_IMG_multisampled_render_to_texture")) { 327 if (NULL == fRenderbufferStorageMultisample || 328 NULL == fFramebufferTexture2DMultisample) { 329 return false; 330 } 331 } 332 } 333 334 // On ES buffer mapping is an extension. On Desktop 335 // buffer mapping was part of original VBO extension 336 // which we require. 337 if (kDesktop_GrGLBinding == binding || extensions.has("GL_OES_mapbuffer")) { 338 if (NULL == fMapBuffer || 339 NULL == fUnmapBuffer) { 340 return false; 341 } 342 } 343 344 // Dual source blending 345 if (kDesktop_GrGLBinding == binding && 346 (glVer >= GR_GL_VER(3,3) || extensions.has("GL_ARB_blend_func_extended"))) { 347 if (NULL == fBindFragDataLocationIndexed) { 348 return false; 349 } 350 } 351 352 if (kDesktop_GrGLBinding == binding && glVer >= GR_GL_VER(3, 0)) { 353 if (NULL == fGetStringi) { 354 return false; 355 } 356 } 357 358 if (kDesktop_GrGLBinding == binding) { 359 if (glVer >= GR_GL_VER(3, 0) || extensions.has("GL_ARB_vertex_array_object")) { 360 if (NULL == fBindVertexArray || 361 NULL == fDeleteVertexArrays || 362 NULL == fGenVertexArrays) { 363 return false; 364 } 365 } 366 } else { 367 if (extensions.has("GL_OES_vertex_array_object")) { 368 if (NULL == fBindVertexArray || 369 NULL == fDeleteVertexArrays || 370 NULL == fGenVertexArrays) { 371 return false; 372 } 373 } 374 } 375 376 return true; 377} 378