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:
parent
5756aff409
commit
56995b5cc0
@ -67,3 +67,10 @@ drawbitmapmatrix
|
||||
|
||||
#junov skbug.com/3176
|
||||
pictureimagefilter
|
||||
|
||||
#joshualitt
|
||||
hairlines
|
||||
patch_primitive
|
||||
xfermodes3
|
||||
multipicturedraw_sierpinski_tiled
|
||||
multipicturedraw_sierpinski_simple
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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:
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -43,6 +43,7 @@ private:
|
||||
bool createLineGeom(GrDrawTarget* target,
|
||||
GrDrawState*,
|
||||
uint8_t coverage,
|
||||
size_t vertexStride,
|
||||
GrDrawTarget::AutoReleaseGeometry* arg,
|
||||
SkRect* devBounds,
|
||||
const SkPath& path,
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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); }
|
||||
};
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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*);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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,
|
||||
|
@ -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",
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -81,7 +81,7 @@ private:
|
||||
|
||||
virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const SK_OVERRIDE {
|
||||
// TODO: Try to do better?
|
||||
inout->mulByUnknownColor();
|
||||
inout->mulByUnknownFourComponents();
|
||||
}
|
||||
|
||||
SkIRect fBounds;
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user