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