This cl moves color and coverage off of drawstate. In an effort to keep this CL manageable, I have left the compute invariant input / output in a bit of a strange state(fixing this will be complicated).

In addition, NVPR makes this very complicated, and I haven't quite figured out a good way to handle it, so for now color and coverage DO live on optstate, but I will figure out some way to refactor that in future CLs.

BUG=skia:

Review URL: https://codereview.chromium.org/783763002
This commit is contained in:
joshualitt 2014-12-09 13:31:14 -08:00 committed by Commit bot
parent f3c78ccf56
commit 2e3b3e369d
55 changed files with 589 additions and 474 deletions

View File

@ -92,7 +92,7 @@ protected:
continue;
}
GrPrimitiveEdgeType et = (GrPrimitiveEdgeType)edgeType;
gp.reset(GrCubicEffect::Create(et, *tt.target()->caps()));
gp.reset(GrCubicEffect::Create(0xff000000, et, *tt.target()->caps()));
if (!gp) {
continue;
}
@ -166,7 +166,6 @@ protected:
ds.setGeometryProcessor(gp);
ds.setRenderTarget(rt);
ds.setColor(0xff000000);
tt.target()->setIndexSourceToBuffer(context->getQuadIndexBuffer());
tt.target()->drawIndexed(&ds, kTriangleFan_GrPrimitiveType, 0, 0, 4, 6);
@ -252,7 +251,7 @@ protected:
continue;
}
GrPrimitiveEdgeType et = (GrPrimitiveEdgeType)edgeType;
gp.reset(GrConicEffect::Create(et, *tt.target()->caps()));
gp.reset(GrConicEffect::Create(0xff000000, et, *tt.target()->caps()));
if (!gp) {
continue;
}
@ -323,7 +322,6 @@ protected:
ds.setGeometryProcessor(gp);
ds.setRenderTarget(rt);
ds.setColor(0xff000000);
tt.target()->setIndexSourceToBuffer(context->getQuadIndexBuffer());
tt.target()->drawIndexed(&ds, kTriangleFan_GrPrimitiveType, 0, 0, 4, 6);
@ -443,7 +441,7 @@ protected:
continue;
}
GrPrimitiveEdgeType et = (GrPrimitiveEdgeType)edgeType;
gp.reset(GrQuadEffect::Create(et, *tt.target()->caps()));
gp.reset(GrQuadEffect::Create(0xff000000, et, *tt.target()->caps()));
if (!gp) {
continue;
}
@ -509,7 +507,6 @@ protected:
ds.setGeometryProcessor(gp);
ds.setRenderTarget(rt);
ds.setColor(0xff000000);
tt.target()->setIndexSourceToBuffer(context->getQuadIndexBuffer());
tt.target()->drawIndexed(&ds, kTriangles_GrPrimitiveType, 0, 0, 4, 6);

View File

@ -133,12 +133,11 @@ protected:
}
GrDrawState ds;
const GrGeometryProcessor* gp = GrDefaultGeoProcFactory::Create();
const GrGeometryProcessor* gp = GrDefaultGeoProcFactory::Create(0xff000000);
ds.setGeometryProcessor(gp)->unref();
ds.addCoverageProcessor(fp);
ds.setIdentityViewMatrix();
ds.setRenderTarget(rt);
ds.setColor(0xff000000);
GrDrawTarget::AutoReleaseGeometry geo(tt.target(), 4, gp->getVertexStride(), 0);
SkASSERT(gp->getVertexStride() == sizeof(SkPoint));
@ -191,12 +190,11 @@ protected:
}
GrDrawState ds;
const GrGeometryProcessor* gp = GrDefaultGeoProcFactory::Create();
const GrGeometryProcessor* gp = GrDefaultGeoProcFactory::Create(0xff000000);
ds.setGeometryProcessor(gp)->unref();
ds.addCoverageProcessor(fp);
ds.setIdentityViewMatrix();
ds.setRenderTarget(rt);
ds.setColor(0xff000000);
GrDrawTarget::AutoReleaseGeometry geo(tt.target(), 4, gp->getVertexStride(), 0);
SkASSERT(gp->getVertexStride() == sizeof(SkPoint));

View File

@ -123,12 +123,11 @@ protected:
drawState.addCoverageProcessor(fp);
drawState.setIdentityViewMatrix();
drawState.setRenderTarget(rt);
drawState.setColor(0xff000000);
SkRect bounds = rrect.getBounds();
bounds.outset(2.f, 2.f);
tt.target()->drawSimpleRect(&drawState, bounds);
tt.target()->drawSimpleRect(&drawState, 0xff000000, bounds);
} else {
drew = false;
}

View File

@ -132,10 +132,9 @@ protected:
viewMatrix.setTranslate(x, y);
GrDrawState drawState(viewMatrix);
drawState.setRenderTarget(rt);
drawState.setColor(0xffffffff);
drawState.addColorProcessor(fp);
tt.target()->drawSimpleRect(&drawState, renderRect);
tt.target()->drawSimpleRect(&drawState, GrColor_WHITE, renderRect);
x += renderRect.width() + kTestPad;
}
y += renderRect.height() + kTestPad;

View File

@ -117,9 +117,8 @@ protected:
viewMatrix.setTranslate(x, y);
GrDrawState drawState(viewMatrix);
drawState.setRenderTarget(rt);
drawState.setColor(0xffffffff);
drawState.addColorProcessor(fp);
tt.target()->drawSimpleRect(&drawState, renderRect);
tt.target()->drawSimpleRect(&drawState, GrColor_WHITE, renderRect);
}
x += renderRect.width() + kTestPad;
}

View File

@ -66,6 +66,9 @@ static inline GrColor GrColorPackRGBA(unsigned r, unsigned g,
*/
#define GrColor_ILLEGAL (~(0xFF << GrColor_SHIFT_A))
#define GrColor_WHITE 0xFFFFFFFF
#define GrColor_TRANS_BLACK 0x0
/**
* Assert in debug builds that a GrColor is premultiplied.
*/

View File

@ -983,6 +983,7 @@ private:
void internalDrawPath(GrDrawTarget*,
GrDrawState*,
GrColor,
bool useAA,
const SkPath&,
const GrStrokeInfo&);

View File

@ -8,6 +8,7 @@
#ifndef GrProcessorUnitTest_DEFINED
#define GrProcessorUnitTest_DEFINED
#include "GrColor.h"
#include "SkRandom.h"
#include "SkTArray.h"
#include "SkTypes.h"
@ -29,6 +30,66 @@ const SkMatrix& TestMatrix(SkRandom*);
}
static inline GrColor GrRandomColor(SkRandom* random) {
// There are only a few cases of random colors which interest us
enum ColorMode {
kAllOnes_ColorMode,
kAllZeros_ColorMode,
kAlphaOne_ColorMode,
kRandom_ColorMode,
kLast_ColorMode = kRandom_ColorMode
};
ColorMode colorMode = ColorMode(random->nextULessThan(kLast_ColorMode + 1));
GrColor color;
switch (colorMode) {
case kAllOnes_ColorMode:
color = GrColorPackRGBA(0xFF, 0xFF, 0xFF, 0xFF);
break;
case kAllZeros_ColorMode:
color = GrColorPackRGBA(0, 0, 0, 0);
break;
case kAlphaOne_ColorMode:
color = GrColorPackRGBA(random->nextULessThan(256),
random->nextULessThan(256),
random->nextULessThan(256),
0xFF);
break;
case kRandom_ColorMode:
uint8_t alpha = random->nextULessThan(256);
color = GrColorPackRGBA(random->nextRangeU(0, alpha),
random->nextRangeU(0, alpha),
random->nextRangeU(0, alpha),
alpha);
break;
}
GrColorIsPMAssert(color);
return color;
}
static inline uint8_t GrRandomCoverage(SkRandom* random) {
enum CoverageMode {
kZero_CoverageMode,
kAllOnes_CoverageMode,
kRandom_CoverageMode,
kLast_CoverageMode = kRandom_CoverageMode
};
CoverageMode colorMode = CoverageMode(random->nextULessThan(kLast_CoverageMode + 1));
uint8_t coverage;
switch (colorMode) {
case kZero_CoverageMode:
coverage = 0;
case kAllOnes_CoverageMode:
coverage = 0xff;
break;
case kRandom_CoverageMode:
coverage = random->nextULessThan(256);
break;
}
return coverage;
}
#if SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
class GrContext;

View File

