Make GrTextContext be owned by the GrDrawContext

This CL makes the GrTextContext be owned (and hidden) by the GrDrawContext. This funnels all the drawText* calls through the GrDrawContext and hides the (dispreferred) GrPipelineBuilder drawText variant.

Some consequences of this are:

GrDrawContext now has to get the text drawing settings (i.e., SkDeviceProperties & useDFT). This means that we need a separate GrDrawContext for each combination of pixel geometry and DFT-use.

All the GrTextContext-derived classes now get a back pointer to the originating GrDrawContext so their method calls no longer take one.

Committed: https://skia.googlesource.com/skia/+/5b16e740fe6ab6d679083d06f07651602265081b

Review URL: https://codereview.chromium.org/1175553002
This commit is contained in:
robertphillips 2015-06-17 05:43:33 -07:00 committed by Commit bot
parent 48fc0ea272
commit 2334fb655f
15 changed files with 293 additions and 201 deletions

View File

@ -43,7 +43,6 @@ class GrTextureParams;
class GrVertexBuffer; class GrVertexBuffer;
class GrStrokeInfo; class GrStrokeInfo;
class GrSoftwarePathRenderer; class GrSoftwarePathRenderer;
class SkGpuDevice;
class SK_API GrContext : public SkRefCnt { class SK_API GrContext : public SkRefCnt {
public: public:
@ -174,11 +173,16 @@ public:
/** /**
* Returns a helper object to orchestrate draws. * Returns a helper object to orchestrate draws.
* Callers should take a ref if they rely on the GrDrawContext sticking around.
* NULL will be returned if the context has been abandoned.
*
* @param devProps the device properties (mainly defines text drawing)
* @param uesDFT should Distance Field Text be used?
* *
* @return a draw context * @return a draw context
*/ */
GrDrawContext* drawContext() { GrDrawContext* drawContext(const SkDeviceProperties* devProps = NULL, bool useDFT = false) {
return fDrawingMgr.drawContext(); return fDrawingMgr.drawContext(devProps, useDFT);
} }
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
@ -390,15 +394,17 @@ private:
GrContext(); // init must be called after the constructor. GrContext(); // init must be called after the constructor.
bool init(GrBackend, GrBackendContext, const GrContextOptions& options); bool init(GrBackend, GrBackendContext, const GrContextOptions& options);
// Currently the DrawingMgr just wraps the single GrDrawTarget in a single // Currently the DrawingMgr stores a separate GrDrawContext for each
// GrDrawContext and hands it out. In the future this class will allocate // combination of text drawing options (pixel geometry x DFT use)
// a new GrDrawContext for each GrRenderTarget/GrDrawTarget and manage // and hands the appropriate one back given the user's request.
// the DAG. // All of the GrDrawContexts still land in the same GrDrawTarget!
//
// In the future this class will allocate a new GrDrawContext for
// each GrRenderTarget/GrDrawTarget and manage the DAG.
class DrawingMgr { class DrawingMgr {
public: public:
DrawingMgr() DrawingMgr() : fDrawTarget(NULL) {
: fDrawTarget(NULL) sk_bzero(fDrawContext, sizeof(fDrawContext));
, fDrawContext(NULL) {
} }
~DrawingMgr(); ~DrawingMgr();
@ -414,14 +420,20 @@ private:
// Callers should take a ref if they rely on the GrDrawContext sticking around. // Callers should take a ref if they rely on the GrDrawContext sticking around.
// NULL will be returned if the context has been abandoned. // NULL will be returned if the context has been abandoned.
GrDrawContext* drawContext(); GrDrawContext* drawContext(const SkDeviceProperties* devProps, bool useDFT);
private: private:
void cleanup();
friend class GrContext; // for access to fDrawTarget for testing friend class GrContext; // for access to fDrawTarget for testing
static const int kNumPixelGeometries = 5; // The different pixel geometries
static const int kNumDFTOptions = 2; // DFT or no DFT
GrContext* fContext;
GrDrawTarget* fDrawTarget; GrDrawTarget* fDrawTarget;
GrDrawContext* fDrawContext; GrDrawContext* fDrawContext[kNumPixelGeometries][kNumDFTOptions];
}; };
DrawingMgr fDrawingMgr; DrawingMgr fDrawingMgr;
@ -429,18 +441,6 @@ private:
void initMockContext(); void initMockContext();
void initCommon(); void initCommon();
/**
* Creates a new text rendering context that is optimal for the
* render target and the context. Caller assumes the ownership
* of the returned object. The returned object must be deleted
* before the context is destroyed.
* TODO bury this behind context!
*/
GrTextContext* createTextContext(GrRenderTarget*,
const SkDeviceProperties&,
bool enableDistanceFieldFonts);
/** /**
* These functions create premul <-> unpremul effects if it is possible to generate a pair * These functions create premul <-> unpremul effects if it is possible to generate a pair
* of effects that make a readToUPM->writeToPM->readToUPM cycle invariant. Otherwise, they * of effects that make a readToUPM->writeToPM->readToUPM cycle invariant. Otherwise, they
@ -461,9 +461,6 @@ private:
*/ */
static void TextBlobCacheOverBudgetCB(void* data); static void TextBlobCacheOverBudgetCB(void* data);
// TODO see note on createTextContext
friend class SkGpuDevice;
typedef SkRefCnt INHERITED; typedef SkRefCnt INHERITED;
}; };

View File

