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