aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2014-01-08 15:42:01 +0000
committerGravatar reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2014-01-08 15:42:01 +0000
commit672588b684d484dce6ae251e9e163e4a46924322 (patch)
treec0fd674c6a905b9f7e4f9f8e58326653ab3fe816
parentc75b25af9e46019b13cde1e642a63b7c253ea5f4 (diff)
change offset to xy for pixelref subsetting
BUG= R=scroggo@google.com Review URL: https://codereview.chromium.org/105893012 git-svn-id: http://skia.googlecode.com/svn/trunk@12958 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r--dm/DMSerializeTask.cpp11
-rw-r--r--gm/gmmain.cpp18
-rw-r--r--include/core/SkBitmap.h48
-rw-r--r--include/core/SkBitmapDevice.h4
-rw-r--r--include/core/SkPicture.h7
-rw-r--r--include/core/SkPixelRef.h2
-rw-r--r--src/core/SkBitmap.cpp188
-rw-r--r--src/core/SkBitmapHeap.cpp12
-rw-r--r--src/core/SkBitmapHeap.h4
-rw-r--r--src/core/SkOrderedWriteBuffer.cpp41
-rw-r--r--src/core/SkScaledImageCache.cpp6
-rw-r--r--src/gpu/SkGpuDevice.cpp4
-rw-r--r--src/gpu/SkGr.cpp19
-rw-r--r--src/image/SkImage_Raster.cpp2
-rw-r--r--src/image/SkSurface_Raster.cpp2
-rw-r--r--tests/PictureTest.cpp3
-rw-r--r--tools/PictureRenderer.cpp12
-rw-r--r--tools/render_pdfs_main.cpp13
18 files changed, 153 insertions, 243 deletions
diff --git a/dm/DMSerializeTask.cpp b/dm/DMSerializeTask.cpp
index 8bc8c8ef98..3359f2e0aa 100644
--- a/dm/DMSerializeTask.cpp
+++ b/dm/DMSerializeTask.cpp
@@ -19,21 +19,12 @@ SerializeTask::SerializeTask(const Task& parent,
, fReference(reference)
{}
-static SkData* trivial_bitmap_encoder(size_t* pixelRefOffset, const SkBitmap& bitmap) {
- if (NULL == bitmap.pixelRef()) {
- return NULL;
- }
- SkData* data = bitmap.pixelRef()->refEncodedData();
- *pixelRefOffset = bitmap.pixelRefOffset();
- return data;
-}
-
void SerializeTask::draw() {
SkPicture recorded;
RecordPicture(fGM.get(), &recorded);
SkDynamicMemoryWStream wStream;
- recorded.serialize(&wStream, &trivial_bitmap_encoder);
+ recorded.serialize(&wStream, NULL);
SkAutoTUnref<SkStream> rStream(wStream.detachAsStream());
SkAutoTUnref<SkPicture> reconstructed(SkPicture::CreateFromStream(rStream));
diff --git a/gm/gmmain.cpp b/gm/gmmain.cpp
index 0e43c554c6..e4c1c30110 100644
--- a/gm/gmmain.cpp
+++ b/gm/gmmain.cpp
@@ -1011,21 +1011,9 @@ public:
return pict;
}
- static SkData* bitmap_encoder(size_t* pixelRefOffset, const SkBitmap& bm) {
- SkPixelRef* pr = bm.pixelRef();
- if (pr != NULL) {
- SkData* data = pr->refEncodedData();
- if (data != NULL) {
- *pixelRefOffset = bm.pixelRefOffset();
- return data;
- }
- }
- return NULL;
- }
-
static SkPicture* stream_to_new_picture(const SkPicture& src) {
SkDynamicMemoryWStream storage;
- src.serialize(&storage, &bitmap_encoder);
+ src.serialize(&storage, NULL);
SkAutoTUnref<SkStreamAsset> pictReadback(storage.detachAsStream());
SkPicture* retval = SkPicture::CreateFromStream(pictReadback,
&SkImageDecoder::DecodeMemory);
@@ -1474,7 +1462,7 @@ DEFINE_int32(pdfRasterDpi, 72, "Scale at which at which the non suported "
"features in PDF are rasterized. Must be be in range 0-10000. "
"Default is 72. N = 0 will disable rasterizing features like "
"text shadows or perspective bitmaps.");
-static SkData* encode_to_dct_data(size_t* pixelRefOffset, const SkBitmap& bitmap) {
+static SkData* encode_to_dct_data(size_t*, const SkBitmap& bitmap) {
// Filter output of warnings that JPEG is not available for the image.
if (bitmap.width() >= 65500 || bitmap.height() >= 65500) return NULL;
if (FLAGS_pdfJpegQuality == -1) return NULL;
@@ -1492,12 +1480,10 @@ static SkData* encode_to_dct_data(size_t* pixelRefOffset, const SkBitmap& bitmap
if (pr != NULL) {
SkData* data = pr->refEncodedData();
if (data != NULL) {
- *pixelRefOffset = bm.pixelRefOffset();
return data;
}
}
- *pixelRefOffset = 0;
return SkImageEncoder::EncodeData(bm,
SkImageEncoder::kJPEG_Type,
FLAGS_pdfJpegQuality);
diff --git a/include/core/SkBitmap.h b/include/core/SkBitmap.h
index 2b900bef34..fe0fc0f9c1 100644
--- a/include/core/SkBitmap.h
+++ b/include/core/SkBitmap.h
@@ -347,18 +347,41 @@ public:
*/
bool allocPixels(Allocator* allocator, SkColorTable* ctable);
- /** Return the current pixelref object, if any
- */
+ /**
+ * Return the current pixelref object or NULL if there is none. This does
+ * not affect the refcount of the pixelref.
+ */
SkPixelRef* pixelRef() const { return fPixelRef; }
- /** Return the offset into the pixelref, if any. Will return 0 if there is
- no pixelref installed.
- */
- size_t pixelRefOffset() const { return fPixelRefOffset; }
- /** Assign a pixelref and optional offset. Pixelrefs are reference counted,
- so the existing one (if any) will be unref'd and the new one will be
- ref'd.
- */
- SkPixelRef* setPixelRef(SkPixelRef* pr, size_t offset = 0);
+
+ /**
+ * A bitmap can reference a subset of a pixelref's pixels. That means the
+ * bitmap's width/height can be <= the dimensions of the pixelref. The
+ * pixelref origin is the x,y location within the pixelref's pixels for
+ * the bitmap's top/left corner. To be valid the following must be true:
+ *
+ * origin_x + bitmap_width <= pixelref_width
+ * origin_y + bitmap_height <= pixelref_height
+ *
+ * pixelRefOrigin() returns this origin, or (0,0) if there is no pixelRef.
+ */
+ SkIPoint pixelRefOrigin() const { return fPixelRefOrigin; }
+
+ /**
+ * Assign a pixelref and origin to the bitmap. Pixelrefs are reference,
+ * so the existing one (if any) will be unref'd and the new one will be
+ * ref'd. (x,y) specify the offset within the pixelref's pixels for the
+ * top/left corner of the bitmap. For a bitmap that encompases the entire
+ * pixels of the pixelref, these will be (0,0).
+ */
+ SkPixelRef* setPixelRef(SkPixelRef* pr, int dx, int dy);
+
+ SkPixelRef* setPixelRef(SkPixelRef* pr, const SkIPoint& origin) {
+ return this->setPixelRef(pr, origin.fX, origin.fY);
+ }
+
+ SkPixelRef* setPixelRef(SkPixelRef* pr) {
+ return this->setPixelRef(pr, 0, 0);
+ }
/** Call this to ensure that the bitmap points to the current pixel address
in the pixelref. Balance it with a call to unlockPixels(). These calls
@@ -665,13 +688,14 @@ private:
mutable MipMap* fMipMap;
mutable SkPixelRef* fPixelRef;
- mutable size_t fPixelRefOffset;
mutable int fPixelLockCount;
// either user-specified (in which case it is not treated as mutable)
// or a cache of the returned value from fPixelRef->lockPixels()
mutable void* fPixels;
mutable SkColorTable* fColorTable; // only meaningful for kIndex8
+ SkIPoint fPixelRefOrigin;
+
enum Flags {
kImageIsOpaque_Flag = 0x01,
kImageIsVolatile_Flag = 0x02,
diff --git a/include/core/SkBitmapDevice.h b/include/core/SkBitmapDevice.h
index f3d40d0ce8..a9208e20a0 100644
--- a/include/core/SkBitmapDevice.h
+++ b/include/core/SkBitmapDevice.h
@@ -199,8 +199,8 @@ protected:
SkPixelRef* getPixelRef() const { return fBitmap.pixelRef(); }
// just for subclasses, to assign a custom pixelref
- SkPixelRef* setPixelRef(SkPixelRef* pr, size_t offset) {
- fBitmap.setPixelRef(pr, offset);
+ SkPixelRef* setPixelRef(SkPixelRef* pr) {
+ fBitmap.setPixelRef(pr);
return pr;
}
diff --git a/include/core/SkPicture.h b/include/core/SkPicture.h
index a1d7644e53..4c7e4b3399 100644
--- a/include/core/SkPicture.h
+++ b/include/core/SkPicture.h
@@ -172,8 +172,8 @@ public:
* signature can be passed to serialize() and SkOrderedWriteBuffer.
* Returning NULL will tell the SkOrderedWriteBuffer to use
* SkBitmap::flatten() to store the bitmap.
- * @param pixelRefOffset Output parameter, telling the deserializer what
- * offset in the bm's pixelRef corresponds to the encoded data.
+ *
+ * @param pixelRefOffset DEPRECATED -- caller assumes it will return 0.
* @return SkData If non-NULL, holds encoded data representing the passed
* in bitmap. The caller is responsible for calling unref().
*/
@@ -221,10 +221,11 @@ protected:
// V15: Remove A1 bitmpa config (and renumber remaining configs)
// V16: Move SkPath's isOval flag to SkPathRef
// V17: SkPixelRef now writes SkImageInfo
+ // V18: SkBitmap now records x,y for its pixelref origin, instead of offset.
#ifndef DELETE_THIS_CODE_WHEN_SKPS_ARE_REBUILT_AT_V16_AND_ALL_OTHER_INSTANCES_TOO
static const uint32_t PRIOR_PICTURE_VERSION = 15; // TODO: remove when .skps regenerated
#endif
- static const uint32_t PICTURE_VERSION = 17;
+ static const uint32_t PICTURE_VERSION = 18;
// fPlayback, fRecord, fWidth & fHeight are protected to allow derived classes to
// install their own SkPicturePlayback-derived players,SkPictureRecord-derived
diff --git a/include/core/SkPixelRef.h b/include/core/SkPixelRef.h
index 4811435721..e0bf8866c6 100644
--- a/include/core/SkPixelRef.h
+++ b/include/core/SkPixelRef.h
@@ -69,6 +69,8 @@ public:
*/
SkColorTable* colorTable() const { return fRec.fColorTable; }
+ size_t rowBytes() const { return fRec.fRowBytes; }
+
/**
* To access the actual pixels of a pixelref, it must be "locked".
* Calling lockPixels returns a LockRec struct (on success).
diff --git a/src/core/SkBitmap.cpp b/src/core/SkBitmap.cpp
index c0d93957ac..cb8ac7231b 100644
--- a/src/core/SkBitmap.cpp
+++ b/src/core/SkBitmap.cpp
@@ -129,7 +129,7 @@ SkBitmap& SkBitmap::operator=(const SkBitmap& src) {
void SkBitmap::swap(SkBitmap& other) {
SkTSwap(fColorTable, other.fColorTable);
SkTSwap(fPixelRef, other.fPixelRef);
- SkTSwap(fPixelRefOffset, other.fPixelRefOffset);
+ SkTSwap(fPixelRefOrigin, other.fPixelRefOrigin);
SkTSwap(fPixelLockCount, other.fPixelLockCount);
SkTSwap(fMipMap, other.fMipMap);
SkTSwap(fPixels, other.fPixels);
@@ -340,7 +340,9 @@ void SkBitmap::updatePixelsFromRef() const {
void* p = fPixelRef->pixels();
if (NULL != p) {
- p = (char*)p + fPixelRefOffset;
+ p = (char*)p
+ + fPixelRef->rowBytes() * fPixelRefOrigin.fY
+ + fPixelRefOrigin.fX * fBytesPerPixel;
}
fPixels = p;
SkRefCnt_SafeAssign(fColorTable, fPixelRef->colorTable());
@@ -397,13 +399,9 @@ bool SkBitmap::asImageInfo(SkImageInfo* info) const {
return true;
}
-SkPixelRef* SkBitmap::setPixelRef(SkPixelRef* pr, size_t offset) {
- // do this first, we that we never have a non-zero offset with a null ref
- if (NULL == pr) {
- offset = 0;
- }
+SkPixelRef* SkBitmap::setPixelRef(SkPixelRef* pr, int dx, int dy) {
#ifdef SK_DEBUG
- else {
+ if (pr) {
SkImageInfo info;
if (this->asImageInfo(&info)) {
const SkImageInfo& prInfo = pr->info();
@@ -428,7 +426,16 @@ SkPixelRef* SkBitmap::setPixelRef(SkPixelRef* pr, size_t offset) {
}
#endif
- if (fPixelRef != pr || fPixelRefOffset != offset) {
+ if (pr) {
+ const SkImageInfo& info = pr->info();
+ fPixelRefOrigin.set(SkPin32(dx, 0, info.fWidth),
+ SkPin32(dy, 0, info.fHeight));
+ } else {
+ // ignore dx,dy if there is no pixelref
+ fPixelRefOrigin.setZero();
+ }
+
+ if (fPixelRef != pr) {
if (fPixelRef != pr) {
this->freePixels();
SkASSERT(NULL == fPixelRef);
@@ -436,7 +443,6 @@ SkPixelRef* SkBitmap::setPixelRef(SkPixelRef* pr, size_t offset) {
SkSafeRef(pr);
fPixelRef = pr;
}
- fPixelRefOffset = offset;
this->updatePixelsFromRef();
}
@@ -468,19 +474,19 @@ bool SkBitmap::lockPixelsAreWritable() const {
void SkBitmap::setPixels(void* p, SkColorTable* ctable) {
if (NULL == p) {
- this->setPixelRef(NULL, 0);
+ this->setPixelRef(NULL);
return;
}
SkImageInfo info;
if (!this->asImageInfo(&info)) {
- this->setPixelRef(NULL, 0);
+ this->setPixelRef(NULL);
return;
}
SkPixelRef* pr = SkMallocPixelRef::NewDirect(info, p, fRowBytes, ctable);
if (NULL == pr) {
- this->setPixelRef(NULL, 0);
+ this->setPixelRef(NULL);
return;
}
@@ -515,7 +521,7 @@ void SkBitmap::freePixels() {
}
fPixelRef->unref();
fPixelRef = NULL;
- fPixelRefOffset = 0;
+ fPixelRefOrigin.setZero();
}
fPixelLockCount = 0;
fPixels = NULL;
@@ -562,7 +568,7 @@ bool SkBitmap::HeapAllocator::allocPixelRef(SkBitmap* dst,
return false;
}
- dst->setPixelRef(pr, 0)->unref();
+ dst->setPixelRef(pr)->unref();
// since we're already allocated, we lockPixels right away
dst->lockPixels();
return true;
@@ -887,84 +893,6 @@ void SkBitmap::eraseArea(const SkIRect& rect, SkColor c) const {
//////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////
-#define SUB_OFFSET_FAILURE ((size_t)-1)
-
-/**
- * Based on the Config and rowBytes() of bm, return the offset into an SkPixelRef of the pixel at
- * (x, y).
- * Note that the SkPixelRef does not need to be set yet. deepCopyTo takes advantage of this fact.
- * Also note that (x, y) may be outside the range of (0 - width(), 0 - height()), so long as it is
- * within the bounds of the SkPixelRef being used.
- */
-static size_t get_sub_offset(const SkBitmap& bm, int x, int y) {
- switch (bm.config()) {
- case SkBitmap::kA8_Config:
- case SkBitmap:: kIndex8_Config:
- // x is fine as is for the calculation
- break;
-
- case SkBitmap::kRGB_565_Config:
- case SkBitmap::kARGB_4444_Config:
- x <<= 1;
- break;
-
- case SkBitmap::kARGB_8888_Config:
- x <<= 2;
- break;
-
- case SkBitmap::kNo_Config:
- default:
- return SUB_OFFSET_FAILURE;
- }
- return y * bm.rowBytes() + x;
-}
-
-/**
- * Using the pixelRefOffset(), rowBytes(), and Config of bm, determine the (x, y) coordinate of the
- * upper left corner of bm relative to its SkPixelRef.
- * x and y must be non-NULL.
- */
-bool get_upper_left_from_offset(SkBitmap::Config config, size_t offset, size_t rowBytes,
- int32_t* x, int32_t* y);
-bool get_upper_left_from_offset(SkBitmap::Config config, size_t offset, size_t rowBytes,
- int32_t* x, int32_t* y) {
- SkASSERT(x != NULL && y != NULL);
- if (0 == offset) {
- *x = *y = 0;
- return true;
- }
- // Use integer division to find the correct y position.
- // The remainder will be the x position, after we reverse get_sub_offset.
- SkTDivMod(offset, rowBytes, y, x);
- switch (config) {
- case SkBitmap::kA8_Config:
- // Fall through.
- case SkBitmap::kIndex8_Config:
- // x is unmodified
- break;
-
- case SkBitmap::kRGB_565_Config:
- // Fall through.
- case SkBitmap::kARGB_4444_Config:
- *x >>= 1;
- break;
-
- case SkBitmap::kARGB_8888_Config:
- *x >>= 2;
- break;
-
- case SkBitmap::kNo_Config:
- // Fall through.
- default:
- return false;
- }
- return true;
-}
-
-static bool get_upper_left_from_offset(const SkBitmap& bm, int32_t* x, int32_t* y) {
- return get_upper_left_from_offset(bm.config(), bm.pixelRefOffset(), bm.rowBytes(), x, y);
-}
-
bool SkBitmap::extractSubset(SkBitmap* result, const SkIRect& subset) const {
SkDEBUGCODE(this->validate();)
@@ -998,19 +926,17 @@ bool SkBitmap::extractSubset(SkBitmap* result, const SkIRect& subset) const {
SkASSERT(static_cast<unsigned>(r.fLeft) < static_cast<unsigned>(this->width()));
SkASSERT(static_cast<unsigned>(r.fTop) < static_cast<unsigned>(this->height()));
- size_t offset = get_sub_offset(*this, r.fLeft, r.fTop);
- if (SUB_OFFSET_FAILURE == offset) {
- return false; // config not supported
- }
-
SkBitmap dst;
dst.setConfig(this->config(), r.width(), r.height(), this->rowBytes(),
this->alphaType());
dst.setIsVolatile(this->isVolatile());
if (fPixelRef) {
+ SkIPoint origin = fPixelRefOrigin;
+ origin.fX += r.fLeft;
+ origin.fY += r.fTop;
// share the pixelref with a custom offset
- dst.setPixelRef(fPixelRef, fPixelRefOffset + offset);
+ dst.setPixelRef(fPixelRef, origin);
}
SkDEBUGCODE(dst.validate();)
@@ -1059,26 +985,23 @@ bool SkBitmap::copyTo(SkBitmap* dst, Config dstConfig, Allocator* alloc) const {
if (fPixelRef) {
SkIRect subset;
- if (get_upper_left_from_offset(*this, &subset.fLeft, &subset.fTop)) {
- subset.fRight = subset.fLeft + fWidth;
- subset.fBottom = subset.fTop + fHeight;
- if (fPixelRef->readPixels(&tmpSrc, &subset)) {
- SkASSERT(tmpSrc.width() == this->width());
- SkASSERT(tmpSrc.height() == this->height());
-
- // did we get lucky and we can just return tmpSrc?
- if (tmpSrc.config() == dstConfig && NULL == alloc) {
- dst->swap(tmpSrc);
- if (dst->pixelRef() && this->config() == dstConfig) {
- // TODO(scroggo): fix issue 1742
- dst->pixelRef()->cloneGenID(*fPixelRef);
- }
- return true;
+ subset.setXYWH(fPixelRefOrigin.fX, fPixelRefOrigin.fY, fWidth, fHeight);
+ if (fPixelRef->readPixels(&tmpSrc, &subset)) {
+ SkASSERT(tmpSrc.width() == this->width());
+ SkASSERT(tmpSrc.height() == this->height());
+
+ // did we get lucky and we can just return tmpSrc?
+ if (tmpSrc.config() == dstConfig && NULL == alloc) {
+ dst->swap(tmpSrc);
+ if (dst->pixelRef() && this->config() == dstConfig) {
+ // TODO(scroggo): fix issue 1742
+ dst->pixelRef()->cloneGenID(*fPixelRef);
}
-
- // fall through to the raster case
- src = &tmpSrc;
+ return true;
}
+
+ // fall through to the raster case
+ src = &tmpSrc;
}
}
@@ -1176,24 +1099,7 @@ bool SkBitmap::deepCopyTo(SkBitmap* dst, Config dstConfig) const {
rowBytes = 0;
}
dst->setConfig(dstConfig, fWidth, fHeight, rowBytes);
-
- size_t pixelRefOffset;
- if (0 == fPixelRefOffset || dstConfig == fConfig) {
- // Use the same offset as the original.
- pixelRefOffset = fPixelRefOffset;
- } else {
- // Find the correct offset in the new config. This needs to be done after calling
- // setConfig so dst's fConfig and fRowBytes have been set properly.
- int32_t x, y;
- if (!get_upper_left_from_offset(*this, &x, &y)) {
- return false;
- }
- pixelRefOffset = get_sub_offset(*dst, x, y);
- if (SUB_OFFSET_FAILURE == pixelRefOffset) {
- return false;
- }
- }
- dst->setPixelRef(pixelRef, pixelRefOffset)->unref();
+ dst->setPixelRef(pixelRef, fPixelRefOrigin)->unref();
return true;
}
}
@@ -1604,7 +1510,8 @@ void SkBitmap::flatten(SkFlattenableWriteBuffer& buffer) const {
if (fPixelRef) {
if (fPixelRef->getFactory()) {
buffer.writeInt(SERIALIZE_PIXELTYPE_REF_DATA);
- buffer.writeUInt(SkToU32(fPixelRefOffset));
+ buffer.writeInt(fPixelRefOrigin.fX);
+ buffer.writeInt(fPixelRefOrigin.fY);
buffer.writeFlattenable(fPixelRef);
return;
}
@@ -1637,13 +1544,16 @@ void SkBitmap::unflatten(SkFlattenableReadBuffer& buffer) {
(SERIALIZE_PIXELTYPE_NONE == reftype))) {
switch (reftype) {
case SERIALIZE_PIXELTYPE_REF_DATA: {
- size_t offset = buffer.readUInt();
+ SkIPoint origin;
+ origin.fX = buffer.readInt();
+ origin.fY = buffer.readInt();
+ size_t offset = origin.fY * rowBytes + origin.fX * fBytesPerPixel;
SkPixelRef* pr = buffer.readPixelRef();
if (!buffer.validate((NULL == pr) ||
(pr->getAllocatedSizeInBytes() >= (offset + this->getSafeSize())))) {
- offset = 0;
+ origin.setZero();
}
- SkSafeUnref(this->setPixelRef(pr, offset));
+ SkSafeUnref(this->setPixelRef(pr, origin));
break;
}
case SERIALIZE_PIXELTYPE_NONE:
diff --git a/src/core/SkBitmapHeap.cpp b/src/core/SkBitmapHeap.cpp
index 1f2f3dcf36..7904492f46 100644
--- a/src/core/SkBitmapHeap.cpp
+++ b/src/core/SkBitmapHeap.cpp
@@ -35,15 +35,23 @@ void SkBitmapHeapEntry::addReferences(int count) {
///////////////////////////////////////////////////////////////////////////////
+static bool operator<(const SkIPoint& a, const SkIPoint& b) {
+ return *(const int64_t*)&a < *(const int64_t*)&b;
+}
+
+static bool operator>(const SkIPoint& a, const SkIPoint& b) {
+ return *(const int64_t*)&a > *(const int64_t*)&b;
+}
+
bool SkBitmapHeap::LookupEntry::Less(const SkBitmapHeap::LookupEntry& a,
const SkBitmapHeap::LookupEntry& b) {
if (a.fGenerationId < b.fGenerationId) {
return true;
} else if (a.fGenerationId > b.fGenerationId) {
return false;
- } else if (a.fPixelOffset < b.fPixelOffset) {
+ } else if (a.fPixelOrigin < b.fPixelOrigin) {
return true;
- } else if (a.fPixelOffset > b.fPixelOffset) {
+ } else if (a.fPixelOrigin > b.fPixelOrigin) {
return false;
} else if (a.fWidth < b.fWidth) {
return true;
diff --git a/src/core/SkBitmapHeap.h b/src/core/SkBitmapHeap.h
index 2547eeec74..467a216997 100644
--- a/src/core/SkBitmapHeap.h
+++ b/src/core/SkBitmapHeap.h
@@ -220,14 +220,14 @@ private:
struct LookupEntry {
LookupEntry(const SkBitmap& bm)
: fGenerationId(bm.getGenerationID())
- , fPixelOffset(bm.pixelRefOffset())
+ , fPixelOrigin(bm.pixelRefOrigin())
, fWidth(bm.width())
, fHeight(bm.height())
, fMoreRecentlyUsed(NULL)
, fLessRecentlyUsed(NULL){}
const uint32_t fGenerationId; // SkPixelRef GenerationID.
- const size_t fPixelOffset;
+ const SkIPoint fPixelOrigin;
const uint32_t fWidth;
const uint32_t fHeight;
diff --git a/src/core/SkOrderedWriteBuffer.cpp b/src/core/SkOrderedWriteBuffer.cpp
index 25ca769168..50fdc72869 100644
--- a/src/core/SkOrderedWriteBuffer.cpp
+++ b/src/core/SkOrderedWriteBuffer.cpp
@@ -9,6 +9,7 @@
#include "SkOrderedWriteBuffer.h"
#include "SkBitmap.h"
#include "SkData.h"
+#include "SkPixelRef.h"
#include "SkPtrRecorder.h"
#include "SkStream.h"
#include "SkTypeface.h"
@@ -143,9 +144,13 @@ bool SkOrderedWriteBuffer::writeToStream(SkWStream* stream) {
return fWriter.writeToStream(stream);
}
-// Defined in SkBitmap.cpp
-bool get_upper_left_from_offset(SkBitmap::Config config, size_t offset, size_t rowBytes,
- int32_t* x, int32_t* y);
+static void write_encoded_bitmap(SkOrderedWriteBuffer* buffer, SkData* data,
+ const SkIPoint& origin) {
+ buffer->writeUInt(SkToU32(data->size()));
+ buffer->getWriter32()->writePad(data->data(), data->size());
+ buffer->write32(origin.fX);
+ buffer->write32(origin.fY);
+}
void SkOrderedWriteBuffer::writeBitmap(const SkBitmap& bitmap) {
// Record the width and height. This way if readBitmap fails a dummy bitmap can be drawn at the
@@ -179,27 +184,29 @@ void SkOrderedWriteBuffer::writeBitmap(const SkBitmap& bitmap) {
fWriter.write32(bitmap.getGenerationID());
return;
}
+
+ // see if the pixelref already has an encoded version
+ if (bitmap.pixelRef()) {
+ SkAutoDataUnref data(bitmap.pixelRef()->refEncodedData());
+ if (data.get() != NULL) {
+ write_encoded_bitmap(this, data, bitmap.pixelRefOrigin());
+ return;
+ }
+ }
+
+ // see if the caller wants to manually encode
if (fBitmapEncoder != NULL) {
SkASSERT(NULL == fBitmapHeap);
- size_t offset = 0;
+ size_t offset = 0; // this parameter is deprecated/ignored
+ // if we have to "encode" the bitmap, then we assume there is no
+ // offset to share, since we are effectively creating a new pixelref
SkAutoDataUnref data(fBitmapEncoder(&offset, bitmap));
if (data.get() != NULL) {
- // Write the length to indicate that the bitmap was encoded successfully, followed
- // by the actual data.
- this->writeUInt(SkToU32(data->size()));
- fWriter.writePad(data->data(), data->size());
- // Store the coordinate of the offset, rather than fPixelRefOffset, which may be
- // different depending on the decoder.
- int32_t x, y;
- if (0 == offset || !get_upper_left_from_offset(bitmap.config(), offset,
- bitmap.rowBytes(), &x, &y)) {
- x = y = 0;
- }
- this->write32(x);
- this->write32(y);
+ write_encoded_bitmap(this, data, SkIPoint::Make(0, 0));
return;
}
}
+
// Bitmap was not encoded. Record a zero, implying that the reader need not decode.
this->writeUInt(0);
bitmap.flatten(*this);
diff --git a/src/core/SkScaledImageCache.cpp b/src/core/SkScaledImageCache.cpp
index 5a772a7cd5..fc3148bdd8 100644
--- a/src/core/SkScaledImageCache.cpp
+++ b/src/core/SkScaledImageCache.cpp
@@ -369,10 +369,8 @@ static SkIRect get_bounds_from_bitmap(const SkBitmap& bm) {
if (!(bm.pixelRef())) {
return SkIRect::MakeEmpty();
}
- size_t x, y;
- SkTDivMod(bm.pixelRefOffset(), bm.rowBytes(), &y, &x);
- x >>= bm.shiftPerPixel();
- return SkIRect::MakeXYWH(x, y, bm.width(), bm.height());
+ SkIPoint origin = bm.pixelRefOrigin();
+ return SkIRect::MakeXYWH(origin.fX, origin.fY, bm.width(), bm.height());
}
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index 680dd89984..25aacca509 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -219,7 +219,7 @@ void SkGpuDevice::initFromRenderTarget(GrContext* context,
surface->asImageInfo(&info);
SkPixelRef* pr = SkNEW_ARGS(SkGrPixelRef, (info, surface, cached));
- this->setPixelRef(pr, 0)->unref();
+ this->setPixelRef(pr)->unref();
}
SkGpuDevice::SkGpuDevice(GrContext* context,
@@ -266,7 +266,7 @@ SkGpuDevice::SkGpuDevice(GrContext* context,
// wrap the bitmap with a pixelref to expose our texture
SkGrPixelRef* pr = SkNEW_ARGS(SkGrPixelRef, (info, texture));
- this->setPixelRef(pr, 0)->unref();
+ this->setPixelRef(pr)->unref();
} else {
GrPrintf("--- failed to create gpu-offscreen [%d %d]\n",
width, height);
diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp
index a3f0eefa91..fa9fa71326 100644
--- a/src/gpu/SkGr.cpp
+++ b/src/gpu/SkGr.cpp
@@ -65,18 +65,19 @@ static void generate_bitmap_cache_id(const SkBitmap& bitmap, GrCacheID* id) {
// Our id includes the offset, width, and height so that bitmaps created by extractSubset()
// are unique.
uint32_t genID = bitmap.getGenerationID();
- size_t offset = bitmap.pixelRefOffset();
- int16_t width = static_cast<int16_t>(bitmap.width());
- int16_t height = static_cast<int16_t>(bitmap.height());
+ SkIPoint origin = bitmap.pixelRefOrigin();
+ int16_t width = SkToS16(bitmap.width());
+ int16_t height = SkToS16(bitmap.height());
GrCacheID::Key key;
- memcpy(key.fData8, &genID, 4);
- memcpy(key.fData8 + 4, &width, 2);
- memcpy(key.fData8 + 6, &height, 2);
- memcpy(key.fData8 + 8, &offset, sizeof(size_t));
- static const size_t kKeyDataSize = 8 + sizeof(size_t);
+ memcpy(key.fData8 + 0, &genID, 4);
+ memcpy(key.fData8 + 4, &origin.fX, 4);
+ memcpy(key.fData8 + 8, &origin.fY, 4);
+ memcpy(key.fData8 + 12, &width, 2);
+ memcpy(key.fData8 + 14, &height, 2);
+ static const size_t kKeyDataSize = 16;
memset(key.fData8 + kKeyDataSize, 0, sizeof(key) - kKeyDataSize);
- GR_STATIC_ASSERT(sizeof(key) >= 8 + sizeof(size_t));
+ GR_STATIC_ASSERT(sizeof(key) >= kKeyDataSize);
static const GrCacheID::Domain gBitmapTextureDomain = GrCacheID::GenerateDomain();
id->reset(gBitmapTextureDomain, key);
}
diff --git a/src/image/SkImage_Raster.cpp b/src/image/SkImage_Raster.cpp
index 819c08f051..9863c337e0 100644
--- a/src/image/SkImage_Raster.cpp
+++ b/src/image/SkImage_Raster.cpp
@@ -87,7 +87,7 @@ SkImage_Raster::SkImage_Raster(const Info& info, SkData* data, size_t rowBytes)
fBitmap.setConfig(info, rowBytes);
SkAutoTUnref<SkPixelRef> ref(
SkMallocPixelRef::NewWithData(info, rowBytes, NULL, data, 0));
- fBitmap.setPixelRef(ref, 0);
+ fBitmap.setPixelRef(ref);
fBitmap.setImmutable();
}
diff --git a/src/image/SkSurface_Raster.cpp b/src/image/SkSurface_Raster.cpp
index 61ade6f46c..48afe4fc20 100644
--- a/src/image/SkSurface_Raster.cpp
+++ b/src/image/SkSurface_Raster.cpp
@@ -123,7 +123,7 @@ void SkSurface_Raster::onCopyOnWrite(ContentChangeMode mode) {
if (SkBitmapImageGetPixelRef(this->getCachedImage()) == fBitmap.pixelRef()) {
SkASSERT(fWeOwnThePixels);
if (kDiscard_ContentChangeMode == mode) {
- fBitmap.setPixelRef(NULL, 0);
+ fBitmap.setPixelRef(NULL);
fBitmap.allocPixels();
} else {
SkBitmap prev(fBitmap);
diff --git a/tests/PictureTest.cpp b/tests/PictureTest.cpp
index b90cc030d7..acde9b6d58 100644
--- a/tests/PictureTest.cpp
+++ b/tests/PictureTest.cpp
@@ -340,8 +340,7 @@ static void test_bad_bitmap() {
}
#endif
-static SkData* encode_bitmap_to_data(size_t* offset, const SkBitmap& bm) {
- *offset = 0;
+static SkData* encode_bitmap_to_data(size_t*, const SkBitmap& bm) {
return SkImageEncoder::EncodeData(bm, SkImageEncoder::kPNG_Type, 100);
}
diff --git a/tools/PictureRenderer.cpp b/tools/PictureRenderer.cpp
index b61288a2bd..53654b923f 100644
--- a/tools/PictureRenderer.cpp
+++ b/tools/PictureRenderer.cpp
@@ -340,16 +340,8 @@ SkCanvas* RecordPictureRenderer::setupCanvas(int width, int height) {
return NULL;
}
-static SkData* encode_bitmap_to_data(size_t* offset, const SkBitmap& bm) {
- SkPixelRef* pr = bm.pixelRef();
- if (pr != NULL) {
- SkData* data = pr->refEncodedData();
- if (data != NULL) {
- *offset = bm.pixelRefOffset();
- return data;
- }
- }
- *offset = 0;
+// the size_t* parameter is deprecated, so we ignore it
+static SkData* encode_bitmap_to_data(size_t*, const SkBitmap& bm) {
return SkImageEncoder::EncodeData(bm, SkImageEncoder::kPNG_Type, 100);
}
diff --git a/tools/render_pdfs_main.cpp b/tools/render_pdfs_main.cpp
index e07664c304..07c894f753 100644
--- a/tools/render_pdfs_main.cpp
+++ b/tools/render_pdfs_main.cpp
@@ -82,7 +82,8 @@ static bool replace_filename_extension(SkString* path,
}
int gJpegQuality = 100;
-static SkData* encode_to_dct_data(size_t* pixelRefOffset, const SkBitmap& bitmap) {
+// the size_t* parameter is deprecated, so we ignore it
+static SkData* encode_to_dct_data(size_t*, const SkBitmap& bitmap) {
if (gJpegQuality == -1) {
return NULL;
}
@@ -96,16 +97,6 @@ static SkData* encode_to_dct_data(size_t* pixelRefOffset, const SkBitmap& bitmap
bm = copy;
#endif
- SkPixelRef* pr = bm.pixelRef();
- if (pr != NULL) {
- SkData* data = pr->refEncodedData();
- if (data != NULL) {
- *pixelRefOffset = bm.pixelRefOffset();
- return data;
- }
- }
-
- *pixelRefOffset = 0;
return SkImageEncoder::EncodeData(bm,
SkImageEncoder::kJPEG_Type,
gJpegQuality);