aboutsummaryrefslogtreecommitdiffhomepage
path: root/gpu
diff options
context:
space:
mode:
authorGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2011-05-17 20:15:30 +0000
committerGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2011-05-17 20:15:30 +0000
commit26c2d0a69e66f1656d2dc23953a6f153e5d5009f (patch)
tree02bcdc6be7b315bd6e5a30d3e4ac202b78b845f6 /gpu
parentdb2566bf9682ef3c4c47dca92cef8a4c28d3b3f5 (diff)
Use coverage stages for supersample AA resolve, edgeAA, and glyph masks. Expose a mask stage through GrPaint
Review URL: http://codereview.appspot.com/4548048/ git-svn-id: http://skia.googlecode.com/svn/trunk@1356 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'gpu')
-rw-r--r--gpu/include/GrContext.h14
-rw-r--r--gpu/include/GrContext_impl.h14
-rw-r--r--gpu/include/GrDrawTarget.h15
-rw-r--r--gpu/include/GrPaint.h177
-rw-r--r--gpu/src/GrContext.cpp147
-rw-r--r--gpu/src/GrTextContext.cpp41
6 files changed, 298 insertions, 110 deletions
diff --git a/gpu/include/GrContext.h b/gpu/include/GrContext.h
index c29526ad17..2fecca5ebd 100644
--- a/gpu/include/GrContext.h
+++ b/gpu/include/GrContext.h
@@ -579,11 +579,6 @@ private:
GrPathRenderer* getPathRenderer(const GrDrawTarget*, const GrPath&, GrPathFill);
struct OffscreenRecord;
- // we currently only expose stage 0 through the paint so use stage 1. We
- // use stage 1 for the offscreen.
- enum {
- kOffscreenStage = 1,
- };
bool doOffscreenAA(GrDrawTarget* target,
const GrPaint& paint,
@@ -602,6 +597,15 @@ private:
const GrIRect& boundRect,
OffscreenRecord* record);
+ // 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]);
+
};
/**
diff --git a/gpu/include/GrContext_impl.h b/gpu/include/GrContext_impl.h
index fae4e923f9..c79a191e2f 100644
--- a/gpu/include/GrContext_impl.h
+++ b/gpu/include/GrContext_impl.h
@@ -40,19 +40,15 @@ inline void GrContext::drawCustomVertices(const GrPaint& paint,
const COL_SRC* colorSrc,
const IDX_SRC* idxSrc) {
- GrVertexLayout layout = 0;
-
GrDrawTarget::AutoReleaseGeometry geo;
GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory);
- if (NULL != paint.getTexture()) {
- if (NULL != texCoordSrc) {
- layout |= GrDrawTarget::StageTexCoordVertexLayoutBit(0,0);
- } else {
- layout |= GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(0);
- }
- }
+ bool hasTexCoords[GrPaint::kTotalStages] = {
+ NULL != texCoordSrc, // texCoordSrc provides explicit stage 0 coords
+ 0 // remaining stages use positions
+ };
+ GrVertexLayout layout = PaintStageVertexLayoutBits(paint, hasTexCoords);
if (NULL != colorSrc) {
layout |= GrDrawTarget::kColor_VertexLayoutBit;
diff --git a/gpu/include/GrDrawTarget.h b/gpu/include/GrDrawTarget.h
index 9a00b57386..985cca7c1b 100644
--- a/gpu/include/GrDrawTarget.h
+++ b/gpu/include/GrDrawTarget.h
@@ -50,7 +50,7 @@ public:
* or not.
*/
enum {
- kNumStages = 2,
+ kNumStages = 3,
kMaxTexCoords = kNumStages
};
@@ -147,6 +147,7 @@ protected:
// default stencil setting should be disabled
GrAssert(fStencilSettings.isDisabled());
+ fFirstCoverageStage = kNumStages;
}
uint32_t fFlagBits;
GrBlendCoeff fSrcBlend;
@@ -250,6 +251,18 @@ public:
}
/**
+ * Shortcut for preConcatSamplerMatrix on all stages in mask with same
+ * matrix
+ */
+ void preConcatSamplerMatrices(int stageMask, const GrMatrix& matrix) {
+ for (int i = 0; i < kNumStages; ++i) {
+ if ((1 << i) & stageMask) {
+ this->preConcatSamplerMatrix(i, matrix);
+ }
+ }
+ }
+
+ /**
* Gets the matrix of a stage's sampler
*
* @param stage the stage to of sampler to get
diff --git a/gpu/include/GrPaint.h b/gpu/include/GrPaint.h
index 3035ca1b67..f7ca34c99a 100644
--- a/gpu/include/GrPaint.h
+++ b/gpu/include/GrPaint.h
@@ -25,12 +25,17 @@
/**
* The paint describes how pixels are colored when the context draws to
- * them.
+ * them. TODO: Make this a "real" class with getters and setters, default
+ * values, and documentation.
*/
class GrPaint {
public:
+ enum {
+ kMaxTextures = 1,
+ kMaxMasks = 1,
+ };
- // All the paint fields are public except texture (it's ref-counted)
+ // All the paint fields are public except textures/samplers
GrBlendCoeff fSrcBlendCoeff;
GrBlendCoeff fDstBlendCoeff;
bool fAntiAlias;
@@ -38,22 +43,75 @@ public:
GrColor fColor;
- GrSamplerState fSampler;
-
GrColor fColorFilterColor;
SkXfermode::Mode fColorFilterXfermode;
- void setTexture(GrTexture* texture) {
+ void setTexture(int i, GrTexture* texture) {
+ GrAssert((unsigned)i < kMaxTextures);
GrSafeRef(texture);
- GrSafeUnref(fTexture);
- fTexture = texture;
+ GrSafeUnref(fTextures[i]);
+ fTextures[i] = texture;
+ }
+
+ GrTexture* getTexture(int i) const {
+ GrAssert((unsigned)i < kMaxTextures);
+ return fTextures[i];
+ }
+
+ GrSamplerState* getTextureSampler(int i) {
+ GrAssert((unsigned)i < kMaxTextures);
+ return fTextureSamplers + i;
+ }
+
+ const GrSamplerState* getTextureSampler(int i) const {
+ GrAssert((unsigned)i < kMaxTextures);
+ return fTextureSamplers + i;
+ }
+
+ // The mask can be alpha-only or per channel. It is applied
+ // after the colorfilter
+ void setMask(int i, GrTexture* mask) {
+ GrAssert((unsigned)i < kMaxMasks);
+ GrSafeRef(mask);
+ GrSafeUnref(fMaskTextures[i]);
+ fMaskTextures[i] = mask;
+ }
+
+ GrTexture* getMask(int i) const {
+ GrAssert((unsigned)i < kMaxMasks);
+ return fMaskTextures[i];
+ }
+
+ // mask's sampler matrix is always applied to the positions
+ // (i.e. no explicit texture coordinates)
+ GrSamplerState* getMaskSampler(int i) {
+ GrAssert((unsigned)i < kMaxMasks);
+ return fMaskSamplers + i;
+ }
+
+ const GrSamplerState* getMaskSampler(int i) const {
+ GrAssert((unsigned)i < kMaxMasks);
+ return fMaskSamplers + i;
}
- GrTexture* getTexture() const { return fTexture; }
+ // pre-concats sampler matrices for non-NULL textures and masks
+ void preConcatActiveSamplerMatrices(const GrMatrix& matrix) {
+ for (int i = 0; i < kMaxTextures; ++i) {
+ fTextureSamplers[i].preConcatMatrix(matrix);
+ }
+ for (int i = 0; i < kMaxMasks; ++i) {
+ fMaskSamplers[i].preConcatMatrix(matrix);
+ }
+ }
// uninitialized
GrPaint() {
- fTexture = NULL;
+ for (int i = 0; i < kMaxTextures; ++i) {
+ fTextures[i] = NULL;
+ }
+ for (int i = 0; i < kMaxMasks; ++i) {
+ fMaskTextures[i] = NULL;
+ }
}
GrPaint(const GrPaint& paint) {
@@ -67,22 +125,35 @@ public:
fColorFilterColor = paint.fColorFilterColor;
fColorFilterXfermode = paint.fColorFilterXfermode;
- fSampler = paint.fSampler;
- fTexture = paint.fTexture;
- GrSafeRef(fTexture);
+ for (int i = 0; i < kMaxTextures; ++i) {
+ fTextureSamplers[i] = paint.fTextureSamplers[i];
+ fTextures[i] = paint.fTextures[i];
+ GrSafeRef(fTextures[i]);
+ }
+ for (int i = 0; i < kMaxMasks; ++i) {
+ fMaskSamplers[i] = paint.fMaskSamplers[i];
+ fMaskTextures[i] = paint.fMaskTextures[i];
+ GrSafeRef(fMaskTextures[i]);
+ }
}
~GrPaint() {
- GrSafeUnref(fTexture);
+ for (int i = 0; i < kMaxTextures; ++i) {
+ GrSafeUnref(fTextures[i]);
+ }
+ for (int i = 0; i < kMaxMasks; ++i) {
+ GrSafeUnref(fMaskTextures[i]);
+ }
}
- // sets paint to src-over, solid white, no texture
+ // sets paint to src-over, solid white, no texture, no mask
void reset() {
- resetBlend();
- resetOptions();
- resetColor();
- resetTexture();
- resetColorFilter();
+ this->resetBlend();
+ this->resetOptions();
+ this->resetColor();
+ this->resetTextures();
+ this->resetColorFilter();
+ this->resetMasks();
}
void resetColorFilter() {
@@ -90,8 +161,60 @@ public:
fColorFilterColor = GrColorPackRGBA(0xff, 0xff, 0xff, 0xff);
}
+ 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]) {
+ mask |= 1 << (i + kFirstTextureStage);
+ }
+ }
+ return mask;
+ }
+
+ int getActiveMaskStageMask() const {
+ int mask;
+ for (int i = 0; i < kMaxMasks; ++i) {
+ if (NULL != fMaskTextures[i]) {
+ 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)
+ enum {
+ kFirstTextureStage = 0,
+ kFirstMaskStage = kMaxTextures,
+ kTotalStages = kMaxTextures + kMaxMasks,
+ };
+
private:
- GrTexture* fTexture;
+
+ GrSamplerState fTextureSamplers[kMaxTextures];
+ GrSamplerState fMaskSamplers[kMaxMasks];
+
+ GrTexture* fTextures[kMaxTextures];
+ GrTexture* fMaskTextures[kMaxMasks];
void resetBlend() {
fSrcBlendCoeff = kOne_BlendCoeff;
@@ -107,11 +230,19 @@ private:
fColor = GrColorPackRGBA(0xff, 0xff, 0xff, 0xff);
}
- void resetTexture() {
- setTexture(NULL);
- fSampler.setClampNoFilter();
+ void resetTextures() {
+ for (int i = 0; i < kMaxTextures; ++i) {
+ this->setTexture(i, NULL);
+ fTextureSamplers[i].setClampNoFilter();
+ }
}
+ void resetMasks() {
+ for (int i = 0; i < kMaxMasks; ++i) {
+ this->setMask(i, NULL);
+ fMaskSamplers[i].setClampNoFilter();
+ }
+ }
};
#endif
diff --git a/gpu/src/GrContext.cpp b/gpu/src/GrContext.cpp
index 3a4233a346..af777c1bf7 100644
--- a/gpu/src/GrContext.cpp
+++ b/gpu/src/GrContext.cpp
@@ -106,6 +106,26 @@ void GrContext::freeGpuResources() {
////////////////////////////////////////////////////////////////////////////////
+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);
+ } else {
+ layout |= GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(i);
+ }
+ }
+ }
+ return layout;
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+
enum {
kNPOTBit = 0x1,
kFilterBit = 0x2,
@@ -576,6 +596,10 @@ void GrContext::offscreenAAPass2(GrDrawTarget* target,
GrTexture* src = record->fEntry0->texture();
int scale;
+ enum {
+ kOffscreenStage = GrPaint::kTotalStages,
+ };
+
if (OffscreenRecord::k4x4TwoPass_Downsample == record->fDownsample) {
GrAssert(NULL != record->fEntry1);
scale = 2;
@@ -605,11 +629,14 @@ void GrContext::offscreenAAPass2(GrDrawTarget* target,
}
// setup for draw back to main RT
+ int stageMask = paint.getActiveStageMask();
+
target->restoreDrawState(record->fSavedState);
- if (NULL != paint.getTexture()) {
+
+ if (stageMask) {
GrMatrix invVM;
if (target->getViewInverse(&invVM)) {
- target->preConcatSamplerMatrix(0, invVM);
+ target->preConcatSamplerMatrices(stageMask, invVM);
}
}
target->setViewMatrix(GrMatrix::I());
@@ -623,7 +650,7 @@ void GrContext::offscreenAAPass2(GrDrawTarget* target,
target->setSamplerState(kOffscreenStage, sampler);
GrRect dstRect;
- int stages = (1 << kOffscreenStage) | (NULL == paint.getTexture() ? 0 : 1);
+ int stages = (1 << kOffscreenStage) | stageMask;
dstRect.set(boundRect);
target->drawSimpleRect(dstRect, NULL, stages);
@@ -661,11 +688,14 @@ static void setStrokeRectStrip(GrPoint verts[10], GrRect rect,
}
static GrColor getColorForMesh(const GrPaint& paint) {
- if (NULL == paint.getTexture()) {
- return paint.fColor;
- } else {
+ // FIXME: This was copied from SkGpuDevice, seems like
+ // we should have already smeared a in caller if that
+ // is what is desired.
+ if (paint.hasTexture()) {
unsigned a = GrColorUnpackA(paint.fColor);
return GrColorPackRGBA(a, a, a, a);
+ } else {
+ return paint.fColor;
}
}
@@ -741,10 +771,8 @@ void GrContext::fillAARect(GrDrawTarget* target,
const GrPaint& paint,
const GrRect& devRect) {
- GrVertexLayout layout = GrDrawTarget::kColor_VertexLayoutBit;
- if (NULL != paint.getTexture()) {
- layout |= GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(0);
- }
+ GrVertexLayout layout = PaintStageVertexLayoutBits(paint, NULL) |
+ GrDrawTarget::kColor_VertexLayoutBit;
size_t vsize = GrDrawTarget::VertexSize(layout);
@@ -782,11 +810,8 @@ void GrContext::strokeAARect(GrDrawTarget* target, const GrPaint& paint,
const GrScalar rx = GrMul(dx, GR_ScalarHalf);
const GrScalar ry = GrMul(dy, GR_ScalarHalf);
- GrVertexLayout layout = GrDrawTarget::kColor_VertexLayoutBit;
-
- if (NULL != paint.getTexture()) {
- layout |= GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(0);
- }
+ GrVertexLayout layout = PaintStageVertexLayoutBits(paint, NULL) |
+ GrDrawTarget::kColor_VertexLayoutBit;
GrScalar spare;
{
@@ -902,9 +927,9 @@ void GrContext::drawRect(const GrPaint& paint,
GrScalar width,
const GrMatrix* matrix) {
- bool textured = NULL != paint.getTexture();
GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory);
+ int stageMask = paint.getActiveStageMask();
GrRect devRect = rect;
GrMatrix combinedMatrix;
@@ -913,10 +938,10 @@ void GrContext::drawRect(const GrPaint& paint,
if (doAA) {
GrDrawTarget::AutoViewMatrixRestore avm(target);
- if (textured) {
+ if (stageMask) {
GrMatrix inv;
if (combinedMatrix.invert(&inv)) {
- target->preConcatSamplerMatrix(0, inv);
+ target->preConcatSamplerMatrices(stageMask, inv);
}
}
target->setViewMatrix(GrMatrix::I());
@@ -940,9 +965,8 @@ 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 = textured ?
- GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(0) :
- 0;
+ GrVertexLayout layout = PaintStageVertexLayoutBits(paint, NULL);
+
static const int worstCaseVertCount = 10;
GrDrawTarget::AutoReleaseGeometry geo(target, layout, worstCaseVertCount, 0);
@@ -973,17 +997,14 @@ void GrContext::drawRect(const GrPaint& paint,
if (NULL != matrix) {
avmr.set(target);
target->preConcatViewMatrix(*matrix);
- if (textured) {
- target->preConcatSamplerMatrix(0, *matrix);
- }
+ target->preConcatSamplerMatrices(stageMask, *matrix);
}
target->drawNonIndexed(primType, 0, vertCount);
} else {
#if GR_STATIC_RECT_VB
- GrVertexLayout layout = (textured) ?
- GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(0) :
- 0;
+ GrVertexLayout layout = PaintStageVertexLayoutBits(paint, NULL);
+
target->setVertexSourceToBuffer(layout,
fGpu->getUnitSquareVertexBuffer());
GrDrawTarget::AutoViewMatrixRestore avmr(target);
@@ -997,13 +1018,11 @@ void GrContext::drawRect(const GrPaint& paint,
}
target->preConcatViewMatrix(m);
-
- if (textured) {
- target->preConcatSamplerMatrix(0, m);
- }
+ target->preConcatSamplerMatrices(stageMask, m);
+
target->drawNonIndexed(kTriangleFan_PrimitiveType, 0, 4);
#else
- target->drawSimpleRect(rect, matrix, textured ? 1 : 0);
+ target->drawSimpleRect(rect, matrix, stageMask);
#endif
}
}
@@ -1014,7 +1033,8 @@ void GrContext::drawRectToRect(const GrPaint& paint,
const GrMatrix* dstMatrix,
const GrMatrix* srcMatrix) {
- if (NULL == paint.getTexture()) {
+ // srcRect refers to paint's first texture
+ if (NULL == paint.getTexture(0)) {
drawRect(paint, dstRect, -1, dstMatrix);
return;
}
@@ -1023,8 +1043,8 @@ void GrContext::drawRectToRect(const GrPaint& paint,
#if GR_STATIC_RECT_VB
GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory);
-
- GrVertexLayout layout = GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(0);
+
+ GrVertexLayout layout = PaintStageVertexLayoutBits(paint, NULL);
GrDrawTarget::AutoViewMatrixRestore avmr(target);
GrMatrix m;
@@ -1037,13 +1057,20 @@ void GrContext::drawRectToRect(const GrPaint& paint,
}
target->preConcatViewMatrix(m);
+ // srcRect refers to first stage
+ int otherStageMask = paint.getActiveStageMask() &
+ (~(1 << GrPaint::kFirstTextureStage));
+ if (otherStageMask) {
+ target->preConcatSamplerMatrices(otherStageMask, m);
+ }
+
m.setAll(srcRect.width(), 0, srcRect.fLeft,
0, srcRect.height(), srcRect.fTop,
0, 0, GrMatrix::I()[8]);
if (NULL != srcMatrix) {
m.postConcat(*srcMatrix);
}
- target->preConcatSamplerMatrix(0, m);
+ target->preConcatSamplerMatrix(GrPaint::kFirstTextureStage, m);
target->setVertexSourceToBuffer(layout, fGpu->getUnitSquareVertexBuffer());
target->drawNonIndexed(kTriangleFan_PrimitiveType, 0, 4);
@@ -1073,26 +1100,22 @@ void GrContext::drawVertices(const GrPaint& paint,
const GrColor colors[],
const uint16_t indices[],
int indexCount) {
- GrVertexLayout layout = 0;
- int vertexSize = sizeof(GrPoint);
GrDrawTarget::AutoReleaseGeometry geo;
GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory);
- if (NULL != paint.getTexture()) {
- if (NULL == texCoords) {
- layout |= GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(0);
- } else {
- layout |= GrDrawTarget::StageTexCoordVertexLayoutBit(0,0);
- vertexSize += sizeof(GrPoint);
- }
- }
+ bool hasTexCoords[GrPaint::kTotalStages] = {
+ NULL != texCoords, // texCoordSrc provides explicit stage 0 coords
+ 0 // remaining stages use positions
+ };
+
+ GrVertexLayout layout = PaintStageVertexLayoutBits(paint, hasTexCoords);
if (NULL != colors) {
layout |= GrDrawTarget::kColor_VertexLayoutBit;
- vertexSize += sizeof(GrColor);
}
+ int vertexSize = GrDrawTarget::VertexSize(layout);
bool doAA = false;
OffscreenRecord record;
@@ -1105,9 +1128,9 @@ void GrContext::drawVertices(const GrPaint& paint,
}
int texOffsets[GrDrawTarget::kMaxTexCoords];
int colorOffset;
- int vsize = GrDrawTarget::VertexSizeAndOffsetsByIdx(layout,
- texOffsets,
- &colorOffset);
+ GrDrawTarget::VertexSizeAndOffsetsByIdx(layout,
+ texOffsets,
+ &colorOffset);
void* curVertex = geo.vertices();
for (int i = 0; i < vertexCount; ++i) {
@@ -1119,7 +1142,7 @@ void GrContext::drawVertices(const GrPaint& paint,
if (colorOffset > 0) {
*(GrColor*)((intptr_t)curVertex + colorOffset) = colors[i];
}
- curVertex = (void*)((intptr_t)curVertex + vsize);
+ curVertex = (void*)((intptr_t)curVertex + vertexSize);
}
} else {
// we don't do offscreen AA when we have per-vertex tex coords or colors
@@ -1193,10 +1216,7 @@ void GrContext::drawPath(const GrPaint& paint, const GrPath& path,
return;
}
}
- GrDrawTarget::StageBitfield enabledStages = 0;
- if (NULL != paint.getTexture()) {
- enabledStages |= 1;
- }
+ GrDrawTarget::StageBitfield enabledStages = paint.getActiveStageMask();
pr->drawPath(target, enabledStages, path, fill, translate);
}
@@ -1308,8 +1328,21 @@ void GrContext::writePixels(int left, int top, int width, int height,
////////////////////////////////////////////////////////////////////////////////
void GrContext::SetPaint(const GrPaint& paint, GrDrawTarget* target) {
- target->setTexture(0, paint.getTexture());
- target->setSamplerState(0, paint.fSampler);
+
+ for (int i = 0; i < GrPaint::kMaxTextures; ++i) {
+ int s = i + GrPaint::kFirstTextureStage;
+ target->setTexture(s, paint.getTexture(i));
+ target->setSamplerState(s, *paint.getTextureSampler(i));
+ }
+
+ target->setFirstCoverageStage(GrPaint::kFirstMaskStage);
+
+ for (int i = 0; i < GrPaint::kMaxMasks; ++i) {
+ int s = i + GrPaint::kFirstMaskStage;
+ target->setTexture(s, paint.getMask(i));
+ target->setSamplerState(s, *paint.getMaskSampler(i));
+ }
+
target->setColor(paint.fColor);
if (paint.fDither) {
diff --git a/gpu/src/GrTextContext.cpp b/gpu/src/GrTextContext.cpp
index 9e8e40a9bd..2aacfa25ad 100644
--- a/gpu/src/GrTextContext.cpp
+++ b/gpu/src/GrTextContext.cpp
@@ -25,11 +25,9 @@
#include "GrGpuVertex.h"
#include "GrDrawTarget.h"
-static const int TEXT_STAGE = 1;
-
-static const GrVertexLayout BASE_VLAYOUT =
- GrDrawTarget::kTextFormat_VertexLayoutBit |
- GrDrawTarget::StageTexCoordVertexLayoutBit(TEXT_STAGE,0);
+enum {
+ kGlyphMaskStage = GrPaint::kTotalStages,
+};
void GrTextContext::flushGlyphs() {
if (fCurrVertex > 0) {
@@ -45,17 +43,17 @@ void GrTextContext::flushGlyphs() {
GrSamplerState sampler(GrSamplerState::kRepeat_WrapMode,
GrSamplerState::kRepeat_WrapMode,
filter);
- fDrawTarget->setSamplerState(TEXT_STAGE, sampler);
+ fDrawTarget->setSamplerState(kGlyphMaskStage, sampler);
GrAssert(GrIsALIGN4(fCurrVertex));
int nIndices = fCurrVertex + (fCurrVertex >> 1);
GrAssert(fCurrTexture);
- fDrawTarget->setTexture(TEXT_STAGE, fCurrTexture);
+ fDrawTarget->setTexture(kGlyphMaskStage, fCurrTexture);
if (!GrPixelConfigIsAlphaOnly(fCurrTexture->config())) {
if (kOne_BlendCoeff != fPaint.fSrcBlendCoeff ||
kISA_BlendCoeff != fPaint.fDstBlendCoeff ||
- NULL != fPaint.getTexture()) {
+ fPaint.hasTexture()) {
GrPrintf("LCD Text will not draw correctly.\n");
}
// setup blend so that we get mask * paintColor + (1-mask)*dstColor
@@ -117,18 +115,31 @@ GrTextContext::GrTextContext(GrContext* context,
fOrigViewMatrix = fContext->getMatrix();
fContext->setMatrix(fExtMatrix);
- fVertexLayout = BASE_VLAYOUT;
- if (NULL != paint.getTexture()) {
- fVertexLayout |= GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(0);
+ fDrawTarget = fContext->getTextTarget(fPaint);
+
+ fVertices = NULL;
+ fMaxVertices = 0;
+
+ fVertexLayout =
+ GrDrawTarget::kTextFormat_VertexLayoutBit |
+ GrDrawTarget::StageTexCoordVertexLayoutBit(kGlyphMaskStage, 0);
+
+ int stageMask = paint.getActiveStageMask();
+ if (stageMask) {
GrMatrix inverseViewMatrix;
if (fOrigViewMatrix.invert(&inverseViewMatrix)) {
- fPaint.fSampler.preConcatMatrix(inverseViewMatrix);
+ fDrawTarget->preConcatSamplerMatrices(stageMask,
+ inverseViewMatrix);
+ }
+ for (int i = 0; i < GrPaint::kTotalStages; ++i) {
+ if ((1 << i) & stageMask) {
+ fVertexLayout |=
+ GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(i);
+ GrAssert(i != kGlyphMaskStage);
+ }
}
}
- fVertices = NULL;
- fMaxVertices = 0;
- fDrawTarget = fContext->getTextTarget(fPaint);
}
GrTextContext::~GrTextContext() {