Consider hw render target limit for offscreen supersample and tile

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



git-svn-id: http://skia.googlecode.com/svn/trunk@1568 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/gpu/include/GrConfig.h b/gpu/include/GrConfig.h
index 9ee37c7..b3025f3 100644
--- a/gpu/include/GrConfig.h
+++ b/gpu/include/GrConfig.h
@@ -371,6 +371,22 @@
     #define GR_GEOM_BUFFER_LOCK_THRESHOLD (1 << 15)
 #endif
 
+/**
+ * Enables/disables use of offscreen AA
+ */
+#if !defined(GR_USE_OFFSCREEN_AA)
+    #define GR_USE_OFFSCREEN_AA 1
+#endif
+
+/**
+ * GR_MAX_OFFSCREEN_AA_SIZE controls the size at which offscreen AA will tile.
+ * Tiling saves GPU memory by limiting the size of the offscreen buffer. The
+ * max offscreen may be as large as (4*GR_MAX_OFFSCREEN_AA_SIZE)^2 pixels.
+ */
+#if !defined(GR_MAX_OFFSCREEN_AA_SIZE)
+    #define GR_MAX_OFFSCREEN_AA_SIZE    256
+#endif
+
 ///////////////////////////////////////////////////////////////////////////////
 // tail section:
 //
diff --git a/gpu/include/GrContext.h b/gpu/include/GrContext.h
index 8809271..5dfe2c9 100644
--- a/gpu/include/GrContext.h
+++ b/gpu/include/GrContext.h
@@ -158,7 +158,13 @@
     /**
      *  Return the max width or height of a texture supported by the current gpu
      */
-    int getMaxTextureDimension();
+    int getMaxTextureSize() const;
+
+    /**
+     * Return the max width or height of a render target supported by the 
+     * current gpu
+     */
+    int getMaxRenderTargetSize() const;
 
     ///////////////////////////////////////////////////////////////////////////
     // Render targets
@@ -399,7 +405,6 @@
                             const TEX_SRC* texCoordSrc,
                             const COL_SRC* colorSrc);
 
-
     ///////////////////////////////////////////////////////////////////////////
     // Misc.
 
@@ -532,6 +537,7 @@
 
     GrIndexBuffer*              fAAFillRectIndexBuffer;
     GrIndexBuffer*              fAAStrokeRectIndexBuffer;
+    int                         fMaxOffscreenAASize;
 
     GrContext(GrGpu* gpu);
 
@@ -568,22 +574,34 @@
 
     struct OffscreenRecord;
 
+    // determines whether offscreen AA should be applied
     bool doOffscreenAA(GrDrawTarget* target, 
                        const GrPaint& paint,
                        bool isLines) const;
 
