From 3110411c60f0c5f9860ba9de4d229e246afadb62 Mon Sep 17 00:00:00 2001 From: Aliaksandr Kalenik Date: Tue, 18 Jun 2024 02:11:35 +0300 Subject: [PATCH] LibGfx: Add release callback for Bitmap In upcoming changes, bitmap is going to be used to wrap the memory of the IOSurface, and we will want to release the corresponding IOSurface along with the bitmap. --- Userland/Libraries/LibGfx/Bitmap.cpp | 16 +++++++++------- Userland/Libraries/LibGfx/Bitmap.h | 6 +++--- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/Userland/Libraries/LibGfx/Bitmap.cpp b/Userland/Libraries/LibGfx/Bitmap.cpp index 70cbcd5e99b..aa9cabd30ae 100644 --- a/Userland/Libraries/LibGfx/Bitmap.cpp +++ b/Userland/Libraries/LibGfx/Bitmap.cpp @@ -84,14 +84,16 @@ Bitmap::Bitmap(BitmapFormat format, IntSize size, BackingStore const& backing_st VERIFY(!size_would_overflow(format, size)); VERIFY(m_data); VERIFY(backing_store.size_in_bytes == size_in_bytes()); - m_data_is_malloced = true; + m_destruction_callback = [data = m_data, size_in_bytes = this->size_in_bytes()] { + kfree_sized(data, size_in_bytes); + }; } -ErrorOr> Bitmap::create_wrapper(BitmapFormat format, IntSize size, size_t pitch, void* data) +ErrorOr> Bitmap::create_wrapper(BitmapFormat format, IntSize size, size_t pitch, void* data, Function&& destruction_callback) { if (size_would_overflow(format, size)) return Error::from_string_literal("Gfx::Bitmap::create_wrapper size overflow"); - return adopt_ref(*new Bitmap(format, size, pitch, data)); + return adopt_ref(*new Bitmap(format, size, pitch, data, move(destruction_callback))); } ErrorOr> Bitmap::load_from_file(StringView path, Optional ideal_size) @@ -118,11 +120,12 @@ ErrorOr> Bitmap::load_from_bytes(ReadonlyBytes bytes, Opti return Error::from_string_literal("Gfx::Bitmap unable to load from file"); } -Bitmap::Bitmap(BitmapFormat format, IntSize size, size_t pitch, void* data) +Bitmap::Bitmap(BitmapFormat format, IntSize size, size_t pitch, void* data, Function&& destruction_callback) : m_size(size) , m_data(data) , m_pitch(pitch) , m_format(format) + , m_destruction_callback(move(destruction_callback)) { VERIFY(pitch >= minimum_pitch(size.width(), format)); VERIFY(!size_would_overflow(format, size)); @@ -368,9 +371,8 @@ ErrorOr> Bitmap::to_bitmap_backed_by_anonymous_buffer() co Bitmap::~Bitmap() { - if (m_data_is_malloced) { - kfree_sized(m_data, size_in_bytes()); - } + if (m_destruction_callback) + m_destruction_callback(); m_data = nullptr; } diff --git a/Userland/Libraries/LibGfx/Bitmap.h b/Userland/Libraries/LibGfx/Bitmap.h index a2b50d42a90..3d183e531a4 100644 --- a/Userland/Libraries/LibGfx/Bitmap.h +++ b/Userland/Libraries/LibGfx/Bitmap.h @@ -63,7 +63,7 @@ class Bitmap : public RefCounted { public: [[nodiscard]] static ErrorOr> create(BitmapFormat, IntSize); [[nodiscard]] static ErrorOr> create_shareable(BitmapFormat, IntSize); - [[nodiscard]] static ErrorOr> create_wrapper(BitmapFormat, IntSize, size_t pitch, void*); + [[nodiscard]] static ErrorOr> create_wrapper(BitmapFormat, IntSize, size_t pitch, void*, Function&& destruction_callback = {}); [[nodiscard]] static ErrorOr> load_from_file(StringView path, Optional ideal_size = {}); [[nodiscard]] static ErrorOr> load_from_file(NonnullOwnPtr, StringView path, Optional ideal_size = {}); [[nodiscard]] static ErrorOr> load_from_bytes(ReadonlyBytes, Optional ideal_size = {}, Optional mine_type = {}); @@ -160,7 +160,7 @@ public: private: Bitmap(BitmapFormat, IntSize, BackingStore const&); - Bitmap(BitmapFormat, IntSize, size_t pitch, void*); + Bitmap(BitmapFormat, IntSize, size_t pitch, void*, Function&& destruction_callback); Bitmap(BitmapFormat, Core::AnonymousBuffer, IntSize); static ErrorOr allocate_backing_store(BitmapFormat format, IntSize size); @@ -169,8 +169,8 @@ private: void* m_data { nullptr }; size_t m_pitch { 0 }; BitmapFormat m_format { BitmapFormat::Invalid }; - bool m_data_is_malloced { false }; Core::AnonymousBuffer m_buffer; + Function m_destruction_callback; }; ALWAYS_INLINE u8* Bitmap::scanline_u8(int y)