From cd7cc37fd395d88f92bd2ff97a5e968313d23865 Mon Sep 17 00:00:00 2001 From: Lorenzo Blasa Date: Tue, 27 Sep 2022 13:00:04 -0700 Subject: [PATCH] Bitmap pool Summary: Bitmaps are not cheap to create. Also, bitmaps are used from the main thread to capture the contents of a view but can be used and processed by background threads. BitmapPool aims to solve both problems. - It is a pool that can be used to recycle bitmaps. - The recyclable bitmap can be processed by a background thread which can explicitly recycle the bitmap once done with it, hence putting it back into the pool. UPDATE: D39815821 That diff changes the approach by defining a single default pool which can handle bitmaps of different sizes. Reviewed By: LukeDefeo Differential Revision: D39812212 fbshipit-source-id: 065eea656f4139aeb9d09cd5a5c7dddfc9c8edfd --- .../plugins/uidebugger/common/BitmapPool.kt | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 android/src/main/java/com/facebook/flipper/plugins/uidebugger/common/BitmapPool.kt diff --git a/android/src/main/java/com/facebook/flipper/plugins/uidebugger/common/BitmapPool.kt b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/common/BitmapPool.kt new file mode 100644 index 000000000..3e44989c7 --- /dev/null +++ b/android/src/main/java/com/facebook/flipper/plugins/uidebugger/common/BitmapPool.kt @@ -0,0 +1,65 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +package com.facebook.flipper.plugins.uidebugger.common + +import android.graphics.Bitmap +import android.os.Handler +import android.os.Looper + +class BitmapPool( + private val width: Int, + private val height: Int, + private val config: Bitmap.Config = Bitmap.Config.RGB_565 +) { + + interface RecyclableBitmap { + val bitmap: Bitmap? + fun recycle() + } + + private var handler: Handler = Handler(Looper.getMainLooper()) + + private val bitmaps: MutableList = mutableListOf() + private var isRecycled = false + + fun recycle() { + isRecycled = true + bitmaps.forEach { bitmap -> bitmap.recycle() } + bitmaps.clear() + } + + fun getBitmap(): RecyclableBitmap { + return if (bitmaps.isEmpty()) { + LeasedBitmap(Bitmap.createBitmap(width, height, config)) + } else { + LeasedBitmap(bitmaps.removeLast()) + } + } + + inner class LeasedBitmap(override val bitmap: Bitmap) : RecyclableBitmap { + override fun recycle() { + handler.post { + if (isRecycled) { + bitmap.recycle() + } else { + bitmaps.add(bitmap) + } + } + } + } + + companion object { + fun createBitmap(width: Int, height: Int, config: Bitmap.Config): Bitmap { + return Bitmap.createBitmap(width, height, config) + } + + fun createBitmapWithDefaultConfig(width: Int, height: Int): Bitmap { + return Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565) + } + } +}