-    // sets up target to draw coverage to the supersampled render target
-    bool setupOffscreenAAPass1(GrDrawTarget* target,
+    // attempts to setup offscreen AA. All paint state must be transferred to
+    // target by the time this is called.
+    bool prepareForOffscreenAA(GrDrawTarget* target,
                                bool requireStencil,
                                const GrIRect& boundRect,
                                OffscreenRecord* record);
 
+    // sets up target to draw coverage to the supersampled render target
+    void setupOffscreenAAPass1(GrDrawTarget* target,
+                               const GrIRect& boundRect,
+                               int tileX, int tileY,
+                               OffscreenRecord* record);
+
     // sets up target to sample coverage of supersampled render target back
     // to the main render target using stage kOffscreenStage.
-    void offscreenAAPass2(GrDrawTarget* target,
-                          const GrPaint& paint,
-                          const GrIRect& boundRect,
-                          OffscreenRecord* record);
+    void doOffscreenAAPass2(GrDrawTarget* target,
+                            const GrPaint& paint,
+                            const GrIRect& boundRect,
+                            int tileX, int tileY,
+                            OffscreenRecord* record);
+
+    // restored the draw target state and releases offscreen target to cache
+    void cleanupOffscreenAA(GrDrawTarget* target, OffscreenRecord* record);
     
     // computes vertex layout bits based on the paint. If paint expresses
     // a texture for a stage, the stage coords will be bound to postitions
diff --git a/gpu/include/GrContext_impl.h b/gpu/include/GrContext_impl.h
index c79a191..b33d0b4 100644
--- a/gpu/include/GrContext_impl.h
+++ b/gpu/include/GrContext_impl.h
@@ -17,20 +17,6 @@
 #ifndef GrContext_impl_DEFINED
 #define GrContext_impl_DEFINED
 
-struct GrContext::OffscreenRecord {
-    OffscreenRecord() { fEntry0 = NULL; fEntry1 = NULL; }
-    ~OffscreenRecord() { GrAssert(NULL == fEntry0 && NULL == fEntry1); }
-
-    enum Downsample {
-        k4x4TwoPass_Downsample,
-        k4x4SinglePass_Downsample,
-        kFSAA_Downsample
-    }                              fDownsample;
-    GrTextureEntry*                fEntry0;
-    GrTextureEntry*                fEntry1;
-    GrDrawTarget::SavedDrawState   fSavedState;
-};
-
 template <typename POS_SRC, typename TEX_SRC,
           typename COL_SRC, typename IDX_SRC>
 inline void GrContext::drawCustomVertices(const GrPaint& paint,
@@ -86,31 +72,14 @@
         idxSrc->writeValue(i, indices + i);
     }
 
-    bool doAA = false;
-    OffscreenRecord record;
-    GrIRect bounds;
-
-    if (-1 == texOffsets[0] && -1 == colorOffset && 
-        this->doOffscreenAA(target, paint, GrIsPrimTypeLines(primitiveType))) {
-        GrRect b;
-        b.setBounds(geo.positions(), vertexCount);
-        target->getViewMatrix().mapRect(&b);
-        b.roundOut(&bounds);
-        if (this->setupOffscreenAAPass1(target, false, bounds, &record)) {
-            doAA = true;
-        }
-    }
+    // we don't currently apply offscreen AA to this path. Need improved 
+    // management of GrDrawTarget's geometry to avoid copying points per-tile.
 
     if (NULL == idxSrc) {
         target->drawNonIndexed(primitiveType, 0, vertexCount);
     } else {
         target->drawIndexed(primitiveType, 0, 0, vertexCount, indexCount);
     }
-
-    if (doAA) {
-        geo.set(NULL, 0, 0, 0); // have to release geom before can draw again
-        this->offscreenAAPass2(target, paint, bounds, &record);
-    }
 }
 
 class GrNullTexCoordSource {
diff --git a/gpu/include/GrGpu.h b/gpu/include/GrGpu.h
index 5cb885a..34ddccf 100644
--- a/gpu/include/GrGpu.h
+++ b/gpu/include/GrGpu.h
@@ -253,7 +253,14 @@
      */
     bool npotRenderTargetSupport() const { return fNPOTRenderTargetSupport; }
 
-    int maxTextureDimension() const { return fMaxTextureDimension; }
+    /**
+     * Gets the largest allowed width and height of a texture.
+     */
+    int maxTextureSize() const { return fMaxTextureSize; }
+    /**
+     * Gets the largest allowed width and height of a render target.
+     */
+    int maxRenderTargetSize() const { return fMaxRenderTargetSize; }
 
     // GrDrawTarget overrides
     virtual void drawIndexed(GrPrimitiveType type,
@@ -404,7 +411,8 @@
     // set by subclass
     int fMinRenderTargetWidth;
     int fMinRenderTargetHeight;
-    int fMaxTextureDimension;
+    int fMaxRenderTargetSize;
+    int fMaxTextureSize;
 
     GrGpuStats fStats;
 
diff --git a/gpu/include/GrTypes.h b/gpu/include/GrTypes.h
index 9348375..e6f3e2c 100644
--- a/gpu/include/GrTypes.h
+++ b/gpu/include/GrTypes.h
@@ -69,6 +69,10 @@
 /**
  *  divide, rounding up
  */
+static inline int32_t GrIDivRoundUp(int x, int y) {
+    GrAssert(y > 0);
+    return (x + (y-1)) / y;
+}
 static inline uint32_t GrUIDivRoundUp(uint32_t x, uint32_t y) {
     return (x + (y-1)) / y;
 }