Add factory class for generating various flavors of GrTextContext.
This is the first pass of making Gr*TextContext more generic and easily subclassed. The next stage will be making GrBitmapTextContext and GrDistanceFieldTextContext more similar by moving the SkDraw loop into each subclass. BUG=skia:2018 R=bsalomon@google.com, reed@google.com Author: jvanverth@google.com Review URL: https://codereview.chromium.org/144283002 git-svn-id: http://skia.googlecode.com/svn/trunk@13142 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
7873333236
commit
ce96b651d3
@ -17,13 +17,14 @@ class GrTextStrike;
|
||||
*/
|
||||
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;
|
||||
|
||||
@ -36,7 +37,6 @@ private:
|
||||
kDefaultRequestedVerts = kDefaultRequestedGlyphs * 4,
|
||||
};
|
||||
|
||||
SkColor fSkPaintColor;
|
||||
SkPoint* fVertices;
|
||||
int32_t fMaxVertices;
|
||||
GrTexture* fCurrTexture;
|
||||
|
@ -17,9 +17,6 @@ class GrTextStrike;
|
||||
*/
|
||||
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;
|
||||
|
||||
@ -33,6 +30,10 @@ public:
|
||||
const SkPaint& getSkPaint() { return fSkPaint; }
|
||||
|
||||
private:
|
||||
GrDistanceFieldTextContext(GrContext*, const GrPaint&, const SkPaint&);
|
||||
virtual ~GrDistanceFieldTextContext();
|
||||
friend class GrTTextContextManager<GrDistanceFieldTextContext>;
|
||||
|
||||
GrTextStrike* fStrike;
|
||||
SkScalar fTextRatio;
|
||||
|
||||
@ -45,7 +46,6 @@ private:
|
||||
kDefaultRequestedVerts = kDefaultRequestedGlyphs * 4,
|
||||
};
|
||||
|
||||
SkPaint fSkPaint;
|
||||
SkPoint* fVertices;
|
||||
int32_t fMaxVertices;
|
||||
GrTexture* fCurrTexture;
|
||||
|
@ -12,6 +12,8 @@
|
||||
#include "GrGlyph.h"
|
||||
#include "GrPaint.h"
|
||||
|
||||
#include "SkPostConfig.h"
|
||||
|
||||
class GrContext;
|
||||
class GrDrawTarget;
|
||||
class GrFontScaler;
|
||||
@ -21,20 +23,88 @@ 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
|
||||
|
@ -16,10 +16,10 @@
|
||||
#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
|
||||
@ -149,6 +149,8 @@ private:
|
||||
|
||||
GrClipData fClipData;
|
||||
|
||||
GrTextContextManager* fTextContextManager;
|
||||
|
||||
// state for our render-target
|
||||
GrRenderTarget* fRenderTarget;
|
||||
bool fNeedClear;
|
||||
|
@ -24,12 +24,10 @@ SK_CONF_DECLARE(bool, c_DumpFontCache, "gpu.dumpFontCache", false,
|
||||
"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;
|
||||
@ -83,11 +81,11 @@ void GrBitmapTextContext::flushGlyphs() {
|
||||
// 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.
|
||||
|
@ -28,8 +28,7 @@ SK_CONF_DECLARE(bool, c_DumpFontCache, "gpu.dumpFontCache", false,
|
||||
GrDistanceFieldTextContext::GrDistanceFieldTextContext(GrContext* context,
|
||||
const GrPaint& grPaint,
|
||||
const SkPaint& skPaint)
|
||||
: GrTextContext(context, grPaint),
|
||||
fSkPaint(skPaint) {
|
||||
: GrTextContext(context, grPaint, skPaint) {
|
||||
fStrike = NULL;
|
||||
|
||||
fCurrTexture = NULL;
|
||||
|
@ -8,7 +8,8 @@
|
||||
|
||||
#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();
|
||||
|
@ -200,6 +200,12 @@ void SkGpuDevice::initFromRenderTarget(GrContext* context,
|
||||
fContext = context;
|
||||
fContext->ref();
|
||||
|
||||
#if SK_DISTANCEFIELD_FONTS
|
||||
fTextContextManager = SkNEW(GrTTextContextManager<GrDistanceFieldTextContext>);
|
||||
#else
|
||||
fTextContextManager = SkNEW(GrTTextContextManager<GrBitmapTextContext>);
|
||||
#endif
|
||||
|
||||
fRenderTarget = NULL;
|
||||
fNeedClear = false;
|
||||
|
||||
@ -235,6 +241,12 @@ SkGpuDevice::SkGpuDevice(GrContext* context,
|
||||
fContext = context;
|
||||
fContext->ref();
|
||||
|
||||
#if SK_DISTANCEFIELD_FONTS
|
||||
fTextContextManager = SkNEW(GrTTextContextManager<GrDistanceFieldTextContext>);
|
||||
#else
|
||||
fTextContextManager = SkNEW(GrTTextContextManager<GrBitmapTextContext>);
|
||||
#endif
|
||||
|
||||
fRenderTarget = NULL;
|
||||
fNeedClear = false;
|
||||
|
||||
@ -279,6 +291,8 @@ SkGpuDevice::~SkGpuDevice() {
|
||||
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.
|
||||
@ -1820,13 +1834,15 @@ void SkGpuDevice::drawText(const SkDraw& draw, const void* text,
|
||||
|
||||
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);
|
||||
@ -1836,8 +1852,8 @@ void SkGpuDevice::drawText(const SkDraw& draw, const void* text,
|
||||
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);
|
||||
}
|
||||
}
|
||||
@ -1861,13 +1877,15 @@ void SkGpuDevice::drawPosText(const SkDraw& draw, const void* text,
|
||||
|
||||
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 {
|
||||
@ -1877,8 +1895,9 @@ void SkGpuDevice::drawPosText(const SkDraw& draw, const void* text,
|
||||
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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user