support lcd16 in text atlas (sans shader support)
git-svn-id: http://skia.googlecode.com/svn/trunk@939 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
b7e9aee1ac
commit
98539c607b
@ -28,10 +28,11 @@ class GrAtlasMgr;
|
|||||||
|
|
||||||
class GrAtlas {
|
class GrAtlas {
|
||||||
public:
|
public:
|
||||||
GrAtlas(GrAtlasMgr*, int plotX, int plotY);
|
GrAtlas(GrAtlasMgr*, int plotX, int plotY, GrMaskFormat);
|
||||||
|
|
||||||
int getPlotX() const { return fPlot.fX; }
|
int getPlotX() const { return fPlot.fX; }
|
||||||
int getPlotY() const { return fPlot.fY; }
|
int getPlotY() const { return fPlot.fY; }
|
||||||
|
GrMaskFormat getMaskFormat() const { return fMaskFormat; }
|
||||||
|
|
||||||
GrTexture* texture() const { return fTexture; }
|
GrTexture* texture() const { return fTexture; }
|
||||||
|
|
||||||
@ -56,6 +57,7 @@ private:
|
|||||||
GrRectanizer* fRects;
|
GrRectanizer* fRects;
|
||||||
GrAtlasMgr* fAtlasMgr;
|
GrAtlasMgr* fAtlasMgr;
|
||||||
GrIPoint16 fPlot;
|
GrIPoint16 fPlot;
|
||||||
|
GrMaskFormat fMaskFormat;
|
||||||
|
|
||||||
friend class GrAtlasMgr;
|
friend class GrAtlasMgr;
|
||||||
};
|
};
|
||||||
@ -68,7 +70,7 @@ public:
|
|||||||
~GrAtlasMgr();
|
~GrAtlasMgr();
|
||||||
|
|
||||||
GrAtlas* addToAtlas(GrAtlas*, int width, int height, const void*,
|
GrAtlas* addToAtlas(GrAtlas*, int width, int height, const void*,
|
||||||
GrIPoint16*);
|
GrMaskFormat, GrIPoint16*);
|
||||||
|
|
||||||
GrTexture* getTexture() const { return fTexture; }
|
GrTexture* getTexture() const { return fTexture; }
|
||||||
|
|
||||||
|
@ -33,6 +33,7 @@ class GrPath;
|
|||||||
class GrFontScaler : public GrRefCnt {
|
class GrFontScaler : public GrRefCnt {
|
||||||
public:
|
public:
|
||||||
virtual const GrKey* getKey() = 0;
|
virtual const GrKey* getKey() = 0;
|
||||||
|
virtual GrMaskFormat getMaskFormat() = 0;
|
||||||
virtual bool getPackedGlyphBounds(GrGlyph::PackedID, GrIRect* bounds) = 0;
|
virtual bool getPackedGlyphBounds(GrGlyph::PackedID, GrIRect* bounds) = 0;
|
||||||
virtual bool getPackedGlyphImage(GrGlyph::PackedID, int width, int height,
|
virtual bool getPackedGlyphImage(GrGlyph::PackedID, int width, int height,
|
||||||
int rowBytes, void* image) = 0;
|
int rowBytes, void* image) = 0;
|
||||||
|
@ -35,11 +35,13 @@ class GrFontPurgeListener;
|
|||||||
*/
|
*/
|
||||||
class GrTextStrike {
|
class GrTextStrike {
|
||||||
public:
|
public:
|
||||||
GrTextStrike(GrFontCache*, const GrKey* fontScalerKey, GrAtlasMgr*);
|
GrTextStrike(GrFontCache*, const GrKey* fontScalerKey, GrMaskFormat,
|
||||||
|
GrAtlasMgr*);
|
||||||
~GrTextStrike();
|
~GrTextStrike();
|
||||||
|
|
||||||
const GrKey* getFontScalerKey() const { return fFontScalerKey; }
|
const GrKey* getFontScalerKey() const { return fFontScalerKey; }
|
||||||
GrFontCache* getFontCache() const { return fFontCache; }
|
GrFontCache* getFontCache() const { return fFontCache; }
|
||||||
|
GrMaskFormat getMaskFormat() const { return fMaskFormat; }
|
||||||
|
|
||||||
inline GrGlyph* getGlyph(GrGlyph::PackedID, GrFontScaler*);
|
inline GrGlyph* getGlyph(GrGlyph::PackedID, GrFontScaler*);
|
||||||
bool getGlyphAtlas(GrGlyph*, GrFontScaler*);
|
bool getGlyphAtlas(GrGlyph*, GrFontScaler*);
|
||||||
@ -66,6 +68,8 @@ private:
|
|||||||
GrAtlasMgr* fAtlasMgr;
|
GrAtlasMgr* fAtlasMgr;
|
||||||
GrAtlas* fAtlas; // linklist
|
GrAtlas* fAtlas; // linklist
|
||||||
|
|
||||||
|
GrMaskFormat fMaskFormat;
|
||||||
|
|
||||||
GrGlyph* generateGlyph(GrGlyph::PackedID packed, GrFontScaler* scaler);
|
GrGlyph* generateGlyph(GrGlyph::PackedID packed, GrFontScaler* scaler);
|
||||||
// returns true if after the purge, the strike is empty
|
// returns true if after the purge, the strike is empty
|
||||||
bool purgeAtlasAtY(GrAtlas* atlas, int yCoord);
|
bool purgeAtlasAtY(GrAtlas* atlas, int yCoord);
|
||||||
|
@ -188,6 +188,22 @@ enum GrBlendCoeff {
|
|||||||
kIDA_BlendCoeff, //<! one minus dst alpha
|
kIDA_BlendCoeff, //<! one minus dst alpha
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Formats for masks, used by the font cache
|
||||||
|
*/
|
||||||
|
enum GrMaskFormat {
|
||||||
|
kA8_GrMaskFormat, //!< 1-byte per pixel
|
||||||
|
kA565_GrMaskFormat //!< 2-bytes per pixel
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the number of bytes-per-pixel for the specified mask format.
|
||||||
|
*/
|
||||||
|
static inline int GrMaskFormatBytesPerPixel(GrMaskFormat format) {
|
||||||
|
GrAssert((unsigned)format <= 1);
|
||||||
|
return (int)format + 1;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set Operations used to construct clips.
|
* Set Operations used to construct clips.
|
||||||
*/
|
*/
|
||||||
|
@ -51,7 +51,7 @@
|
|||||||
static int gCounter;
|
static int gCounter;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
GrAtlas::GrAtlas(GrAtlasMgr* mgr, int plotX, int plotY) {
|
GrAtlas::GrAtlas(GrAtlasMgr* mgr, int plotX, int plotY, GrMaskFormat format) {
|
||||||
fAtlasMgr = mgr; // just a pointer, not an owner
|
fAtlasMgr = mgr; // just a pointer, not an owner
|
||||||
fNext = NULL;
|
fNext = NULL;
|
||||||
fTexture = mgr->getTexture(); // we're not an owner, just a pointer
|
fTexture = mgr->getTexture(); // we're not an owner, just a pointer
|
||||||
@ -60,6 +60,8 @@ GrAtlas::GrAtlas(GrAtlasMgr* mgr, int plotX, int plotY) {
|
|||||||
fRects = GrRectanizer::Factory(GR_ATLAS_WIDTH - BORDER,
|
fRects = GrRectanizer::Factory(GR_ATLAS_WIDTH - BORDER,
|
||||||
GR_ATLAS_HEIGHT - BORDER);
|
GR_ATLAS_HEIGHT - BORDER);
|
||||||
|
|
||||||
|
fMaskFormat = format;
|
||||||
|
|
||||||
#if GR_DEBUG
|
#if GR_DEBUG
|
||||||
GrPrintf(" GrAtlas %p [%d %d] %d\n", this, plotX, plotY, gCounter);
|
GrPrintf(" GrAtlas %p [%d %d] %d\n", this, plotX, plotY, gCounter);
|
||||||
gCounter += 1;
|
gCounter += 1;
|
||||||
@ -82,6 +84,13 @@ static void adjustForPlot(GrIPoint16* loc, const GrIPoint16& plot) {
|
|||||||
loc->fY += plot.fY * GR_ATLAS_HEIGHT;
|
loc->fY += plot.fY * GR_ATLAS_HEIGHT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint8_t* zerofill(uint8_t* ptr, int count) {
|
||||||
|
while (--count >= 0) {
|
||||||
|
*ptr++ = 0;
|
||||||
|
}
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
bool GrAtlas::addSubImage(int width, int height, const void* image,
|
bool GrAtlas::addSubImage(int width, int height, const void* image,
|
||||||
GrIPoint16* loc) {
|
GrIPoint16* loc) {
|
||||||
if (!fRects->addRect(width + BORDER, height + BORDER, loc)) {
|
if (!fRects->addRect(width + BORDER, height + BORDER, loc)) {
|
||||||
@ -89,23 +98,26 @@ bool GrAtlas::addSubImage(int width, int height, const void* image,
|
|||||||
}
|
}
|
||||||
|
|
||||||
GrAutoSMalloc<1024> storage;
|
GrAutoSMalloc<1024> storage;
|
||||||
int srcW = width + 2*BORDER;
|
int dstW = width + 2*BORDER;
|
||||||
int srcH = height + 2*BORDER;
|
int dstH = height + 2*BORDER;
|
||||||
if (BORDER) {
|
if (BORDER) {
|
||||||
uint8_t* ptr = (uint8_t*)storage.realloc(srcW * srcH);
|
const int bpp = GrMaskFormatBytesPerPixel(fMaskFormat);
|
||||||
Gr_bzero(ptr, srcW); // zero top row
|
const size_t dstRB = dstW * bpp;
|
||||||
ptr += srcW;
|
uint8_t* dst = (uint8_t*)storage.realloc(dstH * dstRB);
|
||||||
|
Gr_bzero(dst, dstRB); // zero top row
|
||||||
|
dst += dstRB;
|
||||||
for (int y = 0; y < height; y++) {
|
for (int y = 0; y < height; y++) {
|
||||||
*ptr++ = 0; // zero left edge
|
dst = zerofill(dst, bpp); // zero left edge
|
||||||
memcpy(ptr, image, width); ptr += width;
|
memcpy(dst, image, width * bpp);
|
||||||
*ptr++ = 0; // zero right edge
|
dst += width * bpp;
|
||||||
image = (const void*)((const char*)image + width);
|
dst = zerofill(dst, bpp); // zero right edge
|
||||||
|
image = (const void*)((const char*)image + width * bpp);
|
||||||
}
|
}
|
||||||
Gr_bzero(ptr, srcW); // zero bottom row
|
Gr_bzero(dst, dstRB); // zero bottom row
|
||||||
image = storage.get();
|
image = storage.get();
|
||||||
}
|
}
|
||||||
adjustForPlot(loc, fPlot);
|
adjustForPlot(loc, fPlot);
|
||||||
fTexture->uploadTextureData(loc->fX, loc->fY, srcW, srcH, image);
|
fTexture->uploadTextureData(loc->fX, loc->fY, dstW, dstH, image);
|
||||||
|
|
||||||
// now tell the caller to skip the top/left BORDER
|
// now tell the caller to skip the top/left BORDER
|
||||||
loc->fX += BORDER;
|
loc->fX += BORDER;
|
||||||
@ -128,9 +140,23 @@ GrAtlasMgr::~GrAtlasMgr() {
|
|||||||
fGpu->unref();
|
fGpu->unref();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GrTexture::PixelConfig maskformat2pixelconfig(GrMaskFormat format) {
|
||||||
|
switch (format) {
|
||||||
|
case kA8_GrMaskFormat:
|
||||||
|
return GrTexture::kAlpha_8_PixelConfig;
|
||||||
|
case kA565_GrMaskFormat:
|
||||||
|
return GrTexture::kRGB_565_PixelConfig;
|
||||||
|
default:
|
||||||
|
GrAssert(!"unknown maskformat");
|
||||||
|
}
|
||||||
|
return GrTexture::kUnknown_PixelConfig;
|
||||||
|
}
|
||||||
|
|
||||||
GrAtlas* GrAtlasMgr::addToAtlas(GrAtlas* atlas,
|
GrAtlas* GrAtlasMgr::addToAtlas(GrAtlas* atlas,
|
||||||
int width, int height, const void* image,
|
int width, int height, const void* image,
|
||||||
|
GrMaskFormat format,
|
||||||
GrIPoint16* loc) {
|
GrIPoint16* loc) {
|
||||||
|
GrAssert(NULL == atlas || atlas->getMaskFormat() == format);
|
||||||
if (atlas && atlas->addSubImage(width, height, image, loc)) {
|
if (atlas && atlas->addSubImage(width, height, image, loc)) {
|
||||||
return atlas;
|
return atlas;
|
||||||
}
|
}
|
||||||
@ -149,7 +175,7 @@ GrAtlas* GrAtlasMgr::addToAtlas(GrAtlas* atlas,
|
|||||||
GrGpu::kNone_AALevel,
|
GrGpu::kNone_AALevel,
|
||||||
GR_ATLAS_TEXTURE_WIDTH,
|
GR_ATLAS_TEXTURE_WIDTH,
|
||||||
GR_ATLAS_TEXTURE_HEIGHT,
|
GR_ATLAS_TEXTURE_HEIGHT,
|
||||||
GrTexture::kAlpha_8_PixelConfig
|
maskformat2pixelconfig(format)
|
||||||
};
|
};
|
||||||
fTexture = fGpu->createTexture(desc, NULL, 0);
|
fTexture = fGpu->createTexture(desc, NULL, 0);
|
||||||
if (NULL == fTexture) {
|
if (NULL == fTexture) {
|
||||||
@ -157,7 +183,7 @@ GrAtlas* GrAtlasMgr::addToAtlas(GrAtlas* atlas,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GrAtlas* newAtlas = new GrAtlas(this, plot.fX, plot.fY);
|
GrAtlas* newAtlas = new GrAtlas(this, plot.fX, plot.fY, format);
|
||||||
if (!newAtlas->addSubImage(width, height, image, loc)) {
|
if (!newAtlas->addSubImage(width, height, image, loc)) {
|
||||||
delete newAtlas;
|
delete newAtlas;
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -41,7 +41,8 @@ GrTextStrike* GrFontCache::generateStrike(GrFontScaler* scaler,
|
|||||||
if (NULL == fAtlasMgr) {
|
if (NULL == fAtlasMgr) {
|
||||||
fAtlasMgr = new GrAtlasMgr(fGpu);
|
fAtlasMgr = new GrAtlasMgr(fGpu);
|
||||||
}
|
}
|
||||||
GrTextStrike* strike = new GrTextStrike(this, scaler->getKey(), fAtlasMgr);
|
GrTextStrike* strike = new GrTextStrike(this, scaler->getKey(),
|
||||||
|
scaler->getMaskFormat(), fAtlasMgr);
|
||||||
fCache.insert(key, strike);
|
fCache.insert(key, strike);
|
||||||
|
|
||||||
if (fHead) {
|
if (fHead) {
|
||||||
@ -131,6 +132,7 @@ void GrFontCache::validate() const {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
GrTextStrike::GrTextStrike(GrFontCache* cache, const GrKey* key,
|
GrTextStrike::GrTextStrike(GrFontCache* cache, const GrKey* key,
|
||||||
|
GrMaskFormat format,
|
||||||
GrAtlasMgr* atlasMgr) : fPool(64) {
|
GrAtlasMgr* atlasMgr) : fPool(64) {
|
||||||
fFontScalerKey = key;
|
fFontScalerKey = key;
|
||||||
fFontScalerKey->ref();
|
fFontScalerKey->ref();
|
||||||
@ -139,6 +141,8 @@ GrTextStrike::GrTextStrike(GrFontCache* cache, const GrKey* key,
|
|||||||
fAtlasMgr = atlasMgr; // no need to ref, it won't go away before we do
|
fAtlasMgr = atlasMgr; // no need to ref, it won't go away before we do
|
||||||
fAtlas = NULL;
|
fAtlas = NULL;
|
||||||
|
|
||||||
|
fMaskFormat = format;
|
||||||
|
|
||||||
#if GR_DEBUG
|
#if GR_DEBUG
|
||||||
GrPrintf(" GrTextStrike %p %d\n", this, gCounter);
|
GrPrintf(" GrTextStrike %p %d\n", this, gCounter);
|
||||||
gCounter += 1;
|
gCounter += 1;
|
||||||
@ -181,16 +185,19 @@ bool GrTextStrike::getGlyphAtlas(GrGlyph* glyph, GrFontScaler* scaler) {
|
|||||||
|
|
||||||
GrAutoRef ar(scaler);
|
GrAutoRef ar(scaler);
|
||||||
|
|
||||||
size_t size = glyph->fBounds.area();
|
int bytesPerPixel = GrMaskFormatBytesPerPixel(fMaskFormat);
|
||||||
|
size_t size = glyph->fBounds.area() * bytesPerPixel;
|
||||||
GrAutoSMalloc<1024> storage(size);
|
GrAutoSMalloc<1024> storage(size);
|
||||||
if (!scaler->getPackedGlyphImage(glyph->fPackedID, glyph->width(),
|
if (!scaler->getPackedGlyphImage(glyph->fPackedID, glyph->width(),
|
||||||
glyph->height(), glyph->width(),
|
glyph->height(),
|
||||||
|
glyph->width() * bytesPerPixel,
|
||||||
storage.get())) {
|
storage.get())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
GrAtlas* atlas = fAtlasMgr->addToAtlas(fAtlas, glyph->width(),
|
GrAtlas* atlas = fAtlasMgr->addToAtlas(fAtlas, glyph->width(),
|
||||||
glyph->height(), storage.get(),
|
glyph->height(), storage.get(),
|
||||||
|
fMaskFormat,
|
||||||
&glyph->fAtlasLocation);
|
&glyph->fAtlasLocation);
|
||||||
if (NULL == atlas) {
|
if (NULL == atlas) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -222,6 +222,10 @@ public:
|
|||||||
SkScalerContext(const SkDescriptor* desc);
|
SkScalerContext(const SkDescriptor* desc);
|
||||||
virtual ~SkScalerContext();
|
virtual ~SkScalerContext();
|
||||||
|
|
||||||
|
SkMask::Format getMaskFormat() const {
|
||||||
|
return (SkMask::Format)fRec.fMaskFormat;
|
||||||
|
}
|
||||||
|
|
||||||
// remember our glyph offset/base
|
// remember our glyph offset/base
|
||||||
void setBaseGlyphCount(unsigned baseGlyphCount) {
|
void setBaseGlyphCount(unsigned baseGlyphCount) {
|
||||||
fBaseGlyphCount = baseGlyphCount;
|
fBaseGlyphCount = baseGlyphCount;
|
||||||
|
@ -275,6 +275,7 @@ public:
|
|||||||
|
|
||||||
// overrides
|
// overrides
|
||||||
virtual const GrKey* getKey();
|
virtual const GrKey* getKey();
|
||||||
|
virtual GrMaskFormat getMaskFormat();
|
||||||
virtual bool getPackedGlyphBounds(GrGlyph::PackedID, GrIRect* bounds);
|
virtual bool getPackedGlyphBounds(GrGlyph::PackedID, GrIRect* bounds);
|
||||||
virtual bool getPackedGlyphImage(GrGlyph::PackedID, int width, int height,
|
virtual bool getPackedGlyphImage(GrGlyph::PackedID, int width, int height,
|
||||||
int rowBytes, void* image);
|
int rowBytes, void* image);
|
||||||
|
@ -98,6 +98,10 @@ public:
|
|||||||
|
|
||||||
const SkDescriptor& getDescriptor() const { return *fDesc; }
|
const SkDescriptor& getDescriptor() const { return *fDesc; }
|
||||||
|
|
||||||
|
SkMask::Format getMaskFormat() const {
|
||||||
|
return fScalerContext->getMaskFormat();
|
||||||
|
}
|
||||||
|
|
||||||
/* AuxProc/Data allow a client to associate data with this cache entry.
|
/* AuxProc/Data allow a client to associate data with this cache entry.
|
||||||
Multiple clients can use this, as their data is keyed with a function
|
Multiple clients can use this, as their data is keyed with a function
|
||||||
pointer. In addition to serving as a key, the function pointer is called
|
pointer. In addition to serving as a key, the function pointer is called
|
||||||
|
@ -83,6 +83,19 @@ SkGrFontScaler::~SkGrFontScaler() {
|
|||||||
GrSafeUnref(fKey);
|
GrSafeUnref(fKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GrMaskFormat SkGrFontScaler::getMaskFormat() {
|
||||||
|
SkMask::Format format = fStrike->getMaskFormat();
|
||||||
|
switch (format) {
|
||||||
|
case SkMask::kA8_Format:
|
||||||
|
return kA8_GrMaskFormat;
|
||||||
|
case SkMask::kLCD16_Format:
|
||||||
|
return kA565_GrMaskFormat;
|
||||||
|
default:
|
||||||
|
GrAssert(!"unsupported SkMask::Format");
|
||||||
|
return kA8_GrMaskFormat;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const GrKey* SkGrFontScaler::getKey() {
|
const GrKey* SkGrFontScaler::getKey() {
|
||||||
if (NULL == fKey) {
|
if (NULL == fKey) {
|
||||||
fKey = new SkGrDescKey(fStrike->getDescriptor());
|
fKey = new SkGrDescKey(fStrike->getDescriptor());
|
||||||
@ -117,8 +130,9 @@ bool SkGrFontScaler::getPackedGlyphImage(GrGlyph::PackedID packed,
|
|||||||
if (srcRB == dstRB) {
|
if (srcRB == dstRB) {
|
||||||
memcpy(dst, src, dstRB * height);
|
memcpy(dst, src, dstRB * height);
|
||||||
} else {
|
} else {
|
||||||
|
const int bbp = GrMaskFormatBytesPerPixel(this->getMaskFormat());
|
||||||
for (int y = 0; y < height; y++) {
|
for (int y = 0; y < height; y++) {
|
||||||
memcpy(dst, src, width);
|
memcpy(dst, src, width * bbp);
|
||||||
src = (const char*)src + srcRB;
|
src = (const char*)src + srcRB;
|
||||||
dst = (char*)dst + dstRB;
|
dst = (char*)dst + dstRB;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user