aboutsummaryrefslogtreecommitdiffhomepage
path: root/include
diff options
context:
space:
mode:
authorGravatar reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-12-06 18:41:33 +0000
committerGravatar reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-12-06 18:41:33 +0000
commit3e89524e747b513986abfeeea00b6fac79593f26 (patch)
tree2ccdbfb082b488e8a60749a07d778d9f82fac33c /include
parent332999eabf8738d3b34e91b4a2e92daf5c7d7573 (diff)
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.
R=mtklein@google.com, scroggo@google.com Review URL: https://codereview.chromium.org/68973005 git-svn-id: http://skia.googlecode.com/svn/trunk@12537 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'include')
-rw-r--r--include/core/SkBitmap.h7
-rw-r--r--include/core/SkBitmapDevice.h2
-rw-r--r--include/core/SkImageInfo.h19
-rw-r--r--include/core/SkMallocPixelRef.h51
-rw-r--r--include/core/SkPicture.h3
-rw-r--r--include/core/SkPixelRef.h81
-rw-r--r--include/gpu/GrSurface.h3
-rw-r--r--include/gpu/SkGr.h1
-rw-r--r--include/gpu/SkGrPixelRef.h11
-rw-r--r--include/images/SkImageRef.h7
-rw-r--r--include/images/SkImageRef_GlobalPool.h2
11 files changed, 141 insertions, 46 deletions
diff --git a/include/core/SkBitmap.h b/include/core/SkBitmap.h
index cd85b6a9b1..c0e299ab94 100644
--- a/include/core/SkBitmap.h
+++ b/include/core/SkBitmap.h
@@ -250,6 +250,13 @@ public:
bool setConfig(const SkImageInfo& info, size_t rowBytes = 0);
+ /**
+ * If the bitmap's config can be represented as SkImageInfo, return true,
+ * and if info is not-null, set it to the bitmap's info. If it cannot be
+ * represented as SkImageInfo, return false and ignore the info parameter.
+ */
+ bool asImageInfo(SkImageInfo* info) const;
+
/** Use this to assign a new pixel address for an existing bitmap. This
will automatically release any pixelref previously installed. Only call
this if you are handling ownership/lifetime of the pixel memory.
diff --git a/include/core/SkBitmapDevice.h b/include/core/SkBitmapDevice.h
index 83f480c60c..f3d40d0ce8 100644
--- a/include/core/SkBitmapDevice.h
+++ b/include/core/SkBitmapDevice.h
@@ -258,6 +258,8 @@ private:
friend class SkSurface_Raster;
+ void init(SkBitmap::Config config, int width, int height, bool isOpaque);
+
// used to change the backend's pixels (and possibly config/rowbytes)
// but cannot change the width/height, so there should be no change to
// any clip information.
diff --git a/include/core/SkImageInfo.h b/include/core/SkImageInfo.h
index c22249b842..366d00af70 100644
--- a/include/core/SkImageInfo.h
+++ b/include/core/SkImageInfo.h
@@ -10,6 +10,9 @@
#include "SkTypes.h"
+class SkFlattenableWriteBuffer;
+class SkFlattenableReadBuffer;
+
/**
* Describes how to interpret the alpha compoent of a pixel.
*/
@@ -63,6 +66,7 @@ static inline bool SkAlphaTypeIsOpaque(SkAlphaType at) {
enum SkColorType {
kAlpha_8_SkColorType,
kRGB_565_SkColorType,
+ kARGB_4444_SkColorType,
kRGBA_8888_SkColorType,
kBGRA_8888_SkColorType,
kIndex8_SkColorType,
@@ -82,6 +86,7 @@ static int SkColorTypeBytesPerPixel(SkColorType ct) {
static const uint8_t gSize[] = {
1, // Alpha_8
2, // RGB_565
+ 2, // ARGB_4444
4, // RGBA_8888
4, // BGRA_8888
1, // kIndex_8
@@ -112,12 +117,26 @@ struct SkImageInfo {
return SkColorTypeBytesPerPixel(fColorType);
}
+ size_t minRowBytes() const {
+ return fWidth * this->bytesPerPixel();
+ }
+
bool operator==(const SkImageInfo& other) const {
return 0 == memcmp(this, &other, sizeof(other));
}
bool operator!=(const SkImageInfo& other) const {
return 0 != memcmp(this, &other, sizeof(other));
}
+
+ void unflatten(SkFlattenableReadBuffer&);
+ void flatten(SkFlattenableWriteBuffer&) const;
+
+ size_t getSafeSize(size_t rowBytes) const {
+ if (0 == fHeight) {
+ return 0;
+ }
+ return (fHeight - 1) * rowBytes + fWidth * this->bytesPerPixel();
+ }
};
#endif
diff --git a/include/core/SkMallocPixelRef.h b/include/core/SkMallocPixelRef.h
index 100a15d90a..5ef70d69bc 100644
--- a/include/core/SkMallocPixelRef.h
+++ b/include/core/SkMallocPixelRef.h
@@ -17,33 +17,52 @@
*/
class SkMallocPixelRef : public SkPixelRef {
public:
- /** Allocate the specified buffer for pixels. The memory is freed when the
- last owner of this pixelref is gone. If addr is NULL, sk_malloc_throw()
- is called to allocate it.
+ /**
+ * Return a new SkMallocPixelRef with the provided pixel storage, rowBytes,
+ * and optional colortable. The caller is responsible for managing the
+ * lifetime of the pixel storage buffer, as the pixelref will not try
+ * to delete the storage.
+ *
+ * This pixelref will ref() the specified colortable (if not NULL).
+ *
+ * Returns NULL on failure.
*/
- SkMallocPixelRef(void* addr, size_t size, SkColorTable* ctable, bool ownPixels = true);
- virtual ~SkMallocPixelRef();
+ static SkMallocPixelRef* NewDirect(const SkImageInfo&, void* addr,
+ size_t rowBytes, SkColorTable*);
+
+ /**
+ * Return a new SkMallocPixelRef, automatically allocating storage for the
+ * pixels. If rowBytes are 0, an optimal value will be chosen automatically.
+ * If rowBytes is > 0, then it will be respected, or NULL will be returned
+ * if rowBytes is invalid for the specified info.
+ *
+ * This pixelref will ref() the specified colortable (if not NULL).
+ *
+ * Returns NULL on failure.
+ */
+ static SkMallocPixelRef* NewAllocate(const SkImageInfo& info,
+ size_t rowBytes, SkColorTable*);
void* getAddr() const { return fStorage; }
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkMallocPixelRef)
protected:
- // overrides from SkPixelRef
- virtual void* onLockPixels(SkColorTable**);
- virtual void onUnlockPixels();
-
- SkMallocPixelRef(SkFlattenableReadBuffer& buffer);
+ virtual bool onNewLockPixels(LockRec*) SK_OVERRIDE;
+ virtual void onUnlockPixels() SK_OVERRIDE;
virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;
+ virtual size_t getAllocatedSizeInBytes() const SK_OVERRIDE;
- // Returns the allocation size for the pixels
- virtual size_t getAllocatedSizeInBytes() const SK_OVERRIDE { return fSize; }
+ SkMallocPixelRef(SkFlattenableReadBuffer& buffer);
+ SkMallocPixelRef(const SkImageInfo&, void* addr, size_t rb, SkColorTable*,
+ bool ownsPixels);
+ virtual ~SkMallocPixelRef();
private:
- void* fStorage;
- size_t fSize;
- SkColorTable* fCTable;
- bool fOwnPixels;
+ void* fStorage;
+ SkColorTable* fCTable;
+ size_t fRB;
+ const bool fOwnPixels;
typedef SkPixelRef INHERITED;
};
diff --git a/include/core/SkPicture.h b/include/core/SkPicture.h
index bce343ec04..cd6b3bcbb1 100644
--- a/include/core/SkPicture.h
+++ b/include/core/SkPicture.h
@@ -220,10 +220,11 @@ protected:
// V14: Add flags word to PathRef serialization
// V15: Remove A1 bitmpa config (and renumber remaining configs)
// V16: Move SkPath's isOval flag to SkPathRef
+ // V17: Changes to PixelRef to store SkImageInfo
#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 = 16;
+ static const uint32_t PICTURE_VERSION = 17;
// 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 4c564e40c2..d03c31a685 100644
--- a/include/core/SkPixelRef.h
+++ b/include/core/SkPixelRef.h
@@ -14,8 +14,11 @@
#include "SkRefCnt.h"
#include "SkString.h"
#include "SkFlattenable.h"
+#include "SkImageInfo.h"
#include "SkTDArray.h"
+#define SK_SUPPORT_LEGACY_ONLOCKPIXELS
+
#ifdef SK_DEBUG
/**
* Defining SK_IGNORE_PIXELREF_SETPRELOCKED will force all pixelref
@@ -49,29 +52,55 @@ class SK_API SkPixelRef : public SkFlattenable {
public:
SK_DECLARE_INST_COUNT(SkPixelRef)
- explicit SkPixelRef(SkBaseMutex* mutex = NULL);
+ explicit SkPixelRef(const SkImageInfo&);
+ SkPixelRef(const SkImageInfo&, SkBaseMutex* mutex);
virtual ~SkPixelRef();
+ const SkImageInfo& info() const {
+ return fInfo;
+ }
+
/** Return the pixel memory returned from lockPixels, or null if the
lockCount is 0.
*/
- void* pixels() const { return fPixels; }
+ void* pixels() const { return fRec.fPixels; }
/** Return the current colorTable (if any) if pixels are locked, or null.
*/
- SkColorTable* colorTable() const { return fColorTable; }
+ SkColorTable* colorTable() const { return fRec.fColorTable; }
/**
+ * To access the actual pixels of a pixelref, it must be "locked".
+ * Calling lockPixels returns a LockRec struct (on success).
+ */
+ struct LockRec {
+ void* fPixels;
+ SkColorTable* fColorTable;
+ size_t fRowBytes;
+
+ void zero() { sk_bzero(this, sizeof(*this)); }
+ };
+
+ /**
* Returns true if the lockcount > 0
*/
bool isLocked() const { return fLockCount > 0; }
SkDEBUGCODE(int getLockCount() const { return fLockCount; })
- /** Call to access the pixel memory, which is returned. Balance with a call
- to unlockPixels().
- */
- void lockPixels();
+ /**
+ * Call to access the pixel memory. Return true on success. Balance this
+ * with a call to unlockPixels().
+ */
+ bool lockPixels();
+
+ /**
+ * Call to access the pixel memory. On success, return true and fill out
+ * the specified rec. On failure, return false and ignore the rec parameter.
+ * Balance this with a call to unlockPixels().
+ */
+ bool lockPixels(LockRec* rec);
+
/** Call to balanace a previous call to lockPixels(). Returns the pixels
(or null) after the unlock. NOTE: lock calls can be nested, but the
matching number of unlock calls must be made in order to free the
@@ -228,14 +257,28 @@ public:
void addGenIDChangeListener(GenIDChangeListener* listener);
protected:
- /** Called when the lockCount goes from 0 to 1. The caller will have already
- acquire a mutex for thread safety, so this method need not do that.
- */
- virtual void* onLockPixels(SkColorTable**) = 0;
- /** Called when the lock count goes from 1 to 0. The caller will have
- already acquire a mutex for thread safety, so this method need not do
- that.
- */
+#ifdef SK_SUPPORT_LEGACY_ONLOCKPIXELS
+ virtual void* onLockPixels(SkColorTable**);
+ virtual bool onNewLockPixels(LockRec*);
+#else
+ /**
+ * On success, returns true and fills out the LockRec for the pixels. On
+ * failure returns false and ignores the LockRec parameter.
+ *
+ * The caller will have already acquired a mutex for thread safety, so this
+ * method need not do that.
+ */
+ virtual bool onNewLockPixels(LockRec*) = 0;
+#endif
+
+ /**
+ * Balancing the previous successful call to onNewLockPixels. The locked
+ * pixel address will no longer be referenced, so the subclass is free to
+ * move or discard that memory.
+ *
+ * The caller will have already acquired a mutex for thread safety, so this
+ * method need not do that.
+ */
virtual void onUnlockPixels() = 0;
/** Default impl returns true */
@@ -279,12 +322,14 @@ protected:
// only call from constructor. Flags this to always be locked, removing
// the need to grab the mutex and call onLockPixels/onUnlockPixels.
// Performance tweak to avoid those calls (esp. in multi-thread use case).
- void setPreLocked(void* pixels, SkColorTable* ctable);
+ void setPreLocked(void*, size_t rowBytes, SkColorTable*);
private:
SkBaseMutex* fMutex; // must remain in scope for the life of this object
- void* fPixels;
- SkColorTable* fColorTable; // we do not track ownership, subclass does
+ SkImageInfo fInfo;
+
+ // LockRec is only valid if we're in a locked state (isLocked())
+ LockRec fRec;
int fLockCount;
mutable uint32_t fGenerationID;
diff --git a/include/gpu/GrSurface.h b/include/gpu/GrSurface.h
index c401a905ff..15e44ab593 100644
--- a/include/gpu/GrSurface.h
+++ b/include/gpu/GrSurface.h
@@ -15,6 +15,7 @@
class GrTexture;
class GrRenderTarget;
+struct SkImageInfo;
class GrSurface : public GrResource {
public:
@@ -58,6 +59,8 @@ public:
*/
const GrTextureDesc& desc() const { return fDesc; }
+ void asImageInfo(SkImageInfo*) const;
+
/**
* @return the texture associated with the surface, may be NULL.
*/
diff --git a/include/gpu/SkGr.h b/include/gpu/SkGr.h
index 5e5ca4b72c..db08548f5d 100644
--- a/include/gpu/SkGr.h
+++ b/include/gpu/SkGr.h
@@ -50,6 +50,7 @@ GR_STATIC_ASSERT((int)kIDA_GrBlendCoeff == (int)SkXfermode::kIDA_Coeff);
* kUnknown_PixelConfig if the conversion cannot be done.
*/
GrPixelConfig SkBitmapConfig2GrPixelConfig(SkBitmap::Config);
+bool GrPixelConfig2ColorType(GrPixelConfig, SkColorType*);
static inline GrColor SkColor2GrColor(SkColor c) {
SkPMColor pm = SkPreMultiplyColor(c);
diff --git a/include/gpu/SkGrPixelRef.h b/include/gpu/SkGrPixelRef.h
index da4b8fae09..4d33b9d06b 100644
--- a/include/gpu/SkGrPixelRef.h
+++ b/include/gpu/SkGrPixelRef.h
@@ -23,14 +23,13 @@
*/
class SK_API SkROLockPixelsPixelRef : public SkPixelRef {
public:
- SkROLockPixelsPixelRef();
+ SkROLockPixelsPixelRef(const SkImageInfo&);
virtual ~SkROLockPixelsPixelRef();
protected:
- // override from SkPixelRef
- virtual void* onLockPixels(SkColorTable** ptr);
- virtual void onUnlockPixels();
- virtual bool onLockPixelsAreWritable() const; // return false;
+ virtual bool onNewLockPixels(LockRec*) SK_OVERRIDE;
+ virtual void onUnlockPixels() SK_OVERRIDE;
+ virtual bool onLockPixelsAreWritable() const SK_OVERRIDE; // return false;
private:
SkBitmap fBitmap;
@@ -47,7 +46,7 @@ public:
* cache and would like the pixel ref to unlock it in its destructor then transferCacheLock
* should be set to true.
*/
- SkGrPixelRef(GrSurface* surface, bool transferCacheLock = false);
+ SkGrPixelRef(const SkImageInfo&, GrSurface*, bool transferCacheLock = false);
virtual ~SkGrPixelRef();
// override from SkPixelRef
diff --git a/include/images/SkImageRef.h b/include/images/SkImageRef.h
index 0599a8d963..36f95e64b2 100644
--- a/include/images/SkImageRef.h
+++ b/include/images/SkImageRef.h
@@ -34,7 +34,7 @@ public:
@param config The preferred config of the decoded bitmap.
@param sampleSize Requested sampleSize for decoding. Defaults to 1.
*/
- SkImageRef(SkStreamRewindable*, SkBitmap::Config config, int sampleSize = 1,
+ SkImageRef(const SkImageInfo&, SkStreamRewindable*, int sampleSize = 1,
SkBaseMutex* mutex = NULL);
virtual ~SkImageRef();
@@ -72,9 +72,9 @@ protected:
When these are called, we will have already acquired the mutex!
*/
- virtual void* onLockPixels(SkColorTable**);
+ virtual bool onNewLockPixels(LockRec*) SK_OVERRIDE;
// override this in your subclass to clean up when we're unlocking pixels
- virtual void onUnlockPixels() {}
+ virtual void onUnlockPixels() SK_OVERRIDE {}
SkImageRef(SkFlattenableReadBuffer&, SkBaseMutex* mutex = NULL);
virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;
@@ -89,7 +89,6 @@ private:
SkImageDecoderFactory* fFactory; // may be null
SkStreamRewindable* fStream;
- SkBitmap::Config fConfig;
int fSampleSize;
bool fDoDither;
bool fErrorInDecoding;
diff --git a/include/images/SkImageRef_GlobalPool.h b/include/images/SkImageRef_GlobalPool.h
index 3adc0f6150..caaf2487de 100644
--- a/include/images/SkImageRef_GlobalPool.h
+++ b/include/images/SkImageRef_GlobalPool.h
@@ -15,7 +15,7 @@
class SkImageRef_GlobalPool : public SkImageRef {
public:
// if pool is null, use the global pool
- SkImageRef_GlobalPool(SkStreamRewindable*, SkBitmap::Config,
+ SkImageRef_GlobalPool(const SkImageInfo&, SkStreamRewindable*,
int sampleSize = 1);
virtual ~SkImageRef_GlobalPool();