1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/* 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc. 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */ 73b72f792898237e9cec4dd095ef56169d0317f71reed 87eeba2587760a0802fd2b90765b4fd0e5e895375reed#include "SkBitmapCache.h" 98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPixelRef.h" 108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkThread.h" 1154b666b144e1281c0edf499e5ec1c59edaef6572enne#include "SkTraceEvent.h" 128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 134daa6f613cb7d8a3c07369af3e919ea65405ec55mtklein#ifdef SK_BUILD_FOR_WIN32 144daa6f613cb7d8a3c07369af3e919ea65405ec55mtklein // We don't have SK_BASE_MUTEX_INIT on Windows. 15dd96eb4f5c84a8225396d9ce0ca65d4d8966d741reed@google.com 164daa6f613cb7d8a3c07369af3e919ea65405ec55mtklein // must be a power-of-2. undef to just use 1 mutex 174daa6f613cb7d8a3c07369af3e919ea65405ec55mtklein #define PIXELREF_MUTEX_RING_COUNT 32 184daa6f613cb7d8a3c07369af3e919ea65405ec55mtklein static SkBaseMutex gPixelRefMutexRing[PIXELREF_MUTEX_RING_COUNT]; 194daa6f613cb7d8a3c07369af3e919ea65405ec55mtklein 204daa6f613cb7d8a3c07369af3e919ea65405ec55mtklein#else 21dd96eb4f5c84a8225396d9ce0ca65d4d8966d741reed@google.com static SkBaseMutex gPixelRefMutexRing[] = { 22b83f6c3cbdabc14d8290b00d9f38ba59bf6719a1mtklein SK_BASE_MUTEX_INIT, SK_BASE_MUTEX_INIT, 23b83f6c3cbdabc14d8290b00d9f38ba59bf6719a1mtklein SK_BASE_MUTEX_INIT, SK_BASE_MUTEX_INIT, 24b83f6c3cbdabc14d8290b00d9f38ba59bf6719a1mtklein SK_BASE_MUTEX_INIT, SK_BASE_MUTEX_INIT, 25b83f6c3cbdabc14d8290b00d9f38ba59bf6719a1mtklein SK_BASE_MUTEX_INIT, SK_BASE_MUTEX_INIT, 26b83f6c3cbdabc14d8290b00d9f38ba59bf6719a1mtklein 27b83f6c3cbdabc14d8290b00d9f38ba59bf6719a1mtklein SK_BASE_MUTEX_INIT, SK_BASE_MUTEX_INIT, 28b83f6c3cbdabc14d8290b00d9f38ba59bf6719a1mtklein SK_BASE_MUTEX_INIT, SK_BASE_MUTEX_INIT, 29b83f6c3cbdabc14d8290b00d9f38ba59bf6719a1mtklein SK_BASE_MUTEX_INIT, SK_BASE_MUTEX_INIT, 30b83f6c3cbdabc14d8290b00d9f38ba59bf6719a1mtklein SK_BASE_MUTEX_INIT, SK_BASE_MUTEX_INIT, 31b83f6c3cbdabc14d8290b00d9f38ba59bf6719a1mtklein 32b83f6c3cbdabc14d8290b00d9f38ba59bf6719a1mtklein SK_BASE_MUTEX_INIT, SK_BASE_MUTEX_INIT, 33b83f6c3cbdabc14d8290b00d9f38ba59bf6719a1mtklein SK_BASE_MUTEX_INIT, SK_BASE_MUTEX_INIT, 34b83f6c3cbdabc14d8290b00d9f38ba59bf6719a1mtklein SK_BASE_MUTEX_INIT, SK_BASE_MUTEX_INIT, 35b83f6c3cbdabc14d8290b00d9f38ba59bf6719a1mtklein SK_BASE_MUTEX_INIT, SK_BASE_MUTEX_INIT, 36b83f6c3cbdabc14d8290b00d9f38ba59bf6719a1mtklein 37b83f6c3cbdabc14d8290b00d9f38ba59bf6719a1mtklein SK_BASE_MUTEX_INIT, SK_BASE_MUTEX_INIT, 38b83f6c3cbdabc14d8290b00d9f38ba59bf6719a1mtklein SK_BASE_MUTEX_INIT, SK_BASE_MUTEX_INIT, 39b83f6c3cbdabc14d8290b00d9f38ba59bf6719a1mtklein SK_BASE_MUTEX_INIT, SK_BASE_MUTEX_INIT, 40b83f6c3cbdabc14d8290b00d9f38ba59bf6719a1mtklein SK_BASE_MUTEX_INIT, SK_BASE_MUTEX_INIT, 41dd96eb4f5c84a8225396d9ce0ca65d4d8966d741reed@google.com }; 42dd96eb4f5c84a8225396d9ce0ca65d4d8966d741reed@google.com // must be a power-of-2. undef to just use 1 mutex 43dd96eb4f5c84a8225396d9ce0ca65d4d8966d741reed@google.com #define PIXELREF_MUTEX_RING_COUNT SK_ARRAY_COUNT(gPixelRefMutexRing) 44dd96eb4f5c84a8225396d9ce0ca65d4d8966d741reed@google.com 45ff0da4ff483ba7b4468b862949ffb3de505cba14reed@google.com#endif 46ff0da4ff483ba7b4468b862949ffb3de505cba14reed@google.com 47803eceb6afd13f07416df0b4a9bb714e9370f081caryclark@google.comstatic SkBaseMutex* get_default_mutex() { 48dd96eb4f5c84a8225396d9ce0ca65d4d8966d741reed@google.com static int32_t gPixelRefMutexRingIndex; 49dd96eb4f5c84a8225396d9ce0ca65d4d8966d741reed@google.com 50dd96eb4f5c84a8225396d9ce0ca65d4d8966d741reed@google.com SkASSERT(SkIsPow2(PIXELREF_MUTEX_RING_COUNT)); 51dd96eb4f5c84a8225396d9ce0ca65d4d8966d741reed@google.com 52ff0da4ff483ba7b4468b862949ffb3de505cba14reed@google.com // atomic_inc might be overkill here. It may be fine if once in a while 53ff0da4ff483ba7b4468b862949ffb3de505cba14reed@google.com // we hit a race-condition and two subsequent calls get the same index... 54ff0da4ff483ba7b4468b862949ffb3de505cba14reed@google.com int index = sk_atomic_inc(&gPixelRefMutexRingIndex); 55ff0da4ff483ba7b4468b862949ffb3de505cba14reed@google.com return &gPixelRefMutexRing[index & (PIXELREF_MUTEX_RING_COUNT - 1)]; 56ff0da4ff483ba7b4468b862949ffb3de505cba14reed@google.com} 57ff0da4ff483ba7b4468b862949ffb3de505cba14reed@google.com 58ff0da4ff483ba7b4468b862949ffb3de505cba14reed@google.com/////////////////////////////////////////////////////////////////////////////// 59586f48cfa8b1fa7b29d8ee8d0a028489a33866debsalomon@google.com 6063d0024cde57eba4f7802fdc4fe49467867f52bamtkleinstatic uint32_t next_gen_id() { 6163d0024cde57eba4f7802fdc4fe49467867f52bamtklein static uint32_t gNextGenID = 0; 6263d0024cde57eba4f7802fdc4fe49467867f52bamtklein uint32_t genID; 6363d0024cde57eba4f7802fdc4fe49467867f52bamtklein // Loop in case our global wraps around, as we never want to return a 0. 64586f48cfa8b1fa7b29d8ee8d0a028489a33866debsalomon@google.com do { 6563d0024cde57eba4f7802fdc4fe49467867f52bamtklein genID = sk_atomic_fetch_add(&gNextGenID, 2u) + 2; // Never set the low bit. 66586f48cfa8b1fa7b29d8ee8d0a028489a33866debsalomon@google.com } while (0 == genID); 67586f48cfa8b1fa7b29d8ee8d0a028489a33866debsalomon@google.com return genID; 68586f48cfa8b1fa7b29d8ee8d0a028489a33866debsalomon@google.com} 69586f48cfa8b1fa7b29d8ee8d0a028489a33866debsalomon@google.com 70ff0da4ff483ba7b4468b862949ffb3de505cba14reed@google.com/////////////////////////////////////////////////////////////////////////////// 718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 72ff0da4ff483ba7b4468b862949ffb3de505cba14reed@google.comvoid SkPixelRef::setMutex(SkBaseMutex* mutex) { 738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL == mutex) { 74ff0da4ff483ba7b4468b862949ffb3de505cba14reed@google.com mutex = get_default_mutex(); 758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMutex = mutex; 77ff0da4ff483ba7b4468b862949ffb3de505cba14reed@google.com} 78ff0da4ff483ba7b4468b862949ffb3de505cba14reed@google.com 79ff0da4ff483ba7b4468b862949ffb3de505cba14reed@google.com// just need a > 0 value, so pick a funny one to aid in debugging 80ff0da4ff483ba7b4468b862949ffb3de505cba14reed@google.com#define SKPIXELREF_PRELOCKED_LOCKCOUNT 123456789 81ff0da4ff483ba7b4468b862949ffb3de505cba14reed@google.com 82e5ea500d4714a7d84de2bf913e81be3b65d2de68reedstatic SkImageInfo validate_info(const SkImageInfo& info) { 83e5ea500d4714a7d84de2bf913e81be3b65d2de68reed SkAlphaType newAlphaType = info.alphaType(); 84e5ea500d4714a7d84de2bf913e81be3b65d2de68reed SkAssertResult(SkColorTypeValidateAlphaType(info.colorType(), info.alphaType(), &newAlphaType)); 85e5ea500d4714a7d84de2bf913e81be3b65d2de68reed return info.makeAlphaType(newAlphaType); 86e5ea500d4714a7d84de2bf913e81be3b65d2de68reed} 872fd0d14b9be34a7a945942733c3516d97d07f516scroggo 88f3ca41c723f3a33a766de64a1cda9a01bab20142scroggoSkPixelRef::SkPixelRef(const SkImageInfo& info) 89f3ca41c723f3a33a766de64a1cda9a01bab20142scroggo : fInfo(validate_info(info)) 90f3ca41c723f3a33a766de64a1cda9a01bab20142scroggo#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK 9163d0024cde57eba4f7802fdc4fe49467867f52bamtklein , fStableID(next_gen_id()) 92f3ca41c723f3a33a766de64a1cda9a01bab20142scroggo#endif 93f3ca41c723f3a33a766de64a1cda9a01bab20142scroggo 94f3ca41c723f3a33a766de64a1cda9a01bab20142scroggo{ 95d0419b1fe781ed21d4aa0dc80df6b3e79ed37e46reed@google.com this->setMutex(NULL); 96d0419b1fe781ed21d4aa0dc80df6b3e79ed37e46reed@google.com fRec.zero(); 970daa1adb03b4b1fc11d854cb7754416ac05a31e8robertphillips@google.com fLockCount = 0; 980daa1adb03b4b1fc11d854cb7754416ac05a31e8robertphillips@google.com this->needsNewGenID(); 990daa1adb03b4b1fc11d854cb7754416ac05a31e8robertphillips@google.com fIsImmutable = false; 1000daa1adb03b4b1fc11d854cb7754416ac05a31e8robertphillips@google.com fPreLocked = false; 10161010772e59638ff97acb3200a4ec88aa55037a6mtklein fAddedToCache.store(false); 1020daa1adb03b4b1fc11d854cb7754416ac05a31e8robertphillips@google.com} 1030daa1adb03b4b1fc11d854cb7754416ac05a31e8robertphillips@google.com 104d0419b1fe781ed21d4aa0dc80df6b3e79ed37e46reed@google.com 105f3ca41c723f3a33a766de64a1cda9a01bab20142scroggoSkPixelRef::SkPixelRef(const SkImageInfo& info, SkBaseMutex* mutex) 106f3ca41c723f3a33a766de64a1cda9a01bab20142scroggo : fInfo(validate_info(info)) 107f3ca41c723f3a33a766de64a1cda9a01bab20142scroggo#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK 10863d0024cde57eba4f7802fdc4fe49467867f52bamtklein , fStableID(next_gen_id()) 109f3ca41c723f3a33a766de64a1cda9a01bab20142scroggo#endif 110f3ca41c723f3a33a766de64a1cda9a01bab20142scroggo{ 111d0419b1fe781ed21d4aa0dc80df6b3e79ed37e46reed@google.com this->setMutex(mutex); 112d0419b1fe781ed21d4aa0dc80df6b3e79ed37e46reed@google.com fRec.zero(); 113f1715706f761e7e254f601abf33581702fa8fe17reed@google.com fLockCount = 0; 114f1715706f761e7e254f601abf33581702fa8fe17reed@google.com this->needsNewGenID(); 115f1715706f761e7e254f601abf33581702fa8fe17reed@google.com fIsImmutable = false; 116f1715706f761e7e254f601abf33581702fa8fe17reed@google.com fPreLocked = false; 11761010772e59638ff97acb3200a4ec88aa55037a6mtklein fAddedToCache.store(false); 118f1715706f761e7e254f601abf33581702fa8fe17reed@google.com} 119f1715706f761e7e254f601abf33581702fa8fe17reed@google.com 12050a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.orgSkPixelRef::~SkPixelRef() { 12150a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org this->callGenIDChangeListeners(); 12250a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org} 12350a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org 12450a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.orgvoid SkPixelRef::needsNewGenID() { 12563d0024cde57eba4f7802fdc4fe49467867f52bamtklein fTaggedGenID.store(0); 12663d0024cde57eba4f7802fdc4fe49467867f52bamtklein SkASSERT(!this->genIDIsUnique()); // This method isn't threadsafe, so the assert should be fine. 12750a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org} 12850a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org 12950a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.orgvoid SkPixelRef::cloneGenID(const SkPixelRef& that) { 13050a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org // This is subtle. We must call that.getGenerationID() to make sure its genID isn't 0. 13163d0024cde57eba4f7802fdc4fe49467867f52bamtklein uint32_t genID = that.getGenerationID(); 13263d0024cde57eba4f7802fdc4fe49467867f52bamtklein 13363d0024cde57eba4f7802fdc4fe49467867f52bamtklein // Neither ID is unique any more. 13463d0024cde57eba4f7802fdc4fe49467867f52bamtklein // (These & ~1u are actually redundant. that.getGenerationID() just did it for us.) 13563d0024cde57eba4f7802fdc4fe49467867f52bamtklein this->fTaggedGenID.store(genID & ~1u); 13663d0024cde57eba4f7802fdc4fe49467867f52bamtklein that. fTaggedGenID.store(genID & ~1u); 13763d0024cde57eba4f7802fdc4fe49467867f52bamtklein 13863d0024cde57eba4f7802fdc4fe49467867f52bamtklein // This method isn't threadsafe, so these asserts should be fine. 13963d0024cde57eba4f7802fdc4fe49467867f52bamtklein SkASSERT(!this->genIDIsUnique()); 14063d0024cde57eba4f7802fdc4fe49467867f52bamtklein SkASSERT(!that. genIDIsUnique()); 14150a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org} 14250a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org 1437627c657b039ea9aa2a01a7d74e652fe7e27def4reed@google.comvoid SkPixelRef::setPreLocked(void* pixels, size_t rowBytes, SkColorTable* ctable) { 1442a3f08b0a71d044ba48694ed04b3dc1ce846e9d9reed@google.com#ifndef SK_IGNORE_PIXELREF_SETPRELOCKED 145ff0da4ff483ba7b4468b862949ffb3de505cba14reed@google.com // only call me in your constructor, otherwise fLockCount tracking can get 146ff0da4ff483ba7b4468b862949ffb3de505cba14reed@google.com // out of sync. 147d0419b1fe781ed21d4aa0dc80df6b3e79ed37e46reed@google.com fRec.fPixels = pixels; 148d0419b1fe781ed21d4aa0dc80df6b3e79ed37e46reed@google.com fRec.fColorTable = ctable; 149d0419b1fe781ed21d4aa0dc80df6b3e79ed37e46reed@google.com fRec.fRowBytes = rowBytes; 150ff0da4ff483ba7b4468b862949ffb3de505cba14reed@google.com fLockCount = SKPIXELREF_PRELOCKED_LOCKCOUNT; 151ff0da4ff483ba7b4468b862949ffb3de505cba14reed@google.com fPreLocked = true; 1522a3f08b0a71d044ba48694ed04b3dc1ce846e9d9reed@google.com#endif 1538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 155d0419b1fe781ed21d4aa0dc80df6b3e79ed37e46reed@google.combool SkPixelRef::lockPixels(LockRec* rec) { 156ff0da4ff483ba7b4468b862949ffb3de505cba14reed@google.com SkASSERT(!fPreLocked || SKPIXELREF_PRELOCKED_LOCKCOUNT == fLockCount); 15798272d91421c52211e0e0137f494c1cad01c3c68skia.committer@gmail.com 158ff0da4ff483ba7b4468b862949ffb3de505cba14reed@google.com if (!fPreLocked) { 15954b666b144e1281c0edf499e5ec1c59edaef6572enne TRACE_EVENT_BEGIN0("skia", "SkPixelRef::lockPixelsMutex"); 160ff0da4ff483ba7b4468b862949ffb3de505cba14reed@google.com SkAutoMutexAcquire ac(*fMutex); 16154b666b144e1281c0edf499e5ec1c59edaef6572enne TRACE_EVENT_END0("skia", "SkPixelRef::lockPixelsMutex"); 16298272d91421c52211e0e0137f494c1cad01c3c68skia.committer@gmail.com 16327f890219b09e4774da75e6a11ec82849eadae5acommit-bot@chromium.org if (1 == ++fLockCount) { 164d0419b1fe781ed21d4aa0dc80df6b3e79ed37e46reed@google.com SkASSERT(fRec.isZero()); 165d0419b1fe781ed21d4aa0dc80df6b3e79ed37e46reed@google.com 166d0419b1fe781ed21d4aa0dc80df6b3e79ed37e46reed@google.com LockRec rec; 167d0419b1fe781ed21d4aa0dc80df6b3e79ed37e46reed@google.com if (!this->onNewLockPixels(&rec)) { 168d0419b1fe781ed21d4aa0dc80df6b3e79ed37e46reed@google.com return false; 169c83a91f4721739f05f9df51d496d50b5d028b132reed@google.com } 170d0419b1fe781ed21d4aa0dc80df6b3e79ed37e46reed@google.com SkASSERT(!rec.isZero()); // else why did onNewLock return true? 171d0419b1fe781ed21d4aa0dc80df6b3e79ed37e46reed@google.com fRec = rec; 172ff0da4ff483ba7b4468b862949ffb3de505cba14reed@google.com } 1738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 174d0419b1fe781ed21d4aa0dc80df6b3e79ed37e46reed@google.com *rec = fRec; 175d0419b1fe781ed21d4aa0dc80df6b3e79ed37e46reed@google.com return true; 176d0419b1fe781ed21d4aa0dc80df6b3e79ed37e46reed@google.com} 177d0419b1fe781ed21d4aa0dc80df6b3e79ed37e46reed@google.com 178d0419b1fe781ed21d4aa0dc80df6b3e79ed37e46reed@google.combool SkPixelRef::lockPixels() { 179d0419b1fe781ed21d4aa0dc80df6b3e79ed37e46reed@google.com LockRec rec; 180d0419b1fe781ed21d4aa0dc80df6b3e79ed37e46reed@google.com return this->lockPixels(&rec); 1818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkPixelRef::unlockPixels() { 184ff0da4ff483ba7b4468b862949ffb3de505cba14reed@google.com SkASSERT(!fPreLocked || SKPIXELREF_PRELOCKED_LOCKCOUNT == fLockCount); 185fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 186ff0da4ff483ba7b4468b862949ffb3de505cba14reed@google.com if (!fPreLocked) { 187ff0da4ff483ba7b4468b862949ffb3de505cba14reed@google.com SkAutoMutexAcquire ac(*fMutex); 18893c5f9e787ae06b113c422e4aaabb48c278ea9c5reed@google.com 189ff0da4ff483ba7b4468b862949ffb3de505cba14reed@google.com SkASSERT(fLockCount > 0); 190ff0da4ff483ba7b4468b862949ffb3de505cba14reed@google.com if (0 == --fLockCount) { 191c83a91f4721739f05f9df51d496d50b5d028b132reed@google.com // don't call onUnlockPixels unless onLockPixels succeeded 192d0419b1fe781ed21d4aa0dc80df6b3e79ed37e46reed@google.com if (fRec.fPixels) { 193c83a91f4721739f05f9df51d496d50b5d028b132reed@google.com this->onUnlockPixels(); 194d0419b1fe781ed21d4aa0dc80df6b3e79ed37e46reed@google.com fRec.zero(); 195c83a91f4721739f05f9df51d496d50b5d028b132reed@google.com } else { 196d0419b1fe781ed21d4aa0dc80df6b3e79ed37e46reed@google.com SkASSERT(fRec.isZero()); 197c83a91f4721739f05f9df51d496d50b5d028b132reed@google.com } 198ff0da4ff483ba7b4468b862949ffb3de505cba14reed@google.com } 1998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2029c49bc3e643c435677727c1c0904c4a7cb7a6907reed@google.combool SkPixelRef::lockPixelsAreWritable() const { 2039c49bc3e643c435677727c1c0904c4a7cb7a6907reed@google.com return this->onLockPixelsAreWritable(); 2049c49bc3e643c435677727c1c0904c4a7cb7a6907reed@google.com} 2059c49bc3e643c435677727c1c0904c4a7cb7a6907reed@google.com 2069c49bc3e643c435677727c1c0904c4a7cb7a6907reed@google.combool SkPixelRef::onLockPixelsAreWritable() const { 2079c49bc3e643c435677727c1c0904c4a7cb7a6907reed@google.com return true; 2089c49bc3e643c435677727c1c0904c4a7cb7a6907reed@google.com} 2099c49bc3e643c435677727c1c0904c4a7cb7a6907reed@google.com 2108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comuint32_t SkPixelRef::getGenerationID() const { 21163d0024cde57eba4f7802fdc4fe49467867f52bamtklein uint32_t id = fTaggedGenID.load(); 21286821b56704ebc0a1a6d1e5d1e329369ac797c98mtklein if (0 == id) { 21359c9203321cf4afb48597f39e4bdd4ae91da12a0mtklein uint32_t next = next_gen_id() | 1u; 21459c9203321cf4afb48597f39e4bdd4ae91da12a0mtklein if (fTaggedGenID.compare_exchange(&id, next)) { 21559c9203321cf4afb48597f39e4bdd4ae91da12a0mtklein id = next; // There was no race or we won the race. fTaggedGenID is next now. 21659c9203321cf4afb48597f39e4bdd4ae91da12a0mtklein } else { 21759c9203321cf4afb48597f39e4bdd4ae91da12a0mtklein // We lost a race to set fTaggedGenID. compare_exchange() filled id with the winner. 21859c9203321cf4afb48597f39e4bdd4ae91da12a0mtklein } 21959c9203321cf4afb48597f39e4bdd4ae91da12a0mtklein // We can't quite SkASSERT(this->genIDIsUnique()). It could be non-unique 22059c9203321cf4afb48597f39e4bdd4ae91da12a0mtklein // if we got here via the else path (pretty unlikely, but possible). 2218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 22263d0024cde57eba4f7802fdc4fe49467867f52bamtklein return id & ~1u; // Mask off bottom unique bit. 2238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 22550a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.orgvoid SkPixelRef::addGenIDChangeListener(GenIDChangeListener* listener) { 22663d0024cde57eba4f7802fdc4fe49467867f52bamtklein if (NULL == listener || !this->genIDIsUnique()) { 22750a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org // No point in tracking this if we're not going to call it. 22850a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org SkDELETE(listener); 22950a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org return; 23050a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org } 23150a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org *fGenIDChangeListeners.append() = listener; 23250a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org} 23350a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org 2347eeba2587760a0802fd2b90765b4fd0e5e895375reed// we need to be called *before* the genID gets changed or zerod 23550a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.orgvoid SkPixelRef::callGenIDChangeListeners() { 23650a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org // We don't invalidate ourselves if we think another SkPixelRef is sharing our genID. 23763d0024cde57eba4f7802fdc4fe49467867f52bamtklein if (this->genIDIsUnique()) { 23850a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org for (int i = 0; i < fGenIDChangeListeners.count(); i++) { 23950a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org fGenIDChangeListeners[i]->onChange(); 24050a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org } 2417eeba2587760a0802fd2b90765b4fd0e5e895375reed 24261010772e59638ff97acb3200a4ec88aa55037a6mtklein // TODO: SkAtomic could add "old_value = atomic.xchg(new_value)" to make this clearer. 24361010772e59638ff97acb3200a4ec88aa55037a6mtklein if (fAddedToCache.load()) { 24483787d0ff0a2b2f839a4a3ce6dadd033f83fe643reed SkNotifyBitmapGenIDIsStale(this->getGenerationID()); 24561010772e59638ff97acb3200a4ec88aa55037a6mtklein fAddedToCache.store(false); 24683787d0ff0a2b2f839a4a3ce6dadd033f83fe643reed } 24750a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org } 24850a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org // Listeners get at most one shot, so whether these triggered or not, blow them away. 24950a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org fGenIDChangeListeners.deleteAll(); 25050a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org} 25150a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org 252c1587f94a77eaafe257a6ecf504364d40362c66areed@google.comvoid SkPixelRef::notifyPixelsChanged() { 2533eab80cc1f2031b582b37aed6176e1f8df67b72freed@android.com#ifdef SK_DEBUG 2548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fIsImmutable) { 2558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDebugf("========== notifyPixelsChanged called on immutable pixelref"); 2568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2573eab80cc1f2031b582b37aed6176e1f8df67b72freed@android.com#endif 25850a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org this->callGenIDChangeListeners(); 25950a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org this->needsNewGenID(); 2608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 262c1587f94a77eaafe257a6ecf504364d40362c66areed@google.comvoid SkPixelRef::changeAlphaType(SkAlphaType at) { 263e5ea500d4714a7d84de2bf913e81be3b65d2de68reed *const_cast<SkImageInfo*>(&fInfo) = fInfo.makeAlphaType(at); 264c1587f94a77eaafe257a6ecf504364d40362c66areed@google.com} 265c1587f94a77eaafe257a6ecf504364d40362c66areed@google.com 2668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkPixelRef::setImmutable() { 2678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fIsImmutable = true; 2688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 27050dfa0130b0705414df7ba7da9915139f6320b09reed@google.combool SkPixelRef::readPixels(SkBitmap* dst, const SkIRect* subset) { 27150dfa0130b0705414df7ba7da9915139f6320b09reed@google.com return this->onReadPixels(dst, subset); 27250dfa0130b0705414df7ba7da9915139f6320b09reed@google.com} 27350dfa0130b0705414df7ba7da9915139f6320b09reed@google.com 27450dfa0130b0705414df7ba7da9915139f6320b09reed@google.combool SkPixelRef::onReadPixels(SkBitmap* dst, const SkIRect* subset) { 27550dfa0130b0705414df7ba7da9915139f6320b09reed@google.com return false; 27650dfa0130b0705414df7ba7da9915139f6320b09reed@google.com} 27750dfa0130b0705414df7ba7da9915139f6320b09reed@google.com 278eb776128f5024cc50886634382731220f7424a9areed@google.comSkData* SkPixelRef::onRefEncodedData() { 279eb776128f5024cc50886634382731220f7424a9areed@google.com return NULL; 280eb776128f5024cc50886634382731220f7424a9areed@google.com} 281eb776128f5024cc50886634382731220f7424a9areed@google.com 282abaef86f2b37d8a939506a2076da07f6db456951rileyabool SkPixelRef::onGetYUV8Planes(SkISize sizes[3], void* planes[3], size_t rowBytes[3], 283abaef86f2b37d8a939506a2076da07f6db456951rileya SkYUVColorSpace* colorSpace) { 284518d83dbc1c899e316e8c896af5defb58b83120fsugoi return false; 285518d83dbc1c899e316e8c896af5defb58b83120fsugoi} 286518d83dbc1c899e316e8c896af5defb58b83120fsugoi 287cd3b15ca6364a04b0eeeb4f89c7daa8aefe854c8commit-bot@chromium.orgsize_t SkPixelRef::getAllocatedSizeInBytes() const { 288cd3b15ca6364a04b0eeeb4f89c7daa8aefe854c8commit-bot@chromium.org return 0; 289cd3b15ca6364a04b0eeeb4f89c7daa8aefe854c8commit-bot@chromium.org} 290cd3b15ca6364a04b0eeeb4f89c7daa8aefe854c8commit-bot@chromium.org 291