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
This commit is contained in:
bsalomon@google.com 2011-08-23 15:45:25 +00:00
parent 00245c94cd
commit 471d471dcd
11 changed files with 91 additions and 49 deletions

View File

@ -586,7 +586,7 @@ private:
// determines whether offscreen AA should be applied
bool doOffscreenAA(GrDrawTarget* target,
const GrPaint& paint,
bool isLines) const;
bool isHairLines) const;
// attempts to setup offscreen AA. All paint state must be transferred to
// target by the time this is called.

View File

@ -197,8 +197,8 @@ enum GrPrimitiveType {
kTriangleStrip_PrimitiveType,
kTriangleFan_PrimitiveType,
kPoints_PrimitiveType,
kLines_PrimitiveType,
kLineStrip_PrimitiveType
kLines_PrimitiveType, // 1 pix wide only
kLineStrip_PrimitiveType // 1 pix wide only
};
static inline bool GrIsPrimTypeLines(GrPrimitiveType type) {

View File

@ -630,16 +630,16 @@ struct GrContext::OffscreenRecord {
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 isIRect(const GrRect& r) {
}
static bool apply_aa_to_rect(GrDrawTarget* target,
GrGpu* gpu,
const GrPaint& paint,
const GrRect& rect,
GrScalar width,
@ -1134,7 +1133,7 @@ static bool apply_aa_to_rect(GrDrawTarget* target,
return false;
}
if (0 == width && gpu->supportsAALines()) {
if (0 == width && target->willUseHWAALines()) {
return false;
}
@ -1174,7 +1173,7 @@ void GrContext::drawRect(const GrPaint& paint,
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 @@ void GrContext::setupDrawBuffer() {
DRAW_BUFFER_IBPOOL_BUFFER_SIZE,
DRAW_BUFFER_IBPOOL_PREALLOC_BUFFERS);
fDrawBuffer = new GrInOrderDrawBuffer(fDrawBufferVBAllocPool,
fDrawBuffer = new GrInOrderDrawBuffer(fGpu,
fDrawBufferVBAllocPool,
fDrawBufferIBAllocPool);
#endif

View File

@ -695,47 +695,47 @@ void GrDrawTarget::drawNonIndexed(GrPrimitiveType type,
////////////////////////////////////////////////////////////////////////////////
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 @@ bool GrDrawTarget::canDisableBlend() const {
// ...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 @@ bool GrDrawTarget::canDisableBlend() const {
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));

View File

@ -535,6 +535,13 @@ public:
*/
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.
*
@ -1142,7 +1149,13 @@ public:
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

View File

@ -142,6 +142,13 @@ void GrGpu::unimpl(const char msg[]) {
////////////////////////////////////////////////////////////////////////////////
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();

View File

@ -181,7 +181,7 @@ public:
* 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 @@ public:
*/
void removeResource(GrResource* resource);
// GrDrawTarget overrides
virtual bool willUseHWAALines() const;
protected:
enum PrivateStateBits {
kFirstBit = (kLastPublicStateBit << 1),

View File

@ -1813,18 +1813,6 @@ void GrGpuGL::flushStencil() {
}
}
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 @@ void GrGpuGL::flushAAState(GrPrimitiveType type) {
// 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::flushAAState(GrPrimitiveType type) {
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;

View File

@ -164,8 +164,6 @@ private:
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);

View File

@ -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 @@ GrInOrderDrawBuffer::GrInOrderDrawBuffer(GrVertexBufferAllocPool* vertexPool,
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(GrVertexBufferAllocPool* vertexPool,
GrInOrderDrawBuffer::~GrInOrderDrawBuffer() {
this->reset();
GrSafeUnref(fQuadIndexBuffer);
fGpu->unref();
}
void GrInOrderDrawBuffer::initializeDrawStateAndClip(const GrDrawTarget& target) {
@ -620,3 +625,9 @@ void GrInOrderDrawBuffer::clipWillBeSet(const GrClip& newClip) {
INHERITED::clipWillBeSet(newClip);
fClipSet = true;
}
bool GrInOrderDrawBuffer::willUseHWAALines() const {
return fGpu->supportsHWAALines() &&
CanUseHWAALines(this->getGeomSrc().fVertexLayout, fCurrDrawState);
}

View File

@ -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 @@ public:
/**
* 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 @@ public:
virtual void clear(const GrIRect* rect, GrColor color);
virtual bool willUseHWAALines() const;
private:
struct Draw {
@ -138,6 +145,7 @@ private:
void pushState();
void pushClip();
const GrGpu* fGpu;
GrTAllocator<Draw> fDraws;
GrTAllocator<SavedDrawState> fStates;
GrTAllocator<Clear> fClears;