/* * 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 #include #include #include #include #include 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 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_ */