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 9 #include "GrGLCaps.h" 10 #include "GrGLContext.h" 11 #include "SkTSearch.h" 12 #include "SkTSort.h" 13 14 GrGLCaps::GrGLCaps() { 15 this->reset(); 16 } 17 18 void GrGLCaps::reset() { 19 INHERITED::reset(); 20 21 fVerifiedColorConfigs.reset(); 22 fStencilFormats.reset(); 23 fStencilVerifiedColorConfigs.reset(); 24 fMSFBOType = kNone_MSFBOType; 25 fInvalidateFBType = kNone_InvalidateFBType; 26 fLATCAlias = kLATC_LATCAlias; 27 fMapBufferType = kNone_MapBufferType; 28 fMaxFragmentUniformVectors = 0; 29 fMaxVertexAttributes = 0; 30 fMaxFragmentTextureUnits = 0; 31 fMaxFixedFunctionTextureCoords = 0; 32 fRGBA8RenderbufferSupport = false; 33 fBGRAIsInternalFormat = false; 34 fTextureSwizzleSupport = false; 35 fUnpackRowLengthSupport = false; 36 fUnpackFlipYSupport = false; 37 fPackRowLengthSupport = false; 38 fPackFlipYSupport = false; 39 fTextureUsageSupport = false; 40 fTexStorageSupport = false; 41 fTextureRedSupport = false; 42 fImagingSupport = false; 43 fTwoFormatLimit = false; 44 fFragCoordsConventionSupport = false; 45 fVertexArrayObjectSupport = false; 46 fUseNonVBOVertexAndIndexDynamicData = false; 47 fIsCoreProfile = false; 48 fFullClearIsFree = false; 49 fDropsTileOnZeroDivide = false; 50 fFBFetchSupport = false; 51 fFBFetchColorName = NULL; 52 fFBFetchExtensionString = NULL; 53 } 54 55 GrGLCaps::GrGLCaps(const GrGLCaps& caps) : GrDrawTargetCaps() { 56 *this = caps; 57 } 58 59 GrGLCaps& GrGLCaps::operator= (const GrGLCaps& caps) { 60 INHERITED::operator=(caps); 61 fVerifiedColorConfigs = caps.fVerifiedColorConfigs; 62 fStencilFormats = caps.fStencilFormats; 63 fStencilVerifiedColorConfigs = caps.fStencilVerifiedColorConfigs; 64 fLATCAlias = caps.fLATCAlias; 65 fMaxFragmentUniformVectors = caps.fMaxFragmentUniformVectors; 66 fMaxVertexAttributes = caps.fMaxVertexAttributes; 67 fMaxFragmentTextureUnits = caps.fMaxFragmentTextureUnits; 68 fMaxFixedFunctionTextureCoords = caps.fMaxFixedFunctionTextureCoords; 69 fMSFBOType = caps.fMSFBOType; 70 fInvalidateFBType = caps.fInvalidateFBType; 71 fMapBufferType = caps.fMapBufferType; 72 fRGBA8RenderbufferSupport = caps.fRGBA8RenderbufferSupport; 73 fBGRAIsInternalFormat = caps.fBGRAIsInternalFormat; 74 fTextureSwizzleSupport = caps.fTextureSwizzleSupport; 75 fUnpackRowLengthSupport = caps.fUnpackRowLengthSupport; 76 fUnpackFlipYSupport = caps.fUnpackFlipYSupport; 77 fPackRowLengthSupport = caps.fPackRowLengthSupport; 78 fPackFlipYSupport = caps.fPackFlipYSupport; 79 fTextureUsageSupport = caps.fTextureUsageSupport; 80 fTexStorageSupport = caps.fTexStorageSupport; 81 fTextureRedSupport = caps.fTextureRedSupport; 82 fImagingSupport = caps.fImagingSupport; 83 fTwoFormatLimit = caps.fTwoFormatLimit; 84 fFragCoordsConventionSupport = caps.fFragCoordsConventionSupport; 85 fVertexArrayObjectSupport = caps.fVertexArrayObjectSupport; 86 fUseNonVBOVertexAndIndexDynamicData = caps.fUseNonVBOVertexAndIndexDynamicData; 87 fIsCoreProfile = caps.fIsCoreProfile; 88 fFullClearIsFree = caps.fFullClearIsFree; 89 fDropsTileOnZeroDivide = caps.fDropsTileOnZeroDivide; 90 fFBFetchSupport = caps.fFBFetchSupport; 91 fFBFetchColorName = caps.fFBFetchColorName; 92 fFBFetchExtensionString = caps.fFBFetchExtensionString; 93 94 return *this; 95 } 96 97 bool GrGLCaps::init(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) { 98 99 this->reset(); 100 if (!ctxInfo.isInitialized()) { 101 return false; 102 } 103 104 GrGLStandard standard = ctxInfo.standard(); 105 GrGLVersion version = ctxInfo.version(); 106 107 /************************************************************************** 108 * Caps specific to GrGLCaps 109 **************************************************************************/ 110 111 if (kGLES_GrGLStandard == standard) { 112 GR_GL_GetIntegerv(gli, GR_GL_MAX_FRAGMENT_UNIFORM_VECTORS, 113 &fMaxFragmentUniformVectors); 114 } else { 115 SkASSERT(kGL_GrGLStandard == standard); 116 GrGLint max; 117 GR_GL_GetIntegerv(gli, GR_GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, &max); 118 fMaxFragmentUniformVectors = max / 4; 119 if (version >= GR_GL_VER(3, 2)) { 120 GrGLint profileMask; 121 GR_GL_GetIntegerv(gli, GR_GL_CONTEXT_PROFILE_MASK, &profileMask); 122 fIsCoreProfile = SkToBool(profileMask & GR_GL_CONTEXT_CORE_PROFILE_BIT); 123 } 124 if (!fIsCoreProfile) { 125 GR_GL_GetIntegerv(gli, GR_GL_MAX_TEXTURE_COORDS, &fMaxFixedFunctionTextureCoords); 126 // Sanity check 127 SkASSERT(fMaxFixedFunctionTextureCoords > 0 && fMaxFixedFunctionTextureCoords < 128); 128 } 129 } 130 GR_GL_GetIntegerv(gli, GR_GL_MAX_VERTEX_ATTRIBS, &fMaxVertexAttributes); 131 GR_GL_GetIntegerv(gli, GR_GL_MAX_TEXTURE_IMAGE_UNITS, &fMaxFragmentTextureUnits); 132 133 if (kGL_GrGLStandard == standard) { 134 fRGBA8RenderbufferSupport = true; 135 } else { 136 fRGBA8RenderbufferSupport = version >= GR_GL_VER(3,0) || 137 ctxInfo.hasExtension("GL_OES_rgb8_rgba8") || 138 ctxInfo.hasExtension("GL_ARM_rgba8"); 139 } 140 141 if (kGL_GrGLStandard == standard) { 142 fTextureSwizzleSupport = version >= GR_GL_VER(3,3) || 143 ctxInfo.hasExtension("GL_ARB_texture_swizzle"); 144 } else { 145 fTextureSwizzleSupport = version >= GR_GL_VER(3,0); 146 } 147 148 if (kGL_GrGLStandard == standard) { 149 fUnpackRowLengthSupport = true; 150 fUnpackFlipYSupport = false; 151 fPackRowLengthSupport = true; 152 fPackFlipYSupport = false; 153 } else { 154 fUnpackRowLengthSupport = version >= GR_GL_VER(3,0) || 155 ctxInfo.hasExtension("GL_EXT_unpack_subimage"); 156 fUnpackFlipYSupport = ctxInfo.hasExtension("GL_CHROMIUM_flipy"); 157 fPackRowLengthSupport = version >= GR_GL_VER(3,0) || 158 ctxInfo.hasExtension("GL_NV_pack_subimage"); 159 fPackFlipYSupport = 160 ctxInfo.hasExtension("GL_ANGLE_pack_reverse_row_order"); 161 } 162 163 fTextureUsageSupport = (kGLES_GrGLStandard == standard) && 164 ctxInfo.hasExtension("GL_ANGLE_texture_usage"); 165 166 if (kGL_GrGLStandard == standard) { 167 // The EXT version can apply to either GL or GLES. 168 fTexStorageSupport = version >= GR_GL_VER(4,2) || 169 ctxInfo.hasExtension("GL_ARB_texture_storage") || 170 ctxInfo.hasExtension("GL_EXT_texture_storage"); 171 } else { 172 // Qualcomm Adreno drivers appear to have issues with texture storage. 173 fTexStorageSupport = (version >= GR_GL_VER(3,0) && 174 kQualcomm_GrGLVendor != ctxInfo.vendor()) || 175 ctxInfo.hasExtension("GL_EXT_texture_storage"); 176 } 177 178 // ARB_texture_rg is part of OpenGL 3.0, but mesa doesn't support it if 179 // it doesn't have ARB_texture_rg extension. 180 if (kGL_GrGLStandard == standard) { 181 if (ctxInfo.isMesa()) { 182 fTextureRedSupport = ctxInfo.hasExtension("GL_ARB_texture_rg"); 183 } else { 184 fTextureRedSupport = version >= GR_GL_VER(3,0) || 185 ctxInfo.hasExtension("GL_ARB_texture_rg"); 186 } 187 } else { 188 fTextureRedSupport = version >= GR_GL_VER(3,0) || 189 ctxInfo.hasExtension("GL_EXT_texture_rg"); 190 } 191 192 fImagingSupport = kGL_GrGLStandard == standard && 193 ctxInfo.hasExtension("GL_ARB_imaging"); 194 195 // ES 2 only guarantees RGBA/uchar + one other format/type combo for 196 // ReadPixels. The other format has to checked at run-time since it 197 // can change based on which render target is bound 198 fTwoFormatLimit = kGLES_GrGLStandard == standard; 199 200 // Known issue on at least some Intel platforms: 201 // http://code.google.com/p/skia/issues/detail?id=946 202 if (kIntel_GrGLVendor != ctxInfo.vendor()) { 203 fFragCoordsConventionSupport = ctxInfo.glslGeneration() >= k150_GrGLSLGeneration || 204 ctxInfo.hasExtension("GL_ARB_fragment_coord_conventions"); 205 } 206 207 // SGX and Mali GPUs that are based on a tiled-deferred architecture that have trouble with 208 // frequently changing VBOs. We've measured a performance increase using non-VBO vertex 209 // data for dynamic content on these GPUs. Perhaps we should read the renderer string and 210 // limit this decision to specific GPU families rather than basing it on the vendor alone. 211 if (!GR_GL_MUST_USE_VBO && 212 (kARM_GrGLVendor == ctxInfo.vendor() || 213 kImagination_GrGLVendor == ctxInfo.vendor() || 214 kQualcomm_GrGLVendor == ctxInfo.vendor())) { 215 fUseNonVBOVertexAndIndexDynamicData = true; 216 } 217 218 if ((kGL_GrGLStandard == standard && version >= GR_GL_VER(4,3)) || 219 (kGLES_GrGLStandard == standard && version >= GR_GL_VER(3,0)) || 220 ctxInfo.hasExtension("GL_ARB_invalidate_subdata")) { 221 fDiscardRenderTargetSupport = true; 222 fInvalidateFBType = kInvalidate_InvalidateFBType; 223 } else if (ctxInfo.hasExtension("GL_EXT_discard_framebuffer")) { 224 fDiscardRenderTargetSupport = true; 225 fInvalidateFBType = kDiscard_InvalidateFBType; 226 } 227 228 if (kARM_GrGLVendor == ctxInfo.vendor() || kImagination_GrGLVendor == ctxInfo.vendor()) { 229 fFullClearIsFree = true; 230 } 231 232 if (kGL_GrGLStandard == standard) { 233 fVertexArrayObjectSupport = version >= GR_GL_VER(3, 0) || 234 ctxInfo.hasExtension("GL_ARB_vertex_array_object"); 235 } else { 236 fVertexArrayObjectSupport = version >= GR_GL_VER(3, 0) || 237 ctxInfo.hasExtension("GL_OES_vertex_array_object"); 238 } 239 240 if (kGLES_GrGLStandard == standard) { 241 if (ctxInfo.hasExtension("GL_EXT_shader_framebuffer_fetch")) { 242 fFBFetchSupport = true; 243 fFBFetchColorName = "gl_LastFragData[0]"; 244 fFBFetchExtensionString = "GL_EXT_shader_framebuffer_fetch"; 245 } else if (ctxInfo.hasExtension("GL_NV_shader_framebuffer_fetch")) { 246 fFBFetchSupport = true; 247 fFBFetchColorName = "gl_LastFragData[0]"; 248 fFBFetchExtensionString = "GL_NV_shader_framebuffer_fetch"; 249 } else if (ctxInfo.hasExtension("GL_ARM_shader_framebuffer_fetch")) { 250 // The arm extension also requires an additional flag which we will set onResetContext 251 // This is all temporary. 252 fFBFetchSupport = true; 253 fFBFetchColorName = "gl_LastFragColorARM"; 254 fFBFetchExtensionString = "GL_ARM_shader_framebuffer_fetch"; 255 } 256 } 257 258 // Adreno GPUs have a tendency to drop tiles when there is a divide-by-zero in a shader 259 fDropsTileOnZeroDivide = kQualcomm_GrGLVendor == ctxInfo.vendor(); 260 261 this->initFSAASupport(ctxInfo, gli); 262 this->initStencilFormats(ctxInfo); 263 264 /************************************************************************** 265 * GrDrawTargetCaps fields 266 **************************************************************************/ 267 if (kGL_GrGLStandard == standard) { 268 // we could also look for GL_ATI_separate_stencil extension or 269 // GL_EXT_stencil_two_side but they use different function signatures 270 // than GL2.0+ (and than each other). 271 fTwoSidedStencilSupport = (ctxInfo.version() >= GR_GL_VER(2,0)); 272 // supported on GL 1.4 and higher or by extension 273 fStencilWrapOpsSupport = (ctxInfo.version() >= GR_GL_VER(1,4)) || 274 ctxInfo.hasExtension("GL_EXT_stencil_wrap"); 275 } else { 276 // ES 2 has two sided stencil and stencil wrap 277 fTwoSidedStencilSupport = true; 278 fStencilWrapOpsSupport = true; 279 } 280 281 if (kGL_GrGLStandard == standard) { 282 fMapBufferFlags = kCanMap_MapFlag; // we require VBO support and the desktop VBO 283 // extension includes glMapBuffer. 284 if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_map_buffer_range")) { 285 fMapBufferFlags |= kSubset_MapFlag; 286 fMapBufferType = kMapBufferRange_MapBufferType; 287 } else { 288 fMapBufferType = kMapBuffer_MapBufferType; 289 } 290 } else { 291 // Unextended GLES2 doesn't have any buffer mapping. 292 fMapBufferFlags = kNone_MapBufferType; 293 if (ctxInfo.hasExtension("GL_CHROMIUM_map_sub")) { 294 fMapBufferFlags = kCanMap_MapFlag | kSubset_MapFlag; 295 fMapBufferType = kChromium_MapBufferType; 296 } else if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_EXT_map_buffer_range")) { 297 fMapBufferFlags = kCanMap_MapFlag | kSubset_MapFlag; 298 fMapBufferType = kMapBufferRange_MapBufferType; 299 } else if (ctxInfo.hasExtension("GL_OES_mapbuffer")) { 300 fMapBufferFlags = kCanMap_MapFlag; 301 fMapBufferType = kMapBuffer_MapBufferType; 302 } 303 } 304 305 if (kGL_GrGLStandard == standard) { 306 SkASSERT(ctxInfo.version() >= GR_GL_VER(2,0) || 307 ctxInfo.hasExtension("GL_ARB_texture_non_power_of_two")); 308 fNPOTTextureTileSupport = true; 309 fMipMapSupport = true; 310 } else { 311 // Unextended ES2 supports NPOT textures with clamp_to_edge and non-mip filters only 312 // ES3 has no limitations. 313 fNPOTTextureTileSupport = ctxInfo.version() >= GR_GL_VER(3,0) || 314 ctxInfo.hasExtension("GL_OES_texture_npot"); 315 // ES2 supports MIP mapping for POT textures but our caps don't allow for limited MIP 316 // support. The OES extension or ES 3.0 allow for MIPS on NPOT textures. So, apparently, 317 // does the undocumented GL_IMG_texture_npot extension. This extension does not seem to 318 // to alllow arbitrary wrap modes, however. 319 fMipMapSupport = fNPOTTextureTileSupport || ctxInfo.hasExtension("GL_IMG_texture_npot"); 320 } 321 322 fHWAALineSupport = (kGL_GrGLStandard == standard); 323 324 GR_GL_GetIntegerv(gli, GR_GL_MAX_TEXTURE_SIZE, &fMaxTextureSize); 325 GR_GL_GetIntegerv(gli, GR_GL_MAX_RENDERBUFFER_SIZE, &fMaxRenderTargetSize); 326 // Our render targets are always created with textures as the color 327 // attachment, hence this min: 328 fMaxRenderTargetSize = SkTMin(fMaxTextureSize, fMaxRenderTargetSize); 329 330 fPathRenderingSupport = ctxInfo.hasExtension("GL_NV_path_rendering"); 331 332 if (fPathRenderingSupport) { 333 if (kGL_GrGLStandard == standard) { 334 // We need one of the two possible texturing methods: using fixed function pipeline 335 // (PathTexGen, texcoords, ...) or using the newer NVPR API additions that support 336 // setting individual fragment inputs with ProgramPathFragmentInputGen. The API 337 // additions are detected by checking the existence of the function. Eventually we may 338 // choose to remove the fixed function codepath. 339 // Set fMaxFixedFunctionTextureCoords = 0 here if you want to force 340 // ProgramPathFragmentInputGen usage on desktop. 341 fPathRenderingSupport = ctxInfo.hasExtension("GL_EXT_direct_state_access") && 342 (fMaxFixedFunctionTextureCoords > 0 || 343 ((ctxInfo.version() >= GR_GL_VER(4,3) || 344 ctxInfo.hasExtension("GL_ARB_program_interface_query")) && 345 gli->fFunctions.fProgramPathFragmentInputGen)); 346 } else { 347 fPathRenderingSupport = ctxInfo.version() >= GR_GL_VER(3,1); 348 } 349 } 350 351 fGpuTracingSupport = ctxInfo.hasExtension("GL_EXT_debug_marker"); 352 353 // For now these two are equivalent but we could have dst read in shader via some other method 354 fDstReadInShaderSupport = fFBFetchSupport; 355 356 // Disable scratch texture reuse on Mali and Adreno devices 357 fReuseScratchTextures = kARM_GrGLVendor != ctxInfo.vendor() && 358 kQualcomm_GrGLVendor != ctxInfo.vendor(); 359 360 // Enable supported shader-related caps 361 if (kGL_GrGLStandard == standard) { 362 fDualSourceBlendingSupport = ctxInfo.version() >= GR_GL_VER(3,3) || 363 ctxInfo.hasExtension("GL_ARB_blend_func_extended"); 364 fShaderDerivativeSupport = true; 365 // we don't support GL_ARB_geometry_shader4, just GL 3.2+ GS 366 fGeometryShaderSupport = ctxInfo.version() >= GR_GL_VER(3,2) && 367 ctxInfo.glslGeneration() >= k150_GrGLSLGeneration; 368 } else { 369 fShaderDerivativeSupport = ctxInfo.hasExtension("GL_OES_standard_derivatives"); 370 } 371 372 if (GrGLCaps::kES_IMG_MsToTexture_MSFBOType == fMSFBOType) { 373 GR_GL_GetIntegerv(gli, GR_GL_MAX_SAMPLES_IMG, &fMaxSampleCount); 374 } else if (GrGLCaps::kNone_MSFBOType != fMSFBOType) { 375 GR_GL_GetIntegerv(gli, GR_GL_MAX_SAMPLES, &fMaxSampleCount); 376 } 377 378 this->initConfigTexturableTable(ctxInfo, gli); 379 this->initConfigRenderableTable(ctxInfo); 380 381 return true; 382 } 383 384 void GrGLCaps::initConfigRenderableTable(const GrGLContextInfo& ctxInfo) { 385 386 // OpenGL < 3.0 387 // no support for render targets unless the GL_ARB_framebuffer_object 388 // extension is supported (in which case we get ALPHA, RED, RG, RGB, 389 // RGBA (ALPHA8, RGBA4, RGBA8) for OpenGL > 1.1). Note that we 390 // probably don't get R8 in this case. 391 392 // OpenGL 3.0 393 // base color renderable: ALPHA, RED, RG, RGB, and RGBA 394 // sized derivatives: ALPHA8, R8, RGBA4, RGBA8 395 396 // >= OpenGL 3.1 397 // base color renderable: RED, RG, RGB, and RGBA 398 // sized derivatives: R8, RGBA4, RGBA8 399 // if the GL_ARB_compatibility extension is supported then we get back 400 // support for GL_ALPHA and ALPHA8 401 402 // GL_EXT_bgra adds BGRA render targets to any version 403 404 // ES 2.0 405 // color renderable: RGBA4, RGB5_A1, RGB565 406 // GL_EXT_texture_rg adds support for R8 as a color render target 407 // GL_OES_rgb8_rgba8 and/or GL_ARM_rgba8 adds support for RGBA8 408 // GL_EXT_texture_format_BGRA8888 and/or GL_APPLE_texture_format_BGRA8888 added BGRA support 409 410 // ES 3.0 411 // Same as ES 2.0 except R8 and RGBA8 are supported without extensions (the functions called 412 // below already account for this). 413 414 GrGLStandard standard = ctxInfo.standard(); 415 416 enum { 417 kNo_MSAA = 0, 418 kYes_MSAA = 1, 419 }; 420 421 if (kGL_GrGLStandard == standard) { 422 // Post 3.0 we will get R8 423 // Prior to 3.0 we will get ALPHA8 (with GL_ARB_framebuffer_object) 424 if (ctxInfo.version() >= GR_GL_VER(3,0) || 425 ctxInfo.hasExtension("GL_ARB_framebuffer_object")) { 426 fConfigRenderSupport[kAlpha_8_GrPixelConfig][kNo_MSAA] = true; 427 fConfigRenderSupport[kAlpha_8_GrPixelConfig][kYes_MSAA] = true; 428 } 429 } else { 430 // On ES we can only hope for R8 431 fConfigRenderSupport[kAlpha_8_GrPixelConfig][kNo_MSAA] = fTextureRedSupport; 432 fConfigRenderSupport[kAlpha_8_GrPixelConfig][kYes_MSAA] = fTextureRedSupport; 433 } 434 435 if (kGL_GrGLStandard != standard) { 436 // only available in ES 437 fConfigRenderSupport[kRGB_565_GrPixelConfig][kNo_MSAA] = true; 438 fConfigRenderSupport[kRGB_565_GrPixelConfig][kYes_MSAA] = true; 439 } 440 441 // we no longer support 444 as a render target 442 fConfigRenderSupport[kRGBA_4444_GrPixelConfig][kNo_MSAA] = false; 443 fConfigRenderSupport[kRGBA_4444_GrPixelConfig][kYes_MSAA] = false; 444 445 if (this->fRGBA8RenderbufferSupport) { 446 fConfigRenderSupport[kRGBA_8888_GrPixelConfig][kNo_MSAA] = true; 447 fConfigRenderSupport[kRGBA_8888_GrPixelConfig][kYes_MSAA] = true; 448 } 449 450 if (this->isConfigTexturable(kBGRA_8888_GrPixelConfig)) { 451 fConfigRenderSupport[kBGRA_8888_GrPixelConfig][kNo_MSAA] = true; 452 // The GL_EXT_texture_format_BGRA8888 extension does not add BGRA to the list of 453 // configs that are color-renderable and can be passed to glRenderBufferStorageMultisample. 454 // Chromium may have an extension to allow BGRA renderbuffers to work on desktop platforms. 455 if (ctxInfo.hasExtension("GL_CHROMIUM_renderbuffer_format_BGRA8888")) { 456 fConfigRenderSupport[kBGRA_8888_GrPixelConfig][kYes_MSAA] = true; 457 } else { 458 fConfigRenderSupport[kBGRA_8888_GrPixelConfig][kYes_MSAA] = 459 !fBGRAIsInternalFormat || !this->usesMSAARenderBuffers(); 460 } 461 } 462 463 if (this->isConfigTexturable(kRGBA_float_GrPixelConfig)) { 464 fConfigRenderSupport[kRGBA_float_GrPixelConfig][kNo_MSAA] = true; 465 } 466 467 // If we don't support MSAA then undo any places above where we set a config as renderable with 468 // msaa. 469 if (kNone_MSFBOType == fMSFBOType) { 470 for (int i = 0; i < kGrPixelConfigCnt; ++i) { 471 fConfigRenderSupport[i][kYes_MSAA] = false; 472 } 473 } 474 } 475 476 void GrGLCaps::initConfigTexturableTable(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) { 477 GrGLStandard standard = ctxInfo.standard(); 478 GrGLVersion version = ctxInfo.version(); 479 480 // Base texture support 481 fConfigTextureSupport[kAlpha_8_GrPixelConfig] = true; 482 fConfigTextureSupport[kRGB_565_GrPixelConfig] = true; 483 fConfigTextureSupport[kRGBA_4444_GrPixelConfig] = true; 484 fConfigTextureSupport[kRGBA_8888_GrPixelConfig] = true; 485 486 // Check for 8-bit palette.. 487 GrGLint numFormats; 488 GR_GL_GetIntegerv(gli, GR_GL_NUM_COMPRESSED_TEXTURE_FORMATS, &numFormats); 489 if (numFormats) { 490 SkAutoSTMalloc<10, GrGLint> formats(numFormats); 491 GR_GL_GetIntegerv(gli, GR_GL_COMPRESSED_TEXTURE_FORMATS, formats); 492 for (int i = 0; i < numFormats; ++i) { 493 if (GR_GL_PALETTE8_RGBA8 == formats[i]) { 494 fConfigTextureSupport[kIndex_8_GrPixelConfig] = true; 495 break; 496 } 497 } 498 } 499 500 // Check for BGRA 501 if (kGL_GrGLStandard == standard) { 502 fConfigTextureSupport[kBGRA_8888_GrPixelConfig] = 503 version >= GR_GL_VER(1,2) || ctxInfo.hasExtension("GL_EXT_bgra"); 504 } else { 505 if (ctxInfo.hasExtension("GL_APPLE_texture_format_BGRA8888")) { 506 fConfigTextureSupport[kBGRA_8888_GrPixelConfig] = true; 507 } else if (ctxInfo.hasExtension("GL_EXT_texture_format_BGRA8888")) { 508 fConfigTextureSupport[kBGRA_8888_GrPixelConfig] = true; 509 fBGRAIsInternalFormat = true; 510 } 511 SkASSERT(fConfigTextureSupport[kBGRA_8888_GrPixelConfig] || 512 kSkia8888_GrPixelConfig != kBGRA_8888_GrPixelConfig); 513 } 514 515 // Compressed texture support 516 517 // glCompressedTexImage2D is available on all OpenGL ES devices... 518 // however, it is only available on standard OpenGL after version 1.3 519 bool hasCompressTex2D = (kGL_GrGLStandard != standard || version >= GR_GL_VER(1, 3)); 520 521 fCompressedTexSubImageSupport = 522 hasCompressTex2D && (gli->fFunctions.fCompressedTexSubImage2D); 523 524 // Check for ETC1 525 bool hasETC1 = false; 526 527 // First check version for support 528 if (kGL_GrGLStandard == standard) { 529 hasETC1 = hasCompressTex2D && 530 (version >= GR_GL_VER(4, 3) || 531 ctxInfo.hasExtension("GL_ARB_ES3_compatibility")); 532 } else { 533 hasETC1 = hasCompressTex2D && 534 (version >= GR_GL_VER(3, 0) || 535 ctxInfo.hasExtension("GL_OES_compressed_ETC1_RGB8_texture") || 536 // ETC2 is a superset of ETC1, so we can just check for that, too. 537 (ctxInfo.hasExtension("GL_OES_compressed_ETC2_RGB8_texture") && 538 ctxInfo.hasExtension("GL_OES_compressed_ETC2_RGBA8_texture"))); 539 } 540 fConfigTextureSupport[kETC1_GrPixelConfig] = hasETC1; 541 542 // Check for LATC under its various forms 543 LATCAlias alias = kLATC_LATCAlias; 544 bool hasLATC = hasCompressTex2D && 545 (ctxInfo.hasExtension("GL_EXT_texture_compression_latc") || 546 ctxInfo.hasExtension("GL_NV_texture_compression_latc")); 547 548 // Check for RGTC 549 if (!hasLATC) { 550 // If we're using OpenGL 3.0 or later, then we have RGTC, an identical compression format. 551 if (kGL_GrGLStandard == standard) { 552 hasLATC = version >= GR_GL_VER(3, 0); 553 } 554 555 if (!hasLATC) { 556 hasLATC = 557 ctxInfo.hasExtension("GL_EXT_texture_compression_rgtc") || 558 ctxInfo.hasExtension("GL_ARB_texture_compression_rgtc"); 559 } 560 561 if (hasLATC) { 562 alias = kRGTC_LATCAlias; 563 } 564 } 565 566 // Check for 3DC 567 if (!hasLATC) { 568 hasLATC = ctxInfo.hasExtension("GL_AMD_compressed_3DC_texture"); 569 if (hasLATC) { 570 alias = k3DC_LATCAlias; 571 } 572 } 573 574 fConfigTextureSupport[kLATC_GrPixelConfig] = hasLATC; 575 fLATCAlias = alias; 576 577 // Check for R11_EAC ... We don't support R11_EAC on desktop, as most 578 // cards default to decompressing the textures in the driver, and is 579 // generally slower. 580 if (kGL_GrGLStandard != standard) { 581 fConfigTextureSupport[kR11_EAC_GrPixelConfig] = version >= GR_GL_VER(3, 0); 582 } 583 584 // Check for ASTC 585 fConfigTextureSupport[kASTC_12x12_GrPixelConfig] = 586 ctxInfo.hasExtension("GL_KHR_texture_compression_astc_hdr") || 587 ctxInfo.hasExtension("GL_KHR_texture_compression_astc_ldr") || 588 ctxInfo.hasExtension("GL_OES_texture_compression_astc"); 589 590 // Check for floating point texture support 591 // NOTE: We disallow floating point textures on ES devices if linear 592 // filtering modes are not supported. This is for simplicity, but a more 593 // granular approach is possible. Coincidentally, floating point textures became part of 594 // the standard in ES3.1 / OGL 3.1, hence the shorthand 595 bool hasFPTextures = version >= GR_GL_VER(3, 1); 596 if (!hasFPTextures) { 597 hasFPTextures = ctxInfo.hasExtension("GL_ARB_texture_float") || 598 (ctxInfo.hasExtension("OES_texture_float_linear") && 599 ctxInfo.hasExtension("GL_OES_texture_float")); 600 } 601 fConfigTextureSupport[kRGBA_float_GrPixelConfig] = hasFPTextures; 602 } 603 604 bool GrGLCaps::readPixelsSupported(const GrGLInterface* intf, 605 GrGLenum format, 606 GrGLenum type) const { 607 if (GR_GL_RGBA == format && GR_GL_UNSIGNED_BYTE == type) { 608 // ES 2 guarantees this format is supported 609 return true; 610 } 611 612 if (!fTwoFormatLimit) { 613 // not limited by ES 2's constraints 614 return true; 615 } 616 617 GrGLint otherFormat = GR_GL_RGBA; 618 GrGLint otherType = GR_GL_UNSIGNED_BYTE; 619 620 // The other supported format/type combo supported for ReadPixels 621 // can change based on which render target is bound 622 GR_GL_GetIntegerv(intf, 623 GR_GL_IMPLEMENTATION_COLOR_READ_FORMAT, 624 &otherFormat); 625 626 GR_GL_GetIntegerv(intf, 627 GR_GL_IMPLEMENTATION_COLOR_READ_TYPE, 628 &otherType); 629 630 return (GrGLenum)otherFormat == format && (GrGLenum)otherType == type; 631 } 632 633 void GrGLCaps::initFSAASupport(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) { 634 635 fMSFBOType = kNone_MSFBOType; 636 if (kGL_GrGLStandard != ctxInfo.standard()) { 637 // We prefer the EXT/IMG extension over ES3 MSAA because we've observed 638 // ES3 driver bugs on at least one device with a tiled GPU (N10). 639 if (ctxInfo.hasExtension("GL_EXT_multisampled_render_to_texture")) { 640 fMSFBOType = kES_EXT_MsToTexture_MSFBOType; 641 } else if (ctxInfo.hasExtension("GL_IMG_multisampled_render_to_texture")) { 642 fMSFBOType = kES_IMG_MsToTexture_MSFBOType; 643 } else if (ctxInfo.version() >= GR_GL_VER(3,0)) { 644 fMSFBOType = GrGLCaps::kES_3_0_MSFBOType; 645 } else if (ctxInfo.hasExtension("GL_CHROMIUM_framebuffer_multisample")) { 646 // chrome's extension is equivalent to the EXT msaa 647 // and fbo_blit extensions. 648 fMSFBOType = kDesktop_EXT_MSFBOType; 649 } else if (ctxInfo.hasExtension("GL_APPLE_framebuffer_multisample")) { 650 fMSFBOType = kES_Apple_MSFBOType; 651 } 652 } else { 653 if ((ctxInfo.version() >= GR_GL_VER(3,0)) || 654 ctxInfo.hasExtension("GL_ARB_framebuffer_object")) { 655 fMSFBOType = GrGLCaps::kDesktop_ARB_MSFBOType; 656 } else if (ctxInfo.hasExtension("GL_EXT_framebuffer_multisample") && 657 ctxInfo.hasExtension("GL_EXT_framebuffer_blit")) { 658 fMSFBOType = GrGLCaps::kDesktop_EXT_MSFBOType; 659 } 660 } 661 } 662 663 namespace { 664 const GrGLuint kUnknownBitCount = GrGLStencilBuffer::kUnknownBitCount; 665 } 666 667 void GrGLCaps::initStencilFormats(const GrGLContextInfo& ctxInfo) { 668 669 // Build up list of legal stencil formats (though perhaps not supported on 670 // the particular gpu/driver) from most preferred to least. 671 672 // these consts are in order of most preferred to least preferred 673 // we don't bother with GL_STENCIL_INDEX1 or GL_DEPTH32F_STENCIL8 674 675 static const StencilFormat 676 // internal Format stencil bits total bits packed? 677 gS8 = {GR_GL_STENCIL_INDEX8, 8, 8, false}, 678 gS16 = {GR_GL_STENCIL_INDEX16, 16, 16, false}, 679 gD24S8 = {GR_GL_DEPTH24_STENCIL8, 8, 32, true }, 680 gS4 = {GR_GL_STENCIL_INDEX4, 4, 4, false}, 681 // gS = {GR_GL_STENCIL_INDEX, kUnknownBitCount, kUnknownBitCount, false}, 682 gDS = {GR_GL_DEPTH_STENCIL, kUnknownBitCount, kUnknownBitCount, true }; 683 684 if (kGL_GrGLStandard == ctxInfo.standard()) { 685 bool supportsPackedDS = 686 ctxInfo.version() >= GR_GL_VER(3,0) || 687 ctxInfo.hasExtension("GL_EXT_packed_depth_stencil") || 688 ctxInfo.hasExtension("GL_ARB_framebuffer_object"); 689 690 // S1 thru S16 formats are in GL 3.0+, EXT_FBO, and ARB_FBO since we 691 // require FBO support we can expect these are legal formats and don't 692 // check. These also all support the unsized GL_STENCIL_INDEX. 693 fStencilFormats.push_back() = gS8; 694 fStencilFormats.push_back() = gS16; 695 if (supportsPackedDS) { 696 fStencilFormats.push_back() = gD24S8; 697 } 698 fStencilFormats.push_back() = gS4; 699 if (supportsPackedDS) { 700 fStencilFormats.push_back() = gDS; 701 } 702 } else { 703 // ES2 has STENCIL_INDEX8 without extensions but requires extensions 704 // for other formats. 705 // ES doesn't support using the unsized format. 706 707 fStencilFormats.push_back() = gS8; 708 //fStencilFormats.push_back() = gS16; 709 if (ctxInfo.version() >= GR_GL_VER(3,0) || 710 ctxInfo.hasExtension("GL_OES_packed_depth_stencil")) { 711 fStencilFormats.push_back() = gD24S8; 712 } 713 if (ctxInfo.hasExtension("GL_OES_stencil4")) { 714 fStencilFormats.push_back() = gS4; 715 } 716 } 717 SkASSERT(0 == fStencilVerifiedColorConfigs.count()); 718 fStencilVerifiedColorConfigs.push_back_n(fStencilFormats.count()); 719 } 720 721 void GrGLCaps::markColorConfigAndStencilFormatAsVerified( 722 GrPixelConfig config, 723 const GrGLStencilBuffer::Format& format) { 724 #if !GR_GL_CHECK_FBO_STATUS_ONCE_PER_FORMAT 725 return; 726 #endif 727 SkASSERT((unsigned)config < (unsigned)kGrPixelConfigCnt); 728 SkASSERT(fStencilFormats.count() == fStencilVerifiedColorConfigs.count()); 729 int count = fStencilFormats.count(); 730 // we expect a really small number of possible formats so linear search 731 // should be OK 732 SkASSERT(count < 16); 733 for (int i = 0; i < count; ++i) { 734 if (format.fInternalFormat == 735 fStencilFormats[i].fInternalFormat) { 736 fStencilVerifiedColorConfigs[i].markVerified(config); 737 return; 738 } 739 } 740 SkFAIL("Why are we seeing a stencil format that " 741 "GrGLCaps doesn't know about."); 742 } 743 744 bool GrGLCaps::isColorConfigAndStencilFormatVerified( 745 GrPixelConfig config, 746 const GrGLStencilBuffer::Format& format) const { 747 #if !GR_GL_CHECK_FBO_STATUS_ONCE_PER_FORMAT 748 return false; 749 #endif 750 SkASSERT((unsigned)config < (unsigned)kGrPixelConfigCnt); 751 int count = fStencilFormats.count(); 752 // we expect a really small number of possible formats so linear search 753 // should be OK 754 SkASSERT(count < 16); 755 for (int i = 0; i < count; ++i) { 756 if (format.fInternalFormat == 757 fStencilFormats[i].fInternalFormat) { 758 return fStencilVerifiedColorConfigs[i].isVerified(config); 759 } 760 } 761 SkFAIL("Why are we seeing a stencil format that " 762 "GLCaps doesn't know about."); 763 return false; 764 } 765 766 SkString GrGLCaps::dump() const { 767 768 SkString r = INHERITED::dump(); 769 770 r.appendf("--- GL-Specific ---\n"); 771 for (int i = 0; i < fStencilFormats.count(); ++i) { 772 r.appendf("Stencil Format %d, stencil bits: %02d, total bits: %02d\n", 773 i, 774 fStencilFormats[i].fStencilBits, 775 fStencilFormats[i].fTotalBits); 776 } 777 778 static const char* kMSFBOExtStr[] = { 779 "None", 780 "ARB", 781 "EXT", 782 "ES 3.0", 783 "Apple", 784 "IMG MS To Texture", 785 "EXT MS To Texture", 786 }; 787 GR_STATIC_ASSERT(0 == kNone_MSFBOType); 788 GR_STATIC_ASSERT(1 == kDesktop_ARB_MSFBOType); 789 GR_STATIC_ASSERT(2 == kDesktop_EXT_MSFBOType); 790 GR_STATIC_ASSERT(3 == kES_3_0_MSFBOType); 791 GR_STATIC_ASSERT(4 == kES_Apple_MSFBOType); 792 GR_STATIC_ASSERT(5 == kES_IMG_MsToTexture_MSFBOType); 793 GR_STATIC_ASSERT(6 == kES_EXT_MsToTexture_MSFBOType); 794 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kMSFBOExtStr) == kLast_MSFBOType + 1); 795 796 static const char* kInvalidateFBTypeStr[] = { 797 "None", 798 "Discard", 799 "Invalidate", 800 }; 801 GR_STATIC_ASSERT(0 == kNone_InvalidateFBType); 802 GR_STATIC_ASSERT(1 == kDiscard_InvalidateFBType); 803 GR_STATIC_ASSERT(2 == kInvalidate_InvalidateFBType); 804 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kInvalidateFBTypeStr) == kLast_InvalidateFBType + 1); 805 806 static const char* kMapBufferTypeStr[] = { 807 "None", 808 "MapBuffer", 809 "MapBufferRange", 810 "Chromium", 811 }; 812 GR_STATIC_ASSERT(0 == kNone_MapBufferType); 813 GR_STATIC_ASSERT(1 == kMapBuffer_MapBufferType); 814 GR_STATIC_ASSERT(2 == kMapBufferRange_MapBufferType); 815 GR_STATIC_ASSERT(3 == kChromium_MapBufferType); 816 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kMapBufferTypeStr) == kLast_MapBufferType + 1); 817 818 r.appendf("Core Profile: %s\n", (fIsCoreProfile ? "YES" : "NO")); 819 r.appendf("MSAA Type: %s\n", kMSFBOExtStr[fMSFBOType]); 820 r.appendf("FB Fetch Support: %s\n", (fFBFetchSupport ? "YES" : "NO")); 821 r.appendf("Invalidate FB Type: %s\n", kInvalidateFBTypeStr[fInvalidateFBType]); 822 r.appendf("Map Buffer Type: %s\n", kMapBufferTypeStr[fMapBufferType]); 823 r.appendf("Max FS Uniform Vectors: %d\n", fMaxFragmentUniformVectors); 824 r.appendf("Max FS Texture Units: %d\n", fMaxFragmentTextureUnits); 825 if (!fIsCoreProfile) { 826 r.appendf("Max Fixed Function Texture Coords: %d\n", fMaxFixedFunctionTextureCoords); 827 } 828 r.appendf("Max Vertex Attributes: %d\n", fMaxVertexAttributes); 829 r.appendf("Support RGBA8 Render Buffer: %s\n", (fRGBA8RenderbufferSupport ? "YES": "NO")); 830 r.appendf("BGRA is an internal format: %s\n", (fBGRAIsInternalFormat ? "YES": "NO")); 831 r.appendf("Support texture swizzle: %s\n", (fTextureSwizzleSupport ? "YES": "NO")); 832 r.appendf("Unpack Row length support: %s\n", (fUnpackRowLengthSupport ? "YES": "NO")); 833 r.appendf("Unpack Flip Y support: %s\n", (fUnpackFlipYSupport ? "YES": "NO")); 834 r.appendf("Pack Row length support: %s\n", (fPackRowLengthSupport ? "YES": "NO")); 835 r.appendf("Pack Flip Y support: %s\n", (fPackFlipYSupport ? "YES": "NO")); 836 837 r.appendf("Texture Usage support: %s\n", (fTextureUsageSupport ? "YES": "NO")); 838 r.appendf("Texture Storage support: %s\n", (fTexStorageSupport ? "YES": "NO")); 839 r.appendf("GL_R support: %s\n", (fTextureRedSupport ? "YES": "NO")); 840 r.appendf("GL_ARB_imaging support: %s\n", (fImagingSupport ? "YES": "NO")); 841 r.appendf("Two Format Limit: %s\n", (fTwoFormatLimit ? "YES": "NO")); 842 r.appendf("Fragment coord conventions support: %s\n", 843 (fFragCoordsConventionSupport ? "YES": "NO")); 844 r.appendf("Vertex array object support: %s\n", (fVertexArrayObjectSupport ? "YES": "NO")); 845 r.appendf("Use non-VBO for dynamic data: %s\n", 846 (fUseNonVBOVertexAndIndexDynamicData ? "YES" : "NO")); 847 r.appendf("Full screen clear is free: %s\n", (fFullClearIsFree ? "YES" : "NO")); 848 r.appendf("Drops tile on zero divide: %s\n", (fDropsTileOnZeroDivide ? "YES" : "NO")); 849 return r; 850 } 851