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.

(cherry picked from commit 3110411c60f0c5f9860ba9de4d229e246afadb62;
amended to fix trivial conflicts arising from serenityos still having an
`intrinsic_scale` argument that ladybird removed. We don't need this
commit for IOSurfaces, but for the use added in
LadybirdBrowser/ladybird#688)
This commit is contained in:
Aliaksandr Kalenik 2024-06-18 02:11:35 +03:00 committed by Nico Weber
parent 38ea81c312
commit 7a88c19975
2 changed files with 12 additions and 10 deletions

View file

@ -91,14 +91,16 @@ Bitmap::Bitmap(BitmapFormat format, IntSize size, int scale_factor, BackingStore
VERIFY(!size_would_overflow(format, size, scale_factor));
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<NonnullRefPtr<Bitmap>> Bitmap::create_wrapper(BitmapFormat format, IntSize size, int scale_factor, size_t pitch, void* data)
ErrorOr<NonnullRefPtr<Bitmap>> Bitmap::create_wrapper(BitmapFormat format, IntSize size, int scale_factor, size_t pitch, void* data, Function<void()>&& destruction_callback)
{
if (size_would_overflow(format, size, scale_factor))
return Error::from_string_literal("Gfx::Bitmap::create_wrapper size overflow");
return adopt_ref(*new Bitmap(format, size, scale_factor, pitch, data));
return adopt_ref(*new Bitmap(format, size, scale_factor, pitch, data, move(destruction_callback)));
}
ErrorOr<NonnullRefPtr<Bitmap>> Bitmap::load_from_file(StringView path, int scale_factor, Optional<IntSize> ideal_size)
@ -154,12 +156,13 @@ ErrorOr<NonnullRefPtr<Bitmap>> 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, int scale_factor, size_t pitch, void* data)
Bitmap::Bitmap(BitmapFormat format, IntSize size, int scale_factor, size_t pitch, void* data, Function<void()>&& destruction_callback)
: m_size(size)
, m_scale(scale_factor)
, m_data(data)
, m_pitch(pitch)
, m_format(format)
, m_destruction_callback(move(destruction_callback))
{
VERIFY(pitch >= minimum_pitch(size.width() * scale_factor, format));
VERIFY(!size_would_overflow(format, size, scale_factor));
@ -548,9 +551,8 @@ ErrorOr<NonnullRefPtr<Gfx::Bitmap>> Bitmap::inverted() const
Bitmap::~Bitmap()
{
if (m_data_is_malloced) {
kfree_sized(m_data, size_in_bytes());
}
if (m_destruction_callback)
m_destruction_callback();
m_data = nullptr;
}

View file

@ -98,7 +98,7 @@ class Bitmap : public RefCounted<Bitmap> {
public:
[[nodiscard]] static ErrorOr<NonnullRefPtr<Bitmap>> create(BitmapFormat, IntSize, int intrinsic_scale = 1);
[[nodiscard]] static ErrorOr<NonnullRefPtr<Bitmap>> create_shareable(BitmapFormat, IntSize, int intrinsic_scale = 1);
[[nodiscard]] static ErrorOr<NonnullRefPtr<Bitmap>> create_wrapper(BitmapFormat, IntSize, int intrinsic_scale, size_t pitch, void*);
[[nodiscard]] static ErrorOr<NonnullRefPtr<Bitmap>> create_wrapper(BitmapFormat, IntSize, int intrinsic_scale, size_t pitch, void*, Function<void()>&& destruction_callback = {});
[[nodiscard]] static ErrorOr<NonnullRefPtr<Bitmap>> load_from_file(StringView path, int scale_factor = 1, Optional<IntSize> ideal_size = {});
[[nodiscard]] static ErrorOr<NonnullRefPtr<Bitmap>> load_from_file(NonnullOwnPtr<Core::File>, StringView path, Optional<IntSize> ideal_size = {});
[[nodiscard]] static ErrorOr<NonnullRefPtr<Bitmap>> load_from_bytes(ReadonlyBytes, Optional<IntSize> ideal_size = {}, Optional<ByteString> mine_type = {});
@ -236,7 +236,7 @@ public:
private:
Bitmap(BitmapFormat, IntSize, int, BackingStore const&);
Bitmap(BitmapFormat, IntSize, int, size_t pitch, void*);
Bitmap(BitmapFormat, IntSize, int, size_t pitch, void*, Function<void()>&& destruction_callback);
Bitmap(BitmapFormat, Core::AnonymousBuffer, IntSize, int);
static ErrorOr<BackingStore> allocate_backing_store(BitmapFormat format, IntSize size, int scale_factor);
@ -246,8 +246,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<void()> m_destruction_callback;
};
ALWAYS_INLINE u8* Bitmap::scanline_u8(int y)