xref: /aosp_15_r20/frameworks/base/libs/hwui/hwui/Bitmap.h (revision d57664e9bc4670b3ecf6748a746a57c557b6bc9e)
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 <SkImageInfo.h>
23 #include <SkPixelRef.h>
24 #include <SkRefCnt.h>
25 #include <cutils/compiler.h>
26 #include <utils/StrongPointer.h>
27 
28 #include <mutex>
29 #include <optional>
30 
31 #ifdef __ANDROID__ // Layoutlib does not support hardware acceleration
32 #include <android/hardware_buffer.h>
33 #endif
34 
35 class SkWStream;
36 
37 namespace android {
38 
39 enum class PixelStorageType {
40     WrappedPixelRef = 0,
41     Heap = 1,
42     Ashmem = 2,
43     Hardware = 3,
44 };
45 
46 // TODO: Find a better home for this. It's here because hwui/Bitmap is exported and CanvasTransform
47 // isn't, but cleanup should be done
48 enum class BitmapPalette {
49     Unknown,
50     Light,
51     Dark,
52 };
53 
54 namespace uirenderer {
55 class Gainmap;
56 namespace renderthread {
57 class RenderThread;
58 }
59 }
60 
61 class PixelStorage;
62 
63 typedef void (*FreeFunc)(void* addr, void* context);
64 
65 class Bitmap : public SkPixelRef {
66 public:
67     /* The allocate factories not only construct the Bitmap object but also allocate the
68      * backing store whose type is determined by the specific method that is called.
69      *
70      * The factories that accept SkBitmap* as a param will modify those params by
71      * installing the returned bitmap as their SkPixelRef.
72      *
73      * The factories that accept const SkBitmap& as a param will copy the contents of the
74      * provided bitmap into the newly allocated buffer.
75      */
76     static sk_sp<Bitmap> allocateAshmemBitmap(SkBitmap* bitmap);
77     static sk_sp<Bitmap> allocateHardwareBitmap(const SkBitmap& bitmap);
78     static sk_sp<Bitmap> allocateHeapBitmap(SkBitmap* bitmap);
79     static sk_sp<Bitmap> allocateHeapBitmap(const SkImageInfo& info);
80     static sk_sp<Bitmap> allocateHeapBitmap(size_t size, const SkImageInfo& i, size_t rowBytes);
81 
82     static std::string getAshmemId(const char* tag, uint64_t bitmapId,
83                                    int width, int height, size_t size);
84 
85     /* The createFrom factories construct a new Bitmap object by wrapping the already allocated
86      * memory that is provided as an input param.
87      */
88 #ifdef __ANDROID__ // Layoutlib does not support hardware acceleration
89     static sk_sp<Bitmap> createFrom(AHardwareBuffer* hardwareBuffer,
90                                     sk_sp<SkColorSpace> colorSpace,
91                                     BitmapPalette palette = BitmapPalette::Unknown);
92 
93     static sk_sp<Bitmap> createFrom(AHardwareBuffer* hardwareBuffer,
94                                     SkColorType colorType,
95                                     sk_sp<SkColorSpace> colorSpace,
96                                     SkAlphaType alphaType,
97                                     BitmapPalette palette);
98 #endif
99     static sk_sp<Bitmap> createFrom(const SkImageInfo& info, size_t rowBytes, int fd, void* addr,
100                                     size_t size, bool readOnly);
101     static sk_sp<Bitmap> createFrom(const SkImageInfo&, SkPixelRef&);
102 
rowBytesAsPixels()103     int rowBytesAsPixels() const { return rowBytes() >> mInfo.shiftPerPixel(); }
104 
105     void reconfigure(const SkImageInfo& info, size_t rowBytes);
106     void reconfigure(const SkImageInfo& info);
107     void setColorSpace(sk_sp<SkColorSpace> colorSpace);
108     void setAlphaType(SkAlphaType alphaType);
109 
getId()110     uint64_t getId() const {
111         return mId;
112     }
113 
114     void getSkBitmap(SkBitmap* outBitmap);
115 
getSkBitmap()116     SkBitmap getSkBitmap() {
117         SkBitmap ret;
118         getSkBitmap(&ret);
119         return ret;
120     }
121 
122     int getAshmemFd() const;
123     size_t getAllocationByteCount() const;
124 
125     void setHasHardwareMipMap(bool hasMipMap);
126     bool hasHardwareMipMap() const;
127 
isOpaque()128     bool isOpaque() const { return mInfo.isOpaque(); }
colorType()129     SkColorType colorType() const { return mInfo.colorType(); }
info()130     const SkImageInfo& info() const { return mInfo; }
131 
132     void getBounds(SkRect* bounds) const;
133 
isHardware()134     bool isHardware() const { return mPixelStorageType == PixelStorageType::Hardware; }
hasGainmap()135     bool hasGainmap() const { return mGainmap.get() != nullptr; }
136 
137     sp<uirenderer::Gainmap> gainmap() const;
138 
139     void setGainmap(sp<uirenderer::Gainmap>&& gainmap);
140 
pixelStorageType()141     PixelStorageType pixelStorageType() const { return mPixelStorageType; }
142 
143 #ifdef __ANDROID__ // Layoutlib does not support hardware acceleration
144      AHardwareBuffer* hardwareBuffer();
145 #endif
146 
147     /**
148      * Creates or returns a cached SkImage and is safe to be invoked from either
149      * the UI or RenderThread.
150      *
151      */
152     sk_sp<SkImage> makeImage();
153 
154     static BitmapPalette computePalette(const SkImageInfo& info, const void* addr, size_t rowBytes);
155 
computePalette(const SkBitmap & bitmap)156     static BitmapPalette computePalette(const SkBitmap& bitmap) {
157         return computePalette(bitmap.info(), bitmap.getPixels(), bitmap.rowBytes());
158     }
159 
palette()160     BitmapPalette palette() {
161         if (!isHardware() && mPaletteGenerationId != getGenerationID()) {
162             mPalette = computePalette(info(), pixels(), rowBytes());
163             mPaletteGenerationId = getGenerationID();
164         }
165         return mPalette;
166     }
167 
168   // returns true if rowBytes * height can be represented by a positive int32_t value
169   // and places that value in size.
170   static bool computeAllocationSize(size_t rowBytes, int height, size_t* size);
171 
172   // These must match the int values of CompressFormat in Bitmap.java, as well as
173   // AndroidBitmapCompressFormat.
174   enum class JavaCompressFormat {
175     Jpeg = 0,
176     Png = 1,
177     Webp = 2,
178     WebpLossy = 3,
179     WebpLossless = 4,
180   };
181 
182   bool compress(JavaCompressFormat format, int32_t quality, SkWStream* stream);
183 
184   static bool compress(const SkBitmap& bitmap, JavaCompressFormat format,
185                        int32_t quality, SkWStream* stream);
186 private:
187     static constexpr uint64_t INVALID_BITMAP_ID = 0u;
188 
189     static sk_sp<Bitmap> allocateAshmemBitmap(size_t size, const SkImageInfo& i, size_t rowBytes);
190 
191     Bitmap(void* address, size_t allocSize, const SkImageInfo& info, size_t rowBytes);
192     Bitmap(SkPixelRef& pixelRef, const SkImageInfo& info);
193     Bitmap(void* address, int fd, size_t mappedSize, const SkImageInfo& info, size_t rowBytes,
194            uint64_t id = INVALID_BITMAP_ID);
195 #ifdef __ANDROID__ // Layoutlib does not support hardware acceleration
196     Bitmap(AHardwareBuffer* buffer, const SkImageInfo& info, size_t rowBytes,
197            BitmapPalette palette);
198 
199     // Common code for the two public facing createFrom(AHardwareBuffer*, ...)
200     // methods.
201     // bufferDesc is only used to compute rowBytes.
202     static sk_sp<Bitmap> createFrom(AHardwareBuffer* hardwareBuffer, const SkImageInfo& info,
203                                     const AHardwareBuffer_Desc& bufferDesc, BitmapPalette palette);
204 #endif
205 
206     virtual ~Bitmap();
207 
208     SkImageInfo mInfo;
209 
210     const PixelStorageType mPixelStorageType;
211 
212     BitmapPalette mPalette = BitmapPalette::Unknown;
213     uint32_t mPaletteGenerationId = -1;
214 
215     bool mHasHardwareMipMap = false;
216 
217     sp<uirenderer::Gainmap> mGainmap;
218 
219     union {
220         struct {
221             SkPixelRef* pixelRef;
222         } wrapped;
223         struct {
224             void* address;
225             int fd;
226             size_t size;
227         } ashmem;
228         struct {
229             void* address;
230             size_t size;
231         } heap;
232 #ifdef __ANDROID__ // Layoutlib does not support hardware acceleration
233         struct {
234             AHardwareBuffer* buffer;
235             uint64_t size;
236         } hardware;
237 #endif
238     } mPixelStorage;
239 
240     sk_sp<SkImage> mImage;  // Cache is used only for HW Bitmaps with Skia pipeline.
241 
242     uint64_t mId;                // unique ID for this bitmap
243     static uint64_t getId(PixelStorageType type);
244 
245     // for tracing total number and memory usage of bitmaps
246     static std::mutex mLock;
247     static size_t mTotalBitmapBytes;
248     static size_t mTotalBitmapCount;
249     void traceBitmapCreate();
250     void traceBitmapDelete();
251 };
252 
253 }  // namespace android
254