Bitmap.cpp revision 576b6a8a7994f649c0dbacfc34611d1580e16bd6
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 419163f88140e18f13575886e88af0336e0ab1ec846sergeyv if (android::uirenderer::Caches::hasInstance()) { 420163f88140e18f13575886e88af0336e0ab1ec846sergeyv android::uirenderer::Caches::getInstance().textureCache.releaseTexture(getStableID()); 421163f88140e18f13575886e88af0336e0ab1ec846sergeyv } 422163f88140e18f13575886e88af0336e0ab1ec846sergeyv} 423163f88140e18f13575886e88af0336e0ab1ec846sergeyv 424c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvbool Bitmap::hasHardwareMipMap() const { 425163f88140e18f13575886e88af0336e0ab1ec846sergeyv return mHasHardwareMipMap; 426163f88140e18f13575886e88af0336e0ab1ec846sergeyv} 427163f88140e18f13575886e88af0336e0ab1ec846sergeyv 428c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvvoid Bitmap::setHasHardwareMipMap(bool hasMipMap) { 429163f88140e18f13575886e88af0336e0ab1ec846sergeyv mHasHardwareMipMap = hasMipMap; 430163f88140e18f13575886e88af0336e0ab1ec846sergeyv} 431163f88140e18f13575886e88af0336e0ab1ec846sergeyv 432c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvvoid* Bitmap::getStorage() const { 433163f88140e18f13575886e88af0336e0ab1ec846sergeyv switch (mPixelStorageType) { 434163f88140e18f13575886e88af0336e0ab1ec846sergeyv case PixelStorageType::External: 435163f88140e18f13575886e88af0336e0ab1ec846sergeyv return mPixelStorage.external.address; 436163f88140e18f13575886e88af0336e0ab1ec846sergeyv case PixelStorageType::Ashmem: 437163f88140e18f13575886e88af0336e0ab1ec846sergeyv return mPixelStorage.ashmem.address; 438163f88140e18f13575886e88af0336e0ab1ec846sergeyv case PixelStorageType::Heap: 439163f88140e18f13575886e88af0336e0ab1ec846sergeyv return mPixelStorage.heap.address; 440694d499662838123f474f41b31dea84ec5d563f0sergeyv case PixelStorageType::Hardware: 441694d499662838123f474f41b31dea84ec5d563f0sergeyv return nullptr; 442163f88140e18f13575886e88af0336e0ab1ec846sergeyv } 443163f88140e18f13575886e88af0336e0ab1ec846sergeyv} 444163f88140e18f13575886e88af0336e0ab1ec846sergeyv 445c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvbool Bitmap::onNewLockPixels(LockRec* rec) { 446163f88140e18f13575886e88af0336e0ab1ec846sergeyv rec->fPixels = getStorage(); 447163f88140e18f13575886e88af0336e0ab1ec846sergeyv rec->fRowBytes = mRowBytes; 448163f88140e18f13575886e88af0336e0ab1ec846sergeyv rec->fColorTable = mColorTable.get(); 449163f88140e18f13575886e88af0336e0ab1ec846sergeyv return true; 450163f88140e18f13575886e88af0336e0ab1ec846sergeyv} 451163f88140e18f13575886e88af0336e0ab1ec846sergeyv 452c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvsize_t Bitmap::getAllocatedSizeInBytes() const { 453163f88140e18f13575886e88af0336e0ab1ec846sergeyv return info().getSafeSize(mRowBytes); 454163f88140e18f13575886e88af0336e0ab1ec846sergeyv} 455163f88140e18f13575886e88af0336e0ab1ec846sergeyv 456c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvint Bitmap::getAshmemFd() const { 457163f88140e18f13575886e88af0336e0ab1ec846sergeyv switch (mPixelStorageType) { 458163f88140e18f13575886e88af0336e0ab1ec846sergeyv case PixelStorageType::Ashmem: 459163f88140e18f13575886e88af0336e0ab1ec846sergeyv return mPixelStorage.ashmem.fd; 460163f88140e18f13575886e88af0336e0ab1ec846sergeyv default: 461163f88140e18f13575886e88af0336e0ab1ec846sergeyv return -1; 462163f88140e18f13575886e88af0336e0ab1ec846sergeyv } 463163f88140e18f13575886e88af0336e0ab1ec846sergeyv} 464163f88140e18f13575886e88af0336e0ab1ec846sergeyv 465c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvsize_t Bitmap::getAllocationByteCount() const { 466163f88140e18f13575886e88af0336e0ab1ec846sergeyv switch (mPixelStorageType) { 467163f88140e18f13575886e88af0336e0ab1ec846sergeyv case PixelStorageType::Heap: 468163f88140e18f13575886e88af0336e0ab1ec846sergeyv return mPixelStorage.heap.size; 469163f88140e18f13575886e88af0336e0ab1ec846sergeyv default: 470163f88140e18f13575886e88af0336e0ab1ec846sergeyv return rowBytes() * height(); 471163f88140e18f13575886e88af0336e0ab1ec846sergeyv } 472163f88140e18f13575886e88af0336e0ab1ec846sergeyv} 473163f88140e18f13575886e88af0336e0ab1ec846sergeyv 474c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvvoid Bitmap::reconfigure(const SkImageInfo& info) { 475163f88140e18f13575886e88af0336e0ab1ec846sergeyv reconfigure(info, info.minRowBytes(), nullptr); 476163f88140e18f13575886e88af0336e0ab1ec846sergeyv} 477163f88140e18f13575886e88af0336e0ab1ec846sergeyv 478c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvvoid Bitmap::setAlphaType(SkAlphaType alphaType) { 479163f88140e18f13575886e88af0336e0ab1ec846sergeyv if (!SkColorTypeValidateAlphaType(info().colorType(), alphaType, &alphaType)) { 480163f88140e18f13575886e88af0336e0ab1ec846sergeyv return; 481163f88140e18f13575886e88af0336e0ab1ec846sergeyv } 482163f88140e18f13575886e88af0336e0ab1ec846sergeyv 483163f88140e18f13575886e88af0336e0ab1ec846sergeyv changeAlphaType(alphaType); 484163f88140e18f13575886e88af0336e0ab1ec846sergeyv} 485163f88140e18f13575886e88af0336e0ab1ec846sergeyv 486c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvvoid Bitmap::getSkBitmap(SkBitmap* outBitmap) { 48759eecb526adc5bd7041e7b6147bfcc40dd2c200esergeyv outBitmap->setHasHardwareMipMap(mHasHardwareMipMap); 488694d499662838123f474f41b31dea84ec5d563f0sergeyv if (isHardware()) { 489576b6a8a7994f649c0dbacfc34611d1580e16bd6John Reck outBitmap->allocPixels(info()); 49059eecb526adc5bd7041e7b6147bfcc40dd2c200esergeyv uirenderer::renderthread::RenderProxy::copyGraphicBufferInto(graphicBuffer(), outBitmap); 491694d499662838123f474f41b31dea84ec5d563f0sergeyv return; 492694d499662838123f474f41b31dea84ec5d563f0sergeyv } 493163f88140e18f13575886e88af0336e0ab1ec846sergeyv outBitmap->setInfo(info(), rowBytes()); 494163f88140e18f13575886e88af0336e0ab1ec846sergeyv outBitmap->setPixelRef(this); 495163f88140e18f13575886e88af0336e0ab1ec846sergeyv} 496163f88140e18f13575886e88af0336e0ab1ec846sergeyv 497554ffeb8b7c836da43a637c59eedfc617895b19dsergeyvvoid Bitmap::getSkBitmapForShaders(SkBitmap* outBitmap) { 498554ffeb8b7c836da43a637c59eedfc617895b19dsergeyv outBitmap->setInfo(info(), rowBytes()); 499554ffeb8b7c836da43a637c59eedfc617895b19dsergeyv outBitmap->setPixelRef(this); 500554ffeb8b7c836da43a637c59eedfc617895b19dsergeyv outBitmap->setHasHardwareMipMap(mHasHardwareMipMap); 501554ffeb8b7c836da43a637c59eedfc617895b19dsergeyv} 502554ffeb8b7c836da43a637c59eedfc617895b19dsergeyv 503ec4a4b13eae2241d1613890c1c1c096bed891845sergeyvvoid Bitmap::getBounds(SkRect* bounds) const { 504ec4a4b13eae2241d1613890c1c1c096bed891845sergeyv SkASSERT(bounds); 505ec4a4b13eae2241d1613890c1c1c096bed891845sergeyv bounds->set(0, 0, SkIntToScalar(info().width()), SkIntToScalar(info().height())); 506ec4a4b13eae2241d1613890c1c1c096bed891845sergeyv} 507ec4a4b13eae2241d1613890c1c1c096bed891845sergeyv 508694d499662838123f474f41b31dea84ec5d563f0sergeyvGraphicBuffer* Bitmap::graphicBuffer() { 509694d499662838123f474f41b31dea84ec5d563f0sergeyv if (isHardware()) { 510694d499662838123f474f41b31dea84ec5d563f0sergeyv return mPixelStorage.hardware.buffer; 511694d499662838123f474f41b31dea84ec5d563f0sergeyv } 512694d499662838123f474f41b31dea84ec5d563f0sergeyv return nullptr; 513694d499662838123f474f41b31dea84ec5d563f0sergeyv} 514694d499662838123f474f41b31dea84ec5d563f0sergeyv 515ab12c1fe73734a18ac19a06b97f276528f6d027aMike Reed} // namespace android 516