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