@ -22,14 +22,18 @@ class GrPipelineBuilder;
class GrRenderTarget; class GrRenderTarget;
class GrStrokeInfo; class GrStrokeInfo;
class GrSurface; class GrSurface;
class GrTextContext;
struct SkDeviceProperties;
class SkDrawFilter;
struct SkIPoint; struct SkIPoint;
struct SkIRect; struct SkIRect;
class SkMatrix; class SkMatrix;
class SkPaint;
class SkPath; class SkPath;
struct SkPoint; struct SkPoint;
struct SkRect; struct SkRect;
class SkRRect; class SkRRect;
class SkTextBlob;
/* /*
* A helper object to orchestrate draws * A helper object to orchestrate draws
@ -38,14 +42,28 @@ class SK_API GrDrawContext : public SkRefCnt {
public: public:
SK_DECLARE_INST_COUNT(GrDrawContext) SK_DECLARE_INST_COUNT(GrDrawContext)
~GrDrawContext() override;
void copySurface(GrRenderTarget* dst, GrSurface* src, void copySurface(GrRenderTarget* dst, GrSurface* src,
const SkIRect& srcRect, const SkIPoint& dstPoint); const SkIRect& srcRect, const SkIPoint& dstPoint);
// drawText and drawPaths are thanks to the GrAtlasTextContext and the // TODO: it is odd that we need both the SkPaint in the following 3 methods.
// GrStencilAndCoverTextContext respectively // We should extract the text parameters from SkPaint and pass them separately
// TODO: remove these two // akin to GrStrokeInfo (GrTextInfo?)
void drawText(GrPipelineBuilder* pipelineBuilder, GrBatch* batch); void drawText(GrRenderTarget*, const GrClip&, const GrPaint&, const SkPaint&,
const SkMatrix& viewMatrix, const char text[], size_t byteLength,
SkScalar x, SkScalar y, const SkIRect& clipBounds);
void drawPosText(GrRenderTarget*, const GrClip&, const GrPaint&, const SkPaint&,
const SkMatrix& viewMatrix, const char text[], size_t byteLength,
const SkScalar pos[], int scalarsPerPosition,
const SkPoint& offset, const SkIRect& clipBounds);
void drawTextBlob(GrRenderTarget*, const GrClip&, const SkPaint&,
const SkMatrix& viewMatrix, const SkTextBlob*,
SkScalar x, SkScalar y,
SkDrawFilter*, const SkIRect& clipBounds);
// drawPaths is thanks to GrStencilAndCoverTextContext
// TODO: remove
void drawPaths(GrPipelineBuilder* pipelineBuilder, void drawPaths(GrPipelineBuilder* pipelineBuilder,
const GrPathProcessor* pathProc, const GrPathProcessor* pathProc,
const GrPathRange* pathRange, const GrPathRange* pathRange,
@ -223,16 +241,17 @@ public:
private: private:
friend class GrAtlasTextContext; // for access to drawBatch
friend class GrContext; // for ctor friend class GrContext; // for ctor
GrDrawContext(GrContext* context, GrDrawTarget* drawTarget); GrDrawContext(GrContext*, GrDrawTarget*, const SkDeviceProperties&, bool useDFT);
~GrDrawContext() override;
// Sets the paint. Returns true on success; false on failure. // Sets the paint. Returns true on success; false on failure.
bool prepareToDraw(GrPipelineBuilder*, bool prepareToDraw(GrPipelineBuilder*,
GrRenderTarget* rt, GrRenderTarget* rt,
const GrClip&, const GrClip&,
const GrPaint* paint); const GrPaint* paint);
GrTextContext* createTextContext(GrRenderTarget*, const SkDeviceProperties&, bool useDFT);
// A simpler version of the above which just returns true on success; false on failure. // A simpler version of the above which just returns true on success; false on failure.
// Clip is *NOT* set // Clip is *NOT* set
@ -246,8 +265,16 @@ private:
const SkPath&, const SkPath&,
const GrStrokeInfo&); const GrStrokeInfo&);
GrContext* fContext; // owning context -> no ref // This entry point allows the GrTextContext-derived classes to add their batches to
GrDrawTarget* fDrawTarget; // the drawTarget.
void drawBatch(GrPipelineBuilder* pipelineBuilder, GrBatch* batch);
GrContext* fContext; // owning context -> no ref
GrDrawTarget* fDrawTarget;
GrTextContext* fTextContext; // lazily created
SkDeviceProperties* fDevProps; // ptr b.c. SkDeviceProperties isn't public
bool fUseDFT;
}; };
#endif #endif

View File

@ -19,7 +19,7 @@
#include "SkTextToPathIter.h" #include "SkTextToPathIter.h"
SkBaseDevice::SkBaseDevice() SkBaseDevice::SkBaseDevice()
: fLeakyProperties(SkNEW_ARGS(SkDeviceProperties, (SkDeviceProperties::kLegacyLCD_InitType))) : fLeakyProperties(SkNEW(SkDeviceProperties))
#ifdef SK_DEBUG #ifdef SK_DEBUG
, fAttachedToCanvas(false) , fAttachedToCanvas(false)
#endif #endif

View File

@ -11,11 +11,12 @@
#include "SkSurfacePriv.h" #include "SkSurfacePriv.h"
struct SkDeviceProperties { struct SkDeviceProperties {
enum InitType { SkDeviceProperties(const SkDeviceProperties& src)
kLegacyLCD_InitType : fGamma(src.fGamma)
}; , fPixelGeometry(src.fPixelGeometry) {
}
SkDeviceProperties(InitType, float gamma = SK_GAMMA_EXPONENT) SkDeviceProperties(float gamma = SK_GAMMA_EXPONENT)
: fGamma(gamma) : fGamma(gamma)
, fPixelGeometry(SkSurfacePropsDefaultPixelGeometry()) , fPixelGeometry(SkSurfacePropsDefaultPixelGeometry())
{} {}
@ -25,15 +26,15 @@ struct SkDeviceProperties {
, fPixelGeometry(geo) , fPixelGeometry(geo)
{} {}
SkPixelGeometry pixelGeometry() const { return fPixelGeometry; }
float gamma() const { return fGamma; } float gamma() const { return fGamma; }
SkPixelGeometry pixelGeometry() const { return fPixelGeometry; }
void setPixelGeometry(SkPixelGeometry geo) { void setPixelGeometry(SkPixelGeometry geo) {
fPixelGeometry = geo; fPixelGeometry = geo;
} }
private: private:
const float fGamma; const float fGamma;
SkPixelGeometry fPixelGeometry; SkPixelGeometry fPixelGeometry;
}; };

View File

@ -13,6 +13,7 @@
#include "GrBlurUtils.h" #include "GrBlurUtils.h"
#include "GrDefaultGeoProcFactory.h" #include "GrDefaultGeoProcFactory.h"
#include "GrDrawContext.h" #include "GrDrawContext.h"
#include "GrDrawTarget.h"
#include "GrFontScaler.h" #include "GrFontScaler.h"
#include "GrIndexBuffer.h" #include "GrIndexBuffer.h"
#include "GrResourceProvider.h" #include "GrResourceProvider.h"
@ -97,9 +98,10 @@ static inline GrColor skcolor_to_grcolor_nopremultiply(SkColor c) {
// Distance field text in textblobs // Distance field text in textblobs
GrAtlasTextContext::GrAtlasTextContext(GrContext* context, GrAtlasTextContext::GrAtlasTextContext(GrContext* context,
GrDrawContext* drawContext,
const SkDeviceProperties& properties, const SkDeviceProperties& properties,
bool enableDistanceFields) bool useDFT)
: INHERITED(context, properties) : INHERITED(context, drawContext, properties)
, fDistanceAdjustTable(SkNEW_ARGS(DistanceAdjustTable, (properties.gamma()))) { , fDistanceAdjustTable(SkNEW_ARGS(DistanceAdjustTable, (properties.gamma()))) {
// We overallocate vertices in our textblobs based on the assumption that A8 has the greatest // We overallocate vertices in our textblobs based on the assumption that A8 has the greatest
// vertexStride // vertexStride
@ -111,7 +113,7 @@ GrAtlasTextContext::GrAtlasTextContext(GrContext* context,
#if SK_FORCE_DISTANCE_FIELD_TEXT #if SK_FORCE_DISTANCE_FIELD_TEXT
fEnableDFRendering = true; fEnableDFRendering = true;
#else #else
fEnableDFRendering = enableDistanceFields; fEnableDFRendering = useDFT;
#endif #endif
} }
@ -198,9 +200,10 @@ void GrAtlasTextContext::DistanceAdjustTable::buildDistanceAdjustTable(float gam
} }
GrAtlasTextContext* GrAtlasTextContext::Create(GrContext* context, GrAtlasTextContext* GrAtlasTextContext::Create(GrContext* context,
GrDrawContext* drawContext,
const SkDeviceProperties& props, const SkDeviceProperties& props,
bool enableDistanceFields) { bool useDFT) {
return SkNEW_ARGS(GrAtlasTextContext, (context, props, enableDistanceFields)); return SkNEW_ARGS(GrAtlasTextContext, (context, drawContext, props, useDFT));
} }
bool GrAtlasTextContext::canDraw(const GrRenderTarget*, bool GrAtlasTextContext::canDraw(const GrRenderTarget*,
@ -356,11 +359,6 @@ void GrAtlasTextContext::drawTextBlob(GrRenderTarget* rt,
return; return;
} }
GrDrawContext* drawContext = fContext->drawContext();
if (!drawContext) {
return;
}
SkAutoTUnref<BitmapTextBlob> cacheBlob; SkAutoTUnref<BitmapTextBlob> cacheBlob;
SkMaskFilter::BlurRec blurRec; SkMaskFilter::BlurRec blurRec;
BitmapTextBlob::Key key; BitmapTextBlob::Key key;
@ -435,7 +433,7 @@ void GrAtlasTextContext::drawTextBlob(GrRenderTarget* rt,
} }
cacheBlob->fPaintColor = skPaint.getColor(); cacheBlob->fPaintColor = skPaint.getColor();
this->flush(drawContext, blob, cacheBlob, rt, skPaint, grPaint, drawFilter, this->flush(blob, cacheBlob, rt, skPaint, grPaint, drawFilter,
clip, viewMatrix, clipBounds, x, y, transX, transY); clip, viewMatrix, clipBounds, x, y, transX, transY);
} }
@ -777,36 +775,32 @@ GrAtlasTextContext::createDrawPosTextBlob(GrRenderTarget* rt, const GrClip& clip
return blob; return blob;
} }
void GrAtlasTextContext::onDrawText(GrDrawContext* drawContext, GrRenderTarget* rt, void GrAtlasTextContext::onDrawText(GrRenderTarget* rt,
const GrClip& clip, const GrClip& clip,
const GrPaint& paint, const SkPaint& skPaint, const GrPaint& paint, const SkPaint& skPaint,
const SkMatrix& viewMatrix, const SkMatrix& viewMatrix,
const char text[], size_t byteLength, const char text[], size_t byteLength,
SkScalar x, SkScalar y, const SkIRect& regionClipBounds) { SkScalar x, SkScalar y, const SkIRect& regionClipBounds) {
if (drawContext) { SkAutoTUnref<BitmapTextBlob> blob(
SkAutoTUnref<BitmapTextBlob> blob( this->createDrawTextBlob(rt, clip, paint, skPaint, viewMatrix,
this->createDrawTextBlob(rt, clip, paint, skPaint, viewMatrix, text, byteLength, x, y, regionClipBounds));
text, byteLength, x, y, regionClipBounds)); this->flush(blob, rt, skPaint, paint, clip, regionClipBounds);
this->flush(drawContext, blob, rt, skPaint, paint, clip, regionClipBounds);
}
} }
void GrAtlasTextContext::onDrawPosText(GrDrawContext* drawContext, GrRenderTarget* rt, void GrAtlasTextContext::onDrawPosText(GrRenderTarget* rt,
const GrClip& clip, const GrClip& clip,
const GrPaint& paint, const SkPaint& skPaint, const GrPaint& paint, const SkPaint& skPaint,
const SkMatrix& viewMatrix, const SkMatrix& viewMatrix,
const char text[], size_t byteLength, const char text[], size_t byteLength,
const SkScalar pos[], int scalarsPerPosition, const SkScalar pos[], int scalarsPerPosition,
const SkPoint& offset, const SkIRect& regionClipBounds) { const SkPoint& offset, const SkIRect& regionClipBounds) {
if (drawContext) { SkAutoTUnref<BitmapTextBlob> blob(
SkAutoTUnref<BitmapTextBlob> blob( this->createDrawPosTextBlob(rt, clip, paint, skPaint, viewMatrix,
this->createDrawPosTextBlob(rt, clip, paint, skPaint, viewMatrix, text, byteLength,
text, byteLength, pos, scalarsPerPosition,
pos, scalarsPerPosition, offset, regionClipBounds));
offset, regionClipBounds));
this->flush(drawContext, blob, rt, skPaint, paint, clip, regionClipBounds); this->flush(blob, rt, skPaint, paint, clip, regionClipBounds);
}
} }
void GrAtlasTextContext::internalDrawBMPText(BitmapTextBlob* blob, int runIndex, void GrAtlasTextContext::internalDrawBMPText(BitmapTextBlob* blob, int runIndex,
@ -2045,8 +2039,7 @@ private:
float fGamma; float fGamma;
}; };
void GrAtlasTextContext::flushRunAsPaths(GrDrawContext* drawContext, void GrAtlasTextContext::flushRunAsPaths(GrRenderTarget* rt, const SkTextBlob::RunIterator& it,
GrRenderTarget* rt, const SkTextBlob::RunIterator& it,
const GrClip& clip, const SkPaint& skPaint, const GrClip& clip, const SkPaint& skPaint,
SkDrawFilter* drawFilter, const SkMatrix& viewMatrix, SkDrawFilter* drawFilter, const SkMatrix& viewMatrix,
const SkIRect& clipBounds, SkScalar x, SkScalar y) { const SkIRect& clipBounds, SkScalar x, SkScalar y) {
@ -2065,18 +2058,18 @@ void GrAtlasTextContext::flushRunAsPaths(GrDrawContext* drawContext,
switch (it.positioning()) { switch (it.positioning()) {
case SkTextBlob::kDefault_Positioning: case SkTextBlob::kDefault_Positioning:
this->drawTextAsPath(drawContext, rt, clip, runPaint, viewMatrix, this->drawTextAsPath(rt, clip, runPaint, viewMatrix,
(const char *)it.glyphs(), (const char *)it.glyphs(),
textLen, x + offset.x(), y + offset.y(), clipBounds); textLen, x + offset.x(), y + offset.y(), clipBounds);
break; break;
case SkTextBlob::kHorizontal_Positioning: case SkTextBlob::kHorizontal_Positioning:
this->drawPosTextAsPath(drawContext, rt, clip, runPaint, viewMatrix, this->drawPosTextAsPath(rt, clip, runPaint, viewMatrix,
(const char*)it.glyphs(), (const char*)it.glyphs(),
textLen, it.pos(), 1, SkPoint::Make(x, y + offset.y()), textLen, it.pos(), 1, SkPoint::Make(x, y + offset.y()),
clipBounds); clipBounds);
break; break;
case SkTextBlob::kFull_Positioning: case SkTextBlob::kFull_Positioning:
this->drawPosTextAsPath(drawContext, rt, clip, runPaint, viewMatrix, this->drawPosTextAsPath(rt, clip, runPaint, viewMatrix,
(const char*)it.glyphs(), (const char*)it.glyphs(),
textLen, it.pos(), 2, SkPoint::Make(x, y), clipBounds); textLen, it.pos(), 2, SkPoint::Make(x, y), clipBounds);
break; break;
@ -2128,8 +2121,7 @@ GrAtlasTextContext::createBatch(BitmapTextBlob* cacheBlob, const PerSubRunInfo&
return batch; return batch;
} }
inline void GrAtlasTextContext::flushRun(GrDrawContext* drawContext, inline void GrAtlasTextContext::flushRun(GrPipelineBuilder* pipelineBuilder,
GrPipelineBuilder* pipelineBuilder,
BitmapTextBlob* cacheBlob, int run, GrColor color, BitmapTextBlob* cacheBlob, int run, GrColor color,
SkScalar transX, SkScalar transY, SkScalar transX, SkScalar transY,
const SkPaint& skPaint) { const SkPaint& skPaint) {
@ -2143,12 +2135,11 @@ inline void GrAtlasTextContext::flushRun(GrDrawContext* drawContext,
SkAutoTUnref<BitmapTextBatch> batch(this->createBatch(cacheBlob, info, glyphCount, run, SkAutoTUnref<BitmapTextBatch> batch(this->createBatch(cacheBlob, info, glyphCount, run,
subRun, color, transX, transY, subRun, color, transX, transY,
skPaint)); skPaint));
drawContext->drawText(pipelineBuilder, batch); fDrawContext->drawBatch(pipelineBuilder, batch);
} }
} }
inline void GrAtlasTextContext::flushBigGlyphs(BitmapTextBlob* cacheBlob, inline void GrAtlasTextContext::flushBigGlyphs(BitmapTextBlob* cacheBlob, GrRenderTarget* rt,
GrDrawContext* drawContext, GrRenderTarget* rt,
const GrClip& clip, const SkPaint& skPaint, const GrClip& clip, const SkPaint& skPaint,
SkScalar transX, SkScalar transY, SkScalar transX, SkScalar transY,
const SkIRect& clipBounds) { const SkIRect& clipBounds) {
@ -2169,13 +2160,12 @@ inline void GrAtlasTextContext::flushBigGlyphs(BitmapTextBlob* cacheBlob,
SkMatrix translate = cacheBlob->fViewMatrix; SkMatrix translate = cacheBlob->fViewMatrix;
translate.postTranslate(bigGlyph.fVx, bigGlyph.fVy); translate.postTranslate(bigGlyph.fVx, bigGlyph.fVy);
GrBlurUtils::drawPathWithMaskFilter(fContext, drawContext, rt, clip, bigGlyph.fPath, GrBlurUtils::drawPathWithMaskFilter(fContext, fDrawContext, rt, clip, bigGlyph.fPath,
skPaint, translate, &pathMatrix, clipBounds, false); skPaint, translate, &pathMatrix, clipBounds, false);
} }
} }
void GrAtlasTextContext::flush(GrDrawContext* drawContext, void GrAtlasTextContext::flush(const SkTextBlob* blob,
const SkTextBlob* blob,
BitmapTextBlob* cacheBlob, BitmapTextBlob* cacheBlob,
GrRenderTarget* rt, GrRenderTarget* rt,
const SkPaint& skPaint, const SkPaint& skPaint,
@ -2196,21 +2186,20 @@ void GrAtlasTextContext::flush(GrDrawContext* drawContext,
SkTextBlob::RunIterator it(blob); SkTextBlob::RunIterator it(blob);
for (int run = 0; !it.done(); it.next(), run++) { for (int run = 0; !it.done(); it.next(), run++) {
if (cacheBlob->fRuns[run].fDrawAsPaths) { if (cacheBlob->fRuns[run].fDrawAsPaths) {
this->flushRunAsPaths(drawContext, rt, it, clip, skPaint, this->flushRunAsPaths(rt, it, clip, skPaint,
drawFilter, viewMatrix, clipBounds, x, y); drawFilter, viewMatrix, clipBounds, x, y);
continue; continue;
} }
cacheBlob->fRuns[run].fVertexBounds.offset(transX, transY); cacheBlob->fRuns[run].fVertexBounds.offset(transX, transY);
this->flushRun(drawContext, &pipelineBuilder, cacheBlob, run, color, this->flushRun(&pipelineBuilder, cacheBlob, run, color,
transX, transY, skPaint); transX, transY, skPaint);
} }
// Now flush big glyphs // Now flush big glyphs
this->flushBigGlyphs(cacheBlob, drawContext, rt, clip, skPaint, transX, transY, clipBounds); this->flushBigGlyphs(cacheBlob, rt, clip, skPaint, transX, transY, clipBounds);
} }
void GrAtlasTextContext::flush(GrDrawContext* drawContext, void GrAtlasTextContext::flush(BitmapTextBlob* cacheBlob,
BitmapTextBlob* cacheBlob,
GrRenderTarget* rt, GrRenderTarget* rt,
const SkPaint& skPaint, const SkPaint& skPaint,
const GrPaint& grPaint, const GrPaint& grPaint,
@ -2221,11 +2210,11 @@ void GrAtlasTextContext::flush(GrDrawContext* drawContext,
GrColor color = grPaint.getColor(); GrColor color = grPaint.getColor();
for (int run = 0; run < cacheBlob->fRunCount; run++) { for (int run = 0; run < cacheBlob->fRunCount; run++) {
this->flushRun(drawContext, &pipelineBuilder, cacheBlob, run, color, 0, 0, skPaint); this->flushRun(&pipelineBuilder, cacheBlob, run, color, 0, 0, skPaint);
} }
// Now flush big glyphs // Now flush big glyphs
this->flushBigGlyphs(cacheBlob, drawContext, rt, clip, skPaint, 0, 0, clipBounds); this->flushBigGlyphs(cacheBlob, rt, clip, skPaint, 0, 0, clipBounds);
} }
/////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////
@ -2235,15 +2224,19 @@ void GrAtlasTextContext::flush(GrDrawContext* drawContext,
BATCH_TEST_DEFINE(TextBlobBatch) { BATCH_TEST_DEFINE(TextBlobBatch) {
static uint32_t gContextID = SK_InvalidGenID; static uint32_t gContextID = SK_InvalidGenID;
static GrAtlasTextContext* gTextContext = NULL; static GrAtlasTextContext* gTextContext = NULL;
static SkDeviceProperties gDeviceProperties(SkDeviceProperties::kLegacyLCD_InitType); static SkDeviceProperties gDevProperties;
if (context->uniqueID() != gContextID) { if (context->uniqueID() != gContextID) {
gContextID = context->uniqueID(); gContextID = context->uniqueID();
SkDELETE(gTextContext); SkDELETE(gTextContext);
static const bool kUseDFT = false;
// We don't yet test the fall back to paths in the GrTextContext base class. This is mostly // We don't yet test the fall back to paths in the GrTextContext base class. This is mostly
// because we don't really want to have a gpu device here. // because we don't really want to have a gpu device here.
// We enable distance fields by twiddling a knob on the paint // We enable distance fields by twiddling a knob on the paint
gTextContext = GrAtlasTextContext::Create(context, gDeviceProperties, false); GrDrawContext* drawContext = context->drawContext(&gDevProperties, kUseDFT);
gTextContext = GrAtlasTextContext::Create(context, drawContext, gDevProperties, kUseDFT);
} }
// create dummy render target // create dummy render target

View File

@ -25,6 +25,7 @@
class BitmapTextBatch; class BitmapTextBatch;
class GrDrawContext; class GrDrawContext;
class GrDrawTarget;
class GrPipelineBuilder; class GrPipelineBuilder;
class GrTextBlobCache; class GrTextBlobCache;
@ -34,20 +35,20 @@ class GrTextBlobCache;
*/ */
class GrAtlasTextContext : public GrTextContext { class GrAtlasTextContext : public GrTextContext {
public: public:
static GrAtlasTextContext* Create(GrContext*, const SkDeviceProperties&, static GrAtlasTextContext* Create(GrContext*, GrDrawContext*,
bool enableDistanceFields); const SkDeviceProperties&, bool enableDistanceFields);
private: private:
GrAtlasTextContext(GrContext*, const SkDeviceProperties&, bool enableDistanceFields); GrAtlasTextContext(GrContext*, GrDrawContext*, const SkDeviceProperties&, bool useDFT);
~GrAtlasTextContext() override {} ~GrAtlasTextContext() override {}
bool canDraw(const GrRenderTarget*, const GrClip&, const GrPaint&, bool canDraw(const GrRenderTarget*, const GrClip&, const GrPaint&,
const SkPaint&, const SkMatrix& viewMatrix) override; const SkPaint&, const SkMatrix& viewMatrix) override;
void onDrawText(GrDrawContext*, GrRenderTarget*, const GrClip&, const GrPaint&, const SkPaint&, void onDrawText(GrRenderTarget*, const GrClip&, const GrPaint&, const SkPaint&,
const SkMatrix& viewMatrix, const char text[], size_t byteLength, const SkMatrix& viewMatrix, const char text[], size_t byteLength,
SkScalar x, SkScalar y, const SkIRect& regionClipBounds) override; SkScalar x, SkScalar y, const SkIRect& regionClipBounds) override;
void onDrawPosText(GrDrawContext*, GrRenderTarget*, const GrClip&, const GrPaint&, void onDrawPosText(GrRenderTarget*, const GrClip&, const GrPaint&,
const SkPaint&, const SkMatrix& viewMatrix, const SkPaint&, const SkMatrix& viewMatrix,
const char text[], size_t byteLength, const char text[], size_t byteLength,
const SkScalar pos[], int scalarsPerPosition, const SkScalar pos[], int scalarsPerPosition,
@ -271,7 +272,7 @@ private:
size_t vertexStride, bool useVertexColor, size_t vertexStride, bool useVertexColor,
GrGlyph*); GrGlyph*);
inline void flushRunAsPaths(GrDrawContext*, GrRenderTarget*, inline void flushRunAsPaths(GrRenderTarget*,
const SkTextBlob::RunIterator&, const GrClip& clip, const SkTextBlob::RunIterator&, const GrClip& clip,
const SkPaint&, SkDrawFilter*, const SkPaint&, SkDrawFilter*,
const SkMatrix& viewMatrix, const SkIRect& clipBounds, SkScalar x, const SkMatrix& viewMatrix, const SkIRect& clipBounds, SkScalar x,
@ -280,18 +281,18 @@ private:
int glyphCount, int run, int subRun, int glyphCount, int run, int subRun,
GrColor, SkScalar transX, SkScalar transY, GrColor, SkScalar transX, SkScalar transY,
const SkPaint&); const SkPaint&);
inline void flushRun(GrDrawContext*, GrPipelineBuilder*, BitmapTextBlob*, int run, GrColor, inline void flushRun(GrPipelineBuilder*, BitmapTextBlob*, int run, GrColor,
SkScalar transX, SkScalar transY, const SkPaint&); SkScalar transX, SkScalar transY, const SkPaint&);
inline void flushBigGlyphs(BitmapTextBlob* cacheBlob, GrDrawContext*, GrRenderTarget*, inline void flushBigGlyphs(BitmapTextBlob* cacheBlob, GrRenderTarget*,
const GrClip& clip, const SkPaint& skPaint, const GrClip& clip, const SkPaint& skPaint,
SkScalar transX, SkScalar transY, const SkIRect& clipBounds); SkScalar transX, SkScalar transY, const SkIRect& clipBounds);
// We have to flush SkTextBlobs differently from drawText / drawPosText // We have to flush SkTextBlobs differently from drawText / drawPosText
void flush(GrDrawContext*, const SkTextBlob*, BitmapTextBlob*, GrRenderTarget*, void flush(const SkTextBlob*, BitmapTextBlob*, GrRenderTarget*,
const SkPaint&, const GrPaint&, SkDrawFilter*, const GrClip&, const SkPaint&, const GrPaint&, SkDrawFilter*, const GrClip&,
const SkMatrix& viewMatrix, const SkIRect& clipBounds, SkScalar x, SkScalar y, const SkMatrix& viewMatrix, const SkIRect& clipBounds, SkScalar x, SkScalar y,
SkScalar transX, SkScalar transY); SkScalar transX, SkScalar transY);
void flush(GrDrawContext*, BitmapTextBlob*, GrRenderTarget*, const SkPaint&, void flush(BitmapTextBlob*, GrRenderTarget*, const SkPaint&,
const GrPaint&, const GrClip&, const SkIRect& clipBounds); const GrPaint&, const GrClip&, const SkIRect& clipBounds);
// A helper for drawing BitmapText in a run of distance fields // A helper for drawing BitmapText in a run of distance fields

View File

@ -9,7 +9,6 @@
#include "GrContext.h" #include "GrContext.h"
#include "GrAARectRenderer.h" #include "GrAARectRenderer.h"
#include "GrAtlasTextContext.h"
#include "GrBatch.h" #include "GrBatch.h"
#include "GrBatchFontCache.h" #include "GrBatchFontCache.h"
#include "GrBatchTarget.h" #include "GrBatchTarget.h"
@ -32,7 +31,6 @@
#include "GrResourceCache.h" #include "GrResourceCache.h"
#include "GrResourceProvider.h" #include "GrResourceProvider.h"
#include "GrSoftwarePathRenderer.h" #include "GrSoftwarePathRenderer.h"
#include "GrStencilAndCoverTextContext.h"
#include "GrStrokeInfo.h" #include "GrStrokeInfo.h"
#include "GrSurfacePriv.h" #include "GrSurfacePriv.h"
#include "GrTextBlobCache.h" #include "GrTextBlobCache.h"
@ -62,24 +60,37 @@
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void GrContext::DrawingMgr::init(GrContext* context) { void GrContext::DrawingMgr::init(GrContext* context) {
fContext = context;
#ifdef IMMEDIATE_MODE #ifdef IMMEDIATE_MODE
fDrawTarget = SkNEW_ARGS(GrImmediateDrawTarget, (context)); fDrawTarget = SkNEW_ARGS(GrImmediateDrawTarget, (context));
#else #else
fDrawTarget = SkNEW_ARGS(GrInOrderDrawBuffer, (context)); fDrawTarget = SkNEW_ARGS(GrInOrderDrawBuffer, (context));
#endif #endif
}
fDrawContext = SkNEW_ARGS(GrDrawContext, (context, fDrawTarget)); void GrContext::DrawingMgr::cleanup() {
SkSafeSetNull(fDrawTarget);
for (int i = 0; i < kNumPixelGeometries; ++i) {
SkSafeSetNull(fDrawContext[i][0]);
SkSafeSetNull(fDrawContext[i][1]);
}
} }
GrContext::DrawingMgr::~DrawingMgr() { GrContext::DrawingMgr::~DrawingMgr() {
SkSafeUnref(fDrawTarget); this->cleanup();
SkSafeUnref(fDrawContext);
} }
void GrContext::DrawingMgr::abandon() { void GrContext::DrawingMgr::abandon() {
SkSafeSetNull(fDrawTarget); SkSafeSetNull(fDrawTarget);
SkSafeSetNull(fDrawContext->fDrawTarget); for (int i = 0; i < kNumPixelGeometries; ++i) {
SkSafeSetNull(fDrawContext); for (int j = 0; j < kNumDFTOptions; ++j) {
if (fDrawContext[i][j]) {
SkSafeSetNull(fDrawContext[i][j]->fDrawTarget);
SkSafeSetNull(fDrawContext[i][j]);
}
}
}
} }
void GrContext::DrawingMgr::purgeResources() { void GrContext::DrawingMgr::purgeResources() {
@ -100,11 +111,29 @@ void GrContext::DrawingMgr::flush() {
} }
} }
GrDrawContext* GrContext::DrawingMgr::drawContext() { GrDrawContext* GrContext::DrawingMgr::drawContext(const SkDeviceProperties* devProps, bool useDFT) {
if (this->abandoned()) { if (this->abandoned()) {
return NULL; return NULL;
} }
return fDrawContext;
const SkDeviceProperties defProps;
if (!devProps) {
devProps = &defProps;
}
SkASSERT(devProps->pixelGeometry() < kNumPixelGeometries);
if (!fDrawContext[devProps->pixelGeometry()][useDFT]) {
fDrawContext[devProps->pixelGeometry()][useDFT] =
SkNEW_ARGS(GrDrawContext, (fContext, fDrawTarget, *devProps, useDFT));
}
SkASSERT(fDrawContext[devProps->pixelGeometry()][useDFT]->fDevProps->pixelGeometry() ==
devProps->pixelGeometry());
SkASSERT(fDrawContext[devProps->pixelGeometry()][useDFT]->fDevProps->gamma() ==
devProps->gamma());
SkASSERT(fDrawContext[devProps->pixelGeometry()][useDFT]->fUseDFT == useDFT);
return fDrawContext[devProps->pixelGeometry()][useDFT];
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -185,6 +214,8 @@ GrContext::~GrContext() {
this->flush(); this->flush();
fDrawingMgr.cleanup();
for (int i = 0; i < fCleanUpData.count(); ++i) { for (int i = 0; i < fCleanUpData.count(); ++i) {
(*fCleanUpData[i].fFunc)(this, fCleanUpData[i].fInfo); (*fCleanUpData[i].fFunc)(this, fCleanUpData[i].fInfo);
} }
@ -246,21 +277,6 @@ void GrContext::getResourceCacheUsage(int* resourceCount, size_t* resourceBytes)
} }
} }
GrTextContext* GrContext::createTextContext(GrRenderTarget* renderTarget,
const SkDeviceProperties&
leakyProperties,
bool enableDistanceFieldFonts) {
if (fGpu->caps()->shaderCaps()->pathRenderingSupport() &&
renderTarget->isStencilBufferMultisampled()) {
GrStencilAttachment* sb = renderTarget->renderTargetPriv().attachStencilAttachment();
if (sb) {
return GrStencilAndCoverTextContext::Create(this, leakyProperties);
}
}
return GrAtlasTextContext::Create(this, leakyProperties, enableDistanceFieldFonts);
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void GrContext::OverBudgetCB(void* data) { void GrContext::OverBudgetCB(void* data) {

View File

@ -7,12 +7,16 @@
*/ */
#include "GrAARectRenderer.h" #include "GrAARectRenderer.h"
#include "GrAtlasTextContext.h"
#include "GrBatch.h" #include "GrBatch.h"
#include "GrBatchTest.h" #include "GrBatchTest.h"
#include "GrDefaultGeoProcFactory.h" #include "GrDefaultGeoProcFactory.h"
#include "GrDrawContext.h" #include "GrDrawContext.h"
#include "GrOvalRenderer.h" #include "GrOvalRenderer.h"
#include "GrPathRenderer.h" #include "GrPathRenderer.h"
#include "GrRenderTarget.h"
#include "GrRenderTargetPriv.h"
#include "GrStencilAndCoverTextContext.h"
#define ASSERT_OWNED_RESOURCE(R) SkASSERT(!(R) || (R)->getContext() == fContext) #define ASSERT_OWNED_RESOURCE(R) SkASSERT(!(R) || (R)->getContext() == fContext)
#define RETURN_IF_ABANDONED if (!fDrawTarget) { return; } #define RETURN_IF_ABANDONED if (!fDrawTarget) { return; }
@ -28,13 +32,21 @@ private:
GrContext* fContext; GrContext* fContext;
}; };
GrDrawContext::GrDrawContext(GrContext* context, GrDrawTarget* drawTarget) GrDrawContext::GrDrawContext(GrContext* context,
GrDrawTarget* drawTarget,
const SkDeviceProperties& devProps,
bool useDFT)
: fContext(context) : fContext(context)
, fDrawTarget(SkRef(drawTarget)) { , fDrawTarget(SkRef(drawTarget))
, fTextContext(NULL)
, fDevProps(SkNEW_ARGS(SkDeviceProperties, (devProps)))
, fUseDFT(useDFT) {
} }
GrDrawContext::~GrDrawContext() { GrDrawContext::~GrDrawContext() {
SkSafeUnref(fDrawTarget); SkSafeUnref(fDrawTarget);
SkDELETE(fTextContext);
SkDELETE(fDevProps);
} }
void GrDrawContext::copySurface(GrRenderTarget* dst, GrSurface* src, void GrDrawContext::copySurface(GrRenderTarget* dst, GrSurface* src,
@ -46,8 +58,58 @@ void GrDrawContext::copySurface(GrRenderTarget* dst, GrSurface* src,
fDrawTarget->copySurface(dst, src, srcRect, dstPoint); fDrawTarget->copySurface(dst, src, srcRect, dstPoint);
} }
void GrDrawContext::drawText(GrPipelineBuilder* pipelineBuilder, GrBatch* batch) { GrTextContext* GrDrawContext::createTextContext(GrRenderTarget* renderTarget,
fDrawTarget->drawBatch(pipelineBuilder, batch); const SkDeviceProperties& leakyProperties,
bool enableDistanceFieldFonts) {
if (fContext->caps()->shaderCaps()->pathRenderingSupport() &&
renderTarget->isStencilBufferMultisampled()) {
GrStencilAttachment* sb = renderTarget->renderTargetPriv().attachStencilAttachment();
if (sb) {
return GrStencilAndCoverTextContext::Create(fContext, this,
leakyProperties,
enableDistanceFieldFonts);
}
}
return GrAtlasTextContext::Create(fContext, this, leakyProperties, enableDistanceFieldFonts);
}
void GrDrawContext::drawText(GrRenderTarget* rt, const GrClip& clip, const GrPaint& grPaint,
const SkPaint& skPaint,
const SkMatrix& viewMatrix,
const char text[], size_t byteLength,
SkScalar x, SkScalar y, const SkIRect& clipBounds) {
if (!fTextContext) {
fTextContext = this->createTextContext(rt, *fDevProps, fUseDFT);
}
fTextContext->drawText(rt, clip, grPaint, skPaint, viewMatrix,
text, byteLength, x, y, clipBounds);
}
void GrDrawContext::drawPosText(GrRenderTarget* rt, const GrClip& clip, const GrPaint& grPaint,
const SkPaint& skPaint,
const SkMatrix& viewMatrix,
const char text[], size_t byteLength,
const SkScalar pos[], int scalarsPerPosition,
const SkPoint& offset, const SkIRect& clipBounds) {
if (!fTextContext) {
fTextContext = this->createTextContext(rt, *fDevProps, fUseDFT);
}
fTextContext->drawPosText(rt, clip, grPaint, skPaint, viewMatrix, text, byteLength,
pos, scalarsPerPosition, offset, clipBounds);
}
void GrDrawContext::drawTextBlob(GrRenderTarget* rt, const GrClip& clip, const SkPaint& skPaint,
const SkMatrix& viewMatrix, const SkTextBlob* blob,
SkScalar x, SkScalar y,
SkDrawFilter* filter, const SkIRect& clipBounds) {
if (!fTextContext) {
fTextContext = this->createTextContext(rt, *fDevProps, fUseDFT);
}
fTextContext->drawTextBlob(rt, clip, skPaint, viewMatrix, blob, x, y, filter, clipBounds);
} }
void GrDrawContext::drawPaths(GrPipelineBuilder* pipelineBuilder, void GrDrawContext::drawPaths(GrPipelineBuilder* pipelineBuilder,
@ -1147,6 +1209,10 @@ bool GrDrawContext::prepareToDraw(GrRenderTarget* rt) {
return true; return true;
} }
void GrDrawContext::drawBatch(GrPipelineBuilder* pipelineBuilder, GrBatch* batch) {
fDrawTarget->drawBatch(pipelineBuilder, batch);
}
/////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////
#ifdef GR_TEST_UTILS #ifdef GR_TEST_UTILS

View File

@ -22,18 +22,21 @@
#include "SkTextFormatParams.h" #include "SkTextFormatParams.h"
GrStencilAndCoverTextContext::GrStencilAndCoverTextContext(GrContext* context, GrStencilAndCoverTextContext::GrStencilAndCoverTextContext(GrContext* context,
GrDrawContext* drawContext,
const SkDeviceProperties& properties) const SkDeviceProperties& properties)
: GrTextContext(context, properties) : GrTextContext(context, drawContext, properties)
, fStroke(SkStrokeRec::kFill_InitStyle) , fStroke(SkStrokeRec::kFill_InitStyle)
, fQueuedGlyphCount(0) , fQueuedGlyphCount(0)
, fFallbackGlyphsIdx(kGlyphBufferSize) { , fFallbackGlyphsIdx(kGlyphBufferSize) {
} }
GrStencilAndCoverTextContext* GrStencilAndCoverTextContext*
GrStencilAndCoverTextContext::Create(GrContext* context, const SkDeviceProperties& props) { GrStencilAndCoverTextContext::Create(GrContext* context, GrDrawContext* drawContext,
const SkDeviceProperties& props, bool fallbackUsesDFT) {
GrStencilAndCoverTextContext* textContext = SkNEW_ARGS(GrStencilAndCoverTextContext, GrStencilAndCoverTextContext* textContext = SkNEW_ARGS(GrStencilAndCoverTextContext,
(context, props)); (context, drawContext, props));
textContext->fFallbackTextContext = GrAtlasTextContext::Create(context, props, false); textContext->fFallbackTextContext = GrAtlasTextContext::Create(context, drawContext,
props, fallbackUsesDFT);
return textContext; return textContext;
} }
@ -71,7 +74,7 @@ bool GrStencilAndCoverTextContext::canDraw(const GrRenderTarget* rt,
return rec.getFormat() != SkMask::kARGB32_Format; return rec.getFormat() != SkMask::kARGB32_Format;
} }
void GrStencilAndCoverTextContext::onDrawText(GrDrawContext* drawContext, GrRenderTarget* rt, void GrStencilAndCoverTextContext::onDrawText(GrRenderTarget* rt,
const GrClip& clip, const GrClip& clip,
const GrPaint& paint, const GrPaint& paint,
const SkPaint& skPaint, const SkPaint& skPaint,
@ -154,19 +157,17 @@ void GrStencilAndCoverTextContext::onDrawText(GrDrawContext* drawContext, GrRend
const SkGlyph& glyph = glyphCacheProc(fGlyphCache, &text, 0, 0); const SkGlyph& glyph = glyphCacheProc(fGlyphCache, &text, 0, 0);
fx += SkFixedMul(autokern.adjust(glyph), fixedSizeRatio); fx += SkFixedMul(autokern.adjust(glyph), fixedSizeRatio);
if (glyph.fWidth) { if (glyph.fWidth) {
this->appendGlyph(drawContext, glyph, this->appendGlyph(glyph, SkPoint::Make(SkFixedToScalar(fx), SkFixedToScalar(fy)));
SkPoint::Make(SkFixedToScalar(fx), SkFixedToScalar(fy)));
} }
fx += SkFixedMul(glyph.fAdvanceX, fixedSizeRatio); fx += SkFixedMul(glyph.fAdvanceX, fixedSizeRatio);
fy += SkFixedMul(glyph.fAdvanceY, fixedSizeRatio); fy += SkFixedMul(glyph.fAdvanceY, fixedSizeRatio);
} }
this->finish(drawContext); this->finish();
} }
void GrStencilAndCoverTextContext::onDrawPosText(GrDrawContext* drawContext, void GrStencilAndCoverTextContext::onDrawPosText(GrRenderTarget* rt,
GrRenderTarget* rt,
const GrClip& clip, const GrClip& clip,
const GrPaint& paint, const GrPaint& paint,
const SkPaint& skPaint, const SkPaint& skPaint,
@ -210,12 +211,12 @@ void GrStencilAndCoverTextContext::onDrawPosText(GrDrawContext* drawContext,
SkPoint loc; SkPoint loc;
alignProc(tmsLoc, glyph, &loc); alignProc(tmsLoc, glyph, &loc);
this->appendGlyph(drawContext, glyph, loc); this->appendGlyph(glyph, loc);
} }
pos += scalarsPerPosition; pos += scalarsPerPosition;
} }
this->finish(drawContext); this->finish();
} }
static GrPathRange* get_gr_glyphs(GrContext* ctx, static GrPathRange* get_gr_glyphs(GrContext* ctx,
@ -410,11 +411,10 @@ bool GrStencilAndCoverTextContext::mapToFallbackContext(SkMatrix* inverse) {
return true; return true;
} }
inline void GrStencilAndCoverTextContext::appendGlyph(GrDrawContext* drawContext, inline void GrStencilAndCoverTextContext::appendGlyph(const SkGlyph& glyph, const SkPoint& pos) {
const SkGlyph& glyph, const SkPoint& pos) {
if (fQueuedGlyphCount >= fFallbackGlyphsIdx) { if (fQueuedGlyphCount >= fFallbackGlyphsIdx) {
SkASSERT(fQueuedGlyphCount == fFallbackGlyphsIdx); SkASSERT(fQueuedGlyphCount == fFallbackGlyphsIdx);
this->flush(drawContext); this->flush();
} }
// Stick the glyphs we can't draw at the end of the buffer, growing backwards. // Stick the glyphs we can't draw at the end of the buffer, growing backwards.
@ -432,17 +432,17 @@ static const SkScalar* get_xy_scalar_array(const SkPoint* pointArray) {
return &pointArray[0].fX; return &pointArray[0].fX;
} }
void GrStencilAndCoverTextContext::flush(GrDrawContext* drawContext) { void GrStencilAndCoverTextContext::flush() {
if (fQueuedGlyphCount > 0) { if (fQueuedGlyphCount > 0) {
SkAutoTUnref<GrPathProcessor> pp(GrPathProcessor::Create(fPaint.getColor(), SkAutoTUnref<GrPathProcessor> pp(GrPathProcessor::Create(fPaint.getColor(),
fViewMatrix, fViewMatrix,
fLocalMatrix)); fLocalMatrix));
drawContext->drawPaths(&fPipelineBuilder, pp, fGlyphs, fDrawContext->drawPaths(&fPipelineBuilder, pp, fGlyphs,
fGlyphIndices, GrPathRange::kU16_PathIndexType, fGlyphIndices, GrPathRange::kU16_PathIndexType,
get_xy_scalar_array(fGlyphPositions), get_xy_scalar_array(fGlyphPositions),
GrPathRendering::kTranslate_PathTransformType, GrPathRendering::kTranslate_PathTransformType,
fQueuedGlyphCount, GrPathRendering::kWinding_FillType); fQueuedGlyphCount, GrPathRendering::kWinding_FillType);
fQueuedGlyphCount = 0; fQueuedGlyphCount = 0;
} }
@ -474,8 +474,8 @@ void GrStencilAndCoverTextContext::flush(GrDrawContext* drawContext) {
} }
} }
void GrStencilAndCoverTextContext::finish(GrDrawContext* drawContext) { void GrStencilAndCoverTextContext::finish() {
this->flush(drawContext); this->flush();
fGlyphs->unref(); fGlyphs->unref();
fGlyphs = NULL; fGlyphs = NULL;

View File

@ -23,7 +23,8 @@ class GrPathRange;
*/ */
class GrStencilAndCoverTextContext : public GrTextContext { class GrStencilAndCoverTextContext : public GrTextContext {
public: public:
static GrStencilAndCoverTextContext* Create(GrContext*, const SkDeviceProperties&); static GrStencilAndCoverTextContext* Create(GrContext*, GrDrawContext*,
const SkDeviceProperties&, bool fallbackUsesDFT);
virtual ~GrStencilAndCoverTextContext(); virtual ~GrStencilAndCoverTextContext();
@ -67,16 +68,16 @@ private:
SkMatrix fLocalMatrix; SkMatrix fLocalMatrix;
bool fUsingDeviceSpaceGlyphs; bool fUsingDeviceSpaceGlyphs;
GrStencilAndCoverTextContext(GrContext*, const SkDeviceProperties&); GrStencilAndCoverTextContext(GrContext*, GrDrawContext*, const SkDeviceProperties&);
bool canDraw(const GrRenderTarget*, const GrClip&, const GrPaint&, bool canDraw(const GrRenderTarget*, const GrClip&, const GrPaint&,
const SkPaint&, const SkMatrix& viewMatrix) override; const SkPaint&, const SkMatrix& viewMatrix) override;
void onDrawText(GrDrawContext*, GrRenderTarget*, const GrClip&, const GrPaint&, const SkPaint&, void onDrawText(GrRenderTarget*, const GrClip&, const GrPaint&, const SkPaint&,
const SkMatrix& viewMatrix, const SkMatrix& viewMatrix,
const char text[], size_t byteLength, const char text[], size_t byteLength,
SkScalar x, SkScalar y, const SkIRect& regionClipBounds) override; SkScalar x, SkScalar y, const SkIRect& regionClipBounds) override;
void onDrawPosText(GrDrawContext*, GrRenderTarget*, const GrClip&, const GrPaint&, const SkPaint&, void onDrawPosText(GrRenderTarget*, const GrClip&, const GrPaint&, const SkPaint&,
const SkMatrix& viewMatrix, const SkMatrix& viewMatrix,
const char text[], size_t byteLength, const char text[], size_t byteLength,
const SkScalar pos[], int scalarsPerPosition, const SkScalar pos[], int scalarsPerPosition,
@ -86,9 +87,9 @@ private:
size_t textByteLength, RenderMode, const SkMatrix& viewMatrix, size_t textByteLength, RenderMode, const SkMatrix& viewMatrix,
const SkIRect& regionClipBounds); const SkIRect& regionClipBounds);
bool mapToFallbackContext(SkMatrix* inverse); bool mapToFallbackContext(SkMatrix* inverse);
void appendGlyph(GrDrawContext*, const SkGlyph&, const SkPoint&); void appendGlyph(const SkGlyph&, const SkPoint&);
void flush(GrDrawContext*); void flush();
void finish(GrDrawContext*); void finish();
}; };

View File

@ -20,10 +20,12 @@
#include "SkTextMapStateProc.h" #include "SkTextMapStateProc.h"
#include "SkTextToPathIter.h" #include "SkTextToPathIter.h"
GrTextContext::GrTextContext(GrContext* context, const SkDeviceProperties& properties) GrTextContext::GrTextContext(GrContext* context, GrDrawContext* drawContext,
const SkDeviceProperties& properties)
: fFallbackTextContext(NULL) : fFallbackTextContext(NULL)
, fContext(context) , fContext(context)
, fDeviceProperties(properties) { , fDeviceProperties(properties)
, fDrawContext(drawContext) {
} }
GrTextContext::~GrTextContext() { GrTextContext::~GrTextContext() {
@ -47,19 +49,14 @@ void GrTextContext::drawText(GrRenderTarget* rt, const GrClip& clip, const GrPai
const SkPaint& skPaint, const SkMatrix& viewMatrix, const SkPaint& skPaint, const SkMatrix& viewMatrix,
const char text[], size_t byteLength, const char text[], size_t byteLength,
SkScalar x, SkScalar y, const SkIRect& clipBounds) { SkScalar x, SkScalar y, const SkIRect& clipBounds) {
if (fContext->abandoned()) { if (fContext->abandoned() || !fDrawContext) {
return;
}
GrDrawContext* drawContext = fContext->drawContext();
if (!drawContext) {
return; return;
} }
GrTextContext* textContext = this; GrTextContext* textContext = this;
do { do {
if (textContext->canDraw(rt, clip, paint, skPaint, viewMatrix)) { if (textContext->canDraw(rt, clip, paint, skPaint, viewMatrix)) {
textContext->onDrawText(drawContext, rt, clip, paint, skPaint, viewMatrix, textContext->onDrawText(rt, clip, paint, skPaint, viewMatrix,
text, byteLength, x, y, clipBounds); text, byteLength, x, y, clipBounds);
return; return;
} }
@ -67,7 +64,7 @@ void GrTextContext::drawText(GrRenderTarget* rt, const GrClip& clip, const GrPai
} while (textContext); } while (textContext);
// fall back to drawing as a path // fall back to drawing as a path
this->drawTextAsPath(drawContext, rt, clip, skPaint, viewMatrix, this->drawTextAsPath(rt, clip, skPaint, viewMatrix,
text, byteLength, x, y, clipBounds); text, byteLength, x, y, clipBounds);
} }
@ -76,19 +73,14 @@ void GrTextContext::drawPosText(GrRenderTarget* rt, const GrClip& clip, const Gr
const char text[], size_t byteLength, const char text[], size_t byteLength,
const SkScalar pos[], int scalarsPerPosition, const SkScalar pos[], int scalarsPerPosition,
const SkPoint& offset, const SkIRect& clipBounds) { const SkPoint& offset, const SkIRect& clipBounds) {
if (fContext->abandoned()) { if (fContext->abandoned() || !fDrawContext) {
return;
}
GrDrawContext* drawContext = fContext->drawContext();
if (!drawContext) {
return; return;
} }
GrTextContext* textContext = this; GrTextContext* textContext = this;
do { do {
if (textContext->canDraw(rt, clip, paint, skPaint, viewMatrix)) { if (textContext->canDraw(rt, clip, paint, skPaint, viewMatrix)) {
textContext->onDrawPosText(drawContext, rt, clip, paint, skPaint, viewMatrix, textContext->onDrawPosText(rt, clip, paint, skPaint, viewMatrix,
text, byteLength, pos, text, byteLength, pos,
scalarsPerPosition, offset, clipBounds); scalarsPerPosition, offset, clipBounds);
return; return;
@ -97,7 +89,7 @@ void GrTextContext::drawPosText(GrRenderTarget* rt, const GrClip& clip, const Gr
} while (textContext); } while (textContext);
// fall back to drawing as a path // fall back to drawing as a path
this->drawPosTextAsPath(drawContext, rt, clip, skPaint, viewMatrix, text, byteLength, pos, this->drawPosTextAsPath(rt, clip, skPaint, viewMatrix, text, byteLength, pos,
scalarsPerPosition, offset, clipBounds); scalarsPerPosition, offset, clipBounds);
} }
@ -183,7 +175,7 @@ void GrTextContext::drawTextBlob(GrRenderTarget* rt,
} }
} }
void GrTextContext::drawTextAsPath(GrDrawContext* drawContext, GrRenderTarget* rt, void GrTextContext::drawTextAsPath(GrRenderTarget* rt,
const GrClip& clip, const GrClip& clip,
const SkPaint& skPaint, const SkMatrix& viewMatrix, const SkPaint& skPaint, const SkMatrix& viewMatrix,
const char text[], size_t byteLength, SkScalar x, SkScalar y, const char text[], size_t byteLength, SkScalar x, SkScalar y,
@ -201,14 +193,14 @@ void GrTextContext::drawTextAsPath(GrDrawContext* drawContext, GrRenderTarget* r
matrix.postTranslate(xpos - prevXPos, 0); matrix.postTranslate(xpos - prevXPos, 0);
if (iterPath) { if (iterPath) {
const SkPaint& pnt = iter.getPaint(); const SkPaint& pnt = iter.getPaint();
GrBlurUtils::drawPathWithMaskFilter(fContext, drawContext, rt, clip, *iterPath, GrBlurUtils::drawPathWithMaskFilter(fContext, fDrawContext, rt, clip, *iterPath,
pnt, viewMatrix, &matrix, clipBounds, false); pnt, viewMatrix, &matrix, clipBounds, false);
} }
prevXPos = xpos; prevXPos = xpos;
} }
} }
void GrTextContext::drawPosTextAsPath(GrDrawContext* drawContext, GrRenderTarget* rt, void GrTextContext::drawPosTextAsPath(GrRenderTarget* rt,
const GrClip& clip, const GrClip& clip,
const SkPaint& origPaint, const SkMatrix& viewMatrix, const SkPaint& origPaint, const SkMatrix& viewMatrix,
const char text[], size_t byteLength, const char text[], size_t byteLength,
@ -249,7 +241,7 @@ void GrTextContext::drawPosTextAsPath(GrDrawContext* drawContext, GrRenderTarget
matrix[SkMatrix::kMTransX] = loc.fX; matrix[SkMatrix::kMTransX] = loc.fX;
matrix[SkMatrix::kMTransY] = loc.fY; matrix[SkMatrix::kMTransY] = loc.fY;
GrBlurUtils::drawPathWithMaskFilter(fContext, drawContext, rt, clip, *path, paint, GrBlurUtils::drawPathWithMaskFilter(fContext, fDrawContext, rt, clip, *path, paint,
viewMatrix, &matrix, clipBounds, false); viewMatrix, &matrix, clipBounds, false);
} }
} }

View File

@ -48,6 +48,7 @@ protected:
GrContext* fContext; GrContext* fContext;
SkDeviceProperties fDeviceProperties; SkDeviceProperties fDeviceProperties;
GrDrawContext* fDrawContext; // owning drawContext
SkAutoTUnref<GrRenderTarget> fRenderTarget; SkAutoTUnref<GrRenderTarget> fRenderTarget;
GrClip fClip; GrClip fClip;
SkIRect fClipRect; SkIRect fClipRect;
@ -55,27 +56,27 @@ protected:
GrPaint fPaint; GrPaint fPaint;
SkPaint fSkPaint; SkPaint fSkPaint;
GrTextContext(GrContext*, const SkDeviceProperties&); GrTextContext(GrContext*, GrDrawContext*, const SkDeviceProperties&);
virtual bool canDraw(const GrRenderTarget*, const GrClip&, const GrPaint&, virtual bool canDraw(const GrRenderTarget*, const GrClip&, const GrPaint&,
const SkPaint&, const SkMatrix& viewMatrix) = 0; const SkPaint&, const SkMatrix& viewMatrix) = 0;
virtual void onDrawText(GrDrawContext*, GrRenderTarget*, const GrClip&, virtual void onDrawText(GrRenderTarget*, const GrClip&,
const GrPaint&, const SkPaint&, const GrPaint&, const SkPaint&,
const SkMatrix& viewMatrix, const char text[], size_t byteLength, const SkMatrix& viewMatrix, const char text[], size_t byteLength,
SkScalar x, SkScalar y, const SkIRect& clipBounds) = 0; SkScalar x, SkScalar y, const SkIRect& clipBounds) = 0;
virtual void onDrawPosText(GrDrawContext*, GrRenderTarget*, const GrClip&, virtual void onDrawPosText(GrRenderTarget*, const GrClip&,
const GrPaint&, const SkPaint&, const GrPaint&, const SkPaint&,
const SkMatrix& viewMatrix, const SkMatrix& viewMatrix,
const char text[], size_t byteLength, const char text[], size_t byteLength,
const SkScalar pos[], int scalarsPerPosition, const SkScalar pos[], int scalarsPerPosition,
const SkPoint& offset, const SkIRect& clipBounds) = 0; const SkPoint& offset, const SkIRect& clipBounds) = 0;
void drawTextAsPath(GrDrawContext*, GrRenderTarget*, const GrClip& clip, void drawTextAsPath(GrRenderTarget*, const GrClip& clip,
const SkPaint& origPaint, const SkMatrix& viewMatrix, const SkPaint& origPaint, const SkMatrix& viewMatrix,
const char text[], size_t byteLength, SkScalar x, SkScalar y, const char text[], size_t byteLength, SkScalar x, SkScalar y,
const SkIRect& clipBounds); const SkIRect& clipBounds);
void drawPosTextAsPath(GrDrawContext*, GrRenderTarget*, const GrClip& clip, void drawPosTextAsPath(GrRenderTarget*, const GrClip& clip,
const SkPaint& origPaint, const SkMatrix& viewMatrix, const SkPaint& origPaint, const SkMatrix& viewMatrix,
const char text[], size_t byteLength, const char text[], size_t byteLength,
const SkScalar pos[], int scalarsPerPosition, const SkScalar pos[], int scalarsPerPosition,

View File

@ -10,6 +10,7 @@
#include "GrBlurUtils.h" #include "GrBlurUtils.h"
#include "GrContext.h" #include "GrContext.h"
#include "GrDrawContext.h" #include "GrDrawContext.h"
#include "GrFontScaler.h"
#include "GrGpu.h" #include "GrGpu.h"
#include "GrGpuResourcePriv.h" #include "GrGpuResourcePriv.h"
#include "GrLayerHoister.h" #include "GrLayerHoister.h"
@ -137,7 +138,7 @@ static SkDeviceProperties surfaceprops_to_deviceprops(const SkSurfaceProps* prop
if (props) { if (props) {
return SkDeviceProperties(props->pixelGeometry()); return SkDeviceProperties(props->pixelGeometry());
} else { } else {
return SkDeviceProperties(SkDeviceProperties::kLegacyLCD_InitType); return SkDeviceProperties();
} }
} }
@ -167,8 +168,7 @@ SkGpuDevice::SkGpuDevice(GrRenderTarget* rt, int width, int height,
fLegacyBitmap.setPixelRef(pr)->unref(); fLegacyBitmap.setPixelRef(pr)->unref();
bool useDFT = fSurfaceProps.isUseDistanceFieldFonts(); bool useDFT = fSurfaceProps.isUseDistanceFieldFonts();
fTextContext = fContext->createTextContext(fRenderTarget, this->getLeakyProperties(), useDFT); fDrawContext.reset(SkRef(fContext->drawContext(&this->getLeakyProperties(), useDFT)));
fDrawContext.reset(SkRef(fContext->drawContext()));
} }
GrRenderTarget* SkGpuDevice::CreateRenderTarget(GrContext* context, SkSurface::Budgeted budgeted, GrRenderTarget* SkGpuDevice::CreateRenderTarget(GrContext* context, SkSurface::Budgeted budgeted,
@ -227,8 +227,6 @@ SkGpuDevice::~SkGpuDevice() {
delete fDrawProcs; delete fDrawProcs;
} }
SkDELETE(fTextContext);
fRenderTarget->unref(); fRenderTarget->unref();
fContext->unref(); fContext->unref();
} }
@ -355,7 +353,9 @@ void SkGpuDevice::replaceRenderTarget(bool shouldRetainContent) {
SkPixelRef* pr = SkNEW_ARGS(SkGrPixelRef, (fRenderTarget->surfacePriv().info(), fRenderTarget)); SkPixelRef* pr = SkNEW_ARGS(SkGrPixelRef, (fRenderTarget->surfacePriv().info(), fRenderTarget));
fLegacyBitmap.setPixelRef(pr)->unref(); fLegacyBitmap.setPixelRef(pr)->unref();
fDrawContext.reset(SkRef(fRenderTarget->getContext()->drawContext())); bool useDFT = fSurfaceProps.isUseDistanceFieldFonts();
fDrawContext.reset(SkRef(fRenderTarget->getContext()->drawContext(&this->getLeakyProperties(),
useDFT)));
} }
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
@ -1638,7 +1638,7 @@ void SkGpuDevice::drawText(const SkDraw& draw, const void* text,
SkDEBUGCODE(this->validate();) SkDEBUGCODE(this->validate();)
fTextContext->drawText(fRenderTarget, fClip, grPaint, paint, *draw.fMatrix, fDrawContext->drawText(fRenderTarget, fClip, grPaint, paint, *draw.fMatrix,
(const char *)text, byteLength, x, y, draw.fClip->getBounds()); (const char *)text, byteLength, x, y, draw.fClip->getBounds());
} }
@ -1655,7 +1655,7 @@ void SkGpuDevice::drawPosText(const SkDraw& draw, const void* text, size_t byteL
SkDEBUGCODE(this->validate();) SkDEBUGCODE(this->validate();)
fTextContext->drawPosText(fRenderTarget, fClip, grPaint, paint, *draw.fMatrix, fDrawContext->drawPosText(fRenderTarget, fClip, grPaint, paint, *draw.fMatrix,
(const char *)text, byteLength, pos, scalarsPerPos, offset, (const char *)text, byteLength, pos, scalarsPerPos, offset,
draw.fClip->getBounds()); draw.fClip->getBounds());
} }
@ -1667,7 +1667,7 @@ void SkGpuDevice::drawTextBlob(const SkDraw& draw, const SkTextBlob* blob, SkSca
SkDEBUGCODE(this->validate();) SkDEBUGCODE(this->validate();)
fTextContext->drawTextBlob(fRenderTarget, fClip, paint, *draw.fMatrix, fDrawContext->drawTextBlob(fRenderTarget, fClip, paint, *draw.fMatrix,
blob, x, y, drawFilter, draw.fClip->getBounds()); blob, x, y, drawFilter, draw.fClip->getBounds());
} }

