blob: 82e5ca7b5ea19f34abb33930252d735a30c0855f [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
28/** \class SkPixelRef
29
30 This class is the smart container for pixel memory, and is used with
31 SkBitmap. A pixelref is installed into a bitmap, and then the bitmap can
32 access the actual pixel memory by calling lockPixels/unlockPixels.
33
34 This class can be shared/accessed between multiple threads.
35*/
36class SkPixelRef : public SkRefCnt {
37public:
38 explicit SkPixelRef(SkMutex* mutex = NULL);
39
40 /** Return the pixel memory returned from lockPixels, or null if the
41 lockCount is 0.
42 */
43 void* pixels() const { return fPixels; }
44
45 /** Return the current colorTable (if any) if pixels are locked, or null.
46 */
47 SkColorTable* colorTable() const { return fColorTable; }
48
49 /** Return the current lockcount (defaults to 0)
50 */
51 int getLockCount() const { return fLockCount; }
52
53 /** Call to access the pixel memory, which is returned. Balance with a call
54 to unlockPixels().
55 */
56 void lockPixels();
57 /** Call to balanace a previous call to lockPixels(). Returns the pixels
58 (or null) after the unlock. NOTE: lock calls can be nested, but the
59 matching number of unlock calls must be made in order to free the
60 memory (if the subclass implements caching/deferred-decoding.)
61 */
62 void unlockPixels();
63
64 /** Returns a non-zero, unique value corresponding to the pixels in this
65 pixelref. Each time the pixels are changed (and notifyPixelsChanged is
66 called), a different generation ID will be returned.
67 */
68 uint32_t getGenerationID() const;
69
70 /** Call this if you have changed the contents of the pixels. This will in-
71 turn cause a different generation ID value to be returned from
72 getGenerationID().
73 */
74 void notifyPixelsChanged();
75
76 /** Returns true if this pixelref is marked as immutable, meaning that the
77 contents of its pixels will not change for the lifetime of the pixelref.
78 */
79 bool isImmutable() const { return fIsImmutable; }
80
81 /** Marks this pixelref is immutable, meaning that the contents of its
82 pixels will not change for the lifetime of the pixelref. This state can
83 be set on a pixelref, but it cannot be cleared once it is set.
84 */
85 void setImmutable();
86
87 /** Return the optional URI string associated with this pixelref. May be
88 null.
89 */
90 const char* getURI() const { return fURI.size() ? fURI.c_str() : NULL; }
91
92 /** Copy a URI string to this pixelref, or clear the URI if the uri is null
93 */
94 void setURI(const char uri[]) {
95 fURI.set(uri);
96 }
97
98 /** Copy a URI string to this pixelref
99 */
100 void setURI(const char uri[], size_t len) {
101 fURI.set(uri, len);
102 }
103
104 /** Assign a URI string to this pixelref.
105 */
106 void setURI(const SkString& uri) { fURI = uri; }
107
108 // serialization
109
110 typedef SkPixelRef* (*Factory)(SkFlattenableReadBuffer&);
111
112 virtual Factory getFactory() const { return NULL; }
113 virtual void flatten(SkFlattenableWriteBuffer&) const;
114
115 static Factory NameToFactory(const char name[]);
116 static const char* FactoryToName(Factory);
117 static void Register(const char name[], Factory);
118
119 class Registrar {
120 public:
121 Registrar(const char name[], Factory factory) {
122 SkPixelRef::Register(name, factory);
123 }
124 };
125
126protected:
127 /** Called when the lockCount goes from 0 to 1. The caller will have already
128 acquire a mutex for thread safety, so this method need not do that.
129 */
130 virtual void* onLockPixels(SkColorTable**) = 0;
131 /** Called when the lock count goes from 1 to 0. The caller will have
132 already acquire a mutex for thread safety, so this method need not do
133 that.
134 */
135 virtual void onUnlockPixels() = 0;
136
137 /** Return the mutex associated with this pixelref. This value is assigned
138 in the constructor, and cannot change during the lifetime of the object.
139 */
140 SkMutex* mutex() const { return fMutex; }
141
142 SkPixelRef(SkFlattenableReadBuffer&, SkMutex*);
143
144private:
145 SkMutex* fMutex; // must remain in scope for the life of this object
146 void* fPixels;
147 SkColorTable* fColorTable; // we do not track ownership, subclass does
148 int fLockCount;
149
150 mutable uint32_t fGenerationID;
151
152 SkString fURI;
153
154 // can go from false to true, but never from true to false
155 bool fIsImmutable;
156};
157
158#endif