aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-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
9 files changed, 101 insertions, 177 deletions
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);