Change TextContext handling of stages and draw targets; this allows us to
authortomhudson@google.com <tomhudson@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Wed, 11 Jul 2012 14:41:19 +0000 (14:41 +0000)
committertomhudson@google.com <tomhudson@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Wed, 11 Jul 2012 14:41:19 +0000 (14:41 +0000)
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

gm/gradtext.cpp
src/gpu/GrContext.cpp
src/gpu/GrTextContext.cpp

index a3769d2..c155cb7 100644 (file)
@@ -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 @@ static SkShader* make_grad2(SkScalar width) {
                                           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 @@ private:
 //////////////////////////////////////////////////////////////////////////////
 
 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);
 }
 
index f756f8a..b004f28 100644 (file)
@@ -1589,8 +1589,7 @@ void GrContext::internalWriteRenderTargetPixels(GrRenderTarget* target,
 ////////////////////////////////////////////////////////////////////////////////
 
 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;
index daf48bf..5b61be2 100644 (file)
@@ -23,8 +23,11 @@ enum {
 };
 
 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 @@ void GrTextContext::flushGlyphs() {
         fMaxVertices = 0;
         fCurrVertex = 0;
         GrSafeSetNull(fCurrTexture);
-        drawState->disableStage(kGlyphMaskStage);
     }
+    drawState->disableStages();
+    fDrawTarget = NULL;
 }
 
 GrTextContext::GrTextContext(GrContext* context,
@@ -134,7 +138,7 @@ GrTextContext::GrTextContext(GrContext* context,
         }
     }
 
-    fDrawTarget = fContext->getTextTarget(fPaint);
+    fDrawTarget = NULL;
 
     fVertices = NULL;
     fMaxVertices = 0;
@@ -246,19 +250,20 @@ HAS_ATLAS:
         // 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) {