View File

@ -23,7 +23,6 @@ struct GrSkDrawProcs;
class GrAccelData; class GrAccelData;
struct GrCachedLayer; struct GrCachedLayer;
class GrTextContext;
/** /**
* Subclass of SkBaseDevice, which directs all drawing to the GrGpu owned by the * Subclass of SkBaseDevice, which directs all drawing to the GrGpu owned by the
@ -151,7 +150,6 @@ private:
SkAutoTUnref<const SkClipStack> fClipStack; SkAutoTUnref<const SkClipStack> fClipStack;
SkIPoint fClipOrigin; SkIPoint fClipOrigin;
GrClip fClip; GrClip fClip;
GrTextContext* fTextContext;
SkAutoTUnref<GrDrawContext> fDrawContext; SkAutoTUnref<GrDrawContext> fDrawContext;
SkSurfaceProps fSurfaceProps; SkSurfaceProps fSurfaceProps;
GrRenderTarget* fRenderTarget; GrRenderTarget* fRenderTarget;
@ -219,7 +217,6 @@ private:
int sampleCount); int sampleCount);
friend class GrAtlasTextContext; friend class GrAtlasTextContext;
friend class GrTextContext;
typedef SkBaseDevice INHERITED; typedef SkBaseDevice INHERITED;
}; };

View File

@ -228,8 +228,8 @@ SkImage* SkImage::NewFromYUVTexturesCopy(GrContext* ctx , SkYUVColorSpace colorS
const SkRect rect = SkRect::MakeWH(SkIntToScalar(dstDesc.fWidth), const SkRect rect = SkRect::MakeWH(SkIntToScalar(dstDesc.fWidth),
SkIntToScalar(dstDesc.fHeight)); SkIntToScalar(dstDesc.fHeight));
ctx->drawContext()->drawRect(dst->asRenderTarget(), GrClip::WideOpen(), paint, SkMatrix::I(), GrDrawContext* drawContext = ctx->drawContext();
rect); drawContext->drawRect(dst->asRenderTarget(), GrClip::WideOpen(), paint, SkMatrix::I(), rect);
ctx->flushSurfaceWrites(dst); ctx->flushSurfaceWrites(dst);
return SkNEW_ARGS(SkImage_Gpu, (dstDesc.fWidth, dstDesc.fHeight, kOpaque_SkAlphaType, dst, 0, return SkNEW_ARGS(SkImage_Gpu, (dstDesc.fWidth, dstDesc.fHeight, kOpaque_SkAlphaType, dst, 0,
budgeted)); budgeted));