Remove stage masks

Review URL: http://codereview.appspot.com/6422047/



git-svn-id: http://skia.googlecode.com/svn/trunk@4688 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
bsalomon@google.com 2012-07-20 13:37:06 +00:00
parent 426aebc850
commit e3d3216fe1
23 changed files with 210 additions and 280 deletions

View File

@ -809,15 +809,6 @@ private:
// only have to functions necessary for clients.
friend class GrAtlas;
// computes vertex layout bits based on the paint. If paint expresses
// a texture for a stage, the stage coords will be bound to postitions
// unless hasTexCoords[s]==true in which case stage s's input coords
// are bound to tex coord index s. hasTexCoords == NULL is a shortcut
// for an array where all the values are false.
static int PaintStageVertexLayoutBits(
const GrPaint& paint,
const bool hasTexCoords[GrPaint::kTotalStages]);
// Needed so GrTexture's returnToCache helper function can call
// addExistingTextureToCache
friend class GrTexture;

View File

@ -102,14 +102,55 @@ public:
(NULL != fMaskSamplers[i].getCustomStage());
}
// pre-concats sampler matrices for non-NULL textures and masks
void preConcatActiveSamplerMatrices(const GrMatrix& matrix) {
bool hasMask() const {
for (int i = 0; i < kMaxMasks; ++i) {
if (this->isMaskStageEnabled(i)) {
return true;
}
}
return false;
}
bool hasTexture() const {
for (int i = 0; i < kMaxTextures; ++i) {
fTextureSamplers[i].preConcatMatrix(matrix);
if (this->isTextureStageEnabled(i)) {
return true;
}
}
return false;
}
bool hasTextureOrMask() const { return this->hasTexture() || this->hasMask(); }
/**
* Preconcats the matrix of all samplers in the mask with the inverse of a
* matrix. If the matrix inverse cannot be computed (and there is at least
* one enabled stage) then false is returned.
*/
bool preConcatSamplerMatricesWithInverse(const GrMatrix& matrix) {
GrMatrix inv;
bool computed = false;
for (int i = 0; i < kMaxTextures; ++i) {
if (this->isTextureStageEnabled(i)) {
if (!computed && !matrix.invert(&inv)) {
return false;
} else {
computed = true;
}
fTextureSamplers[i].preConcatMatrix(inv);
}
}
for (int i = 0; i < kMaxMasks; ++i) {
fMaskSamplers[i].preConcatMatrix(matrix);
if (this->isMaskStageEnabled(i)) {
if (!computed && !matrix.invert(&inv)) {
return false;
} else {
computed = true;
}
fMaskSamplers[i].preConcatMatrix(inv);
}
}
return true;
}
// uninitialized
@ -189,46 +230,6 @@ public:
fColorMatrixEnabled = false;
}
bool hasTexture() const {
return 0 != this->getActiveTextureStageMask();
}
bool hasMask() const {
return 0 != this->getActiveMaskStageMask();
}
bool hasTextureOrMask() const {
return this->hasTexture() || this->hasMask();
}
// helpers for GrContext, GrTextContext
int getActiveTextureStageMask() const {
int mask = 0;
for (int i = 0; i < kMaxTextures; ++i) {
if ((NULL != fTextures[i]) ||
(NULL != fTextureSamplers[i].getCustomStage())) {
mask |= 1 << (i + kFirstTextureStage);
}
}
return mask;
}
int getActiveMaskStageMask() const {
int mask = 0;
for (int i = 0; i < kMaxMasks; ++i) {
if ((NULL != fMaskTextures[i]) ||
(NULL != fMaskSamplers[i].getCustomStage())) {
mask |= 1 << (i + kFirstMaskStage);
}
}
return mask;
}
int getActiveStageMask() const {
return this->getActiveTextureStageMask() |
this->getActiveMaskStageMask();
}
// internal use
// GrPaint's textures and masks map to the first N stages
// of GrDrawTarget in that order (textures followed by masks)

View File

