gfx/skia/trunk/include/core/SkPixelRef.h

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

michael@0 1 /*
michael@0 2 * Copyright 2008 The Android Open Source Project
michael@0 3 *
michael@0 4 * Use of this source code is governed by a BSD-style license that can be
michael@0 5 * found in the LICENSE file.
michael@0 6 */
michael@0 7
michael@0 8 #ifndef SkPixelRef_DEFINED
michael@0 9 #define SkPixelRef_DEFINED
michael@0 10
michael@0 11 #include "SkBitmap.h"
michael@0 12 #include "SkRefCnt.h"
michael@0 13 #include "SkString.h"
michael@0 14 #include "SkFlattenable.h"
michael@0 15 #include "SkImageInfo.h"
michael@0 16 #include "SkTDArray.h"
michael@0 17
michael@0 18 //#define xed
michael@0 19
michael@0 20 #ifdef SK_DEBUG
michael@0 21 /**
michael@0 22 * Defining SK_IGNORE_PIXELREF_SETPRELOCKED will force all pixelref
michael@0 23 * subclasses to correctly handle lock/unlock pixels. For performance
michael@0 24 * reasons, simple malloc-based subclasses call setPreLocked() to skip
michael@0 25 * the overhead of implementing these calls.
michael@0 26 *
michael@0 27 * This build-flag disables that optimization, to add in debugging our
michael@0 28 * call-sites, to ensure that they correctly balance their calls of
michael@0 29 * lock and unlock.
michael@0 30 */
michael@0 31 // #define SK_IGNORE_PIXELREF_SETPRELOCKED
michael@0 32 #endif
michael@0 33
michael@0 34 class SkColorTable;
michael@0 35 class SkData;
michael@0 36 struct SkIRect;
michael@0 37 class SkMutex;
michael@0 38
michael@0 39 class GrTexture;
michael@0 40
michael@0 41 /** \class SkPixelRef
michael@0 42
michael@0 43 This class is the smart container for pixel memory, and is used with
michael@0 44 SkBitmap. A pixelref is installed into a bitmap, and then the bitmap can
michael@0 45 access the actual pixel memory by calling lockPixels/unlockPixels.
michael@0 46
michael@0 47 This class can be shared/accessed between multiple threads.
michael@0 48 */
michael@0 49 class SK_API SkPixelRef : public SkFlattenable {
michael@0 50 public:
michael@0 51 SK_DECLARE_INST_COUNT(SkPixelRef)
michael@0 52
michael@0 53 explicit SkPixelRef(const SkImageInfo&);
michael@0 54 SkPixelRef(const SkImageInfo&, SkBaseMutex* mutex);
michael@0 55 virtual ~SkPixelRef();
michael@0 56
michael@0 57 const SkImageInfo& info() const {
michael@0 58 return fInfo;
michael@0 59 }
michael@0 60
michael@0 61 /** Return the pixel memory returned from lockPixels, or null if the
michael@0 62 lockCount is 0.
michael@0 63 */
michael@0 64 void* pixels() const { return fRec.fPixels; }
michael@0 65
michael@0 66 /** Return the current colorTable (if any) if pixels are locked, or null.
michael@0 67 */
michael@0 68 SkColorTable* colorTable() const { return fRec.fColorTable; }
michael@0 69
michael@0 70 size_t rowBytes() const { return fRec.fRowBytes; }
michael@0 71
michael@0 72 /**
michael@0 73 * To access the actual pixels of a pixelref, it must be "locked".
michael@0 74 * Calling lockPixels returns a LockRec struct (on success).
michael@0 75 */
michael@0 76 struct LockRec {
michael@0 77 void* fPixels;
michael@0 78 SkColorTable* fColorTable;
michael@0 79 size_t fRowBytes;
michael@0 80
michael@0 81 void zero() { sk_bzero(this, sizeof(*this)); }
michael@0 82
michael@0 83 bool isZero() const {
michael@0 84 return NULL == fPixels && NULL == fColorTable && 0 == fRowBytes;
michael@0 85 }
michael@0 86 };
michael@0 87
michael@0 88 /**
michael@0 89 * Returns true if the lockcount > 0
michael@0 90 */
michael@0 91 bool isLocked() const { return fLockCount > 0; }
michael@0 92
michael@0 93 SkDEBUGCODE(int getLockCount() const { return fLockCount; })
michael@0 94
michael@0 95 /**
michael@0 96 * Call to access the pixel memory. Return true on success. Balance this
michael@0 97 * with a call to unlockPixels().
michael@0 98 */
michael@0 99 bool lockPixels();
michael@0 100
michael@0 101 /**
michael@0 102 * Call to access the pixel memory. On success, return true and fill out
michael@0 103 * the specified rec. On failure, return false and ignore the rec parameter.
michael@0 104 * Balance this with a call to unlockPixels().
michael@0 105 */
michael@0 106 bool lockPixels(LockRec* rec);
michael@0 107
michael@0 108 /** Call to balanace a previous call to lockPixels(). Returns the pixels
michael@0 109 (or null) after the unlock. NOTE: lock calls can be nested, but the
michael@0 110 matching number of unlock calls must be made in order to free the
michael@0 111 memory (if the subclass implements caching/deferred-decoding.)
michael@0 112 */
michael@0 113 void unlockPixels();
michael@0 114
michael@0 115 /**
michael@0 116 * Some bitmaps can return a copy of their pixels for lockPixels(), but
michael@0 117 * that copy, if modified, will not be pushed back. These bitmaps should
michael@0 118 * not be used as targets for a raster device/canvas (since all pixels
michael@0 119 * modifications will be lost when unlockPixels() is called.)
michael@0 120 */
michael@0 121 bool lockPixelsAreWritable() const;
michael@0 122
michael@0 123 /** Returns a non-zero, unique value corresponding to the pixels in this
michael@0 124 pixelref. Each time the pixels are changed (and notifyPixelsChanged is
michael@0 125 called), a different generation ID will be returned.
michael@0 126 */
michael@0 127 uint32_t getGenerationID() const;
michael@0 128
michael@0 129 /**
michael@0 130 * Call this if you have changed the contents of the pixels. This will in-
michael@0 131 * turn cause a different generation ID value to be returned from
michael@0 132 * getGenerationID().
michael@0 133 */
michael@0 134 void notifyPixelsChanged();
michael@0 135
michael@0 136 /**
michael@0 137 * Change the info's AlphaType. Note that this does not automatically
michael@0 138 * invalidate the generation ID. If the pixel values themselves have
michael@0 139 * changed, then you must explicitly call notifyPixelsChanged() as well.
michael@0 140 */
michael@0 141 void changeAlphaType(SkAlphaType at);
michael@0 142
michael@0 143 /** Returns true if this pixelref is marked as immutable, meaning that the
michael@0 144 contents of its pixels will not change for the lifetime of the pixelref.
michael@0 145 */
michael@0 146 bool isImmutable() const { return fIsImmutable; }
michael@0 147
michael@0 148 /** Marks this pixelref is immutable, meaning that the contents of its
michael@0 149 pixels will not change for the lifetime of the pixelref. This state can
michael@0 150 be set on a pixelref, but it cannot be cleared once it is set.
michael@0 151 */
michael@0 152 void setImmutable();
michael@0 153
michael@0 154 /** Return the optional URI string associated with this pixelref. May be
michael@0 155 null.
michael@0 156 */
michael@0 157 const char* getURI() const { return fURI.size() ? fURI.c_str() : NULL; }
michael@0 158
michael@0 159 /** Copy a URI string to this pixelref, or clear the URI if the uri is null
michael@0 160 */
michael@0 161 void setURI(const char uri[]) {
michael@0 162 fURI.set(uri);
michael@0 163 }
michael@0 164
michael@0 165 /** Copy a URI string to this pixelref
michael@0 166 */
michael@0 167 void setURI(const char uri[], size_t len) {
michael@0 168 fURI.set(uri, len);
michael@0 169 }
michael@0 170
michael@0 171 /** Assign a URI string to this pixelref.
michael@0 172 */
michael@0 173 void setURI(const SkString& uri) { fURI = uri; }
michael@0 174
michael@0 175 /**
michael@0 176 * If the pixelRef has an encoded (i.e. compressed) representation,
michael@0 177 * return a ref to its data. If the pixelRef
michael@0 178 * is uncompressed or otherwise does not have this form, return NULL.
michael@0 179 *
michael@0 180 * If non-null is returned, the caller is responsible for calling unref()
michael@0 181 * on the data when it is finished.
michael@0 182 */
michael@0 183 SkData* refEncodedData() {
michael@0 184 return this->onRefEncodedData();
michael@0 185 }
michael@0 186
michael@0 187 /**
michael@0 188 * Experimental -- tells the caller if it is worth it to call decodeInto().
michael@0 189 * Just an optimization at this point, to avoid checking the cache first.
michael@0 190 * We may remove/change this call in the future.
michael@0 191 */
michael@0 192 bool implementsDecodeInto() {
michael@0 193 return this->onImplementsDecodeInto();
michael@0 194 }
michael@0 195
michael@0 196 /**
michael@0 197 * Return a decoded instance of this pixelRef in bitmap. If this cannot be
michael@0 198 * done, return false and the bitmap parameter is ignored/unchanged.
michael@0 199 *
michael@0 200 * pow2 is the requeste power-of-two downscale that the caller needs. This
michael@0 201 * can be ignored, and the "original" size can be returned, but if the
michael@0 202 * underlying codec can efficiently return a smaller size, that should be
michael@0 203 * done. Some examples:
michael@0 204 *
michael@0 205 * To request the "base" version (original scale), pass 0 for pow2
michael@0 206 * To request 1/2 scale version (1/2 width, 1/2 height), pass 1 for pow2
michael@0 207 * To request 1/4 scale version (1/4 width, 1/4 height), pass 2 for pow2
michael@0 208 * ...
michael@0 209 *
michael@0 210 * If this returns true, then bitmap must be "locked" such that
michael@0 211 * bitmap->getPixels() will return the correct address.
michael@0 212 */
michael@0 213 bool decodeInto(int pow2, SkBitmap* bitmap) {
michael@0 214 SkASSERT(pow2 >= 0);
michael@0 215 return this->onDecodeInto(pow2, bitmap);
michael@0 216 }
michael@0 217
michael@0 218 /** Are we really wrapping a texture instead of a bitmap?
michael@0 219 */
michael@0 220 virtual GrTexture* getTexture() { return NULL; }
michael@0 221
michael@0 222 bool readPixels(SkBitmap* dst, const SkIRect* subset = NULL);
michael@0 223
michael@0 224 /**
michael@0 225 * Makes a deep copy of this PixelRef, respecting the requested config.
michael@0 226 * @param config Desired config.
michael@0 227 * @param subset Subset of this PixelRef to copy. Must be fully contained within the bounds of
michael@0 228 * of this PixelRef.
michael@0 229 * @return A new SkPixelRef, or NULL if either there is an error (e.g. the destination could
michael@0 230 * not be created with the given config), or this PixelRef does not support deep
michael@0 231 * copies.
michael@0 232 */
michael@0 233 virtual SkPixelRef* deepCopy(SkBitmap::Config config, const SkIRect* subset = NULL) {
michael@0 234 return NULL;
michael@0 235 }
michael@0 236
michael@0 237 #ifdef SK_BUILD_FOR_ANDROID
michael@0 238 /**
michael@0 239 * Acquire a "global" ref on this object.
michael@0 240 * The default implementation just calls ref(), but subclasses can override
michael@0 241 * this method to implement additional behavior.
michael@0 242 */
michael@0 243 virtual void globalRef(void* data=NULL);
michael@0 244
michael@0 245 /**
michael@0 246 * Release a "global" ref on this object.
michael@0 247 * The default implementation just calls unref(), but subclasses can override
michael@0 248 * this method to implement additional behavior.
michael@0 249 */
michael@0 250 virtual void globalUnref();
michael@0 251 #endif
michael@0 252
michael@0 253 SK_DEFINE_FLATTENABLE_TYPE(SkPixelRef)
michael@0 254
michael@0 255 // Register a listener that may be called the next time our generation ID changes.
michael@0 256 //
michael@0 257 // We'll only call the listener if we're confident that we are the only SkPixelRef with this
michael@0 258 // generation ID. If our generation ID changes and we decide not to call the listener, we'll
michael@0 259 // never call it: you must add a new listener for each generation ID change. We also won't call
michael@0 260 // the listener when we're certain no one knows what our generation ID is.
michael@0 261 //
michael@0 262 // This can be used to invalidate caches keyed by SkPixelRef generation ID.
michael@0 263 struct GenIDChangeListener {
michael@0 264 virtual ~GenIDChangeListener() {}
michael@0 265 virtual void onChange() = 0;
michael@0 266 };
michael@0 267
michael@0 268 // Takes ownership of listener.
michael@0 269 void addGenIDChangeListener(GenIDChangeListener* listener);
michael@0 270
michael@0 271 protected:
michael@0 272 /**
michael@0 273 * On success, returns true and fills out the LockRec for the pixels. On
michael@0 274 * failure returns false and ignores the LockRec parameter.
michael@0 275 *
michael@0 276 * The caller will have already acquired a mutex for thread safety, so this
michael@0 277 * method need not do that.
michael@0 278 */
michael@0 279 virtual bool onNewLockPixels(LockRec*) = 0;
michael@0 280
michael@0 281 /**
michael@0 282 * Balancing the previous successful call to onNewLockPixels. The locked
michael@0 283 * pixel address will no longer be referenced, so the subclass is free to
michael@0 284 * move or discard that memory.
michael@0 285 *
michael@0 286 * The caller will have already acquired a mutex for thread safety, so this
michael@0 287 * method need not do that.
michael@0 288 */
michael@0 289 virtual void onUnlockPixels() = 0;
michael@0 290
michael@0 291 /** Default impl returns true */
michael@0 292 virtual bool onLockPixelsAreWritable() const;
michael@0 293
michael@0 294 // returns false;
michael@0 295 virtual bool onImplementsDecodeInto();
michael@0 296 // returns false;
michael@0 297 virtual bool onDecodeInto(int pow2, SkBitmap* bitmap);
michael@0 298
michael@0 299 /**
michael@0 300 * For pixelrefs that don't have access to their raw pixels, they may be
michael@0 301 * able to make a copy of them (e.g. if the pixels are on the GPU).
michael@0 302 *
michael@0 303 * The base class implementation returns false;
michael@0 304 */
michael@0 305 virtual bool onReadPixels(SkBitmap* dst, const SkIRect* subsetOrNull);
michael@0 306
michael@0 307 // default impl returns NULL.
michael@0 308 virtual SkData* onRefEncodedData();
michael@0 309
michael@0 310 /**
michael@0 311 * Returns the size (in bytes) of the internally allocated memory.
michael@0 312 * This should be implemented in all serializable SkPixelRef derived classes.
michael@0 313 * SkBitmap::fPixelRefOffset + SkBitmap::getSafeSize() should never overflow this value,
michael@0 314 * otherwise the rendering code may attempt to read memory out of bounds.
michael@0 315 *
michael@0 316 * @return default impl returns 0.
michael@0 317 */
michael@0 318 virtual size_t getAllocatedSizeInBytes() const;
michael@0 319
michael@0 320 /** Return the mutex associated with this pixelref. This value is assigned
michael@0 321 in the constructor, and cannot change during the lifetime of the object.
michael@0 322 */
michael@0 323 SkBaseMutex* mutex() const { return fMutex; }
michael@0 324
michael@0 325 // serialization
michael@0 326 SkPixelRef(SkReadBuffer&, SkBaseMutex*);
michael@0 327 virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
michael@0 328
michael@0 329 // only call from constructor. Flags this to always be locked, removing
michael@0 330 // the need to grab the mutex and call onLockPixels/onUnlockPixels.
michael@0 331 // Performance tweak to avoid those calls (esp. in multi-thread use case).
michael@0 332 void setPreLocked(void*, size_t rowBytes, SkColorTable*);
michael@0 333
michael@0 334 private:
michael@0 335 SkBaseMutex* fMutex; // must remain in scope for the life of this object
michael@0 336
michael@0 337 // mostly const. fInfo.fAlpahType can be changed at runtime.
michael@0 338 const SkImageInfo fInfo;
michael@0 339
michael@0 340 // LockRec is only valid if we're in a locked state (isLocked())
michael@0 341 LockRec fRec;
michael@0 342 int fLockCount;
michael@0 343
michael@0 344 mutable uint32_t fGenerationID;
michael@0 345 mutable bool fUniqueGenerationID;
michael@0 346
michael@0 347 SkTDArray<GenIDChangeListener*> fGenIDChangeListeners; // pointers are owned
michael@0 348
michael@0 349 SkString fURI;
michael@0 350
michael@0 351 // can go from false to true, but never from true to false
michael@0 352 bool fIsImmutable;
michael@0 353 // only ever set in constructor, const after that
michael@0 354 bool fPreLocked;
michael@0 355
michael@0 356 void needsNewGenID();
michael@0 357 void callGenIDChangeListeners();
michael@0 358
michael@0 359 void setMutex(SkBaseMutex* mutex);
michael@0 360
michael@0 361 // When copying a bitmap to another with the same shape and config, we can safely
michael@0 362 // clone the pixelref generation ID too, which makes them equivalent under caching.
michael@0 363 friend class SkBitmap; // only for cloneGenID
michael@0 364 void cloneGenID(const SkPixelRef&);
michael@0 365
michael@0 366 typedef SkFlattenable INHERITED;
michael@0 367 };
michael@0 368
michael@0 369 class SkPixelRefFactory : public SkRefCnt {
michael@0 370 public:
michael@0 371 /**
michael@0 372 * Allocate a new pixelref matching the specified ImageInfo, allocating
michael@0 373 * the memory for the pixels. If the ImageInfo requires a ColorTable,
michael@0 374 * the pixelref will ref() the colortable.
michael@0 375 * On failure return NULL.
michael@0 376 */
michael@0 377 virtual SkPixelRef* create(const SkImageInfo&, SkColorTable*) = 0;
michael@0 378 };
michael@0 379
michael@0 380 #endif

mercurial