1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 #pragma once 17 18 #include <SkBitmap.h> 19 #include <SkColorFilter.h> 20 #include <SkColorSpace.h> 21 #include <SkImage.h> 22 #include <SkImage.h> 23 #include <SkImageInfo.h> 24 #include <SkPixelRef.h> 25 #include <cutils/compiler.h> 26 #ifdef __ANDROID__ // Layoutlib does not support hardware acceleration 27 #include <android/hardware_buffer.h> 28 #endif 29 30 class SkWStream; 31 32 namespace android { 33 34 enum class PixelStorageType { 35 WrappedPixelRef, 36 Heap, 37 Ashmem, 38 Hardware, 39 }; 40 41 // TODO: Find a better home for this. It's here because hwui/Bitmap is exported and CanvasTransform 42 // isn't, but cleanup should be done 43 enum class BitmapPalette { 44 Unknown, 45 Light, 46 Dark, 47 }; 48 49 namespace uirenderer { 50 namespace renderthread { 51 class RenderThread; 52 } 53 } 54 55 class PixelStorage; 56 57 typedef void (*FreeFunc)(void* addr, void* context); 58 59 class Bitmap : public SkPixelRef { 60 public: 61 /* The allocate factories not only construct the Bitmap object but also allocate the 62 * backing store whose type is determined by the specific method that is called. 63 * 64 * The factories that accept SkBitmap* as a param will modify those params by 65 * installing the returned bitmap as their SkPixelRef. 66 * 67 * The factories that accept const SkBitmap& as a param will copy the contents of the 68 * provided bitmap into the newly allocated buffer. 69 */ 70 static sk_sp<Bitmap> allocateAshmemBitmap(SkBitmap* bitmap); 71 static sk_sp<Bitmap> allocateHardwareBitmap(const SkBitmap& bitmap); 72 static sk_sp<Bitmap> allocateHeapBitmap(SkBitmap* bitmap); 73 static sk_sp<Bitmap> allocateHeapBitmap(const SkImageInfo& info); 74 static sk_sp<Bitmap> allocateHeapBitmap(size_t size, const SkImageInfo& i, size_t rowBytes); 75 76 /* The createFrom factories construct a new Bitmap object by wrapping the already allocated 77 * memory that is provided as an input param. 78 */ 79 #ifdef __ANDROID__ // Layoutlib does not support hardware acceleration 80 static sk_sp<Bitmap> createFrom(AHardwareBuffer* hardwareBuffer, 81 sk_sp<SkColorSpace> colorSpace, 82 BitmapPalette palette = BitmapPalette::Unknown); 83 84 static sk_sp<Bitmap> createFrom(AHardwareBuffer* hardwareBuffer, 85 SkColorType colorType, 86 sk_sp<SkColorSpace> colorSpace, 87 SkAlphaType alphaType, 88 BitmapPalette palette); 89 #endif 90 static sk_sp<Bitmap> createFrom(const SkImageInfo& info, size_t rowBytes, int fd, void* addr, 91 size_t size, bool readOnly); 92 static sk_sp<Bitmap> createFrom(const SkImageInfo&, SkPixelRef&); 93 rowBytesAsPixels()94 int rowBytesAsPixels() const { return rowBytes() >> mInfo.shiftPerPixel(); } 95 96 void reconfigure(const SkImageInfo& info, size_t rowBytes); 97 void reconfigure(const SkImageInfo& info); 98 void setColorSpace(sk_sp<SkColorSpace> colorSpace); 99 void setAlphaType(SkAlphaType alphaType); 100 101 void getSkBitmap(SkBitmap* outBitmap); 102 getSkBitmap()103 SkBitmap getSkBitmap() { 104 SkBitmap ret; 105 getSkBitmap(&ret); 106 return ret; 107 } 108 109 int getAshmemFd() const; 110 size_t getAllocationByteCount() const; 111 112 void setHasHardwareMipMap(bool hasMipMap); 113 bool hasHardwareMipMap() const; 114 isOpaque()115 bool isOpaque() const { return mInfo.isOpaque(); } colorType()116 SkColorType colorType() const { return mInfo.colorType(); } info()117 const SkImageInfo& info() const { return mInfo; } 118 119 void getBounds(SkRect* bounds) const; 120 isHardware()121 bool isHardware() const { return mPixelStorageType == PixelStorageType::Hardware; } 122 pixelStorageType()123 PixelStorageType pixelStorageType() const { return mPixelStorageType; } 124 125 #ifdef __ANDROID__ // Layoutlib does not support hardware acceleration 126 AHardwareBuffer* hardwareBuffer(); 127 #endif 128 129 /** 130 * Creates or returns a cached SkImage and is safe to be invoked from either 131 * the UI or RenderThread. 132 * 133 */ 134 sk_sp<SkImage> makeImage(); 135 136 static BitmapPalette computePalette(const SkImageInfo& info, const void* addr, size_t rowBytes); 137 computePalette(const SkBitmap & bitmap)138 static BitmapPalette computePalette(const SkBitmap& bitmap) { 139 return computePalette(bitmap.info(), bitmap.getPixels(), bitmap.rowBytes()); 140 } 141 palette()142 BitmapPalette palette() { 143 if (!isHardware() && mPaletteGenerationId != getGenerationID()) { 144 mPalette = computePalette(info(), pixels(), rowBytes()); 145 mPaletteGenerationId = getGenerationID(); 146 } 147 return mPalette; 148 } 149 150 // returns true if rowBytes * height can be represented by a positive int32_t value 151 // and places that value in size. 152 static bool computeAllocationSize(size_t rowBytes, int height, size_t* size); 153 154 // These must match the int values of CompressFormat in Bitmap.java, as well as 155 // AndroidBitmapCompressFormat. 156 enum class JavaCompressFormat { 157 Jpeg = 0, 158 Png = 1, 159 Webp = 2, 160 WebpLossy = 3, 161 WebpLossless = 4, 162 }; 163 164 bool compress(JavaCompressFormat format, int32_t quality, SkWStream* stream); 165 166 static bool compress(const SkBitmap& bitmap, JavaCompressFormat format, 167 int32_t quality, SkWStream* stream); 168 private: 169 static sk_sp<Bitmap> allocateAshmemBitmap(size_t size, const SkImageInfo& i, size_t rowBytes); 170 171 Bitmap(void* address, size_t allocSize, const SkImageInfo& info, size_t rowBytes); 172 Bitmap(SkPixelRef& pixelRef, const SkImageInfo& info); 173 Bitmap(void* address, int fd, size_t mappedSize, const SkImageInfo& info, size_t rowBytes); 174 #ifdef __ANDROID__ // Layoutlib does not support hardware acceleration 175 Bitmap(AHardwareBuffer* buffer, const SkImageInfo& info, size_t rowBytes, 176 BitmapPalette palette); 177 178 // Common code for the two public facing createFrom(AHardwareBuffer*, ...) 179 // methods. 180 // bufferDesc is only used to compute rowBytes. 181 static sk_sp<Bitmap> createFrom(AHardwareBuffer* hardwareBuffer, const SkImageInfo& info, 182 const AHardwareBuffer_Desc& bufferDesc, BitmapPalette palette); 183 #endif 184 185 virtual ~Bitmap(); 186 187 SkImageInfo mInfo; 188 189 const PixelStorageType mPixelStorageType; 190 191 BitmapPalette mPalette = BitmapPalette::Unknown; 192 uint32_t mPaletteGenerationId = -1; 193 194 bool mHasHardwareMipMap = false; 195 196 union { 197 struct { 198 SkPixelRef* pixelRef; 199 } wrapped; 200 struct { 201 void* address; 202 int fd; 203 size_t size; 204 } ashmem; 205 struct { 206 void* address; 207 size_t size; 208 } heap; 209 #ifdef __ANDROID__ // Layoutlib does not support hardware acceleration 210 struct { 211 AHardwareBuffer* buffer; 212 } hardware; 213 #endif 214 } mPixelStorage; 215 216 sk_sp<SkImage> mImage; // Cache is used only for HW Bitmaps with Skia pipeline. 217 }; 218 219 } // namespace android 220