@ -447,7 +447,6 @@ bool GrAAConvexPathRenderer::onDrawPath(const SkPath& origPath,
GrPathFill fill,
const GrVec* translate,
GrDrawTarget* target,
GrDrawState::StageMask stageMask,
bool antiAlias) {
const SkPath* path = &origPath;
@ -462,9 +461,8 @@ bool GrAAConvexPathRenderer::onDrawPath(const SkPath& origPath,
if (NULL != translate) {
vm.postTranslate(translate->fX, translate->fY);
}
GrMatrix ivm;
if (vm.invert(&ivm)) {
drawState->preConcatSamplerMatrices(stageMask, ivm);
if (!drawState->preConcatSamplerMatricesWithInverse(vm)) {
return false;
}
drawState->viewMatrix()->reset();

View File

@ -23,6 +23,5 @@ protected:
GrPathFill fill,
const GrVec* translate,
GrDrawTarget* target,
GrDrawState::StageMask stageMask,
bool antiAlias) SK_OVERRIDE;
};

View File

@ -505,7 +505,6 @@ bool GrAAHairLinePathRenderer::createGeom(
const SkPath& path,
const GrVec* translate,
GrDrawTarget* target,
GrDrawState::StageMask stageMask,
int* lineCnt,
int* quadCnt,
GrDrawTarget::AutoReleaseGeometry* arg) {
@ -585,7 +584,6 @@ bool GrAAHairLinePathRenderer::onDrawPath(const SkPath& path,
GrPathFill fill,
const GrVec* translate,
GrDrawTarget* target,
GrDrawState::StageMask stageMask,
bool antiAlias) {
int lineCnt;
@ -594,7 +592,6 @@ bool GrAAHairLinePathRenderer::onDrawPath(const SkPath& path,
if (!this->createGeom(path,
translate,
target,
stageMask,
&lineCnt,
&quadCnt,
&arg)) {
@ -609,9 +606,8 @@ bool GrAAHairLinePathRenderer::onDrawPath(const SkPath& path,
asr.set(target,
GrDrawTarget::kPreserve_ASRInit);
drawState = target->drawState();
GrMatrix ivm;
if (drawState->getViewInverse(&ivm)) {
drawState->preConcatSamplerMatrices(stageMask, ivm);
if (!drawState->preConcatSamplerMatricesWithInverse(drawState->getViewMatrix())) {
return false;
}
drawState->viewMatrix()->reset();
}

View File

@ -27,7 +27,6 @@ protected:
GrPathFill fill,
const GrVec* translate,
GrDrawTarget* target,
GrDrawState::StageMask stageMask,
bool antiAlias) SK_OVERRIDE;
private:
@ -39,7 +38,6 @@ private:
bool createGeom(const SkPath& path,
const GrVec* translate,
GrDrawTarget* target,
GrDrawState::StageMask stageMask,
int* lineCnt,
int* quadCnt,
GrDrawTarget::AutoReleaseGeometry* arg);

View File

@ -367,7 +367,7 @@ bool draw_path_in_software(GrContext* context,
// The ClipMaskManager accumulates the clip mask in the UL corner
GrIRect rect = GrIRect::MakeWH(resultBounds.width(), resultBounds.height());
GrSWMaskHelper::DrawToTargetWithPathMask(texture, gpu, 0, rect);
GrSWMaskHelper::DrawToTargetWithPathMask(texture, gpu, rect);
GrAssert(!GrIsFillInverted(fill));
return true;
@ -387,7 +387,7 @@ bool draw_path(GrContext* context,
return draw_path_in_software(context, gpu, path, fill, doAA, resultBounds);
}
pr->drawPath(path, fill, NULL, gpu, 0, doAA);
pr->drawPath(path, fill, NULL, gpu, doAA);
return true;
}
@ -409,7 +409,7 @@ bool GrClipMaskManager::drawClipShape(GrTexture* target,
clipIn.getRect(index),
true);
} else {
fGpu->drawSimpleRect(clipIn.getRect(index), NULL, 0);
fGpu->drawSimpleRect(clipIn.getRect(index), NULL);
}
} else {
return draw_path(this->getContext(), fGpu,
@ -440,7 +440,7 @@ void GrClipMaskManager::drawTexture(GrTexture* target,
GrRect rect = GrRect::MakeWH(SkIntToScalar(target->width()),
SkIntToScalar(target->height()));
fGpu->drawSimpleRect(rect, NULL, 1 << 0);
fGpu->drawSimpleRect(rect, NULL);
drawState->disableStage(0);
}
@ -789,11 +789,11 @@ bool GrClipMaskManager::createStencilClipMask(const GrClip& clipIn,
SET_RANDOM_COLOR
if (kRect_ClipType == clipCopy.getElementType(c)) {
*drawState->stencil() = gDrawToStencil;
fGpu->drawSimpleRect(clipCopy.getRect(c), NULL, 0);
fGpu->drawSimpleRect(clipCopy.getRect(c), NULL);
} else {
if (canRenderDirectToStencil) {
*drawState->stencil() = gDrawToStencil;
pr->drawPath(*clipPath, fill, NULL, fGpu, 0, false);
pr->drawPath(*clipPath, fill, NULL, fGpu, false);
} else {
pr->drawPathToStencil(*clipPath, fill, fGpu);
}
@ -808,10 +808,10 @@ bool GrClipMaskManager::createStencilClipMask(const GrClip& clipIn,
if (canDrawDirectToClip) {
if (kRect_ClipType == clipCopy.getElementType(c)) {
SET_RANDOM_COLOR
fGpu->drawSimpleRect(clipCopy.getRect(c), NULL, 0);
fGpu->drawSimpleRect(clipCopy.getRect(c), NULL);
} else {
SET_RANDOM_COLOR
pr->drawPath(*clipPath, fill, NULL, fGpu, 0, false);
pr->drawPath(*clipPath, fill, NULL, fGpu, false);
}
} else {
SET_RANDOM_COLOR
@ -820,7 +820,7 @@ bool GrClipMaskManager::createStencilClipMask(const GrClip& clipIn,
SkIntToScalar(bounds.fTop),
SkIntToScalar(bounds.fRight),
SkIntToScalar(bounds.fBottom));
fGpu->drawSimpleRect(rect, NULL, 0);
fGpu->drawSimpleRect(rect, NULL);
}
}
}

View File

@ -166,24 +166,6 @@ size_t GrContext::getGpuTextureCacheBytes() const {
return fTextureCache->getCachedResourceBytes();
}
////////////////////////////////////////////////////////////////////////////////
int GrContext::PaintStageVertexLayoutBits(
const GrPaint& paint,
const bool hasTexCoords[GrPaint::kTotalStages]) {
int stageMask = paint.getActiveStageMask();
int layout = 0;
for (int i = 0; i < GrPaint::kTotalStages; ++i) {
if ((1 << i) & stageMask) {
if (NULL != hasTexCoords && hasTexCoords[i]) {
layout |= GrDrawTarget::StageTexCoordVertexLayoutBit(i, i);
}
}
}
return layout;
}
////////////////////////////////////////////////////////////////////////////////
GrTexture* GrContext::TextureCacheEntry::texture() const {
@ -247,7 +229,7 @@ void apply_morphology(GrGpu* gpu,
SkAutoTUnref<GrCustomStage> morph(
SkNEW_ARGS(GrMorphologyEffect, (texture, direction, radius, morphType)));
drawState->sampler(0)->setCustomStage(morph);
gpu->drawSimpleRect(rect, NULL, 1 << 0);
gpu->drawSimpleRect(rect, NULL);
}
void convolve_gaussian(GrGpu* gpu,
@ -267,7 +249,7 @@ void convolve_gaussian(GrGpu* gpu,
(texture, direction, radius,
sigma)));
drawState->sampler(0)->setCustomStage(conv);
gpu->drawSimpleRect(rect, NULL, 1 << 0);
gpu->drawSimpleRect(rect, NULL);
}
}
@ -644,19 +626,17 @@ void GrContext::drawPaint(const GrPaint& paint) {
// produce a correct result for some perspective matrices.
if (!this->getMatrix().hasPerspective()) {
if (!fDrawState->getViewInverse(&inverse)) {
GrPrintf("Could not invert matrix");
GrPrintf("Could not invert matrix\n");
return;
}
inverse.mapRect(&r);
} else {
if (paint.getActiveMaskStageMask() || paint.getActiveStageMask()) {
if (!fDrawState->getViewInverse(&inverse)) {
GrPrintf("Could not invert matrix");
return;
}
if (paint.hasTextureOrMask()) {
tmpPaint.set(paint);
tmpPaint.get()->preConcatActiveSamplerMatrices(inverse);
p = tmpPaint.get();
if (!tmpPaint.get()->preConcatSamplerMatricesWithInverse(fDrawState->getViewMatrix())) {
GrPrintf("Could not invert matrix\n");
}
}
am.set(this, GrMatrix::I());
}
@ -780,7 +760,6 @@ void GrContext::drawRect(const GrPaint& paint,
GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory);
GrDrawState::AutoStageDisable atr(fDrawState);
int stageMask = paint.getActiveStageMask();
GrRect devRect = rect;
GrMatrix combinedMatrix;
@ -792,7 +771,10 @@ void GrContext::drawRect(const GrPaint& paint,
&useVertexCoverage);
if (doAA) {
GrDrawTarget::AutoDeviceCoordDraw adcd(target, stageMask);
GrDrawTarget::AutoDeviceCoordDraw adcd(target);
if (!adcd.succeeded()) {
return;
}
if (width >= 0) {
GrVec strokeSize;;
if (width > 0) {
@ -815,10 +797,9 @@ void GrContext::drawRect(const GrPaint& paint,
// TODO: consider making static vertex buffers for these cases.
// Hairline could be done by just adding closing vertex to
// unitSquareVertexBuffer()
GrVertexLayout layout = PaintStageVertexLayoutBits(paint, NULL);
static const int worstCaseVertCount = 10;
GrDrawTarget::AutoReleaseGeometry geo(target, layout, worstCaseVertCount, 0);
GrDrawTarget::AutoReleaseGeometry geo(target, 0, worstCaseVertCount, 0);
if (!geo.succeeded()) {
GrPrintf("Failed to get space for vertices!\n");
@ -849,19 +830,18 @@ void GrContext::drawRect(const GrPaint& paint,
GrDrawState* drawState = target->drawState();
avmr.set(drawState);
drawState->preConcatViewMatrix(*matrix);
drawState->preConcatSamplerMatrices(stageMask, *matrix);
drawState->preConcatSamplerMatrices(*matrix);
}
target->drawNonIndexed(primType, 0, vertCount);
} else {
#if GR_STATIC_RECT_VB
GrVertexLayout layout = PaintStageVertexLayoutBits(paint, NULL);
const GrVertexBuffer* sqVB = fGpu->getUnitSquareVertexBuffer();
if (NULL == sqVB) {
GrPrintf("Failed to create static rect vb.\n");
return;
}
target->setVertexSourceToBuffer(layout, sqVB);
target->setVertexSourceToBuffer(0, sqVB);
GrDrawState* drawState = target->drawState();
GrDrawState::AutoViewMatrixRestore avmr(drawState);
GrMatrix m;
@ -873,11 +853,11 @@ void GrContext::drawRect(const GrPaint& paint,
m.postConcat(*matrix);
}
drawState->preConcatViewMatrix(m);
drawState->preConcatSamplerMatrices(stageMask, m);
drawState->preConcatSamplerMatrices(m);
target->drawNonIndexed(kTriangleFan_GrPrimitiveType, 0, 4);
#else
target->drawSimpleRect(rect, matrix, stageMask);
target->drawSimpleRect(rect, matrix);
#endif
}
}
@ -901,7 +881,6 @@ void GrContext::drawRectToRect(const GrPaint& paint,
GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory);
GrDrawState::AutoStageDisable atr(fDrawState);
GrDrawState* drawState = target->drawState();
GrVertexLayout layout = PaintStageVertexLayoutBits(paint, NULL);
GrDrawState::AutoViewMatrixRestore avmr(drawState);
GrMatrix m;
@ -914,11 +893,12 @@ void GrContext::drawRectToRect(const GrPaint& paint,
}
drawState->preConcatViewMatrix(m);
// srcRect refers to first stage
int otherStageMask = paint.getActiveStageMask() &
(~(1 << GrPaint::kFirstTextureStage));
if (otherStageMask) {
drawState->preConcatSamplerMatrices(otherStageMask, m);
// we explicitly setup the correct coords for the first stage. The others
// must know about the view matrix change.
for (int s = 1; s < GrPaint::kTotalStages; ++s) {
if (drawState->isStageEnabled(s)) {
drawState->sampler(s)->preConcatMatrix(m);
}
}
m.setAll(srcRect.width(), 0, srcRect.fLeft,
@ -934,7 +914,7 @@ void GrContext::drawRectToRect(const GrPaint& paint,
GrPrintf("Failed to create static rect vb.\n");
return;
}
target->setVertexSourceToBuffer(layout, sqVB);
target->setVertexSourceToBuffer(0, sqVB);
target->drawNonIndexed(kTriangleFan_GrPrimitiveType, 0, 4);
#else
@ -951,7 +931,7 @@ void GrContext::drawRectToRect(const GrPaint& paint,
srcRects[0] = &srcRect;
srcMatrices[0] = srcMatrix;
target->drawRect(dstRect, dstMatrix, 1, srcRects, srcMatrices);
target->drawRect(dstRect, dstMatrix, srcRects, srcMatrices);
#endif
}
@ -970,13 +950,10 @@ void GrContext::drawVertices(const GrPaint& paint,
GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory);
GrDrawState::AutoStageDisable atr(fDrawState);
bool hasTexCoords[GrPaint::kTotalStages] = {
NULL != texCoords, // texCoordSrc provides explicit stage 0 coords
0 // remaining stages use positions
};
GrVertexLayout layout = PaintStageVertexLayoutBits(paint, hasTexCoords);
GrVertexLayout layout = 0;
if (NULL != texCoords) {
layout |= GrDrawTarget::StageTexCoordVertexLayoutBit(0, 0);
}
if (NULL != colors) {
layout |= GrDrawTarget::kColor_VertexLayoutBit;
}
@ -1093,10 +1070,12 @@ void GrContext::drawOval(const GrPaint& paint,
return;
}
GrDrawTarget::AutoDeviceCoordDraw adcd(target, paint.getActiveStageMask());
GrDrawTarget::AutoDeviceCoordDraw adcd(target);
if (!adcd.succeeded()) {
return;
}
GrVertexLayout layout = PaintStageVertexLayoutBits(paint, NULL);
layout |= GrDrawTarget::kEdge_VertexLayoutBit;
GrVertexLayout layout = GrDrawTarget::kEdge_VertexLayoutBit;
GrAssert(sizeof(CircleVertex) == GrDrawTarget::VertexSize(layout));
GrPoint center = GrPoint::Make(rect.centerX(), rect.centerY());
@ -1183,7 +1162,6 @@ void GrContext::internalDrawPath(const GrPaint& paint, const SkPath& path,
kUnbuffered_DrawCategory;
GrDrawTarget* target = this->prepareToDraw(paint, category);
GrDrawState::AutoStageDisable atr(fDrawState);
GrDrawState::StageMask stageMask = paint.getActiveStageMask();
bool prAA = paint.fAntiAlias && !this->getRenderTarget()->isMultisampled();
@ -1206,7 +1184,7 @@ void GrContext::internalDrawPath(const GrPaint& paint, const SkPath& path,
return;
}
pr->drawPath(path, fill, translate, target, stageMask, prAA);
pr->drawPath(path, fill, translate, target, prAA);
}
////////////////////////////////////////////////////////////////////////////////
@ -1430,7 +1408,7 @@ bool GrContext::internalReadRenderTargetPixels(GrRenderTarget* target,
drawState->sampler(0)->setCustomStage(SkNEW_ARGS(GrSingleTextureEffect, (src)))->unref();
GrRect rect;
rect.setXYWH(0, 0, SK_Scalar1 * width, SK_Scalar1 * height);
fGpu->drawSimpleRect(rect, NULL, 0x1);
fGpu->drawSimpleRect(rect, NULL);
left = 0;
top = 0;
}
@ -1471,7 +1449,7 @@ void GrContext::copyTexture(GrTexture* src, GrRenderTarget* dst) {
SkRect rect = SkRect::MakeXYWH(0, 0,
SK_Scalar1 * src->width(),
SK_Scalar1 * src->height());
fGpu->drawSimpleRect(rect, NULL, 1 << 0);
fGpu->drawSimpleRect(rect, NULL);
}
void GrContext::internalWriteRenderTargetPixels(GrRenderTarget* target,
@ -1632,7 +1610,7 @@ void GrContext::setPaint(const GrPaint& paint) {
fDrawState->setColorFilter(paint.fColorFilterColor, paint.fColorFilterXfermode);
fDrawState->setCoverage(paint.fCoverage);
#if GR_DEBUG_PARTIAL_COVERAGE_CHECK
if ((paint.getActiveMaskStageMask() || 0xff != paint.fCoverage) &&
if ((paint.hasMask() || 0xff != paint.fCoverage) &&
!fGpu->canApplyCoverage()) {
GrPrintf("Partial pixel coverage will be incorrectly blended.\n");
}

View File

@ -186,7 +186,6 @@ bool GrDefaultPathRenderer::createGeom(const SkPath& path,
const GrVec* translate,
GrScalar srcSpaceTol,
GrDrawTarget* target,
GrDrawState::StageMask stageMask,
GrPrimitiveType* primType,
int* vertexCnt,
int* indexCnt,
@ -328,7 +327,6 @@ bool GrDefaultPathRenderer::internalDrawPath(const SkPath& path,
GrPathFill fill,
const GrVec* translate,
GrDrawTarget* target,
GrDrawState::StageMask stageMask,
bool stencilOnly) {
GrMatrix viewM = target->getDrawState().getViewMatrix();
@ -344,7 +342,6 @@ bool GrDefaultPathRenderer::internalDrawPath(const SkPath& path,
translate,
tol,
target,
stageMask,
&primType,
&vertexCnt,
&indexCnt,
@ -475,12 +472,10 @@ bool GrDefaultPathRenderer::internalDrawPath(const SkPath& path,
drawState->getViewInverse(&vmi)) {
vmi.mapRect(&bounds);
} else {
if (stageMask) {
if (!drawState->getViewInverse(&vmi)) {
GrPrintf("Could not invert matrix.");
return false;
}
drawState->preConcatSamplerMatrices(stageMask, vmi);
const GrMatrix& vm = drawState->getViewMatrix();
if (!drawState->preConcatSamplerMatricesWithInverse(vm)) {
GrPrintf("Could not invert matrix.\n");
return false;
}
drawState->viewMatrix()->reset();
}
@ -491,7 +486,7 @@ bool GrDefaultPathRenderer::internalDrawPath(const SkPath& path,
}
}
GrDrawTarget::AutoGeometryPush agp(target);
target->drawSimpleRect(bounds, NULL, stageMask);
target->drawSimpleRect(bounds, NULL);
} else {
if (passCount > 1) {
drawState->enableState(GrDrawState::kNoColorWrites_StateBit);
@ -521,13 +516,11 @@ bool GrDefaultPathRenderer::onDrawPath(const SkPath& path,
GrPathFill fill,
const GrVec* translate,
GrDrawTarget* target,
GrDrawState::StageMask stageMask,
bool antiAlias) {
return this->internalDrawPath(path,
fill,
translate,
target,
stageMask,
false);
}
@ -536,5 +529,5 @@ void GrDefaultPathRenderer::drawPathToStencil(const SkPath& path,
GrDrawTarget* target) {
GrAssert(kInverseEvenOdd_GrPathFill != fill);
GrAssert(kInverseWinding_GrPathFill != fill);
this->internalDrawPath(path, fill, NULL, target, 0, true);
this->internalDrawPath(path, fill, NULL, target, true);
}

View File

@ -40,14 +40,12 @@ private:
GrPathFill fill,
const GrVec* translate,
GrDrawTarget* target,
GrDrawState::StageMask stageMask,
bool antiAlias) SK_OVERRIDE;
bool internalDrawPath(const SkPath& path,
GrPathFill fill,
const GrVec* translate,
GrDrawTarget* target,
GrDrawState::StageMask stageMask,
bool stencilOnly);
bool createGeom(const SkPath& path,
@ -55,7 +53,6 @@ private:
const GrVec* translate,
GrScalar srcSpaceTol,
GrDrawTarget* target,
GrDrawState::StageMask stages,
GrPrimitiveType* primType,
int* vertexCnt,
int* indexCnt,

View File

@ -48,12 +48,6 @@ public:
kMaxTexCoords = kNumStages
};
/**
* Bitfield used to indicate a set of stages.
*/
typedef uint32_t StageMask;
GR_STATIC_ASSERT(sizeof(StageMask)*8 >= GrDrawState::kNumStages);
GrDrawState()
: fRenderTarget(NULL) {
@ -288,17 +282,37 @@ public:
}
/**
* Preconcats the matrix of all samplers in the mask with the same matrix.
* Preconcats the matrix of all samplers of enabled stages with a matrix.
*/
void preConcatSamplerMatrices(StageMask stageMask, const GrMatrix& matrix) {
GrAssert(!(stageMask & kIllegalStageMaskBits));
void preConcatSamplerMatrices(const GrMatrix& matrix) {
for (int i = 0; i < kNumStages; ++i) {
if ((1 << i) & stageMask) {
if (this->isStageEnabled(i)) {
fSamplerStates[i].preConcatMatrix(matrix);
}
}
}
/**
* Preconcats the matrix of all samplers in the mask with the inverse of a
* matrix. If the matrix inverse cannot be computed (and there is at least
* one enabled stage) then false is returned.
*/
bool preConcatSamplerMatricesWithInverse(const GrMatrix& matrix) {
GrMatrix inv;
bool computed = false;
for (int i = 0; i < kNumStages; ++i) {
if (this->isStageEnabled(i)) {
if (!computed && !matrix.invert(&inv)) {
return false;
} else {
computed = true;
}
fSamplerStates[i].preConcatMatrix(inv);
}
}
return true;
}
/// @}
///////////////////////////////////////////////////////////////////////////
@ -860,7 +874,6 @@ private:
sizeof(fPodEndMarker);
}
static const StageMask kIllegalStageMaskBits = ~((1U << kNumStages)-1);
// @{ these fields can be initialized with memset to 0
union {
GrColor fBlendConstant;

View File

@ -1040,10 +1040,9 @@ void GrDrawTarget::drawIndexedInstances(GrPrimitiveType type,
void GrDrawTarget::drawRect(const GrRect& rect,
const GrMatrix* matrix,
StageMask stageMask,
const GrRect* srcRects[],
const GrMatrix* srcMatrices[]) {
GrVertexLayout layout = GetRectVertexLayout(stageMask, srcRects);
GrVertexLayout layout = GetRectVertexLayout(srcRects);
AutoReleaseGeometry geo(this, layout, 4, 0);
if (!geo.succeeded()) {
@ -1057,17 +1056,17 @@ void GrDrawTarget::drawRect(const GrRect& rect,
drawNonIndexed(kTriangleFan_GrPrimitiveType, 0, 4);
}
GrVertexLayout GrDrawTarget::GetRectVertexLayout(StageMask stageMask,
const GrRect* srcRects[]) {
GrVertexLayout layout = 0;
GrVertexLayout GrDrawTarget::GetRectVertexLayout(const GrRect* srcRects[]) {
if (NULL == srcRects) {
return 0;
}
GrVertexLayout layout = 0;
for (int i = 0; i < GrDrawState::kNumStages; ++i) {
int numTC = 0;
if (stageMask & (1 << i)) {
if (NULL != srcRects && NULL != srcRects[i]) {
layout |= StageTexCoordVertexLayoutBit(i, numTC);
++numTC;
}
if (NULL != srcRects[i]) {
layout |= StageTexCoordVertexLayoutBit(i, numTC);
++numTC;
}
}
return layout;
@ -1153,27 +1152,30 @@ void GrDrawTarget::AutoStateRestore::set(GrDrawTarget* target, ASRInit init) {
////////////////////////////////////////////////////////////////////////////////
GrDrawTarget::AutoDeviceCoordDraw::AutoDeviceCoordDraw(
GrDrawTarget* target,
GrDrawState::StageMask stageMask) {
GrDrawTarget::AutoDeviceCoordDraw::AutoDeviceCoordDraw(GrDrawTarget* target,
uint32_t explicitCoordStageMask) {
GrAssert(NULL != target);
GrDrawState* drawState = target->drawState();
fDrawTarget = target;
fViewMatrix = drawState->getViewMatrix();
fStageMask = stageMask;
if (fStageMask) {
GrMatrix invVM;
if (fViewMatrix.invert(&invVM)) {
for (int s = 0; s < GrDrawState::kNumStages; ++s) {
if (fStageMask & (1 << s)) {
fSamplerMatrices[s] = drawState->getSampler(s).getMatrix();
}
fRestoreMask = 0;
GrMatrix invVM;
bool inverted = false;
for (int s = 0; s < GrDrawState::kNumStages; ++s) {
if (!(explicitCoordStageMask & (1 << s)) && drawState->isStageEnabled(s)) {
if (!inverted && !fViewMatrix.invert(&invVM)) {
// sad trombone sound
fDrawTarget = NULL;
return;
} else {
inverted = true;
}
drawState->preConcatSamplerMatrices(fStageMask, invVM);
} else {
// sad trombone sound
fStageMask = 0;
fRestoreMask |= (1 << s);
GrSamplerState* sampler = drawState->sampler(s);
fSamplerMatrices[s] = sampler->getMatrix();
sampler->preConcatMatrix(invVM);
}
}
drawState->viewMatrix()->reset();
@ -1183,7 +1185,7 @@ GrDrawTarget::AutoDeviceCoordDraw::~AutoDeviceCoordDraw() {
GrDrawState* drawState = fDrawTarget->drawState();
drawState->setViewMatrix(fViewMatrix);
for (int s = 0; s < GrDrawState::kNumStages; ++s) {
if (fStageMask & (1 << s)) {
if (fRestoreMask & (1 << s)) {
*drawState->sampler(s)->matrix() = fSamplerMatrices[s];
}
}

View File

@ -55,9 +55,6 @@ public:
int fMaxTextureSize;
};
// for convenience
typedef GrDrawState::StageMask StageMask;
///////////////////////////////////////////////////////////////////////////
GrDrawTarget();
@ -104,17 +101,6 @@ public:
*/
GrDrawState* drawState() { return fDrawState; }
/**
* Shortcut for drawState()->preConcatSamplerMatrices() on all enabled
* stages
*
* @param matrix the matrix to concat
*/
void preConcatEnabledSamplerMatrices(const GrMatrix& matrix) {
StageMask stageMask = this->enabledStages();
this->drawState()->preConcatSamplerMatrices(stageMask, matrix);
}
/**
* Color alpha and coverage are two inputs to the drawing pipeline. For some
* blend modes it is safe to fold the coverage into constant or per-vertex
@ -452,8 +438,6 @@ public:
* drawNonIndexed.
* @param rect the rect to draw
* @param matrix optional matrix applied to rect (before viewMatrix)
* @param stageMask bitmask indicating which stages are enabled.
* Bit i indicates whether stage i is enabled.
* @param srcRects specifies rects for stages enabled by stageEnableMask.
* if stageEnableMask bit i is 1, srcRects is not NULL,
* and srcRects[i] is not NULL, then srcRects[i] will be
@ -467,7 +451,6 @@ public:
*/
virtual void drawRect(const GrRect& rect,
const GrMatrix* matrix,
StageMask stageMask,
const GrRect* srcRects[],
const GrMatrix* srcMatrices[]);
@ -509,9 +492,8 @@ public:
* matrices.
*/
void drawSimpleRect(const GrRect& rect,
const GrMatrix* matrix,
StageMask stageEnableBitfield) {
drawRect(rect, matrix, stageEnableBitfield, NULL, NULL);
const GrMatrix* matrix) {
drawRect(rect, matrix, NULL, NULL);
}
/**
@ -597,13 +579,24 @@ public:
*/
class AutoDeviceCoordDraw : ::GrNoncopyable {
public:
AutoDeviceCoordDraw(GrDrawTarget* target, StageMask stageMask);
/**
* If a stage's texture matrix is applied to explicit per-vertex coords,
* rather than to positions, then we don't want to modify its matrix.
* The explicitCoordStageMask is used to specify such stages.
*
* TODO: Remove this when custom stage's control their own texture
* matrix and there is a "view matrix has changed" notification to the
* custom stages.
*/
AutoDeviceCoordDraw(GrDrawTarget* target,
uint32_t explicitCoordStageMask = 0);
bool succeeded() const { return NULL != fDrawTarget; }
~AutoDeviceCoordDraw();
private:
GrDrawTarget* fDrawTarget;
GrMatrix fViewMatrix;
GrMatrix fSamplerMatrices[GrDrawState::kNumStages];
int fStageMask;
int fRestoreMask;
};
////////////////////////////////////////////////////////////////////////////
@ -954,14 +947,6 @@ protected:
return this->getDrawState().isStageEnabled(stage);
}
StageMask enabledStages() const {
StageMask mask = 0;
for (int s = 0; s < GrDrawState::kNumStages; ++s) {
mask |= this->isStageEnabled(s) ? 1 : 0;
}
return mask;
}
// A sublcass can optionally overload this function to be notified before
// vertex and index space is reserved.
virtual void willReserveVertexAndIndexSpace(GrVertexLayout vertexLayout,
@ -1006,8 +991,7 @@ protected:
// Helpers for drawRect, protected so subclasses that override drawRect
// can use them.
static GrVertexLayout GetRectVertexLayout(StageMask stageEnableBitfield,
const GrRect* srcRects[]);
static GrVertexLayout GetRectVertexLayout(const GrRect* srcRects[]);
static void SetRectVertices(const GrRect& rect,
const GrMatrix* matrix,

View File

@ -76,7 +76,6 @@ void GrInOrderDrawBuffer::resetDrawTracking() {
void GrInOrderDrawBuffer::drawRect(const GrRect& rect,
const GrMatrix* matrix,
StageMask stageMask,
const GrRect* srcRects[],
const GrMatrix* srcMatrices[]) {
@ -91,7 +90,7 @@ void GrInOrderDrawBuffer::drawRect(const GrRect& rect,
if (fMaxQuads) {
bool appendToPreviousDraw = false;
GrVertexLayout layout = GetRectVertexLayout(stageMask, srcRects);
GrVertexLayout layout = GetRectVertexLayout(srcRects);
AutoReleaseGeometry geo(this, layout, 4, 0);
if (!geo.succeeded()) {
GrPrintf("Failed to get space for vertices!\n");
@ -103,8 +102,18 @@ void GrInOrderDrawBuffer::drawRect(const GrRect& rect,
// then we don't want to modify the sampler matrices. Otherwise we do
// we have to account for the view matrix change in the sampler
// matrices.
StageMask devCoordMask = (NULL == srcRects) ? stageMask : 0;
GrDrawTarget::AutoDeviceCoordDraw adcd(this, devCoordMask);
uint32_t explicitCoordMask = 0;
if (srcRects) {
for (int s = 0; s < GrDrawState::kNumStages; ++s) {
if (srcRects[s]) {
explicitCoordMask |= (1 << s);
}
}
}
GrDrawTarget::AutoDeviceCoordDraw adcd(this, explicitCoordMask);
if (!adcd.succeeded()) {
return;
}
if (NULL != matrix) {
combinedMatrix.preConcat(*matrix);
}
@ -193,7 +202,7 @@ void GrInOrderDrawBuffer::drawRect(const GrRect& rect,
}
fInstancedDrawTracker.reset();
} else {
INHERITED::drawRect(rect, matrix, stageMask, srcRects, srcMatrices);
INHERITED::drawRect(rect, matrix, srcRects, srcMatrices);
}
}

View File

@ -115,7 +115,6 @@ public:
// overrides from GrDrawTarget
virtual void drawRect(const GrRect& rect,
const GrMatrix* matrix = NULL,
StageMask stageEnableMask = 0,
const GrRect* srcRects[] = NULL,
const GrMatrix* srcMatrices[] = NULL) SK_OVERRIDE;

View File

@ -100,22 +100,15 @@ public:
* @param translate optional additional translation applied to
* the path (can be NULL)
* @param target target that the path will be rendered to
* @param stageMask bitfield that indicates which stages are
* in use. All enabled stages expect positions
* as texture coordinates. The path renderer
* can use the remaining stages for its path
* filling algorithm.
* @param antiAlias true if anti-aliasing is required.
*/
virtual bool drawPath(const SkPath& path,
GrPathFill fill,
const GrVec* translate,
GrDrawTarget* target,
GrDrawState::StageMask stageMask,
bool antiAlias) {
GrAssert(this->canDrawPath(path, fill, target, antiAlias));
return this->onDrawPath(path, fill, translate,
target, stageMask, antiAlias);
return this->onDrawPath(path, fill, translate, target, antiAlias);
}
/**
@ -145,18 +138,12 @@ protected:
* @param translate optional additional translation applied to
* the path
* @param target target that the path will be rendered to
* @param stageMask bitfield that indicates which stages are
* in use. All enabled stages expect positions
* as texture coordinates. The path renderer
* use the remaining stages for its path
* filling algorithm.
* @param antiAlias whether antialiasing is enabled or not.
*/
virtual bool onDrawPath(const SkPath& path,
GrPathFill fill,
const GrVec* translate,
GrDrawTarget* target,
GrDrawState::StageMask stageMask,
bool antiAlias) = 0;
private:

View File

@ -199,11 +199,13 @@ GrTexture* GrSWMaskHelper::DrawPathMaskToTexture(GrContext* context,
void GrSWMaskHelper::DrawToTargetWithPathMask(GrTexture* texture,
GrDrawTarget* target,
GrDrawState::StageMask stageMask,
const GrIRect& rect) {
GrDrawState* drawState = target->drawState();
GrDrawTarget::AutoDeviceCoordDraw adcd(target, stageMask);
GrDrawTarget::AutoDeviceCoordDraw adcd(target);
if (!adcd.succeeded()) {
return;
}
enum {
// the SW path renderer shares this stage with glyph
// rendering (kGlyphMaskStage in GrBatchedTextContext)
@ -219,13 +221,12 @@ void GrSWMaskHelper::DrawToTargetWithPathMask(GrTexture* texture,
const GrRect* srcRects[GrDrawState::kNumStages] = { NULL };
srcRects[kPathMaskStage] = &maskRect;
stageMask |= 1 << kPathMaskStage;
GrRect dstRect = GrRect::MakeLTRB(
SK_Scalar1 * rect.fLeft,
SK_Scalar1 * rect.fTop,
SK_Scalar1 * rect.fRight,
SK_Scalar1 * rect.fBottom);
target->drawRect(dstRect, NULL, stageMask, srcRects, NULL);
target->drawRect(dstRect, NULL, srcRects, NULL);
drawState->disableStage(kPathMaskStage);
}

View File

@ -91,7 +91,6 @@ public:
// output of DrawPathMaskToTexture.
static void DrawToTargetWithPathMask(GrTexture* texture,
GrDrawTarget* target,
GrDrawState::StageMask stageMask,
const GrIRect& rect);
protected:

View File

@ -71,30 +71,32 @@ bool get_path_and_clip_bounds(const GrDrawTarget* target,
////////////////////////////////////////////////////////////////////////////////
void draw_around_inv_path(GrDrawTarget* target,
GrDrawState::StageMask stageMask,
const GrIRect& clipBounds,
const GrIRect& pathBounds) {
GrDrawTarget::AutoDeviceCoordDraw adcd(target, stageMask);
GrDrawTarget::AutoDeviceCoordDraw adcd(target);
if (!adcd.succeeded()) {
return;
}
GrRect rect;
if (clipBounds.fTop < pathBounds.fTop) {
rect.iset(clipBounds.fLeft, clipBounds.fTop,
clipBounds.fRight, pathBounds.fTop);
target->drawSimpleRect(rect, NULL, stageMask);
target->drawSimpleRect(rect, NULL);
}
if (clipBounds.fLeft < pathBounds.fLeft) {
rect.iset(clipBounds.fLeft, pathBounds.fTop,
pathBounds.fLeft, pathBounds.fBottom);
target->drawSimpleRect(rect, NULL, stageMask);
target->drawSimpleRect(rect, NULL);
}
if (clipBounds.fRight > pathBounds.fRight) {
rect.iset(pathBounds.fRight, pathBounds.fTop,
clipBounds.fRight, pathBounds.fBottom);
target->drawSimpleRect(rect, NULL, stageMask);
target->drawSimpleRect(rect, NULL);
}
if (clipBounds.fBottom > pathBounds.fBottom) {
rect.iset(clipBounds.fLeft, pathBounds.fBottom,
clipBounds.fRight, clipBounds.fBottom);
target->drawSimpleRect(rect, NULL, stageMask);
target->drawSimpleRect(rect, NULL);
}
}
@ -106,7 +108,6 @@ bool GrSoftwarePathRenderer::onDrawPath(const SkPath& path,
GrPathFill fill,
const GrVec* translate,
GrDrawTarget* target,
GrDrawState::StageMask stageMask,
bool antiAlias) {
if (NULL == fContext) {
@ -124,8 +125,7 @@ bool GrSoftwarePathRenderer::onDrawPath(const SkPath& path,
if (!get_path_and_clip_bounds(target, path, vm,
&pathBounds, &clipBounds)) {
if (GrIsFillInverted(fill)) {
draw_around_inv_path(target, stageMask,
clipBounds, pathBounds);
draw_around_inv_path(target, clipBounds, pathBounds);
}
return true;
}
@ -138,12 +138,10 @@ bool GrSoftwarePathRenderer::onDrawPath(const SkPath& path,
return false;
}
GrSWMaskHelper::DrawToTargetWithPathMask(texture, target,
stageMask, pathBounds);
GrSWMaskHelper::DrawToTargetWithPathMask(texture, target, pathBounds);
if (GrIsFillInverted(fill)) {
draw_around_inv_path(target, stageMask,
clipBounds, pathBounds);
draw_around_inv_path(target, clipBounds, pathBounds);
}
return true;

View File

@ -33,7 +33,6 @@ protected:
GrPathFill fill,
const GrVec* translate,
GrDrawTarget* target,
GrDrawState::StageMask stageMask,
bool antiAlias) SK_OVERRIDE;
private:

View File

@ -59,7 +59,6 @@ bool GrStencilAndCoverPathRenderer::onDrawPath(const SkPath& path,
GrPathFill fill,
const GrVec* translate,
GrDrawTarget* target,
GrDrawState::StageMask stageMask,
bool antiAlias){
GrAssert(!antiAlias);
GrAssert(kHairLine_GrPathFill != fill);
@ -112,12 +111,9 @@ bool GrStencilAndCoverPathRenderer::onDrawPath(const SkPath& path,
// theoretically could set bloat = 0, instead leave it because of matrix inversion
// precision.
} else {
if (stageMask) {
if (!drawState->getViewInverse(&vmi)) {
GrPrintf("Could not invert matrix.");
return false;
}
drawState->preConcatSamplerMatrices(stageMask, vmi);
if (!drawState->preConcatSamplerMatricesWithInverse(drawState->getViewMatrix())) {
GrPrintf("Could not invert matrix.\n");
return false;
}
if (avmr.isSet()) {
avmr.set(drawState);
@ -128,7 +124,7 @@ bool GrStencilAndCoverPathRenderer::onDrawPath(const SkPath& path,
*drawState->stencil() = kInvertedStencilPass;
}
bounds.outset(bloat, bloat);
target->drawSimpleRect(bounds, NULL, stageMask);
target->drawSimpleRect(bounds, NULL);
target->drawState()->stencil()->setDisabled();
return true;
}

View File

@ -43,7 +43,6 @@ protected:
GrPathFill fill,
const GrVec* translate,
GrDrawTarget* target,
GrDrawState::StageMask stageMask,
bool antiAlias) SK_OVERRIDE;
private:

View File

@ -927,12 +927,8 @@ bool drawWithGPUMaskFilter(GrContext* context, const SkPath& path,
context->setRenderTarget(oldRenderTarget);
context->setClip(oldClip);
if (grp->hasTextureOrMask()) {
GrMatrix inverse;
if (!matrix.invert(&inverse)) {
return false;
}
grp->preConcatActiveSamplerMatrices(inverse);
if (!grp->preConcatSamplerMatricesWithInverse(matrix)) {
return false;
}
static const int MASK_IDX = GrPaint::kMaxMasks - 1;
@ -978,11 +974,12 @@ bool drawWithMaskFilter(GrContext* context, const SkPath& path,
// we now have a device-aligned 8bit mask in dstM, ready to be drawn using
// the current clip (and identity matrix) and grpaint settings
// used to compute inverse view, if necessary
GrMatrix ivm = matrix;
GrContext::AutoMatrix avm(context, GrMatrix::I());
if (!grp->preConcatSamplerMatricesWithInverse(matrix)) {
return false;
}
GrTextureDesc desc;
desc.fWidth = dstM.fBounds.width();
desc.fHeight = dstM.fBounds.height();
@ -997,10 +994,6 @@ bool drawWithMaskFilter(GrContext* context, const SkPath& path,
texture->writePixels(0, 0, desc.fWidth, desc.fHeight, desc.fConfig,
dstM.fImage, dstM.fRowBytes);
if (grp->hasTextureOrMask() && ivm.invert(&ivm)) {
grp->preConcatActiveSamplerMatrices(ivm);
}
static const int MASK_IDX = GrPaint::kMaxMasks - 1;
// we assume the last mask index is available for use
GrAssert(!grp->isMaskStageEnabled(MASK_IDX));