Correctly determine whether HW AA lines can be used
Review URL: http://codereview.appspot.com/4937049/
git-svn-id: http://skia.googlecode.com/svn/trunk@2162 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/gpu/src/GrContext.cpp b/gpu/src/GrContext.cpp
index 9c3f298..7bac3ba 100644
--- a/gpu/src/GrContext.cpp
+++ b/gpu/src/GrContext.cpp
@@ -630,16 +630,16 @@
GrClip fClip;
};
-bool GrContext::doOffscreenAA(GrDrawTarget* target,
+bool GrContext::doOffscreenAA(GrDrawTarget* target,
const GrPaint& paint,
- bool isLines) const {
+ bool isHairLines) const {
#if !GR_USE_OFFSCREEN_AA
return false;
#else
if (!paint.fAntiAlias) {
return false;
}
- if (isLines && fGpu->supportsAALines()) {
+ if (isHairLines && target->willUseHWAALines()) {
return false;
}
if (target->getRenderTarget()->isMultisampled()) {
@@ -1114,7 +1114,6 @@
}
static bool apply_aa_to_rect(GrDrawTarget* target,
- GrGpu* gpu,
const GrPaint& paint,
const GrRect& rect,
GrScalar width,
@@ -1134,7 +1133,7 @@
return false;
}
- if (0 == width && gpu->supportsAALines()) {
+ if (0 == width && target->willUseHWAALines()) {
return false;
}
@@ -1174,7 +1173,7 @@
GrRect devRect = rect;
GrMatrix combinedMatrix;
- bool doAA = apply_aa_to_rect(target, fGpu, paint, rect, width, matrix,
+ bool doAA = apply_aa_to_rect(target, paint, rect, width, matrix,
&combinedMatrix, &devRect);
if (doAA) {
@@ -1769,7 +1768,8 @@
DRAW_BUFFER_IBPOOL_BUFFER_SIZE,
DRAW_BUFFER_IBPOOL_PREALLOC_BUFFERS);
- fDrawBuffer = new GrInOrderDrawBuffer(fDrawBufferVBAllocPool,
+ fDrawBuffer = new GrInOrderDrawBuffer(fGpu,
+ fDrawBufferVBAllocPool,
fDrawBufferIBAllocPool);
#endif
diff --git a/gpu/src/GrDrawTarget.cpp b/gpu/src/GrDrawTarget.cpp
index 7efe381..29a37a4 100644
--- a/gpu/src/GrDrawTarget.cpp
+++ b/gpu/src/GrDrawTarget.cpp
@@ -695,47 +695,47 @@
////////////////////////////////////////////////////////////////////////////////
-bool GrDrawTarget::canDisableBlend() const {
+bool GrDrawTarget::CanDisableBlend(GrVertexLayout layout, const DrState& state) {
// If we compute a coverage value (using edge AA or a coverage stage) then
// we can't force blending off.
- if (fCurrDrawState.fEdgeAANumEdges > 0) {
+ if (state.fEdgeAANumEdges > 0) {
return false;
}
- for (int s = fCurrDrawState.fFirstCoverageStage; s < kNumStages; ++s) {
- if (this->isStageEnabled(s)) {
+ for (int s = state.fFirstCoverageStage; s < kNumStages; ++s) {
+ if (StageWillBeUsed(s, layout, state)) {
return false;
}
}
- if ((kOne_BlendCoeff == fCurrDrawState.fSrcBlend) &&
- (kZero_BlendCoeff == fCurrDrawState.fDstBlend)) {
+ if ((kOne_BlendCoeff == state.fSrcBlend) &&
+ (kZero_BlendCoeff == state.fDstBlend)) {
return true;
}
// If we have vertex color without alpha then we can't force blend off
- if ((this->getGeomSrc().fVertexLayout & kColor_VertexLayoutBit) ||
- 0xff != GrColorUnpackA(fCurrDrawState.fColor)) {
+ if ((layout & kColor_VertexLayoutBit) ||
+ 0xff != GrColorUnpackA(state.fColor)) {
return false;
}
// If the src coef will always be 1...
- if (kSA_BlendCoeff != fCurrDrawState.fSrcBlend &&
- kOne_BlendCoeff != fCurrDrawState.fSrcBlend) {
+ if (kSA_BlendCoeff != state.fSrcBlend &&
+ kOne_BlendCoeff != state.fSrcBlend) {
return false;
}
// ...and the dst coef is always 0...
- if (kISA_BlendCoeff != fCurrDrawState.fDstBlend &&
- kZero_BlendCoeff != fCurrDrawState.fDstBlend) {
+ if (kISA_BlendCoeff != state.fDstBlend &&
+ kZero_BlendCoeff != state.fDstBlend) {
return false;
}
// ...and there isn't a texture stage with an alpha channel...
- for (int s = 0; s < fCurrDrawState.fFirstCoverageStage; ++s) {
- if (this->isStageEnabled(s)) {
- GrAssert(NULL != fCurrDrawState.fTextures[s]);
+ for (int s = 0; s < state.fFirstCoverageStage; ++s) {
+ if (StageWillBeUsed(s, layout, state)) {
+ GrAssert(NULL != state.fTextures[s]);
- GrPixelConfig config = fCurrDrawState.fTextures[s]->config();
+ GrPixelConfig config = state.fTextures[s]->config();
if (!GrPixelConfigIsOpaque(config)) {
return false;
@@ -746,7 +746,7 @@
// ...and there isn't an interesting color filter...
// TODO: Consider being more aggressive with regards to disabling
// blending when a color filter is used.
- if (SkXfermode::kDst_Mode != fCurrDrawState.fColorFilterXfermode) {
+ if (SkXfermode::kDst_Mode != state.fColorFilterXfermode) {
return false;
}
@@ -754,7 +754,21 @@
return true;
}
+bool GrDrawTarget::CanUseHWAALines(GrVertexLayout layout, const DrState& state) {
+ // there is a conflict between using smooth lines and our use of
+ // premultiplied alpha. Smooth lines tweak the incoming alpha value
+ // but not in a premul-alpha way. So we only use them when our alpha
+ // is 0xff.
+ return (kAntialias_StateBit & state.fFlagBits) &&
+ CanDisableBlend(layout, state);
+}
+
+bool GrDrawTarget::canDisableBlend() const {
+ return CanDisableBlend(this->getGeomSrc().fVertexLayout, fCurrDrawState);
+}
+
///////////////////////////////////////////////////////////////////////////////
+
void GrDrawTarget::setEdgeAAData(const Edge* edges, int numEdges) {
GrAssert(numEdges <= kMaxEdges);
memcpy(fCurrDrawState.fEdgeAAEdges, edges, numEdges * sizeof(Edge));
diff --git a/gpu/src/GrDrawTarget.h b/gpu/src/GrDrawTarget.h
index 8196beb..f170fda 100644
--- a/gpu/src/GrDrawTarget.h
+++ b/gpu/src/GrDrawTarget.h
@@ -536,6 +536,13 @@
bool canDisableBlend() const;
/**
+ * Given the current draw state, vertex layout, and hw support, will HW AA
+ * lines be used (if line primitive type is drawn)? (Note that lines are
+ * always 1 pixel wide)
+ */
+ virtual bool willUseHWAALines() const = 0;
+
+ /**
* Sets the edge data required for edge antialiasing.
*
* @param edges 3 * 6 float values, representing the edge
@@ -1142,7 +1149,13 @@
static void VertexLayoutUnitTest();
protected:
-
+
+ // determines whether HW blending can be disabled or not
+ static bool CanDisableBlend(GrVertexLayout layout, const DrState& state);
+
+ // determines whether HW AA lines can be used or not
+ static bool CanUseHWAALines(GrVertexLayout layout, const DrState& state);
+
enum GeometrySrcType {
kNone_GeometrySrcType, //<! src has not been specified
kReserved_GeometrySrcType, //<! src was set using reserve*Space
diff --git a/gpu/src/GrGpu.cpp b/gpu/src/GrGpu.cpp
index 24950c4..b492952 100644
--- a/gpu/src/GrGpu.cpp
+++ b/gpu/src/GrGpu.cpp
@@ -142,6 +142,13 @@
////////////////////////////////////////////////////////////////////////////////
+bool GrGpu::willUseHWAALines() const {
+ return (kAntialias_StateBit & fCurrDrawState.fFlagBits) &&
+ CanUseHWAALines(this->getGeomSrc().fVertexLayout, fCurrDrawState);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
GrTexture* GrGpu::createTexture(const GrTextureDesc& desc,
const void* srcData, size_t rowBytes) {
this->handleDirtyContext();
diff --git a/gpu/src/GrGpu.h b/gpu/src/GrGpu.h
index deaba67..1e9505b 100644
--- a/gpu/src/GrGpu.h
+++ b/gpu/src/GrGpu.h
@@ -181,7 +181,7 @@
* 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; }
+ bool supportsHWAALines() const { return fAALineSupport; }
/**
* Does the subclass support GrSamplerState::k4x4Downsample_Filter
@@ -319,6 +319,9 @@
*/
void removeResource(GrResource* resource);
+ // GrDrawTarget overrides
+ virtual bool willUseHWAALines() const;
+
protected:
enum PrivateStateBits {
kFirstBit = (kLastPublicStateBit << 1),
diff --git a/gpu/src/GrGpuGL.cpp b/gpu/src/GrGpuGL.cpp
index ba7615d..936ada3 100644
--- a/gpu/src/GrGpuGL.cpp
+++ b/gpu/src/GrGpuGL.cpp
@@ -1813,18 +1813,6 @@
}
}
-bool GrGpuGL::useSmoothLines() {
- // there is a conflict between using smooth lines and our use of
- // premultiplied alpha. Smooth lines tweak the incoming alpha value
- // but not in a premul-alpha way. So we only use them when our alpha
- // is 0xff.
-
- // TODO: write a smarter line frag shader.
-
- return (kAntialias_StateBit & fCurrDrawState.fFlagBits) &&
- canDisableBlend();
-}
-
void GrGpuGL::flushAAState(GrPrimitiveType type) {
if (kDesktop_GrGLBinding == this->glBinding()) {
// ES doesn't support toggling GL_MULTISAMPLE and doesn't have
@@ -1833,7 +1821,7 @@
// we prefer smooth lines over multisampled lines
// msaa should be disabled if drawing smooth lines.
if (GrIsPrimTypeLines(type)) {
- bool smooth = useSmoothLines();
+ bool smooth = this->willUseHWAALines();
if (!fHWAAState.fSmoothLineEnabled && smooth) {
GL_CALL(Enable(GR_GL_LINE_SMOOTH));
fHWAAState.fSmoothLineEnabled = true;
@@ -1863,7 +1851,7 @@
void GrGpuGL::flushBlend(GrPrimitiveType type,
GrBlendCoeff srcCoeff,
GrBlendCoeff dstCoeff) {
- if (GrIsPrimTypeLines(type) && useSmoothLines()) {
+ if (GrIsPrimTypeLines(type) && this->willUseHWAALines()) {
if (fHWBlendDisabled) {
GL_CALL(Enable(GR_GL_BLEND));
fHWBlendDisabled = false;
diff --git a/gpu/src/GrGpuGL.h b/gpu/src/GrGpuGL.h
index b45928f..30a50e1 100644
--- a/gpu/src/GrGpuGL.h
+++ b/gpu/src/GrGpuGL.h
@@ -164,8 +164,6 @@
void setSpareTextureUnit();
- bool useSmoothLines();
-
// bound is region that may be modified and therefore has to be resolved.
// NULL means whole target. Can be an empty rect.
void flushRenderTarget(const GrIRect* bound);
diff --git a/gpu/src/GrInOrderDrawBuffer.cpp b/gpu/src/GrInOrderDrawBuffer.cpp
index 39bf275..85af430 100644
--- a/gpu/src/GrInOrderDrawBuffer.cpp
+++ b/gpu/src/GrInOrderDrawBuffer.cpp
@@ -15,9 +15,11 @@
#include "GrVertexBuffer.h"
#include "GrGpu.h"
-GrInOrderDrawBuffer::GrInOrderDrawBuffer(GrVertexBufferAllocPool* vertexPool,
+GrInOrderDrawBuffer::GrInOrderDrawBuffer(const GrGpu* gpu,
+ GrVertexBufferAllocPool* vertexPool,
GrIndexBufferAllocPool* indexPool)
- : fDraws(&fDrawStorage)
+ : fGpu(gpu)
+ , fDraws(&fDrawStorage)
, fStates(&fStateStorage)
, fClears(&fClearStorage)
, fClips(&fClipStorage)
@@ -35,6 +37,8 @@
GrAssert(NULL != vertexPool);
GrAssert(NULL != indexPool);
+ gpu->ref();
+
GeometryPoolState& poolState = fGeoPoolStateStack.push_back();
poolState.fUsedPoolVertexBytes = 0;
poolState.fUsedPoolIndexBytes = 0;
@@ -49,6 +53,7 @@
GrInOrderDrawBuffer::~GrInOrderDrawBuffer() {
this->reset();
GrSafeUnref(fQuadIndexBuffer);
+ fGpu->unref();
}
void GrInOrderDrawBuffer::initializeDrawStateAndClip(const GrDrawTarget& target) {
@@ -620,3 +625,9 @@
INHERITED::clipWillBeSet(newClip);
fClipSet = true;
}
+
+bool GrInOrderDrawBuffer::willUseHWAALines() const {
+ return fGpu->supportsHWAALines() &&
+ CanUseHWAALines(this->getGeomSrc().fVertexLayout, fCurrDrawState);
+}
+
diff --git a/gpu/src/GrInOrderDrawBuffer.h b/gpu/src/GrInOrderDrawBuffer.h
index 2a3bddb..dbf6144 100644
--- a/gpu/src/GrInOrderDrawBuffer.h
+++ b/gpu/src/GrInOrderDrawBuffer.h
@@ -16,8 +16,9 @@
#include "GrAllocator.h"
#include "GrClip.h"
-class GrVertexBufferAllocPool;
+class GrGpu;
class GrIndexBufferAllocPool;
+class GrVertexBufferAllocPool;
/**
* GrInOrderDrawBuffer is an implementation of GrDrawTarget that queues up
@@ -37,12 +38,16 @@
/**
* Creates a GrInOrderDrawBuffer
*
+ * @param gpu the gpu object where this will be played back
+ * (possible indirectly). GrResources used with the draw
+ * buffer are created by this gpu object.
* @param vertexPool pool where vertices for queued draws will be saved when
* the vertex source is either reserved or array.
* @param indexPool pool where indices for queued draws will be saved when
* the index source is either reserved or array.
*/
- GrInOrderDrawBuffer(GrVertexBufferAllocPool* vertexPool,
+ GrInOrderDrawBuffer(const GrGpu* gpu,
+ GrVertexBufferAllocPool* vertexPool,
GrIndexBufferAllocPool* indexPool);
virtual ~GrInOrderDrawBuffer();
@@ -86,6 +91,8 @@
virtual void clear(const GrIRect* rect, GrColor color);
+ virtual bool willUseHWAALines() const;
+
private:
struct Draw {
@@ -138,6 +145,7 @@
void pushState();
void pushClip();
+ const GrGpu* fGpu;
GrTAllocator<Draw> fDraws;
GrTAllocator<SavedDrawState> fStates;
GrTAllocator<Clear> fClears;