Sanitizing source files in Housekeeper-Nightly
git-svn-id: http://skia.googlecode.com/svn/trunk@12427 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/animator/SkDrawBitmap.cpp b/src/animator/SkDrawBitmap.cpp
index 327e813..568401d 100644
--- a/src/animator/SkDrawBitmap.cpp
+++ b/src/animator/SkDrawBitmap.cpp
@@ -75,10 +75,11 @@
const char* formatName;
switch (format) {
case 0: formatName = "none"; break;
- case 1: formatName = "A8"; break;
- case 2: formatName = "Index8"; break;
- case 3: formatName = "RGB16"; break;
- case 4: formatName = "RGB32"; break;
+ case 1: formatName = "A1"; break;
+ case 2: formatName = "A8"; break;
+ case 3: formatName = "Index8"; break;
+ case 4: formatName = "RGB16"; break;
+ case 5: formatName = "RGB32"; break;
}
SkDebugf("format=\"%s\" />\n", formatName);
}
diff --git a/src/core/SkBitmap.cpp b/src/core/SkBitmap.cpp
index 9d4aa87..429d092 100644
--- a/src/core/SkBitmap.cpp
+++ b/src/core/SkBitmap.cpp
@@ -161,6 +161,7 @@
int bpp;
switch (config) {
case kNo_Config:
+ case kA1_Config:
bpp = 0; // not applicable
break;
case kA8_Config:
@@ -193,6 +194,11 @@
switch (c) {
case kNo_Config:
break;
+ case kA1_Config:
+ rowBytes.set(width);
+ rowBytes.add(7);
+ rowBytes.shiftRight(3);
+ break;
case kA8_Config:
case kIndex8_Config:
rowBytes.set(width);
@@ -269,6 +275,7 @@
case SkBitmap::kNo_Config:
alphaType = kIgnore_SkAlphaType;
break;
+ case SkBitmap::kA1_Config:
case SkBitmap::kA8_Config:
if (kUnpremul_SkAlphaType == alphaType) {
alphaType = kPremul_SkAlphaType;
@@ -284,8 +291,6 @@
case SkBitmap::kRGB_565_Config:
alphaType = kOpaque_SkAlphaType;
break;
- default:
- return false;
}
if (canonical) {
*canonical = alphaType;
@@ -601,6 +606,8 @@
case SkBitmap::kIndex8_Config:
base += x;
break;
+ case SkBitmap::kA1_Config:
+ base += x >> 3;
break;
default:
SkDEBUGFAIL("Can't return addr for config");
@@ -616,6 +623,15 @@
SkASSERT((unsigned)y < (unsigned)this->height());
switch (this->config()) {
+ case SkBitmap::kA1_Config: {
+ uint8_t* addr = this->getAddr1(x, y);
+ uint8_t mask = 1 << (7 - (x % 8));
+ if (addr[0] & mask) {
+ return SK_ColorBLACK;
+ } else {
+ return 0;
+ }
+ }
case SkBitmap::kA8_Config: {
uint8_t* addr = this->getAddr8(x, y);
return SkColorSetA(0, addr[0]);
@@ -638,7 +654,6 @@
return SkUnPreMultiply::PMColorToColor(addr[0]);
}
case kNo_Config:
- default:
SkASSERT(false);
return 0;
}
@@ -656,6 +671,9 @@
const int width = bm.width();
switch (bm.config()) {
+ case SkBitmap::kA1_Config: {
+ // TODO
+ } break;
case SkBitmap::kA8_Config: {
unsigned a = 0xFF;
for (int y = 0; y < height; ++y) {
@@ -761,6 +779,38 @@
}
switch (fConfig) {
+ case kA1_Config: {
+ uint8_t* p = this->getAddr1(area.fLeft, area.fTop);
+ const int left = area.fLeft >> 3;
+ const int right = area.fRight >> 3;
+
+ int middle = right - left - 1;
+
+ uint8_t leftMask = 0xFF >> (area.fLeft & 7);
+ uint8_t rightMask = ~(0xFF >> (area.fRight & 7));
+ if (left == right) {
+ leftMask &= rightMask;
+ rightMask = 0;
+ }
+
+ a = (a >> 7) ? 0xFF : 0;
+ while (--height >= 0) {
+ uint8_t* startP = p;
+
+ *p = (*p & ~leftMask) | (a & leftMask);
+ p++;
+ if (middle > 0) {
+ memset(p, a, middle);
+ p += middle;
+ }
+ if (rightMask) {
+ *p = (*p & ~rightMask) | (a & rightMask);
+ }
+
+ p = startP + rowBytes;
+ }
+ break;
+ }
case kA8_Config: {
uint8_t* p = this->getAddr8(area.fLeft, area.fTop);
while (--height >= 0) {
@@ -846,6 +896,7 @@
break;
case SkBitmap::kNo_Config:
+ case SkBitmap::kA1_Config:
default:
return SUB_OFFSET_FAILURE;
}
@@ -888,6 +939,8 @@
case SkBitmap::kNo_Config:
// Fall through.
+ case SkBitmap::kA1_Config:
+ // Fall through.
default:
return false;
}
@@ -968,6 +1021,7 @@
case kRGB_565_Config:
case kARGB_8888_Config:
break;
+ case kA1_Config:
case kIndex8_Config:
if (!sameConfigs) {
return false;
@@ -978,6 +1032,12 @@
default:
return false;
}
+
+ // do not copy src if srcConfig == kA1_Config while dstConfig != kA1_Config
+ if (this->config() == kA1_Config && !sameConfigs) {
+ return false;
+ }
+
return true;
}
@@ -1623,7 +1683,7 @@
void SkBitmap::toString(SkString* str) const {
static const char* gConfigNames[kConfigCount] = {
- "NONE", "A8", "INDEX8", "565", "4444", "8888"
+ "NONE", "A1", "A8", "INDEX8", "565", "4444", "8888"
};
str->appendf("bitmap: ((%d, %d) %s", this->width(), this->height(),
diff --git a/src/core/SkBlitter.cpp b/src/core/SkBlitter.cpp
index 9682d55..dc7946a 100644
--- a/src/core/SkBlitter.cpp
+++ b/src/core/SkBlitter.cpp
@@ -945,6 +945,11 @@
switch (device.config()) {
+ case SkBitmap::kA1_Config:
+ SK_PLACEMENT_NEW_ARGS(blitter, SkA1_Blitter,
+ storage, storageSize, (device, *paint));
+ break;
+
case SkBitmap::kA8_Config:
if (drawCoverage) {
SkASSERT(NULL == shader);
diff --git a/src/core/SkBlitter_A1.cpp b/src/core/SkBlitter_A1.cpp
new file mode 100644
index 0000000..b64afe2
--- /dev/null
+++ b/src/core/SkBlitter_A1.cpp
@@ -0,0 +1,50 @@
+
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#include "SkCoreBlitters.h"
+
+SkA1_Blitter::SkA1_Blitter(const SkBitmap& device, const SkPaint& paint)
+ : INHERITED(device) {
+ fSrcA = paint.getAlpha();
+}
+
+void SkA1_Blitter::blitH(int x, int y, int width) {
+ SkASSERT(x >= 0 && y >= 0 &&
+ (unsigned)(x + width) <= (unsigned)fDevice.width());
+
+ if (fSrcA <= 0x7F) {
+ return;
+ }
+ uint8_t* dst = fDevice.getAddr1(x, y);
+ int right = x + width;
+
+ int left_mask = 0xFF >> (x & 7);
+ int rite_mask = 0xFF << (8 - (right & 7));
+ int full_runs = (right >> 3) - ((x + 7) >> 3);
+
+ // check for empty right mask, so we don't read off the end
+ // (or go slower than we need to)
+ if (rite_mask == 0) {
+ SkASSERT(full_runs >= 0);
+ full_runs -= 1;
+ rite_mask = 0xFF;
+ }
+ if (left_mask == 0xFF) {
+ full_runs -= 1;
+ }
+ if (full_runs < 0) {
+ SkASSERT((left_mask & rite_mask) != 0);
+ *dst |= (left_mask & rite_mask);
+ } else {
+ *dst++ |= left_mask;
+ memset(dst, 0xFF, full_runs);
+ dst += full_runs;
+ *dst |= rite_mask;
+ }
+}
diff --git a/src/core/SkCoreBlitters.h b/src/core/SkCoreBlitters.h
index 1605a52..673b874 100644
--- a/src/core/SkCoreBlitters.h
+++ b/src/core/SkCoreBlitters.h
@@ -162,6 +162,22 @@
///////////////////////////////////////////////////////////////////////////////
+class SkA1_Blitter : public SkRasterBlitter {
+public:
+ SkA1_Blitter(const SkBitmap& device, const SkPaint& paint);
+ virtual void blitH(int x, int y, int width) SK_OVERRIDE;
+
+private:
+ uint8_t fSrcA;
+
+ // illegal
+ SkA1_Blitter& operator=(const SkA1_Blitter&);
+
+ typedef SkRasterBlitter INHERITED;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
/* These return the correct subclass of blitter for their device config.
Currently, they make the following assumptions about the state of the
diff --git a/src/core/SkGlyphCache.cpp b/src/core/SkGlyphCache.cpp
index a78b197..faa3f89 100644
--- a/src/core/SkGlyphCache.cpp
+++ b/src/core/SkGlyphCache.cpp
@@ -87,6 +87,8 @@
fGlyphArray.setReserve(kMinGlyphCount);
+ fMetricsCount = 0;
+ fAdvanceCount = 0;
fAuxProcList = NULL;
}
@@ -318,9 +320,11 @@
if (kJustAdvance_MetricsType == mtype) {
fScalerContext->getAdvance(glyph);
+ fAdvanceCount += 1;
} else {
SkASSERT(kFull_MetricsType == mtype);
fScalerContext->getMetrics(glyph);
+ fMetricsCount += 1;
}
return glyph;
diff --git a/src/core/SkGlyphCache.h b/src/core/SkGlyphCache.h
index 7b2ebb8..52a8132 100644
--- a/src/core/SkGlyphCache.h
+++ b/src/core/SkGlyphCache.h
@@ -211,6 +211,8 @@
SkTDArray<SkGlyph*> fGlyphArray;
SkChunkAlloc fGlyphAlloc;
+ int fMetricsCount, fAdvanceCount;
+
struct CharGlyphRec {
uint32_t fID; // unichar + subpixel
SkGlyph* fGlyph;
diff --git a/src/core/SkPaint.cpp b/src/core/SkPaint.cpp
index 91a76e1..d6948dd 100644
--- a/src/core/SkPaint.cpp
+++ b/src/core/SkPaint.cpp
@@ -2005,7 +2005,11 @@
};
// The size of a flat paint's POD fields
-static const uint32_t kPODPaintSize = 5 * sizeof(SkScalar) +
+// Include an SkScalar for hinting scale factor whether it is
+// supported or not so that an SKP is valid whether it was
+// created with support or not.
+
+static const uint32_t kPODPaintSize = 6 * sizeof(SkScalar) +
1 * sizeof(SkColor) +
1 * sizeof(uint16_t) +
6 * sizeof(uint8_t);
@@ -2042,6 +2046,8 @@
ptr = write_scalar(ptr, this->getTextSize());
ptr = write_scalar(ptr, this->getTextScaleX());
ptr = write_scalar(ptr, this->getTextSkewX());
+ // Dummy value for obsolete hinting scale factor. TODO: remove with next picture version
+ ptr = write_scalar(ptr, SK_Scalar1);
ptr = write_scalar(ptr, this->getStrokeWidth());
ptr = write_scalar(ptr, this->getStrokeMiter());
*ptr++ = this->getColor();
@@ -2058,6 +2064,8 @@
buffer.writeScalar(fTextSize);
buffer.writeScalar(fTextScaleX);
buffer.writeScalar(fTextSkewX);
+ // Dummy value for obsolete hinting scale factor. TODO: remove with next picture version
+ buffer.writeScalar(SK_Scalar1);
buffer.writeScalar(fWidth);
buffer.writeScalar(fMiterLimit);
buffer.writeColor(fColor);
@@ -2112,6 +2120,8 @@
this->setTextSize(read_scalar(pod));
this->setTextScaleX(read_scalar(pod));
this->setTextSkewX(read_scalar(pod));
+ // Skip the hinting scalar factor, which is not supported.
+ read_scalar(pod);
this->setStrokeWidth(read_scalar(pod));
this->setStrokeMiter(read_scalar(pod));
this->setColor(*pod++);
diff --git a/src/core/SkPicture.cpp b/src/core/SkPicture.cpp
index 2520e6b..4acc549 100644
--- a/src/core/SkPicture.cpp
+++ b/src/core/SkPicture.cpp
@@ -266,20 +266,11 @@
#include "SkStream.h"
-static const char kMagic[] = { 's', 'k', 'i', 'a', 'p', 'i', 'c', 't' };
-
bool SkPicture::StreamIsSKP(SkStream* stream, SkPictInfo* pInfo) {
if (NULL == stream) {
return false;
}
- // Check magic bytes.
- char magic[sizeof(kMagic)];
- stream->read(magic, sizeof(kMagic));
- if (0 != memcmp(magic, kMagic, sizeof(kMagic))) {
- return false;
- }
-
SkPictInfo info;
if (!stream->read(&info, sizeof(SkPictInfo))) {
return false;
@@ -350,10 +341,6 @@
info.fFlags |= SkPictInfo::kPtrIs64Bit_Flag;
}
- // Write 8 magic bytes to ID this file format.
- SkASSERT(sizeof(kMagic) == 8);
- stream->write(kMagic, sizeof(kMagic));
-
stream->write(&info, sizeof(info));
if (playback) {
stream->writeBool(true);
diff --git a/src/core/SkScaledImageCache.cpp b/src/core/SkScaledImageCache.cpp
index 55eadb8..ea29843 100644
--- a/src/core/SkScaledImageCache.cpp
+++ b/src/core/SkScaledImageCache.cpp
@@ -49,7 +49,7 @@
return hash;
}
-struct SkScaledImageCache::Key {
+struct Key {
Key(uint32_t genID,
SkScalar scaleX,
SkScalar scaleY,
@@ -129,24 +129,22 @@
#include "SkTDynamicHash.h"
namespace { // can't use static functions w/ template parameters
-const SkScaledImageCache::Key& key_from_rec(const SkScaledImageCache::Rec& rec) {
+const Key& key_from_rec(const SkScaledImageCache::Rec& rec) {
return rec.fKey;
}
-uint32_t hash_from_key(const SkScaledImageCache::Key& key) {
+uint32_t hash_from_key(const Key& key) {
return key.fHash;
}
-bool eq_rec_key(const SkScaledImageCache::Rec& rec, const SkScaledImageCache::Key& key) {
+bool eq_rec_key(const SkScaledImageCache::Rec& rec, const Key& key) {
return rec.fKey == key;
}
}
class SkScaledImageCache::Hash : public SkTDynamicHash<SkScaledImageCache::Rec,
- SkScaledImageCache::Key,
- key_from_rec,
- hash_from_key,
- eq_rec_key> {};
+ Key, key_from_rec, hash_from_key,
+ eq_rec_key> {};
///////////////////////////////////////////////////////////////////////////////
@@ -189,22 +187,17 @@
////////////////////////////////////////////////////////////////////////////////
-
+/**
+ This private method is the fully general record finder. All other
+ record finders should call this funtion. */
SkScaledImageCache::Rec* SkScaledImageCache::findAndLock(uint32_t genID,
SkScalar scaleX,
SkScalar scaleY,
const SkIRect& bounds) {
- const Key key(genID, scaleX, scaleY, bounds);
- return this->findAndLock(key);
-}
-
-/**
- This private method is the fully general record finder. All other
- record finders should call this function or the one above. */
-SkScaledImageCache::Rec* SkScaledImageCache::findAndLock(const SkScaledImageCache::Key& key) {
- if (key.fBounds.isEmpty()) {
+ if (bounds.isEmpty()) {
return NULL;
}
+ Key key(genID, scaleX, scaleY, bounds);
#ifdef USE_HASH
Rec* rec = fHash->find(key);
#else
@@ -282,14 +275,8 @@
/**
This private method is the fully general record adder. All other
record adders should call this funtion. */
-SkScaledImageCache::ID* SkScaledImageCache::addAndLock(SkScaledImageCache::Rec* rec) {
+void SkScaledImageCache::addAndLock(SkScaledImageCache::Rec* rec) {
SkASSERT(rec);
- // See if we already have this key (racy inserts, etc.)
- Rec* existing = this->findAndLock(rec->fKey);
- if (existing != NULL) {
- return rec_to_id(existing);
- }
-
this->addToHead(rec);
SkASSERT(1 == rec->fLockCount);
#ifdef USE_HASH
@@ -298,7 +285,6 @@
#endif
// We may (now) be overbudget, so see if we need to purge something.
this->purgeAsNeeded();
- return rec_to_id(rec);
}
SkScaledImageCache::ID* SkScaledImageCache::addAndLock(uint32_t genID,
@@ -307,7 +293,8 @@
const SkBitmap& bitmap) {
Key key(genID, SK_Scalar1, SK_Scalar1, SkIRect::MakeWH(width, height));
Rec* rec = SkNEW_ARGS(Rec, (key, bitmap));
- return this->addAndLock(rec);
+ this->addAndLock(rec);
+ return rec_to_id(rec);
}
SkScaledImageCache::ID* SkScaledImageCache::addAndLock(const SkBitmap& orig,
@@ -324,7 +311,8 @@
}
Key key(orig.getGenerationID(), scaleX, scaleY, bounds);
Rec* rec = SkNEW_ARGS(Rec, (key, scaled));
- return this->addAndLock(rec);
+ this->addAndLock(rec);
+ return rec_to_id(rec);
}
SkScaledImageCache::ID* SkScaledImageCache::addAndLockMip(const SkBitmap& orig,
@@ -335,7 +323,8 @@
}
Key key(orig.getGenerationID(), 0, 0, bounds);
Rec* rec = SkNEW_ARGS(Rec, (key, mip));
- return this->addAndLock(rec);
+ this->addAndLock(rec);
+ return rec_to_id(rec);
}
void SkScaledImageCache::unlock(SkScaledImageCache::ID* id) {
diff --git a/src/core/SkScaledImageCache.h b/src/core/SkScaledImageCache.h
index 44ef1f8..fee69d2 100644
--- a/src/core/SkScaledImageCache.h
+++ b/src/core/SkScaledImageCache.h
@@ -126,7 +126,6 @@
public:
struct Rec;
- struct Key;
private:
Rec* fHead;
Rec* fTail;
@@ -140,8 +139,7 @@
Rec* findAndLock(uint32_t generationID, SkScalar sx, SkScalar sy,
const SkIRect& bounds);
- Rec* findAndLock(const Key& key);
- ID* addAndLock(Rec* rec);
+ void addAndLock(Rec* rec);
void purgeAsNeeded();
diff --git a/src/core/SkScalerContext.cpp b/src/core/SkScalerContext.cpp
index 4996a73..1d6c2f7 100644
--- a/src/core/SkScalerContext.cpp
+++ b/src/core/SkScalerContext.cpp
@@ -352,16 +352,16 @@
glyph->fHeight = SkToU16(ir.height());
if (glyph->fWidth > 0) {
- switch (fRec.fMaskFormat) {
- case SkMask::kLCD16_Format:
- case SkMask::kLCD32_Format:
- glyph->fWidth += 2;
- glyph->fLeft -= 1;
- break;
- default:
- break;
- }
+ switch (fRec.fMaskFormat) {
+ case SkMask::kLCD16_Format:
+ case SkMask::kLCD32_Format:
+ glyph->fWidth += 2;
+ glyph->fLeft -= 1;
+ break;
+ default:
+ break;
}
+ }
}
}
@@ -523,54 +523,10 @@
}
}
-static inline int convert_8_to_1(unsigned byte) {
- SkASSERT(byte <= 0xFF);
- return byte >> 7;
-}
-
-static uint8_t pack_8_to_1(const uint8_t alpha[8]) {
- unsigned bits = 0;
- for (int i = 0; i < 8; ++i) {
- bits <<= 1;
- bits |= convert_8_to_1(alpha[i]);
- }
- return SkToU8(bits);
-}
-
-static void packA8ToA1(const SkMask& mask, const uint8_t* src, size_t srcRB) {
- const int height = mask.fBounds.height();
- const int width = mask.fBounds.width();
- const int octs = width >> 3;
- const int leftOverBits = width & 7;
-
- uint8_t* dst = mask.fImage;
- const int dstPad = mask.fRowBytes - SkAlign8(width)/8;
- SkASSERT(dstPad >= 0);
-
- const int srcPad = srcRB - width;
- SkASSERT(srcPad >= 0);
-
- for (int y = 0; y < height; ++y) {
- for (int i = 0; i < octs; ++i) {
- *dst++ = pack_8_to_1(src);
- src += 8;
- }
- if (leftOverBits > 0) {
- unsigned bits = 0;
- int shift = 7;
- for (int i = 0; i < leftOverBits; ++i, --shift) {
- bits |= convert_8_to_1(*src++ >> 7) << shift;
- }
- *dst++ = bits;
- }
- src += srcPad;
- dst += dstPad;
- }
-}
-
static void generateMask(const SkMask& mask, const SkPath& path,
const SkMaskGamma::PreBlend& maskPreBlend) {
- SkPaint paint;
+ SkBitmap::Config config;
+ SkPaint paint;
int srcW = mask.fBounds.width();
int srcH = mask.fBounds.height();
@@ -582,25 +538,27 @@
matrix.setTranslate(-SkIntToScalar(mask.fBounds.fLeft),
-SkIntToScalar(mask.fBounds.fTop));
- SkBitmap::Config config = SkBitmap::kA8_Config;
- paint.setAntiAlias(SkMask::kBW_Format != mask.fFormat);
- switch (mask.fFormat) {
- case SkMask::kBW_Format:
- dstRB = 0; // signals we need a copy
- break;
- case SkMask::kA8_Format:
- break;
- case SkMask::kLCD16_Format:
- case SkMask::kLCD32_Format:
- // TODO: trigger off LCD orientation
- dstW = 4*dstW - 8;
- matrix.setTranslate(-SkIntToScalar(mask.fBounds.fLeft + 1),
- -SkIntToScalar(mask.fBounds.fTop));
- matrix.postScale(SkIntToScalar(4), SK_Scalar1);
- dstRB = 0; // signals we need a copy
- break;
- default:
- SkDEBUGFAIL("unexpected mask format");
+ if (SkMask::kBW_Format == mask.fFormat) {
+ config = SkBitmap::kA1_Config;
+ paint.setAntiAlias(false);
+ } else {
+ config = SkBitmap::kA8_Config;
+ paint.setAntiAlias(true);
+ switch (mask.fFormat) {
+ case SkMask::kA8_Format:
+ break;
+ case SkMask::kLCD16_Format:
+ case SkMask::kLCD32_Format:
+ // TODO: trigger off LCD orientation
+ dstW = 4*dstW - 8;
+ matrix.setTranslate(-SkIntToScalar(mask.fBounds.fLeft + 1),
+ -SkIntToScalar(mask.fBounds.fTop));
+ matrix.postScale(SkIntToScalar(4), SK_Scalar1);
+ dstRB = 0; // signals we need a copy
+ break;
+ default:
+ SkDEBUGFAIL("unexpected mask format");
+ }
}
SkRasterClip clip;
@@ -629,9 +587,6 @@
draw.drawPath(path, paint);
switch (mask.fFormat) {
- case SkMask::kBW_Format:
- packA8ToA1(mask, bm.getAddr8(0, 0), bm.rowBytes());
- break;
case SkMask::kA8_Format:
if (maskPreBlend.isApplicable()) {
applyLUTToA8Mask(mask, maskPreBlend.fG);
diff --git a/src/core/SkScalerContext.h b/src/core/SkScalerContext.h
index e4950ed..2820b5a 100644
--- a/src/core/SkScalerContext.h
+++ b/src/core/SkScalerContext.h
@@ -202,57 +202,16 @@
Rec fRec;
unsigned fBaseGlyphCount;
- /** Generates the contents of glyph.fAdvanceX and glyph.fAdvanceY.
- * May call getMetrics if that would be just as fast.
- */
- virtual void generateAdvance(SkGlyph* glyph) = 0;
-
- /** Generates the contents of glyph.fWidth, fHeight, fTop, fLeft,
- * as well as fAdvanceX and fAdvanceY if not already set.
- *
- * TODO: fMaskFormat is set by getMetrics later; cannot be set here.
- */
- virtual void generateMetrics(SkGlyph* glyph) = 0;
-
- /** Generates the contents of glyph.fImage.
- * When called, glyph.fImage will be pointing to a pre-allocated,
- * uninitialized region of memory of size glyph.computeImageSize().
- * This method may change glyph.fMaskFormat if the new image size is
- * less than or equal to the old image size.
- *
- * Because glyph.computeImageSize() will determine the size of fImage,
- * generateMetrics will be called before generateImage.
- */
- virtual void generateImage(const SkGlyph& glyph) = 0;
-
- /** Sets the passed path to the glyph outline.
- * If this cannot be done the path is set to empty;
- * this is indistinguishable from a glyph with an empty path.
- * This does not set glyph.fPath.
- *
- * TODO: path is always glyph.fPath, no reason to pass separately.
- */
- virtual void generatePath(const SkGlyph& glyph, SkPath* path) = 0;
-
- /** Retrieves font metrics.
- * TODO: there is now a vertical bit, no need for two parameters.
- */
+ virtual unsigned generateGlyphCount() = 0;
+ virtual uint16_t generateCharToGlyph(SkUnichar) = 0;
+ virtual void generateAdvance(SkGlyph*) = 0;
+ virtual void generateMetrics(SkGlyph*) = 0;
+ virtual void generateImage(const SkGlyph&) = 0;
+ virtual void generatePath(const SkGlyph&, SkPath*) = 0;
virtual void generateFontMetrics(SkPaint::FontMetrics* mX,
SkPaint::FontMetrics* mY) = 0;
-
- /** Returns the number of glyphs in the font. */
- virtual unsigned generateGlyphCount() = 0;
-
- /** Returns the glyph id for the given unichar.
- * If there is no 1:1 mapping from the unichar to a glyph id, returns 0.
- */
- virtual uint16_t generateCharToGlyph(SkUnichar unichar) = 0;
-
- /** Returns the unichar for the given glyph id.
- * If there is no 1:1 mapping from the glyph id to a unichar, returns 0.
- * The default implementation always returns 0, indicating failure.
- */
- virtual SkUnichar generateGlyphToChar(uint16_t glyphId);
+ // default impl returns 0, indicating failure.
+ virtual SkUnichar generateGlyphToChar(uint16_t);
void forceGenerateImageFromPath() { fGenerateImageFromPath = true; }
diff --git a/src/core/SkString.cpp b/src/core/SkString.cpp
index 643dfb1..e30b89f 100644
--- a/src/core/SkString.cpp
+++ b/src/core/SkString.cpp
@@ -634,17 +634,5 @@
return formattedOutput;
}
-void SkStrSplit(const char* str, const char* delimiters, SkTArray<SkString>* out) {
- const char* end = str + strlen(str);
- while (str != end) {
- // Find a token.
- const size_t len = strcspn(str, delimiters);
- out->push_back().set(str, len);
- str += len;
- // Skip any delimiters.
- str += strspn(str, delimiters);
- }
-}
-
#undef VSNPRINTF
#undef SNPRINTF
diff --git a/src/core/SkValidatingReadBuffer.cpp b/src/core/SkValidatingReadBuffer.cpp
index 4a8ac47..a92c1b9 100644
--- a/src/core/SkValidatingReadBuffer.cpp
+++ b/src/core/SkValidatingReadBuffer.cpp
@@ -203,7 +203,7 @@
uint32_t SkValidatingReadBuffer::getArrayCount() {
const size_t inc = sizeof(uint32_t);
fError = fError || !IsPtrAlign4(fReader.peek()) || !fReader.isAvailable(inc);
- return fError ? 0 : *(uint32_t*)fReader.peek();
+ return *(uint32_t*)fReader.peek();
}
void SkValidatingReadBuffer::readBitmap(SkBitmap* bitmap) {
diff --git a/src/effects/SkDropShadowImageFilter.cpp b/src/effects/SkDropShadowImageFilter.cpp
index 5be633e..b4d8689 100644
--- a/src/effects/SkDropShadowImageFilter.cpp
+++ b/src/effects/SkDropShadowImageFilter.cpp
@@ -15,21 +15,10 @@
#include "SkFlattenableBuffers.h"
SkDropShadowImageFilter::SkDropShadowImageFilter(SkScalar dx, SkScalar dy, SkScalar sigma, SkColor color, SkImageFilter* input)
- : INHERITED(input)
+ : SkImageFilter(input)
, fDx(dx)
, fDy(dy)
- , fSigmaX(sigma)
- , fSigmaY(sigma)
- , fColor(color)
-{
-}
-
-SkDropShadowImageFilter::SkDropShadowImageFilter(SkScalar dx, SkScalar dy, SkScalar sigmaX, SkScalar sigmaY, SkColor color, SkImageFilter* input, const CropRect* cropRect)
- : INHERITED(input, cropRect)
- , fDx(dx)
- , fDy(dy)
- , fSigmaX(sigmaX)
- , fSigmaY(sigmaY)
+ , fSigma(sigma)
, fColor(color)
{
}
@@ -38,13 +27,11 @@
: INHERITED(1, buffer) {
fDx = buffer.readScalar();
fDy = buffer.readScalar();
- fSigmaX = buffer.readScalar();
- fSigmaY = buffer.readScalar();
+ fSigma = buffer.readScalar();
fColor = buffer.readColor();
buffer.validate(SkScalarIsFinite(fDx) &&
SkScalarIsFinite(fDy) &&
- SkScalarIsFinite(fSigmaX) &&
- SkScalarIsFinite(fSigmaY));
+ SkScalarIsFinite(fSigma));
}
void SkDropShadowImageFilter::flatten(SkFlattenableWriteBuffer& buffer) const
@@ -52,8 +39,7 @@
this->INHERITED::flatten(buffer);
buffer.writeScalar(fDx);
buffer.writeScalar(fDy);
- buffer.writeScalar(fSigmaX);
- buffer.writeScalar(fSigmaY);
+ buffer.writeScalar(fSigma);
buffer.writeColor(fColor);
}
@@ -63,26 +49,17 @@
if (getInput(0) && !getInput(0)->filterImage(proxy, source, matrix, &src, loc))
return false;
- SkIRect bounds;
- src.getBounds(&bounds);
- if (!this->applyCropRect(&bounds, matrix)) {
- return false;
- }
-
- SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(bounds.width(), bounds.height()));
+ SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(src.width(), src.height()));
SkCanvas canvas(device.get());
- SkAutoTUnref<SkImageFilter> blurFilter(new SkBlurImageFilter(fSigmaX, fSigmaY));
+ SkAutoTUnref<SkImageFilter> blurFilter(new SkBlurImageFilter(fSigma, fSigma));
SkAutoTUnref<SkColorFilter> colorFilter(SkColorFilter::CreateModeFilter(fColor, SkXfermode::kSrcIn_Mode));
SkPaint paint;
paint.setImageFilter(blurFilter.get());
paint.setColorFilter(colorFilter.get());
paint.setXfermodeMode(SkXfermode::kSrcOver_Mode);
- canvas.translate(-SkIntToScalar(bounds.fLeft), -SkIntToScalar(bounds.fTop));
canvas.drawBitmap(src, fDx, fDy, &paint);
canvas.drawBitmap(src, 0, 0);
*result = device->accessBitmap(false);
- loc->fX += bounds.fLeft;
- loc->fY += bounds.fTop;
return true;
}
diff --git a/src/effects/SkTransparentShader.cpp b/src/effects/SkTransparentShader.cpp
index 1d7e808..970e74f 100644
--- a/src/effects/SkTransparentShader.cpp
+++ b/src/effects/SkTransparentShader.cpp
@@ -94,6 +94,9 @@
}
break;
}
+ case SkBitmap::kA1_Config:
+ SkDEBUGFAIL("kA1_Config umimplemented at this time");
+ break;
default: // to avoid warnings
break;
}
diff --git a/src/fonts/SkGScalerContext.cpp b/src/fonts/SkGScalerContext.cpp
index 551b01c..f0543c5 100644
--- a/src/fonts/SkGScalerContext.cpp
+++ b/src/fonts/SkGScalerContext.cpp
@@ -176,8 +176,6 @@
void SkGTypeface::onFilterRec(SkScalerContextRec* rec) const {
fProxy->filterRec(rec);
- rec->setHinting(SkPaint::kNo_Hinting);
- rec->fMaskFormat = SkMask::kARGB32_Format;
}
SkAdvancedTypefaceMetrics* SkGTypeface::onGetAdvancedTypefaceMetrics(
diff --git a/src/gpu/GrBinHashKey.h b/src/gpu/GrBinHashKey.h
index 585a1a1..7d4aa0f 100644
--- a/src/gpu/GrBinHashKey.h
+++ b/src/gpu/GrBinHashKey.h
@@ -13,19 +13,37 @@
#include "GrTypes.h"
/**
- * GrBinHashKey is a hash key class that can take a data chunk of any predetermined
- * length. The hash function used is the One-at-a-Time Hash
- * (http://burtleburtle.net/bob/hash/doobs.html).
+ * Hash function class that can take a data chunk of any predetermined length. The hash function
+ * used is the One-at-a-Time Hash (http://burtleburtle.net/bob/hash/doobs.html).
+ *
+ * Keys are computed from ENTRY objects. ENTRY must be fully ordered by a member:
+ * int compare(const GrTBinHashKey<ENTRY, ..>& k);
+ * which returns negative if the ENTRY < k, 0 if it equals k, and positive if k < the ENTRY.
+ * Additionally, ENTRY must be flattenable into the key using setKeyData.
+ *
+ * This class satisfies the requirements to be a key for a GrTHashTable.
*/
-template<size_t KEY_SIZE>
-class GrBinHashKey {
+template<typename ENTRY, size_t KEY_SIZE>
+class GrTBinHashKey {
public:
enum { kKeySize = KEY_SIZE };
- GrBinHashKey() {
+ GrTBinHashKey() {
this->reset();
}
+ GrTBinHashKey(const GrTBinHashKey<ENTRY, KEY_SIZE>& other) {
+ *this = other;
+ }
+
+ GrTBinHashKey<ENTRY, KEY_SIZE>& operator=(const GrTBinHashKey<ENTRY, KEY_SIZE>& other) {
+ memcpy(this, &other, sizeof(*this));
+ return *this;
+ }
+
+ ~GrTBinHashKey() {
+ }
+
void reset() {
fHash = 0;
#ifdef SK_DEBUG
@@ -34,49 +52,39 @@
}
void setKeyData(const uint32_t* SK_RESTRICT data) {
- SK_COMPILE_ASSERT(KEY_SIZE % 4 == 0, key_size_mismatch);
+ SkASSERT(GrIsALIGN4(KEY_SIZE));
memcpy(&fData, data, KEY_SIZE);
uint32_t hash = 0;
size_t len = KEY_SIZE;
while (len >= 4) {
hash += *data++;
- hash += (hash << 10);
+ hash += (fHash << 10);
hash ^= (hash >> 6);
len -= 4;
}
- hash += (hash << 3);
- hash ^= (hash >> 11);
- hash += (hash << 15);
+ hash += (fHash << 3);
+ hash ^= (fHash >> 11);
+ hash += (fHash << 15);
#ifdef SK_DEBUG
fIsValid = true;
#endif
fHash = hash;
}
- bool operator==(const GrBinHashKey<KEY_SIZE>& key) const {
+ int compare(const GrTBinHashKey<ENTRY, KEY_SIZE>& key) const {
SkASSERT(fIsValid && key.fIsValid);
- if (fHash != key.fHash) {
- return false;
- }
- for (size_t i = 0; i < SK_ARRAY_COUNT(fData); ++i) {
- if (fData[i] != key.fData[i]) {
- return false;
- }
- }
- return true;
+ return memcmp(fData, key.fData, KEY_SIZE);
}
- bool operator<(const GrBinHashKey<KEY_SIZE>& key) const {
- SkASSERT(fIsValid && key.fIsValid);
- for (size_t i = 0; i < SK_ARRAY_COUNT(fData); ++i) {
- if (fData[i] < key.fData[i]) {
- return true;
- } else if (fData[i] > key.fData[i]) {
- return false;
- }
- }
- return false;
+ static bool EQ(const ENTRY& entry, const GrTBinHashKey<ENTRY, KEY_SIZE>& key) {
+ SkASSERT(key.fIsValid);
+ return 0 == entry.compare(key);
+ }
+
+ static bool LT(const ENTRY& entry, const GrTBinHashKey<ENTRY, KEY_SIZE>& key) {
+ SkASSERT(key.fIsValid);
+ return entry.compare(key) < 0;
}
uint32_t getHash() const {
@@ -86,12 +94,12 @@
const uint8_t* getData() const {
SkASSERT(fIsValid);
- return reinterpret_cast<const uint8_t*>(fData);
+ return fData;
}
private:
uint32_t fHash;
- uint32_t fData[KEY_SIZE / sizeof(uint32_t)]; // Buffer for key storage.
+ uint8_t fData[KEY_SIZE]; // Buffer for key storage
#ifdef SK_DEBUG
public:
diff --git a/src/gpu/GrResourceCache.h b/src/gpu/GrResourceCache.h
index ca30732..38378ac 100644
--- a/src/gpu/GrResourceCache.h
+++ b/src/gpu/GrResourceCache.h
@@ -54,7 +54,7 @@
}
GrResourceKey() {
- fKey.reset();
+ fKey.fHashedKey.reset();
}
void reset(const GrCacheID& id, ResourceType type, ResourceFlags flags) {
@@ -63,34 +63,41 @@
//!< returns hash value [0..kHashMask] for the key
int getHash() const {
- return fKey.getHash() & kHashMask;
+ return fKey.fHashedKey.getHash() & kHashMask;
}
bool isScratch() const {
return ScratchDomain() ==
- *reinterpret_cast<const GrCacheID::Domain*>(fKey.getData() +
+ *reinterpret_cast<const GrCacheID::Domain*>(fKey.fHashedKey.getData() +
kCacheIDDomainOffset);
}
ResourceType getResourceType() const {
- return *reinterpret_cast<const ResourceType*>(fKey.getData() +
+ return *reinterpret_cast<const ResourceType*>(fKey.fHashedKey.getData() +
kResourceTypeOffset);
}
ResourceFlags getResourceFlags() const {
- return *reinterpret_cast<const ResourceFlags*>(fKey.getData() +
+ return *reinterpret_cast<const ResourceFlags*>(fKey.fHashedKey.getData() +
kResourceFlagsOffset);
}
- bool operator==(const GrResourceKey& other) const { return fKey == other.fKey; }
- bool operator<(const GrResourceKey& other) const { return fKey < other.fKey; }
+ int compare(const GrResourceKey& other) const {
+ return fKey.fHashedKey.compare(other.fKey.fHashedKey);
+ }
- static bool LessThan(const GrResourceEntry& entry, const GrResourceKey& key);
- static bool Equals(const GrResourceEntry& entry, const GrResourceKey& key);
-#ifdef SK_DEBUG
- static bool LessThan(const GrResourceEntry& a, const GrResourceEntry& b);
- static bool Equals(const GrResourceEntry& a, const GrResourceEntry& b);
-#endif
+ static bool LT(const GrResourceKey& a, const GrResourceKey& b) {
+ return a.compare(b) < 0;
+ }
+
+ static bool EQ(const GrResourceKey& a, const GrResourceKey& b) {
+ return 0 == a.compare(b);
+ }
+
+ inline static bool LT(const GrResourceEntry& entry, const GrResourceKey& key);
+ inline static bool EQ(const GrResourceEntry& entry, const GrResourceKey& key);
+ inline static bool LT(const GrResourceEntry& a, const GrResourceEntry& b);
+ inline static bool EQ(const GrResourceEntry& a, const GrResourceEntry& b);
private:
enum {
@@ -118,9 +125,21 @@
memcpy(k + kResourceTypeOffset, &type, sizeof(ResourceType));
memcpy(k + kResourceFlagsOffset, &flags, sizeof(ResourceFlags));
memset(k + kPadOffset, 0, kPadSize);
- fKey.setKeyData(keyData.fKey32);
+ fKey.fHashedKey.setKeyData(keyData.fKey32);
}
- GrBinHashKey<kKeySize> fKey;
+
+ struct Key;
+ typedef GrTBinHashKey<Key, kKeySize> HashedKey;
+
+ struct Key {
+ int compare(const HashedKey& hashedKey) const {
+ return fHashedKey.compare(hashedKey);
+ }
+
+ HashedKey fHashedKey;
+ };
+
+ Key fKey;
};
// The cache listens for these messages to purge junk resources proactively.
@@ -155,23 +174,21 @@
friend class GrDLinkedList;
};
-inline bool GrResourceKey::LessThan(const GrResourceEntry& entry, const GrResourceKey& key) {
- return entry.key() < key;
+bool GrResourceKey::LT(const GrResourceEntry& entry, const GrResourceKey& key) {
+ return LT(entry.key(), key);
}
-inline bool GrResourceKey::Equals(const GrResourceEntry& entry, const GrResourceKey& key) {
- return entry.key() == key;
+bool GrResourceKey::EQ(const GrResourceEntry& entry, const GrResourceKey& key) {
+ return EQ(entry.key(), key);
}
-#ifdef SK_DEBUG
-inline bool GrResourceKey::LessThan(const GrResourceEntry& a, const GrResourceEntry& b) {
- return a.key() < b.key();
+bool GrResourceKey::LT(const GrResourceEntry& a, const GrResourceEntry& b) {
+ return LT(a.key(), b.key());
}
-inline bool GrResourceKey::Equals(const GrResourceEntry& a, const GrResourceEntry& b) {
- return a.key() == b.key();
+bool GrResourceKey::EQ(const GrResourceEntry& a, const GrResourceEntry& b) {
+ return EQ(a.key(), b.key());
}
-#endif
///////////////////////////////////////////////////////////////////////////////
diff --git a/src/gpu/GrTHashTable.h b/src/gpu/GrTHashTable.h
index 83462c7..3b32977 100644
--- a/src/gpu/GrTHashTable.h
+++ b/src/gpu/GrTHashTable.h
@@ -16,10 +16,8 @@
/**
* Key needs
- * static bool Equals(const Entry&, const Key&);
- * static bool LessThan(const Entry&, const Key&);
- * static bool Equals(const Entry&, const Entry&); for SK_DEBUG if GrTHashTable::validate() is called
- * static bool LessThan(const Entry&, const Entry&); for SK_DEBUG if GrTHashTable::validate() is called
+ * static bool EQ(const Entry&, const HashKey&);
+ * static bool LT(const Entry&, const HashKey&);
* uint32_t getHash() const;
*
* Allows duplicate key entries but on find you may get
@@ -92,7 +90,7 @@
int low = 0;
while (high > low) {
int index = (low + high) >> 1;
- if (Key::LessThan(*array[index], key)) {
+ if (Key::LT(*array[index], key)) {
low = index + 1;
} else {
high = index;
@@ -100,15 +98,15 @@
}
// check if we found it
- if (Key::Equals(*array[high], key)) {
+ if (Key::EQ(*array[high], key)) {
// above search should have found the first occurrence if there
// are multiple.
- SkASSERT(0 == high || Key::LessThan(*array[high - 1], key));
+ SkASSERT(0 == high || Key::LT(*array[high - 1], key));
return high;
}
// now return the ~ of where we should insert it
- if (Key::LessThan(*array[high], key)) {
+ if (Key::LT(*array[high], key)) {
high += 1;
}
return ~high;
@@ -121,7 +119,7 @@
int hashIndex = hash2Index(key.getHash());
T* elem = fHash[hashIndex];
- if (NULL != elem && Key::Equals(*elem, key) && filter(elem)) {
+ if (NULL != elem && Key::EQ(*elem, key) && filter(elem)) {
return elem;
}
@@ -135,9 +133,9 @@
// above search should have found the first occurrence if there
// are multiple.
- SkASSERT(0 == index || Key::LessThan(*array[index - 1], key));
+ SkASSERT(0 == index || Key::LT(*array[index - 1], key));
- for ( ; index < count() && Key::Equals(*array[index], key); ++index) {
+ for ( ; index < count() && Key::EQ(*array[index], key); ++index) {
if (filter(fSorted[index])) {
// update the hash
fHash[hashIndex] = fSorted[index];
@@ -194,8 +192,8 @@
void GrTHashTable<T, Key, kHashBits>::validate() const {
int count = fSorted.count();
for (int i = 1; i < count; i++) {
- SkASSERT(Key::LessThan(*fSorted[i - 1], *fSorted[i]) ||
- Key::Equals(*fSorted[i - 1], *fSorted[i]));
+ SkASSERT(Key::LT(*fSorted[i - 1], *fSorted[i]) ||
+ Key::EQ(*fSorted[i - 1], *fSorted[i]));
}
}
diff --git a/src/gpu/GrTextStrike_impl.h b/src/gpu/GrTextStrike_impl.h
index 0691eaa..4297185 100644
--- a/src/gpu/GrTextStrike_impl.h
+++ b/src/gpu/GrTextStrike_impl.h
@@ -19,10 +19,10 @@
intptr_t getHash() const { return fFontScalerKey->getHash(); }
- static bool LessThan(const GrTextStrike& strike, const Key& key) {
+ static bool LT(const GrTextStrike& strike, const Key& key) {
return *strike.getFontScalerKey() < *key.fFontScalerKey;
}
- static bool Equals(const GrTextStrike& strike, const Key& key) {
+ static bool EQ(const GrTextStrike& strike, const Key& key) {
return *strike.getFontScalerKey() == *key.fFontScalerKey;
}
@@ -88,10 +88,10 @@
uint32_t getHash() const { return fPackedID; }
- static bool LessThan(const GrGlyph& glyph, const Key& key) {
+ static bool LT(const GrGlyph& glyph, const Key& key) {
return glyph.fPackedID < key.fPackedID;
}
- static bool Equals(const GrGlyph& glyph, const Key& key) {
+ static bool EQ(const GrGlyph& glyph, const Key& key) {
return glyph.fPackedID == key.fPackedID;
}
diff --git a/src/gpu/SkGrFontScaler.cpp b/src/gpu/SkGrFontScaler.cpp
index 1ca9357..6514866 100644
--- a/src/gpu/SkGrFontScaler.cpp
+++ b/src/gpu/SkGrFontScaler.cpp
@@ -85,8 +85,6 @@
return kA8_GrMaskFormat;
case SkMask::kLCD16_Format:
return kA565_GrMaskFormat;
- // TODO: properly support kARGB32_Format.
- case SkMask::kARGB32_Format:
case SkMask::kLCD32_Format:
return kA888_GrMaskFormat;
default:
diff --git a/src/gpu/effects/GrTextureStripAtlas.h b/src/gpu/effects/GrTextureStripAtlas.h
index e06e273..e56e736 100644
--- a/src/gpu/effects/GrTextureStripAtlas.h
+++ b/src/gpu/effects/GrTextureStripAtlas.h
@@ -136,15 +136,12 @@
// Hash table entry for atlases
class AtlasEntry;
- class AtlasHashKey : public GrBinHashKey<sizeof(GrTextureStripAtlas::Desc)> {
- public:
- static bool Equals(const AtlasEntry& entry, const AtlasHashKey& key);
- static bool LessThan(const AtlasEntry& entry, const AtlasHashKey& key);
- };
+ typedef GrTBinHashKey<AtlasEntry, sizeof(GrTextureStripAtlas::Desc)> AtlasHashKey;
class AtlasEntry : public ::SkNoncopyable {
public:
AtlasEntry() : fAtlas(NULL) {}
~AtlasEntry() { SkDELETE(fAtlas); }
+ int compare(const AtlasHashKey& key) const { return fKey.compare(key); }
AtlasHashKey fKey;
GrTextureStripAtlas* fAtlas;
};
@@ -181,14 +178,4 @@
SkTDArray<AtlasRow*> fKeyTable;
};
-inline bool GrTextureStripAtlas::AtlasHashKey::Equals(const AtlasEntry& entry,
- const AtlasHashKey& key) {
- return entry.fKey == key;
-}
-
-inline bool GrTextureStripAtlas::AtlasHashKey::LessThan(const AtlasEntry& entry,
- const AtlasHashKey& key) {
- return entry.fKey < key;
-}
-
#endif
diff --git a/src/gpu/gl/GrGpuGL.cpp b/src/gpu/gl/GrGpuGL.cpp
index 00d27b3..9cf39b6 100644
--- a/src/gpu/gl/GrGpuGL.cpp
+++ b/src/gpu/gl/GrGpuGL.cpp
@@ -1276,7 +1276,6 @@
return;
}
}
-
this->flushRenderTarget(rect);
GrAutoTRestore<ScissorState> asr(&fScissorState);
fScissorState.fEnabled = (NULL != rect);
@@ -1523,16 +1522,10 @@
if (fHWBoundRenderTarget != rt) {
GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, rt->renderFBOID()));
#ifdef SK_DEBUG
- // don't do this check in Chromium -- this is causing
- // lots of repeated command buffer flushes when the compositor is
- // rendering with Ganesh, which is really slow; even too slow for
- // Debug mode.
- if (!this->glContext().info().isChromium()) {
- GrGLenum status;
- GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER));
- if (status != GR_GL_FRAMEBUFFER_COMPLETE) {
- GrPrintf("GrGpuGL::flushRenderTarget glCheckFramebufferStatus %x\n", status);
- }
+ GrGLenum status;
+ GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER));
+ if (status != GR_GL_FRAMEBUFFER_COMPLETE) {
+ GrPrintf("GrGpuGL::flushRenderTarget glCheckFramebufferStatus %x\n", status);
}
#endif
fHWBoundRenderTarget = rt;
diff --git a/src/gpu/gr_unittests.cpp b/src/gpu/gr_unittests.cpp
new file mode 100644
index 0000000..ae9f67f
--- /dev/null
+++ b/src/gpu/gr_unittests.cpp
@@ -0,0 +1,80 @@
+
+/*
+ * 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 "GrBinHashKey.h"
+#include "GrDrawTarget.h"
+#include "SkMatrix.h"
+#include "GrRedBlackTree.h"
+
+// FIXME: needs to be in a header
+void gr_run_unittests();
+
+// If we aren't inheriting these as #defines from elsewhere,
+// clang demands they be declared before we #include the template
+// that relies on them.
+#ifdef SK_DEBUG
+static bool LT(const int& elem, int value) {
+ return elem < value;
+}
+static bool EQ(const int& elem, int value) {
+ return elem == value;
+}
+#include "GrTBSearch.h"
+
+static void test_bsearch() {
+ const int array[] = {
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 22, 33, 44, 55, 66, 77, 88, 99
+ };
+
+ for (int n = 0; n < static_cast<int>(GR_ARRAY_COUNT(array)); ++n) {
+ for (int i = 0; i < n; i++) {
+ int index = GrTBSearch<int, int>(array, n, array[i]);
+ SkASSERT(index == (int) i);
+ index = GrTBSearch<int, int>(array, n, -array[i]);
+ SkASSERT(index < 0);
+ }
+ }
+}
+#endif
+
+// bogus empty class for GrBinHashKey
+class BogusEntry {};
+
+static void test_binHashKey()
+{
+ const char* testStringA_ = "abcdABCD";
+ const char* testStringB_ = "abcdBBCD";
+ const uint32_t* testStringA = reinterpret_cast<const uint32_t*>(testStringA_);
+ const uint32_t* testStringB = reinterpret_cast<const uint32_t*>(testStringB_);
+ enum {
+ kDataLenUsedForKey = 8
+ };
+
+ GrTBinHashKey<BogusEntry, kDataLenUsedForKey> keyA;
+ keyA.setKeyData(testStringA);
+ // test copy constructor and comparison
+ GrTBinHashKey<BogusEntry, kDataLenUsedForKey> keyA2(keyA);
+ SkASSERT(keyA.compare(keyA2) == 0);
+ SkASSERT(keyA.getHash() == keyA2.getHash());
+ // test re-init
+ keyA2.setKeyData(testStringA);
+ SkASSERT(keyA.compare(keyA2) == 0);
+ SkASSERT(keyA.getHash() == keyA2.getHash());
+ // test sorting
+ GrTBinHashKey<BogusEntry, kDataLenUsedForKey> keyB;
+ keyB.setKeyData(testStringB);
+ SkASSERT(keyA.compare(keyB) < 0);
+ SkASSERT(keyA.getHash() != keyB.getHash());
+}
+
+
+void gr_run_unittests() {
+ SkDEBUGCODE(test_bsearch();)
+ test_binHashKey();
+ GrRedBlackTree<int>::UnitTest();
+}
diff --git a/src/opts/SkBlitMask_opts_arm.cpp b/src/opts/SkBlitMask_opts_arm.cpp
index 2bf7603..0ad0919 100644
--- a/src/opts/SkBlitMask_opts_arm.cpp
+++ b/src/opts/SkBlitMask_opts_arm.cpp
@@ -1,39 +1,14 @@
-#include "SkColor.h"
-#include "SkColorPriv.h"
#include "SkBlitMask.h"
-#include "SkUtilsArm.h"
-#include "SkBlitMask_opts_arm_neon.h"
SkBlitMask::ColorProc SkBlitMask::PlatformColorProcs(SkBitmap::Config dstConfig,
SkMask::Format maskFormat,
SkColor color) {
-#if SK_ARM_NEON_IS_NONE
- return NULL;
-#else
-#if SK_ARM_NEON_IS_DYNAMIC
- if (!sk_cpu_arm_has_neon()) {
- return NULL;
- }
-#endif
- if ((SkBitmap::kARGB_8888_Config == dstConfig) &&
- (SkMask::kA8_Format == maskFormat)) {
- return D32_A8_Factory_neon(color);
- }
-#endif
-
- // We don't need to handle the SkMask::kLCD16_Format case as the default
- // LCD16 will call us through SkBlitMask::PlatformBlitRowProcs16()
-
return NULL;
}
SkBlitMask::BlitLCD16RowProc SkBlitMask::PlatformBlitRowProcs16(bool isOpaque) {
- if (isOpaque) {
- return SK_ARM_NEON_WRAP(SkBlitLCD16OpaqueRow);
- } else {
- return SK_ARM_NEON_WRAP(SkBlitLCD16Row);
- }
+ return NULL;
}
SkBlitMask::RowProc SkBlitMask::PlatformRowProcs(SkBitmap::Config dstConfig,
diff --git a/src/opts/SkColor_opts_neon.h b/src/opts/SkColor_opts_neon.h
index 85752f5..f812397 100644
--- a/src/opts/SkColor_opts_neon.h
+++ b/src/opts/SkColor_opts_neon.h
@@ -2,7 +2,6 @@
#define SkColor_opts_neon_DEFINED
#include "SkTypes.h"
-#include "SkColorPriv.h"
#include <arm_neon.h>
@@ -66,20 +65,4 @@
return ret;
}
-/* This function blends 8 pixels of the same channel in the exact same way as
- * SkBlend32.
- */
-static inline uint8x8_t SkBlend32_neon8(uint8x8_t src, uint8x8_t dst, uint16x8_t scale) {
- int16x8_t src_wide, dst_wide;
-
- src_wide = vreinterpretq_s16_u16(vmovl_u8(src));
- dst_wide = vreinterpretq_s16_u16(vmovl_u8(dst));
-
- src_wide = (src_wide - dst_wide) * vreinterpretq_s16_u16(scale);
-
- dst_wide += vshrq_n_s16(src_wide, 5);
-
- return vmovn_u16(vreinterpretq_u16_s16(dst_wide));
-}
-
#endif /* #ifndef SkColor_opts_neon_DEFINED */
diff --git a/src/pdf/SkPDFImage.cpp b/src/pdf/SkPDFImage.cpp
index 81adcc2..a99c9fe 100644
--- a/src/pdf/SkPDFImage.cpp
+++ b/src/pdf/SkPDFImage.cpp
@@ -36,6 +36,7 @@
return srcRect.width() * 3 * srcRect.height();
case SkBitmap::kARGB_8888_Config:
return srcRect.width() * 3 * srcRect.height();
+ case SkBitmap::kA1_Config:
case SkBitmap::kA8_Config:
return 1;
default:
@@ -165,6 +166,48 @@
return stream;
}
+static SkStream* extract_a1_alpha(const SkBitmap& bitmap,
+ const SkIRect& srcRect,
+ bool* isOpaque,
+ bool* isTransparent) {
+ const int alphaRowBytes = (srcRect.width() + 7) / 8;
+ SkStream* stream = SkNEW_ARGS(SkMemoryStream,
+ (alphaRowBytes * srcRect.height()));
+ uint8_t* alphaDst = (uint8_t*)stream->getMemoryBase();
+
+ int offset1 = srcRect.fLeft % 8;
+ int offset2 = 8 - offset1;
+
+ for (int y = srcRect.fTop; y < srcRect.fBottom; y++) {
+ uint8_t* src = bitmap.getAddr1(0, y);
+ // This may read up to one byte after src, but the
+ // potentially invalid bits are never used for computation.
+ for (int x = srcRect.fLeft; x < srcRect.fRight; x += 8) {
+ if (offset1) {
+ alphaDst[0] = src[x / 8] << offset1 |
+ src[x / 8 + 1] >> offset2;
+ } else {
+ alphaDst[0] = src[x / 8];
+ }
+ if (x + 7 < srcRect.fRight) {
+ *isOpaque &= alphaDst[0] == SK_AlphaOPAQUE;
+ *isTransparent &= alphaDst[0] == SK_AlphaTRANSPARENT;
+ }
+ alphaDst++;
+ }
+ // Calculate the mask of bits we're interested in within the
+ // last byte of alphaDst.
+ // width mod 8 == 1 -> 0x80 ... width mod 8 == 7 -> 0xFE
+ uint8_t mask = ~((1 << (8 - (srcRect.width() % 8))) - 1);
+ if (srcRect.width() % 8) {
+ *isOpaque &= (alphaDst[-1] & mask) == (SK_AlphaOPAQUE & mask);
+ *isTransparent &=
+ (alphaDst[-1] & mask) == (SK_AlphaTRANSPARENT & mask);
+ }
+ }
+ return stream;
+}
+
static SkStream* extract_a8_alpha(const SkBitmap& bitmap,
const SkIRect& srcRect,
bool* isOpaque,
@@ -240,6 +283,14 @@
stream = extract_argb8888_data(bitmap, srcRect, extractAlpha,
&isOpaque, &transparent);
break;
+ case SkBitmap::kA1_Config:
+ if (!extractAlpha) {
+ stream = create_black_image();
+ } else {
+ stream = extract_a1_alpha(bitmap, srcRect,
+ &isOpaque, &transparent);
+ }
+ break;
case SkBitmap::kA8_Config:
if (!extractAlpha) {
stream = create_black_image();
@@ -523,7 +574,8 @@
insertName("Type", "XObject");
insertName("Subtype", "Image");
- bool alphaOnly = (config == SkBitmap::kA8_Config);
+ bool alphaOnly = (config == SkBitmap::kA1_Config ||
+ config == SkBitmap::kA8_Config);
if (!isAlpha && alphaOnly) {
// For alpha only images, we stretch a single pixel of black for
@@ -549,6 +601,8 @@
int bitsPerComp = 8;
if (config == SkBitmap::kARGB_4444_Config) {
bitsPerComp = 4;
+ } else if (isAlpha && config == SkBitmap::kA1_Config) {
+ bitsPerComp = 1;
}
insertInt("BitsPerComponent", bitsPerComp);
diff --git a/src/utils/debugger/SkObjectParser.cpp b/src/utils/debugger/SkObjectParser.cpp
index ebbd400..54ae077 100644
--- a/src/utils/debugger/SkObjectParser.cpp
+++ b/src/utils/debugger/SkObjectParser.cpp
@@ -26,9 +26,9 @@
mBitmap->appendS32(bitmap.height());
const char* gConfigStrings[] = {
- "None", "A8", "Index8", "RGB565", "ARGB4444", "ARGB8888"
+ "None", "A1", "A8", "Index8", "RGB565", "ARGB4444", "ARGB8888"
};
- SkASSERT(SkBitmap::kConfigCount == SK_ARRAY_COUNT(gConfigStrings));
+ SkASSERT(SkBitmap::kConfigCount == 7);
mBitmap->append(" Config: ");
mBitmap->append(gConfigStrings[bitmap.config()]);