From 24b5295b3038dc0b7a49367476b5b8594268163d Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sat, 24 Jul 2021 18:31:59 +0200 Subject: [PATCH] LibGfx: Remove "purgeable Gfx::Bitmap" as a separate concept This was a really weird thing to begin with, purgeable bitmaps were basically regular bitmaps without a physical memory reservation. Since all the clients of this code ended up populating the bitmaps with pixels immediately after allocating them anyway, there was no need to avoid the reservation. Instead, all Gfx::Bitmaps are now purgeable, in the sense that they can be marked as volatile or non-volatile. The only difference here is that allocation failure is surfaced when we try to create the bitmap instead of during the handling of a subsequent page fault. --- Userland/Libraries/LibGfx/BMPLoader.cpp | 2 +- Userland/Libraries/LibGfx/Bitmap.cpp | 32 ++++--------------- Userland/Libraries/LibGfx/Bitmap.h | 11 ++----- Userland/Libraries/LibGfx/DDSLoader.cpp | 2 +- Userland/Libraries/LibGfx/GIFLoader.cpp | 4 +-- Userland/Libraries/LibGfx/ICOLoader.cpp | 2 +- Userland/Libraries/LibGfx/JPGLoader.cpp | 2 +- Userland/Libraries/LibGfx/PNGLoader.cpp | 4 +-- .../LibGfx/PortableImageLoaderCommon.h | 2 +- 9 files changed, 17 insertions(+), 44 deletions(-) diff --git a/Userland/Libraries/LibGfx/BMPLoader.cpp b/Userland/Libraries/LibGfx/BMPLoader.cpp index 9e13aad455..f1dce58e75 100644 --- a/Userland/Libraries/LibGfx/BMPLoader.cpp +++ b/Userland/Libraries/LibGfx/BMPLoader.cpp @@ -1185,7 +1185,7 @@ static bool decode_bmp_pixel_data(BMPLoadingContext& context) const u32 width = abs(context.dib.core.width); const u32 height = abs(context.dib.core.height); - context.bitmap = Bitmap::try_create_purgeable(format, { static_cast(width), static_cast(height) }); + context.bitmap = Bitmap::try_create(format, { static_cast(width), static_cast(height) }); if (!context.bitmap) { dbgln("BMP appears to have overly large dimensions"); return false; diff --git a/Userland/Libraries/LibGfx/Bitmap.cpp b/Userland/Libraries/LibGfx/Bitmap.cpp index 355941cd58..104aec4462 100644 --- a/Userland/Libraries/LibGfx/Bitmap.cpp +++ b/Userland/Libraries/LibGfx/Bitmap.cpp @@ -67,18 +67,10 @@ static bool size_would_overflow(BitmapFormat format, const IntSize& size, int sc RefPtr Bitmap::try_create(BitmapFormat format, const IntSize& size, int scale_factor) { - auto backing_store = Bitmap::try_allocate_backing_store(format, size, scale_factor, Purgeable::No); + auto backing_store = Bitmap::try_allocate_backing_store(format, size, scale_factor); if (!backing_store.has_value()) return nullptr; - return adopt_ref(*new Bitmap(format, size, scale_factor, Purgeable::No, backing_store.value())); -} - -RefPtr Bitmap::try_create_purgeable(BitmapFormat format, const IntSize& size, int scale_factor) -{ - auto backing_store = Bitmap::try_allocate_backing_store(format, size, scale_factor, Purgeable::Yes); - if (!backing_store.has_value()) - return nullptr; - return adopt_ref(*new Bitmap(format, size, scale_factor, Purgeable::Yes, backing_store.value())); + return adopt_ref(*new Bitmap(format, size, scale_factor, backing_store.value())); } RefPtr Bitmap::try_create_shareable(BitmapFormat format, const IntSize& size, int scale_factor) @@ -95,13 +87,12 @@ RefPtr Bitmap::try_create_shareable(BitmapFormat format, const IntSize& return Bitmap::try_create_with_anonymous_buffer(format, buffer, size, scale_factor, {}); } -Bitmap::Bitmap(BitmapFormat format, const IntSize& size, int scale_factor, Purgeable purgeable, const BackingStore& backing_store) +Bitmap::Bitmap(BitmapFormat format, const IntSize& size, int scale_factor, const BackingStore& backing_store) : m_size(size) , m_scale(scale_factor) , m_data(backing_store.data) , m_pitch(backing_store.pitch) , m_format(format) - , m_purgeable(purgeable == Purgeable::Yes) { VERIFY(!m_size.is_empty()); VERIFY(!size_would_overflow(format, size, scale_factor)); @@ -289,7 +280,6 @@ Bitmap::Bitmap(BitmapFormat format, Core::AnonymousBuffer buffer, const IntSize& , m_data(buffer.data()) , m_pitch(minimum_pitch(size.width() * scale_factor, format)) , m_format(format) - , m_purgeable(true) , m_buffer(move(buffer)) { VERIFY(!is_indexed() || !palette.is_empty()); @@ -301,16 +291,10 @@ Bitmap::Bitmap(BitmapFormat format, Core::AnonymousBuffer buffer, const IntSize& RefPtr Bitmap::clone() const { - RefPtr new_bitmap {}; - if (m_purgeable) { - new_bitmap = Bitmap::try_create_purgeable(format(), size(), scale()); - } else { - new_bitmap = Bitmap::try_create(format(), size(), scale()); - } + auto new_bitmap = Bitmap::try_create(format(), size(), scale()); - if (!new_bitmap) { + if (!new_bitmap) return nullptr; - } VERIFY(size_in_bytes() == new_bitmap->size_in_bytes()); memcpy(new_bitmap->scanline(0), scanline(0), size_in_bytes()); @@ -537,7 +521,6 @@ void Bitmap::fill(Color color) void Bitmap::set_volatile() { - VERIFY(m_purgeable); if (m_volatile) return; #ifdef __serenity__ @@ -552,7 +535,6 @@ void Bitmap::set_volatile() [[nodiscard]] bool Bitmap::set_nonvolatile() { - VERIFY(m_purgeable); if (!m_volatile) return true; #ifdef __serenity__ @@ -576,7 +558,7 @@ ShareableBitmap Bitmap::to_shareable_bitmap() const return ShareableBitmap(*bitmap); } -Optional Bitmap::try_allocate_backing_store(BitmapFormat format, IntSize const& size, int scale_factor, [[maybe_unused]] Purgeable purgeable) +Optional Bitmap::try_allocate_backing_store(BitmapFormat format, IntSize const& size, int scale_factor) { if (size_would_overflow(format, size, scale_factor)) return {}; @@ -585,8 +567,6 @@ Optional Bitmap::try_allocate_backing_store(BitmapFormat format, I const auto data_size_in_bytes = size_in_bytes(pitch, size.height() * scale_factor); int map_flags = MAP_ANONYMOUS | MAP_PRIVATE; - if (purgeable == Purgeable::Yes) - map_flags |= MAP_NORESERVE; #ifdef __serenity__ void* data = mmap_with_name(nullptr, data_size_in_bytes, PROT_READ | PROT_WRITE, map_flags, 0, 0, String::formatted("GraphicsBitmap [{}]", size).characters()); #else diff --git a/Userland/Libraries/LibGfx/Bitmap.h b/Userland/Libraries/LibGfx/Bitmap.h index b08622f6c3..5481adb278 100644 --- a/Userland/Libraries/LibGfx/Bitmap.h +++ b/Userland/Libraries/LibGfx/Bitmap.h @@ -92,7 +92,6 @@ class Bitmap : public RefCounted { public: [[nodiscard]] static RefPtr try_create(BitmapFormat, const IntSize&, int intrinsic_scale = 1); [[nodiscard]] static RefPtr try_create_shareable(BitmapFormat, const IntSize&, int intrinsic_scale = 1); - [[nodiscard]] static RefPtr try_create_purgeable(BitmapFormat, const IntSize&, int intrinsic_scale = 1); [[nodiscard]] static RefPtr try_create_wrapper(BitmapFormat, const IntSize&, int intrinsic_scale, size_t pitch, void*); [[nodiscard]] static RefPtr try_load_from_file(String const& path, int scale_factor = 1); [[nodiscard]] static RefPtr try_create_with_anonymous_buffer(BitmapFormat, Core::AnonymousBuffer, const IntSize&, int intrinsic_scale, const Vector& palette); @@ -226,7 +225,6 @@ public: set_pixel(physical_position.x(), physical_position.y(), color); } - [[nodiscard]] bool is_purgeable() const { return m_purgeable; } [[nodiscard]] bool is_volatile() const { return m_volatile; } void set_volatile(); [[nodiscard]] bool set_nonvolatile(); @@ -235,15 +233,11 @@ public: [[nodiscard]] Core::AnonymousBuffer const& anonymous_buffer() const { return m_buffer; } private: - enum class Purgeable { - No, - Yes - }; - Bitmap(BitmapFormat, const IntSize&, int, Purgeable, const BackingStore&); + Bitmap(BitmapFormat, IntSize const&, int, BackingStore const&); Bitmap(BitmapFormat, const IntSize&, int, size_t pitch, void*); Bitmap(BitmapFormat, Core::AnonymousBuffer, const IntSize&, int, const Vector& palette); - static Optional try_allocate_backing_store(BitmapFormat format, IntSize const& size, int scale_factor, Purgeable); + static Optional try_allocate_backing_store(BitmapFormat format, IntSize const& size, int scale_factor); void allocate_palette_from_format(BitmapFormat, const Vector& source_palette); @@ -254,7 +248,6 @@ private: size_t m_pitch { 0 }; BitmapFormat m_format { BitmapFormat::Invalid }; bool m_needs_munmap { false }; - bool m_purgeable { false }; bool m_volatile { false }; Core::AnonymousBuffer m_buffer; }; diff --git a/Userland/Libraries/LibGfx/DDSLoader.cpp b/Userland/Libraries/LibGfx/DDSLoader.cpp index 43a28d9d4d..5d0a22c31d 100644 --- a/Userland/Libraries/LibGfx/DDSLoader.cpp +++ b/Userland/Libraries/LibGfx/DDSLoader.cpp @@ -792,7 +792,7 @@ static bool decode_dds(DDSLoadingContext& context) dbgln_if(DDS_DEBUG, "There are {} bytes remaining, we need {} for mipmap level {} of the image", stream.remaining(), needed_bytes, mipmap_level); VERIFY(stream.remaining() >= needed_bytes); - context.bitmap = Bitmap::try_create_purgeable(BitmapFormat::BGRA8888, { width, height }); + context.bitmap = Bitmap::try_create(BitmapFormat::BGRA8888, { width, height }); decode_bitmap(stream, context, format, width, height); diff --git a/Userland/Libraries/LibGfx/GIFLoader.cpp b/Userland/Libraries/LibGfx/GIFLoader.cpp index 2db9ec6060..fa47e9a0f8 100644 --- a/Userland/Libraries/LibGfx/GIFLoader.cpp +++ b/Userland/Libraries/LibGfx/GIFLoader.cpp @@ -299,10 +299,10 @@ static bool decode_frame(GIFLoadingContext& context, size_t frame_index) size_t start_frame = context.current_frame + 1; if (context.state < GIFLoadingContext::State::FrameComplete) { start_frame = 0; - context.frame_buffer = Bitmap::try_create_purgeable(BitmapFormat::BGRA8888, { context.logical_screen.width, context.logical_screen.height }); + context.frame_buffer = Bitmap::try_create(BitmapFormat::BGRA8888, { context.logical_screen.width, context.logical_screen.height }); if (!context.frame_buffer) return false; - context.prev_frame_buffer = Bitmap::try_create_purgeable(BitmapFormat::BGRA8888, { context.logical_screen.width, context.logical_screen.height }); + context.prev_frame_buffer = Bitmap::try_create(BitmapFormat::BGRA8888, { context.logical_screen.width, context.logical_screen.height }); if (!context.prev_frame_buffer) return false; } else if (frame_index < context.current_frame) { diff --git a/Userland/Libraries/LibGfx/ICOLoader.cpp b/Userland/Libraries/LibGfx/ICOLoader.cpp index e9d458c345..ad94fe652e 100644 --- a/Userland/Libraries/LibGfx/ICOLoader.cpp +++ b/Userland/Libraries/LibGfx/ICOLoader.cpp @@ -246,7 +246,7 @@ static bool load_ico_bmp(ICOLoadingContext& context, ICOImageDescriptor& desc) return false; } - desc.bitmap = Bitmap::try_create_purgeable(BitmapFormat::BGRA8888, { desc.width, desc.height }); + desc.bitmap = Bitmap::try_create(BitmapFormat::BGRA8888, { desc.width, desc.height }); if (!desc.bitmap) return false; Bitmap& bitmap = *desc.bitmap; diff --git a/Userland/Libraries/LibGfx/JPGLoader.cpp b/Userland/Libraries/LibGfx/JPGLoader.cpp index 3d784f85c2..9e0239e67a 100644 --- a/Userland/Libraries/LibGfx/JPGLoader.cpp +++ b/Userland/Libraries/LibGfx/JPGLoader.cpp @@ -1064,7 +1064,7 @@ static void ycbcr_to_rgb(const JPGLoadingContext& context, Vector& m static bool compose_bitmap(JPGLoadingContext& context, const Vector& macroblocks) { - context.bitmap = Bitmap::try_create_purgeable(BitmapFormat::BGRx8888, { context.frame.width, context.frame.height }); + context.bitmap = Bitmap::try_create(BitmapFormat::BGRx8888, { context.frame.width, context.frame.height }); if (!context.bitmap) return false; diff --git a/Userland/Libraries/LibGfx/PNGLoader.cpp b/Userland/Libraries/LibGfx/PNGLoader.cpp index d40ba7591f..760b0cba91 100644 --- a/Userland/Libraries/LibGfx/PNGLoader.cpp +++ b/Userland/Libraries/LibGfx/PNGLoader.cpp @@ -606,7 +606,7 @@ static bool decode_png_bitmap_simple(PNGLoadingContext& context) } } - context.bitmap = Bitmap::try_create_purgeable(context.has_alpha() ? BitmapFormat::BGRA8888 : BitmapFormat::BGRx8888, { context.width, context.height }); + context.bitmap = Bitmap::try_create(context.has_alpha() ? BitmapFormat::BGRA8888 : BitmapFormat::BGRx8888, { context.width, context.height }); if (!context.bitmap) { context.state = PNGLoadingContext::State::Error; @@ -726,7 +726,7 @@ static bool decode_adam7_pass(PNGLoadingContext& context, Streamer& streamer, in static bool decode_png_adam7(PNGLoadingContext& context) { Streamer streamer(context.decompression_buffer->data(), context.decompression_buffer->size()); - context.bitmap = Bitmap::try_create_purgeable(context.has_alpha() ? BitmapFormat::BGRA8888 : BitmapFormat::BGRx8888, { context.width, context.height }); + context.bitmap = Bitmap::try_create(context.has_alpha() ? BitmapFormat::BGRA8888 : BitmapFormat::BGRx8888, { context.width, context.height }); if (!context.bitmap) return false; diff --git a/Userland/Libraries/LibGfx/PortableImageLoaderCommon.h b/Userland/Libraries/LibGfx/PortableImageLoaderCommon.h index ac1793b25d..0130f07654 100644 --- a/Userland/Libraries/LibGfx/PortableImageLoaderCommon.h +++ b/Userland/Libraries/LibGfx/PortableImageLoaderCommon.h @@ -178,7 +178,7 @@ static bool read_max_val(TContext& context, Streamer& streamer) template static bool create_bitmap(TContext& context) { - context.bitmap = Bitmap::try_create_purgeable(BitmapFormat::BGRx8888, { context.width, context.height }); + context.bitmap = Bitmap::try_create(BitmapFormat::BGRx8888, { context.width, context.height }); if (!context.bitmap) { context.state = TContext::State::Error; return false;