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