support lcd16 in text atlas (sans shader support)
git-svn-id: http://skia.googlecode.com/svn/trunk@939 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/gpu/include/GrAtlas.h b/gpu/include/GrAtlas.h
index 9526e0b..9fd2cab 100644
--- a/gpu/include/GrAtlas.h
+++ b/gpu/include/GrAtlas.h
@@ -28,10 +28,11 @@
class GrAtlas {
public:
- GrAtlas(GrAtlasMgr*, int plotX, int plotY);
+ GrAtlas(GrAtlasMgr*, int plotX, int plotY, GrMaskFormat);
int getPlotX() const { return fPlot.fX; }
int getPlotY() const { return fPlot.fY; }
+ GrMaskFormat getMaskFormat() const { return fMaskFormat; }
GrTexture* texture() const { return fTexture; }
@@ -56,6 +57,7 @@
GrRectanizer* fRects;
GrAtlasMgr* fAtlasMgr;
GrIPoint16 fPlot;
+ GrMaskFormat fMaskFormat;
friend class GrAtlasMgr;
};
@@ -68,7 +70,7 @@
~GrAtlasMgr();
GrAtlas* addToAtlas(GrAtlas*, int width, int height, const void*,
- GrIPoint16*);
+ GrMaskFormat, GrIPoint16*);
GrTexture* getTexture() const { return fTexture; }
diff --git a/gpu/include/GrFontScaler.h b/gpu/include/GrFontScaler.h
index 6baa56f..77730d7 100644
--- a/gpu/include/GrFontScaler.h
+++ b/gpu/include/GrFontScaler.h
@@ -33,6 +33,7 @@
class GrFontScaler : public GrRefCnt {
public:
virtual const GrKey* getKey() = 0;
+ virtual GrMaskFormat getMaskFormat() = 0;
virtual bool getPackedGlyphBounds(GrGlyph::PackedID, GrIRect* bounds) = 0;
virtual bool getPackedGlyphImage(GrGlyph::PackedID, int width, int height,
int rowBytes, void* image) = 0;
diff --git a/gpu/include/GrTextStrike.h b/gpu/include/GrTextStrike.h
index abafa57..610222c 100644
--- a/gpu/include/GrTextStrike.h
+++ b/gpu/include/GrTextStrike.h
@@ -35,11 +35,13 @@
*/
class GrTextStrike {
public:
- GrTextStrike(GrFontCache*, const GrKey* fontScalerKey, GrAtlasMgr*);
+ GrTextStrike(GrFontCache*, const GrKey* fontScalerKey, GrMaskFormat,
+ GrAtlasMgr*);
~GrTextStrike();
const GrKey* getFontScalerKey() const { return fFontScalerKey; }
GrFontCache* getFontCache() const { return fFontCache; }
+ GrMaskFormat getMaskFormat() const { return fMaskFormat; }
inline GrGlyph* getGlyph(GrGlyph::PackedID, GrFontScaler*);
bool getGlyphAtlas(GrGlyph*, GrFontScaler*);
@@ -66,6 +68,8 @@
GrAtlasMgr* fAtlasMgr;
GrAtlas* fAtlas; // linklist
+ GrMaskFormat fMaskFormat;
+
GrGlyph* generateGlyph(GrGlyph::PackedID packed, GrFontScaler* scaler);
// returns true if after the purge, the strike is empty
bool purgeAtlasAtY(GrAtlas* atlas, int yCoord);
@@ -110,7 +114,7 @@
GrGpu* fGpu;
GrAtlasMgr* fAtlasMgr;
-
+
GrTextStrike* generateStrike(GrFontScaler*, const Key&);
inline void detachStrikeFromList(GrTextStrike*);
};
diff --git a/gpu/include/GrTypes.h b/gpu/include/GrTypes.h
index f407e2f..3c137f8 100644
--- a/gpu/include/GrTypes.h
+++ b/gpu/include/GrTypes.h
@@ -189,6 +189,22 @@
};
/**
+ * 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.
*/
enum GrSetOp {
diff --git a/gpu/src/GrAtlas.cpp b/gpu/src/GrAtlas.cpp
index b55a029..ea32719 100644
--- a/gpu/src/GrAtlas.cpp
+++ b/gpu/src/GrAtlas.cpp
@@ -51,7 +51,7 @@
static int gCounter;
#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
fNext = NULL;
fTexture = mgr->getTexture(); // we're not an owner, just a pointer
@@ -60,6 +60,8 @@
fRects = GrRectanizer::Factory(GR_ATLAS_WIDTH - BORDER,
GR_ATLAS_HEIGHT - BORDER);
+ fMaskFormat = format;
+
#if GR_DEBUG
GrPrintf(" GrAtlas %p [%d %d] %d\n", this, plotX, plotY, gCounter);
gCounter += 1;
@@ -82,6 +84,13 @@
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,
GrIPoint16* loc) {
if (!fRects->addRect(width + BORDER, height + BORDER, loc)) {
@@ -89,23 +98,26 @@
}
GrAutoSMalloc<1024> storage;
- int srcW = width + 2*BORDER;
- int srcH = height + 2*BORDER;
+ int dstW = width + 2*BORDER;
+ int dstH = height + 2*BORDER;
if (BORDER) {
- uint8_t* ptr = (uint8_t*)storage.realloc(srcW * srcH);
- Gr_bzero(ptr, srcW); // zero top row
- ptr += srcW;
+ const int bpp = GrMaskFormatBytesPerPixel(fMaskFormat);
+ const size_t dstRB = dstW * bpp;
+ 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++) {
- *ptr++ = 0; // zero left edge
- memcpy(ptr, image, width); ptr += width;
- *ptr++ = 0; // zero right edge
- image = (const void*)((const char*)image + width);
+ dst = zerofill(dst, bpp); // zero left edge
+ memcpy(dst, image, width * bpp);
+ dst += width * bpp;
+ 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();
}
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
loc->fX += BORDER;
@@ -128,9 +140,23 @@
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,
int width, int height, const void* image,
+ GrMaskFormat format,
GrIPoint16* loc) {
+ GrAssert(NULL == atlas || atlas->getMaskFormat() == format);
if (atlas && atlas->addSubImage(width, height, image, loc)) {
return atlas;
}
@@ -145,11 +171,11 @@
if (NULL == fTexture) {
GrGpu::TextureDesc desc = {
- GrGpu::kDynamicUpdate_TextureFlag,
+ GrGpu::kDynamicUpdate_TextureFlag,
GrGpu::kNone_AALevel,
- GR_ATLAS_TEXTURE_WIDTH,
+ GR_ATLAS_TEXTURE_WIDTH,
GR_ATLAS_TEXTURE_HEIGHT,
- GrTexture::kAlpha_8_PixelConfig
+ maskformat2pixelconfig(format)
};
fTexture = fGpu->createTexture(desc, NULL, 0);
if (NULL == fTexture) {
@@ -157,7 +183,7 @@
}
}
- 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)) {
delete newAtlas;
return NULL;
diff --git a/gpu/src/GrTextStrike.cpp b/gpu/src/GrTextStrike.cpp
index c2d81d5..6cdb61c 100644
--- a/gpu/src/GrTextStrike.cpp
+++ b/gpu/src/GrTextStrike.cpp
@@ -41,7 +41,8 @@
if (NULL == fAtlasMgr) {
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);
if (fHead) {
@@ -131,6 +132,7 @@
*/
GrTextStrike::GrTextStrike(GrFontCache* cache, const GrKey* key,
+ GrMaskFormat format,
GrAtlasMgr* atlasMgr) : fPool(64) {
fFontScalerKey = key;
fFontScalerKey->ref();
@@ -139,6 +141,8 @@
fAtlasMgr = atlasMgr; // no need to ref, it won't go away before we do
fAtlas = NULL;
+ fMaskFormat = format;
+
#if GR_DEBUG
GrPrintf(" GrTextStrike %p %d\n", this, gCounter);
gCounter += 1;
@@ -180,17 +184,20 @@
}
GrAutoRef ar(scaler);
-
- size_t size = glyph->fBounds.area();
+
+ int bytesPerPixel = GrMaskFormatBytesPerPixel(fMaskFormat);
+ size_t size = glyph->fBounds.area() * bytesPerPixel;
GrAutoSMalloc<1024> storage(size);
if (!scaler->getPackedGlyphImage(glyph->fPackedID, glyph->width(),
- glyph->height(), glyph->width(),
+ glyph->height(),
+ glyph->width() * bytesPerPixel,
storage.get())) {
return false;
}
GrAtlas* atlas = fAtlasMgr->addToAtlas(fAtlas, glyph->width(),
glyph->height(), storage.get(),
+ fMaskFormat,
&glyph->fAtlasLocation);
if (NULL == atlas) {
return false;