mirror of
https://github.com/zebrajr/ladybird.git
synced 2025-12-06 12:20:00 +01:00
LibGfx: Don't create AnonymousBuffer for each bitmap in BitmapSequence
When decoding a BitmapSequence received over IPC, we were creating an AnonymousBuffer for each bitmap and then making a Gfx::Bitmap wrapper around it. This was unnecessarily using up one file descriptor per bitmap, and also wasting a lot of memory for small bitmaps since we always allocated at least one VM page. This patch changes the BitmapSequence decoder to use malloc memory instead, saving file descriptors and using less memory overall.
This commit is contained in:
parent
3593c3b687
commit
4f684bb4c9
|
|
@ -127,6 +127,16 @@ ErrorOr<NonnullRefPtr<Bitmap>> Bitmap::create_with_anonymous_buffer(BitmapFormat
|
|||
return adopt_nonnull_ref_or_enomem(new (nothrow) Bitmap(format, alpha_type, move(buffer), size));
|
||||
}
|
||||
|
||||
ErrorOr<NonnullRefPtr<Bitmap>> Bitmap::create_with_raw_data(BitmapFormat format, AlphaType alpha_type, ReadonlyBytes raw_data, IntSize size)
|
||||
{
|
||||
if (size_would_overflow(format, size))
|
||||
return Error::from_string_literal("Gfx::Bitmap::create_with_raw_data size overflow");
|
||||
|
||||
auto backing_store = TRY(Bitmap::allocate_backing_store(format, size, InitializeBackingStore::No));
|
||||
raw_data.copy_to(Bytes { backing_store.data, backing_store.size_in_bytes });
|
||||
return AK::adopt_nonnull_ref_or_enomem(new (nothrow) Bitmap(format, alpha_type, size, backing_store));
|
||||
}
|
||||
|
||||
Bitmap::Bitmap(BitmapFormat format, AlphaType alpha_type, Core::AnonymousBuffer buffer, IntSize size)
|
||||
: m_size(size)
|
||||
, m_data(buffer.data<void>())
|
||||
|
|
@ -242,7 +252,7 @@ Gfx::ShareableBitmap Bitmap::to_shareable_bitmap() const
|
|||
return Gfx::ShareableBitmap { bitmap_or_error.release_value_but_fixme_should_propagate_errors(), Gfx::ShareableBitmap::ConstructWithKnownGoodBitmap };
|
||||
}
|
||||
|
||||
ErrorOr<BackingStore> Bitmap::allocate_backing_store(BitmapFormat format, IntSize size)
|
||||
ErrorOr<BackingStore> Bitmap::allocate_backing_store(BitmapFormat format, IntSize size, InitializeBackingStore initialize_backing_store)
|
||||
{
|
||||
if (size.is_empty())
|
||||
return Error::from_string_literal("Gfx::Bitmap backing store size is empty");
|
||||
|
|
@ -253,7 +263,11 @@ ErrorOr<BackingStore> Bitmap::allocate_backing_store(BitmapFormat format, IntSiz
|
|||
auto const pitch = minimum_pitch(size.width(), format);
|
||||
auto const data_size_in_bytes = size_in_bytes(pitch, size.height());
|
||||
|
||||
void* data = kcalloc(1, data_size_in_bytes);
|
||||
void* data;
|
||||
if (initialize_backing_store == InitializeBackingStore::Yes)
|
||||
data = kcalloc(1, data_size_in_bytes);
|
||||
else
|
||||
data = kmalloc(data_size_in_bytes);
|
||||
if (data == nullptr)
|
||||
return Error::from_errno(errno);
|
||||
return BackingStore { data, pitch, data_size_in_bytes };
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2024, Andreas Kling <andreas@ladybird.org>
|
||||
* Copyright (c) 2018-2025, Andreas Kling <andreas@ladybird.org>
|
||||
* Copyright (c) 2022, Timothy Slater <tslater2006@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
|
|
@ -70,6 +70,7 @@ public:
|
|||
[[nodiscard]] static ErrorOr<NonnullRefPtr<Bitmap>> create(BitmapFormat, AlphaType, IntSize);
|
||||
[[nodiscard]] static ErrorOr<NonnullRefPtr<Bitmap>> create_shareable(BitmapFormat, AlphaType, IntSize);
|
||||
[[nodiscard]] static ErrorOr<NonnullRefPtr<Bitmap>> create_wrapper(BitmapFormat, AlphaType, IntSize, size_t pitch, void*, Function<void()>&& destruction_callback = {});
|
||||
[[nodiscard]] static ErrorOr<NonnullRefPtr<Bitmap>> create_with_raw_data(BitmapFormat, AlphaType, ReadonlyBytes, IntSize);
|
||||
[[nodiscard]] static ErrorOr<NonnullRefPtr<Bitmap>> create_with_anonymous_buffer(BitmapFormat, AlphaType, Core::AnonymousBuffer, IntSize);
|
||||
|
||||
ErrorOr<NonnullRefPtr<Gfx::Bitmap>> clone() const;
|
||||
|
|
@ -172,7 +173,11 @@ private:
|
|||
Bitmap(BitmapFormat, AlphaType, IntSize, size_t pitch, void*, Function<void()>&& destruction_callback);
|
||||
Bitmap(BitmapFormat, AlphaType, Core::AnonymousBuffer, IntSize);
|
||||
|
||||
static ErrorOr<BackingStore> allocate_backing_store(BitmapFormat format, IntSize size);
|
||||
enum class InitializeBackingStore {
|
||||
No,
|
||||
Yes,
|
||||
};
|
||||
static ErrorOr<BackingStore> allocate_backing_store(BitmapFormat format, IntSize size, InitializeBackingStore = InitializeBackingStore::Yes);
|
||||
|
||||
IntSize m_size;
|
||||
void* m_data { nullptr };
|
||||
|
|
|
|||
|
|
@ -128,14 +128,9 @@ ErrorOr<Gfx::BitmapSequence> decode(Decoder& decoder)
|
|||
if (size_check.has_overflow() || size_check.value() > bytes.size())
|
||||
return Error::from_string_literal("IPC: Invalid Gfx::BitmapSequence buffer data");
|
||||
|
||||
auto buffer = TRY(Core::AnonymousBuffer::create_with_size(size_in_bytes));
|
||||
auto buffer_bytes = Bytes { buffer.data<u8>(), buffer.size() };
|
||||
|
||||
bytes.slice(bytes_read, size_in_bytes).copy_to(buffer_bytes);
|
||||
|
||||
auto slice = bytes.slice(bytes_read, size_in_bytes);
|
||||
bytes_read += size_in_bytes;
|
||||
|
||||
bitmap = TRY(Gfx::Bitmap::create_with_anonymous_buffer(metadata.format, metadata.alpha_type, move(buffer), metadata.size));
|
||||
bitmap = TRY(Gfx::Bitmap::create_with_raw_data(metadata.format, metadata.alpha_type, slice, metadata.size));
|
||||
}
|
||||
|
||||
bitmaps.append(bitmap);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user