Replace factory generation of TextContexts with persistent objects.
authorcommit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>
Thu, 30 Jan 2014 22:05:47 +0000 (22:05 +0000)
committercommit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>
Thu, 30 Jan 2014 22:05:47 +0000 (22:05 +0000)
BUG=skia:2018
R=bsalomon@google.com

Author: jvanverth@google.com

Review URL: https://codereview.chromium.org/150743002

git-svn-id: http://skia.googlecode.com/svn/trunk@13249 2bbb7eff-a529-9590-31e7-b0007b416f81

include/gpu/SkGpuDevice.h
src/gpu/GrBitmapTextContext.cpp
src/gpu/GrBitmapTextContext.h
src/gpu/GrDistanceFieldTextContext.cpp
src/gpu/GrDistanceFieldTextContext.h
src/gpu/GrTextContext.cpp
src/gpu/GrTextContext.h
src/gpu/SkGpuDevice.cpp

index bfcdba3..e791ca4 100644 (file)
@@ -20,7 +20,7 @@
 struct SkDrawProcs;
 struct GrSkDrawProcs;
 
-class GrTextContextManager;
+class GrTextContext;
 
 /**
  *  Subclass of SkBitmapDevice, which directs all drawing to the GrGpu owned by the
@@ -150,7 +150,8 @@ private:
 
     GrClipData      fClipData;
 
-    GrTextContextManager* fTextContextManager;
+    GrTextContext*  fMainTextContext;
+    GrTextContext*  fFallbackTextContext;
 
     // state for our render-target
     GrRenderTarget*     fRenderTarget;
index 488aa13..c7beb14 100755 (executable)
@@ -29,15 +29,9 @@ static const int kGlyphCoordsAttributeIndex = 1;
 SK_CONF_DECLARE(bool, c_DumpFontCache, "gpu.dumpFontCache", false,
                 "Dump the contents of the font cache before every purge.");
 
-bool GrBitmapTextContext::CanDraw(const SkPaint& paint, const SkMatrix& ctm) {
-    return !SkDraw::ShouldDrawTextAsPaths(paint, ctm);
-}
-
 GrBitmapTextContext::GrBitmapTextContext(GrContext* context,
-                                         const GrPaint& grPaint,
-                                         const SkPaint& skPaint,
                                          const SkDeviceProperties& properties)
-                                       : GrTextContext(context, grPaint, skPaint, properties) {
+                                       : GrTextContext(context, properties) {
     fStrike = NULL;
 
     fCurrTexture = NULL;
@@ -51,6 +45,10 @@ GrBitmapTextContext::~GrBitmapTextContext() {
     this->flushGlyphs();
 }
 
+bool GrBitmapTextContext::canDraw(const SkPaint& paint) {
+    return !SkDraw::ShouldDrawTextAsPaths(paint, fContext->getMatrix());
+}
+
 static inline GrColor skcolor_to_grcolor_nopremultiply(SkColor c) {
     unsigned r = SkColorGetR(c);
     unsigned g = SkColorGetG(c);
@@ -117,7 +115,26 @@ void GrBitmapTextContext::flushGlyphs() {
     }
 }
 
-void GrBitmapTextContext::drawText(const char text[], size_t byteLength,
+inline void GrBitmapTextContext::init(const GrPaint& paint, const SkPaint& skPaint) {
+    GrTextContext::init(paint, skPaint);
+
+    fStrike = NULL;
+
+    fCurrTexture = NULL;
+    fCurrVertex = 0;
+
+    fVertices = NULL;
+    fMaxVertices = 0;
+}
+
+inline void GrBitmapTextContext::finish() {
+    flushGlyphs();
+
+    GrTextContext::finish();
+}
+
+void GrBitmapTextContext::drawText(const GrPaint& paint, const SkPaint& skPaint, 
+                                   const char text[], size_t byteLength,
                                    SkScalar x, SkScalar y) {
     SkASSERT(byteLength == 0 || text != NULL);
 
@@ -126,6 +143,8 @@ void GrBitmapTextContext::drawText(const char text[], size_t byteLength,
         return;
     }
 
+    this->init(paint, skPaint);
+
     SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc();
 
     SkAutoGlyphCache    autoCache(fSkPaint, &fDeviceProperties, &fContext->getMatrix());
@@ -201,6 +220,8 @@ void GrBitmapTextContext::drawText(const char text[], size_t byteLength,
         fx += glyph.fAdvanceX;
         fy += glyph.fAdvanceY;
     }
+
+    this->finish();
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -295,7 +316,8 @@ BitmapTextMapState::Proc BitmapTextMapState::pickProc(int scalarsPerPosition) {
 
 ///////////////////////////////////////////////////////////////////////////////
 
-void GrBitmapTextContext::drawPosText(const char text[], size_t byteLength,
+void GrBitmapTextContext::drawPosText(const GrPaint& paint, const SkPaint& skPaint, 
+                                      const char text[], size_t byteLength,
                                       const SkScalar pos[], SkScalar constY,
                                       int scalarsPerPosition) {
     SkASSERT(byteLength == 0 || text != NULL);
@@ -306,6 +328,8 @@ void GrBitmapTextContext::drawPosText(const char text[], size_t byteLength,
         return;
     }
 
+    this->init(paint, skPaint);
+
     SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc();
 
     SkAutoGlyphCache    autoCache(fSkPaint, &fDeviceProperties, &fContext->getMatrix());
@@ -439,6 +463,8 @@ void GrBitmapTextContext::drawPosText(const char text[], size_t byteLength,
             }
         }
     }
+
+    this->finish();
 }
 
 namespace {
index 6550e3c..8d6edda 100755 (executable)
@@ -17,21 +17,25 @@ class GrTextStrike;
  */
 class GrBitmapTextContext : public GrTextContext {
 public:
-    GrBitmapTextContext(GrContext*, const GrPaint&, const SkPaint&, const SkDeviceProperties&);
+    GrBitmapTextContext(GrContext*, const SkDeviceProperties&);
     virtual ~GrBitmapTextContext();
 
-    virtual void drawText(const char text[], size_t byteLength, SkScalar x, SkScalar y) SK_OVERRIDE;
-    virtual void drawPosText(const char text[], size_t byteLength,
+    virtual void drawText(const GrPaint&, const SkPaint&, const char text[], size_t byteLength, 
+                          SkScalar x, SkScalar y) SK_OVERRIDE;
+    virtual void drawPosText(const GrPaint&, const SkPaint&, 
+                             const char text[], size_t byteLength,
                              const SkScalar pos[], SkScalar constY,
                              int scalarsPerPosition) SK_OVERRIDE;
 
-    static bool CanDraw(const SkPaint& paint, const SkMatrix& ctm);
+    virtual bool canDraw(const SkPaint& paint) SK_OVERRIDE;
     
 private:
     GrTextStrike*          fStrike;
 
+    void init(const GrPaint&, const SkPaint&);
     void drawPackedGlyph(GrGlyph::PackedID, GrFixed left, GrFixed top, GrFontScaler*);
     void flushGlyphs();                 // automatically called by destructor
+    void finish();
 
     enum {
         kMinRequestedGlyphs      = 1,
index 52b714c..ac93433 100755 (executable)
@@ -27,17 +27,9 @@ static const int kBaseDFFontSize = 32;
 SK_CONF_DECLARE(bool, c_DumpFontCache, "gpu.dumpFontCache", false,
                 "Dump the contents of the font cache before every purge.");
 
-bool GrDistanceFieldTextContext::CanDraw(const SkPaint& paint, const SkMatrix& ctm) {
-    return !paint.getRasterizer() && !paint.getMaskFilter() &&
-           paint.getStyle() == SkPaint::kFill_Style &&
-           !SkDraw::ShouldDrawTextAsPaths(paint, ctm);
-}
-
 GrDistanceFieldTextContext::GrDistanceFieldTextContext(GrContext* context,
-                                                       const GrPaint& grPaint,
-                                                       const SkPaint& skPaint,
                                                        const SkDeviceProperties& properties)
-                                            : GrTextContext(context, grPaint, skPaint, properties) {
+                                                    : GrTextContext(context, properties) {
     fStrike = NULL;
 
     fCurrTexture = NULL;
@@ -45,19 +37,18 @@ GrDistanceFieldTextContext::GrDistanceFieldTextContext(GrContext* context,
 
     fVertices = NULL;
     fMaxVertices = 0;
-
-    fTextRatio = fSkPaint.getTextSize()/kBaseDFFontSize;
-
-    fSkPaint.setTextSize(SkIntToScalar(kBaseDFFontSize));
-    fSkPaint.setLCDRenderText(false);
-    fSkPaint.setAutohinted(false);
-    fSkPaint.setSubpixelText(false);
 }
 
 GrDistanceFieldTextContext::~GrDistanceFieldTextContext() {
     this->flushGlyphs();
 }
 
+bool GrDistanceFieldTextContext::canDraw(const SkPaint& paint) {
+    return !paint.getRasterizer() && !paint.getMaskFilter() &&
+           paint.getStyle() == SkPaint::kFill_Style &&
+           !SkDraw::ShouldDrawTextAsPaths(paint, fContext->getMatrix());
+}
+
 static inline GrColor skcolor_to_grcolor_nopremultiply(SkColor c) {
     unsigned r = SkColorGetR(c);
     unsigned g = SkColorGetG(c);
@@ -291,7 +282,33 @@ HAS_ATLAS:
     fCurrVertex += 4;
 }
 
-void GrDistanceFieldTextContext::drawText(const char text[], size_t byteLength,
+inline void GrDistanceFieldTextContext::init(const GrPaint& paint, const SkPaint& skPaint) {
+    GrTextContext::init(paint, skPaint);
+
+    fStrike = NULL;
+
+    fCurrTexture = NULL;
+    fCurrVertex = 0;
+
+    fVertices = NULL;
+    fMaxVertices = 0;
+
+    fTextRatio = fSkPaint.getTextSize()/kBaseDFFontSize;
+         
+    fSkPaint.setTextSize(SkIntToScalar(kBaseDFFontSize));
+    fSkPaint.setLCDRenderText(false);
+    fSkPaint.setAutohinted(false);
+    fSkPaint.setSubpixelText(false);
+}
+
+inline void GrDistanceFieldTextContext::finish() {
+    flushGlyphs();
+
+    GrTextContext::finish();
+}
+
+void GrDistanceFieldTextContext::drawText(const GrPaint& paint, const SkPaint& skPaint,
+                                          const char text[], size_t byteLength,
                                           SkScalar x, SkScalar y) {
     SkASSERT(byteLength == 0 || text != NULL);
 
@@ -301,6 +318,8 @@ void GrDistanceFieldTextContext::drawText(const char text[], size_t byteLength,
         return;
     }
 
+    this->init(paint, skPaint);
+
     SkScalar sizeRatio = fTextRatio;
 
     SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc();
@@ -357,9 +376,12 @@ void GrDistanceFieldTextContext::drawText(const char text[], size_t byteLength,
         fx += SkFixedMul_portable(glyph.fAdvanceX, fixedScale);
         fy += SkFixedMul_portable(glyph.fAdvanceY, fixedScale);
     }
+
+    this->finish();
 }
 
-void GrDistanceFieldTextContext::drawPosText(const char text[], size_t byteLength,
+void GrDistanceFieldTextContext::drawPosText(const GrPaint& paint, const SkPaint& skPaint,
+                                             const char text[], size_t byteLength,
                                              const SkScalar pos[], SkScalar constY,
                                              int scalarsPerPosition) {
 
@@ -367,11 +389,12 @@ void GrDistanceFieldTextContext::drawPosText(const char text[], size_t byteLengt
     SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition);
 
     // nothing to draw
-    if (text == NULL || byteLength == 0 /* no raster clip? || fRC->isEmpty()*/
-        || fSkPaint.getRasterizer()) {
+    if (text == NULL || byteLength == 0 /* no raster clip? || fRC->isEmpty()*/) {
         return;
     }
 
+    this->init(paint, skPaint);
+
     SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc();
 
     SkAutoGlyphCache    autoCache(fSkPaint, &fDeviceProperties, NULL);
@@ -420,4 +443,6 @@ void GrDistanceFieldTextContext::drawPosText(const char text[], size_t byteLengt
             pos += scalarsPerPosition;
         }
     }
+
+    this->finish();
 }
index 8b94038..2129898 100755 (executable)
@@ -17,24 +17,26 @@ class GrTextStrike;
  */
 class GrDistanceFieldTextContext : public GrTextContext {
 public:
-    virtual void drawText(const char text[], size_t byteLength, SkScalar x, SkScalar y) SK_OVERRIDE;
-    virtual void drawPosText(const char text[], size_t byteLength,
+    GrDistanceFieldTextContext(GrContext*, const SkDeviceProperties&);
+    virtual ~GrDistanceFieldTextContext();
+
+    virtual void drawText(const GrPaint&, const SkPaint&, const char text[], size_t byteLength, 
+                          SkScalar x, SkScalar y) SK_OVERRIDE;
+    virtual void drawPosText(const GrPaint&, const SkPaint&, 
+                             const char text[], size_t byteLength,
                              const SkScalar pos[], SkScalar constY,
                              int scalarsPerPosition) SK_OVERRIDE;
     
-    static bool CanDraw(const SkPaint& paint, const SkMatrix& ctm);
+    virtual bool canDraw(const SkPaint& paint) SK_OVERRIDE;
 
 private:
-    GrDistanceFieldTextContext(GrContext*, const GrPaint&, const SkPaint&,
-                               const SkDeviceProperties&);
-    virtual ~GrDistanceFieldTextContext();
-    friend class GrTTextContextManager<GrDistanceFieldTextContext>;
-
     GrTextStrike*           fStrike;
     SkScalar                fTextRatio;
 
+    void init(const GrPaint&, const SkPaint&);
     void drawPackedGlyph(GrGlyph::PackedID, GrFixed left, GrFixed top, GrFontScaler*);
     void flushGlyphs();                 // automatically called by destructor
+    void finish();
 
     enum {
         kMinRequestedGlyphs      = 1,
index 0c9e149..bc11671 100644 (file)
 #include "SkGlyphCache.h"
 #include "SkGr.h"
 
-GrTextContext::GrTextContext(GrContext* context, const GrPaint& paint,
-                             const SkPaint& skPaint, const SkDeviceProperties& properties) :
-                            fContext(context), fPaint(paint), fSkPaint(skPaint),
-                            fDeviceProperties(properties) {
+GrTextContext::GrTextContext(GrContext* context, const SkDeviceProperties& properties) :
+                            fContext(context), fDeviceProperties(properties), fDrawTarget(NULL) {
+}
 
-    const GrClipData* clipData = context->getClip();
+void GrTextContext::init(const GrPaint& grPaint, const SkPaint& skPaint) {
+    const GrClipData* clipData = fContext->getClip();
 
     SkRect devConservativeBound;
     clipData->fClipStack->getConservativeBounds(
                                      -clipData->fOrigin.fX,
                                      -clipData->fOrigin.fY,
-                                     context->getRenderTarget()->width(),
-                                     context->getRenderTarget()->height(),
+                                     fContext->getRenderTarget()->width(),
+                                     fContext->getRenderTarget()->height(),
                                      &devConservativeBound);
 
     devConservativeBound.roundOut(&fClipRect);
 
-    fDrawTarget = context->getTextTarget();
+    fDrawTarget = fContext->getTextTarget();
+
+    fPaint = grPaint;
+    fSkPaint = skPaint;
 }
 
 //*** change to output positions?
index c572d0d..ea089cc 100644 (file)
@@ -25,105 +25,32 @@ class GrFontScaler;
 class GrTextContext {
 public:
     virtual ~GrTextContext() {}
-    virtual void drawText(const char text[], size_t byteLength, SkScalar x, SkScalar y) = 0;
-    virtual void drawPosText(const char text[], size_t byteLength,
+    virtual void drawText(const GrPaint&, const SkPaint&, const char text[], size_t byteLength, 
+                          SkScalar x, SkScalar y) = 0;
+    virtual void drawPosText(const GrPaint&, const SkPaint&,
+                             const char text[], size_t byteLength,
                              const SkScalar pos[], SkScalar constY,
                              int scalarsPerPosition) = 0;
+
+    virtual bool canDraw(const SkPaint& paint) = 0;
     
 protected:
-    GrTextContext(GrContext*, const GrPaint&, const SkPaint&, const SkDeviceProperties&);
+    GrTextContext(GrContext*, const SkDeviceProperties&);
 
     static GrFontScaler* GetGrFontScaler(SkGlyphCache* cache);
     static void MeasureText(SkGlyphCache* cache, SkDrawCacheProc glyphCacheProc,
                             const char text[], size_t byteLength, SkVector* stopVector);
 
+    void init(const GrPaint&, const SkPaint&);
+    void finish() { fDrawTarget = NULL; }
+
     GrContext*         fContext;
-    GrPaint            fPaint;
-    SkPaint            fSkPaint;
     SkDeviceProperties fDeviceProperties;
-    GrDrawTarget*      fDrawTarget;
 
+    GrDrawTarget*      fDrawTarget;
     SkIRect            fClipRect;
-};
-
-/*
- * These classes wrap the creation of a single text context for a given GPU device. The
- * assumption is that we'll only be using one text context at a time for that device.
- */
-class GrTextContextManager {
-public:
-    virtual ~GrTextContextManager() {}
-    virtual GrTextContext* create(GrContext* grContext, const GrPaint& grPaint,
-                                  const SkPaint& skPaint, const SkDeviceProperties& props) = 0;
-    virtual bool canDraw(const SkPaint& paint, const SkMatrix& ctm) = 0;
-};
-
-template <class TextContextClass>
-class GrTTextContextManager : public GrTextContextManager {
-private:
-    class ManagedTextContext : public TextContextClass {
-    public:
-        virtual ~ManagedTextContext() {}
-
-        ManagedTextContext(GrContext* grContext,
-                           const GrPaint& grPaint,
-                           const SkPaint& skPaint,
-                           const SkDeviceProperties& properties,
-                           GrTTextContextManager<TextContextClass>* manager) :
-                          TextContextClass(grContext, grPaint, skPaint, properties) {
-            fManager = manager;
-        }
-
-        static void operator delete(void* ptr) {
-            if (ptr == NULL) {
-                return;
-            }
-            ManagedTextContext* context = reinterpret_cast<ManagedTextContext*>(ptr);
-            context->fManager->recycle(context);
-        }
-
-        static void operator delete(void*, void*) {
-        }
-
-        GrTTextContextManager<TextContextClass>* fManager;
-    };
-
-public:
-    GrTTextContextManager() {
-        fAllocation = sk_malloc_throw(sizeof(ManagedTextContext));
-        fUsed = false;
-    }
-
-    virtual ~GrTTextContextManager() {
-        SkASSERT(!fUsed);
-        sk_free(fAllocation);
-    }
-
-    virtual GrTextContext* create(GrContext* grContext, const GrPaint& grPaint,
-                                  const SkPaint& skPaint, const SkDeviceProperties& properties)
-                                 SK_OVERRIDE {
-        // add check for usePath here?
-        SkASSERT(!fUsed);
-        ManagedTextContext* obj = SkNEW_PLACEMENT_ARGS(fAllocation, ManagedTextContext,
-                                                       (grContext, grPaint, skPaint, properties,
-                                                        this));
-        fUsed = true;
-        return obj;
-    }
-
-    virtual bool canDraw(const SkPaint& paint, const SkMatrix& ctm) SK_OVERRIDE {
-        return TextContextClass::CanDraw(paint, ctm);
-    }
-
-private:
-    void recycle(GrTextContext* textContext) {
-        SkASSERT((void*)textContext == fAllocation);
-        SkASSERT(fUsed);
-        fUsed = false;
-    }
-
-    void* fAllocation;
-    bool  fUsed;
+    GrPaint            fPaint;
+    SkPaint            fSkPaint;
 };
 
 #endif
index c858403..dfae1c4 100644 (file)
@@ -201,9 +201,11 @@ void SkGpuDevice::initFromRenderTarget(GrContext* context,
     fContext->ref();
 
 #if SK_DISTANCEFIELD_FONTS
-    fTextContextManager = SkNEW(GrTTextContextManager<GrDistanceFieldTextContext>);
+    fMainTextContext = SkNEW_ARGS(GrDistanceFieldTextContext, (fContext, fLeakyProperties));
+    fFallbackTextContext = SkNEW_ARGS(GrBitmapTextContext, (fContext, fLeakyProperties));
 #else
-    fTextContextManager = SkNEW(GrTTextContextManager<GrBitmapTextContext>);
+    fMainTextContext = SkNEW_ARGS(GrBitmapTextContext, (fContext, fLeakyProperties));
+    fFallbackTextContext = NULL;
 #endif
 
     fRenderTarget = NULL;
@@ -242,9 +244,11 @@ SkGpuDevice::SkGpuDevice(GrContext* context,
     fContext->ref();
 
 #if SK_DISTANCEFIELD_FONTS
-    fTextContextManager = SkNEW(GrTTextContextManager<GrDistanceFieldTextContext>);
+    fMainTextContext = SkNEW_ARGS(GrDistanceFieldTextContext, (fContext, fLeakyProperties));
+    fFallbackTextContext = SkNEW_ARGS(GrBitmapTextContext, (fContext, fLeakyProperties));
 #else
-    fTextContextManager = SkNEW(GrTTextContextManager<GrBitmapTextContext>);
+    fMainTextContext = SkNEW_ARGS(GrBitmapTextContext, (fContext, fLeakyProperties));
+    fFallbackTextContext = NULL;
 #endif
 
     fRenderTarget = NULL;
@@ -292,7 +296,8 @@ SkGpuDevice::~SkGpuDevice() {
         delete fDrawProcs;
     }
 
-    delete fTextContextManager;
+    delete fMainTextContext;
+    delete fFallbackTextContext;
 
     // The GrContext takes a ref on the target. We don't want to cause the render
     // target to be unnecessarily kept alive.
@@ -1778,7 +1783,7 @@ void SkGpuDevice::drawText(const SkDraw& draw, const void* text,
                           const SkPaint& paint) {
     CHECK_SHOULD_DRAW(draw, false);
 
-    if (fTextContextManager->canDraw(paint, fContext->getMatrix())) {
+    if (fMainTextContext->canDraw(paint)) {
         GrPaint grPaint;
         if (!skPaint2GrPaintShader(this, paint, true, &grPaint)) {
             return;
@@ -1786,11 +1791,8 @@ void SkGpuDevice::drawText(const SkDraw& draw, const void* text,
 
         SkDEBUGCODE(this->validate();)
 
-        SkAutoTDelete<GrTextContext> ctx(fTextContextManager->create(this->context(),
-                                                                     grPaint, paint,
-                                                                     this->getDeviceProperties()));
-        ctx->drawText((const char *)text, byteLength, x, y);
-    } else if (GrBitmapTextContext::CanDraw(paint, fContext->getMatrix())) {
+        fMainTextContext->drawText(grPaint, paint, (const char *)text, byteLength, x, y);
+    } else if (fFallbackTextContext && fFallbackTextContext->canDraw(paint)) {
         GrPaint grPaint;
         if (!skPaint2GrPaintShader(this, paint, true, &grPaint)) {
             return;
@@ -1798,9 +1800,7 @@ void SkGpuDevice::drawText(const SkDraw& draw, const void* text,
 
         SkDEBUGCODE(this->validate();)
 
-        GrBitmapTextContext textContext(this->context(), grPaint, paint,
-                                        this->getDeviceProperties());
-        textContext.drawText((const char *)text, byteLength, x, y);
+        fFallbackTextContext->drawText(grPaint, paint, (const char *)text, byteLength, x, y);
     } else {
         // this guy will just call our drawPath()
         draw.drawText_asPaths((const char*)text, byteLength, x, y, paint);
@@ -1813,7 +1813,7 @@ void SkGpuDevice::drawPosText(const SkDraw& draw, const void* text,
                              const SkPaint& paint) {
     CHECK_SHOULD_DRAW(draw, false);
 
-    if (fTextContextManager->canDraw(paint, fContext->getMatrix())) {
+    if (fMainTextContext->canDraw(paint)) {
         GrPaint grPaint;
         if (!skPaint2GrPaintShader(this, paint, true, &grPaint)) {
             return;
@@ -1821,11 +1821,9 @@ void SkGpuDevice::drawPosText(const SkDraw& draw, const void* text,
 
         SkDEBUGCODE(this->validate();)
 
-        SkAutoTDelete<GrTextContext> ctx(fTextContextManager->create(this->context(),
-                                                                     grPaint, paint,
-                                                                     this->getDeviceProperties()));
-        ctx->drawPosText((const char *)text, byteLength, pos, constY, scalarsPerPos);
-    } else if (GrBitmapTextContext::CanDraw(paint, fContext->getMatrix())) {
+        fMainTextContext->drawPosText(grPaint, paint, (const char *)text, byteLength, pos, 
+                                      constY, scalarsPerPos);
+    } else if (fFallbackTextContext && fFallbackTextContext->canDraw(paint)) {
         GrPaint grPaint;
         if (!skPaint2GrPaintShader(this, paint, true, &grPaint)) {
             return;
@@ -1833,9 +1831,8 @@ void SkGpuDevice::drawPosText(const SkDraw& draw, const void* text,
         
         SkDEBUGCODE(this->validate();)
         
-        GrBitmapTextContext textContext(this->context(), grPaint, paint,
-                                        this->getDeviceProperties());
-        textContext.drawPosText((const char *)text, byteLength, pos, constY, scalarsPerPos);
+        fFallbackTextContext->drawPosText(grPaint, paint, (const char *)text, byteLength, pos, 
+                                          constY, scalarsPerPos);
     } else {
         draw.drawPosText_asPaths((const char*)text, byteLength, pos, constY,
                                  scalarsPerPos, paint);