Change TextContext handling of stages and draw targets; this allows us to
assert in GrContext::setPaint() that all stages are disabled every time
the paint is set.
Watch for possible performance implications.
http://codereview.appspot.com/6347043/
git-svn-id: http://skia.googlecode.com/svn/trunk@4531 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/gm/gradtext.cpp b/gm/gradtext.cpp
index a3769d2..c155cb7 100644
--- a/gm/gradtext.cpp
+++ b/gm/gradtext.cpp
@@ -8,6 +8,7 @@
#include "gm.h"
#include "SkCanvas.h"
#include "SkGradientShader.h"
+#include "SkTypeface.h"
// test shader w/ transparency
static SkShader* make_grad(SkScalar width) {
@@ -27,8 +28,77 @@
SkShader::kMirror_TileMode);
}
+static SkShader* make_chrome_solid() {
+ SkColor colors[] = { SK_ColorGREEN, SK_ColorGREEN };
+ SkPoint pts[] = { { 0, 0 }, { 1, 0 } };
+ return SkGradientShader::CreateLinear(pts, colors, NULL, 2,
+ SkShader::kClamp_TileMode);
+}
+
namespace skiagm {
+// Replicate chrome layout test - clipped pathed gradient-shaded text
+class ChromeGradTextGM1 : public GM {
+public:
+ ChromeGradTextGM1() { }
+protected:
+
+ virtual SkString onShortName() { return SkString("chrome_gradtext1"); }
+ virtual SkISize onISize() { return make_isize(500, 480); }
+ virtual void onDraw(SkCanvas* canvas) {
+ SkPaint paint;
+ const SkISize& size = this->getISize();
+ SkRect r = SkRect::MakeWH(SkIntToScalar(100), SkIntToScalar(100));
+
+ canvas->clipRect(r);
+
+ paint.setColor(SK_ColorRED);
+ canvas->drawRect(r, paint);
+
+ // Minimal repro doesn't require AA, LCD, or a nondefault typeface
+ paint.setShader(make_chrome_solid())->unref();
+ paint.setTextSize(SkIntToScalar(500));
+
+ canvas->drawText("I", 1, 0, 100, paint);
+ }
+private:
+ typedef GM INHERITED;
+};
+
+
+// Replicate chrome layout test - switching between solid & gadient text
+class ChromeGradTextGM2 : public GM {
+public:
+ ChromeGradTextGM2() { }
+protected:
+
+ virtual SkString onShortName() { return SkString("chrome_gradtext2"); }
+ virtual SkISize onISize() { return make_isize(500, 480); }
+ virtual void onDraw(SkCanvas* canvas) {
+ SkPaint paint;
+ const SkISize& size = this->getISize();
+ SkRect r = SkRect::MakeWH(SkIntToScalar(100), SkIntToScalar(100));
+
+
+ paint.setStyle(SkPaint::kFill_Style);
+ canvas->drawText("Normal Fill Text", 16, 0, 50, paint);
+ paint.setStyle(SkPaint::kStroke_Style);
+ canvas->drawText("Normal Stroke Text", 18, 0, 100, paint);
+
+ // Minimal repro doesn't require AA, LCD, or a nondefault typeface
+ paint.setShader(make_chrome_solid())->unref();
+
+ paint.setStyle(SkPaint::kFill_Style);
+ canvas->drawText("Gradient Fill Text", 18, 0, 150, paint);
+ paint.setStyle(SkPaint::kStroke_Style);
+ canvas->drawText("Gradient Stroke Text", 20, 0, 200, paint);
+ }
+private:
+ typedef GM INHERITED;
+};
+
+
+
class GradTextGM : public GM {
public:
GradTextGM () {}
@@ -91,7 +161,11 @@
//////////////////////////////////////////////////////////////////////////////
static GM* MyFactory(void*) { return new GradTextGM; }
-static GMRegistry reg(MyFactory);
+static GM* CMyFactory(void*) { return new ChromeGradTextGM1; }
+static GM* CMyFactory2(void*) { return new ChromeGradTextGM2; }
+static GMRegistry reg(MyFactory);
+static GMRegistry Creg(CMyFactory);
+static GMRegistry Creg2(CMyFactory2);
}
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index f756f8a..b004f28 100644
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -1589,8 +1589,7 @@
////////////////////////////////////////////////////////////////////////////////
void GrContext::setPaint(const GrPaint& paint) {
- // TODO: reenable this once we've cleaned up text state management
- //GrAssert(fDrawState->stagesDisabled());
+ GrAssert(fDrawState->stagesDisabled());
for (int i = 0; i < GrPaint::kMaxTextures; ++i) {
int s = i + GrPaint::kFirstTextureStage;
diff --git a/src/gpu/GrTextContext.cpp b/src/gpu/GrTextContext.cpp
index daf48bf..5b61be2 100644
--- a/src/gpu/GrTextContext.cpp
+++ b/src/gpu/GrTextContext.cpp
@@ -23,8 +23,11 @@
};
void GrTextContext::flushGlyphs() {
+ if (NULL == fDrawTarget) {
+ return;
+ }
+ GrDrawState* drawState = fDrawTarget->drawState();
if (fCurrVertex > 0) {
- GrDrawState* drawState = fDrawTarget->drawState();
// setup our sampler state for our text texture/atlas
GrSamplerState::Filter filter;
if (fExtMatrix.isIdentity()) {
@@ -68,8 +71,9 @@
fMaxVertices = 0;
fCurrVertex = 0;
GrSafeSetNull(fCurrTexture);
- drawState->disableStage(kGlyphMaskStage);
}
+ drawState->disableStages();
+ fDrawTarget = NULL;
}
GrTextContext::GrTextContext(GrContext* context,
@@ -134,7 +138,7 @@
}
}
- fDrawTarget = fContext->getTextTarget(fPaint);
+ fDrawTarget = NULL;
fVertices = NULL;
fMaxVertices = 0;
@@ -246,19 +250,20 @@
// If we need to reserve vertices allow the draw target to suggest
// a number of verts to reserve and whether to perform a flush.
fMaxVertices = kMinRequestedVerts;
- bool flush = fDrawTarget->geometryHints(fVertexLayout,
+ bool flush = (NULL != fDrawTarget) &&
+ fDrawTarget->geometryHints(fVertexLayout,
&fMaxVertices,
NULL);
if (flush) {
this->flushGlyphs();
fContext->flush();
- fDrawTarget = fContext->getTextTarget(fPaint);
- fMaxVertices = kDefaultRequestedVerts;
- // ignore return, no point in flushing again.
- fDrawTarget->geometryHints(fVertexLayout,
- &fMaxVertices,
- NULL);
}
+ fDrawTarget = fContext->getTextTarget(fPaint);
+ fMaxVertices = kDefaultRequestedVerts;
+ // ignore return, no point in flushing again.
+ fDrawTarget->geometryHints(fVertexLayout,
+ &fMaxVertices,
+ NULL);
int maxQuadVertices = 4 * fContext->getQuadIndexBuffer()->maxQuads();
if (fMaxVertices < kMinRequestedVerts) {