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
88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPixelRef.h"
98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkThread.h"
108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
11dd96eb4f5c84a8225396d9ce0ca65d4d8966d741reed@google.com#ifdef SK_USE_POSIX_THREADS
12dd96eb4f5c84a8225396d9ce0ca65d4d8966d741reed@google.com
13dd96eb4f5c84a8225396d9ce0ca65d4d8966d741reed@google.com    static SkBaseMutex gPixelRefMutexRing[] = {
14b83f6c3cbdabc14d8290b00d9f38ba59bf6719a1mtklein        SK_BASE_MUTEX_INIT, SK_BASE_MUTEX_INIT,
15b83f6c3cbdabc14d8290b00d9f38ba59bf6719a1mtklein        SK_BASE_MUTEX_INIT, SK_BASE_MUTEX_INIT,
16b83f6c3cbdabc14d8290b00d9f38ba59bf6719a1mtklein        SK_BASE_MUTEX_INIT, SK_BASE_MUTEX_INIT,
17b83f6c3cbdabc14d8290b00d9f38ba59bf6719a1mtklein        SK_BASE_MUTEX_INIT, SK_BASE_MUTEX_INIT,
18b83f6c3cbdabc14d8290b00d9f38ba59bf6719a1mtklein
19b83f6c3cbdabc14d8290b00d9f38ba59bf6719a1mtklein        SK_BASE_MUTEX_INIT, SK_BASE_MUTEX_INIT,
20b83f6c3cbdabc14d8290b00d9f38ba59bf6719a1mtklein        SK_BASE_MUTEX_INIT, SK_BASE_MUTEX_INIT,
21b83f6c3cbdabc14d8290b00d9f38ba59bf6719a1mtklein        SK_BASE_MUTEX_INIT, SK_BASE_MUTEX_INIT,
22b83f6c3cbdabc14d8290b00d9f38ba59bf6719a1mtklein        SK_BASE_MUTEX_INIT, SK_BASE_MUTEX_INIT,
23b83f6c3cbdabc14d8290b00d9f38ba59bf6719a1mtklein
24b83f6c3cbdabc14d8290b00d9f38ba59bf6719a1mtklein        SK_BASE_MUTEX_INIT, SK_BASE_MUTEX_INIT,
25b83f6c3cbdabc14d8290b00d9f38ba59bf6719a1mtklein        SK_BASE_MUTEX_INIT, SK_BASE_MUTEX_INIT,
26b83f6c3cbdabc14d8290b00d9f38ba59bf6719a1mtklein        SK_BASE_MUTEX_INIT, SK_BASE_MUTEX_INIT,
27b83f6c3cbdabc14d8290b00d9f38ba59bf6719a1mtklein        SK_BASE_MUTEX_INIT, SK_BASE_MUTEX_INIT,
28b83f6c3cbdabc14d8290b00d9f38ba59bf6719a1mtklein
29b83f6c3cbdabc14d8290b00d9f38ba59bf6719a1mtklein        SK_BASE_MUTEX_INIT, SK_BASE_MUTEX_INIT,
30b83f6c3cbdabc14d8290b00d9f38ba59bf6719a1mtklein        SK_BASE_MUTEX_INIT, SK_BASE_MUTEX_INIT,
31b83f6c3cbdabc14d8290b00d9f38ba59bf6719a1mtklein        SK_BASE_MUTEX_INIT, SK_BASE_MUTEX_INIT,
32b83f6c3cbdabc14d8290b00d9f38ba59bf6719a1mtklein        SK_BASE_MUTEX_INIT, SK_BASE_MUTEX_INIT,
33dd96eb4f5c84a8225396d9ce0ca65d4d8966d741reed@google.com    };
34dd96eb4f5c84a8225396d9ce0ca65d4d8966d741reed@google.com
35dd96eb4f5c84a8225396d9ce0ca65d4d8966d741reed@google.com    // must be a power-of-2. undef to just use 1 mutex
36dd96eb4f5c84a8225396d9ce0ca65d4d8966d741reed@google.com    #define PIXELREF_MUTEX_RING_COUNT SK_ARRAY_COUNT(gPixelRefMutexRing)
37dd96eb4f5c84a8225396d9ce0ca65d4d8966d741reed@google.com
38dd96eb4f5c84a8225396d9ce0ca65d4d8966d741reed@google.com#else // not pthreads
39dd96eb4f5c84a8225396d9ce0ca65d4d8966d741reed@google.com
40dd96eb4f5c84a8225396d9ce0ca65d4d8966d741reed@google.com    // must be a power-of-2. undef to just use 1 mutex
41dd96eb4f5c84a8225396d9ce0ca65d4d8966d741reed@google.com    #define PIXELREF_MUTEX_RING_COUNT       32
42dd96eb4f5c84a8225396d9ce0ca65d4d8966d741reed@google.com    static SkBaseMutex gPixelRefMutexRing[PIXELREF_MUTEX_RING_COUNT];
43dd96eb4f5c84a8225396d9ce0ca65d4d8966d741reed@google.com
44ff0da4ff483ba7b4468b862949ffb3de505cba14reed@google.com#endif
45ff0da4ff483ba7b4468b862949ffb3de505cba14reed@google.com
46803eceb6afd13f07416df0b4a9bb714e9370f081caryclark@google.comstatic SkBaseMutex* get_default_mutex() {
47dd96eb4f5c84a8225396d9ce0ca65d4d8966d741reed@google.com    static int32_t gPixelRefMutexRingIndex;
48dd96eb4f5c84a8225396d9ce0ca65d4d8966d741reed@google.com
49dd96eb4f5c84a8225396d9ce0ca65d4d8966d741reed@google.com    SkASSERT(SkIsPow2(PIXELREF_MUTEX_RING_COUNT));
50dd96eb4f5c84a8225396d9ce0ca65d4d8966d741reed@google.com
51ff0da4ff483ba7b4468b862949ffb3de505cba14reed@google.com    // atomic_inc might be overkill here. It may be fine if once in a while
52ff0da4ff483ba7b4468b862949ffb3de505cba14reed@google.com    // we hit a race-condition and two subsequent calls get the same index...
53ff0da4ff483ba7b4468b862949ffb3de505cba14reed@google.com    int index = sk_atomic_inc(&gPixelRefMutexRingIndex);
54ff0da4ff483ba7b4468b862949ffb3de505cba14reed@google.com    return &gPixelRefMutexRing[index & (PIXELREF_MUTEX_RING_COUNT - 1)];
55ff0da4ff483ba7b4468b862949ffb3de505cba14reed@google.com}
56ff0da4ff483ba7b4468b862949ffb3de505cba14reed@google.com
57ff0da4ff483ba7b4468b862949ffb3de505cba14reed@google.com///////////////////////////////////////////////////////////////////////////////
58586f48cfa8b1fa7b29d8ee8d0a028489a33866debsalomon@google.com
59100abf49e10544bc4f436bf1f38e6929779621f4bsalomon@google.comint32_t SkNextPixelRefGenerationID();
60100abf49e10544bc4f436bf1f38e6929779621f4bsalomon@google.com
619c49bc3e643c435677727c1c0904c4a7cb7a6907reed@google.comint32_t SkNextPixelRefGenerationID() {
62586f48cfa8b1fa7b29d8ee8d0a028489a33866debsalomon@google.com    static int32_t  gPixelRefGenerationID;
63586f48cfa8b1fa7b29d8ee8d0a028489a33866debsalomon@google.com    // do a loop in case our global wraps around, as we never want to
64586f48cfa8b1fa7b29d8ee8d0a028489a33866debsalomon@google.com    // return a 0
65586f48cfa8b1fa7b29d8ee8d0a028489a33866debsalomon@google.com    int32_t genID;
66586f48cfa8b1fa7b29d8ee8d0a028489a33866debsalomon@google.com    do {
67586f48cfa8b1fa7b29d8ee8d0a028489a33866debsalomon@google.com        genID = sk_atomic_inc(&gPixelRefGenerationID) + 1;
68586f48cfa8b1fa7b29d8ee8d0a028489a33866debsalomon@google.com    } while (0 == genID);
69586f48cfa8b1fa7b29d8ee8d0a028489a33866debsalomon@google.com    return genID;
70586f48cfa8b1fa7b29d8ee8d0a028489a33866debsalomon@google.com}
71586f48cfa8b1fa7b29d8ee8d0a028489a33866debsalomon@google.com
72ff0da4ff483ba7b4468b862949ffb3de505cba14reed@google.com///////////////////////////////////////////////////////////////////////////////
738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
74ff0da4ff483ba7b4468b862949ffb3de505cba14reed@google.comvoid SkPixelRef::setMutex(SkBaseMutex* mutex) {
758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (NULL == mutex) {
76ff0da4ff483ba7b4468b862949ffb3de505cba14reed@google.com        mutex = get_default_mutex();
778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fMutex = mutex;
79ff0da4ff483ba7b4468b862949ffb3de505cba14reed@google.com}
80ff0da4ff483ba7b4468b862949ffb3de505cba14reed@google.com
81ff0da4ff483ba7b4468b862949ffb3de505cba14reed@google.com// just need a > 0 value, so pick a funny one to aid in debugging
82ff0da4ff483ba7b4468b862949ffb3de505cba14reed@google.com#define SKPIXELREF_PRELOCKED_LOCKCOUNT     123456789
83ff0da4ff483ba7b4468b862949ffb3de505cba14reed@google.com
84e5ea500d4714a7d84de2bf913e81be3b65d2de68reedstatic SkImageInfo validate_info(const SkImageInfo& info) {
85e5ea500d4714a7d84de2bf913e81be3b65d2de68reed    SkAlphaType newAlphaType = info.alphaType();
86e5ea500d4714a7d84de2bf913e81be3b65d2de68reed    SkAssertResult(SkColorTypeValidateAlphaType(info.colorType(), info.alphaType(), &newAlphaType));
87e5ea500d4714a7d84de2bf913e81be3b65d2de68reed    return info.makeAlphaType(newAlphaType);
88e5ea500d4714a7d84de2bf913e81be3b65d2de68reed}
892fd0d14b9be34a7a945942733c3516d97d07f516scroggo
90e5ea500d4714a7d84de2bf913e81be3b65d2de68reedSkPixelRef::SkPixelRef(const SkImageInfo& info) : fInfo(validate_info(info)) {
91d0419b1fe781ed21d4aa0dc80df6b3e79ed37e46reed@google.com    this->setMutex(NULL);
92d0419b1fe781ed21d4aa0dc80df6b3e79ed37e46reed@google.com    fRec.zero();
930daa1adb03b4b1fc11d854cb7754416ac05a31e8robertphillips@google.com    fLockCount = 0;
940daa1adb03b4b1fc11d854cb7754416ac05a31e8robertphillips@google.com    this->needsNewGenID();
950daa1adb03b4b1fc11d854cb7754416ac05a31e8robertphillips@google.com    fIsImmutable = false;
960daa1adb03b4b1fc11d854cb7754416ac05a31e8robertphillips@google.com    fPreLocked = false;
970daa1adb03b4b1fc11d854cb7754416ac05a31e8robertphillips@google.com}
980daa1adb03b4b1fc11d854cb7754416ac05a31e8robertphillips@google.com
99d0419b1fe781ed21d4aa0dc80df6b3e79ed37e46reed@google.com
100e5ea500d4714a7d84de2bf913e81be3b65d2de68reedSkPixelRef::SkPixelRef(const SkImageInfo& info, SkBaseMutex* mutex) : fInfo(validate_info(info)) {
101d0419b1fe781ed21d4aa0dc80df6b3e79ed37e46reed@google.com    this->setMutex(mutex);
102d0419b1fe781ed21d4aa0dc80df6b3e79ed37e46reed@google.com    fRec.zero();
103f1715706f761e7e254f601abf33581702fa8fe17reed@google.com    fLockCount = 0;
104f1715706f761e7e254f601abf33581702fa8fe17reed@google.com    this->needsNewGenID();
105f1715706f761e7e254f601abf33581702fa8fe17reed@google.com    fIsImmutable = false;
106f1715706f761e7e254f601abf33581702fa8fe17reed@google.com    fPreLocked = false;
107f1715706f761e7e254f601abf33581702fa8fe17reed@google.com}
108f1715706f761e7e254f601abf33581702fa8fe17reed@google.com
10950a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.orgSkPixelRef::~SkPixelRef() {
11050a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org    this->callGenIDChangeListeners();
11150a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org}
11250a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org
11350a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.orgvoid SkPixelRef::needsNewGenID() {
11450a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org    fGenerationID = 0;
11550a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org    fUniqueGenerationID = false;
11650a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org}
11750a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org
11850a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.orgvoid SkPixelRef::cloneGenID(const SkPixelRef& that) {
11950a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org    // This is subtle.  We must call that.getGenerationID() to make sure its genID isn't 0.
12050a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org    this->fGenerationID = that.getGenerationID();
12150a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org    this->fUniqueGenerationID = false;
12250a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org    that.fUniqueGenerationID = false;
12350a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org}
12450a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org
1257627c657b039ea9aa2a01a7d74e652fe7e27def4reed@google.comvoid SkPixelRef::setPreLocked(void* pixels, size_t rowBytes, SkColorTable* ctable) {
1262a3f08b0a71d044ba48694ed04b3dc1ce846e9d9reed@google.com#ifndef SK_IGNORE_PIXELREF_SETPRELOCKED
127ff0da4ff483ba7b4468b862949ffb3de505cba14reed@google.com    // only call me in your constructor, otherwise fLockCount tracking can get
128ff0da4ff483ba7b4468b862949ffb3de505cba14reed@google.com    // out of sync.
129d0419b1fe781ed21d4aa0dc80df6b3e79ed37e46reed@google.com    fRec.fPixels = pixels;
130d0419b1fe781ed21d4aa0dc80df6b3e79ed37e46reed@google.com    fRec.fColorTable = ctable;
131d0419b1fe781ed21d4aa0dc80df6b3e79ed37e46reed@google.com    fRec.fRowBytes = rowBytes;
132ff0da4ff483ba7b4468b862949ffb3de505cba14reed@google.com    fLockCount = SKPIXELREF_PRELOCKED_LOCKCOUNT;
133ff0da4ff483ba7b4468b862949ffb3de505cba14reed@google.com    fPreLocked = true;
1342a3f08b0a71d044ba48694ed04b3dc1ce846e9d9reed@google.com#endif
1358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
137d0419b1fe781ed21d4aa0dc80df6b3e79ed37e46reed@google.combool SkPixelRef::lockPixels(LockRec* rec) {
138ff0da4ff483ba7b4468b862949ffb3de505cba14reed@google.com    SkASSERT(!fPreLocked || SKPIXELREF_PRELOCKED_LOCKCOUNT == fLockCount);
13998272d91421c52211e0e0137f494c1cad01c3c68skia.committer@gmail.com
140ff0da4ff483ba7b4468b862949ffb3de505cba14reed@google.com    if (!fPreLocked) {
141ff0da4ff483ba7b4468b862949ffb3de505cba14reed@google.com        SkAutoMutexAcquire  ac(*fMutex);
14298272d91421c52211e0e0137f494c1cad01c3c68skia.committer@gmail.com
14327f890219b09e4774da75e6a11ec82849eadae5acommit-bot@chromium.org        if (1 == ++fLockCount) {
144d0419b1fe781ed21d4aa0dc80df6b3e79ed37e46reed@google.com            SkASSERT(fRec.isZero());
145d0419b1fe781ed21d4aa0dc80df6b3e79ed37e46reed@google.com
146d0419b1fe781ed21d4aa0dc80df6b3e79ed37e46reed@google.com            LockRec rec;
147d0419b1fe781ed21d4aa0dc80df6b3e79ed37e46reed@google.com            if (!this->onNewLockPixels(&rec)) {
148d0419b1fe781ed21d4aa0dc80df6b3e79ed37e46reed@google.com                return false;
149c83a91f4721739f05f9df51d496d50b5d028b132reed@google.com            }
150d0419b1fe781ed21d4aa0dc80df6b3e79ed37e46reed@google.com            SkASSERT(!rec.isZero());    // else why did onNewLock return true?
151d0419b1fe781ed21d4aa0dc80df6b3e79ed37e46reed@google.com            fRec = rec;
152ff0da4ff483ba7b4468b862949ffb3de505cba14reed@google.com        }
1538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
154d0419b1fe781ed21d4aa0dc80df6b3e79ed37e46reed@google.com    *rec = fRec;
155d0419b1fe781ed21d4aa0dc80df6b3e79ed37e46reed@google.com    return true;
156d0419b1fe781ed21d4aa0dc80df6b3e79ed37e46reed@google.com}
157d0419b1fe781ed21d4aa0dc80df6b3e79ed37e46reed@google.com
158d0419b1fe781ed21d4aa0dc80df6b3e79ed37e46reed@google.combool SkPixelRef::lockPixels() {
159d0419b1fe781ed21d4aa0dc80df6b3e79ed37e46reed@google.com    LockRec rec;
160d0419b1fe781ed21d4aa0dc80df6b3e79ed37e46reed@google.com    return this->lockPixels(&rec);
1618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkPixelRef::unlockPixels() {
164ff0da4ff483ba7b4468b862949ffb3de505cba14reed@google.com    SkASSERT(!fPreLocked || SKPIXELREF_PRELOCKED_LOCKCOUNT == fLockCount);
165fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
166ff0da4ff483ba7b4468b862949ffb3de505cba14reed@google.com    if (!fPreLocked) {
167ff0da4ff483ba7b4468b862949ffb3de505cba14reed@google.com        SkAutoMutexAcquire  ac(*fMutex);
16893c5f9e787ae06b113c422e4aaabb48c278ea9c5reed@google.com
169ff0da4ff483ba7b4468b862949ffb3de505cba14reed@google.com        SkASSERT(fLockCount > 0);
170ff0da4ff483ba7b4468b862949ffb3de505cba14reed@google.com        if (0 == --fLockCount) {
171c83a91f4721739f05f9df51d496d50b5d028b132reed@google.com            // don't call onUnlockPixels unless onLockPixels succeeded
172d0419b1fe781ed21d4aa0dc80df6b3e79ed37e46reed@google.com            if (fRec.fPixels) {
173c83a91f4721739f05f9df51d496d50b5d028b132reed@google.com                this->onUnlockPixels();
174d0419b1fe781ed21d4aa0dc80df6b3e79ed37e46reed@google.com                fRec.zero();
175c83a91f4721739f05f9df51d496d50b5d028b132reed@google.com            } else {
176d0419b1fe781ed21d4aa0dc80df6b3e79ed37e46reed@google.com                SkASSERT(fRec.isZero());
177c83a91f4721739f05f9df51d496d50b5d028b132reed@google.com            }
178ff0da4ff483ba7b4468b862949ffb3de505cba14reed@google.com        }
1798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1829c49bc3e643c435677727c1c0904c4a7cb7a6907reed@google.combool SkPixelRef::lockPixelsAreWritable() const {
1839c49bc3e643c435677727c1c0904c4a7cb7a6907reed@google.com    return this->onLockPixelsAreWritable();
1849c49bc3e643c435677727c1c0904c4a7cb7a6907reed@google.com}
1859c49bc3e643c435677727c1c0904c4a7cb7a6907reed@google.com
1869c49bc3e643c435677727c1c0904c4a7cb7a6907reed@google.combool SkPixelRef::onLockPixelsAreWritable() const {
1879c49bc3e643c435677727c1c0904c4a7cb7a6907reed@google.com    return true;
1889c49bc3e643c435677727c1c0904c4a7cb7a6907reed@google.com}
1899c49bc3e643c435677727c1c0904c4a7cb7a6907reed@google.com
190cee9dcb8377e1f85a7a232822a894464ea6ccddcreed@google.combool SkPixelRef::onImplementsDecodeInto() {
191cee9dcb8377e1f85a7a232822a894464ea6ccddcreed@google.com    return false;
192cee9dcb8377e1f85a7a232822a894464ea6ccddcreed@google.com}
193cee9dcb8377e1f85a7a232822a894464ea6ccddcreed@google.com
194cee9dcb8377e1f85a7a232822a894464ea6ccddcreed@google.combool SkPixelRef::onDecodeInto(int pow2, SkBitmap* bitmap) {
195cee9dcb8377e1f85a7a232822a894464ea6ccddcreed@google.com    return false;
196cee9dcb8377e1f85a7a232822a894464ea6ccddcreed@google.com}
197cee9dcb8377e1f85a7a232822a894464ea6ccddcreed@google.com
1988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comuint32_t SkPixelRef::getGenerationID() const {
199586f48cfa8b1fa7b29d8ee8d0a028489a33866debsalomon@google.com    if (0 == fGenerationID) {
200586f48cfa8b1fa7b29d8ee8d0a028489a33866debsalomon@google.com        fGenerationID = SkNextPixelRefGenerationID();
20150a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org        fUniqueGenerationID = true;  // The only time we can be sure of this!
2028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
203586f48cfa8b1fa7b29d8ee8d0a028489a33866debsalomon@google.com    return fGenerationID;
2048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
20650a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.orgvoid SkPixelRef::addGenIDChangeListener(GenIDChangeListener* listener) {
20750a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org    if (NULL == listener || !fUniqueGenerationID) {
20850a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org        // No point in tracking this if we're not going to call it.
20950a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org        SkDELETE(listener);
21050a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org        return;
21150a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org    }
21250a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org    *fGenIDChangeListeners.append() = listener;
21350a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org}
21450a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org
21550a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.orgvoid SkPixelRef::callGenIDChangeListeners() {
21650a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org    // We don't invalidate ourselves if we think another SkPixelRef is sharing our genID.
21750a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org    if (fUniqueGenerationID) {
21850a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org        for (int i = 0; i < fGenIDChangeListeners.count(); i++) {
21950a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org            fGenIDChangeListeners[i]->onChange();
22050a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org        }
22150a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org    }
22250a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org    // Listeners get at most one shot, so whether these triggered or not, blow them away.
22350a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org    fGenIDChangeListeners.deleteAll();
22450a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org}
22550a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org
226c1587f94a77eaafe257a6ecf504364d40362c66areed@google.comvoid SkPixelRef::notifyPixelsChanged() {
2273eab80cc1f2031b582b37aed6176e1f8df67b72freed@android.com#ifdef SK_DEBUG
2288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (fIsImmutable) {
2298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkDebugf("========== notifyPixelsChanged called on immutable pixelref");
2308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
2313eab80cc1f2031b582b37aed6176e1f8df67b72freed@android.com#endif
23250a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org    this->callGenIDChangeListeners();
23350a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org    this->needsNewGenID();
2348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
236c1587f94a77eaafe257a6ecf504364d40362c66areed@google.comvoid SkPixelRef::changeAlphaType(SkAlphaType at) {
237e5ea500d4714a7d84de2bf913e81be3b65d2de68reed    *const_cast<SkImageInfo*>(&fInfo) = fInfo.makeAlphaType(at);
238c1587f94a77eaafe257a6ecf504364d40362c66areed@google.com}
239c1587f94a77eaafe257a6ecf504364d40362c66areed@google.com
2408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkPixelRef::setImmutable() {
2418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fIsImmutable = true;
2428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
24450dfa0130b0705414df7ba7da9915139f6320b09reed@google.combool SkPixelRef::readPixels(SkBitmap* dst, const SkIRect* subset) {
24550dfa0130b0705414df7ba7da9915139f6320b09reed@google.com    return this->onReadPixels(dst, subset);
24650dfa0130b0705414df7ba7da9915139f6320b09reed@google.com}
24750dfa0130b0705414df7ba7da9915139f6320b09reed@google.com
24850dfa0130b0705414df7ba7da9915139f6320b09reed@google.combool SkPixelRef::onReadPixels(SkBitmap* dst, const SkIRect* subset) {
24950dfa0130b0705414df7ba7da9915139f6320b09reed@google.com    return false;
25050dfa0130b0705414df7ba7da9915139f6320b09reed@google.com}
25150dfa0130b0705414df7ba7da9915139f6320b09reed@google.com
252eb776128f5024cc50886634382731220f7424a9areed@google.comSkData* SkPixelRef::onRefEncodedData() {
253eb776128f5024cc50886634382731220f7424a9areed@google.com    return NULL;
254eb776128f5024cc50886634382731220f7424a9areed@google.com}
255eb776128f5024cc50886634382731220f7424a9areed@google.com
256abaef86f2b37d8a939506a2076da07f6db456951rileyabool SkPixelRef::onGetYUV8Planes(SkISize sizes[3], void* planes[3], size_t rowBytes[3],
257abaef86f2b37d8a939506a2076da07f6db456951rileya                                 SkYUVColorSpace* colorSpace) {
258518d83dbc1c899e316e8c896af5defb58b83120fsugoi    return false;
259518d83dbc1c899e316e8c896af5defb58b83120fsugoi}
260518d83dbc1c899e316e8c896af5defb58b83120fsugoi
261cd3b15ca6364a04b0eeeb4f89c7daa8aefe854c8commit-bot@chromium.orgsize_t SkPixelRef::getAllocatedSizeInBytes() const {
262cd3b15ca6364a04b0eeeb4f89c7daa8aefe854c8commit-bot@chromium.org    return 0;
263cd3b15ca6364a04b0eeeb4f89c7daa8aefe854c8commit-bot@chromium.org}
264cd3b15ca6364a04b0eeeb4f89c7daa8aefe854c8commit-bot@chromium.org
2658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////////
2668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
26756c69773aea56c6c6bd47bc7e7970dd081205184djsollen@google.com#ifdef SK_BUILD_FOR_ANDROID
26857f4969724a1dd88c8d9ae35a863e6cf621181d5djsollen@google.comvoid SkPixelRef::globalRef(void* data) {
26957f4969724a1dd88c8d9ae35a863e6cf621181d5djsollen@google.com    this->ref();
27057f4969724a1dd88c8d9ae35a863e6cf621181d5djsollen@google.com}
27157f4969724a1dd88c8d9ae35a863e6cf621181d5djsollen@google.com
27257f4969724a1dd88c8d9ae35a863e6cf621181d5djsollen@google.comvoid SkPixelRef::globalUnref() {
27357f4969724a1dd88c8d9ae35a863e6cf621181d5djsollen@google.com    this->unref();
27457f4969724a1dd88c8d9ae35a863e6cf621181d5djsollen@google.com}
27593c5f9e787ae06b113c422e4aaabb48c278ea9c5reed@google.com#endif
276