/src/skia/include/core/SkPixelRef.h
Line | Count | Source (jump to first uncovered line) |
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 "include/core/SkRefCnt.h" |
12 | | #include "include/core/SkSize.h" |
13 | | #include "include/private/SkIDChangeListener.h" |
14 | | #include "include/private/base/SkAPI.h" |
15 | | #include "include/private/base/SkTo.h" |
16 | | |
17 | | #include <atomic> |
18 | | #include <cstddef> |
19 | | #include <cstdint> |
20 | | |
21 | | class SkDiscardableMemory; |
22 | | |
23 | | /** \class SkPixelRef |
24 | | |
25 | | This class is the smart container for pixel memory, and is used with SkBitmap. |
26 | | This class can be shared/accessed between multiple threads. |
27 | | */ |
28 | | class SK_API SkPixelRef : public SkRefCnt { |
29 | | public: |
30 | | SkPixelRef(int width, int height, void* addr, size_t rowBytes); |
31 | | ~SkPixelRef() override; |
32 | | |
33 | 0 | SkISize dimensions() const { return {fWidth, fHeight}; } |
34 | 174k | int width() const { return fWidth; } |
35 | 174k | int height() const { return fHeight; } |
36 | 1.16M | void* pixels() const { return fPixels; } |
37 | 644k | size_t rowBytes() const { return fRowBytes; } |
38 | | |
39 | | /** Returns a non-zero, unique value corresponding to the pixels in this |
40 | | pixelref. Each time the pixels are changed (and notifyPixelsChanged is |
41 | | called), a different generation ID will be returned. |
42 | | */ |
43 | | uint32_t getGenerationID() const; |
44 | | |
45 | | /** |
46 | | * Call this if you have changed the contents of the pixels. This will in- |
47 | | * turn cause a different generation ID value to be returned from |
48 | | * getGenerationID(). |
49 | | */ |
50 | | void notifyPixelsChanged(); |
51 | | |
52 | | /** Returns true if this pixelref is marked as immutable, meaning that the |
53 | | contents of its pixels will not change for the lifetime of the pixelref. |
54 | | */ |
55 | 150k | bool isImmutable() const { return fMutability != kMutable; } |
56 | | |
57 | | /** Marks this pixelref is immutable, meaning that the contents of its |
58 | | pixels will not change for the lifetime of the pixelref. This state can |
59 | | be set on a pixelref, but it cannot be cleared once it is set. |
60 | | */ |
61 | | void setImmutable(); |
62 | | |
63 | | // Register a listener that may be called the next time our generation ID changes. |
64 | | // |
65 | | // We'll only call the listener if we're confident that we are the only SkPixelRef with this |
66 | | // generation ID. If our generation ID changes and we decide not to call the listener, we'll |
67 | | // never call it: you must add a new listener for each generation ID change. We also won't call |
68 | | // the listener when we're certain no one knows what our generation ID is. |
69 | | // |
70 | | // This can be used to invalidate caches keyed by SkPixelRef generation ID. |
71 | | // Takes ownership of listener. Threadsafe. |
72 | | void addGenIDChangeListener(sk_sp<SkIDChangeListener> listener); |
73 | | |
74 | | // Call when this pixelref is part of the key to a resourcecache entry. This allows the cache |
75 | | // to know automatically those entries can be purged when this pixelref is changed or deleted. |
76 | 303 | void notifyAddedToCache() { |
77 | 303 | fAddedToCache.store(true); |
78 | 303 | } |
79 | | |
80 | 0 | virtual SkDiscardableMemory* diagnostic_only_getDiscardable() const { return nullptr; } |
81 | | |
82 | | protected: |
83 | | void android_only_reset(int width, int height, size_t rowBytes); |
84 | | |
85 | | private: |
86 | | int fWidth; |
87 | | int fHeight; |
88 | | void* fPixels; |
89 | | size_t fRowBytes; |
90 | | |
91 | | // Bottom bit indicates the Gen ID is unique. |
92 | 1.14M | bool genIDIsUnique() const { return SkToBool(fTaggedGenID.load() & 1); } |
93 | | mutable std::atomic<uint32_t> fTaggedGenID; |
94 | | |
95 | | SkIDChangeListener::List fGenIDChangeListeners; |
96 | | |
97 | | // Set true by caches when they cache content that's derived from the current pixels. |
98 | | std::atomic<bool> fAddedToCache; |
99 | | |
100 | | enum Mutability { |
101 | | kMutable, // PixelRefs begin mutable. |
102 | | kTemporarilyImmutable, // Considered immutable, but can revert to mutable. |
103 | | kImmutable, // Once set to this state, it never leaves. |
104 | | } fMutability : 8; // easily fits inside a byte |
105 | | |
106 | | void needsNewGenID(); |
107 | | void callGenIDChangeListeners(); |
108 | | |
109 | | void setTemporarilyImmutable(); |
110 | | void restoreMutability(); |
111 | | friend class SkSurface_Raster; // For temporary immutable methods above. |
112 | | |
113 | | void setImmutableWithID(uint32_t genID); |
114 | | friend void SkBitmapCache_setImmutableWithID(SkPixelRef*, uint32_t); |
115 | | |
116 | | using INHERITED = SkRefCnt; |
117 | | }; |
118 | | |
119 | | #endif |