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