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 "GrGLContextInfo.h" 11 #include "SkTSearch.h" 12 13 GrGLCaps::GrGLCaps() { 14 this->reset(); 15 } 16 17 void GrGLCaps::reset() { 18 fVerifiedColorConfigs.reset(); 19 fStencilFormats.reset(); 20 fStencilVerifiedColorConfigs.reset(); 21 fMSFBOType = kNone_MSFBOType; 22 fMaxSampleCount = 0; 23 fCoverageAAType = kNone_CoverageAAType; 24 fMaxFragmentUniformVectors = 0; 25 fMaxVertexAttributes = 0; 26 fRGBA8RenderbufferSupport = false; 27 fBGRAFormatSupport = false; 28 fBGRAIsInternalFormat = false; 29 fTextureSwizzleSupport = false; 30 fUnpackRowLengthSupport = false; 31 fUnpackFlipYSupport = false; 32 fPackRowLengthSupport = false; 33 fPackFlipYSupport = false; 34 fTextureUsageSupport = false; 35 fTexStorageSupport = false; 36 fTextureRedSupport = false; 37 fImagingSupport = false; 38 fTwoFormatLimit = false; 39 fFragCoordsConventionSupport = false; 40 } 41 42 GrGLCaps::GrGLCaps(const GrGLCaps& caps) { 43 *this = caps; 44 } 45 46 GrGLCaps& GrGLCaps::operator = (const GrGLCaps& caps) { 47 fVerifiedColorConfigs = caps.fVerifiedColorConfigs; 48 fStencilFormats = caps.fStencilFormats; 49 fStencilVerifiedColorConfigs = caps.fStencilVerifiedColorConfigs; 50 fMaxFragmentUniformVectors = caps.fMaxFragmentUniformVectors; 51 fMaxVertexAttributes = caps.fMaxVertexAttributes; 52 fMSFBOType = caps.fMSFBOType; 53 fMaxSampleCount = caps.fMaxSampleCount; 54 fCoverageAAType = caps.fCoverageAAType; 55 fMSAACoverageModes = caps.fMSAACoverageModes; 56 fRGBA8RenderbufferSupport = caps.fRGBA8RenderbufferSupport; 57 fBGRAFormatSupport = caps.fBGRAFormatSupport; 58 fBGRAIsInternalFormat = caps.fBGRAIsInternalFormat; 59 fTextureSwizzleSupport = caps.fTextureSwizzleSupport; 60 fUnpackRowLengthSupport = caps.fUnpackRowLengthSupport; 61 fUnpackFlipYSupport = caps.fUnpackFlipYSupport; 62 fPackRowLengthSupport = caps.fPackRowLengthSupport; 63 fPackFlipYSupport = caps.fPackFlipYSupport; 64 fTextureUsageSupport = caps.fTextureUsageSupport; 65 fTexStorageSupport = caps.fTexStorageSupport; 66 fTextureRedSupport = caps.fTextureRedSupport; 67 fImagingSupport = caps.fImagingSupport; 68 fTwoFormatLimit = caps.fTwoFormatLimit; 69 fFragCoordsConventionSupport = caps.fFragCoordsConventionSupport; 70 71 return *this; 72 } 73 74 void GrGLCaps::init(const GrGLContextInfo& ctxInfo) { 75 76 this->reset(); 77 if (!ctxInfo.isInitialized()) { 78 return; 79 } 80 81 const GrGLInterface* gli = ctxInfo.interface(); 82 GrGLBinding binding = ctxInfo.binding(); 83 GrGLVersion version = ctxInfo.version(); 84 85 if (kES2_GrGLBinding == binding) { 86 GR_GL_GetIntegerv(gli, GR_GL_MAX_FRAGMENT_UNIFORM_VECTORS, 87 &fMaxFragmentUniformVectors); 88 } else { 89 GrAssert(kDesktop_GrGLBinding == binding); 90 GrGLint max; 91 GR_GL_GetIntegerv(gli, GR_GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, &max); 92 fMaxFragmentUniformVectors = max / 4; 93 } 94 GR_GL_GetIntegerv(gli, GR_GL_MAX_VERTEX_ATTRIBS, &fMaxVertexAttributes); 95 96 if (kDesktop_GrGLBinding == binding) { 97 fRGBA8RenderbufferSupport = true; 98 } else { 99 fRGBA8RenderbufferSupport = ctxInfo.hasExtension("GL_OES_rgb8_rgba8") || 100 ctxInfo.hasExtension("GL_ARM_rgba8"); 101 } 102 103 if (kDesktop_GrGLBinding == binding) { 104 fBGRAFormatSupport = version >= GR_GL_VER(1,2) || 105 ctxInfo.hasExtension("GL_EXT_bgra"); 106 } else { 107 if (ctxInfo.hasExtension("GL_APPLE_texture_format_BGRA8888")) { 108 fBGRAFormatSupport = true; 109 } else if (ctxInfo.hasExtension("GL_EXT_texture_format_BGRA8888")) { 110 fBGRAFormatSupport = true; 111 fBGRAIsInternalFormat = true; 112 } 113 GrAssert(fBGRAFormatSupport || 114 kSkia8888_GrPixelConfig != kBGRA_8888_GrPixelConfig); 115 } 116 117 if (kDesktop_GrGLBinding == binding) { 118 fTextureSwizzleSupport = version >= GR_GL_VER(3,3) || 119 ctxInfo.hasExtension("GL_ARB_texture_swizzle"); 120 } else { 121 fTextureSwizzleSupport = false; 122 } 123 124 if (kDesktop_GrGLBinding == binding) { 125 fUnpackRowLengthSupport = true; 126 fUnpackFlipYSupport = false; 127 fPackRowLengthSupport = true; 128 fPackFlipYSupport = false; 129 } else { 130 fUnpackRowLengthSupport =ctxInfo.hasExtension("GL_EXT_unpack_subimage"); 131 fUnpackFlipYSupport = ctxInfo.hasExtension("GL_CHROMIUM_flipy"); 132 // no extension for pack row length 133 fPackRowLengthSupport = false; 134 fPackFlipYSupport = 135 ctxInfo.hasExtension("GL_ANGLE_pack_reverse_row_order"); 136 } 137 138 fTextureUsageSupport = (kES2_GrGLBinding == binding) && 139 ctxInfo.hasExtension("GL_ANGLE_texture_usage"); 140 141 // Tex storage is in desktop 4.2 and can be an extension to desktop or ES. 142 fTexStorageSupport = (kDesktop_GrGLBinding == binding && 143 version >= GR_GL_VER(4,2)) || 144 ctxInfo.hasExtension("GL_ARB_texture_storage") || 145 ctxInfo.hasExtension("GL_EXT_texture_storage"); 146 147 // ARB_texture_rg is part of OpenGL 3.0 148 if (kDesktop_GrGLBinding == binding) { 149 fTextureRedSupport = version >= GR_GL_VER(3,0) || 150 ctxInfo.hasExtension("GL_ARB_texture_rg"); 151 } else { 152 fTextureRedSupport = ctxInfo.hasExtension("GL_EXT_texture_rg"); 153 } 154 155 fImagingSupport = kDesktop_GrGLBinding == binding && 156 ctxInfo.hasExtension("GL_ARB_imaging"); 157 158 // ES 2 only guarantees RGBA/uchar + one other format/type combo for 159 // ReadPixels. The other format has to checked at run-time since it 160 // can change based on which render target is bound 161 fTwoFormatLimit = kES2_GrGLBinding == binding; 162 163 // Known issue on at least some Intel platforms: 164 // http://code.google.com/p/skia/issues/detail?id=946 165 if (kIntel_GrGLVendor != ctxInfo.vendor()) { 166 fFragCoordsConventionSupport = ctxInfo.glslGeneration() >= k150_GrGLSLGeneration || 167 ctxInfo.hasExtension("GL_ARB_fragment_coord_conventions"); 168 } 169 170 this->initFSAASupport(ctxInfo); 171 this->initStencilFormats(ctxInfo); 172 } 173 174 bool GrGLCaps::readPixelsSupported(const GrGLInterface* intf, 175 GrGLenum format, 176 GrGLenum type) const { 177 if (GR_GL_RGBA == format && GR_GL_UNSIGNED_BYTE == type) { 178 // ES 2 guarantees this format is supported 179 return true; 180 } 181 182 if (!fTwoFormatLimit) { 183 // not limited by ES 2's constraints 184 return true; 185 } 186 187 GrGLint otherFormat = GR_GL_RGBA; 188 GrGLint otherType = GR_GL_UNSIGNED_BYTE; 189 190 // The other supported format/type combo supported for ReadPixels 191 // can change based on which render target is bound 192 GR_GL_GetIntegerv(intf, 193 GR_GL_IMPLEMENTATION_COLOR_READ_FORMAT, 194 &otherFormat); 195 196 GR_GL_GetIntegerv(intf, 197 GR_GL_IMPLEMENTATION_COLOR_READ_TYPE, 198 &otherType); 199 200 return (GrGLenum)otherFormat == format && (GrGLenum)otherType == type; 201 } 202 203 namespace { 204 int coverage_mode_compare(const GrGLCaps::MSAACoverageMode* left, 205 const GrGLCaps::MSAACoverageMode* right) { 206 if (left->fCoverageSampleCnt < right->fCoverageSampleCnt) { 207 return -1; 208 } else if (right->fCoverageSampleCnt < left->fCoverageSampleCnt) { 209 return 1; 210 } else if (left->fColorSampleCnt < right->fColorSampleCnt) { 211 return -1; 212 } else if (right->fColorSampleCnt < left->fColorSampleCnt) { 213 return 1; 214 } 215 return 0; 216 } 217 } 218 219 void GrGLCaps::initFSAASupport(const GrGLContextInfo& ctxInfo) { 220 221 fMSFBOType = kNone_MSFBOType; 222 if (kDesktop_GrGLBinding != ctxInfo.binding()) { 223 if (ctxInfo.hasExtension("GL_CHROMIUM_framebuffer_multisample")) { 224 // chrome's extension is equivalent to the EXT msaa 225 // and fbo_blit extensions. 226 fMSFBOType = kDesktopEXT_MSFBOType; 227 } else if (ctxInfo.hasExtension("GL_APPLE_framebuffer_multisample")) { 228 fMSFBOType = kAppleES_MSFBOType; 229 } 230 } else { 231 if ((ctxInfo.version() >= GR_GL_VER(3,0)) || 232 ctxInfo.hasExtension("GL_ARB_framebuffer_object")) { 233 fMSFBOType = GrGLCaps::kDesktopARB_MSFBOType; 234 } else if (ctxInfo.hasExtension("GL_EXT_framebuffer_multisample") && 235 ctxInfo.hasExtension("GL_EXT_framebuffer_blit")) { 236 fMSFBOType = GrGLCaps::kDesktopEXT_MSFBOType; 237 } 238 // TODO: We could populate fMSAACoverageModes using GetInternalformativ 239 // on GL 4.2+. It's format-specific, though. See also 240 // http://code.google.com/p/skia/issues/detail?id=470 about using actual 241 // rather than requested sample counts in cache key. 242 if (ctxInfo.hasExtension("GL_NV_framebuffer_multisample_coverage")) { 243 fCoverageAAType = kNVDesktop_CoverageAAType; 244 GrGLint count; 245 GR_GL_GetIntegerv(ctxInfo.interface(), 246 GR_GL_MAX_MULTISAMPLE_COVERAGE_MODES, 247 &count); 248 fMSAACoverageModes.setCount(count); 249 GR_GL_GetIntegerv(ctxInfo.interface(), 250 GR_GL_MULTISAMPLE_COVERAGE_MODES, 251 (int*)&fMSAACoverageModes[0]); 252 // The NV driver seems to return the modes already sorted but the 253 // spec doesn't require this. So we sort. 254 qsort(&fMSAACoverageModes[0], 255 count, 256 sizeof(MSAACoverageMode), 257 SkCastForQSort(coverage_mode_compare)); 258 } 259 } 260 if (kNone_MSFBOType != fMSFBOType) { 261 GR_GL_GetIntegerv(ctxInfo.interface(), 262 GR_GL_MAX_SAMPLES, 263 &fMaxSampleCount); 264 } 265 } 266 267 const GrGLCaps::MSAACoverageMode& GrGLCaps::getMSAACoverageMode( 268 int desiredSampleCount) const { 269 static const MSAACoverageMode kNoneMode = {0, 0}; 270 if (0 == fMSAACoverageModes.count()) { 271 return kNoneMode; 272 } else { 273 GrAssert(kNone_CoverageAAType != fCoverageAAType); 274 int max = (fMSAACoverageModes.end() - 1)->fCoverageSampleCnt; 275 desiredSampleCount = GrMin(desiredSampleCount, max); 276 MSAACoverageMode desiredMode = {desiredSampleCount, 0}; 277 int idx = SkTSearch<MSAACoverageMode>(&fMSAACoverageModes[0], 278 fMSAACoverageModes.count(), 279 desiredMode, 280 sizeof(MSAACoverageMode), 281 &coverage_mode_compare); 282 if (idx < 0) { 283 idx = ~idx; 284 } 285 GrAssert(idx >= 0 && idx < fMSAACoverageModes.count()); 286 return fMSAACoverageModes[idx]; 287 } 288 } 289 290 namespace { 291 const GrGLuint kUnknownBitCount = GrGLStencilBuffer::kUnknownBitCount; 292 } 293 294 void GrGLCaps::initStencilFormats(const GrGLContextInfo& ctxInfo) { 295 296 // Build up list of legal stencil formats (though perhaps not supported on 297 // the particular gpu/driver) from most preferred to least. 298 299 // these consts are in order of most preferred to least preferred 300 // we don't bother with GL_STENCIL_INDEX1 or GL_DEPTH32F_STENCIL8 301 302 static const StencilFormat 303 // internal Format stencil bits total bits packed? 304 gS8 = {GR_GL_STENCIL_INDEX8, 8, 8, false}, 305 gS16 = {GR_GL_STENCIL_INDEX16, 16, 16, false}, 306 gD24S8 = {GR_GL_DEPTH24_STENCIL8, 8, 32, true }, 307 gS4 = {GR_GL_STENCIL_INDEX4, 4, 4, false}, 308 // gS = {GR_GL_STENCIL_INDEX, kUnknownBitCount, kUnknownBitCount, false}, 309 gDS = {GR_GL_DEPTH_STENCIL, kUnknownBitCount, kUnknownBitCount, true }; 310 311 if (kDesktop_GrGLBinding == ctxInfo.binding()) { 312 bool supportsPackedDS = 313 ctxInfo.version() >= GR_GL_VER(3,0) || 314 ctxInfo.hasExtension("GL_EXT_packed_depth_stencil") || 315 ctxInfo.hasExtension("GL_ARB_framebuffer_object"); 316 317 // S1 thru S16 formats are in GL 3.0+, EXT_FBO, and ARB_FBO since we 318 // require FBO support we can expect these are legal formats and don't 319 // check. These also all support the unsized GL_STENCIL_INDEX. 320 fStencilFormats.push_back() = gS8; 321 fStencilFormats.push_back() = gS16; 322 if (supportsPackedDS) { 323 fStencilFormats.push_back() = gD24S8; 324 } 325 fStencilFormats.push_back() = gS4; 326 if (supportsPackedDS) { 327 fStencilFormats.push_back() = gDS; 328 } 329 } else { 330 // ES2 has STENCIL_INDEX8 without extensions but requires extensions 331 // for other formats. 332 // ES doesn't support using the unsized format. 333 334 fStencilFormats.push_back() = gS8; 335 //fStencilFormats.push_back() = gS16; 336 if (ctxInfo.hasExtension("GL_OES_packed_depth_stencil")) { 337 fStencilFormats.push_back() = gD24S8; 338 } 339 if (ctxInfo.hasExtension("GL_OES_stencil4")) { 340 fStencilFormats.push_back() = gS4; 341 } 342 } 343 GrAssert(0 == fStencilVerifiedColorConfigs.count()); 344 fStencilVerifiedColorConfigs.push_back_n(fStencilFormats.count()); 345 } 346 347 void GrGLCaps::markColorConfigAndStencilFormatAsVerified( 348 GrPixelConfig config, 349 const GrGLStencilBuffer::Format& format) { 350 #if !GR_GL_CHECK_FBO_STATUS_ONCE_PER_FORMAT 351 return; 352 #endif 353 GrAssert((unsigned)config < kGrPixelConfigCount); 354 GrAssert(fStencilFormats.count() == fStencilVerifiedColorConfigs.count()); 355 int count = fStencilFormats.count(); 356 // we expect a really small number of possible formats so linear search 357 // should be OK 358 GrAssert(count < 16); 359 for (int i = 0; i < count; ++i) { 360 if (format.fInternalFormat == 361 fStencilFormats[i].fInternalFormat) { 362 fStencilVerifiedColorConfigs[i].markVerified(config); 363 return; 364 } 365 } 366 GrCrash("Why are we seeing a stencil format that " 367 "GrGLCaps doesn't know about."); 368 } 369 370 bool GrGLCaps::isColorConfigAndStencilFormatVerified( 371 GrPixelConfig config, 372 const GrGLStencilBuffer::Format& format) const { 373 #if !GR_GL_CHECK_FBO_STATUS_ONCE_PER_FORMAT 374 return false; 375 #endif 376 GrAssert((unsigned)config < kGrPixelConfigCount); 377 int count = fStencilFormats.count(); 378 // we expect a really small number of possible formats so linear search 379 // should be OK 380 GrAssert(count < 16); 381 for (int i = 0; i < count; ++i) { 382 if (format.fInternalFormat == 383 fStencilFormats[i].fInternalFormat) { 384 return fStencilVerifiedColorConfigs[i].isVerified(config); 385 } 386 } 387 GrCrash("Why are we seeing a stencil format that " 388 "GLCaps doesn't know about."); 389 return false; 390 } 391 392 void GrGLCaps::print() const { 393 for (int i = 0; i < fStencilFormats.count(); ++i) { 394 GrPrintf("Stencil Format %d, stencil bits: %02d, total bits: %02d\n", 395 i, 396 fStencilFormats[i].fStencilBits, 397 fStencilFormats[i].fTotalBits); 398 } 399 400 GR_STATIC_ASSERT(0 == kNone_MSFBOType); 401 GR_STATIC_ASSERT(1 == kDesktopARB_MSFBOType); 402 GR_STATIC_ASSERT(2 == kDesktopEXT_MSFBOType); 403 GR_STATIC_ASSERT(3 == kAppleES_MSFBOType); 404 static const char* gMSFBOExtStr[] = { 405 "None", 406 "ARB", 407 "EXT", 408 "Apple", 409 }; 410 GrPrintf("MSAA Type: %s\n", gMSFBOExtStr[fMSFBOType]); 411 GrPrintf("Max FS Uniform Vectors: %d\n", fMaxFragmentUniformVectors); 412 GrPrintf("Support RGBA8 Render Buffer: %s\n", 413 (fRGBA8RenderbufferSupport ? "YES": "NO")); 414 GrPrintf("BGRA is an internal format: %s\n", 415 (fBGRAIsInternalFormat ? "YES": "NO")); 416 GrPrintf("Support texture swizzle: %s\n", 417 (fTextureSwizzleSupport ? "YES": "NO")); 418 GrPrintf("Unpack Row length support: %s\n", 419 (fUnpackRowLengthSupport ? "YES": "NO")); 420 GrPrintf("Unpack Flip Y support: %s\n", 421 (fUnpackFlipYSupport ? "YES": "NO")); 422 GrPrintf("Pack Row length support: %s\n", 423 (fPackRowLengthSupport ? "YES": "NO")); 424 GrPrintf("Pack Flip Y support: %s\n", 425 (fPackFlipYSupport ? "YES": "NO")); 426 GrPrintf("Two Format Limit: %s\n", (fTwoFormatLimit ? "YES": "NO")); 427 GrPrintf("Fragment coord conventions support: %s\n", (fFragCoordsConventionSupport ? "YES": "NO")); 428 } 429