From 672588b684d484dce6ae251e9e163e4a46924322 Mon Sep 17 00:00:00 2001 From: "reed@google.com" Date: Wed, 8 Jan 2014 15:42:01 +0000 Subject: 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 --- dm/DMSerializeTask.cpp | 11 +-- gm/gmmain.cpp | 18 +--- include/core/SkBitmap.h | 48 +++++++--- include/core/SkBitmapDevice.h | 4 +- include/core/SkPicture.h | 7 +- include/core/SkPixelRef.h | 2 + src/core/SkBitmap.cpp | 188 ++++++++++---------------------------- src/core/SkBitmapHeap.cpp | 12 ++- src/core/SkBitmapHeap.h | 4 +- src/core/SkOrderedWriteBuffer.cpp | 41 +++++---- src/core/SkScaledImageCache.cpp | 6 +- src/gpu/SkGpuDevice.cpp | 4 +- src/gpu/SkGr.cpp | 19 ++-- src/image/SkImage_Raster.cpp | 2 +- src/image/SkSurface_Raster.cpp | 2 +- tests/PictureTest.cpp | 3 +- tools/PictureRenderer.cpp | 12 +-- tools/render_pdfs_main.cpp | 13 +-- 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 rStream(wStream.detachAsStream()); SkAutoTUnref 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 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(r.fLeft) < static_cast(this->width())); SkASSERT(static_cast(r.fTop) < static_cast(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(bitmap.width()); - int16_t height = static_cast(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 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); -- cgit v1.2.3