Bitmap.cpp revision 6f773a0d8717162f81ff21d943baaa539a2d6c7e
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 <sys/mman.h> 246f773a0d8717162f81ff21d943baaa539a2d6c7eMark Salyzyn 256f773a0d8717162f81ff21d943baaa539a2d6c7eMark Salyzyn#include <log/log.h> 26163f88140e18f13575886e88af0336e0ab1ec846sergeyv#include <cutils/ashmem.h> 27163f88140e18f13575886e88af0336e0ab1ec846sergeyv 28694d499662838123f474f41b31dea84ec5d563f0sergeyv#include <GLES2/gl2.h> 29694d499662838123f474f41b31dea84ec5d563f0sergeyv#include <GLES2/gl2ext.h> 30694d499662838123f474f41b31dea84ec5d563f0sergeyv#include <EGL/egl.h> 31694d499662838123f474f41b31dea84ec5d563f0sergeyv#include <EGL/eglext.h> 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; 1099505a6552764461c22ce48f1ac13d025d23e1579Romain Guy case GL_RGBA16F: 1109505a6552764461c22ce48f1ac13d025d23e1579Romain Guy return PIXEL_FORMAT_RGBA_FP16; 111694d499662838123f474f41b31dea84ec5d563f0sergeyv default: 112694d499662838123f474f41b31dea84ec5d563f0sergeyv LOG_ALWAYS_FATAL("Unsupported bitmap colorType: %d", internalFormat); 113694d499662838123f474f41b31dea84ec5d563f0sergeyv return PIXEL_FORMAT_UNKNOWN; 114694d499662838123f474f41b31dea84ec5d563f0sergeyv } 115694d499662838123f474f41b31dea84ec5d563f0sergeyv} 116694d499662838123f474f41b31dea84ec5d563f0sergeyv 117694d499662838123f474f41b31dea84ec5d563f0sergeyvclass AutoEglFence { 118694d499662838123f474f41b31dea84ec5d563f0sergeyvpublic: 119694d499662838123f474f41b31dea84ec5d563f0sergeyv AutoEglFence(EGLDisplay display) 120694d499662838123f474f41b31dea84ec5d563f0sergeyv : mDisplay(display) { 121694d499662838123f474f41b31dea84ec5d563f0sergeyv fence = eglCreateSyncKHR(mDisplay, EGL_SYNC_FENCE_KHR, NULL); 122694d499662838123f474f41b31dea84ec5d563f0sergeyv } 123694d499662838123f474f41b31dea84ec5d563f0sergeyv 124694d499662838123f474f41b31dea84ec5d563f0sergeyv ~AutoEglFence() { 125694d499662838123f474f41b31dea84ec5d563f0sergeyv if (fence != EGL_NO_SYNC_KHR) { 126694d499662838123f474f41b31dea84ec5d563f0sergeyv eglDestroySyncKHR(mDisplay, fence); 127694d499662838123f474f41b31dea84ec5d563f0sergeyv } 128694d499662838123f474f41b31dea84ec5d563f0sergeyv } 129694d499662838123f474f41b31dea84ec5d563f0sergeyv 130694d499662838123f474f41b31dea84ec5d563f0sergeyv EGLSyncKHR fence = EGL_NO_SYNC_KHR; 131694d499662838123f474f41b31dea84ec5d563f0sergeyvprivate: 132694d499662838123f474f41b31dea84ec5d563f0sergeyv EGLDisplay mDisplay = EGL_NO_DISPLAY; 133694d499662838123f474f41b31dea84ec5d563f0sergeyv}; 134694d499662838123f474f41b31dea84ec5d563f0sergeyv 135694d499662838123f474f41b31dea84ec5d563f0sergeyvclass AutoEglImage { 136694d499662838123f474f41b31dea84ec5d563f0sergeyvpublic: 137694d499662838123f474f41b31dea84ec5d563f0sergeyv AutoEglImage(EGLDisplay display, EGLClientBuffer clientBuffer) 138694d499662838123f474f41b31dea84ec5d563f0sergeyv : mDisplay(display) { 139694d499662838123f474f41b31dea84ec5d563f0sergeyv EGLint imageAttrs[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE }; 140694d499662838123f474f41b31dea84ec5d563f0sergeyv image = eglCreateImageKHR(display, EGL_NO_CONTEXT, 141694d499662838123f474f41b31dea84ec5d563f0sergeyv EGL_NATIVE_BUFFER_ANDROID, clientBuffer, imageAttrs); 142694d499662838123f474f41b31dea84ec5d563f0sergeyv } 143694d499662838123f474f41b31dea84ec5d563f0sergeyv 144694d499662838123f474f41b31dea84ec5d563f0sergeyv ~AutoEglImage() { 145694d499662838123f474f41b31dea84ec5d563f0sergeyv if (image != EGL_NO_IMAGE_KHR) { 146694d499662838123f474f41b31dea84ec5d563f0sergeyv eglDestroyImageKHR(mDisplay, image); 147694d499662838123f474f41b31dea84ec5d563f0sergeyv } 148694d499662838123f474f41b31dea84ec5d563f0sergeyv } 149694d499662838123f474f41b31dea84ec5d563f0sergeyv 150694d499662838123f474f41b31dea84ec5d563f0sergeyv EGLImageKHR image = EGL_NO_IMAGE_KHR; 151694d499662838123f474f41b31dea84ec5d563f0sergeyvprivate: 152694d499662838123f474f41b31dea84ec5d563f0sergeyv EGLDisplay mDisplay = EGL_NO_DISPLAY; 153694d499662838123f474f41b31dea84ec5d563f0sergeyv}; 154694d499662838123f474f41b31dea84ec5d563f0sergeyv 155694d499662838123f474f41b31dea84ec5d563f0sergeyvstatic bool uploadBitmapToGraphicBuffer(uirenderer::Caches& caches, SkBitmap& bitmap, 156694d499662838123f474f41b31dea84ec5d563f0sergeyv GraphicBuffer& buffer, GLint format, GLint type) { 157694d499662838123f474f41b31dea84ec5d563f0sergeyv SkAutoLockPixels alp(bitmap); 158694d499662838123f474f41b31dea84ec5d563f0sergeyv EGLDisplay display = eglGetCurrentDisplay(); 159694d499662838123f474f41b31dea84ec5d563f0sergeyv LOG_ALWAYS_FATAL_IF(display == EGL_NO_DISPLAY, 160694d499662838123f474f41b31dea84ec5d563f0sergeyv "Failed to get EGL_DEFAULT_DISPLAY! err=%s", 161694d499662838123f474f41b31dea84ec5d563f0sergeyv uirenderer::renderthread::EglManager::eglErrorString()); 162694d499662838123f474f41b31dea84ec5d563f0sergeyv // These objects are initialized below but the default "null" 163694d499662838123f474f41b31dea84ec5d563f0sergeyv // values are used to cleanup properly at any point in the 164694d499662838123f474f41b31dea84ec5d563f0sergeyv // initialization sequenc 165694d499662838123f474f41b31dea84ec5d563f0sergeyv GLuint texture = 0; 166694d499662838123f474f41b31dea84ec5d563f0sergeyv // We use an EGLImage to access the content of the GraphicBuffer 167694d499662838123f474f41b31dea84ec5d563f0sergeyv // The EGL image is later bound to a 2D texture 168694d499662838123f474f41b31dea84ec5d563f0sergeyv EGLClientBuffer clientBuffer = (EGLClientBuffer) buffer.getNativeBuffer(); 169694d499662838123f474f41b31dea84ec5d563f0sergeyv AutoEglImage autoImage(display, clientBuffer); 170694d499662838123f474f41b31dea84ec5d563f0sergeyv if (autoImage.image == EGL_NO_IMAGE_KHR) { 171694d499662838123f474f41b31dea84ec5d563f0sergeyv ALOGW("Could not create EGL image, err =%s", 172694d499662838123f474f41b31dea84ec5d563f0sergeyv uirenderer::renderthread::EglManager::eglErrorString()); 173694d499662838123f474f41b31dea84ec5d563f0sergeyv return false; 174694d499662838123f474f41b31dea84ec5d563f0sergeyv } 175694d499662838123f474f41b31dea84ec5d563f0sergeyv glGenTextures(1, &texture); 176694d499662838123f474f41b31dea84ec5d563f0sergeyv caches.textureState().bindTexture(texture); 177694d499662838123f474f41b31dea84ec5d563f0sergeyv glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, autoImage.image); 178694d499662838123f474f41b31dea84ec5d563f0sergeyv 179694d499662838123f474f41b31dea84ec5d563f0sergeyv GL_CHECKPOINT(MODERATE); 180694d499662838123f474f41b31dea84ec5d563f0sergeyv 181694d499662838123f474f41b31dea84ec5d563f0sergeyv glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, bitmap.width(), bitmap.height(), 182694d499662838123f474f41b31dea84ec5d563f0sergeyv format, type, bitmap.getPixels()); 183694d499662838123f474f41b31dea84ec5d563f0sergeyv 184694d499662838123f474f41b31dea84ec5d563f0sergeyv GL_CHECKPOINT(MODERATE); 185694d499662838123f474f41b31dea84ec5d563f0sergeyv 186694d499662838123f474f41b31dea84ec5d563f0sergeyv // The fence is used to wait for the texture upload to finish 187694d499662838123f474f41b31dea84ec5d563f0sergeyv // properly. We cannot rely on glFlush() and glFinish() as 188694d499662838123f474f41b31dea84ec5d563f0sergeyv // some drivers completely ignore these API calls 189694d499662838123f474f41b31dea84ec5d563f0sergeyv AutoEglFence autoFence(display); 190694d499662838123f474f41b31dea84ec5d563f0sergeyv if (autoFence.fence == EGL_NO_SYNC_KHR) { 191694d499662838123f474f41b31dea84ec5d563f0sergeyv LOG_ALWAYS_FATAL("Could not create sync fence %#x", eglGetError()); 192694d499662838123f474f41b31dea84ec5d563f0sergeyv return false; 193694d499662838123f474f41b31dea84ec5d563f0sergeyv } 194694d499662838123f474f41b31dea84ec5d563f0sergeyv // The flag EGL_SYNC_FLUSH_COMMANDS_BIT_KHR will trigger a 195694d499662838123f474f41b31dea84ec5d563f0sergeyv // pipeline flush (similar to what a glFlush() would do.) 196694d499662838123f474f41b31dea84ec5d563f0sergeyv EGLint waitStatus = eglClientWaitSyncKHR(display, autoFence.fence, 197694d499662838123f474f41b31dea84ec5d563f0sergeyv EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, FENCE_TIMEOUT); 198694d499662838123f474f41b31dea84ec5d563f0sergeyv if (waitStatus != EGL_CONDITION_SATISFIED_KHR) { 199694d499662838123f474f41b31dea84ec5d563f0sergeyv LOG_ALWAYS_FATAL("Failed to wait for the fence %#x", eglGetError()); 200694d499662838123f474f41b31dea84ec5d563f0sergeyv return false; 201694d499662838123f474f41b31dea84ec5d563f0sergeyv } 202694d499662838123f474f41b31dea84ec5d563f0sergeyv return true; 203694d499662838123f474f41b31dea84ec5d563f0sergeyv} 204694d499662838123f474f41b31dea84ec5d563f0sergeyv 205694d499662838123f474f41b31dea84ec5d563f0sergeyvsk_sp<Bitmap> Bitmap::allocateHardwareBitmap(uirenderer::renderthread::RenderThread& renderThread, 206694d499662838123f474f41b31dea84ec5d563f0sergeyv SkBitmap& skBitmap) { 207694d499662838123f474f41b31dea84ec5d563f0sergeyv renderThread.eglManager().initialize(); 208694d499662838123f474f41b31dea84ec5d563f0sergeyv uirenderer::Caches& caches = uirenderer::Caches::getInstance(); 209694d499662838123f474f41b31dea84ec5d563f0sergeyv 210694d499662838123f474f41b31dea84ec5d563f0sergeyv sp<ISurfaceComposer> composer(ComposerService::getComposerService()); 211694d499662838123f474f41b31dea84ec5d563f0sergeyv sp<IGraphicBufferAlloc> alloc(composer->createGraphicBufferAlloc()); 212694d499662838123f474f41b31dea84ec5d563f0sergeyv if (alloc == NULL) { 213694d499662838123f474f41b31dea84ec5d563f0sergeyv ALOGW("createGraphicBufferAlloc() failed in GraphicBuffer.create()"); 214694d499662838123f474f41b31dea84ec5d563f0sergeyv return nullptr; 215694d499662838123f474f41b31dea84ec5d563f0sergeyv } 216694d499662838123f474f41b31dea84ec5d563f0sergeyv 217694d499662838123f474f41b31dea84ec5d563f0sergeyv const SkImageInfo& info = skBitmap.info(); 21805126d151eb3caa85bd3a039cffb6e37940c3fa4sergeyv if (info.colorType() == kUnknown_SkColorType || info.colorType() == kAlpha_8_SkColorType) { 21905126d151eb3caa85bd3a039cffb6e37940c3fa4sergeyv ALOGW("unable to create hardware bitmap of colortype: %d", info.colorType()); 220694d499662838123f474f41b31dea84ec5d563f0sergeyv return nullptr; 221694d499662838123f474f41b31dea84ec5d563f0sergeyv } 222694d499662838123f474f41b31dea84ec5d563f0sergeyv 223ab12c1fe73734a18ac19a06b97f276528f6d027aMike Reed sk_sp<SkColorSpace> sRGB = SkColorSpace::MakeNamed(SkColorSpace::kSRGB_Named); 224694d499662838123f474f41b31dea84ec5d563f0sergeyv bool needSRGB = skBitmap.info().colorSpace() == sRGB.get(); 225694d499662838123f474f41b31dea84ec5d563f0sergeyv bool hasSRGB = caches.extensions().hasSRGB(); 226694d499662838123f474f41b31dea84ec5d563f0sergeyv GLint format, type, internalFormat; 227694d499662838123f474f41b31dea84ec5d563f0sergeyv uirenderer::Texture::colorTypeToGlFormatAndType(caches, skBitmap.colorType(), 228694d499662838123f474f41b31dea84ec5d563f0sergeyv needSRGB, &internalFormat, &format, &type); 229694d499662838123f474f41b31dea84ec5d563f0sergeyv 230694d499662838123f474f41b31dea84ec5d563f0sergeyv PixelFormat pixelFormat = internalFormatToPixelFormat(internalFormat); 231694d499662838123f474f41b31dea84ec5d563f0sergeyv status_t error; 232694d499662838123f474f41b31dea84ec5d563f0sergeyv sp<GraphicBuffer> buffer = alloc->createGraphicBuffer(info.width(), info.height(), pixelFormat, 233850054cb46b25e20c1ae0b409734c0fa5c634b18Craig Donner 1, GraphicBuffer::USAGE_HW_TEXTURE | GraphicBuffer::USAGE_SW_WRITE_NEVER 234694d499662838123f474f41b31dea84ec5d563f0sergeyv | GraphicBuffer::USAGE_SW_READ_NEVER , &error); 235694d499662838123f474f41b31dea84ec5d563f0sergeyv 236694d499662838123f474f41b31dea84ec5d563f0sergeyv if (!buffer.get()) { 237694d499662838123f474f41b31dea84ec5d563f0sergeyv ALOGW("createGraphicBuffer() failed in GraphicBuffer.create()"); 238694d499662838123f474f41b31dea84ec5d563f0sergeyv return nullptr; 239694d499662838123f474f41b31dea84ec5d563f0sergeyv } 240694d499662838123f474f41b31dea84ec5d563f0sergeyv 241694d499662838123f474f41b31dea84ec5d563f0sergeyv SkBitmap bitmap; 242694d499662838123f474f41b31dea84ec5d563f0sergeyv if (CC_UNLIKELY(uirenderer::Texture::hasUnsupportedColorType(skBitmap.info(), 243694d499662838123f474f41b31dea84ec5d563f0sergeyv hasSRGB, sRGB.get()))) { 244694d499662838123f474f41b31dea84ec5d563f0sergeyv bitmap = uirenderer::Texture::uploadToN32(skBitmap, hasSRGB, std::move(sRGB)); 245694d499662838123f474f41b31dea84ec5d563f0sergeyv } else { 246694d499662838123f474f41b31dea84ec5d563f0sergeyv bitmap = skBitmap; 247694d499662838123f474f41b31dea84ec5d563f0sergeyv } 248694d499662838123f474f41b31dea84ec5d563f0sergeyv 249694d499662838123f474f41b31dea84ec5d563f0sergeyv if (!uploadBitmapToGraphicBuffer(caches, bitmap, *buffer, format, type)) { 250694d499662838123f474f41b31dea84ec5d563f0sergeyv return nullptr; 251694d499662838123f474f41b31dea84ec5d563f0sergeyv } 25205126d151eb3caa85bd3a039cffb6e37940c3fa4sergeyv return sk_sp<Bitmap>(new Bitmap(buffer.get(), bitmap.info())); 253694d499662838123f474f41b31dea84ec5d563f0sergeyv} 254694d499662838123f474f41b31dea84ec5d563f0sergeyv 255694d499662838123f474f41b31dea84ec5d563f0sergeyvsk_sp<Bitmap> Bitmap::allocateHardwareBitmap(SkBitmap& bitmap) { 256694d499662838123f474f41b31dea84ec5d563f0sergeyv return uirenderer::renderthread::RenderProxy::allocateHardwareBitmap(bitmap); 257694d499662838123f474f41b31dea84ec5d563f0sergeyv} 258694d499662838123f474f41b31dea84ec5d563f0sergeyv 259fc9999505a36c66892d7ccce85187936105f4f36sergeyvsk_sp<Bitmap> Bitmap::allocateHeapBitmap(SkBitmap* bitmap, SkColorTable* ctable) { 260fc9999505a36c66892d7ccce85187936105f4f36sergeyv return allocateBitmap(bitmap, ctable, &android::allocateHeapBitmap); 261fc9999505a36c66892d7ccce85187936105f4f36sergeyv} 262fc9999505a36c66892d7ccce85187936105f4f36sergeyv 263fc9999505a36c66892d7ccce85187936105f4f36sergeyvsk_sp<Bitmap> Bitmap::allocateHeapBitmap(const SkImageInfo& info) { 264fc9999505a36c66892d7ccce85187936105f4f36sergeyv size_t size; 265fc9999505a36c66892d7ccce85187936105f4f36sergeyv if (!computeAllocationSize(info.minRowBytes(), info.height(), &size)) { 266fc9999505a36c66892d7ccce85187936105f4f36sergeyv LOG_ALWAYS_FATAL("trying to allocate too large bitmap"); 267fc9999505a36c66892d7ccce85187936105f4f36sergeyv return nullptr; 268fc9999505a36c66892d7ccce85187936105f4f36sergeyv } 269fc9999505a36c66892d7ccce85187936105f4f36sergeyv return android::allocateHeapBitmap(size, info, info.minRowBytes(), nullptr); 270fc9999505a36c66892d7ccce85187936105f4f36sergeyv} 271fc9999505a36c66892d7ccce85187936105f4f36sergeyv 272c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvsk_sp<Bitmap> Bitmap::allocateAshmemBitmap(size_t size, const SkImageInfo& info, 273c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv size_t rowBytes, SkColorTable* ctable) { 274c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv // Create new ashmem region with read/write priv 275c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv int fd = ashmem_create_region("bitmap", size); 276c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv if (fd < 0) { 277c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv return nullptr; 278c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv } 279c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv 280c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv void* addr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 281c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv if (addr == MAP_FAILED) { 282c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv close(fd); 283c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv return nullptr; 284c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv } 285c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv 286c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv if (ashmem_set_prot_region(fd, PROT_READ) < 0) { 287c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv munmap(addr, size); 288c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv close(fd); 289c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv return nullptr; 290c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv } 291c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv return sk_sp<Bitmap>(new Bitmap(addr, fd, size, info, rowBytes, ctable)); 292c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv} 293c36bd6c16ddfc160732ff7e4518564714c8aa66esergeyv 294aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyvvoid FreePixelRef(void* addr, void* context) { 295aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv auto pixelRef = (SkPixelRef*) context; 296aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv pixelRef->unlockPixels(); 297aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv pixelRef->unref(); 298aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv} 299aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv 300aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyvsk_sp<Bitmap> Bitmap::createFrom(const SkImageInfo& info, SkPixelRef& pixelRef) { 301aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv pixelRef.ref(); 302aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv pixelRef.lockPixels(); 303aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv return sk_sp<Bitmap>(new Bitmap((void*) pixelRef.pixels(), (void*) &pixelRef, FreePixelRef, 304aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv info, pixelRef.rowBytes(), pixelRef.colorTable())); 305aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv} 306aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv 3079a029876422926e313f646f44ab3592cfd4f9933sergeyvsk_sp<Bitmap> Bitmap::createFrom(sp<GraphicBuffer> graphicBuffer) { 3089a029876422926e313f646f44ab3592cfd4f9933sergeyv PixelFormat format = graphicBuffer->getPixelFormat(); 3099505a6552764461c22ce48f1ac13d025d23e1579Romain Guy if (!graphicBuffer.get() || 3109505a6552764461c22ce48f1ac13d025d23e1579Romain Guy (format != PIXEL_FORMAT_RGBA_8888 && format != PIXEL_FORMAT_RGBA_FP16)) { 3119a029876422926e313f646f44ab3592cfd4f9933sergeyv return nullptr; 3129a029876422926e313f646f44ab3592cfd4f9933sergeyv } 3139a029876422926e313f646f44ab3592cfd4f9933sergeyv SkImageInfo info = SkImageInfo::Make(graphicBuffer->getWidth(), graphicBuffer->getHeight(), 31405126d151eb3caa85bd3a039cffb6e37940c3fa4sergeyv kRGBA_8888_SkColorType, kPremul_SkAlphaType, 31505126d151eb3caa85bd3a039cffb6e37940c3fa4sergeyv SkColorSpace::MakeNamed(SkColorSpace::kSRGB_Named)); 3169a029876422926e313f646f44ab3592cfd4f9933sergeyv return sk_sp<Bitmap>(new Bitmap(graphicBuffer.get(), info)); 3179a029876422926e313f646f44ab3592cfd4f9933sergeyv} 3189a029876422926e313f646f44ab3592cfd4f9933sergeyv 319c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvvoid Bitmap::reconfigure(const SkImageInfo& newInfo, size_t rowBytes, SkColorTable* ctable) { 320163f88140e18f13575886e88af0336e0ab1ec846sergeyv if (kIndex_8_SkColorType != newInfo.colorType()) { 321163f88140e18f13575886e88af0336e0ab1ec846sergeyv ctable = nullptr; 322163f88140e18f13575886e88af0336e0ab1ec846sergeyv } 323163f88140e18f13575886e88af0336e0ab1ec846sergeyv mRowBytes = rowBytes; 324163f88140e18f13575886e88af0336e0ab1ec846sergeyv if (mColorTable.get() != ctable) { 325003f14256271a6955baacba93e54f09d366f1c3bsergeyv mColorTable.reset(SkSafeRef(ctable)); 326163f88140e18f13575886e88af0336e0ab1ec846sergeyv } 327163f88140e18f13575886e88af0336e0ab1ec846sergeyv 328163f88140e18f13575886e88af0336e0ab1ec846sergeyv // Need to validate the alpha type to filter against the color type 329163f88140e18f13575886e88af0336e0ab1ec846sergeyv // to prevent things like a non-opaque RGB565 bitmap 330163f88140e18f13575886e88af0336e0ab1ec846sergeyv SkAlphaType alphaType; 331163f88140e18f13575886e88af0336e0ab1ec846sergeyv LOG_ALWAYS_FATAL_IF(!SkColorTypeValidateAlphaType( 332163f88140e18f13575886e88af0336e0ab1ec846sergeyv newInfo.colorType(), newInfo.alphaType(), &alphaType), 333163f88140e18f13575886e88af0336e0ab1ec846sergeyv "Failed to validate alpha type!"); 334163f88140e18f13575886e88af0336e0ab1ec846sergeyv 335163f88140e18f13575886e88af0336e0ab1ec846sergeyv // Dirty hack is dirty 336163f88140e18f13575886e88af0336e0ab1ec846sergeyv // TODO: Figure something out here, Skia's current design makes this 337163f88140e18f13575886e88af0336e0ab1ec846sergeyv // really hard to work with. Skia really, really wants immutable objects, 338163f88140e18f13575886e88af0336e0ab1ec846sergeyv // but with the nested-ref-count hackery going on that's just not 339163f88140e18f13575886e88af0336e0ab1ec846sergeyv // feasible without going insane trying to figure it out 340163f88140e18f13575886e88af0336e0ab1ec846sergeyv SkImageInfo* myInfo = const_cast<SkImageInfo*>(&this->info()); 341163f88140e18f13575886e88af0336e0ab1ec846sergeyv *myInfo = newInfo; 342163f88140e18f13575886e88af0336e0ab1ec846sergeyv changeAlphaType(alphaType); 343163f88140e18f13575886e88af0336e0ab1ec846sergeyv 344163f88140e18f13575886e88af0336e0ab1ec846sergeyv // Docs say to only call this in the ctor, but we're going to call 345163f88140e18f13575886e88af0336e0ab1ec846sergeyv // it anyway even if this isn't always the ctor. 346163f88140e18f13575886e88af0336e0ab1ec846sergeyv // TODO: Fix this too as part of the above TODO 347163f88140e18f13575886e88af0336e0ab1ec846sergeyv setPreLocked(getStorage(), mRowBytes, mColorTable.get()); 348163f88140e18f13575886e88af0336e0ab1ec846sergeyv} 349163f88140e18f13575886e88af0336e0ab1ec846sergeyv 350c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvBitmap::Bitmap(void* address, size_t size, const SkImageInfo& info, size_t rowBytes, SkColorTable* ctable) 351163f88140e18f13575886e88af0336e0ab1ec846sergeyv : SkPixelRef(info) 352163f88140e18f13575886e88af0336e0ab1ec846sergeyv , mPixelStorageType(PixelStorageType::Heap) { 353163f88140e18f13575886e88af0336e0ab1ec846sergeyv mPixelStorage.heap.address = address; 354163f88140e18f13575886e88af0336e0ab1ec846sergeyv mPixelStorage.heap.size = size; 355163f88140e18f13575886e88af0336e0ab1ec846sergeyv reconfigure(info, rowBytes, ctable); 356163f88140e18f13575886e88af0336e0ab1ec846sergeyv} 357163f88140e18f13575886e88af0336e0ab1ec846sergeyv 358c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvBitmap::Bitmap(void* address, void* context, FreeFunc freeFunc, 359163f88140e18f13575886e88af0336e0ab1ec846sergeyv const SkImageInfo& info, size_t rowBytes, SkColorTable* ctable) 360163f88140e18f13575886e88af0336e0ab1ec846sergeyv : SkPixelRef(info) 361163f88140e18f13575886e88af0336e0ab1ec846sergeyv , mPixelStorageType(PixelStorageType::External) { 362163f88140e18f13575886e88af0336e0ab1ec846sergeyv mPixelStorage.external.address = address; 363163f88140e18f13575886e88af0336e0ab1ec846sergeyv mPixelStorage.external.context = context; 364163f88140e18f13575886e88af0336e0ab1ec846sergeyv mPixelStorage.external.freeFunc = freeFunc; 365163f88140e18f13575886e88af0336e0ab1ec846sergeyv reconfigure(info, rowBytes, ctable); 366163f88140e18f13575886e88af0336e0ab1ec846sergeyv} 367163f88140e18f13575886e88af0336e0ab1ec846sergeyv 368c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvBitmap::Bitmap(void* address, int fd, size_t mappedSize, 369163f88140e18f13575886e88af0336e0ab1ec846sergeyv const SkImageInfo& info, size_t rowBytes, SkColorTable* ctable) 370163f88140e18f13575886e88af0336e0ab1ec846sergeyv : SkPixelRef(info) 371163f88140e18f13575886e88af0336e0ab1ec846sergeyv , mPixelStorageType(PixelStorageType::Ashmem) { 372163f88140e18f13575886e88af0336e0ab1ec846sergeyv mPixelStorage.ashmem.address = address; 373163f88140e18f13575886e88af0336e0ab1ec846sergeyv mPixelStorage.ashmem.fd = fd; 374163f88140e18f13575886e88af0336e0ab1ec846sergeyv mPixelStorage.ashmem.size = mappedSize; 375163f88140e18f13575886e88af0336e0ab1ec846sergeyv reconfigure(info, rowBytes, ctable); 376163f88140e18f13575886e88af0336e0ab1ec846sergeyv} 377163f88140e18f13575886e88af0336e0ab1ec846sergeyv 3789a029876422926e313f646f44ab3592cfd4f9933sergeyvBitmap::Bitmap(GraphicBuffer* buffer, const SkImageInfo& info) 379694d499662838123f474f41b31dea84ec5d563f0sergeyv : SkPixelRef(info) 380694d499662838123f474f41b31dea84ec5d563f0sergeyv , mPixelStorageType(PixelStorageType::Hardware) { 3819a029876422926e313f646f44ab3592cfd4f9933sergeyv mPixelStorage.hardware.buffer = buffer; 3829a029876422926e313f646f44ab3592cfd4f9933sergeyv buffer->incStrong(buffer); 383694d499662838123f474f41b31dea84ec5d563f0sergeyv mRowBytes = bytesPerPixel(buffer->getPixelFormat()) * buffer->getStride(); 384694d499662838123f474f41b31dea84ec5d563f0sergeyv} 3859a029876422926e313f646f44ab3592cfd4f9933sergeyv 386c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvBitmap::~Bitmap() { 387163f88140e18f13575886e88af0336e0ab1ec846sergeyv switch (mPixelStorageType) { 388163f88140e18f13575886e88af0336e0ab1ec846sergeyv case PixelStorageType::External: 389163f88140e18f13575886e88af0336e0ab1ec846sergeyv mPixelStorage.external.freeFunc(mPixelStorage.external.address, 390163f88140e18f13575886e88af0336e0ab1ec846sergeyv mPixelStorage.external.context); 391163f88140e18f13575886e88af0336e0ab1ec846sergeyv break; 392163f88140e18f13575886e88af0336e0ab1ec846sergeyv case PixelStorageType::Ashmem: 393163f88140e18f13575886e88af0336e0ab1ec846sergeyv munmap(mPixelStorage.ashmem.address, mPixelStorage.ashmem.size); 394163f88140e18f13575886e88af0336e0ab1ec846sergeyv close(mPixelStorage.ashmem.fd); 395163f88140e18f13575886e88af0336e0ab1ec846sergeyv break; 396163f88140e18f13575886e88af0336e0ab1ec846sergeyv case PixelStorageType::Heap: 397163f88140e18f13575886e88af0336e0ab1ec846sergeyv free(mPixelStorage.heap.address); 398163f88140e18f13575886e88af0336e0ab1ec846sergeyv break; 399694d499662838123f474f41b31dea84ec5d563f0sergeyv case PixelStorageType::Hardware: 400694d499662838123f474f41b31dea84ec5d563f0sergeyv auto buffer = mPixelStorage.hardware.buffer; 401694d499662838123f474f41b31dea84ec5d563f0sergeyv buffer->decStrong(buffer); 402694d499662838123f474f41b31dea84ec5d563f0sergeyv mPixelStorage.hardware.buffer = nullptr; 403694d499662838123f474f41b31dea84ec5d563f0sergeyv break; 404694d499662838123f474f41b31dea84ec5d563f0sergeyv 405163f88140e18f13575886e88af0336e0ab1ec846sergeyv } 406163f88140e18f13575886e88af0336e0ab1ec846sergeyv 407163f88140e18f13575886e88af0336e0ab1ec846sergeyv if (android::uirenderer::Caches::hasInstance()) { 408163f88140e18f13575886e88af0336e0ab1ec846sergeyv android::uirenderer::Caches::getInstance().textureCache.releaseTexture(getStableID()); 409163f88140e18f13575886e88af0336e0ab1ec846sergeyv } 410163f88140e18f13575886e88af0336e0ab1ec846sergeyv} 411163f88140e18f13575886e88af0336e0ab1ec846sergeyv 412c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvbool Bitmap::hasHardwareMipMap() const { 413163f88140e18f13575886e88af0336e0ab1ec846sergeyv return mHasHardwareMipMap; 414163f88140e18f13575886e88af0336e0ab1ec846sergeyv} 415163f88140e18f13575886e88af0336e0ab1ec846sergeyv 416c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvvoid Bitmap::setHasHardwareMipMap(bool hasMipMap) { 417163f88140e18f13575886e88af0336e0ab1ec846sergeyv mHasHardwareMipMap = hasMipMap; 418163f88140e18f13575886e88af0336e0ab1ec846sergeyv} 419163f88140e18f13575886e88af0336e0ab1ec846sergeyv 420c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvvoid* Bitmap::getStorage() const { 421163f88140e18f13575886e88af0336e0ab1ec846sergeyv switch (mPixelStorageType) { 422163f88140e18f13575886e88af0336e0ab1ec846sergeyv case PixelStorageType::External: 423163f88140e18f13575886e88af0336e0ab1ec846sergeyv return mPixelStorage.external.address; 424163f88140e18f13575886e88af0336e0ab1ec846sergeyv case PixelStorageType::Ashmem: 425163f88140e18f13575886e88af0336e0ab1ec846sergeyv return mPixelStorage.ashmem.address; 426163f88140e18f13575886e88af0336e0ab1ec846sergeyv case PixelStorageType::Heap: 427163f88140e18f13575886e88af0336e0ab1ec846sergeyv return mPixelStorage.heap.address; 428694d499662838123f474f41b31dea84ec5d563f0sergeyv case PixelStorageType::Hardware: 429694d499662838123f474f41b31dea84ec5d563f0sergeyv return nullptr; 430163f88140e18f13575886e88af0336e0ab1ec846sergeyv } 431163f88140e18f13575886e88af0336e0ab1ec846sergeyv} 432163f88140e18f13575886e88af0336e0ab1ec846sergeyv 433c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvbool Bitmap::onNewLockPixels(LockRec* rec) { 434163f88140e18f13575886e88af0336e0ab1ec846sergeyv rec->fPixels = getStorage(); 435163f88140e18f13575886e88af0336e0ab1ec846sergeyv rec->fRowBytes = mRowBytes; 436163f88140e18f13575886e88af0336e0ab1ec846sergeyv rec->fColorTable = mColorTable.get(); 437163f88140e18f13575886e88af0336e0ab1ec846sergeyv return true; 438163f88140e18f13575886e88af0336e0ab1ec846sergeyv} 439163f88140e18f13575886e88af0336e0ab1ec846sergeyv 440c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvsize_t Bitmap::getAllocatedSizeInBytes() const { 441163f88140e18f13575886e88af0336e0ab1ec846sergeyv return info().getSafeSize(mRowBytes); 442163f88140e18f13575886e88af0336e0ab1ec846sergeyv} 443163f88140e18f13575886e88af0336e0ab1ec846sergeyv 444c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvint Bitmap::getAshmemFd() const { 445163f88140e18f13575886e88af0336e0ab1ec846sergeyv switch (mPixelStorageType) { 446163f88140e18f13575886e88af0336e0ab1ec846sergeyv case PixelStorageType::Ashmem: 447163f88140e18f13575886e88af0336e0ab1ec846sergeyv return mPixelStorage.ashmem.fd; 448163f88140e18f13575886e88af0336e0ab1ec846sergeyv default: 449163f88140e18f13575886e88af0336e0ab1ec846sergeyv return -1; 450163f88140e18f13575886e88af0336e0ab1ec846sergeyv } 451163f88140e18f13575886e88af0336e0ab1ec846sergeyv} 452163f88140e18f13575886e88af0336e0ab1ec846sergeyv 453c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvsize_t Bitmap::getAllocationByteCount() const { 454163f88140e18f13575886e88af0336e0ab1ec846sergeyv switch (mPixelStorageType) { 455163f88140e18f13575886e88af0336e0ab1ec846sergeyv case PixelStorageType::Heap: 456163f88140e18f13575886e88af0336e0ab1ec846sergeyv return mPixelStorage.heap.size; 457163f88140e18f13575886e88af0336e0ab1ec846sergeyv default: 458163f88140e18f13575886e88af0336e0ab1ec846sergeyv return rowBytes() * height(); 459163f88140e18f13575886e88af0336e0ab1ec846sergeyv } 460163f88140e18f13575886e88af0336e0ab1ec846sergeyv} 461163f88140e18f13575886e88af0336e0ab1ec846sergeyv 462c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvvoid Bitmap::reconfigure(const SkImageInfo& info) { 463163f88140e18f13575886e88af0336e0ab1ec846sergeyv reconfigure(info, info.minRowBytes(), nullptr); 464163f88140e18f13575886e88af0336e0ab1ec846sergeyv} 465163f88140e18f13575886e88af0336e0ab1ec846sergeyv 466c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvvoid Bitmap::setAlphaType(SkAlphaType alphaType) { 467163f88140e18f13575886e88af0336e0ab1ec846sergeyv if (!SkColorTypeValidateAlphaType(info().colorType(), alphaType, &alphaType)) { 468163f88140e18f13575886e88af0336e0ab1ec846sergeyv return; 469163f88140e18f13575886e88af0336e0ab1ec846sergeyv } 470163f88140e18f13575886e88af0336e0ab1ec846sergeyv 471163f88140e18f13575886e88af0336e0ab1ec846sergeyv changeAlphaType(alphaType); 472163f88140e18f13575886e88af0336e0ab1ec846sergeyv} 473163f88140e18f13575886e88af0336e0ab1ec846sergeyv 474c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvvoid Bitmap::getSkBitmap(SkBitmap* outBitmap) { 47559eecb526adc5bd7041e7b6147bfcc40dd2c200esergeyv outBitmap->setHasHardwareMipMap(mHasHardwareMipMap); 476694d499662838123f474f41b31dea84ec5d563f0sergeyv if (isHardware()) { 47759eecb526adc5bd7041e7b6147bfcc40dd2c200esergeyv ALOGW("Warning: attempt to read pixels from hardware bitmap, which is very slow operation"); 47859eecb526adc5bd7041e7b6147bfcc40dd2c200esergeyv outBitmap->allocPixels(info()); 47959eecb526adc5bd7041e7b6147bfcc40dd2c200esergeyv uirenderer::renderthread::RenderProxy::copyGraphicBufferInto(graphicBuffer(), outBitmap); 480694d499662838123f474f41b31dea84ec5d563f0sergeyv return; 481694d499662838123f474f41b31dea84ec5d563f0sergeyv } 482163f88140e18f13575886e88af0336e0ab1ec846sergeyv outBitmap->setInfo(info(), rowBytes()); 483163f88140e18f13575886e88af0336e0ab1ec846sergeyv outBitmap->setPixelRef(this); 484163f88140e18f13575886e88af0336e0ab1ec846sergeyv} 485163f88140e18f13575886e88af0336e0ab1ec846sergeyv 486554ffeb8b7c836da43a637c59eedfc617895b19dsergeyvvoid Bitmap::getSkBitmapForShaders(SkBitmap* outBitmap) { 487554ffeb8b7c836da43a637c59eedfc617895b19dsergeyv outBitmap->setInfo(info(), rowBytes()); 488554ffeb8b7c836da43a637c59eedfc617895b19dsergeyv outBitmap->setPixelRef(this); 489554ffeb8b7c836da43a637c59eedfc617895b19dsergeyv outBitmap->setHasHardwareMipMap(mHasHardwareMipMap); 490554ffeb8b7c836da43a637c59eedfc617895b19dsergeyv} 491554ffeb8b7c836da43a637c59eedfc617895b19dsergeyv 492ec4a4b13eae2241d1613890c1c1c096bed891845sergeyvvoid Bitmap::getBounds(SkRect* bounds) const { 493ec4a4b13eae2241d1613890c1c1c096bed891845sergeyv SkASSERT(bounds); 494ec4a4b13eae2241d1613890c1c1c096bed891845sergeyv bounds->set(0, 0, SkIntToScalar(info().width()), SkIntToScalar(info().height())); 495ec4a4b13eae2241d1613890c1c1c096bed891845sergeyv} 496ec4a4b13eae2241d1613890c1c1c096bed891845sergeyv 497694d499662838123f474f41b31dea84ec5d563f0sergeyvGraphicBuffer* Bitmap::graphicBuffer() { 498694d499662838123f474f41b31dea84ec5d563f0sergeyv if (isHardware()) { 499694d499662838123f474f41b31dea84ec5d563f0sergeyv return mPixelStorage.hardware.buffer; 500694d499662838123f474f41b31dea84ec5d563f0sergeyv } 501694d499662838123f474f41b31dea84ec5d563f0sergeyv return nullptr; 502694d499662838123f474f41b31dea84ec5d563f0sergeyv} 503694d499662838123f474f41b31dea84ec5d563f0sergeyv 504ab12c1fe73734a18ac19a06b97f276528f6d027aMike Reed} // namespace android 505