• 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 SkColorTable;
24 class SkMutex;
25 class SkFlattenableReadBuffer;
26 class 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 */
36 class SkPixelRef : public SkRefCnt {
37 public:
38     explicit SkPixelRef(SkMutex* mutex = NULL);
39 
40     /** Return the pixel memory returned from lockPixels, or null if the
41         lockCount is 0.
42     */
pixels()43     void* pixels() const { return fPixels; }
44 
45     /** Return the current colorTable (if any) if pixels are locked, or null.
46     */
colorTable()47     SkColorTable* colorTable() const { return fColorTable; }
48 
49     /** Return the current lockcount (defaults to 0)
50     */
getLockCount()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     */
isImmutable()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     */
getURI()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      */
setURI(const char uri[])94     void setURI(const char uri[]) {
95         fURI.set(uri);
96     }
97 
98     /** Copy a URI string to this pixelref
99      */
setURI(const char uri[],size_t len)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     */
setURI(const SkString & uri)106     void setURI(const SkString& uri) { fURI = uri; }
107 
108     // serialization
109 
110     typedef SkPixelRef* (*Factory)(SkFlattenableReadBuffer&);
111 
getFactory()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:
Registrar(const char name[],Factory factory)121         Registrar(const char name[], Factory factory) {
122             SkPixelRef::Register(name, factory);
123         }
124     };
125 
126 protected:
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     */
mutex()140     SkMutex* mutex() const { return fMutex; }
141 
142     SkPixelRef(SkFlattenableReadBuffer&, SkMutex*);
143 
144 private:
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
159