blob: 8375cc7f74cc5a916bb91391ecc9e3b3eaa8648a [file] [log] [blame]
reed@android.com8a1c16f2008-12-17 15:59:43 +00001/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef SkPixelRef_DEFINED
18#define SkPixelRef_DEFINED
19
20#include "SkRefCnt.h"
21#include "SkString.h"
22
23class SkColorTable;
24class SkMutex;
25class SkFlattenableReadBuffer;
26class SkFlattenableWriteBuffer;
27
reed@android.comce4e53a2010-09-09 16:01:26 +000028// this is an opaque class, not interpreted by skia
29class SkGpuTexture;
30
reed@android.com8a1c16f2008-12-17 15:59:43 +000031/** \class SkPixelRef
32
33 This class is the smart container for pixel memory, and is used with
34 SkBitmap. A pixelref is installed into a bitmap, and then the bitmap can
35 access the actual pixel memory by calling lockPixels/unlockPixels.
36
37 This class can be shared/accessed between multiple threads.
38*/
39class SkPixelRef : public SkRefCnt {
40public:
41 explicit SkPixelRef(SkMutex* mutex = NULL);
42
43 /** Return the pixel memory returned from lockPixels, or null if the
44 lockCount is 0.
45 */
46 void* pixels() const { return fPixels; }
47
48 /** Return the current colorTable (if any) if pixels are locked, or null.
49 */
50 SkColorTable* colorTable() const { return fColorTable; }
51
52 /** Return the current lockcount (defaults to 0)
53 */
54 int getLockCount() const { return fLockCount; }
55
56 /** Call to access the pixel memory, which is returned. Balance with a call
57 to unlockPixels().
58 */
59 void lockPixels();
60 /** Call to balanace a previous call to lockPixels(). Returns the pixels
61 (or null) after the unlock. NOTE: lock calls can be nested, but the
62 matching number of unlock calls must be made in order to free the
63 memory (if the subclass implements caching/deferred-decoding.)
64 */
65 void unlockPixels();
66
67 /** Returns a non-zero, unique value corresponding to the pixels in this
68 pixelref. Each time the pixels are changed (and notifyPixelsChanged is
69 called), a different generation ID will be returned.
70 */
71 uint32_t getGenerationID() const;
72
73 /** Call this if you have changed the contents of the pixels. This will in-
74 turn cause a different generation ID value to be returned from
75 getGenerationID().
76 */
77 void notifyPixelsChanged();
78
79 /** Returns true if this pixelref is marked as immutable, meaning that the
80 contents of its pixels will not change for the lifetime of the pixelref.
81 */
82 bool isImmutable() const { return fIsImmutable; }
83
84 /** Marks this pixelref is immutable, meaning that the contents of its
85 pixels will not change for the lifetime of the pixelref. This state can
86 be set on a pixelref, but it cannot be cleared once it is set.
87 */
88 void setImmutable();
89
90 /** Return the optional URI string associated with this pixelref. May be
91 null.
92 */
93 const char* getURI() const { return fURI.size() ? fURI.c_str() : NULL; }
94
95 /** Copy a URI string to this pixelref, or clear the URI if the uri is null
96 */
97 void setURI(const char uri[]) {
98 fURI.set(uri);
99 }
100
101 /** Copy a URI string to this pixelref
102 */
103 void setURI(const char uri[], size_t len) {
104 fURI.set(uri, len);
105 }
106
107 /** Assign a URI string to this pixelref.
108 */
109 void setURI(const SkString& uri) { fURI = uri; }
110
reed@android.comce4e53a2010-09-09 16:01:26 +0000111 /** Are we really wrapping a texture instead of a bitmap?
112 */
113 virtual SkGpuTexture* getTexture() { return NULL; }
114
reed@android.com8a1c16f2008-12-17 15:59:43 +0000115 // serialization
116
117 typedef SkPixelRef* (*Factory)(SkFlattenableReadBuffer&);
118
119 virtual Factory getFactory() const { return NULL; }
120 virtual void flatten(SkFlattenableWriteBuffer&) const;
121
122 static Factory NameToFactory(const char name[]);
123 static const char* FactoryToName(Factory);
124 static void Register(const char name[], Factory);
125
126 class Registrar {
127 public:
128 Registrar(const char name[], Factory factory) {
129 SkPixelRef::Register(name, factory);
130 }
131 };
132
133protected:
134 /** Called when the lockCount goes from 0 to 1. The caller will have already
135 acquire a mutex for thread safety, so this method need not do that.
136 */
137 virtual void* onLockPixels(SkColorTable**) = 0;
138 /** Called when the lock count goes from 1 to 0. The caller will have
139 already acquire a mutex for thread safety, so this method need not do
140 that.
141 */
142 virtual void onUnlockPixels() = 0;
143
144 /** Return the mutex associated with this pixelref. This value is assigned
145 in the constructor, and cannot change during the lifetime of the object.
146 */
147 SkMutex* mutex() const { return fMutex; }
148
149 SkPixelRef(SkFlattenableReadBuffer&, SkMutex*);
150
151private:
152 SkMutex* fMutex; // must remain in scope for the life of this object
153 void* fPixels;
154 SkColorTable* fColorTable; // we do not track ownership, subclass does
155 int fLockCount;
156
157 mutable uint32_t fGenerationID;
158
159 SkString fURI;
160
161 // can go from false to true, but never from true to false
162 bool fIsImmutable;
163};
164
165#endif