clipped-bitmap-shaders-clamp
clipped-bitmap-shaders-clamp-hq
+# joshualitt
+path_primitive
+xfermodes3
+multipicturedraw_sierpinski_tiled
+multipicturedraw_sierpinski_simple
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) {
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) {
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) {
}
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);
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);
}
}
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);
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);
}
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
*/
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
#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)
, 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 {
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 {
}
}
- void mulByUnknownAlpha() {
+ void mulByUnknownSingleComponent() {
if (this->hasZeroAlpha()) {
this->internalSetToTransparentBlack();
} else {
}
}
- void mulByKnownAlpha(uint8_t alpha) {
+ void mulByKnownSingleComponent(uint8_t alpha) {
if (this->hasZeroAlpha() || 0 == alpha) {
this->internalSetToTransparentBlack();
} else {
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;
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;
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
*/
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;
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();
}
}
}
void GrRectBlurEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const {
- inout->mulByUnknownAlpha();
+ inout->mulByUnknownSingleComponent();
}
GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrRectBlurEffect);
}
void GrRRectBlurEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const {
- inout->mulByUnknownAlpha();
+ inout->mulByUnknownSingleComponent();
}
GrRRectBlurEffect::GrRRectBlurEffect(float sigma, const SkRRect& rrect, GrTexture *ninePatchTexture)
virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const SK_OVERRIDE {
// lighting shaders are complicated. We just throw up our hands.
- inout->mulByUnknownColor();
+ inout->mulByUnknownFourComponents();
}
private:
void GrGradientEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const {
if (fIsOpaque) {
- inout->mulByUnknownOpaqueColor();
+ inout->mulByUnknownOpaqueFourComponents();
} else {
- inout->mulByUnknownColor();
+ inout->mulByUnknownFourComponents();
}
}
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;
// 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));
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
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));
fEffectFlags = flags;
}
- drawState->setGeometryProcessor(fCachedGeometryProcessor.get());
void* vertices = NULL;
bool success = target->reserveVertexAndIndexSpace(4,
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;
bool GrAAHairLinePathRenderer::createLineGeom(GrDrawTarget* target,
GrDrawState* drawState,
uint8_t coverage,
+ size_t vertexStride,
GrDrawTarget::AutoReleaseGeometry* arg,
SkRect* devBounds,
const SkPath& path,
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;
}
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,
+ newCoverage));
if (!this->createLineGeom(target,
drawState,
newCoverage,
+ gp->getVertexStride(),
&arg,
&devBounds,
path,
while (lines < lineCnt) {
int n = SkTMin(lineCnt - lines, kLineSegsNumInIdxBuffer);
target->drawIndexed(drawState,
+ gp,
kTriangles_GrPrimitiveType,
kLineSegNumVertices*lines, // startV
0, // startI
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
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
bool createLineGeom(GrDrawTarget* target,
GrDrawState*,
uint8_t coverage,
+ size_t vertexStride,
GrDrawTarget::AutoReleaseGeometry* arg,
SkRect* devBounds,
const SkPath& path,
};
}
-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);
+ SkASSERT(gp->getVertexStride()==sizeof(GrDefaultGeoProcFactory::PositionColorCoverageAttr));
+ *type = kUseCoverage_CoverageAttribType;
}
+ return gp;
}
static void set_inset_fan(SkPoint* pts, size_t stride,
const SkRect& devRect) {
GrDrawState::AutoRestoreEffects are(drawState);
- CoverageAttribType covAttribType = set_rect_attribs(drawState, color);
- if (kUseCoverage_CoverageAttribType == covAttribType && GrColorIsOpaque(color)) {
+ CoverageAttribType type;
+ SkAutoTUnref<const GrGeometryProcessor> gp(create_rect_gp(*drawState, color, &type));
+ if (kUseCoverage_CoverageAttribType == type && GrColorIsOpaque(color)) {
drawState->setHint(GrDrawState::kVertexColorsAreOpaque_Hint, true);
}
- 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;
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());
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] = {
// 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;
}
}
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,
const SkRect& devInside,
bool miterStroke) {
GrDrawState::AutoRestoreEffects are(drawState);
- CoverageAttribType covAttribType = set_rect_attribs(drawState, color);
- if (kUseCoverage_CoverageAttribType == covAttribType && GrColorIsOpaque(color)) {
+ CoverageAttribType type;
+ SkAutoTUnref<const GrGeometryProcessor> gp(create_rect_gp(*drawState, color, &type));
+
+ if (kUseCoverage_CoverageAttribType == type && GrColorIsOpaque(color)) {
drawState->setHint(GrDrawState::kVertexColorsAreOpaque_Hint, true);
}
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");
// 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 {
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 {
// 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 {
target->setIndexSourceToBuffer(indexBuffer);
target->drawIndexedInstances(drawState,
+ gp,
kTriangles_GrPrimitiveType,
1,
totalVertexNum,
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;
fCachedGeometryProcessor.reset(GrBitmapTextGeoProc::Create(color,
fCurrTexture,
hasColor));
fEffectTextureUniqueID = textureUniqueID;
}
- drawState.setGeometryProcessor(fCachedGeometryProcessor.get());
}
int nGlyphs = fCurrVertex / kVerticesPerGlyph;
fDrawTarget->setIndexSourceToBuffer(fContext->getQuadIndexBuffer());
fDrawTarget->drawIndexedInstances(&drawState,
+ fCachedGeometryProcessor.get(),
kTriangles_GrPrimitiveType,
nGlyphs,
kVerticesPerGlyph,
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));
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
// 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(),
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);
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;
*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,
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)) {
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);
}
}
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());
}
}
drawState->enableState(GrDrawState::kNoColorWrites_StateBit);
}
GrDrawState::AutoRestoreEffects are(drawState);
- drawState->setGeometryProcessor(
+ SkAutoTUnref<const GrGeometryProcessor> gp(
GrDefaultGeoProcFactory::Create(color,
GrDefaultGeoProcFactory::kPosition_GPType,
- newCoverage))->unref();
+ newCoverage));
if (indexCnt) {
target->drawIndexed(drawState,
+ gp,
primType,
0,
0,
indexCnt,
&devBounds);
} else {
- target->drawNonIndexed(drawState, primType, 0, vertexCnt, &devBounds);
+ target->drawNonIndexed(drawState, gp, primType, 0, vertexCnt, &devBounds);
}
}
}
}
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
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,
#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() ||
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;
}
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;
}
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();
fColorCache = GrColor_ILLEGAL;
fCoverageCache = GrColor_ILLEGAL;
+
+ fColorPrimProc = NULL;
+ fCoveragePrimProc = NULL;
+
}
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();
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;
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
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);
}
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;)
////////////////////////////////////////////////////////////////////////////////
-bool GrDrawState::srcAlphaWillBeOne(GrColor color, GrColor coverage) const {
- this->calcColorInvariantOutput(color);
- if (this->isCoverageDrawing()) {
- this->calcCoverageInvariantOutput(coverage);
- return (fColorProcInfo.isOpaque() && fCoverageProcInfo.isOpaque());
+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;
}
- return fColorProcInfo.isOpaque();
}
-bool GrDrawState::willBlendWithDst(GrColor color, GrColor coverage) const {
- this->calcColorInvariantOutput(color);
- this->calcCoverageInvariantOutput(coverage);
- return fXPFactory->willBlendWithDst(fColorProcInfo, fCoverageProcInfo,
- this->isCoverageDrawing(), this->isColorWriteDisabled());
+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;
}
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;
}
*/
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();
- }
-
/// @}
/**
/**
* 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
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(); }
* 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.
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);
private:
GrDrawState* fDrawState;
- uint32_t fOriginalGPID;
int fColorEffectCnt;
int fCoverageEffectCnt;
};
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.
+ */
+ void calcColorInvariantOutput(const GrPrimitiveProcessor*) const;
+
+ /**
+ * If fCoverageProcInfoValid is false, function calculates the invariant output for the coverage
+ * stages and results are stored in fCoverageProcInfo.
*/
- bool srcAlphaWillBeOne(GrColor color, GrColor coverage) const;
+ void calcCoverageInvariantOutput(const GrPrimitiveProcessor*) const;
/**
* If fColorProcInfoValid is false, function calculates the invariant output for the color
uint32_t fFlagBits;
GrStencilSettings fStencilSettings;
DrawFace fDrawFace;
- SkAutoTUnref<const GrGeometryProcessor> fGeometryProcessor;
SkAutoTUnref<const GrXPFactory> fXPFactory;
FragmentStageArray fColorStages;
FragmentStageArray fCoverageStages;
mutable bool fCoverageProcInfoValid;
mutable GrColor fColorCache;
mutable GrColor fCoverageCache;
+ mutable const GrPrimitiveProcessor* fColorPrimProc;
+ mutable const GrPrimitiveProcessor* fCoveragePrimProc;
friend class GrOptDrawState;
};
////////////////////////////////////////////////////////////////////////////////
bool GrDrawTarget::checkDraw(const GrDrawState& drawState,
+ const GrGeometryProcessor* gp,
GrPrimitiveType type,
int startVertex,
int startIndex,
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);
}
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;
}
void GrDrawTarget::drawIndexed(GrDrawState* ds,
+ const GrGeometryProcessor* gp,
GrPrimitiveType type,
int startVertex,
int startIndex,
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;
// 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;
// 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::stencilPath(GrDrawState* ds,
+ const GrPathProcessor* pathProc,
const GrPath* path,
GrPathRendering::FillType fill) {
// TODO: extract portions of checkDraw that are relevant to path stenciling.
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.
&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,
// 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);
}
////////////////////////////////////////////////////////////////////////////////
void GrDrawTarget::drawIndexedInstances(GrDrawState* ds,
+ const GrGeometryProcessor* gp,
GrPrimitiveType type,
int instanceCount,
int verticesPerInstance,
// 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;
}
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;
* not a request for clipping.
*/
void drawIndexed(GrDrawState*,
+ const GrGeometryProcessor*,
GrPrimitiveType type,
int startVertex,
int startIndex,
* not a request for clipping.
*/
void drawNonIndexed(GrDrawState*,
+ const GrGeometryProcessor*,
GrPrimitiveType type,
int startVertex,
int vertexCount,
* 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
* @param fill Fill type for drawing all the paths
*/
void drawPaths(GrDrawState*,
- GrColor,
+ const GrPathProcessor*,
const GrPathRange* pathRange,
const void* indices,
PathIndexType indexType,
* not a request for clipping.
*/
void drawIndexedInstances(GrDrawState*,
+ const GrGeometryProcessor*,
GrPrimitiveType type,
int instanceCount,
int verticesPerInstance,
// 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);
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;
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,
// 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,
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
* 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)
: fVertexStride(0)
return false;
}
- if (!fHasVertexColor && this->getColor() != that.getColor()) {
+ if (!fHasVertexColor && this->color() != that.color()) {
return false;
}
- if (!fHasVertexCoverage && this->getCoverage() != that.getCoverage()) {
+ // 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);
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
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:
/**
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;
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
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();
+ const GrGeometryProcessor* gp = GrDefaultGeoProcFactory::Create(color, flags);
if (0xFF == GrColorUnpackA(color)) {
drawState->setHint(GrDrawState::kVertexColorsAreOpaque_Hint, true);
}
+ return gp;
}
static bool path_fill_type_is_winding(const GrStencilSettings& pathStencilSettings) {
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);
}
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) {
}
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;
}
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;
}
}
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));
}
void GrInOrderDrawBuffer::onDrawPaths(const GrDrawState& ds,
- GrColor color,
+ const GrPathProcessor* pathProc,
const GrPathRange* pathRange,
const void* indices,
PathIndexType indexType,
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;
}
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;
}
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();
};
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;
// overrides from GrDrawTarget
void onDraw(const GrDrawState&,
+ const GrGeometryProcessor*,
const DrawInfo&,
const ScissorState&,
const GrDeviceCoordTexture* dstCopy) SK_OVERRIDE;
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,
// 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*);
#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(
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();
int firstCoverageStageIdx = 0;
fDescInfo.fInputCoverageIsUsed = true;
-
GrXferProcessor::BlendInfo blendInfo;
fXferProcessor->getBlendInfo(&blendInfo);
fSrcBlend = blendInfo.fSrcBlend;
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,
}
// let the GP init the batch tracker
- if (drawState.hasGeometryProcessor()) {
+ if (gp) {
GrGeometryProcessor::InitBT init;
init.fOutputColor = fDescInfo.fInputColorIsUsed;
init.fOutputCoverage = fDescInfo.fInputCoverageIsUsed;
class GrDeviceCoordTexture;
class GrDrawState;
+class GrPathProcessor;
/**
* Class that holds an optimized version of a GrDrawState. It is meant to be an immutable class,
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); }
* 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 {
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;
GrBlendCoeff fDstBlend;
uint32_t fFlags;
ProgramGeometryProcessor fGeometryProcessor;
+ ProgramPrimitiveProcessor fPrimitiveProcessor;
GrBatchTracker fBatchTracker;
ProgramXferProcessor fXferProcessor;
FragmentStageArray fFragmentStages;
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;
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;
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;
}
}
- 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));
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();
}
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));
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;
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));
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;
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));
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
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));
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);
}
#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;
+ 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;
fInOut.resetNonMulStageFound();
// Reset these since we don't care if previous stages read these values
fReadsDst = false;
- fReadsFragPosition = false;
+ fReadsFragPosition = initWillReadFragmentPosition;
}
}
}
-
class GrFragmentStage;
class GrFragmentProcessor;
-class GrGeometryProcessor;
+class GrPrimitiveProcessor;
class GrProcessor;
/**
, 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(); }
bool readsFragPosition() const { return fReadsFragPosition; }
private:
+ void internalCalc(const GrFragmentStage*, int stagecount, bool initWillReadFragPosition);
+
GrInvariantOutput fInOut;
int fFirstEffectStageIndex;
bool fInputColorIsUsed;
return true;
}
-void GrProcessor::computeInvariantOutput(GrInvariantOutput* inout) const {
- this->onComputeInvariantOutput(inout);
-}
-
///////////////////////////////////////////////////////////////////////////////////////////////////
void GrFragmentProcessor::addCoordTransform(const GrCoordTransform* transform) {
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) {
+ 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);
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// Initial static variable from GrXPFactory
int32_t GrXPFactory::gCurrXPFClassID =
GrXPFactory::kIllegalXPFClassID;
-
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,
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,
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();
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,
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;
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;
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;
void GrBicubicEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const {
// FIXME: Perhaps we can do better.
- inout->mulByUnknownAlpha();
+ inout->mulByUnknownSingleComponent();
}
GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrBicubicEffect);
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();
}
}
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;
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();
}
}
GrConvexPolyEffect::~GrConvexPolyEffect() {}
void GrConvexPolyEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const {
- inout->mulByUnknownAlpha();
+ inout->mulByUnknownSingleComponent();
}
void GrConvexPolyEffect::getGLProcessorKey(const GrGLCaps& caps,
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;
devIntervals[0] = lineLength;
}
- const GrGeometryProcessor* gp;
+ SkAutoTUnref<const GrGeometryProcessor> gp;
bool fullDash = devIntervals[1] > 0.f || useAA;
if (fullDash) {
SkPathEffect::DashInfo devInfo;
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;
}
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;
}
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;
DashingCircleEffect::~DashingCircleEffect() {}
-void DashingCircleEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const {
- inout->mulByUnknownAlpha();
+void DashingCircleEffect::onGetInvariantOutputCoverage(GrInitInvariantOutput* out) const {
+ out->setUnknownSingleComponent();
}
void DashingCircleEffect::getGLProcessorKey(const GrBatchTracker& bt,
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;
DashingLineEffect::~DashingLineEffect() {}
-void DashingLineEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const {
- inout->mulByUnknownAlpha();
+void DashingLineEffect::onGetInvariantOutputCoverage(GrInitInvariantOutput* out) const {
+ out->setUnknownSingleComponent();
}
void DashingLineEffect::getGLProcessorKey(const GrBatchTracker& bt,
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,
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,
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,
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
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;
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;
virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const SK_OVERRIDE {
// TODO: Try to do better?
- inout->mulByUnknownColor();
+ inout->mulByUnknownFourComponents();
}
SkIRect fBounds;
}
void CircleEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const {
- inout->mulByUnknownAlpha();
+ inout->mulByUnknownSingleComponent();
}
CircleEffect::CircleEffect(GrPrimitiveEdgeType edgeType, const SkPoint& c, SkScalar r)
}
void EllipseEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const {
- inout->mulByUnknownAlpha();
+ inout->mulByUnknownSingleComponent();
}
EllipseEffect::EllipseEffect(GrPrimitiveEdgeType edgeType, const SkPoint& c, SkScalar rx, SkScalar ry)
}
void CircularRRectEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const {
- inout->mulByUnknownAlpha();
+ inout->mulByUnknownSingleComponent();
}
CircularRRectEffect::CircularRRectEffect(GrPrimitiveEdgeType edgeType, uint32_t circularCornerFlags,
}
void EllipticalRRectEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const {
- inout->mulByUnknownAlpha();
+ inout->mulByUnknownSingleComponent();
}
EllipticalRRectEffect::EllipticalRRectEffect(GrPrimitiveEdgeType edgeType, const SkRRect& rrect)
*/
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();
}
}
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);
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,
// 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,
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;
}