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:
parent
00245c94cd
commit
471d471dcd
@ -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.
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
||||
|
@ -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));
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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),
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user