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;
}