Add code path for Gr client to resolve an Gr-created MSAA render target.

Review URL: http://codereview.appspot.com/5580049/


git-svn-id: http://skia.googlecode.com/svn/trunk@3112 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index 1e87cab..dd1b276 100644
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -1900,6 +1900,16 @@
                             config, buffer, rowBytes, flipY);
 }
 
+void GrContext::resolveRenderTarget(GrRenderTarget* target) {
+    GrAssert(target);
+    ASSERT_OWNED_RESOURCE(target);
+    // In the future we may track whether there are any pending draws to this
+    // target. We don't today so we always perform a flush. We don't promise
+    // this to our clients, though.
+    this->flush();
+    fGpu->resolveRenderTarget(target);
+}
+
 void GrContext::copyTexture(GrTexture* src, GrRenderTarget* dst) {
     if (NULL == src || NULL == dst) {
         return;
diff --git a/src/gpu/GrGpu.cpp b/src/gpu/GrGpu.cpp
index 27a4497..39960de 100644
--- a/src/gpu/GrGpu.cpp
+++ b/src/gpu/GrGpu.cpp
@@ -260,6 +260,13 @@
                                config, buffer, rowBytes);
 }
 
+void GrGpu::resolveRenderTarget(GrRenderTarget* target) {
+    GrAssert(target);
+    this->handleDirtyContext();
+    this->onResolveRenderTarget(target);
+}
+
+
 ////////////////////////////////////////////////////////////////////////////////
 
 static const int MAX_QUADS = 1 << 12; // max possible: (1 << 14) - 1;
diff --git a/src/gpu/GrGpu.h b/src/gpu/GrGpu.h
index 8c23daa..e617efb 100644
--- a/src/gpu/GrGpu.h
+++ b/src/gpu/GrGpu.h
@@ -172,6 +172,11 @@
     const GrVertexBuffer* getUnitSquareVertexBuffer() const;
 
     /**
+     * Resolves MSAA.
+     */
+    void resolveRenderTarget(GrRenderTarget* target);
+
+    /**
      * Ensures that the current render target is actually set in the
      * underlying 3D API. Used when client wants to use 3D API to directly
      * render to the RT.
@@ -433,6 +438,9 @@
                                       GrPixelConfig config, const void* buffer,
                                       size_t rowBytes) = 0;
 
+    // overridden by API-specific derived class to perform the resolve
+    virtual void onResolveRenderTarget(GrRenderTarget* target) = 0;
+
     // called to program the vertex data, indexCount will be 0 if drawing non-
     // indexed geometry. The subclass may adjust the startVertex and/or
     // startIndex since it may have already accounted for these in the setup.
diff --git a/src/gpu/GrGpuGL.cpp b/src/gpu/GrGpuGL.cpp
index a4a49ac..70d28d6 100644
--- a/src/gpu/GrGpuGL.cpp
+++ b/src/gpu/GrGpuGL.cpp
@@ -1452,7 +1452,7 @@
             this->flushRenderTarget(&GrIRect::EmptyIRect());
             break;
         case GrGLRenderTarget::kCanResolve_ResolveType:
-            this->resolveRenderTarget(tgt);
+            this->onResolveRenderTarget(tgt);
             // we don't track the state of the READ FBO ID.
             GL_CALL(BindFramebuffer(GR_GL_READ_FRAMEBUFFER,
                                     tgt->textureFBOID()));
@@ -1666,7 +1666,9 @@
 #endif
 }
 
-void GrGpuGL::resolveRenderTarget(GrGLRenderTarget* rt) {
+void GrGpuGL::onResolveRenderTarget(GrRenderTarget* target) {
+
+    GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(target);
 
     if (rt->needsResolve()) {
         GrAssert(GLCaps::kNone_MSFBO != fGLCaps.fMSFBOType);
@@ -2050,7 +2052,7 @@
             GrGLRenderTarget* texRT = 
                 static_cast<GrGLRenderTarget*>(nextTexture->asRenderTarget());
             if (NULL != texRT) {
-                resolveRenderTarget(texRT);
+                this->onResolveRenderTarget(texRT);
             }
 
             if (fHWDrawState.getTexture(s) != nextTexture) {
diff --git a/src/gpu/GrGpuGL.h b/src/gpu/GrGpuGL.h
index 3196c89..6ac4809 100644
--- a/src/gpu/GrGpuGL.h
+++ b/src/gpu/GrGpuGL.h
@@ -41,6 +41,7 @@
                                     GrPixelConfig config,
                                     size_t rowBytes) const SK_OVERRIDE;
     virtual bool fullReadPixelsIsFasterThanPartial() const SK_OVERRIDE;
+
 protected:
     GrGpuGL(const GrGLInterface* glInterface, GrGLBinding glBinding);
 
@@ -193,6 +194,9 @@
                                       GrPixelConfig config, const void* buffer,
                                       size_t rowBytes) SK_OVERRIDE;
 
+    virtual void onResolveRenderTarget(GrRenderTarget* target) SK_OVERRIDE;
+
+
     virtual void onGpuDrawIndexed(GrPrimitiveType type,
                                   uint32_t startVertex,
                                   uint32_t startIndex,
@@ -276,8 +280,6 @@
     void flushStencil();
     void flushAAState(GrPrimitiveType type);
 
-    void resolveRenderTarget(GrGLRenderTarget* texture);
-
     bool configToGLFormats(GrPixelConfig config,
                            bool getSizedInternal,
                            GrGLenum* internalFormat,
diff --git a/src/gpu/GrRenderTarget.cpp b/src/gpu/GrRenderTarget.cpp
index 7901648..ed1a018 100644
--- a/src/gpu/GrRenderTarget.cpp
+++ b/src/gpu/GrRenderTarget.cpp
@@ -41,6 +41,15 @@
                                      config, buffer, rowBytes);
 }
 
+void GrRenderTarget::resolve() {
+    // go through context so that all necessary flushing occurs
+    GrContext* context = this->getContext();
+    if (NULL == context) {
+        return;
+    }
+    context->resolveRenderTarget(this);
+}
+
 size_t GrRenderTarget::sizeInBytes() const {
     int colorBits;
     if (kUnknown_GrPixelConfig == fConfig) {
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index d34ef6a..da97fde 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -1769,7 +1769,7 @@
 }
 
 void SkGpuDevice::flush() {
-    fContext->flush(false);
+    fContext->resolveRenderTarget(fRenderTarget);
 }
 
 ///////////////////////////////////////////////////////////////////////////////