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