• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
23 class SkBitmap;
24 class SkColorTable;
25 struct SkIRect;
26 class SkMutex;
27 class SkFlattenableReadBuffer;
28 class SkFlattenableWriteBuffer;
29 
30 // this is an opaque class, not interpreted by skia
31 class SkGpuTexture;
32 
33 /** \class SkPixelRef
34 
35     This class is the smart container for pixel memory, and is used with
36     SkBitmap. A pixelref is installed into a bitmap, and then the bitmap can
37     access the actual pixel memory by calling lockPixels/unlockPixels.
38 
39     This class can be shared/accessed between multiple threads.
40 */
41 class SkPixelRef : public SkRefCnt {
42 public:
43     explicit SkPixelRef(SkMutex* mutex = NULL);
44 
45     /** Return the pixel memory returned from lockPixels, or null if the
46         lockCount is 0.
47     */
pixels()48     void* pixels() const { return fPixels; }
49 
50     /** Return the current colorTable (if any) if pixels are locked, or null.
51     */
colorTable()52     SkColorTable* colorTable() const { return fColorTable; }
53 
54     /** Return the current lockcount (defaults to 0)
55     */
getLockCount()56     int getLockCount() const { return fLockCount; }
57 
58     /** Call to access the pixel memory, which is returned. Balance with a call
59         to unlockPixels().
60     */
61     void lockPixels();
62     /** Call to balanace a previous call to lockPixels(). Returns the pixels
63         (or null) after the unlock. NOTE: lock calls can be nested, but the
64         matching number of unlock calls must be made in order to free the
65         memory (if the subclass implements caching/deferred-decoding.)
66     */
67     void unlockPixels();
68 
69     /** Returns a non-zero, unique value corresponding to the pixels in this
70         pixelref. Each time the pixels are changed (and notifyPixelsChanged is
71         called), a different generation ID will be returned.
72     */
73     uint32_t getGenerationID() const;
74 
75     /** Call this if you have changed the contents of the pixels. This will in-
76         turn cause a different generation ID value to be returned from
77         getGenerationID().
78     */
79     void notifyPixelsChanged();
80 
81     /** Returns true if this pixelref is marked as immutable, meaning that the
82         contents of its pixels will not change for the lifetime of the pixelref.
83     */
isImmutable()84     bool isImmutable() const { return fIsImmutable; }
85 
86     /** Marks this pixelref is immutable, meaning that the contents of its
87         pixels will not change for the lifetime of the pixelref. This state can
88         be set on a pixelref, but it cannot be cleared once it is set.
89     */
90     void setImmutable();
91 
92     /** Return the optional URI string associated with this pixelref. May be
93         null.
94     */
getURI()95     const char* getURI() const { return fURI.size() ? fURI.c_str() : NULL; }
96 
97     /** Copy a URI string to this pixelref, or clear the URI if the uri is null
98      */
setURI(const char uri[])99     void setURI(const char uri[]) {
100         fURI.set(uri);
101     }
102 
103     /** Copy a URI string to this pixelref
104      */
setURI(const char uri[],size_t len)105     void setURI(const char uri[], size_t len) {
106         fURI.set(uri, len);
107     }
108 
109     /** Assign a URI string to this pixelref.
110     */
setURI(const SkString & uri)111     void setURI(const SkString& uri) { fURI = uri; }
112 
113     /** Are we really wrapping a texture instead of a bitmap?
114      */
getTexture()115     virtual SkGpuTexture* getTexture() { return NULL; }
116 
117     bool readPixels(SkBitmap* dst, const SkIRect* subset = NULL);
118 
119     // serialization
120 
121     typedef SkPixelRef* (*Factory)(SkFlattenableReadBuffer&);
122 
getFactory()123     virtual Factory getFactory() const { return NULL; }
124     virtual void flatten(SkFlattenableWriteBuffer&) const;
125 
126 #ifdef ANDROID
127     /**
128      *  Acquire a "global" ref on this object.
129      *  The default implementation just calls ref(), but subclasses can override
130      *  this method to implement additional behavior.
131      */
132     virtual void globalRef(void* data=NULL);
133 
134     /**
135      *  Release a "global" ref on this object.
136      *  The default implementation just calls unref(), but subclasses can override
137      *  this method to implement additional behavior.
138      */
139     virtual void globalUnref();
140 #endif
141 
142     static Factory NameToFactory(const char name[]);
143     static const char* FactoryToName(Factory);
144     static void Register(const char name[], Factory);
145 
146     class Registrar {
147     public:
Registrar(const char name[],Factory factory)148         Registrar(const char name[], Factory factory) {
149             SkPixelRef::Register(name, factory);
150         }
151     };
152 
153 protected:
154     /** Called when the lockCount goes from 0 to 1. The caller will have already
155         acquire a mutex for thread safety, so this method need not do that.
156     */
157     virtual void* onLockPixels(SkColorTable**) = 0;
158     /** Called when the lock count goes from 1 to 0. The caller will have
159         already acquire a mutex for thread safety, so this method need not do
160         that.
161     */
162     virtual void onUnlockPixels() = 0;
163 
164     /**
165      *  For pixelrefs that don't have access to their raw pixels, they may be
166      *  able to make a copy of them (e.g. if the pixels are on the GPU).
167      *
168      *  The base class implementation returns false;
169      */
170     virtual bool onReadPixels(SkBitmap* dst, const SkIRect* subsetOrNull);
171 
172     /** Return the mutex associated with this pixelref. This value is assigned
173         in the constructor, and cannot change during the lifetime of the object.
174     */
mutex()175     SkMutex* mutex() const { return fMutex; }
176 
177     SkPixelRef(SkFlattenableReadBuffer&, SkMutex*);
178 
179 private:
180     SkMutex*        fMutex; // must remain in scope for the life of this object
181     void*           fPixels;
182     SkColorTable*   fColorTable;    // we do not track ownership, subclass does
183     int             fLockCount;
184 
185     mutable uint32_t fGenerationID;
186 
187     SkString    fURI;
188 
189     // can go from false to true, but never from true to false
190     bool    fIsImmutable;
191 };
192 
193 #endif
194