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