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 #ifndef BITMAP_H_
17 #define BITMAP_H_
18 
19 #include <jni.h>
20 #include <SkBitmap.h>
21 #include <SkColorTable.h>
22 #include <SkImageInfo.h>
23 #include <utils/Mutex.h>
24 #include <memory>
25 
26 namespace android {
27 
28 enum class PixelStorageType {
29     Invalid,
30     External,
31     Java,
32     Ashmem,
33 };
34 
35 class WrappedPixelRef;
36 
37 typedef void (*FreeFunc)(void* addr, void* context);
38 
39 /**
40  * Glue-thingy that deals with managing the interaction between the Java
41  * Bitmap object & SkBitmap along with trying to map a notion of strong/weak
42  * lifecycles onto SkPixelRef which only has strong counts to avoid requiring
43  * two GC passes to free the byte[] that backs a Bitmap.
44  *
45  * Since not all Bitmaps are byte[]-backed it also supports external allocations,
46  * which currently is used by screenshots to wrap a gralloc buffer.
47  */
48 class Bitmap {
49 public:
50     Bitmap(JNIEnv* env, jbyteArray storageObj, void* address,
51             const SkImageInfo& info, size_t rowBytes, SkColorTable* ctable);
52     Bitmap(void* address, void* context, FreeFunc freeFunc,
53             const SkImageInfo& info, size_t rowBytes, SkColorTable* ctable);
54     Bitmap(void* address, int fd, const SkImageInfo& info, size_t rowBytes,
55             SkColorTable* ctable);
56 
57     const SkImageInfo& info() const;
58 
59     // Returns nullptr if it is not backed by a jbyteArray
javaByteArray()60     jbyteArray javaByteArray() const {
61         return mPixelStorageType == PixelStorageType::Java
62                 ? mPixelStorage.java.jstrongRef : nullptr;
63     }
64 
width()65     int width() const { return info().width(); }
height()66     int height() const { return info().height(); }
67     size_t rowBytes() const;
68     SkPixelRef* peekAtPixelRef() const;
69     SkPixelRef* refPixelRef();
valid()70     bool valid() const { return mPixelStorageType != PixelStorageType::Invalid; }
71 
72     void reconfigure(const SkImageInfo& info, size_t rowBytes, SkColorTable* ctable);
73     void reconfigure(const SkImageInfo& info);
74     void setAlphaType(SkAlphaType alphaType);
75 
76     void getSkBitmap(SkBitmap* outBitmap);
77     void detachFromJava();
78 
79     void freePixels();
80 
81     bool hasHardwareMipMap();
82     void setHasHardwareMipMap(bool hasMipMap);
83     int getAshmemFd() const;
84 
85 private:
86     friend class WrappedPixelRef;
87 
88     ~Bitmap();
89     void doFreePixels();
90     void onStrongRefDestroyed();
91 
92     void pinPixelsLocked();
93     void unpinPixelsLocked();
94     JNIEnv* jniEnv();
95     bool shouldDisposeSelfLocked();
96     void assertValid() const;
97     SkPixelRef* refPixelRefLocked();
98 
99     android::Mutex mLock;
100     int mPinnedRefCount = 0;
101     std::unique_ptr<WrappedPixelRef> mPixelRef;
102     PixelStorageType mPixelStorageType;
103     bool mAttachedToJava = true;
104 
105     union {
106         struct {
107             void* address;
108             void* context;
109             FreeFunc freeFunc;
110         } external;
111         struct {
112             void* address;
113             int fd;
114             size_t size;
115         } ashmem;
116         struct {
117             JavaVM* jvm;
118             jweak jweakRef;
119             jbyteArray jstrongRef;
120         } java;
121     } mPixelStorage;
122 };
123 
124 } // namespace android
125 
126 #endif /* BITMAP_H_ */
127