Home | History | Annotate | Download | only in gl
      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