Bitmap.h revision 39d7f30ebe490c1d6aee76b0b61e3e67dec13e34
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
26namespace android {
27
28enum class PixelStorageType {
29    Invalid,
30    External,
31    Java,
32    Ashmem,
33};
34
35class WrappedPixelRef;
36
37typedef 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 */
48class Bitmap {
49public:
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
60    jbyteArray javaByteArray() const {
61        return mPixelStorageType == PixelStorageType::Java
62                ? mPixelStorage.java.jstrongRef : nullptr;
63    }
64
65    int width() const { return info().width(); }
66    int height() const { return info().height(); }
67    size_t rowBytes() const;
68    SkPixelRef* peekAtPixelRef() const;
69    SkPixelRef* refPixelRef();
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
75    void getSkBitmap(SkBitmap* outBitmap);
76    void detachFromJava();
77
78    void freePixels();
79
80    bool hasHardwareMipMap();
81    void setHasHardwareMipMap(bool hasMipMap);
82    int getAshmemFd() const;
83
84private:
85    friend class WrappedPixelRef;
86
87    ~Bitmap();
88    void doFreePixels();
89    void onStrongRefDestroyed();
90
91    void pinPixelsLocked();
92    void unpinPixelsLocked();
93    JNIEnv* jniEnv();
94    bool shouldDisposeSelfLocked();
95    void assertValid() const;
96    SkPixelRef* refPixelRefLocked();
97
98    android::Mutex mLock;
99    int mPinnedRefCount = 0;
100    std::unique_ptr<WrappedPixelRef> mPixelRef;
101    PixelStorageType mPixelStorageType;
102    bool mAttachedToJava = true;
103
104    union {
105        struct {
106            void* address;
107            void* context;
108            FreeFunc freeFunc;
109        } external;
110        struct {
111            void* address;
112            int fd;
113            size_t size;
114        } ashmem;
115        struct {
116            JavaVM* jvm;
117            jweak jweakRef;
118            jbyteArray jstrongRef;
119        } java;
120    } mPixelStorage;
121};
122
123} // namespace android
124
125#endif /* BITMAP_H_ */
126