Home | History | Annotate | Download | only in core
      1 /*
      2  * Copyright 2008 The Android Open Source Project
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #ifndef SkPixelRef_DEFINED
      9 #define SkPixelRef_DEFINED
     10 
     11 #include "../private/SkAtomics.h"
     12 #include "../private/SkMutex.h"
     13 #include "../private/SkTDArray.h"
     14 #include "SkBitmap.h"
     15 #include "SkFilterQuality.h"
     16 #include "SkImageInfo.h"
     17 #include "SkPixmap.h"
     18 #include "SkRefCnt.h"
     19 #include "SkSize.h"
     20 #include "SkString.h"
     21 
     22 #ifdef SK_SUPPORT_LEGACY_COLORTABLE
     23 class SkColorTable;
     24 #endif
     25 struct SkIRect;
     26 
     27 class GrTexture;
     28 class SkDiscardableMemory;
     29 
     30 /** \class SkPixelRef
     31 
     32     This class is the smart container for pixel memory, and is used with SkBitmap.
     33     This class can be shared/accessed between multiple threads.
     34 */
     35 class SK_API SkPixelRef : public SkRefCnt {
     36 public:
     37     SkPixelRef(int width, int height, void* addr, size_t rowBytes);
     38     ~SkPixelRef() override;
     39 
     40     int width() const { return fWidth; }
     41     int height() const { return fHeight; }
     42     void* pixels() const { return fPixels; }
     43     size_t rowBytes() const { return fRowBytes; }
     44 
     45     /** Returns a non-zero, unique value corresponding to the pixels in this
     46         pixelref. Each time the pixels are changed (and notifyPixelsChanged is
     47         called), a different generation ID will be returned.
     48     */
     49     uint32_t getGenerationID() const;
     50 
     51 #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
     52     /** Returns a non-zero, unique value corresponding to this SkPixelRef.
     53         Unlike the generation ID, this ID remains the same even when the pixels
     54         are changed. IDs are not reused (until uint32_t wraps), so it is safe
     55         to consider this ID unique even after this SkPixelRef is deleted.
     56 
     57         Can be used as a key which uniquely identifies this SkPixelRef
     58         regardless of changes to its pixels or deletion of this object.
     59      */
     60     uint32_t getStableID() const { return fStableID; }
     61 #endif
     62 
     63     /**
     64      *  Call this if you have changed the contents of the pixels. This will in-
     65      *  turn cause a different generation ID value to be returned from
     66      *  getGenerationID().
     67      */
     68     void notifyPixelsChanged();
     69 
     70     /** Returns true if this pixelref is marked as immutable, meaning that the
     71         contents of its pixels will not change for the lifetime of the pixelref.
     72     */
     73     bool isImmutable() const { return fMutability != kMutable; }
     74 
     75     /** Marks this pixelref is immutable, meaning that the contents of its
     76         pixels will not change for the lifetime of the pixelref. This state can
     77         be set on a pixelref, but it cannot be cleared once it is set.
     78     */
     79     void setImmutable();
     80 
     81     // Register a listener that may be called the next time our generation ID changes.
     82     //
     83     // We'll only call the listener if we're confident that we are the only SkPixelRef with this
     84     // generation ID.  If our generation ID changes and we decide not to call the listener, we'll
     85     // never call it: you must add a new listener for each generation ID change.  We also won't call
     86     // the listener when we're certain no one knows what our generation ID is.
     87     //
     88     // This can be used to invalidate caches keyed by SkPixelRef generation ID.
     89     struct GenIDChangeListener {
     90         virtual ~GenIDChangeListener() {}
     91         virtual void onChange() = 0;
     92     };
     93 
     94     // Takes ownership of listener.
     95     void addGenIDChangeListener(GenIDChangeListener* listener);
     96 
     97     // Call when this pixelref is part of the key to a resourcecache entry. This allows the cache
     98     // to know automatically those entries can be purged when this pixelref is changed or deleted.
     99     void notifyAddedToCache() {
    100         fAddedToCache.store(true);
    101     }
    102 
    103     virtual SkDiscardableMemory* diagnostic_only_getDiscardable() const { return NULL; }
    104 
    105 #ifdef SK_SUPPORT_LEGACY_COLORTABLE
    106     SkPixelRef(int width, int height, void* addr, size_t rowBytes, sk_sp<SkColorTable>);
    107     SkColorTable* colorTable() const { return nullptr; }
    108 #endif
    109 protected:
    110     // default impl does nothing.
    111     virtual void onNotifyPixelsChanged();
    112 
    113 #ifdef SK_SUPPORT_LEGACY_COLORTABLE
    114     void android_only_reset(int width, int height, size_t rowBytes, sk_sp<SkColorTable>);
    115 #else
    116     void android_only_reset(int width, int height, size_t rowBytes);
    117 #endif
    118 
    119 private:
    120     int                 fWidth;
    121     int                 fHeight;
    122     void*               fPixels;
    123     size_t              fRowBytes;
    124 
    125     // Bottom bit indicates the Gen ID is unique.
    126     bool genIDIsUnique() const { return SkToBool(fTaggedGenID.load() & 1); }
    127     mutable SkAtomic<uint32_t> fTaggedGenID;
    128 
    129 #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
    130     const uint32_t fStableID;
    131 #endif
    132 
    133     SkTDArray<GenIDChangeListener*> fGenIDChangeListeners;  // pointers are owned
    134 
    135     // Set true by caches when they cache content that's derived from the current pixels.
    136     SkAtomic<bool> fAddedToCache;
    137 
    138     enum {
    139         kMutable,               // PixelRefs begin mutable.
    140         kTemporarilyImmutable,  // Considered immutable, but can revert to mutable.
    141         kImmutable,             // Once set to this state, it never leaves.
    142     } fMutability : 8;          // easily fits inside a byte
    143 
    144     void needsNewGenID();
    145     void callGenIDChangeListeners();
    146 
    147     void setTemporarilyImmutable();
    148     void restoreMutability();
    149     friend class SkSurface_Raster;   // For the two methods above.
    150 
    151     friend class SkImage_Raster;
    152     friend class SkSpecialImage_Raster;
    153 
    154     void setImmutableWithID(uint32_t genID);
    155     friend class SkImage_Gpu;
    156     friend class SkImage_Lazy;
    157     friend class SkSpecialImage_Gpu;
    158     friend void SkBitmapCache_setImmutableWithID(SkPixelRef*, uint32_t);
    159 
    160     typedef SkRefCnt INHERITED;
    161 };
    162 
    163 #endif
    164