Revert of Move copy-surface-as-draw fallback to GrGLGpu. (patchset #12 id:220001...
authormtklein <mtklein@google.com>
Mon, 18 May 2015 16:29:10 +0000 (09:29 -0700)
committerCommit bot <commit-bot@chromium.org>
Mon, 18 May 2015 16:29:10 +0000 (09:29 -0700)
Reason for revert:
Many GMs changed, some totally busted.

Original issue's description:
> Move copy-surface-as-draw fallback to GrGLGpu.
>
> Committed: https://skia.googlesource.com/skia/+/5df6fee929823f50c55cc50f7c882a309c1b1de9

TBR=joshualitt@google.com,egdaniel@google.com,bsalomon@google.com
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true

Review URL: https://codereview.chromium.org/1142003003

17 files changed:
src/gpu/GrDrawTarget.cpp
src/gpu/GrDrawTarget.h
src/gpu/GrGpu.h
src/gpu/GrInOrderDrawBuffer.cpp
src/gpu/GrTest.cpp
src/gpu/gl/GrGLCaps.cpp
src/gpu/gl/GrGLCaps.h
src/gpu/gl/GrGLGpu.cpp
src/gpu/gl/GrGLGpu.h
src/gpu/gl/GrGLGpuProgramCache.cpp
src/gpu/gl/GrGLSL.cpp
src/gpu/gl/GrGLSL.h
src/gpu/gl/GrGLVertexArray.cpp
src/gpu/gl/GrGLVertexArray.h
src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp
src/gpu/gl/builders/GrGLProgramBuilder.cpp
src/gpu/gl/builders/GrGLShaderBuilder.cpp

index 7565cd1df865aaeca1ce55d479de2a3ef8b449e1..549ab374c8f71940f77b5a003a69b575b14c4972 100644 (file)
@@ -100,10 +100,13 @@ bool GrDrawTarget::setupDstReadIfNecessary(const GrPipelineBuilder& pipelineBuil
         return false;
     }
     SkIPoint dstPoint = {0, 0};
-    this->copySurface(copy, rt, copyRect, dstPoint);
-    dstCopy->setTexture(copy);
-    dstCopy->setOffset(copyRect.fLeft, copyRect.fTop);
-    return true;
+    if (this->copySurface(copy, rt, copyRect, dstPoint)) {
+        dstCopy->setTexture(copy);
+        dstCopy->setOffset(copyRect.fLeft, copyRect.fTop);
+        return true;
+    } else {
+        return false;
+    }
 }
 
 void GrDrawTarget::flush() {
@@ -418,7 +421,7 @@ bool clip_srcrect_and_dstpoint(const GrSurface* dst,
 }
 }
 
