| /* |
| * Copyright (C) 2015 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| #ifndef BITMAP_H_ |
| #define BITMAP_H_ |
| |
| #include <jni.h> |
| #include <SkBitmap.h> |
| #include <SkColorTable.h> |
| #include <SkImageInfo.h> |
| #include <utils/Mutex.h> |
| #include <memory> |
| |
| namespace android { |
| |
| enum class PixelStorageType { |
| Invalid, |
| External, |
| Java, |
| Ashmem, |
| }; |
| |
| class WrappedPixelRef; |
| |
| typedef void (*FreeFunc)(void* addr, void* context); |
| |
| /** |
| * Glue-thingy that deals with managing the interaction between the Java |
| * Bitmap object & SkBitmap along with trying to map a notion of strong/weak |
| * lifecycles onto SkPixelRef which only has strong counts to avoid requiring |
| * two GC passes to free the byte[] that backs a Bitmap. |
| * |
| * Since not all Bitmaps are byte[]-backed it also supports external allocations, |
| * which currently is used by screenshots to wrap a gralloc buffer. |
| */ |
| class Bitmap { |
| public: |
| Bitmap(JNIEnv* env, jbyteArray storageObj, void* address, |
| const SkImageInfo& info, size_t rowBytes, SkColorTable* ctable); |
| Bitmap(void* address, void* context, FreeFunc freeFunc, |
| const SkImageInfo& info, size_t rowBytes, SkColorTable* ctable); |
| Bitmap(void* address, int fd, const SkImageInfo& info, size_t rowBytes, |
| SkColorTable* ctable); |
| |
| const SkImageInfo& info() const; |
| |
| // Returns nullptr if it is not backed by a jbyteArray |
| jbyteArray javaByteArray() const { |
| return mPixelStorageType == PixelStorageType::Java |
| ? mPixelStorage.java.jstrongRef : nullptr; |
| } |
| |
| int width() const { return info().width(); } |
| int height() const { return info().height(); } |
| size_t rowBytes() const; |
| SkPixelRef* peekAtPixelRef() const; |
| SkPixelRef* refPixelRef(); |
| bool valid() const { return mPixelStorageType != PixelStorageType::Invalid; } |
| |
| void reconfigure(const SkImageInfo& info, size_t rowBytes, SkColorTable* ctable); |
| void reconfigure(const SkImageInfo& info); |
| void setAlphaType(SkAlphaType alphaType); |
| |
| void getSkBitmap(SkBitmap* outBitmap); |
| void detachFromJava(); |
| |
| void freePixels(); |
| |
| bool hasHardwareMipMap(); |
| void setHasHardwareMipMap(bool hasMipMap); |
| int getAshmemFd() const; |
| |
| private: |
| friend class WrappedPixelRef; |
| |
| ~Bitmap(); |
| void doFreePixels(); |
| void onStrongRefDestroyed(); |
| |
| void pinPixelsLocked(); |
| void unpinPixelsLocked(); |
| JNIEnv* jniEnv(); |
| bool shouldDisposeSelfLocked(); |
| void assertValid() const; |
| SkPixelRef* refPixelRefLocked(); |
| |
| android::Mutex mLock; |
| int mPinnedRefCount = 0; |
| std::unique_ptr<WrappedPixelRef> mPixelRef; |
| PixelStorageType mPixelStorageType; |
| bool mAttachedToJava = true; |
| |
| union { |
| struct { |
| void* address; |
| void* context; |
| FreeFunc freeFunc; |
| } external; |
| struct { |
| void* address; |
| int fd; |
| size_t size; |
| } ashmem; |
| struct { |
| JavaVM* jvm; |
| jweak jweakRef; |
| jbyteArray jstrongRef; |
| } java; |
| } mPixelStorage; |
| }; |
| |
| } // namespace android |
| |
| #endif /* BITMAP_H_ */ |