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"
22caaaa66e57293e4a6f312649bf472eab84d5c7feRomain Guy#include "utils/Color.h"
23163f88140e18f13575886e88af0336e0ab1ec846sergeyv
24163f88140e18f13575886e88af0336e0ab1ec846sergeyv#include <sys/mman.h>
256f773a0d8717162f81ff21d943baaa539a2d6c7eMark Salyzyn
266f773a0d8717162f81ff21d943baaa539a2d6c7eMark Salyzyn#include <log/log.h>
27163f88140e18f13575886e88af0336e0ab1ec846sergeyv#include <cutils/ashmem.h>
28163f88140e18f13575886e88af0336e0ab1ec846sergeyv
29694d499662838123f474f41b31dea84ec5d563f0sergeyv#include <GLES2/gl2.h>
30694d499662838123f474f41b31dea84ec5d563f0sergeyv#include <GLES2/gl2ext.h>
31694d499662838123f474f41b31dea84ec5d563f0sergeyv#include <EGL/egl.h>
32694d499662838123f474f41b31dea84ec5d563f0sergeyv#include <EGL/eglext.h>
33694d499662838123f474f41b31dea84ec5d563f0sergeyv
34694d499662838123f474f41b31dea84ec5d563f0sergeyv#include <private/gui/ComposerService.h>
35694d499662838123f474f41b31dea84ec5d563f0sergeyv#include <binder/IServiceManager.h>
36694d499662838123f474f41b31dea84ec5d563f0sergeyv#include <ui/PixelFormat.h>
37694d499662838123f474f41b31dea84ec5d563f0sergeyv
38694d499662838123f474f41b31dea84ec5d563f0sergeyv#include <SkCanvas.h>
39694d499662838123f474f41b31dea84ec5d563f0sergeyv
40163f88140e18f13575886e88af0336e0ab1ec846sergeyvnamespace android {
41163f88140e18f13575886e88af0336e0ab1ec846sergeyv
42fc9999505a36c66892d7ccce85187936105f4f36sergeyvstatic bool computeAllocationSize(size_t rowBytes, int height, size_t* size) {
43fc9999505a36c66892d7ccce85187936105f4f36sergeyv    int32_t rowBytes32 = SkToS32(rowBytes);
44fc9999505a36c66892d7ccce85187936105f4f36sergeyv    int64_t bigSize = (int64_t) height * rowBytes32;
45c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    if (rowBytes32 < 0 || !sk_64_isS32(bigSize)) {
46c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv        return false; // allocation will be too large
47c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    }
48c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv
49c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    *size = sk_64_asS32(bigSize);
50c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    return true;
51c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv}
52c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv
53c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvtypedef sk_sp<Bitmap> (*AllocPixeRef)(size_t allocSize, const SkImageInfo& info, size_t rowBytes,
54c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv        SkColorTable* ctable);
55c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv
56c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvstatic sk_sp<Bitmap> allocateBitmap(SkBitmap* bitmap, SkColorTable* ctable, AllocPixeRef alloc) {
57c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    const SkImageInfo& info = bitmap->info();
58c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    if (info.colorType() == kUnknown_SkColorType) {
59c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv        LOG_ALWAYS_FATAL("unknown bitmap configuration");
60c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv        return nullptr;
61c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    }
62c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv
63c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    size_t size;
64c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv
65c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    // we must respect the rowBytes value already set on the bitmap instead of
66c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    // attempting to compute our own.
67c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    const size_t rowBytes = bitmap->rowBytes();
68fc9999505a36c66892d7ccce85187936105f4f36sergeyv    if (!computeAllocationSize(rowBytes, bitmap->height(), &size)) {
69fc9999505a36c66892d7ccce85187936105f4f36sergeyv        return nullptr;
70fc9999505a36c66892d7ccce85187936105f4f36sergeyv    }
71fc9999505a36c66892d7ccce85187936105f4f36sergeyv
72c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    auto wrapper = alloc(size, info, rowBytes, ctable);
73c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    if (wrapper) {
74c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv        wrapper->getSkBitmap(bitmap);
75c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv        // since we're already allocated, we lockPixels right away
76c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv        // HeapAllocator behaves this way too
77c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv        bitmap->lockPixels();
78c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    }
79c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    return wrapper;
80c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv}
81c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv
82c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvsk_sp<Bitmap> Bitmap::allocateAshmemBitmap(SkBitmap* bitmap, SkColorTable* ctable) {
83c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv   return allocateBitmap(bitmap, ctable, &Bitmap::allocateAshmemBitmap);
84c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv}
85c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv
86fc9999505a36c66892d7ccce85187936105f4f36sergeyvstatic sk_sp<Bitmap> allocateHeapBitmap(size_t size, const SkImageInfo& info, size_t rowBytes,
87c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv        SkColorTable* ctable) {
88c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    void* addr = calloc(size, 1);
89c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    if (!addr) {
90c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv        return nullptr;
91c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    }
92c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv    return sk_sp<Bitmap>(new Bitmap(addr, size, info, rowBytes, ctable));
93c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv}
94c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv
95694d499662838123f474f41b31dea84ec5d563f0sergeyv#define FENCE_TIMEOUT 2000000000
96694d499662838123f474f41b31dea84ec5d563f0sergeyv
97694d499662838123f474f41b31dea84ec5d563f0sergeyv// TODO: handle SRGB sanely
98694d499662838123f474f41b31dea84ec5d563f0sergeyvstatic PixelFormat internalFormatToPixelFormat(GLint internalFormat) {
99694d499662838123f474f41b31dea84ec5d563f0sergeyv    switch (internalFormat) {
100694d499662838123f474f41b31dea84ec5d563f0sergeyv    case GL_LUMINANCE:
101694d499662838123f474f41b31dea84ec5d563f0sergeyv        return PIXEL_FORMAT_RGBA_8888;
102694d499662838123f474f41b31dea84ec5d563f0sergeyv    case GL_SRGB8_ALPHA8:
103694d499662838123f474f41b31dea84ec5d563f0sergeyv        return PIXEL_FORMAT_RGBA_8888;
104694d499662838123f474f41b31dea84ec5d563f0sergeyv    case GL_RGBA:
105694d499662838123f474f41b31dea84ec5d563f0sergeyv        return PIXEL_FORMAT_RGBA_8888;
10691d6354cde90b6625d4af6a5d909d886bf602a49sergeyv    case GL_RGB:
10791d6354cde90b6625d4af6a5d909d886bf602a49sergeyv        return PIXEL_FORMAT_RGB_565;
1089505a6552764461c22ce48f1ac13d025d23e1579Romain Guy    case GL_RGBA16F:
1099505a6552764461c22ce48f1ac13d025d23e1579Romain Guy        return PIXEL_FORMAT_RGBA_FP16;
110694d499662838123f474f41b31dea84ec5d563f0sergeyv    default:
111694d499662838123f474f41b31dea84ec5d563f0sergeyv        LOG_ALWAYS_FATAL("Unsupported bitmap colorType: %d", internalFormat);
112694d499662838123f474f41b31dea84ec5d563f0sergeyv        return PIXEL_FORMAT_UNKNOWN;
113694d499662838123f474f41b31dea84ec5d563f0sergeyv    }
114694d499662838123f474f41b31dea84ec5d563f0sergeyv}
115694d499662838123f474f41b31dea84ec5d563f0sergeyv
116694d499662838123f474f41b31dea84ec5d563f0sergeyvclass AutoEglFence {
117694d499662838123f474f41b31dea84ec5d563f0sergeyvpublic:
118694d499662838123f474f41b31dea84ec5d563f0sergeyv    AutoEglFence(EGLDisplay display)
119694d499662838123f474f41b31dea84ec5d563f0sergeyv            : mDisplay(display) {
120694d499662838123f474f41b31dea84ec5d563f0sergeyv        fence = eglCreateSyncKHR(mDisplay, EGL_SYNC_FENCE_KHR, NULL);
121694d499662838123f474f41b31dea84ec5d563f0sergeyv    }
122694d499662838123f474f41b31dea84ec5d563f0sergeyv
123694d499662838123f474f41b31dea84ec5d563f0sergeyv    ~AutoEglFence() {
124694d499662838123f474f41b31dea84ec5d563f0sergeyv        if (fence != EGL_NO_SYNC_KHR) {
125694d499662838123f474f41b31dea84ec5d563f0sergeyv            eglDestroySyncKHR(mDisplay, fence);
126694d499662838123f474f41b31dea84ec5d563f0sergeyv        }
127694d499662838123f474f41b31dea84ec5d563f0sergeyv    }
128694d499662838123f474f41b31dea84ec5d563f0sergeyv
129694d499662838123f474f41b31dea84ec5d563f0sergeyv    EGLSyncKHR fence = EGL_NO_SYNC_KHR;
130694d499662838123f474f41b31dea84ec5d563f0sergeyvprivate:
131694d499662838123f474f41b31dea84ec5d563f0sergeyv    EGLDisplay mDisplay = EGL_NO_DISPLAY;
132694d499662838123f474f41b31dea84ec5d563f0sergeyv};
133694d499662838123f474f41b31dea84ec5d563f0sergeyv
134694d499662838123f474f41b31dea84ec5d563f0sergeyvclass AutoEglImage {
135694d499662838123f474f41b31dea84ec5d563f0sergeyvpublic:
136694d499662838123f474f41b31dea84ec5d563f0sergeyv    AutoEglImage(EGLDisplay display, EGLClientBuffer clientBuffer)
137694d499662838123f474f41b31dea84ec5d563f0sergeyv            : mDisplay(display) {
138694d499662838123f474f41b31dea84ec5d563f0sergeyv        EGLint imageAttrs[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE };
139694d499662838123f474f41b31dea84ec5d563f0sergeyv        image = eglCreateImageKHR(display, EGL_NO_CONTEXT,
140694d499662838123f474f41b31dea84ec5d563f0sergeyv                EGL_NATIVE_BUFFER_ANDROID, clientBuffer, imageAttrs);
141694d499662838123f474f41b31dea84ec5d563f0sergeyv    }
142694d499662838123f474f41b31dea84ec5d563f0sergeyv
143694d499662838123f474f41b31dea84ec5d563f0sergeyv    ~AutoEglImage() {
144694d499662838123f474f41b31dea84ec5d563f0sergeyv        if (image != EGL_NO_IMAGE_KHR) {
145694d499662838123f474f41b31dea84ec5d563f0sergeyv            eglDestroyImageKHR(mDisplay, image);
146694d499662838123f474f41b31dea84ec5d563f0sergeyv        }
147694d499662838123f474f41b31dea84ec5d563f0sergeyv    }
148694d499662838123f474f41b31dea84ec5d563f0sergeyv
149694d499662838123f474f41b31dea84ec5d563f0sergeyv    EGLImageKHR image = EGL_NO_IMAGE_KHR;
150694d499662838123f474f41b31dea84ec5d563f0sergeyvprivate:
151694d499662838123f474f41b31dea84ec5d563f0sergeyv    EGLDisplay mDisplay = EGL_NO_DISPLAY;
152694d499662838123f474f41b31dea84ec5d563f0sergeyv};
153694d499662838123f474f41b31dea84ec5d563f0sergeyv
1549f4a82f5692831ad80f515fa831fddfdfe50b7b0sergeyvclass AutoGlTexture {
1559f4a82f5692831ad80f515fa831fddfdfe50b7b0sergeyvpublic:
1569f4a82f5692831ad80f515fa831fddfdfe50b7b0sergeyv    AutoGlTexture(uirenderer::Caches& caches)
1579f4a82f5692831ad80f515fa831fddfdfe50b7b0sergeyv            : mCaches(caches) {
1589f4a82f5692831ad80f515fa831fddfdfe50b7b0sergeyv        glGenTextures(1, &mTexture);
1599f4a82f5692831ad80f515fa831fddfdfe50b7b0sergeyv        caches.textureState().bindTexture(mTexture);
1609f4a82f5692831ad80f515fa831fddfdfe50b7b0sergeyv    }
1619f4a82f5692831ad80f515fa831fddfdfe50b7b0sergeyv
1629f4a82f5692831ad80f515fa831fddfdfe50b7b0sergeyv    ~AutoGlTexture() {
1639f4a82f5692831ad80f515fa831fddfdfe50b7b0sergeyv        mCaches.textureState().deleteTexture(mTexture);
1649f4a82f5692831ad80f515fa831fddfdfe50b7b0sergeyv    }
1659f4a82f5692831ad80f515fa831fddfdfe50b7b0sergeyv
1669f4a82f5692831ad80f515fa831fddfdfe50b7b0sergeyvprivate:
1679f4a82f5692831ad80f515fa831fddfdfe50b7b0sergeyv    uirenderer::Caches& mCaches;
1689f4a82f5692831ad80f515fa831fddfdfe50b7b0sergeyv    GLuint mTexture = 0;
1699f4a82f5692831ad80f515fa831fddfdfe50b7b0sergeyv};
1709f4a82f5692831ad80f515fa831fddfdfe50b7b0sergeyv
171694d499662838123f474f41b31dea84ec5d563f0sergeyvstatic bool uploadBitmapToGraphicBuffer(uirenderer::Caches& caches, SkBitmap& bitmap,
172694d499662838123f474f41b31dea84ec5d563f0sergeyv        GraphicBuffer& buffer, GLint format, GLint type) {
173694d499662838123f474f41b31dea84ec5d563f0sergeyv    SkAutoLockPixels alp(bitmap);
174694d499662838123f474f41b31dea84ec5d563f0sergeyv    EGLDisplay display = eglGetCurrentDisplay();
175694d499662838123f474f41b31dea84ec5d563f0sergeyv    LOG_ALWAYS_FATAL_IF(display == EGL_NO_DISPLAY,
176694d499662838123f474f41b31dea84ec5d563f0sergeyv                "Failed to get EGL_DEFAULT_DISPLAY! err=%s",
177694d499662838123f474f41b31dea84ec5d563f0sergeyv                uirenderer::renderthread::EglManager::eglErrorString());
178694d499662838123f474f41b31dea84ec5d563f0sergeyv    // We use an EGLImage to access the content of the GraphicBuffer
179694d499662838123f474f41b31dea84ec5d563f0sergeyv    // The EGL image is later bound to a 2D texture
180694d499662838123f474f41b31dea84ec5d563f0sergeyv    EGLClientBuffer clientBuffer = (EGLClientBuffer) buffer.getNativeBuffer();
181694d499662838123f474f41b31dea84ec5d563f0sergeyv    AutoEglImage autoImage(display, clientBuffer);
182694d499662838123f474f41b31dea84ec5d563f0sergeyv    if (autoImage.image == EGL_NO_IMAGE_KHR) {
183694d499662838123f474f41b31dea84ec5d563f0sergeyv        ALOGW("Could not create EGL image, err =%s",
184694d499662838123f474f41b31dea84ec5d563f0sergeyv                uirenderer::renderthread::EglManager::eglErrorString());
185694d499662838123f474f41b31dea84ec5d563f0sergeyv        return false;
186694d499662838123f474f41b31dea84ec5d563f0sergeyv    }
1879f4a82f5692831ad80f515fa831fddfdfe50b7b0sergeyv    AutoGlTexture glTexture(caches);
188694d499662838123f474f41b31dea84ec5d563f0sergeyv    glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, autoImage.image);
189694d499662838123f474f41b31dea84ec5d563f0sergeyv
190694d499662838123f474f41b31dea84ec5d563f0sergeyv    GL_CHECKPOINT(MODERATE);
191694d499662838123f474f41b31dea84ec5d563f0sergeyv
192694d499662838123f474f41b31dea84ec5d563f0sergeyv    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, bitmap.width(), bitmap.height(),
193694d499662838123f474f41b31dea84ec5d563f0sergeyv            format, type, bitmap.getPixels());
194694d499662838123f474f41b31dea84ec5d563f0sergeyv
195694d499662838123f474f41b31dea84ec5d563f0sergeyv    GL_CHECKPOINT(MODERATE);
196694d499662838123f474f41b31dea84ec5d563f0sergeyv
197694d499662838123f474f41b31dea84ec5d563f0sergeyv    // The fence is used to wait for the texture upload to finish
198694d499662838123f474f41b31dea84ec5d563f0sergeyv    // properly. We cannot rely on glFlush() and glFinish() as
199694d499662838123f474f41b31dea84ec5d563f0sergeyv    // some drivers completely ignore these API calls
200694d499662838123f474f41b31dea84ec5d563f0sergeyv    AutoEglFence autoFence(display);
201694d499662838123f474f41b31dea84ec5d563f0sergeyv    if (autoFence.fence == EGL_NO_SYNC_KHR) {
202694d499662838123f474f41b31dea84ec5d563f0sergeyv        LOG_ALWAYS_FATAL("Could not create sync fence %#x", eglGetError());
203694d499662838123f474f41b31dea84ec5d563f0sergeyv        return false;
204694d499662838123f474f41b31dea84ec5d563f0sergeyv    }
205694d499662838123f474f41b31dea84ec5d563f0sergeyv    // The flag EGL_SYNC_FLUSH_COMMANDS_BIT_KHR will trigger a
206694d499662838123f474f41b31dea84ec5d563f0sergeyv    // pipeline flush (similar to what a glFlush() would do.)
207694d499662838123f474f41b31dea84ec5d563f0sergeyv    EGLint waitStatus = eglClientWaitSyncKHR(display, autoFence.fence,
208694d499662838123f474f41b31dea84ec5d563f0sergeyv            EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, FENCE_TIMEOUT);
209694d499662838123f474f41b31dea84ec5d563f0sergeyv    if (waitStatus != EGL_CONDITION_SATISFIED_KHR) {
210694d499662838123f474f41b31dea84ec5d563f0sergeyv        LOG_ALWAYS_FATAL("Failed to wait for the fence %#x", eglGetError());
211694d499662838123f474f41b31dea84ec5d563f0sergeyv        return false;
212694d499662838123f474f41b31dea84ec5d563f0sergeyv    }
213694d499662838123f474f41b31dea84ec5d563f0sergeyv    return true;
214694d499662838123f474f41b31dea84ec5d563f0sergeyv}
215694d499662838123f474f41b31dea84ec5d563f0sergeyv
216694d499662838123f474f41b31dea84ec5d563f0sergeyvsk_sp<Bitmap> Bitmap::allocateHardwareBitmap(uirenderer::renderthread::RenderThread& renderThread,
217694d499662838123f474f41b31dea84ec5d563f0sergeyv        SkBitmap& skBitmap) {
218694d499662838123f474f41b31dea84ec5d563f0sergeyv    renderThread.eglManager().initialize();
219694d499662838123f474f41b31dea84ec5d563f0sergeyv    uirenderer::Caches& caches = uirenderer::Caches::getInstance();
220694d499662838123f474f41b31dea84ec5d563f0sergeyv
221694d499662838123f474f41b31dea84ec5d563f0sergeyv    const SkImageInfo& info = skBitmap.info();
22205126d151eb3caa85bd3a039cffb6e37940c3fa4sergeyv    if (info.colorType() == kUnknown_SkColorType || info.colorType() == kAlpha_8_SkColorType) {
22305126d151eb3caa85bd3a039cffb6e37940c3fa4sergeyv        ALOGW("unable to create hardware bitmap of colortype: %d", info.colorType());
224694d499662838123f474f41b31dea84ec5d563f0sergeyv        return nullptr;
225694d499662838123f474f41b31dea84ec5d563f0sergeyv    }
226694d499662838123f474f41b31dea84ec5d563f0sergeyv
227caaaa66e57293e4a6f312649bf472eab84d5c7feRomain Guy    bool needSRGB = uirenderer::transferFunctionCloseToSRGB(skBitmap.info().colorSpace());
228efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy    bool hasLinearBlending = caches.extensions().hasLinearBlending();
229694d499662838123f474f41b31dea84ec5d563f0sergeyv    GLint format, type, internalFormat;
230694d499662838123f474f41b31dea84ec5d563f0sergeyv    uirenderer::Texture::colorTypeToGlFormatAndType(caches, skBitmap.colorType(),
2317c98f5da3d95ef383de04fb5e941adec4fe1a4cfRomain Guy            needSRGB && hasLinearBlending, &internalFormat, &format, &type);
232694d499662838123f474f41b31dea84ec5d563f0sergeyv
233694d499662838123f474f41b31dea84ec5d563f0sergeyv    PixelFormat pixelFormat = internalFormatToPixelFormat(internalFormat);
2342bd7d98fe844ebd6632a55eee9abf6d18651caf5Mathias Agopian    sp<GraphicBuffer> buffer = new GraphicBuffer(info.width(), info.height(), pixelFormat,
2352bd7d98fe844ebd6632a55eee9abf6d18651caf5Mathias Agopian            GraphicBuffer::USAGE_HW_TEXTURE |
2362bd7d98fe844ebd6632a55eee9abf6d18651caf5Mathias Agopian            GraphicBuffer::USAGE_SW_WRITE_NEVER |
2372bd7d98fe844ebd6632a55eee9abf6d18651caf5Mathias Agopian            GraphicBuffer::USAGE_SW_READ_NEVER,
2382bd7d98fe844ebd6632a55eee9abf6d18651caf5Mathias Agopian            std::string("Bitmap::allocateHardwareBitmap pid [") + std::to_string(getpid()) + "]");
2392bd7d98fe844ebd6632a55eee9abf6d18651caf5Mathias Agopian
2402bd7d98fe844ebd6632a55eee9abf6d18651caf5Mathias Agopian    status_t error = buffer->initCheck();
2412bd7d98fe844ebd6632a55eee9abf6d18651caf5Mathias Agopian    if (error < 0) {
242694d499662838123f474f41b31dea84ec5d563f0sergeyv        ALOGW("createGraphicBuffer() failed in GraphicBuffer.create()");
243694d499662838123f474f41b31dea84ec5d563f0sergeyv        return nullptr;
244694d499662838123f474f41b31dea84ec5d563f0sergeyv    }
245694d499662838123f474f41b31dea84ec5d563f0sergeyv
246694d499662838123f474f41b31dea84ec5d563f0sergeyv    SkBitmap bitmap;
247694d499662838123f474f41b31dea84ec5d563f0sergeyv    if (CC_UNLIKELY(uirenderer::Texture::hasUnsupportedColorType(skBitmap.info(),
248caaaa66e57293e4a6f312649bf472eab84d5c7feRomain Guy            hasLinearBlending))) {
249caaaa66e57293e4a6f312649bf472eab84d5c7feRomain Guy        sk_sp<SkColorSpace> sRGB = SkColorSpace::MakeSRGB();
250efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy        bitmap = uirenderer::Texture::uploadToN32(skBitmap, hasLinearBlending, std::move(sRGB));
251694d499662838123f474f41b31dea84ec5d563f0sergeyv    } else {
252694d499662838123f474f41b31dea84ec5d563f0sergeyv        bitmap = skBitmap;
253694d499662838123f474f41b31dea84ec5d563f0sergeyv    }
254694d499662838123f474f41b31dea84ec5d563f0sergeyv
255694d499662838123f474f41b31dea84ec5d563f0sergeyv    if (!uploadBitmapToGraphicBuffer(caches, bitmap, *buffer, format, type)) {
256694d499662838123f474f41b31dea84ec5d563f0sergeyv        return nullptr;
257694d499662838123f474f41b31dea84ec5d563f0sergeyv    }
25805126d151eb3caa85bd3a039cffb6e37940c3fa4sergeyv    return sk_sp<Bitmap>(new Bitmap(buffer.get(), bitmap.info()));
259694d499662838123f474f41b31dea84ec5d563f0sergeyv}
260694d499662838123f474f41b31dea84ec5d563f0sergeyv
261694d499662838123f474f41b31dea84ec5d563f0sergeyvsk_sp<Bitmap> Bitmap::allocateHardwareBitmap(SkBitmap& bitmap) {
262694d499662838123f474f41b31dea84ec5d563f0sergeyv    return uirenderer::renderthread::RenderProxy::allocateHardwareBitmap(bitmap);
263694d499662838123f474f41b31dea84ec5d563f0sergeyv}
264694d499662838123f474f41b31dea84ec5d563f0sergeyv
265fc9999505a36c66892d7ccce85187936105f4f36sergeyvsk_sp<Bitmap> Bitmap::allocateHeapBitmap(SkBitmap* bitmap, SkColorTable* ctable) {
266fc9999505a36c66892d7ccce85187936105f4f36sergeyv   return allocateBitmap(bitmap, ctable, &android::allocateHeapBitmap);
267fc9999505a36c66892d7ccce85187936105f4f36sergeyv}
268fc9999505a36c66892d7ccce85187936105f4f36sergeyv
269fc9999505a36c66892d7ccce85187936105f4f36sergeyvsk_sp<Bitmap> Bitmap::allocateHeapBitmap(const SkImageInfo& info) {
270fc9999505a36c66892d7ccce85187936105f4f36sergeyv    size_t size;
271fc9999505a36c66892d7ccce85187936105f4f36sergeyv    if (!computeAllocationSize(info.minRowBytes(), info.height(), &size)) {
272fc9999505a36c66892d7ccce85187936105f4f36sergeyv        LOG_ALWAYS_FATAL("trying to allocate too large bitmap");
273fc9999505a36c66892d7ccce85187936105f4f36sergeyv        return nullptr;
274fc9999505a36c66892d7ccce85187936105f4f36sergeyv    }
275fc9999505a36c66892d7ccce85187936105f4f36sergeyv    return android::allocateHeapBitmap(size, info, info.minRowBytes(), nullptr);
276fc9999505a36c66892d7ccce85187936105f4f36sergeyv}
277fc9999505a36c66892d7ccce85187936105f4f36sergeyv
278c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvsk_sp<Bitmap> Bitmap::allocateAshmemBitmap(size_t size, const SkImageInfo& info,
279c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv        size_t rowBytes, SkColorTable* ctable) {
280c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    // Create new ashmem region with read/write priv
281c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    int fd = ashmem_create_region("bitmap", size);
282c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    if (fd < 0) {
283c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv        return nullptr;
284c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    }
285c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv
286c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    void* addr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
287c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    if (addr == MAP_FAILED) {
288c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv        close(fd);
289c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv        return nullptr;
290c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    }
291c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv
292c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    if (ashmem_set_prot_region(fd, PROT_READ) < 0) {
293c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv        munmap(addr, size);
294c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv        close(fd);
295c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv        return nullptr;
296c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv    }
297c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv    return sk_sp<Bitmap>(new Bitmap(addr, fd, size, info, rowBytes, ctable));
298c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv}
299c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv
300aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyvvoid FreePixelRef(void* addr, void* context) {
301aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv    auto pixelRef = (SkPixelRef*) context;
302aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv    pixelRef->unlockPixels();
303aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv    pixelRef->unref();
304aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv}
305aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv
306aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyvsk_sp<Bitmap> Bitmap::createFrom(const SkImageInfo& info, SkPixelRef& pixelRef) {
307aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv    pixelRef.ref();
308aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv    pixelRef.lockPixels();
309aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv    return sk_sp<Bitmap>(new Bitmap((void*) pixelRef.pixels(), (void*) &pixelRef, FreePixelRef,
310aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv            info, pixelRef.rowBytes(), pixelRef.colorTable()));
311aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv}
312aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv
3139a029876422926e313f646f44ab3592cfd4f9933sergeyvsk_sp<Bitmap> Bitmap::createFrom(sp<GraphicBuffer> graphicBuffer) {
3149a029876422926e313f646f44ab3592cfd4f9933sergeyv    PixelFormat format = graphicBuffer->getPixelFormat();
3159505a6552764461c22ce48f1ac13d025d23e1579Romain Guy    if (!graphicBuffer.get() ||
3169505a6552764461c22ce48f1ac13d025d23e1579Romain Guy            (format != PIXEL_FORMAT_RGBA_8888 && format != PIXEL_FORMAT_RGBA_FP16)) {
3179a029876422926e313f646f44ab3592cfd4f9933sergeyv        return nullptr;
3189a029876422926e313f646f44ab3592cfd4f9933sergeyv    }
3199a029876422926e313f646f44ab3592cfd4f9933sergeyv    SkImageInfo info = SkImageInfo::Make(graphicBuffer->getWidth(), graphicBuffer->getHeight(),
320576b6a8a7994f649c0dbacfc34611d1580e16bd6John Reck            kRGBA_8888_SkColorType, kPremul_SkAlphaType,
321576b6a8a7994f649c0dbacfc34611d1580e16bd6John Reck            SkColorSpace::MakeSRGB());
3229a029876422926e313f646f44ab3592cfd4f9933sergeyv    return sk_sp<Bitmap>(new Bitmap(graphicBuffer.get(), info));
3239a029876422926e313f646f44ab3592cfd4f9933sergeyv}
3249a029876422926e313f646f44ab3592cfd4f9933sergeyv
3258242656f495847c50c9ceaea92839dce78218a75Romain Guyvoid Bitmap::setColorSpace(sk_sp<SkColorSpace> colorSpace) {
3268242656f495847c50c9ceaea92839dce78218a75Romain Guy    // TODO: See todo in reconfigure() below
3278242656f495847c50c9ceaea92839dce78218a75Romain Guy    SkImageInfo* myInfo = const_cast<SkImageInfo*>(&this->info());
3288242656f495847c50c9ceaea92839dce78218a75Romain Guy    *myInfo = info().makeColorSpace(std::move(colorSpace));
3298242656f495847c50c9ceaea92839dce78218a75Romain Guy}
3308242656f495847c50c9ceaea92839dce78218a75Romain Guy
331c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvvoid Bitmap::reconfigure(const SkImageInfo& newInfo, size_t rowBytes, SkColorTable* ctable) {
332163f88140e18f13575886e88af0336e0ab1ec846sergeyv    if (kIndex_8_SkColorType != newInfo.colorType()) {
333163f88140e18f13575886e88af0336e0ab1ec846sergeyv        ctable = nullptr;
334163f88140e18f13575886e88af0336e0ab1ec846sergeyv    }
335163f88140e18f13575886e88af0336e0ab1ec846sergeyv    mRowBytes = rowBytes;
336163f88140e18f13575886e88af0336e0ab1ec846sergeyv    if (mColorTable.get() != ctable) {
337003f14256271a6955baacba93e54f09d366f1c3bsergeyv        mColorTable.reset(SkSafeRef(ctable));
338163f88140e18f13575886e88af0336e0ab1ec846sergeyv    }
339163f88140e18f13575886e88af0336e0ab1ec846sergeyv
340163f88140e18f13575886e88af0336e0ab1ec846sergeyv    // Need to validate the alpha type to filter against the color type
341163f88140e18f13575886e88af0336e0ab1ec846sergeyv    // to prevent things like a non-opaque RGB565 bitmap
342163f88140e18f13575886e88af0336e0ab1ec846sergeyv    SkAlphaType alphaType;
343163f88140e18f13575886e88af0336e0ab1ec846sergeyv    LOG_ALWAYS_FATAL_IF(!SkColorTypeValidateAlphaType(
344163f88140e18f13575886e88af0336e0ab1ec846sergeyv            newInfo.colorType(), newInfo.alphaType(), &alphaType),
345163f88140e18f13575886e88af0336e0ab1ec846sergeyv            "Failed to validate alpha type!");
346163f88140e18f13575886e88af0336e0ab1ec846sergeyv
347163f88140e18f13575886e88af0336e0ab1ec846sergeyv    // Dirty hack is dirty
348163f88140e18f13575886e88af0336e0ab1ec846sergeyv    // TODO: Figure something out here, Skia's current design makes this
349163f88140e18f13575886e88af0336e0ab1ec846sergeyv    // really hard to work with. Skia really, really wants immutable objects,
350163f88140e18f13575886e88af0336e0ab1ec846sergeyv    // but with the nested-ref-count hackery going on that's just not
351163f88140e18f13575886e88af0336e0ab1ec846sergeyv    // feasible without going insane trying to figure it out
352163f88140e18f13575886e88af0336e0ab1ec846sergeyv    SkImageInfo* myInfo = const_cast<SkImageInfo*>(&this->info());
353163f88140e18f13575886e88af0336e0ab1ec846sergeyv    *myInfo = newInfo;
354163f88140e18f13575886e88af0336e0ab1ec846sergeyv    changeAlphaType(alphaType);
355163f88140e18f13575886e88af0336e0ab1ec846sergeyv
356163f88140e18f13575886e88af0336e0ab1ec846sergeyv    // Docs say to only call this in the ctor, but we're going to call
357163f88140e18f13575886e88af0336e0ab1ec846sergeyv    // it anyway even if this isn't always the ctor.
358163f88140e18f13575886e88af0336e0ab1ec846sergeyv    // TODO: Fix this too as part of the above TODO
359163f88140e18f13575886e88af0336e0ab1ec846sergeyv    setPreLocked(getStorage(), mRowBytes, mColorTable.get());
360163f88140e18f13575886e88af0336e0ab1ec846sergeyv}
361163f88140e18f13575886e88af0336e0ab1ec846sergeyv
362c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvBitmap::Bitmap(void* address, size_t size, const SkImageInfo& info, size_t rowBytes, SkColorTable* ctable)
363163f88140e18f13575886e88af0336e0ab1ec846sergeyv            : SkPixelRef(info)
364163f88140e18f13575886e88af0336e0ab1ec846sergeyv            , mPixelStorageType(PixelStorageType::Heap) {
365163f88140e18f13575886e88af0336e0ab1ec846sergeyv    mPixelStorage.heap.address = address;
366163f88140e18f13575886e88af0336e0ab1ec846sergeyv    mPixelStorage.heap.size = size;
367163f88140e18f13575886e88af0336e0ab1ec846sergeyv    reconfigure(info, rowBytes, ctable);
368163f88140e18f13575886e88af0336e0ab1ec846sergeyv}
369163f88140e18f13575886e88af0336e0ab1ec846sergeyv
370c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvBitmap::Bitmap(void* address, void* context, FreeFunc freeFunc,
371163f88140e18f13575886e88af0336e0ab1ec846sergeyv                const SkImageInfo& info, size_t rowBytes, SkColorTable* ctable)
372163f88140e18f13575886e88af0336e0ab1ec846sergeyv            : SkPixelRef(info)
373163f88140e18f13575886e88af0336e0ab1ec846sergeyv            , mPixelStorageType(PixelStorageType::External) {
374163f88140e18f13575886e88af0336e0ab1ec846sergeyv    mPixelStorage.external.address = address;
375163f88140e18f13575886e88af0336e0ab1ec846sergeyv    mPixelStorage.external.context = context;
376163f88140e18f13575886e88af0336e0ab1ec846sergeyv    mPixelStorage.external.freeFunc = freeFunc;
377163f88140e18f13575886e88af0336e0ab1ec846sergeyv    reconfigure(info, rowBytes, ctable);
378163f88140e18f13575886e88af0336e0ab1ec846sergeyv}
379163f88140e18f13575886e88af0336e0ab1ec846sergeyv
380c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvBitmap::Bitmap(void* address, int fd, size_t mappedSize,
381163f88140e18f13575886e88af0336e0ab1ec846sergeyv                const SkImageInfo& info, size_t rowBytes, SkColorTable* ctable)
382163f88140e18f13575886e88af0336e0ab1ec846sergeyv            : SkPixelRef(info)
383163f88140e18f13575886e88af0336e0ab1ec846sergeyv            , mPixelStorageType(PixelStorageType::Ashmem) {
384163f88140e18f13575886e88af0336e0ab1ec846sergeyv    mPixelStorage.ashmem.address = address;
385163f88140e18f13575886e88af0336e0ab1ec846sergeyv    mPixelStorage.ashmem.fd = fd;
386163f88140e18f13575886e88af0336e0ab1ec846sergeyv    mPixelStorage.ashmem.size = mappedSize;
387163f88140e18f13575886e88af0336e0ab1ec846sergeyv    reconfigure(info, rowBytes, ctable);
388163f88140e18f13575886e88af0336e0ab1ec846sergeyv}
389163f88140e18f13575886e88af0336e0ab1ec846sergeyv
3909a029876422926e313f646f44ab3592cfd4f9933sergeyvBitmap::Bitmap(GraphicBuffer* buffer, const SkImageInfo& info)
391694d499662838123f474f41b31dea84ec5d563f0sergeyv        : SkPixelRef(info)
392694d499662838123f474f41b31dea84ec5d563f0sergeyv        , mPixelStorageType(PixelStorageType::Hardware) {
3939a029876422926e313f646f44ab3592cfd4f9933sergeyv    mPixelStorage.hardware.buffer = buffer;
3949a029876422926e313f646f44ab3592cfd4f9933sergeyv    buffer->incStrong(buffer);
395694d499662838123f474f41b31dea84ec5d563f0sergeyv    mRowBytes = bytesPerPixel(buffer->getPixelFormat()) * buffer->getStride();
396694d499662838123f474f41b31dea84ec5d563f0sergeyv}
3979a029876422926e313f646f44ab3592cfd4f9933sergeyv
398c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvBitmap::~Bitmap() {
399163f88140e18f13575886e88af0336e0ab1ec846sergeyv    switch (mPixelStorageType) {
400163f88140e18f13575886e88af0336e0ab1ec846sergeyv    case PixelStorageType::External:
401163f88140e18f13575886e88af0336e0ab1ec846sergeyv        mPixelStorage.external.freeFunc(mPixelStorage.external.address,
402163f88140e18f13575886e88af0336e0ab1ec846sergeyv                mPixelStorage.external.context);
403163f88140e18f13575886e88af0336e0ab1ec846sergeyv        break;
404163f88140e18f13575886e88af0336e0ab1ec846sergeyv    case PixelStorageType::Ashmem:
405163f88140e18f13575886e88af0336e0ab1ec846sergeyv        munmap(mPixelStorage.ashmem.address, mPixelStorage.ashmem.size);
406163f88140e18f13575886e88af0336e0ab1ec846sergeyv        close(mPixelStorage.ashmem.fd);
407163f88140e18f13575886e88af0336e0ab1ec846sergeyv        break;
408163f88140e18f13575886e88af0336e0ab1ec846sergeyv    case PixelStorageType::Heap:
409163f88140e18f13575886e88af0336e0ab1ec846sergeyv        free(mPixelStorage.heap.address);
410163f88140e18f13575886e88af0336e0ab1ec846sergeyv        break;
411694d499662838123f474f41b31dea84ec5d563f0sergeyv    case PixelStorageType::Hardware:
412694d499662838123f474f41b31dea84ec5d563f0sergeyv        auto buffer = mPixelStorage.hardware.buffer;
413694d499662838123f474f41b31dea84ec5d563f0sergeyv        buffer->decStrong(buffer);
414694d499662838123f474f41b31dea84ec5d563f0sergeyv        mPixelStorage.hardware.buffer = nullptr;
415694d499662838123f474f41b31dea84ec5d563f0sergeyv        break;
416694d499662838123f474f41b31dea84ec5d563f0sergeyv
417163f88140e18f13575886e88af0336e0ab1ec846sergeyv    }
418163f88140e18f13575886e88af0336e0ab1ec846sergeyv
4199a814875c4e3a98fea99dae623f22268a9afa38aJohn Reck    android::uirenderer::renderthread::RenderProxy::onBitmapDestroyed(getStableID());
420163f88140e18f13575886e88af0336e0ab1ec846sergeyv}
421163f88140e18f13575886e88af0336e0ab1ec846sergeyv
422c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvbool Bitmap::hasHardwareMipMap() const {
423163f88140e18f13575886e88af0336e0ab1ec846sergeyv    return mHasHardwareMipMap;
424163f88140e18f13575886e88af0336e0ab1ec846sergeyv}
425163f88140e18f13575886e88af0336e0ab1ec846sergeyv
426c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvvoid Bitmap::setHasHardwareMipMap(bool hasMipMap) {
427163f88140e18f13575886e88af0336e0ab1ec846sergeyv    mHasHardwareMipMap = hasMipMap;
428163f88140e18f13575886e88af0336e0ab1ec846sergeyv}
429163f88140e18f13575886e88af0336e0ab1ec846sergeyv
430c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvvoid* Bitmap::getStorage() const {
431163f88140e18f13575886e88af0336e0ab1ec846sergeyv    switch (mPixelStorageType) {
432163f88140e18f13575886e88af0336e0ab1ec846sergeyv    case PixelStorageType::External:
433163f88140e18f13575886e88af0336e0ab1ec846sergeyv        return mPixelStorage.external.address;
434163f88140e18f13575886e88af0336e0ab1ec846sergeyv    case PixelStorageType::Ashmem:
435163f88140e18f13575886e88af0336e0ab1ec846sergeyv        return mPixelStorage.ashmem.address;
436163f88140e18f13575886e88af0336e0ab1ec846sergeyv    case PixelStorageType::Heap:
437163f88140e18f13575886e88af0336e0ab1ec846sergeyv        return mPixelStorage.heap.address;
438694d499662838123f474f41b31dea84ec5d563f0sergeyv    case PixelStorageType::Hardware:
439694d499662838123f474f41b31dea84ec5d563f0sergeyv        return nullptr;
440163f88140e18f13575886e88af0336e0ab1ec846sergeyv    }
441163f88140e18f13575886e88af0336e0ab1ec846sergeyv}
442163f88140e18f13575886e88af0336e0ab1ec846sergeyv
443c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvbool Bitmap::onNewLockPixels(LockRec* rec) {
444163f88140e18f13575886e88af0336e0ab1ec846sergeyv    rec->fPixels = getStorage();
445163f88140e18f13575886e88af0336e0ab1ec846sergeyv    rec->fRowBytes = mRowBytes;
446163f88140e18f13575886e88af0336e0ab1ec846sergeyv    rec->fColorTable = mColorTable.get();
447163f88140e18f13575886e88af0336e0ab1ec846sergeyv    return true;
448163f88140e18f13575886e88af0336e0ab1ec846sergeyv}
449163f88140e18f13575886e88af0336e0ab1ec846sergeyv
450c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvsize_t Bitmap::getAllocatedSizeInBytes() const {
451163f88140e18f13575886e88af0336e0ab1ec846sergeyv    return info().getSafeSize(mRowBytes);
452163f88140e18f13575886e88af0336e0ab1ec846sergeyv}
453163f88140e18f13575886e88af0336e0ab1ec846sergeyv
454c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvint Bitmap::getAshmemFd() const {
455163f88140e18f13575886e88af0336e0ab1ec846sergeyv    switch (mPixelStorageType) {
456163f88140e18f13575886e88af0336e0ab1ec846sergeyv    case PixelStorageType::Ashmem:
457163f88140e18f13575886e88af0336e0ab1ec846sergeyv        return mPixelStorage.ashmem.fd;
458163f88140e18f13575886e88af0336e0ab1ec846sergeyv    default:
459163f88140e18f13575886e88af0336e0ab1ec846sergeyv        return -1;
460163f88140e18f13575886e88af0336e0ab1ec846sergeyv    }
461163f88140e18f13575886e88af0336e0ab1ec846sergeyv}
462163f88140e18f13575886e88af0336e0ab1ec846sergeyv
463c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvsize_t Bitmap::getAllocationByteCount() const {
464163f88140e18f13575886e88af0336e0ab1ec846sergeyv    switch (mPixelStorageType) {
465163f88140e18f13575886e88af0336e0ab1ec846sergeyv    case PixelStorageType::Heap:
466163f88140e18f13575886e88af0336e0ab1ec846sergeyv        return mPixelStorage.heap.size;
467163f88140e18f13575886e88af0336e0ab1ec846sergeyv    default:
468163f88140e18f13575886e88af0336e0ab1ec846sergeyv        return rowBytes() * height();
469163f88140e18f13575886e88af0336e0ab1ec846sergeyv    }
470163f88140e18f13575886e88af0336e0ab1ec846sergeyv}
471163f88140e18f13575886e88af0336e0ab1ec846sergeyv
472c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvvoid Bitmap::reconfigure(const SkImageInfo& info) {
473163f88140e18f13575886e88af0336e0ab1ec846sergeyv    reconfigure(info, info.minRowBytes(), nullptr);
474163f88140e18f13575886e88af0336e0ab1ec846sergeyv}
475163f88140e18f13575886e88af0336e0ab1ec846sergeyv
476c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvvoid Bitmap::setAlphaType(SkAlphaType alphaType) {
477163f88140e18f13575886e88af0336e0ab1ec846sergeyv    if (!SkColorTypeValidateAlphaType(info().colorType(), alphaType, &alphaType)) {
478163f88140e18f13575886e88af0336e0ab1ec846sergeyv        return;
479163f88140e18f13575886e88af0336e0ab1ec846sergeyv    }
480163f88140e18f13575886e88af0336e0ab1ec846sergeyv
481163f88140e18f13575886e88af0336e0ab1ec846sergeyv    changeAlphaType(alphaType);
482163f88140e18f13575886e88af0336e0ab1ec846sergeyv}
483163f88140e18f13575886e88af0336e0ab1ec846sergeyv
484c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvvoid Bitmap::getSkBitmap(SkBitmap* outBitmap) {
48559eecb526adc5bd7041e7b6147bfcc40dd2c200esergeyv    outBitmap->setHasHardwareMipMap(mHasHardwareMipMap);
486694d499662838123f474f41b31dea84ec5d563f0sergeyv    if (isHardware()) {
487f5f27cd828084456bbc01520b44688df2b49b4b2Stan Iliev        if (uirenderer::Properties::isSkiaEnabled()) {
488f5f27cd828084456bbc01520b44688df2b49b4b2Stan Iliev            // TODO: add color correctness for Skia pipeline - pass null color space for now
489f5f27cd828084456bbc01520b44688df2b49b4b2Stan Iliev            outBitmap->allocPixels(SkImageInfo::Make(info().width(), info().height(),
490f5f27cd828084456bbc01520b44688df2b49b4b2Stan Iliev                    info().colorType(), info().alphaType(), nullptr));
491f5f27cd828084456bbc01520b44688df2b49b4b2Stan Iliev        } else {
492f5f27cd828084456bbc01520b44688df2b49b4b2Stan Iliev            outBitmap->allocPixels(info());
493f5f27cd828084456bbc01520b44688df2b49b4b2Stan Iliev        }
49459eecb526adc5bd7041e7b6147bfcc40dd2c200esergeyv        uirenderer::renderthread::RenderProxy::copyGraphicBufferInto(graphicBuffer(), outBitmap);
495694d499662838123f474f41b31dea84ec5d563f0sergeyv        return;
496694d499662838123f474f41b31dea84ec5d563f0sergeyv    }
497163f88140e18f13575886e88af0336e0ab1ec846sergeyv    outBitmap->setInfo(info(), rowBytes());
498163f88140e18f13575886e88af0336e0ab1ec846sergeyv    outBitmap->setPixelRef(this);
499163f88140e18f13575886e88af0336e0ab1ec846sergeyv}
500163f88140e18f13575886e88af0336e0ab1ec846sergeyv
501554ffeb8b7c836da43a637c59eedfc617895b19dsergeyvvoid Bitmap::getSkBitmapForShaders(SkBitmap* outBitmap) {
502f5f27cd828084456bbc01520b44688df2b49b4b2Stan Iliev    if (isHardware() && uirenderer::Properties::isSkiaEnabled()) {
503f5f27cd828084456bbc01520b44688df2b49b4b2Stan Iliev        getSkBitmap(outBitmap);
504f5f27cd828084456bbc01520b44688df2b49b4b2Stan Iliev    } else {
505f5f27cd828084456bbc01520b44688df2b49b4b2Stan Iliev        outBitmap->setInfo(info(), rowBytes());
506f5f27cd828084456bbc01520b44688df2b49b4b2Stan Iliev        outBitmap->setPixelRef(this);
507f5f27cd828084456bbc01520b44688df2b49b4b2Stan Iliev        outBitmap->setHasHardwareMipMap(mHasHardwareMipMap);
508f5f27cd828084456bbc01520b44688df2b49b4b2Stan Iliev    }
509554ffeb8b7c836da43a637c59eedfc617895b19dsergeyv}
510554ffeb8b7c836da43a637c59eedfc617895b19dsergeyv
511ec4a4b13eae2241d1613890c1c1c096bed891845sergeyvvoid Bitmap::getBounds(SkRect* bounds) const {
512ec4a4b13eae2241d1613890c1c1c096bed891845sergeyv    SkASSERT(bounds);
513ec4a4b13eae2241d1613890c1c1c096bed891845sergeyv    bounds->set(0, 0, SkIntToScalar(info().width()), SkIntToScalar(info().height()));
514ec4a4b13eae2241d1613890c1c1c096bed891845sergeyv}
515ec4a4b13eae2241d1613890c1c1c096bed891845sergeyv
516694d499662838123f474f41b31dea84ec5d563f0sergeyvGraphicBuffer* Bitmap::graphicBuffer() {
517694d499662838123f474f41b31dea84ec5d563f0sergeyv    if (isHardware()) {
518694d499662838123f474f41b31dea84ec5d563f0sergeyv        return mPixelStorage.hardware.buffer;
519694d499662838123f474f41b31dea84ec5d563f0sergeyv    }
520694d499662838123f474f41b31dea84ec5d563f0sergeyv    return nullptr;
521694d499662838123f474f41b31dea84ec5d563f0sergeyv}
522694d499662838123f474f41b31dea84ec5d563f0sergeyv
523ab12c1fe73734a18ac19a06b97f276528f6d027aMike Reed} // namespace android
524