-void GrDrawTarget::copySurface(GrSurface* dst,
+bool GrDrawTarget::copySurface(GrSurface* dst,
                                GrSurface* src,
                                const SkIRect& srcRect,
                                const SkIPoint& dstPoint) {
@@ -434,10 +437,56 @@ void GrDrawTarget::copySurface(GrSurface* dst,
                                    dstPoint,
                                    &clippedSrcRect,
                                    &clippedDstPoint)) {
-        return;
+        return true;
     }
 
-    this->onCopySurface(dst, src, clippedSrcRect, clippedDstPoint);
+    if (this->getGpu()->canCopySurface(dst, src, clippedSrcRect, clippedDstPoint)) {
+        this->onCopySurface(dst, src, clippedSrcRect, clippedDstPoint);
+        return true;
+    }
+
+    GrRenderTarget* rt = dst->asRenderTarget();
+    GrTexture* tex = src->asTexture();
+
+    if ((dst == src) || !rt || !tex) {
+        return false;
+    }
+
+    GrPipelineBuilder pipelineBuilder;
+    pipelineBuilder.setRenderTarget(rt);
+    SkMatrix matrix;
+    matrix.setTranslate(SkIntToScalar(clippedSrcRect.fLeft - clippedDstPoint.fX),
+                        SkIntToScalar(clippedSrcRect.fTop - clippedDstPoint.fY));
+    matrix.postIDiv(tex->width(), tex->height());
+    pipelineBuilder.addColorTextureProcessor(tex, matrix);
+    SkIRect dstRect = SkIRect::MakeXYWH(clippedDstPoint.fX,
+                                        clippedDstPoint.fY,
+                                        clippedSrcRect.width(),
+                                        clippedSrcRect.height());
+    this->drawSimpleRect(&pipelineBuilder, GrColor_WHITE, SkMatrix::I(), dstRect);
+    return true;
+}
+
+bool GrDrawTarget::canCopySurface(const GrSurface* dst,
+                                  const GrSurface* src,
+                                  const SkIRect& srcRect,
+                                  const SkIPoint& dstPoint) {
+    SkASSERT(dst);
+    SkASSERT(src);
+
+    SkIRect clippedSrcRect;
+    SkIPoint clippedDstPoint;
+    // If the rect is outside the src or dst then we're guaranteed success
+    if (!clip_srcrect_and_dstpoint(dst,
+                                   src,
+                                   srcRect,
+                                   dstPoint,
+                                   &clippedSrcRect,
+                                   &clippedDstPoint)) {
+        return true;
+    }
+    return ((dst != src) && dst->asRenderTarget() && src->asTexture()) ||
+           this->getGpu()->canCopySurface(dst, src, clippedSrcRect, clippedDstPoint);
 }
 
 void GrDrawTarget::setupPipeline(const PipelineInfo& pipelineInfo,
index 0157354f88ec02891ca476f08f64f2b534d030a0..84f7eb2197a4aa736aabba9847b9ba5b08ab5518 100644 (file)
@@ -178,14 +178,24 @@ public:
      * copied are specified by srcRect. They are copied to a rect of the same
      * size in dst with top left at dstPoint. If the src rect is clipped by the
      * src bounds then  pixel values in the dst rect corresponding to area clipped
-     * by the src rect are not overwritten. This method is not guaranteed to succeed
+     * by the src rect are not overwritten. This method can fail and return false
      * depending on the type of surface, configs, etc, and the backend-specific
-     * limitations.
+     * limitations. If rect is clipped out entirely by the src or dst bounds then
+     * true is returned since there is no actual copy necessary to succeed.
      */
-    void copySurface(GrSurface* dst,
+    bool copySurface(GrSurface* dst,
                      GrSurface* src,
                      const SkIRect& srcRect,
                      const SkIPoint& dstPoint);
+    /**
+     * Function that determines whether a copySurface call would succeed without actually
+     * performing the copy.
+     */
+    bool canCopySurface(const GrSurface* dst,
+                        const GrSurface* src,
+                        const SkIRect& srcRect,
+                        const SkIPoint& dstPoint);
+
     /**
      * Release any resources that are cached but not currently in use. This
      * is intended to give an application some recourse when resources are low.
index e8d493930490c07dc28fdc2dc7093cc677fa51c6..f2ad10f41714c6faf9beb947eed234025b20677e 100644 (file)
@@ -257,6 +257,16 @@ public:
                                   const GrPipeline&,
                                   const GrBatchTracker&) const = 0;
 
+    // Called to determine whether a copySurface call would succeed or not. Derived
+    // classes must keep this consistent with their implementation of onCopySurface(). Fallbacks
+    // to issuing a draw from the src to dst take place at the GrDrawTarget level and this function
+    // should only return true if a faster copy path exists. The rect and point are pre-clipped. The
+    // src rect and implied dst rect are guaranteed to be within the src/dst bounds and non-empty.
+    virtual bool canCopySurface(const GrSurface* dst,
+                                const GrSurface* src,
+                                const SkIRect& srcRect,
+                                const SkIPoint& dstPoint) = 0;
+
     // Called to perform a surface to surface copy. Fallbacks to issuing a draw from the src to dst
     // take place at the GrDrawTarget level and this function implement faster copy paths. The rect
     // and point are pre-clipped. The src rect and implied dst rect are guaranteed to be within the
index 8cc365841f1a71c5fbea229b564e24b61b40c026..6b6490c7eaea5ff33bc57c2851690e1120054a8f 100644 (file)
@@ -121,6 +121,7 @@ void GrInOrderDrawBuffer::onCopySurface(GrSurface* dst,
                                         GrSurface* src,
                                         const SkIRect& srcRect,
                                         const SkIPoint& dstPoint) {
+    SkASSERT(this->getGpu()->canCopySurface(dst, src, srcRect, dstPoint));
     GrTargetCommands::Cmd* cmd = fCommands->recordCopySurface(dst, src, srcRect, dstPoint);
     this->recordTraceMarkersIfNecessary(cmd);
 }
index 6504acf38d3da63865a65acdf0510a4009c395aa..0b3d030cdb61244d061c6da745b01a9295f74e1e 100644 (file)
@@ -155,6 +155,11 @@ public:
 
     void discard(GrRenderTarget*) override {}
 
+    bool canCopySurface(const GrSurface* dst,
+                        const GrSurface* src,
+                        const SkIRect& srcRect,
+                        const SkIPoint& dstPoint) override { return false; };
+
     bool copySurface(GrSurface* dst,
                      GrSurface* src,
                      const SkIRect& srcRect,
index 5ee75460cf1664476d1c1e0a78260839c95692df..06ebe3d34d0890468870cd1245f643a9220df16c 100644 (file)
@@ -942,7 +942,6 @@ GrGLSLCaps::GrGLSLCaps(const GrGLSLCaps& caps) : GrShaderCaps() {
 
 GrGLSLCaps& GrGLSLCaps::operator= (const GrGLSLCaps& caps) {
     INHERITED::operator=(caps);
-    fGLSLGeneration = caps.fGLSLGeneration;
     fDropsTileOnZeroDivide = caps.fDropsTileOnZeroDivide;
     fFBFetchSupport = caps.fFBFetchSupport;
     fFBFetchNeedsCustomOutput = caps.fFBFetchNeedsCustomOutput;
@@ -961,8 +960,6 @@ bool GrGLSLCaps::init(const GrGLContextInfo& ctxInfo,
         return false;
     }
 
-    fGLSLGeneration = ctxInfo.glslGeneration();
-    
     GrGLStandard standard = ctxInfo.standard();
     GrGLVersion version = ctxInfo.version();
 
index dfc6233b6bc2a849b0d046cbb1eed14eb1d7c0ed..25c7889b973c183f4d8c2ec6183ded5415cc9da9 100644 (file)
@@ -374,7 +374,6 @@ private:
     typedef GrDrawTargetCaps INHERITED;
 };
 
-#include "GrGLSL.h"
 
 class GrGLSLCaps : public GrShaderCaps {
 public:
@@ -439,12 +438,6 @@ public:
     bool mustEnableSpecificAdvBlendEqs() const {
         return fAdvBlendEqInteraction == kSpecificEnables_AdvBlendEqInteraction;
     }
-    
-    bool mustDeclareFragmentShaderOutput() const {
-        return fGLSLGeneration > k110_GrGLSLGeneration;
-    }
-
-    GrGLSLGeneration generation() const { return fGLSLGeneration; }
 
     /**
     * Returns a string containing the caps info.
@@ -455,8 +448,6 @@ private:
     // Must be called after fGeometryShaderSupport is initialized.
     void initShaderPrecisionTable(const GrGLContextInfo&, const GrGLInterface*);
 
-    GrGLSLGeneration fGLSLGeneration;
-    
     bool fDropsTileOnZeroDivide : 1;
     bool fFBFetchSupport : 1;
     bool fFBFetchNeedsCustomOutput : 1;
index 56b3d42c4fabd05878b6edf03dd0fcba91d50482..6d97804fc65ffa52ddf350c58cd9d6f2b0232723 100644 (file)
@@ -17,7 +17,6 @@
 #include "GrTexturePriv.h"
 #include "GrTypes.h"
 #include "GrVertices.h"
-#include "builders/GrGLShaderStringBuilder.h"
 #include "SkStrokeRec.h"
 #include "SkTemplates.h"
 
@@ -201,14 +200,13 @@ GrGLGpu::GrGLGpu(const GrGLContext& ctx, GrContext* context)
     if (this->glCaps().shaderCaps()->pathRenderingSupport()) {
         fPathRendering.reset(new GrGLPathRendering(this));
     }
-
-    this->createCopyProgram();
 }
 
 GrGLGpu::~GrGLGpu() {
     if (0 != fHWProgramID) {
         // detach the current program so there is no confusion on OpenGL's part
         // that we want it to be deleted
+        SkASSERT(fHWProgramID == fCurrentProgram->programID());
         GL_CALL(UseProgram(0));
     }
 
@@ -222,14 +220,6 @@ GrGLGpu::~GrGLGpu() {
         GL_CALL(DeleteFramebuffers(1, &fStencilClearFBOID));
     }
 
-    if (0 != fCopyProgram.fArrayBuffer) {
-        GL_CALL(DeleteBuffers(1, &fCopyProgram.fArrayBuffer));
-    }
-
-    if (0 != fCopyProgram.fProgram) {
-        GL_CALL(DeleteProgram(fCopyProgram.fProgram));
-    }
-
     delete fProgramCache;
 }
 
@@ -240,8 +230,6 @@ void GrGLGpu::contextAbandoned() {
     fTempSrcFBOID = 0;
     fTempDstFBOID = 0;
     fStencilClearFBOID = 0;
-    fCopyProgram.fArrayBuffer = 0;
-    fCopyProgram.fProgram = 0;
     if (this->glCaps().shaderCaps()->pathRenderingSupport()) {
         this->glPathRendering()->abandonGpuResources();
     }
@@ -1429,13 +1417,15 @@ bool GrGLGpu::flushGLState(const DrawArgs& args) {
     this->flushColorWrite(blendInfo.fWriteColor);
     this->flushDrawFace(pipeline.getDrawFace());
 
-    SkAutoTUnref<GrGLProgram> program(fProgramCache->refProgram(args));
-    if (!program) {
+    fCurrentProgram.reset(fProgramCache->getProgram(args));
+    if (NULL == fCurrentProgram.get()) {
         GrContextDebugf(this->getContext(), "Failed to create program!\n");
         return false;
     }
 
-    GrGLuint programID = program->programID();
+    fCurrentProgram.get()->ref();
+
+    GrGLuint programID = fCurrentProgram->programID();
     if (fHWProgramID != programID) {
         GL_CALL(UseProgram(programID));
         fHWProgramID = programID;
@@ -1445,7 +1435,7 @@ bool GrGLGpu::flushGLState(const DrawArgs& args) {
         this->flushBlend(blendInfo);
     }
 
-    program->setData(*args.fPrimitiveProcessor, pipeline, *args.fBatchTracker);
+    fCurrentProgram->setData(*args.fPrimitiveProcessor, pipeline, *args.fBatchTracker);
 
     GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(pipeline.getRenderTarget());
     this->flushStencil(pipeline.getStencil());
@@ -1500,7 +1490,7 @@ void GrGLGpu::setupGeometry(const GrPrimitiveProcessor& primProc,
             GrVertexAttribType attribType = attrib.fType;
             attribState->set(this,
                              attribIndex,
-                             vbuf->bufferID(),
+                             vbuf,
                              GrGLAttribTypeToLayout(attribType).fCount,
                              GrGLAttribTypeToLayout(attribType).fType,
                              GrGLAttribTypeToLayout(attribType).fNormalized,
@@ -2628,16 +2618,7 @@ void GrGLGpu::unbindTextureFromFBO(GrGLenum fboTarget) {
 }
 
 bool GrGLGpu::initCopySurfaceDstDesc(const GrSurface* src, GrSurfaceDesc* desc) {
-    // If the src is a texture, we can implement the blit as a draw assuming the config is
-    // renderable.
-    if (src->asTexture() && this->caps()->isConfigRenderable(src->config(), false)) {
-        desc->fOrigin = kDefault_GrSurfaceOrigin;
-        desc->fFlags = kRenderTarget_GrSurfaceFlag;
-        desc->fConfig = src->config();
-        return true;
-    }
-
-    // We look for opportunities to use CopyTexSubImage, or fbo blit. If neither are
+    // In here we look for opportunities to use CopyTexSubImage, or fbo blit. If neither are
     // possible and we return false to fallback to creating a render target dst for render-to-
     // texture. This code prefers CopyTexSubImage to fbo blit and avoids triggering temporary fbo
     // creation. It isn't clear that avoiding temporary fbo creation is actually optimal.
@@ -2683,295 +2664,127 @@ bool GrGLGpu::copySurface(GrSurface* dst,
                           GrSurface* src,
                           const SkIRect& srcRect,
                           const SkIPoint& dstPoint) {
-    if (src->asTexture() && dst->asRenderTarget()) {
-        this->copySurfaceAsDraw(dst, src, srcRect, dstPoint);
-        return true;
+    bool copied = false;
+    if (can_copy_texsubimage(dst, src, this)) {
+        GrGLuint srcFBO;
+        GrGLIRect srcVP;
+        srcFBO = this->bindSurfaceAsFBO(src, GR_GL_FRAMEBUFFER, &srcVP, kSrc_TempFBOTarget);
+        GrGLTexture* dstTex = static_cast<GrGLTexture*>(dst->asTexture());
+        SkASSERT(dstTex);
+        // We modified the bound FBO
+        fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID;
+        GrGLIRect srcGLRect;
+        srcGLRect.setRelativeTo(srcVP,
+                                srcRect.fLeft,
+                                srcRect.fTop,
+                                srcRect.width(),
+                                srcRect.height(),
+                                src->origin());
+
+        this->setScratchTextureUnit();
+        GL_CALL(BindTexture(GR_GL_TEXTURE_2D, dstTex->textureID()));
+        GrGLint dstY;
+        if (kBottomLeft_GrSurfaceOrigin == dst->origin()) {
+            dstY = dst->height() - (dstPoint.fY + srcGLRect.fHeight);
+        } else {
+            dstY = dstPoint.fY;
+        }
+        GL_CALL(CopyTexSubImage2D(GR_GL_TEXTURE_2D, 0,
+                                  dstPoint.fX, dstY,
+                                  srcGLRect.fLeft, srcGLRect.fBottom,
+                                  srcGLRect.fWidth, srcGLRect.fHeight));
+        copied = true;
+        if (srcFBO) {
+            this->unbindTextureFromFBO(GR_GL_FRAMEBUFFER);
+        }
+    } else if (can_blit_framebuffer(dst, src, this)) {
+        SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.fX, dstPoint.fY,
+                                            srcRect.width(), srcRect.height());
+        bool selfOverlap = false;
+        if (dst == src) {
+            selfOverlap = SkIRect::IntersectsNoEmptyCheck(dstRect, srcRect);
+        }
+
+        if (!selfOverlap) {
+            GrGLuint dstFBO;
+            GrGLuint srcFBO;
+            GrGLIRect dstVP;
+            GrGLIRect srcVP;
+            dstFBO = this->bindSurfaceAsFBO(dst, GR_GL_DRAW_FRAMEBUFFER, &dstVP,
+                                            kDst_TempFBOTarget);
+            srcFBO = this->bindSurfaceAsFBO(src, GR_GL_READ_FRAMEBUFFER, &srcVP,
+                                            kSrc_TempFBOTarget);
+            // We modified the bound FBO
+            fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID;
+            GrGLIRect srcGLRect;
+            GrGLIRect dstGLRect;
+            srcGLRect.setRelativeTo(srcVP,
+                                    srcRect.fLeft,
+                                    srcRect.fTop,
+                                    srcRect.width(),
+                                    srcRect.height(),
+                                    src->origin());
+            dstGLRect.setRelativeTo(dstVP,
+                                    dstRect.fLeft,
+                                    dstRect.fTop,
+                                    dstRect.width(),
+                                    dstRect.height(),
+                                    dst->origin());
+
+            // BlitFrameBuffer respects the scissor, so disable it.
+            this->disableScissor();
+
+            GrGLint srcY0;
+            GrGLint srcY1;
+            // Does the blit need to y-mirror or not?
+            if (src->origin() == dst->origin()) {
+                srcY0 = srcGLRect.fBottom;
+                srcY1 = srcGLRect.fBottom + srcGLRect.fHeight;
+            } else {
+                srcY0 = srcGLRect.fBottom + srcGLRect.fHeight;
+                srcY1 = srcGLRect.fBottom;
+            }
+            GL_CALL(BlitFramebuffer(srcGLRect.fLeft,
+                                    srcY0,
+                                    srcGLRect.fLeft + srcGLRect.fWidth,
+                                    srcY1,
+                                    dstGLRect.fLeft,
+                                    dstGLRect.fBottom,
+                                    dstGLRect.fLeft + dstGLRect.fWidth,
+                                    dstGLRect.fBottom + dstGLRect.fHeight,
+                                    GR_GL_COLOR_BUFFER_BIT, GR_GL_NEAREST));
+            if (dstFBO) {
+                this->unbindTextureFromFBO(GR_GL_DRAW_FRAMEBUFFER);
+            }
+            if (srcFBO) {
+                this->unbindTextureFromFBO(GR_GL_READ_FRAMEBUFFER);
+            }
+            copied = true;
+        }
     }
-    
+    return copied;
+}
+
+bool GrGLGpu::canCopySurface(const GrSurface* dst,
+                             const GrSurface* src,
+                             const SkIRect& srcRect,
+                             const SkIPoint& dstPoint) {
+    // This mirrors the logic in onCopySurface.
     if (can_copy_texsubimage(dst, src, this)) {
-        this->copySurfaceAsCopyTexSubImage(dst, src, srcRect, dstPoint);
         return true;
     }
-
     if (can_blit_framebuffer(dst, src, this)) {
-        return this->copySurfaceAsBlitFramebuffer(dst, src, srcRect, dstPoint);
-    }
-
-    return false;
-}
-
-
-void GrGLGpu::createCopyProgram() {
-    const char* version = GrGetGLSLVersionDecl(this->ctxInfo());
-
-    GrGLShaderVar aVertex("a_vertex", kVec2f_GrSLType, GrShaderVar::kAttribute_TypeModifier);
-    GrGLShaderVar uTexCoordXform("u_texCoordXform", kVec4f_GrSLType,
-                                 GrShaderVar::kUniform_TypeModifier);
-    GrGLShaderVar uPosXform("u_posXform", kVec4f_GrSLType, GrShaderVar::kUniform_TypeModifier);
-    GrGLShaderVar uTexture("u_texture", kSampler2D_GrSLType, GrShaderVar::kUniform_TypeModifier);
-    GrGLShaderVar vTexCoord("v_texCoord", kVec2f_GrSLType, GrShaderVar::kVaryingOut_TypeModifier);
-    GrGLShaderVar oFragColor("o_FragColor", kVec4f_GrSLType, GrShaderVar::kOut_TypeModifier);
-    
-    SkString vshaderTxt(version);
-    aVertex.appendDecl(this->ctxInfo(), &vshaderTxt);
-    vshaderTxt.append(";");
-    uTexCoordXform.appendDecl(this->ctxInfo(), &vshaderTxt);
-    vshaderTxt.append(";");
-    uPosXform.appendDecl(this->ctxInfo(), &vshaderTxt);
-    vshaderTxt.append(";");
-    vTexCoord.appendDecl(this->ctxInfo(), &vshaderTxt);
-    vshaderTxt.append(";");
-    
-    vshaderTxt.append(
-        "// Copy Program VS\n"
-        "void main() {"
-        "  v_texCoord = a_vertex.xy * u_texCoordXform.xy + u_texCoordXform.zw;"
-        "  gl_Position.xy = a_vertex * u_posXform.xy + u_posXform.zw;"
-        "  gl_Position.zw = vec2(0, 1);"
-        "}"
-    );
-
-    SkString fshaderTxt(version);
-    GrGLSLAppendDefaultFloatPrecisionDeclaration(kDefault_GrSLPrecision, this->glStandard(),
-                                                 &fshaderTxt);
-    vTexCoord.setTypeModifier(GrShaderVar::kVaryingIn_TypeModifier);
-    vTexCoord.appendDecl(this->ctxInfo(), &fshaderTxt);
-    fshaderTxt.append(";");
-    uTexture.appendDecl(this->ctxInfo(), &fshaderTxt);
-    fshaderTxt.append(";");
-    const char* fsOutName;
-    if (this->glCaps().glslCaps()->mustDeclareFragmentShaderOutput()) {
-        oFragColor.appendDecl(this->ctxInfo(), &fshaderTxt);
-        fshaderTxt.append(";");
-        fsOutName = oFragColor.c_str();
-    } else {
-        fsOutName = "gl_FragColor";
-    }
-    fshaderTxt.appendf(
-        "// Copy Program FS\n"
-        "void main() {"
-        "  %s = %s(u_texture, v_texCoord);"
-        "}",
-        fsOutName,
-        GrGLSLTexture2DFunctionName(kVec2f_GrSLType, this->glslGeneration())
-    );
-    
-    GL_CALL_RET(fCopyProgram.fProgram, CreateProgram());
-    const char* str;
-    GrGLint length;
-
-    str = vshaderTxt.c_str();
-    length = SkToInt(vshaderTxt.size());
-    GrGLuint vshader = GrGLCompileAndAttachShader(fGLContext, fCopyProgram.fProgram,
-                                                  GR_GL_VERTEX_SHADER, &str, &length, 1, &fStats);
-
-    str = fshaderTxt.c_str();
-    length = SkToInt(fshaderTxt.size());
-    GrGLuint fshader = GrGLCompileAndAttachShader(fGLContext, fCopyProgram.fProgram,
-                                                  GR_GL_FRAGMENT_SHADER, &str, &length, 1, &fStats);
-
-    GL_CALL(LinkProgram(fCopyProgram.fProgram));
-
-    GL_CALL_RET(fCopyProgram.fTextureUniform, GetUniformLocation(fCopyProgram.fProgram,
-                                                                 "u_texture"));
-    GL_CALL_RET(fCopyProgram.fPosXformUniform, GetUniformLocation(fCopyProgram.fProgram,
-                                                                  "u_posXform"));
-    GL_CALL_RET(fCopyProgram.fTexCoordXformUniform, GetUniformLocation(fCopyProgram.fProgram,
-                                                                       "u_texCoordXform"));
-
-    GL_CALL(BindAttribLocation(fCopyProgram.fProgram, 0, "a_vertex"));
-
-    GL_CALL(DeleteShader(vshader));
-    GL_CALL(DeleteShader(fshader));
-
-    GL_CALL(GenBuffers(1, &fCopyProgram.fArrayBuffer));
-    fHWGeometryState.setVertexBufferID(this, fCopyProgram.fArrayBuffer);
-    static const GrGLfloat vdata[] = {
-        0, 0,
-        0, 1,
-        1, 0,
-        1, 1
-    };
-    GL_ALLOC_CALL(this->glInterface(),
-                  BufferData(GR_GL_ARRAY_BUFFER,
-                             (GrGLsizeiptr) sizeof(vdata),
-                             vdata,  // data ptr
-                             GR_GL_STATIC_DRAW));
-}
-
-void GrGLGpu::copySurfaceAsDraw(GrSurface* dst,
-                                GrSurface* src,
-                                const SkIRect& srcRect,
-                                const SkIPoint& dstPoint) {
-    int w = srcRect.width();
-    int h = srcRect.height();
-
-    GrGLTexture* srcTex = static_cast<GrGLTexture*>(src->asTexture());
-    GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::kNone_FilterMode);
-    this->bindTexture(0, params, srcTex);
-
-    GrGLRenderTarget* dstRT = static_cast<GrGLRenderTarget*>(dst->asRenderTarget());
-    SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.fX, dstPoint.fY, w, h);
-    this->flushRenderTarget(dstRT, &dstRect);
-
-    GL_CALL(UseProgram(fCopyProgram.fProgram));
-    fHWProgramID = fCopyProgram.fProgram;
-
-    fHWGeometryState.setVertexArrayID(this, 0);
-
-    GrGLAttribArrayState* attribs =
-        fHWGeometryState.bindArrayAndBufferToDraw(this, fCopyProgram.fArrayBuffer);
-    attribs->set(this, 0, fCopyProgram.fArrayBuffer, 2, GR_GL_FLOAT, false,
-                    2 * sizeof(GrGLfloat), 0);
-
-
-    // dst rect edges in NDC (-1 to 1)
-    int dw = dst->width();
-    int dh = dst->height();
-    GrGLfloat dx0 = 2.f * dstPoint.fX / dw - 1.f;
-    GrGLfloat dx1 = 2.f * (dstPoint.fX + w) / dw - 1.f;
-    GrGLfloat dy0 = 2.f * dstPoint.fY / dh - 1.f;
-    GrGLfloat dy1 = 2.f * (dstPoint.fY + h) / dh - 1.f;
-    if (kBottomLeft_GrSurfaceOrigin == dst->origin()) {
-        dy0 = -dy0;
-        dy1 = -dy1;
-    }
-
-    // src rect edges in normalized texture space (0 to 1)
-    int sw = src->width();
-    int sh = src->height();
-    GrGLfloat sx0 = (GrGLfloat)srcRect.fLeft / sw;
-    GrGLfloat sx1 = (GrGLfloat)(srcRect.fLeft + w) / sw;
-    GrGLfloat sy0 = (GrGLfloat)srcRect.fTop / sh;
-    GrGLfloat sy1 = (GrGLfloat)(srcRect.fTop + h) / sh;
-    if (kBottomLeft_GrSurfaceOrigin == src->origin()) {
-        sy0 = 1.f - sy0;
-        sy1 = 1.f - sy1;
-    }
-
-    GL_CALL(Uniform4f(fCopyProgram.fPosXformUniform, dx1 - dx0, dy1 - dy0, dx0, dy0));
-    GL_CALL(Uniform4f(fCopyProgram.fTexCoordXformUniform, sx1 - sx0, sy1 - sy0, sx0, sy0));
-    GL_CALL(Uniform1i(fCopyProgram.fTextureUniform, 0));
-
-    GrXferProcessor::BlendInfo blendInfo;
-    blendInfo.reset();
-    this->flushBlend(blendInfo);
-    this->flushColorWrite(true);
-    this->flushDither(false);
-    this->flushDrawFace(GrPipelineBuilder::kBoth_DrawFace);
-    this->flushHWAAState(dstRT, false);
-    this->disableScissor();
-    GrStencilSettings stencil;
-    stencil.setDisabled();
-    this->flushStencil(stencil);
-
-    GL_CALL(DrawArrays(GR_GL_TRIANGLE_STRIP, 0, 4));
-}
-
-void GrGLGpu::copySurfaceAsCopyTexSubImage(GrSurface* dst,
-                                           GrSurface* src,
-                                           const SkIRect& srcRect,
-                                           const SkIPoint& dstPoint) {
-    SkASSERT(can_copy_texsubimage(dst, src, this));
-    GrGLuint srcFBO;
-    GrGLIRect srcVP;
-    srcFBO = this->bindSurfaceAsFBO(src, GR_GL_FRAMEBUFFER, &srcVP, kSrc_TempFBOTarget);
-    GrGLTexture* dstTex = static_cast<GrGLTexture*>(dst->asTexture());
-    SkASSERT(dstTex);
-    // We modified the bound FBO
-    fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID;
-    GrGLIRect srcGLRect;
-    srcGLRect.setRelativeTo(srcVP,
-                            srcRect.fLeft,
-                            srcRect.fTop,
-                            srcRect.width(),
-                            srcRect.height(),
-                            src->origin());
-
-    this->setScratchTextureUnit();
-    GL_CALL(BindTexture(GR_GL_TEXTURE_2D, dstTex->textureID()));
-    GrGLint dstY;
-    if (kBottomLeft_GrSurfaceOrigin == dst->origin()) {
-        dstY = dst->height() - (dstPoint.fY + srcGLRect.fHeight);
-    } else {
-        dstY = dstPoint.fY;
-    }
-    GL_CALL(CopyTexSubImage2D(GR_GL_TEXTURE_2D, 0,
-                                dstPoint.fX, dstY,
-                                srcGLRect.fLeft, srcGLRect.fBottom,
-                                srcGLRect.fWidth, srcGLRect.fHeight));
-    if (srcFBO) {
-        this->unbindTextureFromFBO(GR_GL_FRAMEBUFFER);
-    }
-}
-
-bool GrGLGpu::copySurfaceAsBlitFramebuffer(GrSurface* dst,
-                                           GrSurface* src,
-                                           const SkIRect& srcRect,
-                                           const SkIPoint& dstPoint) {
-    SkASSERT(can_blit_framebuffer(dst, src, this));
-    SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.fX, dstPoint.fY,
-                                        srcRect.width(), srcRect.height());
-    if (dst == src) {
-        if (SkIRect::IntersectsNoEmptyCheck(dstRect, srcRect)) {
-            return false;
+        if (dst == src) {
+            SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.fX, dstPoint.fY,
+                                                srcRect.width(), srcRect.height());
+            if(!SkIRect::IntersectsNoEmptyCheck(dstRect, srcRect)) {
+                return true;
+            }
+        } else {
+            return true;
         }
     }
-
-    GrGLuint dstFBO;
-    GrGLuint srcFBO;
-    GrGLIRect dstVP;
-    GrGLIRect srcVP;
-    dstFBO = this->bindSurfaceAsFBO(dst, GR_GL_DRAW_FRAMEBUFFER, &dstVP,
-                                    kDst_TempFBOTarget);
-    srcFBO = this->bindSurfaceAsFBO(src, GR_GL_READ_FRAMEBUFFER, &srcVP,
-                                    kSrc_TempFBOTarget);
-    // We modified the bound FBO
-    fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID;
-    GrGLIRect srcGLRect;
-    GrGLIRect dstGLRect;
-    srcGLRect.setRelativeTo(srcVP,
-                            srcRect.fLeft,
-                            srcRect.fTop,
-                            srcRect.width(),
-                            srcRect.height(),
-                            src->origin());
-    dstGLRect.setRelativeTo(dstVP,
-                            dstRect.fLeft,
-                            dstRect.fTop,
-                            dstRect.width(),
-                            dstRect.height(),
-                            dst->origin());
-
-    // BlitFrameBuffer respects the scissor, so disable it.
-    this->disableScissor();
-
-    GrGLint srcY0;
-    GrGLint srcY1;
-    // Does the blit need to y-mirror or not?
-    if (src->origin() == dst->origin()) {
-        srcY0 = srcGLRect.fBottom;
-        srcY1 = srcGLRect.fBottom + srcGLRect.fHeight;
-    } else {
-        srcY0 = srcGLRect.fBottom + srcGLRect.fHeight;
-        srcY1 = srcGLRect.fBottom;
-    }
-    GL_CALL(BlitFramebuffer(srcGLRect.fLeft,
-                            srcY0,
-                            srcGLRect.fLeft + srcGLRect.fWidth,
-                            srcY1,
-                            dstGLRect.fLeft,
-                            dstGLRect.fBottom,
-                            dstGLRect.fLeft + dstGLRect.fWidth,
-                            dstGLRect.fBottom + dstGLRect.fHeight,
-                            GR_GL_COLOR_BUFFER_BIT, GR_GL_NEAREST));
-    if (dstFBO) {
-        this->unbindTextureFromFBO(GR_GL_DRAW_FRAMEBUFFER);
-    }
-    if (srcFBO) {
-        this->unbindTextureFromFBO(GR_GL_READ_FRAMEBUFFER);
-    }
-    return true;
+    return false;
 }
 
 void GrGLGpu::xferBarrier(GrRenderTarget* rt, GrXferBarrierType type) {
@@ -3019,52 +2832,26 @@ void GrGLGpu::didRemoveGpuTraceMarker() {
 }
 
 ///////////////////////////////////////////////////////////////////////////////
+
 GrGLAttribArrayState* GrGLGpu::HWGeometryState::bindArrayAndBuffersToDraw(
                                                 GrGLGpu* gpu,
                                                 const GrGLVertexBuffer* vbuffer,
                                                 const GrGLIndexBuffer* ibuffer) {
     SkASSERT(vbuffer);
-    GrGLuint vbufferID = vbuffer->bufferID();
-    GrGLuint* ibufferIDPtr = NULL;
-    GrGLuint ibufferID;
-    if (ibuffer) {
-        ibufferID = ibuffer->bufferID();
-        ibufferIDPtr = &ibufferID;
-    }
-    return this->internalBind(gpu, vbufferID, ibufferIDPtr);
-}
-
-GrGLAttribArrayState* GrGLGpu::HWGeometryState::bindArrayAndBufferToDraw(GrGLGpu* gpu,
-                                                                         GrGLuint vbufferID) {
-    return this->internalBind(gpu, vbufferID, NULL);
-}
-
-GrGLAttribArrayState* GrGLGpu::HWGeometryState::bindArrayAndBuffersToDraw(GrGLGpu* gpu,
-                                                                          GrGLuint vbufferID,
-                                                                          GrGLuint ibufferID) {
-    return this->internalBind(gpu, vbufferID, &ibufferID);
-}
-
-GrGLAttribArrayState* GrGLGpu::HWGeometryState::internalBind(GrGLGpu* gpu,
-                                                             GrGLuint vbufferID,
-                                                             GrGLuint* ibufferID) {
     GrGLAttribArrayState* attribState;
 
-    if (gpu->glCaps().isCoreProfile() && 0 != vbufferID) {
+    // We use a vertex array if we're on a core profile and the verts are in a VBO.
+    if (gpu->glCaps().isCoreProfile() && !vbuffer->isCPUBacked()) {
         if (!fVBOVertexArray) {
             GrGLuint arrayID;
             GR_GL_CALL(gpu->glInterface(), GenVertexArrays(1, &arrayID));
             int attrCount = gpu->glCaps().maxVertexAttributes();
             fVBOVertexArray = SkNEW_ARGS(GrGLVertexArray, (arrayID, attrCount));
         }
-        if (ibufferID) {
-            attribState = fVBOVertexArray->bindWithIndexBuffer(gpu, *ibufferID);
-        } else {
-            attribState = fVBOVertexArray->bind(gpu);
-        }
+        attribState = fVBOVertexArray->bindWithIndexBuffer(gpu, ibuffer);
     } else {
-        if (ibufferID) {
-            this->setIndexBufferIDOnDefaultVertexArray(gpu, *ibufferID);
+        if (ibuffer) {
+            this->setIndexBufferIDOnDefaultVertexArray(gpu, ibuffer->bufferID());
         } else {
             this->setVertexArrayID(gpu, 0);
         }
index 986045ac9880204d031967b418930b7496b2b038..3323ece07960c14179ac165fdc0e1b90b68668a9 100644 (file)
@@ -101,6 +101,11 @@ public:
                      const SkIRect& srcRect,
                      const SkIPoint& dstPoint) override;
 
+    bool canCopySurface(const GrSurface* dst,
+                        const GrSurface* src,
+                        const SkIRect& srcRect,
+                        const SkIPoint& dstPoint) override;
+
     void xferBarrier(GrRenderTarget*, GrXferBarrierType) override;
 
     void buildProgramDesc(GrProgramDesc*,
@@ -178,19 +183,6 @@ private:
     // Subclasses should call this to flush the blend state.
     void flushBlend(const GrXferProcessor::BlendInfo& blendInfo);
 
-    void copySurfaceAsDraw(GrSurface* dst,
-                           GrSurface* src,
-                           const SkIRect& srcRect,
-                           const SkIPoint& dstPoint);
-    void copySurfaceAsCopyTexSubImage(GrSurface* dst,
-                                      GrSurface* src,
-                                      const SkIRect& srcRect,
-                                      const SkIPoint& dstPoint);
-    bool copySurfaceAsBlitFramebuffer(GrSurface* dst,
-                                      GrSurface* src,
-                                      const SkIRect& srcRect,
-                                      const SkIPoint& dstPoint);
-
     bool hasExtension(const char* ext) const { return fGLContext.hasExtension(ext); }
 
     static bool BlendCoeffReferencesConstant(GrBlendCoeff coeff);
@@ -201,7 +193,7 @@ private:
         ~ProgramCache();
 
         void abandon();
-        GrGLProgram* refProgram(const DrawArgs&);
+        GrGLProgram* getProgram(const DrawArgs&);
 
     private:
         enum {
@@ -302,12 +294,11 @@ private:
 
     void unbindTextureFromFBO(GrGLenum fboTarget);
 
-    void createCopyProgram();
-
     GrGLContext fGLContext;
 
     // GL program-related state
     ProgramCache*               fProgramCache;
+    SkAutoTUnref<GrGLProgram>   fCurrentProgram;
 
     ///////////////////////////////////////////////////////////////////////////
     ///@name Caching of GL State
@@ -429,17 +420,7 @@ private:
                                                         const GrGLVertexBuffer* vbuffer,
                                                         const GrGLIndexBuffer* ibuffer);
 
-        /** Variants of the above that takes GL buffer IDs. Note that 0 does not imply that a 
-            buffer won't be bound. The "default buffer" will be bound, which is used for client-side
-            array rendering. */
-        GrGLAttribArrayState* bindArrayAndBufferToDraw(GrGLGpu* gpu, GrGLuint vbufferID);
-        GrGLAttribArrayState* bindArrayAndBuffersToDraw(GrGLGpu* gpu,
-                                                        GrGLuint vbufferID,
-                                                        GrGLuint ibufferID);
-
     private:
-        GrGLAttribArrayState* internalBind(GrGLGpu* gpu, GrGLuint vbufferID, GrGLuint* ibufferID);
-
         GrGLuint                fBoundVertexArrayID;
         GrGLuint                fBoundVertexBufferID;
         bool                    fBoundVertexArrayIDIsValid;
@@ -473,15 +454,6 @@ private:
         }
     } fHWBlendState;
 
