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 External, 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 ANDROID_API 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 75 /* The createFrom factories construct a new Bitmap object by wrapping the already allocated 76 * memory that is provided as an input param. 77 */ 78 #ifdef __ANDROID__ // Layoutlib does not support hardware acceleration 79 static sk_sp<Bitmap> createFrom(AHardwareBuffer* hardwareBuffer, 80 sk_sp<SkColorSpace> colorSpace, 81 BitmapPalette palette = BitmapPalette::Unknown); 82 83 static sk_sp<Bitmap> createFrom(AHardwareBuffer* hardwareBuffer, 84 SkColorType colorType, 85 sk_sp<SkColorSpace> colorSpace, 86 SkAlphaType alphaType, 87 BitmapPalette palette); 88 #endif 89 static sk_sp<Bitmap> createFrom(const SkImageInfo& info, size_t rowBytes, int fd, void* addr, 90 size_t size, bool readOnly); 91 static sk_sp<Bitmap> createFrom(const SkImageInfo&, SkPixelRef&); 92 rowBytesAsPixels()93 int rowBytesAsPixels() const { return rowBytes() >> mInfo.shiftPerPixel(); } 94 95 void reconfigure(const SkImageInfo& info, size_t rowBytes); 96 void reconfigure(const SkImageInfo& info); 97 void setColorSpace(sk_sp<SkColorSpace> colorSpace); 98 void setAlphaType(SkAlphaType alphaType); 99 100 void getSkBitmap(SkBitmap* outBitmap); 101 102 int getAshmemFd() const; 103 size_t getAllocationByteCount() const; 104 105 void setHasHardwareMipMap(bool hasMipMap); 106 bool hasHardwareMipMap() const; 107 isOpaque()108 bool isOpaque() const { return mInfo.isOpaque(); } colorType()109 SkColorType colorType() const { return mInfo.colorType(); } info()110 const SkImageInfo& info() const { return mInfo; } 111 112 void getBounds(SkRect* bounds) const; 113 isHardware()114 bool isHardware() const { return mPixelStorageType == PixelStorageType::Hardware; } 115 pixelStorageType()116 PixelStorageType pixelStorageType() const { return mPixelStorageType; } 117 118 #ifdef __ANDROID__ // Layoutlib does not support hardware acceleration 119 AHardwareBuffer* hardwareBuffer(); 120 #endif 121 122 /** 123 * Creates or returns a cached SkImage and is safe to be invoked from either 124 * the UI or RenderThread. 125 * 126 */ 127 sk_sp<SkImage> makeImage(); 128 129 static BitmapPalette computePalette(const SkImageInfo& info, const void* addr, size_t rowBytes); 130 computePalette(const SkBitmap & bitmap)131 static BitmapPalette computePalette(const SkBitmap& bitmap) { 132 return computePalette(bitmap.info(), bitmap.getPixels(), bitmap.rowBytes()); 133 } 134 palette()135 BitmapPalette palette() { 136 if (!isHardware() && mPaletteGenerationId != getGenerationID()) { 137 mPalette = computePalette(info(), pixels(), rowBytes()); 138 mPaletteGenerationId = getGenerationID(); 139 } 140 return mPalette; 141 } 142 143 // returns true if rowBytes * height can be represented by a positive int32_t value 144 // and places that value in size. 145 static bool computeAllocationSize(size_t rowBytes, int height, size_t* size); 146 147 // These must match the int values of CompressFormat in Bitmap.java, as well as 148 // AndroidBitmapCompressFormat. 149 enum class JavaCompressFormat { 150 Jpeg = 0, 151 Png = 1, 152 Webp = 2, 153 WebpLossy = 3, 154 WebpLossless = 4, 155 }; 156 157 bool compress(JavaCompressFormat format, int32_t quality, SkWStream* stream); 158 159 static bool compress(const SkBitmap& bitmap, JavaCompressFormat format, 160 int32_t quality, SkWStream* stream); 161 private: 162 static sk_sp<Bitmap> allocateAshmemBitmap(size_t size, const SkImageInfo& i, size_t rowBytes); 163 static sk_sp<Bitmap> allocateHeapBitmap(size_t size, const SkImageInfo& i, size_t rowBytes); 164 165 Bitmap(void* address, size_t allocSize, const SkImageInfo& info, size_t rowBytes); 166 Bitmap(void* address, void* context, FreeFunc freeFunc, const SkImageInfo& info, 167 size_t rowBytes); 168 Bitmap(void* address, int fd, size_t mappedSize, const SkImageInfo& info, size_t rowBytes); 169 #ifdef __ANDROID__ // Layoutlib does not support hardware acceleration 170 Bitmap(AHardwareBuffer* buffer, const SkImageInfo& info, size_t rowBytes, 171 BitmapPalette palette); 172 173 // Common code for the two public facing createFrom(AHardwareBuffer*, ...) 174 // methods. 175 // bufferDesc is only used to compute rowBytes. 176 static sk_sp<Bitmap> createFrom(AHardwareBuffer* hardwareBuffer, const SkImageInfo& info, 177 const AHardwareBuffer_Desc& bufferDesc, BitmapPalette palette); 178 #endif 179 180 virtual ~Bitmap(); 181 void* getStorage() const; 182 183 SkImageInfo mInfo; 184 185 const PixelStorageType mPixelStorageType; 186 187 BitmapPalette mPalette = BitmapPalette::Unknown; 188 uint32_t mPaletteGenerationId = -1; 189 190 bool mHasHardwareMipMap = false; 191 192 union { 193 struct { 194 void* address; 195 void* context; 196 FreeFunc freeFunc; 197 } external; 198 struct { 199 void* address; 200 int fd; 201 size_t size; 202 } ashmem; 203 struct { 204 void* address; 205 size_t size; 206 } heap; 207 #ifdef __ANDROID__ // Layoutlib does not support hardware acceleration 208 struct { 209 AHardwareBuffer* buffer; 210 } hardware; 211 #endif 212 } mPixelStorage; 213 214 sk_sp<SkImage> mImage; // Cache is used only for HW Bitmaps with Skia pipeline. 215 }; 216 217 } // namespace android 218