Remove GP from drawstate, revision of invariant output for GP

BUG=skia:

Committed: https://skia.googlesource.com/skia/+/c6bc58eded89b0c0a36b8e20e193c200f297a0da

Review URL: https://codereview.chromium.org/791743003
This commit is contained in:
joshualitt 2014-12-11 15:44:02 -08:00 committed by Commit bot
parent 5756aff409
commit 56995b5cc0
53 changed files with 652 additions and 550 deletions

View File

@ -67,3 +67,10 @@ drawbitmapmatrix
#junov skbug.com/3176
pictureimagefilter
#joshualitt
hairlines
patch_primitive
xfermodes3
multipicturedraw_sierpinski_tiled
multipicturedraw_sierpinski_simple

View File

@ -164,11 +164,10 @@ protected:
verts[v].fKLM[2] = eval_line(verts[v].fPosition, klmEqs + 6, 1.f);
}
ds.setGeometryProcessor(gp);
ds.setRenderTarget(rt);
tt.target()->setIndexSourceToBuffer(context->getQuadIndexBuffer());
tt.target()->drawIndexed(&ds, kTriangleFan_GrPrimitiveType, 0, 0, 4, 6);
tt.target()->drawIndexed(&ds, gp, kTriangleFan_GrPrimitiveType, 0, 0,4,6);
}
++col;
if (numCols == col) {
@ -320,11 +319,10 @@ protected:
verts[v].fKLM[2] = eval_line(verts[v].fPosition, klmEqs + 6, 1.f);
}
ds.setGeometryProcessor(gp);
ds.setRenderTarget(rt);
tt.target()->setIndexSourceToBuffer(context->getQuadIndexBuffer());
tt.target()->drawIndexed(&ds, kTriangleFan_GrPrimitiveType, 0, 0, 4, 6);
tt.target()->drawIndexed(&ds, gp, kTriangleFan_GrPrimitiveType, 0, 0,4,6);
}
++col;
if (numCols == col) {
@ -505,11 +503,10 @@ protected:
GrPathUtils::QuadUVMatrix DevToUV(pts);
DevToUV.apply<4, sizeof(Vertex), sizeof(SkPoint)>(verts);
ds.setGeometryProcessor(gp);
ds.setRenderTarget(rt);
tt.target()->setIndexSourceToBuffer(context->getQuadIndexBuffer());
tt.target()->drawIndexed(&ds, kTriangles_GrPrimitiveType, 0, 0, 4, 6);
tt.target()->drawIndexed(&ds, gp, kTriangles_GrPrimitiveType, 0, 0, 4, 6);
}
++col;
if (numCols == col) {

View File

@ -133,8 +133,8 @@ protected:
}
GrDrawState ds;
const GrGeometryProcessor* gp = GrDefaultGeoProcFactory::Create(0xff000000);
ds.setGeometryProcessor(gp)->unref();
SkAutoTUnref<const GrGeometryProcessor> gp(
GrDefaultGeoProcFactory::Create(0xff000000));
ds.addCoverageProcessor(fp);
ds.setIdentityViewMatrix();
ds.setRenderTarget(rt);
@ -150,7 +150,7 @@ protected:
bounds.toQuad(verts);
tt.target()->setIndexSourceToBuffer(context->getQuadIndexBuffer());
tt.target()->drawIndexed(&ds, kTriangleFan_GrPrimitiveType, 0, 0, 4, 6);
tt.target()->drawIndexed(&ds, gp, kTriangleFan_GrPrimitiveType, 0, 0, 4, 6);
x += SkScalarCeilToScalar(path->getBounds().width() + 10.f);
}
@ -190,8 +190,8 @@ protected:
}
GrDrawState ds;
const GrGeometryProcessor* gp = GrDefaultGeoProcFactory::Create(0xff000000);
ds.setGeometryProcessor(gp)->unref();
SkAutoTUnref<const GrGeometryProcessor> gp(
GrDefaultGeoProcFactory::Create(0xff000000));
ds.addCoverageProcessor(fp);
ds.setIdentityViewMatrix();
ds.setRenderTarget(rt);
@ -205,7 +205,7 @@ protected:
bounds.toQuad(verts);
tt.target()->setIndexSourceToBuffer(context->getQuadIndexBuffer());
tt.target()->drawIndexed(&ds, kTriangleFan_GrPrimitiveType, 0, 0, 4, 6);
tt.target()->drawIndexed(&ds, gp, kTriangleFan_GrPrimitiveType, 0, 0, 4, 6);
x += SkScalarCeilToScalar(rect.width() + 10.f);
}

View File

