*/
class GrBitmapTextContext : public GrTextContext {
public:
- GrBitmapTextContext(GrContext*, const GrPaint&, SkColor);
- virtual ~GrBitmapTextContext();
-
virtual void drawPackedGlyph(GrGlyph::PackedID, GrFixed left, GrFixed top,
GrFontScaler*) SK_OVERRIDE;
private:
+ GrBitmapTextContext(GrContext*, const GrPaint&, const SkPaint&);
+ virtual ~GrBitmapTextContext();
+ friend class GrTTextContextManager<GrBitmapTextContext>;
+
GrContext::AutoMatrix fAutoMatrix;
GrTextStrike* fStrike;
kDefaultRequestedVerts = kDefaultRequestedGlyphs * 4,
};
- SkColor fSkPaintColor;
SkPoint* fVertices;
int32_t fMaxVertices;
GrTexture* fCurrTexture;
*/
class GrDistanceFieldTextContext : public GrTextContext {
public:
- GrDistanceFieldTextContext(GrContext*, const GrPaint&, const SkPaint&);
- virtual ~GrDistanceFieldTextContext();
-
virtual void drawPackedGlyph(GrGlyph::PackedID, GrFixed left, GrFixed top,
GrFontScaler*) SK_OVERRIDE;
const SkPaint& getSkPaint() { return fSkPaint; }
private:
+ GrDistanceFieldTextContext(GrContext*, const GrPaint&, const SkPaint&);
+ virtual ~GrDistanceFieldTextContext();
+ friend class GrTTextContextManager<GrDistanceFieldTextContext>;
+
GrTextStrike* fStrike;
SkScalar fTextRatio;
kDefaultRequestedVerts = kDefaultRequestedGlyphs * 4,
};
- SkPaint fSkPaint;
SkPoint* fVertices;
int32_t fMaxVertices;
GrTexture* fCurrTexture;
#include "GrGlyph.h"
#include "GrPaint.h"
+#include "SkPostConfig.h"
+
class GrContext;
class GrDrawTarget;
class GrFontScaler;
*/
class GrTextContext {
public:
+ virtual ~GrTextContext() {}
virtual void drawPackedGlyph(GrGlyph::PackedID, GrFixed left, GrFixed top,
GrFontScaler*) = 0;
protected:
- GrTextContext(GrContext*, const GrPaint&);
- virtual ~GrTextContext() {}
+ GrTextContext(GrContext*, const GrPaint&, const SkPaint&);
GrPaint fPaint;
+ SkPaint fSkPaint;
GrContext* fContext;
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* context, const GrPaint& grPaint,
+ const SkPaint& skPaint) = 0;
+};
+template <class TextContextClass>
+class GrTTextContextManager : public GrTextContextManager {
private:
+ class ManagedTextContext : public TextContextClass {
+ public:
+ ~ManagedTextContext() {}
+
+ ManagedTextContext(GrContext* context,
+ const GrPaint& grPaint,
+ const SkPaint& skPaint,
+ GrTTextContextManager<TextContextClass>* manager) :
+ TextContextClass(context, grPaint, skPaint) {
+ fManager = manager;
+ }
+
+ static void operator delete(void* ptr) {
+ if (ptr == NULL) {
+ return;
+ }
+ ManagedTextContext* context = reinterpret_cast<ManagedTextContext*>(ptr);
+ context->fManager->recycle(context);
+ }
+
+ GrTTextContextManager<TextContextClass>* fManager;
+ };
+
+public:
+ GrTTextContextManager() {
+ fAllocation = sk_malloc_throw(sizeof(ManagedTextContext));
+ fUsed = false;
+ }
+
+ ~GrTTextContextManager() {
+ SkASSERT(!fUsed);
+ sk_free(fAllocation);
+ }
+
+ GrTextContext* create(GrContext* context, const GrPaint& grPaint,
+ const SkPaint& skPaint) {
+ // add check for usePath here?
+ SkASSERT(!fUsed);
+ ManagedTextContext* obj = SkNEW_PLACEMENT_ARGS(fAllocation, ManagedTextContext,
+ (context, grPaint, skPaint, this));
+ fUsed = true;
+ return obj;
+ }
+
+private:
+ void recycle(GrTextContext* textContext) {
+ SkASSERT((void*)textContext == fAllocation);
+ SkASSERT(fUsed);
+ fUsed = false;
+ }
+
+ void* fAllocation;
+ bool fUsed;
};
#endif
#include "SkBitmapDevice.h"
#include "SkRegion.h"
#include "GrContext.h"
+#include "GrTextContext.h"
struct SkDrawProcs;
struct GrSkDrawProcs;
-class GrTextContext;
/**
* Subclass of SkBitmapDevice, which directs all drawing to the GrGpu owned by the
GrClipData fClipData;
+ GrTextContextManager* fTextContextManager;
+
// state for our render-target
GrRenderTarget* fRenderTarget;
bool fNeedClear;
"Dump the contents of the font cache before every purge.");
GrBitmapTextContext::GrBitmapTextContext(GrContext* context, const GrPaint& paint,
- SkColor color) :
- GrTextContext(context, paint) {
+ const SkPaint& skPaint) :
+ GrTextContext(context, paint, skPaint) {
fAutoMatrix.setIdentity(fContext, &fPaint);
- fSkPaintColor = color;
-
fStrike = NULL;
fCurrTexture = NULL;
// alpha. Instead we feed in a non-premultiplied color, and multiply its alpha by
// the mask texture color. The end result is that we get
// mask*paintAlpha*paintColor + (1-mask*paintAlpha)*dstColor
- int a = SkColorGetA(fSkPaintColor);
+ int a = SkColorGetA(fSkPaint.getColor());
// paintAlpha
drawState->setColor(SkColorSetARGB(a, a, a, a));
// paintColor
- drawState->setBlendConstant(skcolor_to_grcolor_nopremultiply(fSkPaintColor));
+ drawState->setBlendConstant(skcolor_to_grcolor_nopremultiply(fSkPaint.getColor()));
drawState->setBlendFunc(kConstC_GrBlendCoeff, kISC_GrBlendCoeff);
} else {
// set back to normal in case we took LCD path previously.
GrDistanceFieldTextContext::GrDistanceFieldTextContext(GrContext* context,
const GrPaint& grPaint,
const SkPaint& skPaint)
- : GrTextContext(context, grPaint),
- fSkPaint(skPaint) {
+ : GrTextContext(context, grPaint, skPaint) {
fStrike = NULL;
fCurrTexture = NULL;
#include "GrTextContext.h"
-GrTextContext::GrTextContext(GrContext* context, const GrPaint& paint) : fPaint(paint) {
+GrTextContext::GrTextContext(GrContext* context, const GrPaint& paint,
+ const SkPaint& skPaint) : fPaint(paint), fSkPaint(skPaint) {
fContext = context;
const GrClipData* clipData = context->getClip();
fContext = context;
fContext->ref();
+#if SK_DISTANCEFIELD_FONTS
+ fTextContextManager = SkNEW(GrTTextContextManager<GrDistanceFieldTextContext>);
+#else
+ fTextContextManager = SkNEW(GrTTextContextManager<GrBitmapTextContext>);
+#endif
+
fRenderTarget = NULL;
fNeedClear = false;
fContext = context;
fContext->ref();
+#if SK_DISTANCEFIELD_FONTS
+ fTextContextManager = SkNEW(GrTTextContextManager<GrDistanceFieldTextContext>);
+#else
+ fTextContextManager = SkNEW(GrTTextContextManager<GrBitmapTextContext>);
+#endif
+
fRenderTarget = NULL;
fNeedClear = false;
if (fDrawProcs) {
delete fDrawProcs;
}
+
+ delete fTextContextManager;
// The GrContext takes a ref on the target. We don't want to cause the render
// target to be unnecessarily kept alive.
SkDEBUGCODE(this->validate();)
- GrDistanceFieldTextContext context(fContext, grPaint, paint);
+ SkAutoTDelete<GrTextContext> context(fTextContextManager->create(fContext, grPaint, paint));
+ GrDistanceFieldTextContext* dfContext =
+ static_cast<GrDistanceFieldTextContext*>(context.get());
- SkAutoGlyphCache autoCache(context.getSkPaint(), &this->fLeakyProperties, NULL);
+ SkAutoGlyphCache autoCache(dfContext->getSkPaint(), &this->fLeakyProperties, NULL);
SkGlyphCache* cache = autoCache.getCache();
GrFontScaler* fontScaler = get_gr_font_scaler(cache);
- context.drawText((const char *)text, byteLength, x, y, cache, fontScaler);
+ dfContext->drawText((const char *)text, byteLength, x, y, cache, fontScaler);
#endif
} else {
SkDraw myDraw(draw);
return;
}
- GrBitmapTextContext context(fContext, grPaint, paint.getColor());
- myDraw.fProcs = this->initDrawForText(&context);
+ SkAutoTDelete<GrTextContext> context(fTextContextManager->create(fContext, grPaint, paint));
+ myDraw.fProcs = this->initDrawForText(context.get());
this->INHERITED::drawText(myDraw, text, byteLength, x, y, paint);
}
}
SkDEBUGCODE(this->validate();)
- GrDistanceFieldTextContext context(fContext, grPaint, paint);
-
- SkAutoGlyphCache autoCache(context.getSkPaint(), &this->fLeakyProperties, NULL);
+ SkAutoTDelete<GrTextContext> context(fTextContextManager->create(fContext, grPaint, paint));
+ GrDistanceFieldTextContext* dfContext =
+ static_cast<GrDistanceFieldTextContext*>(context.get());
+
+ SkAutoGlyphCache autoCache(dfContext->getSkPaint(), &this->fLeakyProperties, NULL);
SkGlyphCache* cache = autoCache.getCache();
GrFontScaler* fontScaler = get_gr_font_scaler(cache);
-
- context.drawPosText((const char *)text, byteLength, pos, constY, scalarsPerPos,
+
+ dfContext->drawPosText((const char *)text, byteLength, pos, constY, scalarsPerPos,
cache, fontScaler);
#endif
} else {
if (!skPaint2GrPaintShader(this, paint, true, &grPaint)) {
return;
}
- GrBitmapTextContext context(fContext, grPaint, paint.getColor());
- myDraw.fProcs = this->initDrawForText(&context);
+
+ SkAutoTDelete<GrTextContext> context(fTextContextManager->create(fContext, grPaint, paint));
+ myDraw.fProcs = this->initDrawForText(context.get());
this->INHERITED::drawPosText(myDraw, text, byteLength, pos, constY,
scalarsPerPos, paint);
}