-    /** IDs for copy surface program. */
-    struct {
-        GrGLuint    fProgram;
-        GrGLint     fTextureUniform;
-        GrGLint     fTexCoordXformUniform;
-        GrGLint     fPosXformUniform;
-        GrGLuint    fArrayBuffer;
-    } fCopyProgram;
-
     TriState fMSAAEnabled;
 
     GrStencilSettings           fHWStencilSettings;
index 06efe299c1c916dd92bcfd843e4d7b11e08aa307..911fd936e80296293c767ede5d071ad193e205eb 100644 (file)
@@ -90,7 +90,7 @@ int GrGLGpu::ProgramCache::search(const GrProgramDesc& desc) const {
     return SkTSearch(fEntries, fCount, desc, sizeof(Entry*), less);
 }
 
-GrGLProgram* GrGLGpu::ProgramCache::refProgram(const DrawArgs& args) {
+GrGLProgram* GrGLGpu::ProgramCache::getProgram(const DrawArgs& args) {
 #ifdef PROGRAM_CACHE_STATS
     ++fTotalRequests;
 #endif
@@ -193,5 +193,5 @@ GrGLProgram* GrGLGpu::ProgramCache::refProgram(const DrawArgs& args) {
         }
     }
     ++fCurrLRUStamp;
-    return SkRef(entry->fProgram.get());
+    return entry->fProgram;
 }
