Split GrTextContext into baseclass and subclass
This is a step towards enabling alternate text rendering code paths (GLyphy in particular) Committed on behalf of baranowski@chromium.org Review URL: http://codereview.appspot.com/5796071/ git-svn-id: http://skia.googlecode.com/svn/trunk@3412 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
aa3b6a965e
commit
f4a9c82918
@ -189,6 +189,8 @@
|
||||
'../src/gpu/GrAllocPool.cpp',
|
||||
'../src/gpu/GrAtlas.cpp',
|
||||
'../src/gpu/GrAtlas.h',
|
||||
'../src/gpu/GrBatchedTextContext.cpp',
|
||||
'../src/gpu/GrBatchedTextContext.h',
|
||||
'../src/gpu/GrBinHashKey.h',
|
||||
'../src/gpu/GrBufferAllocPool.cpp',
|
||||
'../src/gpu/GrBufferAllocPool.h',
|
||||
@ -196,6 +198,8 @@
|
||||
'../src/gpu/GrContext.cpp',
|
||||
'../src/gpu/GrDefaultPathRenderer.cpp',
|
||||
'../src/gpu/GrDefaultPathRenderer.h',
|
||||
'../src/gpu/GrDefaultTextContext.cpp',
|
||||
'../src/gpu/GrDefaultTextContext.h',
|
||||
'../src/gpu/GrDrawState.h',
|
||||
'../src/gpu/GrDrawTarget.cpp',
|
||||
'../src/gpu/GrDrawTarget.h',
|
||||
@ -233,7 +237,6 @@
|
||||
'../src/gpu/GrTDArray.h',
|
||||
'../src/gpu/GrTesselatedPathRenderer.cpp',
|
||||
'../src/gpu/GrTesselatedPathRenderer.h',
|
||||
'../src/gpu/GrTextContext.cpp',
|
||||
'../src/gpu/GrTextStrike.cpp',
|
||||
'../src/gpu/GrTextStrike.h',
|
||||
'../src/gpu/GrTextStrike_impl.h',
|
||||
|
@ -12,57 +12,99 @@
|
||||
#define GrTextContext_DEFINED
|
||||
|
||||
#include "GrGlyph.h"
|
||||
#include "GrPaint.h"
|
||||
#include "GrMatrix.h"
|
||||
#include "GrRefCnt.h"
|
||||
|
||||
struct GrGpuTextVertex;
|
||||
class GrContext;
|
||||
class GrTextStrike;
|
||||
class GrFontScaler;
|
||||
class GrDrawTarget;
|
||||
class GrPaint;
|
||||
|
||||
class GrTextContext {
|
||||
public:
|
||||
GrTextContext(GrContext*,
|
||||
const GrPaint& paint,
|
||||
const GrMatrix* extMatrix = NULL);
|
||||
~GrTextContext();
|
||||
class SkGpuDevice;
|
||||
class SkPaint;
|
||||
|
||||
void drawPackedGlyph(GrGlyph::PackedID, GrFixed left, GrFixed top,
|
||||
GrFontScaler*);
|
||||
|
||||
void flush(); // optional; automatically called by destructor
|
||||
|
||||
private:
|
||||
GrPaint fPaint;
|
||||
GrVertexLayout fVertexLayout;
|
||||
class GrTextContext: public GrRefCnt {
|
||||
protected:
|
||||
GrContext* fContext;
|
||||
GrDrawTarget* fDrawTarget;
|
||||
|
||||
GrMatrix fExtMatrix;
|
||||
GrFontScaler* fScaler;
|
||||
GrTextStrike* fStrike;
|
||||
public:
|
||||
/**
|
||||
* To use a text context it must be wrapped in an AutoFinish. AutoFinish's
|
||||
* destructor ensures all drawing is flushed to the GrContext.
|
||||
*/
|
||||
class AutoFinish {
|
||||
public:
|
||||
AutoFinish(GrTextContext* textContext, GrContext* context,
|
||||
const GrPaint&, const GrMatrix* extMatrix);
|
||||
~AutoFinish();
|
||||
GrTextContext* getTextContext() const;
|
||||
|
||||
inline void flushGlyphs();
|
||||
void setupDrawTarget();
|
||||
|
||||
enum {
|
||||
kMinRequestedGlyphs = 1,
|
||||
kDefaultRequestedGlyphs = 64,
|
||||
kMinRequestedVerts = kMinRequestedGlyphs * 4,
|
||||
kDefaultRequestedVerts = kDefaultRequestedGlyphs * 4,
|
||||
private:
|
||||
GrTextContext* fTextContext;
|
||||
};
|
||||
|
||||
GrGpuTextVertex* fVertices;
|
||||
virtual void drawPackedGlyph(GrGlyph::PackedID, GrFixed left, GrFixed top,
|
||||
GrFontScaler*) = 0;
|
||||
|
||||
int32_t fMaxVertices;
|
||||
GrTexture* fCurrTexture;
|
||||
int fCurrVertex;
|
||||
virtual ~GrTextContext() {}
|
||||
|
||||
GrIRect fClipRect;
|
||||
GrMatrix fOrigViewMatrix; // restore previous viewmatrix
|
||||
protected:
|
||||
GrTextContext() {
|
||||
fContext = NULL;
|
||||
}
|
||||
|
||||
bool isValid() const {
|
||||
return (NULL != fContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the object.
|
||||
*
|
||||
* Before call to this method, the instance is considered to be in
|
||||
* invalid state. I.e. call to any method other than isValid will result in
|
||||
* undefined behaviour.
|
||||
*
|
||||
* @see finish
|
||||
*/
|
||||
virtual void init(GrContext* context, const GrPaint&,
|
||||
const GrMatrix* extMatrix) {
|
||||
fContext = context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the object to invalid state.
|
||||
*
|
||||
* After call to this method, the instance is considered to be in
|
||||
* invalid state.
|
||||
*
|
||||
* It might be brought back to a valid state by calling init.
|
||||
*
|
||||
* @see init
|
||||
*/
|
||||
virtual void finish() {
|
||||
fContext = NULL;
|
||||
}
|
||||
|
||||
private:
|
||||
typedef GrRefCnt INHERITED;
|
||||
};
|
||||
|
||||
inline GrTextContext::AutoFinish::AutoFinish(GrTextContext* textContext,
|
||||
GrContext* context,
|
||||
const GrPaint& grPaint,
|
||||
const GrMatrix* extMatrix) {
|
||||
GrAssert(NULL != textContext);
|
||||
fTextContext = textContext;
|
||||
fTextContext->ref();
|
||||
fTextContext->init(context, grPaint, extMatrix);
|
||||
}
|
||||
|
||||
inline GrTextContext::AutoFinish::~AutoFinish() {
|
||||
fTextContext->finish();
|
||||
fTextContext->unref();
|
||||
}
|
||||
|
||||
inline GrTextContext* GrTextContext::AutoFinish::getTextContext() const {
|
||||
return fTextContext;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -147,6 +147,8 @@ private:
|
||||
bool fNeedClear;
|
||||
bool fNeedPrepareRenderTarget;
|
||||
|
||||
GrTextContext* fTextContext;
|
||||
|
||||
// called from rt and tex cons
|
||||
void initFromRenderTarget(GrContext*, GrRenderTarget*);
|
||||
|
||||
@ -167,6 +169,11 @@ private:
|
||||
void internalDrawBitmap(const SkDraw&, const SkBitmap&,
|
||||
const SkIRect&, const SkMatrix&, GrPaint* grPaint);
|
||||
|
||||
/**
|
||||
* Returns non-initialized instance.
|
||||
*/
|
||||
GrTextContext* getTextContext();
|
||||
|
||||
typedef SkDevice INHERITED;
|
||||
};
|
||||
|
||||
|
97
src/gpu/GrBatchedTextContext.cpp
Normal file
97
src/gpu/GrBatchedTextContext.cpp
Normal file
@ -0,0 +1,97 @@
|
||||
|
||||
/*
|
||||
* Copyright 2010 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "GrBatchedTextContext.h"
|
||||
#include "GrContext.h"
|
||||
#include "GrDrawTarget.h"
|
||||
#include "GrIndexBuffer.h"
|
||||
#include "GrTextContext.h"
|
||||
|
||||
|
||||
GrBatchedTextContext::GrBatchedTextContext() {
|
||||
}
|
||||
|
||||
GrBatchedTextContext::~GrBatchedTextContext() {
|
||||
}
|
||||
|
||||
void GrBatchedTextContext::init(GrContext* context,
|
||||
const GrPaint& grPaint,
|
||||
const GrMatrix* extMatrix) {
|
||||
this->INHERITED::init(context, grPaint, extMatrix);
|
||||
fGrPaint = grPaint;
|
||||
fDrawTarget = fContext->getTextTarget(fGrPaint);
|
||||
|
||||
fMaxVertices = 0;
|
||||
fCurrTexture = NULL;
|
||||
fCurrVertex = 0;
|
||||
}
|
||||
|
||||
void GrBatchedTextContext::finish() {
|
||||
fDrawTarget = NULL;
|
||||
|
||||
this->INHERITED::finish();
|
||||
}
|
||||
|
||||
void GrBatchedTextContext::reset() {
|
||||
GrAssert(this->isValid());
|
||||
fDrawTarget->resetVertexSource();
|
||||
fMaxVertices = 0;
|
||||
fCurrVertex = 0;
|
||||
fCurrTexture->unref();
|
||||
fCurrTexture = NULL;
|
||||
}
|
||||
|
||||
void GrBatchedTextContext::prepareForGlyph(GrTexture* texture) {
|
||||
GrAssert(this->isValid());
|
||||
GrAssert(texture);
|
||||
if (fCurrTexture != texture || fCurrVertex + 4 > fMaxVertices) {
|
||||
this->flush();
|
||||
fCurrTexture = texture;
|
||||
fCurrTexture->ref();
|
||||
}
|
||||
}
|
||||
|
||||
void GrBatchedTextContext::setupVertexBuff(void** vertexBuff,
|
||||
GrVertexLayout vertexLayout) {
|
||||
GrAssert(this->isValid());
|
||||
if (NULL == *vertexBuff) {
|
||||
// If we need to reserve vertices allow the draw target to suggest
|
||||
// a number of verts to reserve and whether to perform a flush.
|
||||
fMaxVertices = kMinRequestedVerts;
|
||||
bool flush = fDrawTarget->geometryHints(vertexLayout,
|
||||
&fMaxVertices,
|
||||
NULL);
|
||||
if (flush) {
|
||||
this->flush();
|
||||
fContext->flushText();
|
||||
fDrawTarget = fContext->getTextTarget(fGrPaint);
|
||||
fMaxVertices = kDefaultRequestedVerts;
|
||||
// ignore return, no point in flushing again.
|
||||
fDrawTarget->geometryHints(vertexLayout,
|
||||
&fMaxVertices,
|
||||
NULL);
|
||||
}
|
||||
|
||||
int maxQuadVertices = 4 * fContext->getQuadIndexBuffer()->maxQuads();
|
||||
if (fMaxVertices < kMinRequestedVerts) {
|
||||
fMaxVertices = kDefaultRequestedVerts;
|
||||
} else if (fMaxVertices > maxQuadVertices) {
|
||||
// don't exceed the limit of the index buffer
|
||||
fMaxVertices = maxQuadVertices;
|
||||
}
|
||||
bool success = fDrawTarget->reserveVertexAndIndexSpace(
|
||||
vertexLayout,
|
||||
fMaxVertices,
|
||||
0,
|
||||
vertexBuff,
|
||||
NULL);
|
||||
GrAlwaysAssert(success);
|
||||
}
|
||||
}
|
82
src/gpu/GrBatchedTextContext.h
Normal file
82
src/gpu/GrBatchedTextContext.h
Normal file
@ -0,0 +1,82 @@
|
||||
|
||||
/*
|
||||
* Copyright 2010 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef GrBatchedTextContext_DEFINED
|
||||
#define GrBatchedTextContext_DEFINED
|
||||
|
||||
#include "GrPaint.h"
|
||||
#include "GrTextContext.h"
|
||||
|
||||
class GrDrawTarget;
|
||||
class GrTexture;
|
||||
|
||||
/**
|
||||
* Base class for TextContexts that can batch multiple glyphs into single draw.
|
||||
*
|
||||
* Every glyph is encoded on a single texture.
|
||||
* Every glyph is enclosed within a quad (formed by triangle fan) represented
|
||||
* by 4 vertices.
|
||||
*/
|
||||
class GrBatchedTextContext: public GrTextContext {
|
||||
public:
|
||||
virtual ~GrBatchedTextContext();
|
||||
|
||||
protected:
|
||||
enum {
|
||||
kMinRequestedGlyphs = 1,
|
||||
kDefaultRequestedGlyphs = 64,
|
||||
kMinRequestedVerts = kMinRequestedGlyphs * 4,
|
||||
kDefaultRequestedVerts = kDefaultRequestedGlyphs * 4,
|
||||
kGlyphMaskStage = GrPaint::kTotalStages,
|
||||
};
|
||||
|
||||
GrPaint fGrPaint;
|
||||
GrDrawTarget* fDrawTarget;
|
||||
|
||||
int32_t fMaxVertices;
|
||||
GrTexture* fCurrTexture;
|
||||
int fCurrVertex;
|
||||
|
||||
GrBatchedTextContext();
|
||||
virtual void init(GrContext* context, const GrPaint&,
|
||||
const GrMatrix* extMatrix) SK_OVERRIDE;
|
||||
virtual void finish() SK_OVERRIDE;
|
||||
|
||||
/**
|
||||
* Prepare to add another glyph to buffer. The glyph is encoded on the
|
||||
* texture provided. Make sure we are using the right texture (or switch
|
||||
* to a new texture) and that our buffer is big enough.
|
||||
*/
|
||||
void prepareForGlyph(GrTexture*);
|
||||
|
||||
/**
|
||||
* Flush the buffer. Called when switching textures.
|
||||
* Must be called in finish() method of all derived classes.
|
||||
*/
|
||||
virtual void flush() = 0;
|
||||
|
||||
/**
|
||||
* Set up a buffer to hold vertices of given layout.
|
||||
* If NULL != *vertexBuff, don't do anything.
|
||||
* Might cause flushing, if draw target suggests it.
|
||||
*/
|
||||
void setupVertexBuff(void** vertexBuff, GrVertexLayout vertexLayout);
|
||||
|
||||
/**
|
||||
* Reset after flushing.
|
||||
*/
|
||||
void reset();
|
||||
|
||||
private:
|
||||
|
||||
typedef GrTextContext INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
@ -8,21 +8,18 @@
|
||||
|
||||
|
||||
|
||||
#include "GrTextContext.h"
|
||||
#include "GrAtlas.h"
|
||||
#include "GrDefaultTextContext.h"
|
||||
#include "GrContext.h"
|
||||
#include "GrDrawTarget.h"
|
||||
#include "GrFontScaler.h"
|
||||
#include "GrGpuVertex.h"
|
||||
#include "GrTemplates.h"
|
||||
#include "GrTextStrike.h"
|
||||
#include "GrTextStrike_impl.h"
|
||||
#include "GrFontScaler.h"
|
||||
#include "GrIndexBuffer.h"
|
||||
#include "GrGpuVertex.h"
|
||||
#include "GrDrawTarget.h"
|
||||
|
||||
enum {
|
||||
kGlyphMaskStage = GrPaint::kTotalStages,
|
||||
};
|
||||
|
||||
void GrTextContext::flushGlyphs() {
|
||||
void GrDefaultTextContext::flushGlyphs() {
|
||||
GrAssert(this->isValid());
|
||||
if (fCurrVertex > 0) {
|
||||
GrDrawTarget::AutoStateRestore asr(fDrawTarget);
|
||||
GrDrawState* drawState = fDrawTarget->drawState();
|
||||
@ -42,44 +39,44 @@ void GrTextContext::flushGlyphs() {
|
||||
drawState->setTexture(kGlyphMaskStage, fCurrTexture);
|
||||
|
||||
if (!GrPixelConfigIsAlphaOnly(fCurrTexture->config())) {
|
||||
if (kOne_BlendCoeff != fPaint.fSrcBlendCoeff ||
|
||||
kISA_BlendCoeff != fPaint.fDstBlendCoeff ||
|
||||
fPaint.hasTexture()) {
|
||||
if (kOne_BlendCoeff != fGrPaint.fSrcBlendCoeff ||
|
||||
kISA_BlendCoeff != fGrPaint.fDstBlendCoeff ||
|
||||
fGrPaint.hasTexture()) {
|
||||
GrPrintf("LCD Text will not draw correctly.\n");
|
||||
}
|
||||
// setup blend so that we get mask * paintColor + (1-mask)*dstColor
|
||||
drawState->setBlendConstant(fPaint.fColor);
|
||||
drawState->setBlendConstant(fGrPaint.fColor);
|
||||
drawState->setBlendFunc(kConstC_BlendCoeff, kISC_BlendCoeff);
|
||||
// don't modulate by the paint's color in the frag since we're
|
||||
// already doing it via the blend const.
|
||||
drawState->setColor(0xffffffff);
|
||||
} else {
|
||||
// set back to normal in case we took LCD path previously.
|
||||
drawState->setBlendFunc(fPaint.fSrcBlendCoeff, fPaint.fDstBlendCoeff);
|
||||
drawState->setColor(fPaint.fColor);
|
||||
drawState->setBlendFunc(fGrPaint.fSrcBlendCoeff, fGrPaint.fDstBlendCoeff);
|
||||
drawState->setColor(fGrPaint.fColor);
|
||||
}
|
||||
|
||||
fDrawTarget->setIndexSourceToBuffer(fContext->getQuadIndexBuffer());
|
||||
|
||||
fDrawTarget->drawIndexed(kTriangles_PrimitiveType,
|
||||
0, 0, fCurrVertex, nIndices);
|
||||
fDrawTarget->resetVertexSource();
|
||||
fVertices = NULL;
|
||||
fMaxVertices = 0;
|
||||
fCurrVertex = 0;
|
||||
fCurrTexture->unref();
|
||||
fCurrTexture = NULL;
|
||||
this->INHERITED::reset();
|
||||
}
|
||||
}
|
||||
|
||||
GrTextContext::GrTextContext(GrContext* context,
|
||||
const GrPaint& paint,
|
||||
const GrMatrix* extMatrix) : fPaint(paint) {
|
||||
fContext = context;
|
||||
fStrike = NULL;
|
||||
GrDefaultTextContext::GrDefaultTextContext() {
|
||||
}
|
||||
|
||||
fCurrTexture = NULL;
|
||||
fCurrVertex = 0;
|
||||
GrDefaultTextContext::~GrDefaultTextContext() {
|
||||
}
|
||||
|
||||
void GrDefaultTextContext::init(GrContext* context,
|
||||
const GrPaint& paint,
|
||||
const GrMatrix* extMatrix) {
|
||||
this->INHERITED::init(context, paint, extMatrix);
|
||||
|
||||
fStrike = NULL;
|
||||
|
||||
if (NULL != extMatrix) {
|
||||
fExtMatrix = *extMatrix;
|
||||
@ -102,7 +99,7 @@ GrTextContext::GrTextContext(GrContext* context,
|
||||
}
|
||||
|
||||
// save the context's original matrix off and restore in destructor
|
||||
// this must be done before getTextTarget.
|
||||
// getTextTarget should be called after that
|
||||
fOrigViewMatrix = fContext->getMatrix();
|
||||
fContext->setMatrix(fExtMatrix);
|
||||
|
||||
@ -118,26 +115,27 @@ GrTextContext::GrTextContext(GrContext* context,
|
||||
bool invVMComputed = false;
|
||||
GrMatrix invVM;
|
||||
for (int t = 0; t < GrPaint::kMaxTextures; ++t) {
|
||||
if (NULL != fPaint.getTexture(t)) {
|
||||
if (NULL != fGrPaint.getTexture(t)) {
|
||||
if (invVMComputed || fOrigViewMatrix.invert(&invVM)) {
|
||||
invVMComputed = true;
|
||||
fPaint.textureSampler(t)->preConcatMatrix(invVM);
|
||||
fGrPaint.textureSampler(t)->preConcatMatrix(invVM);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int m = 0; m < GrPaint::kMaxMasks; ++m) {
|
||||
if (NULL != fPaint.getMask(m)) {
|
||||
if (NULL != fGrPaint.getMask(m)) {
|
||||
if (invVMComputed || fOrigViewMatrix.invert(&invVM)) {
|
||||
invVMComputed = true;
|
||||
fPaint.maskSampler(m)->preConcatMatrix(invVM);
|
||||
fGrPaint.maskSampler(m)->preConcatMatrix(invVM);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fDrawTarget = fContext->getTextTarget(fPaint);
|
||||
// this has been already done in the baseclass, but we need to repeat
|
||||
// due to new matrix
|
||||
fDrawTarget = fContext->getTextTarget(fGrPaint);
|
||||
|
||||
fVertices = NULL;
|
||||
fMaxVertices = 0;
|
||||
|
||||
fVertexLayout =
|
||||
GrDrawTarget::kTextFormat_VertexLayoutBit |
|
||||
@ -155,12 +153,17 @@ GrTextContext::GrTextContext(GrContext* context,
|
||||
}
|
||||
}
|
||||
|
||||
GrTextContext::~GrTextContext() {
|
||||
this->flushGlyphs();
|
||||
void GrDefaultTextContext::finish() {
|
||||
this->flush();
|
||||
|
||||
fStrike = NULL;
|
||||
fContext->setMatrix(fOrigViewMatrix);
|
||||
|
||||
this->INHERITED::finish();
|
||||
}
|
||||
|
||||
void GrTextContext::flush() {
|
||||
void GrDefaultTextContext::flush() {
|
||||
GrAssert(this->isValid());
|
||||
this->flushGlyphs();
|
||||
}
|
||||
|
||||
@ -172,9 +175,10 @@ static inline void setRectFan(GrGpuTextVertex v[4], int l, int t, int r, int b,
|
||||
v[3 * stride].setI(r, t);
|
||||
}
|
||||
|
||||
void GrTextContext::drawPackedGlyph(GrGlyph::PackedID packed,
|
||||
void GrDefaultTextContext::drawPackedGlyph(GrGlyph::PackedID packed,
|
||||
GrFixed vx, GrFixed vy,
|
||||
GrFontScaler* scaler) {
|
||||
GrAssert(this->isValid());
|
||||
if (NULL == fStrike) {
|
||||
fStrike = fContext->getFontCache()->getStrike(scaler);
|
||||
}
|
||||
@ -229,7 +233,7 @@ void GrTextContext::drawPackedGlyph(GrGlyph::PackedID packed,
|
||||
GrPoint translate;
|
||||
translate.set(GrFixedToScalar(vx - GrIntToFixed(glyph->fBounds.fLeft)),
|
||||
GrFixedToScalar(vy - GrIntToFixed(glyph->fBounds.fTop)));
|
||||
fContext->drawPath(fPaint, *glyph->fPath, kWinding_PathFill,
|
||||
fContext->drawPath(fGrPaint, *glyph->fPath, kWinding_PathFill,
|
||||
&translate);
|
||||
return;
|
||||
}
|
||||
@ -242,47 +246,10 @@ HAS_ATLAS:
|
||||
height = GrIntToFixed(height);
|
||||
|
||||
GrTexture* texture = glyph->fAtlas->texture();
|
||||
GrAssert(texture);
|
||||
this->prepareForGlyph(texture);
|
||||
|
||||
if (fCurrTexture != texture || fCurrVertex + 4 > fMaxVertices) {
|
||||
this->flushGlyphs();
|
||||
fCurrTexture = texture;
|
||||
fCurrTexture->ref();
|
||||
}
|
||||
|
||||
if (NULL == fVertices) {
|
||||
// If we need to reserve vertices allow the draw target to suggest
|
||||
// a number of verts to reserve and whether to perform a flush.
|
||||
fMaxVertices = kMinRequestedVerts;
|
||||
bool flush = fDrawTarget->geometryHints(fVertexLayout,
|
||||
&fMaxVertices,
|
||||
NULL);
|
||||
if (flush) {
|
||||
this->flushGlyphs();
|
||||
fContext->flushText();
|
||||
fDrawTarget = fContext->getTextTarget(fPaint);
|
||||
fMaxVertices = kDefaultRequestedVerts;
|
||||
// ignore return, no point in flushing again.
|
||||
fDrawTarget->geometryHints(fVertexLayout,
|
||||
&fMaxVertices,
|
||||
NULL);
|
||||
}
|
||||
|
||||
int maxQuadVertices = 4 * fContext->getQuadIndexBuffer()->maxQuads();
|
||||
if (fMaxVertices < kMinRequestedVerts) {
|
||||
fMaxVertices = kDefaultRequestedVerts;
|
||||
} else if (fMaxVertices > maxQuadVertices) {
|
||||
// don't exceed the limit of the index buffer
|
||||
fMaxVertices = maxQuadVertices;
|
||||
}
|
||||
bool success = fDrawTarget->reserveVertexAndIndexSpace(
|
||||
fVertexLayout,
|
||||
fMaxVertices,
|
||||
0,
|
||||
GrTCast<void**>(&fVertices),
|
||||
NULL);
|
||||
GrAlwaysAssert(success);
|
||||
}
|
||||
this->setupVertexBuff(GrTCast<void**>(&fVertices),
|
||||
fVertexLayout);
|
||||
|
||||
GrFixed tx = GrIntToFixed(glyph->fAtlasLocation.fX);
|
||||
GrFixed ty = GrIntToFixed(glyph->fAtlasLocation.fY);
|
||||
@ -311,5 +278,3 @@ HAS_ATLAS:
|
||||
#endif
|
||||
fCurrVertex += 4;
|
||||
}
|
||||
|
||||
|
49
src/gpu/GrDefaultTextContext.h
Normal file
49
src/gpu/GrDefaultTextContext.h
Normal file
@ -0,0 +1,49 @@
|
||||
|
||||
/*
|
||||
* Copyright 2010 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef GrDefaultTextContext_DEFINED
|
||||
#define GrDefaultTextContext_DEFINED
|
||||
|
||||
#include "GrBatchedTextContext.h"
|
||||
|
||||
struct GrGpuTextVertex;
|
||||
class GrTextStrike;
|
||||
|
||||
class GrDefaultTextContext: public GrBatchedTextContext {
|
||||
public:
|
||||
GrDefaultTextContext();
|
||||
~GrDefaultTextContext();
|
||||
|
||||
virtual void drawPackedGlyph(GrGlyph::PackedID, GrFixed left, GrFixed top,
|
||||
GrFontScaler*) SK_OVERRIDE;
|
||||
|
||||
protected:
|
||||
virtual void flush() SK_OVERRIDE;
|
||||
virtual void init(GrContext* context, const GrPaint&,
|
||||
const GrMatrix* extMatrix) SK_OVERRIDE;
|
||||
virtual void finish() SK_OVERRIDE;
|
||||
|
||||
private:
|
||||
GrVertexLayout fVertexLayout;
|
||||
GrGpuTextVertex* fVertices;
|
||||
GrIRect fClipRect;
|
||||
|
||||
GrFontScaler* fScaler;
|
||||
GrTextStrike* fStrike;
|
||||
|
||||
GrMatrix fExtMatrix;
|
||||
GrMatrix fOrigViewMatrix; // restore previous viewmatrix
|
||||
|
||||
inline void flushGlyphs();
|
||||
|
||||
typedef GrBatchedTextContext INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
@ -9,6 +9,7 @@
|
||||
|
||||
|
||||
#include "GrContext.h"
|
||||
#include "GrDefaultTextContext.h"
|
||||
#include "GrTextContext.h"
|
||||
|
||||
#include "SkGpuDevice.h"
|
||||
@ -184,6 +185,8 @@ void SkGpuDevice::initFromRenderTarget(GrContext* context,
|
||||
pr = new SkGrRenderTargetPixelRef(fRenderTarget);
|
||||
}
|
||||
this->setPixelRef(pr, 0)->unref();
|
||||
|
||||
fTextContext = NULL;
|
||||
}
|
||||
|
||||
SkGpuDevice::SkGpuDevice(GrContext* context, SkBitmap::Config config, int width,
|
||||
@ -245,6 +248,8 @@ SkGpuDevice::SkGpuDevice(GrContext* context, SkBitmap::Config config, int width,
|
||||
width, height);
|
||||
GrAssert(false);
|
||||
}
|
||||
|
||||
fTextContext = NULL;
|
||||
}
|
||||
|
||||
SkGpuDevice::~SkGpuDevice() {
|
||||
@ -260,6 +265,10 @@ SkGpuDevice::~SkGpuDevice() {
|
||||
fContext->unlockTexture(fCache);
|
||||
}
|
||||
fContext->unref();
|
||||
|
||||
if (NULL != fTextContext) {
|
||||
fTextContext->unref();
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@ -1595,8 +1604,9 @@ void SkGpuDevice::drawText(const SkDraw& draw, const void* text,
|
||||
&grPaint)) {
|
||||
return;
|
||||
}
|
||||
GrTextContext context(fContext, grPaint, draw.fExtMatrix);
|
||||
myDraw.fProcs = this->initDrawForText(&context);
|
||||
GrTextContext::AutoFinish txtCtxAF(this->getTextContext(), fContext,
|
||||
grPaint, draw.fExtMatrix);
|
||||
myDraw.fProcs = this->initDrawForText(txtCtxAF.getTextContext());
|
||||
this->INHERITED::drawText(myDraw, text, byteLength, x, y, paint);
|
||||
}
|
||||
}
|
||||
@ -1624,9 +1634,9 @@ void SkGpuDevice::drawPosText(const SkDraw& draw, const void* text,
|
||||
&grPaint)) {
|
||||
return;
|
||||
}
|
||||
|
||||
GrTextContext context(fContext, grPaint, draw.fExtMatrix);
|
||||
myDraw.fProcs = this->initDrawForText(&context);
|
||||
GrTextContext::AutoFinish txtCtxAF(this->getTextContext(), fContext,
|
||||
grPaint, draw.fExtMatrix);
|
||||
myDraw.fProcs = this->initDrawForText(txtCtxAF.getTextContext());
|
||||
this->INHERITED::drawPosText(myDraw, text, byteLength, pos, constY,
|
||||
scalarsPerPos, paint);
|
||||
}
|
||||
@ -1742,3 +1752,9 @@ SkDevice* SkGpuDevice::onCreateCompatibleDevice(SkBitmap::Config config,
|
||||
width, height, usage));
|
||||
}
|
||||
|
||||
GrTextContext* SkGpuDevice::getTextContext() {
|
||||
if (NULL == fTextContext) {
|
||||
fTextContext = new GrDefaultTextContext();
|
||||
}
|
||||
return fTextContext;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user