Revert "Remove Bitmaps Raw Pixel Support."
BUG=
TEST=
Review URL: https://codereview.appspot.com/6449049
git-svn-id: http://skia.googlecode.com/svn/trunk@4780 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/core/SkBitmap.cpp b/src/core/SkBitmap.cpp
index 687cf7a..b1a4b7e 100644
--- a/src/core/SkBitmap.cpp
+++ b/src/core/SkBitmap.cpp
@@ -22,6 +22,8 @@
SK_DEFINE_INST_COUNT(SkBitmap::Allocator)
+extern int32_t SkNextPixelRefGenerationID();
+
static bool isPos32Bits(const Sk64& value) {
return !value.isNeg() && value.is32();
}
@@ -137,6 +139,7 @@
SkTSwap(fPixelLockCount, other.fPixelLockCount);
SkTSwap(fMipMap, other.fMipMap);
SkTSwap(fPixels, other.fPixels);
+ SkTSwap(fRawPixelGenerationID, other.fRawPixelGenerationID);
SkTSwap(fRowBytes, other.fRowBytes);
SkTSwap(fWidth, other.fWidth);
SkTSwap(fHeight, other.fHeight);
@@ -356,16 +359,18 @@
}
bool SkBitmap::lockPixelsAreWritable() const {
- return (fPixelRef) ? fPixelRef->lockPixelsAreWritable() : false;
+ if (fPixelRef) {
+ return fPixelRef->lockPixelsAreWritable();
+ } else {
+ return fPixels != NULL;
+ }
}
void SkBitmap::setPixels(void* p, SkColorTable* ctable) {
- Sk64 size = this->getSize64();
- SkASSERT(!size.isNeg() && size.is32());
+ this->freePixels();
+ fPixels = p;
+ SkRefCnt_SafeAssign(fColorTable, ctable);
- this->setPixelRef(new SkMallocPixelRef(p, size.get32(), ctable, false))->unref();
- // since we're already allocated, we lockPixels right away
- this->lockPixels();
SkDEBUGCODE(this->validate();)
}
@@ -407,13 +412,23 @@
}
uint32_t SkBitmap::getGenerationID() const {
- return (fPixelRef) ? fPixelRef->getGenerationID() : 0;
+ if (fPixelRef) {
+ return fPixelRef->getGenerationID();
+ } else {
+ SkASSERT(fPixels || !fRawPixelGenerationID);
+ if (fPixels && !fRawPixelGenerationID) {
+ fRawPixelGenerationID = SkNextPixelRefGenerationID();
+ }
+ return fRawPixelGenerationID;
+ }
}
void SkBitmap::notifyPixelsChanged() const {
SkASSERT(!this->isImmutable());
if (fPixelRef) {
fPixelRef->notifyPixelsChanged();
+ } else {
+ fRawPixelGenerationID = 0; // will grab next ID in getGenerationID
}
}
@@ -776,7 +791,7 @@
bool SkBitmap::extractSubset(SkBitmap* result, const SkIRect& subset) const {
SkDEBUGCODE(this->validate();)
- if (NULL == result || NULL == fPixelRef) {
+ if (NULL == result || (NULL == fPixelRef && NULL == fPixels)) {
return false; // no src pixels
}
@@ -826,6 +841,9 @@
if (fPixelRef) {
// share the pixelref with a custom offset
dst.setPixelRef(fPixelRef, fPixelRefOffset + offset);
+ } else {
+ // share the pixels (owned by the caller)
+ dst.setPixels((char*)fPixels + offset, this->getColorTable());
}
SkDEBUGCODE(dst.validate();)
@@ -1358,6 +1376,8 @@
enum {
SERIALIZE_PIXELTYPE_NONE,
+ SERIALIZE_PIXELTYPE_RAW_WITH_CTABLE,
+ SERIALIZE_PIXELTYPE_RAW_NO_CTABLE,
SERIALIZE_PIXELTYPE_REF_DATA,
SERIALIZE_PIXELTYPE_REF_PTR
};
@@ -1409,6 +1429,21 @@
}
// if we get here, we can't record the pixels
buffer.write8(SERIALIZE_PIXELTYPE_NONE);
+ } else if (fPixels) {
+ if (fColorTable) {
+ buffer.write8(SERIALIZE_PIXELTYPE_RAW_WITH_CTABLE);
+ buffer.writeFlattenable(fColorTable);
+ } else {
+ buffer.write8(SERIALIZE_PIXELTYPE_RAW_NO_CTABLE);
+ }
+ buffer.writePad(fPixels, this->getSafeSize());
+ // There is no writeZeroPad() fcn, so write individual bytes.
+ if (this->getSize() > this->getSafeSize()) {
+ size_t deltaSize = this->getSize() - this->getSafeSize();
+ // Need aligned pointer to write into due to internal implementa-
+ // tion of SkWriter32.
+ memset(buffer.reserve(SkAlign4(deltaSize)), 0, deltaSize);
+ }
} else {
buffer.write8(SERIALIZE_PIXELTYPE_NONE);
}
@@ -1439,6 +1474,26 @@
SkSafeUnref(this->setPixelRef(pr, offset));
break;
}
+ case SERIALIZE_PIXELTYPE_RAW_WITH_CTABLE:
+ case SERIALIZE_PIXELTYPE_RAW_NO_CTABLE: {
+ SkColorTable* ctable = NULL;
+ if (SERIALIZE_PIXELTYPE_RAW_WITH_CTABLE == reftype) {
+ ctable = static_cast<SkColorTable*>(buffer.readFlattenable());
+ }
+ size_t size = this->getSize();
+ if (this->allocPixels(ctable)) {
+ this->lockPixels();
+ // Just read what we need.
+ buffer.read(this->getPixels(), this->getSafeSize());
+ // Keep aligned for subsequent reads.
+ buffer.skip(size - this->getSafeSize());
+ this->unlockPixels();
+ } else {
+ buffer.skip(size); // Still skip the full-sized buffer though.
+ }
+ SkSafeUnref(ctable);
+ break;
+ }
case SERIALIZE_PIXELTYPE_NONE:
break;
default: