Home | History | Annotate | Download | only in gl
      1 
      2 /*
      3  * Copyright 2011 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 "GrGpuGL.h"
     11 #include "GrGLStencilBuffer.h"
     12 #include "GrTypes.h"
     13 #include "SkTemplates.h"
     14 
     15 static const GrGLuint GR_MAX_GLUINT = ~0;
     16 static const GrGLint  GR_INVAL_GLINT = ~0;
     17 
     18 #define GL_CALL(X) GR_GL_CALL(this->glInterface(), X)
     19 #define GL_CALL_RET(RET, X) GR_GL_CALL_RET(this->glInterface(), RET, X)
     20 
     21 // we use a spare texture unit to avoid
     22 // mucking with the state of any of the stages.
     23 static const int SPARE_TEX_UNIT = GrDrawState::kNumStages;
     24 
     25 #define SKIP_CACHE_CHECK    true
     26 
     27 #if GR_GL_CHECK_ALLOC_WITH_GET_ERROR
     28     #define CLEAR_ERROR_BEFORE_ALLOC(iface)   GrGLClearErr(iface)
     29     #define GL_ALLOC_CALL(iface, call)        GR_GL_CALL_NOERRCHECK(iface, call)
     30     #define CHECK_ALLOC_ERROR(iface)          GR_GL_GET_ERROR(iface)
     31 #else
     32     #define CLEAR_ERROR_BEFORE_ALLOC(iface)
     33     #define GL_ALLOC_CALL(iface, call)        GR_GL_CALL(iface, call)
     34     #define CHECK_ALLOC_ERROR(iface)          GR_GL_NO_ERROR
     35 #endif
     36 
     37 
     38 ///////////////////////////////////////////////////////////////////////////////
     39 
     40 static const GrGLenum gXfermodeCoeff2Blend[] = {
     41     GR_GL_ZERO,
     42     GR_GL_ONE,
     43     GR_GL_SRC_COLOR,
     44     GR_GL_ONE_MINUS_SRC_COLOR,
     45     GR_GL_DST_COLOR,
     46     GR_GL_ONE_MINUS_DST_COLOR,
     47     GR_GL_SRC_ALPHA,
     48     GR_GL_ONE_MINUS_SRC_ALPHA,
     49     GR_GL_DST_ALPHA,
     50     GR_GL_ONE_MINUS_DST_ALPHA,
     51     GR_GL_CONSTANT_COLOR,
     52     GR_GL_ONE_MINUS_CONSTANT_COLOR,
     53     GR_GL_CONSTANT_ALPHA,
     54     GR_GL_ONE_MINUS_CONSTANT_ALPHA,
     55 
     56     // extended blend coeffs
     57     GR_GL_SRC1_COLOR,
     58     GR_GL_ONE_MINUS_SRC1_COLOR,
     59     GR_GL_SRC1_ALPHA,
     60     GR_GL_ONE_MINUS_SRC1_ALPHA,
     61 };
     62 
     63 bool GrGpuGL::BlendCoeffReferencesConstant(GrBlendCoeff coeff) {
     64     static const bool gCoeffReferencesBlendConst[] = {
     65         false,
     66         false,
     67         false,
     68         false,
     69         false,
     70         false,
     71         false,
     72         false,
     73         false,
     74         false,
     75         true,
     76         true,
     77         true,
     78         true,
     79 
     80         // extended blend coeffs
     81         false,
     82         false,
     83         false,
     84         false,
     85     };
     86     return gCoeffReferencesBlendConst[coeff];
     87     GR_STATIC_ASSERT(kTotalBlendCoeffCount == GR_ARRAY_COUNT(gCoeffReferencesBlendConst));
     88 
     89     GR_STATIC_ASSERT(0 == kZero_BlendCoeff);
     90     GR_STATIC_ASSERT(1 == kOne_BlendCoeff);
     91     GR_STATIC_ASSERT(2 == kSC_BlendCoeff);
     92     GR_STATIC_ASSERT(3 == kISC_BlendCoeff);
     93     GR_STATIC_ASSERT(4 == kDC_BlendCoeff);
     94     GR_STATIC_ASSERT(5 == kIDC_BlendCoeff);
     95     GR_STATIC_ASSERT(6 == kSA_BlendCoeff);
     96     GR_STATIC_ASSERT(7 == kISA_BlendCoeff);
     97     GR_STATIC_ASSERT(8 == kDA_BlendCoeff);
     98     GR_STATIC_ASSERT(9 == kIDA_BlendCoeff);
     99     GR_STATIC_ASSERT(10 == kConstC_BlendCoeff);
    100     GR_STATIC_ASSERT(11 == kIConstC_BlendCoeff);
    101     GR_STATIC_ASSERT(12 == kConstA_BlendCoeff);
    102     GR_STATIC_ASSERT(13 == kIConstA_BlendCoeff);
    103 
    104     GR_STATIC_ASSERT(14 == kS2C_BlendCoeff);
    105     GR_STATIC_ASSERT(15 == kIS2C_BlendCoeff);
    106     GR_STATIC_ASSERT(16 == kS2A_BlendCoeff);
    107     GR_STATIC_ASSERT(17 == kIS2A_BlendCoeff);
    108 
    109     // assertion for gXfermodeCoeff2Blend have to be in GrGpu scope
    110     GR_STATIC_ASSERT(kTotalBlendCoeffCount == GR_ARRAY_COUNT(gXfermodeCoeff2Blend));
    111 }
    112 
    113 ///////////////////////////////////////////////////////////////////////////////
    114 
    115 void GrGpuGL::AdjustTextureMatrix(const GrGLTexture* texture,
    116                                   GrSamplerState::SampleMode mode,
    117                                   GrMatrix* matrix) {
    118     GrAssert(NULL != texture);
    119     GrAssert(NULL != matrix);
    120     GrGLTexture::Orientation orientation = texture->orientation();
    121     if (GrGLTexture::kBottomUp_Orientation == orientation) {
    122         GrMatrix invY;
    123         invY.setAll(GR_Scalar1, 0,           0,
    124                     0,          -GR_Scalar1, GR_Scalar1,
    125                     0,          0,           GrMatrix::I()[8]);
    126         matrix->postConcat(invY);
    127     } else {
    128         GrAssert(GrGLTexture::kTopDown_Orientation == orientation);
    129     }
    130 }
    131 
    132 bool GrGpuGL::TextureMatrixIsIdentity(const GrGLTexture* texture,
    133                                       const GrSamplerState& sampler) {
    134     GrAssert(NULL != texture);
    135     if (!sampler.getMatrix().isIdentity()) {
    136         return false;
    137     }
    138     GrGLTexture::Orientation orientation = texture->orientation();
    139     if (GrGLTexture::kBottomUp_Orientation == orientation) {
    140         return false;
    141     } else {
    142         GrAssert(GrGLTexture::kTopDown_Orientation == orientation);
    143     }
    144     return true;
    145 }
    146 
    147 ///////////////////////////////////////////////////////////////////////////////
    148 
    149 static bool gPrintStartupSpew;
    150 
    151 static bool fbo_test(const GrGLInterface* gl, int w, int h) {
    152 
    153     GR_GL_CALL(gl, ActiveTexture(GR_GL_TEXTURE0 + SPARE_TEX_UNIT));
    154 
    155     GrGLuint testFBO;
    156     GR_GL_CALL(gl, GenFramebuffers(1, &testFBO));
    157     GR_GL_CALL(gl, BindFramebuffer(GR_GL_FRAMEBUFFER, testFBO));
    158     GrGLuint testRTTex;
    159     GR_GL_CALL(gl, GenTextures(1, &testRTTex));
    160     GR_GL_CALL(gl, BindTexture(GR_GL_TEXTURE_2D, testRTTex));
    161     // some implementations require texture to be mip-map complete before
    162     // FBO with level 0 bound as color attachment will be framebuffer complete.
    163     GR_GL_CALL(gl, TexParameteri(GR_GL_TEXTURE_2D,
    164                                  GR_GL_TEXTURE_MIN_FILTER,
    165                                  GR_GL_NEAREST));
    166     GR_GL_CALL(gl, TexImage2D(GR_GL_TEXTURE_2D, 0, GR_GL_RGBA, w, h,
    167                               0, GR_GL_RGBA, GR_GL_UNSIGNED_BYTE, NULL));
    168     GR_GL_CALL(gl, BindTexture(GR_GL_TEXTURE_2D, 0));
    169     GR_GL_CALL(gl, FramebufferTexture2D(GR_GL_FRAMEBUFFER,
    170                                         GR_GL_COLOR_ATTACHMENT0,
    171                                         GR_GL_TEXTURE_2D, testRTTex, 0));
    172     GrGLenum status;
    173     GR_GL_CALL_RET(gl, status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER));
    174     GR_GL_CALL(gl, DeleteFramebuffers(1, &testFBO));
    175     GR_GL_CALL(gl, DeleteTextures(1, &testRTTex));
    176 
    177     return status == GR_GL_FRAMEBUFFER_COMPLETE;
    178 }
    179 
    180 GrGpuGL::GrGpuGL(const GrGLContextInfo& ctxInfo) : fGLContextInfo(ctxInfo) {
    181 
    182     GrAssert(ctxInfo.isInitialized());
    183 
    184     fPrintedCaps = false;
    185 
    186     GrGLClearErr(fGLContextInfo.interface());
    187 
    188     if (gPrintStartupSpew) {
    189         const GrGLubyte* ext;
    190         GL_CALL_RET(ext, GetString(GR_GL_EXTENSIONS));
    191         const GrGLubyte* vendor;
    192         const GrGLubyte* renderer;
    193         const GrGLubyte* version;
    194         GL_CALL_RET(vendor, GetString(GR_GL_VENDOR));
    195         GL_CALL_RET(renderer, GetString(GR_GL_RENDERER));
    196         GL_CALL_RET(version, GetString(GR_GL_VERSION));
    197         GrPrintf("------------------------- create GrGpuGL %p --------------\n",
    198                  this);
    199         GrPrintf("------ VENDOR %s\n", vendor);
    200         GrPrintf("------ RENDERER %s\n", renderer);
    201         GrPrintf("------ VERSION %s\n",  version);
    202         GrPrintf("------ EXTENSIONS\n %s \n", ext);
    203     }
    204 
    205     this->resetDirtyFlags();
    206 
    207     this->initCaps();
    208 
    209     fLastSuccessfulStencilFmtIdx = 0;
    210     fCanPreserveUnpremulRoundtrip = kUnknown_CanPreserveUnpremulRoundtrip;
    211 }
    212 
    213 GrGpuGL::~GrGpuGL() {
    214     // This must be called by before the GrDrawTarget destructor
    215     this->releaseGeometry();
    216     // This subclass must do this before the base class destructor runs
    217     // since we will unref the GrGLInterface.
    218     this->releaseResources();
    219 }
    220 
    221 ///////////////////////////////////////////////////////////////////////////////
    222 
    223 void GrGpuGL::initCaps() {
    224     GrGLint maxTextureUnits;
    225     // check FS and fixed-function texture unit limits
    226     // we only use textures in the fragment stage currently.
    227     // checks are > to make sure we have a spare unit.
    228     const GrGLInterface* gl = this->glInterface();
    229     GR_GL_GetIntegerv(gl, GR_GL_MAX_TEXTURE_IMAGE_UNITS, &maxTextureUnits);
    230     GrAssert(maxTextureUnits > GrDrawState::kNumStages);
    231     if (kES2_GrGLBinding != this->glBinding()) {
    232         GR_GL_GetIntegerv(gl, GR_GL_MAX_TEXTURE_UNITS, &maxTextureUnits);
    233         GrAssert(maxTextureUnits > GrDrawState::kNumStages);
    234     }
    235 
    236     GrGLint numFormats;
    237     GR_GL_GetIntegerv(gl, GR_GL_NUM_COMPRESSED_TEXTURE_FORMATS, &numFormats);
    238     SkAutoSTMalloc<10, GrGLint> formats(numFormats);
    239     GR_GL_GetIntegerv(gl, GR_GL_COMPRESSED_TEXTURE_FORMATS, formats);
    240     for (int i = 0; i < numFormats; ++i) {
    241         if (formats[i] == GR_GL_PALETTE8_RGBA8) {
    242             fCaps.f8BitPaletteSupport = true;
    243             break;
    244         }
    245     }
    246 
    247     if (kDesktop_GrGLBinding == this->glBinding()) {
    248         // we could also look for GL_ATI_separate_stencil extension or
    249         // GL_EXT_stencil_two_side but they use different function signatures
    250         // than GL2.0+ (and than each other).
    251         fCaps.fTwoSidedStencilSupport = (this->glVersion() >= GR_GL_VER(2,0));
    252         // supported on GL 1.4 and higher or by extension
    253         fCaps.fStencilWrapOpsSupport = (this->glVersion() >= GR_GL_VER(1,4)) ||
    254                                        this->hasExtension("GL_EXT_stencil_wrap");
    255     } else {
    256         // ES 2 has two sided stencil and stencil wrap
    257         fCaps.fTwoSidedStencilSupport = true;
    258         fCaps.fStencilWrapOpsSupport = true;
    259     }
    260 
    261     if (kDesktop_GrGLBinding == this->glBinding()) {
    262         fCaps.fBufferLockSupport = true; // we require VBO support and the desktop VBO
    263                                          // extension includes glMapBuffer.
    264     } else {
    265         fCaps.fBufferLockSupport = this->hasExtension("GL_OES_mapbuffer");
    266     }
    267 
    268     if (kDesktop_GrGLBinding == this->glBinding()) {
    269         if (this->glVersion() >= GR_GL_VER(2,0) ||
    270             this->hasExtension("GL_ARB_texture_non_power_of_two")) {
    271             fCaps.fNPOTTextureTileSupport = true;
    272         } else {
    273             fCaps.fNPOTTextureTileSupport = false;
    274         }
    275     } else {
    276         // Unextended ES2 supports NPOT textures with clamp_to_edge and non-mip filters only
    277         fCaps.fNPOTTextureTileSupport = this->hasExtension("GL_OES_texture_npot");
    278     }
    279 
    280     fCaps.fHWAALineSupport = (kDesktop_GrGLBinding == this->glBinding());
    281 
    282     ////////////////////////////////////////////////////////////////////////////
    283     // Experiments to determine limitations that can't be queried.
    284     // TODO: Make these a preprocess that generate some compile time constants.
    285     // TODO: probe once at startup, rather than once per context creation.
    286 
    287     GR_GL_GetIntegerv(gl, GR_GL_MAX_TEXTURE_SIZE, &fCaps.fMaxTextureSize);
    288     GR_GL_GetIntegerv(gl, GR_GL_MAX_RENDERBUFFER_SIZE, &fCaps.fMaxRenderTargetSize);
    289     // Our render targets are always created with textures as the color
    290     // attachment, hence this min:
    291     fCaps.fMaxRenderTargetSize = GrMin(fCaps.fMaxTextureSize, fCaps.fMaxRenderTargetSize);
    292 
    293     fCaps.fFSAASupport = GrGLCaps::kNone_MSFBOType != this->glCaps().msFBOType();
    294 }
    295 
    296 bool GrGpuGL::canPreserveReadWriteUnpremulPixels() {
    297     if (kUnknown_CanPreserveUnpremulRoundtrip ==
    298         fCanPreserveUnpremulRoundtrip) {
    299 
    300         SkAutoTMalloc<uint32_t> data(256 * 256 * 3);
    301         uint32_t* srcData = data.get();
    302         uint32_t* firstRead = data.get() + 256 * 256;
    303         uint32_t* secondRead = data.get() + 2 * 256 * 256;
    304 
    305         for (int y = 0; y < 256; ++y) {
    306             for (int x = 0; x < 256; ++x) {
    307                 uint8_t* color = reinterpret_cast<uint8_t*>(&srcData[256*y + x]);
    308                 color[3] = y;
    309                 color[2] = x;
    310                 color[1] = x;
    311                 color[0] = x;
    312             }
    313         }
    314 
    315         // We have broader support for read/write pixels on render targets
    316         // than on textures.
    317         GrTextureDesc dstDesc;
    318         dstDesc.fFlags = kRenderTarget_GrTextureFlagBit |
    319                          kNoStencil_GrTextureFlagBit;
    320         dstDesc.fWidth = 256;
    321         dstDesc.fHeight = 256;
    322         dstDesc.fConfig = kRGBA_8888_GrPixelConfig;
    323         dstDesc.fSampleCnt = 0;
    324 
    325         SkAutoTUnref<GrTexture> dstTex(this->createTexture(dstDesc, NULL, 0));
    326         if (!dstTex.get()) {
    327             return false;
    328         }
    329         GrRenderTarget* rt = dstTex.get()->asRenderTarget();
    330         GrAssert(NULL != rt);
    331 
    332         bool failed = true;
    333         static const UnpremulConversion gMethods[] = {
    334             kUpOnWrite_DownOnRead_UnpremulConversion,
    335             kDownOnWrite_UpOnRead_UnpremulConversion,
    336         };
    337 
    338         // pretend that we can do the roundtrip to avoid recursive calls to
    339         // this function
    340         fCanPreserveUnpremulRoundtrip = kYes_CanPreserveUnpremulRoundtrip;
    341         for (size_t i = 0; i < GR_ARRAY_COUNT(gMethods) && failed; ++i) {
    342             fUnpremulConversion = gMethods[i];
    343             rt->writePixels(0, 0,
    344                             256, 256,
    345                             kRGBA_8888_UPM_GrPixelConfig, srcData, 0);
    346             rt->readPixels(0, 0,
    347                            256, 256,
    348                            kRGBA_8888_UPM_GrPixelConfig, firstRead, 0);
    349             rt->writePixels(0, 0,
    350                             256, 256,
    351                             kRGBA_8888_UPM_GrPixelConfig, firstRead, 0);
    352             rt->readPixels(0, 0,
    353                            256, 256,
    354                            kRGBA_8888_UPM_GrPixelConfig, secondRead, 0);
    355             failed = false;
    356             for (int j = 0; j < 256 * 256; ++j) {
    357                 if (firstRead[j] != secondRead[j]) {
    358                     failed = true;
    359                     break;
    360                 }
    361             }
    362         }
    363         fCanPreserveUnpremulRoundtrip = failed ?
    364                         kNo_CanPreserveUnpremulRoundtrip :
    365                         kYes_CanPreserveUnpremulRoundtrip;
    366     }
    367 
    368     if (kYes_CanPreserveUnpremulRoundtrip == fCanPreserveUnpremulRoundtrip) {
    369         return true;
    370     } else {
    371         return false;
    372     }
    373 }
    374 
    375 GrPixelConfig GrGpuGL::preferredReadPixelsConfig(GrPixelConfig config) const {
    376     if (GR_GL_RGBA_8888_PIXEL_OPS_SLOW && GrPixelConfigIsRGBA8888(config)) {
    377         return GrPixelConfigSwapRAndB(config);
    378     } else {
    379         return config;
    380     }
    381 }
    382 
    383 GrPixelConfig GrGpuGL::preferredWritePixelsConfig(GrPixelConfig config) const {
    384     if (GR_GL_RGBA_8888_PIXEL_OPS_SLOW && GrPixelConfigIsRGBA8888(config)) {
    385         return GrPixelConfigSwapRAndB(config);
    386     } else {
    387         return config;
    388     }
    389 }
    390 
    391 bool GrGpuGL::fullReadPixelsIsFasterThanPartial() const {
    392     return SkToBool(GR_GL_FULL_READPIXELS_FASTER_THAN_PARTIAL);
    393 }
    394 
    395 void GrGpuGL::onResetContext() {
    396     if (gPrintStartupSpew && !fPrintedCaps) {
    397         fPrintedCaps = true;
    398         this->getCaps().print();
    399         this->glCaps().print();
    400     }
    401 
    402     // We detect cases when blending is effectively off
    403     fHWBlendDisabled = false;
    404     GL_CALL(Enable(GR_GL_BLEND));
    405 
    406     // we don't use the zb at all
    407     GL_CALL(Disable(GR_GL_DEPTH_TEST));
    408     GL_CALL(DepthMask(GR_GL_FALSE));
    409 
    410     GL_CALL(Disable(GR_GL_CULL_FACE));
    411     GL_CALL(FrontFace(GR_GL_CCW));
    412     fHWDrawState.setDrawFace(GrDrawState::kBoth_DrawFace);
    413 
    414     GL_CALL(Disable(GR_GL_DITHER));
    415     if (kDesktop_GrGLBinding == this->glBinding()) {
    416         GL_CALL(Disable(GR_GL_LINE_SMOOTH));
    417         GL_CALL(Disable(GR_GL_POINT_SMOOTH));
    418         GL_CALL(Disable(GR_GL_MULTISAMPLE));
    419         fHWAAState.fMSAAEnabled = false;
    420         fHWAAState.fSmoothLineEnabled = false;
    421     }
    422 
    423     GL_CALL(ColorMask(GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE));
    424     fHWDrawState.resetStateFlags();
    425 
    426     // we only ever use lines in hairline mode
    427     GL_CALL(LineWidth(1));
    428 
    429     // invalid
    430     fActiveTextureUnitIdx = -1;
    431 
    432     // illegal values
    433     fHWDrawState.setBlendFunc((GrBlendCoeff)0xFF, (GrBlendCoeff)0xFF);
    434 
    435     fHWDrawState.setBlendConstant(0x00000000);
    436     GL_CALL(BlendColor(0,0,0,0));
    437 
    438     fHWDrawState.setColor(GrColor_ILLEGAL);
    439 
    440     fHWDrawState.setViewMatrix(GrMatrix::InvalidMatrix());
    441 
    442     for (int s = 0; s < GrDrawState::kNumStages; ++s) {
    443         fHWDrawState.setTexture(s, NULL);
    444         fHWDrawState.sampler(s)->setRadial2Params(-GR_ScalarMax,
    445                                                   -GR_ScalarMax,
    446                                                   true);
    447         *fHWDrawState.sampler(s)->matrix() = GrMatrix::InvalidMatrix();
    448         fHWDrawState.sampler(s)->setConvolutionParams(0, NULL);
    449     }
    450 
    451     fHWBounds.fScissorRect.invalidate();
    452     fHWBounds.fScissorEnabled = false;
    453     GL_CALL(Disable(GR_GL_SCISSOR_TEST));
    454     fHWBounds.fViewportRect.invalidate();
    455 
    456     fHWDrawState.stencil()->invalidate();
    457     fHWStencilClip = false;
    458     fClipInStencil = false;
    459 
    460     fHWGeometryState.fIndexBuffer = NULL;
    461     fHWGeometryState.fVertexBuffer = NULL;
    462 
    463     fHWGeometryState.fArrayPtrsDirty = true;
    464 
    465     GL_CALL(ColorMask(GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE));
    466     fHWDrawState.setRenderTarget(NULL);
    467 
    468     // we assume these values
    469     if (this->glCaps().unpackRowLengthSupport()) {
    470         GL_CALL(PixelStorei(GR_GL_UNPACK_ROW_LENGTH, 0));
    471     }
    472     if (this->glCaps().packRowLengthSupport()) {
    473         GL_CALL(PixelStorei(GR_GL_PACK_ROW_LENGTH, 0));
    474     }
    475     if (this->glCaps().unpackFlipYSupport()) {
    476         GL_CALL(PixelStorei(GR_GL_UNPACK_FLIP_Y, GR_GL_FALSE));
    477     }
    478     if (this->glCaps().packFlipYSupport()) {
    479         GL_CALL(PixelStorei(GR_GL_PACK_REVERSE_ROW_ORDER, GR_GL_FALSE));
    480     }
    481 }
    482 
    483 GrTexture* GrGpuGL::onCreatePlatformTexture(const GrPlatformTextureDesc& desc) {
    484     GrGLTexture::Desc glTexDesc;
    485     if (!configToGLFormats(desc.fConfig, false, NULL, NULL, NULL)) {
    486         return NULL;
    487     }
    488 
    489     glTexDesc.fWidth = desc.fWidth;
    490     glTexDesc.fHeight = desc.fHeight;
    491     glTexDesc.fConfig = desc.fConfig;
    492     glTexDesc.fTextureID = static_cast<GrGLuint>(desc.fTextureHandle);
    493     glTexDesc.fOwnsID = false;
    494     glTexDesc.fOrientation = GrGLTexture::kBottomUp_Orientation;
    495 
    496     GrGLTexture* texture = NULL;
    497     if (desc.fFlags & kRenderTarget_GrPlatformTextureFlag) {
    498         GrGLRenderTarget::Desc glRTDesc;
    499         glRTDesc.fRTFBOID = 0;
    500         glRTDesc.fTexFBOID = 0;
    501         glRTDesc.fMSColorRenderbufferID = 0;
    502         glRTDesc.fOwnIDs = true;
    503         glRTDesc.fConfig = desc.fConfig;
    504         glRTDesc.fSampleCnt = desc.fSampleCnt;
    505         if (!this->createRenderTargetObjects(glTexDesc.fWidth,
    506                                              glTexDesc.fHeight,
    507                                              glTexDesc.fTextureID,
    508                                              &glRTDesc)) {
    509             return NULL;
    510         }
    511         texture = new GrGLTexture(this, glTexDesc, glRTDesc);
    512     } else {
    513         texture = new GrGLTexture(this, glTexDesc);
    514     }
    515     if (NULL == texture) {
    516         return NULL;
    517     }
    518 
    519     this->setSpareTextureUnit();
    520     return texture;
    521 }
    522 
    523 GrRenderTarget* GrGpuGL::onCreatePlatformRenderTarget(const GrPlatformRenderTargetDesc& desc) {
    524     GrGLRenderTarget::Desc glDesc;
    525     glDesc.fConfig = desc.fConfig;
    526     glDesc.fRTFBOID = static_cast<GrGLuint>(desc.fRenderTargetHandle);
    527     glDesc.fMSColorRenderbufferID = 0;
    528     glDesc.fTexFBOID = GrGLRenderTarget::kUnresolvableFBOID;
    529     glDesc.fSampleCnt = desc.fSampleCnt;
    530     glDesc.fOwnIDs = false;
    531     GrGLIRect viewport;
    532     viewport.fLeft   = 0;
    533     viewport.fBottom = 0;
    534     viewport.fWidth  = desc.fWidth;
    535     viewport.fHeight = desc.fHeight;
    536 
    537     GrRenderTarget* tgt = new GrGLRenderTarget(this, glDesc, viewport);
    538     if (desc.fStencilBits) {
    539         GrGLStencilBuffer::Format format;
    540         format.fInternalFormat = GrGLStencilBuffer::kUnknownInternalFormat;
    541         format.fPacked = false;
    542         format.fStencilBits = desc.fStencilBits;
    543         format.fTotalBits = desc.fStencilBits;
    544         GrGLStencilBuffer* sb = new GrGLStencilBuffer(this,
    545                                                       0,
    546                                                       desc.fWidth,
    547                                                       desc.fHeight,
    548                                                       desc.fSampleCnt,
    549                                                       format);
    550         tgt->setStencilBuffer(sb);
    551         sb->unref();
    552     }
    553     return tgt;
    554 }
    555 
    556 ////////////////////////////////////////////////////////////////////////////////
    557 
    558 void GrGpuGL::onWriteTexturePixels(GrTexture* texture,
    559                                    int left, int top, int width, int height,
    560                                    GrPixelConfig config, const void* buffer,
    561                                    size_t rowBytes) {
    562     if (NULL == buffer) {
    563         return;
    564     }
    565     GrGLTexture* glTex = static_cast<GrGLTexture*>(texture);
    566 
    567     this->setSpareTextureUnit();
    568     GL_CALL(BindTexture(GR_GL_TEXTURE_2D, glTex->textureID()));
    569     GrGLTexture::Desc desc;
    570     desc.fConfig = glTex->config();
    571     desc.fWidth = glTex->width();
    572     desc.fHeight = glTex->height();
    573     desc.fOrientation = glTex->orientation();
    574     desc.fTextureID = glTex->textureID();
    575 
    576     this->uploadTexData(desc, false,
    577                         left, top, width, height,
    578                         config, buffer, rowBytes);
    579 }
    580 
    581 namespace {
    582 bool adjust_pixel_ops_params(int surfaceWidth,
    583                              int surfaceHeight,
    584                              size_t bpp,
    585                              int* left, int* top, int* width, int* height,
    586                              const void** data,
    587                              size_t* rowBytes) {
    588     if (!*rowBytes) {
    589         *rowBytes = *width * bpp;
    590     }
    591 
    592     GrIRect subRect = GrIRect::MakeXYWH(*left, *top, *width, *height);
    593     GrIRect bounds = GrIRect::MakeWH(surfaceWidth, surfaceHeight);
    594 
    595     if (!subRect.intersect(bounds)) {
    596         return false;
    597     }
    598     *data = reinterpret_cast<const void*>(reinterpret_cast<intptr_t>(*data) +
    599           (subRect.fTop - *top) * *rowBytes + (subRect.fLeft - *left) * bpp);
    600 
    601     *left = subRect.fLeft;
    602     *top = subRect.fTop;
    603     *width = subRect.width();
    604     *height = subRect.height();
    605     return true;
    606 }
    607 }
    608 
    609 bool GrGpuGL::uploadTexData(const GrGLTexture::Desc& desc,
    610                             bool isNewTexture,
    611                             int left, int top, int width, int height,
    612                             GrPixelConfig dataConfig,
    613                             const void* data,
    614                             size_t rowBytes) {
    615     GrAssert(NULL != data || isNewTexture);
    616 
    617     size_t bpp = GrBytesPerPixel(dataConfig);
    618     if (!adjust_pixel_ops_params(desc.fWidth, desc.fHeight, bpp, &left, &top,
    619                                  &width, &height, &data, &rowBytes)) {
    620         return false;
    621     }
    622     size_t trimRowBytes = width * bpp;
    623 
    624     // in case we need a temporary, trimmed copy of the src pixels
    625     SkAutoSMalloc<128 * 128> tempStorage;
    626 
    627     bool useTexStorage = isNewTexture &&
    628                          this->glCaps().texStorageSupport();
    629     if (useTexStorage) {
    630         if (kDesktop_GrGLBinding == this->glBinding()) {
    631             // 565 is not a sized internal format on desktop GL. So on desktop
    632             // with 565 we always use an unsized internal format to let the
    633             // system pick the best sized format to convert the 565 data to.
    634             // Since glTexStorage only allows sized internal formats we will
    635             // instead fallback to glTexImage2D.
    636             useTexStorage = desc.fConfig != kRGB_565_GrPixelConfig;
    637         } else {
    638             // ES doesn't allow paletted textures to be used with tex storage
    639             useTexStorage = desc.fConfig != kIndex_8_GrPixelConfig;
    640         }
    641     }
    642 
    643     GrGLenum internalFormat;
    644     GrGLenum externalFormat;
    645     GrGLenum externalType;
    646     // glTexStorage requires sized internal formats on both desktop and ES. ES
    647     // glTexImage requires an unsized format.
    648     if (!this->configToGLFormats(dataConfig, useTexStorage, &internalFormat,
    649                                  &externalFormat, &externalType)) {
    650         return false;
    651     }
    652 
    653     if (!isNewTexture && GR_GL_PALETTE8_RGBA8 == internalFormat) {
    654         // paletted textures cannot be updated
    655         return false;
    656     }
    657 
    658     /*
    659      *  check whether to allocate a temporary buffer for flipping y or
    660      *  because our srcData has extra bytes past each row. If so, we need
    661      *  to trim those off here, since GL ES may not let us specify
    662      *  GL_UNPACK_ROW_LENGTH.
    663      */
    664     bool restoreGLRowLength = false;
    665     bool swFlipY = false;
    666     bool glFlipY = false;
    667     if (NULL != data) {
    668         if (GrGLTexture::kBottomUp_Orientation == desc.fOrientation) {
    669             if (this->glCaps().unpackFlipYSupport()) {
    670                 glFlipY = true;
    671             } else {
    672                 swFlipY = true;
    673             }
    674         }
    675         if (this->glCaps().unpackRowLengthSupport() && !swFlipY) {
    676             // can't use this for flipping, only non-neg values allowed. :(
    677             if (rowBytes != trimRowBytes) {
    678                 GrGLint rowLength = static_cast<GrGLint>(rowBytes / bpp);
    679                 GL_CALL(PixelStorei(GR_GL_UNPACK_ROW_LENGTH, rowLength));
    680                 restoreGLRowLength = true;
    681             }
    682         } else {
    683             if (trimRowBytes != rowBytes || swFlipY) {
    684                 // copy data into our new storage, skipping the trailing bytes
    685                 size_t trimSize = height * trimRowBytes;
    686                 const char* src = (const char*)data;
    687                 if (swFlipY) {
    688                     src += (height - 1) * rowBytes;
    689                 }
    690                 char* dst = (char*)tempStorage.reset(trimSize);
    691                 for (int y = 0; y < height; y++) {
    692                     memcpy(dst, src, trimRowBytes);
    693                     if (swFlipY) {
    694                         src -= rowBytes;
    695                     } else {
    696                         src += rowBytes;
    697                     }
    698                     dst += trimRowBytes;
    699                 }
    700                 // now point data to our copied version
    701                 data = tempStorage.get();
    702             }
    703         }
    704         if (glFlipY) {
    705             GL_CALL(PixelStorei(GR_GL_UNPACK_FLIP_Y, GR_GL_TRUE));
    706         }
    707         GL_CALL(PixelStorei(GR_GL_UNPACK_ALIGNMENT, static_cast<GrGLint>(bpp)));
    708     }
    709     bool succeeded = true;
    710     if (isNewTexture &&
    711         0 == left && 0 == top &&
    712         desc.fWidth == width && desc.fHeight == height) {
    713         CLEAR_ERROR_BEFORE_ALLOC(this->glInterface());
    714         if (useTexStorage) {
    715             // We never resize  or change formats of textures. We don't use
    716             // mipmaps currently.
    717             GL_ALLOC_CALL(this->glInterface(),
    718                           TexStorage2D(GR_GL_TEXTURE_2D,
    719                                        1, // levels
    720                                        internalFormat,
    721                                        desc.fWidth, desc.fHeight));
    722         } else {
    723             if (GR_GL_PALETTE8_RGBA8 == internalFormat) {
    724                 GrGLsizei imageSize = desc.fWidth * desc.fHeight +
    725                                       kGrColorTableSize;
    726                 GL_ALLOC_CALL(this->glInterface(),
    727                               CompressedTexImage2D(GR_GL_TEXTURE_2D,
    728                                                    0, // level
    729                                                    internalFormat,
    730                                                    desc.fWidth, desc.fHeight,
    731                                                    0, // border
    732                                                    imageSize,
    733                                                    data));
    734             } else {
    735                 GL_ALLOC_CALL(this->glInterface(),
    736                               TexImage2D(GR_GL_TEXTURE_2D,
    737                                          0, // level
    738                                          internalFormat,
    739                                          desc.fWidth, desc.fHeight,
    740                                          0, // border
    741                                          externalFormat, externalType,
    742                                          data));
    743             }
    744         }
    745         GrGLenum error = CHECK_ALLOC_ERROR(this->glInterface());
    746         if (error != GR_GL_NO_ERROR) {
    747             succeeded = false;
    748         } else {
    749             // if we have data and we used TexStorage to create the texture, we
    750             // now upload with TexSubImage.
    751             if (NULL != data && useTexStorage) {
    752                 GL_CALL(TexSubImage2D(GR_GL_TEXTURE_2D,
    753                                       0, // level
    754                                       left, top,
    755                                       width, height,
    756                                       externalFormat, externalType,
    757                                       data));
    758             }
    759         }
    760     } else {
    761         if (swFlipY || glFlipY) {
    762             top = desc.fHeight - (top + height);
    763         }
    764         GL_CALL(TexSubImage2D(GR_GL_TEXTURE_2D,
    765                               0, // level
    766                               left, top,
    767                               width, height,
    768                               externalFormat, externalType, data));
    769     }
    770 
    771     if (restoreGLRowLength) {
    772         GrAssert(this->glCaps().unpackRowLengthSupport());
    773         GL_CALL(PixelStorei(GR_GL_UNPACK_ROW_LENGTH, 0));
    774     }
    775     if (glFlipY) {
    776         GL_CALL(PixelStorei(GR_GL_UNPACK_FLIP_Y, GR_GL_FALSE));
    777     }
    778     return succeeded;
    779 }
    780 
    781 bool GrGpuGL::createRenderTargetObjects(int width, int height,
    782                                         GrGLuint texID,
    783                                         GrGLRenderTarget::Desc* desc) {
    784     desc->fMSColorRenderbufferID = 0;
    785     desc->fRTFBOID = 0;
    786     desc->fTexFBOID = 0;
    787     desc->fOwnIDs = true;
    788 
    789     GrGLenum status;
    790     GrGLint err;
    791 
    792     GrGLenum msColorFormat = 0; // suppress warning
    793 
    794     GL_CALL(GenFramebuffers(1, &desc->fTexFBOID));
    795     if (!desc->fTexFBOID) {
    796         goto FAILED;
    797     }
    798 
    799 
    800     // If we are using multisampling we will create two FBOS. We render
    801     // to one and then resolve to the texture bound to the other.
    802     if (desc->fSampleCnt > 0) {
    803         if (GrGLCaps::kNone_MSFBOType == this->glCaps().msFBOType()) {
    804             goto FAILED;
    805         }
    806         GL_CALL(GenFramebuffers(1, &desc->fRTFBOID));
    807         GL_CALL(GenRenderbuffers(1, &desc->fMSColorRenderbufferID));
    808         if (!desc->fRTFBOID ||
    809             !desc->fMSColorRenderbufferID ||
    810             !this->configToGLFormats(desc->fConfig,
    811                                      // GLES requires sized internal formats
    812                                      kES2_GrGLBinding == this->glBinding(),
    813                                      &msColorFormat, NULL, NULL)) {
    814             goto FAILED;
    815         }
    816     } else {
    817         desc->fRTFBOID = desc->fTexFBOID;
    818     }
    819 
    820     // below here we may bind the FBO
    821     fHWDrawState.setRenderTarget(NULL);
    822     if (desc->fRTFBOID != desc->fTexFBOID) {
    823         GrAssert(desc->fSampleCnt > 1);
    824         GL_CALL(BindRenderbuffer(GR_GL_RENDERBUFFER,
    825                                desc->fMSColorRenderbufferID));
    826         CLEAR_ERROR_BEFORE_ALLOC(this->glInterface());
    827         GL_ALLOC_CALL(this->glInterface(),
    828                       RenderbufferStorageMultisample(GR_GL_RENDERBUFFER,
    829                                                      desc->fSampleCnt,
    830                                                      msColorFormat,
    831                                                      width, height));
    832         err = CHECK_ALLOC_ERROR(this->glInterface());
    833         if (err != GR_GL_NO_ERROR) {
    834             goto FAILED;
    835         }
    836         GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, desc->fRTFBOID));
    837         GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
    838                                       GR_GL_COLOR_ATTACHMENT0,
    839                                       GR_GL_RENDERBUFFER,
    840                                       desc->fMSColorRenderbufferID));
    841         if (!this->glCaps().isConfigVerifiedColorAttachment(desc->fConfig)) {
    842             GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER));
    843             if (status != GR_GL_FRAMEBUFFER_COMPLETE) {
    844                 goto FAILED;
    845             }
    846             fGLContextInfo.caps().markConfigAsValidColorAttachment(
    847                                                                 desc->fConfig);
    848         }
    849     }
    850     GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, desc->fTexFBOID));
    851 
    852     GL_CALL(FramebufferTexture2D(GR_GL_FRAMEBUFFER,
    853                                  GR_GL_COLOR_ATTACHMENT0,
    854                                  GR_GL_TEXTURE_2D,
    855                                  texID, 0));
    856     if (!this->glCaps().isConfigVerifiedColorAttachment(desc->fConfig)) {
    857         GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER));
    858         if (status != GR_GL_FRAMEBUFFER_COMPLETE) {
    859             goto FAILED;
    860         }
    861         fGLContextInfo.caps().markConfigAsValidColorAttachment(desc->fConfig);
    862     }
    863 
    864     return true;
    865 
    866 FAILED:
    867     if (desc->fMSColorRenderbufferID) {
    868         GL_CALL(DeleteRenderbuffers(1, &desc->fMSColorRenderbufferID));
    869     }
    870     if (desc->fRTFBOID != desc->fTexFBOID) {
    871         GL_CALL(DeleteFramebuffers(1, &desc->fRTFBOID));
    872     }
    873     if (desc->fTexFBOID) {
    874         GL_CALL(DeleteFramebuffers(1, &desc->fTexFBOID));
    875     }
    876     return false;
    877 }
    878 
    879 // good to set a break-point here to know when createTexture fails
    880 static GrTexture* return_null_texture() {
    881 //    GrAssert(!"null texture");
    882     return NULL;
    883 }
    884 
    885 #if GR_DEBUG
    886 static size_t as_size_t(int x) {
    887     return x;
    888 }
    889 #endif
    890 
    891 GrTexture* GrGpuGL::onCreateTexture(const GrTextureDesc& desc,
    892                                     const void* srcData,
    893                                     size_t rowBytes) {
    894 
    895 #if GR_COLLECT_STATS
    896     ++fStats.fTextureCreateCnt;
    897 #endif
    898 
    899     GrGLTexture::Desc glTexDesc;
    900     GrGLRenderTarget::Desc  glRTDesc;
    901 
    902     // Attempt to catch un- or wrongly initialized sample counts;
    903     GrAssert(desc.fSampleCnt >= 0 && desc.fSampleCnt <= 64);
    904 
    905     glTexDesc.fWidth  = desc.fWidth;
    906     glTexDesc.fHeight = desc.fHeight;
    907     glTexDesc.fConfig = desc.fConfig;
    908     glTexDesc.fOwnsID = true;
    909 
    910     glRTDesc.fMSColorRenderbufferID = 0;
    911     glRTDesc.fRTFBOID = 0;
    912     glRTDesc.fTexFBOID = 0;
    913     glRTDesc.fOwnIDs = true;
    914     glRTDesc.fConfig = glTexDesc.fConfig;
    915 
    916     bool renderTarget = 0 != (desc.fFlags & kRenderTarget_GrTextureFlagBit);
    917 
    918     const Caps& caps = this->getCaps();
    919 
    920     // We keep GrRenderTargets in GL's normal orientation so that they
    921     // can be drawn to by the outside world without the client having
    922     // to render upside down.
    923     glTexDesc.fOrientation = renderTarget ? GrGLTexture::kBottomUp_Orientation :
    924                                             GrGLTexture::kTopDown_Orientation;
    925 
    926     glRTDesc.fSampleCnt = desc.fSampleCnt;
    927     if (GrGLCaps::kNone_MSFBOType == this->glCaps().msFBOType() &&
    928         desc.fSampleCnt) {
    929         GrPrintf("MSAA RT requested but not supported on this platform.");
    930     }
    931 
    932     if (renderTarget) {
    933         if (glTexDesc.fWidth > caps.fMaxRenderTargetSize ||
    934             glTexDesc.fHeight > caps.fMaxRenderTargetSize) {
    935             return return_null_texture();
    936         }
    937     }
    938 
    939     GL_CALL(GenTextures(1, &glTexDesc.fTextureID));
    940     if (renderTarget && this->glCaps().textureUsageSupport()) {
    941         // provides a hint about how this texture will be used
    942         GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
    943                               GR_GL_TEXTURE_USAGE,
    944                               GR_GL_FRAMEBUFFER_ATTACHMENT));
    945     }
    946     if (!glTexDesc.fTextureID) {
    947         return return_null_texture();
    948     }
    949 
    950     this->setSpareTextureUnit();
    951     GL_CALL(BindTexture(GR_GL_TEXTURE_2D, glTexDesc.fTextureID));
    952 
    953     // Some drivers like to know filter/wrap before seeing glTexImage2D. Some
    954     // drivers have a bug where an FBO won't be complete if it includes a
    955     // texture that is not mipmap complete (considering the filter in use).
    956     GrGLTexture::TexParams initialTexParams;
    957     // we only set a subset here so invalidate first
    958     initialTexParams.invalidate();
    959     initialTexParams.fFilter = GR_GL_NEAREST;
    960     initialTexParams.fWrapS = GR_GL_CLAMP_TO_EDGE;
    961     initialTexParams.fWrapT = GR_GL_CLAMP_TO_EDGE;
    962     GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
    963                           GR_GL_TEXTURE_MAG_FILTER,
    964                           initialTexParams.fFilter));
    965     GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
    966                           GR_GL_TEXTURE_MIN_FILTER,
    967                           initialTexParams.fFilter));
    968     GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
    969                           GR_GL_TEXTURE_WRAP_S,
    970                           initialTexParams.fWrapS));
    971     GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
    972                           GR_GL_TEXTURE_WRAP_T,
    973                           initialTexParams.fWrapT));
    974     if (!this->uploadTexData(glTexDesc, true, 0, 0,
    975                              glTexDesc.fWidth, glTexDesc.fHeight,
    976                              desc.fConfig, srcData, rowBytes)) {
    977         GL_CALL(DeleteTextures(1, &glTexDesc.fTextureID));
    978         return return_null_texture();
    979     }
    980 
    981     GrGLTexture* tex;
    982     if (renderTarget) {
    983 #if GR_COLLECT_STATS
    984         ++fStats.fRenderTargetCreateCnt;
    985 #endif
    986         if (!this->createRenderTargetObjects(glTexDesc.fWidth,
    987                                              glTexDesc.fHeight,
    988                                              glTexDesc.fTextureID,
    989                                              &glRTDesc)) {
    990             GL_CALL(DeleteTextures(1, &glTexDesc.fTextureID));
    991             return return_null_texture();
    992         }
    993         tex = new GrGLTexture(this, glTexDesc, glRTDesc);
    994     } else {
    995         tex = new GrGLTexture(this, glTexDesc);
    996     }
    997     tex->setCachedTexParams(initialTexParams, this->getResetTimestamp());
    998 #ifdef TRACE_TEXTURE_CREATION
    999     GrPrintf("--- new texture [%d] size=(%d %d) config=%d\n",
   1000              glTexDesc.fTextureID, desc.fWidth, desc.fHeight, desc.fConfig);
   1001 #endif
   1002     return tex;
   1003 }
   1004 
   1005 namespace {
   1006 
   1007 const GrGLuint kUnknownBitCount = GrGLStencilBuffer::kUnknownBitCount;
   1008 
   1009 void inline get_stencil_rb_sizes(const GrGLInterface* gl,
   1010                                  GrGLuint rb,
   1011                                  GrGLStencilBuffer::Format* format) {
   1012     // we shouldn't ever know one size and not the other
   1013     GrAssert((kUnknownBitCount == format->fStencilBits) ==
   1014              (kUnknownBitCount == format->fTotalBits));
   1015     if (kUnknownBitCount == format->fStencilBits) {
   1016         GR_GL_GetRenderbufferParameteriv(gl, GR_GL_RENDERBUFFER,
   1017                                          GR_GL_RENDERBUFFER_STENCIL_SIZE,
   1018                                          (GrGLint*)&format->fStencilBits);
   1019         if (format->fPacked) {
   1020             GR_GL_GetRenderbufferParameteriv(gl, GR_GL_RENDERBUFFER,
   1021                                              GR_GL_RENDERBUFFER_DEPTH_SIZE,
   1022                                              (GrGLint*)&format->fTotalBits);
   1023             format->fTotalBits += format->fStencilBits;
   1024         } else {
   1025             format->fTotalBits = format->fStencilBits;
   1026         }
   1027     }
   1028 }
   1029 }
   1030 
   1031 bool GrGpuGL::createStencilBufferForRenderTarget(GrRenderTarget* rt,
   1032                                                  int width, int height) {
   1033 
   1034     // All internally created RTs are also textures. We don't create
   1035     // SBs for a client's standalone RT (that is RT that isnt also a texture).
   1036     GrAssert(rt->asTexture());
   1037     GrAssert(width >= rt->width());
   1038     GrAssert(height >= rt->height());
   1039 
   1040     int samples = rt->numSamples();
   1041     GrGLuint sbID;
   1042     GL_CALL(GenRenderbuffers(1, &sbID));
   1043     if (!sbID) {
   1044         return false;
   1045     }
   1046 
   1047     GrGLStencilBuffer* sb = NULL;
   1048 
   1049     int stencilFmtCnt = this->glCaps().stencilFormats().count();
   1050     for (int i = 0; i < stencilFmtCnt; ++i) {
   1051         GL_CALL(BindRenderbuffer(GR_GL_RENDERBUFFER, sbID));
   1052         // we start with the last stencil format that succeeded in hopes
   1053         // that we won't go through this loop more than once after the
   1054         // first (painful) stencil creation.
   1055         int sIdx = (i + fLastSuccessfulStencilFmtIdx) % stencilFmtCnt;
   1056         const GrGLCaps::StencilFormat& sFmt =
   1057                 this->glCaps().stencilFormats()[sIdx];
   1058         CLEAR_ERROR_BEFORE_ALLOC(this->glInterface());
   1059         // we do this "if" so that we don't call the multisample
   1060         // version on a GL that doesn't have an MSAA extension.
   1061         if (samples > 1) {
   1062             GL_ALLOC_CALL(this->glInterface(),
   1063                           RenderbufferStorageMultisample(GR_GL_RENDERBUFFER,
   1064                                                          samples,
   1065                                                          sFmt.fInternalFormat,
   1066                                                          width, height));
   1067         } else {
   1068             GL_ALLOC_CALL(this->glInterface(),
   1069                           RenderbufferStorage(GR_GL_RENDERBUFFER,
   1070                                               sFmt.fInternalFormat,
   1071                                               width, height));
   1072         }
   1073 
   1074         GrGLenum err = CHECK_ALLOC_ERROR(this->glInterface());
   1075         if (err == GR_GL_NO_ERROR) {
   1076             // After sized formats we attempt an unsized format and take whatever
   1077             // sizes GL gives us. In that case we query for the size.
   1078             GrGLStencilBuffer::Format format = sFmt;
   1079             get_stencil_rb_sizes(this->glInterface(), sbID, &format);
   1080             sb = new GrGLStencilBuffer(this, sbID, width, height,
   1081                                        samples, format);
   1082             if (this->attachStencilBufferToRenderTarget(sb, rt)) {
   1083                 fLastSuccessfulStencilFmtIdx = sIdx;
   1084                 rt->setStencilBuffer(sb);
   1085                 sb->unref();
   1086                 return true;
   1087            }
   1088            sb->abandon(); // otherwise we lose sbID
   1089            sb->unref();
   1090         }
   1091     }
   1092     GL_CALL(DeleteRenderbuffers(1, &sbID));
   1093     return false;
   1094 }
   1095 
   1096 bool GrGpuGL::attachStencilBufferToRenderTarget(GrStencilBuffer* sb,
   1097                                                 GrRenderTarget* rt) {
   1098     GrGLRenderTarget* glrt = (GrGLRenderTarget*) rt;
   1099 
   1100     GrGLuint fbo = glrt->renderFBOID();
   1101 
   1102     if (NULL == sb) {
   1103         if (NULL != rt->getStencilBuffer()) {
   1104             GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
   1105                                           GR_GL_STENCIL_ATTACHMENT,
   1106                                           GR_GL_RENDERBUFFER, 0));
   1107             GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
   1108                                           GR_GL_DEPTH_ATTACHMENT,
   1109                                           GR_GL_RENDERBUFFER, 0));
   1110 #if GR_DEBUG
   1111             GrGLenum status;
   1112             GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER));
   1113             GrAssert(GR_GL_FRAMEBUFFER_COMPLETE == status);
   1114 #endif
   1115         }
   1116         return true;
   1117     } else {
   1118         GrGLStencilBuffer* glsb = (GrGLStencilBuffer*) sb;
   1119         GrGLuint rb = glsb->renderbufferID();
   1120 
   1121         fHWDrawState.setRenderTarget(NULL);
   1122         GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, fbo));
   1123         GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
   1124                                       GR_GL_STENCIL_ATTACHMENT,
   1125                                       GR_GL_RENDERBUFFER, rb));
   1126         if (glsb->format().fPacked) {
   1127             GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
   1128                                           GR_GL_DEPTH_ATTACHMENT,
   1129                                           GR_GL_RENDERBUFFER, rb));
   1130         } else {
   1131             GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
   1132                                           GR_GL_DEPTH_ATTACHMENT,
   1133                                           GR_GL_RENDERBUFFER, 0));
   1134         }
   1135 
   1136         GrGLenum status;
   1137         if (!this->glCaps().isColorConfigAndStencilFormatVerified(rt->config(),
   1138                                                            glsb->format())) {
   1139             GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER));
   1140             if (status != GR_GL_FRAMEBUFFER_COMPLETE) {
   1141                 GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
   1142                                               GR_GL_STENCIL_ATTACHMENT,
   1143                                               GR_GL_RENDERBUFFER, 0));
   1144                 if (glsb->format().fPacked) {
   1145                     GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
   1146                                                   GR_GL_DEPTH_ATTACHMENT,
   1147                                                   GR_GL_RENDERBUFFER, 0));
   1148                 }
   1149                 return false;
   1150             } else {
   1151                 fGLContextInfo.caps().markColorConfigAndStencilFormatAsVerified(
   1152                     rt->config(),
   1153                     glsb->format());
   1154             }
   1155         }
   1156         return true;
   1157     }
   1158 }
   1159 
   1160 ////////////////////////////////////////////////////////////////////////////////
   1161 
   1162 GrVertexBuffer* GrGpuGL::onCreateVertexBuffer(uint32_t size, bool dynamic) {
   1163     GrGLuint id;
   1164     GL_CALL(GenBuffers(1, &id));
   1165     if (id) {
   1166         GL_CALL(BindBuffer(GR_GL_ARRAY_BUFFER, id));
   1167         fHWGeometryState.fArrayPtrsDirty = true;
   1168         CLEAR_ERROR_BEFORE_ALLOC(this->glInterface());
   1169         // make sure driver can allocate memory for this buffer
   1170         GL_ALLOC_CALL(this->glInterface(),
   1171                       BufferData(GR_GL_ARRAY_BUFFER,
   1172                                  size,
   1173                                  NULL,   // data ptr
   1174                                  dynamic ? GR_GL_DYNAMIC_DRAW :
   1175                                            GR_GL_STATIC_DRAW));
   1176         if (CHECK_ALLOC_ERROR(this->glInterface()) != GR_GL_NO_ERROR) {
   1177             GL_CALL(DeleteBuffers(1, &id));
   1178             // deleting bound buffer does implicit bind to 0
   1179             fHWGeometryState.fVertexBuffer = NULL;
   1180             return NULL;
   1181         }
   1182         GrGLVertexBuffer* vertexBuffer = new GrGLVertexBuffer(this, id,
   1183                                                               size, dynamic);
   1184         fHWGeometryState.fVertexBuffer = vertexBuffer;
   1185         return vertexBuffer;
   1186     }
   1187     return NULL;
   1188 }
   1189 
   1190 GrIndexBuffer* GrGpuGL::onCreateIndexBuffer(uint32_t size, bool dynamic) {
   1191     GrGLuint id;
   1192     GL_CALL(GenBuffers(1, &id));
   1193     if (id) {
   1194         GL_CALL(BindBuffer(GR_GL_ELEMENT_ARRAY_BUFFER, id));
   1195         CLEAR_ERROR_BEFORE_ALLOC(this->glInterface());
   1196         // make sure driver can allocate memory for this buffer
   1197         GL_ALLOC_CALL(this->glInterface(),
   1198                       BufferData(GR_GL_ELEMENT_ARRAY_BUFFER,
   1199                                  size,
   1200                                  NULL,  // data ptr
   1201                                  dynamic ? GR_GL_DYNAMIC_DRAW :
   1202                                            GR_GL_STATIC_DRAW));
   1203         if (CHECK_ALLOC_ERROR(this->glInterface()) != GR_GL_NO_ERROR) {
   1204             GL_CALL(DeleteBuffers(1, &id));
   1205             // deleting bound buffer does implicit bind to 0
   1206             fHWGeometryState.fIndexBuffer = NULL;
   1207             return NULL;
   1208         }
   1209         GrIndexBuffer* indexBuffer = new GrGLIndexBuffer(this, id,
   1210                                                          size, dynamic);
   1211         fHWGeometryState.fIndexBuffer = indexBuffer;
   1212         return indexBuffer;
   1213     }
   1214     return NULL;
   1215 }
   1216 
   1217 void GrGpuGL::flushScissor(const GrIRect* rect) {
   1218     const GrDrawState& drawState = this->getDrawState();
   1219     const GrGLRenderTarget* rt =
   1220         static_cast<const GrGLRenderTarget*>(drawState.getRenderTarget());
   1221 
   1222     GrAssert(NULL != rt);
   1223     const GrGLIRect& vp = rt->getViewport();
   1224 
   1225     GrGLIRect scissor;
   1226     if (NULL != rect) {
   1227         scissor.setRelativeTo(vp, rect->fLeft, rect->fTop,
   1228                               rect->width(), rect->height());
   1229         if (scissor.contains(vp)) {
   1230             rect = NULL;
   1231         }
   1232     }
   1233 
   1234     if (NULL != rect) {
   1235         if (fHWBounds.fScissorRect != scissor) {
   1236             scissor.pushToGLScissor(this->glInterface());
   1237             fHWBounds.fScissorRect = scissor;
   1238         }
   1239         if (!fHWBounds.fScissorEnabled) {
   1240             GL_CALL(Enable(GR_GL_SCISSOR_TEST));
   1241             fHWBounds.fScissorEnabled = true;
   1242         }
   1243     } else {
   1244         if (fHWBounds.fScissorEnabled) {
   1245             GL_CALL(Disable(GR_GL_SCISSOR_TEST));
   1246             fHWBounds.fScissorEnabled = false;
   1247         }
   1248     }
   1249 }
   1250 
   1251 void GrGpuGL::onClear(const GrIRect* rect, GrColor color) {
   1252     const GrDrawState& drawState = this->getDrawState();
   1253     const GrRenderTarget* rt = drawState.getRenderTarget();
   1254     // parent class should never let us get here with no RT
   1255     GrAssert(NULL != rt);
   1256 
   1257     GrIRect clippedRect;
   1258     if (NULL != rect) {
   1259         // flushScissor expects rect to be clipped to the target.
   1260         clippedRect = *rect;
   1261         GrIRect rtRect = SkIRect::MakeWH(rt->width(), rt->height());
   1262         if (clippedRect.intersect(rtRect)) {
   1263             rect = &clippedRect;
   1264         } else {
   1265             return;
   1266         }
   1267     }
   1268     this->flushRenderTarget(rect);
   1269     this->flushScissor(rect);
   1270 
   1271     GrGLfloat r, g, b, a;
   1272     static const GrGLfloat scale255 = 1.f / 255.f;
   1273     a = GrColorUnpackA(color) * scale255;
   1274     GrGLfloat scaleRGB = scale255;
   1275     if (GrPixelConfigIsUnpremultiplied(rt->config())) {
   1276         scaleRGB *= a;
   1277     }
   1278     r = GrColorUnpackR(color) * scaleRGB;
   1279     g = GrColorUnpackG(color) * scaleRGB;
   1280     b = GrColorUnpackB(color) * scaleRGB;
   1281 
   1282     GL_CALL(ColorMask(GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE));
   1283     fHWDrawState.disableState(GrDrawState::kNoColorWrites_StateBit);
   1284     GL_CALL(ClearColor(r, g, b, a));
   1285     GL_CALL(Clear(GR_GL_COLOR_BUFFER_BIT));
   1286 }
   1287 
   1288 void GrGpuGL::clearStencil() {
   1289     if (NULL == this->getDrawState().getRenderTarget()) {
   1290         return;
   1291     }
   1292 
   1293     this->flushRenderTarget(&GrIRect::EmptyIRect());
   1294 
   1295     if (fHWBounds.fScissorEnabled) {
   1296         GL_CALL(Disable(GR_GL_SCISSOR_TEST));
   1297         fHWBounds.fScissorEnabled = false;
   1298     }
   1299     GL_CALL(StencilMask(0xffffffff));
   1300     GL_CALL(ClearStencil(0));
   1301     GL_CALL(Clear(GR_GL_STENCIL_BUFFER_BIT));
   1302     fHWDrawState.stencil()->invalidate();
   1303 }
   1304 
   1305 void GrGpuGL::clearStencilClip(const GrIRect& rect, bool insideClip) {
   1306     const GrDrawState& drawState = this->getDrawState();
   1307     const GrRenderTarget* rt = drawState.getRenderTarget();
   1308     GrAssert(NULL != rt);
   1309 
   1310     // this should only be called internally when we know we have a
   1311     // stencil buffer.
   1312     GrAssert(NULL != rt->getStencilBuffer());
   1313     GrGLint stencilBitCount =  rt->getStencilBuffer()->bits();
   1314 #if 0
   1315     GrAssert(stencilBitCount > 0);
   1316     GrGLint clipStencilMask  = (1 << (stencilBitCount - 1));
   1317 #else
   1318     // we could just clear the clip bit but when we go through
   1319     // ANGLE a partial stencil mask will cause clears to be
   1320     // turned into draws. Our contract on GrDrawTarget says that
   1321     // changing the clip between stencil passes may or may not
   1322     // zero the client's clip bits. So we just clear the whole thing.
   1323     static const GrGLint clipStencilMask  = ~0;
   1324 #endif
   1325     GrGLint value;
   1326     if (insideClip) {
   1327         value = (1 << (stencilBitCount - 1));
   1328     } else {
   1329         value = 0;
   1330     }
   1331     this->flushRenderTarget(&GrIRect::EmptyIRect());
   1332     this->flushScissor(&rect);
   1333     GL_CALL(StencilMask(clipStencilMask));
   1334     GL_CALL(ClearStencil(value));
   1335     GL_CALL(Clear(GR_GL_STENCIL_BUFFER_BIT));
   1336     fHWDrawState.stencil()->invalidate();
   1337 }
   1338 
   1339 void GrGpuGL::onForceRenderTargetFlush() {
   1340     this->flushRenderTarget(&GrIRect::EmptyIRect());
   1341 }
   1342 
   1343 bool GrGpuGL::readPixelsWillPayForYFlip(GrRenderTarget* renderTarget,
   1344                                         int left, int top,
   1345                                         int width, int height,
   1346                                         GrPixelConfig config,
   1347                                         size_t rowBytes) const {
   1348     // if GL can do the flip then we'll never pay for it.
   1349     if (this->glCaps().packFlipYSupport()) {
   1350         return false;
   1351     }
   1352 
   1353     // If we have to do memcpy to handle non-trim rowBytes then we
   1354     // get the flip for free. Otherwise it costs.
   1355     if (this->glCaps().packRowLengthSupport()) {
   1356         return true;
   1357     }
   1358     // If we have to do memcpys to handle rowBytes then y-flip is free
   1359     // Note the rowBytes might be tight to the passed in data, but if data
   1360     // gets clipped in x to the target the rowBytes will no longer be tight.
   1361     if (left >= 0 && (left + width) < renderTarget->width()) {
   1362            return 0 == rowBytes ||
   1363                   GrBytesPerPixel(config) * width == rowBytes;
   1364     } else {
   1365         return false;
   1366     }
   1367 }
   1368 
   1369 bool GrGpuGL::onReadPixels(GrRenderTarget* target,
   1370                            int left, int top,
   1371                            int width, int height,
   1372                            GrPixelConfig config,
   1373                            void* buffer,
   1374                            size_t rowBytes,
   1375                            bool invertY) {
   1376     GrGLenum format;
   1377     GrGLenum type;
   1378     if (!this->configToGLFormats(config, false, NULL, &format, &type)) {
   1379         return false;
   1380     }
   1381     size_t bpp = GrBytesPerPixel(config);
   1382     if (!adjust_pixel_ops_params(target->width(), target->height(), bpp,
   1383                                  &left, &top, &width, &height,
   1384                                  const_cast<const void**>(&buffer),
   1385                                  &rowBytes)) {
   1386         return false;
   1387     }
   1388 
   1389     // resolve the render target if necessary
   1390     GrGLRenderTarget* tgt = static_cast<GrGLRenderTarget*>(target);
   1391     GrDrawState::AutoRenderTargetRestore artr;
   1392     switch (tgt->getResolveType()) {
   1393         case GrGLRenderTarget::kCantResolve_ResolveType:
   1394             return false;
   1395         case GrGLRenderTarget::kAutoResolves_ResolveType:
   1396             artr.set(this->drawState(), target);
   1397             this->flushRenderTarget(&GrIRect::EmptyIRect());
   1398             break;
   1399         case GrGLRenderTarget::kCanResolve_ResolveType:
   1400             this->onResolveRenderTarget(tgt);
   1401             // we don't track the state of the READ FBO ID.
   1402             GL_CALL(BindFramebuffer(GR_GL_READ_FRAMEBUFFER,
   1403                                     tgt->textureFBOID()));
   1404             break;
   1405         default:
   1406             GrCrash("Unknown resolve type");
   1407     }
   1408 
   1409     const GrGLIRect& glvp = tgt->getViewport();
   1410 
   1411     // the read rect is viewport-relative
   1412     GrGLIRect readRect;
   1413     readRect.setRelativeTo(glvp, left, top, width, height);
   1414 
   1415     size_t tightRowBytes = bpp * width;
   1416     if (0 == rowBytes) {
   1417         rowBytes = tightRowBytes;
   1418     }
   1419     size_t readDstRowBytes = tightRowBytes;
   1420     void* readDst = buffer;
   1421 
   1422     // determine if GL can read using the passed rowBytes or if we need
   1423     // a scratch buffer.
   1424     SkAutoSMalloc<32 * sizeof(GrColor)> scratch;
   1425     if (rowBytes != tightRowBytes) {
   1426         if (this->glCaps().packRowLengthSupport()) {
   1427             GrAssert(!(rowBytes % sizeof(GrColor)));
   1428             GL_CALL(PixelStorei(GR_GL_PACK_ROW_LENGTH, rowBytes / sizeof(GrColor)));
   1429             readDstRowBytes = rowBytes;
   1430         } else {
   1431             scratch.reset(tightRowBytes * height);
   1432             readDst = scratch.get();
   1433         }
   1434     }
   1435     if (!invertY && this->glCaps().packFlipYSupport()) {
   1436         GL_CALL(PixelStorei(GR_GL_PACK_REVERSE_ROW_ORDER, 1));
   1437     }
   1438     GL_CALL(ReadPixels(readRect.fLeft, readRect.fBottom,
   1439                        readRect.fWidth, readRect.fHeight,
   1440                        format, type, readDst));
   1441     if (readDstRowBytes != tightRowBytes) {
   1442         GrAssert(this->glCaps().packRowLengthSupport());
   1443         GL_CALL(PixelStorei(GR_GL_PACK_ROW_LENGTH, 0));
   1444     }
   1445     if (!invertY && this->glCaps().packFlipYSupport()) {
   1446         GL_CALL(PixelStorei(GR_GL_PACK_REVERSE_ROW_ORDER, 0));
   1447         invertY = true;
   1448     }
   1449 
   1450     // now reverse the order of the rows, since GL's are bottom-to-top, but our
   1451     // API presents top-to-bottom. We must preserve the padding contents. Note
   1452     // that the above readPixels did not overwrite the padding.
   1453     if (readDst == buffer) {
   1454         GrAssert(rowBytes == readDstRowBytes);
   1455         if (!invertY) {
   1456             scratch.reset(tightRowBytes);
   1457             void* tmpRow = scratch.get();
   1458             // flip y in-place by rows
   1459             const int halfY = height >> 1;
   1460             char* top = reinterpret_cast<char*>(buffer);
   1461             char* bottom = top + (height - 1) * rowBytes;
   1462             for (int y = 0; y < halfY; y++) {
   1463                 memcpy(tmpRow, top, tightRowBytes);
   1464                 memcpy(top, bottom, tightRowBytes);
   1465                 memcpy(bottom, tmpRow, tightRowBytes);
   1466                 top += rowBytes;
   1467                 bottom -= rowBytes;
   1468             }
   1469         }
   1470     } else {
   1471         GrAssert(readDst != buffer);        GrAssert(rowBytes != tightRowBytes);
   1472         // copy from readDst to buffer while flipping y
   1473         const int halfY = height >> 1;
   1474         const char* src = reinterpret_cast<const char*>(readDst);
   1475         char* dst = reinterpret_cast<char*>(buffer);
   1476         if (!invertY) {
   1477             dst += (height-1) * rowBytes;
   1478         }
   1479         for (int y = 0; y < height; y++) {
   1480             memcpy(dst, src, tightRowBytes);
   1481             src += readDstRowBytes;
   1482             if (invertY) {
   1483                 dst += rowBytes;
   1484             } else {
   1485                 dst -= rowBytes;
   1486             }
   1487         }
   1488     }
   1489     return true;
   1490 }
   1491 
   1492 void GrGpuGL::flushRenderTarget(const GrIRect* bound) {
   1493 
   1494     GrGLRenderTarget* rt =
   1495         static_cast<GrGLRenderTarget*>(this->drawState()->getRenderTarget());
   1496     GrAssert(NULL != rt);
   1497 
   1498     if (fHWDrawState.getRenderTarget() != rt) {
   1499         GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, rt->renderFBOID()));
   1500     #if GR_COLLECT_STATS
   1501         ++fStats.fRenderTargetChngCnt;
   1502     #endif
   1503     #if GR_DEBUG
   1504         GrGLenum status;
   1505         GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER));
   1506         if (status != GR_GL_FRAMEBUFFER_COMPLETE) {
   1507             GrPrintf("GrGpuGL::flushRenderTarget glCheckFramebufferStatus %x\n", status);
   1508         }
   1509     #endif
   1510         fDirtyFlags.fRenderTargetChanged = true;
   1511         fHWDrawState.setRenderTarget(rt);
   1512         const GrGLIRect& vp = rt->getViewport();
   1513         if (fHWBounds.fViewportRect != vp) {
   1514             vp.pushToGLViewport(this->glInterface());
   1515             fHWBounds.fViewportRect = vp;
   1516         }
   1517     }
   1518     if (NULL == bound || !bound->isEmpty()) {
   1519         rt->flagAsNeedingResolve(bound);
   1520     }
   1521 }
   1522 
   1523 GrGLenum gPrimitiveType2GLMode[] = {
   1524     GR_GL_TRIANGLES,
   1525     GR_GL_TRIANGLE_STRIP,
   1526     GR_GL_TRIANGLE_FAN,
   1527     GR_GL_POINTS,
   1528     GR_GL_LINES,
   1529     GR_GL_LINE_STRIP
   1530 };
   1531 
   1532 #define SWAP_PER_DRAW 0
   1533 
   1534 #if SWAP_PER_DRAW
   1535     #if GR_MAC_BUILD
   1536         #include <AGL/agl.h>
   1537     #elif GR_WIN32_BUILD
   1538         void SwapBuf() {
   1539             DWORD procID = GetCurrentProcessId();
   1540             HWND hwnd = GetTopWindow(GetDesktopWindow());
   1541             while(hwnd) {
   1542                 DWORD wndProcID = 0;
   1543                 GetWindowThreadProcessId(hwnd, &wndProcID);
   1544                 if(wndProcID == procID) {
   1545                     SwapBuffers(GetDC(hwnd));
   1546                 }
   1547                 hwnd = GetNextWindow(hwnd, GW_HWNDNEXT);
   1548             }
   1549          }
   1550     #endif
   1551 #endif
   1552 
   1553 void GrGpuGL::onGpuDrawIndexed(GrPrimitiveType type,
   1554                                uint32_t startVertex,
   1555                                uint32_t startIndex,
   1556                                uint32_t vertexCount,
   1557                                uint32_t indexCount) {
   1558     GrAssert((size_t)type < GR_ARRAY_COUNT(gPrimitiveType2GLMode));
   1559 
   1560     GrGLvoid* indices = (GrGLvoid*)(sizeof(uint16_t) * startIndex);
   1561 
   1562     GrAssert(NULL != fHWGeometryState.fIndexBuffer);
   1563     GrAssert(NULL != fHWGeometryState.fVertexBuffer);
   1564 
   1565     // our setupGeometry better have adjusted this to zero since
   1566     // DrawElements always draws from the begining of the arrays for idx 0.
   1567     GrAssert(0 == startVertex);
   1568 
   1569     GL_CALL(DrawElements(gPrimitiveType2GLMode[type], indexCount,
   1570                          GR_GL_UNSIGNED_SHORT, indices));
   1571 #if SWAP_PER_DRAW
   1572     glFlush();
   1573     #if GR_MAC_BUILD
   1574         aglSwapBuffers(aglGetCurrentContext());
   1575         int set_a_break_pt_here = 9;
   1576         aglSwapBuffers(aglGetCurrentContext());
   1577     #elif GR_WIN32_BUILD
   1578         SwapBuf();
   1579         int set_a_break_pt_here = 9;
   1580         SwapBuf();
   1581     #endif
   1582 #endif
   1583 }
   1584 
   1585 void GrGpuGL::onGpuDrawNonIndexed(GrPrimitiveType type,
   1586                                   uint32_t startVertex,
   1587                                   uint32_t vertexCount) {
   1588     GrAssert((size_t)type < GR_ARRAY_COUNT(gPrimitiveType2GLMode));
   1589 
   1590     GrAssert(NULL != fHWGeometryState.fVertexBuffer);
   1591 
   1592     // our setupGeometry better have adjusted this to zero.
   1593     // DrawElements doesn't take an offset so we always adjus the startVertex.
   1594     GrAssert(0 == startVertex);
   1595 
   1596     // pass 0 for parameter first. We have to adjust gl*Pointer() to
   1597     // account for startVertex in the DrawElements case. So we always
   1598     // rely on setupGeometry to have accounted for startVertex.
   1599     GL_CALL(DrawArrays(gPrimitiveType2GLMode[type], 0, vertexCount));
   1600 #if SWAP_PER_DRAW
   1601     glFlush();
   1602     #if GR_MAC_BUILD
   1603         aglSwapBuffers(aglGetCurrentContext());
   1604         int set_a_break_pt_here = 9;
   1605         aglSwapBuffers(aglGetCurrentContext());
   1606     #elif GR_WIN32_BUILD
   1607         SwapBuf();
   1608         int set_a_break_pt_here = 9;
   1609         SwapBuf();
   1610     #endif
   1611 #endif
   1612 }
   1613 
   1614 void GrGpuGL::onResolveRenderTarget(GrRenderTarget* target) {
   1615 
   1616     GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(target);
   1617 
   1618     if (rt->needsResolve()) {
   1619         GrAssert(GrGLCaps::kNone_MSFBOType != this->glCaps().msFBOType());
   1620         GrAssert(rt->textureFBOID() != rt->renderFBOID());
   1621         GL_CALL(BindFramebuffer(GR_GL_READ_FRAMEBUFFER,
   1622                                 rt->renderFBOID()));
   1623         GL_CALL(BindFramebuffer(GR_GL_DRAW_FRAMEBUFFER,
   1624                                 rt->textureFBOID()));
   1625     #if GR_COLLECT_STATS
   1626         ++fStats.fRenderTargetChngCnt;
   1627     #endif
   1628         // make sure we go through flushRenderTarget() since we've modified
   1629         // the bound DRAW FBO ID.
   1630         fHWDrawState.setRenderTarget(NULL);
   1631         const GrGLIRect& vp = rt->getViewport();
   1632         const GrIRect dirtyRect = rt->getResolveRect();
   1633         GrGLIRect r;
   1634         r.setRelativeTo(vp, dirtyRect.fLeft, dirtyRect.fTop,
   1635                         dirtyRect.width(), dirtyRect.height());
   1636 
   1637         if (GrGLCaps::kAppleES_MSFBOType == this->glCaps().msFBOType()) {
   1638             // Apple's extension uses the scissor as the blit bounds.
   1639             GL_CALL(Enable(GR_GL_SCISSOR_TEST));
   1640             GL_CALL(Scissor(r.fLeft, r.fBottom,
   1641                             r.fWidth, r.fHeight));
   1642             GL_CALL(ResolveMultisampleFramebuffer());
   1643             fHWBounds.fScissorRect.invalidate();
   1644             fHWBounds.fScissorEnabled = true;
   1645         } else {
   1646             if (GrGLCaps::kDesktopARB_MSFBOType != this->glCaps().msFBOType()) {
   1647                 // this respects the scissor during the blit, so disable it.
   1648                 GrAssert(GrGLCaps::kDesktopEXT_MSFBOType ==
   1649                          this->glCaps().msFBOType());
   1650                 this->flushScissor(NULL);
   1651             }
   1652             int right = r.fLeft + r.fWidth;
   1653             int top = r.fBottom + r.fHeight;
   1654             GL_CALL(BlitFramebuffer(r.fLeft, r.fBottom, right, top,
   1655                                     r.fLeft, r.fBottom, right, top,
   1656                                     GR_GL_COLOR_BUFFER_BIT, GR_GL_NEAREST));
   1657         }
   1658         rt->flagAsResolved();
   1659     }
   1660 }
   1661 
   1662 static const GrGLenum grToGLStencilFunc[] = {
   1663     GR_GL_ALWAYS,           // kAlways_StencilFunc
   1664     GR_GL_NEVER,            // kNever_StencilFunc
   1665     GR_GL_GREATER,          // kGreater_StencilFunc
   1666     GR_GL_GEQUAL,           // kGEqual_StencilFunc
   1667     GR_GL_LESS,             // kLess_StencilFunc
   1668     GR_GL_LEQUAL,           // kLEqual_StencilFunc,
   1669     GR_GL_EQUAL,            // kEqual_StencilFunc,
   1670     GR_GL_NOTEQUAL,         // kNotEqual_StencilFunc,
   1671 };
   1672 GR_STATIC_ASSERT(GR_ARRAY_COUNT(grToGLStencilFunc) == kBasicStencilFuncCount);
   1673 GR_STATIC_ASSERT(0 == kAlways_StencilFunc);
   1674 GR_STATIC_ASSERT(1 == kNever_StencilFunc);
   1675 GR_STATIC_ASSERT(2 == kGreater_StencilFunc);
   1676 GR_STATIC_ASSERT(3 == kGEqual_StencilFunc);
   1677 GR_STATIC_ASSERT(4 == kLess_StencilFunc);
   1678 GR_STATIC_ASSERT(5 == kLEqual_StencilFunc);
   1679 GR_STATIC_ASSERT(6 == kEqual_StencilFunc);
   1680 GR_STATIC_ASSERT(7 == kNotEqual_StencilFunc);
   1681 
   1682 static const GrGLenum grToGLStencilOp[] = {
   1683     GR_GL_KEEP,        // kKeep_StencilOp
   1684     GR_GL_REPLACE,     // kReplace_StencilOp
   1685     GR_GL_INCR_WRAP,   // kIncWrap_StencilOp
   1686     GR_GL_INCR,        // kIncClamp_StencilOp
   1687     GR_GL_DECR_WRAP,   // kDecWrap_StencilOp
   1688     GR_GL_DECR,        // kDecClamp_StencilOp
   1689     GR_GL_ZERO,        // kZero_StencilOp
   1690     GR_GL_INVERT,      // kInvert_StencilOp
   1691 };
   1692 GR_STATIC_ASSERT(GR_ARRAY_COUNT(grToGLStencilOp) == kStencilOpCount);
   1693 GR_STATIC_ASSERT(0 == kKeep_StencilOp);
   1694 GR_STATIC_ASSERT(1 == kReplace_StencilOp);
   1695 GR_STATIC_ASSERT(2 == kIncWrap_StencilOp);
   1696 GR_STATIC_ASSERT(3 == kIncClamp_StencilOp);
   1697 GR_STATIC_ASSERT(4 == kDecWrap_StencilOp);
   1698 GR_STATIC_ASSERT(5 == kDecClamp_StencilOp);
   1699 GR_STATIC_ASSERT(6 == kZero_StencilOp);
   1700 GR_STATIC_ASSERT(7 == kInvert_StencilOp);
   1701 
   1702 void GrGpuGL::flushStencil() {
   1703     const GrDrawState& drawState = this->getDrawState();
   1704 
   1705     const GrStencilSettings* settings = &drawState.getStencil();
   1706 
   1707     // use stencil for clipping if clipping is enabled and the clip
   1708     // has been written into the stencil.
   1709     bool stencilClip = fClipInStencil && drawState.isClipState();
   1710     bool drawClipToStencil =
   1711         drawState.isStateFlagEnabled(kModifyStencilClip_StateBit);
   1712     bool stencilChange = (fHWDrawState.getStencil() != *settings) ||
   1713                          (fHWStencilClip != stencilClip) ||
   1714                          (fHWDrawState.isStateFlagEnabled(kModifyStencilClip_StateBit) !=
   1715                           drawClipToStencil);
   1716 
   1717     if (stencilChange) {
   1718 
   1719         // we can't simultaneously perform stencil-clipping and
   1720         // modify the stencil clip
   1721         GrAssert(!stencilClip || !drawClipToStencil);
   1722 
   1723         if (settings->isDisabled()) {
   1724             if (stencilClip) {
   1725                 settings = GetClipStencilSettings();
   1726             }
   1727         }
   1728 
   1729         if (settings->isDisabled()) {
   1730             GL_CALL(Disable(GR_GL_STENCIL_TEST));
   1731         } else {
   1732             GL_CALL(Enable(GR_GL_STENCIL_TEST));
   1733     #if GR_DEBUG
   1734             if (!this->getCaps().fStencilWrapOpsSupport) {
   1735                 GrAssert(settings->frontPassOp() != kIncWrap_StencilOp);
   1736                 GrAssert(settings->frontPassOp() != kDecWrap_StencilOp);
   1737                 GrAssert(settings->frontFailOp() != kIncWrap_StencilOp);
   1738                 GrAssert(settings->backFailOp() != kDecWrap_StencilOp);
   1739                 GrAssert(settings->backPassOp() != kIncWrap_StencilOp);
   1740                 GrAssert(settings->backPassOp() != kDecWrap_StencilOp);
   1741                 GrAssert(settings->backFailOp() != kIncWrap_StencilOp);
   1742                 GrAssert(settings->frontFailOp() != kDecWrap_StencilOp);
   1743             }
   1744     #endif
   1745             int stencilBits = 0;
   1746             GrStencilBuffer* stencilBuffer =
   1747                 drawState.getRenderTarget()->getStencilBuffer();
   1748             if (NULL != stencilBuffer) {
   1749                 stencilBits = stencilBuffer->bits();
   1750             }
   1751             // TODO: dynamically attach a stencil buffer
   1752             GrAssert(stencilBits || settings->isDisabled());
   1753 
   1754             GrGLuint clipStencilMask = 0;
   1755             GrGLuint userStencilMask = ~0;
   1756             if (stencilBits > 0) {
   1757                 clipStencilMask =  1 << (stencilBits - 1);
   1758                 userStencilMask = clipStencilMask - 1;
   1759             }
   1760 
   1761             unsigned int frontRef  = settings->frontFuncRef();
   1762             unsigned int frontMask = settings->frontFuncMask();
   1763             unsigned int frontWriteMask = settings->frontWriteMask();
   1764             GrGLenum frontFunc;
   1765 
   1766             if (drawClipToStencil) {
   1767                 GrAssert(settings->frontFunc() < kBasicStencilFuncCount);
   1768                 frontFunc = grToGLStencilFunc[settings->frontFunc()];
   1769             } else {
   1770                 frontFunc = grToGLStencilFunc[ConvertStencilFunc(
   1771                         stencilClip, settings->frontFunc())];
   1772 
   1773                 ConvertStencilFuncAndMask(settings->frontFunc(),
   1774                                           stencilClip,
   1775                                           clipStencilMask,
   1776                                           userStencilMask,
   1777                                           &frontRef,
   1778                                           &frontMask);
   1779                 frontWriteMask &= userStencilMask;
   1780             }
   1781             GrAssert((size_t)
   1782                 settings->frontFailOp() < GR_ARRAY_COUNT(grToGLStencilOp));
   1783             GrAssert((size_t)
   1784                 settings->frontPassOp() < GR_ARRAY_COUNT(grToGLStencilOp));
   1785             GrAssert((size_t)
   1786                 settings->backFailOp() < GR_ARRAY_COUNT(grToGLStencilOp));
   1787             GrAssert((size_t)
   1788                 settings->backPassOp() < GR_ARRAY_COUNT(grToGLStencilOp));
   1789             if (this->getCaps().fTwoSidedStencilSupport) {
   1790                 GrGLenum backFunc;
   1791 
   1792                 unsigned int backRef  = settings->backFuncRef();
   1793                 unsigned int backMask = settings->backFuncMask();
   1794                 unsigned int backWriteMask = settings->backWriteMask();
   1795 
   1796 
   1797                 if (drawClipToStencil) {
   1798                     GrAssert(settings->backFunc() < kBasicStencilFuncCount);
   1799                     backFunc = grToGLStencilFunc[settings->backFunc()];
   1800                 } else {
   1801                     backFunc = grToGLStencilFunc[ConvertStencilFunc(
   1802                         stencilClip, settings->backFunc())];
   1803                     ConvertStencilFuncAndMask(settings->backFunc(),
   1804                                               stencilClip,
   1805                                               clipStencilMask,
   1806                                               userStencilMask,
   1807                                               &backRef,
   1808                                               &backMask);
   1809                     backWriteMask &= userStencilMask;
   1810                 }
   1811 
   1812                 GL_CALL(StencilFuncSeparate(GR_GL_FRONT, frontFunc,
   1813                                             frontRef, frontMask));
   1814                 GL_CALL(StencilMaskSeparate(GR_GL_FRONT, frontWriteMask));
   1815                 GL_CALL(StencilFuncSeparate(GR_GL_BACK, backFunc,
   1816                                             backRef, backMask));
   1817                 GL_CALL(StencilMaskSeparate(GR_GL_BACK, backWriteMask));
   1818                 GL_CALL(StencilOpSeparate(GR_GL_FRONT,
   1819                                     grToGLStencilOp[settings->frontFailOp()],
   1820                                     grToGLStencilOp[settings->frontPassOp()],
   1821                                     grToGLStencilOp[settings->frontPassOp()]));
   1822 
   1823                 GL_CALL(StencilOpSeparate(GR_GL_BACK,
   1824                                     grToGLStencilOp[settings->backFailOp()],
   1825                                     grToGLStencilOp[settings->backPassOp()],
   1826                                     grToGLStencilOp[settings->backPassOp()]));
   1827             } else {
   1828                 GL_CALL(StencilFunc(frontFunc, frontRef, frontMask));
   1829                 GL_CALL(StencilMask(frontWriteMask));
   1830                 GL_CALL(StencilOp(grToGLStencilOp[settings->frontFailOp()],
   1831                                 grToGLStencilOp[settings->frontPassOp()],
   1832                                 grToGLStencilOp[settings->frontPassOp()]));
   1833             }
   1834         }
   1835         *fHWDrawState.stencil() = *settings;
   1836         fHWStencilClip = stencilClip;
   1837     }
   1838 }
   1839 
   1840 void GrGpuGL::flushAAState(GrPrimitiveType type) {
   1841     const GrRenderTarget* rt = this->getDrawState().getRenderTarget();
   1842     if (kDesktop_GrGLBinding == this->glBinding()) {
   1843         // ES doesn't support toggling GL_MULTISAMPLE and doesn't have
   1844         // smooth lines.
   1845 
   1846         // we prefer smooth lines over multisampled lines
   1847         // msaa should be disabled if drawing smooth lines.
   1848         if (GrIsPrimTypeLines(type)) {
   1849             bool smooth = this->willUseHWAALines();
   1850             if (!fHWAAState.fSmoothLineEnabled && smooth) {
   1851                 GL_CALL(Enable(GR_GL_LINE_SMOOTH));
   1852                 fHWAAState.fSmoothLineEnabled = true;
   1853             } else if (fHWAAState.fSmoothLineEnabled && !smooth) {
   1854                 GL_CALL(Disable(GR_GL_LINE_SMOOTH));
   1855                 fHWAAState.fSmoothLineEnabled = false;
   1856             }
   1857             if (rt->isMultisampled() &&
   1858                 fHWAAState.fMSAAEnabled) {
   1859                 GL_CALL(Disable(GR_GL_MULTISAMPLE));
   1860                 fHWAAState.fMSAAEnabled = false;
   1861             }
   1862         } else if (rt->isMultisampled() &&
   1863                    this->getDrawState().isHWAntialiasState() !=
   1864                    fHWAAState.fMSAAEnabled) {
   1865             if (fHWAAState.fMSAAEnabled) {
   1866                 GL_CALL(Disable(GR_GL_MULTISAMPLE));
   1867                 fHWAAState.fMSAAEnabled = false;
   1868             } else {
   1869                 GL_CALL(Enable(GR_GL_MULTISAMPLE));
   1870                 fHWAAState.fMSAAEnabled = true;
   1871             }
   1872         }
   1873     }
   1874 }
   1875 
   1876 void GrGpuGL::flushBlend(GrPrimitiveType type,
   1877                          GrBlendCoeff srcCoeff,
   1878                          GrBlendCoeff dstCoeff) {
   1879     if (GrIsPrimTypeLines(type) && this->willUseHWAALines()) {
   1880         if (fHWBlendDisabled) {
   1881             GL_CALL(Enable(GR_GL_BLEND));
   1882             fHWBlendDisabled = false;
   1883         }
   1884         if (kSA_BlendCoeff != fHWDrawState.getSrcBlendCoeff() ||
   1885             kISA_BlendCoeff != fHWDrawState.getDstBlendCoeff()) {
   1886             GL_CALL(BlendFunc(gXfermodeCoeff2Blend[kSA_BlendCoeff],
   1887                               gXfermodeCoeff2Blend[kISA_BlendCoeff]));
   1888             fHWDrawState.setBlendFunc(kSA_BlendCoeff, kISA_BlendCoeff);
   1889         }
   1890     } else {
   1891         // any optimization to disable blending should
   1892         // have already been applied and tweaked the coeffs
   1893         // to (1, 0).
   1894         bool blendOff = kOne_BlendCoeff == srcCoeff &&
   1895                         kZero_BlendCoeff == dstCoeff;
   1896         if (fHWBlendDisabled != blendOff) {
   1897             if (blendOff) {
   1898                 GL_CALL(Disable(GR_GL_BLEND));
   1899             } else {
   1900                 GL_CALL(Enable(GR_GL_BLEND));
   1901             }
   1902             fHWBlendDisabled = blendOff;
   1903         }
   1904         if (!blendOff) {
   1905             if (fHWDrawState.getSrcBlendCoeff() != srcCoeff ||
   1906                 fHWDrawState.getDstBlendCoeff() != dstCoeff) {
   1907                 GL_CALL(BlendFunc(gXfermodeCoeff2Blend[srcCoeff],
   1908                                   gXfermodeCoeff2Blend[dstCoeff]));
   1909                 fHWDrawState.setBlendFunc(srcCoeff, dstCoeff);
   1910             }
   1911             GrColor blendConst = fCurrDrawState.getBlendConstant();
   1912             if ((BlendCoeffReferencesConstant(srcCoeff) ||
   1913                  BlendCoeffReferencesConstant(dstCoeff)) &&
   1914                 fHWDrawState.getBlendConstant() != blendConst) {
   1915 
   1916                 float c[] = {
   1917                     GrColorUnpackR(blendConst) / 255.f,
   1918                     GrColorUnpackG(blendConst) / 255.f,
   1919                     GrColorUnpackB(blendConst) / 255.f,
   1920                     GrColorUnpackA(blendConst) / 255.f
   1921                 };
   1922                 GL_CALL(BlendColor(c[0], c[1], c[2], c[3]));
   1923                 fHWDrawState.setBlendConstant(blendConst);
   1924             }
   1925         }
   1926     }
   1927 }
   1928 
   1929 namespace {
   1930 
   1931 unsigned gr_to_gl_filter(GrSamplerState::Filter filter) {
   1932     switch (filter) {
   1933         case GrSamplerState::kBilinear_Filter:
   1934         case GrSamplerState::k4x4Downsample_Filter:
   1935             return GR_GL_LINEAR;
   1936         case GrSamplerState::kNearest_Filter:
   1937         case GrSamplerState::kConvolution_Filter:
   1938         case GrSamplerState::kErode_Filter:
   1939         case GrSamplerState::kDilate_Filter:
   1940             return GR_GL_NEAREST;
   1941         default:
   1942             GrAssert(!"Unknown filter type");
   1943             return GR_GL_LINEAR;
   1944     }
   1945 }
   1946 
   1947 const GrGLenum* get_swizzle(GrPixelConfig config,
   1948                             const GrSamplerState& sampler) {
   1949     if (GrPixelConfigIsAlphaOnly(config)) {
   1950         static const GrGLenum gAlphaSmear[] = { GR_GL_ALPHA, GR_GL_ALPHA,
   1951                                                 GR_GL_ALPHA, GR_GL_ALPHA };
   1952         return gAlphaSmear;
   1953     } else if (sampler.swapsRAndB()) {
   1954         static const GrGLenum gRedBlueSwap[] = { GR_GL_BLUE, GR_GL_GREEN,
   1955                                                  GR_GL_RED,  GR_GL_ALPHA };
   1956         return gRedBlueSwap;
   1957     } else {
   1958         static const GrGLenum gStraight[] = { GR_GL_RED, GR_GL_GREEN,
   1959                                               GR_GL_BLUE,  GR_GL_ALPHA };
   1960         return gStraight;
   1961     }
   1962 }
   1963 
   1964 void set_tex_swizzle(GrGLenum swizzle[4], const GrGLInterface* gl) {
   1965     // should add texparameteri to interface to make 1 instead of 4 calls here
   1966     GR_GL_CALL(gl, TexParameteri(GR_GL_TEXTURE_2D,
   1967                                  GR_GL_TEXTURE_SWIZZLE_R,
   1968                                  swizzle[0]));
   1969     GR_GL_CALL(gl, TexParameteri(GR_GL_TEXTURE_2D,
   1970                                  GR_GL_TEXTURE_SWIZZLE_G,
   1971                                  swizzle[1]));
   1972     GR_GL_CALL(gl, TexParameteri(GR_GL_TEXTURE_2D,
   1973                                  GR_GL_TEXTURE_SWIZZLE_B,
   1974                                  swizzle[2]));
   1975     GR_GL_CALL(gl, TexParameteri(GR_GL_TEXTURE_2D,
   1976                                  GR_GL_TEXTURE_SWIZZLE_A,
   1977                                  swizzle[3]));
   1978 }
   1979 }
   1980 
   1981 bool GrGpuGL::flushGLStateCommon(GrPrimitiveType type) {
   1982 
   1983     GrDrawState* drawState = this->drawState();
   1984     // GrGpu::setupClipAndFlushState should have already checked this
   1985     // and bailed if not true.
   1986     GrAssert(NULL != drawState->getRenderTarget());
   1987 
   1988     for (int s = 0; s < GrDrawState::kNumStages; ++s) {
   1989         // bind texture and set sampler state
   1990         if (this->isStageEnabled(s)) {
   1991             GrGLTexture* nextTexture =
   1992                 static_cast<GrGLTexture*>(drawState->getTexture(s));
   1993 
   1994             // true for now, but maybe not with GrEffect.
   1995             GrAssert(NULL != nextTexture);
   1996             // if we created a rt/tex and rendered to it without using a
   1997             // texture and now we're texuring from the rt it will still be
   1998             // the last bound texture, but it needs resolving. So keep this
   1999             // out of the "last != next" check.
   2000             GrGLRenderTarget* texRT =
   2001                 static_cast<GrGLRenderTarget*>(nextTexture->asRenderTarget());
   2002             if (NULL != texRT) {
   2003                 this->onResolveRenderTarget(texRT);
   2004             }
   2005 
   2006             if (fHWDrawState.getTexture(s) != nextTexture) {
   2007                 setTextureUnit(s);
   2008                 GL_CALL(BindTexture(GR_GL_TEXTURE_2D, nextTexture->textureID()));
   2009             #if GR_COLLECT_STATS
   2010                 ++fStats.fTextureChngCnt;
   2011             #endif
   2012                 //GrPrintf("---- bindtexture %d\n", nextTexture->textureID());
   2013                 fHWDrawState.setTexture(s, nextTexture);
   2014                 // The texture matrix has to compensate for texture width/height
   2015                 // and NPOT-embedded-in-POT
   2016                 fDirtyFlags.fTextureChangedMask |= (1 << s);
   2017             }
   2018 
   2019             const GrSamplerState& sampler = drawState->getSampler(s);
   2020             ResetTimestamp timestamp;
   2021             const GrGLTexture::TexParams& oldTexParams =
   2022                                     nextTexture->getCachedTexParams(&timestamp);
   2023             bool setAll = timestamp < this->getResetTimestamp();
   2024             GrGLTexture::TexParams newTexParams;
   2025 
   2026             newTexParams.fFilter = gr_to_gl_filter(sampler.getFilter());
   2027 
   2028             const GrGLenum* wraps =  GrGLTexture::WrapMode2GLWrap();
   2029             newTexParams.fWrapS = wraps[sampler.getWrapX()];
   2030             newTexParams.fWrapT = wraps[sampler.getWrapY()];
   2031             memcpy(newTexParams.fSwizzleRGBA,
   2032                    get_swizzle(nextTexture->config(), sampler),
   2033                    sizeof(newTexParams.fSwizzleRGBA));
   2034             if (setAll || newTexParams.fFilter != oldTexParams.fFilter) {
   2035                 setTextureUnit(s);
   2036                 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
   2037                                         GR_GL_TEXTURE_MAG_FILTER,
   2038                                         newTexParams.fFilter));
   2039                 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
   2040                                         GR_GL_TEXTURE_MIN_FILTER,
   2041                                         newTexParams.fFilter));
   2042             }
   2043             if (setAll || newTexParams.fWrapS != oldTexParams.fWrapS) {
   2044                 setTextureUnit(s);
   2045                 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
   2046                                         GR_GL_TEXTURE_WRAP_S,
   2047                                         newTexParams.fWrapS));
   2048             }
   2049             if (setAll || newTexParams.fWrapT != oldTexParams.fWrapT) {
   2050                 setTextureUnit(s);
   2051                 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
   2052                                         GR_GL_TEXTURE_WRAP_T,
   2053                                         newTexParams.fWrapT));
   2054             }
   2055             if (this->glCaps().textureSwizzleSupport() &&
   2056                 (setAll ||
   2057                  memcmp(newTexParams.fSwizzleRGBA,
   2058                         oldTexParams.fSwizzleRGBA,
   2059                         sizeof(newTexParams.fSwizzleRGBA)))) {
   2060                 setTextureUnit(s);
   2061                 set_tex_swizzle(newTexParams.fSwizzleRGBA,
   2062                                 this->glInterface());
   2063             }
   2064             nextTexture->setCachedTexParams(newTexParams,
   2065                                             this->getResetTimestamp());
   2066         }
   2067     }
   2068 
   2069     GrIRect* rect = NULL;
   2070     GrIRect clipBounds;
   2071     if (drawState->isClipState() &&
   2072         fClip.hasConservativeBounds()) {
   2073         fClip.getConservativeBounds().roundOut(&clipBounds);
   2074         rect = &clipBounds;
   2075     }
   2076     this->flushRenderTarget(rect);
   2077     this->flushAAState(type);
   2078 
   2079     if (drawState->isDitherState() != fHWDrawState.isDitherState()) {
   2080         if (drawState->isDitherState()) {
   2081             GL_CALL(Enable(GR_GL_DITHER));
   2082         } else {
   2083             GL_CALL(Disable(GR_GL_DITHER));
   2084         }
   2085     }
   2086 
   2087     if (drawState->isColorWriteDisabled() !=
   2088         fHWDrawState.isColorWriteDisabled()) {
   2089         GrGLenum mask;
   2090         if (drawState->isColorWriteDisabled()) {
   2091             mask = GR_GL_FALSE;
   2092         } else {
   2093             mask = GR_GL_TRUE;
   2094         }
   2095         GL_CALL(ColorMask(mask, mask, mask, mask));
   2096     }
   2097 
   2098     if (fHWDrawState.getDrawFace() != drawState->getDrawFace()) {
   2099         switch (fCurrDrawState.getDrawFace()) {
   2100             case GrDrawState::kCCW_DrawFace:
   2101                 GL_CALL(Enable(GR_GL_CULL_FACE));
   2102                 GL_CALL(CullFace(GR_GL_BACK));
   2103                 break;
   2104             case GrDrawState::kCW_DrawFace:
   2105                 GL_CALL(Enable(GR_GL_CULL_FACE));
   2106                 GL_CALL(CullFace(GR_GL_FRONT));
   2107                 break;
   2108             case GrDrawState::kBoth_DrawFace:
   2109                 GL_CALL(Disable(GR_GL_CULL_FACE));
   2110                 break;
   2111             default:
   2112                 GrCrash("Unknown draw face.");
   2113         }
   2114         fHWDrawState.setDrawFace(drawState->getDrawFace());
   2115     }
   2116 
   2117 #if GR_DEBUG
   2118     // check for circular rendering
   2119     for (int s = 0; s < GrDrawState::kNumStages; ++s) {
   2120         GrAssert(!this->isStageEnabled(s) ||
   2121                  NULL == drawState->getRenderTarget() ||
   2122                  NULL == drawState->getTexture(s) ||
   2123                  drawState->getTexture(s)->asRenderTarget() !=
   2124                     drawState->getRenderTarget());
   2125     }
   2126 #endif
   2127 
   2128     this->flushStencil();
   2129 
   2130     // This copy must happen after flushStencil() is called. flushStencil()
   2131     // relies on detecting when the kModifyStencilClip_StateBit state has
   2132     // changed since the last draw.
   2133     fHWDrawState.copyStateFlags(*drawState);
   2134     return true;
   2135 }
   2136 
   2137 void GrGpuGL::notifyVertexBufferBind(const GrGLVertexBuffer* buffer) {
   2138     if (fHWGeometryState.fVertexBuffer != buffer) {
   2139         fHWGeometryState.fArrayPtrsDirty = true;
   2140         fHWGeometryState.fVertexBuffer = buffer;
   2141     }
   2142 }
   2143 
   2144 void GrGpuGL::notifyVertexBufferDelete(const GrGLVertexBuffer* buffer) {
   2145     if (fHWGeometryState.fVertexBuffer == buffer) {
   2146         // deleting bound buffer does implied bind to 0
   2147         fHWGeometryState.fVertexBuffer = NULL;
   2148         fHWGeometryState.fArrayPtrsDirty = true;
   2149     }
   2150 }
   2151 
   2152 void GrGpuGL::notifyIndexBufferBind(const GrGLIndexBuffer* buffer) {
   2153     fHWGeometryState.fIndexBuffer = buffer;
   2154 }
   2155 
   2156 void GrGpuGL::notifyIndexBufferDelete(const GrGLIndexBuffer* buffer) {
   2157     if (fHWGeometryState.fIndexBuffer == buffer) {
   2158         // deleting bound buffer does implied bind to 0
   2159         fHWGeometryState.fIndexBuffer = NULL;
   2160     }
   2161 }
   2162 
   2163 void GrGpuGL::notifyRenderTargetDelete(GrRenderTarget* renderTarget) {
   2164     GrAssert(NULL != renderTarget);
   2165     GrDrawState* drawState = this->drawState();
   2166     if (drawState->getRenderTarget() == renderTarget) {
   2167         drawState->setRenderTarget(NULL);
   2168     }
   2169     if (fHWDrawState.getRenderTarget() == renderTarget) {
   2170         fHWDrawState.setRenderTarget(NULL);
   2171     }
   2172 }
   2173 
   2174 void GrGpuGL::notifyTextureDelete(GrGLTexture* texture) {
   2175     for (int s = 0; s < GrDrawState::kNumStages; ++s) {
   2176         GrDrawState* drawState = this->drawState();
   2177         if (drawState->getTexture(s) == texture) {
   2178             fCurrDrawState.setTexture(s, NULL);
   2179         }
   2180         if (fHWDrawState.getTexture(s) == texture) {
   2181             // deleting bound texture does implied bind to 0
   2182             fHWDrawState.setTexture(s, NULL);
   2183        }
   2184     }
   2185 }
   2186 
   2187 bool GrGpuGL::configToGLFormats(GrPixelConfig config,
   2188                                 bool getSizedInternalFormat,
   2189                                 GrGLenum* internalFormat,
   2190                                 GrGLenum* externalFormat,
   2191                                 GrGLenum* externalType) {
   2192     GrGLenum dontCare;
   2193     if (NULL == internalFormat) {
   2194         internalFormat = &dontCare;
   2195     }
   2196     if (NULL == externalFormat) {
   2197         externalFormat = &dontCare;
   2198     }
   2199     if (NULL == externalType) {
   2200         externalType = &dontCare;
   2201     }
   2202 
   2203     switch (config) {
   2204         case kRGBA_8888_PM_GrPixelConfig:
   2205         case kRGBA_8888_UPM_GrPixelConfig:
   2206             *internalFormat = GR_GL_RGBA;
   2207             *externalFormat = GR_GL_RGBA;
   2208             if (getSizedInternalFormat) {
   2209                 *internalFormat = GR_GL_RGBA8;
   2210             } else {
   2211                 *internalFormat = GR_GL_RGBA;
   2212             }
   2213             *externalType = GR_GL_UNSIGNED_BYTE;
   2214             break;
   2215         case kBGRA_8888_PM_GrPixelConfig:
   2216         case kBGRA_8888_UPM_GrPixelConfig:
   2217             if (!this->glCaps().bgraFormatSupport()) {
   2218                 return false;
   2219             }
   2220             if (this->glCaps().bgraIsInternalFormat()) {
   2221                 if (getSizedInternalFormat) {
   2222                     *internalFormat = GR_GL_BGRA8;
   2223                 } else {
   2224                     *internalFormat = GR_GL_BGRA;
   2225                 }
   2226             } else {
   2227                 if (getSizedInternalFormat) {
   2228                     *internalFormat = GR_GL_RGBA8;
   2229                 } else {
   2230                     *internalFormat = GR_GL_RGBA;
   2231                 }
   2232             }
   2233             *externalFormat = GR_GL_BGRA;
   2234             *externalType = GR_GL_UNSIGNED_BYTE;
   2235             break;
   2236         case kRGB_565_GrPixelConfig:
   2237             *internalFormat = GR_GL_RGB;
   2238             *externalFormat = GR_GL_RGB;
   2239             if (getSizedInternalFormat) {
   2240                 if (this->glBinding() == kDesktop_GrGLBinding) {
   2241                     return false;
   2242                 } else {
   2243                     *internalFormat = GR_GL_RGB565;
   2244                 }
   2245             } else {
   2246                 *internalFormat = GR_GL_RGB;
   2247             }
   2248             *externalType = GR_GL_UNSIGNED_SHORT_5_6_5;
   2249             break;
   2250         case kRGBA_4444_GrPixelConfig:
   2251             *internalFormat = GR_GL_RGBA;
   2252             *externalFormat = GR_GL_RGBA;
   2253             if (getSizedInternalFormat) {
   2254                 *internalFormat = GR_GL_RGBA4;
   2255             } else {
   2256                 *internalFormat = GR_GL_RGBA;
   2257             }
   2258             *externalType = GR_GL_UNSIGNED_SHORT_4_4_4_4;
   2259             break;
   2260         case kIndex_8_GrPixelConfig:
   2261             if (this->getCaps().f8BitPaletteSupport) {
   2262                 *internalFormat = GR_GL_PALETTE8_RGBA8;
   2263                 // glCompressedTexImage doesn't take external params
   2264                 *externalFormat = GR_GL_PALETTE8_RGBA8;
   2265                 // no sized/unsized internal format distinction here
   2266                 *internalFormat = GR_GL_PALETTE8_RGBA8;
   2267                 // unused with CompressedTexImage
   2268                 *externalType = GR_GL_UNSIGNED_BYTE;
   2269             } else {
   2270                 return false;
   2271             }
   2272             break;
   2273         case kAlpha_8_GrPixelConfig:
   2274             *internalFormat = GR_GL_ALPHA;
   2275             *externalFormat = GR_GL_ALPHA;
   2276             if (getSizedInternalFormat) {
   2277                 *internalFormat = GR_GL_ALPHA8;
   2278             } else {
   2279                 *internalFormat = GR_GL_ALPHA;
   2280             }
   2281             *externalType = GR_GL_UNSIGNED_BYTE;
   2282             break;
   2283         default:
   2284             return false;
   2285     }
   2286     return true;
   2287 }
   2288 
   2289 void GrGpuGL::setTextureUnit(int unit) {
   2290     GrAssert(unit >= 0 && unit < GrDrawState::kNumStages);
   2291     if (fActiveTextureUnitIdx != unit) {
   2292         GL_CALL(ActiveTexture(GR_GL_TEXTURE0 + unit));
   2293         fActiveTextureUnitIdx = unit;
   2294     }
   2295 }
   2296 
   2297 void GrGpuGL::setSpareTextureUnit() {
   2298     if (fActiveTextureUnitIdx != (GR_GL_TEXTURE0 + SPARE_TEX_UNIT)) {
   2299         GL_CALL(ActiveTexture(GR_GL_TEXTURE0 + SPARE_TEX_UNIT));
   2300         fActiveTextureUnitIdx = SPARE_TEX_UNIT;
   2301     }
   2302 }
   2303 
   2304 void GrGpuGL::resetDirtyFlags() {
   2305     Gr_bzero(&fDirtyFlags, sizeof(fDirtyFlags));
   2306 }
   2307 
   2308 void GrGpuGL::setBuffers(bool indexed,
   2309                          int* extraVertexOffset,
   2310                          int* extraIndexOffset) {
   2311 
   2312     GrAssert(NULL != extraVertexOffset);
   2313 
   2314     const GeometryPoolState& geoPoolState = this->getGeomPoolState();
   2315 
   2316     GrGLVertexBuffer* vbuf;
   2317     switch (this->getGeomSrc().fVertexSrc) {
   2318     case kBuffer_GeometrySrcType:
   2319         *extraVertexOffset = 0;
   2320         vbuf = (GrGLVertexBuffer*) this->getGeomSrc().fVertexBuffer;
   2321         break;
   2322     case kArray_GeometrySrcType:
   2323     case kReserved_GeometrySrcType:
   2324         this->finalizeReservedVertices();
   2325         *extraVertexOffset = geoPoolState.fPoolStartVertex;
   2326         vbuf = (GrGLVertexBuffer*) geoPoolState.fPoolVertexBuffer;
   2327         break;
   2328     default:
   2329         vbuf = NULL; // suppress warning
   2330         GrCrash("Unknown geometry src type!");
   2331     }
   2332 
   2333     GrAssert(NULL != vbuf);
   2334     GrAssert(!vbuf->isLocked());
   2335     if (fHWGeometryState.fVertexBuffer != vbuf) {
   2336         GL_CALL(BindBuffer(GR_GL_ARRAY_BUFFER, vbuf->bufferID()));
   2337         fHWGeometryState.fArrayPtrsDirty = true;
   2338         fHWGeometryState.fVertexBuffer = vbuf;
   2339     }
   2340 
   2341     if (indexed) {
   2342         GrAssert(NULL != extraIndexOffset);
   2343 
   2344         GrGLIndexBuffer* ibuf;
   2345         switch (this->getGeomSrc().fIndexSrc) {
   2346         case kBuffer_GeometrySrcType:
   2347             *extraIndexOffset = 0;
   2348             ibuf = (GrGLIndexBuffer*)this->getGeomSrc().fIndexBuffer;
   2349             break;
   2350         case kArray_GeometrySrcType:
   2351         case kReserved_GeometrySrcType:
   2352             this->finalizeReservedIndices();
   2353             *extraIndexOffset = geoPoolState.fPoolStartIndex;
   2354             ibuf = (GrGLIndexBuffer*) geoPoolState.fPoolIndexBuffer;
   2355             break;
   2356         default:
   2357             ibuf = NULL; // suppress warning
   2358             GrCrash("Unknown geometry src type!");
   2359         }
   2360 
   2361         GrAssert(NULL != ibuf);
   2362         GrAssert(!ibuf->isLocked());
   2363         if (fHWGeometryState.fIndexBuffer != ibuf) {
   2364             GL_CALL(BindBuffer(GR_GL_ELEMENT_ARRAY_BUFFER, ibuf->bufferID()));
   2365             fHWGeometryState.fIndexBuffer = ibuf;
   2366         }
   2367     }
   2368 }
   2369 
   2370 int GrGpuGL::getMaxEdges() const {
   2371     // FIXME:  This is a pessimistic estimate based on how many other things
   2372     // want to add uniforms.  This should be centralized somewhere.
   2373     return GR_CT_MIN(this->glCaps().maxFragmentUniformVectors() - 8,
   2374                      GrDrawState::kMaxEdges);
   2375 }
   2376 
   2377