From 6965a0a2df9d35cd0a25e1738f0388272d03f399 Mon Sep 17 00:00:00 2001 From: "reed@google.com" Date: Wed, 11 Dec 2013 18:04:56 +0000 Subject: 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."""" BUG= Review URL: https://codereview.chromium.org/110503003 git-svn-id: http://skia.googlecode.com/svn/trunk@12622 2bbb7eff-a529-9590-31e7-b0007b416f81 --- include/core/SkBitmapDevice.h | 2 + include/core/SkMallocPixelRef.h | 51 ++++++++++++++++------- include/core/SkPicture.h | 3 +- include/core/SkPixelRef.h | 76 +++++++++++++++++++++++++--------- include/gpu/GrSurface.h | 3 ++ include/gpu/SkGr.h | 1 + include/gpu/SkGrPixelRef.h | 10 ++--- include/images/SkImageRef.h | 7 ++-- include/images/SkImageRef_GlobalPool.h | 2 +- 9 files changed, 108 insertions(+), 47 deletions(-) (limited to 'include') 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/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 b87b0dc114..472599eeb3 100644 --- a/include/core/SkPixelRef.h +++ b/include/core/SkPixelRef.h @@ -14,9 +14,12 @@ #include "SkRefCnt.h" #include "SkString.h" #include "SkFlattenable.h" +#include "SkImageInfo.h" #include "SkTDArray.h" -#define SK_SUPPORT_LEGACY_PIXELREF_CONSTRUCTOR +//#define SK_SUPPORT_LEGACY_PIXELREF_CONSTRUCTOR + +#define SK_SUPPORT_LEGACY_ONLOCKPIXELS #ifdef SK_DEBUG /** @@ -67,12 +70,24 @@ public: /** 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 */ @@ -80,10 +95,19 @@ public: 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 @@ -240,14 +264,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 */ @@ -291,14 +329,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 SkImageInfo fInfo; - - void* fPixels; - SkColorTable* fColorTable; // we do not track ownership, subclass does + + // 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 c29c27fb3b..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,6 @@ public: * cache and would like the pixel ref to unlock it in its destructor then transferCacheLock * should be set to true. */ - SkGrPixelRef(GrSurface*, bool transferCacheLock = false); SkGrPixelRef(const SkImageInfo&, GrSurface*, bool transferCacheLock = false); virtual ~SkGrPixelRef(); 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(); -- cgit v1.2.3