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 #include <ui/GraphicBuffer.h>
27 
28 namespace android {
29 
30 enum class PixelStorageType {
31     External,
32     Heap,
33     Ashmem,
34     Hardware,
35 };
36 
37 // TODO: Find a better home for this. It's here because hwui/Bitmap is exported and CanvasTransform
38 // isn't, but cleanup should be done
39 enum class BitmapPalette {
40     Unknown,
41     Light,
42     Dark,
43 };
44 
45 namespace uirenderer {
46 namespace renderthread {
47 class RenderThread;
48 }
49 }
50 
51 class PixelStorage;
52 
53 typedef void (*FreeFunc)(void* addr, void* context);
54 
55 class ANDROID_API Bitmap : public SkPixelRef {
56 public:
57     /* The allocate factories not only construct the Bitmap object but also allocate the
58      * backing store whose type is determined by the specific method that is called.
59      *
60      * The factories that accept SkBitmap* as a param will modify those params by
61      * installing the returned bitmap as their SkPixelRef.
62      *
63      * The factories that accept const SkBitmap& as a param will copy the contents of the
64      * provided bitmap into the newly allocated buffer.
65      */
66     static sk_sp<Bitmap> allocateAshmemBitmap(SkBitmap* bitmap);
67     static sk_sp<Bitmap> allocateHardwareBitmap(const SkBitmap& bitmap);
68     static sk_sp<Bitmap> allocateHeapBitmap(SkBitmap* bitmap);
69     static sk_sp<Bitmap> allocateHeapBitmap(const SkImageInfo& info);
70 
71     /* The createFrom factories construct a new Bitmap object by wrapping the already allocated
72      * memory that is provided as an input param.
73      */
74     static sk_sp<Bitmap> createFrom(sp<GraphicBuffer> graphicBuffer,
75                                     SkColorType colorType,
76                                     sk_sp<SkColorSpace> colorSpace,
77                                     SkAlphaType alphaType = kPremul_SkAlphaType,
78                                     BitmapPalette palette = BitmapPalette::Unknown);
79     static sk_sp<Bitmap> createFrom(const SkImageInfo& info, size_t rowBytes, int fd, void* addr,
80                                     size_t size, bool readOnly);
81     static sk_sp<Bitmap> createFrom(const SkImageInfo&, SkPixelRef&);
82 
rowBytesAsPixels()83     int rowBytesAsPixels() const { return rowBytes() >> mInfo.shiftPerPixel(); }
84 
85     void reconfigure(const SkImageInfo& info, size_t rowBytes);
86     void reconfigure(const SkImageInfo& info);
87     void setColorSpace(sk_sp<SkColorSpace> colorSpace);
88     void setAlphaType(SkAlphaType alphaType);
89 
90     void getSkBitmap(SkBitmap* outBitmap);
91 
92     int getAshmemFd() const;
93     size_t getAllocationByteCount() const;
94 
95     void setHasHardwareMipMap(bool hasMipMap);
96     bool hasHardwareMipMap() const;
97 
isOpaque()98     bool isOpaque() const { return mInfo.isOpaque(); }
colorType()99     SkColorType colorType() const { return mInfo.colorType(); }
info()100     const SkImageInfo& info() const { return mInfo; }
101 
102     void getBounds(SkRect* bounds) const;
103 
isHardware()104     bool isHardware() const { return mPixelStorageType == PixelStorageType::Hardware; }
105 
pixelStorageType()106     PixelStorageType pixelStorageType() const { return mPixelStorageType; }
107 
108     GraphicBuffer* graphicBuffer();
109 
110     /**
111      * Creates or returns a cached SkImage and is safe to be invoked from either
112      * the UI or RenderThread.
113      *
114      */
115     sk_sp<SkImage> makeImage();
116 
117     static BitmapPalette computePalette(const SkImageInfo& info, const void* addr, size_t rowBytes);
118 
computePalette(const SkBitmap & bitmap)119     static BitmapPalette computePalette(const SkBitmap& bitmap) {
120         return computePalette(bitmap.info(), bitmap.getPixels(), bitmap.rowBytes());
121     }
122 
palette()123     BitmapPalette palette() {
124         if (!isHardware() && mPaletteGenerationId != getGenerationID()) {
125             mPalette = computePalette(info(), pixels(), rowBytes());
126             mPaletteGenerationId = getGenerationID();
127         }
128         return mPalette;
129     }
130 
131 private:
132     static sk_sp<Bitmap> allocateAshmemBitmap(size_t size, const SkImageInfo& i, size_t rowBytes);
133     static sk_sp<Bitmap> allocateHeapBitmap(size_t size, const SkImageInfo& i, size_t rowBytes);
134 
135     Bitmap(void* address, size_t allocSize, const SkImageInfo& info, size_t rowBytes);
136     Bitmap(void* address, void* context, FreeFunc freeFunc, const SkImageInfo& info,
137            size_t rowBytes);
138     Bitmap(void* address, int fd, size_t mappedSize, const SkImageInfo& info, size_t rowBytes);
139     Bitmap(GraphicBuffer* buffer, const SkImageInfo& info, BitmapPalette palette);
140 
141     virtual ~Bitmap();
142     void* getStorage() const;
143 
144     SkImageInfo mInfo;
145 
146     const PixelStorageType mPixelStorageType;
147 
148     BitmapPalette mPalette = BitmapPalette::Unknown;
149     uint32_t mPaletteGenerationId = -1;
150 
151     bool mHasHardwareMipMap = false;
152 
153     union {
154         struct {
155             void* address;
156             void* context;
157             FreeFunc freeFunc;
158         } external;
159         struct {
160             void* address;
161             int fd;
162             size_t size;
163         } ashmem;
164         struct {
165             void* address;
166             size_t size;
167         } heap;
168         struct {
169             GraphicBuffer* buffer;
170         } hardware;
171     } mPixelStorage;
172 
173     sk_sp<SkImage> mImage;  // Cache is used only for HW Bitmaps with Skia pipeline.
174 };
175 
176 }  // namespace android
177