summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorreed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-12-11 18:38:46 +0000
committerreed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-12-11 18:38:46 +0000
commit515392df84309ea716d7af351aea1bde00bf058d (patch)
tree58dec45d356e1b5cc331d4214c470077f1da22d8
parent786f86cea3fa73c8a640abb4643bcb29a65906eb (diff)
downloadsrc-515392df84309ea716d7af351aea1bde00bf058d.tar.gz
remvoe duplicate impl for SkImageInfo flattening
Revert "Revert "PixelRef now returns (nearly) everything that is currently in SkBitmap. The goal is to refactor bitmap later to remove redundancy, and more interestingly, remove the chance for a disconnect between the actual (pixelref) rowbytes and config, and the one claimed by the bitmap."""""" This reverts commit eabd6b2ed4e494b323c08f32358f45950a0368c3. BUG= Review URL: https://codereview.chromium.org/108773003 git-svn-id: http://skia.googlecode.com/svn/trunk/src@12624 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r--core/SkBitmap.cpp30
-rw-r--r--core/SkBitmapDevice.cpp35
-rw-r--r--core/SkImageFilterUtils.cpp16
-rw-r--r--core/SkMallocPixelRef.cpp131
-rw-r--r--core/SkMaskFilter.cpp8
-rw-r--r--core/SkPixelRef.cpp84
-rw-r--r--effects/gradients/SkGradientShader.cpp14
-rw-r--r--gpu/GrSurface.cpp10
-rw-r--r--gpu/SkGpuDevice.cpp28
-rw-r--r--gpu/SkGr.cpp30
-rw-r--r--gpu/SkGrPixelRef.cpp51
-rw-r--r--image/SkDataPixelRef.cpp25
-rw-r--r--image/SkDataPixelRef.h7
-rw-r--r--image/SkImage_Raster.cpp6
-rw-r--r--image/SkSurface_Raster.cpp16
-rw-r--r--images/SkImageRef.cpp31
-rw-r--r--images/SkImageRef_GlobalPool.cpp6
-rw-r--r--images/SkImageRef_ashmem.cpp8
-rw-r--r--images/SkImageRef_ashmem.h2
-rw-r--r--lazy/SkCachingPixelRef.cpp34
-rw-r--r--lazy/SkCachingPixelRef.h4
-rw-r--r--lazy/SkDiscardablePixelRef.cpp38
-rw-r--r--lazy/SkDiscardablePixelRef.h9
23 files changed, 409 insertions, 214 deletions
diff --git a/core/SkBitmap.cpp b/core/SkBitmap.cpp
index 25a6b1db..7a7f690b 100644
--- a/core/SkBitmap.cpp
+++ b/core/SkBitmap.cpp
@@ -453,10 +453,20 @@ void SkBitmap::setPixels(void* p, SkColorTable* ctable) {
return;
}
- Sk64 size = this->getSize64();
- SkASSERT(!size.isNeg() && size.is32());
+ SkImageInfo info;
+ if (!this->asImageInfo(&info)) {
+ this->setPixelRef(NULL, 0);
+ return;
+ }
+
+ SkPixelRef* pr = SkMallocPixelRef::NewDirect(info, p, fRowBytes, ctable);
+ if (NULL == pr) {
+ this->setPixelRef(NULL, 0);
+ return;
+ }
+
+ this->setPixelRef(pr)->unref();
- this->setPixelRef(new SkMallocPixelRef(p, size.get32(), ctable, false))->unref();
// since we're already allocated, we lockPixels right away
this->lockPixels();
SkDEBUGCODE(this->validate();)
@@ -521,17 +531,19 @@ GrTexture* SkBitmap::getTexture() const {
*/
bool SkBitmap::HeapAllocator::allocPixelRef(SkBitmap* dst,
SkColorTable* ctable) {
- Sk64 size = dst->getSize64();
- if (size.isNeg() || !size.is32()) {
+ SkImageInfo info;
+ if (!dst->asImageInfo(&info)) {
+// SkDebugf("unsupported config for info %d\n", dst->config());
return false;
}
-
- void* addr = sk_malloc_flags(size.get32(), 0); // returns NULL on failure
- if (NULL == addr) {
+
+ SkPixelRef* pr = SkMallocPixelRef::NewAllocate(info, dst->rowBytes(),
+ ctable);
+ if (NULL == pr) {
return false;
}
- dst->setPixelRef(new SkMallocPixelRef(addr, size.get32(), ctable))->unref();
+ dst->setPixelRef(pr, 0)->unref();
// since we're already allocated, we lockPixels right away
dst->lockPixels();
return true;
diff --git a/core/SkBitmapDevice.cpp b/core/SkBitmapDevice.cpp
index 1668618c..368c8075 100644
--- a/core/SkBitmapDevice.cpp
+++ b/core/SkBitmapDevice.cpp
@@ -24,31 +24,30 @@ SkBitmapDevice::SkBitmapDevice(const SkBitmap& bitmap, const SkDeviceProperties&
, fBitmap(bitmap) {
}
-SkBitmapDevice::SkBitmapDevice(SkBitmap::Config config, int width, int height, bool isOpaque) {
+void SkBitmapDevice::init(SkBitmap::Config config, int width, int height, bool isOpaque) {
fBitmap.setConfig(config, width, height, 0, isOpaque ?
kOpaque_SkAlphaType : kPremul_SkAlphaType);
- if (!fBitmap.allocPixels()) {
- fBitmap.setConfig(config, 0, 0, 0, isOpaque ?
- kOpaque_SkAlphaType : kPremul_SkAlphaType);
- }
- if (!isOpaque) {
- fBitmap.eraseColor(SK_ColorTRANSPARENT);
+
+ if (SkBitmap::kNo_Config != config) {
+ if (!fBitmap.allocPixels()) {
+ // indicate failure by zeroing our bitmap
+ fBitmap.setConfig(config, 0, 0, 0, isOpaque ?
+ kOpaque_SkAlphaType : kPremul_SkAlphaType);
+ } else if (!isOpaque) {
+ fBitmap.eraseColor(SK_ColorTRANSPARENT);
+ }
}
}
+SkBitmapDevice::SkBitmapDevice(SkBitmap::Config config, int width, int height, bool isOpaque) {
+ this->init(config, width, height, isOpaque);
+}
+
SkBitmapDevice::SkBitmapDevice(SkBitmap::Config config, int width, int height, bool isOpaque,
const SkDeviceProperties& deviceProperties)
- : SkBaseDevice(deviceProperties) {
-
- fBitmap.setConfig(config, width, height, 0, isOpaque ?
- kOpaque_SkAlphaType : kPremul_SkAlphaType);
- if (!fBitmap.allocPixels()) {
- fBitmap.setConfig(config, 0, 0, 0, isOpaque ?
- kOpaque_SkAlphaType : kPremul_SkAlphaType);
- }
- if (!isOpaque) {
- fBitmap.eraseColor(SK_ColorTRANSPARENT);
- }
+ : SkBaseDevice(deviceProperties)
+{
+ this->init(config, width, height, isOpaque);
}
SkBitmapDevice::~SkBitmapDevice() {
diff --git a/core/SkImageFilterUtils.cpp b/core/SkImageFilterUtils.cpp
index 8385fb44..e535d934 100644
--- a/core/SkImageFilterUtils.cpp
+++ b/core/SkImageFilterUtils.cpp
@@ -15,8 +15,14 @@
#include "SkGr.h"
bool SkImageFilterUtils::WrapTexture(GrTexture* texture, int width, int height, SkBitmap* result) {
- result->setConfig(SkBitmap::kARGB_8888_Config, width, height);
- result->setPixelRef(SkNEW_ARGS(SkGrPixelRef, (texture)))->unref();
+ SkImageInfo info;
+ info.fWidth = width;
+ info.fHeight = height;
+ info.fColorType = kPMColor_SkColorType;
+ info.fAlphaType = kPremul_SkAlphaType;
+
+ result->setConfig(info);
+ result->setPixelRef(SkNEW_ARGS(SkGrPixelRef, (info, texture)))->unref();
return true;
}
@@ -36,8 +42,12 @@ bool SkImageFilterUtils::GetInputResultGPU(SkImageFilter* filter, SkImageFilter:
} else {
if (filter->filterImage(proxy, src, ctm, result, offset)) {
if (!result->getTexture()) {
+ SkImageInfo info;
+ if (!result->asImageInfo(&info)) {
+ return false;
+ }
GrTexture* resultTex = GrLockAndRefCachedBitmapTexture(context, *result, NULL);
- result->setPixelRef(new SkGrPixelRef(resultTex))->unref();
+ result->setPixelRef(new SkGrPixelRef(info, resultTex))->unref();
GrUnlockAndUnrefCachedBitmapTexture(resultTex);
}
return true;
diff --git a/core/SkMallocPixelRef.cpp b/core/SkMallocPixelRef.cpp
index f229e9de..613491a3 100644
--- a/core/SkMallocPixelRef.cpp
+++ b/core/SkMallocPixelRef.cpp
@@ -1,27 +1,105 @@
-
/*
* Copyright 2011 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
+
#include "SkMallocPixelRef.h"
#include "SkBitmap.h"
#include "SkFlattenableBuffers.h"
-SkMallocPixelRef::SkMallocPixelRef(void* storage, size_t size,
- SkColorTable* ctable, bool ownPixels) {
- if (NULL == storage) {
- SkASSERT(ownPixels);
- storage = sk_malloc_throw(size);
+static bool check_info(const SkImageInfo& info, SkColorTable* ctable) {
+ if (info.fWidth < 0 ||
+ info.fHeight < 0 ||
+ (unsigned)info.fColorType > (unsigned)kLastEnum_SkColorType ||
+ (unsigned)info.fAlphaType > (unsigned)kLastEnum_SkAlphaType)
+ {
+ return false;
+ }
+
+ // these seem like good checks, but currently we have (at least) tests
+ // that expect the pixelref to succeed even when there is a mismatch
+ // with colortables. fix?
+#if 0
+ if (kIndex8_SkColorType == info.fColorType && NULL == ctable) {
+ return false;
+ }
+ if (kIndex8_SkColorType != info.fColorType && NULL != ctable) {
+ return false;
+ }
+#endif
+ return true;
+}
+
+SkMallocPixelRef* SkMallocPixelRef::NewDirect(const SkImageInfo& info,
+ void* addr,
+ size_t rowBytes,
+ SkColorTable* ctable) {
+ if (!check_info(info, ctable)) {
+ return NULL;
+ }
+ return SkNEW_ARGS(SkMallocPixelRef, (info, addr, rowBytes, ctable, false));
+}
+
+SkMallocPixelRef* SkMallocPixelRef::NewAllocate(const SkImageInfo& info,
+ size_t requestedRowBytes,
+ SkColorTable* ctable) {
+ if (!check_info(info, ctable)) {
+ return NULL;
+ }
+
+ int32_t minRB = info.minRowBytes();
+ if (minRB < 0) {
+ return NULL; // allocation will be too large
+ }
+ if (requestedRowBytes > 0 && (int32_t)requestedRowBytes < minRB) {
+ return NULL; // cannot meet requested rowbytes
+ }
+
+ int32_t rowBytes;
+ if (requestedRowBytes) {
+ rowBytes = requestedRowBytes;
+ } else {
+ rowBytes = minRB;
}
+
+ Sk64 bigSize;
+ bigSize.setMul(info.fHeight, rowBytes);
+ if (!bigSize.is32()) {
+ return NULL;
+ }
+
+ size_t size = bigSize.get32();
+ void* addr = sk_malloc_flags(size, 0);
+ if (NULL == addr) {
+ return NULL;
+ }
+
+ return SkNEW_ARGS(SkMallocPixelRef, (info, addr, rowBytes, ctable, true));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+SkMallocPixelRef::SkMallocPixelRef(const SkImageInfo& info, void* storage,
+ size_t rowBytes, SkColorTable* ctable,
+ bool ownsPixels)
+ : SkPixelRef(info)
+ , fOwnPixels(ownsPixels)
+{
+ SkASSERT(check_info(info, ctable));
+ SkASSERT(rowBytes >= info.minRowBytes());
+
+ if (kIndex_8_SkColorType != info.fColorType) {
+ ctable = NULL;
+ }
+
fStorage = storage;
- fSize = size;
fCTable = ctable;
+ fRB = rowBytes;
SkSafeRef(ctable);
- fOwnPixels = ownPixels;
-
- this->setPreLocked(fStorage, fCTable);
+
+ this->setPreLocked(fStorage, fRB, fCTable);
}
SkMallocPixelRef::~SkMallocPixelRef() {
@@ -31,19 +109,30 @@ SkMallocPixelRef::~SkMallocPixelRef() {
}
}
-void* SkMallocPixelRef::onLockPixels(SkColorTable** ct) {
- *ct = fCTable;
- return fStorage;
+bool SkMallocPixelRef::onNewLockPixels(LockRec* rec) {
+ rec->fPixels = fStorage;
+ rec->fRowBytes = fRB;
+ rec->fColorTable = fCTable;
+ return true;
}
void SkMallocPixelRef::onUnlockPixels() {
// nothing to do
}
+size_t SkMallocPixelRef::getAllocatedSizeInBytes() const {
+ return this->info().getSafeSize(fRB);
+}
+
void SkMallocPixelRef::flatten(SkFlattenableWriteBuffer& buffer) const {
this->INHERITED::flatten(buffer);
- buffer.writeByteArray(fStorage, fSize);
+ buffer.write32(fRB);
+
+ // TODO: replace this bulk write with a chunky one that can trim off any
+ // trailing bytes on each scanline (in case rowbytes > width*size)
+ size_t size = this->info().getSafeSize(fRB);
+ buffer.writeByteArray(fStorage, size);
buffer.writeBool(fCTable != NULL);
if (fCTable) {
fCTable->writeToBuffer(buffer);
@@ -51,16 +140,18 @@ void SkMallocPixelRef::flatten(SkFlattenableWriteBuffer& buffer) const {
}
SkMallocPixelRef::SkMallocPixelRef(SkFlattenableReadBuffer& buffer)
- : INHERITED(buffer, NULL) {
- fSize = buffer.getArrayCount();
- fStorage = sk_malloc_throw(fSize);
- buffer.readByteArray(fStorage, fSize);
+ : INHERITED(buffer, NULL)
+ , fOwnPixels(true)
+{
+ fRB = buffer.read32();
+ size_t size = this->info().getSafeSize(fRB);
+ fStorage = sk_malloc_throw(size);
+ buffer.readByteArray(fStorage, size);
if (buffer.readBool()) {
fCTable = SkNEW_ARGS(SkColorTable, (buffer));
} else {
fCTable = NULL;
}
- fOwnPixels = true;
- this->setPreLocked(fStorage, fCTable);
+ this->setPreLocked(fStorage, fRB, fCTable);
}
diff --git a/core/SkMaskFilter.cpp b/core/SkMaskFilter.cpp
index f062f135..adfed410 100644
--- a/core/SkMaskFilter.cpp
+++ b/core/SkMaskFilter.cpp
@@ -349,10 +349,14 @@ bool SkMaskFilter::filterMaskGPU(GrContext* context,
if (!result) {
return false;
}
+ SkAutoUnref aur(dst);
+ SkImageInfo info;
resultBM->setConfig(srcBM.config(), dst->width(), dst->height());
- resultBM->setPixelRef(SkNEW_ARGS(SkGrPixelRef, (dst)))->unref();
- dst->unref();
+ if (resultBM->asImageInfo(&info)) {
+ return false;
+ }
+ resultBM->setPixelRef(SkNEW_ARGS(SkGrPixelRef, (info, dst)))->unref();
return true;
}
diff --git a/core/SkPixelRef.cpp b/core/SkPixelRef.cpp
index b5daf0b5..60b5cfb2 100644
--- a/core/SkPixelRef.cpp
+++ b/core/SkPixelRef.cpp
@@ -82,44 +82,32 @@ void SkPixelRef::setMutex(SkBaseMutex* mutex) {
// just need a > 0 value, so pick a funny one to aid in debugging
#define SKPIXELREF_PRELOCKED_LOCKCOUNT 123456789
-SkPixelRef::SkPixelRef(const SkImageInfo&, SkBaseMutex* mutex) {
- this->setMutex(mutex);
- fPixels = NULL;
- fColorTable = NULL; // we do not track ownership of this
- fLockCount = 0;
- this->needsNewGenID();
- fIsImmutable = false;
- fPreLocked = false;
-}
-
-SkPixelRef::SkPixelRef(const SkImageInfo&) {
+SkPixelRef::SkPixelRef(const SkImageInfo& info) {
this->setMutex(NULL);
- fPixels = NULL;
- fColorTable = NULL; // we do not track ownership of this
+ fInfo = info;
+ fRec.zero();
fLockCount = 0;
this->needsNewGenID();
fIsImmutable = false;
fPreLocked = false;
}
-#ifdef SK_SUPPORT_LEGACY_PIXELREF_CONSTRUCTOR
-// THIS GUY IS DEPRECATED -- don't use me!
-SkPixelRef::SkPixelRef(SkBaseMutex* mutex) {
+SkPixelRef::SkPixelRef(const SkImageInfo& info, SkBaseMutex* mutex) {
this->setMutex(mutex);
- fPixels = NULL;
- fColorTable = NULL; // we do not track ownership of this
+ fInfo = info;
+ fRec.zero();
fLockCount = 0;
this->needsNewGenID();
fIsImmutable = false;
fPreLocked = false;
}
-#endif
SkPixelRef::SkPixelRef(SkFlattenableReadBuffer& buffer, SkBaseMutex* mutex)
: INHERITED(buffer) {
this->setMutex(mutex);
- fPixels = NULL;
- fColorTable = NULL; // we do not track ownership of this
+
+ fInfo.unflatten(buffer);
+ fRec.zero();
fLockCount = 0;
fIsImmutable = buffer.readBool();
fGenerationID = buffer.readUInt();
@@ -143,12 +131,13 @@ void SkPixelRef::cloneGenID(const SkPixelRef& that) {
that.fUniqueGenerationID = false;
}
-void SkPixelRef::setPreLocked(void* pixels, SkColorTable* ctable) {
+void SkPixelRef::setPreLocked(void* pixels, size_t rowBytes, SkColorTable* ctable) {
#ifndef SK_IGNORE_PIXELREF_SETPRELOCKED
// only call me in your constructor, otherwise fLockCount tracking can get
// out of sync.
- fPixels = pixels;
- fColorTable = ctable;
+ fRec.fPixels = pixels;
+ fRec.fColorTable = ctable;
+ fRec.fRowBytes = rowBytes;
fLockCount = SKPIXELREF_PRELOCKED_LOCKCOUNT;
fPreLocked = true;
#endif
@@ -156,6 +145,8 @@ void SkPixelRef::setPreLocked(void* pixels, SkColorTable* ctable) {
void SkPixelRef::flatten(SkFlattenableWriteBuffer& buffer) const {
this->INHERITED::flatten(buffer);
+
+ fInfo.flatten(buffer);
buffer.writeBool(fIsImmutable);
// We write the gen ID into the picture for within-process recording. This
// is safe since the same genID will never refer to two different sets of
@@ -170,16 +161,27 @@ void SkPixelRef::flatten(SkFlattenableWriteBuffer& buffer) const {
}
}
-void SkPixelRef::lockPixels() {
+bool SkPixelRef::lockPixels(LockRec* rec) {
SkASSERT(!fPreLocked || SKPIXELREF_PRELOCKED_LOCKCOUNT == fLockCount);
-
+
if (!fPreLocked) {
SkAutoMutexAcquire ac(*fMutex);
-
+
if (1 == ++fLockCount) {
- fPixels = this->onLockPixels(&fColorTable);
+ LockRec rec;
+ if (!this->onNewLockPixels(&rec)) {
+ return false;
+ }
+ fRec = rec;
}
}
+ *rec = fRec;
+ return true;
+}
+
+bool SkPixelRef::lockPixels() {
+ LockRec rec;
+ return this->lockPixels(&rec);
}
void SkPixelRef::unlockPixels() {
@@ -191,8 +193,7 @@ void SkPixelRef::unlockPixels() {
SkASSERT(fLockCount > 0);
if (0 == --fLockCount) {
this->onUnlockPixels();
- fPixels = NULL;
- fColorTable = NULL;
+ fRec.zero();
}
}
}
@@ -273,6 +274,29 @@ size_t SkPixelRef::getAllocatedSizeInBytes() const {
///////////////////////////////////////////////////////////////////////////////
+#ifdef SK_SUPPORT_LEGACY_ONLOCKPIXELS
+
+void* SkPixelRef::onLockPixels(SkColorTable** ctable) {
+ return NULL;
+}
+
+bool SkPixelRef::onNewLockPixels(LockRec* rec) {
+ SkColorTable* ctable;
+ void* pixels = this->onLockPixels(&ctable);
+ if (!pixels) {
+ return false;
+ }
+
+ rec->fPixels = pixels;
+ rec->fColorTable = ctable;
+ rec->fRowBytes = 0; // callers don't currently need this (thank goodness)
+ return true;
+}
+
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+
#ifdef SK_BUILD_FOR_ANDROID
void SkPixelRef::globalRef(void* data) {
this->ref();
diff --git a/effects/gradients/SkGradientShader.cpp b/effects/gradients/SkGradientShader.cpp
index 27761993..5d200d18 100644
--- a/effects/gradients/SkGradientShader.cpp
+++ b/effects/gradients/SkGradientShader.cpp
@@ -513,13 +513,14 @@ const uint16_t* SkGradientShaderBase::getCache16() const {
const SkPMColor* SkGradientShaderBase::getCache32() const {
if (fCache32 == NULL) {
- // double the count for dither entries
- const int entryCount = kCache32Count * 4;
- const size_t allocSize = sizeof(SkPMColor) * entryCount;
+ SkImageInfo info;
+ info.fWidth = kCache32Count;
+ info.fHeight = 4; // for our 4 dither rows
+ info.fAlphaType = kPremul_SkAlphaType;
+ info.fColorType = kPMColor_SkColorType;
if (NULL == fCache32PixelRef) {
- fCache32PixelRef = SkNEW_ARGS(SkMallocPixelRef,
- (NULL, allocSize, NULL));
+ fCache32PixelRef = SkMallocPixelRef::NewAllocate(info, 0, NULL);
}
fCache32 = (SkPMColor*)fCache32PixelRef->getAddr();
if (fColorCount == 2) {
@@ -541,8 +542,7 @@ const SkPMColor* SkGradientShaderBase::getCache32() const {
}
if (fMapper) {
- SkMallocPixelRef* newPR = SkNEW_ARGS(SkMallocPixelRef,
- (NULL, allocSize, NULL));
+ SkMallocPixelRef* newPR = SkMallocPixelRef::NewAllocate(info, 0, NULL);
SkPMColor* linear = fCache32; // just computed linear data
SkPMColor* mapped = (SkPMColor*)newPR->getAddr(); // storage for mapped data
SkUnitMapper* map = fMapper;
diff --git a/gpu/GrSurface.cpp b/gpu/GrSurface.cpp
index fed95f23..1fcc4ff1 100644
--- a/gpu/GrSurface.cpp
+++ b/gpu/GrSurface.cpp
@@ -8,9 +8,19 @@
#include "GrSurface.h"
#include "SkBitmap.h"
+#include "SkGr.h"
#include "SkImageEncoder.h"
#include <stdio.h>
+void GrSurface::asImageInfo(SkImageInfo* info) const {
+ if (!GrPixelConfig2ColorType(this->config(), &info->fColorType)) {
+ sk_throw();
+ }
+ info->fWidth = this->width();
+ info->fHeight = this->height();
+ info->fAlphaType = kPremul_SkAlphaType;
+}
+
bool GrSurface::savePixels(const char* filename) {
SkBitmap bm;
bm.setConfig(SkBitmap::kARGB_8888_Config, this->width(), this->height());
diff --git a/gpu/SkGpuDevice.cpp b/gpu/SkGpuDevice.cpp
index ce02f2c5..a413d042 100644
--- a/gpu/SkGpuDevice.cpp
+++ b/gpu/SkGpuDevice.cpp
@@ -214,7 +214,10 @@ void SkGpuDevice::initFromRenderTarget(GrContext* context,
if (NULL == surface) {
surface = fRenderTarget;
}
- SkPixelRef* pr = SkNEW_ARGS(SkGrPixelRef, (surface, cached));
+
+ SkImageInfo info;
+ surface->asImageInfo(&info);
+ SkPixelRef* pr = SkNEW_ARGS(SkGrPixelRef, (info, surface, cached));
this->setPixelRef(pr, 0)->unref();
}
@@ -224,8 +227,8 @@ SkGpuDevice::SkGpuDevice(GrContext* context,
int width,
int height,
int sampleCount)
- : SkBitmapDevice(make_bitmap(config, width, height, false /*isOpaque*/)) {
-
+ : SkBitmapDevice(make_bitmap(config, width, height, false /*isOpaque*/))
+{
fDrawProcs = NULL;
fContext = context;
@@ -245,6 +248,14 @@ SkGpuDevice::SkGpuDevice(GrContext* context,
desc.fConfig = SkBitmapConfig2GrPixelConfig(config);
desc.fSampleCnt = sampleCount;
+ SkImageInfo info;
+ if (!GrPixelConfig2ColorType(desc.fConfig, &info.fColorType)) {
+ sk_throw();
+ }
+ info.fWidth = width;
+ info.fHeight = height;
+ info.fAlphaType = kPremul_SkAlphaType;
+
SkAutoTUnref<GrTexture> texture(fContext->createUncachedTexture(desc, NULL, 0));
if (NULL != texture) {
@@ -254,7 +265,7 @@ SkGpuDevice::SkGpuDevice(GrContext* context,
SkASSERT(NULL != fRenderTarget);
// wrap the bitmap with a pixelref to expose our texture
- SkGrPixelRef* pr = SkNEW_ARGS(SkGrPixelRef, (texture));
+ SkGrPixelRef* pr = SkNEW_ARGS(SkGrPixelRef, (info, texture));
this->setPixelRef(pr, 0)->unref();
} else {
GrPrintf("--- failed to create gpu-offscreen [%d %d]\n",
@@ -840,11 +851,12 @@ bool create_mask_GPU(GrContext* context,
}
SkBitmap wrap_texture(GrTexture* texture) {
+ SkImageInfo info;
+ texture->asImageInfo(&info);
+
SkBitmap result;
- bool dummy;
- SkBitmap::Config config = grConfig2skConfig(texture->config(), &dummy);
- result.setConfig(config, texture->width(), texture->height());
- result.setPixelRef(SkNEW_ARGS(SkGrPixelRef, (texture)))->unref();
+ result.setConfig(info);
+ result.setPixelRef(SkNEW_ARGS(SkGrPixelRef, (info, texture)))->unref();
return result;
}
diff --git a/gpu/SkGr.cpp b/gpu/SkGr.cpp
index c7ae0c8f..a3f0eefa 100644
--- a/gpu/SkGr.cpp
+++ b/gpu/SkGr.cpp
@@ -258,3 +258,33 @@ GrPixelConfig SkBitmapConfig2GrPixelConfig(SkBitmap::Config config) {
return kUnknown_GrPixelConfig;
}
}
+
+bool GrPixelConfig2ColorType(GrPixelConfig config, SkColorType* ctOut) {
+ SkColorType ct;
+ switch (config) {
+ case kAlpha_8_GrPixelConfig:
+ ct = kAlpha_8_SkColorType;
+ break;
+ case kIndex_8_GrPixelConfig:
+ ct = kIndex_8_SkColorType;
+ break;
+ case kRGB_565_GrPixelConfig:
+ ct = kRGB_565_SkColorType;
+ break;
+ case kRGBA_4444_GrPixelConfig:
+ ct = kARGB_4444_SkColorType;
+ break;
+ case kRGBA_8888_GrPixelConfig:
+ ct = kRGBA_8888_SkColorType;
+ break;
+ case kBGRA_8888_GrPixelConfig:
+ ct = kBGRA_8888_SkColorType;
+ break;
+ default:
+ return false;
+ }
+ if (ctOut) {
+ *ctOut = ct;
+ }
+ return true;
+}
diff --git a/gpu/SkGrPixelRef.cpp b/gpu/SkGrPixelRef.cpp
index 01294266..74b1a4fa 100644
--- a/gpu/SkGrPixelRef.cpp
+++ b/gpu/SkGrPixelRef.cpp
@@ -18,24 +18,29 @@
// to avoid deadlock with the default one provided by SkPixelRef.
SK_DECLARE_STATIC_MUTEX(gROLockPixelsPixelRefMutex);
-SkROLockPixelsPixelRef::SkROLockPixelsPixelRef() : INHERITED(&gROLockPixelsPixelRefMutex) {
+SkROLockPixelsPixelRef::SkROLockPixelsPixelRef(const SkImageInfo& info)
+ : INHERITED(info, &gROLockPixelsPixelRefMutex) {
}
SkROLockPixelsPixelRef::~SkROLockPixelsPixelRef() {
}
-void* SkROLockPixelsPixelRef::onLockPixels(SkColorTable** ctable) {
- if (ctable) {
- *ctable = NULL;
- }
+bool SkROLockPixelsPixelRef::onNewLockPixels(LockRec* rec) {
fBitmap.reset();
// SkDebugf("---------- calling readpixels in support of lockpixels\n");
if (!this->onReadPixels(&fBitmap, NULL)) {
SkDebugf("SkROLockPixelsPixelRef::onLockPixels failed!\n");
- return NULL;
+ return false;
}
fBitmap.lockPixels();
- return fBitmap.getPixels();
+ if (NULL == fBitmap.getPixels()) {
+ return false;
+ }
+
+ rec->fPixels = fBitmap.getPixels();
+ rec->fColorTable = NULL;
+ rec->fRowBytes = fBitmap.rowBytes();
+ return true;
}
void SkROLockPixelsPixelRef::onUnlockPixels() {
@@ -76,6 +81,14 @@ static SkGrPixelRef* copyToTexturePixelRef(GrTexture* texture, SkBitmap::Config
desc.fFlags = kRenderTarget_GrTextureFlagBit | kNoStencil_GrTextureFlagBit;
desc.fConfig = SkBitmapConfig2GrPixelConfig(dstConfig);
+ SkImageInfo info;
+ if (!GrPixelConfig2ColorType(desc.fConfig, &info.fColorType)) {
+ return NULL;
+ }
+ info.fWidth = desc.fWidth;
+ info.fHeight = desc.fHeight;
+ info.fAlphaType = kPremul_SkAlphaType;
+
GrTexture* dst = context->createUncachedTexture(desc, NULL, 0);
if (NULL == dst) {
return NULL;
@@ -93,31 +106,17 @@ static SkGrPixelRef* copyToTexturePixelRef(GrTexture* texture, SkBitmap::Config
dst->releaseRenderTarget();
#endif
- SkGrPixelRef* pixelRef = SkNEW_ARGS(SkGrPixelRef, (dst));
+ SkGrPixelRef* pixelRef = SkNEW_ARGS(SkGrPixelRef, (info, dst));
SkSafeUnref(dst);
return pixelRef;
}
///////////////////////////////////////////////////////////////////////////////
-SkGrPixelRef::SkGrPixelRef(GrSurface* surface, bool transferCacheLock) {
- // TODO: figure out if this is responsible for Chrome canvas errors
-#if 0
- // The GrTexture has a ref to the GrRenderTarget but not vice versa.
- // If the GrTexture exists take a ref to that (rather than the render
- // target)
- fSurface = surface->asTexture();
-#else
- fSurface = NULL;
-#endif
- if (NULL == fSurface) {
- fSurface = surface;
- }
- fUnlock = transferCacheLock;
- SkSafeRef(surface);
-}
-
-SkGrPixelRef::SkGrPixelRef(const SkImageInfo&, GrSurface* surface, bool transferCacheLock) {
+SkGrPixelRef::SkGrPixelRef(const SkImageInfo& info, GrSurface* surface,
+ bool transferCacheLock)
+ : INHERITED(info)
+{
// TODO: figure out if this is responsible for Chrome canvas errors
#if 0
// The GrTexture has a ref to the GrRenderTarget but not vice versa.
diff --git a/image/SkDataPixelRef.cpp b/image/SkDataPixelRef.cpp
index 7897bf93..875f933b 100644
--- a/image/SkDataPixelRef.cpp
+++ b/image/SkDataPixelRef.cpp
@@ -9,18 +9,25 @@
#include "SkData.h"
#include "SkFlattenableBuffers.h"
-SkDataPixelRef::SkDataPixelRef(SkData* data) : fData(data) {
+SkDataPixelRef::SkDataPixelRef(const SkImageInfo& info,
+ SkData* data, size_t rowBytes)
+ : INHERITED(info)
+ , fData(data)
+ , fRB(rowBytes)
+{
fData->ref();
- this->setPreLocked(const_cast<void*>(fData->data()), NULL);
+ this->setPreLocked(const_cast<void*>(fData->data()), rowBytes, NULL);
}
SkDataPixelRef::~SkDataPixelRef() {
fData->unref();
}
-void* SkDataPixelRef::onLockPixels(SkColorTable** ct) {
- *ct = NULL;
- return const_cast<void*>(fData->data());
+bool SkDataPixelRef::onNewLockPixels(LockRec* rec) {
+ rec->fPixels = const_cast<void*>(fData->data());
+ rec->fColorTable = NULL;
+ rec->fRowBytes = fRB;
+ return true;
}
void SkDataPixelRef::onUnlockPixels() {
@@ -33,11 +40,15 @@ size_t SkDataPixelRef::getAllocatedSizeInBytes() const {
void SkDataPixelRef::flatten(SkFlattenableWriteBuffer& buffer) const {
this->INHERITED::flatten(buffer);
+
buffer.writeDataAsByteArray(fData);
+ buffer.write32(fRB);
}
SkDataPixelRef::SkDataPixelRef(SkFlattenableReadBuffer& buffer)
- : INHERITED(buffer, NULL) {
+ : INHERITED(buffer, NULL)
+{
fData = buffer.readByteArrayAsData();
- this->setPreLocked(const_cast<void*>(fData->data()), NULL);
+ fRB = buffer.read32();
+ this->setPreLocked(const_cast<void*>(fData->data()), fRB, NULL);
}
diff --git a/image/SkDataPixelRef.h b/image/SkDataPixelRef.h
index 50c88571..c2e52cd9 100644
--- a/image/SkDataPixelRef.h
+++ b/image/SkDataPixelRef.h
@@ -14,13 +14,13 @@ class SkData;
class SkDataPixelRef : public SkPixelRef {
public:
- SkDataPixelRef(SkData* data);
+ SkDataPixelRef(const SkImageInfo&, SkData* data, size_t rowBytes);
virtual ~SkDataPixelRef();
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkDataPixelRef)
protected:
- virtual void* onLockPixels(SkColorTable**) SK_OVERRIDE;
+ virtual bool onNewLockPixels(LockRec*) SK_OVERRIDE;
virtual void onUnlockPixels() SK_OVERRIDE;
virtual size_t getAllocatedSizeInBytes() const SK_OVERRIDE;
@@ -28,7 +28,8 @@ protected:
virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;
private:
- SkData* fData;
+ SkData* fData;
+ size_t fRB;
typedef SkPixelRef INHERITED;
};
diff --git a/image/SkImage_Raster.cpp b/image/SkImage_Raster.cpp
index a872ae36..93de5ea3 100644
--- a/image/SkImage_Raster.cpp
+++ b/image/SkImage_Raster.cpp
@@ -84,10 +84,8 @@ SkImage* SkImage_Raster::NewEmpty() {
SkImage_Raster::SkImage_Raster(const Info& info, SkData* data, size_t rowBytes)
: INHERITED(info.fWidth, info.fHeight) {
- SkBitmap::Config config = SkImageInfoToBitmapConfig(info);
-
- fBitmap.setConfig(config, info.fWidth, info.fHeight, rowBytes, info.fAlphaType);
- fBitmap.setPixelRef(SkNEW_ARGS(SkDataPixelRef, (data)))->unref();
+ fBitmap.setConfig(info, rowBytes);
+ fBitmap.setPixelRef(SkNEW_ARGS(SkDataPixelRef, (info, data, rowBytes)))->unref();
fBitmap.setImmutable();
}
diff --git a/image/SkSurface_Raster.cpp b/image/SkSurface_Raster.cpp
index 27db504d..61ade6f4 100644
--- a/image/SkSurface_Raster.cpp
+++ b/image/SkSurface_Raster.cpp
@@ -155,19 +155,9 @@ SkSurface* SkSurface::NewRaster(const SkImageInfo& info) {
return NULL;
}
- static const size_t kMaxTotalSize = SK_MaxS32;
- size_t rowBytes = SkImageMinRowBytes(info);
- uint64_t size64 = (uint64_t)info.fHeight * rowBytes;
- if (size64 > kMaxTotalSize) {
- return NULL;
- }
-
- size_t size = (size_t)size64;
- void* pixels = sk_malloc_throw(size);
- if (NULL == pixels) {
+ SkAutoTUnref<SkPixelRef> pr(SkMallocPixelRef::NewAllocate(info, 0, NULL));
+ if (NULL == pr.get()) {
return NULL;
}
-
- SkAutoTUnref<SkPixelRef> pr(SkNEW_ARGS(SkMallocPixelRef, (pixels, size, NULL, true)));
- return SkNEW_ARGS(SkSurface_Raster, (info, pr, rowBytes));
+ return SkNEW_ARGS(SkSurface_Raster, (info, pr, info.minRowBytes()));
}
diff --git a/images/SkImageRef.cpp b/images/SkImageRef.cpp
index 1a8284bd..99782c45 100644
--- a/images/SkImageRef.cpp
+++ b/images/SkImageRef.cpp
@@ -15,16 +15,14 @@
//#define DUMP_IMAGEREF_LIFECYCLE
-
///////////////////////////////////////////////////////////////////////////////
-SkImageRef::SkImageRef(SkStreamRewindable* stream, SkBitmap::Config config,
+SkImageRef::SkImageRef(const SkImageInfo& info, SkStreamRewindable* stream,
int sampleSize, SkBaseMutex* mutex)
- : SkPixelRef(mutex), fErrorInDecoding(false) {
+ : INHERITED(info, mutex), fErrorInDecoding(false) {
SkASSERT(stream);
stream->ref();
fStream = stream;
- fConfig = config;
fSampleSize = sampleSize;
fDoDither = true;
fPrev = fNext = NULL;
@@ -40,7 +38,7 @@ SkImageRef::~SkImageRef() {
#ifdef DUMP_IMAGEREF_LIFECYCLE
SkDebugf("delete ImageRef %p [%d] data=%d\n",
- this, fConfig, (int)fStream->getLength());
+ this, this->info().fColorType, (int)fStream->getLength());
#endif
fStream->unref();
@@ -92,14 +90,6 @@ bool SkImageRef::prepareBitmap(SkImageDecoder::Mode mode) {
return false;
}
- /* As soon as we really know our config, we record it, so that on
- subsequent calls to the codec, we are sure we will always get the same
- result.
- */
- if (SkBitmap::kNo_Config != fBitmap.config()) {
- fConfig = fBitmap.config();
- }
-
if (NULL != fBitmap.getPixels() ||
(SkBitmap::kNo_Config != fBitmap.config() &&
SkImageDecoder::kDecodeBounds_Mode == mode)) {
@@ -125,7 +115,7 @@ bool SkImageRef::prepareBitmap(SkImageDecoder::Mode mode) {
codec->setSampleSize(fSampleSize);
codec->setDitherImage(fDoDither);
- if (this->onDecode(codec, fStream, &fBitmap, fConfig, mode)) {
+ if (this->onDecode(codec, fStream, &fBitmap, fBitmap.config(), mode)) {
return true;
}
}
@@ -143,15 +133,18 @@ bool SkImageRef::prepareBitmap(SkImageDecoder::Mode mode) {
return false;
}
-void* SkImageRef::onLockPixels(SkColorTable** ct) {
+bool SkImageRef::onNewLockPixels(LockRec* rec) {
if (NULL == fBitmap.getPixels()) {
(void)this->prepareBitmap(SkImageDecoder::kDecodePixels_Mode);
}
- if (ct) {
- *ct = fBitmap.getColorTable();
+ if (NULL == fBitmap.getPixels()) {
+ return false;
}
- return fBitmap.getPixels();
+ rec->fPixels = fBitmap.getPixels();
+ rec->fColorTable = NULL;
+ rec->fRowBytes = fBitmap.rowBytes();
+ return true;
}
size_t SkImageRef::ramUsed() const {
@@ -170,7 +163,6 @@ size_t SkImageRef::ramUsed() const {
SkImageRef::SkImageRef(SkFlattenableReadBuffer& buffer, SkBaseMutex* mutex)
: INHERITED(buffer, mutex), fErrorInDecoding(false) {
- fConfig = (SkBitmap::Config)buffer.readUInt();
fSampleSize = buffer.readInt();
fDoDither = buffer.readBool();
@@ -185,7 +177,6 @@ SkImageRef::SkImageRef(SkFlattenableReadBuffer& buffer, SkBaseMutex* mutex)
void SkImageRef::flatten(SkFlattenableWriteBuffer& buffer) const {
this->INHERITED::flatten(buffer);
- buffer.writeUInt(fConfig);
buffer.writeInt(fSampleSize);
buffer.writeBool(fDoDither);
// FIXME: Consider moving this logic should go into writeStream itself.
diff --git a/images/SkImageRef_GlobalPool.cpp b/images/SkImageRef_GlobalPool.cpp
index 352dd42d..f91cebab 100644
--- a/images/SkImageRef_GlobalPool.cpp
+++ b/images/SkImageRef_GlobalPool.cpp
@@ -24,10 +24,10 @@ static SkImageRefPool* GetGlobalPool() {
return gPool;
}
-SkImageRef_GlobalPool::SkImageRef_GlobalPool(SkStreamRewindable* stream,
- SkBitmap::Config config,
+SkImageRef_GlobalPool::SkImageRef_GlobalPool(const SkImageInfo& info,
+ SkStreamRewindable* stream,
int sampleSize)
- : SkImageRef(stream, config, sampleSize, &gGlobalPoolMutex) {
+ : SkImageRef(info, stream, sampleSize, &gGlobalPoolMutex) {
SkASSERT(&gGlobalPoolMutex == this->mutex());
SkAutoMutexAcquire ac(gGlobalPoolMutex);
GetGlobalPool()->addToHead(this);
diff --git a/images/SkImageRef_ashmem.cpp b/images/SkImageRef_ashmem.cpp
index 0dba1d11..383a487d 100644
--- a/images/SkImageRef_ashmem.cpp
+++ b/images/SkImageRef_ashmem.cpp
@@ -31,10 +31,10 @@ static size_t roundToPageSize(size_t size) {
return newsize;
}
-SkImageRef_ashmem::SkImageRef_ashmem(SkStreamRewindable* stream,
- SkBitmap::Config config,
- int sampleSize)
- : SkImageRef(stream, config, sampleSize) {
+SkImageRef_ashmem::SkImageRef_ashmem(const SkImageInfo& info,
+ SkStreamRewindable* stream,
+ int sampleSize)
+ : SkImageRef(info, stream, sampleSize) {
fRec.fFD = -1;
fRec.fAddr = NULL;
diff --git a/images/SkImageRef_ashmem.h b/images/SkImageRef_ashmem.h
index efee5e75..a2652fbc 100644
--- a/images/SkImageRef_ashmem.h
+++ b/images/SkImageRef_ashmem.h
@@ -19,7 +19,7 @@ struct SkAshmemRec {
class SkImageRef_ashmem : public SkImageRef {
public:
- SkImageRef_ashmem(SkStreamRewindable*, SkBitmap::Config, int sampleSize = 1);
+ SkImageRef_ashmem(const SkImageInfo&, SkStreamRewindable*, int sampleSize = 1);
virtual ~SkImageRef_ashmem();
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkImageRef_ashmem)
diff --git a/lazy/SkCachingPixelRef.cpp b/lazy/SkCachingPixelRef.cpp
index 667a9493..fba98455 100644
--- a/lazy/SkCachingPixelRef.cpp
+++ b/lazy/SkCachingPixelRef.cpp
@@ -8,7 +8,6 @@
#include "SkCachingPixelRef.h"
#include "SkScaledImageCache.h"
-
bool SkCachingPixelRef::Install(SkImageGenerator* generator,
SkBitmap* dst) {
SkImageInfo info;
@@ -31,10 +30,10 @@ bool SkCachingPixelRef::Install(SkImageGenerator* generator,
SkCachingPixelRef::SkCachingPixelRef(SkImageGenerator* generator,
const SkImageInfo& info,
size_t rowBytes)
- : fImageGenerator(generator)
+ : INHERITED(info)
+ , fImageGenerator(generator)
, fErrorInDecoding(false)
, fScaledCacheId(NULL)
- , fInfo(info)
, fRowBytes(rowBytes) {
SkASSERT(fImageGenerator != NULL);
}
@@ -44,31 +43,32 @@ SkCachingPixelRef::~SkCachingPixelRef() {
// Assert always unlock before unref.
}
-void* SkCachingPixelRef::onLockPixels(SkColorTable** colorTable) {
- (void)colorTable;
+bool SkCachingPixelRef::onNewLockPixels(LockRec* rec) {
if (fErrorInDecoding) {
- return NULL; // don't try again.
+ return false; // don't try again.
}
+
+ const SkImageInfo& info = this->info();
SkBitmap bitmap;
SkASSERT(NULL == fScaledCacheId);
fScaledCacheId = SkScaledImageCache::FindAndLock(this->getGenerationID(),
- fInfo.fWidth,
- fInfo.fHeight,
+ info.fWidth,
+ info.fHeight,
&bitmap);
if (NULL == fScaledCacheId) {
// Cache has been purged, must re-decode.
- if ((!bitmap.setConfig(fInfo, fRowBytes)) || !bitmap.allocPixels()) {
+ if ((!bitmap.setConfig(info, fRowBytes)) || !bitmap.allocPixels()) {
fErrorInDecoding = true;
- return NULL;
+ return false;
}
SkAutoLockPixels autoLockPixels(bitmap);
- if (!fImageGenerator->getPixels(fInfo, bitmap.getPixels(), fRowBytes)) {
+ if (!fImageGenerator->getPixels(info, bitmap.getPixels(), fRowBytes)) {
fErrorInDecoding = true;
- return NULL;
+ return false;
}
fScaledCacheId = SkScaledImageCache::AddAndLock(this->getGenerationID(),
- fInfo.fWidth,
- fInfo.fHeight,
+ info.fWidth,
+ info.fHeight,
bitmap);
SkASSERT(fScaledCacheId != NULL);
}
@@ -78,6 +78,7 @@ void* SkCachingPixelRef::onLockPixels(SkColorTable** colorTable) {
SkAutoLockPixels autoLockPixels(bitmap);
void* pixels = bitmap.getPixels();
SkASSERT(pixels != NULL);
+
// At this point, the autoLockPixels will unlockPixels()
// to remove bitmap's lock on the pixels. We will then
// destroy bitmap. The *only* guarantee that this pointer
@@ -86,7 +87,10 @@ void* SkCachingPixelRef::onLockPixels(SkColorTable** colorTable) {
// bitmap (SkScaledImageCache::Rec.fBitmap) that holds a
// reference to the concrete PixelRef while this record is
// locked.
- return pixels;
+ rec->fPixels = pixels;
+ rec->fColorTable = NULL;
+ rec->fRowBytes = bitmap.rowBytes();
+ return true;
}
void SkCachingPixelRef::onUnlockPixels() {
diff --git a/lazy/SkCachingPixelRef.h b/lazy/SkCachingPixelRef.h
index 4a0387dd..75710d8b 100644
--- a/lazy/SkCachingPixelRef.h
+++ b/lazy/SkCachingPixelRef.h
@@ -40,7 +40,7 @@ public:
protected:
virtual ~SkCachingPixelRef();
- virtual void* onLockPixels(SkColorTable** colorTable) SK_OVERRIDE;
+ virtual bool onNewLockPixels(LockRec*) SK_OVERRIDE;
virtual void onUnlockPixels() SK_OVERRIDE;
virtual bool onLockPixelsAreWritable() const SK_OVERRIDE { return false; }
@@ -58,12 +58,12 @@ private:
SkImageGenerator* const fImageGenerator;
bool fErrorInDecoding;
void* fScaledCacheId;
- const SkImageInfo fInfo;
const size_t fRowBytes;
SkCachingPixelRef(SkImageGenerator* imageGenerator,
const SkImageInfo& info,
size_t rowBytes);
+
typedef SkPixelRef INHERITED;
};
diff --git a/lazy/SkDiscardablePixelRef.cpp b/lazy/SkDiscardablePixelRef.cpp
index 6a9507c8..eb35d0fc 100644
--- a/lazy/SkDiscardablePixelRef.cpp
+++ b/lazy/SkDiscardablePixelRef.cpp
@@ -11,17 +11,15 @@
SkDiscardablePixelRef::SkDiscardablePixelRef(SkImageGenerator* generator,
const SkImageInfo& info,
- size_t size,
size_t rowBytes,
SkDiscardableMemory::Factory* fact)
- : fGenerator(generator)
+ : INHERITED(info)
+ , fGenerator(generator)
, fDMFactory(fact)
- , fInfo(info)
- , fSize(size)
, fRowBytes(rowBytes)
- , fDiscardableMemory(NULL) {
+ , fDiscardableMemory(NULL)
+{
SkASSERT(fGenerator != NULL);
- SkASSERT(fSize > 0);
SkASSERT(fRowBytes > 0);
// The SkImageGenerator contract requires fGenerator to always
// decode the same image on each call to getPixels().
@@ -35,28 +33,39 @@ SkDiscardablePixelRef::~SkDiscardablePixelRef() {
SkDELETE(fGenerator);
}
-void* SkDiscardablePixelRef::onLockPixels(SkColorTable**) {
+bool SkDiscardablePixelRef::onNewLockPixels(LockRec* rec) {
if (fDiscardableMemory != NULL) {
if (fDiscardableMemory->lock()) {
- return fDiscardableMemory->data();
+ rec->fPixels = fDiscardableMemory->data();
+ rec->fColorTable = NULL;
+ rec->fRowBytes = fRowBytes;
+ return true;
}
SkDELETE(fDiscardableMemory);
fDiscardableMemory = NULL;
}
+
+ const size_t size = this->info().getSafeSize(fRowBytes);
if (fDMFactory != NULL) {
- fDiscardableMemory = fDMFactory->create(fSize);
+ fDiscardableMemory = fDMFactory->create(size);
} else {
- fDiscardableMemory = SkDiscardableMemory::Create(fSize);
+ fDiscardableMemory = SkDiscardableMemory::Create(size);
}
if (NULL == fDiscardableMemory) {
- return NULL; // Memory allocation failed.
+ return false; // Memory allocation failed.
}
+
void* pixels = fDiscardableMemory->data();
- if (!fGenerator->getPixels(fInfo, pixels, fRowBytes)) {
- return NULL; // TODO(halcanary) Find out correct thing to do.
+ if (!fGenerator->getPixels(this->info(), pixels, fRowBytes)) {
+ return false; // TODO(halcanary) Find out correct thing to do.
}
- return pixels;
+
+ rec->fPixels = pixels;
+ rec->fColorTable = NULL;
+ rec->fRowBytes = fRowBytes;
+ return true;
}
+
void SkDiscardablePixelRef::onUnlockPixels() {
if (fDiscardableMemory != NULL) {
fDiscardableMemory->unlock();
@@ -81,7 +90,6 @@ bool SkInstallDiscardablePixelRef(SkImageGenerator* generator,
}
SkAutoTUnref<SkDiscardablePixelRef> ref(SkNEW_ARGS(SkDiscardablePixelRef,
(generator, info,
- dst->getSize(),
dst->rowBytes(),
factory)));
dst->setPixelRef(ref);
diff --git a/lazy/SkDiscardablePixelRef.h b/lazy/SkDiscardablePixelRef.h
index 44c6df96..0a727b63 100644
--- a/lazy/SkDiscardablePixelRef.h
+++ b/lazy/SkDiscardablePixelRef.h
@@ -19,7 +19,8 @@ public:
protected:
~SkDiscardablePixelRef();
- virtual void* onLockPixels(SkColorTable**) SK_OVERRIDE;
+
+ virtual bool onNewLockPixels(LockRec*) SK_OVERRIDE;
virtual void onUnlockPixels() SK_OVERRIDE;
virtual bool onLockPixelsAreWritable() const SK_OVERRIDE { return false; }
@@ -30,8 +31,6 @@ protected:
private:
SkImageGenerator* const fGenerator;
SkDiscardableMemory::Factory* const fDMFactory;
- const SkImageInfo fInfo;
- const size_t fSize; // size of memory to be allocated
const size_t fRowBytes;
// These const members should not change over the life of the
// PixelRef, since the SkBitmap doesn't expect them to change.
@@ -41,12 +40,14 @@ private:
/* Takes ownership of SkImageGenerator. */
SkDiscardablePixelRef(SkImageGenerator* generator,
const SkImageInfo& info,
- size_t size,
size_t rowBytes,
SkDiscardableMemory::Factory* factory);
+
friend bool SkInstallDiscardablePixelRef(SkImageGenerator*,
SkBitmap*,
SkDiscardableMemory::Factory*);
+
typedef SkPixelRef INHERITED;
};
+
#endif // SkDiscardablePixelRef_DEFINED