Home | History | Annotate | Download | only in graphics
      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
     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     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