• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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