@ -67,6 +67,16 @@ public:
return this->onIsEqual(that);
}
/**
* This function is used to perform optimizations. When called the invarientOuput param
* indicate whether the input components to this processor in the FS will have known values.
* In inout the validFlags member is a bitfield of GrColorComponentFlags. The isSingleComponent
* member indicates whether the input will be 1 or 4 bytes. The function updates the members of
* inout to indicate known values of its output. A component of the color member only has
* meaning if the corresponding bit in validFlags is set.
*/
void computeInvariantOutput(GrInvariantOutput* inout) const;
protected:
/**
* Fragment Processor subclasses call this from their constructor to register coordinate
@ -101,6 +111,11 @@ protected:
*/
void setWillNotUseInputColor() { fWillUseInputColor = false; }
/**
* Subclass implements this to support getConstantColorComponents(...).
*/
virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const = 0;
private:
/**
* Subclass implements this to support isEqual(). It will only be called if it is known that

View File

@ -10,6 +10,49 @@
#include "GrColor.h"
struct GrInitInvariantOutput {
GrInitInvariantOutput()
: fValidFlags(0)
, fColor(0)
, fIsSingleComponent(false)
, fIsLCDCoverage(false) {}
void setKnownFourComponents(GrColor color) {
fColor = color;
fValidFlags = kRGBA_GrColorComponentFlags;
fIsSingleComponent = false;
}
void setUnknownFourComponents() {
fValidFlags = 0;
fIsSingleComponent = false;
}
void setUnknownOpaqueFourComponents() {
fColor = 0xff << GrColor_SHIFT_A;
fValidFlags = kA_GrColorComponentFlag;
fIsSingleComponent = false;
}
void setKnownSingleComponent(uint8_t alpha) {
fColor = GrColorPackRGBA(alpha, alpha, alpha, alpha);
fValidFlags = kRGBA_GrColorComponentFlags;
fIsSingleComponent = true;
}
void setUnknownSingleComponent() {
fValidFlags = 0;
fIsSingleComponent = true;
}
void setUsingLCDCoverage() { fIsLCDCoverage = true; }
uint32_t fValidFlags;
GrColor fColor;
bool fIsSingleComponent;
bool fIsLCDCoverage; // Temorary data member until texture pixel configs are updated
};
class GrInvariantOutput {
public:
GrInvariantOutput(GrColor color, GrColorComponentFlags flags, bool isSingleComponent)
@ -20,6 +63,14 @@ public:
, fWillUseInputColor(true)
, fIsLCDCoverage(false) {}
GrInvariantOutput(const GrInitInvariantOutput& io)
: fColor(io.fColor)
, fValidFlags(io.fValidFlags)
, fIsSingleComponent(io.fIsSingleComponent)
, fNonMulStageFound(false)
, fWillUseInputColor(false)
, fIsLCDCoverage(io.fIsLCDCoverage) {}
virtual ~GrInvariantOutput() {}
enum ReadInput {
@ -27,18 +78,18 @@ public:
kWillNot_ReadInput,
};
void mulByUnknownOpaqueColor() {
void mulByUnknownOpaqueFourComponents() {
if (this->isOpaque()) {
fValidFlags = kA_GrColorComponentFlag;
fIsSingleComponent = false;
} else {
// Since the current state is not opaque we no longer care if the color being
// multiplied is opaque.
this->mulByUnknownColor();
this->mulByUnknownFourComponents();
}
}
void mulByUnknownColor() {
void mulByUnknownFourComponents() {
if (this->hasZeroAlpha()) {
this->internalSetToTransparentBlack();
} else {
@ -46,7 +97,7 @@ public:
}
}
void mulByUnknownAlpha() {
void mulByUnknownSingleComponent() {
if (this->hasZeroAlpha()) {
this->internalSetToTransparentBlack();
} else {
@ -55,7 +106,7 @@ public:
}
}
void mulByKnownAlpha(uint8_t alpha) {
void mulByKnownSingleComponent(uint8_t alpha) {
if (this->hasZeroAlpha() || 0 == alpha) {
this->internalSetToTransparentBlack();
} else {
@ -122,6 +173,15 @@ private:
fWillUseInputColor = true;
}
void reset(const GrInitInvariantOutput& io) {
fColor = io.fColor;
fValidFlags = io.fValidFlags;
fIsSingleComponent = io.fIsSingleComponent;
fNonMulStageFound = false;
fWillUseInputColor = true;
fIsLCDCoverage = io.fIsLCDCoverage;
}
void internalSetToTransparentBlack() {
fValidFlags = kRGBA_GrColorComponentFlags;
fColor = 0;

View File

@ -61,16 +61,6 @@ public:
virtual ~GrProcessor();
/**
* This function is used to perform optimizations. When called the invarientOuput param
* indicate whether the input components to this processor in the FS will have known values.
* In inout the validFlags member is a bitfield of GrColorComponentFlags. The isSingleComponent
* member indicates whether the input will be 1 or 4 bytes. The function updates the members of
* inout to indicate known values of its output. A component of the color member only has
* meaning if the corresponding bit in validFlags is set.
*/
void computeInvariantOutput(GrInvariantOutput* inout) const;
/** Human-meaningful string to identify this prcoessor; may be embedded
in generated shader code. */
virtual const char* name() const = 0;
@ -132,11 +122,6 @@ protected:
uint32_t fClassID;
private:
/**
* Subclass implements this to support getConstantColorComponents(...).
*/
virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const = 0;
static uint32_t GenClassID() {
// fCurrProcessorClassID has been initialized to kIllegalProcessorClassID. The
// atomic inc returns the old value not the incremented value. So we add

View File

@ -134,6 +134,11 @@ protected:
*/
void setWillReadDstColor() { fWillReadDstColor = true; }
/**
* Subclass implements this to support getConstantColorComponents(...).
*/
virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const = 0;
private:
virtual bool onIsEqual(const GrXferProcessor&) const = 0;

View File

@ -230,11 +230,11 @@ bool AlphaThresholdEffect::onIsEqual(const GrFragmentProcessor& sBase) const {
void AlphaThresholdEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const {
if (GrPixelConfigIsAlphaOnly(this->texture(0)->config())) {
inout->mulByUnknownAlpha();
inout->mulByUnknownSingleComponent();
} else if (GrPixelConfigIsOpaque(this->texture(0)->config()) && fOuterThreshold >= 1.f) {
inout->mulByUnknownOpaqueColor();
inout->mulByUnknownOpaqueFourComponents();
} else {
inout->mulByUnknownColor();
inout->mulByUnknownFourComponents();
}
}

View File

@ -817,7 +817,7 @@ bool GrRectBlurEffect::onIsEqual(const GrFragmentProcessor& sBase) const {
}
void GrRectBlurEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const {
inout->mulByUnknownAlpha();
inout->mulByUnknownSingleComponent();
}
GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrRectBlurEffect);
@ -979,7 +979,7 @@ GrFragmentProcessor* GrRRectBlurEffect::Create(GrContext* context, float sigma,
}
void GrRRectBlurEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const {
inout->mulByUnknownAlpha();
inout->mulByUnknownSingleComponent();
}
GrRRectBlurEffect::GrRRectBlurEffect(float sigma, const SkRRect& rrect, GrTexture *ninePatchTexture)

View File

@ -349,7 +349,7 @@ protected:
virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const SK_OVERRIDE {
// lighting shaders are complicated. We just throw up our hands.
inout->mulByUnknownColor();
inout->mulByUnknownFourComponents();
}
private:

View File

@ -1158,9 +1158,9 @@ bool GrGradientEffect::onIsEqual(const GrFragmentProcessor& processor) const {
void GrGradientEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const {
if (fIsOpaque) {
inout->mulByUnknownOpaqueColor();
inout->mulByUnknownOpaqueFourComponents();
} else {
inout->mulByUnknownColor();
inout->mulByUnknownFourComponents();
}
}

View File

@ -596,8 +596,8 @@ private:
return true;
}
virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const SK_OVERRIDE {
inout->mulByUnknownAlpha();
virtual void onGetInvariantOutputCoverage(GrInitInvariantOutput* out) const SK_OVERRIDE {
out->setUnknownSingleComponent();
}
const GrAttribute* fInPosition;
@ -679,8 +679,7 @@ bool GrAAConvexPathRenderer::onDrawPath(GrDrawTarget* target,
// Our computed verts should all be within one pixel of the segment control points.
devBounds.outset(SK_Scalar1, SK_Scalar1);
GrGeometryProcessor* quadProcessor = QuadEdgeEffect::Create(color);
drawState->setGeometryProcessor(quadProcessor)->unref();
SkAutoTUnref<GrGeometryProcessor> quadProcessor(QuadEdgeEffect::Create(color));
GrDrawTarget::AutoReleaseGeometry arg(target, vCount, quadProcessor->getVertexStride(), iCount);
SkASSERT(quadProcessor->getVertexStride() == sizeof(QuadVertex));
@ -709,6 +708,7 @@ bool GrAAConvexPathRenderer::onDrawPath(GrDrawTarget* target,
for (int i = 0; i < draws.count(); ++i) {
const Draw& draw = draws[i];
target->drawIndexed(drawState,
quadProcessor,
kTriangles_GrPrimitiveType,
vOffset, // start vertex
0, // start index

View File

@ -323,14 +323,14 @@ bool GrAADistanceFieldPathRenderer::internalDrawPath(GrDrawTarget* target,
flags |= vm.isSimilarity() ? kSimilarity_DistanceFieldEffectFlag : 0;
GrTextureParams params(SkShader::kRepeat_TileMode, GrTextureParams::kBilerp_FilterMode);
if (flags != fEffectFlags || fCachedGeometryProcessor->getColor() != color) {
if (flags != fEffectFlags || fCachedGeometryProcessor->color() != color) {
fCachedGeometryProcessor.reset(GrDistanceFieldNoGammaTextureEffect::Create(color,
texture,
params,
flags));
flags,
false));
fEffectFlags = flags;
}
drawState->setGeometryProcessor(fCachedGeometryProcessor.get());
void* vertices = NULL;
bool success = target->reserveVertexAndIndexSpace(4,
@ -372,7 +372,8 @@ bool GrAADistanceFieldPathRenderer::internalDrawPath(GrDrawTarget* target,
vm.mapRect(&r);
target->setIndexSourceToBuffer(fContext->getQuadIndexBuffer());
target->drawIndexedInstances(drawState, kTriangles_GrPrimitiveType, 1, 4, 6, &r);
target->drawIndexedInstances(drawState, fCachedGeometryProcessor.get(),
kTriangles_GrPrimitiveType, 1, 4, 6, &r);
target->resetVertexSource();
return true;

View File

@ -644,6 +644,7 @@ void add_line(const SkPoint p[2],
bool GrAAHairLinePathRenderer::createLineGeom(GrDrawTarget* target,
GrDrawState* drawState,
uint8_t coverage,
size_t vertexStride,
GrDrawTarget::AutoReleaseGeometry* arg,
SkRect* devBounds,
const SkPath& path,
@ -653,9 +654,8 @@ bool GrAAHairLinePathRenderer::createLineGeom(GrDrawTarget* target,
int vertCnt = kLineSegNumVertices * lineCnt;
size_t vstride = drawState->getGeometryProcessor()->getVertexStride();
SkASSERT(vstride == sizeof(LineVertex));
if (!arg->set(target, vertCnt, vstride, 0)) {
SkASSERT(vertexStride == sizeof(LineVertex));
if (!arg->set(target, vertCnt, vertexStride, 0)) {
return false;
}
@ -839,13 +839,15 @@ bool GrAAHairLinePathRenderer::onDrawPath(GrDrawTarget* target,
uint32_t gpFlags = GrDefaultGeoProcFactory::kPosition_GPType |
GrDefaultGeoProcFactory::kCoverage_GPType;
GrDrawState::AutoRestoreEffects are(drawState);
drawState->setGeometryProcessor(GrDefaultGeoProcFactory::Create(color,
gpFlags,
newCoverage))->unref();
SkAutoTUnref<const GrGeometryProcessor> gp(GrDefaultGeoProcFactory::Create(color,
gpFlags,
false,
newCoverage));
if (!this->createLineGeom(target,
drawState,
newCoverage,
gp->getVertexStride(),
&arg,
&devBounds,
path,
@ -871,6 +873,7 @@ bool GrAAHairLinePathRenderer::onDrawPath(GrDrawTarget* target,
while (lines < lineCnt) {
int n = SkTMin(lineCnt - lines, kLineSegsNumInIdxBuffer);
target->drawIndexed(drawState,
gp,
kTriangles_GrPrimitiveType,
kLineSegNumVertices*lines, // startV
0, // startI
@ -915,20 +918,20 @@ bool GrAAHairLinePathRenderer::onDrawPath(GrDrawTarget* target,
kQuadNumVertices * quadCnt + kQuadNumVertices * conicCnt));
if (quadCnt > 0) {
GrGeometryProcessor* hairQuadProcessor =
SkAutoTUnref<GrGeometryProcessor> hairQuadProcessor(
GrQuadEffect::Create(color,
kHairlineAA_GrProcessorEdgeType,
*target->caps(),
newCoverage);
newCoverage));
SkASSERT(hairQuadProcessor);
GrDrawState::AutoRestoreEffects are(drawState);
target->setIndexSourceToBuffer(fQuadsIndexBuffer);
drawState->setGeometryProcessor(hairQuadProcessor)->unref();
int quads = 0;
while (quads < quadCnt) {
int n = SkTMin(quadCnt - quads, kQuadsNumInIdxBuffer);
target->drawIndexed(drawState,
hairQuadProcessor,
kTriangles_GrPrimitiveType,
kQuadNumVertices*quads, // startV
0, // startI
@ -941,15 +944,16 @@ bool GrAAHairLinePathRenderer::onDrawPath(GrDrawTarget* target,
if (conicCnt > 0) {
GrDrawState::AutoRestoreEffects are(drawState);
GrGeometryProcessor* hairConicProcessor = GrConicEffect::Create(
color, kHairlineAA_GrProcessorEdgeType, *target->caps(), newCoverage);
SkAutoTUnref<GrGeometryProcessor> hairConicProcessor(
GrConicEffect::Create(color, kHairlineAA_GrProcessorEdgeType, *target->caps(),
newCoverage));
SkASSERT(hairConicProcessor);
drawState->setGeometryProcessor(hairConicProcessor)->unref();
int conics = 0;
while (conics < conicCnt) {
int n = SkTMin(conicCnt - conics, kQuadsNumInIdxBuffer);
target->drawIndexed(drawState,
hairConicProcessor,
kTriangles_GrPrimitiveType,
kQuadNumVertices*(quadCnt + conics), // startV
0, // startI

View File

@ -43,6 +43,7 @@ private:
bool createLineGeom(GrDrawTarget* target,
GrDrawState*,
uint8_t coverage,
size_t vertexStride,
GrDrawTarget::AutoReleaseGeometry* arg,
SkRect* devBounds,
const SkPath& path,

View File

@ -25,20 +25,21 @@ enum CoverageAttribType {
};
}
static CoverageAttribType set_rect_attribs(GrDrawState* drawState, GrColor color) {
static const GrGeometryProcessor* create_rect_gp(const GrDrawState& drawState, GrColor color,
CoverageAttribType* type) {
uint32_t flags = GrDefaultGeoProcFactory::kColor_GPType;
if (drawState->canTweakAlphaForCoverage()) {
drawState->setGeometryProcessor(GrDefaultGeoProcFactory::Create(color, flags))->unref();
SkASSERT(drawState->getGeometryProcessor()->getVertexStride() ==
sizeof(GrDefaultGeoProcFactory::PositionColorAttr));
return kUseColor_CoverageAttribType;
const GrGeometryProcessor* gp;
if (drawState.canTweakAlphaForCoverage()) {
gp = GrDefaultGeoProcFactory::Create(color, flags);
SkASSERT(gp->getVertexStride() == sizeof(GrDefaultGeoProcFactory::PositionColorAttr));
*type = kUseColor_CoverageAttribType;
} else {
flags |= GrDefaultGeoProcFactory::kCoverage_GPType;
drawState->setGeometryProcessor(GrDefaultGeoProcFactory::Create(color, flags))->unref();
SkASSERT(drawState->getGeometryProcessor()->getVertexStride() ==
sizeof(GrDefaultGeoProcFactory::PositionColorCoverageAttr));
return kUseCoverage_CoverageAttribType;
gp = GrDefaultGeoProcFactory::Create(color, flags, GrColorIsOpaque(color));
SkASSERT(gp->getVertexStride()==sizeof(GrDefaultGeoProcFactory::PositionColorCoverageAttr));
*type = kUseCoverage_CoverageAttribType;
}
return gp;
}
static void set_inset_fan(SkPoint* pts, size_t stride,
@ -182,13 +183,11 @@ void GrAARectRenderer::geometryFillAARect(GrDrawTarget* target,
const SkRect& devRect) {
GrDrawState::AutoRestoreEffects are(drawState);
CoverageAttribType covAttribType = set_rect_attribs(drawState, color);
if (kUseCoverage_CoverageAttribType == covAttribType && GrColorIsOpaque(color)) {
drawState->setHint(GrDrawState::kVertexColorsAreOpaque_Hint, true);
}
CoverageAttribType type;
SkAutoTUnref<const GrGeometryProcessor> gp(create_rect_gp(*drawState, color, &type));
size_t vstride = drawState->getGeometryProcessor()->getVertexStride();
GrDrawTarget::AutoReleaseGeometry geo(target, 8, vstride, 0);
size_t vertexStride = gp->getVertexStride();
GrDrawTarget::AutoReleaseGeometry geo(target, 8, vertexStride, 0);
if (!geo.succeeded()) {
SkDebugf("Failed to get space for vertices!\n");
return;
@ -209,7 +208,7 @@ void GrAARectRenderer::geometryFillAARect(GrDrawTarget* target,
intptr_t verts = reinterpret_cast<intptr_t>(geo.vertices());
SkPoint* fan0Pos = reinterpret_cast<SkPoint*>(verts);
SkPoint* fan1Pos = reinterpret_cast<SkPoint*>(verts + 4 * vstride);
SkPoint* fan1Pos = reinterpret_cast<SkPoint*>(verts + 4 * vertexStride);
SkScalar inset = SkMinScalar(devRect.width(), SK_Scalar1);
inset = SK_ScalarHalf * SkMinScalar(inset, devRect.height());
@ -223,8 +222,8 @@ void GrAARectRenderer::geometryFillAARect(GrDrawTarget* target,
combinedMatrix.mapRect(&devRect, rect);
#endif
set_inset_fan(fan0Pos, vstride, devRect, -SK_ScalarHalf, -SK_ScalarHalf);
set_inset_fan(fan1Pos, vstride, devRect, inset, inset);
set_inset_fan(fan0Pos, vertexStride, devRect, -SK_ScalarHalf, -SK_ScalarHalf);
set_inset_fan(fan1Pos, vertexStride, devRect, inset, inset);
} else {
// compute transformed (1, 0) and (0, 1) vectors
SkVector vec[2] = {
@ -239,38 +238,38 @@ void GrAARectRenderer::geometryFillAARect(GrDrawTarget* target,
// create the rotated rect
fan0Pos->setRectFan(rect.fLeft, rect.fTop,
rect.fRight, rect.fBottom, vstride);
combinedMatrix.mapPointsWithStride(fan0Pos, vstride, 4);
rect.fRight, rect.fBottom, vertexStride);
combinedMatrix.mapPointsWithStride(fan0Pos, vertexStride, 4);
// Now create the inset points and then outset the original
// rotated points
// TL
*((SkPoint*)((intptr_t)fan1Pos + 0 * vstride)) =
*((SkPoint*)((intptr_t)fan0Pos + 0 * vstride)) + vec[0] + vec[1];
*((SkPoint*)((intptr_t)fan0Pos + 0 * vstride)) -= vec[0] + vec[1];
*((SkPoint*)((intptr_t)fan1Pos + 0 * vertexStride)) =
*((SkPoint*)((intptr_t)fan0Pos + 0 * vertexStride)) + vec[0] + vec[1];
*((SkPoint*)((intptr_t)fan0Pos + 0 * vertexStride)) -= vec[0] + vec[1];
// BL
*((SkPoint*)((intptr_t)fan1Pos + 1 * vstride)) =
*((SkPoint*)((intptr_t)fan0Pos + 1 * vstride)) + vec[0] - vec[1];
*((SkPoint*)((intptr_t)fan0Pos + 1 * vstride)) -= vec[0] - vec[1];
*((SkPoint*)((intptr_t)fan1Pos + 1 * vertexStride)) =
*((SkPoint*)((intptr_t)fan0Pos + 1 * vertexStride)) + vec[0] - vec[1];
*((SkPoint*)((intptr_t)fan0Pos + 1 * vertexStride)) -= vec[0] - vec[1];
// BR
*((SkPoint*)((intptr_t)fan1Pos + 2 * vstride)) =
*((SkPoint*)((intptr_t)fan0Pos + 2 * vstride)) - vec[0] - vec[1];
*((SkPoint*)((intptr_t)fan0Pos + 2 * vstride)) += vec[0] + vec[1];
*((SkPoint*)((intptr_t)fan1Pos + 2 * vertexStride)) =
*((SkPoint*)((intptr_t)fan0Pos + 2 * vertexStride)) - vec[0] - vec[1];
*((SkPoint*)((intptr_t)fan0Pos + 2 * vertexStride)) += vec[0] + vec[1];
// TR
*((SkPoint*)((intptr_t)fan1Pos + 3 * vstride)) =
*((SkPoint*)((intptr_t)fan0Pos + 3 * vstride)) - vec[0] + vec[1];
*((SkPoint*)((intptr_t)fan0Pos + 3 * vstride)) += vec[0] - vec[1];
*((SkPoint*)((intptr_t)fan1Pos + 3 * vertexStride)) =
*((SkPoint*)((intptr_t)fan0Pos + 3 * vertexStride)) - vec[0] + vec[1];
*((SkPoint*)((intptr_t)fan0Pos + 3 * vertexStride)) += vec[0] - vec[1];
}
// Make verts point to vertex color and then set all the color and coverage vertex attrs values.
verts += sizeof(SkPoint);
for (int i = 0; i < 4; ++i) {
if (kUseCoverage_CoverageAttribType == covAttribType) {
*reinterpret_cast<GrColor*>(verts + i * vstride) = color;
*reinterpret_cast<float*>(verts + i * vstride + sizeof(GrColor)) = 0;
if (kUseCoverage_CoverageAttribType == type) {
*reinterpret_cast<GrColor*>(verts + i * vertexStride) = color;
*reinterpret_cast<float*>(verts + i * vertexStride + sizeof(GrColor)) = 0;
} else {
*reinterpret_cast<GrColor*>(verts + i * vstride) = 0;
*reinterpret_cast<GrColor*>(verts + i * vertexStride) = 0;
}
}
@ -282,22 +281,23 @@ void GrAARectRenderer::geometryFillAARect(GrDrawTarget* target,
scale = 0xff;
}
verts += 4 * vstride;
verts += 4 * vertexStride;
float innerCoverage = GrNormalizeByteToFloat(scale);
GrColor scaledColor = (0xff == scale) ? color : SkAlphaMulQ(color, scale);
for (int i = 0; i < 4; ++i) {
if (kUseCoverage_CoverageAttribType == covAttribType) {
*reinterpret_cast<GrColor*>(verts + i * vstride) = color;
*reinterpret_cast<float*>(verts + i * vstride + sizeof(GrColor)) = innerCoverage;
if (kUseCoverage_CoverageAttribType == type) {
*reinterpret_cast<GrColor*>(verts + i * vertexStride) = color;
*reinterpret_cast<float*>(verts + i * vertexStride + sizeof(GrColor)) = innerCoverage;
} else {
*reinterpret_cast<GrColor*>(verts + i * vstride) = scaledColor;
*reinterpret_cast<GrColor*>(verts + i * vertexStride) = scaledColor;
}
}
target->setIndexSourceToBuffer(indexBuffer);
target->drawIndexedInstances(drawState,
gp,
kTriangles_GrPrimitiveType,
1,
kVertsPerAAFillRect,
@ -383,17 +383,15 @@ void GrAARectRenderer::geometryStrokeAARect(GrDrawTarget* target,
const SkRect& devInside,
bool miterStroke) {
GrDrawState::AutoRestoreEffects are(drawState);
CoverageAttribType covAttribType = set_rect_attribs(drawState, color);
if (kUseCoverage_CoverageAttribType == covAttribType && GrColorIsOpaque(color)) {
drawState->setHint(GrDrawState::kVertexColorsAreOpaque_Hint, true);
}
CoverageAttribType type;
SkAutoTUnref<const GrGeometryProcessor> gp(create_rect_gp(*drawState, color, &type));
int innerVertexNum = 4;
int outerVertexNum = miterStroke ? 4 : 8;
int totalVertexNum = (outerVertexNum + innerVertexNum) * 2;
size_t vstride = drawState->getGeometryProcessor()->getVertexStride();
size_t vstride = gp->getVertexStride();
GrDrawTarget::AutoReleaseGeometry geo(target, totalVertexNum, vstride, 0);
if (!geo.succeeded()) {
SkDebugf("Failed to get space for vertices!\n");
@ -458,7 +456,7 @@ void GrAARectRenderer::geometryStrokeAARect(GrDrawTarget* target,
// The outermost rect has 0 coverage
verts += sizeof(SkPoint);
for (int i = 0; i < outerVertexNum; ++i) {
if (kUseCoverage_CoverageAttribType == covAttribType) {
if (kUseCoverage_CoverageAttribType == type) {
*reinterpret_cast<GrColor*>(verts + i * vstride) = color;
*reinterpret_cast<float*>(verts + i * vstride + sizeof(GrColor)) = 0;
} else {
@ -480,7 +478,7 @@ void GrAARectRenderer::geometryStrokeAARect(GrDrawTarget* target,
verts += outerVertexNum * vstride;
for (int i = 0; i < outerVertexNum + innerVertexNum; ++i) {
if (kUseCoverage_CoverageAttribType == covAttribType) {
if (kUseCoverage_CoverageAttribType == type) {
*reinterpret_cast<GrColor*>(verts + i * vstride) = color;
*reinterpret_cast<float*>(verts + i * vstride + sizeof(GrColor)) = innerCoverage;
} else {
@ -491,7 +489,7 @@ void GrAARectRenderer::geometryStrokeAARect(GrDrawTarget* target,
// The innermost rect has 0 coverage
verts += (outerVertexNum + innerVertexNum) * vstride;
for (int i = 0; i < innerVertexNum; ++i) {
if (kUseCoverage_CoverageAttribType == covAttribType) {
if (kUseCoverage_CoverageAttribType == type) {
*reinterpret_cast<GrColor*>(verts + i * vstride) = color;
*reinterpret_cast<GrColor*>(verts + i * vstride + sizeof(GrColor)) = 0;
} else {
@ -501,6 +499,7 @@ void GrAARectRenderer::geometryStrokeAARect(GrDrawTarget* target,
target->setIndexSourceToBuffer(indexBuffer);
target->drawIndexedInstances(drawState,
gp,
kTriangles_GrPrimitiveType,
1,
totalVertexNum,

View File

@ -549,8 +549,6 @@ void GrBitmapTextContext::flush() {
}
// Grayscale/BW text
case kA8_GrMaskFormat:
drawState.setHint(GrDrawState::kVertexColorsAreOpaque_Hint,
0xFF == GrColorUnpackA(fPaint.getColor()));
break;
default:
SkFAIL("Unexpected mask format.");
@ -561,32 +559,33 @@ void GrBitmapTextContext::flush() {
if (kARGB_GrMaskFormat == fCurrMaskFormat) {
uint32_t textureUniqueID = fCurrTexture->getUniqueID();
if (textureUniqueID != fEffectTextureUniqueID ||
fCachedGeometryProcessor->getColor() != color) {
fCachedGeometryProcessor->color() != color) {
uint32_t flags = GrDefaultGeoProcFactory::kLocalCoord_GPType;
fCachedGeometryProcessor.reset(GrDefaultGeoProcFactory::Create(color, flags));
fCachedTextureProcessor.reset(GrSimpleTextureEffect::Create(fCurrTexture,
SkMatrix::I(),
params));
}
drawState.setGeometryProcessor(fCachedGeometryProcessor.get());
drawState.addColorProcessor(fCachedTextureProcessor.get());
} else {
uint32_t textureUniqueID = fCurrTexture->getUniqueID();
if (textureUniqueID != fEffectTextureUniqueID ||
fCachedGeometryProcessor->getColor() != color) {
fCachedGeometryProcessor->color() != color) {
bool hasColor = kA8_GrMaskFormat == fCurrMaskFormat;
bool opaqueVertexColors = GrColorIsOpaque(fPaint.getColor());
fCachedGeometryProcessor.reset(GrBitmapTextGeoProc::Create(color,
fCurrTexture,
params,
hasColor));
fCurrTexture,
params,
hasColor,
opaqueVertexColors));
fEffectTextureUniqueID = textureUniqueID;
}
drawState.setGeometryProcessor(fCachedGeometryProcessor.get());
}
int nGlyphs = fCurrVertex / kVerticesPerGlyph;
fDrawTarget->setIndexSourceToBuffer(fContext->getQuadIndexBuffer());
fDrawTarget->drawIndexedInstances(&drawState,
fCachedGeometryProcessor.get(),
kTriangles_GrPrimitiveType,
nGlyphs,
kVerticesPerGlyph,

View File

@ -315,8 +315,8 @@ GrTexture* GrContext::createResizedTexture(const GrSurfaceDesc& desc,
uint32_t flags = GrDefaultGeoProcFactory::kPosition_GPType |
GrDefaultGeoProcFactory::kLocalCoord_GPType;
const GrGeometryProcessor* gp = GrDefaultGeoProcFactory::Create(GrColor_WHITE, flags);
drawState.setGeometryProcessor(gp)->unref();
SkAutoTUnref<const GrGeometryProcessor> gp(
GrDefaultGeoProcFactory::Create(GrColor_WHITE, flags));
GrDrawTarget::AutoReleaseGeometry arg(fDrawBuffer, 4, gp->getVertexStride(), 0);
SkASSERT(gp->getVertexStride() == 2 * sizeof(SkPoint));
@ -325,7 +325,7 @@ GrTexture* GrContext::createResizedTexture(const GrSurfaceDesc& desc,
SkPoint* verts = (SkPoint*) arg.vertices();
verts[0].setIRectFan(0, 0, texture->width(), texture->height(), 2 * sizeof(SkPoint));
verts[1].setIRectFan(0, 0, 1, 1, 2 * sizeof(SkPoint));
fDrawBuffer->drawNonIndexed(&drawState, kTriangleFan_GrPrimitiveType, 0, 4);
fDrawBuffer->drawNonIndexed(&drawState, gp, kTriangleFan_GrPrimitiveType, 0, 4);
}
} else {
// TODO: Our CPU stretch doesn't filter. But we create separate
@ -758,8 +758,7 @@ void GrContext::drawRect(const GrPaint& paint,
// unitSquareVertexBuffer()
static const int worstCaseVertCount = 10;
const GrGeometryProcessor* gp = GrDefaultGeoProcFactory::Create(color);
drawState.setGeometryProcessor(gp)->unref();
SkAutoTUnref<const GrGeometryProcessor> gp(GrDefaultGeoProcFactory::Create(color));
GrDrawTarget::AutoReleaseGeometry geo(target,
worstCaseVertCount,
gp->getVertexStride(),
@ -790,7 +789,7 @@ void GrContext::drawRect(const GrPaint& paint,
vertex[4].set(rect.fLeft, rect.fTop);
}
target->drawNonIndexed(&drawState, primType, 0, vertCount);
target->drawNonIndexed(&drawState, gp, primType, 0, vertCount);
} else {
// filled BW rect
target->drawSimpleRect(&drawState, color, rect);
@ -813,12 +812,11 @@ void GrContext::drawRectToRect(const GrPaint& paint,
target->drawRect(&drawState, paint.getColor(), dstRect, &localRect, localMatrix);
}
static void set_vertex_attributes(GrDrawState* drawState,
const SkPoint* texCoords,
const GrColor* colors,
int* colorOffset,
int* texOffset,
GrColor color) {
static const GrGeometryProcessor* set_vertex_attributes(const SkPoint* texCoords,
const GrColor* colors,
int* colorOffset,
int* texOffset,
GrColor color) {
*texOffset = -1;
*colorOffset = -1;
@ -835,7 +833,7 @@ static void set_vertex_attributes(GrDrawState* drawState,
*colorOffset = sizeof(SkPoint);
flags |= GrDefaultGeoProcFactory::kColor_GPType;
}
drawState->setGeometryProcessor(GrDefaultGeoProcFactory::Create(color, flags))->unref();
return GrDefaultGeoProcFactory::Create(color, flags);
}
void GrContext::drawVertices(const GrPaint& paint,
@ -858,10 +856,10 @@ void GrContext::drawVertices(const GrPaint& paint,
GR_CREATE_TRACE_MARKER("GrContext::drawVertices", target);
int colorOffset = -1, texOffset = -1;
set_vertex_attributes(&drawState, texCoords, colors, &colorOffset, &texOffset,
paint.getColor());
SkAutoTUnref<const GrGeometryProcessor> gp(
set_vertex_attributes(texCoords, colors, &colorOffset, &texOffset, paint.getColor()));
size_t vertexStride = drawState.getGeometryProcessor()->getVertexStride();
size_t vertexStride = gp->getVertexStride();
SkASSERT(vertexStride == sizeof(SkPoint) + (SkToBool(texCoords) ? sizeof(SkPoint) : 0)
+ (SkToBool(colors) ? sizeof(GrColor) : 0));
if (!geo.set(target, vertexCount, vertexStride, indexCount)) {
@ -889,9 +887,9 @@ void GrContext::drawVertices(const GrPaint& paint,
for (int i = 0; i < indexCount; ++i) {
curIndex[i] = indices[i];
}
target->drawIndexed(&drawState, primitiveType, 0, 0, vertexCount, indexCount);
target->drawIndexed(&drawState, gp, primitiveType, 0, 0, vertexCount, indexCount);
} else {
target->drawNonIndexed(&drawState, primitiveType, 0, vertexCount);
target->drawNonIndexed(&drawState, gp, primitiveType, 0, vertexCount);
}
}

View File

@ -21,8 +21,9 @@ typedef GrDefaultGeoProcFactory Flag;
class DefaultGeoProc : public GrGeometryProcessor {
public:
static GrGeometryProcessor* Create(GrColor color, uint8_t coverage, uint32_t gpTypeFlags) {
return SkNEW_ARGS(DefaultGeoProc, (color, coverage, gpTypeFlags));
static GrGeometryProcessor* Create(GrColor color, uint8_t coverage, uint32_t gpTypeFlags,
bool opaqueVertexColors) {
return SkNEW_ARGS(DefaultGeoProc, (color, coverage, gpTypeFlags, opaqueVertexColors));
}
virtual const char* name() const SK_OVERRIDE { return "DefaultGeometryProcessor"; }
@ -95,8 +96,8 @@ public:
}
private:
DefaultGeoProc(GrColor color, uint8_t coverage, uint32_t gpTypeFlags)
: INHERITED(color, coverage)
DefaultGeoProc(GrColor color, uint8_t coverage, uint32_t gpTypeFlags, bool opaqueVertexColors)
: INHERITED(color, opaqueVertexColors, coverage)
, fInPosition(NULL)
, fInColor(NULL)
, fInLocalCoords(NULL)
@ -128,11 +129,12 @@ private:
return gp.fFlags == this->fFlags;
}
virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const SK_OVERRIDE {
virtual void onGetInvariantOutputCoverage(GrInitInvariantOutput* out) const SK_OVERRIDE {
if (fInCoverage) {
inout->mulByUnknownAlpha();
out->setUnknownSingleComponent();
} else {
inout->mulByKnownAlpha(255);
// uniform coverage
out->setKnownSingleComponent(this->coverage());
}
}
@ -164,10 +166,13 @@ GrGeometryProcessor* DefaultGeoProc::TestCreate(SkRandom* random,
flags |= GrDefaultGeoProcFactory::kLocalCoord_GPType;
}
return DefaultGeoProc::Create(GrRandomColor(random), GrRandomCoverage(random), flags);
return DefaultGeoProc::Create(GrRandomColor(random), GrRandomCoverage(random),
flags, random->nextBool());
}
const GrGeometryProcessor* GrDefaultGeoProcFactory::Create(GrColor color, uint32_t gpTypeFlags,
const GrGeometryProcessor* GrDefaultGeoProcFactory::Create(GrColor color,
uint32_t gpTypeFlags,
bool opaqueVertexColors,
uint8_t coverage) {
return DefaultGeoProc::Create(color, coverage, gpTypeFlags);
return DefaultGeoProc::Create(color, coverage, gpTypeFlags, opaqueVertexColors);
}

View File

@ -80,7 +80,9 @@ public:
*
* You must unref the return from Create.
*/
static const GrGeometryProcessor* Create(GrColor, uint32_t gpTypeFlags = 0,
static const GrGeometryProcessor* Create(GrColor,
uint32_t gpTypeFlags = 0,
bool opaqueVertexColors = false,
uint8_t coverage = 0xff);
static size_t DefaultVertexStride() { return sizeof(PositionAttr); }
};

View File

@ -498,12 +498,14 @@ bool GrDefaultPathRenderer::internalDrawPath(GrDrawTarget* target,
drawState->enableState(GrDrawState::kNoColorWrites_StateBit);
}
GrDrawState::AutoRestoreEffects are(drawState);
drawState->setGeometryProcessor(
SkAutoTUnref<const GrGeometryProcessor> gp(
GrDefaultGeoProcFactory::Create(color,
GrDefaultGeoProcFactory::kPosition_GPType,
newCoverage))->unref();
false,
newCoverage));
if (indexCnt) {
target->drawIndexed(drawState,
gp,
primType,
0,
0,
@ -511,7 +513,7 @@ bool GrDefaultPathRenderer::internalDrawPath(GrDrawTarget* target,
indexCnt,
&devBounds);
} else {
target->drawNonIndexed(drawState, primType, 0, vertexCnt, &devBounds);
target->drawNonIndexed(drawState, gp, primType, 0, vertexCnt, &devBounds);
}
}
}

View File

@ -415,6 +415,7 @@ void GrDistanceFieldTextContext::setupCoverageEffect(const SkColor& filteredColo
flags));
} else {
flags |= kColorAttr_DistanceFieldEffectFlag;
bool opaque = GrColorIsOpaque(color);
#ifdef SK_GAMMA_APPLY_TO_A8
U8CPU lum = SkColorSpaceLuminance::computeLuminance(fDeviceProperties.gamma(),
filteredColor);
@ -424,12 +425,14 @@ void GrDistanceFieldTextContext::setupCoverageEffect(const SkColor& filteredColo
fGammaTexture,
gammaParams,
lum/255.f,
flags));
flags,
opaque));
#else
fCachedGeometryProcessor.reset(GrDistanceFieldNoGammaTextureEffect::Create(color,
fCurrTexture,
params,
flags));
flags,
opaque));
#endif
}
fEffectTextureUniqueID = textureUniqueID;
@ -637,9 +640,6 @@ void GrDistanceFieldTextContext::flush() {
}
this->setupCoverageEffect(filteredColor);
// Effects could be stored with one of the cache objects (atlas?)
drawState.setGeometryProcessor(fCachedGeometryProcessor.get());
// Set draw state
if (fUseLCDText) {
// TODO: move supportsRGBCoverage check to setupCoverageEffect and only add LCD
@ -648,17 +648,15 @@ void GrDistanceFieldTextContext::flush() {
if (!drawState.getXPFactory()->supportsRGBCoverage(0, kRGBA_GrColorComponentFlags)) {
SkDebugf("LCD Text will not draw correctly.\n");
}
SkASSERT(!drawState.hasColorVertexAttribute());
SkASSERT(!fCachedGeometryProcessor->hasVertexColor());
} else {
if (0xFF == GrColorUnpackA(fPaint.getColor())) {
drawState.setHint(GrDrawState::kVertexColorsAreOpaque_Hint, true);
}
// We're using per-vertex color.
SkASSERT(drawState.hasColorVertexAttribute());
SkASSERT(fCachedGeometryProcessor->hasVertexColor());
}
int nGlyphs = fCurrVertex / kVerticesPerGlyph;
fDrawTarget->setIndexSourceToBuffer(fContext->getQuadIndexBuffer());
fDrawTarget->drawIndexedInstances(&drawState,
fCachedGeometryProcessor.get(),
kTriangles_GrPrimitiveType,
nGlyphs,
kVerticesPerGlyph,

View File

@ -14,7 +14,7 @@
#include "GrXferProcessor.h"
#include "effects/GrPorterDuffXferProcessor.h"
bool GrDrawState::isEqual(const GrDrawState& that) const {
bool GrDrawState::isEqual(const GrDrawState& that, bool explicitLocalCoords) const {
if (this->getRenderTarget() != that.getRenderTarget() ||
this->fColorStages.count() != that.fColorStages.count() ||
this->fCoverageStages.count() != that.fCoverageStages.count() ||
@ -25,17 +25,6 @@ bool GrDrawState::isEqual(const GrDrawState& that) const {
return false;
}
bool explicitLocalCoords = this->hasLocalCoordAttribute();
if (this->hasGeometryProcessor()) {
if (!that.hasGeometryProcessor()) {
return false;
} else if (!this->getGeometryProcessor()->isEqual(*that.getGeometryProcessor())) {
return false;
}
} else if (that.hasGeometryProcessor()) {
return false;
}
if (!this->getXPFactory()->isEqual(*that.getXPFactory())) {
return false;
}
@ -77,13 +66,10 @@ GrDrawState& GrDrawState::operator=(const GrDrawState& that) {
fFlagBits = that.fFlagBits;
fStencilSettings = that.fStencilSettings;
fDrawFace = that.fDrawFace;
fGeometryProcessor.reset(SkSafeRef(that.fGeometryProcessor.get()));
fXPFactory.reset(SkRef(that.getXPFactory()));
fColorStages = that.fColorStages;
fCoverageStages = that.fCoverageStages;
fHints = that.fHints;
fColorProcInfoValid = that.fColorProcInfoValid;
fCoverageProcInfoValid = that.fCoverageProcInfoValid;
fColorCache = that.fColorCache;
@ -98,10 +84,9 @@ GrDrawState& GrDrawState::operator=(const GrDrawState& that) {
}
void GrDrawState::onReset(const SkMatrix* initialViewMatrix) {
SkASSERT(0 == fBlockEffectRemovalCnt || 0 == this->numTotalStages());
SkASSERT(0 == fBlockEffectRemovalCnt || 0 == this->numFragmentStages());
fRenderTarget.reset(NULL);
fGeometryProcessor.reset(NULL);
fXPFactory.reset(GrPorterDuffXPFactory::Create(SkXfermode::kSrc_Mode));
fColorStages.reset();
fCoverageStages.reset();
@ -115,13 +100,15 @@ void GrDrawState::onReset(const SkMatrix* initialViewMatrix) {
fStencilSettings.setDisabled();
fDrawFace = kBoth_DrawFace;
fHints = 0;
fColorProcInfoValid = false;
fCoverageProcInfoValid = false;
fColorCache = GrColor_ILLEGAL;
fCoverageCache = GrColor_ILLEGAL;
fColorPrimProc = NULL;
fCoveragePrimProc = NULL;
}
bool GrDrawState::setIdentityViewMatrix() {
@ -143,9 +130,8 @@ bool GrDrawState::setIdentityViewMatrix() {
}
void GrDrawState::setFromPaint(const GrPaint& paint, const SkMatrix& vm, GrRenderTarget* rt) {
SkASSERT(0 == fBlockEffectRemovalCnt || 0 == this->numTotalStages());
SkASSERT(0 == fBlockEffectRemovalCnt || 0 == this->numFragmentStages());
fGeometryProcessor.reset(NULL);
fColorStages.reset();
fCoverageStages.reset();
@ -167,7 +153,6 @@ void GrDrawState::setFromPaint(const GrPaint& paint, const SkMatrix& vm, GrRende
fDrawFace = kBoth_DrawFace;
fStencilSettings.setDisabled();
fFlagBits = 0;
fHints = 0;
// Enable the clip bit
this->enableState(GrDrawState::kClip_StateBit);
@ -199,7 +184,7 @@ bool GrDrawState::canUseFracCoveragePrimProc(GrColor color, const GrDrawTargetCa
this->isCoverageDrawing(), this->isColorWriteDisabled());
}
bool GrDrawState::hasSolidCoverage(GrColor coverage) const {
bool GrDrawState::hasSolidCoverage(const GrPrimitiveProcessor* pp) const {
// If we're drawing coverage directly then coverage is effectively treated as color.
if (this->isCoverageDrawing()) {
return true;
@ -209,15 +194,15 @@ bool GrDrawState::hasSolidCoverage(GrColor coverage) const {
return false;
}
this->calcCoverageInvariantOutput(coverage);
this->calcCoverageInvariantOutput(pp);
return fCoverageProcInfo.isSolidWhite();
}
//////////////////////////////////////////////////////////////////////////////s
bool GrDrawState::willEffectReadDstColor(GrColor color, GrColor coverage) const {
this->calcColorInvariantOutput(color);
this->calcCoverageInvariantOutput(coverage);
bool GrDrawState::willEffectReadDstColor(const GrPrimitiveProcessor* pp) const {
this->calcColorInvariantOutput(pp);
this->calcCoverageInvariantOutput(pp);
// TODO: Remove need to create the XP here.
// Also once all custom blends are turned into XPs we can remove the need
// to check other stages since only xp's will be able to read dst
@ -237,15 +222,6 @@ bool GrDrawState::willEffectReadDstColor(GrColor color, GrColor coverage) const
void GrDrawState::AutoRestoreEffects::set(GrDrawState* ds) {
if (fDrawState) {
// See the big comment on the class definition about GPs.
if (SK_InvalidUniqueID == fOriginalGPID) {
fDrawState->fGeometryProcessor.reset(NULL);
} else {
SkASSERT(fDrawState->getGeometryProcessor()->getUniqueID() ==
fOriginalGPID);
fOriginalGPID = SK_InvalidUniqueID;
}
int m = fDrawState->numColorStages() - fColorEffectCnt;
SkASSERT(m >= 0);
fDrawState->fColorStages.pop_back_n(m);
@ -261,10 +237,6 @@ void GrDrawState::AutoRestoreEffects::set(GrDrawState* ds) {
}
fDrawState = ds;
if (NULL != ds) {
SkASSERT(SK_InvalidUniqueID == fOriginalGPID);
if (NULL != ds->getGeometryProcessor()) {
fOriginalGPID = ds->getGeometryProcessor()->getUniqueID();
}
fColorEffectCnt = ds->numColorStages();
fCoverageEffectCnt = ds->numCoverageStages();
SkDEBUGCODE(++ds->fBlockEffectRemovalCnt;)
@ -374,38 +346,35 @@ GrDrawState::~GrDrawState() {
////////////////////////////////////////////////////////////////////////////////
bool GrDrawState::srcAlphaWillBeOne(GrColor color, GrColor coverage) const {
this->calcColorInvariantOutput(color);
if (this->isCoverageDrawing()) {
this->calcCoverageInvariantOutput(coverage);
return (fColorProcInfo.isOpaque() && fCoverageProcInfo.isOpaque());
}
return fColorProcInfo.isOpaque();
}
bool GrDrawState::willBlendWithDst(GrColor color, GrColor coverage) const {
this->calcColorInvariantOutput(color);
this->calcCoverageInvariantOutput(coverage);
bool GrDrawState::willBlendWithDst(const GrPrimitiveProcessor* pp) const {
this->calcColorInvariantOutput(pp);
this->calcCoverageInvariantOutput(pp);
return fXPFactory->willBlendWithDst(fColorProcInfo, fCoverageProcInfo,
this->isCoverageDrawing(), this->isColorWriteDisabled());
}
void GrDrawState::calcColorInvariantOutput(const GrPrimitiveProcessor* pp) const {
if (!fColorProcInfoValid || fColorPrimProc != pp) {
fColorProcInfo.calcColorWithPrimProc(pp, fColorStages.begin(), this->numColorStages());
fColorProcInfoValid = true;
fColorPrimProc = pp;
}
}
void GrDrawState::calcCoverageInvariantOutput(const GrPrimitiveProcessor* pp) const {
if (!fCoverageProcInfoValid || fCoveragePrimProc != pp) {
fCoverageProcInfo.calcCoverageWithPrimProc(pp, fCoverageStages.begin(),
this->numCoverageStages());
fCoverageProcInfoValid = true;
fCoveragePrimProc = pp;
}
}
void GrDrawState::calcColorInvariantOutput(GrColor color) const {
if (!fColorProcInfoValid || color != fColorCache) {
GrColorComponentFlags flags;
if (this->hasColorVertexAttribute()) {
if (fHints & kVertexColorsAreOpaque_Hint) {
flags = kA_GrColorComponentFlag;
color = 0xFF << GrColor_SHIFT_A;
} else {
flags = static_cast<GrColorComponentFlags>(0);
color = 0;
}
} else {
flags = kRGBA_GrColorComponentFlags;
}
fColorProcInfo.calcWithInitialValues(fColorStages.begin(), this->numColorStages(),
color, flags, false);
GrColorComponentFlags flags = kRGBA_GrColorComponentFlags;
fColorProcInfo.calcWithInitialValues(fColorStages.begin(), this->numColorStages(), color,
flags, false);
fColorProcInfoValid = true;
fColorCache = color;
}
@ -413,16 +382,10 @@ void GrDrawState::calcColorInvariantOutput(GrColor color) const {
void GrDrawState::calcCoverageInvariantOutput(GrColor coverage) const {
if (!fCoverageProcInfoValid || coverage != fCoverageCache) {
GrColorComponentFlags flags;
// Check if per-vertex or constant color may have partial alpha
if (this->hasCoverageVertexAttribute()) {
flags = static_cast<GrColorComponentFlags>(0);
coverage = 0;
} else {
flags = kRGBA_GrColorComponentFlags;
}
fCoverageProcInfo.calcWithInitialValues(fCoverageStages.begin(), this->numCoverageStages(),
coverage, flags, true, fGeometryProcessor.get());
GrColorComponentFlags flags = kRGBA_GrColorComponentFlags;
fCoverageProcInfo.calcWithInitialValues(fCoverageStages.begin(),
this->numCoverageStages(), coverage, flags,
true);
fCoverageProcInfoValid = true;
fCoverageCache = coverage;
}

View File

@ -68,21 +68,6 @@ public:
*/
void setFromPaint(const GrPaint& , const SkMatrix& viewMatrix, GrRenderTarget*);
///////////////////////////////////////////////////////////////////////////
/// @name Vertex Attributes
////
// TODO when we move this info off of GrGeometryProcessor, delete these
bool hasLocalCoordAttribute() const {
return this->hasGeometryProcessor() && this->getGeometryProcessor()->hasLocalCoords();
}
bool hasColorVertexAttribute() const {
return this->hasGeometryProcessor() && this->getGeometryProcessor()->hasVertexColor();
}
bool hasCoverageVertexAttribute() const {
return this->hasGeometryProcessor() && this->getGeometryProcessor()->hasVertexCoverage();
}
/// @}
/**
@ -100,29 +85,13 @@ public:
/**
* Determines whether the output coverage is guaranteed to be one for all pixels hit by a draw.
*/
bool hasSolidCoverage(GrColor coverage) const;
bool hasSolidCoverage(const GrPrimitiveProcessor*) const;
/**
* This function returns true if the render target destination pixel values will be read for
* blending during draw.
*/
bool willBlendWithDst(GrColor color, GrColor coverage) const;
/// @}
/**
* The geometry processor is the sole element of the skia pipeline which can use the vertex,
* geometry, and tesselation shaders. The GP may also compute a coverage in its fragment shader
* but is never put in the color processing pipeline.
*/
const GrGeometryProcessor* setGeometryProcessor(const GrGeometryProcessor* geometryProcessor) {
SkASSERT(geometryProcessor);
SkASSERT(!this->hasGeometryProcessor());
fGeometryProcessor.reset(SkRef(geometryProcessor));
fCoverageProcInfoValid = false;
return geometryProcessor;
}
bool willBlendWithDst(const GrPrimitiveProcessor*) const;
///////////////////////////////////////////////////////////////////////////
/// @name Effect Stages
@ -147,12 +116,6 @@ public:
int numColorStages() const { return fColorStages.count(); }
int numCoverageStages() const { return fCoverageStages.count(); }
int numFragmentStages() const { return this->numColorStages() + this->numCoverageStages(); }
int numTotalStages() const {
return this->numFragmentStages() + (this->hasGeometryProcessor() ? 1 : 0);
}
bool hasGeometryProcessor() const { return SkToBool(fGeometryProcessor.get()); }
const GrGeometryProcessor* getGeometryProcessor() const { return fGeometryProcessor.get(); }
const GrXPFactory* getXPFactory() const { return fXPFactory.get(); }
@ -163,7 +126,7 @@ public:
* Checks whether any of the effects will read the dst pixel color.
* TODO remove when we have an XP
*/
bool willEffectReadDstColor(GrColor color, GrColor coverage) const;
bool willEffectReadDstColor(const GrPrimitiveProcessor*) const;
/**
* The xfer processor factory.
@ -238,13 +201,11 @@ public:
public:
AutoRestoreEffects()
: fDrawState(NULL)
, fOriginalGPID(SK_InvalidUniqueID)
, fColorEffectCnt(0)
, fCoverageEffectCnt(0) {}
AutoRestoreEffects(GrDrawState* ds)
: fDrawState(NULL)
, fOriginalGPID(SK_InvalidUniqueID)
, fColorEffectCnt(0)
, fCoverageEffectCnt(0) {
this->set(ds);
@ -258,7 +219,6 @@ public:
private:
GrDrawState* fDrawState;
uint32_t fOriginalGPID;
int fColorEffectCnt;
int fCoverageEffectCnt;
};
@ -534,43 +494,34 @@ public:
/// @}
///////////////////////////////////////////////////////////////////////////
/// @name Hints
/// Hints that when provided can enable optimizations.
////
enum Hints {
kVertexColorsAreOpaque_Hint = 0x1,
kLast_Hint = kVertexColorsAreOpaque_Hint
};
void setHint(Hints hint, bool value) { fHints = value ? (fHints | hint) : (fHints & ~hint); }
bool vertexColorsAreOpaque() const { return kVertexColorsAreOpaque_Hint & fHints; }
/// @}
///////////////////////////////////////////////////////////////////////////
GrDrawState& operator= (const GrDrawState& that);
private:
bool isEqual(const GrDrawState& that) const;
bool isEqual(const GrDrawState& that, bool explicitLocalCoords) const;
const GrProcOptInfo& colorProcInfo(GrColor color) const {
this->calcColorInvariantOutput(color);
const GrProcOptInfo& colorProcInfo(const GrPrimitiveProcessor* pp) const {
this->calcColorInvariantOutput(pp);
return fColorProcInfo;
}
const GrProcOptInfo& coverageProcInfo(GrColor coverage) const {
this->calcCoverageInvariantOutput(coverage);
const GrProcOptInfo& coverageProcInfo(const GrPrimitiveProcessor* pp) const {
this->calcCoverageInvariantOutput(pp);
return fCoverageProcInfo;
}
/**
* Determines whether src alpha is guaranteed to be one for all src pixels
* If fColorProcInfoValid is false, function calculates the invariant output for the color
* stages and results are stored in fColorProcInfo.
*/
bool srcAlphaWillBeOne(GrColor color, GrColor coverage) const;
void calcColorInvariantOutput(const GrPrimitiveProcessor*) const;
/**
* If fCoverageProcInfoValid is false, function calculates the invariant output for the coverage
* stages and results are stored in fCoverageProcInfo.
*/
void calcCoverageInvariantOutput(const GrPrimitiveProcessor*) const;
/**
* If fColorProcInfoValid is false, function calculates the invariant output for the color
@ -597,11 +548,9 @@ private:
uint32_t fFlagBits;
GrStencilSettings fStencilSettings;
DrawFace fDrawFace;
SkAutoTUnref<const GrGeometryProcessor> fGeometryProcessor;
SkAutoTUnref<const GrXPFactory> fXPFactory;
FragmentStageArray fColorStages;
FragmentStageArray fCoverageStages;
uint32_t fHints;
mutable GrProcOptInfo fColorProcInfo;
mutable GrProcOptInfo fCoverageProcInfo;
@ -609,6 +558,8 @@ private:
mutable bool fCoverageProcInfoValid;
mutable GrColor fColorCache;
mutable GrColor fCoverageCache;
mutable const GrPrimitiveProcessor* fColorPrimProc;
mutable const GrPrimitiveProcessor* fCoveragePrimProc;
friend class GrOptDrawState;
};

View File

@ -307,6 +307,7 @@ void GrDrawTarget::popGeometrySource() {
////////////////////////////////////////////////////////////////////////////////
bool GrDrawTarget::checkDraw(const GrDrawState& drawState,
const GrGeometryProcessor* gp,
GrPrimitiveType type,
int startVertex,
int startIndex,
@ -349,8 +350,7 @@ bool GrDrawTarget::checkDraw(const GrDrawState& drawState,
SkASSERT(drawState.getRenderTarget());
if (drawState.hasGeometryProcessor()) {
const GrGeometryProcessor* gp = drawState.getGeometryProcessor();
if (gp) {
int numTextures = gp->numTextures();
for (int t = 0; t < numTextures; ++t) {
GrTexture* texture = gp->texture(t);
@ -383,12 +383,10 @@ bool GrDrawTarget::checkDraw(const GrDrawState& drawState,
}
bool GrDrawTarget::setupDstReadIfNecessary(GrDrawState* ds,
GrColor color,
uint8_t coverage,
const GrPrimitiveProcessor* primProc,
GrDeviceCoordTexture* dstCopy,
const SkRect* drawBounds) {
GrColor c = GrColorPackRGBA(coverage, coverage, coverage, coverage);
if (this->caps()->dstReadInShaderSupport() || !ds->willEffectReadDstColor(color, c)) {
if (this->caps()->dstReadInShaderSupport() || !ds->willEffectReadDstColor(primProc)) {
return true;
}
SkIRect copyRect;
@ -436,6 +434,7 @@ bool GrDrawTarget::setupDstReadIfNecessary(GrDrawState* ds,
}
void GrDrawTarget::drawIndexed(GrDrawState* ds,
const GrGeometryProcessor* gp,
GrPrimitiveType type,
int startVertex,
int startIndex,
@ -444,7 +443,7 @@ void GrDrawTarget::drawIndexed(GrDrawState* ds,
const SkRect* devBounds) {
SkASSERT(ds);
if (indexCount > 0 &&
this->checkDraw(*ds, type, startVertex, startIndex, vertexCount, indexCount)) {
this->checkDraw(*ds, gp, type, startVertex, startIndex, vertexCount, indexCount)) {
// Setup clip
GrClipMaskManager::ScissorState scissorState;
@ -471,24 +470,23 @@ void GrDrawTarget::drawIndexed(GrDrawState* ds,
// TODO: We should continue with incorrect blending.
GrDeviceCoordTexture dstCopy;
const GrGeometryProcessor* gp = ds->getGeometryProcessor();
if (!this->setupDstReadIfNecessary(ds, gp->getColor(), gp->getCoverage(), &dstCopy,
devBounds)) {
if (!this->setupDstReadIfNecessary(ds, gp, &dstCopy, devBounds)) {
return;
}
this->setDrawBuffers(&info, gp->getVertexStride());
this->onDraw(*ds, info, scissorState, dstCopy.texture() ? &dstCopy : NULL);
this->onDraw(*ds, gp, info, scissorState, dstCopy.texture() ? &dstCopy : NULL);
}
}
void GrDrawTarget::drawNonIndexed(GrDrawState* ds,
const GrGeometryProcessor* gp,
GrPrimitiveType type,
int startVertex,
int vertexCount,
const SkRect* devBounds) {
SkASSERT(ds);
if (vertexCount > 0 && this->checkDraw(*ds, type, startVertex, -1, vertexCount, -1)) {
if (vertexCount > 0 && this->checkDraw(*ds, gp, type, startVertex, -1, vertexCount, -1)) {
// Setup clip
GrClipMaskManager::ScissorState scissorState;
@ -515,15 +513,13 @@ void GrDrawTarget::drawNonIndexed(GrDrawState* ds,
// TODO: We should continue with incorrect blending.
GrDeviceCoordTexture dstCopy;
const GrGeometryProcessor* gp = ds->getGeometryProcessor();
if (!this->setupDstReadIfNecessary(ds, gp->getColor(), gp->getCoverage(), &dstCopy,
devBounds)) {
if (!this->setupDstReadIfNecessary(ds, gp, &dstCopy, devBounds)) {
return;
}
this->setDrawBuffers(&info, gp->getVertexStride());
this->onDraw(*ds, info, scissorState, dstCopy.texture() ? &dstCopy : NULL);
this->onDraw(*ds, gp, info, scissorState, dstCopy.texture() ? &dstCopy : NULL);
}
}
@ -563,6 +559,7 @@ void GrDrawTarget::getPathStencilSettingsForFilltype(GrPathRendering::FillType f
}
void GrDrawTarget::stencilPath(GrDrawState* ds,
const GrPathProcessor* pathProc,
const GrPath* path,
GrPathRendering::FillType fill) {
// TODO: extract portions of checkDraw that are relevant to path stenciling.
@ -584,11 +581,11 @@ void GrDrawTarget::stencilPath(GrDrawState* ds,
ds->getRenderTarget()->getStencilBuffer(),
&stencilSettings);
this->onStencilPath(*ds, path, scissorState, stencilSettings);
this->onStencilPath(*ds, pathProc, path, scissorState, stencilSettings);
}
void GrDrawTarget::drawPath(GrDrawState* ds,
GrColor color,
const GrPathProcessor* pathProc,
const GrPath* path,
GrPathRendering::FillType fill) {
// TODO: extract portions of checkDraw that are relevant to path rendering.
@ -615,16 +612,16 @@ void GrDrawTarget::drawPath(GrDrawState* ds,
&stencilSettings);
GrDeviceCoordTexture dstCopy;
if (!this->setupDstReadIfNecessary(ds, color, 0xff, &dstCopy, &devBounds)) {
if (!this->setupDstReadIfNecessary(ds, pathProc, &dstCopy, &devBounds)) {
return;
}
this->onDrawPath(*ds, color, path, scissorState, stencilSettings, dstCopy.texture() ? &dstCopy :
NULL);
this->onDrawPath(*ds, pathProc, path, scissorState, stencilSettings, dstCopy.texture() ? &dstCopy :
NULL);
}
void GrDrawTarget::drawPaths(GrDrawState* ds,
GrColor color,
const GrPathProcessor* pathProc,
const GrPathRange* pathRange,
const void* indices,
PathIndexType indexType,
@ -659,11 +656,11 @@ void GrDrawTarget::drawPaths(GrDrawState* ds,
// point, because any context that supports NV_path_rendering will also
// support NV_blend_equation_advanced.
GrDeviceCoordTexture dstCopy;
if (!this->setupDstReadIfNecessary(ds, color, 0xff, &dstCopy, NULL)) {
if (!this->setupDstReadIfNecessary(ds, pathProc, &dstCopy, NULL)) {
return;
}
this->onDrawPaths(*ds, color, pathRange, indices, indexType, transformValues, transformType,
this->onDrawPaths(*ds, pathProc, pathRange, indices, indexType, transformValues, transformType,
count, scissorState, stencilSettings, dstCopy.texture() ? &dstCopy : NULL);
}
@ -733,6 +730,7 @@ void GrDrawTarget::removeGpuTraceMarker(const GrGpuTraceMarker* marker) {
////////////////////////////////////////////////////////////////////////////////
void GrDrawTarget::drawIndexedInstances(GrDrawState* ds,
const GrGeometryProcessor* gp,
GrPrimitiveType type,
int instanceCount,
int verticesPerInstance,
@ -771,8 +769,7 @@ void GrDrawTarget::drawIndexedInstances(GrDrawState* ds,
// TODO: We should continue with incorrect blending.
GrDeviceCoordTexture dstCopy;
const GrGeometryProcessor* gp = ds->getGeometryProcessor();
if (!this->setupDstReadIfNecessary(ds, gp->getColor(), gp->getCoverage(), &dstCopy,devBounds)) {
if (!this->setupDstReadIfNecessary(ds, gp, &dstCopy,devBounds)) {
return;
}
@ -782,13 +779,14 @@ void GrDrawTarget::drawIndexedInstances(GrDrawState* ds,
info.fIndexCount = info.fInstanceCount * indicesPerInstance;
if (this->checkDraw(*ds,
gp,
type,
info.fStartVertex,
info.fStartIndex,
info.fVertexCount,
info.fIndexCount)) {
this->setDrawBuffers(&info, gp->getVertexStride());
this->onDraw(*ds, info, scissorState, dstCopy.texture() ? &dstCopy : NULL);
this->onDraw(*ds, gp, info, scissorState, dstCopy.texture() ? &dstCopy : NULL);
}
info.fStartVertex += info.fVertexCount;
instanceCount -= info.fInstanceCount;

View File

@ -233,6 +233,7 @@ public:
* not a request for clipping.
*/
void drawIndexed(GrDrawState*,
const GrGeometryProcessor*,
GrPrimitiveType type,
int startVertex,
int startIndex,
@ -252,6 +253,7 @@ public:
* not a request for clipping.
*/
void drawNonIndexed(GrDrawState*,
const GrGeometryProcessor*,
GrPrimitiveType type,
int startVertex,
int vertexCount,
@ -263,13 +265,13 @@ public:
* on the draw state (if possible in the 3D API). Note, we will never have an inverse fill
* with stencil path
*/
void stencilPath(GrDrawState*, const GrPath*, GrPathRendering::FillType fill);
void stencilPath(GrDrawState*, const GrPathProcessor*, const GrPath*,GrPathRendering::FillType);
/**
* Draws a path. Fill must not be a hairline. It will respect the HW
* antialias flag on the draw state (if possible in the 3D API).
*/
void drawPath(GrDrawState*, GrColor, const GrPath*, GrPathRendering::FillType fill);
void drawPath(GrDrawState*, const GrPathProcessor*, const GrPath*, GrPathRendering::FillType);
/**
* Draws the aggregate path from combining multiple. Note that this will not
@ -285,7 +287,7 @@ public:
* @param fill Fill type for drawing all the paths
*/
void drawPaths(GrDrawState*,
GrColor,
const GrPathProcessor*,
const GrPathRange* pathRange,
const void* indices,
PathIndexType indexType,
@ -357,6 +359,7 @@ public:
* not a request for clipping.
*/
void drawIndexedInstances(GrDrawState*,
const GrGeometryProcessor*,
GrPrimitiveType type,
int instanceCount,
int verticesPerInstance,
@ -656,8 +659,7 @@ protected:
// but couldn't be made. Otherwise, returns true. This method needs to be protected because it
// needs to be accessed by GLPrograms to setup a correct drawstate
bool setupDstReadIfNecessary(GrDrawState*,
GrColor,
uint8_t,
const GrPrimitiveProcessor*,
GrDeviceCoordTexture* dstCopy,
const SkRect* drawBounds);
@ -698,6 +700,7 @@ private:
virtual void geometrySourceWillPop(const GeometrySrcState& restoredState) = 0;
// subclass called to perform drawing
virtual void onDraw(const GrDrawState&,
const GrGeometryProcessor*,
const DrawInfo&,
const GrClipMaskManager::ScissorState&,
const GrDeviceCoordTexture* dstCopy) = 0;
@ -709,17 +712,18 @@ private:
const SkMatrix* localMatrix) = 0;
virtual void onStencilPath(const GrDrawState&,
const GrPathProcessor*,
const GrPath*,
const GrClipMaskManager::ScissorState&,
const GrStencilSettings&) = 0;
virtual void onDrawPath(const GrDrawState&,
GrColor,
const GrPathProcessor*,
const GrPath*,
const GrClipMaskManager::ScissorState&,
const GrStencilSettings&,
const GrDeviceCoordTexture* dstCopy) = 0;
virtual void onDrawPaths(const GrDrawState&,
GrColor,
const GrPathProcessor*,
const GrPathRange*,
const void* indices,
PathIndexType,
@ -766,6 +770,7 @@ private:
// called by drawIndexed and drawNonIndexed. Use a negative indexCount to
// indicate non-indexed drawing.
bool checkDraw(const GrDrawState&,
const GrGeometryProcessor*,
GrPrimitiveType type,
int startVertex,
int startIndex,

View File

@ -39,6 +39,23 @@ class GrGLCaps;
class GrGLGeometryProcessor;
class GrOptDrawState;
struct GrInitInvariantOutput;
/*
* GrGeometryProcessors and GrPathProcessors may effect invariantColor
*/
class GrPrimitiveProcessor : public GrProcessor {
public:
// TODO GPs and PPs have to provide an initial coverage because the coverage invariant code is
// broken right now
virtual uint8_t coverage() const = 0;
virtual void getInvariantOutputColor(GrInitInvariantOutput* out) const = 0;
virtual void getInvariantOutputCoverage(GrInitInvariantOutput* out) const = 0;
private:
typedef GrProcessor INHERITED;
};
/**
* A GrGeometryProcessor is used to perform computation in the vertex shader and
* add support for custom vertex attributes. A GrGemeotryProcessor is typically
@ -49,12 +66,15 @@ class GrOptDrawState;
* added to the vertex attribute array specified on the GrDrawState.
* GrGeometryProcessor subclasses should be immutable after construction.
*/
class GrGeometryProcessor : public GrProcessor {
class GrGeometryProcessor : public GrPrimitiveProcessor {
public:
GrGeometryProcessor(GrColor color, uint8_t coverage = 0xff)
// TODO the Hint can be handled in a much more clean way when we have deferred geometry or
// atleast bundles
GrGeometryProcessor(GrColor color, bool opaqueVertexColors = false, uint8_t coverage = 0xff)
: fVertexStride(0)
, fColor(color)
, fCoverage(coverage)
, fOpaqueVertexColors(opaqueVertexColors)
, fWillUseGeoShader(false)
, fHasVertexColor(false)
, fHasVertexCoverage(false)
@ -114,11 +134,18 @@ public:
return false;
}
if (!fHasVertexColor && this->getColor() != that.getColor()) {
// TODO remove the hint
if (fHasVertexColor && fOpaqueVertexColors != that.fOpaqueVertexColors) {
return false;
}
if (!fHasVertexCoverage && this->getCoverage() != that.getCoverage()) {
if (!fHasVertexColor && this->color() != that.color()) {
return false;
}
// TODO this is fragile, most gps set their coverage to 0xff so this is okay. In the long
// term this should move to subclasses which set explicit coverage
if (!fHasVertexCoverage && this->coverage() != that.coverage()) {
return false;
}
return this->onIsEqual(that);
@ -133,8 +160,8 @@ public:
virtual void initBatchTracker(GrBatchTracker*, const InitBT&) const {}
GrColor getColor() const { return fColor; }
uint8_t getCoverage() const { return fCoverage; }
GrColor color() const { return fColor; }
uint8_t coverage() const { return fCoverage; }
// TODO this is a total hack until the gp can own whether or not it uses uniform
// color / coverage
@ -142,7 +169,8 @@ public:
bool hasVertexCoverage() const { return fHasVertexCoverage; }
bool hasLocalCoords() const { return fHasLocalCoords; }
void computeInvariantColor(GrInvariantOutput* inout) const;
void getInvariantOutputColor(GrInitInvariantOutput* out) const SK_OVERRIDE;
void getInvariantOutputCoverage(GrInitInvariantOutput* out) const SK_OVERRIDE;
protected:
/**
@ -163,6 +191,9 @@ protected:
void setHasVertexCoverage() { fHasVertexCoverage = true; }
void setHasLocalCoords() { fHasLocalCoords = true; }
virtual void onGetInvariantOutputColor(GrInitInvariantOutput*) const {}
virtual void onGetInvariantOutputCoverage(GrInitInvariantOutput*) const = 0;
private:
virtual bool onIsEqual(const GrGeometryProcessor&) const = 0;
@ -170,6 +201,7 @@ private:
size_t fVertexStride;
GrColor fColor;
uint8_t fCoverage;
bool fOpaqueVertexColors;
bool fWillUseGeoShader;
bool fHasVertexColor;
bool fHasVertexCoverage;
@ -177,4 +209,26 @@ private:
typedef GrProcessor INHERITED;
};
/*
* The path equivalent of the GP. For now this just manages color. In the long term we plan on
* extending this class to handle all nvpr uniform / varying / program work.
*/
class GrPathProcessor : public GrPrimitiveProcessor {
public:
static GrPathProcessor* Create(GrColor color) {
return SkNEW_ARGS(GrPathProcessor, (color));
}
const char* name() const SK_OVERRIDE { return "PathProcessor"; }
uint8_t coverage() const SK_OVERRIDE { return 0xff; }
void getInvariantOutputColor(GrInitInvariantOutput* out) const SK_OVERRIDE;
void getInvariantOutputCoverage(GrInitInvariantOutput* out) const SK_OVERRIDE;
private:
GrPathProcessor(GrColor color) : fColor(color) {}
GrColor fColor;
typedef GrProcessor INHERITED;
};
#endif

View File

@ -62,14 +62,13 @@ void get_vertex_bounds(const void* vertices,
The vertex attrib order is always pos, color, [local coords].
*/
static void set_vertex_attributes(GrDrawState* drawState, bool hasLocalCoords, GrColor color) {
static const GrGeometryProcessor* create_rect_gp(GrDrawState* drawState,
bool hasLocalCoords,
GrColor color) {
uint32_t flags = GrDefaultGeoProcFactory::kPosition_GPType |
GrDefaultGeoProcFactory::kColor_GPType;
flags |= hasLocalCoords ? GrDefaultGeoProcFactory::kLocalCoord_GPType : 0;
drawState->setGeometryProcessor(GrDefaultGeoProcFactory::Create(color, flags))->unref();
if (0xFF == GrColorUnpackA(color)) {
drawState->setHint(GrDrawState::kVertexColorsAreOpaque_Hint, true);
}
return GrDefaultGeoProcFactory::Create(color, flags, GrColorIsOpaque(color));
}
static bool path_fill_type_is_winding(const GrStencilSettings& pathStencilSettings) {
@ -116,9 +115,9 @@ void GrInOrderDrawBuffer::onDrawRect(GrDrawState* ds,
const SkMatrix* localMatrix) {
GrDrawState::AutoRestoreEffects are(ds);
set_vertex_attributes(ds, SkToBool(localRect), color);
SkAutoTUnref<const GrGeometryProcessor> gp(create_rect_gp(ds, SkToBool(localRect), color));
size_t vstride = ds->getGeometryProcessor()->getVertexStride();
size_t vstride = gp->getVertexStride();
SkASSERT(vstride == sizeof(SkPoint) + sizeof(GrColor) + (SkToBool(localRect) ? sizeof(SkPoint) :
0));
AutoReleaseGeometry geo(this, 4, vstride, 0);
@ -165,7 +164,7 @@ void GrInOrderDrawBuffer::onDrawRect(GrDrawState* ds,
}
this->setIndexSourceToBuffer(this->getContext()->getQuadIndexBuffer());
this->drawIndexedInstances(ds, kTriangles_GrPrimitiveType, 1, 4, 6, &devBounds);
this->drawIndexedInstances(ds, gp, kTriangles_GrPrimitiveType, 1, 4, 6, &devBounds);
}
int GrInOrderDrawBuffer::concatInstancedDraw(const GrDrawState& ds, const DrawInfo& info) {
@ -221,13 +220,13 @@ int GrInOrderDrawBuffer::concatInstancedDraw(const GrDrawState& ds, const DrawIn
}
void GrInOrderDrawBuffer::onDraw(const GrDrawState& ds,
const GrGeometryProcessor* gp,
const DrawInfo& info,
const ScissorState& scissorState,
const GrDeviceCoordTexture* dstCopy) {
SkASSERT(info.vertexBuffer() && (!info.isIndexed() || info.indexBuffer()));
const GrGeometryProcessor* gp = ds.getGeometryProcessor();
if (!this->recordStateAndShouldDraw(ds, gp->getColor(), gp->getCoverage(),
if (!this->recordStateAndShouldDraw(ds, gp, NULL,
GrGpu::PrimTypeToDrawType(info.primitiveType()),
scissorState, dstCopy)) {
return;
@ -249,11 +248,12 @@ void GrInOrderDrawBuffer::onDraw(const GrDrawState& ds,
}
void GrInOrderDrawBuffer::onStencilPath(const GrDrawState& ds,
const GrPathProcessor* pathProc,
const GrPath* path,
const GrClipMaskManager::ScissorState& scissorState,
const GrStencilSettings& stencilSettings) {
// Only compare the subset of GrDrawState relevant to path stenciling?
if (!this->recordStateAndShouldDraw(ds, GrColor_WHITE, 0xff, GrGpu::kStencilPath_DrawType,
if (!this->recordStateAndShouldDraw(ds, NULL, pathProc, GrGpu::kStencilPath_DrawType,
scissorState, NULL)) {
return;
}
@ -263,14 +263,14 @@ void GrInOrderDrawBuffer::onStencilPath(const GrDrawState& ds,
}
void GrInOrderDrawBuffer::onDrawPath(const GrDrawState& ds,
GrColor color,
const GrPathProcessor* pathProc,
const GrPath* path,
const GrClipMaskManager::ScissorState& scissorState,
const GrStencilSettings& stencilSettings,
const GrDeviceCoordTexture* dstCopy) {
// TODO: Only compare the subset of GrDrawState relevant to path covering?
if (!this->recordStateAndShouldDraw(ds, color, 0xff, GrGpu::kDrawPath_DrawType, scissorState,
dstCopy)) {
if (!this->recordStateAndShouldDraw(ds, NULL, pathProc, GrGpu::kDrawPath_DrawType,
scissorState, dstCopy)) {
return;
}
DrawPath* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPath, (path));
@ -279,7 +279,7 @@ void GrInOrderDrawBuffer::onDrawPath(const GrDrawState& ds,
}
void GrInOrderDrawBuffer::onDrawPaths(const GrDrawState& ds,
GrColor color,
const GrPathProcessor* pathProc,
const GrPathRange* pathRange,
const void* indices,
PathIndexType indexType,
@ -293,7 +293,7 @@ void GrInOrderDrawBuffer::onDrawPaths(const GrDrawState& ds,
SkASSERT(indices);
SkASSERT(transformValues);
if (!this->recordStateAndShouldDraw(ds, color, 0xff, GrGpu::kDrawPath_DrawType, scissorState,
if (!this->recordStateAndShouldDraw(ds, NULL, pathProc, GrGpu::kDrawPath_DrawType, scissorState,
dstCopy)) {
return;
}
@ -324,7 +324,7 @@ void GrInOrderDrawBuffer::onDrawPaths(const GrDrawState& ds,
transformType == previous->fTransformType &&
stencilSettings == previous->fStencilSettings &&
path_fill_type_is_winding(stencilSettings) &&
!ds.willBlendWithDst(color, GrColor_WHITE)) {
!ds.willBlendWithDst(pathProc)) {
// Fold this DrawPaths call into the one previous.
previous->fCount += count;
return;
@ -490,13 +490,13 @@ bool GrInOrderDrawBuffer::onCopySurface(GrSurface* dst,
}
bool GrInOrderDrawBuffer::recordStateAndShouldDraw(const GrDrawState& ds,
GrColor color,
uint8_t coverage,
const GrGeometryProcessor* gp,
const GrPathProcessor* pathProc,
GrGpu::DrawType drawType,
const GrClipMaskManager::ScissorState& scissor,
const GrDeviceCoordTexture* dstCopy) {
SetState* ss = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState,
(ds, color, coverage, *this->getGpu()->caps(), scissor,
(ds, gp, pathProc, *this->getGpu()->caps(), scissor,
dstCopy, drawType));
if (ss->fState.mustSkip()) {
fCmdBuffer.pop_back();

View File

@ -171,11 +171,12 @@ private:
};
struct SetState : public Cmd {
SetState(const GrDrawState& drawState, GrColor color, uint8_t coverage,
const GrDrawTargetCaps& caps, const ScissorState& scissor,
const GrDeviceCoordTexture* dstCopy, GrGpu::DrawType drawType)
SetState(const GrDrawState& drawState, const GrGeometryProcessor* gp,
const GrPathProcessor* pp, const GrDrawTargetCaps& caps,
const ScissorState& scissor, const GrDeviceCoordTexture* dstCopy,
GrGpu::DrawType drawType)
: Cmd(kSetState_Cmd)
, fState(drawState, color, coverage, caps, scissor, dstCopy, drawType) {}
, fState(drawState, gp, pp, caps, scissor, dstCopy, drawType) {}
void execute(GrInOrderDrawBuffer*, const GrOptDrawState*) SK_OVERRIDE;
@ -190,6 +191,7 @@ private:
// overrides from GrDrawTarget
void onDraw(const GrDrawState&,
const GrGeometryProcessor*,
const DrawInfo&,
const ScissorState&,
const GrDeviceCoordTexture* dstCopy) SK_OVERRIDE;
@ -200,17 +202,18 @@ private:
const SkMatrix* localMatrix) SK_OVERRIDE;
void onStencilPath(const GrDrawState&,
const GrPathProcessor*,
const GrPath*,
const ScissorState&,
const GrStencilSettings&) SK_OVERRIDE;
void onDrawPath(const GrDrawState&,
GrColor,
const GrPathProcessor*,
const GrPath*,
const ScissorState&,
const GrStencilSettings&,
const GrDeviceCoordTexture* dstCopy) SK_OVERRIDE;
void onDrawPaths(const GrDrawState&,
GrColor,
const GrPathProcessor*,
const GrPathRange*,
const void* indices,
PathIndexType,
@ -237,8 +240,8 @@ private:
// records it. If the draw can be skipped false is returned and no new GrOptDrawState is
// recorded.
bool SK_WARN_UNUSED_RESULT recordStateAndShouldDraw(const GrDrawState&,
GrColor,
uint8_t coverage,
const GrGeometryProcessor*,
const GrPathProcessor*,
GrGpu::DrawType,
const GrClipMaskManager::ScissorState&,
const GrDeviceCoordTexture*);

View File

@ -14,21 +14,36 @@
#include "GrXferProcessor.h"
GrOptDrawState::GrOptDrawState(const GrDrawState& drawState,
GrColor color,
uint8_t coverage,
const GrGeometryProcessor* gp,
const GrPathProcessor* pathProc,
const GrDrawTargetCaps& caps,
const ScissorState& scissorState,
const GrDeviceCoordTexture* dstCopy,
GrGpu::DrawType drawType)
: fFinalized(false) {
GrColor coverageColor = GrColorPackRGBA(coverage, coverage, coverage, coverage);
fDrawType = drawType;
const GrProcOptInfo& colorPOI = drawState.colorProcInfo(color);
const GrProcOptInfo& coveragePOI = drawState.coverageProcInfo(coverageColor);
// Copy GeometryProcesssor from DS or ODS
if (gp) {
SkASSERT(!pathProc);
SkASSERT(!(GrGpu::IsPathRenderingDrawType(drawType) ||
GrGpu::kStencilPath_DrawType == drawType));
fGeometryProcessor.reset(gp);
fPrimitiveProcessor.reset(gp);
} else {
SkASSERT(!gp && pathProc && (GrGpu::IsPathRenderingDrawType(drawType) ||
GrGpu::kStencilPath_DrawType == drawType));
fPrimitiveProcessor.reset(pathProc);
}
const GrProcOptInfo& colorPOI = drawState.colorProcInfo(fPrimitiveProcessor);
const GrProcOptInfo& coveragePOI = drawState.coverageProcInfo(fPrimitiveProcessor);
fColor = colorPOI.inputColorToEffectiveStage();
fCoverage = coverage;
// TODO fix this when coverage stages work correctly
// fCoverage = coveragePOI.inputColorToEffectiveStage();
fCoverage = fPrimitiveProcessor->coverage();
// Create XferProcessor from DS's XPFactory
SkAutoTUnref<GrXferProcessor> xferProcessor(
@ -83,14 +98,11 @@ GrOptDrawState::GrOptDrawState(const GrDrawState& drawState,
fFlags |= kDither_Flag;
}
fDescInfo.fHasVertexColor = drawState.hasGeometryProcessor() &&
drawState.getGeometryProcessor()->hasVertexColor();
fDescInfo.fHasVertexColor = gp && gp->hasVertexColor();
fDescInfo.fHasVertexCoverage = drawState.hasGeometryProcessor() &&
drawState.getGeometryProcessor()->hasVertexCoverage();
fDescInfo.fHasVertexCoverage = gp && gp->hasVertexCoverage();
bool hasLocalCoords = drawState.hasGeometryProcessor() &&
drawState.getGeometryProcessor()->hasLocalCoords();
bool hasLocalCoords = gp && gp->hasLocalCoords();
int firstColorStageIdx = colorPOI.firstEffectiveStageIndex();
fDescInfo.fInputColorIsUsed = colorPOI.inputColorIsUsed();
@ -103,7 +115,6 @@ GrOptDrawState::GrOptDrawState(const GrDrawState& drawState,
int firstCoverageStageIdx = 0;
fDescInfo.fInputCoverageIsUsed = true;
GrXferProcessor::BlendInfo blendInfo;
fXferProcessor->getBlendInfo(&blendInfo);
@ -112,12 +123,6 @@ GrOptDrawState::GrOptDrawState(const GrDrawState& drawState,
fDescInfo.fRequiresLocalCoordAttrib = hasLocalCoords;
// Copy GeometryProcesssor from DS or ODS
SkASSERT(GrGpu::IsPathRenderingDrawType(drawType) ||
GrGpu::kStencilPath_DrawType ||
drawState.hasGeometryProcessor());
fGeometryProcessor.reset(drawState.getGeometryProcessor());
// Copy Stages from DS to ODS
for (int i = firstColorStageIdx; i < drawState.numColorStages(); ++i) {
SkNEW_APPEND_TO_TARRAY(&fFragmentStages,
@ -133,7 +138,7 @@ GrOptDrawState::GrOptDrawState(const GrDrawState& drawState,
}
// let the GP init the batch tracker
if (drawState.hasGeometryProcessor()) {
if (gp) {
GrGeometryProcessor::InitBT init;
init.fOutputColor = fDescInfo.fInputColorIsUsed;
init.fOutputCoverage = fDescInfo.fInputCoverageIsUsed;

View File

@ -19,6 +19,7 @@
class GrDeviceCoordTexture;
class GrDrawState;
class GrPathProcessor;
/**
* Class that holds an optimized version of a GrDrawState. It is meant to be an immutable class,
@ -30,8 +31,9 @@ public:
typedef GrClipMaskManager::ScissorState ScissorState;
GrOptDrawState(const GrDrawState& drawState, GrColor, uint8_t coverage, const GrDrawTargetCaps&,
const ScissorState&, const GrDeviceCoordTexture* dstCopy, GrGpu::DrawType);
GrOptDrawState(const GrDrawState& drawState, const GrGeometryProcessor*, const GrPathProcessor*,
const GrDrawTargetCaps&, const ScissorState&,
const GrDeviceCoordTexture* dstCopy, GrGpu::DrawType);
bool operator== (const GrOptDrawState& that) const;
bool operator!= (const GrOptDrawState& that) const { return !(*this == that); }
@ -192,7 +194,7 @@ private:
* the function may adjust the blend coefficients. After this function is called the src and dst
* blend coeffs will represent those used by backend API.
*/
void setOutputStateInfo(const GrDrawState& ds, GrColor coverage, GrXferProcessor::OptFlags,
void setOutputStateInfo(const GrDrawState& ds, GrXferProcessor::OptFlags,
const GrDrawTargetCaps&);
enum Flags {
@ -204,6 +206,7 @@ private:
typedef GrPendingIOResource<GrRenderTarget, kWrite_GrIOType> RenderTarget;
typedef SkSTArray<8, GrPendingFragmentStage> FragmentStageArray;
typedef GrPendingProgramElement<const GrGeometryProcessor> ProgramGeometryProcessor;
typedef GrPendingProgramElement<const GrPrimitiveProcessor> ProgramPrimitiveProcessor;
typedef GrPendingProgramElement<const GrXferProcessor> ProgramXferProcessor;
RenderTarget fRenderTarget;
ScissorState fScissorState;
@ -215,6 +218,7 @@ private:
GrDeviceCoordTexture fDstCopy;
uint32_t fFlags;
ProgramGeometryProcessor fGeometryProcessor;
ProgramPrimitiveProcessor fPrimitiveProcessor;
GrBatchTracker fBatchTracker;
ProgramXferProcessor fXferProcessor;
FragmentStageArray fFragmentStages;

View File

@ -144,8 +144,8 @@ private:
return cee.fStroke == fStroke;
}
virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const SK_OVERRIDE {
inout->mulByUnknownAlpha();
virtual void onGetInvariantOutputCoverage(GrInitInvariantOutput* out) const SK_OVERRIDE {
out->setUnknownSingleComponent();
}
const GrAttribute* fInPosition;
@ -290,8 +290,8 @@ private:
return eee.fStroke == fStroke;
}
virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const SK_OVERRIDE {
inout->mulByUnknownAlpha();
virtual void onGetInvariantOutputCoverage(GrInitInvariantOutput* out) const SK_OVERRIDE {
out->setUnknownSingleComponent();
}
const GrAttribute* fInPosition;
@ -455,8 +455,8 @@ private:
return eee.fMode == fMode;
}
virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const SK_OVERRIDE {
inout->mulByUnknownAlpha();
virtual void onGetInvariantOutputCoverage(GrInitInvariantOutput* out) const SK_OVERRIDE {
out->setUnknownSingleComponent();
}
const GrAttribute* fInPosition;
@ -562,8 +562,8 @@ void GrOvalRenderer::drawCircle(GrDrawTarget* target,
}
}
GrGeometryProcessor* gp = CircleEdgeEffect::Create(color, isStrokeOnly && innerRadius > 0);
drawState->setGeometryProcessor(gp)->unref();
SkAutoTUnref<GrGeometryProcessor> gp(
CircleEdgeEffect::Create(color, isStrokeOnly && innerRadius > 0));
GrDrawTarget::AutoReleaseGeometry geo(target, 4, gp->getVertexStride(), 0);
SkASSERT(gp->getVertexStride() == sizeof(CircleVertex));
@ -609,7 +609,7 @@ void GrOvalRenderer::drawCircle(GrDrawTarget* target,
verts[3].fInnerRadius = innerRadius;
target->setIndexSourceToBuffer(context->getGpu()->getQuadIndexBuffer());
target->drawIndexedInstances(drawState, kTriangles_GrPrimitiveType, 1, 4, 6, &bounds);
target->drawIndexedInstances(drawState, gp, kTriangles_GrPrimitiveType, 1, 4, 6, &bounds);
target->resetIndexSource();
}
@ -689,11 +689,8 @@ bool GrOvalRenderer::drawEllipse(GrDrawTarget* target,
return false;
}
GrGeometryProcessor* gp = EllipseEdgeEffect::Create(color,
isStrokeOnly &&
innerXRadius > 0 && innerYRadius > 0);
drawState->setGeometryProcessor(gp)->unref();
SkAutoTUnref<GrGeometryProcessor> gp(
EllipseEdgeEffect::Create(color, isStrokeOnly && innerXRadius > 0 && innerYRadius > 0));
GrDrawTarget::AutoReleaseGeometry geo(target, 4, gp->getVertexStride(), 0);
SkASSERT(gp->getVertexStride() == sizeof(EllipseVertex));
@ -744,7 +741,7 @@ bool GrOvalRenderer::drawEllipse(GrDrawTarget* target,
verts[3].fInnerRadii = SkPoint::Make(xInnerRadRecip, yInnerRadRecip);
target->setIndexSourceToBuffer(context->getGpu()->getQuadIndexBuffer());
target->drawIndexedInstances(drawState, kTriangles_GrPrimitiveType, 1, 4, 6, &bounds);
target->drawIndexedInstances(drawState, gp, kTriangles_GrPrimitiveType, 1, 4, 6, &bounds);
target->resetIndexSource();
return true;
@ -809,9 +806,7 @@ bool GrOvalRenderer::drawDIEllipse(GrDrawTarget* target,
SkScalar innerRatioX = SkScalarDiv(xRadius, innerXRadius);
SkScalar innerRatioY = SkScalarDiv(yRadius, innerYRadius);
GrGeometryProcessor* gp = DIEllipseEdgeEffect::Create(color, mode);
drawState->setGeometryProcessor(gp)->unref();
SkAutoTUnref<GrGeometryProcessor> gp(DIEllipseEdgeEffect::Create(color, mode));
GrDrawTarget::AutoReleaseGeometry geo(target, 4, gp->getVertexStride(), 0);
SkASSERT(gp->getVertexStride() == sizeof(DIEllipseVertex));
@ -857,7 +852,7 @@ bool GrOvalRenderer::drawDIEllipse(GrDrawTarget* target,
verts[3].fInnerOffset = SkPoint::Make(innerRatioX + offsetDx, -innerRatioY - offsetDy);
target->setIndexSourceToBuffer(context->getGpu()->getQuadIndexBuffer());
target->drawIndexedInstances(drawState, kTriangles_GrPrimitiveType, 1, 4, 6, &bounds);
target->drawIndexedInstances(drawState, gp, kTriangles_GrPrimitiveType, 1, 4, 6, &bounds);
target->resetIndexSource();
return true;
@ -1077,8 +1072,7 @@ bool GrOvalRenderer::drawRRect(GrDrawTarget* target,
isStrokeOnly = (isStrokeOnly && innerRadius >= 0);
GrGeometryProcessor* effect = CircleEdgeEffect::Create(color, isStrokeOnly);
drawState->setGeometryProcessor(effect)->unref();
SkAutoTUnref<GrGeometryProcessor> effect(CircleEdgeEffect::Create(color, isStrokeOnly));
GrDrawTarget::AutoReleaseGeometry geo(target, 16, effect->getVertexStride(), 0);
SkASSERT(effect->getVertexStride() == sizeof(CircleVertex));
@ -1140,7 +1134,7 @@ bool GrOvalRenderer::drawRRect(GrDrawTarget* target,
int indexCnt = isStrokeOnly ? SK_ARRAY_COUNT(gRRectIndices) - 6 :
SK_ARRAY_COUNT(gRRectIndices);
target->setIndexSourceToBuffer(indexBuffer);
target->drawIndexedInstances(drawState, kTriangles_GrPrimitiveType, 1, 16, indexCnt,
target->drawIndexedInstances(drawState, effect, kTriangles_GrPrimitiveType, 1, 16, indexCnt,
&bounds);
// otherwise we use the ellipse renderer
@ -1179,8 +1173,7 @@ bool GrOvalRenderer::drawRRect(GrDrawTarget* target,
isStrokeOnly = (isStrokeOnly && innerXRadius >= 0 && innerYRadius >= 0);
GrGeometryProcessor* effect = EllipseEdgeEffect::Create(color, isStrokeOnly);
drawState->setGeometryProcessor(effect)->unref();
SkAutoTUnref<GrGeometryProcessor> effect(EllipseEdgeEffect::Create(color, isStrokeOnly));
GrDrawTarget::AutoReleaseGeometry geo(target, 16, effect->getVertexStride(), 0);
SkASSERT(effect->getVertexStride() == sizeof(EllipseVertex));
@ -1247,7 +1240,7 @@ bool GrOvalRenderer::drawRRect(GrDrawTarget* target,
int indexCnt = isStrokeOnly ? SK_ARRAY_COUNT(gRRectIndices) - 6 :
SK_ARRAY_COUNT(gRRectIndices);
target->setIndexSourceToBuffer(indexBuffer);
target->drawIndexedInstances(drawState, kTriangles_GrPrimitiveType, 1, 16, indexCnt,
target->drawIndexedInstances(drawState, effect, kTriangles_GrPrimitiveType, 1, 16, indexCnt,
&bounds);
}

View File

@ -11,37 +11,58 @@
#include "GrFragmentStage.h"
#include "GrGeometryProcessor.h"
void GrProcOptInfo::calcColorWithPrimProc(const GrPrimitiveProcessor* primProc,
const GrFragmentStage* stages,
int stageCount) {
GrInitInvariantOutput out;
primProc->getInvariantOutputColor(&out);
fInOut.reset(out);
this->internalCalc(stages, stageCount, primProc->willReadFragmentPosition());
}
void GrProcOptInfo::calcCoverageWithPrimProc(const GrPrimitiveProcessor* primProc,
const GrFragmentStage* stages,
int stageCount) {
GrInitInvariantOutput out;
primProc->getInvariantOutputCoverage(&out);
fInOut.reset(out);
this->internalCalc(stages, stageCount, primProc->willReadFragmentPosition());
}
void GrProcOptInfo::calcWithInitialValues(const GrFragmentStage* stages,
int stageCount,
GrColor startColor,
GrColorComponentFlags flags,
bool areCoverageStages,
const GrGeometryProcessor* gp) {
fInOut.reset(startColor, flags, areCoverageStages);
bool areCoverageStages) {
GrInitInvariantOutput out;
out.fIsSingleComponent = areCoverageStages;
out.fColor = startColor;
out.fValidFlags = flags;
fInOut.reset(out);
this->internalCalc(stages, stageCount, false);
}
void GrProcOptInfo::internalCalc(const GrFragmentStage* stages,
int stageCount,
bool initWillReadFragmentPosition) {
fFirstEffectStageIndex = 0;
fInputColorIsUsed = true;
fInputColor = startColor;
fInputColor = fInOut.color();
fRemoveVertexAttrib = false;
fReadsDst = false;
fReadsFragPosition = false;
if (areCoverageStages && gp) {
gp->computeInvariantOutput(&fInOut);
}
fReadsFragPosition = initWillReadFragmentPosition;
for (int i = 0; i < stageCount; ++i) {
const GrFragmentProcessor* processor = stages[i].getProcessor();
fInOut.resetWillUseInputColor();
processor->computeInvariantOutput(&fInOut);
#ifdef SK_DEBUG
fInOut.validate();
#endif
SkDEBUGCODE(fInOut.validate());
if (!fInOut.willUseInputColor()) {
fFirstEffectStageIndex = i;
fInputColorIsUsed = false;
// Reset these since we don't care if previous stages read these values
fReadsDst = false;
fReadsFragPosition = false;
fReadsFragPosition = initWillReadFragmentPosition;
}
if (processor->willReadDstColor()) {
fReadsDst = true;
@ -59,8 +80,7 @@ void GrProcOptInfo::calcWithInitialValues(const GrFragmentStage* stages,
fInOut.resetNonMulStageFound();
// Reset these since we don't care if previous stages read these values
fReadsDst = false;
fReadsFragPosition = false;
fReadsFragPosition = initWillReadFragmentPosition;
}
}
}

View File

@ -13,7 +13,7 @@
class GrFragmentStage;
class GrFragmentProcessor;
class GrGeometryProcessor;
class GrPrimitiveProcessor;
class GrProcessor;
/**
@ -33,8 +33,11 @@ public:
, fReadsFragPosition(false) {}
void calcWithInitialValues(const GrFragmentStage*, int stageCount, GrColor startColor,
GrColorComponentFlags flags, bool areCoverageStages,
const GrGeometryProcessor* gp = NULL);
GrColorComponentFlags flags, bool areCoverageStages);
void calcColorWithPrimProc(const GrPrimitiveProcessor*, const GrFragmentStage*, int stagecount);
void calcCoverageWithPrimProc(const GrPrimitiveProcessor*, const GrFragmentStage*,
int stagecount);
bool isSolidWhite() const { return fInOut.isSolidWhite(); }
bool isOpaque() const { return fInOut.isOpaque(); }
@ -89,6 +92,8 @@ public:
bool readsFragPosition() const { return fReadsFragPosition; }
private:
void internalCalc(const GrFragmentStage*, int stagecount, bool initWillReadFragPosition);
GrInvariantOutput fInOut;
int fFirstEffectStageIndex;
bool fInputColorIsUsed;

View File

@ -145,10 +145,6 @@ bool GrProcessor::hasSameTextureAccesses(const GrProcessor& that) const {
return true;
}
void GrProcessor::computeInvariantOutput(GrInvariantOutput* inout) const {
this->onComputeInvariantOutput(inout);
}
///////////////////////////////////////////////////////////////////////////////////////////////////
void GrFragmentProcessor::addCoordTransform(const GrCoordTransform* transform) {
@ -169,10 +165,37 @@ bool GrFragmentProcessor::hasSameTransforms(const GrFragmentProcessor& that) con
return true;
}
void GrFragmentProcessor::computeInvariantOutput(GrInvariantOutput* inout) const {
this->onComputeInvariantOutput(inout);
}
///////////////////////////////////////////////////////////////////////////////////////////////////
void GrGeometryProcessor::computeInvariantColor(GrInvariantOutput* intout) const {
void GrGeometryProcessor::getInvariantOutputColor(GrInitInvariantOutput* out) const {
if (fHasVertexColor) {
if (fOpaqueVertexColors) {
out->setUnknownOpaqueFourComponents();
} else {
out->setUnknownFourComponents();
}
} else {
out->setKnownFourComponents(fColor);
}
this->onGetInvariantOutputColor(out);
}
void GrGeometryProcessor::getInvariantOutputCoverage(GrInitInvariantOutput* out) const {
this->onGetInvariantOutputCoverage(out);
}
///////////////////////////////////////////////////////////////////////////////////////////////////
void GrPathProcessor::getInvariantOutputColor(GrInitInvariantOutput* out) const {
out->setKnownFourComponents(fColor);
}
void GrPathProcessor::getInvariantOutputCoverage(GrInitInvariantOutput* out) const {
out->setKnownSingleComponent(0xff);
}
///////////////////////////////////////////////////////////////////////////////////////////////////
@ -193,4 +216,3 @@ void GrGeometryData::operator delete(void* target) {
// Initial static variable from GrXPFactory
int32_t GrXPFactory::gCurrXPFClassID =
GrXPFactory::kIllegalXPFClassID;

View File

@ -85,8 +85,9 @@ void GrStencilAndCoverPathRenderer::onStencilPath(GrDrawTarget* target,
const SkPath& path,
const SkStrokeRec& stroke) {
SkASSERT(!path.isInverseFillType());
SkAutoTUnref<GrPathProcessor> pp(GrPathProcessor::Create(GrColor_WHITE));
SkAutoTUnref<GrPath> p(get_gr_path(fGpu, path, stroke));
target->stencilPath(drawState, p, convert_skpath_filltype(path.getFillType()));
target->stencilPath(drawState, pp, p, convert_skpath_filltype(path.getFillType()));
}
bool GrStencilAndCoverPathRenderer::onDrawPath(GrDrawTarget* target,
@ -117,7 +118,8 @@ bool GrStencilAndCoverPathRenderer::onDrawPath(GrDrawTarget* target,
drawState->setStencil(kInvertedStencilPass);
// fake inverse with a stencil and cover
target->stencilPath(drawState, p, convert_skpath_filltype(path.getFillType()));
SkAutoTUnref<GrPathProcessor> pp(GrPathProcessor::Create(GrColor_WHITE));
target->stencilPath(drawState, pp, p, convert_skpath_filltype(path.getFillType()));
GrDrawState::AutoViewMatrixRestore avmr;
SkRect bounds = SkRect::MakeLTRB(0, 0,
@ -145,7 +147,8 @@ bool GrStencilAndCoverPathRenderer::onDrawPath(GrDrawTarget* target,
0xffff);
drawState->setStencil(kStencilPass);
target->drawPath(drawState, color, p, convert_skpath_filltype(path.getFillType()));
SkAutoTUnref<GrPathProcessor> pp(GrPathProcessor::Create(color));
target->drawPath(drawState, pp, p, convert_skpath_filltype(path.getFillType()));
}
drawState->stencil()->setDisabled();

View File

@ -399,7 +399,8 @@ static const SkScalar* get_xy_scalar_array(const SkPoint* pointArray) {
void GrStencilAndCoverTextContext::flush() {
if (fQueuedGlyphCount > 0) {
fDrawTarget->drawPaths(&fDrawState, fPaint.getColor(), fGlyphs,
SkAutoTUnref<GrPathProcessor> pp(GrPathProcessor::Create(fPaint.getColor()));
fDrawTarget->drawPaths(&fDrawState, pp, fGlyphs,
fGlyphIndices, GrPathRange::kU16_PathIndexType,
get_xy_scalar_array(fGlyphPositions),
GrPathRendering::kTranslate_PathTransformType,

View File

@ -140,7 +140,7 @@ GrGLGeometryProcessor* GrConicEffect::createGLInstance(const GrBatchTracker& bt)
}
GrConicEffect::GrConicEffect(GrColor color, uint8_t coverage, GrPrimitiveEdgeType edgeType)
: INHERITED(color, coverage), fEdgeType(edgeType) {
: INHERITED(color, false, coverage), fEdgeType(edgeType) {
this->initClassID<GrConicEffect>();
fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_GrVertexAttribType));
fInConicCoeffs = &this->addVertexAttrib(GrAttribute("inConicCoeffs",
@ -287,7 +287,7 @@ GrGLGeometryProcessor* GrQuadEffect::createGLInstance(const GrBatchTracker& bt)
}
GrQuadEffect::GrQuadEffect(GrColor color, uint8_t coverage, GrPrimitiveEdgeType edgeType)
: INHERITED(color, coverage), fEdgeType(edgeType) {
: INHERITED(color, false, coverage), fEdgeType(edgeType) {
this->initClassID<GrQuadEffect>();
fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_GrVertexAttribType));
fInHairQuadEdge = &this->addVertexAttrib(GrAttribute("inHairQuadEdge",

View File

@ -102,8 +102,8 @@ private:
virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE;
virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const SK_OVERRIDE {
inout->mulByUnknownAlpha();
virtual void onGetInvariantOutputCoverage(GrInitInvariantOutput* out) const SK_OVERRIDE {
out->setUnknownSingleComponent();
}
GrPrimitiveEdgeType fEdgeType;
@ -171,8 +171,8 @@ private:
virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE;
virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const SK_OVERRIDE {
inout->mulByUnknownAlpha();
virtual void onGetInvariantOutputCoverage(GrInitInvariantOutput* out) const SK_OVERRIDE {
out->setUnknownSingleComponent();
}
GrPrimitiveEdgeType fEdgeType;
@ -241,8 +241,8 @@ private:
virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE;
virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const SK_OVERRIDE {
inout->mulByUnknownAlpha();
virtual void onGetInvariantOutputCoverage(GrInitInvariantOutput* out) const SK_OVERRIDE {
out->setUnknownSingleComponent();
}
GrPrimitiveEdgeType fEdgeType;

View File

@ -175,7 +175,7 @@ bool GrBicubicEffect::onIsEqual(const GrFragmentProcessor& sBase) const {
void GrBicubicEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const {
// FIXME: Perhaps we can do better.
inout->mulByUnknownAlpha();
inout->mulByUnknownSingleComponent();
}
GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrBicubicEffect);

View File

@ -66,8 +66,9 @@ private:
///////////////////////////////////////////////////////////////////////////////
GrBitmapTextGeoProc::GrBitmapTextGeoProc(GrColor color, GrTexture* texture,
const GrTextureParams& params, bool useColorAttrib)
: INHERITED(color), fTextureAccess(texture, params), fInColor(NULL) {
const GrTextureParams& params, bool useColorAttrib,
bool opaqueVertexColors)
: INHERITED(color, opaqueVertexColors), fTextureAccess(texture, params), fInColor(NULL) {
this->initClassID<GrBitmapTextGeoProc>();
fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_GrVertexAttribType));
if (useColorAttrib) {
@ -84,15 +85,15 @@ bool GrBitmapTextGeoProc::onIsEqual(const GrGeometryProcessor& other) const {
return SkToBool(this->inColor()) == SkToBool(gp.inColor());
}
void GrBitmapTextGeoProc::onComputeInvariantOutput(GrInvariantOutput* inout) const {
void GrBitmapTextGeoProc::onGetInvariantOutputCoverage(GrInitInvariantOutput* out) const {
if (GrPixelConfigIsAlphaOnly(this->texture(0)->config())) {
inout->mulByUnknownAlpha();
out->setUnknownSingleComponent();
} else if (GrPixelConfigIsOpaque(this->texture(0)->config())) {
inout->mulByUnknownOpaqueColor();
inout->setUsingLCDCoverage();
out->setUnknownOpaqueFourComponents();
out->setUsingLCDCoverage();
} else {
inout->mulByUnknownColor();
inout->setUsingLCDCoverage();
out->setUnknownFourComponents();
out->setUsingLCDCoverage();
}
}
@ -129,5 +130,5 @@ GrGeometryProcessor* GrBitmapTextGeoProc::TestCreate(SkRandom* random,
GrTextureParams::kNone_FilterMode);
return GrBitmapTextGeoProc::Create(GrRandomColor(random), textures[texIdx], params,
random->nextBool());
random->nextBool(), random->nextBool());
}

View File

@ -22,8 +22,8 @@ class GrInvariantOutput;
class GrBitmapTextGeoProc : public GrGeometryProcessor {
public:
static GrGeometryProcessor* Create(GrColor color, GrTexture* tex, const GrTextureParams& p,
bool useColorAttrib) {
return SkNEW_ARGS(GrBitmapTextGeoProc, (color, tex, p, useColorAttrib));
bool useColorAttrib, bool opaqueVertexColors) {
return SkNEW_ARGS(GrBitmapTextGeoProc, (color, tex, p, useColorAttrib, opaqueVertexColors));
}
virtual ~GrBitmapTextGeoProc() {}
@ -41,11 +41,12 @@ public:
virtual GrGLGeometryProcessor* createGLInstance(const GrBatchTracker& bt) const SK_OVERRIDE;
private:
GrBitmapTextGeoProc(GrColor, GrTexture* texture, const GrTextureParams& params, bool useColorAttrib);
GrBitmapTextGeoProc(GrColor, GrTexture* texture, const GrTextureParams& params,
bool useColorAttrib, bool opaqueVertexColors);
virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE;
virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const SK_OVERRIDE;
virtual void onGetInvariantOutputCoverage(GrInitInvariantOutput*) const SK_OVERRIDE;
GrTextureAccess fTextureAccess;
const GrAttribute* fInPosition;

View File

@ -44,9 +44,9 @@ private:
virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const SK_OVERRIDE {
if (fRect.isEmpty()) {
// An empty rect will have no coverage anywhere.
inout->mulByKnownAlpha(0);
inout->mulByKnownSingleComponent(0);
} else {
inout->mulByUnknownAlpha();
inout->mulByUnknownSingleComponent();
}
}
@ -323,7 +323,7 @@ GrFragmentProcessor* GrConvexPolyEffect::Create(GrPrimitiveEdgeType edgeType, co
GrConvexPolyEffect::~GrConvexPolyEffect() {}
void GrConvexPolyEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const {
inout->mulByUnknownAlpha();
inout->mulByUnknownSingleComponent();
}
void GrConvexPolyEffect::getGLProcessorKey(const GrGLCaps& caps,

View File

@ -99,7 +99,7 @@ private:
virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const {
// If the texture was opaque we could know that the output color if we knew the sum of the
// kernel values.
inout->mulByUnknownColor();
inout->mulByUnknownFourComponents();
}
GR_DECLARE_FRAGMENT_PROCESSOR_TEST;

View File

@ -335,7 +335,7 @@ bool GrDashingEffect::DrawDashLine(GrGpu* gpu, GrDrawTarget* target, GrDrawState
devIntervals[0] = lineLength;
}
const GrGeometryProcessor* gp;
SkAutoTUnref<const GrGeometryProcessor> gp;
bool fullDash = devIntervals[1] > 0.f || useAA;
if (fullDash) {
SkPathEffect::DashInfo devInfo;
@ -347,14 +347,12 @@ bool GrDashingEffect::DrawDashLine(GrGpu* gpu, GrDrawTarget* target, GrDrawState
bool isRoundCap = SkPaint::kRound_Cap == cap;
GrDashingEffect::DashCap capType = isRoundCap ? GrDashingEffect::kRound_DashCap :
GrDashingEffect::kNonRound_DashCap;
gp = GrDashingEffect::Create(color, edgeType, devInfo, strokeWidth, capType);
gp.reset(GrDashingEffect::Create(color, edgeType, devInfo, strokeWidth, capType));
} else {
// Set up the vertex data for the line and start/end dashes
gp = GrDefaultGeoProcFactory::Create(color, GrDefaultGeoProcFactory::kPosition_GPType);
gp.reset(GrDefaultGeoProcFactory::Create(color, GrDefaultGeoProcFactory::kPosition_GPType));
}
drawState->setGeometryProcessor(gp)->unref();
int totalRectCnt = 0;
totalRectCnt += !lineDone ? 1 : 0;
@ -435,7 +433,7 @@ bool GrDashingEffect::DrawDashLine(GrGpu* gpu, GrDrawTarget* target, GrDrawState
}
target->setIndexSourceToBuffer(gpu->getContext()->getQuadIndexBuffer());
target->drawIndexedInstances(drawState, kTriangles_GrPrimitiveType, totalRectCnt, 4, 6);
target->drawIndexedInstances(drawState, gp, kTriangles_GrPrimitiveType, totalRectCnt, 4, 6);
target->resetIndexSource();
return true;
}
@ -489,7 +487,7 @@ private:
virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE;
virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const SK_OVERRIDE;
virtual void onGetInvariantOutputCoverage(GrInitInvariantOutput*) const SK_OVERRIDE;
GrPrimitiveEdgeType fEdgeType;
const GrAttribute* fInPosition;
@ -614,8 +612,8 @@ GrGeometryProcessor* DashingCircleEffect::Create(GrColor color,
DashingCircleEffect::~DashingCircleEffect() {}
void DashingCircleEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const {
inout->mulByUnknownAlpha();
void DashingCircleEffect::onGetInvariantOutputCoverage(GrInitInvariantOutput* out) const {
out->setUnknownSingleComponent();
}
void DashingCircleEffect::getGLProcessorKey(const GrBatchTracker& bt,
@ -719,7 +717,7 @@ private:
virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE;
virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const SK_OVERRIDE;
virtual void onGetInvariantOutputCoverage(GrInitInvariantOutput*) const SK_OVERRIDE;
GrPrimitiveEdgeType fEdgeType;
const GrAttribute* fInPosition;
@ -857,8 +855,8 @@ GrGeometryProcessor* DashingLineEffect::Create(GrColor color,
DashingLineEffect::~DashingLineEffect() {}
void DashingLineEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const {
inout->mulByUnknownAlpha();
void DashingLineEffect::onGetInvariantOutputCoverage(GrInitInvariantOutput* out) const {
out->setUnknownSingleComponent();
}
void DashingLineEffect::getGLProcessorKey(const GrBatchTracker& bt,

View File

@ -173,8 +173,8 @@ GrDistanceFieldTextureEffect::GrDistanceFieldTextureEffect(GrColor color,
const GrTextureParams& gammaParams,
float luminance,
#endif
uint32_t flags)
: INHERITED(color)
uint32_t flags, bool opaqueVertexColors)
: INHERITED(color, opaqueVertexColors)
, fTextureAccess(texture, params)
#ifdef SK_GAMMA_APPLY_TO_A8
, fGammaTextureAccess(gamma, gammaParams)
@ -206,8 +206,8 @@ bool GrDistanceFieldTextureEffect::onIsEqual(const GrGeometryProcessor& other) c
fFlags == cte.fFlags;
}
void GrDistanceFieldTextureEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const {
inout->mulByUnknownAlpha();
void GrDistanceFieldTextureEffect::onGetInvariantOutputCoverage(GrInitInvariantOutput* out) const {
out->setUnknownSingleComponent();
}
void GrDistanceFieldTextureEffect::getGLProcessorKey(const GrBatchTracker& bt,
@ -257,7 +257,8 @@ GrGeometryProcessor* GrDistanceFieldTextureEffect::TestCreate(SkRandom* random,
random->nextF(),
#endif
random->nextBool() ?
kSimilarity_DistanceFieldEffectFlag : 0);
kSimilarity_DistanceFieldEffectFlag : 0,
random->nextBool());
}
///////////////////////////////////////////////////////////////////////////////
@ -384,8 +385,9 @@ GrDistanceFieldNoGammaTextureEffect::GrDistanceFieldNoGammaTextureEffect(
GrColor color,
GrTexture* texture,
const GrTextureParams& params,
uint32_t flags)
: INHERITED(color)
uint32_t flags,
bool opaqueVertexColors)
: INHERITED(color, opaqueVertexColors)
, fTextureAccess(texture, params)
, fFlags(flags & kNonLCD_DistanceFieldEffectMask)
, fInColor(NULL) {
@ -407,8 +409,8 @@ bool GrDistanceFieldNoGammaTextureEffect::onIsEqual(const GrGeometryProcessor& o
return fFlags == cte.fFlags;
}
void GrDistanceFieldNoGammaTextureEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const {
inout->mulByUnknownAlpha();
void GrDistanceFieldNoGammaTextureEffect::onGetInvariantOutputCoverage(GrInitInvariantOutput* out) const{
out->setUnknownSingleComponent();
}
void GrDistanceFieldNoGammaTextureEffect::getGLProcessorKey(const GrBatchTracker& bt,
@ -446,7 +448,7 @@ GrGeometryProcessor* GrDistanceFieldNoGammaTextureEffect::TestCreate(SkRandom* r
return GrDistanceFieldNoGammaTextureEffect::Create(GrRandomColor(random), textures[texIdx],
params,
random->nextBool() ? kSimilarity_DistanceFieldEffectFlag : 0);
random->nextBool() ? kSimilarity_DistanceFieldEffectFlag : 0, random->nextBool());
}
///////////////////////////////////////////////////////////////////////////////
@ -665,9 +667,9 @@ bool GrDistanceFieldLCDTextureEffect::onIsEqual(const GrGeometryProcessor& other
fFlags == cte.fFlags);
}
void GrDistanceFieldLCDTextureEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const {
inout->mulByUnknownColor();
inout->setUsingLCDCoverage();
void GrDistanceFieldLCDTextureEffect::onGetInvariantOutputCoverage(GrInitInvariantOutput* out) const {
out->setUnknownFourComponents();
out->setUsingLCDCoverage();
}
void GrDistanceFieldLCDTextureEffect::getGLProcessorKey(const GrBatchTracker& bt,

View File

@ -49,14 +49,15 @@ public:
#ifdef SK_GAMMA_APPLY_TO_A8
static GrGeometryProcessor* Create(GrColor color, GrTexture* tex, const GrTextureParams& params,
GrTexture* gamma, const GrTextureParams& gammaParams,
float lum, uint32_t flags) {
float lum, uint32_t flags, bool opaqueVertexColors) {
return SkNEW_ARGS(GrDistanceFieldTextureEffect, (color, tex, params, gamma, gammaParams, lum,
flags));
flags, opaqueVertexColors));
}
#else
static GrGeometryProcessor* Create(GrColor color, GrTexture* tex, const GrTextureParams& params,
uint32_t flags) {
return SkNEW_ARGS(GrDistanceFieldTextureEffect, (color, tex, params, flags));
uint32_t flags, bool opaqueVertexColors) {
return SkNEW_ARGS(GrDistanceFieldTextureEffect, (color, tex, params, flags,
opaqueVertexColors));
}
#endif
@ -83,11 +84,11 @@ private:
#ifdef SK_GAMMA_APPLY_TO_A8
GrTexture* gamma, const GrTextureParams& gammaParams, float lum,
#endif
uint32_t flags);
uint32_t flags, bool opaqueVertexColors);
virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE;
virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const SK_OVERRIDE;
virtual void onGetInvariantOutputCoverage(GrInitInvariantOutput*) const SK_OVERRIDE;
GrTextureAccess fTextureAccess;
#ifdef SK_GAMMA_APPLY_TO_A8
@ -114,8 +115,9 @@ private:
class GrDistanceFieldNoGammaTextureEffect : public GrGeometryProcessor {
public:
static GrGeometryProcessor* Create(GrColor color, GrTexture* tex, const GrTextureParams& params,
uint32_t flags) {
return SkNEW_ARGS(GrDistanceFieldNoGammaTextureEffect, (color, tex, params, flags));
uint32_t flags, bool opaqueVertexColors) {
return SkNEW_ARGS(GrDistanceFieldNoGammaTextureEffect, (color, tex, params, flags,
opaqueVertexColors));
}
virtual ~GrDistanceFieldNoGammaTextureEffect() {}
@ -135,11 +137,11 @@ public:
private:
GrDistanceFieldNoGammaTextureEffect(GrColor, GrTexture* texture, const GrTextureParams& params,
uint32_t flags);
uint32_t flags, bool opaqueVertexColors);
virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE;
virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const SK_OVERRIDE;
virtual void onGetInvariantOutputCoverage(GrInitInvariantOutput*) const SK_OVERRIDE;
GrTextureAccess fTextureAccess;
uint32_t fFlags;
@ -190,7 +192,7 @@ private:
virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE;
virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const SK_OVERRIDE;
virtual void onGetInvariantOutputCoverage(GrInitInvariantOutput*) const SK_OVERRIDE;
GrTextureAccess fTextureAccess;
GrTextureAccess fGammaTextureAccess;

View File

@ -81,7 +81,7 @@ private:
virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const SK_OVERRIDE {
// TODO: Try to do better?
inout->mulByUnknownColor();
inout->mulByUnknownFourComponents();
}
SkIRect fBounds;

View File

@ -56,7 +56,7 @@ GrFragmentProcessor* CircleEffect::Create(GrPrimitiveEdgeType edgeType, const Sk
}
void CircleEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const {
inout->mulByUnknownAlpha();
inout->mulByUnknownSingleComponent();
}
CircleEffect::CircleEffect(GrPrimitiveEdgeType edgeType, const SkPoint& c, SkScalar r)
@ -233,7 +233,7 @@ GrFragmentProcessor* EllipseEffect::Create(GrPrimitiveEdgeType edgeType,
}
void EllipseEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const {
inout->mulByUnknownAlpha();
inout->mulByUnknownSingleComponent();
}
EllipseEffect::EllipseEffect(GrPrimitiveEdgeType edgeType, const SkPoint& c, SkScalar rx, SkScalar ry)

View File

@ -86,7 +86,7 @@ GrFragmentProcessor* CircularRRectEffect::Create(GrPrimitiveEdgeType edgeType,
}
void CircularRRectEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const {
inout->mulByUnknownAlpha();
inout->mulByUnknownSingleComponent();
}
CircularRRectEffect::CircularRRectEffect(GrPrimitiveEdgeType edgeType, uint32_t circularCornerFlags,
@ -426,7 +426,7 @@ EllipticalRRectEffect::Create(GrPrimitiveEdgeType edgeType, const SkRRect& rrect
}
void EllipticalRRectEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const {
inout->mulByUnknownAlpha();
inout->mulByUnknownSingleComponent();
}
EllipticalRRectEffect::EllipticalRRectEffect(GrPrimitiveEdgeType edgeType, const SkRRect& rrect)

View File

@ -41,11 +41,11 @@ protected:
*/
void updateInvariantOutputForModulation(GrInvariantOutput* inout) const {
if (GrPixelConfigIsAlphaOnly(this->texture(0)->config())) {
inout->mulByUnknownAlpha();
inout->mulByUnknownSingleComponent();
} else if (GrPixelConfigIsOpaque(this->texture(0)->config())) {
inout->mulByUnknownOpaqueColor();
inout->mulByUnknownOpaqueFourComponents();
} else {
inout->mulByUnknownColor();
inout->mulByUnknownFourComponents();
}
}

View File

@ -273,9 +273,9 @@ bool GrTextureDomainEffect::onIsEqual(const GrFragmentProcessor& sBase) const {
void GrTextureDomainEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const {
if (GrTextureDomain::kDecal_Mode == fTextureDomain.mode()) { // TODO: helper
if (GrPixelConfigIsAlphaOnly(this->texture(0)->config())) {
inout->mulByUnknownAlpha();
inout->mulByUnknownSingleComponent();
} else {
inout->mulByUnknownColor();
inout->mulByUnknownFourComponents();
}
} else {
this->updateInvariantOutputForModulation(inout);

View File

@ -129,19 +129,14 @@ static void set_random_xpf(GrContext* context, const GrDrawTargetCaps& caps, GrD
ds->setXPFactory(xpf.get());
}
static void set_random_gp(GrContext* context,
const GrDrawTargetCaps& caps,
GrDrawState* ds,
SkRandom* random,
GrTexture* dummyTextures[]) {
SkAutoTUnref<const GrGeometryProcessor> gp(
GrProcessorTestFactory<GrGeometryProcessor>::CreateStage(random,
context,
caps,
dummyTextures));
SkASSERT(gp);
ds->setGeometryProcessor(gp);
static const GrGeometryProcessor* get_random_gp(GrContext* context,
const GrDrawTargetCaps& caps,
SkRandom* random,
GrTexture* dummyTextures[]) {
return GrProcessorTestFactory<GrGeometryProcessor>::CreateStage(random,
context,
caps,
dummyTextures);
}
static void set_random_color_coverage_stages(GrGpuGL* gpu,
@ -189,12 +184,6 @@ static void set_random_color_coverage_stages(GrGpuGL* gpu,
}
}
static void set_random_hints(GrDrawState* ds, SkRandom* random) {
for (int i = 1; i <= GrDrawState::kLast_Hint; i <<= 1) {
ds->setHint(GrDrawState::Hints(i), random->nextBool());
}
}
static void set_random_state(GrDrawState* ds, SkRandom* random) {
int state = 0;
for (int i = 1; i <= GrDrawState::kLast_StateBit; i <<= 1) {
@ -293,8 +282,12 @@ bool GrDrawTarget::programUnitTest(int maxStages) {
// twiddle drawstate knobs randomly
bool hasGeometryProcessor = !usePathRendering;
const GrGeometryProcessor* gp = NULL;
const GrPathProcessor* pathProc = NULL;
if (hasGeometryProcessor) {
set_random_gp(fContext, gpu->glCaps(), &ds, &random, dummyTextures);
gp = get_random_gp(fContext, gpu->glCaps(), &random, dummyTextures);
} else {
pathProc = GrPathProcessor::Create(GrColor_WHITE);
}
set_random_color_coverage_stages(gpu,
&ds,
@ -306,25 +299,25 @@ bool GrDrawTarget::programUnitTest(int maxStages) {
// creates a random xfer processor factory on the draw state
set_random_xpf(fContext, gpu->glCaps(), &ds, &random, dummyTextures);
set_random_hints(&ds, &random);
set_random_state(&ds, &random);
set_random_stencil(&ds, &random);
GrDeviceCoordTexture dstCopy;
// TODO take color off the PP when its installed
GrColor color = ds.hasGeometryProcessor() ? ds.getGeometryProcessor()->getColor() :
GrColor_WHITE;
uint8_t coverage = ds.hasGeometryProcessor() ? ds.getGeometryProcessor()->getCoverage() :
0xff;
if (!this->setupDstReadIfNecessary(&ds, color, coverage, &dstCopy, NULL)) {
const GrPrimitiveProcessor* primProc;
if (hasGeometryProcessor) {
primProc = gp;
} else {
primProc = pathProc;
}
if (!this->setupDstReadIfNecessary(&ds, primProc, &dstCopy, NULL)) {
SkDebugf("Couldn't setup dst read texture");
return false;
}
// create optimized draw state, setup readDst texture if required, and build a descriptor
// and program. ODS creation can fail, so we have to check
GrOptDrawState ods(ds, color, coverage, *gpu->caps(), scissor, &dstCopy, drawType);
GrOptDrawState ods(ds, gp, pathProc, *gpu->caps(), scissor, &dstCopy, drawType);
if (ods.mustSkip()) {
continue;
}