index f4caf5201292ffbe837129d077fccbbc1d0586b1..d388d9120a1d3fc43891ba47a50f2f4221ddb432 100644 (file)
@@ -91,25 +91,6 @@ const char* GrGetGLSLVersionDecl(const GrGLContextInfo& info) {
     }
 }
 
-void GrGLSLAppendDefaultFloatPrecisionDeclaration(GrSLPrecision p, GrGLStandard s, SkString* out) {
-    // Desktop GLSL has added precision qualifiers but they don't do anything.
-    if (kGLES_GrGLStandard == s) {
-        switch (p) {
-            case kHigh_GrSLPrecision:
-                out->append("precision highp float;\n");
-                break;
-            case kMedium_GrSLPrecision:
-                out->append("precision mediump float;\n");
-                break;
-            case kLow_GrSLPrecision:
-                out->append("precision lowp float;\n");
-                break;
-            default:
-                SkFAIL("Unknown precision value.");
-        }
-    }
-}
-
 void GrGLSLMulVarBy4f(SkString* outAppend, const char* vec4VarName, const GrGLSLExpr4& mulFactor) {
     if (mulFactor.isOnes()) {
         *outAppend = SkString();
index db8e1bdca5092a42f7524604d462c88d3b4bf9e4..99671c130e0c5e3a431cc5b74a0ba27f2be7594c 100644 (file)
@@ -56,24 +56,6 @@ bool GrGetGLSLGeneration(const GrGLInterface* gl, GrGLSLGeneration* generation);
  */
 const char* GrGetGLSLVersionDecl(const GrGLContextInfo&);
 
-/**
- * Adds a line of GLSL code to declare the default precision for float types.
- */
-void GrGLSLAppendDefaultFloatPrecisionDeclaration(GrSLPrecision, GrGLStandard, SkString* out);
-
-/**
- * Gets the name of the function that should be used to sample a 2D texture. Coord type is used
- * to indicate whether the texture is sampled using projective textured (kVec3f) or not (kVec2f).
- */
-inline const char* GrGLSLTexture2DFunctionName(GrSLType coordType, GrGLSLGeneration glslGen) {
-    if (kVec2f_GrSLType == coordType) {
-        return glslGen >= k130_GrGLSLGeneration ? "texture" : "texture2D";
-    } else {
-        SkASSERT(kVec3f_GrSLType == coordType);
-        return glslGen >= k130_GrGLSLGeneration ? "textureProj" : "texture2DProj";
-    }
-}
-
 /**
  * Converts a GrSLType to a string containing the name of the equivalent GLSL type.
  */
index 265b5b35ea6964034882a89e9a714747f633c67e..e20dbb5fed94c779f00ef5e7760e9059ec15bd32 100644 (file)
@@ -9,10 +9,9 @@
 #include "GrGLGpu.h"
 
 
-
-void GrGLAttribArrayState::set(GrGLGpu* gpu,
+void GrGLAttribArrayState::set(const GrGLGpu* gpu,
                                int index,
-                               GrGLuint vertexBufferID,
+                               GrGLVertexBuffer* buffer,
                                GrGLint size,
                                GrGLenum type,
                                GrGLboolean normalized,
@@ -26,13 +25,13 @@ void GrGLAttribArrayState::set(GrGLGpu* gpu,
         array->fEnabled = true;
     }
     if (!array->fAttribPointerIsValid ||
-        array->fVertexBufferID != vertexBufferID ||
+        array->fVertexBufferID != buffer->bufferID() ||
         array->fSize != size ||
         array->fNormalized != normalized ||
         array->fStride != stride ||
         array->fOffset != offset) {
 
-        gpu->bindVertexBuffer(vertexBufferID);
+        buffer->bind();
         GR_GL_CALL(gpu->glInterface(), VertexAttribPointer(index,
                                                            size,
                                                            type,
@@ -40,7 +39,7 @@ void GrGLAttribArrayState::set(GrGLGpu* gpu,
                                                            stride,
                                                            offset));
         array->fAttribPointerIsValid = true;
-        array->fVertexBufferID = vertexBufferID;
+        array->fVertexBufferID = buffer->bufferID();
         array->fSize = size;
         array->fNormalized = normalized;
         array->fStride = stride;
@@ -81,13 +80,15 @@ GrGLAttribArrayState* GrGLVertexArray::bind(GrGLGpu* gpu) {
     return &fAttribArrays;
 }
 
-GrGLAttribArrayState* GrGLVertexArray::bindWithIndexBuffer(GrGLGpu* gpu, GrGLuint ibufferID) {
+GrGLAttribArrayState* GrGLVertexArray::bindWithIndexBuffer(GrGLGpu* gpu,
+                                                           const GrGLIndexBuffer* buffer) {
     GrGLAttribArrayState* state = this->bind(gpu);
-    if (state) {
-        if (!fIndexBufferIDIsValid || ibufferID != fIndexBufferID) {            
-            GR_GL_CALL(gpu->glInterface(), BindBuffer(GR_GL_ELEMENT_ARRAY_BUFFER, ibufferID));
+    if (state && buffer) {
+        GrGLuint bufferID = buffer->bufferID();
+        if (!fIndexBufferIDIsValid || bufferID != fIndexBufferID) {            
+            GR_GL_CALL(gpu->glInterface(), BindBuffer(GR_GL_ELEMENT_ARRAY_BUFFER, bufferID));
             fIndexBufferIDIsValid = true;
-            fIndexBufferID = ibufferID;
+            fIndexBufferID = bufferID;
         }
     }
     return state;
index afb23c5d204281c3703cc6e9835b352ea91763ed..a8feb73087583796ed4d71b200754925059f3327 100644 (file)
@@ -67,9 +67,9 @@ public:
      * assumed that the GrGLAttribArrayState is tracking the state of the currently bound vertex
      * array object.
      */
-    void set(GrGLGpu*,
-             int attribIndex,
-             GrGLuint vertexBufferID,
+    void set(const GrGLGpu*,
+             int index,
+             GrGLVertexBuffer*,
              GrGLint size,
              GrGLenum type,
              GrGLboolean normalized,
@@ -147,7 +147,7 @@ public:
      * This is a version of the above function that also binds an index buffer to the vertex
      * array object.
      */
-    GrGLAttribArrayState* bindWithIndexBuffer(GrGLGpu* gpu, GrGLuint indexBufferID);
+    GrGLAttribArrayState* bindWithIndexBuffer(GrGLGpu* gpu, const GrGLIndexBuffer*);
 
     void notifyIndexBufferDelete(GrGLuint bufferID);
 
index afb0718cbdcee5094d139c27527f62bcf1be7308..044752f7a538b2fc68f5b53430f31a197e81afb9 100644 (file)
 const char* GrGLFragmentShaderBuilder::kDstCopyColorName = "_dstColor";
 static const char* declared_color_output_name() { return "fsColorOut"; }
 static const char* dual_source_output_name() { return "dualSourceOut"; }
+static void append_default_precision_qualifier(GrSLPrecision p,
+                                               GrGLStandard standard,
+                                               SkString* str) {
+    // Desktop GLSL has added precision qualifiers but they don't do anything.
+    if (kGLES_GrGLStandard == standard) {
+        switch (p) {
+            case kHigh_GrSLPrecision:
+                str->append("precision highp float;\n");
+                break;
+            case kMedium_GrSLPrecision:
+                str->append("precision mediump float;\n");
+                break;
+            case kLow_GrSLPrecision:
+                str->append("precision lowp float;\n");
+                break;
+            default:
+                SkFAIL("Unknown precision value.");
+        }
+    }
+}
 
 static const char* specific_layout_qualifier_name(GrBlendEquation equation) {
     SkASSERT(GrBlendEquationIsAdvanced(equation));
@@ -250,9 +270,9 @@ bool GrGLFragmentShaderBuilder::compileAndAttachShaders(GrGLuint programId,
                                                         SkTDArray<GrGLuint>* shaderIds) {
     GrGLGpu* gpu = fProgramBuilder->gpu();
     this->versionDecl() = GrGetGLSLVersionDecl(gpu->ctxInfo());
-    GrGLSLAppendDefaultFloatPrecisionDeclaration(kDefault_GrSLPrecision,
-                                                 gpu->glStandard(),
-                                                 &this->precisionQualifier());
+    append_default_precision_qualifier(kDefault_GrSLPrecision,
+                                       gpu->glStandard(),
+                                       &this->precisionQualifier());
     this->compileAndAppendLayoutQualifiers();
     fProgramBuilder->appendUniformDecls(GrGLProgramBuilder::kFragment_Visibility,
                                         &this->uniforms());
index 95f75ffd448f167ca0cf5cb38e185b7c3f21b2a9..28e1fba20cfca8eaf70e671414576be9bb6b48a6 100644 (file)
@@ -343,7 +343,8 @@ void GrGLProgramBuilder::emitAndInstallXferProc(const GrXferProcessor& xp,
         fFS.enableSecondaryOutput();
     }
 
-    if (this->ctxInfo().caps()->glslCaps()->mustDeclareFragmentShaderOutput()) {
+    // On any post 1.10 GLSL supporting GPU, we declare custom output
+    if (k110_GrGLSLGeneration != fFS.fProgramBuilder->gpu()->glslGeneration()) {
         fFS.enableCustomOutput();
     }
 
index 984233dd77f0bb74f72083734594d05a16ec8585..67fbe2451dc4c148977c2a1ce10df4675c384f78 100644 (file)
 #include "../GrGLShaderVar.h"
 
 namespace {
+inline const char* sample_function_name(GrSLType type, GrGLSLGeneration glslGen) {
+    if (kVec2f_GrSLType == type) {
+        return glslGen >= k130_GrGLSLGeneration ? "texture" : "texture2D";
+    } else {
+        SkASSERT(kVec3f_GrSLType == type);
+        return glslGen >= k130_GrGLSLGeneration ? "textureProj" : "texture2DProj";
+    }
+}
 void append_texture_lookup(SkString* out,
                            GrGLGpu* gpu,
                            const char* samplerName,
@@ -22,7 +30,7 @@ void append_texture_lookup(SkString* out,
     SkASSERT(coordName);
 
     out->appendf("%s(%s, %s)",
-                 GrGLSLTexture2DFunctionName(varyingType, gpu->glslGeneration()),
+                 sample_function_name(varyingType, gpu->glslGeneration()),
                  samplerName,
                  coordName);