Bitmap.cpp revision 05126d151eb3caa85bd3a039cffb6e37940c3fa4
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"
19cd55852fcd840f7f4c4d7a0a7253a2995c77afa2Greg Daniel#include "renderthread/EglManager.h"
20694d499662838123f474f41b31dea84ec5d563f0sergeyv#include "renderthread/RenderThread.h"
21694d499662838123f474f41b31dea84ec5d563f0sergeyv#include "renderthread/RenderProxy.h"
22163f88140e18f13575886e88af0336e0ab1ec846sergeyv
23163f88140e18f13575886e88af0336e0ab1ec846sergeyv#include <cutils/log.h>
24163f88140e18f13575886e88af0336e0ab1ec846sergeyv#include <sys/mman.h>
25163f88140e18f13575886e88af0336e0ab1ec846sergeyv#include <cutils/ashmem.h>
26163f88140e18f13575886e88af0336e0ab1ec846sergeyv
27694d499662838123f474f41b31dea84ec5d563f0sergeyv#include <GLES2/gl2.h>
28694d499662838123f474f41b31dea84ec5d563f0sergeyv#include <GLES2/gl2ext.h>
29694d499662838123f474f41b31dea84ec5d563f0sergeyv#include <EGL/egl.h>
30694d499662838123f474f41b31dea84ec5d563f0sergeyv#include <EGL/eglext.h>
31694d499662838123f474f41b31dea84ec5d563f0sergeyv
32694d499662838123f474f41b31dea84ec5d563f0sergeyv
33694d499662838123f474f41b31dea84ec5d563f0sergeyv#include <gui/IGraphicBufferAlloc.h>
34694d499662838123f474f41b31dea84ec5d563f0sergeyv#include <gui/ISurfaceComposer.h>
35694d499662838123f474f41b31dea84ec5d563f0sergeyv#include <private/gui/ComposerService.h>
36694d499662838123f474f41b31dea84ec5d563f0sergeyv#include <binder/IServiceManager.h>
37694d499662838123f474f41b31dea84ec5d563f0sergeyv#include <ui/PixelFormat.h>
38694d499662838123f474f41b31dea84ec5d563f0sergeyv
39694d499662838123f474f41b31dea84ec5d563f0sergeyv#include <SkCanvas.h>
40694d499662838123f474f41b31dea84ec5d563f0sergeyv
41163f88140e18f13575886e88af0336e0ab1ec846sergeyvnamespace android {
42163f88140e18f13575886e88af0336e0ab1ec846sergeyv
43fc9999505a36c66892d7ccce85187936105f4f36sergeyvstatic bool computeAllocationSize(size_t rowBytes, int height, size_t* size) {
44fc9999505a36c66892d7ccce85187936105f4f36sergeyv    int32_t rowBytes32 = SkToS32(rowBytes);
45fc9999505a36c66892d7ccce85187936105f4f36sergeyv    int64_t bigSize = (int64_t) height * rowBytes32;
46c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    if (rowBytes32 < 0 || !sk_64_isS32(bigSize)) {
47c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv        return false; // allocation will be too large
48c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    }
49c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv
50c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    *size = sk_64_asS32(bigSize);
51c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    return true;
52c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv}
53c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv
54c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvtypedef sk_sp<Bitmap> (*AllocPixeRef)(size_t allocSize, const SkImageInfo& info, size_t rowBytes,
55c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv        SkColorTable* ctable);
56c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv
57c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvstatic sk_sp<Bitmap> allocateBitmap(SkBitmap* bitmap, SkColorTable* ctable, AllocPixeRef alloc) {
58c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    const SkImageInfo& info = bitmap->info();
59c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    if (info.colorType() == kUnknown_SkColorType) {
60c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv        LOG_ALWAYS_FATAL("unknown bitmap configuration");
61c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv        return nullptr;
62c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    }
63c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv
64c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    size_t size;
65c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv
66c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    // we must respect the rowBytes value already set on the bitmap instead of
67c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    // attempting to compute our own.
68c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    const size_t rowBytes = bitmap->rowBytes();
69fc9999505a36c66892d7ccce85187936105f4f36sergeyv    if (!computeAllocationSize(rowBytes, bitmap->height(), &size)) {
70fc9999505a36c66892d7ccce85187936105f4f36sergeyv        return nullptr;
71fc9999505a36c66892d7ccce85187936105f4f36sergeyv    }
72fc9999505a36c66892d7ccce85187936105f4f36sergeyv
73c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    auto wrapper = alloc(size, info, rowBytes, ctable);
74c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    if (wrapper) {
75c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv        wrapper->getSkBitmap(bitmap);
76c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv        // since we're already allocated, we lockPixels right away
77c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv        // HeapAllocator behaves this way too
78c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv        bitmap->lockPixels();
79c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    }
80c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    return wrapper;
81c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv}
82c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv
83c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvsk_sp<Bitmap> Bitmap::allocateAshmemBitmap(SkBitmap* bitmap, SkColorTable* ctable) {
84c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv   return allocateBitmap(bitmap, ctable, &Bitmap::allocateAshmemBitmap);
85c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv}
86c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv
87fc9999505a36c66892d7ccce85187936105f4f36sergeyvstatic sk_sp<Bitmap> allocateHeapBitmap(size_t size, const SkImageInfo& info, size_t rowBytes,
88c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv        SkColorTable* ctable) {
89c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    void* addr = calloc(size, 1);
90c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    if (!addr) {
91c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv        return nullptr;
92c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    }
93c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv    return sk_sp<Bitmap>(new Bitmap(addr, size, info, rowBytes, ctable));
94c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv}
95c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv
96694d499662838123f474f41b31dea84ec5d563f0sergeyv#define FENCE_TIMEOUT 2000000000
97694d499662838123f474f41b31dea84ec5d563f0sergeyv
98694d499662838123f474f41b31dea84ec5d563f0sergeyv// TODO: handle SRGB sanely
99694d499662838123f474f41b31dea84ec5d563f0sergeyvstatic PixelFormat internalFormatToPixelFormat(GLint internalFormat) {
100694d499662838123f474f41b31dea84ec5d563f0sergeyv    switch (internalFormat) {
101694d499662838123f474f41b31dea84ec5d563f0sergeyv    case GL_LUMINANCE:
102694d499662838123f474f41b31dea84ec5d563f0sergeyv        return PIXEL_FORMAT_RGBA_8888;
103694d499662838123f474f41b31dea84ec5d563f0sergeyv    case GL_SRGB8_ALPHA8:
104694d499662838123f474f41b31dea84ec5d563f0sergeyv        return PIXEL_FORMAT_RGBA_8888;
105694d499662838123f474f41b31dea84ec5d563f0sergeyv    case GL_RGBA:
106694d499662838123f474f41b31dea84ec5d563f0sergeyv        return PIXEL_FORMAT_RGBA_8888;
10791d6354cde90b6625d4af6a5d909d886bf602a49sergeyv    case GL_RGB:
10891d6354cde90b6625d4af6a5d909d886bf602a49sergeyv        return PIXEL_FORMAT_RGB_565;
109694d499662838123f474f41b31dea84ec5d563f0sergeyv    default:
110694d499662838123f474f41b31dea84ec5d563f0sergeyv        LOG_ALWAYS_FATAL("Unsupported bitmap colorType: %d", internalFormat);
111694d499662838123f474f41b31dea84ec5d563f0sergeyv        return PIXEL_FORMAT_UNKNOWN;
112694d499662838123f474f41b31dea84ec5d563f0sergeyv    }
113694d499662838123f474f41b31dea84ec5d563f0sergeyv}
114694d499662838123f474f41b31dea84ec5d563f0sergeyv
115694d499662838123f474f41b31dea84ec5d563f0sergeyvclass AutoEglFence {
116694d499662838123f474f41b31dea84ec5d563f0sergeyvpublic:
117694d499662838123f474f41b31dea84ec5d563f0sergeyv    AutoEglFence(EGLDisplay display)
118694d499662838123f474f41b31dea84ec5d563f0sergeyv            : mDisplay(display) {
119694d499662838123f474f41b31dea84ec5d563f0sergeyv        fence = eglCreateSyncKHR(mDisplay, EGL_SYNC_FENCE_KHR, NULL);
120694d499662838123f474f41b31dea84ec5d563f0sergeyv    }
121694d499662838123f474f41b31dea84ec5d563f0sergeyv
122694d499662838123f474f41b31dea84ec5d563f0sergeyv    ~AutoEglFence() {
123694d499662838123f474f41b31dea84ec5d563f0sergeyv        if (fence != EGL_NO_SYNC_KHR) {
124694d499662838123f474f41b31dea84ec5d563f0sergeyv            eglDestroySyncKHR(mDisplay, fence);
125694d499662838123f474f41b31dea84ec5d563f0sergeyv        }
126694d499662838123f474f41b31dea84ec5d563f0sergeyv    }
127694d499662838123f474f41b31dea84ec5d563f0sergeyv
128694d499662838123f474f41b31dea84ec5d563f0sergeyv    EGLSyncKHR fence = EGL_NO_SYNC_KHR;
129694d499662838123f474f41b31dea84ec5d563f0sergeyvprivate:
130694d499662838123f474f41b31dea84ec5d563f0sergeyv    EGLDisplay mDisplay = EGL_NO_DISPLAY;
131694d499662838123f474f41b31dea84ec5d563f0sergeyv};
132694d499662838123f474f41b31dea84ec5d563f0sergeyv
133694d499662838123f474f41b31dea84ec5d563f0sergeyvclass AutoEglImage {
134694d499662838123f474f41b31dea84ec5d563f0sergeyvpublic:
135694d499662838123f474f41b31dea84ec5d563f0sergeyv    AutoEglImage(EGLDisplay display, EGLClientBuffer clientBuffer)
136694d499662838123f474f41b31dea84ec5d563f0sergeyv            : mDisplay(display) {
137694d499662838123f474f41b31dea84ec5d563f0sergeyv        EGLint imageAttrs[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE };
138694d499662838123f474f41b31dea84ec5d563f0sergeyv        image = eglCreateImageKHR(display, EGL_NO_CONTEXT,
139694d499662838123f474f41b31dea84ec5d563f0sergeyv                EGL_NATIVE_BUFFER_ANDROID, clientBuffer, imageAttrs);
140694d499662838123f474f41b31dea84ec5d563f0sergeyv    }
141694d499662838123f474f41b31dea84ec5d563f0sergeyv
142694d499662838123f474f41b31dea84ec5d563f0sergeyv    ~AutoEglImage() {
143694d499662838123f474f41b31dea84ec5d563f0sergeyv        if (image != EGL_NO_IMAGE_KHR) {
144694d499662838123f474f41b31dea84ec5d563f0sergeyv            eglDestroyImageKHR(mDisplay, image);
145694d499662838123f474f41b31dea84ec5d563f0sergeyv        }
146694d499662838123f474f41b31dea84ec5d563f0sergeyv    }
147694d499662838123f474f41b31dea84ec5d563f0sergeyv
148694d499662838123f474f41b31dea84ec5d563f0sergeyv    EGLImageKHR image = EGL_NO_IMAGE_KHR;
149694d499662838123f474f41b31dea84ec5d563f0sergeyvprivate:
150694d499662838123f474f41b31dea84ec5d563f0sergeyv    EGLDisplay mDisplay = EGL_NO_DISPLAY;
151694d499662838123f474f41b31dea84ec5d563f0sergeyv};
152694d499662838123f474f41b31dea84ec5d563f0sergeyv
153694d499662838123f474f41b31dea84ec5d563f0sergeyvstatic bool uploadBitmapToGraphicBuffer(uirenderer::Caches& caches, SkBitmap& bitmap,
154694d499662838123f474f41b31dea84ec5d563f0sergeyv        GraphicBuffer& buffer, GLint format, GLint type) {
155694d499662838123f474f41b31dea84ec5d563f0sergeyv    SkAutoLockPixels alp(bitmap);
156694d499662838123f474f41b31dea84ec5d563f0sergeyv    EGLDisplay display = eglGetCurrentDisplay();
157694d499662838123f474f41b31dea84ec5d563f0sergeyv    LOG_ALWAYS_FATAL_IF(display == EGL_NO_DISPLAY,
158694d499662838123f474f41b31dea84ec5d563f0sergeyv                "Failed to get EGL_DEFAULT_DISPLAY! err=%s",
159694d499662838123f474f41b31dea84ec5d563f0sergeyv                uirenderer::renderthread::EglManager::eglErrorString());
160694d499662838123f474f41b31dea84ec5d563f0sergeyv    // These objects are initialized below but the default "null"
161694d499662838123f474f41b31dea84ec5d563f0sergeyv    // values are used to cleanup properly at any point in the
162694d499662838123f474f41b31dea84ec5d563f0sergeyv    // initialization sequenc
163694d499662838123f474f41b31dea84ec5d563f0sergeyv    GLuint texture = 0;
164694d499662838123f474f41b31dea84ec5d563f0sergeyv    // We use an EGLImage to access the content of the GraphicBuffer
165694d499662838123f474f41b31dea84ec5d563f0sergeyv    // The EGL image is later bound to a 2D texture
166694d499662838123f474f41b31dea84ec5d563f0sergeyv    EGLClientBuffer clientBuffer = (EGLClientBuffer) buffer.getNativeBuffer();
167694d499662838123f474f41b31dea84ec5d563f0sergeyv    AutoEglImage autoImage(display, clientBuffer);
168694d499662838123f474f41b31dea84ec5d563f0sergeyv    if (autoImage.image == EGL_NO_IMAGE_KHR) {
169694d499662838123f474f41b31dea84ec5d563f0sergeyv        ALOGW("Could not create EGL image, err =%s",
170694d499662838123f474f41b31dea84ec5d563f0sergeyv                uirenderer::renderthread::EglManager::eglErrorString());
171694d499662838123f474f41b31dea84ec5d563f0sergeyv        return false;
172694d499662838123f474f41b31dea84ec5d563f0sergeyv    }
173694d499662838123f474f41b31dea84ec5d563f0sergeyv    glGenTextures(1, &texture);
174694d499662838123f474f41b31dea84ec5d563f0sergeyv    caches.textureState().bindTexture(texture);
175694d499662838123f474f41b31dea84ec5d563f0sergeyv    glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, autoImage.image);
176694d499662838123f474f41b31dea84ec5d563f0sergeyv
177694d499662838123f474f41b31dea84ec5d563f0sergeyv    GL_CHECKPOINT(MODERATE);
178694d499662838123f474f41b31dea84ec5d563f0sergeyv
179694d499662838123f474f41b31dea84ec5d563f0sergeyv    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, bitmap.width(), bitmap.height(),
180694d499662838123f474f41b31dea84ec5d563f0sergeyv            format, type, bitmap.getPixels());
181694d499662838123f474f41b31dea84ec5d563f0sergeyv
182694d499662838123f474f41b31dea84ec5d563f0sergeyv    GL_CHECKPOINT(MODERATE);
183694d499662838123f474f41b31dea84ec5d563f0sergeyv
184694d499662838123f474f41b31dea84ec5d563f0sergeyv    // The fence is used to wait for the texture upload to finish
185694d499662838123f474f41b31dea84ec5d563f0sergeyv    // properly. We cannot rely on glFlush() and glFinish() as
186694d499662838123f474f41b31dea84ec5d563f0sergeyv    // some drivers completely ignore these API calls
187694d499662838123f474f41b31dea84ec5d563f0sergeyv    AutoEglFence autoFence(display);
188694d499662838123f474f41b31dea84ec5d563f0sergeyv    if (autoFence.fence == EGL_NO_SYNC_KHR) {
189694d499662838123f474f41b31dea84ec5d563f0sergeyv        LOG_ALWAYS_FATAL("Could not create sync fence %#x", eglGetError());
190694d499662838123f474f41b31dea84ec5d563f0sergeyv        return false;
191694d499662838123f474f41b31dea84ec5d563f0sergeyv    }
192694d499662838123f474f41b31dea84ec5d563f0sergeyv    // The flag EGL_SYNC_FLUSH_COMMANDS_BIT_KHR will trigger a
193694d499662838123f474f41b31dea84ec5d563f0sergeyv    // pipeline flush (similar to what a glFlush() would do.)
194694d499662838123f474f41b31dea84ec5d563f0sergeyv    EGLint waitStatus = eglClientWaitSyncKHR(display, autoFence.fence,
195694d499662838123f474f41b31dea84ec5d563f0sergeyv            EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, FENCE_TIMEOUT);
196694d499662838123f474f41b31dea84ec5d563f0sergeyv    if (waitStatus != EGL_CONDITION_SATISFIED_KHR) {
197694d499662838123f474f41b31dea84ec5d563f0sergeyv        LOG_ALWAYS_FATAL("Failed to wait for the fence %#x", eglGetError());
198694d499662838123f474f41b31dea84ec5d563f0sergeyv        return false;
199694d499662838123f474f41b31dea84ec5d563f0sergeyv    }
200694d499662838123f474f41b31dea84ec5d563f0sergeyv    return true;
201694d499662838123f474f41b31dea84ec5d563f0sergeyv}
202694d499662838123f474f41b31dea84ec5d563f0sergeyv
203694d499662838123f474f41b31dea84ec5d563f0sergeyvsk_sp<Bitmap> Bitmap::allocateHardwareBitmap(uirenderer::renderthread::RenderThread& renderThread,
204694d499662838123f474f41b31dea84ec5d563f0sergeyv        SkBitmap& skBitmap) {
205694d499662838123f474f41b31dea84ec5d563f0sergeyv    renderThread.eglManager().initialize();
206694d499662838123f474f41b31dea84ec5d563f0sergeyv    uirenderer::Caches& caches = uirenderer::Caches::getInstance();
207694d499662838123f474f41b31dea84ec5d563f0sergeyv
208694d499662838123f474f41b31dea84ec5d563f0sergeyv    sp<ISurfaceComposer> composer(ComposerService::getComposerService());
209694d499662838123f474f41b31dea84ec5d563f0sergeyv    sp<IGraphicBufferAlloc> alloc(composer->createGraphicBufferAlloc());
210694d499662838123f474f41b31dea84ec5d563f0sergeyv    if (alloc == NULL) {
211694d499662838123f474f41b31dea84ec5d563f0sergeyv        ALOGW("createGraphicBufferAlloc() failed in GraphicBuffer.create()");
212694d499662838123f474f41b31dea84ec5d563f0sergeyv        return nullptr;
213694d499662838123f474f41b31dea84ec5d563f0sergeyv    }
214694d499662838123f474f41b31dea84ec5d563f0sergeyv
215694d499662838123f474f41b31dea84ec5d563f0sergeyv    const SkImageInfo& info = skBitmap.info();
21605126d151eb3caa85bd3a039cffb6e37940c3fa4sergeyv    if (info.colorType() == kUnknown_SkColorType || info.colorType() == kAlpha_8_SkColorType) {
21705126d151eb3caa85bd3a039cffb6e37940c3fa4sergeyv        ALOGW("unable to create hardware bitmap of colortype: %d", info.colorType());
218694d499662838123f474f41b31dea84ec5d563f0sergeyv        return nullptr;
219694d499662838123f474f41b31dea84ec5d563f0sergeyv    }
220694d499662838123f474f41b31dea84ec5d563f0sergeyv
221ab12c1fe73734a18ac19a06b97f276528f6d027aMike Reed    sk_sp<SkColorSpace> sRGB = SkColorSpace::MakeNamed(SkColorSpace::kSRGB_Named);
222694d499662838123f474f41b31dea84ec5d563f0sergeyv    bool needSRGB = skBitmap.info().colorSpace() == sRGB.get();
223694d499662838123f474f41b31dea84ec5d563f0sergeyv    bool hasSRGB = caches.extensions().hasSRGB();
224694d499662838123f474f41b31dea84ec5d563f0sergeyv    GLint format, type, internalFormat;
225694d499662838123f474f41b31dea84ec5d563f0sergeyv    uirenderer::Texture::colorTypeToGlFormatAndType(caches, skBitmap.colorType(),
226694d499662838123f474f41b31dea84ec5d563f0sergeyv            needSRGB, &internalFormat, &format, &type);
227694d499662838123f474f41b31dea84ec5d563f0sergeyv
228694d499662838123f474f41b31dea84ec5d563f0sergeyv    PixelFormat pixelFormat = internalFormatToPixelFormat(internalFormat);
229694d499662838123f474f41b31dea84ec5d563f0sergeyv    status_t error;
230694d499662838123f474f41b31dea84ec5d563f0sergeyv    sp<GraphicBuffer> buffer = alloc->createGraphicBuffer(info.width(), info.height(), pixelFormat,
231850054cb46b25e20c1ae0b409734c0fa5c634b18Craig Donner            1, GraphicBuffer::USAGE_HW_TEXTURE | GraphicBuffer::USAGE_SW_WRITE_NEVER
232694d499662838123f474f41b31dea84ec5d563f0sergeyv            | GraphicBuffer::USAGE_SW_READ_NEVER , &error);
233694d499662838123f474f41b31dea84ec5d563f0sergeyv
234694d499662838123f474f41b31dea84ec5d563f0sergeyv    if (!buffer.get()) {
235694d499662838123f474f41b31dea84ec5d563f0sergeyv        ALOGW("createGraphicBuffer() failed in GraphicBuffer.create()");
236694d499662838123f474f41b31dea84ec5d563f0sergeyv        return nullptr;
237694d499662838123f474f41b31dea84ec5d563f0sergeyv    }
238694d499662838123f474f41b31dea84ec5d563f0sergeyv
239694d499662838123f474f41b31dea84ec5d563f0sergeyv    SkBitmap bitmap;
240694d499662838123f474f41b31dea84ec5d563f0sergeyv    if (CC_UNLIKELY(uirenderer::Texture::hasUnsupportedColorType(skBitmap.info(),
241694d499662838123f474f41b31dea84ec5d563f0sergeyv            hasSRGB, sRGB.get()))) {
242694d499662838123f474f41b31dea84ec5d563f0sergeyv        bitmap = uirenderer::Texture::uploadToN32(skBitmap, hasSRGB, std::move(sRGB));
243694d499662838123f474f41b31dea84ec5d563f0sergeyv    } else {
244694d499662838123f474f41b31dea84ec5d563f0sergeyv        bitmap = skBitmap;
245694d499662838123f474f41b31dea84ec5d563f0sergeyv    }
246694d499662838123f474f41b31dea84ec5d563f0sergeyv
247694d499662838123f474f41b31dea84ec5d563f0sergeyv    if (!uploadBitmapToGraphicBuffer(caches, bitmap, *buffer, format, type)) {
248694d499662838123f474f41b31dea84ec5d563f0sergeyv        return nullptr;
249694d499662838123f474f41b31dea84ec5d563f0sergeyv    }
25005126d151eb3caa85bd3a039cffb6e37940c3fa4sergeyv    return sk_sp<Bitmap>(new Bitmap(buffer.get(), bitmap.info()));
251694d499662838123f474f41b31dea84ec5d563f0sergeyv}
252694d499662838123f474f41b31dea84ec5d563f0sergeyv
253694d499662838123f474f41b31dea84ec5d563f0sergeyvsk_sp<Bitmap> Bitmap::allocateHardwareBitmap(SkBitmap& bitmap) {
254694d499662838123f474f41b31dea84ec5d563f0sergeyv    return uirenderer::renderthread::RenderProxy::allocateHardwareBitmap(bitmap);
255694d499662838123f474f41b31dea84ec5d563f0sergeyv}
256694d499662838123f474f41b31dea84ec5d563f0sergeyv
257fc9999505a36c66892d7ccce85187936105f4f36sergeyvsk_sp<Bitmap> Bitmap::allocateHeapBitmap(SkBitmap* bitmap, SkColorTable* ctable) {
258fc9999505a36c66892d7ccce85187936105f4f36sergeyv   return allocateBitmap(bitmap, ctable, &android::allocateHeapBitmap);
259fc9999505a36c66892d7ccce85187936105f4f36sergeyv}
260fc9999505a36c66892d7ccce85187936105f4f36sergeyv
261fc9999505a36c66892d7ccce85187936105f4f36sergeyvsk_sp<Bitmap> Bitmap::allocateHeapBitmap(const SkImageInfo& info) {
262fc9999505a36c66892d7ccce85187936105f4f36sergeyv    size_t size;
263fc9999505a36c66892d7ccce85187936105f4f36sergeyv    if (!computeAllocationSize(info.minRowBytes(), info.height(), &size)) {
264fc9999505a36c66892d7ccce85187936105f4f36sergeyv        LOG_ALWAYS_FATAL("trying to allocate too large bitmap");
265fc9999505a36c66892d7ccce85187936105f4f36sergeyv        return nullptr;
266fc9999505a36c66892d7ccce85187936105f4f36sergeyv    }
267fc9999505a36c66892d7ccce85187936105f4f36sergeyv    return android::allocateHeapBitmap(size, info, info.minRowBytes(), nullptr);
268fc9999505a36c66892d7ccce85187936105f4f36sergeyv}
269fc9999505a36c66892d7ccce85187936105f4f36sergeyv
270c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvsk_sp<Bitmap> Bitmap::allocateAshmemBitmap(size_t size, const SkImageInfo& info,
271c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv        size_t rowBytes, SkColorTable* ctable) {
272c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    // Create new ashmem region with read/write priv
273c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    int fd = ashmem_create_region("bitmap", size);
274c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    if (fd < 0) {
275c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv        return nullptr;
276c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    }
277c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv
278c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    void* addr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
279c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    if (addr == MAP_FAILED) {
280c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv        close(fd);
281c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv        return nullptr;
282c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    }
283c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv
284c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    if (ashmem_set_prot_region(fd, PROT_READ) < 0) {
285c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv        munmap(addr, size);
286c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv        close(fd);
287c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv        return nullptr;
288c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    }
289c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv    return sk_sp<Bitmap>(new Bitmap(addr, fd, size, info, rowBytes, ctable));
290c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv}
291c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv
292aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyvvoid FreePixelRef(void* addr, void* context) {
293aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv    auto pixelRef = (SkPixelRef*) context;
294aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv    pixelRef->unlockPixels();
295aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv    pixelRef->unref();
296aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv}
297aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv
298aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyvsk_sp<Bitmap> Bitmap::createFrom(const SkImageInfo& info, SkPixelRef& pixelRef) {
299aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv    pixelRef.ref();
300aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv    pixelRef.lockPixels();
301aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv    return sk_sp<Bitmap>(new Bitmap((void*) pixelRef.pixels(), (void*) &pixelRef, FreePixelRef,
302aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv            info, pixelRef.rowBytes(), pixelRef.colorTable()));
303aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv}
304aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv
3059a029876422926e313f646f44ab3592cfd4f9933sergeyvsk_sp<Bitmap> Bitmap::createFrom(sp<GraphicBuffer> graphicBuffer) {
3069a029876422926e313f646f44ab3592cfd4f9933sergeyv    PixelFormat format = graphicBuffer->getPixelFormat();
3079a029876422926e313f646f44ab3592cfd4f9933sergeyv    if (!graphicBuffer.get() || format != PIXEL_FORMAT_RGBA_8888) {
3089a029876422926e313f646f44ab3592cfd4f9933sergeyv        return nullptr;
3099a029876422926e313f646f44ab3592cfd4f9933sergeyv    }
3109a029876422926e313f646f44ab3592cfd4f9933sergeyv    SkImageInfo info = SkImageInfo::Make(graphicBuffer->getWidth(), graphicBuffer->getHeight(),
31105126d151eb3caa85bd3a039cffb6e37940c3fa4sergeyv            kRGBA_8888_SkColorType, kPremul_SkAlphaType,
31205126d151eb3caa85bd3a039cffb6e37940c3fa4sergeyv            SkColorSpace::MakeNamed(SkColorSpace::kSRGB_Named));
3139a029876422926e313f646f44ab3592cfd4f9933sergeyv    return sk_sp<Bitmap>(new Bitmap(graphicBuffer.get(), info));
3149a029876422926e313f646f44ab3592cfd4f9933sergeyv}
3159a029876422926e313f646f44ab3592cfd4f9933sergeyv
316c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvvoid Bitmap::reconfigure(const SkImageInfo& newInfo, size_t rowBytes, SkColorTable* ctable) {
317163f88140e18f13575886e88af0336e0ab1ec846sergeyv    if (kIndex_8_SkColorType != newInfo.colorType()) {
318163f88140e18f13575886e88af0336e0ab1ec846sergeyv        ctable = nullptr;
319163f88140e18f13575886e88af0336e0ab1ec846sergeyv    }
320163f88140e18f13575886e88af0336e0ab1ec846sergeyv    mRowBytes = rowBytes;
321163f88140e18f13575886e88af0336e0ab1ec846sergeyv    if (mColorTable.get() != ctable) {
322003f14256271a6955baacba93e54f09d366f1c3bsergeyv        mColorTable.reset(SkSafeRef(ctable));
323163f88140e18f13575886e88af0336e0ab1ec846sergeyv    }
324163f88140e18f13575886e88af0336e0ab1ec846sergeyv
325163f88140e18f13575886e88af0336e0ab1ec846sergeyv    // Need to validate the alpha type to filter against the color type
326163f88140e18f13575886e88af0336e0ab1ec846sergeyv    // to prevent things like a non-opaque RGB565 bitmap
327163f88140e18f13575886e88af0336e0ab1ec846sergeyv    SkAlphaType alphaType;
328163f88140e18f13575886e88af0336e0ab1ec846sergeyv    LOG_ALWAYS_FATAL_IF(!SkColorTypeValidateAlphaType(
329163f88140e18f13575886e88af0336e0ab1ec846sergeyv            newInfo.colorType(), newInfo.alphaType(), &alphaType),
330163f88140e18f13575886e88af0336e0ab1ec846sergeyv            "Failed to validate alpha type!");
331163f88140e18f13575886e88af0336e0ab1ec846sergeyv
332163f88140e18f13575886e88af0336e0ab1ec846sergeyv    // Dirty hack is dirty
333163f88140e18f13575886e88af0336e0ab1ec846sergeyv    // TODO: Figure something out here, Skia's current design makes this
334163f88140e18f13575886e88af0336e0ab1ec846sergeyv    // really hard to work with. Skia really, really wants immutable objects,
335163f88140e18f13575886e88af0336e0ab1ec846sergeyv    // but with the nested-ref-count hackery going on that's just not
336163f88140e18f13575886e88af0336e0ab1ec846sergeyv    // feasible without going insane trying to figure it out
337163f88140e18f13575886e88af0336e0ab1ec846sergeyv    SkImageInfo* myInfo = const_cast<SkImageInfo*>(&this->info());
338163f88140e18f13575886e88af0336e0ab1ec846sergeyv    *myInfo = newInfo;
339163f88140e18f13575886e88af0336e0ab1ec846sergeyv    changeAlphaType(alphaType);
340163f88140e18f13575886e88af0336e0ab1ec846sergeyv
341163f88140e18f13575886e88af0336e0ab1ec846sergeyv    // Docs say to only call this in the ctor, but we're going to call
342163f88140e18f13575886e88af0336e0ab1ec846sergeyv    // it anyway even if this isn't always the ctor.
343163f88140e18f13575886e88af0336e0ab1ec846sergeyv    // TODO: Fix this too as part of the above TODO
344163f88140e18f13575886e88af0336e0ab1ec846sergeyv    setPreLocked(getStorage(), mRowBytes, mColorTable.get());
345163f88140e18f13575886e88af0336e0ab1ec846sergeyv}
346163f88140e18f13575886e88af0336e0ab1ec846sergeyv
347c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvBitmap::Bitmap(void* address, size_t size, const SkImageInfo& info, size_t rowBytes, SkColorTable* ctable)
348163f88140e18f13575886e88af0336e0ab1ec846sergeyv            : SkPixelRef(info)
349163f88140e18f13575886e88af0336e0ab1ec846sergeyv            , mPixelStorageType(PixelStorageType::Heap) {
350163f88140e18f13575886e88af0336e0ab1ec846sergeyv    mPixelStorage.heap.address = address;
351163f88140e18f13575886e88af0336e0ab1ec846sergeyv    mPixelStorage.heap.size = size;
352163f88140e18f13575886e88af0336e0ab1ec846sergeyv    reconfigure(info, rowBytes, ctable);
353163f88140e18f13575886e88af0336e0ab1ec846sergeyv}
354163f88140e18f13575886e88af0336e0ab1ec846sergeyv
355c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvBitmap::Bitmap(void* address, void* context, FreeFunc freeFunc,
356163f88140e18f13575886e88af0336e0ab1ec846sergeyv                const SkImageInfo& info, size_t rowBytes, SkColorTable* ctable)
357163f88140e18f13575886e88af0336e0ab1ec846sergeyv            : SkPixelRef(info)
358163f88140e18f13575886e88af0336e0ab1ec846sergeyv            , mPixelStorageType(PixelStorageType::External) {
359163f88140e18f13575886e88af0336e0ab1ec846sergeyv    mPixelStorage.external.address = address;
360163f88140e18f13575886e88af0336e0ab1ec846sergeyv    mPixelStorage.external.context = context;
361163f88140e18f13575886e88af0336e0ab1ec846sergeyv    mPixelStorage.external.freeFunc = freeFunc;
362163f88140e18f13575886e88af0336e0ab1ec846sergeyv    reconfigure(info, rowBytes, ctable);
363163f88140e18f13575886e88af0336e0ab1ec846sergeyv}
364163f88140e18f13575886e88af0336e0ab1ec846sergeyv
365c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvBitmap::Bitmap(void* address, int fd, size_t mappedSize,
366163f88140e18f13575886e88af0336e0ab1ec846sergeyv                const SkImageInfo& info, size_t rowBytes, SkColorTable* ctable)
367163f88140e18f13575886e88af0336e0ab1ec846sergeyv            : SkPixelRef(info)
368163f88140e18f13575886e88af0336e0ab1ec846sergeyv            , mPixelStorageType(PixelStorageType::Ashmem) {
369163f88140e18f13575886e88af0336e0ab1ec846sergeyv    mPixelStorage.ashmem.address = address;
370163f88140e18f13575886e88af0336e0ab1ec846sergeyv    mPixelStorage.ashmem.fd = fd;
371163f88140e18f13575886e88af0336e0ab1ec846sergeyv    mPixelStorage.ashmem.size = mappedSize;
372163f88140e18f13575886e88af0336e0ab1ec846sergeyv    reconfigure(info, rowBytes, ctable);
373163f88140e18f13575886e88af0336e0ab1ec846sergeyv}
374163f88140e18f13575886e88af0336e0ab1ec846sergeyv
3759a029876422926e313f646f44ab3592cfd4f9933sergeyvBitmap::Bitmap(GraphicBuffer* buffer, const SkImageInfo& info)
376694d499662838123f474f41b31dea84ec5d563f0sergeyv        : SkPixelRef(info)
377694d499662838123f474f41b31dea84ec5d563f0sergeyv        , mPixelStorageType(PixelStorageType::Hardware) {
3789a029876422926e313f646f44ab3592cfd4f9933sergeyv    mPixelStorage.hardware.buffer = buffer;
3799a029876422926e313f646f44ab3592cfd4f9933sergeyv    buffer->incStrong(buffer);
380694d499662838123f474f41b31dea84ec5d563f0sergeyv    mRowBytes = bytesPerPixel(buffer->getPixelFormat()) * buffer->getStride();
381694d499662838123f474f41b31dea84ec5d563f0sergeyv}
3829a029876422926e313f646f44ab3592cfd4f9933sergeyv
383c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvBitmap::~Bitmap() {
384163f88140e18f13575886e88af0336e0ab1ec846sergeyv    switch (mPixelStorageType) {
385163f88140e18f13575886e88af0336e0ab1ec846sergeyv    case PixelStorageType::External:
386163f88140e18f13575886e88af0336e0ab1ec846sergeyv        mPixelStorage.external.freeFunc(mPixelStorage.external.address,
387163f88140e18f13575886e88af0336e0ab1ec846sergeyv                mPixelStorage.external.context);
388163f88140e18f13575886e88af0336e0ab1ec846sergeyv        break;
389163f88140e18f13575886e88af0336e0ab1ec846sergeyv    case PixelStorageType::Ashmem:
390163f88140e18f13575886e88af0336e0ab1ec846sergeyv        munmap(mPixelStorage.ashmem.address, mPixelStorage.ashmem.size);
391163f88140e18f13575886e88af0336e0ab1ec846sergeyv        close(mPixelStorage.ashmem.fd);
392163f88140e18f13575886e88af0336e0ab1ec846sergeyv        break;
393163f88140e18f13575886e88af0336e0ab1ec846sergeyv    case PixelStorageType::Heap:
394163f88140e18f13575886e88af0336e0ab1ec846sergeyv        free(mPixelStorage.heap.address);
395163f88140e18f13575886e88af0336e0ab1ec846sergeyv        break;
396694d499662838123f474f41b31dea84ec5d563f0sergeyv    case PixelStorageType::Hardware:
397694d499662838123f474f41b31dea84ec5d563f0sergeyv        auto buffer = mPixelStorage.hardware.buffer;
398694d499662838123f474f41b31dea84ec5d563f0sergeyv        buffer->decStrong(buffer);
399694d499662838123f474f41b31dea84ec5d563f0sergeyv        mPixelStorage.hardware.buffer = nullptr;
400694d499662838123f474f41b31dea84ec5d563f0sergeyv        break;
401694d499662838123f474f41b31dea84ec5d563f0sergeyv
402163f88140e18f13575886e88af0336e0ab1ec846sergeyv    }
403163f88140e18f13575886e88af0336e0ab1ec846sergeyv
404163f88140e18f13575886e88af0336e0ab1ec846sergeyv    if (android::uirenderer::Caches::hasInstance()) {
405163f88140e18f13575886e88af0336e0ab1ec846sergeyv        android::uirenderer::Caches::getInstance().textureCache.releaseTexture(getStableID());
406163f88140e18f13575886e88af0336e0ab1ec846sergeyv    }
407163f88140e18f13575886e88af0336e0ab1ec846sergeyv}
408163f88140e18f13575886e88af0336e0ab1ec846sergeyv
409c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvbool Bitmap::hasHardwareMipMap() const {
410163f88140e18f13575886e88af0336e0ab1ec846sergeyv    return mHasHardwareMipMap;
411163f88140e18f13575886e88af0336e0ab1ec846sergeyv}
412163f88140e18f13575886e88af0336e0ab1ec846sergeyv
413c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvvoid Bitmap::setHasHardwareMipMap(bool hasMipMap) {
414163f88140e18f13575886e88af0336e0ab1ec846sergeyv    mHasHardwareMipMap = hasMipMap;
415163f88140e18f13575886e88af0336e0ab1ec846sergeyv}
416163f88140e18f13575886e88af0336e0ab1ec846sergeyv
417c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvvoid* Bitmap::getStorage() const {
418163f88140e18f13575886e88af0336e0ab1ec846sergeyv    switch (mPixelStorageType) {
419163f88140e18f13575886e88af0336e0ab1ec846sergeyv    case PixelStorageType::External:
420163f88140e18f13575886e88af0336e0ab1ec846sergeyv        return mPixelStorage.external.address;
421163f88140e18f13575886e88af0336e0ab1ec846sergeyv    case PixelStorageType::Ashmem:
422163f88140e18f13575886e88af0336e0ab1ec846sergeyv        return mPixelStorage.ashmem.address;
423163f88140e18f13575886e88af0336e0ab1ec846sergeyv    case PixelStorageType::Heap:
424163f88140e18f13575886e88af0336e0ab1ec846sergeyv        return mPixelStorage.heap.address;
425694d499662838123f474f41b31dea84ec5d563f0sergeyv    case PixelStorageType::Hardware:
426694d499662838123f474f41b31dea84ec5d563f0sergeyv        return nullptr;
427163f88140e18f13575886e88af0336e0ab1ec846sergeyv    }
428163f88140e18f13575886e88af0336e0ab1ec846sergeyv}
429163f88140e18f13575886e88af0336e0ab1ec846sergeyv
430c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvbool Bitmap::onNewLockPixels(LockRec* rec) {
431163f88140e18f13575886e88af0336e0ab1ec846sergeyv    rec->fPixels = getStorage();
432163f88140e18f13575886e88af0336e0ab1ec846sergeyv    rec->fRowBytes = mRowBytes;
433163f88140e18f13575886e88af0336e0ab1ec846sergeyv    rec->fColorTable = mColorTable.get();
434163f88140e18f13575886e88af0336e0ab1ec846sergeyv    return true;
435163f88140e18f13575886e88af0336e0ab1ec846sergeyv}
436163f88140e18f13575886e88af0336e0ab1ec846sergeyv
437c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvsize_t Bitmap::getAllocatedSizeInBytes() const {
438163f88140e18f13575886e88af0336e0ab1ec846sergeyv    return info().getSafeSize(mRowBytes);
439163f88140e18f13575886e88af0336e0ab1ec846sergeyv}
440163f88140e18f13575886e88af0336e0ab1ec846sergeyv
441c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvint Bitmap::getAshmemFd() const {
442163f88140e18f13575886e88af0336e0ab1ec846sergeyv    switch (mPixelStorageType) {
443163f88140e18f13575886e88af0336e0ab1ec846sergeyv    case PixelStorageType::Ashmem:
444163f88140e18f13575886e88af0336e0ab1ec846sergeyv        return mPixelStorage.ashmem.fd;
445163f88140e18f13575886e88af0336e0ab1ec846sergeyv    default:
446163f88140e18f13575886e88af0336e0ab1ec846sergeyv        return -1;
447163f88140e18f13575886e88af0336e0ab1ec846sergeyv    }
448163f88140e18f13575886e88af0336e0ab1ec846sergeyv}
449163f88140e18f13575886e88af0336e0ab1ec846sergeyv
450c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvsize_t Bitmap::getAllocationByteCount() const {
451163f88140e18f13575886e88af0336e0ab1ec846sergeyv    switch (mPixelStorageType) {
452163f88140e18f13575886e88af0336e0ab1ec846sergeyv    case PixelStorageType::Heap:
453163f88140e18f13575886e88af0336e0ab1ec846sergeyv        return mPixelStorage.heap.size;
454163f88140e18f13575886e88af0336e0ab1ec846sergeyv    default:
455163f88140e18f13575886e88af0336e0ab1ec846sergeyv        return rowBytes() * height();
456163f88140e18f13575886e88af0336e0ab1ec846sergeyv    }
457163f88140e18f13575886e88af0336e0ab1ec846sergeyv}
458163f88140e18f13575886e88af0336e0ab1ec846sergeyv
459c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvvoid Bitmap::reconfigure(const SkImageInfo& info) {
460163f88140e18f13575886e88af0336e0ab1ec846sergeyv    reconfigure(info, info.minRowBytes(), nullptr);
461163f88140e18f13575886e88af0336e0ab1ec846sergeyv}
462163f88140e18f13575886e88af0336e0ab1ec846sergeyv
463c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvvoid Bitmap::setAlphaType(SkAlphaType alphaType) {
464163f88140e18f13575886e88af0336e0ab1ec846sergeyv    if (!SkColorTypeValidateAlphaType(info().colorType(), alphaType, &alphaType)) {
465163f88140e18f13575886e88af0336e0ab1ec846sergeyv        return;
466163f88140e18f13575886e88af0336e0ab1ec846sergeyv    }
467163f88140e18f13575886e88af0336e0ab1ec846sergeyv
468163f88140e18f13575886e88af0336e0ab1ec846sergeyv    changeAlphaType(alphaType);
469163f88140e18f13575886e88af0336e0ab1ec846sergeyv}
470163f88140e18f13575886e88af0336e0ab1ec846sergeyv
471c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvvoid Bitmap::getSkBitmap(SkBitmap* outBitmap) {
47259eecb526adc5bd7041e7b6147bfcc40dd2c200esergeyv    outBitmap->setHasHardwareMipMap(mHasHardwareMipMap);
473694d499662838123f474f41b31dea84ec5d563f0sergeyv    if (isHardware()) {
47459eecb526adc5bd7041e7b6147bfcc40dd2c200esergeyv        ALOGW("Warning: attempt to read pixels from hardware bitmap, which is very slow operation");
47559eecb526adc5bd7041e7b6147bfcc40dd2c200esergeyv        outBitmap->allocPixels(info());
47659eecb526adc5bd7041e7b6147bfcc40dd2c200esergeyv        uirenderer::renderthread::RenderProxy::copyGraphicBufferInto(graphicBuffer(), outBitmap);
477694d499662838123f474f41b31dea84ec5d563f0sergeyv        return;
478694d499662838123f474f41b31dea84ec5d563f0sergeyv    }
479163f88140e18f13575886e88af0336e0ab1ec846sergeyv    outBitmap->setInfo(info(), rowBytes());
480163f88140e18f13575886e88af0336e0ab1ec846sergeyv    outBitmap->setPixelRef(this);
481163f88140e18f13575886e88af0336e0ab1ec846sergeyv}
482163f88140e18f13575886e88af0336e0ab1ec846sergeyv
483554ffeb8b7c836da43a637c59eedfc617895b19dsergeyvvoid Bitmap::getSkBitmapForShaders(SkBitmap* outBitmap) {
484554ffeb8b7c836da43a637c59eedfc617895b19dsergeyv    outBitmap->setInfo(info(), rowBytes());
485554ffeb8b7c836da43a637c59eedfc617895b19dsergeyv    outBitmap->setPixelRef(this);
486554ffeb8b7c836da43a637c59eedfc617895b19dsergeyv    outBitmap->setHasHardwareMipMap(mHasHardwareMipMap);
487554ffeb8b7c836da43a637c59eedfc617895b19dsergeyv}
488554ffeb8b7c836da43a637c59eedfc617895b19dsergeyv
489ec4a4b13eae2241d1613890c1c1c096bed891845sergeyvvoid Bitmap::getBounds(SkRect* bounds) const {
490ec4a4b13eae2241d1613890c1c1c096bed891845sergeyv    SkASSERT(bounds);
491ec4a4b13eae2241d1613890c1c1c096bed891845sergeyv    bounds->set(0, 0, SkIntToScalar(info().width()), SkIntToScalar(info().height()));
492ec4a4b13eae2241d1613890c1c1c096bed891845sergeyv}
493ec4a4b13eae2241d1613890c1c1c096bed891845sergeyv
494694d499662838123f474f41b31dea84ec5d563f0sergeyvGraphicBuffer* Bitmap::graphicBuffer() {
495694d499662838123f474f41b31dea84ec5d563f0sergeyv    if (isHardware()) {
496694d499662838123f474f41b31dea84ec5d563f0sergeyv        return mPixelStorage.hardware.buffer;
497694d499662838123f474f41b31dea84ec5d563f0sergeyv    }
498694d499662838123f474f41b31dea84ec5d563f0sergeyv    return nullptr;
499694d499662838123f474f41b31dea84ec5d563f0sergeyv}
500694d499662838123f474f41b31dea84ec5d563f0sergeyv
501ab12c1fe73734a18ac19a06b97f276528f6d027aMike Reed} // namespace android
502