Bitmap.cpp revision fc9999505a36c66892d7ccce85187936105f4f36
1163f88140e18f13575886e88af0336e0ab1ec846sergeyv/*
2163f88140e18f13575886e88af0336e0ab1ec846sergeyv * Copyright (C) 2015 The Android Open Source Project
3163f88140e18f13575886e88af0336e0ab1ec846sergeyv *
4163f88140e18f13575886e88af0336e0ab1ec846sergeyv * Licensed under the Apache License, Version 2.0 (the "License");
5163f88140e18f13575886e88af0336e0ab1ec846sergeyv * you may not use this file except in compliance with the License.
6163f88140e18f13575886e88af0336e0ab1ec846sergeyv * You may obtain a copy of the License at
7163f88140e18f13575886e88af0336e0ab1ec846sergeyv *
8163f88140e18f13575886e88af0336e0ab1ec846sergeyv *      http://www.apache.org/licenses/LICENSE-2.0
9163f88140e18f13575886e88af0336e0ab1ec846sergeyv *
10163f88140e18f13575886e88af0336e0ab1ec846sergeyv * Unless required by applicable law or agreed to in writing, software
11163f88140e18f13575886e88af0336e0ab1ec846sergeyv * distributed under the License is distributed on an "AS IS" BASIS,
12163f88140e18f13575886e88af0336e0ab1ec846sergeyv * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13163f88140e18f13575886e88af0336e0ab1ec846sergeyv * See the License for the specific language governing permissions and
14163f88140e18f13575886e88af0336e0ab1ec846sergeyv * limitations under the License.
15163f88140e18f13575886e88af0336e0ab1ec846sergeyv */
16c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv#include "Bitmap.h"
17163f88140e18f13575886e88af0336e0ab1ec846sergeyv
18163f88140e18f13575886e88af0336e0ab1ec846sergeyv#include "Caches.h"
19163f88140e18f13575886e88af0336e0ab1ec846sergeyv
20163f88140e18f13575886e88af0336e0ab1ec846sergeyv#include <cutils/log.h>
21163f88140e18f13575886e88af0336e0ab1ec846sergeyv#include <sys/mman.h>
22163f88140e18f13575886e88af0336e0ab1ec846sergeyv#include <cutils/ashmem.h>
23163f88140e18f13575886e88af0336e0ab1ec846sergeyv
24163f88140e18f13575886e88af0336e0ab1ec846sergeyvnamespace android {
25163f88140e18f13575886e88af0336e0ab1ec846sergeyv
26fc9999505a36c66892d7ccce85187936105f4f36sergeyvstatic bool computeAllocationSize(size_t rowBytes, int height, size_t* size) {
27fc9999505a36c66892d7ccce85187936105f4f36sergeyv    int32_t rowBytes32 = SkToS32(rowBytes);
28fc9999505a36c66892d7ccce85187936105f4f36sergeyv    int64_t bigSize = (int64_t) height * rowBytes32;
29c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    if (rowBytes32 < 0 || !sk_64_isS32(bigSize)) {
30c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv        return false; // allocation will be too large
31c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    }
32c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv
33c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    *size = sk_64_asS32(bigSize);
34c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    return true;
35c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv}
36c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv
37c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvtypedef sk_sp<Bitmap> (*AllocPixeRef)(size_t allocSize, const SkImageInfo& info, size_t rowBytes,
38c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv        SkColorTable* ctable);
39c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv
40c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvstatic sk_sp<Bitmap> allocateBitmap(SkBitmap* bitmap, SkColorTable* ctable, AllocPixeRef alloc) {
41c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    const SkImageInfo& info = bitmap->info();
42c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    if (info.colorType() == kUnknown_SkColorType) {
43c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv        LOG_ALWAYS_FATAL("unknown bitmap configuration");
44c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv        return nullptr;
45c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    }
46c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv
47c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    size_t size;
48c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv
49c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    // we must respect the rowBytes value already set on the bitmap instead of
50c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    // attempting to compute our own.
51c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    const size_t rowBytes = bitmap->rowBytes();
52fc9999505a36c66892d7ccce85187936105f4f36sergeyv    if (!computeAllocationSize(rowBytes, bitmap->height(), &size)) {
53fc9999505a36c66892d7ccce85187936105f4f36sergeyv        return nullptr;
54fc9999505a36c66892d7ccce85187936105f4f36sergeyv    }
55fc9999505a36c66892d7ccce85187936105f4f36sergeyv
56c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    auto wrapper = alloc(size, info, rowBytes, ctable);
57c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    if (wrapper) {
58c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv        wrapper->getSkBitmap(bitmap);
59c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv        // since we're already allocated, we lockPixels right away
60c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv        // HeapAllocator behaves this way too
61c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv        bitmap->lockPixels();
62c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    }
63c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    return wrapper;
64c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv}
65c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv
66c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvsk_sp<Bitmap> Bitmap::allocateAshmemBitmap(SkBitmap* bitmap, SkColorTable* ctable) {
67c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv   return allocateBitmap(bitmap, ctable, &Bitmap::allocateAshmemBitmap);
68c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv}
69c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv
70fc9999505a36c66892d7ccce85187936105f4f36sergeyvstatic sk_sp<Bitmap> allocateHeapBitmap(size_t size, const SkImageInfo& info, size_t rowBytes,
71c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv        SkColorTable* ctable) {
72c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    void* addr = calloc(size, 1);
73c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    if (!addr) {
74c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv        return nullptr;
75c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    }
76c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv    return sk_sp<Bitmap>(new Bitmap(addr, size, info, rowBytes, ctable));
77c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv}
78c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv
79fc9999505a36c66892d7ccce85187936105f4f36sergeyvsk_sp<Bitmap> Bitmap::allocateHeapBitmap(SkBitmap* bitmap, SkColorTable* ctable) {
80fc9999505a36c66892d7ccce85187936105f4f36sergeyv   return allocateBitmap(bitmap, ctable, &android::allocateHeapBitmap);
81fc9999505a36c66892d7ccce85187936105f4f36sergeyv}
82fc9999505a36c66892d7ccce85187936105f4f36sergeyv
83fc9999505a36c66892d7ccce85187936105f4f36sergeyvsk_sp<Bitmap> Bitmap::allocateHeapBitmap(const SkImageInfo& info) {
84fc9999505a36c66892d7ccce85187936105f4f36sergeyv    size_t size;
85fc9999505a36c66892d7ccce85187936105f4f36sergeyv    if (!computeAllocationSize(info.minRowBytes(), info.height(), &size)) {
86fc9999505a36c66892d7ccce85187936105f4f36sergeyv        LOG_ALWAYS_FATAL("trying to allocate too large bitmap");
87fc9999505a36c66892d7ccce85187936105f4f36sergeyv        return nullptr;
88fc9999505a36c66892d7ccce85187936105f4f36sergeyv    }
89fc9999505a36c66892d7ccce85187936105f4f36sergeyv    return android::allocateHeapBitmap(size, info, info.minRowBytes(), nullptr);
90fc9999505a36c66892d7ccce85187936105f4f36sergeyv}
91fc9999505a36c66892d7ccce85187936105f4f36sergeyv
92c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvsk_sp<Bitmap> Bitmap::allocateAshmemBitmap(size_t size, const SkImageInfo& info,
93c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv        size_t rowBytes, SkColorTable* ctable) {
94c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    // Create new ashmem region with read/write priv
95c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    int fd = ashmem_create_region("bitmap", size);
96c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    if (fd < 0) {
97c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv        return nullptr;
98c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    }
99c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv
100c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    void* addr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
101c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    if (addr == MAP_FAILED) {
102c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv        close(fd);
103c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv        return nullptr;
104c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    }
105c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv
106c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    if (ashmem_set_prot_region(fd, PROT_READ) < 0) {
107c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv        munmap(addr, size);
108c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv        close(fd);
109c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv        return nullptr;
110c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    }
111c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv    return sk_sp<Bitmap>(new Bitmap(addr, fd, size, info, rowBytes, ctable));
112c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv}
113c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv
114aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyvvoid FreePixelRef(void* addr, void* context) {
115aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv    auto pixelRef = (SkPixelRef*) context;
116aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv    pixelRef->unlockPixels();
117aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv    pixelRef->unref();
118aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv}
119aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv
120aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyvsk_sp<Bitmap> Bitmap::createFrom(const SkImageInfo& info, SkPixelRef& pixelRef) {
121aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv    pixelRef.ref();
122aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv    pixelRef.lockPixels();
123aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv    return sk_sp<Bitmap>(new Bitmap((void*) pixelRef.pixels(), (void*) &pixelRef, FreePixelRef,
124aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv            info, pixelRef.rowBytes(), pixelRef.colorTable()));
125aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv}
126aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv
127c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvvoid Bitmap::reconfigure(const SkImageInfo& newInfo, size_t rowBytes, SkColorTable* ctable) {
128163f88140e18f13575886e88af0336e0ab1ec846sergeyv    if (kIndex_8_SkColorType != newInfo.colorType()) {
129163f88140e18f13575886e88af0336e0ab1ec846sergeyv        ctable = nullptr;
130163f88140e18f13575886e88af0336e0ab1ec846sergeyv    }
131163f88140e18f13575886e88af0336e0ab1ec846sergeyv    mRowBytes = rowBytes;
132163f88140e18f13575886e88af0336e0ab1ec846sergeyv    if (mColorTable.get() != ctable) {
133163f88140e18f13575886e88af0336e0ab1ec846sergeyv        mColorTable.reset(ctable);
134163f88140e18f13575886e88af0336e0ab1ec846sergeyv    }
135163f88140e18f13575886e88af0336e0ab1ec846sergeyv
136163f88140e18f13575886e88af0336e0ab1ec846sergeyv    // Need to validate the alpha type to filter against the color type
137163f88140e18f13575886e88af0336e0ab1ec846sergeyv    // to prevent things like a non-opaque RGB565 bitmap
138163f88140e18f13575886e88af0336e0ab1ec846sergeyv    SkAlphaType alphaType;
139163f88140e18f13575886e88af0336e0ab1ec846sergeyv    LOG_ALWAYS_FATAL_IF(!SkColorTypeValidateAlphaType(
140163f88140e18f13575886e88af0336e0ab1ec846sergeyv            newInfo.colorType(), newInfo.alphaType(), &alphaType),
141163f88140e18f13575886e88af0336e0ab1ec846sergeyv            "Failed to validate alpha type!");
142163f88140e18f13575886e88af0336e0ab1ec846sergeyv
143163f88140e18f13575886e88af0336e0ab1ec846sergeyv    // Dirty hack is dirty
144163f88140e18f13575886e88af0336e0ab1ec846sergeyv    // TODO: Figure something out here, Skia's current design makes this
145163f88140e18f13575886e88af0336e0ab1ec846sergeyv    // really hard to work with. Skia really, really wants immutable objects,
146163f88140e18f13575886e88af0336e0ab1ec846sergeyv    // but with the nested-ref-count hackery going on that's just not
147163f88140e18f13575886e88af0336e0ab1ec846sergeyv    // feasible without going insane trying to figure it out
148163f88140e18f13575886e88af0336e0ab1ec846sergeyv    SkImageInfo* myInfo = const_cast<SkImageInfo*>(&this->info());
149163f88140e18f13575886e88af0336e0ab1ec846sergeyv    *myInfo = newInfo;
150163f88140e18f13575886e88af0336e0ab1ec846sergeyv    changeAlphaType(alphaType);
151163f88140e18f13575886e88af0336e0ab1ec846sergeyv
152163f88140e18f13575886e88af0336e0ab1ec846sergeyv    // Docs say to only call this in the ctor, but we're going to call
153163f88140e18f13575886e88af0336e0ab1ec846sergeyv    // it anyway even if this isn't always the ctor.
154163f88140e18f13575886e88af0336e0ab1ec846sergeyv    // TODO: Fix this too as part of the above TODO
155163f88140e18f13575886e88af0336e0ab1ec846sergeyv    setPreLocked(getStorage(), mRowBytes, mColorTable.get());
156163f88140e18f13575886e88af0336e0ab1ec846sergeyv}
157163f88140e18f13575886e88af0336e0ab1ec846sergeyv
158c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvBitmap::Bitmap(void* address, size_t size, const SkImageInfo& info, size_t rowBytes, SkColorTable* ctable)
159163f88140e18f13575886e88af0336e0ab1ec846sergeyv            : SkPixelRef(info)
160163f88140e18f13575886e88af0336e0ab1ec846sergeyv            , mPixelStorageType(PixelStorageType::Heap) {
161163f88140e18f13575886e88af0336e0ab1ec846sergeyv    mPixelStorage.heap.address = address;
162163f88140e18f13575886e88af0336e0ab1ec846sergeyv    mPixelStorage.heap.size = size;
163163f88140e18f13575886e88af0336e0ab1ec846sergeyv    reconfigure(info, rowBytes, ctable);
164163f88140e18f13575886e88af0336e0ab1ec846sergeyv}
165163f88140e18f13575886e88af0336e0ab1ec846sergeyv
166c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvBitmap::Bitmap(void* address, void* context, FreeFunc freeFunc,
167163f88140e18f13575886e88af0336e0ab1ec846sergeyv                const SkImageInfo& info, size_t rowBytes, SkColorTable* ctable)
168163f88140e18f13575886e88af0336e0ab1ec846sergeyv            : SkPixelRef(info)
169163f88140e18f13575886e88af0336e0ab1ec846sergeyv            , mPixelStorageType(PixelStorageType::External) {
170163f88140e18f13575886e88af0336e0ab1ec846sergeyv    mPixelStorage.external.address = address;
171163f88140e18f13575886e88af0336e0ab1ec846sergeyv    mPixelStorage.external.context = context;
172163f88140e18f13575886e88af0336e0ab1ec846sergeyv    mPixelStorage.external.freeFunc = freeFunc;
173163f88140e18f13575886e88af0336e0ab1ec846sergeyv    reconfigure(info, rowBytes, ctable);
174163f88140e18f13575886e88af0336e0ab1ec846sergeyv}
175163f88140e18f13575886e88af0336e0ab1ec846sergeyv
176c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvBitmap::Bitmap(void* address, int fd, size_t mappedSize,
177163f88140e18f13575886e88af0336e0ab1ec846sergeyv                const SkImageInfo& info, size_t rowBytes, SkColorTable* ctable)
178163f88140e18f13575886e88af0336e0ab1ec846sergeyv            : SkPixelRef(info)
179163f88140e18f13575886e88af0336e0ab1ec846sergeyv            , mPixelStorageType(PixelStorageType::Ashmem) {
180163f88140e18f13575886e88af0336e0ab1ec846sergeyv    mPixelStorage.ashmem.address = address;
181163f88140e18f13575886e88af0336e0ab1ec846sergeyv    mPixelStorage.ashmem.fd = fd;
182163f88140e18f13575886e88af0336e0ab1ec846sergeyv    mPixelStorage.ashmem.size = mappedSize;
183163f88140e18f13575886e88af0336e0ab1ec846sergeyv    reconfigure(info, rowBytes, ctable);
184163f88140e18f13575886e88af0336e0ab1ec846sergeyv}
185163f88140e18f13575886e88af0336e0ab1ec846sergeyv
186c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvBitmap::~Bitmap() {
187163f88140e18f13575886e88af0336e0ab1ec846sergeyv    switch (mPixelStorageType) {
188163f88140e18f13575886e88af0336e0ab1ec846sergeyv    case PixelStorageType::External:
189163f88140e18f13575886e88af0336e0ab1ec846sergeyv        mPixelStorage.external.freeFunc(mPixelStorage.external.address,
190163f88140e18f13575886e88af0336e0ab1ec846sergeyv                mPixelStorage.external.context);
191163f88140e18f13575886e88af0336e0ab1ec846sergeyv        break;
192163f88140e18f13575886e88af0336e0ab1ec846sergeyv    case PixelStorageType::Ashmem:
193163f88140e18f13575886e88af0336e0ab1ec846sergeyv        munmap(mPixelStorage.ashmem.address, mPixelStorage.ashmem.size);
194163f88140e18f13575886e88af0336e0ab1ec846sergeyv        close(mPixelStorage.ashmem.fd);
195163f88140e18f13575886e88af0336e0ab1ec846sergeyv        break;
196163f88140e18f13575886e88af0336e0ab1ec846sergeyv    case PixelStorageType::Heap:
197163f88140e18f13575886e88af0336e0ab1ec846sergeyv        free(mPixelStorage.heap.address);
198163f88140e18f13575886e88af0336e0ab1ec846sergeyv        break;
199163f88140e18f13575886e88af0336e0ab1ec846sergeyv    }
200163f88140e18f13575886e88af0336e0ab1ec846sergeyv
201163f88140e18f13575886e88af0336e0ab1ec846sergeyv    if (android::uirenderer::Caches::hasInstance()) {
202163f88140e18f13575886e88af0336e0ab1ec846sergeyv        android::uirenderer::Caches::getInstance().textureCache.releaseTexture(getStableID());
203163f88140e18f13575886e88af0336e0ab1ec846sergeyv    }
204163f88140e18f13575886e88af0336e0ab1ec846sergeyv}
205163f88140e18f13575886e88af0336e0ab1ec846sergeyv
206c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvbool Bitmap::hasHardwareMipMap() const {
207163f88140e18f13575886e88af0336e0ab1ec846sergeyv    return mHasHardwareMipMap;
208163f88140e18f13575886e88af0336e0ab1ec846sergeyv}
209163f88140e18f13575886e88af0336e0ab1ec846sergeyv
210c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvvoid Bitmap::setHasHardwareMipMap(bool hasMipMap) {
211163f88140e18f13575886e88af0336e0ab1ec846sergeyv    mHasHardwareMipMap = hasMipMap;
212163f88140e18f13575886e88af0336e0ab1ec846sergeyv}
213163f88140e18f13575886e88af0336e0ab1ec846sergeyv
214c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvvoid* Bitmap::getStorage() const {
215163f88140e18f13575886e88af0336e0ab1ec846sergeyv    switch (mPixelStorageType) {
216163f88140e18f13575886e88af0336e0ab1ec846sergeyv    case PixelStorageType::External:
217163f88140e18f13575886e88af0336e0ab1ec846sergeyv        return mPixelStorage.external.address;
218163f88140e18f13575886e88af0336e0ab1ec846sergeyv    case PixelStorageType::Ashmem:
219163f88140e18f13575886e88af0336e0ab1ec846sergeyv        return mPixelStorage.ashmem.address;
220163f88140e18f13575886e88af0336e0ab1ec846sergeyv    case PixelStorageType::Heap:
221163f88140e18f13575886e88af0336e0ab1ec846sergeyv        return mPixelStorage.heap.address;
222163f88140e18f13575886e88af0336e0ab1ec846sergeyv    }
223163f88140e18f13575886e88af0336e0ab1ec846sergeyv}
224163f88140e18f13575886e88af0336e0ab1ec846sergeyv
225c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvbool Bitmap::onNewLockPixels(LockRec* rec) {
226163f88140e18f13575886e88af0336e0ab1ec846sergeyv    rec->fPixels = getStorage();
227163f88140e18f13575886e88af0336e0ab1ec846sergeyv    rec->fRowBytes = mRowBytes;
228163f88140e18f13575886e88af0336e0ab1ec846sergeyv    rec->fColorTable = mColorTable.get();
229163f88140e18f13575886e88af0336e0ab1ec846sergeyv    return true;
230163f88140e18f13575886e88af0336e0ab1ec846sergeyv}
231163f88140e18f13575886e88af0336e0ab1ec846sergeyv
232c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvsize_t Bitmap::getAllocatedSizeInBytes() const {
233163f88140e18f13575886e88af0336e0ab1ec846sergeyv    return info().getSafeSize(mRowBytes);
234163f88140e18f13575886e88af0336e0ab1ec846sergeyv}
235163f88140e18f13575886e88af0336e0ab1ec846sergeyv
236c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvint Bitmap::getAshmemFd() const {
237163f88140e18f13575886e88af0336e0ab1ec846sergeyv    switch (mPixelStorageType) {
238163f88140e18f13575886e88af0336e0ab1ec846sergeyv    case PixelStorageType::Ashmem:
239163f88140e18f13575886e88af0336e0ab1ec846sergeyv        return mPixelStorage.ashmem.fd;
240163f88140e18f13575886e88af0336e0ab1ec846sergeyv    default:
241163f88140e18f13575886e88af0336e0ab1ec846sergeyv        return -1;
242163f88140e18f13575886e88af0336e0ab1ec846sergeyv    }
243163f88140e18f13575886e88af0336e0ab1ec846sergeyv}
244163f88140e18f13575886e88af0336e0ab1ec846sergeyv
245c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvsize_t Bitmap::getAllocationByteCount() const {
246163f88140e18f13575886e88af0336e0ab1ec846sergeyv    switch (mPixelStorageType) {
247163f88140e18f13575886e88af0336e0ab1ec846sergeyv    case PixelStorageType::Heap:
248163f88140e18f13575886e88af0336e0ab1ec846sergeyv        return mPixelStorage.heap.size;
249163f88140e18f13575886e88af0336e0ab1ec846sergeyv    default:
250163f88140e18f13575886e88af0336e0ab1ec846sergeyv        return rowBytes() * height();
251163f88140e18f13575886e88af0336e0ab1ec846sergeyv    }
252163f88140e18f13575886e88af0336e0ab1ec846sergeyv}
253163f88140e18f13575886e88af0336e0ab1ec846sergeyv
254c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvvoid Bitmap::reconfigure(const SkImageInfo& info) {
255163f88140e18f13575886e88af0336e0ab1ec846sergeyv    reconfigure(info, info.minRowBytes(), nullptr);
256163f88140e18f13575886e88af0336e0ab1ec846sergeyv}
257163f88140e18f13575886e88af0336e0ab1ec846sergeyv
258c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvvoid Bitmap::setAlphaType(SkAlphaType alphaType) {
259163f88140e18f13575886e88af0336e0ab1ec846sergeyv    if (!SkColorTypeValidateAlphaType(info().colorType(), alphaType, &alphaType)) {
260163f88140e18f13575886e88af0336e0ab1ec846sergeyv        return;
261163f88140e18f13575886e88af0336e0ab1ec846sergeyv    }
262163f88140e18f13575886e88af0336e0ab1ec846sergeyv
263163f88140e18f13575886e88af0336e0ab1ec846sergeyv    changeAlphaType(alphaType);
264163f88140e18f13575886e88af0336e0ab1ec846sergeyv}
265163f88140e18f13575886e88af0336e0ab1ec846sergeyv
266c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvvoid Bitmap::getSkBitmap(SkBitmap* outBitmap) {
267163f88140e18f13575886e88af0336e0ab1ec846sergeyv    outBitmap->setInfo(info(), rowBytes());
268163f88140e18f13575886e88af0336e0ab1ec846sergeyv    outBitmap->setPixelRef(this);
269163f88140e18f13575886e88af0336e0ab1ec846sergeyv    outBitmap->setHasHardwareMipMap(mHasHardwareMipMap);
270163f88140e18f13575886e88af0336e0ab1ec846sergeyv}
271163f88140e18f13575886e88af0336e0ab1ec846sergeyv
272163f88140e18f13575886e88af0336e0ab1ec846sergeyv} // namespace android