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 "GrOptDrawState.h"
12#include "GrTemplates.h"
13#include "GrTypes.h"
14#include "SkStrokeRec.h"
15#include "SkTemplates.h"
16
17#define GL_CALL(X) GR_GL_CALL(this->glInterface(), X)
18#define GL_CALL_RET(RET, X) GR_GL_CALL_RET(this->glInterface(), RET, X)
19
20#define SKIP_CACHE_CHECK    true
21
22#if GR_GL_CHECK_ALLOC_WITH_GET_ERROR
23    #define CLEAR_ERROR_BEFORE_ALLOC(iface)   GrGLClearErr(iface)
24    #define GL_ALLOC_CALL(iface, call)        GR_GL_CALL_NOERRCHECK(iface, call)
25    #define CHECK_ALLOC_ERROR(iface)          GR_GL_GET_ERROR(iface)
26#else
27    #define CLEAR_ERROR_BEFORE_ALLOC(iface)
28    #define GL_ALLOC_CALL(iface, call)        GR_GL_CALL(iface, call)
29    #define CHECK_ALLOC_ERROR(iface)          GR_GL_NO_ERROR
30#endif
31
32
33///////////////////////////////////////////////////////////////////////////////
34
35
36static const GrGLenum gXfermodeCoeff2Blend[] = {
37    GR_GL_ZERO,
38    GR_GL_ONE,
39    GR_GL_SRC_COLOR,
40    GR_GL_ONE_MINUS_SRC_COLOR,
41    GR_GL_DST_COLOR,
42    GR_GL_ONE_MINUS_DST_COLOR,
43    GR_GL_SRC_ALPHA,
44    GR_GL_ONE_MINUS_SRC_ALPHA,
45    GR_GL_DST_ALPHA,
46    GR_GL_ONE_MINUS_DST_ALPHA,
47    GR_GL_CONSTANT_COLOR,
48    GR_GL_ONE_MINUS_CONSTANT_COLOR,
49    GR_GL_CONSTANT_ALPHA,
50    GR_GL_ONE_MINUS_CONSTANT_ALPHA,
51
52    // extended blend coeffs
53    GR_GL_SRC1_COLOR,
54    GR_GL_ONE_MINUS_SRC1_COLOR,
55    GR_GL_SRC1_ALPHA,
56    GR_GL_ONE_MINUS_SRC1_ALPHA,
57};
58
59bool GrGpuGL::BlendCoeffReferencesConstant(GrBlendCoeff coeff) {
60    static const bool gCoeffReferencesBlendConst[] = {
61        false,
62        false,
63        false,
64        false,
65        false,
66        false,
67        false,
68        false,
69        false,
70        false,
71        true,
72        true,
73        true,
74        true,
75
76        // extended blend coeffs
77        false,
78        false,
79        false,
80        false,
81    };
82    return gCoeffReferencesBlendConst[coeff];
83    GR_STATIC_ASSERT(kTotalGrBlendCoeffCount ==
84                     SK_ARRAY_COUNT(gCoeffReferencesBlendConst));
85
86    GR_STATIC_ASSERT(0 == kZero_GrBlendCoeff);
87    GR_STATIC_ASSERT(1 == kOne_GrBlendCoeff);
88    GR_STATIC_ASSERT(2 == kSC_GrBlendCoeff);
89    GR_STATIC_ASSERT(3 == kISC_GrBlendCoeff);
90    GR_STATIC_ASSERT(4 == kDC_GrBlendCoeff);
91    GR_STATIC_ASSERT(5 == kIDC_GrBlendCoeff);
92    GR_STATIC_ASSERT(6 == kSA_GrBlendCoeff);
93    GR_STATIC_ASSERT(7 == kISA_GrBlendCoeff);
94    GR_STATIC_ASSERT(8 == kDA_GrBlendCoeff);
95    GR_STATIC_ASSERT(9 == kIDA_GrBlendCoeff);
96    GR_STATIC_ASSERT(10 == kConstC_GrBlendCoeff);
97    GR_STATIC_ASSERT(11 == kIConstC_GrBlendCoeff);
98    GR_STATIC_ASSERT(12 == kConstA_GrBlendCoeff);
99    GR_STATIC_ASSERT(13 == kIConstA_GrBlendCoeff);
100
101    GR_STATIC_ASSERT(14 == kS2C_GrBlendCoeff);
102    GR_STATIC_ASSERT(15 == kIS2C_GrBlendCoeff);
103    GR_STATIC_ASSERT(16 == kS2A_GrBlendCoeff);
104    GR_STATIC_ASSERT(17 == kIS2A_GrBlendCoeff);
105
106    // assertion for gXfermodeCoeff2Blend have to be in GrGpu scope
107    GR_STATIC_ASSERT(kTotalGrBlendCoeffCount ==
108                     SK_ARRAY_COUNT(gXfermodeCoeff2Blend));
109}
110
111///////////////////////////////////////////////////////////////////////////////
112
113static bool gPrintStartupSpew;
114
115GrGpuGL::GrGpuGL(const GrGLContext& ctx, GrContext* context)
116    : GrGpu(context)
117    , fGLContext(ctx) {
118
119    SkASSERT(ctx.isInitialized());
120    fCaps.reset(SkRef(ctx.caps()));
121
122    fHWBoundTextureUniqueIDs.reset(this->glCaps().maxFragmentTextureUnits());
123
124    GrGLClearErr(fGLContext.interface());
125    if (gPrintStartupSpew) {
126        const GrGLubyte* vendor;
127        const GrGLubyte* renderer;
128        const GrGLubyte* version;
129        GL_CALL_RET(vendor, GetString(GR_GL_VENDOR));
130        GL_CALL_RET(renderer, GetString(GR_GL_RENDERER));
131        GL_CALL_RET(version, GetString(GR_GL_VERSION));
132        GrPrintf("------------------------- create GrGpuGL %p --------------\n",
133                 this);
134        GrPrintf("------ VENDOR %s\n", vendor);
135        GrPrintf("------ RENDERER %s\n", renderer);
136        GrPrintf("------ VERSION %s\n",  version);
137        GrPrintf("------ EXTENSIONS\n");
138        ctx.extensions().print();
139        GrPrintf("\n");
140        GrPrintf(this->glCaps().dump().c_str());
141    }
142
143    fProgramCache = SkNEW_ARGS(ProgramCache, (this));
144
145    SkASSERT(this->glCaps().maxVertexAttributes() >= GrDrawState::kMaxVertexAttribCnt);
146
147    fLastSuccessfulStencilFmtIdx = 0;
148    fHWProgramID = 0;
149
150    if (this->glCaps().pathRenderingSupport()) {
151        fPathRendering.reset(new GrGLPathRendering(this));
152    }
153}
154
155GrGpuGL::~GrGpuGL() {
156    if (0 != fHWProgramID) {
157        // detach the current program so there is no confusion on OpenGL's part
158        // that we want it to be deleted
159        SkASSERT(fHWProgramID == fCurrentProgram->programID());
160        GL_CALL(UseProgram(0));
161    }
162
163    delete fProgramCache;
164
165    // This must be called by before the GrDrawTarget destructor
166    this->releaseGeometry();
167}
168
169void GrGpuGL::contextAbandoned() {
170    INHERITED::contextAbandoned();
171    fProgramCache->abandon();
172    fHWProgramID = 0;
173    if (this->glCaps().pathRenderingSupport()) {
174        this->glPathRendering()->abandonGpuResources();
175    }
176}
177
178///////////////////////////////////////////////////////////////////////////////
179
180
181GrPixelConfig GrGpuGL::preferredReadPixelsConfig(GrPixelConfig readConfig,
182                                                 GrPixelConfig surfaceConfig) const {
183    if (GR_GL_RGBA_8888_PIXEL_OPS_SLOW && kRGBA_8888_GrPixelConfig == readConfig) {
184        return kBGRA_8888_GrPixelConfig;
185    } else if (this->glContext().isMesa() &&
186               GrBytesPerPixel(readConfig) == 4 &&
187               GrPixelConfigSwapRAndB(readConfig) == surfaceConfig) {
188        // Mesa 3D takes a slow path on when reading back  BGRA from an RGBA surface and vice-versa.
189        // Perhaps this should be guarded by some compiletime or runtime check.
190        return surfaceConfig;
191    } else if (readConfig == kBGRA_8888_GrPixelConfig &&
192               !this->glCaps().readPixelsSupported(this->glInterface(),
193                                                   GR_GL_BGRA, GR_GL_UNSIGNED_BYTE)) {
194        return kRGBA_8888_GrPixelConfig;
195    } else {
196        return readConfig;
197    }
198}
199
200GrPixelConfig GrGpuGL::preferredWritePixelsConfig(GrPixelConfig writeConfig,
201                                                  GrPixelConfig surfaceConfig) const {
202    if (GR_GL_RGBA_8888_PIXEL_OPS_SLOW && kRGBA_8888_GrPixelConfig == writeConfig) {
203        return kBGRA_8888_GrPixelConfig;
204    } else {
205        return writeConfig;
206    }
207}
208
209bool GrGpuGL::canWriteTexturePixels(const GrTexture* texture, GrPixelConfig srcConfig) const {
210    if (kIndex_8_GrPixelConfig == srcConfig || kIndex_8_GrPixelConfig == texture->config()) {
211        return false;
212    }
213    if (srcConfig != texture->config() && kGLES_GrGLStandard == this->glStandard()) {
214        // In general ES2 requires the internal format of the texture and the format of the src
215        // pixels to match. However, It may or may not be possible to upload BGRA data to a RGBA
216        // texture. It depends upon which extension added BGRA. The Apple extension allows it
217        // (BGRA's internal format is RGBA) while the EXT extension does not (BGRA is its own
218        // internal format).
219        if (this->glCaps().isConfigTexturable(kBGRA_8888_GrPixelConfig) &&
220            !this->glCaps().bgraIsInternalFormat() &&
221            kBGRA_8888_GrPixelConfig == srcConfig &&
222            kRGBA_8888_GrPixelConfig == texture->config()) {
223            return true;
224        } else {
225            return false;
226        }
227    } else {
228        return true;
229    }
230}
231
232bool GrGpuGL::fullReadPixelsIsFasterThanPartial() const {
233    return SkToBool(GR_GL_FULL_READPIXELS_FASTER_THAN_PARTIAL);
234}
235
236void GrGpuGL::onResetContext(uint32_t resetBits) {
237    // we don't use the zb at all
238    if (resetBits & kMisc_GrGLBackendState) {
239        GL_CALL(Disable(GR_GL_DEPTH_TEST));
240        GL_CALL(DepthMask(GR_GL_FALSE));
241
242        fHWDrawFace = GrDrawState::kInvalid_DrawFace;
243        fHWDitherEnabled = kUnknown_TriState;
244
245        if (kGL_GrGLStandard == this->glStandard()) {
246            // Desktop-only state that we never change
247            if (!this->glCaps().isCoreProfile()) {
248                GL_CALL(Disable(GR_GL_POINT_SMOOTH));
249                GL_CALL(Disable(GR_GL_LINE_SMOOTH));
250                GL_CALL(Disable(GR_GL_POLYGON_SMOOTH));
251                GL_CALL(Disable(GR_GL_POLYGON_STIPPLE));
252                GL_CALL(Disable(GR_GL_COLOR_LOGIC_OP));
253                GL_CALL(Disable(GR_GL_INDEX_LOGIC_OP));
254            }
255            // The windows NVIDIA driver has GL_ARB_imaging in the extension string when using a
256            // core profile. This seems like a bug since the core spec removes any mention of
257            // GL_ARB_imaging.
258            if (this->glCaps().imagingSupport() && !this->glCaps().isCoreProfile()) {
259                GL_CALL(Disable(GR_GL_COLOR_TABLE));
260            }
261            GL_CALL(Disable(GR_GL_POLYGON_OFFSET_FILL));
262            // Since ES doesn't support glPointSize at all we always use the VS to
263            // set the point size
264            GL_CALL(Enable(GR_GL_VERTEX_PROGRAM_POINT_SIZE));
265
266            // We should set glPolygonMode(FRONT_AND_BACK,FILL) here, too. It isn't
267            // currently part of our gl interface. There are probably others as
268            // well.
269        }
270
271        if (kGLES_GrGLStandard == this->glStandard() &&
272                fGLContext.hasExtension("GL_ARM_shader_framebuffer_fetch")) {
273            // The arm extension requires specifically enabling MSAA fetching per sample.
274            // On some devices this may have a perf hit.  Also multiple render targets are disabled
275            GL_CALL(Enable(GR_GL_FETCH_PER_SAMPLE_ARM));
276        }
277        fHWWriteToColor = kUnknown_TriState;
278        // we only ever use lines in hairline mode
279        GL_CALL(LineWidth(1));
280    }
281
282    if (resetBits & kMSAAEnable_GrGLBackendState) {
283        fMSAAEnabled = kUnknown_TriState;
284    }
285
286    fHWActiveTextureUnitIdx = -1; // invalid
287
288    if (resetBits & kTextureBinding_GrGLBackendState) {
289        for (int s = 0; s < fHWBoundTextureUniqueIDs.count(); ++s) {
290            fHWBoundTextureUniqueIDs[s] = SK_InvalidUniqueID;
291        }
292    }
293
294    if (resetBits & kBlend_GrGLBackendState) {
295        fHWBlendState.invalidate();
296    }
297
298    if (resetBits & kView_GrGLBackendState) {
299        fHWScissorSettings.invalidate();
300        fHWViewport.invalidate();
301    }
302
303    if (resetBits & kStencil_GrGLBackendState) {
304        fHWStencilSettings.invalidate();
305        fHWStencilTestEnabled = kUnknown_TriState;
306    }
307
308    // Vertex
309    if (resetBits & kVertex_GrGLBackendState) {
310        fHWGeometryState.invalidate();
311    }
312
313    if (resetBits & kRenderTarget_GrGLBackendState) {
314        fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID;
315    }
316
317    if (resetBits & kPathRendering_GrGLBackendState) {
318        if (this->caps()->pathRenderingSupport()) {
319            this->glPathRendering()->resetContext();
320        }
321    }
322
323    // we assume these values
324    if (resetBits & kPixelStore_GrGLBackendState) {
325        if (this->glCaps().unpackRowLengthSupport()) {
326            GL_CALL(PixelStorei(GR_GL_UNPACK_ROW_LENGTH, 0));
327        }
328        if (this->glCaps().packRowLengthSupport()) {
329            GL_CALL(PixelStorei(GR_GL_PACK_ROW_LENGTH, 0));
330        }
331        if (this->glCaps().unpackFlipYSupport()) {
332            GL_CALL(PixelStorei(GR_GL_UNPACK_FLIP_Y, GR_GL_FALSE));
333        }
334        if (this->glCaps().packFlipYSupport()) {
335            GL_CALL(PixelStorei(GR_GL_PACK_REVERSE_ROW_ORDER, GR_GL_FALSE));
336        }
337    }
338
339    if (resetBits & kProgram_GrGLBackendState) {
340        fHWProgramID = 0;
341        fSharedGLProgramState.invalidate();
342    }
343}
344
345namespace {
346
347GrSurfaceOrigin resolve_origin(GrSurfaceOrigin origin, bool renderTarget) {
348    // By default, GrRenderTargets are GL's normal orientation so that they
349    // can be drawn to by the outside world without the client having
350    // to render upside down.
351    if (kDefault_GrSurfaceOrigin == origin) {
352        return renderTarget ? kBottomLeft_GrSurfaceOrigin : kTopLeft_GrSurfaceOrigin;
353    } else {
354        return origin;
355    }
356}
357
358}
359
360GrTexture* GrGpuGL::onWrapBackendTexture(const GrBackendTextureDesc& desc) {
361    if (!this->configToGLFormats(desc.fConfig, false, NULL, NULL, NULL)) {
362        return NULL;
363    }
364
365    if (0 == desc.fTextureHandle) {
366        return NULL;
367    }
368
369    int maxSize = this->caps()->maxTextureSize();
370    if (desc.fWidth > maxSize || desc.fHeight > maxSize) {
371        return NULL;
372    }
373
374    GrGLTexture::Desc glTexDesc;
375    // next line relies on GrBackendTextureDesc's flags matching GrTexture's
376    glTexDesc.fFlags = (GrTextureFlags) desc.fFlags;
377    glTexDesc.fWidth = desc.fWidth;
378    glTexDesc.fHeight = desc.fHeight;
379    glTexDesc.fConfig = desc.fConfig;
380    glTexDesc.fSampleCnt = desc.fSampleCnt;
381    glTexDesc.fTextureID = static_cast<GrGLuint>(desc.fTextureHandle);
382    glTexDesc.fIsWrapped = true;
383    bool renderTarget = SkToBool(desc.fFlags & kRenderTarget_GrBackendTextureFlag);
384    // FIXME:  this should be calling resolve_origin(), but Chrome code is currently
385    // assuming the old behaviour, which is that backend textures are always
386    // BottomLeft, even for non-RT's.  Once Chrome is fixed, change this to:
387    // glTexDesc.fOrigin = resolve_origin(desc.fOrigin, renderTarget);
388    if (kDefault_GrSurfaceOrigin == desc.fOrigin) {
389        glTexDesc.fOrigin = kBottomLeft_GrSurfaceOrigin;
390    } else {
391        glTexDesc.fOrigin = desc.fOrigin;
392    }
393
394    GrGLTexture* texture = NULL;
395    if (renderTarget) {
396        GrGLRenderTarget::Desc glRTDesc;
397        glRTDesc.fRTFBOID = 0;
398        glRTDesc.fTexFBOID = 0;
399        glRTDesc.fMSColorRenderbufferID = 0;
400        glRTDesc.fConfig = desc.fConfig;
401        glRTDesc.fSampleCnt = desc.fSampleCnt;
402        glRTDesc.fOrigin = glTexDesc.fOrigin;
403        glRTDesc.fCheckAllocation = false;
404        if (!this->createRenderTargetObjects(glTexDesc.fWidth,
405                                             glTexDesc.fHeight,
406                                             glTexDesc.fTextureID,
407                                             &glRTDesc)) {
408            return NULL;
409        }
410        texture = SkNEW_ARGS(GrGLTexture, (this, glTexDesc, glRTDesc));
411    } else {
412        texture = SkNEW_ARGS(GrGLTexture, (this, glTexDesc));
413    }
414    if (NULL == texture) {
415        return NULL;
416    }
417
418    return texture;
419}
420
421GrRenderTarget* GrGpuGL::onWrapBackendRenderTarget(const GrBackendRenderTargetDesc& desc) {
422    GrGLRenderTarget::Desc glDesc;
423    glDesc.fConfig = desc.fConfig;
424    glDesc.fRTFBOID = static_cast<GrGLuint>(desc.fRenderTargetHandle);
425    glDesc.fMSColorRenderbufferID = 0;
426    glDesc.fTexFBOID = GrGLRenderTarget::kUnresolvableFBOID;
427    glDesc.fSampleCnt = desc.fSampleCnt;
428    glDesc.fIsWrapped = true;
429    glDesc.fCheckAllocation = false;
430
431    glDesc.fOrigin = resolve_origin(desc.fOrigin, true);
432    GrGLIRect viewport;
433    viewport.fLeft   = 0;
434    viewport.fBottom = 0;
435    viewport.fWidth  = desc.fWidth;
436    viewport.fHeight = desc.fHeight;
437
438    GrRenderTarget* tgt = SkNEW_ARGS(GrGLRenderTarget,
439                                     (this, glDesc, viewport));
440    if (desc.fStencilBits) {
441        GrGLStencilBuffer::Format format;
442        format.fInternalFormat = GrGLStencilBuffer::kUnknownInternalFormat;
443        format.fPacked = false;
444        format.fStencilBits = desc.fStencilBits;
445        format.fTotalBits = desc.fStencilBits;
446        static const bool kIsSBWrapped = false;
447        GrGLStencilBuffer* sb = SkNEW_ARGS(GrGLStencilBuffer,
448                                           (this,
449                                            kIsSBWrapped,
450                                            0,
451                                            desc.fWidth,
452                                            desc.fHeight,
453                                            desc.fSampleCnt,
454                                            format));
455        tgt->setStencilBuffer(sb);
456        sb->unref();
457    }
458    return tgt;
459}
460
461////////////////////////////////////////////////////////////////////////////////
462
463bool GrGpuGL::onWriteTexturePixels(GrTexture* texture,
464                                   int left, int top, int width, int height,
465                                   GrPixelConfig config, const void* buffer,
466                                   size_t rowBytes) {
467    if (NULL == buffer) {
468        return false;
469    }
470    GrGLTexture* glTex = static_cast<GrGLTexture*>(texture);
471
472    this->setScratchTextureUnit();
473    GL_CALL(BindTexture(GR_GL_TEXTURE_2D, glTex->textureID()));
474    GrGLTexture::Desc desc;
475    desc.fFlags = glTex->desc().fFlags;
476    desc.fWidth = glTex->width();
477    desc.fHeight = glTex->height();
478    desc.fConfig = glTex->config();
479    desc.fSampleCnt = glTex->desc().fSampleCnt;
480    desc.fTextureID = glTex->textureID();
481    desc.fOrigin = glTex->origin();
482
483    bool success = false;
484    if (GrPixelConfigIsCompressed(desc.fConfig)) {
485        // We check that config == desc.fConfig in GrGpuGL::canWriteTexturePixels()
486        SkASSERT(config == desc.fConfig);
487        success = this->uploadCompressedTexData(desc, buffer, false,
488                                                left, top, width, height);
489    } else {
490        success = this->uploadTexData(desc, false,
491                                      left, top, width, height,
492                                      config, buffer, rowBytes);
493    }
494
495    if (success) {
496        texture->impl()->dirtyMipMaps(true);
497        return true;
498    }
499
500    return false;
501}
502
503namespace {
504bool adjust_pixel_ops_params(int surfaceWidth,
505                             int surfaceHeight,
506                             size_t bpp,
507                             int* left, int* top, int* width, int* height,
508                             const void** data,
509                             size_t* rowBytes) {
510    if (!*rowBytes) {
511        *rowBytes = *width * bpp;
512    }
513
514    SkIRect subRect = SkIRect::MakeXYWH(*left, *top, *width, *height);
515    SkIRect bounds = SkIRect::MakeWH(surfaceWidth, surfaceHeight);
516
517    if (!subRect.intersect(bounds)) {
518        return false;
519    }
520    *data = reinterpret_cast<const void*>(reinterpret_cast<intptr_t>(*data) +
521          (subRect.fTop - *top) * *rowBytes + (subRect.fLeft - *left) * bpp);
522
523    *left = subRect.fLeft;
524    *top = subRect.fTop;
525    *width = subRect.width();
526    *height = subRect.height();
527    return true;
528}
529
530GrGLenum check_alloc_error(const GrTextureDesc& desc, const GrGLInterface* interface) {
531    if (SkToBool(desc.fFlags & kCheckAllocation_GrTextureFlagBit)) {
532        return GR_GL_GET_ERROR(interface);
533    } else {
534        return CHECK_ALLOC_ERROR(interface);
535    }
536}
537
538}
539
540bool GrGpuGL::uploadTexData(const GrGLTexture::Desc& desc,
541                            bool isNewTexture,
542                            int left, int top, int width, int height,
543                            GrPixelConfig dataConfig,
544                            const void* data,
545                            size_t rowBytes) {
546    SkASSERT(data || isNewTexture);
547
548    // If we're uploading compressed data then we should be using uploadCompressedTexData
549    SkASSERT(!GrPixelConfigIsCompressed(dataConfig));
550
551    size_t bpp = GrBytesPerPixel(dataConfig);
552    if (!adjust_pixel_ops_params(desc.fWidth, desc.fHeight, bpp, &left, &top,
553                                 &width, &height, &data, &rowBytes)) {
554        return false;
555    }
556    size_t trimRowBytes = width * bpp;
557
558    // in case we need a temporary, trimmed copy of the src pixels
559    GrAutoMalloc<128 * 128> tempStorage;
560
561    // We currently lazily create MIPMAPs when the we see a draw with
562    // GrTextureParams::kMipMap_FilterMode. Using texture storage requires that the
563    // MIP levels are all created when the texture is created. So for now we don't use
564    // texture storage.
565    bool useTexStorage = false &&
566                         isNewTexture &&
567                         this->glCaps().texStorageSupport();
568
569    if (useTexStorage && kGL_GrGLStandard == this->glStandard()) {
570        // 565 is not a sized internal format on desktop GL. So on desktop with
571        // 565 we always use an unsized internal format to let the system pick
572        // the best sized format to convert the 565 data to. Since TexStorage
573        // only allows sized internal formats we will instead use TexImage2D.
574        useTexStorage = desc.fConfig != kRGB_565_GrPixelConfig;
575    }
576
577    GrGLenum internalFormat;
578    GrGLenum externalFormat = 0x0; // suprress warning
579    GrGLenum externalType = 0x0;// suprress warning
580
581    // glTexStorage requires sized internal formats on both desktop and ES. ES2 requires an unsized
582    // format for glTexImage, unlike ES3 and desktop. However, we allow the driver to decide the
583    // size of the internal format whenever possible and so only use a sized internal format when
584    // using texture storage.
585    bool useSizedFormat = useTexStorage;
586    // At least some versions of the desktop ES3 drivers for NVIDIA won't accept GL_RED in
587    // glTexImage2D for the internal format but will accept GL_R8.
588    if (!useSizedFormat && kNVIDIA_GrGLVendor == this->glContext().vendor() &&
589        kGLES_GrGLStandard == this->glStandard() && this->glVersion() >= GR_GL_VER(3, 0)) {
590        useSizedFormat = true;
591    }
592    if (!this->configToGLFormats(dataConfig, useSizedFormat, &internalFormat,
593                                 &externalFormat, &externalType)) {
594        return false;
595    }
596
597    /*
598     *  check whether to allocate a temporary buffer for flipping y or
599     *  because our srcData has extra bytes past each row. If so, we need
600     *  to trim those off here, since GL ES may not let us specify
601     *  GL_UNPACK_ROW_LENGTH.
602     */
603    bool restoreGLRowLength = false;
604    bool swFlipY = false;
605    bool glFlipY = false;
606    if (data) {
607        if (kBottomLeft_GrSurfaceOrigin == desc.fOrigin) {
608            if (this->glCaps().unpackFlipYSupport()) {
609                glFlipY = true;
610            } else {
611                swFlipY = true;
612            }
613        }
614        if (this->glCaps().unpackRowLengthSupport() && !swFlipY) {
615            // can't use this for flipping, only non-neg values allowed. :(
616            if (rowBytes != trimRowBytes) {
617                GrGLint rowLength = static_cast<GrGLint>(rowBytes / bpp);
618                GL_CALL(PixelStorei(GR_GL_UNPACK_ROW_LENGTH, rowLength));
619                restoreGLRowLength = true;
620            }
621        } else {
622            if (trimRowBytes != rowBytes || swFlipY) {
623                // copy data into our new storage, skipping the trailing bytes
624                size_t trimSize = height * trimRowBytes;
625                const char* src = (const char*)data;
626                if (swFlipY) {
627                    src += (height - 1) * rowBytes;
628                }
629                char* dst = (char*)tempStorage.reset(trimSize);
630                for (int y = 0; y < height; y++) {
631                    memcpy(dst, src, trimRowBytes);
632                    if (swFlipY) {
633                        src -= rowBytes;
634                    } else {
635                        src += rowBytes;
636                    }
637                    dst += trimRowBytes;
638                }
639                // now point data to our copied version
640                data = tempStorage.get();
641            }
642        }
643        if (glFlipY) {
644            GL_CALL(PixelStorei(GR_GL_UNPACK_FLIP_Y, GR_GL_TRUE));
645        }
646        GL_CALL(PixelStorei(GR_GL_UNPACK_ALIGNMENT,
647              static_cast<GrGLint>(GrUnpackAlignment(dataConfig))));
648    }
649    bool succeeded = true;
650    if (isNewTexture &&
651        0 == left && 0 == top &&
652        desc.fWidth == width && desc.fHeight == height) {
653        CLEAR_ERROR_BEFORE_ALLOC(this->glInterface());
654        if (useTexStorage) {
655            // We never resize  or change formats of textures.
656            GL_ALLOC_CALL(this->glInterface(),
657                          TexStorage2D(GR_GL_TEXTURE_2D,
658                                       1, // levels
659                                       internalFormat,
660                                       desc.fWidth, desc.fHeight));
661        } else {
662            GL_ALLOC_CALL(this->glInterface(),
663                          TexImage2D(GR_GL_TEXTURE_2D,
664                                     0, // level
665                                     internalFormat,
666                                     desc.fWidth, desc.fHeight,
667                                     0, // border
668                                     externalFormat, externalType,
669                                     data));
670        }
671        GrGLenum error = check_alloc_error(desc, this->glInterface());
672        if (error != GR_GL_NO_ERROR) {
673            succeeded = false;
674        } else {
675            // if we have data and we used TexStorage to create the texture, we
676            // now upload with TexSubImage.
677            if (data && useTexStorage) {
678                GL_CALL(TexSubImage2D(GR_GL_TEXTURE_2D,
679                                      0, // level
680                                      left, top,
681                                      width, height,
682                                      externalFormat, externalType,
683                                      data));
684            }
685        }
686    } else {
687        if (swFlipY || glFlipY) {
688            top = desc.fHeight - (top + height);
689        }
690        GL_CALL(TexSubImage2D(GR_GL_TEXTURE_2D,
691                              0, // level
692                              left, top,
693                              width, height,
694                              externalFormat, externalType, data));
695    }
696
697    if (restoreGLRowLength) {
698        SkASSERT(this->glCaps().unpackRowLengthSupport());
699        GL_CALL(PixelStorei(GR_GL_UNPACK_ROW_LENGTH, 0));
700    }
701    if (glFlipY) {
702        GL_CALL(PixelStorei(GR_GL_UNPACK_FLIP_Y, GR_GL_FALSE));
703    }
704    return succeeded;
705}
706
707// TODO: This function is using a lot of wonky semantics like, if width == -1
708// then set width = desc.fWdith ... blah. A better way to do it might be to
709// create a CompressedTexData struct that takes a desc/ptr and figures out
710// the proper upload semantics. Then users can construct this function how they
711// see fit if they want to go against the "standard" way to do it.
712bool GrGpuGL::uploadCompressedTexData(const GrGLTexture::Desc& desc,
713                                      const void* data,
714                                      bool isNewTexture,
715                                      int left, int top, int width, int height) {
716    SkASSERT(data || isNewTexture);
717
718    // No support for software flip y, yet...
719    SkASSERT(kBottomLeft_GrSurfaceOrigin != desc.fOrigin);
720
721    if (-1 == width) {
722        width = desc.fWidth;
723    }
724#ifdef SK_DEBUG
725    else {
726        SkASSERT(width <= desc.fWidth);
727    }
728#endif
729
730    if (-1 == height) {
731        height = desc.fHeight;
732    }
733#ifdef SK_DEBUG
734    else {
735        SkASSERT(height <= desc.fHeight);
736    }
737#endif
738
739    // Make sure that the width and height that we pass to OpenGL
740    // is a multiple of the block size.
741    int dataSize = GrCompressedFormatDataSize(desc.fConfig, width, height);
742
743    // We only need the internal format for compressed 2D textures.
744    GrGLenum internalFormat = 0;
745    if (!this->configToGLFormats(desc.fConfig, false, &internalFormat, NULL, NULL)) {
746        return false;
747    }
748
749    if (isNewTexture) {
750        CLEAR_ERROR_BEFORE_ALLOC(this->glInterface());
751        GL_ALLOC_CALL(this->glInterface(),
752                      CompressedTexImage2D(GR_GL_TEXTURE_2D,
753                                           0, // level
754                                           internalFormat,
755                                           width, height,
756                                           0, // border
757                                           dataSize,
758                                           data));
759        GrGLenum error = check_alloc_error(desc, this->glInterface());
760        if (error != GR_GL_NO_ERROR) {
761            return false;
762        }
763    } else {
764        // Paletted textures can't be updated.
765        if (GR_GL_PALETTE8_RGBA8 == internalFormat) {
766            return false;
767        }
768        GL_CALL(CompressedTexSubImage2D(GR_GL_TEXTURE_2D,
769                                        0, // level
770                                        left, top,
771                                        width, height,
772                                        internalFormat,
773                                        dataSize,
774                                        data));
775    }
776
777    return true;
778}
779
780static bool renderbuffer_storage_msaa(GrGLContext& ctx,
781                                      int sampleCount,
782                                      GrGLenum format,
783                                      int width, int height) {
784    CLEAR_ERROR_BEFORE_ALLOC(ctx.interface());
785    SkASSERT(GrGLCaps::kNone_MSFBOType != ctx.caps()->msFBOType());
786    switch (ctx.caps()->msFBOType()) {
787        case GrGLCaps::kDesktop_ARB_MSFBOType:
788        case GrGLCaps::kDesktop_EXT_MSFBOType:
789        case GrGLCaps::kES_3_0_MSFBOType:
790            GL_ALLOC_CALL(ctx.interface(),
791                            RenderbufferStorageMultisample(GR_GL_RENDERBUFFER,
792                                                            sampleCount,
793                                                            format,
794                                                            width, height));
795            break;
796        case GrGLCaps::kES_Apple_MSFBOType:
797            GL_ALLOC_CALL(ctx.interface(),
798                            RenderbufferStorageMultisampleES2APPLE(GR_GL_RENDERBUFFER,
799                                                                    sampleCount,
800                                                                    format,
801                                                                    width, height));
802            break;
803        case GrGLCaps::kES_EXT_MsToTexture_MSFBOType:
804        case GrGLCaps::kES_IMG_MsToTexture_MSFBOType:
805            GL_ALLOC_CALL(ctx.interface(),
806                            RenderbufferStorageMultisampleES2EXT(GR_GL_RENDERBUFFER,
807                                                                sampleCount,
808                                                                format,
809                                                                width, height));
810            break;
811        case GrGLCaps::kNone_MSFBOType:
812            SkFAIL("Shouldn't be here if we don't support multisampled renderbuffers.");
813            break;
814    }
815    return (GR_GL_NO_ERROR == CHECK_ALLOC_ERROR(ctx.interface()));;
816}
817
818bool GrGpuGL::createRenderTargetObjects(int width, int height,
819                                        GrGLuint texID,
820                                        GrGLRenderTarget::Desc* desc) {
821    desc->fMSColorRenderbufferID = 0;
822    desc->fRTFBOID = 0;
823    desc->fTexFBOID = 0;
824    desc->fIsWrapped = false;
825
826    GrGLenum status;
827
828    GrGLenum msColorFormat = 0; // suppress warning
829
830    if (desc->fSampleCnt > 0 && GrGLCaps::kNone_MSFBOType == this->glCaps().msFBOType()) {
831        goto FAILED;
832    }
833
834    GL_CALL(GenFramebuffers(1, &desc->fTexFBOID));
835    if (!desc->fTexFBOID) {
836        goto FAILED;
837    }
838
839
840    // If we are using multisampling we will create two FBOS. We render to one and then resolve to
841    // the texture bound to the other. The exception is the IMG multisample extension. With this
842    // extension the texture is multisampled when rendered to and then auto-resolves it when it is
843    // rendered from.
844    if (desc->fSampleCnt > 0 && this->glCaps().usesMSAARenderBuffers()) {
845        GL_CALL(GenFramebuffers(1, &desc->fRTFBOID));
846        GL_CALL(GenRenderbuffers(1, &desc->fMSColorRenderbufferID));
847        if (!desc->fRTFBOID ||
848            !desc->fMSColorRenderbufferID ||
849            !this->configToGLFormats(desc->fConfig,
850                                     // ES2 and ES3 require sized internal formats for rb storage.
851                                     kGLES_GrGLStandard == this->glStandard(),
852                                     &msColorFormat,
853                                     NULL,
854                                     NULL)) {
855            goto FAILED;
856        }
857    } else {
858        desc->fRTFBOID = desc->fTexFBOID;
859    }
860
861    // below here we may bind the FBO
862    fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID;
863    if (desc->fRTFBOID != desc->fTexFBOID) {
864        SkASSERT(desc->fSampleCnt > 0);
865        GL_CALL(BindRenderbuffer(GR_GL_RENDERBUFFER,
866                               desc->fMSColorRenderbufferID));
867        if (!renderbuffer_storage_msaa(fGLContext,
868                                       desc->fSampleCnt,
869                                       msColorFormat,
870                                       width, height)) {
871            goto FAILED;
872        }
873        fGPUStats.incRenderTargetBinds();
874        GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, desc->fRTFBOID));
875        GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
876                                      GR_GL_COLOR_ATTACHMENT0,
877                                      GR_GL_RENDERBUFFER,
878                                      desc->fMSColorRenderbufferID));
879        if (desc->fCheckAllocation ||
880            !this->glCaps().isConfigVerifiedColorAttachment(desc->fConfig)) {
881            GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER));
882            if (status != GR_GL_FRAMEBUFFER_COMPLETE) {
883                goto FAILED;
884            }
885            fGLContext.caps()->markConfigAsValidColorAttachment(desc->fConfig);
886        }
887    }
888    fGPUStats.incRenderTargetBinds();
889    GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, desc->fTexFBOID));
890
891    if (this->glCaps().usesImplicitMSAAResolve() && desc->fSampleCnt > 0) {
892        GL_CALL(FramebufferTexture2DMultisample(GR_GL_FRAMEBUFFER,
893                                                GR_GL_COLOR_ATTACHMENT0,
894                                                GR_GL_TEXTURE_2D,
895                                                texID, 0, desc->fSampleCnt));
896    } else {
897        GL_CALL(FramebufferTexture2D(GR_GL_FRAMEBUFFER,
898                                     GR_GL_COLOR_ATTACHMENT0,
899                                     GR_GL_TEXTURE_2D,
900                                     texID, 0));
901    }
902    if (desc->fCheckAllocation ||
903        !this->glCaps().isConfigVerifiedColorAttachment(desc->fConfig)) {
904        GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER));
905        if (status != GR_GL_FRAMEBUFFER_COMPLETE) {
906            goto FAILED;
907        }
908        fGLContext.caps()->markConfigAsValidColorAttachment(desc->fConfig);
909    }
910
911    return true;
912
913FAILED:
914    if (desc->fMSColorRenderbufferID) {
915        GL_CALL(DeleteRenderbuffers(1, &desc->fMSColorRenderbufferID));
916    }
917    if (desc->fRTFBOID != desc->fTexFBOID) {
918        GL_CALL(DeleteFramebuffers(1, &desc->fRTFBOID));
919    }
920    if (desc->fTexFBOID) {
921        GL_CALL(DeleteFramebuffers(1, &desc->fTexFBOID));
922    }
923    return false;
924}
925
926// good to set a break-point here to know when createTexture fails
927static GrTexture* return_null_texture() {
928//    SkDEBUGFAIL("null texture");
929    return NULL;
930}
931
932#if 0 && defined(SK_DEBUG)
933static size_t as_size_t(int x) {
934    return x;
935}
936#endif
937
938GrTexture* GrGpuGL::onCreateTexture(const GrTextureDesc& desc,
939                                    const void* srcData,
940                                    size_t rowBytes) {
941
942    GrGLTexture::Desc glTexDesc;
943    GrGLRenderTarget::Desc  glRTDesc;
944
945    // Attempt to catch un- or wrongly initialized sample counts;
946    SkASSERT(desc.fSampleCnt >= 0 && desc.fSampleCnt <= 64);
947    // We fail if the MSAA was requested and is not available.
948    if (GrGLCaps::kNone_MSFBOType == this->glCaps().msFBOType() && desc.fSampleCnt) {
949        //GrPrintf("MSAA RT requested but not supported on this platform.");
950        return return_null_texture();
951    }
952    // If the sample count exceeds the max then we clamp it.
953    glTexDesc.fSampleCnt = SkTMin(desc.fSampleCnt, this->caps()->maxSampleCount());
954
955    glTexDesc.fFlags  = desc.fFlags;
956    glTexDesc.fWidth  = desc.fWidth;
957    glTexDesc.fHeight = desc.fHeight;
958    glTexDesc.fConfig = desc.fConfig;
959    glTexDesc.fIsWrapped = false;
960
961    glRTDesc.fMSColorRenderbufferID = 0;
962    glRTDesc.fRTFBOID = 0;
963    glRTDesc.fTexFBOID = 0;
964    glRTDesc.fIsWrapped = false;
965    glRTDesc.fConfig = glTexDesc.fConfig;
966    glRTDesc.fCheckAllocation = SkToBool(desc.fFlags & kCheckAllocation_GrTextureFlagBit);
967
968    bool renderTarget = SkToBool(desc.fFlags & kRenderTarget_GrTextureFlagBit);
969
970    glTexDesc.fOrigin = resolve_origin(desc.fOrigin, renderTarget);
971    glRTDesc.fOrigin = glTexDesc.fOrigin;
972
973    glRTDesc.fSampleCnt = glTexDesc.fSampleCnt;
974    if (GrGLCaps::kNone_MSFBOType == this->glCaps().msFBOType() &&
975        desc.fSampleCnt) {
976        //GrPrintf("MSAA RT requested but not supported on this platform.");
977        return return_null_texture();
978    }
979
980    if (renderTarget) {
981        int maxRTSize = this->caps()->maxRenderTargetSize();
982        if (glTexDesc.fWidth > maxRTSize || glTexDesc.fHeight > maxRTSize) {
983            return return_null_texture();
984        }
985    } else {
986        int maxSize = this->caps()->maxTextureSize();
987        if (glTexDesc.fWidth > maxSize || glTexDesc.fHeight > maxSize) {
988            return return_null_texture();
989        }
990    }
991
992    GL_CALL(GenTextures(1, &glTexDesc.fTextureID));
993
994    if (!glTexDesc.fTextureID) {
995        return return_null_texture();
996    }
997
998    this->setScratchTextureUnit();
999    GL_CALL(BindTexture(GR_GL_TEXTURE_2D, glTexDesc.fTextureID));
1000
1001    if (renderTarget && this->glCaps().textureUsageSupport()) {
1002        // provides a hint about how this texture will be used
1003        GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
1004                              GR_GL_TEXTURE_USAGE,
1005                              GR_GL_FRAMEBUFFER_ATTACHMENT));
1006    }
1007
1008    // Some drivers like to know filter/wrap before seeing glTexImage2D. Some
1009    // drivers have a bug where an FBO won't be complete if it includes a
1010    // texture that is not mipmap complete (considering the filter in use).
1011    GrGLTexture::TexParams initialTexParams;
1012    // we only set a subset here so invalidate first
1013    initialTexParams.invalidate();
1014    initialTexParams.fMinFilter = GR_GL_NEAREST;
1015    initialTexParams.fMagFilter = GR_GL_NEAREST;
1016    initialTexParams.fWrapS = GR_GL_CLAMP_TO_EDGE;
1017    initialTexParams.fWrapT = GR_GL_CLAMP_TO_EDGE;
1018    GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
1019                          GR_GL_TEXTURE_MAG_FILTER,
1020                          initialTexParams.fMagFilter));
1021    GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
1022                          GR_GL_TEXTURE_MIN_FILTER,
1023                          initialTexParams.fMinFilter));
1024    GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
1025                          GR_GL_TEXTURE_WRAP_S,
1026                          initialTexParams.fWrapS));
1027    GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
1028                          GR_GL_TEXTURE_WRAP_T,
1029                          initialTexParams.fWrapT));
1030    if (!this->uploadTexData(glTexDesc, true, 0, 0,
1031                             glTexDesc.fWidth, glTexDesc.fHeight,
1032                             desc.fConfig, srcData, rowBytes)) {
1033        GL_CALL(DeleteTextures(1, &glTexDesc.fTextureID));
1034        return return_null_texture();
1035    }
1036
1037    GrGLTexture* tex;
1038    if (renderTarget) {
1039        // unbind the texture from the texture unit before binding it to the frame buffer
1040        GL_CALL(BindTexture(GR_GL_TEXTURE_2D, 0));
1041
1042        if (!this->createRenderTargetObjects(glTexDesc.fWidth,
1043                                             glTexDesc.fHeight,
1044                                             glTexDesc.fTextureID,
1045                                             &glRTDesc)) {
1046            GL_CALL(DeleteTextures(1, &glTexDesc.fTextureID));
1047            return return_null_texture();
1048        }
1049        tex = SkNEW_ARGS(GrGLTexture, (this, glTexDesc, glRTDesc));
1050    } else {
1051        tex = SkNEW_ARGS(GrGLTexture, (this, glTexDesc));
1052    }
1053    tex->setCachedTexParams(initialTexParams, this->getResetTimestamp());
1054#ifdef TRACE_TEXTURE_CREATION
1055    GrPrintf("--- new texture [%d] size=(%d %d) config=%d\n",
1056             glTexDesc.fTextureID, desc.fWidth, desc.fHeight, desc.fConfig);
1057#endif
1058    return tex;
1059}
1060
1061GrTexture* GrGpuGL::onCreateCompressedTexture(const GrTextureDesc& desc,
1062                                              const void* srcData) {
1063
1064    if(SkToBool(desc.fFlags & kRenderTarget_GrTextureFlagBit)) {
1065        return return_null_texture();
1066    }
1067
1068    // Make sure that we're not flipping Y.
1069    GrSurfaceOrigin texOrigin = resolve_origin(desc.fOrigin, false);
1070    if (kBottomLeft_GrSurfaceOrigin == texOrigin) {
1071        return return_null_texture();
1072    }
1073
1074    GrGLTexture::Desc glTexDesc;
1075
1076    glTexDesc.fFlags  = desc.fFlags;
1077    glTexDesc.fWidth  = desc.fWidth;
1078    glTexDesc.fHeight = desc.fHeight;
1079    glTexDesc.fConfig = desc.fConfig;
1080    glTexDesc.fIsWrapped = false;
1081    glTexDesc.fOrigin = texOrigin;
1082
1083    int maxSize = this->caps()->maxTextureSize();
1084    if (glTexDesc.fWidth > maxSize || glTexDesc.fHeight > maxSize) {
1085        return return_null_texture();
1086    }
1087
1088    GL_CALL(GenTextures(1, &glTexDesc.fTextureID));
1089
1090    if (!glTexDesc.fTextureID) {
1091        return return_null_texture();
1092    }
1093
1094    this->setScratchTextureUnit();
1095    GL_CALL(BindTexture(GR_GL_TEXTURE_2D, glTexDesc.fTextureID));
1096
1097    // Some drivers like to know filter/wrap before seeing glTexImage2D. Some
1098    // drivers have a bug where an FBO won't be complete if it includes a
1099    // texture that is not mipmap complete (considering the filter in use).
1100    GrGLTexture::TexParams initialTexParams;
1101    // we only set a subset here so invalidate first
1102    initialTexParams.invalidate();
1103    initialTexParams.fMinFilter = GR_GL_NEAREST;
1104    initialTexParams.fMagFilter = GR_GL_NEAREST;
1105    initialTexParams.fWrapS = GR_GL_CLAMP_TO_EDGE;
1106    initialTexParams.fWrapT = GR_GL_CLAMP_TO_EDGE;
1107    GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
1108                          GR_GL_TEXTURE_MAG_FILTER,
1109                          initialTexParams.fMagFilter));
1110    GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
1111                          GR_GL_TEXTURE_MIN_FILTER,
1112                          initialTexParams.fMinFilter));
1113    GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
1114                          GR_GL_TEXTURE_WRAP_S,
1115                          initialTexParams.fWrapS));
1116    GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
1117                          GR_GL_TEXTURE_WRAP_T,
1118                          initialTexParams.fWrapT));
1119
1120    if (!this->uploadCompressedTexData(glTexDesc, srcData)) {
1121        GL_CALL(DeleteTextures(1, &glTexDesc.fTextureID));
1122        return return_null_texture();
1123    }
1124
1125    GrGLTexture* tex;
1126    tex = SkNEW_ARGS(GrGLTexture, (this, glTexDesc));
1127    tex->setCachedTexParams(initialTexParams, this->getResetTimestamp());
1128#ifdef TRACE_TEXTURE_CREATION
1129    GrPrintf("--- new compressed texture [%d] size=(%d %d) config=%d\n",
1130             glTexDesc.fTextureID, desc.fWidth, desc.fHeight, desc.fConfig);
1131#endif
1132    return tex;
1133}
1134
1135namespace {
1136
1137const GrGLuint kUnknownBitCount = GrGLStencilBuffer::kUnknownBitCount;
1138
1139void inline get_stencil_rb_sizes(const GrGLInterface* gl,
1140                                 GrGLStencilBuffer::Format* format) {
1141
1142    // we shouldn't ever know one size and not the other
1143    SkASSERT((kUnknownBitCount == format->fStencilBits) ==
1144             (kUnknownBitCount == format->fTotalBits));
1145    if (kUnknownBitCount == format->fStencilBits) {
1146        GR_GL_GetRenderbufferParameteriv(gl, GR_GL_RENDERBUFFER,
1147                                         GR_GL_RENDERBUFFER_STENCIL_SIZE,
1148                                         (GrGLint*)&format->fStencilBits);
1149        if (format->fPacked) {
1150            GR_GL_GetRenderbufferParameteriv(gl, GR_GL_RENDERBUFFER,
1151                                             GR_GL_RENDERBUFFER_DEPTH_SIZE,
1152                                             (GrGLint*)&format->fTotalBits);
1153            format->fTotalBits += format->fStencilBits;
1154        } else {
1155            format->fTotalBits = format->fStencilBits;
1156        }
1157    }
1158}
1159}
1160
1161bool GrGpuGL::createStencilBufferForRenderTarget(GrRenderTarget* rt,
1162                                                 int width, int height) {
1163
1164    // All internally created RTs are also textures. We don't create
1165    // SBs for a client's standalone RT (that is a RT that isn't also a texture).
1166    SkASSERT(rt->asTexture());
1167    SkASSERT(width >= rt->width());
1168    SkASSERT(height >= rt->height());
1169
1170    int samples = rt->numSamples();
1171    GrGLuint sbID;
1172    GL_CALL(GenRenderbuffers(1, &sbID));
1173    if (!sbID) {
1174        return false;
1175    }
1176
1177    int stencilFmtCnt = this->glCaps().stencilFormats().count();
1178    for (int i = 0; i < stencilFmtCnt; ++i) {
1179        GL_CALL(BindRenderbuffer(GR_GL_RENDERBUFFER, sbID));
1180        // we start with the last stencil format that succeeded in hopes
1181        // that we won't go through this loop more than once after the
1182        // first (painful) stencil creation.
1183        int sIdx = (i + fLastSuccessfulStencilFmtIdx) % stencilFmtCnt;
1184        const GrGLCaps::StencilFormat& sFmt =
1185                this->glCaps().stencilFormats()[sIdx];
1186        CLEAR_ERROR_BEFORE_ALLOC(this->glInterface());
1187        // we do this "if" so that we don't call the multisample
1188        // version on a GL that doesn't have an MSAA extension.
1189        bool created;
1190        if (samples > 0) {
1191            created = renderbuffer_storage_msaa(fGLContext,
1192                                                samples,
1193                                                sFmt.fInternalFormat,
1194                                                width, height);
1195        } else {
1196            GL_ALLOC_CALL(this->glInterface(),
1197                          RenderbufferStorage(GR_GL_RENDERBUFFER,
1198                                              sFmt.fInternalFormat,
1199                                              width, height));
1200            created =
1201                (GR_GL_NO_ERROR == check_alloc_error(rt->desc(), this->glInterface()));
1202        }
1203        if (created) {
1204            // After sized formats we attempt an unsized format and take
1205            // whatever sizes GL gives us. In that case we query for the size.
1206            GrGLStencilBuffer::Format format = sFmt;
1207            get_stencil_rb_sizes(this->glInterface(), &format);
1208            static const bool kIsWrapped = false;
1209            SkAutoTUnref<GrStencilBuffer> sb(SkNEW_ARGS(GrGLStencilBuffer,
1210                                                  (this, kIsWrapped, sbID, width, height,
1211                                                  samples, format)));
1212            if (this->attachStencilBufferToRenderTarget(sb, rt)) {
1213                fLastSuccessfulStencilFmtIdx = sIdx;
1214                sb->transferToCache();
1215                rt->setStencilBuffer(sb);
1216                return true;
1217           }
1218           sb->abandon(); // otherwise we lose sbID
1219        }
1220    }
1221    GL_CALL(DeleteRenderbuffers(1, &sbID));
1222    return false;
1223}
1224
1225bool GrGpuGL::attachStencilBufferToRenderTarget(GrStencilBuffer* sb, GrRenderTarget* rt) {
1226    GrGLRenderTarget* glrt = (GrGLRenderTarget*) rt;
1227
1228    GrGLuint fbo = glrt->renderFBOID();
1229
1230    if (NULL == sb) {
1231        if (rt->getStencilBuffer()) {
1232            GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
1233                                            GR_GL_STENCIL_ATTACHMENT,
1234                                            GR_GL_RENDERBUFFER, 0));
1235            GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
1236                                            GR_GL_DEPTH_ATTACHMENT,
1237                                            GR_GL_RENDERBUFFER, 0));
1238#ifdef SK_DEBUG
1239            GrGLenum status;
1240            GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER));
1241            SkASSERT(GR_GL_FRAMEBUFFER_COMPLETE == status);
1242#endif
1243        }
1244        return true;
1245    } else {
1246        GrGLStencilBuffer* glsb = static_cast<GrGLStencilBuffer*>(sb);
1247        GrGLuint rb = glsb->renderbufferID();
1248
1249        fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID;
1250        fGPUStats.incRenderTargetBinds();
1251        GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, fbo));
1252        GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
1253                                        GR_GL_STENCIL_ATTACHMENT,
1254                                        GR_GL_RENDERBUFFER, rb));
1255        if (glsb->format().fPacked) {
1256            GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
1257                                            GR_GL_DEPTH_ATTACHMENT,
1258                                            GR_GL_RENDERBUFFER, rb));
1259        } else {
1260            GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
1261                                            GR_GL_DEPTH_ATTACHMENT,
1262                                            GR_GL_RENDERBUFFER, 0));
1263        }
1264
1265        GrGLenum status;
1266        if (!this->glCaps().isColorConfigAndStencilFormatVerified(rt->config(), glsb->format())) {
1267            GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER));
1268            if (status != GR_GL_FRAMEBUFFER_COMPLETE) {
1269                GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
1270                                              GR_GL_STENCIL_ATTACHMENT,
1271                                              GR_GL_RENDERBUFFER, 0));
1272                if (glsb->format().fPacked) {
1273                    GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
1274                                                  GR_GL_DEPTH_ATTACHMENT,
1275                                                  GR_GL_RENDERBUFFER, 0));
1276                }
1277                return false;
1278            } else {
1279                fGLContext.caps()->markColorConfigAndStencilFormatAsVerified(
1280                    rt->config(),
1281                    glsb->format());
1282            }
1283        }
1284        return true;
1285    }
1286}
1287
1288////////////////////////////////////////////////////////////////////////////////
1289
1290GrVertexBuffer* GrGpuGL::onCreateVertexBuffer(size_t size, bool dynamic) {
1291    GrGLVertexBuffer::Desc desc;
1292    desc.fDynamic = dynamic;
1293    desc.fSizeInBytes = size;
1294    desc.fIsWrapped = false;
1295
1296    if (this->glCaps().useNonVBOVertexAndIndexDynamicData() && desc.fDynamic) {
1297        desc.fID = 0;
1298        GrGLVertexBuffer* vertexBuffer = SkNEW_ARGS(GrGLVertexBuffer, (this, desc));
1299        return vertexBuffer;
1300    } else {
1301        GL_CALL(GenBuffers(1, &desc.fID));
1302        if (desc.fID) {
1303            fHWGeometryState.setVertexBufferID(this, desc.fID);
1304            CLEAR_ERROR_BEFORE_ALLOC(this->glInterface());
1305            // make sure driver can allocate memory for this buffer
1306            GL_ALLOC_CALL(this->glInterface(),
1307                          BufferData(GR_GL_ARRAY_BUFFER,
1308                                     (GrGLsizeiptr) desc.fSizeInBytes,
1309                                     NULL,   // data ptr
1310                                     desc.fDynamic ? GR_GL_DYNAMIC_DRAW : GR_GL_STATIC_DRAW));
1311            if (CHECK_ALLOC_ERROR(this->glInterface()) != GR_GL_NO_ERROR) {
1312                GL_CALL(DeleteBuffers(1, &desc.fID));
1313                this->notifyVertexBufferDelete(desc.fID);
1314                return NULL;
1315            }
1316            GrGLVertexBuffer* vertexBuffer = SkNEW_ARGS(GrGLVertexBuffer, (this, desc));
1317            return vertexBuffer;
1318        }
1319        return NULL;
1320    }
1321}
1322
1323GrIndexBuffer* GrGpuGL::onCreateIndexBuffer(size_t size, bool dynamic) {
1324    GrGLIndexBuffer::Desc desc;
1325    desc.fDynamic = dynamic;
1326    desc.fSizeInBytes = size;
1327    desc.fIsWrapped = false;
1328
1329    if (this->glCaps().useNonVBOVertexAndIndexDynamicData() && desc.fDynamic) {
1330        desc.fID = 0;
1331        GrIndexBuffer* indexBuffer = SkNEW_ARGS(GrGLIndexBuffer, (this, desc));
1332        return indexBuffer;
1333    } else {
1334        GL_CALL(GenBuffers(1, &desc.fID));
1335        if (desc.fID) {
1336            fHWGeometryState.setIndexBufferIDOnDefaultVertexArray(this, desc.fID);
1337            CLEAR_ERROR_BEFORE_ALLOC(this->glInterface());
1338            // make sure driver can allocate memory for this buffer
1339            GL_ALLOC_CALL(this->glInterface(),
1340                          BufferData(GR_GL_ELEMENT_ARRAY_BUFFER,
1341                                     (GrGLsizeiptr) desc.fSizeInBytes,
1342                                     NULL,  // data ptr
1343                                     desc.fDynamic ? GR_GL_DYNAMIC_DRAW : GR_GL_STATIC_DRAW));
1344            if (CHECK_ALLOC_ERROR(this->glInterface()) != GR_GL_NO_ERROR) {
1345                GL_CALL(DeleteBuffers(1, &desc.fID));
1346                this->notifyIndexBufferDelete(desc.fID);
1347                return NULL;
1348            }
1349            GrIndexBuffer* indexBuffer = SkNEW_ARGS(GrGLIndexBuffer, (this, desc));
1350            return indexBuffer;
1351        }
1352        return NULL;
1353    }
1354}
1355
1356void GrGpuGL::flushScissor(const GrGLIRect& rtViewport, GrSurfaceOrigin rtOrigin) {
1357    if (fScissorState.fEnabled) {
1358        GrGLIRect scissor;
1359        scissor.setRelativeTo(rtViewport,
1360                              fScissorState.fRect.fLeft,
1361                              fScissorState.fRect.fTop,
1362                              fScissorState.fRect.width(),
1363                              fScissorState.fRect.height(),
1364                              rtOrigin);
1365        // if the scissor fully contains the viewport then we fall through and
1366        // disable the scissor test.
1367        if (!scissor.contains(rtViewport)) {
1368            if (fHWScissorSettings.fRect != scissor) {
1369                scissor.pushToGLScissor(this->glInterface());
1370                fHWScissorSettings.fRect = scissor;
1371            }
1372            if (kYes_TriState != fHWScissorSettings.fEnabled) {
1373                GL_CALL(Enable(GR_GL_SCISSOR_TEST));
1374                fHWScissorSettings.fEnabled = kYes_TriState;
1375            }
1376            return;
1377        }
1378    }
1379    if (kNo_TriState != fHWScissorSettings.fEnabled) {
1380        GL_CALL(Disable(GR_GL_SCISSOR_TEST));
1381        fHWScissorSettings.fEnabled = kNo_TriState;
1382        return;
1383    }
1384}
1385
1386void GrGpuGL::onClear(GrRenderTarget* target, const SkIRect* rect, GrColor color,
1387                      bool canIgnoreRect) {
1388    // parent class should never let us get here with no RT
1389    SkASSERT(target);
1390    GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(target);
1391
1392    if (canIgnoreRect && this->glCaps().fullClearIsFree()) {
1393        rect = NULL;
1394    }
1395
1396    SkIRect clippedRect;
1397    if (rect) {
1398        // flushScissor expects rect to be clipped to the target.
1399        clippedRect = *rect;
1400        SkIRect rtRect = SkIRect::MakeWH(target->width(), target->height());
1401        if (clippedRect.intersect(rtRect)) {
1402            rect = &clippedRect;
1403        } else {
1404            return;
1405        }
1406    }
1407
1408    this->flushRenderTarget(glRT, rect);
1409    GrAutoTRestore<ScissorState> asr(&fScissorState);
1410    fScissorState.fEnabled = SkToBool(rect);
1411    if (fScissorState.fEnabled) {
1412        fScissorState.fRect = *rect;
1413    }
1414    this->flushScissor(glRT->getViewport(), glRT->origin());
1415
1416    GrGLfloat r, g, b, a;
1417    static const GrGLfloat scale255 = 1.f / 255.f;
1418    a = GrColorUnpackA(color) * scale255;
1419    GrGLfloat scaleRGB = scale255;
1420    r = GrColorUnpackR(color) * scaleRGB;
1421    g = GrColorUnpackG(color) * scaleRGB;
1422    b = GrColorUnpackB(color) * scaleRGB;
1423
1424    GL_CALL(ColorMask(GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE));
1425    fHWWriteToColor = kYes_TriState;
1426    GL_CALL(ClearColor(r, g, b, a));
1427    GL_CALL(Clear(GR_GL_COLOR_BUFFER_BIT));
1428}
1429
1430void GrGpuGL::discard(GrRenderTarget* renderTarget) {
1431    if (!this->caps()->discardRenderTargetSupport()) {
1432        return;
1433    }
1434    if (NULL == renderTarget) {
1435        renderTarget = this->drawState()->getRenderTarget();
1436        if (NULL == renderTarget) {
1437            return;
1438        }
1439    }
1440
1441    GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(renderTarget);
1442    if (renderTarget->getUniqueID() != fHWBoundRenderTargetUniqueID) {
1443        fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID;
1444        fGPUStats.incRenderTargetBinds();
1445        GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, glRT->renderFBOID()));
1446    }
1447    switch (this->glCaps().invalidateFBType()) {
1448        case GrGLCaps::kNone_InvalidateFBType:
1449            SkFAIL("Should never get here.");
1450            break;
1451        case GrGLCaps::kInvalidate_InvalidateFBType:
1452            if (0 == glRT->renderFBOID()) {
1453                //  When rendering to the default framebuffer the legal values for attachments
1454                //  are GL_COLOR, GL_DEPTH, GL_STENCIL, ... rather than the various FBO attachment
1455                //  types.
1456                static const GrGLenum attachments[] = { GR_GL_COLOR };
1457                GL_CALL(InvalidateFramebuffer(GR_GL_FRAMEBUFFER, SK_ARRAY_COUNT(attachments),
1458                        attachments));
1459            } else {
1460                static const GrGLenum attachments[] = { GR_GL_COLOR_ATTACHMENT0 };
1461                GL_CALL(InvalidateFramebuffer(GR_GL_FRAMEBUFFER, SK_ARRAY_COUNT(attachments),
1462                        attachments));
1463            }
1464            break;
1465        case GrGLCaps::kDiscard_InvalidateFBType: {
1466            if (0 == glRT->renderFBOID()) {
1467                //  When rendering to the default framebuffer the legal values for attachments
1468                //  are GL_COLOR, GL_DEPTH, GL_STENCIL, ... rather than the various FBO attachment
1469                //  types. See glDiscardFramebuffer() spec.
1470                static const GrGLenum attachments[] = { GR_GL_COLOR };
1471                GL_CALL(DiscardFramebuffer(GR_GL_FRAMEBUFFER, SK_ARRAY_COUNT(attachments),
1472                        attachments));
1473            } else {
1474                static const GrGLenum attachments[] = { GR_GL_COLOR_ATTACHMENT0 };
1475                GL_CALL(DiscardFramebuffer(GR_GL_FRAMEBUFFER, SK_ARRAY_COUNT(attachments),
1476                        attachments));
1477            }
1478            break;
1479        }
1480    }
1481    renderTarget->flagAsResolved();
1482}
1483
1484
1485void GrGpuGL::clearStencil(GrRenderTarget* target) {
1486    if (NULL == target) {
1487        return;
1488    }
1489    GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(target);
1490    this->flushRenderTarget(glRT, &SkIRect::EmptyIRect());
1491
1492    GrAutoTRestore<ScissorState> asr(&fScissorState);
1493    fScissorState.fEnabled = false;
1494    this->flushScissor(glRT->getViewport(), glRT->origin());
1495
1496    GL_CALL(StencilMask(0xffffffff));
1497    GL_CALL(ClearStencil(0));
1498    GL_CALL(Clear(GR_GL_STENCIL_BUFFER_BIT));
1499    fHWStencilSettings.invalidate();
1500}
1501
1502void GrGpuGL::clearStencilClip(GrRenderTarget* target, const SkIRect& rect, bool insideClip) {
1503    SkASSERT(target);
1504
1505    // this should only be called internally when we know we have a
1506    // stencil buffer.
1507    SkASSERT(target->getStencilBuffer());
1508    GrGLint stencilBitCount =  target->getStencilBuffer()->bits();
1509#if 0
1510    SkASSERT(stencilBitCount > 0);
1511    GrGLint clipStencilMask  = (1 << (stencilBitCount - 1));
1512#else
1513    // we could just clear the clip bit but when we go through
1514    // ANGLE a partial stencil mask will cause clears to be
1515    // turned into draws. Our contract on GrDrawTarget says that
1516    // changing the clip between stencil passes may or may not
1517    // zero the client's clip bits. So we just clear the whole thing.
1518    static const GrGLint clipStencilMask  = ~0;
1519#endif
1520    GrGLint value;
1521    if (insideClip) {
1522        value = (1 << (stencilBitCount - 1));
1523    } else {
1524        value = 0;
1525    }
1526    GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(target);
1527    this->flushRenderTarget(glRT, &SkIRect::EmptyIRect());
1528
1529    GrAutoTRestore<ScissorState> asr(&fScissorState);
1530    fScissorState.fEnabled = true;
1531    fScissorState.fRect = rect;
1532    this->flushScissor(glRT->getViewport(), glRT->origin());
1533
1534    GL_CALL(StencilMask((uint32_t) clipStencilMask));
1535    GL_CALL(ClearStencil(value));
1536    GL_CALL(Clear(GR_GL_STENCIL_BUFFER_BIT));
1537    fHWStencilSettings.invalidate();
1538}
1539
1540bool GrGpuGL::readPixelsWillPayForYFlip(GrRenderTarget* renderTarget,
1541                                        int left, int top,
1542                                        int width, int height,
1543                                        GrPixelConfig config,
1544                                        size_t rowBytes) const {
1545    // If this rendertarget is aready TopLeft, we don't need to flip.
1546    if (kTopLeft_GrSurfaceOrigin == renderTarget->origin()) {
1547        return false;
1548    }
1549
1550    // if GL can do the flip then we'll never pay for it.
1551    if (this->glCaps().packFlipYSupport()) {
1552        return false;
1553    }
1554
1555    // If we have to do memcpy to handle non-trim rowBytes then we
1556    // get the flip for free. Otherwise it costs.
1557    if (this->glCaps().packRowLengthSupport()) {
1558        return true;
1559    }
1560    // If we have to do memcpys to handle rowBytes then y-flip is free
1561    // Note the rowBytes might be tight to the passed in data, but if data
1562    // gets clipped in x to the target the rowBytes will no longer be tight.
1563    if (left >= 0 && (left + width) < renderTarget->width()) {
1564           return 0 == rowBytes ||
1565                  GrBytesPerPixel(config) * width == rowBytes;
1566    } else {
1567        return false;
1568    }
1569}
1570
1571bool GrGpuGL::onReadPixels(GrRenderTarget* target,
1572                           int left, int top,
1573                           int width, int height,
1574                           GrPixelConfig config,
1575                           void* buffer,
1576                           size_t rowBytes) {
1577    // We cannot read pixels into a compressed buffer
1578    if (GrPixelConfigIsCompressed(config)) {
1579        return false;
1580    }
1581
1582    GrGLenum format = 0;
1583    GrGLenum type = 0;
1584    bool flipY = kBottomLeft_GrSurfaceOrigin == target->origin();
1585    if (!this->configToGLFormats(config, false, NULL, &format, &type)) {
1586        return false;
1587    }
1588    size_t bpp = GrBytesPerPixel(config);
1589    if (!adjust_pixel_ops_params(target->width(), target->height(), bpp,
1590                                 &left, &top, &width, &height,
1591                                 const_cast<const void**>(&buffer),
1592                                 &rowBytes)) {
1593        return false;
1594    }
1595
1596    // resolve the render target if necessary
1597    GrGLRenderTarget* tgt = static_cast<GrGLRenderTarget*>(target);
1598    switch (tgt->getResolveType()) {
1599        case GrGLRenderTarget::kCantResolve_ResolveType:
1600            return false;
1601        case GrGLRenderTarget::kAutoResolves_ResolveType:
1602            this->flushRenderTarget(static_cast<GrGLRenderTarget*>(target),
1603                                    &SkIRect::EmptyIRect());
1604            break;
1605        case GrGLRenderTarget::kCanResolve_ResolveType:
1606            this->onResolveRenderTarget(tgt);
1607            // we don't track the state of the READ FBO ID.
1608            fGPUStats.incRenderTargetBinds();
1609            GL_CALL(BindFramebuffer(GR_GL_READ_FRAMEBUFFER,
1610                                    tgt->textureFBOID()));
1611            break;
1612        default:
1613            SkFAIL("Unknown resolve type");
1614    }
1615
1616    const GrGLIRect& glvp = tgt->getViewport();
1617
1618    // the read rect is viewport-relative
1619    GrGLIRect readRect;
1620    readRect.setRelativeTo(glvp, left, top, width, height, target->origin());
1621
1622    size_t tightRowBytes = bpp * width;
1623    if (0 == rowBytes) {
1624        rowBytes = tightRowBytes;
1625    }
1626    size_t readDstRowBytes = tightRowBytes;
1627    void* readDst = buffer;
1628
1629    // determine if GL can read using the passed rowBytes or if we need
1630    // a scratch buffer.
1631    GrAutoMalloc<32 * sizeof(GrColor)> scratch;
1632    if (rowBytes != tightRowBytes) {
1633        if (this->glCaps().packRowLengthSupport()) {
1634            SkASSERT(!(rowBytes % sizeof(GrColor)));
1635            GL_CALL(PixelStorei(GR_GL_PACK_ROW_LENGTH,
1636                                static_cast<GrGLint>(rowBytes / sizeof(GrColor))));
1637            readDstRowBytes = rowBytes;
1638        } else {
1639            scratch.reset(tightRowBytes * height);
1640            readDst = scratch.get();
1641        }
1642    }
1643    if (flipY && this->glCaps().packFlipYSupport()) {
1644        GL_CALL(PixelStorei(GR_GL_PACK_REVERSE_ROW_ORDER, 1));
1645    }
1646    GL_CALL(ReadPixels(readRect.fLeft, readRect.fBottom,
1647                       readRect.fWidth, readRect.fHeight,
1648                       format, type, readDst));
1649    if (readDstRowBytes != tightRowBytes) {
1650        SkASSERT(this->glCaps().packRowLengthSupport());
1651        GL_CALL(PixelStorei(GR_GL_PACK_ROW_LENGTH, 0));
1652    }
1653    if (flipY && this->glCaps().packFlipYSupport()) {
1654        GL_CALL(PixelStorei(GR_GL_PACK_REVERSE_ROW_ORDER, 0));
1655        flipY = false;
1656    }
1657
1658    // now reverse the order of the rows, since GL's are bottom-to-top, but our
1659    // API presents top-to-bottom. We must preserve the padding contents. Note
1660    // that the above readPixels did not overwrite the padding.
1661    if (readDst == buffer) {
1662        SkASSERT(rowBytes == readDstRowBytes);
1663        if (flipY) {
1664            scratch.reset(tightRowBytes);
1665            void* tmpRow = scratch.get();
1666            // flip y in-place by rows
1667            const int halfY = height >> 1;
1668            char* top = reinterpret_cast<char*>(buffer);
1669            char* bottom = top + (height - 1) * rowBytes;
1670            for (int y = 0; y < halfY; y++) {
1671                memcpy(tmpRow, top, tightRowBytes);
1672                memcpy(top, bottom, tightRowBytes);
1673                memcpy(bottom, tmpRow, tightRowBytes);
1674                top += rowBytes;
1675                bottom -= rowBytes;
1676            }
1677        }
1678    } else {
1679        SkASSERT(readDst != buffer);        SkASSERT(rowBytes != tightRowBytes);
1680        // copy from readDst to buffer while flipping y
1681        // const int halfY = height >> 1;
1682        const char* src = reinterpret_cast<const char*>(readDst);
1683        char* dst = reinterpret_cast<char*>(buffer);
1684        if (flipY) {
1685            dst += (height-1) * rowBytes;
1686        }
1687        for (int y = 0; y < height; y++) {
1688            memcpy(dst, src, tightRowBytes);
1689            src += readDstRowBytes;
1690            if (!flipY) {
1691                dst += rowBytes;
1692            } else {
1693                dst -= rowBytes;
1694            }
1695        }
1696    }
1697    return true;
1698}
1699
1700void GrGpuGL::flushRenderTarget(GrGLRenderTarget* target, const SkIRect* bound) {
1701
1702    SkASSERT(target);
1703
1704    uint32_t rtID = target->getUniqueID();
1705    if (fHWBoundRenderTargetUniqueID != rtID) {
1706        fGPUStats.incRenderTargetBinds();
1707        GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, target->renderFBOID()));
1708#ifdef SK_DEBUG
1709        // don't do this check in Chromium -- this is causing
1710        // lots of repeated command buffer flushes when the compositor is
1711        // rendering with Ganesh, which is really slow; even too slow for
1712        // Debug mode.
1713        if (!this->glContext().isChromium()) {
1714            GrGLenum status;
1715            GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER));
1716            if (status != GR_GL_FRAMEBUFFER_COMPLETE) {
1717                GrPrintf("GrGpuGL::flushRenderTarget glCheckFramebufferStatus %x\n", status);
1718            }
1719        }
1720#endif
1721        fHWBoundRenderTargetUniqueID = rtID;
1722        const GrGLIRect& vp = target->getViewport();
1723        if (fHWViewport != vp) {
1724            vp.pushToGLViewport(this->glInterface());
1725            fHWViewport = vp;
1726        }
1727    }
1728    if (NULL == bound || !bound->isEmpty()) {
1729        target->flagAsNeedingResolve(bound);
1730    }
1731
1732    GrTexture *texture = target->asTexture();
1733    if (texture) {
1734        texture->impl()->dirtyMipMaps(true);
1735    }
1736}
1737
1738GrGLenum gPrimitiveType2GLMode[] = {
1739    GR_GL_TRIANGLES,
1740    GR_GL_TRIANGLE_STRIP,
1741    GR_GL_TRIANGLE_FAN,
1742    GR_GL_POINTS,
1743    GR_GL_LINES,
1744    GR_GL_LINE_STRIP
1745};
1746
1747#define SWAP_PER_DRAW 0
1748
1749#if SWAP_PER_DRAW
1750    #if defined(SK_BUILD_FOR_MAC)
1751        #include <AGL/agl.h>
1752    #elif defined(SK_BUILD_FOR_WIN32)
1753        #include <gl/GL.h>
1754        void SwapBuf() {
1755            DWORD procID = GetCurrentProcessId();
1756            HWND hwnd = GetTopWindow(GetDesktopWindow());
1757            while(hwnd) {
1758                DWORD wndProcID = 0;
1759                GetWindowThreadProcessId(hwnd, &wndProcID);
1760                if(wndProcID == procID) {
1761                    SwapBuffers(GetDC(hwnd));
1762                }
1763                hwnd = GetNextWindow(hwnd, GW_HWNDNEXT);
1764            }
1765         }
1766    #endif
1767#endif
1768
1769void GrGpuGL::onGpuDraw(const DrawInfo& info) {
1770    size_t indexOffsetInBytes;
1771    this->setupGeometry(info, &indexOffsetInBytes);
1772
1773    SkASSERT((size_t)info.primitiveType() < SK_ARRAY_COUNT(gPrimitiveType2GLMode));
1774
1775    if (info.isIndexed()) {
1776        GrGLvoid* indices =
1777            reinterpret_cast<GrGLvoid*>(indexOffsetInBytes + sizeof(uint16_t) * info.startIndex());
1778        // info.startVertex() was accounted for by setupGeometry.
1779        GL_CALL(DrawElements(gPrimitiveType2GLMode[info.primitiveType()],
1780                             info.indexCount(),
1781                             GR_GL_UNSIGNED_SHORT,
1782                             indices));
1783    } else {
1784        // Pass 0 for parameter first. We have to adjust glVertexAttribPointer() to account for
1785        // startVertex in the DrawElements case. So we always rely on setupGeometry to have
1786        // accounted for startVertex.
1787        GL_CALL(DrawArrays(gPrimitiveType2GLMode[info.primitiveType()], 0, info.vertexCount()));
1788    }
1789#if SWAP_PER_DRAW
1790    glFlush();
1791    #if defined(SK_BUILD_FOR_MAC)
1792        aglSwapBuffers(aglGetCurrentContext());
1793        int set_a_break_pt_here = 9;
1794        aglSwapBuffers(aglGetCurrentContext());
1795    #elif defined(SK_BUILD_FOR_WIN32)
1796        SwapBuf();
1797        int set_a_break_pt_here = 9;
1798        SwapBuf();
1799    #endif
1800#endif
1801}
1802
1803void GrGpuGL::onResolveRenderTarget(GrRenderTarget* target) {
1804    GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(target);
1805    if (rt->needsResolve()) {
1806        // Some extensions automatically resolves the texture when it is read.
1807        if (this->glCaps().usesMSAARenderBuffers()) {
1808            SkASSERT(rt->textureFBOID() != rt->renderFBOID());
1809            fGPUStats.incRenderTargetBinds();
1810            fGPUStats.incRenderTargetBinds();
1811            GL_CALL(BindFramebuffer(GR_GL_READ_FRAMEBUFFER, rt->renderFBOID()));
1812            GL_CALL(BindFramebuffer(GR_GL_DRAW_FRAMEBUFFER, rt->textureFBOID()));
1813            // make sure we go through flushRenderTarget() since we've modified
1814            // the bound DRAW FBO ID.
1815            fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID;
1816            const GrGLIRect& vp = rt->getViewport();
1817            const SkIRect dirtyRect = rt->getResolveRect();
1818            GrGLIRect r;
1819            r.setRelativeTo(vp, dirtyRect.fLeft, dirtyRect.fTop,
1820                            dirtyRect.width(), dirtyRect.height(), target->origin());
1821
1822            GrAutoTRestore<ScissorState> asr;
1823            if (GrGLCaps::kES_Apple_MSFBOType == this->glCaps().msFBOType()) {
1824                // Apple's extension uses the scissor as the blit bounds.
1825                asr.reset(&fScissorState);
1826                fScissorState.fEnabled = true;
1827                fScissorState.fRect = dirtyRect;
1828                this->flushScissor(rt->getViewport(), rt->origin());
1829                GL_CALL(ResolveMultisampleFramebuffer());
1830            } else {
1831                int right = r.fLeft + r.fWidth;
1832                int top = r.fBottom + r.fHeight;
1833
1834                // BlitFrameBuffer respects the scissor, so disable it.
1835                asr.reset(&fScissorState);
1836                fScissorState.fEnabled = false;
1837                this->flushScissor(rt->getViewport(), rt->origin());
1838                GL_CALL(BlitFramebuffer(r.fLeft, r.fBottom, right, top,
1839                                        r.fLeft, r.fBottom, right, top,
1840                                        GR_GL_COLOR_BUFFER_BIT, GR_GL_NEAREST));
1841            }
1842        }
1843        rt->flagAsResolved();
1844    }
1845}
1846
1847namespace {
1848
1849
1850GrGLenum gr_to_gl_stencil_op(GrStencilOp op) {
1851    static const GrGLenum gTable[] = {
1852        GR_GL_KEEP,        // kKeep_StencilOp
1853        GR_GL_REPLACE,     // kReplace_StencilOp
1854        GR_GL_INCR_WRAP,   // kIncWrap_StencilOp
1855        GR_GL_INCR,        // kIncClamp_StencilOp
1856        GR_GL_DECR_WRAP,   // kDecWrap_StencilOp
1857        GR_GL_DECR,        // kDecClamp_StencilOp
1858        GR_GL_ZERO,        // kZero_StencilOp
1859        GR_GL_INVERT,      // kInvert_StencilOp
1860    };
1861    GR_STATIC_ASSERT(SK_ARRAY_COUNT(gTable) == kStencilOpCount);
1862    GR_STATIC_ASSERT(0 == kKeep_StencilOp);
1863    GR_STATIC_ASSERT(1 == kReplace_StencilOp);
1864    GR_STATIC_ASSERT(2 == kIncWrap_StencilOp);
1865    GR_STATIC_ASSERT(3 == kIncClamp_StencilOp);
1866    GR_STATIC_ASSERT(4 == kDecWrap_StencilOp);
1867    GR_STATIC_ASSERT(5 == kDecClamp_StencilOp);
1868    GR_STATIC_ASSERT(6 == kZero_StencilOp);
1869    GR_STATIC_ASSERT(7 == kInvert_StencilOp);
1870    SkASSERT((unsigned) op < kStencilOpCount);
1871    return gTable[op];
1872}
1873
1874void set_gl_stencil(const GrGLInterface* gl,
1875                    const GrStencilSettings& settings,
1876                    GrGLenum glFace,
1877                    GrStencilSettings::Face grFace) {
1878    GrGLenum glFunc = GrToGLStencilFunc(settings.func(grFace));
1879    GrGLenum glFailOp = gr_to_gl_stencil_op(settings.failOp(grFace));
1880    GrGLenum glPassOp = gr_to_gl_stencil_op(settings.passOp(grFace));
1881
1882    GrGLint ref = settings.funcRef(grFace);
1883    GrGLint mask = settings.funcMask(grFace);
1884    GrGLint writeMask = settings.writeMask(grFace);
1885
1886    if (GR_GL_FRONT_AND_BACK == glFace) {
1887        // we call the combined func just in case separate stencil is not
1888        // supported.
1889        GR_GL_CALL(gl, StencilFunc(glFunc, ref, mask));
1890        GR_GL_CALL(gl, StencilMask(writeMask));
1891        GR_GL_CALL(gl, StencilOp(glFailOp, glPassOp, glPassOp));
1892    } else {
1893        GR_GL_CALL(gl, StencilFuncSeparate(glFace, glFunc, ref, mask));
1894        GR_GL_CALL(gl, StencilMaskSeparate(glFace, writeMask));
1895        GR_GL_CALL(gl, StencilOpSeparate(glFace, glFailOp, glPassOp, glPassOp));
1896    }
1897}
1898}
1899
1900void GrGpuGL::flushStencil(DrawType type) {
1901    if (kStencilPath_DrawType != type && fHWStencilSettings != fStencilSettings) {
1902        if (fStencilSettings.isDisabled()) {
1903            if (kNo_TriState != fHWStencilTestEnabled) {
1904                GL_CALL(Disable(GR_GL_STENCIL_TEST));
1905                fHWStencilTestEnabled = kNo_TriState;
1906            }
1907        } else {
1908            if (kYes_TriState != fHWStencilTestEnabled) {
1909                GL_CALL(Enable(GR_GL_STENCIL_TEST));
1910                fHWStencilTestEnabled = kYes_TriState;
1911            }
1912        }
1913        if (!fStencilSettings.isDisabled()) {
1914            if (this->caps()->twoSidedStencilSupport()) {
1915                set_gl_stencil(this->glInterface(),
1916                               fStencilSettings,
1917                               GR_GL_FRONT,
1918                               GrStencilSettings::kFront_Face);
1919                set_gl_stencil(this->glInterface(),
1920                               fStencilSettings,
1921                               GR_GL_BACK,
1922                               GrStencilSettings::kBack_Face);
1923            } else {
1924                set_gl_stencil(this->glInterface(),
1925                               fStencilSettings,
1926                               GR_GL_FRONT_AND_BACK,
1927                               GrStencilSettings::kFront_Face);
1928            }
1929        }
1930        fHWStencilSettings = fStencilSettings;
1931    }
1932}
1933
1934void GrGpuGL::flushAAState(const GrOptDrawState& optState, DrawType type) {
1935// At least some ATI linux drivers will render GL_LINES incorrectly when MSAA state is enabled but
1936// the target is not multisampled. Single pixel wide lines are rendered thicker than 1 pixel wide.
1937#if 0
1938    // Replace RT_HAS_MSAA with this definition once this driver bug is no longer a relevant concern
1939    #define RT_HAS_MSAA rt->isMultisampled()
1940#else
1941    #define RT_HAS_MSAA (rt->isMultisampled() || kDrawLines_DrawType == type)
1942#endif
1943
1944    const GrRenderTarget* rt = optState.getRenderTarget();
1945    if (kGL_GrGLStandard == this->glStandard()) {
1946        if (RT_HAS_MSAA) {
1947            // FIXME: GL_NV_pr doesn't seem to like MSAA disabled. The paths
1948            // convex hulls of each segment appear to get filled.
1949            bool enableMSAA = kStencilPath_DrawType == type ||
1950                              optState.isHWAntialiasState();
1951            if (enableMSAA) {
1952                if (kYes_TriState != fMSAAEnabled) {
1953                    GL_CALL(Enable(GR_GL_MULTISAMPLE));
1954                    fMSAAEnabled = kYes_TriState;
1955                }
1956            } else {
1957                if (kNo_TriState != fMSAAEnabled) {
1958                    GL_CALL(Disable(GR_GL_MULTISAMPLE));
1959                    fMSAAEnabled = kNo_TriState;
1960                }
1961            }
1962        }
1963    }
1964}
1965
1966void GrGpuGL::flushBlend(const GrOptDrawState& optState, bool isLines,
1967                         GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff) {
1968    // Any optimization to disable blending should have already been applied and
1969    // tweaked the coeffs to (1, 0).
1970    bool blendOff = kOne_GrBlendCoeff == srcCoeff && kZero_GrBlendCoeff == dstCoeff;
1971    if (blendOff) {
1972        if (kNo_TriState != fHWBlendState.fEnabled) {
1973            GL_CALL(Disable(GR_GL_BLEND));
1974            fHWBlendState.fEnabled = kNo_TriState;
1975        }
1976    } else {
1977        if (kYes_TriState != fHWBlendState.fEnabled) {
1978            GL_CALL(Enable(GR_GL_BLEND));
1979            fHWBlendState.fEnabled = kYes_TriState;
1980        }
1981        if (fHWBlendState.fSrcCoeff != srcCoeff ||
1982            fHWBlendState.fDstCoeff != dstCoeff) {
1983            GL_CALL(BlendFunc(gXfermodeCoeff2Blend[srcCoeff],
1984                              gXfermodeCoeff2Blend[dstCoeff]));
1985            fHWBlendState.fSrcCoeff = srcCoeff;
1986            fHWBlendState.fDstCoeff = dstCoeff;
1987        }
1988        GrColor blendConst = optState.getBlendConstant();
1989        if ((BlendCoeffReferencesConstant(srcCoeff) ||
1990             BlendCoeffReferencesConstant(dstCoeff)) &&
1991            (!fHWBlendState.fConstColorValid ||
1992             fHWBlendState.fConstColor != blendConst)) {
1993            GrGLfloat c[4];
1994            GrColorToRGBAFloat(blendConst, c);
1995            GL_CALL(BlendColor(c[0], c[1], c[2], c[3]));
1996            fHWBlendState.fConstColor = blendConst;
1997            fHWBlendState.fConstColorValid = true;
1998        }
1999    }
2000}
2001
2002static inline GrGLenum tile_to_gl_wrap(SkShader::TileMode tm) {
2003    static const GrGLenum gWrapModes[] = {
2004        GR_GL_CLAMP_TO_EDGE,
2005        GR_GL_REPEAT,
2006        GR_GL_MIRRORED_REPEAT
2007    };
2008    GR_STATIC_ASSERT(SkShader::kTileModeCount == SK_ARRAY_COUNT(gWrapModes));
2009    GR_STATIC_ASSERT(0 == SkShader::kClamp_TileMode);
2010    GR_STATIC_ASSERT(1 == SkShader::kRepeat_TileMode);
2011    GR_STATIC_ASSERT(2 == SkShader::kMirror_TileMode);
2012    return gWrapModes[tm];
2013}
2014
2015void GrGpuGL::bindTexture(int unitIdx, const GrTextureParams& params, GrGLTexture* texture) {
2016    SkASSERT(texture);
2017
2018    // If we created a rt/tex and rendered to it without using a texture and now we're texturing
2019    // from the rt it will still be the last bound texture, but it needs resolving. So keep this
2020    // out of the "last != next" check.
2021    GrGLRenderTarget* texRT =  static_cast<GrGLRenderTarget*>(texture->asRenderTarget());
2022    if (texRT) {
2023        this->onResolveRenderTarget(texRT);
2024    }
2025
2026    uint32_t textureID = texture->getUniqueID();
2027    if (fHWBoundTextureUniqueIDs[unitIdx] != textureID) {
2028        this->setTextureUnit(unitIdx);
2029        GL_CALL(BindTexture(GR_GL_TEXTURE_2D, texture->textureID()));
2030        fHWBoundTextureUniqueIDs[unitIdx] = textureID;
2031    }
2032
2033    ResetTimestamp timestamp;
2034    const GrGLTexture::TexParams& oldTexParams = texture->getCachedTexParams(&timestamp);
2035    bool setAll = timestamp < this->getResetTimestamp();
2036    GrGLTexture::TexParams newTexParams;
2037
2038    static GrGLenum glMinFilterModes[] = {
2039        GR_GL_NEAREST,
2040        GR_GL_LINEAR,
2041        GR_GL_LINEAR_MIPMAP_LINEAR
2042    };
2043    static GrGLenum glMagFilterModes[] = {
2044        GR_GL_NEAREST,
2045        GR_GL_LINEAR,
2046        GR_GL_LINEAR
2047    };
2048    GrTextureParams::FilterMode filterMode = params.filterMode();
2049    if (!this->caps()->mipMapSupport() && GrTextureParams::kMipMap_FilterMode == filterMode) {
2050        filterMode = GrTextureParams::kBilerp_FilterMode;
2051    }
2052    newTexParams.fMinFilter = glMinFilterModes[filterMode];
2053    newTexParams.fMagFilter = glMagFilterModes[filterMode];
2054
2055    if (GrTextureParams::kMipMap_FilterMode == filterMode &&
2056        texture->mipMapsAreDirty() && !GrPixelConfigIsCompressed(texture->config())) {
2057        GL_CALL(GenerateMipmap(GR_GL_TEXTURE_2D));
2058        texture->dirtyMipMaps(false);
2059    }
2060
2061    newTexParams.fWrapS = tile_to_gl_wrap(params.getTileModeX());
2062    newTexParams.fWrapT = tile_to_gl_wrap(params.getTileModeY());
2063    memcpy(newTexParams.fSwizzleRGBA,
2064           GrGLShaderBuilder::GetTexParamSwizzle(texture->config(), this->glCaps()),
2065           sizeof(newTexParams.fSwizzleRGBA));
2066    if (setAll || newTexParams.fMagFilter != oldTexParams.fMagFilter) {
2067        this->setTextureUnit(unitIdx);
2068        GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
2069                              GR_GL_TEXTURE_MAG_FILTER,
2070                              newTexParams.fMagFilter));
2071    }
2072    if (setAll || newTexParams.fMinFilter != oldTexParams.fMinFilter) {
2073        this->setTextureUnit(unitIdx);
2074        GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
2075                              GR_GL_TEXTURE_MIN_FILTER,
2076                              newTexParams.fMinFilter));
2077    }
2078    if (setAll || newTexParams.fWrapS != oldTexParams.fWrapS) {
2079        this->setTextureUnit(unitIdx);
2080        GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
2081                              GR_GL_TEXTURE_WRAP_S,
2082                              newTexParams.fWrapS));
2083    }
2084    if (setAll || newTexParams.fWrapT != oldTexParams.fWrapT) {
2085        this->setTextureUnit(unitIdx);
2086        GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
2087                              GR_GL_TEXTURE_WRAP_T,
2088                              newTexParams.fWrapT));
2089    }
2090    if (this->glCaps().textureSwizzleSupport() &&
2091        (setAll || memcmp(newTexParams.fSwizzleRGBA,
2092                          oldTexParams.fSwizzleRGBA,
2093                          sizeof(newTexParams.fSwizzleRGBA)))) {
2094        this->setTextureUnit(unitIdx);
2095        if (this->glStandard() == kGLES_GrGLStandard) {
2096            // ES3 added swizzle support but not GL_TEXTURE_SWIZZLE_RGBA.
2097            const GrGLenum* swizzle = newTexParams.fSwizzleRGBA;
2098            GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, GR_GL_TEXTURE_SWIZZLE_R, swizzle[0]));
2099            GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, GR_GL_TEXTURE_SWIZZLE_G, swizzle[1]));
2100            GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, GR_GL_TEXTURE_SWIZZLE_B, swizzle[2]));
2101            GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, GR_GL_TEXTURE_SWIZZLE_A, swizzle[3]));
2102        } else {
2103            GR_STATIC_ASSERT(sizeof(newTexParams.fSwizzleRGBA[0]) == sizeof(GrGLint));
2104            const GrGLint* swizzle = reinterpret_cast<const GrGLint*>(newTexParams.fSwizzleRGBA);
2105            GL_CALL(TexParameteriv(GR_GL_TEXTURE_2D, GR_GL_TEXTURE_SWIZZLE_RGBA, swizzle));
2106        }
2107    }
2108    texture->setCachedTexParams(newTexParams, this->getResetTimestamp());
2109}
2110
2111void GrGpuGL::flushMiscFixedFunctionState(const GrOptDrawState& optState) {
2112    if (optState.isDitherState()) {
2113        if (kYes_TriState != fHWDitherEnabled) {
2114            GL_CALL(Enable(GR_GL_DITHER));
2115            fHWDitherEnabled = kYes_TriState;
2116        }
2117    } else {
2118        if (kNo_TriState != fHWDitherEnabled) {
2119            GL_CALL(Disable(GR_GL_DITHER));
2120            fHWDitherEnabled = kNo_TriState;
2121        }
2122    }
2123
2124    if (optState.isColorWriteDisabled()) {
2125        if (kNo_TriState != fHWWriteToColor) {
2126            GL_CALL(ColorMask(GR_GL_FALSE, GR_GL_FALSE,
2127                              GR_GL_FALSE, GR_GL_FALSE));
2128            fHWWriteToColor = kNo_TriState;
2129        }
2130    } else {
2131        if (kYes_TriState != fHWWriteToColor) {
2132            GL_CALL(ColorMask(GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE));
2133            fHWWriteToColor = kYes_TriState;
2134        }
2135    }
2136
2137    if (fHWDrawFace != optState.getDrawFace()) {
2138        switch (optState.getDrawFace()) {
2139            case GrDrawState::kCCW_DrawFace:
2140                GL_CALL(Enable(GR_GL_CULL_FACE));
2141                GL_CALL(CullFace(GR_GL_BACK));
2142                break;
2143            case GrDrawState::kCW_DrawFace:
2144                GL_CALL(Enable(GR_GL_CULL_FACE));
2145                GL_CALL(CullFace(GR_GL_FRONT));
2146                break;
2147            case GrDrawState::kBoth_DrawFace:
2148                GL_CALL(Disable(GR_GL_CULL_FACE));
2149                break;
2150            default:
2151                SkFAIL("Unknown draw face.");
2152        }
2153        fHWDrawFace = optState.getDrawFace();
2154    }
2155}
2156
2157bool GrGpuGL::configToGLFormats(GrPixelConfig config,
2158                                bool getSizedInternalFormat,
2159                                GrGLenum* internalFormat,
2160                                GrGLenum* externalFormat,
2161                                GrGLenum* externalType) {
2162    GrGLenum dontCare;
2163    if (NULL == internalFormat) {
2164        internalFormat = &dontCare;
2165    }
2166    if (NULL == externalFormat) {
2167        externalFormat = &dontCare;
2168    }
2169    if (NULL == externalType) {
2170        externalType = &dontCare;
2171    }
2172
2173    if(!this->glCaps().isConfigTexturable(config)) {
2174        return false;
2175    }
2176
2177    switch (config) {
2178        case kRGBA_8888_GrPixelConfig:
2179            *internalFormat = GR_GL_RGBA;
2180            *externalFormat = GR_GL_RGBA;
2181            if (getSizedInternalFormat) {
2182                *internalFormat = GR_GL_RGBA8;
2183            } else {
2184                *internalFormat = GR_GL_RGBA;
2185            }
2186            *externalType = GR_GL_UNSIGNED_BYTE;
2187            break;
2188        case kBGRA_8888_GrPixelConfig:
2189            if (this->glCaps().bgraIsInternalFormat()) {
2190                if (getSizedInternalFormat) {
2191                    *internalFormat = GR_GL_BGRA8;
2192                } else {
2193                    *internalFormat = GR_GL_BGRA;
2194                }
2195            } else {
2196                if (getSizedInternalFormat) {
2197                    *internalFormat = GR_GL_RGBA8;
2198                } else {
2199                    *internalFormat = GR_GL_RGBA;
2200                }
2201            }
2202            *externalFormat = GR_GL_BGRA;
2203            *externalType = GR_GL_UNSIGNED_BYTE;
2204            break;
2205        case kRGB_565_GrPixelConfig:
2206            *internalFormat = GR_GL_RGB;
2207            *externalFormat = GR_GL_RGB;
2208            if (getSizedInternalFormat) {
2209                if (this->glStandard() == kGL_GrGLStandard) {
2210                    return false;
2211                } else {
2212                    *internalFormat = GR_GL_RGB565;
2213                }
2214            } else {
2215                *internalFormat = GR_GL_RGB;
2216            }
2217            *externalType = GR_GL_UNSIGNED_SHORT_5_6_5;
2218            break;
2219        case kRGBA_4444_GrPixelConfig:
2220            *internalFormat = GR_GL_RGBA;
2221            *externalFormat = GR_GL_RGBA;
2222            if (getSizedInternalFormat) {
2223                *internalFormat = GR_GL_RGBA4;
2224            } else {
2225                *internalFormat = GR_GL_RGBA;
2226            }
2227            *externalType = GR_GL_UNSIGNED_SHORT_4_4_4_4;
2228            break;
2229        case kIndex_8_GrPixelConfig:
2230            // no sized/unsized internal format distinction here
2231            *internalFormat = GR_GL_PALETTE8_RGBA8;
2232            break;
2233        case kAlpha_8_GrPixelConfig:
2234            if (this->glCaps().textureRedSupport()) {
2235                *internalFormat = GR_GL_RED;
2236                *externalFormat = GR_GL_RED;
2237                if (getSizedInternalFormat) {
2238                    *internalFormat = GR_GL_R8;
2239                } else {
2240                    *internalFormat = GR_GL_RED;
2241                }
2242                *externalType = GR_GL_UNSIGNED_BYTE;
2243            } else {
2244                *internalFormat = GR_GL_ALPHA;
2245                *externalFormat = GR_GL_ALPHA;
2246                if (getSizedInternalFormat) {
2247                    *internalFormat = GR_GL_ALPHA8;
2248                } else {
2249                    *internalFormat = GR_GL_ALPHA;
2250                }
2251                *externalType = GR_GL_UNSIGNED_BYTE;
2252            }
2253            break;
2254        case kETC1_GrPixelConfig:
2255            *internalFormat = GR_GL_COMPRESSED_RGB8_ETC1;
2256            break;
2257        case kLATC_GrPixelConfig:
2258            switch(this->glCaps().latcAlias()) {
2259                case GrGLCaps::kLATC_LATCAlias:
2260                    *internalFormat = GR_GL_COMPRESSED_LUMINANCE_LATC1;
2261                    break;
2262                case GrGLCaps::kRGTC_LATCAlias:
2263                    *internalFormat = GR_GL_COMPRESSED_RED_RGTC1;
2264                    break;
2265                case GrGLCaps::k3DC_LATCAlias:
2266                    *internalFormat = GR_GL_COMPRESSED_3DC_X;
2267                    break;
2268            }
2269            break;
2270        case kR11_EAC_GrPixelConfig:
2271            *internalFormat = GR_GL_COMPRESSED_R11;
2272            break;
2273
2274        case kASTC_12x12_GrPixelConfig:
2275            *internalFormat = GR_GL_COMPRESSED_RGBA_ASTC_12x12;
2276            break;
2277
2278        case kRGBA_float_GrPixelConfig:
2279            *internalFormat = GR_GL_RGBA32F;
2280            *externalFormat = GR_GL_RGBA;
2281            *externalType = GR_GL_FLOAT;
2282            break;
2283
2284        default:
2285            return false;
2286    }
2287    return true;
2288}
2289
2290void GrGpuGL::setTextureUnit(int unit) {
2291    SkASSERT(unit >= 0 && unit < fHWBoundTextureUniqueIDs.count());
2292    if (unit != fHWActiveTextureUnitIdx) {
2293        GL_CALL(ActiveTexture(GR_GL_TEXTURE0 + unit));
2294        fHWActiveTextureUnitIdx = unit;
2295    }
2296}
2297
2298void GrGpuGL::setScratchTextureUnit() {
2299    // Bind the last texture unit since it is the least likely to be used by GrGLProgram.
2300    int lastUnitIdx = fHWBoundTextureUniqueIDs.count() - 1;
2301    if (lastUnitIdx != fHWActiveTextureUnitIdx) {
2302        GL_CALL(ActiveTexture(GR_GL_TEXTURE0 + lastUnitIdx));
2303        fHWActiveTextureUnitIdx = lastUnitIdx;
2304    }
2305    // clear out the this field so that if a program does use this unit it will rebind the correct
2306    // texture.
2307    fHWBoundTextureUniqueIDs[lastUnitIdx] = SK_InvalidUniqueID;
2308}
2309
2310namespace {
2311// Determines whether glBlitFramebuffer could be used between src and dst.
2312inline bool can_blit_framebuffer(const GrSurface* dst,
2313                                 const GrSurface* src,
2314                                 const GrGpuGL* gpu,
2315                                 bool* wouldNeedTempFBO = NULL) {
2316    if (gpu->glCaps().isConfigRenderable(dst->config(), dst->desc().fSampleCnt > 0) &&
2317        gpu->glCaps().isConfigRenderable(src->config(), src->desc().fSampleCnt > 0) &&
2318        gpu->glCaps().usesMSAARenderBuffers()) {
2319        // ES3 doesn't allow framebuffer blits when the src has MSAA and the configs don't match
2320        // or the rects are not the same (not just the same size but have the same edges).
2321        if (GrGLCaps::kES_3_0_MSFBOType == gpu->glCaps().msFBOType() &&
2322            (src->desc().fSampleCnt > 0 || src->config() != dst->config())) {
2323           return false;
2324        }
2325        if (wouldNeedTempFBO) {
2326            *wouldNeedTempFBO = NULL == dst->asRenderTarget() || NULL == src->asRenderTarget();
2327        }
2328        return true;
2329    } else {
2330        return false;
2331    }
2332}
2333
2334inline bool can_copy_texsubimage(const GrSurface* dst,
2335                                 const GrSurface* src,
2336                                 const GrGpuGL* gpu,
2337                                 bool* wouldNeedTempFBO = NULL) {
2338    // Table 3.9 of the ES2 spec indicates the supported formats with CopyTexSubImage
2339    // and BGRA isn't in the spec. There doesn't appear to be any extension that adds it. Perhaps
2340    // many drivers would allow it to work, but ANGLE does not.
2341    if (kGLES_GrGLStandard == gpu->glStandard() && gpu->glCaps().bgraIsInternalFormat() &&
2342        (kBGRA_8888_GrPixelConfig == dst->config() || kBGRA_8888_GrPixelConfig == src->config())) {
2343        return false;
2344    }
2345    const GrGLRenderTarget* dstRT = static_cast<const GrGLRenderTarget*>(dst->asRenderTarget());
2346    // If dst is multisampled (and uses an extension where there is a separate MSAA renderbuffer)
2347    // then we don't want to copy to the texture but to the MSAA buffer.
2348    if (dstRT && dstRT->renderFBOID() != dstRT->textureFBOID()) {
2349        return false;
2350    }
2351    const GrGLRenderTarget* srcRT = static_cast<const GrGLRenderTarget*>(src->asRenderTarget());
2352    // If the src is multisampled (and uses an extension where there is a separate MSAA
2353    // renderbuffer) then it is an invalid operation to call CopyTexSubImage
2354    if (srcRT && srcRT->renderFBOID() != srcRT->textureFBOID()) {
2355        return false;
2356    }
2357    if (gpu->glCaps().isConfigRenderable(src->config(), src->desc().fSampleCnt > 0) &&
2358        dst->asTexture() &&
2359        dst->origin() == src->origin() &&
2360        !GrPixelConfigIsCompressed(src->config())) {
2361        if (wouldNeedTempFBO) {
2362            *wouldNeedTempFBO = NULL == src->asRenderTarget();
2363        }
2364        return true;
2365    } else {
2366        return false;
2367    }
2368}
2369
2370}
2371
2372// If a temporary FBO was created, its non-zero ID is returned. The viewport that the copy rect is
2373// relative to is output.
2374GrGLuint GrGpuGL::bindSurfaceAsFBO(GrSurface* surface, GrGLenum fboTarget, GrGLIRect* viewport) {
2375    GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(surface->asRenderTarget());
2376    GrGLuint tempFBOID;
2377    if (NULL == rt) {
2378        SkASSERT(surface->asTexture());
2379        GrGLuint texID = static_cast<GrGLTexture*>(surface->asTexture())->textureID();
2380        GR_GL_CALL(this->glInterface(), GenFramebuffers(1, &tempFBOID));
2381        fGPUStats.incRenderTargetBinds();
2382        GR_GL_CALL(this->glInterface(), BindFramebuffer(fboTarget, tempFBOID));
2383        GR_GL_CALL(this->glInterface(), FramebufferTexture2D(fboTarget,
2384                                                             GR_GL_COLOR_ATTACHMENT0,
2385                                                             GR_GL_TEXTURE_2D,
2386                                                             texID,
2387                                                             0));
2388        viewport->fLeft = 0;
2389        viewport->fBottom = 0;
2390        viewport->fWidth = surface->width();
2391        viewport->fHeight = surface->height();
2392    } else {
2393        tempFBOID = 0;
2394        fGPUStats.incRenderTargetBinds();
2395        GR_GL_CALL(this->glInterface(), BindFramebuffer(fboTarget, rt->renderFBOID()));
2396        *viewport = rt->getViewport();
2397    }
2398    return tempFBOID;
2399}
2400
2401void GrGpuGL::initCopySurfaceDstDesc(const GrSurface* src, GrTextureDesc* desc) {
2402    // Check for format issues with glCopyTexSubImage2D
2403    if (kGLES_GrGLStandard == this->glStandard() && this->glCaps().bgraIsInternalFormat() &&
2404        kBGRA_8888_GrPixelConfig == src->config()) {
2405        // glCopyTexSubImage2D doesn't work with this config. We'll want to make it a render target
2406        // in order to call glBlitFramebuffer or to copy to it by rendering.
2407        INHERITED::initCopySurfaceDstDesc(src, desc);
2408        return;
2409    } else if (NULL == src->asRenderTarget()) {
2410        // We don't want to have to create an FBO just to use glCopyTexSubImage2D. Let the base
2411        // class handle it by rendering.
2412        INHERITED::initCopySurfaceDstDesc(src, desc);
2413        return;
2414    }
2415
2416    const GrGLRenderTarget* srcRT = static_cast<const GrGLRenderTarget*>(src->asRenderTarget());
2417    if (srcRT && srcRT->renderFBOID() != srcRT->textureFBOID()) {
2418        // It's illegal to call CopyTexSubImage2D on a MSAA renderbuffer.
2419        INHERITED::initCopySurfaceDstDesc(src, desc);
2420    } else {
2421        desc->fConfig = src->config();
2422        desc->fOrigin = src->origin();
2423        desc->fFlags = kNone_GrTextureFlags;
2424    }
2425}
2426
2427bool GrGpuGL::onCopySurface(GrSurface* dst,
2428                            GrSurface* src,
2429                            const SkIRect& srcRect,
2430                            const SkIPoint& dstPoint) {
2431    bool inheritedCouldCopy = INHERITED::onCanCopySurface(dst, src, srcRect, dstPoint);
2432    bool copied = false;
2433    bool wouldNeedTempFBO = false;
2434    if (can_copy_texsubimage(dst, src, this, &wouldNeedTempFBO) &&
2435        (!wouldNeedTempFBO || !inheritedCouldCopy)) {
2436        GrGLuint srcFBO;
2437        GrGLIRect srcVP;
2438        srcFBO = this->bindSurfaceAsFBO(src, GR_GL_FRAMEBUFFER, &srcVP);
2439        GrGLTexture* dstTex = static_cast<GrGLTexture*>(dst->asTexture());
2440        SkASSERT(dstTex);
2441        // We modified the bound FBO
2442        fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID;
2443        GrGLIRect srcGLRect;
2444        srcGLRect.setRelativeTo(srcVP,
2445                                srcRect.fLeft,
2446                                srcRect.fTop,
2447                                srcRect.width(),
2448                                srcRect.height(),
2449                                src->origin());
2450
2451        this->setScratchTextureUnit();
2452        GL_CALL(BindTexture(GR_GL_TEXTURE_2D, dstTex->textureID()));
2453        GrGLint dstY;
2454        if (kBottomLeft_GrSurfaceOrigin == dst->origin()) {
2455            dstY = dst->height() - (dstPoint.fY + srcGLRect.fHeight);
2456        } else {
2457            dstY = dstPoint.fY;
2458        }
2459        GL_CALL(CopyTexSubImage2D(GR_GL_TEXTURE_2D, 0,
2460                                  dstPoint.fX, dstY,
2461                                  srcGLRect.fLeft, srcGLRect.fBottom,
2462                                  srcGLRect.fWidth, srcGLRect.fHeight));
2463        copied = true;
2464        if (srcFBO) {
2465            GL_CALL(DeleteFramebuffers(1, &srcFBO));
2466        }
2467    } else if (can_blit_framebuffer(dst, src, this, &wouldNeedTempFBO) &&
2468               (!wouldNeedTempFBO || !inheritedCouldCopy)) {
2469        SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.fX, dstPoint.fY,
2470                                            srcRect.width(), srcRect.height());
2471        bool selfOverlap = false;
2472        if (dst->isSameAs(src)) {
2473            selfOverlap = SkIRect::IntersectsNoEmptyCheck(dstRect, srcRect);
2474        }
2475
2476        if (!selfOverlap) {
2477            GrGLuint dstFBO;
2478            GrGLuint srcFBO;
2479            GrGLIRect dstVP;
2480            GrGLIRect srcVP;
2481            dstFBO = this->bindSurfaceAsFBO(dst, GR_GL_DRAW_FRAMEBUFFER, &dstVP);
2482            srcFBO = this->bindSurfaceAsFBO(src, GR_GL_READ_FRAMEBUFFER, &srcVP);
2483            // We modified the bound FBO
2484            fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID;
2485            GrGLIRect srcGLRect;
2486            GrGLIRect dstGLRect;
2487            srcGLRect.setRelativeTo(srcVP,
2488                                    srcRect.fLeft,
2489                                    srcRect.fTop,
2490                                    srcRect.width(),
2491                                    srcRect.height(),
2492                                    src->origin());
2493            dstGLRect.setRelativeTo(dstVP,
2494                                    dstRect.fLeft,
2495                                    dstRect.fTop,
2496                                    dstRect.width(),
2497                                    dstRect.height(),
2498                                    dst->origin());
2499
2500            GrAutoTRestore<ScissorState> asr;
2501            // BlitFrameBuffer respects the scissor, so disable it.
2502            asr.reset(&fScissorState);
2503            fScissorState.fEnabled = false;
2504            this->flushScissor(dstGLRect, dst->origin());
2505
2506            GrGLint srcY0;
2507            GrGLint srcY1;
2508            // Does the blit need to y-mirror or not?
2509            if (src->origin() == dst->origin()) {
2510                srcY0 = srcGLRect.fBottom;
2511                srcY1 = srcGLRect.fBottom + srcGLRect.fHeight;
2512            } else {
2513                srcY0 = srcGLRect.fBottom + srcGLRect.fHeight;
2514                srcY1 = srcGLRect.fBottom;
2515            }
2516            GL_CALL(BlitFramebuffer(srcGLRect.fLeft,
2517                                    srcY0,
2518                                    srcGLRect.fLeft + srcGLRect.fWidth,
2519                                    srcY1,
2520                                    dstGLRect.fLeft,
2521                                    dstGLRect.fBottom,
2522                                    dstGLRect.fLeft + dstGLRect.fWidth,
2523                                    dstGLRect.fBottom + dstGLRect.fHeight,
2524                                    GR_GL_COLOR_BUFFER_BIT, GR_GL_NEAREST));
2525            if (dstFBO) {
2526                GL_CALL(DeleteFramebuffers(1, &dstFBO));
2527            }
2528            if (srcFBO) {
2529                GL_CALL(DeleteFramebuffers(1, &srcFBO));
2530            }
2531            copied = true;
2532        }
2533    }
2534    if (!copied && inheritedCouldCopy) {
2535        copied = INHERITED::onCopySurface(dst, src, srcRect, dstPoint);
2536        SkASSERT(copied);
2537    }
2538    return copied;
2539}
2540
2541bool GrGpuGL::onCanCopySurface(GrSurface* dst,
2542                               GrSurface* src,
2543                               const SkIRect& srcRect,
2544                               const SkIPoint& dstPoint) {
2545    // This mirrors the logic in onCopySurface.
2546    if (can_copy_texsubimage(dst, src, this)) {
2547        return true;
2548    }
2549    if (can_blit_framebuffer(dst, src, this)) {
2550        if (dst->isSameAs(src)) {
2551            SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.fX, dstPoint.fY,
2552                                                srcRect.width(), srcRect.height());
2553            if(!SkIRect::IntersectsNoEmptyCheck(dstRect, srcRect)) {
2554                return true;
2555            }
2556        } else {
2557            return true;
2558        }
2559    }
2560    return INHERITED::onCanCopySurface(dst, src, srcRect, dstPoint);
2561}
2562
2563void GrGpuGL::didAddGpuTraceMarker() {
2564    if (this->caps()->gpuTracingSupport()) {
2565        const GrTraceMarkerSet& markerArray = this->getActiveTraceMarkers();
2566        SkString markerString = markerArray.toStringLast();
2567        GL_CALL(PushGroupMarker(0, markerString.c_str()));
2568    }
2569}
2570
2571void GrGpuGL::didRemoveGpuTraceMarker() {
2572    if (this->caps()->gpuTracingSupport()) {
2573        GL_CALL(PopGroupMarker());
2574    }
2575}
2576///////////////////////////////////////////////////////////////////////////////
2577
2578GrGLAttribArrayState* GrGpuGL::HWGeometryState::bindArrayAndBuffersToDraw(
2579                                                GrGpuGL* gpu,
2580                                                const GrGLVertexBuffer* vbuffer,
2581                                                const GrGLIndexBuffer* ibuffer) {
2582    SkASSERT(vbuffer);
2583    GrGLAttribArrayState* attribState;
2584
2585    // We use a vertex array if we're on a core profile and the verts are in a VBO.
2586    if (gpu->glCaps().isCoreProfile() && !vbuffer->isCPUBacked()) {
2587        if (NULL == fVBOVertexArray || fVBOVertexArray->wasDestroyed()) {
2588            SkSafeUnref(fVBOVertexArray);
2589            GrGLuint arrayID;
2590            GR_GL_CALL(gpu->glInterface(), GenVertexArrays(1, &arrayID));
2591            int attrCount = gpu->glCaps().maxVertexAttributes();
2592            fVBOVertexArray = SkNEW_ARGS(GrGLVertexArray, (gpu, arrayID, attrCount));
2593        }
2594        attribState = fVBOVertexArray->bindWithIndexBuffer(ibuffer);
2595    } else {
2596        if (ibuffer) {
2597            this->setIndexBufferIDOnDefaultVertexArray(gpu, ibuffer->bufferID());
2598        } else {
2599            this->setVertexArrayID(gpu, 0);
2600        }
2601        int attrCount = gpu->glCaps().maxVertexAttributes();
2602        if (fDefaultVertexArrayAttribState.count() != attrCount) {
2603            fDefaultVertexArrayAttribState.resize(attrCount);
2604        }
2605        attribState = &fDefaultVertexArrayAttribState;
2606    }
2607    return attribState;
2608}
2609