@ -505,8 +505,8 @@ static void create_vertices(const SegmentArray& segments,
class QuadEdgeEffect : public GrGeometryProcessor {
public:
static GrGeometryProcessor* Create() {
return SkNEW(QuadEdgeEffect);
static GrGeometryProcessor* Create(GrColor color) {
return SkNEW_ARGS(QuadEdgeEffect, (color));
}
virtual ~QuadEdgeEffect() {}
@ -586,7 +586,7 @@ public:
}
private:
QuadEdgeEffect() {
QuadEdgeEffect(GrColor color) : INHERITED(color) {
this->initClassID<QuadEdgeEffect>();
fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_GrVertexAttribType));
fInQuadEdge = &this->addVertexAttrib(GrAttribute("inQuadEdge", kVec4f_GrVertexAttribType));
@ -605,7 +605,7 @@ private:
GR_DECLARE_GEOMETRY_PROCESSOR_TEST;
typedef GrFragmentProcessor INHERITED;
typedef GrGeometryProcessor INHERITED;
};
GR_DEFINE_GEOMETRY_PROCESSOR_TEST(QuadEdgeEffect);
@ -615,7 +615,7 @@ GrGeometryProcessor* QuadEdgeEffect::TestCreate(SkRandom* random,
const GrDrawTargetCaps& caps,
GrTexture*[]) {
// Doesn't work without derivative instructions.
return caps.shaderDerivativeSupport() ? QuadEdgeEffect::Create() : NULL;
return caps.shaderDerivativeSupport() ? QuadEdgeEffect::Create(GrRandomColor(random)) : NULL;
}
///////////////////////////////////////////////////////////////////////////////
@ -631,6 +631,7 @@ bool GrAAConvexPathRenderer::canDrawPath(const GrDrawTarget* target,
bool GrAAConvexPathRenderer::onDrawPath(GrDrawTarget* target,
GrDrawState* drawState,
GrColor color,
const SkPath& origPath,
const SkStrokeRec&,
bool antiAlias) {
@ -678,7 +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();
GrGeometryProcessor* quadProcessor = QuadEdgeEffect::Create(color);
drawState->setGeometryProcessor(quadProcessor)->unref();
GrDrawTarget::AutoReleaseGeometry arg(target, vCount, quadProcessor->getVertexStride(), iCount);

View File

@ -24,6 +24,7 @@ public:
protected:
virtual bool onDrawPath(GrDrawTarget*,
GrDrawState*,
GrColor,
const SkPath&,
const SkStrokeRec&,
bool antiAlias) SK_OVERRIDE;

View File

@ -105,6 +105,7 @@ GrAADistanceFieldPathRenderer::onGetStencilSupport(const GrDrawTarget*,
bool GrAADistanceFieldPathRenderer::onDrawPath(GrDrawTarget* target,
GrDrawState* drawState,
GrColor color,
const SkPath& path,
const SkStrokeRec& stroke,
bool antiAlias) {
@ -143,7 +144,7 @@ bool GrAADistanceFieldPathRenderer::onDrawPath(GrDrawTarget* target,
}
// use signed distance field to render
return this->internalDrawPath(target, drawState, path, pathData);
return this->internalDrawPath(target, drawState, color, path, pathData);
}
// padding around path bounds to allow for antialiased pixels
@ -306,6 +307,7 @@ bool GrAADistanceFieldPathRenderer::freeUnusedPlot() {
bool GrAADistanceFieldPathRenderer::internalDrawPath(GrDrawTarget* target,
GrDrawState* drawState,
GrColor color,
const SkPath& path,
const PathData* pathData) {
GrTexture* texture = fAtlas->getTexture();
@ -321,8 +323,9 @@ bool GrAADistanceFieldPathRenderer::internalDrawPath(GrDrawTarget* target,
flags |= vm.isSimilarity() ? kSimilarity_DistanceFieldEffectFlag : 0;
GrTextureParams params(SkShader::kRepeat_TileMode, GrTextureParams::kBilerp_FilterMode);
if (flags != fEffectFlags) {
fCachedGeometryProcessor.reset(GrDistanceFieldNoGammaTextureEffect::Create(texture,
if (flags != fEffectFlags || fCachedGeometryProcessor->getColor() != color) {
fCachedGeometryProcessor.reset(GrDistanceFieldNoGammaTextureEffect::Create(color,
texture,
params,
flags));
fEffectFlags = flags;

View File

@ -38,6 +38,7 @@ protected:
virtual bool onDrawPath(GrDrawTarget*,
GrDrawState*,
GrColor,
const SkPath&,
const SkStrokeRec&,
bool antiAlias) SK_OVERRIDE;
@ -78,7 +79,7 @@ private:
SkTDynamicHash<PathData, PathData::Key> fPathCache;
PathDataList fPathList;
bool internalDrawPath(GrDrawTarget*, GrDrawState*, const SkPath& path,
bool internalDrawPath(GrDrawTarget*, GrDrawState*, GrColor, const SkPath& path,
const PathData* pathData);
PathData* addPathToAtlas(const SkPath& path, const SkStrokeRec& stroke, bool antiAlias,
uint32_t dimension, SkScalar scale);

View File

@ -643,6 +643,7 @@ void add_line(const SkPoint p[2],
bool GrAAHairLinePathRenderer::createLineGeom(GrDrawTarget* target,
GrDrawState* drawState,
uint8_t coverage,
GrDrawTarget::AutoReleaseGeometry* arg,
SkRect* devBounds,
const SkPath& path,
@ -670,7 +671,7 @@ bool GrAAHairLinePathRenderer::createLineGeom(GrDrawTarget* target,
}
devBounds->set(lines.begin(), lines.count());
for (int i = 0; i < lineCnt; ++i) {
add_line(&lines[2*i], toSrc, drawState->getCoverage(), &verts);
add_line(&lines[2*i], toSrc, coverage, &verts);
}
// All the verts computed by add_line are within sqrt(1^2 + 0.5^2) of the end points.
static const SkScalar kSqrtOfOneAndAQuarter = 1.118f;
@ -803,14 +804,15 @@ bool check_bounds(GrDrawState* drawState, const SkRect& devBounds, void* vertice
bool GrAAHairLinePathRenderer::onDrawPath(GrDrawTarget* target,
GrDrawState* drawState,
GrColor color,
const SkPath& path,
const SkStrokeRec& stroke,
bool antiAlias) {
SkScalar hairlineCoverage;
uint8_t newCoverage = 0xff;
if (IsStrokeHairlineOrEquivalent(stroke, drawState->getViewMatrix(),
&hairlineCoverage)) {
uint8_t newCoverage = SkScalarRoundToInt(hairlineCoverage * drawState->getCoverage());
drawState->setCoverage(newCoverage);
newCoverage = SkScalarRoundToInt(hairlineCoverage * 0xff);
}
SkIRect devClipBounds;
@ -837,10 +839,13 @@ bool GrAAHairLinePathRenderer::onDrawPath(GrDrawTarget* target,
uint32_t gpFlags = GrDefaultGeoProcFactory::kPosition_GPType |
GrDefaultGeoProcFactory::kCoverage_GPType;
GrDrawState::AutoRestoreEffects are(drawState);
drawState->setGeometryProcessor(GrDefaultGeoProcFactory::Create(gpFlags))->unref();
drawState->setGeometryProcessor(GrDefaultGeoProcFactory::Create(color,
gpFlags,
newCoverage))->unref();
if (!this->createLineGeom(target,
drawState,
newCoverage,
&arg,
&devBounds,
path,
@ -911,7 +916,10 @@ bool GrAAHairLinePathRenderer::onDrawPath(GrDrawTarget* target,
if (quadCnt > 0) {
GrGeometryProcessor* hairQuadProcessor =
GrQuadEffect::Create(kHairlineAA_GrProcessorEdgeType, *target->caps());
GrQuadEffect::Create(color,
kHairlineAA_GrProcessorEdgeType,
*target->caps(),
newCoverage);
SkASSERT(hairQuadProcessor);
GrDrawState::AutoRestoreEffects are(drawState);
target->setIndexSourceToBuffer(fQuadsIndexBuffer);
@ -934,7 +942,7 @@ bool GrAAHairLinePathRenderer::onDrawPath(GrDrawTarget* target,
if (conicCnt > 0) {
GrDrawState::AutoRestoreEffects are(drawState);
GrGeometryProcessor* hairConicProcessor = GrConicEffect::Create(
kHairlineAA_GrProcessorEdgeType, *target->caps());
color, kHairlineAA_GrProcessorEdgeType, *target->caps(), newCoverage);
SkASSERT(hairConicProcessor);
drawState->setGeometryProcessor(hairConicProcessor)->unref();

View File

@ -30,6 +30,7 @@ public:
protected:
virtual bool onDrawPath(GrDrawTarget*,
GrDrawState*,
GrColor,
const SkPath&,
const SkStrokeRec&,
bool antiAlias) SK_OVERRIDE;
@ -41,6 +42,7 @@ private:
bool createLineGeom(GrDrawTarget* target,
GrDrawState*,
uint8_t coverage,
GrDrawTarget::AutoReleaseGeometry* arg,
SkRect* devBounds,
const SkPath& path,

View File

@ -25,16 +25,16 @@ enum CoverageAttribType {
};
}
static CoverageAttribType set_rect_attribs(GrDrawState* drawState) {
static CoverageAttribType set_rect_attribs(GrDrawState* drawState, GrColor color) {
uint32_t flags = GrDefaultGeoProcFactory::kColor_GPType;
if (drawState->canTweakAlphaForCoverage()) {
drawState->setGeometryProcessor(GrDefaultGeoProcFactory::Create(flags))->unref();
drawState->setGeometryProcessor(GrDefaultGeoProcFactory::Create(color, flags))->unref();
SkASSERT(drawState->getGeometryProcessor()->getVertexStride() ==
sizeof(GrDefaultGeoProcFactory::PositionColorAttr));
return kUseColor_CoverageAttribType;
} else {
flags |= GrDefaultGeoProcFactory::kCoverage_GPType;
drawState->setGeometryProcessor(GrDefaultGeoProcFactory::Create(flags))->unref();
drawState->setGeometryProcessor(GrDefaultGeoProcFactory::Create(color, flags))->unref();
SkASSERT(drawState->getGeometryProcessor()->getVertexStride() ==
sizeof(GrDefaultGeoProcFactory::PositionColorCoverageAttr));
return kUseCoverage_CoverageAttribType;
@ -176,14 +176,13 @@ GrIndexBuffer* GrAARectRenderer::aaStrokeRectIndexBuffer(bool miterStroke) {
void GrAARectRenderer::geometryFillAARect(GrDrawTarget* target,
GrDrawState* drawState,
GrColor color,
const SkRect& rect,
const SkMatrix& combinedMatrix,
const SkRect& devRect) {
GrDrawState::AutoRestoreEffects are(drawState);
GrColor color = drawState->getColor();
CoverageAttribType covAttribType = set_rect_attribs(drawState);
CoverageAttribType covAttribType = set_rect_attribs(drawState, color);
if (kUseCoverage_CoverageAttribType == covAttribType && GrColorIsOpaque(color)) {
drawState->setHint(GrDrawState::kVertexColorsAreOpaque_Hint, true);
}
@ -308,6 +307,7 @@ void GrAARectRenderer::geometryFillAARect(GrDrawTarget* target,
void GrAARectRenderer::strokeAARect(GrDrawTarget* target,
GrDrawState* drawState,
GrColor color,
const SkRect& rect,
const SkMatrix& combinedMatrix,
const SkRect& devRect,
@ -354,7 +354,7 @@ void GrAARectRenderer::strokeAARect(GrDrawTarget* target,
}
if (spare <= 0 && miterStroke) {
this->fillAARect(target, drawState, devOutside, SkMatrix::I(), devOutside);
this->fillAARect(target, drawState, color, devOutside, SkMatrix::I(), devOutside);
return;
}
@ -371,20 +371,20 @@ void GrAARectRenderer::strokeAARect(GrDrawTarget* target,
devOutsideAssist.outset(0, ry);
}
this->geometryStrokeAARect(target, drawState, devOutside, devOutsideAssist, devInside,
this->geometryStrokeAARect(target, drawState, color, devOutside, devOutsideAssist, devInside,
miterStroke);
}
void GrAARectRenderer::geometryStrokeAARect(GrDrawTarget* target,
GrDrawState* drawState,
GrColor color,
const SkRect& devOutside,
const SkRect& devOutsideAssist,
const SkRect& devInside,
bool miterStroke) {
GrDrawState::AutoRestoreEffects are(drawState);
CoverageAttribType covAttribType = set_rect_attribs(drawState);
CoverageAttribType covAttribType = set_rect_attribs(drawState, color);
GrColor color = drawState->getColor();
if (kUseCoverage_CoverageAttribType == covAttribType && GrColorIsOpaque(color)) {
drawState->setHint(GrDrawState::kVertexColorsAreOpaque_Hint, true);
}
@ -510,6 +510,7 @@ void GrAARectRenderer::geometryStrokeAARect(GrDrawTarget* target,
void GrAARectRenderer::fillAANestedRects(GrDrawTarget* target,
GrDrawState* drawState,
GrColor color,
const SkRect rects[2],
const SkMatrix& combinedMatrix) {
SkASSERT(combinedMatrix.rectStaysRect());
@ -521,9 +522,10 @@ void GrAARectRenderer::fillAANestedRects(GrDrawTarget* target,
combinedMatrix.mapPoints((SkPoint*)&devInside, (const SkPoint*)&rects[1], 2);
if (devInside.isEmpty()) {
this->fillAARect(target, drawState, devOutside, SkMatrix::I(), devOutside);
this->fillAARect(target, drawState, color, devOutside, SkMatrix::I(), devOutside);
return;
}
this->geometryStrokeAARect(target, drawState, devOutside, devOutsideAssist, devInside, true);
this->geometryStrokeAARect(target, drawState, color, devOutside, devOutsideAssist, devInside,
true);
}

View File

@ -8,6 +8,7 @@
#ifndef GrAARectRenderer_DEFINED
#define GrAARectRenderer_DEFINED
#include "GrColor.h"
#include "SkMatrix.h"
#include "SkRect.h"
#include "SkRefCnt.h"
@ -43,14 +44,16 @@ public:
void fillAARect(GrDrawTarget* target,
GrDrawState* ds,
GrColor color,
const SkRect& rect,
const SkMatrix& combinedMatrix,
const SkRect& devRect) {
this->geometryFillAARect(target, ds, rect, combinedMatrix, devRect);
this->geometryFillAARect(target, ds, color, rect, combinedMatrix, devRect);
}
void strokeAARect(GrDrawTarget*,
GrDrawState*,
GrColor,
const SkRect& rect,
const SkMatrix& combinedMatrix,
const SkRect& devRect,
@ -59,6 +62,7 @@ public:
// First rect is outer; second rect is inner
void fillAANestedRects(GrDrawTarget*,
GrDrawState*,
GrColor,
const SkRect rects[2],
const SkMatrix& combinedMatrix);
@ -67,12 +71,14 @@ private:
void geometryFillAARect(GrDrawTarget*,
GrDrawState*,
GrColor,
const SkRect& rect,
const SkMatrix& combinedMatrix,
const SkRect& devRect);
void geometryStrokeAARect(GrDrawTarget*,
GrDrawState*,
GrColor,
const SkRect& devOutside,
const SkRect& devOutsideAssist,
const SkRect& devInside,

View File

@ -528,34 +528,15 @@ void GrBitmapTextContext::flush() {
SkASSERT(SkIsAlign4(fCurrVertex));
SkASSERT(fCurrTexture);
// This effect could be stored with one of the cache objects (atlas?)
GrTextureParams params(SkShader::kRepeat_TileMode, GrTextureParams::kNone_FilterMode);
if (kARGB_GrMaskFormat == fCurrMaskFormat) {
uint32_t flags = GrDefaultGeoProcFactory::kLocalCoord_GPType;
drawState.setGeometryProcessor(GrDefaultGeoProcFactory::Create(flags))->unref();
GrFragmentProcessor* fragProcessor = GrSimpleTextureEffect::Create(fCurrTexture,
SkMatrix::I(),
params);
drawState.addColorProcessor(fragProcessor)->unref();
} else {
uint32_t textureUniqueID = fCurrTexture->getUniqueID();
if (textureUniqueID != fEffectTextureUniqueID) {
bool useColorAttrib = kA8_GrMaskFormat == fCurrMaskFormat;
fCachedGeometryProcessor.reset(GrBitmapTextGeoProc::Create(fCurrTexture,
params,
useColorAttrib));
fEffectTextureUniqueID = textureUniqueID;
}
drawState.setGeometryProcessor(fCachedGeometryProcessor.get());
}
SkASSERT(fStrike);
GrColor color = fPaint.getColor();
switch (fCurrMaskFormat) {
// Color bitmap text
case kARGB_GrMaskFormat:
SkASSERT(!drawState.hasColorVertexAttribute());
drawState.setAlpha(fSkPaint.getAlpha());
case kARGB_GrMaskFormat: {
int a = fSkPaint.getAlpha();
color = SkColorSetARGB(a, a, a, a);
break;
}
// LCD text
case kA565_GrMaskFormat: {
// TODO: move supportsRGBCoverage check to setupCoverageEffect and only add LCD
@ -564,19 +545,45 @@ void GrBitmapTextContext::flush() {
if (!drawState.getXPFactory()->supportsRGBCoverage(0, kRGBA_GrColorComponentFlags)) {
SkDebugf("LCD Text will not draw correctly.\n");
}
SkASSERT(!drawState.hasColorVertexAttribute());
break;
}
// Grayscale/BW text
case kA8_GrMaskFormat:
drawState.setHint(GrDrawState::kVertexColorsAreOpaque_Hint,
0xFF == GrColorUnpackA(fPaint.getColor()));
// We're using per-vertex color.
SkASSERT(drawState.hasColorVertexAttribute());
break;
default:
SkFAIL("Unexpected mask format.");
}
GrTextureParams params(SkShader::kRepeat_TileMode, GrTextureParams::kNone_FilterMode);
// TODO cache these GPs
if (kARGB_GrMaskFormat == fCurrMaskFormat) {
uint32_t textureUniqueID = fCurrTexture->getUniqueID();
if (textureUniqueID != fEffectTextureUniqueID ||
fCachedGeometryProcessor->getColor() != 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) {
bool hasColor = kA8_GrMaskFormat == fCurrMaskFormat;
fCachedGeometryProcessor.reset(GrBitmapTextGeoProc::Create(color,
fCurrTexture,
params,
hasColor));
fEffectTextureUniqueID = textureUniqueID;
}
drawState.setGeometryProcessor(fCachedGeometryProcessor.get());
}
int nGlyphs = fCurrVertex / kVerticesPerGlyph;
fDrawTarget->setIndexSourceToBuffer(fContext->getQuadIndexBuffer());
fDrawTarget->drawIndexedInstances(&drawState,

View File

@ -31,7 +31,8 @@ private:
SkRect fVertexBounds;
GrTexture* fCurrTexture;
GrMaskFormat fCurrMaskFormat;
SkAutoTUnref<GrGeometryProcessor> fCachedGeometryProcessor;
SkAutoTUnref<const GrGeometryProcessor> fCachedGeometryProcessor;
SkAutoTUnref<const GrFragmentProcessor> fCachedTextureProcessor;
// Used to check whether fCachedEffect is still valid.
uint32_t fEffectTextureUniqueID;

View File

@ -362,6 +362,7 @@ void setup_boolean_blendcoeffs(SkRegion::Op op, GrDrawState* drawState) {
////////////////////////////////////////////////////////////////////////////////
bool GrClipMaskManager::drawElement(GrDrawState* drawState,
GrColor color,
GrTexture* target,
const SkClipStack::Element* element,
GrPathRenderer* pr) {
@ -380,11 +381,12 @@ bool GrClipMaskManager::drawElement(GrDrawState* drawState,
if (element->isAA()) {
this->getContext()->getAARectRenderer()->fillAARect(fClipTarget,
drawState,
color,
element->getRect(),
SkMatrix::I(),
element->getRect());
} else {
fClipTarget->drawSimpleRect(drawState, element->getRect());
fClipTarget->drawSimpleRect(drawState, color, element->getRect());
}
return true;
default: {
@ -406,7 +408,7 @@ bool GrClipMaskManager::drawElement(GrDrawState* drawState,
return false;
}
pr->drawPath(fClipTarget, drawState, path, stroke, element->isAA());
pr->drawPath(fClipTarget, drawState, color, path, stroke, element->isAA());
break;
}
}
@ -460,7 +462,7 @@ void GrClipMaskManager::mergeMask(GrDrawState* drawState,
GrTextureDomain::MakeTexelDomain(srcMask, srcBound),
GrTextureDomain::kDecal_Mode,
GrTextureParams::kNone_FilterMode))->unref();
fClipTarget->drawSimpleRect(drawState, SkRect::Make(dstBound));
fClipTarget->drawSimpleRect(drawState, GrColor_WHITE, SkRect::Make(dstBound));
}
GrTexture* GrClipMaskManager::createTempMask(int width, int height) {
@ -617,13 +619,12 @@ GrTexture* GrClipMaskManager::createAlphaClipMask(int32_t elementsGenID,
setup_boolean_blendcoeffs(op, &drawState);
}
drawState.setAlpha(invert ? 0x00 : 0xff);
// We have to backup the drawstate because the drawElement call may call into
// renderers which consume it.
GrDrawState backupDrawState(drawState);
if (!this->drawElement(&drawState, dst, element, pr)) {
if (!this->drawElement(&drawState, invert ? GrColor_TRANS_BLACK :
GrColor_WHITE, dst, element, pr)) {
fAACache.reset();
return NULL;
}
@ -639,7 +640,6 @@ GrTexture* GrClipMaskManager::createAlphaClipMask(int32_t elementsGenID,
maskSpaceElementIBounds);
} else {
// Draw to the exterior pixels (those with a zero stencil value).
backupDrawState.setAlpha(invert ? 0xff : 0x00);
GR_STATIC_CONST_SAME_STENCIL(kDrawOutsideElement,
kZero_StencilOp,
kZero_StencilOp,
@ -648,7 +648,9 @@ GrTexture* GrClipMaskManager::createAlphaClipMask(int32_t elementsGenID,
0x0000,
0xffff);
backupDrawState.setStencil(kDrawOutsideElement);
fClipTarget->drawSimpleRect(&backupDrawState, clipSpaceIBounds);
fClipTarget->drawSimpleRect(&backupDrawState,
invert ? GrColor_WHITE : GrColor_TRANS_BLACK,
clipSpaceIBounds);
}
} else {
GrDrawState drawState(translate);
@ -656,9 +658,8 @@ GrTexture* GrClipMaskManager::createAlphaClipMask(int32_t elementsGenID,
GrDrawState::kClip_StateBit);
// all the remaining ops can just be directly draw into the accumulation buffer
drawState.setAlpha(0xff);
setup_boolean_blendcoeffs(op, &drawState);
this->drawElement(&drawState, result, element);
this->drawElement(&drawState, GrColor_WHITE, result, element);
}
}
@ -783,13 +784,14 @@ bool GrClipMaskManager::createStencilClipMask(GrRenderTarget* rt,
0xffff);
if (Element::kRect_Type == element->getType()) {
*drawState.stencil() = gDrawToStencil;
fClipTarget->drawSimpleRect(&drawState, element->getRect());
fClipTarget->drawSimpleRect(&drawState, GrColor_WHITE, element->getRect());
} else {
if (!clipPath.isEmpty()) {
GrDrawTarget::AutoGeometryPush agp(fClipTarget);
if (canRenderDirectToStencil) {
*drawState.stencil() = gDrawToStencil;
pr->drawPath(fClipTarget, &drawState, clipPath, stroke, false);
pr->drawPath(fClipTarget, &drawState, GrColor_WHITE, clipPath, stroke,
false);
} else {
pr->stencilPath(fClipTarget, &drawState, clipPath, stroke);
}
@ -806,15 +808,17 @@ bool GrClipMaskManager::createStencilClipMask(GrRenderTarget* rt,
if (canDrawDirectToClip) {
if (Element::kRect_Type == element->getType()) {
fClipTarget->drawSimpleRect(&drawStateCopy, element->getRect());
fClipTarget->drawSimpleRect(&drawStateCopy, GrColor_WHITE,
element->getRect());
} else {
GrDrawTarget::AutoGeometryPush agp(fClipTarget);
pr->drawPath(fClipTarget, &drawStateCopy, clipPath, stroke, false);
pr->drawPath(fClipTarget, &drawStateCopy, GrColor_WHITE, clipPath, stroke, false);
}
} else {
// The view matrix is setup to do clip space -> stencil space translation, so
// draw rect in clip space.
fClipTarget->drawSimpleRect(&drawStateCopy, SkRect::Make(clipSpaceIBounds));
fClipTarget->drawSimpleRect(&drawStateCopy, GrColor_WHITE,
SkRect::Make(clipSpaceIBounds));
}
}
}

View File

@ -152,6 +152,7 @@ private:
// desired blend operation. Optionally if the caller already selected a path renderer it can
// be passed. Otherwise the function will select one if the element is a path.
bool drawElement(GrDrawState*,
GrColor,
GrTexture* target,
const SkClipStack::Element*,
GrPathRenderer* pr = NULL);

View File

@ -315,7 +315,7 @@ GrTexture* GrContext::createResizedTexture(const GrSurfaceDesc& desc,
uint32_t flags = GrDefaultGeoProcFactory::kPosition_GPType |
GrDefaultGeoProcFactory::kLocalCoord_GPType;
const GrGeometryProcessor* gp = GrDefaultGeoProcFactory::Create(flags);
const GrGeometryProcessor* gp = GrDefaultGeoProcFactory::Create(GrColor_WHITE, flags);
drawState.setGeometryProcessor(gp)->unref();
GrDrawTarget::AutoReleaseGeometry arg(fDrawBuffer, 4, gp->getVertexStride(), 0);
@ -622,8 +622,10 @@ static bool apply_aa_to_rect(GrDrawTarget* target,
SkRect* devBoundRect,
const SkRect& rect,
SkScalar strokeWidth,
const SkMatrix& combinedMatrix) {
if (!ds->canTweakAlphaForCoverage() && !ds->couldApplyCoverage(*target->caps())) {
const SkMatrix& combinedMatrix,
GrColor color) {
if (!ds->canTweakAlphaForCoverage() && !ds->canUseFracCoveragePrimProc(color,
*target->caps())) {
#ifdef SK_DEBUG
//SkDebugf("Turning off AA to correctly apply blend.\n");
#endif
@ -722,9 +724,11 @@ void GrContext::drawRect(const GrPaint& paint,
}
}
GrColor color = paint.getColor();
SkRect devBoundRect;
bool needAA = paint.isAntiAlias() && !drawState.getRenderTarget()->isMultisampled();
bool doAA = needAA && apply_aa_to_rect(target, &drawState, &devBoundRect, rect, width, matrix);
bool doAA = needAA && apply_aa_to_rect(target, &drawState, &devBoundRect, rect, width, matrix,
color);
if (doAA) {
GrDrawState::AutoViewMatrixRestore avmr;
@ -736,13 +740,14 @@ void GrContext::drawRect(const GrPaint& paint,
const SkStrokeRec& strokeRec = strokeInfo->getStrokeRec();
fAARectRenderer->strokeAARect(target,
&drawState,
color,
rect,
matrix,
devBoundRect,
strokeRec);
} else {
// filled AA rect
fAARectRenderer->fillAARect(target, &drawState, rect, matrix, devBoundRect);
fAARectRenderer->fillAARect(target, &drawState, color, rect, matrix, devBoundRect);
}
return;
}
@ -753,7 +758,7 @@ void GrContext::drawRect(const GrPaint& paint,
// unitSquareVertexBuffer()
static const int worstCaseVertCount = 10;
const GrGeometryProcessor* gp = GrDefaultGeoProcFactory::Create();
const GrGeometryProcessor* gp = GrDefaultGeoProcFactory::Create(color);
drawState.setGeometryProcessor(gp)->unref();
GrDrawTarget::AutoReleaseGeometry geo(target,
worstCaseVertCount,
@ -788,7 +793,7 @@ void GrContext::drawRect(const GrPaint& paint,
target->drawNonIndexed(&drawState, primType, 0, vertCount);
} else {
// filled BW rect
target->drawSimpleRect(&drawState, rect);
target->drawSimpleRect(&drawState, color, rect);
}
}
@ -805,14 +810,15 @@ void GrContext::drawRectToRect(const GrPaint& paint,
GR_CREATE_TRACE_MARKER("GrContext::drawRectToRect", target);
target->drawRect(&drawState, dstRect, &localRect, localMatrix);
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) {
int* texOffset,
GrColor color) {
*texOffset = -1;
*colorOffset = -1;
@ -829,7 +835,7 @@ static void set_vertex_attributes(GrDrawState* drawState,
*colorOffset = sizeof(SkPoint);
flags |= GrDefaultGeoProcFactory::kColor_GPType;
}
drawState->setGeometryProcessor(GrDefaultGeoProcFactory::Create(flags))->unref();
drawState->setGeometryProcessor(GrDefaultGeoProcFactory::Create(color, flags))->unref();
}
void GrContext::drawVertices(const GrPaint& paint,
@ -852,7 +858,8 @@ 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);
set_vertex_attributes(&drawState, texCoords, colors, &colorOffset, &texOffset,
paint.getColor());
size_t vertexStride = drawState.getGeometryProcessor()->getVertexStride();
SkASSERT(vertexStride == sizeof(SkPoint) + (SkToBool(texCoords) ? sizeof(SkPoint) : 0)
@ -915,11 +922,12 @@ void GrContext::drawRRect(const GrPaint& paint,
const SkStrokeRec& strokeRec = strokeInfo.getStrokeRec();
if (!fOvalRenderer->drawRRect(target, &drawState, this, paint.isAntiAlias(), rrect,
GrColor color = paint.getColor();
if (!fOvalRenderer->drawRRect(target, &drawState, color, this, paint.isAntiAlias(), rrect,
strokeRec)) {
SkPath path;
path.addRRect(rrect);
this->internalDrawPath(target, &drawState, paint.isAntiAlias(), path, strokeInfo);
this->internalDrawPath(target, &drawState, color, paint.isAntiAlias(), path, strokeInfo);
}
}
@ -938,14 +946,16 @@ void GrContext::drawDRRect(const GrPaint& paint,
GR_CREATE_TRACE_MARKER("GrContext::drawDRRect", target);
if (!fOvalRenderer->drawDRRect(target, &drawState, this, paint.isAntiAlias(), outer, inner)) {
GrColor color = paint.getColor();
if (!fOvalRenderer->drawDRRect(target, &drawState, color, this, paint.isAntiAlias(), outer,
inner)) {
SkPath path;
path.addRRect(inner);
path.addRRect(outer);
path.setFillType(SkPath::kEvenOdd_FillType);
GrStrokeInfo fillRec(SkStrokeRec::kFill_InitStyle);
this->internalDrawPath(target, &drawState, paint.isAntiAlias(), path, fillRec);
this->internalDrawPath(target, &drawState, color, paint.isAntiAlias(), path, fillRec);
}
}
@ -976,17 +986,19 @@ void GrContext::drawOval(const GrPaint& paint,
const SkStrokeRec& strokeRec = strokeInfo.getStrokeRec();
if (!fOvalRenderer->drawOval(target, &drawState, this, paint.isAntiAlias(), oval, strokeRec)) {
GrColor color = paint.getColor();
if (!fOvalRenderer->drawOval(target, &drawState, color, this, paint.isAntiAlias(), oval,
strokeRec)) {
SkPath path;
path.addOval(oval);
this->internalDrawPath(target, &drawState, paint.isAntiAlias(), path, strokeInfo);
this->internalDrawPath(target, &drawState, color, paint.isAntiAlias(), path, strokeInfo);
}
}
// Can 'path' be drawn as a pair of filled nested rectangles?
static bool is_nested_rects(GrDrawTarget* target,
GrDrawState* drawState,
GrColor color,
const SkPath& path,
const SkStrokeRec& stroke,
SkRect rects[2]) {
@ -1002,7 +1014,8 @@ static bool is_nested_rects(GrDrawTarget* target,
return false;
}
if (!drawState->canTweakAlphaForCoverage() && !drawState->couldApplyCoverage(*target->caps())) {
if (!drawState->canTweakAlphaForCoverage() &&
!drawState->canUseFracCoveragePrimProc(color, *target->caps())) {
return false;
}
@ -1048,6 +1061,7 @@ void GrContext::drawPath(const GrPaint& paint, const SkPath& path, const GrStrok
return;
}
GrColor color = paint.getColor();
if (strokeInfo.isDashed()) {
SkPoint pts[2];
if (path.isLine(pts)) {
@ -1061,7 +1075,7 @@ void GrContext::drawPath(const GrPaint& paint, const SkPath& path, const GrStrok
SkMatrix origViewMatrix = drawState.getViewMatrix();
GrDrawState::AutoViewMatrixRestore avmr;
if (avmr.setIdentity(&drawState)) {
if (GrDashingEffect::DrawDashLine(fGpu, target, &drawState, pts, paint,
if (GrDashingEffect::DrawDashLine(fGpu, target, &drawState, color, pts, paint,
strokeInfo, origViewMatrix)) {
return;
}
@ -1104,14 +1118,14 @@ void GrContext::drawPath(const GrPaint& paint, const SkPath& path, const GrStrok
// Concave AA paths are expensive - try to avoid them for special cases
SkRect rects[2];
if (is_nested_rects(target, &drawState, path, strokeRec, rects)) {
if (is_nested_rects(target, &drawState, color, path, strokeRec, rects)) {
SkMatrix origViewMatrix = drawState.getViewMatrix();
GrDrawState::AutoViewMatrixRestore avmr;
if (!avmr.setIdentity(&drawState)) {
return;
}
fAARectRenderer->fillAANestedRects(target, &drawState, rects, origViewMatrix);
fAARectRenderer->fillAANestedRects(target, &drawState, color, rects, origViewMatrix);
return;
}
}
@ -1120,14 +1134,15 @@ void GrContext::drawPath(const GrPaint& paint, const SkPath& path, const GrStrok
bool isOval = path.isOval(&ovalRect);
if (!isOval || path.isInverseFillType()
|| !fOvalRenderer->drawOval(target, &drawState, this, paint.isAntiAlias(), ovalRect,
|| !fOvalRenderer->drawOval(target, &drawState, color, this, paint.isAntiAlias(), ovalRect,
strokeRec)) {
this->internalDrawPath(target, &drawState, paint.isAntiAlias(), path, strokeInfo);
this->internalDrawPath(target, &drawState, color, paint.isAntiAlias(), path, strokeInfo);
}
}
void GrContext::internalDrawPath(GrDrawTarget* target,
GrDrawState* drawState,
GrColor color,
bool useAA,
const SkPath& path,
const GrStrokeInfo& strokeInfo) {
@ -1142,7 +1157,7 @@ void GrContext::internalDrawPath(GrDrawTarget* target,
// thing WRT to the blend then we'll need some query on the PR.
bool useCoverageAA = useAA &&
!drawState->getRenderTarget()->isMultisampled() &&
drawState->couldApplyCoverage(*target->caps());
drawState->canUseFracCoveragePrimProc(color, *target->caps());
GrPathRendererChain::DrawType type =
@ -1179,7 +1194,7 @@ void GrContext::internalDrawPath(GrDrawTarget* target,
return;
}
pr->drawPath(target, drawState, *pathPtr, *stroke, useCoverageAA);
pr->drawPath(target, drawState, color, *pathPtr, *stroke, useCoverageAA);
}
////////////////////////////////////////////////////////////////////////////////
@ -1320,8 +1335,8 @@ bool GrContext::writeSurfacePixels(GrSurface* surface,
GrDrawState drawState(matrix);
drawState.addColorProcessor(fp);
drawState.setRenderTarget(renderTarget);
drawTarget->drawSimpleRect(&drawState, SkRect::MakeWH(SkIntToScalar(width),
SkIntToScalar(height)));
drawTarget->drawSimpleRect(&drawState, GrColor_WHITE,SkRect::MakeWH(SkIntToScalar(width),
SkIntToScalar(height)));
}
if (kFlushWrites_PixelOp & pixelOpsFlags) {
@ -1442,7 +1457,7 @@ bool GrContext::readRenderTargetPixels(GrRenderTarget* target,
drawState.setRenderTarget(tempTexture->asRenderTarget());
SkRect rect = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height));
fDrawBuffer->drawSimpleRect(&drawState, rect);
fDrawBuffer->drawSimpleRect(&drawState, GrColor_WHITE, rect);
// we want to read back from the scratch's origin
left = 0;
top = 0;
@ -1543,8 +1558,8 @@ GrDrawTarget* GrContext::prepareToDraw(GrDrawState* ds,
SkASSERT(acf);
ds->setFromPaint(*paint, fViewMatrix, fRenderTarget.get());
#if GR_DEBUG_PARTIAL_COVERAGE_CHECK
if ((paint->hasMask() || 0xff != paint->fCoverage) &&
!fDrawState->couldApplyCoverage(fGpu->caps())) {
if ((paint->hasMask()) &&
!fDrawState->canUseFracCoveragePrimProc(paint.getColor(), fGpu->caps())) {
SkDebugf("Partial pixel coverage will be incorrectly blended.\n");
}
#endif

View File

@ -21,8 +21,8 @@ typedef GrDefaultGeoProcFactory Flag;
class DefaultGeoProc : public GrGeometryProcessor {
public:
static GrGeometryProcessor* Create(uint32_t gpTypeFlags) {
return SkNEW_ARGS(DefaultGeoProc, (gpTypeFlags));
static GrGeometryProcessor* Create(GrColor color, uint8_t coverage, uint32_t gpTypeFlags) {
return SkNEW_ARGS(DefaultGeoProc, (color, coverage, gpTypeFlags));
}
virtual const char* name() const SK_OVERRIDE { return "DefaultGeometryProcessor"; }
@ -95,8 +95,9 @@ public:
}
private:
DefaultGeoProc(uint32_t gpTypeFlags)
: fInPosition(NULL)
DefaultGeoProc(GrColor color, uint8_t coverage, uint32_t gpTypeFlags)
: INHERITED(color, coverage)
, fInPosition(NULL)
, fInColor(NULL)
, fInLocalCoords(NULL)
, fInCoverage(NULL)
@ -143,7 +144,7 @@ private:
GR_DECLARE_GEOMETRY_PROCESSOR_TEST;
typedef GrFragmentProcessor INHERITED;
typedef GrGeometryProcessor INHERITED;
};
GR_DEFINE_GEOMETRY_PROCESSOR_TEST(DefaultGeoProc);
@ -163,9 +164,10 @@ GrGeometryProcessor* DefaultGeoProc::TestCreate(SkRandom* random,
flags |= GrDefaultGeoProcFactory::kLocalCoord_GPType;
}
return DefaultGeoProc::Create(flags);
return DefaultGeoProc::Create(GrRandomColor(random), GrRandomCoverage(random), flags);
}
const GrGeometryProcessor* GrDefaultGeoProcFactory::Create(uint32_t gpTypeFlags) {
return DefaultGeoProc::Create(gpTypeFlags);
const GrGeometryProcessor* GrDefaultGeoProcFactory::Create(GrColor color, uint32_t gpTypeFlags,
uint8_t coverage) {
return DefaultGeoProc::Create(color, coverage, gpTypeFlags);
}

View File

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

View File

@ -233,12 +233,10 @@ bool GrDefaultPathRenderer::createGeom(GrDrawTarget* target,
}
}
// TODO this is really wierd, I just need default vertex stride, can I think of a better way?
SkAutoTUnref<const GrGeometryProcessor> gp(GrDefaultGeoProcFactory::Create());
if (!arg->set(target, maxPts, gp->getVertexStride(), maxIdxs)) {
if (!arg->set(target, maxPts, GrDefaultGeoProcFactory::DefaultVertexStride(), maxIdxs)) {
return false;
}
SkASSERT(gp->getVertexStride() == sizeof(SkPoint));
SkASSERT(GrDefaultGeoProcFactory::DefaultVertexStride() == sizeof(SkPoint));
uint16_t* idxBase = reinterpret_cast<uint16_t*>(arg->indices());
uint16_t* idx = idxBase;
@ -330,6 +328,7 @@ FINISHED:
bool GrDefaultPathRenderer::internalDrawPath(GrDrawTarget* target,
GrDrawState* drawState,
GrColor color,
const SkPath& path,
const SkStrokeRec& origStroke,
bool stencilOnly) {
@ -337,10 +336,10 @@ bool GrDefaultPathRenderer::internalDrawPath(GrDrawTarget* target,
SkTCopyOnFirstWrite<SkStrokeRec> stroke(origStroke);
SkScalar hairlineCoverage;
uint8_t newCoverage = 0xff;
if (IsStrokeHairlineOrEquivalent(*stroke, drawState->getViewMatrix(),
&hairlineCoverage)) {
uint8_t newCoverage = SkScalarRoundToInt(hairlineCoverage * drawState->getCoverage());
drawState->setCoverage(newCoverage);
newCoverage = SkScalarRoundToInt(hairlineCoverage * 0xff);
if (!stroke->isHairlineStyle()) {
stroke.writable()->setHairlineStyle();
@ -493,13 +492,16 @@ bool GrDefaultPathRenderer::internalDrawPath(GrDrawTarget* target,
bounds = path.getBounds();
}
GrDrawTarget::AutoGeometryPush agp(target);
target->drawSimpleRect(drawState, bounds);
target->drawSimpleRect(drawState, color, bounds);
} else {
if (passCount > 1) {
drawState->enableState(GrDrawState::kNoColorWrites_StateBit);
}
GrDrawState::AutoRestoreEffects are(drawState);
drawState->setGeometryProcessor(GrDefaultGeoProcFactory::Create())->unref();
drawState->setGeometryProcessor(
GrDefaultGeoProcFactory::Create(color,
GrDefaultGeoProcFactory::kPosition_GPType,
newCoverage))->unref();
if (indexCnt) {
target->drawIndexed(drawState,
primType,
@ -530,11 +532,13 @@ bool GrDefaultPathRenderer::canDrawPath(const GrDrawTarget* target,
bool GrDefaultPathRenderer::onDrawPath(GrDrawTarget* target,
GrDrawState* drawState,
GrColor color,
const SkPath& path,
const SkStrokeRec& stroke,
bool antiAlias) {
return this->internalDrawPath(target,
drawState,
color,
path,
stroke,
false);
@ -546,5 +550,5 @@ void GrDefaultPathRenderer::onStencilPath(GrDrawTarget* target,
const SkStrokeRec& stroke) {
SkASSERT(SkPath::kInverseEvenOdd_FillType != path.getFillType());
SkASSERT(SkPath::kInverseWinding_FillType != path.getFillType());
this->internalDrawPath(target, drawState, path, stroke, true);
this->internalDrawPath(target, drawState, GrColor_WHITE, path, stroke, true);
}

View File

@ -34,6 +34,7 @@ private:
virtual bool onDrawPath(GrDrawTarget*,
GrDrawState*,
GrColor,
const SkPath&,
const SkStrokeRec&,
bool antiAlias) SK_OVERRIDE;
@ -45,6 +46,7 @@ private:
bool internalDrawPath(GrDrawTarget*,
GrDrawState*,
GrColor,
const SkPath&,
const SkStrokeRec&,
bool stencilOnly);

View File

@ -403,9 +403,11 @@ void GrDistanceFieldTextContext::setupCoverageEffect(const SkColor& filteredColo
if (textureUniqueID != fEffectTextureUniqueID ||
filteredColor != fEffectColor ||
flags != fEffectFlags) {
GrColor color = fPaint.getColor();
if (fUseLCDText) {
GrColor colorNoPreMul = skcolor_to_grcolor_nopremultiply(filteredColor);
fCachedGeometryProcessor.reset(GrDistanceFieldLCDTextureEffect::Create(fCurrTexture,
fCachedGeometryProcessor.reset(GrDistanceFieldLCDTextureEffect::Create(color,
fCurrTexture,
params,
fGammaTexture,
gammaParams,
@ -416,15 +418,18 @@ void GrDistanceFieldTextContext::setupCoverageEffect(const SkColor& filteredColo
#ifdef SK_GAMMA_APPLY_TO_A8
U8CPU lum = SkColorSpaceLuminance::computeLuminance(fDeviceProperties.gamma(),
filteredColor);
fCachedGeometryProcessor.reset(GrDistanceFieldTextureEffect::Create(fCurrTexture,
fCachedGeometryProcessor.reset(GrDistanceFieldTextureEffect::Create(color,
fCurrTexture,
params,
fGammaTexture,
gammaParams,
lum/255.f,
flags));
#else
fCachedGeometryProcessor.reset(GrDistanceFieldNoGammaTextureEffect::Create(fCurrTexture,
params, flags));
fCachedGeometryProcessor.reset(GrDistanceFieldNoGammaTextureEffect::Create(color,
fCurrTexture,
params,
flags));
#endif
}
fEffectTextureUniqueID = textureUniqueID;

View File

@ -15,11 +15,6 @@
#include "effects/GrPorterDuffXferProcessor.h"
bool GrDrawState::isEqual(const GrDrawState& that) const {
bool usingVertexColors = this->hasColorVertexAttribute();
if (!usingVertexColors && this->fColor != that.fColor) {
return false;
}
if (this->getRenderTarget() != that.getRenderTarget() ||
this->fColorStages.count() != that.fColorStages.count() ||
this->fCoverageStages.count() != that.fCoverageStages.count() ||
@ -30,11 +25,6 @@ bool GrDrawState::isEqual(const GrDrawState& that) const {
return false;
}
bool usingVertexCoverage = this->hasCoverageVertexAttribute();
if (!usingVertexCoverage && this->fCoverage != that.fCoverage) {
return false;
}
bool explicitLocalCoords = this->hasLocalCoordAttribute();
if (this->hasGeometryProcessor()) {
if (!that.hasGeometryProcessor()) {
@ -83,11 +73,9 @@ GrDrawState::GrDrawState(const GrDrawState& state, const SkMatrix& preConcatMatr
GrDrawState& GrDrawState::operator=(const GrDrawState& that) {
fRenderTarget.reset(SkSafeRef(that.fRenderTarget.get()));
fColor = that.fColor;
fViewMatrix = that.fViewMatrix;
fFlagBits = that.fFlagBits;
fStencilSettings = that.fStencilSettings;
fCoverage = that.fCoverage;
fDrawFace = that.fDrawFace;
fGeometryProcessor.reset(SkSafeRef(that.fGeometryProcessor.get()));
fXPFactory.reset(SkRef(that.getXPFactory()));
@ -116,7 +104,6 @@ void GrDrawState::onReset(const SkMatrix* initialViewMatrix) {
fColorStages.reset();
fCoverageStages.reset();
fColor = 0xffffffff;
if (NULL == initialViewMatrix) {
fViewMatrix.reset();
} else {
@ -124,7 +111,6 @@ void GrDrawState::onReset(const SkMatrix* initialViewMatrix) {
}
fFlagBits = 0x0;
fStencilSettings.setDisabled();
fCoverage = 0xff;
fDrawFace = kBoth_DrawFace;
fHints = 0;
@ -181,29 +167,34 @@ void GrDrawState::setFromPaint(const GrPaint& paint, const SkMatrix& vm, GrRende
// Enable the clip bit
this->enableState(GrDrawState::kClip_StateBit);
this->setColor(paint.getColor());
this->setState(GrDrawState::kDither_StateBit, paint.isDither());
this->setState(GrDrawState::kHWAntialias_StateBit, paint.isAntiAlias());
this->setCoverage(0xFF);
fColorProcInfoValid = false;
fCoverageProcInfoValid = false;
fColorCache = GrColor_ILLEGAL;
fCoverageCache = GrColor_ILLEGAL;
}
////////////////////////////////////////////////////////////////////////////////
bool GrDrawState::couldApplyCoverage(const GrDrawTargetCaps& caps) const {
bool GrDrawState::canUseFracCoveragePrimProc(GrColor color, const GrDrawTargetCaps& caps) const {
if (caps.dualSourceBlendingSupport()) {
return true;
}
this->calcColorInvariantOutput();
this->calcCoverageInvariantOutput();
this->calcColorInvariantOutput(color);
// The coverage isn't actually white, its unknown, but this will produce the same effect
// TODO we want to cache the result of this call, but we can probably clean up the interface
// so we don't have to pass in a seemingly known coverage
this->calcCoverageInvariantOutput(GrColor_WHITE);
return fXPFactory->canApplyCoverage(fColorProcInfo, fCoverageProcInfo,
this->isCoverageDrawing(), this->isColorWriteDisabled());
}
bool GrDrawState::hasSolidCoverage() const {
bool GrDrawState::hasSolidCoverage(GrColor coverage) const {
// If we're drawing coverage directly then coverage is effectively treated as color.
if (this->isCoverageDrawing()) {
return true;
@ -213,15 +204,15 @@ bool GrDrawState::hasSolidCoverage() const {
return false;
}
this->calcCoverageInvariantOutput();
this->calcCoverageInvariantOutput(coverage);
return fCoverageProcInfo.isSolidWhite();
}
//////////////////////////////////////////////////////////////////////////////s
bool GrDrawState::willEffectReadDstColor() const {
this->calcColorInvariantOutput();
this->calcCoverageInvariantOutput();
bool GrDrawState::willEffectReadDstColor(GrColor color, GrColor coverage) const {
this->calcColorInvariantOutput(color);
this->calcCoverageInvariantOutput(coverage);
// 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
@ -378,25 +369,24 @@ GrDrawState::~GrDrawState() {
////////////////////////////////////////////////////////////////////////////////
bool GrDrawState::srcAlphaWillBeOne() const {
this->calcColorInvariantOutput();
bool GrDrawState::srcAlphaWillBeOne(GrColor color, GrColor coverage) const {
this->calcColorInvariantOutput(color);
if (this->isCoverageDrawing()) {
this->calcCoverageInvariantOutput();
this->calcCoverageInvariantOutput(coverage);
return (fColorProcInfo.isOpaque() && fCoverageProcInfo.isOpaque());
}
return fColorProcInfo.isOpaque();
}
bool GrDrawState::willBlendWithDst() const {
this->calcColorInvariantOutput();
this->calcCoverageInvariantOutput();
bool GrDrawState::willBlendWithDst(GrColor color, GrColor coverage) const {
this->calcColorInvariantOutput(color);
this->calcCoverageInvariantOutput(coverage);
return fXPFactory->willBlendWithDst(fColorProcInfo, fCoverageProcInfo,
this->isCoverageDrawing(), this->isColorWriteDisabled());
}
void GrDrawState::calcColorInvariantOutput() const {
if (!fColorProcInfoValid) {
GrColor color;
void GrDrawState::calcColorInvariantOutput(GrColor color) const {
if (!fColorProcInfoValid || color != fColorCache) {
GrColorComponentFlags flags;
if (this->hasColorVertexAttribute()) {
if (fHints & kVertexColorsAreOpaque_Hint) {
@ -408,28 +398,27 @@ void GrDrawState::calcColorInvariantOutput() const {
}
} else {
flags = kRGBA_GrColorComponentFlags;
color = this->getColor();
}
fColorProcInfo.calcWithInitialValues(fColorStages.begin(), this->numColorStages(),
color, flags, false);
fColorProcInfoValid = true;
fColorCache = color;
}
}
void GrDrawState::calcCoverageInvariantOutput() const {
if (!fCoverageProcInfoValid) {
GrColor color;
void GrDrawState::calcCoverageInvariantOutput(GrColor coverage) const {
if (!fCoverageProcInfoValid || coverage != fCoverageCache) {
GrColorComponentFlags flags;
// Check if per-vertex or constant color may have partial alpha
if (this->hasCoverageVertexAttribute()) {
flags = static_cast<GrColorComponentFlags>(0);
color = 0;
coverage = 0;
} else {
flags = kRGBA_GrColorComponentFlags;
color = this->getCoverageColor();
}
fCoverageProcInfo.calcWithInitialValues(fCoverageStages.begin(), this->numCoverageStages(),
color, flags, true, fGeometryProcessor.get());
coverage, flags, true, fGeometryProcessor.get());
fCoverageProcInfoValid = true;
fCoverageCache = coverage;
}
}

View File

@ -92,73 +92,21 @@ public:
*
* This function considers the current draw state and the draw target's capabilities to
* determine whether coverage can be handled correctly. This function assumes that the caller
* intends to specify fractional pixel coverage (via setCoverage(), through a coverage vertex
* attribute, or a coverage effect) but may not have specified it yet.
* intends to specify fractional pixel coverage via a primitive processor but may not have
* specified it yet.
*/
bool couldApplyCoverage(const GrDrawTargetCaps& caps) const;
bool canUseFracCoveragePrimProc(GrColor color, const GrDrawTargetCaps& caps) const;
/**
* Determines whether the output coverage is guaranteed to be one for all pixels hit by a draw.
*/
bool hasSolidCoverage() const;
bool hasSolidCoverage(GrColor coverage) const;
/**
* This function returns true if the render target destination pixel values will be read for
* blending during draw.
*/
bool willBlendWithDst() const;
/// @}
///////////////////////////////////////////////////////////////////////////
/// @name Color
////
GrColor getColor() const { return fColor; }
/**
* Sets color for next draw to a premultiplied-alpha color.
*
* @param color the color to set.
*/
void setColor(GrColor color) {
if (color != fColor) {
fColor = color;
fColorProcInfoValid = false;
}
}
/**
* Sets the color to be used for the next draw to be
* (r,g,b,a) = (alpha, alpha, alpha, alpha).
*
* @param alpha The alpha value to set as the color.
*/
void setAlpha(uint8_t a) { this->setColor((a << 24) | (a << 16) | (a << 8) | a); }
/// @}
///////////////////////////////////////////////////////////////////////////
/// @name Coverage
////
uint8_t getCoverage() const { return fCoverage; }
GrColor getCoverageColor() const {
return GrColorPackRGBA(fCoverage, fCoverage, fCoverage, fCoverage);
}
/**
* Sets a constant fractional coverage to be applied to the draw. The
* initial value (after construction or reset()) is 0xff. The constant
* coverage is ignored when per-vertex coverage is provided.
*/
void setCoverage(uint8_t coverage) {
if (coverage != fCoverage) {
fCoverage = coverage;
fCoverageProcInfoValid = false;
}
}
bool willBlendWithDst(GrColor color, GrColor coverage) const;
/// @}
@ -213,8 +161,9 @@ public:
/**
* Checks whether any of the effects will read the dst pixel color.
* TODO remove when we have an XP
*/
bool willEffectReadDstColor() const;
bool willEffectReadDstColor(GrColor color, GrColor coverage) const;
/**
* The xfer processor factory.
@ -608,32 +557,32 @@ public:
private:
bool isEqual(const GrDrawState& that) const;
const GrProcOptInfo& colorProcInfo() const {
this->calcColorInvariantOutput();
const GrProcOptInfo& colorProcInfo(GrColor color) const {
this->calcColorInvariantOutput(color);
return fColorProcInfo;
}
const GrProcOptInfo& coverageProcInfo() const {
this->calcCoverageInvariantOutput();
const GrProcOptInfo& coverageProcInfo(GrColor coverage) const {
this->calcCoverageInvariantOutput(coverage);
return fCoverageProcInfo;
}
/**
* Determines whether src alpha is guaranteed to be one for all src pixels
*/
bool srcAlphaWillBeOne() const;
bool srcAlphaWillBeOne(GrColor color, GrColor coverage) const;
/**
* If fColorProcInfoValid is false, function calculates the invariant output for the color
* stages and results are stored in fColorProcInfo.
*/
void calcColorInvariantOutput() const;
void calcColorInvariantOutput(GrColor) const;
/**
* If fCoverageProcInfoValid is false, function calculates the invariant output for the coverage
* stages and results are stored in fCoverageProcInfo.
*/
void calcCoverageInvariantOutput() const;
void calcCoverageInvariantOutput(GrColor) const;
void onReset(const SkMatrix* initialViewMatrix);
@ -644,11 +593,9 @@ private:
typedef SkSTArray<4, GrFragmentStage> FragmentStageArray;
SkAutoTUnref<GrRenderTarget> fRenderTarget;
GrColor fColor;
SkMatrix fViewMatrix;
uint32_t fFlagBits;
GrStencilSettings fStencilSettings;
uint8_t fCoverage;
DrawFace fDrawFace;
SkAutoTUnref<const GrGeometryProcessor> fGeometryProcessor;
SkAutoTUnref<const GrXPFactory> fXPFactory;
@ -660,6 +607,8 @@ private:
mutable GrProcOptInfo fCoverageProcInfo;
mutable bool fColorProcInfoValid;
mutable bool fCoverageProcInfoValid;
mutable GrColor fColorCache;
mutable GrColor fCoverageCache;
friend class GrOptDrawState;
};

View File

@ -383,9 +383,12 @@ bool GrDrawTarget::checkDraw(const GrDrawState& drawState,
}
bool GrDrawTarget::setupDstReadIfNecessary(GrDrawState* ds,
GrColor color,
uint8_t coverage,
GrDeviceCoordTexture* dstCopy,
const SkRect* drawBounds) {
if (this->caps()->dstReadInShaderSupport() || !ds->willEffectReadDstColor()) {
GrColor c = GrColorPackRGBA(coverage, coverage, coverage, coverage);
if (this->caps()->dstReadInShaderSupport() || !ds->willEffectReadDstColor(color, c)) {
return true;
}
SkIRect copyRect;
@ -468,10 +471,12 @@ void GrDrawTarget::drawIndexed(GrDrawState* ds,
// TODO: We should continue with incorrect blending.
GrDeviceCoordTexture dstCopy;
if (!this->setupDstReadIfNecessary(ds, &dstCopy, devBounds)) {
const GrGeometryProcessor* gp = ds->getGeometryProcessor();
if (!this->setupDstReadIfNecessary(ds, gp->getColor(), gp->getCoverage(), &dstCopy,
devBounds)) {
return;
}
this->setDrawBuffers(&info, ds->getGeometryProcessor()->getVertexStride());
this->setDrawBuffers(&info, gp->getVertexStride());
this->onDraw(*ds, info, scissorState, dstCopy.texture() ? &dstCopy : NULL);
}
@ -510,11 +515,13 @@ void GrDrawTarget::drawNonIndexed(GrDrawState* ds,
// TODO: We should continue with incorrect blending.
GrDeviceCoordTexture dstCopy;
if (!this->setupDstReadIfNecessary(ds, &dstCopy, devBounds)) {
const GrGeometryProcessor* gp = ds->getGeometryProcessor();
if (!this->setupDstReadIfNecessary(ds, gp->getColor(), gp->getCoverage(), &dstCopy,
devBounds)) {
return;
}
this->setDrawBuffers(&info, ds->getGeometryProcessor()->getVertexStride());
this->setDrawBuffers(&info, gp->getVertexStride());
this->onDraw(*ds, info, scissorState, dstCopy.texture() ? &dstCopy : NULL);
}
@ -581,6 +588,7 @@ void GrDrawTarget::stencilPath(GrDrawState* ds,
}
void GrDrawTarget::drawPath(GrDrawState* ds,
GrColor color,
const GrPath* path,
GrPathRendering::FillType fill) {
// TODO: extract portions of checkDraw that are relevant to path rendering.
@ -607,14 +615,16 @@ void GrDrawTarget::drawPath(GrDrawState* ds,
&stencilSettings);
GrDeviceCoordTexture dstCopy;
if (!this->setupDstReadIfNecessary(ds, &dstCopy, &devBounds)) {
if (!this->setupDstReadIfNecessary(ds, color, 0xff, &dstCopy, &devBounds)) {
return;
}
this->onDrawPath(*ds, path, scissorState, stencilSettings, dstCopy.texture() ? &dstCopy : NULL);
this->onDrawPath(*ds, color, path, scissorState, stencilSettings, dstCopy.texture() ? &dstCopy :
NULL);
}
void GrDrawTarget::drawPaths(GrDrawState* ds,
GrColor color,
const GrPathRange* pathRange,
const void* indices,
PathIndexType indexType,
@ -649,12 +659,12 @@ 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, &dstCopy, NULL)) {
if (!this->setupDstReadIfNecessary(ds, color, 0xff, &dstCopy, NULL)) {
return;
}
this->onDrawPaths(*ds, pathRange, indices, indexType, transformValues, transformType, count,
scissorState, stencilSettings, dstCopy.texture() ? &dstCopy : NULL);
this->onDrawPaths(*ds, color, pathRange, indices, indexType, transformValues, transformType,
count, scissorState, stencilSettings, dstCopy.texture() ? &dstCopy : NULL);
}
void GrDrawTarget::clear(const SkIRect* rect,
@ -673,11 +683,9 @@ void GrDrawTarget::clear(const SkIRect* rect,
}
GrDrawState drawState;
drawState.setColor(color);
drawState.setRenderTarget(renderTarget);
this->drawSimpleRect(&drawState, *rect);
this->drawSimpleRect(&drawState, color, *rect);
} else {
this->onClear(rect, color, canIgnoreRect, renderTarget);
}
@ -763,7 +771,8 @@ void GrDrawTarget::drawIndexedInstances(GrDrawState* ds,
// TODO: We should continue with incorrect blending.
GrDeviceCoordTexture dstCopy;
if (!this->setupDstReadIfNecessary(ds, &dstCopy, devBounds)) {
const GrGeometryProcessor* gp = ds->getGeometryProcessor();
if (!this->setupDstReadIfNecessary(ds, gp->getColor(), gp->getCoverage(), &dstCopy,devBounds)) {
return;
}
@ -778,7 +787,7 @@ void GrDrawTarget::drawIndexedInstances(GrDrawState* ds,
info.fStartIndex,
info.fVertexCount,
info.fIndexCount)) {
this->setDrawBuffers(&info, ds->getGeometryProcessor()->getVertexStride());
this->setDrawBuffers(&info, gp->getVertexStride());
this->onDraw(*ds, info, scissorState, dstCopy.texture() ? &dstCopy : NULL);
}
info.fStartVertex += info.fVertexCount;
@ -944,7 +953,7 @@ bool GrDrawTarget::copySurface(GrSurface* dst,
clippedDstPoint.fY,
clippedSrcRect.width(),
clippedSrcRect.height());
this->drawSimpleRect(&drawState, dstRect);
this->drawSimpleRect(&drawState, GrColor_WHITE, dstRect);
return true;
}

View File

@ -269,7 +269,7 @@ public:
* 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*, const GrPath*, GrPathRendering::FillType fill);
void drawPath(GrDrawState*, GrColor, const GrPath*, GrPathRendering::FillType fill);
/**
* Draws the aggregate path from combining multiple. Note that this will not
@ -284,7 +284,9 @@ public:
* @param count Number of paths to draw
* @param fill Fill type for drawing all the paths
*/
void drawPaths(GrDrawState*, const GrPathRange* pathRange,
void drawPaths(GrDrawState*,
GrColor,
const GrPathRange* pathRange,
const void* indices,
PathIndexType indexType,
const float transformValues[],
@ -305,22 +307,23 @@ public:
* srcMatrix can be NULL when no srcMatrix is desired.
*/
void drawRect(GrDrawState* ds,
GrColor color,
const SkRect& rect,
const SkRect* localRect,
const SkMatrix* localMatrix) {
AutoGeometryPush agp(this);
this->onDrawRect(ds, rect, localRect, localMatrix);
this->onDrawRect(ds, color, rect, localRect, localMatrix);
}
/**
* Helper for drawRect when the caller doesn't need separate local rects or matrices.
*/
void drawSimpleRect(GrDrawState* ds, const SkRect& rect) {
this->drawRect(ds, rect, NULL, NULL);
void drawSimpleRect(GrDrawState* ds, GrColor color, const SkRect& rect) {
this->drawRect(ds, color, rect, NULL, NULL);
}
void drawSimpleRect(GrDrawState* ds, const SkIRect& irect) {
void drawSimpleRect(GrDrawState* ds, GrColor color, const SkIRect& irect) {
SkRect rect = SkRect::Make(irect);
this->drawRect(ds, rect, NULL, NULL);
this->drawRect(ds, color, rect, NULL, NULL);
}
/**
@ -653,6 +656,8 @@ 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,
GrDeviceCoordTexture* dstCopy,
const SkRect* drawBounds);
@ -698,6 +703,7 @@ private:
const GrDeviceCoordTexture* dstCopy) = 0;
// TODO copy in order drawbuffer onDrawRect to here
virtual void onDrawRect(GrDrawState*,
GrColor color,
const SkRect& rect,
const SkRect* localRect,
const SkMatrix* localMatrix) = 0;
@ -707,11 +713,13 @@ private:
const GrClipMaskManager::ScissorState&,
const GrStencilSettings&) = 0;
virtual void onDrawPath(const GrDrawState&,
GrColor,
const GrPath*,
const GrClipMaskManager::ScissorState&,
const GrStencilSettings&,
const GrDeviceCoordTexture* dstCopy) = 0;
virtual void onDrawPaths(const GrDrawState&,
GrColor,
const GrPathRange*,
const void* indices,
PathIndexType,

View File

@ -8,6 +8,7 @@
#ifndef GrGeometryProcessor_DEFINED
#define GrGeometryProcessor_DEFINED
#include "GrColor.h"
#include "GrGeometryData.h"
#include "GrProcessor.h"
#include "GrShaderVar.h"
@ -50,8 +51,10 @@ class GrOptDrawState;
*/
class GrGeometryProcessor : public GrProcessor {
public:
GrGeometryProcessor()
GrGeometryProcessor(GrColor color, uint8_t coverage = 0xff)
: fVertexStride(0)
, fColor(color)
, fCoverage(coverage)
, fWillUseGeoShader(false)
, fHasVertexColor(false)
, fHasVertexCoverage(false)
@ -107,6 +110,14 @@ public:
if (this->classID() != that.classID() || !this->hasSameTextureAccesses(that)) {
return false;
}
if (!fHasVertexColor && this->getColor() != that.getColor()) {
return false;
}
if (!fHasVertexCoverage && this->getCoverage() != that.getCoverage()) {
return false;
}
return this->onIsEqual(that);
}
@ -119,12 +130,17 @@ public:
virtual void initBatchTracker(GrBatchTracker*, const InitBT&) const {}
GrColor getColor() const { return fColor; }
uint8_t getCoverage() const { return fCoverage; }
// TODO this is a total hack until the gp can own whether or not it uses uniform
// color / coverage
bool hasVertexColor() const { return fHasVertexColor; }
bool hasVertexCoverage() const { return fHasVertexCoverage; }
bool hasLocalCoords() const { return fHasLocalCoords; }
void computeInvariantColor(GrInvariantOutput* inout) const;
protected:
/**
* Subclasses call this from their constructor to register vertex attributes. Attributes
@ -149,6 +165,8 @@ private:
SkSTArray<kMaxVertexAttribs, GrAttribute, true> fAttribs;
size_t fVertexStride;
GrColor fColor;
uint8_t fCoverage;
bool fWillUseGeoShader;
bool fHasVertexColor;
bool fHasVertexCoverage;

View File

@ -66,7 +66,7 @@ static void set_vertex_attributes(GrDrawState* drawState, bool hasLocalCoords, G
uint32_t flags = GrDefaultGeoProcFactory::kPosition_GPType |
GrDefaultGeoProcFactory::kColor_GPType;
flags |= hasLocalCoords ? GrDefaultGeoProcFactory::kLocalCoord_GPType : 0;
drawState->setGeometryProcessor(GrDefaultGeoProcFactory::Create(flags))->unref();
drawState->setGeometryProcessor(GrDefaultGeoProcFactory::Create(color, flags))->unref();
if (0xFF == GrColorUnpackA(color)) {
drawState->setHint(GrDrawState::kVertexColorsAreOpaque_Hint, true);
}
@ -110,12 +110,12 @@ static inline uint8_t strip_trace_bit(uint8_t cmd) { return cmd & kCmdMask; }
static inline bool cmd_has_trace_marker(uint8_t cmd) { return SkToBool(cmd & kTraceCmdBit); }
void GrInOrderDrawBuffer::onDrawRect(GrDrawState* ds,
GrColor color,
const SkRect& rect,
const SkRect* localRect,
const SkMatrix* localMatrix) {
GrDrawState::AutoRestoreEffects are(ds);
GrColor color = ds->getColor();
set_vertex_attributes(ds, SkToBool(localRect), color);
size_t vstride = ds->getGeometryProcessor()->getVertexStride();
@ -226,7 +226,9 @@ void GrInOrderDrawBuffer::onDraw(const GrDrawState& ds,
const GrDeviceCoordTexture* dstCopy) {
SkASSERT(info.vertexBuffer() && (!info.isIndexed() || info.indexBuffer()));
if (!this->recordStateAndShouldDraw(ds, GrGpu::PrimTypeToDrawType(info.primitiveType()),
const GrGeometryProcessor* gp = ds.getGeometryProcessor();
if (!this->recordStateAndShouldDraw(ds, gp->getColor(), gp->getCoverage(),
GrGpu::PrimTypeToDrawType(info.primitiveType()),
scissorState, dstCopy)) {
return;
}
@ -251,7 +253,8 @@ void GrInOrderDrawBuffer::onStencilPath(const GrDrawState& ds,
const GrClipMaskManager::ScissorState& scissorState,
const GrStencilSettings& stencilSettings) {
// Only compare the subset of GrDrawState relevant to path stenciling?
if (!this->recordStateAndShouldDraw(ds, GrGpu::kStencilPath_DrawType, scissorState, NULL)) {
if (!this->recordStateAndShouldDraw(ds, GrColor_WHITE, 0xff, GrGpu::kStencilPath_DrawType,
scissorState, NULL)) {
return;
}
StencilPath* sp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, StencilPath, (path));
@ -260,12 +263,14 @@ void GrInOrderDrawBuffer::onStencilPath(const GrDrawState& ds,
}
void GrInOrderDrawBuffer::onDrawPath(const GrDrawState& ds,
GrColor color,
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, GrGpu::kDrawPath_DrawType, scissorState, dstCopy)) {
if (!this->recordStateAndShouldDraw(ds, color, 0xff, GrGpu::kDrawPath_DrawType, scissorState,
dstCopy)) {
return;
}
DrawPath* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPath, (path));
@ -274,6 +279,7 @@ void GrInOrderDrawBuffer::onDrawPath(const GrDrawState& ds,
}
void GrInOrderDrawBuffer::onDrawPaths(const GrDrawState& ds,
GrColor color,
const GrPathRange* pathRange,
const void* indices,
PathIndexType indexType,
@ -287,7 +293,8 @@ void GrInOrderDrawBuffer::onDrawPaths(const GrDrawState& ds,
SkASSERT(indices);
SkASSERT(transformValues);
if (!this->recordStateAndShouldDraw(ds, GrGpu::kDrawPath_DrawType, scissorState, dstCopy)) {
if (!this->recordStateAndShouldDraw(ds, color, 0xff, GrGpu::kDrawPath_DrawType, scissorState,
dstCopy)) {
return;
}
@ -317,7 +324,7 @@ void GrInOrderDrawBuffer::onDrawPaths(const GrDrawState& ds,
transformType == previous->fTransformType &&
stencilSettings == previous->fStencilSettings &&
path_fill_type_is_winding(stencilSettings) &&
!ds.willBlendWithDst()) {
!ds.willBlendWithDst(color, GrColor_WHITE)) {
// Fold this DrawPaths call into the one previous.
previous->fCount += count;
return;
@ -483,12 +490,14 @@ bool GrInOrderDrawBuffer::onCopySurface(GrSurface* dst,
}
bool GrInOrderDrawBuffer::recordStateAndShouldDraw(const GrDrawState& ds,
GrColor color,
uint8_t coverage,
GrGpu::DrawType drawType,
const GrClipMaskManager::ScissorState& scissor,
const GrDeviceCoordTexture* dstCopy) {
SetState* ss = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState,
(ds, *this->getGpu()->caps(), scissor, dstCopy,
drawType));
(ds, color, coverage, *this->getGpu()->caps(), scissor,
dstCopy, drawType));
if (ss->fState.mustSkip()) {
fCmdBuffer.pop_back();
return false;

View File

@ -171,11 +171,11 @@ private:
};
struct SetState : public Cmd {
SetState(const GrDrawState& drawState, const GrDrawTargetCaps& caps,
const ScissorState& scissor, const GrDeviceCoordTexture* dstCopy,
GrGpu::DrawType drawType)
SetState(const GrDrawState& drawState, GrColor color, uint8_t coverage,
const GrDrawTargetCaps& caps, const ScissorState& scissor,
const GrDeviceCoordTexture* dstCopy, GrGpu::DrawType drawType)
: Cmd(kSetState_Cmd)
, fState(drawState, caps, scissor, dstCopy, drawType) {}
, fState(drawState, color, coverage, caps, scissor, dstCopy, drawType) {}
void execute(GrInOrderDrawBuffer*, const GrOptDrawState*) SK_OVERRIDE;
@ -194,6 +194,7 @@ private:
const ScissorState&,
const GrDeviceCoordTexture* dstCopy) SK_OVERRIDE;
void onDrawRect(GrDrawState*,
GrColor,
const SkRect& rect,
const SkRect* localRect,
const SkMatrix* localMatrix) SK_OVERRIDE;
@ -203,11 +204,13 @@ private:
const ScissorState&,
const GrStencilSettings&) SK_OVERRIDE;
void onDrawPath(const GrDrawState&,
GrColor,
const GrPath*,
const ScissorState&,
const GrStencilSettings&,
const GrDeviceCoordTexture* dstCopy) SK_OVERRIDE;
void onDrawPaths(const GrDrawState&,
GrColor,
const GrPathRange*,
const void* indices,
PathIndexType,
@ -234,6 +237,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,
GrGpu::DrawType,
const GrClipMaskManager::ScissorState&,
const GrDeviceCoordTexture*);

View File

@ -14,18 +14,21 @@
#include "GrXferProcessor.h"
GrOptDrawState::GrOptDrawState(const GrDrawState& drawState,
GrColor color,
uint8_t coverage,
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();
const GrProcOptInfo& coveragePOI = drawState.coverageProcInfo();
const GrProcOptInfo& colorPOI = drawState.colorProcInfo(color);
const GrProcOptInfo& coveragePOI = drawState.coverageProcInfo(coverageColor);
fColor = colorPOI.inputColorToEffectiveStage();
fCoverage = drawState.getCoverage();
fCoverage = coverage;
// Create XferProcessor from DS's XPFactory
SkAutoTUnref<GrXferProcessor> xferProcessor(
@ -144,10 +147,11 @@ GrOptDrawState::GrOptDrawState(const GrDrawState& drawState,
fGeometryProcessor->initBatchTracker(&fBatchTracker, init);
}
this->setOutputStateInfo(drawState, optFlags, caps);
this->setOutputStateInfo(drawState, coverageColor, optFlags, caps);
}
void GrOptDrawState::setOutputStateInfo(const GrDrawState& ds,
GrColor coverage,
GrXferProcessor::OptFlags optFlags,
const GrDrawTargetCaps& caps) {
// Set this default and then possibly change our mind if there is coverage.
@ -157,7 +161,7 @@ void GrOptDrawState::setOutputStateInfo(const GrDrawState& ds,
// Determine whether we should use dual source blending or shader code to keep coverage
// separate from color.
bool keepCoverageSeparate = !(optFlags & GrXferProcessor::kSetCoverageDrawing_OptFlag);
if (keepCoverageSeparate && !ds.hasSolidCoverage()) {
if (keepCoverageSeparate && !ds.hasSolidCoverage(coverage)) {
if (caps.dualSourceBlendingSupport()) {
if (kZero_GrBlendCoeff == fDstBlend) {
// write the coverage value to second color

View File

@ -30,8 +30,8 @@ public:
typedef GrClipMaskManager::ScissorState ScissorState;
GrOptDrawState(const GrDrawState& drawState, const GrDrawTargetCaps&, const ScissorState&,
const GrDeviceCoordTexture* dstCopy, GrGpu::DrawType);
GrOptDrawState(const GrDrawState& drawState, GrColor, uint8_t coverage, const GrDrawTargetCaps&,
const ScissorState&, const GrDeviceCoordTexture* dstCopy, GrGpu::DrawType);
bool operator== (const GrOptDrawState& that) const;
bool operator!= (const GrOptDrawState& that) const { return !(*this == that); }
@ -206,7 +206,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, GrXferProcessor::OptFlags,
void setOutputStateInfo(const GrDrawState& ds, GrColor coverage, GrXferProcessor::OptFlags,
const GrDrawTargetCaps&);
enum Flags {

View File

@ -59,8 +59,8 @@ inline bool circle_stays_circle(const SkMatrix& m) {
class CircleEdgeEffect : public GrGeometryProcessor {
public:
static GrGeometryProcessor* Create(bool stroke) {
return SkNEW_ARGS(CircleEdgeEffect, (stroke));
static GrGeometryProcessor* Create(GrColor color, bool stroke) {
return SkNEW_ARGS(CircleEdgeEffect, (color, stroke));
}
const GrAttribute* inPosition() const { return fInPosition; }
@ -131,7 +131,7 @@ public:
}
private:
CircleEdgeEffect(bool stroke) {
CircleEdgeEffect(GrColor color, bool stroke) : INHERITED(color) {
this->initClassID<CircleEdgeEffect>();
fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_GrVertexAttribType));
fInCircleEdge = &this->addVertexAttrib(GrAttribute("inCircleEdge",
@ -163,7 +163,7 @@ GrGeometryProcessor* CircleEdgeEffect::TestCreate(SkRandom* random,
GrContext* context,
const GrDrawTargetCaps&,
GrTexture* textures[]) {
return CircleEdgeEffect::Create(random->nextBool());
return CircleEdgeEffect::Create(GrRandomColor(random), random->nextBool());
}
///////////////////////////////////////////////////////////////////////////////
@ -178,8 +178,8 @@ GrGeometryProcessor* CircleEdgeEffect::TestCreate(SkRandom* random,
class EllipseEdgeEffect : public GrGeometryProcessor {
public:
static GrGeometryProcessor* Create(bool stroke) {
return SkNEW_ARGS(EllipseEdgeEffect, (stroke));
static GrGeometryProcessor* Create(GrColor color, bool stroke) {
return SkNEW_ARGS(EllipseEdgeEffect, (color, stroke));
}
virtual ~EllipseEdgeEffect() {}
@ -275,7 +275,7 @@ public:
}
private:
EllipseEdgeEffect(bool stroke) {
EllipseEdgeEffect(GrColor color, bool stroke) : INHERITED(color) {
this->initClassID<EllipseEdgeEffect>();
fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_GrVertexAttribType));
fInEllipseOffset = &this->addVertexAttrib(GrAttribute("inEllipseOffset",
@ -310,7 +310,7 @@ GrGeometryProcessor* EllipseEdgeEffect::TestCreate(SkRandom* random,
GrContext* context,
const GrDrawTargetCaps&,
GrTexture* textures[]) {
return EllipseEdgeEffect::Create(random->nextBool());
return EllipseEdgeEffect::Create(GrRandomColor(random), random->nextBool());
}
///////////////////////////////////////////////////////////////////////////////
@ -328,8 +328,8 @@ class DIEllipseEdgeEffect : public GrGeometryProcessor {
public:
enum Mode { kStroke = 0, kHairline, kFill };
static GrGeometryProcessor* Create(Mode mode) {
return SkNEW_ARGS(DIEllipseEdgeEffect, (mode));
static GrGeometryProcessor* Create(GrColor color, Mode mode) {
return SkNEW_ARGS(DIEllipseEdgeEffect, (color, mode));
}
virtual ~DIEllipseEdgeEffect() {}
@ -440,7 +440,7 @@ public:
}
private:
DIEllipseEdgeEffect(Mode mode) {
DIEllipseEdgeEffect(GrColor color, Mode mode) : INHERITED(color) {
this->initClassID<DIEllipseEdgeEffect>();
fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_GrVertexAttribType));
fInEllipseOffsets0 = &this->addVertexAttrib(GrAttribute("inEllipseOffsets0",
@ -475,7 +475,7 @@ GrGeometryProcessor* DIEllipseEdgeEffect::TestCreate(SkRandom* random,
GrContext* context,
const GrDrawTargetCaps&,
GrTexture* textures[]) {
return DIEllipseEdgeEffect::Create((Mode)(random->nextRangeU(0,2)));
return DIEllipseEdgeEffect::Create(GrRandomColor(random), (Mode)(random->nextRangeU(0,2)));
}
///////////////////////////////////////////////////////////////////////////////
@ -487,6 +487,7 @@ void GrOvalRenderer::reset() {
bool GrOvalRenderer::drawOval(GrDrawTarget* target,
GrDrawState* drawState,
GrColor color,
const GrContext* context,
bool useAA,
const SkRect& oval,
@ -494,7 +495,7 @@ bool GrOvalRenderer::drawOval(GrDrawTarget* target,
{
bool useCoverageAA = useAA &&
!drawState->getRenderTarget()->isMultisampled() &&
drawState->couldApplyCoverage(*target->caps());
drawState->canUseFracCoveragePrimProc(color, *target->caps());
if (!useCoverageAA) {
return false;
@ -505,13 +506,13 @@ bool GrOvalRenderer::drawOval(GrDrawTarget* target,
// we can draw circles
if (SkScalarNearlyEqual(oval.width(), oval.height())
&& circle_stays_circle(vm)) {
this->drawCircle(target, drawState, context, useCoverageAA, oval, stroke);
this->drawCircle(target, drawState, color, context, useCoverageAA, oval, stroke);
// if we have shader derivative support, render as device-independent
} else if (target->caps()->shaderDerivativeSupport()) {
return this->drawDIEllipse(target, drawState, context, useCoverageAA, oval, stroke);
return this->drawDIEllipse(target, drawState, color, context, useCoverageAA, oval, stroke);
// otherwise axis-aligned ellipses only
} else if (vm.rectStaysRect()) {
return this->drawEllipse(target, drawState, context, useCoverageAA, oval, stroke);
return this->drawEllipse(target, drawState, color, context, useCoverageAA, oval, stroke);
} else {
return false;
}
@ -523,6 +524,7 @@ bool GrOvalRenderer::drawOval(GrDrawTarget* target,
void GrOvalRenderer::drawCircle(GrDrawTarget* target,
GrDrawState* drawState,
GrColor color,
const GrContext* context,
bool useCoverageAA,
const SkRect& circle,
@ -560,7 +562,7 @@ void GrOvalRenderer::drawCircle(GrDrawTarget* target,
}
}
GrGeometryProcessor* gp = CircleEdgeEffect::Create(isStrokeOnly && innerRadius > 0);
GrGeometryProcessor* gp = CircleEdgeEffect::Create(color, isStrokeOnly && innerRadius > 0);
drawState->setGeometryProcessor(gp)->unref();
GrDrawTarget::AutoReleaseGeometry geo(target, 4, gp->getVertexStride(), 0);
@ -615,6 +617,7 @@ void GrOvalRenderer::drawCircle(GrDrawTarget* target,
bool GrOvalRenderer::drawEllipse(GrDrawTarget* target,
GrDrawState* drawState,
GrColor color,
const GrContext* context,
bool useCoverageAA,
const SkRect& ellipse,
@ -686,7 +689,8 @@ bool GrOvalRenderer::drawEllipse(GrDrawTarget* target,
return false;
}
GrGeometryProcessor* gp = EllipseEdgeEffect::Create(isStrokeOnly &&
GrGeometryProcessor* gp = EllipseEdgeEffect::Create(color,
isStrokeOnly &&
innerXRadius > 0 && innerYRadius > 0);
drawState->setGeometryProcessor(gp)->unref();
@ -748,6 +752,7 @@ bool GrOvalRenderer::drawEllipse(GrDrawTarget* target,
bool GrOvalRenderer::drawDIEllipse(GrDrawTarget* target,
GrDrawState* drawState,
GrColor color,
const GrContext* context,
bool useCoverageAA,
const SkRect& ellipse,
@ -804,7 +809,7 @@ bool GrOvalRenderer::drawDIEllipse(GrDrawTarget* target,
SkScalar innerRatioX = SkScalarDiv(xRadius, innerXRadius);
SkScalar innerRatioY = SkScalarDiv(yRadius, innerYRadius);
GrGeometryProcessor* gp = DIEllipseEdgeEffect::Create(mode);
GrGeometryProcessor* gp = DIEllipseEdgeEffect::Create(color, mode);
drawState->setGeometryProcessor(gp)->unref();
@ -905,13 +910,14 @@ GrIndexBuffer* GrOvalRenderer::rRectIndexBuffer(bool isStrokeOnly, GrGpu* gpu) {
bool GrOvalRenderer::drawDRRect(GrDrawTarget* target,
GrDrawState* drawState,
GrColor color,
GrContext* context,
bool useAA,
const SkRRect& origOuter,
const SkRRect& origInner) {
bool applyAA = useAA &&
!drawState->getRenderTarget()->isMultisampled() &&
drawState->couldApplyCoverage(*target->caps());
drawState->canUseFracCoveragePrimProc(color, *target->caps());
GrDrawState::AutoRestoreEffects are;
if (!origInner.isEmpty()) {
SkTCopyOnFirstWrite<SkRRect> inner(origInner);
@ -923,6 +929,7 @@ bool GrOvalRenderer::drawDRRect(GrDrawTarget* target,
GrPrimitiveEdgeType edgeType = applyAA ?
kInverseFillAA_GrProcessorEdgeType :
kInverseFillBW_GrProcessorEdgeType;
// TODO this needs to be a geometry processor
GrFragmentProcessor* fp = GrRRectEffect::Create(edgeType, *inner);
if (NULL == fp) {
return false;
@ -932,7 +939,7 @@ bool GrOvalRenderer::drawDRRect(GrDrawTarget* target,
}
SkStrokeRec fillRec(SkStrokeRec::kFill_InitStyle);
if (this->drawRRect(target, drawState, context, useAA, origOuter, fillRec)) {
if (this->drawRRect(target, drawState, color, context, useAA, origOuter, fillRec)) {
return true;
}
@ -961,23 +968,24 @@ bool GrOvalRenderer::drawDRRect(GrDrawTarget* target,
if (applyAA) {
bounds.outset(SK_ScalarHalf, SK_ScalarHalf);
}
target->drawRect(drawState, bounds, NULL, NULL);
target->drawRect(drawState, color, bounds, NULL, NULL);
return true;
}
bool GrOvalRenderer::drawRRect(GrDrawTarget* target,
GrDrawState* drawState,
GrColor color,
GrContext* context,
bool useAA,
const SkRRect& rrect,
const SkStrokeRec& stroke) {
if (rrect.isOval()) {
return this->drawOval(target, drawState, context, useAA, rrect.getBounds(), stroke);
return this->drawOval(target, drawState, color, context, useAA, rrect.getBounds(), stroke);
}
bool useCoverageAA = useAA &&
!drawState->getRenderTarget()->isMultisampled() &&
drawState->couldApplyCoverage(*target->caps());
drawState->canUseFracCoveragePrimProc(color, *target->caps());
// only anti-aliased rrects for now
if (!useCoverageAA) {
@ -1069,7 +1077,7 @@ bool GrOvalRenderer::drawRRect(GrDrawTarget* target,
isStrokeOnly = (isStrokeOnly && innerRadius >= 0);
GrGeometryProcessor* effect = CircleEdgeEffect::Create(isStrokeOnly);
GrGeometryProcessor* effect = CircleEdgeEffect::Create(color, isStrokeOnly);
drawState->setGeometryProcessor(effect)->unref();
GrDrawTarget::AutoReleaseGeometry geo(target, 16, effect->getVertexStride(), 0);
@ -1171,7 +1179,7 @@ bool GrOvalRenderer::drawRRect(GrDrawTarget* target,
isStrokeOnly = (isStrokeOnly && innerXRadius >= 0 && innerYRadius >= 0);
GrGeometryProcessor* effect = EllipseEdgeEffect::Create(isStrokeOnly);
GrGeometryProcessor* effect = EllipseEdgeEffect::Create(color, isStrokeOnly);
drawState->setGeometryProcessor(effect)->unref();
GrDrawTarget::AutoReleaseGeometry geo(target, 16, effect->getVertexStride(), 0);

View File

@ -33,18 +33,21 @@ public:
bool drawOval(GrDrawTarget*,
GrDrawState*,
GrColor,
const GrContext*,
bool useAA,
const SkRect& oval,
const SkStrokeRec& stroke);
bool drawRRect(GrDrawTarget*,
GrDrawState*,
GrColor,
GrContext*,
bool useAA,
const SkRRect& rrect,
const SkStrokeRec& stroke);
bool drawDRRect(GrDrawTarget* target,
GrDrawState*,
GrColor,
GrContext* context,
bool useAA,
const SkRRect& outer,
@ -53,18 +56,21 @@ public:
private:
bool drawEllipse(GrDrawTarget* target,
GrDrawState*,
GrColor,
const GrContext* context,
bool useCoverageAA,
const SkRect& ellipse,
const SkStrokeRec& stroke);
bool drawDIEllipse(GrDrawTarget* target,
GrDrawState*,
GrColor,
const GrContext* context,
bool useCoverageAA,
const SkRect& ellipse,
const SkStrokeRec& stroke);
void drawCircle(GrDrawTarget* target,
GrDrawState*,
GrColor,
const GrContext* context,
bool useCoverageAA,
const SkRect& circle,

View File

@ -117,6 +117,7 @@ public:
*/
bool drawPath(GrDrawTarget* target,
GrDrawState* ds,
GrColor color,
const SkPath& path,
const SkStrokeRec& stroke,
bool antiAlias) {
@ -125,7 +126,7 @@ public:
SkASSERT(ds->getStencil().isDisabled() ||
kNoRestriction_StencilSupport == this->getStencilSupport(target, ds, path,
stroke));
return this->onDrawPath(target, ds, path, stroke, antiAlias);
return this->onDrawPath(target, ds, color, path, stroke, antiAlias);
}
/**
@ -175,6 +176,7 @@ protected:
*/
virtual bool onDrawPath(GrDrawTarget*,
GrDrawState*,
GrColor,
const SkPath&,
const SkStrokeRec&,
bool antiAlias) = 0;
@ -196,7 +198,7 @@ protected:
0xffff);
drawState->setStencil(kIncrementStencil);
drawState->enableState(GrDrawState::kNoColorWrites_StateBit);
this->drawPath(target, drawState, path, stroke, false);
this->drawPath(target, drawState, GrColor_WHITE, path, stroke, false);
}
// Helper for getting the device bounds of a path. Inverse filled paths will have bounds set

View File

@ -9,6 +9,7 @@
#include "GrContext.h"
#include "GrCoordTransform.h"
#include "GrGeometryData.h"
#include "GrGeometryProcessor.h"
#include "GrInvariantOutput.h"
#include "GrMemoryPool.h"
#include "GrXferProcessor.h"
@ -170,6 +171,12 @@ bool GrFragmentProcessor::hasSameTransforms(const GrFragmentProcessor& that) con
///////////////////////////////////////////////////////////////////////////////////////////////////
void GrGeometryProcessor::computeInvariantColor(GrInvariantOutput* intout) const {
}
///////////////////////////////////////////////////////////////////////////////////////////////////
/*
* GrGeometryData shares the same pool so it lives in this file too
*/

View File

@ -348,6 +348,7 @@ GrTexture* GrSWMaskHelper::DrawPathMaskToTexture(GrContext* context,
void GrSWMaskHelper::DrawToTargetWithPathMask(GrTexture* texture,
GrDrawTarget* target,
GrDrawState* drawState,
GrColor color,
const SkIRect& rect) {
GrDrawState::AutoViewMatrixRestore avmr;
if (!avmr.setIdentity(drawState)) {
@ -375,5 +376,5 @@ void GrSWMaskHelper::DrawToTargetWithPathMask(GrTexture* texture,
GrTextureParams::kNone_FilterMode,
kPosition_GrCoordSet))->unref();
target->drawSimpleRect(drawState, dstRect);
target->drawSimpleRect(drawState, color, dstRect);
}

View File

@ -93,6 +93,7 @@ public:
static void DrawToTargetWithPathMask(GrTexture* texture,
GrDrawTarget* target,
GrDrawState* drawState,
GrColor,
const SkIRect& rect);
private:

View File

@ -78,6 +78,7 @@ bool get_path_and_clip_bounds(const GrDrawTarget* target,
////////////////////////////////////////////////////////////////////////////////
void draw_around_inv_path(GrDrawTarget* target,
GrDrawState* drawState,
GrColor color,
const SkIRect& devClipBounds,
const SkIRect& devPathBounds) {
GrDrawState::AutoViewMatrixRestore avmr;
@ -88,22 +89,22 @@ void draw_around_inv_path(GrDrawTarget* target,
if (devClipBounds.fTop < devPathBounds.fTop) {
rect.iset(devClipBounds.fLeft, devClipBounds.fTop,
devClipBounds.fRight, devPathBounds.fTop);
target->drawSimpleRect(drawState, rect);
target->drawSimpleRect(drawState, color, rect);
}
if (devClipBounds.fLeft < devPathBounds.fLeft) {
rect.iset(devClipBounds.fLeft, devPathBounds.fTop,
devPathBounds.fLeft, devPathBounds.fBottom);
target->drawSimpleRect(drawState, rect);
target->drawSimpleRect(drawState, color, rect);
}
if (devClipBounds.fRight > devPathBounds.fRight) {
rect.iset(devPathBounds.fRight, devPathBounds.fTop,
devClipBounds.fRight, devPathBounds.fBottom);
target->drawSimpleRect(drawState, rect);
target->drawSimpleRect(drawState, color, rect);
}
if (devClipBounds.fBottom > devPathBounds.fBottom) {
rect.iset(devClipBounds.fLeft, devPathBounds.fBottom,
devClipBounds.fRight, devClipBounds.fBottom);
target->drawSimpleRect(drawState, rect);
target->drawSimpleRect(drawState, color, rect);
}
}
@ -113,6 +114,7 @@ void draw_around_inv_path(GrDrawTarget* target,
// return true on success; false on failure
bool GrSoftwarePathRenderer::onDrawPath(GrDrawTarget* target,
GrDrawState* drawState,
GrColor color,
const SkPath& path,
const SkStrokeRec& stroke,
bool antiAlias) {
@ -127,7 +129,7 @@ bool GrSoftwarePathRenderer::onDrawPath(GrDrawTarget* target,
if (!get_path_and_clip_bounds(target, drawState, path, vm,
&devPathBounds, &devClipBounds)) {
if (path.isInverseFillType()) {
draw_around_inv_path(target, drawState, devClipBounds, devPathBounds);
draw_around_inv_path(target, drawState, color, devClipBounds, devPathBounds);
}
return true;
}
@ -141,10 +143,10 @@ bool GrSoftwarePathRenderer::onDrawPath(GrDrawTarget* target,
}
GrDrawState copy = *drawState;
GrSWMaskHelper::DrawToTargetWithPathMask(texture, target, &copy, devPathBounds);
GrSWMaskHelper::DrawToTargetWithPathMask(texture, target, &copy, color, devPathBounds);
if (path.isInverseFillType()) {
draw_around_inv_path(target, drawState, devClipBounds, devPathBounds);
draw_around_inv_path(target, drawState, color, devClipBounds, devPathBounds);
}
return true;

View File

@ -36,6 +36,7 @@ protected:
virtual bool onDrawPath(GrDrawTarget*,
GrDrawState*,
GrColor,
const SkPath&,
const SkStrokeRec&,
bool antiAlias) SK_OVERRIDE;

View File

@ -91,6 +91,7 @@ void GrStencilAndCoverPathRenderer::onStencilPath(GrDrawTarget* target,
bool GrStencilAndCoverPathRenderer::onDrawPath(GrDrawTarget* target,
GrDrawState* drawState,
GrColor color,
const SkPath& path,
const SkStrokeRec& stroke,
bool antiAlias) {
@ -133,7 +134,7 @@ bool GrStencilAndCoverPathRenderer::onDrawPath(GrDrawTarget* target,
} else {
avmr.setIdentity(drawState);
}
target->drawSimpleRect(drawState, bounds);
target->drawSimpleRect(drawState, color, bounds);
} else {
GR_STATIC_CONST_SAME_STENCIL(kStencilPass,
kZero_StencilOp,
@ -144,7 +145,7 @@ bool GrStencilAndCoverPathRenderer::onDrawPath(GrDrawTarget* target,
0xffff);
drawState->setStencil(kStencilPass);
target->drawPath(drawState, p, convert_skpath_filltype(path.getFillType()));
target->drawPath(drawState, color, p, convert_skpath_filltype(path.getFillType()));
}
drawState->stencil()->setDisabled();

View File

@ -39,6 +39,7 @@ protected:
virtual bool onDrawPath(GrDrawTarget*,
GrDrawState*,
GrColor,
const SkPath&,
const SkStrokeRec&,
bool antiAlias) SK_OVERRIDE;

View File

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

View File

@ -139,8 +139,8 @@ GrGLGeometryProcessor* GrConicEffect::createGLInstance(const GrBatchTracker& bt)
return SkNEW_ARGS(GrGLConicEffect, (*this, bt));
}
GrConicEffect::GrConicEffect(GrPrimitiveEdgeType edgeType)
: fEdgeType(edgeType) {
GrConicEffect::GrConicEffect(GrColor color, uint8_t coverage, GrPrimitiveEdgeType edgeType)
: INHERITED(color, coverage), fEdgeType(edgeType) {
this->initClassID<GrConicEffect>();
fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_GrVertexAttribType));
fInConicCoeffs = &this->addVertexAttrib(GrAttribute("inConicCoeffs",
@ -164,7 +164,7 @@ GrGeometryProcessor* GrConicEffect::TestCreate(SkRandom* random,
do {
GrPrimitiveEdgeType edgeType = static_cast<GrPrimitiveEdgeType>(
random->nextULessThan(kGrProcessorEdgeTypeCnt));
gp = GrConicEffect::Create(edgeType, caps);
gp = GrConicEffect::Create(GrRandomColor(random), edgeType, caps);
} while (NULL == gp);
return gp;
}
@ -286,8 +286,8 @@ GrGLGeometryProcessor* GrQuadEffect::createGLInstance(const GrBatchTracker& bt)
return SkNEW_ARGS(GrGLQuadEffect, (*this, bt));
}
GrQuadEffect::GrQuadEffect(GrPrimitiveEdgeType edgeType)
: fEdgeType(edgeType) {
GrQuadEffect::GrQuadEffect(GrColor color, uint8_t coverage, GrPrimitiveEdgeType edgeType)
: INHERITED(color, coverage), fEdgeType(edgeType) {
this->initClassID<GrQuadEffect>();
fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_GrVertexAttribType));
fInHairQuadEdge = &this->addVertexAttrib(GrAttribute("inHairQuadEdge",
@ -311,7 +311,7 @@ GrGeometryProcessor* GrQuadEffect::TestCreate(SkRandom* random,
do {
GrPrimitiveEdgeType edgeType = static_cast<GrPrimitiveEdgeType>(
random->nextULessThan(kGrProcessorEdgeTypeCnt));
gp = GrQuadEffect::Create(edgeType, caps);
gp = GrQuadEffect::Create(GrRandomColor(random), edgeType, caps);
} while (NULL == gp);
return gp;
}
@ -474,8 +474,8 @@ GrGLGeometryProcessor* GrCubicEffect::createGLInstance(const GrBatchTracker& bt)
return SkNEW_ARGS(GrGLCubicEffect, (*this, bt));
}
GrCubicEffect::GrCubicEffect(GrPrimitiveEdgeType edgeType)
: fEdgeType(edgeType) {
GrCubicEffect::GrCubicEffect(GrColor color, GrPrimitiveEdgeType edgeType)
: INHERITED(color), fEdgeType(edgeType) {
this->initClassID<GrCubicEffect>();
fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_GrVertexAttribType));
fInCubicCoeffs = &this->addVertexAttrib(GrAttribute("inCubicCoeffs",
@ -499,7 +499,7 @@ GrGeometryProcessor* GrCubicEffect::TestCreate(SkRandom* random,
do {
GrPrimitiveEdgeType edgeType = static_cast<GrPrimitiveEdgeType>(
random->nextULessThan(kGrProcessorEdgeTypeCnt));
gp = GrCubicEffect::Create(edgeType, caps);
gp = GrCubicEffect::Create(GrRandomColor(random), edgeType, caps);
} while (NULL == gp);
return gp;
}

View File

@ -58,21 +58,24 @@ class GrGLConicEffect;
class GrConicEffect : public GrGeometryProcessor {
public:
static GrGeometryProcessor* Create(const GrPrimitiveEdgeType edgeType,
const GrDrawTargetCaps& caps) {
static GrGeometryProcessor* Create(GrColor color,
const GrPrimitiveEdgeType edgeType,
const GrDrawTargetCaps& caps,
uint8_t coverage = 0xff) {
switch (edgeType) {
case kFillAA_GrProcessorEdgeType:
if (!caps.shaderDerivativeSupport()) {
return NULL;
}
return SkNEW_ARGS(GrConicEffect, (kFillAA_GrProcessorEdgeType));
return SkNEW_ARGS(GrConicEffect, (color, coverage, kFillAA_GrProcessorEdgeType));
case kHairlineAA_GrProcessorEdgeType:
if (!caps.shaderDerivativeSupport()) {
return NULL;
}
return SkNEW_ARGS(GrConicEffect, (kHairlineAA_GrProcessorEdgeType));
return SkNEW_ARGS(GrConicEffect, (color, coverage,
kHairlineAA_GrProcessorEdgeType));
case kFillBW_GrProcessorEdgeType:
return SkNEW_ARGS(GrConicEffect, (kFillBW_GrProcessorEdgeType));;
return SkNEW_ARGS(GrConicEffect, (color, coverage, kFillBW_GrProcessorEdgeType));;
default:
return NULL;
}
@ -95,7 +98,7 @@ public:
virtual GrGLGeometryProcessor* createGLInstance(const GrBatchTracker& bt) const SK_OVERRIDE;
private:
GrConicEffect(GrPrimitiveEdgeType);
GrConicEffect(GrColor, uint8_t coverage, GrPrimitiveEdgeType);
virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE;
@ -125,21 +128,23 @@ class GrGLQuadEffect;
class GrQuadEffect : public GrGeometryProcessor {
public:
static GrGeometryProcessor* Create(const GrPrimitiveEdgeType edgeType,
const GrDrawTargetCaps& caps) {
static GrGeometryProcessor* Create(GrColor color,
const GrPrimitiveEdgeType edgeType,
const GrDrawTargetCaps& caps,
uint8_t coverage = 0xff) {
switch (edgeType) {
case kFillAA_GrProcessorEdgeType:
if (!caps.shaderDerivativeSupport()) {
return NULL;
}
return SkNEW_ARGS(GrQuadEffect, (kFillAA_GrProcessorEdgeType));
return SkNEW_ARGS(GrQuadEffect, (color, coverage, kFillAA_GrProcessorEdgeType));
case kHairlineAA_GrProcessorEdgeType:
if (!caps.shaderDerivativeSupport()) {
return NULL;
}
return SkNEW_ARGS(GrQuadEffect, (kHairlineAA_GrProcessorEdgeType));
return SkNEW_ARGS(GrQuadEffect, (color, coverage, kHairlineAA_GrProcessorEdgeType));
case kFillBW_GrProcessorEdgeType:
return SkNEW_ARGS(GrQuadEffect, (kFillBW_GrProcessorEdgeType));
return SkNEW_ARGS(GrQuadEffect, (color, coverage, kFillBW_GrProcessorEdgeType));
default:
return NULL;
}
@ -162,7 +167,7 @@ public:
virtual GrGLGeometryProcessor* createGLInstance(const GrBatchTracker& bt) const SK_OVERRIDE;
private:
GrQuadEffect(GrPrimitiveEdgeType);
GrQuadEffect(GrColor, uint8_t coverage, GrPrimitiveEdgeType);
virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE;
@ -194,21 +199,22 @@ class GrGLCubicEffect;
class GrCubicEffect : public GrGeometryProcessor {
public:
static GrGeometryProcessor* Create(const GrPrimitiveEdgeType edgeType,
static GrGeometryProcessor* Create(GrColor color,
const GrPrimitiveEdgeType edgeType,
const GrDrawTargetCaps& caps) {
switch (edgeType) {
case kFillAA_GrProcessorEdgeType:
if (!caps.shaderDerivativeSupport()) {
return NULL;
}
return SkNEW_ARGS(GrCubicEffect, (kFillAA_GrProcessorEdgeType));
return SkNEW_ARGS(GrCubicEffect, (color, kFillAA_GrProcessorEdgeType));
case kHairlineAA_GrProcessorEdgeType:
if (!caps.shaderDerivativeSupport()) {
return NULL;
}
return SkNEW_ARGS(GrCubicEffect, (kHairlineAA_GrProcessorEdgeType));
return SkNEW_ARGS(GrCubicEffect, (color, kHairlineAA_GrProcessorEdgeType));
case kFillBW_GrProcessorEdgeType:
return SkNEW_ARGS(GrCubicEffect, (kFillBW_GrProcessorEdgeType));
return SkNEW_ARGS(GrCubicEffect, (color, kFillBW_GrProcessorEdgeType));
default:
return NULL;
}
@ -231,7 +237,7 @@ public:
virtual GrGLGeometryProcessor* createGLInstance(const GrBatchTracker& bt) const SK_OVERRIDE;
private:
GrCubicEffect(GrPrimitiveEdgeType);
GrCubicEffect(GrColor, GrPrimitiveEdgeType);
virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE;

View File

@ -65,9 +65,9 @@ private:
///////////////////////////////////////////////////////////////////////////////
GrBitmapTextGeoProc::GrBitmapTextGeoProc(GrTexture* texture, const GrTextureParams& params,
bool useColorAttrib)
: fTextureAccess(texture, params), fInColor(NULL) {
GrBitmapTextGeoProc::GrBitmapTextGeoProc(GrColor color, GrTexture* texture,
const GrTextureParams& params, bool useColorAttrib)
: INHERITED(color), fTextureAccess(texture, params), fInColor(NULL) {
this->initClassID<GrBitmapTextGeoProc>();
fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_GrVertexAttribType));
if (useColorAttrib) {
@ -128,5 +128,6 @@ GrGeometryProcessor* GrBitmapTextGeoProc::TestCreate(SkRandom* random,
GrTextureParams params(tileModes, random->nextBool() ? GrTextureParams::kBilerp_FilterMode :
GrTextureParams::kNone_FilterMode);
return GrBitmapTextGeoProc::Create(textures[texIdx], params, random->nextBool());
return GrBitmapTextGeoProc::Create(GrRandomColor(random), textures[texIdx], params,
random->nextBool());
}

View File

@ -21,9 +21,9 @@ class GrInvariantOutput;
*/
class GrBitmapTextGeoProc : public GrGeometryProcessor {
public:
static GrGeometryProcessor* Create(GrTexture* tex, const GrTextureParams& p,
static GrGeometryProcessor* Create(GrColor color, GrTexture* tex, const GrTextureParams& p,
bool useColorAttrib) {
return SkNEW_ARGS(GrBitmapTextGeoProc, (tex, p, useColorAttrib));
return SkNEW_ARGS(GrBitmapTextGeoProc, (color, tex, p, useColorAttrib));
}
virtual ~GrBitmapTextGeoProc() {}
@ -41,7 +41,7 @@ public:
virtual GrGLGeometryProcessor* createGLInstance(const GrBatchTracker& bt) const SK_OVERRIDE;
private:
GrBitmapTextGeoProc(GrTexture* texture, const GrTextureParams& params, bool useColorAttrib);
GrBitmapTextGeoProc(GrColor, GrTexture* texture, const GrTextureParams& params, bool useColorAttrib);
virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE;

View File

@ -165,7 +165,7 @@ static void setup_dashed_rect_pos(const SkRect& rect, int idx, const SkMatrix& m
}
bool GrDashingEffect::DrawDashLine(GrGpu* gpu, GrDrawTarget* target, GrDrawState* drawState,
const SkPoint pts[2], const GrPaint& paint,
GrColor color, const SkPoint pts[2], const GrPaint& paint,
const GrStrokeInfo& strokeInfo, const SkMatrix& vm) {
if (!can_fast_path_dash(pts, strokeInfo, *target, *drawState, vm)) {
@ -347,10 +347,10 @@ 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(edgeType, devInfo, strokeWidth, capType);
gp = GrDashingEffect::Create(color, edgeType, devInfo, strokeWidth, capType);
} else {
// Set up the vertex data for the line and start/end dashes
gp = GrDefaultGeoProcFactory::Create(GrDefaultGeoProcFactory::kPosition_GPType);
gp = GrDefaultGeoProcFactory::Create(color, GrDefaultGeoProcFactory::kPosition_GPType);
}
drawState->setGeometryProcessor(gp)->unref();
@ -456,7 +456,8 @@ class DashingCircleEffect : public GrGeometryProcessor {
public:
typedef SkPathEffect::DashInfo DashInfo;
static GrGeometryProcessor* Create(GrPrimitiveEdgeType edgeType,
static GrGeometryProcessor* Create(GrColor,
GrPrimitiveEdgeType edgeType,
const DashInfo& info,
SkScalar radius);
@ -483,7 +484,8 @@ public:
virtual GrGLGeometryProcessor* createGLInstance(const GrBatchTracker&) const SK_OVERRIDE;
private:
DashingCircleEffect(GrPrimitiveEdgeType edgeType, const DashInfo& info, SkScalar radius);
DashingCircleEffect(GrColor, GrPrimitiveEdgeType edgeType, const DashInfo& info,
SkScalar radius);
virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE;
@ -599,13 +601,15 @@ void GLDashingCircleEffect::GenKey(const GrGeometryProcessor& processor,
//////////////////////////////////////////////////////////////////////////////
GrGeometryProcessor* DashingCircleEffect::Create(GrPrimitiveEdgeType edgeType, const DashInfo& info,
GrGeometryProcessor* DashingCircleEffect::Create(GrColor color,
GrPrimitiveEdgeType edgeType,
const DashInfo& info,
SkScalar radius) {
if (info.fCount != 2 || info.fIntervals[0] != 0) {
return NULL;
}
return SkNEW_ARGS(DashingCircleEffect, (edgeType, info, radius));
return SkNEW_ARGS(DashingCircleEffect, (color, edgeType, info, radius));
}
DashingCircleEffect::~DashingCircleEffect() {}
@ -624,9 +628,11 @@ GrGLGeometryProcessor* DashingCircleEffect::createGLInstance(const GrBatchTracke
return SkNEW_ARGS(GLDashingCircleEffect, (*this, bt));
}
DashingCircleEffect::DashingCircleEffect(GrPrimitiveEdgeType edgeType, const DashInfo& info,
DashingCircleEffect::DashingCircleEffect(GrColor color,
GrPrimitiveEdgeType edgeType,
const DashInfo& info,
SkScalar radius)
: fEdgeType(edgeType) {
: INHERITED(color), fEdgeType(edgeType) {
this->initClassID<DashingCircleEffect>();
fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_GrVertexAttribType));
fInCoord = &this->addVertexAttrib(GrAttribute("inCoord", kVec2f_GrVertexAttribType));
@ -662,7 +668,7 @@ GrGeometryProcessor* DashingCircleEffect::TestCreate(SkRandom* random,
info.fIntervals[1] = random->nextRangeScalar(0, 10.f);
info.fPhase = random->nextRangeScalar(0, info.fIntervals[1]);
return DashingCircleEffect::Create(edgeType, info, strokeWidth);
return DashingCircleEffect::Create(GrRandomColor(random), edgeType, info, strokeWidth);
}
//////////////////////////////////////////////////////////////////////////////
@ -682,7 +688,8 @@ class DashingLineEffect : public GrGeometryProcessor {
public:
typedef SkPathEffect::DashInfo DashInfo;
static GrGeometryProcessor* Create(GrPrimitiveEdgeType edgeType,
static GrGeometryProcessor* Create(GrColor,
GrPrimitiveEdgeType edgeType,
const DashInfo& info,
SkScalar strokeWidth);
@ -707,7 +714,8 @@ public:
virtual GrGLGeometryProcessor* createGLInstance(const GrBatchTracker& bt) const SK_OVERRIDE;
private:
DashingLineEffect(GrPrimitiveEdgeType edgeType, const DashInfo& info, SkScalar strokeWidth);
DashingLineEffect(GrColor, GrPrimitiveEdgeType edgeType, const DashInfo& info,
SkScalar strokeWidth);
virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE;
@ -836,14 +844,15 @@ void GLDashingLineEffect::GenKey(const GrGeometryProcessor& processor,
//////////////////////////////////////////////////////////////////////////////
GrGeometryProcessor* DashingLineEffect::Create(GrPrimitiveEdgeType edgeType,
GrGeometryProcessor* DashingLineEffect::Create(GrColor color,
GrPrimitiveEdgeType edgeType,
const DashInfo& info,
SkScalar strokeWidth) {
if (info.fCount != 2) {
return NULL;
}
return SkNEW_ARGS(DashingLineEffect, (edgeType, info, strokeWidth));
return SkNEW_ARGS(DashingLineEffect, (color, edgeType, info, strokeWidth));
}
DashingLineEffect::~DashingLineEffect() {}
@ -862,9 +871,11 @@ GrGLGeometryProcessor* DashingLineEffect::createGLInstance(const GrBatchTracker&
return SkNEW_ARGS(GLDashingLineEffect, (*this, bt));
}
DashingLineEffect::DashingLineEffect(GrPrimitiveEdgeType edgeType, const DashInfo& info,
DashingLineEffect::DashingLineEffect(GrColor color,
GrPrimitiveEdgeType edgeType,
const DashInfo& info,
SkScalar strokeWidth)
: fEdgeType(edgeType) {
: INHERITED(color), fEdgeType(edgeType) {
this->initClassID<DashingLineEffect>();
fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_GrVertexAttribType));
fInCoord = &this->addVertexAttrib(GrAttribute("inCoord", kVec2f_GrVertexAttribType));
@ -900,20 +911,21 @@ GrGeometryProcessor* DashingLineEffect::TestCreate(SkRandom* random,
info.fIntervals[1] = random->nextRangeScalar(0, 10.f);
info.fPhase = random->nextRangeScalar(0, info.fIntervals[0] + info.fIntervals[1]);
return DashingLineEffect::Create(edgeType, info, strokeWidth);
return DashingLineEffect::Create(GrRandomColor(random), edgeType, info, strokeWidth);
}
//////////////////////////////////////////////////////////////////////////////
GrGeometryProcessor* GrDashingEffect::Create(GrPrimitiveEdgeType edgeType,
GrGeometryProcessor* GrDashingEffect::Create(GrColor color,
GrPrimitiveEdgeType edgeType,
const SkPathEffect::DashInfo& info,
SkScalar strokeWidth,
GrDashingEffect::DashCap cap) {
switch (cap) {
case GrDashingEffect::kRound_DashCap:
return DashingCircleEffect::Create(edgeType, info, SkScalarHalf(strokeWidth));
return DashingCircleEffect::Create(color, edgeType, info, SkScalarHalf(strokeWidth));
case GrDashingEffect::kNonRound_DashCap:
return DashingLineEffect::Create(edgeType, info, strokeWidth);
return DashingLineEffect::Create(color, edgeType, info, strokeWidth);
default:
SkFAIL("Unexpected dashed cap.");
}

View File

@ -9,6 +9,7 @@
#ifndef GrDashingEffect_DEFINED
#define GrDashingEffect_DEFINED
#include "GrColor.h"
#include "GrTypesPriv.h"
#include "SkPathEffect.h"
@ -23,7 +24,7 @@ class GrGLDashingEffect;
class SkPath;
namespace GrDashingEffect {
bool DrawDashLine(GrGpu*, GrDrawTarget*, GrDrawState*, const SkPoint pts[2],
bool DrawDashLine(GrGpu*, GrDrawTarget*, GrDrawState*, GrColor, const SkPoint pts[2],
const GrPaint& paint, const GrStrokeInfo& strokeInfo,
const SkMatrix& vm);
@ -38,7 +39,8 @@ namespace GrDashingEffect {
* Bounding geometry is rendered and the effect computes coverage based on the fragment's
* position relative to the dashed line.
*/
GrGeometryProcessor* Create(GrPrimitiveEdgeType edgeType,
GrGeometryProcessor* Create(GrColor,
GrPrimitiveEdgeType edgeType,
const SkPathEffect::DashInfo& info,
SkScalar strokeWidth,
DashCap cap);

View File

@ -165,7 +165,8 @@ private:
///////////////////////////////////////////////////////////////////////////////
GrDistanceFieldTextureEffect::GrDistanceFieldTextureEffect(GrTexture* texture,
GrDistanceFieldTextureEffect::GrDistanceFieldTextureEffect(GrColor color,
GrTexture* texture,
const GrTextureParams& params,
#ifdef SK_GAMMA_APPLY_TO_A8
GrTexture* gamma,
@ -173,7 +174,8 @@ GrDistanceFieldTextureEffect::GrDistanceFieldTextureEffect(GrTexture* texture,
float luminance,
#endif
uint32_t flags)
: fTextureAccess(texture, params)
: INHERITED(color)
, fTextureAccess(texture, params)
#ifdef SK_GAMMA_APPLY_TO_A8
, fGammaTextureAccess(gamma, gammaParams)
, fLuminance(luminance)
@ -249,7 +251,7 @@ GrGeometryProcessor* GrDistanceFieldTextureEffect::TestCreate(SkRandom* random,
GrTextureParams::kNone_FilterMode);
#endif
return GrDistanceFieldTextureEffect::Create(textures[texIdx], params,
return GrDistanceFieldTextureEffect::Create(GrRandomColor(random), textures[texIdx], params,
#ifdef SK_GAMMA_APPLY_TO_A8
textures[texIdx2], params2,
random->nextF(),
@ -378,10 +380,13 @@ private:
///////////////////////////////////////////////////////////////////////////////
GrDistanceFieldNoGammaTextureEffect::GrDistanceFieldNoGammaTextureEffect(GrTexture* texture,
const GrTextureParams& params,
uint32_t flags)
: fTextureAccess(texture, params)
GrDistanceFieldNoGammaTextureEffect::GrDistanceFieldNoGammaTextureEffect(
GrColor color,
GrTexture* texture,
const GrTextureParams& params,
uint32_t flags)
: INHERITED(color)
, fTextureAccess(texture, params)
, fFlags(flags & kNonLCD_DistanceFieldEffectMask)
, fInColor(NULL) {
SkASSERT(!(flags & ~kNonLCD_DistanceFieldEffectMask));
@ -439,7 +444,8 @@ GrGeometryProcessor* GrDistanceFieldNoGammaTextureEffect::TestCreate(SkRandom* r
GrTextureParams params(tileModes, random->nextBool() ? GrTextureParams::kBilerp_FilterMode
: GrTextureParams::kNone_FilterMode);
return GrDistanceFieldNoGammaTextureEffect::Create(textures[texIdx], params,
return GrDistanceFieldNoGammaTextureEffect::Create(GrRandomColor(random), textures[texIdx],
params,
random->nextBool() ? kSimilarity_DistanceFieldEffectFlag : 0);
}
@ -634,11 +640,13 @@ private:
///////////////////////////////////////////////////////////////////////////////
GrDistanceFieldLCDTextureEffect::GrDistanceFieldLCDTextureEffect(
GrColor color,
GrTexture* texture, const GrTextureParams& params,
GrTexture* gamma, const GrTextureParams& gParams,
SkColor textColor,
uint32_t flags)
: fTextureAccess(texture, params)
: INHERITED(color)
, fTextureAccess(texture, params)
, fGammaTextureAccess(gamma, gParams)
, fTextColor(textColor)
, fFlags(flags & kLCD_DistanceFieldEffectMask){
@ -705,7 +713,7 @@ GrGeometryProcessor* GrDistanceFieldLCDTextureEffect::TestCreate(SkRandom* rando
uint32_t flags = kUseLCD_DistanceFieldEffectFlag;
flags |= random->nextBool() ? kUniformScale_DistanceFieldEffectMask : 0;
flags |= random->nextBool() ? kBGR_DistanceFieldEffectFlag : 0;
return GrDistanceFieldLCDTextureEffect::Create(textures[texIdx], params,
return GrDistanceFieldLCDTextureEffect::Create(GrRandomColor(random), textures[texIdx], params,
textures[texIdx2], params2,
textColor,
flags);

View File

@ -47,16 +47,16 @@ enum GrDistanceFieldEffectFlags {
class GrDistanceFieldTextureEffect : public GrGeometryProcessor {
public:
#ifdef SK_GAMMA_APPLY_TO_A8
static GrGeometryProcessor* Create(GrTexture* tex, const GrTextureParams& params,
static GrGeometryProcessor* Create(GrColor color, GrTexture* tex, const GrTextureParams& params,
GrTexture* gamma, const GrTextureParams& gammaParams,
float lum, uint32_t flags) {
return SkNEW_ARGS(GrDistanceFieldTextureEffect, (tex, params, gamma, gammaParams, lum,
return SkNEW_ARGS(GrDistanceFieldTextureEffect, (color, tex, params, gamma, gammaParams, lum,
flags));
}
#else
static GrGeometryProcessor* Create(GrTexture* tex, const GrTextureParams& params,
static GrGeometryProcessor* Create(GrColor color, GrTexture* tex, const GrTextureParams& params,
uint32_t flags) {
return SkNEW_ARGS(GrDistanceFieldTextureEffect, (tex, params, flags));
return SkNEW_ARGS(GrDistanceFieldTextureEffect, (color, tex, params, flags));
}
#endif
@ -79,7 +79,7 @@ public:
virtual GrGLGeometryProcessor* createGLInstance(const GrBatchTracker& bt) const SK_OVERRIDE;
private:
GrDistanceFieldTextureEffect(GrTexture* texture, const GrTextureParams& params,
GrDistanceFieldTextureEffect(GrColor, GrTexture* texture, const GrTextureParams& params,
#ifdef SK_GAMMA_APPLY_TO_A8
GrTexture* gamma, const GrTextureParams& gammaParams, float lum,
#endif
@ -113,9 +113,9 @@ private:
*/
class GrDistanceFieldNoGammaTextureEffect : public GrGeometryProcessor {
public:
static GrGeometryProcessor* Create(GrTexture* tex, const GrTextureParams& params,
static GrGeometryProcessor* Create(GrColor color, GrTexture* tex, const GrTextureParams& params,
uint32_t flags) {
return SkNEW_ARGS(GrDistanceFieldNoGammaTextureEffect, (tex, params, flags));
return SkNEW_ARGS(GrDistanceFieldNoGammaTextureEffect, (color, tex, params, flags));
}
virtual ~GrDistanceFieldNoGammaTextureEffect() {}
@ -134,7 +134,7 @@ public:
virtual GrGLGeometryProcessor* createGLInstance(const GrBatchTracker& bt) const SK_OVERRIDE;
private:
GrDistanceFieldNoGammaTextureEffect(GrTexture* texture, const GrTextureParams& params,
GrDistanceFieldNoGammaTextureEffect(GrColor, GrTexture* texture, const GrTextureParams& params,
uint32_t flags);
virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE;
@ -160,11 +160,11 @@ private:
*/
class GrDistanceFieldLCDTextureEffect : public GrGeometryProcessor {
public:
static GrGeometryProcessor* Create(GrTexture* tex, const GrTextureParams& params,
static GrGeometryProcessor* Create(GrColor color, GrTexture* tex, const GrTextureParams& params,
GrTexture* gamma, const GrTextureParams& gammaParams,
SkColor textColor, uint32_t flags) {
return SkNEW_ARGS(GrDistanceFieldLCDTextureEffect,
(tex, params, gamma, gammaParams, textColor, flags));
(color, tex, params, gamma, gammaParams, textColor, flags));
}
virtual ~GrDistanceFieldLCDTextureEffect() {}
@ -183,7 +183,7 @@ public:
virtual GrGLGeometryProcessor* createGLInstance(const GrBatchTracker& bt) const SK_OVERRIDE;
private:
GrDistanceFieldLCDTextureEffect(GrTexture* texture, const GrTextureParams& params,
GrDistanceFieldLCDTextureEffect(GrColor, GrTexture* texture, const GrTextureParams& params,
GrTexture* gamma, const GrTextureParams& gammaParams,
SkColor textColor,
uint32_t flags);

View File

@ -181,68 +181,6 @@ static void set_random_color_coverage_stages(GrGpuGL* gpu,
}
}
// There are only a few cases of random colors which interest us
enum ColorMode {
kAllOnes_ColorMode,
kAllZeros_ColorMode,
kAlphaOne_ColorMode,
kRandom_ColorMode,
kLast_ColorMode = kRandom_ColorMode
};
static void set_random_color(GrDrawState* ds, SkRandom* random) {
ColorMode colorMode = ColorMode(random->nextULessThan(kLast_ColorMode + 1));
GrColor color;
switch (colorMode) {
case kAllOnes_ColorMode:
color = GrColorPackRGBA(0xFF, 0xFF, 0xFF, 0xFF);
break;
case kAllZeros_ColorMode:
color = GrColorPackRGBA(0, 0, 0, 0);
break;
case kAlphaOne_ColorMode:
color = GrColorPackRGBA(random->nextULessThan(256),
random->nextULessThan(256),
random->nextULessThan(256),
0xFF);
break;
case kRandom_ColorMode:
uint8_t alpha = random->nextULessThan(256);
color = GrColorPackRGBA(random->nextRangeU(0, alpha),
random->nextRangeU(0, alpha),
random->nextRangeU(0, alpha),
alpha);
break;
}
GrColorIsPMAssert(color);
ds->setColor(color);
}
// There are only a few cases of random coverages which interest us
enum CoverageMode {
kZero_CoverageMode,
kFF_CoverageMode,
kRandom_CoverageMode,
kLast_CoverageMode = kRandom_CoverageMode
};
static void set_random_coverage(GrDrawState* ds, SkRandom* random) {
CoverageMode coverageMode = CoverageMode(random->nextULessThan(kLast_CoverageMode + 1));
uint8_t coverage;
switch (coverageMode) {
case kZero_CoverageMode:
coverage = 0;
break;
case kFF_CoverageMode:
coverage = 0xFF;
break;
case kRandom_CoverageMode:
coverage = uint8_t(random->nextU());
break;
}
ds->setCoverage(coverage);
}
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());
@ -372,8 +310,6 @@ bool GrDrawTarget::programUnitTest(int maxStages) {
usePathRendering,
&random,
dummyTextures);
set_random_color(&ds, &random);
set_random_coverage(&ds, &random);
set_random_hints(&ds, &random);
set_random_state(&ds, &random);
set_random_blend_func(&ds, &random);
@ -381,14 +317,19 @@ bool GrDrawTarget::programUnitTest(int maxStages) {
GrDeviceCoordTexture dstCopy;
if (!this->setupDstReadIfNecessary(&ds, &dstCopy, NULL)) {
// 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)) {
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, *gpu->caps(), scissor, &dstCopy, drawType);
GrOptDrawState ods(ds, color, coverage, *gpu->caps(), scissor, &dstCopy, drawType);
if (ods.mustSkip()) {
continue;
}