diff options
author | 2013-12-06 18:41:33 +0000 | |
---|---|---|
committer | 2013-12-06 18:41:33 +0000 | |
commit | 3e89524e747b513986abfeeea00b6fac79593f26 (patch) | |
tree | 2ccdbfb082b488e8a60749a07d778d9f82fac33c /include | |
parent | 332999eabf8738d3b34e91b4a2e92daf5c7d7573 (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.h | 7 | ||||
-rw-r--r-- | include/core/SkBitmapDevice.h | 2 | ||||
-rw-r--r-- | include/core/SkImageInfo.h | 19 | ||||
-rw-r--r-- | include/core/SkMallocPixelRef.h | 51 | ||||
-rw-r--r-- | include/core/SkPicture.h | 3 | ||||
-rw-r--r-- | include/core/SkPixelRef.h | 81 | ||||
-rw-r--r-- | include/gpu/GrSurface.h | 3 | ||||
-rw-r--r-- | include/gpu/SkGr.h | 1 | ||||
-rw-r--r-- | include/gpu/SkGrPixelRef.h | 11 | ||||
-rw-r--r-- | include/images/SkImageRef.h | 7 | ||||
-rw-r--r-- | include/images/SkImageRef_GlobalPool.h | 2 |
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(); |