Home | History | Annotate | Download | only in gl
      1 
      2 /*
      3  * Copyright 2012 Google Inc.
      4  *
      5  * Use of this source code is governed by a BSD-style license that can be
      6  * found in the LICENSE file.
      7  */
      8 
      9 
     10 #include "GrGLCaps.h"
     11 #include "GrGLContextInfo.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     fMaxFragmentUniformVectors = 0;
     23     fRGBA8RenderbufferSupport = false;
     24     fBGRAFormatSupport = false;
     25     fBGRAIsInternalFormat = false;
     26     fTextureSwizzleSupport = false;
     27     fUnpackRowLengthSupport = false;
     28     fUnpackFlipYSupport = false;
     29     fPackRowLengthSupport = false;
     30     fPackFlipYSupport = false;
     31     fTextureUsageSupport = false;
     32     fTexStorageSupport = false;
     33 }
     34 
     35 GrGLCaps::GrGLCaps(const GrGLCaps& caps) {
     36     *this = caps;
     37 }
     38 
     39 GrGLCaps& GrGLCaps::operator = (const GrGLCaps& caps) {
     40     fVerifiedColorConfigs = caps.fVerifiedColorConfigs;
     41     fStencilFormats = caps.fStencilFormats;
     42     fStencilVerifiedColorConfigs = caps.fStencilVerifiedColorConfigs;
     43     fMaxFragmentUniformVectors = caps.fMaxFragmentUniformVectors;
     44     fMSFBOType = caps.fMSFBOType;
     45     fRGBA8RenderbufferSupport = caps.fRGBA8RenderbufferSupport;
     46     fBGRAFormatSupport = caps.fBGRAFormatSupport;
     47     fBGRAIsInternalFormat = caps.fBGRAIsInternalFormat;
     48     fTextureSwizzleSupport = caps.fTextureSwizzleSupport;
     49     fUnpackRowLengthSupport = caps.fUnpackRowLengthSupport;
     50     fUnpackFlipYSupport = caps.fUnpackFlipYSupport;
     51     fPackRowLengthSupport = caps.fPackRowLengthSupport;
     52     fPackFlipYSupport = caps.fPackFlipYSupport;
     53     fTextureUsageSupport = caps.fTextureUsageSupport;
     54     fTexStorageSupport = caps.fTexStorageSupport;
     55 
     56     return *this;
     57 }
     58 
     59 void GrGLCaps::init(const GrGLContextInfo& ctxInfo) {
     60 
     61     this->reset();
     62     if (!ctxInfo.isInitialized()) {
     63         return;
     64     }
     65 
     66     const GrGLInterface* gli = ctxInfo.interface();
     67     GrGLBinding binding = ctxInfo.binding();
     68     GrGLVersion version = ctxInfo.version();
     69 
     70     if (kES2_GrGLBinding == binding) {
     71         GR_GL_GetIntegerv(gli, GR_GL_MAX_FRAGMENT_UNIFORM_VECTORS,
     72                           &fMaxFragmentUniformVectors);
     73     } else {
     74         GrAssert(kDesktop_GrGLBinding == binding);
     75         GrGLint max;
     76         GR_GL_GetIntegerv(gli, GR_GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, &max);
     77         fMaxFragmentUniformVectors = max / 4;
     78     }
     79 
     80     if (kDesktop_GrGLBinding == binding) {
     81         fRGBA8RenderbufferSupport = true;
     82     } else {
     83         fRGBA8RenderbufferSupport = ctxInfo.hasExtension("GL_OES_rgb8_rgba8") ||
     84                                     ctxInfo.hasExtension("GL_ARM_rgba8");
     85     }
     86 
     87     if (kDesktop_GrGLBinding == binding) {
     88         fBGRAFormatSupport = version >= GR_GL_VER(1,2) ||
     89                              ctxInfo.hasExtension("GL_EXT_bgra");
     90     } else {
     91         bool hasBGRAExt = false;
     92         if (ctxInfo.hasExtension("GL_APPLE_texture_format_BGRA8888")) {
     93             fBGRAFormatSupport = true;
     94         } else if (ctxInfo.hasExtension("GL_EXT_texture_format_BGRA8888")) {
     95             fBGRAFormatSupport = true;
     96             fBGRAIsInternalFormat = true;
     97         }
     98         GrAssert(fBGRAFormatSupport ||
     99                  kSkia8888_PM_GrPixelConfig != kBGRA_8888_PM_GrPixelConfig);
    100     }
    101 
    102     if (kDesktop_GrGLBinding == binding) {
    103         fTextureSwizzleSupport = version >= GR_GL_VER(3,3) ||
    104                                  ctxInfo.hasExtension("GL_ARB_texture_swizzle");
    105     } else {
    106         fTextureSwizzleSupport = false;
    107     }
    108 
    109     if (kDesktop_GrGLBinding == binding) {
    110         fUnpackRowLengthSupport = true;
    111         fUnpackFlipYSupport = false;
    112         fPackRowLengthSupport = true;
    113         fPackFlipYSupport = false;
    114     } else {
    115         fUnpackRowLengthSupport =ctxInfo.hasExtension("GL_EXT_unpack_subimage");
    116         fUnpackFlipYSupport = ctxInfo.hasExtension("GL_CHROMIUM_flipy");
    117         // no extension for pack row length
    118         fPackRowLengthSupport = false;
    119         fPackFlipYSupport =
    120             ctxInfo.hasExtension("GL_ANGLE_pack_reverse_row_order");
    121     }
    122 
    123     fTextureUsageSupport = (kES2_GrGLBinding == binding) &&
    124                             ctxInfo.hasExtension("GL_ANGLE_texture_usage");
    125 
    126     // Tex storage is in desktop 4.2 and can be an extension to desktop or ES.
    127     fTexStorageSupport = (kDesktop_GrGLBinding == binding &&
    128                           version >= GR_GL_VER(4,2)) ||
    129                          ctxInfo.hasExtension("GL_ARB_texture_storage") ||
    130                          ctxInfo.hasExtension("GL_EXT_texture_storage");
    131 
    132     this->initFSAASupport(ctxInfo);
    133     this->initStencilFormats(ctxInfo);
    134 }
    135 
    136 void GrGLCaps::initFSAASupport(const GrGLContextInfo& ctxInfo) {
    137 
    138     fMSFBOType = kNone_MSFBOType;
    139     if (kDesktop_GrGLBinding != ctxInfo.binding()) {
    140        if (ctxInfo.hasExtension("GL_CHROMIUM_framebuffer_multisample")) {
    141            // chrome's extension is equivalent to the EXT msaa
    142            // and fbo_blit extensions.
    143            fMSFBOType = kDesktopEXT_MSFBOType;
    144        } else if (ctxInfo.hasExtension("GL_APPLE_framebuffer_multisample")) {
    145             fMSFBOType = kAppleES_MSFBOType;
    146         }
    147     } else {
    148         if ((ctxInfo.version() >= GR_GL_VER(3,0)) ||
    149             ctxInfo.hasExtension("GL_ARB_framebuffer_object")) {
    150             fMSFBOType = GrGLCaps::kDesktopARB_MSFBOType;
    151         } else if (ctxInfo.hasExtension("GL_EXT_framebuffer_multisample") &&
    152                    ctxInfo.hasExtension("GL_EXT_framebuffer_blit")) {
    153             fMSFBOType = GrGLCaps::kDesktopEXT_MSFBOType;
    154         }
    155     }
    156 }
    157 
    158 namespace {
    159 const GrGLuint kUnknownBitCount = GrGLStencilBuffer::kUnknownBitCount;
    160 }
    161 
    162 void GrGLCaps::initStencilFormats(const GrGLContextInfo& ctxInfo) {
    163 
    164     // Build up list of legal stencil formats (though perhaps not supported on
    165     // the particular gpu/driver) from most preferred to least.
    166 
    167     // these consts are in order of most preferred to least preferred
    168     // we don't bother with GL_STENCIL_INDEX1 or GL_DEPTH32F_STENCIL8
    169 
    170     static const StencilFormat
    171                   // internal Format      stencil bits      total bits        packed?
    172         gS8    = {GR_GL_STENCIL_INDEX8,   8,                8,                false},
    173         gS16   = {GR_GL_STENCIL_INDEX16,  16,               16,               false},
    174         gD24S8 = {GR_GL_DEPTH24_STENCIL8, 8,                32,               true },
    175         gS4    = {GR_GL_STENCIL_INDEX4,   4,                4,                false},
    176         gS     = {GR_GL_STENCIL_INDEX,    kUnknownBitCount, kUnknownBitCount, false},
    177         gDS    = {GR_GL_DEPTH_STENCIL,    kUnknownBitCount, kUnknownBitCount, true };
    178 
    179     if (kDesktop_GrGLBinding == ctxInfo.binding()) {
    180         bool supportsPackedDS =
    181             ctxInfo.version() >= GR_GL_VER(3,0) ||
    182             ctxInfo.hasExtension("GL_EXT_packed_depth_stencil") ||
    183             ctxInfo.hasExtension("GL_ARB_framebuffer_object");
    184 
    185         // S1 thru S16 formats are in GL 3.0+, EXT_FBO, and ARB_FBO since we
    186         // require FBO support we can expect these are legal formats and don't
    187         // check. These also all support the unsized GL_STENCIL_INDEX.
    188         fStencilFormats.push_back() = gS8;
    189         fStencilFormats.push_back() = gS16;
    190         if (supportsPackedDS) {
    191             fStencilFormats.push_back() = gD24S8;
    192         }
    193         fStencilFormats.push_back() = gS4;
    194         if (supportsPackedDS) {
    195             fStencilFormats.push_back() = gDS;
    196         }
    197     } else {
    198         // ES2 has STENCIL_INDEX8 without extensions but requires extensions
    199         // for other formats.
    200         // ES doesn't support using the unsized format.
    201 
    202         fStencilFormats.push_back() = gS8;
    203         //fStencilFormats.push_back() = gS16;
    204         if (ctxInfo.hasExtension("GL_OES_packed_depth_stencil")) {
    205             fStencilFormats.push_back() = gD24S8;
    206         }
    207         if (ctxInfo.hasExtension("GL_OES_stencil4")) {
    208             fStencilFormats.push_back() = gS4;
    209         }
    210     }
    211     GrAssert(0 == fStencilVerifiedColorConfigs.count());
    212     fStencilVerifiedColorConfigs.push_back_n(fStencilFormats.count());
    213 }
    214 
    215 void GrGLCaps::markColorConfigAndStencilFormatAsVerified(
    216                                     GrPixelConfig config,
    217                                     const GrGLStencilBuffer::Format& format) {
    218 #if !GR_GL_CHECK_FBO_STATUS_ONCE_PER_FORMAT
    219     return;
    220 #endif
    221     GrAssert((unsigned)config < kGrPixelConfigCount);
    222     GrAssert(fStencilFormats.count() == fStencilVerifiedColorConfigs.count());
    223     int count = fStencilFormats.count();
    224     // we expect a really small number of possible formats so linear search
    225     // should be OK
    226     GrAssert(count < 16);
    227     for (int i = 0; i < count; ++i) {
    228         if (format.fInternalFormat ==
    229             fStencilFormats[i].fInternalFormat) {
    230             fStencilVerifiedColorConfigs[i].markVerified(config);
    231             return;
    232         }
    233     }
    234     GrCrash("Why are we seeing a stencil format that "
    235             "GrGLCaps doesn't know about.");
    236 }
    237 
    238 bool GrGLCaps::isColorConfigAndStencilFormatVerified(
    239                                 GrPixelConfig config,
    240                                 const GrGLStencilBuffer::Format& format) const {
    241 #if !GR_GL_CHECK_FBO_STATUS_ONCE_PER_FORMAT
    242     return false;
    243 #endif
    244     GrAssert((unsigned)config < kGrPixelConfigCount);
    245     int count = fStencilFormats.count();
    246     // we expect a really small number of possible formats so linear search
    247     // should be OK
    248     GrAssert(count < 16);
    249     for (int i = 0; i < count; ++i) {
    250         if (format.fInternalFormat ==
    251             fStencilFormats[i].fInternalFormat) {
    252             return fStencilVerifiedColorConfigs[i].isVerified(config);
    253         }
    254     }
    255     GrCrash("Why are we seeing a stencil format that "
    256             "GLCaps doesn't know about.");
    257     return false;
    258 }
    259 
    260 void GrGLCaps::print() const {
    261     for (int i = 0; i < fStencilFormats.count(); ++i) {
    262         GrPrintf("Stencil Format %d, stencil bits: %02d, total bits: %02d\n",
    263                  i,
    264                  fStencilFormats[i].fStencilBits,
    265                  fStencilFormats[i].fTotalBits);
    266     }
    267 
    268     GR_STATIC_ASSERT(0 == kNone_MSFBOType);
    269     GR_STATIC_ASSERT(1 == kDesktopARB_MSFBOType);
    270     GR_STATIC_ASSERT(2 == kDesktopEXT_MSFBOType);
    271     GR_STATIC_ASSERT(3 == kAppleES_MSFBOType);
    272     static const char* gMSFBOExtStr[] = {
    273         "None",
    274         "ARB",
    275         "EXT",
    276         "Apple",
    277     };
    278     GrPrintf("MSAA Type: %s\n", gMSFBOExtStr[fMSFBOType]);
    279     GrPrintf("Max FS Uniform Vectors: %d\n", fMaxFragmentUniformVectors);
    280     GrPrintf("Support RGBA8 Render Buffer: %s\n",
    281              (fRGBA8RenderbufferSupport ? "YES": "NO"));
    282     GrPrintf("BGRA is an internal format: %s\n",
    283              (fBGRAIsInternalFormat ? "YES": "NO"));
    284     GrPrintf("Support texture swizzle: %s\n",
    285              (fTextureSwizzleSupport ? "YES": "NO"));
    286     GrPrintf("Unpack Row length support: %s\n",
    287              (fUnpackRowLengthSupport ? "YES": "NO"));
    288     GrPrintf("Unpack Flip Y support: %s\n",
    289              (fUnpackFlipYSupport ? "YES": "NO"));
    290     GrPrintf("Pack Row length support: %s\n",
    291              (fPackRowLengthSupport ? "YES": "NO"));
    292     GrPrintf("Pack Flip Y support: %s\n",
    293              (fPackFlipYSupport ? "YES": "NO"));
    294 }
    295 
    296