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