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 */ 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 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 */ 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