Move alpha-ramp AA to GrContext, detect cases when AA is applied via other methods (smooth lines, MSAA) or rect falls on integer coords and skip the alpha ramp path. Use pre-fab index buffer for alpha-ramped fill rects and stroke rects.
Review URL: http://codereview.appspot.com/4449047/
git-svn-id: http://skia.googlecode.com/svn/trunk@1169 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/gpu/include/GrContext.h b/gpu/include/GrContext.h
index 5eda2b7..07d76f8 100644
--- a/gpu/include/GrContext.h
+++ b/gpu/include/GrContext.h
@@ -568,8 +568,26 @@
GrIndexBufferAllocPool* fDrawBufferIBAllocPool;
GrInOrderDrawBuffer* fDrawBuffer;
+ GrIndexBuffer* fAAFillRectIndexBuffer;
+ GrIndexBuffer* fAAStrokeRectIndexBuffer;
+
GrContext(GrGpu* gpu);
+ void fillAARect(GrDrawTarget* target,
+ const GrPaint& paint,
+ const GrRect& devRect);
+
+ void strokeAARect(GrDrawTarget* target,
+ const GrPaint& paint,
+ const GrRect& devRect,
+ const GrVec& devStrokeSize);
+
+ inline int aaFillRectIndexCount() const;
+ GrIndexBuffer* aaFillRectIndexBuffer();
+
+ inline int aaStrokeRectIndexCount() const;
+ GrIndexBuffer* aaStrokeRectIndexBuffer();
+
void setupDrawBuffer();
void flushDrawBuffer();
diff --git a/gpu/include/GrGpu.h b/gpu/include/GrGpu.h
index 7dd9959..5bbe85d 100644
--- a/gpu/include/GrGpu.h
+++ b/gpu/include/GrGpu.h
@@ -273,6 +273,12 @@
bool supportsBufferLocking() const { return fBufferLockSupport; }
/**
+ * Does the 3D API support anti-aliased lines. If so then line primitive
+ * types will use this functionality when the AA state flag is set.
+ */
+ bool supportsAALines() const { return fAALineSupport; }
+
+ /**
* Gets the minimum width of a render target. If a texture/rt is created
* with a width less than this size the GrGpu object will clamp it to this
* value.
@@ -445,6 +451,7 @@
bool fNPOTRenderTargetSupport;
bool fTwoSidedStencilSupport;
bool fStencilWrapOpsSupport;
+ bool fAALineSupport;
// set by subclass to true if index and vertex buffers can be locked, false
// otherwise.
diff --git a/gpu/include/GrMatrix.h b/gpu/include/GrMatrix.h
index 9a2e660..1ebc0b4 100644
--- a/gpu/include/GrMatrix.h
+++ b/gpu/include/GrMatrix.h
@@ -135,7 +135,7 @@
GrScalar scaleY,
GrScalar transY,
GrScalar persp0,
- GrScalar persp1,
+ GrScalar persp1,
GrScalar persp2) {
fM[kScaleX] = scaleX;
fM[kSkewX] = skewX;
@@ -253,6 +253,21 @@
start = (GrPoint*)((intptr_t)start + stride);
}
}
+
+ /**
+ * Transforms a vector by the matrix. Doesn't handle cases when a
+ * homogeneous vector maps to a point (i.e. perspective transform).
+ * In this case the desired answer is dependent on where the tail of
+ * the vector is in space.
+ */
+ void mapVec(GrVec* vec) {
+ GrAssert(!this->hasPerspective());
+ if (!this->isIdentity()) {
+ GrScalar x = vec->fX;
+ vec->fX = (*this)[kScaleX] * x + (*this)[kSkewX] * vec->fY;
+ vec->fY = (*this)[kSkewY ] * x + (*this)[kScaleY] * vec->fY;
+ }
+ }
/**
* Transform the 4 corners of the src rect, and return the bounding rect
@@ -278,7 +293,12 @@
* @return true if matrix is idenity
*/
bool isIdentity() const;
-
+
+ /**
+ * Do axis-aligned lines stay axis aligned? May do 90 degree rotation / mirroring.
+ */
+ bool preservesAxisAlignment() const;
+
/**
* Calculates the maximum stretching factor of the matrix. Only defined if
* the matrix does not have perspective.
diff --git a/gpu/include/GrPoint.h b/gpu/include/GrPoint.h
index c07543b..8c540f0 100644
--- a/gpu/include/GrPoint.h
+++ b/gpu/include/GrPoint.h
@@ -153,6 +153,14 @@
fX = x;
fY = y;
}
+
+ /**
+ * set this to (abs(v.x), abs(v.y))
+ */
+ void setAbs(const GrVec& v) {
+ fX = GrScalarAbs(v.fX);
+ fY = GrScalarAbs(v.fY);
+ }
/**
* set vector to point from a to b.
diff --git a/gpu/include/GrRect.h b/gpu/include/GrRect.h
index 67e366c..a9ff6ec 100644
--- a/gpu/include/GrRect.h
+++ b/gpu/include/GrRect.h
@@ -206,6 +206,14 @@
}
/**
+ * Returns true if the rects edges are integer-aligned.
+ */
+ bool isIRect() const {
+ return GrScalarIsInt(fLeft) && GrScalarIsInt(fTop) &&
+ GrScalarIsInt(fRight) && GrScalarIsInt(fBottom);
+ }
+
+ /**
* Does this rect contain a point.
*/
bool contains(const GrPoint& point) const {
@@ -363,6 +371,22 @@
return pts + 4;
}
+ /**
+ * Swaps (left and right) and/or (top and bottom) if they are inverted
+ */
+ void sort() {
+ if (fLeft > fRight) {
+ GrScalar temp = fLeft;
+ fLeft = fRight;
+ fRight = temp;
+ }
+ if (fTop > fBottom) {
+ GrScalar temp = fTop;
+ fTop = fBottom;
+ fBottom = temp;
+ }
+ }
+
bool operator ==(const GrRect& r) const {
return fLeft == r.fLeft &&
fTop == r.fTop &&
diff --git a/gpu/include/GrScalar.h b/gpu/include/GrScalar.h
index 1353fb2..7aaa43d 100644
--- a/gpu/include/GrScalar.h
+++ b/gpu/include/GrScalar.h
@@ -56,11 +56,19 @@
*/
#define GrFloatToFixed(x) ((GrFixed)((x) * GR_Fixed1))
-inline GrFixed GrFixedAbs(GrFixed x) {
+static inline GrFixed GrFixedAbs(GrFixed x) {
int32_t s = (x & 0x80000000) >> 31;
return (GrFixed)(((int32_t)x ^ s) - s);
}
+static inline bool GrFixedIsInt(GrFixed x) {
+ return 0 == (x & 0xffff);
+}
+
+static inline bool GrFloatIsInt(float x) {
+ return x == (float)(int)x;
+}
+
///////////////////////////////////////////////////////////////////////////////
#if GR_SCALAR_IS_FIXED
@@ -72,6 +80,7 @@
#define GrScalarHalf(x) ((x) >> 1)
#define GrScalarAve(x,y) (((x)+(y)) >> 1)
#define GrScalarAbs(x) GrFixedAbs(x)
+ #define GrScalarIsInt GrFixedIsInt
#define GR_Scalar1 GR_Fixed1
#define GR_ScalarHalf GR_FixedHalf
#define GR_ScalarMax GR_FixedMax
@@ -85,6 +94,7 @@
#define GrScalarHalf(x) ((x) * 0.5f)
#define GrScalarAbs(x) fabsf(x)
#define GrScalarAve(x,y) (((x) + (y)) * 0.5f)
+ #define GrScalarIsInt GrFloatIsInt
#define GR_Scalar1 1.f
#define GR_ScalarHalf 0.5f
#define GR_ScalarMax (FLT_MAX)