1f29ed28c7b878ef28058bc730715d0d32445bc57John Reck/*
2f29ed28c7b878ef28058bc730715d0d32445bc57John Reck * Copyright (C) 2015 The Android Open Source Project
3f29ed28c7b878ef28058bc730715d0d32445bc57John Reck *
4f29ed28c7b878ef28058bc730715d0d32445bc57John Reck * Licensed under the Apache License, Version 2.0 (the "License");
5f29ed28c7b878ef28058bc730715d0d32445bc57John Reck * you may not use this file except in compliance with the License.
6f29ed28c7b878ef28058bc730715d0d32445bc57John Reck * You may obtain a copy of the License at
7f29ed28c7b878ef28058bc730715d0d32445bc57John Reck *
8f29ed28c7b878ef28058bc730715d0d32445bc57John Reck *      http://www.apache.org/licenses/LICENSE-2.0
9f29ed28c7b878ef28058bc730715d0d32445bc57John Reck *
10f29ed28c7b878ef28058bc730715d0d32445bc57John Reck * Unless required by applicable law or agreed to in writing, software
11f29ed28c7b878ef28058bc730715d0d32445bc57John Reck * distributed under the License is distributed on an "AS IS" BASIS,
12f29ed28c7b878ef28058bc730715d0d32445bc57John Reck * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f29ed28c7b878ef28058bc730715d0d32445bc57John Reck * See the License for the specific language governing permissions and
14f29ed28c7b878ef28058bc730715d0d32445bc57John Reck * limitations under the License.
15f29ed28c7b878ef28058bc730715d0d32445bc57John Reck */
16f29ed28c7b878ef28058bc730715d0d32445bc57John Reck#ifndef BITMAP_H_
17f29ed28c7b878ef28058bc730715d0d32445bc57John Reck#define BITMAP_H_
18f29ed28c7b878ef28058bc730715d0d32445bc57John Reck
19f29ed28c7b878ef28058bc730715d0d32445bc57John Reck#include <jni.h>
20f29ed28c7b878ef28058bc730715d0d32445bc57John Reck#include <SkBitmap.h>
21f29ed28c7b878ef28058bc730715d0d32445bc57John Reck#include <SkColorTable.h>
22f29ed28c7b878ef28058bc730715d0d32445bc57John Reck#include <SkImageInfo.h>
23f29ed28c7b878ef28058bc730715d0d32445bc57John Reck#include <utils/Mutex.h>
24f29ed28c7b878ef28058bc730715d0d32445bc57John Reck#include <memory>
25f29ed28c7b878ef28058bc730715d0d32445bc57John Reck
26f29ed28c7b878ef28058bc730715d0d32445bc57John Recknamespace android {
27f29ed28c7b878ef28058bc730715d0d32445bc57John Reck
28f29ed28c7b878ef28058bc730715d0d32445bc57John Reckenum class PixelStorageType {
29f29ed28c7b878ef28058bc730715d0d32445bc57John Reck    Invalid,
30f29ed28c7b878ef28058bc730715d0d32445bc57John Reck    External,
31f29ed28c7b878ef28058bc730715d0d32445bc57John Reck    Java,
3239d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews    Ashmem,
33f29ed28c7b878ef28058bc730715d0d32445bc57John Reck};
34f29ed28c7b878ef28058bc730715d0d32445bc57John Reck
35f29ed28c7b878ef28058bc730715d0d32445bc57John Reckclass WrappedPixelRef;
36f29ed28c7b878ef28058bc730715d0d32445bc57John Reck
37f29ed28c7b878ef28058bc730715d0d32445bc57John Recktypedef void (*FreeFunc)(void* addr, void* context);
38f29ed28c7b878ef28058bc730715d0d32445bc57John Reck
39f29ed28c7b878ef28058bc730715d0d32445bc57John Reck/**
40f29ed28c7b878ef28058bc730715d0d32445bc57John Reck * Glue-thingy that deals with managing the interaction between the Java
41f29ed28c7b878ef28058bc730715d0d32445bc57John Reck * Bitmap object & SkBitmap along with trying to map a notion of strong/weak
42f29ed28c7b878ef28058bc730715d0d32445bc57John Reck * lifecycles onto SkPixelRef which only has strong counts to avoid requiring
43f29ed28c7b878ef28058bc730715d0d32445bc57John Reck * two GC passes to free the byte[] that backs a Bitmap.
44f29ed28c7b878ef28058bc730715d0d32445bc57John Reck *
45f29ed28c7b878ef28058bc730715d0d32445bc57John Reck * Since not all Bitmaps are byte[]-backed it also supports external allocations,
46f29ed28c7b878ef28058bc730715d0d32445bc57John Reck * which currently is used by screenshots to wrap a gralloc buffer.
47f29ed28c7b878ef28058bc730715d0d32445bc57John Reck */
48f29ed28c7b878ef28058bc730715d0d32445bc57John Reckclass Bitmap {
49f29ed28c7b878ef28058bc730715d0d32445bc57John Reckpublic:
50f29ed28c7b878ef28058bc730715d0d32445bc57John Reck    Bitmap(JNIEnv* env, jbyteArray storageObj, void* address,
51f29ed28c7b878ef28058bc730715d0d32445bc57John Reck            const SkImageInfo& info, size_t rowBytes, SkColorTable* ctable);
52f29ed28c7b878ef28058bc730715d0d32445bc57John Reck    Bitmap(void* address, void* context, FreeFunc freeFunc,
53f29ed28c7b878ef28058bc730715d0d32445bc57John Reck            const SkImageInfo& info, size_t rowBytes, SkColorTable* ctable);
5439d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews    Bitmap(void* address, int fd, const SkImageInfo& info, size_t rowBytes,
5539d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews            SkColorTable* ctable);
56f29ed28c7b878ef28058bc730715d0d32445bc57John Reck
57f29ed28c7b878ef28058bc730715d0d32445bc57John Reck    const SkImageInfo& info() const;
58f29ed28c7b878ef28058bc730715d0d32445bc57John Reck
59f29ed28c7b878ef28058bc730715d0d32445bc57John Reck    // Returns nullptr if it is not backed by a jbyteArray
60f29ed28c7b878ef28058bc730715d0d32445bc57John Reck    jbyteArray javaByteArray() const {
61f29ed28c7b878ef28058bc730715d0d32445bc57John Reck        return mPixelStorageType == PixelStorageType::Java
62f29ed28c7b878ef28058bc730715d0d32445bc57John Reck                ? mPixelStorage.java.jstrongRef : nullptr;
63f29ed28c7b878ef28058bc730715d0d32445bc57John Reck    }
64f29ed28c7b878ef28058bc730715d0d32445bc57John Reck
65f29ed28c7b878ef28058bc730715d0d32445bc57John Reck    int width() const { return info().width(); }
66f29ed28c7b878ef28058bc730715d0d32445bc57John Reck    int height() const { return info().height(); }
67f29ed28c7b878ef28058bc730715d0d32445bc57John Reck    size_t rowBytes() const;
68ae2e8b4891491e8e89bed5f2c9626415adee09cbJohn Reck    SkPixelRef* peekAtPixelRef() const;
69ae2e8b4891491e8e89bed5f2c9626415adee09cbJohn Reck    SkPixelRef* refPixelRef();
70f29ed28c7b878ef28058bc730715d0d32445bc57John Reck    bool valid() const { return mPixelStorageType != PixelStorageType::Invalid; }
71f29ed28c7b878ef28058bc730715d0d32445bc57John Reck
72f29ed28c7b878ef28058bc730715d0d32445bc57John Reck    void reconfigure(const SkImageInfo& info, size_t rowBytes, SkColorTable* ctable);
73f29ed28c7b878ef28058bc730715d0d32445bc57John Reck    void reconfigure(const SkImageInfo& info);
740781a2f116be045ff1a3aca721c47f9fef980beaJohn Reck    void setAlphaType(SkAlphaType alphaType);
75f29ed28c7b878ef28058bc730715d0d32445bc57John Reck
76f29ed28c7b878ef28058bc730715d0d32445bc57John Reck    void getSkBitmap(SkBitmap* outBitmap);
77f29ed28c7b878ef28058bc730715d0d32445bc57John Reck    void detachFromJava();
78f29ed28c7b878ef28058bc730715d0d32445bc57John Reck
79f29ed28c7b878ef28058bc730715d0d32445bc57John Reck    void freePixels();
80f29ed28c7b878ef28058bc730715d0d32445bc57John Reck
81f29ed28c7b878ef28058bc730715d0d32445bc57John Reck    bool hasHardwareMipMap();
82f29ed28c7b878ef28058bc730715d0d32445bc57John Reck    void setHasHardwareMipMap(bool hasMipMap);
8339d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews    int getAshmemFd() const;
84f29ed28c7b878ef28058bc730715d0d32445bc57John Reck
85f29ed28c7b878ef28058bc730715d0d32445bc57John Reckprivate:
86f29ed28c7b878ef28058bc730715d0d32445bc57John Reck    friend class WrappedPixelRef;
87f29ed28c7b878ef28058bc730715d0d32445bc57John Reck
88f29ed28c7b878ef28058bc730715d0d32445bc57John Reck    ~Bitmap();
89f29ed28c7b878ef28058bc730715d0d32445bc57John Reck    void doFreePixels();
90f29ed28c7b878ef28058bc730715d0d32445bc57John Reck    void onStrongRefDestroyed();
91f29ed28c7b878ef28058bc730715d0d32445bc57John Reck
92f29ed28c7b878ef28058bc730715d0d32445bc57John Reck    void pinPixelsLocked();
93f29ed28c7b878ef28058bc730715d0d32445bc57John Reck    void unpinPixelsLocked();
94f29ed28c7b878ef28058bc730715d0d32445bc57John Reck    JNIEnv* jniEnv();
95f29ed28c7b878ef28058bc730715d0d32445bc57John Reck    bool shouldDisposeSelfLocked();
96f29ed28c7b878ef28058bc730715d0d32445bc57John Reck    void assertValid() const;
97ae2e8b4891491e8e89bed5f2c9626415adee09cbJohn Reck    SkPixelRef* refPixelRefLocked();
98f29ed28c7b878ef28058bc730715d0d32445bc57John Reck
99f29ed28c7b878ef28058bc730715d0d32445bc57John Reck    android::Mutex mLock;
100f29ed28c7b878ef28058bc730715d0d32445bc57John Reck    int mPinnedRefCount = 0;
101f29ed28c7b878ef28058bc730715d0d32445bc57John Reck    std::unique_ptr<WrappedPixelRef> mPixelRef;
102f29ed28c7b878ef28058bc730715d0d32445bc57John Reck    PixelStorageType mPixelStorageType;
103f29ed28c7b878ef28058bc730715d0d32445bc57John Reck    bool mAttachedToJava = true;
104f29ed28c7b878ef28058bc730715d0d32445bc57John Reck
105f29ed28c7b878ef28058bc730715d0d32445bc57John Reck    union {
106f29ed28c7b878ef28058bc730715d0d32445bc57John Reck        struct {
107f29ed28c7b878ef28058bc730715d0d32445bc57John Reck            void* address;
108f29ed28c7b878ef28058bc730715d0d32445bc57John Reck            void* context;
109f29ed28c7b878ef28058bc730715d0d32445bc57John Reck            FreeFunc freeFunc;
110f29ed28c7b878ef28058bc730715d0d32445bc57John Reck        } external;
111f29ed28c7b878ef28058bc730715d0d32445bc57John Reck        struct {
11239d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews            void* address;
11339d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews            int fd;
11439d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews            size_t size;
11539d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews        } ashmem;
11639d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews        struct {
117f29ed28c7b878ef28058bc730715d0d32445bc57John Reck            JavaVM* jvm;
118f29ed28c7b878ef28058bc730715d0d32445bc57John Reck            jweak jweakRef;
119f29ed28c7b878ef28058bc730715d0d32445bc57John Reck            jbyteArray jstrongRef;
120f29ed28c7b878ef28058bc730715d0d32445bc57John Reck        } java;
121f29ed28c7b878ef28058bc730715d0d32445bc57John Reck    } mPixelStorage;
122f29ed28c7b878ef28058bc730715d0d32445bc57John Reck};
123f29ed28c7b878ef28058bc730715d0d32445bc57John Reck
124f29ed28c7b878ef28058bc730715d0d32445bc57John Reck} // namespace android
125f29ed28c7b878ef28058bc730715d0d32445bc57John Reck
126f29ed28c7b878ef28058bc730715d0d32445bc57John Reck#endif /* BITMAP_H_ */
127