diff --git a/Userland/Libraries/LibGUI/Window.cpp b/Userland/Libraries/LibGUI/Window.cpp index feeeb5a88b..d3ade0736d 100644 --- a/Userland/Libraries/LibGUI/Window.cpp +++ b/Userland/Libraries/LibGUI/Window.cpp @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include @@ -744,7 +743,7 @@ void Window::set_hovered_widget(Widget* widget) void Window::set_current_backing_store(WindowBackingStore& backing_store, bool flush_immediately) { auto& bitmap = backing_store.bitmap(); - WindowServerConnection::the().set_window_backing_store(m_window_id, 32, bitmap.pitch(), bitmap.anon_fd(), backing_store.serial(), bitmap.has_alpha_channel(), bitmap.size(), flush_immediately); + WindowServerConnection::the().set_window_backing_store(m_window_id, 32, bitmap.pitch(), bitmap.anonymous_buffer().fd(), backing_store.serial(), bitmap.has_alpha_channel(), bitmap.size(), flush_immediately); } void Window::flip(const Vector& dirty_rects) @@ -777,14 +776,14 @@ OwnPtr Window::create_backing_store(const Gfx::IntSize& size size_t pitch = Gfx::Bitmap::minimum_pitch(size.width(), format); size_t size_in_bytes = size.height() * pitch; - auto anon_fd = anon_create(round_up_to_power_of_two(size_in_bytes, PAGE_SIZE), O_CLOEXEC); - if (anon_fd < 0) { + auto buffer = Core::AnonymousBuffer::create_with_size(round_up_to_power_of_two(size_in_bytes, PAGE_SIZE)); + if (!buffer.is_valid()) { perror("anon_create"); return {}; } // FIXME: Plumb scale factor here eventually. - auto bitmap = Gfx::Bitmap::create_with_anon_fd(format, anon_fd, size, 1, {}, Gfx::Bitmap::ShouldCloseAnonymousFile::No); + auto bitmap = Gfx::Bitmap::create_with_anonymous_buffer(format, buffer, size, 1, {}); if (!bitmap) return {}; return make(bitmap.release_nonnull()); diff --git a/Userland/Libraries/LibGfx/Bitmap.cpp b/Userland/Libraries/LibGfx/Bitmap.cpp index 7a2e3df1a4..35011614a2 100644 --- a/Userland/Libraries/LibGfx/Bitmap.cpp +++ b/Userland/Libraries/LibGfx/Bitmap.cpp @@ -26,10 +26,6 @@ #include #include -#ifdef __serenity__ -# include -#endif - namespace Gfx { struct BackingStore { @@ -85,7 +81,6 @@ RefPtr Bitmap::create_purgeable(BitmapFormat format, const IntSize& size return adopt_ref(*new Bitmap(format, size, scale_factor, Purgeable::Yes, backing_store.value())); } -#ifdef __serenity__ RefPtr Bitmap::create_shareable(BitmapFormat format, const IntSize& size, int scale_factor) { if (size_would_overflow(format, size, scale_factor)) @@ -94,12 +89,11 @@ RefPtr Bitmap::create_shareable(BitmapFormat format, const IntSize& size const auto pitch = minimum_pitch(size.width() * scale_factor, format); const auto data_size = size_in_bytes(pitch, size.height() * scale_factor); - auto anon_fd = anon_create(round_up_to_power_of_two(data_size, PAGE_SIZE), O_CLOEXEC); - if (anon_fd < 0) + auto buffer = Core::AnonymousBuffer::create_with_size(round_up_to_power_of_two(data_size, PAGE_SIZE)); + if (!buffer.is_valid()) return nullptr; - return Bitmap::create_with_anon_fd(format, anon_fd, size, scale_factor, {}, ShouldCloseAnonymousFile::No); + return Bitmap::create_with_anonymous_buffer(format, buffer, size, scale_factor, {}); } -#endif Bitmap::Bitmap(BitmapFormat format, const IntSize& size, int scale_factor, Purgeable purgeable, const BackingStore& backing_store) : m_size(size) @@ -194,33 +188,12 @@ static bool check_size(const IntSize& size, int scale_factor, BitmapFormat forma return true; } -RefPtr Bitmap::create_with_anon_fd(BitmapFormat format, int anon_fd, const IntSize& size, int scale_factor, const Vector& palette, ShouldCloseAnonymousFile should_close_anon_fd) +RefPtr Bitmap::create_with_anonymous_buffer(BitmapFormat format, Core::AnonymousBuffer buffer, const IntSize& size, int scale_factor, const Vector& palette) { - void* data = nullptr; - { - // If ShouldCloseAnonymousFile::Yes, it's our responsibility to close 'anon_fd' no matter what. - ScopeGuard close_guard = [&] { - if (should_close_anon_fd == ShouldCloseAnonymousFile::Yes) { - int rc = close(anon_fd); - VERIFY(rc == 0); - anon_fd = -1; - } - }; + if (size_would_overflow(format, size, scale_factor)) + return nullptr; - if (size_would_overflow(format, size, scale_factor)) - return nullptr; - - const auto pitch = minimum_pitch(size.width() * scale_factor, format); - const auto data_size_in_bytes = size_in_bytes(pitch, size.height() * scale_factor); - - data = mmap(nullptr, round_up_to_power_of_two(data_size_in_bytes, PAGE_SIZE), PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, anon_fd, 0); - if (data == MAP_FAILED) { - perror("mmap"); - return nullptr; - } - } - - return adopt_ref(*new Bitmap(format, anon_fd, size, scale_factor, data, palette)); + return adopt_ref(*new Bitmap(format, buffer, size, scale_factor, palette)); } /// Read a bitmap as described by: @@ -310,15 +283,14 @@ ByteBuffer Bitmap::serialize_to_byte_buffer() const return buffer; } -Bitmap::Bitmap(BitmapFormat format, int anon_fd, const IntSize& size, int scale_factor, void* data, const Vector& palette) +Bitmap::Bitmap(BitmapFormat format, Core::AnonymousBuffer buffer, const IntSize& size, int scale_factor, const Vector& palette) : m_size(size) , m_scale(scale_factor) - , m_data(data) + , m_data(buffer.data()) , m_pitch(minimum_pitch(size.width() * scale_factor, format)) , m_format(format) - , m_needs_munmap(true) , m_purgeable(true) - , m_anon_fd(anon_fd) + , m_buffer(buffer) { VERIFY(!is_indexed() || !palette.is_empty()); VERIFY(!size_would_overflow(format, size, scale_factor)); @@ -522,21 +494,19 @@ RefPtr Bitmap::cropped(Gfx::IntRect crop) const return new_bitmap; } -#ifdef __serenity__ -RefPtr Bitmap::to_bitmap_backed_by_anon_fd() const +RefPtr Bitmap::to_bitmap_backed_by_anonymous_buffer() const { - if (m_anon_fd != -1) + if (m_buffer.is_valid()) return *this; - auto anon_fd = anon_create(round_up_to_power_of_two(size_in_bytes(), PAGE_SIZE), O_CLOEXEC); - if (anon_fd < 0) + auto buffer = Core::AnonymousBuffer::create_with_size(round_up_to_power_of_two(size_in_bytes(), PAGE_SIZE)); + if (!buffer.is_valid()) return nullptr; - auto bitmap = Bitmap::create_with_anon_fd(m_format, anon_fd, size(), scale(), palette_to_vector(), ShouldCloseAnonymousFile::No); + auto bitmap = Bitmap::create_with_anonymous_buffer(m_format, buffer, size(), scale(), palette_to_vector()); if (!bitmap) return nullptr; memcpy(bitmap->scanline(0), scanline(0), size_in_bytes()); return bitmap; } -#endif Bitmap::~Bitmap() { @@ -544,10 +514,6 @@ Bitmap::~Bitmap() int rc = munmap(m_data, size_in_bytes()); VERIFY(rc == 0); } - if (m_anon_fd != -1) { - int rc = close(m_anon_fd); - VERIFY(rc == 0); - } m_data = nullptr; delete[] m_palette; } @@ -602,15 +568,13 @@ void Bitmap::set_volatile() return rc == 0; } -#ifdef __serenity__ ShareableBitmap Bitmap::to_shareable_bitmap() const { - auto bitmap = to_bitmap_backed_by_anon_fd(); + auto bitmap = to_bitmap_backed_by_anonymous_buffer(); if (!bitmap) return {}; return ShareableBitmap(*bitmap); } -#endif Optional Bitmap::allocate_backing_store(BitmapFormat format, const IntSize& size, int scale_factor, [[maybe_unused]] Purgeable purgeable) { diff --git a/Userland/Libraries/LibGfx/Bitmap.h b/Userland/Libraries/LibGfx/Bitmap.h index 3f606a561d..87f2499f18 100644 --- a/Userland/Libraries/LibGfx/Bitmap.h +++ b/Userland/Libraries/LibGfx/Bitmap.h @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -89,17 +90,12 @@ enum RotationDirection { class Bitmap : public RefCounted { public: - enum class ShouldCloseAnonymousFile { - No, - Yes, - }; - static RefPtr create(BitmapFormat, const IntSize&, int intrinsic_scale = 1); static RefPtr create_shareable(BitmapFormat, const IntSize&, int intrinsic_scale = 1); static RefPtr create_purgeable(BitmapFormat, const IntSize&, int intrinsic_scale = 1); static RefPtr create_wrapper(BitmapFormat, const IntSize&, int intrinsic_scale, size_t pitch, void*); static RefPtr load_from_file(String const& path, int scale_factor = 1); - static RefPtr create_with_anon_fd(BitmapFormat, int anon_fd, const IntSize&, int intrinsic_scale, const Vector& palette, ShouldCloseAnonymousFile); + static RefPtr create_with_anonymous_buffer(BitmapFormat, Core::AnonymousBuffer, const IntSize&, int intrinsic_scale, const Vector& palette); static RefPtr create_from_serialized_byte_buffer(ByteBuffer&& buffer); static bool is_path_a_supported_image_format(const StringView& path) { @@ -119,7 +115,7 @@ public: RefPtr scaled(int sx, int sy) const; RefPtr scaled(float sx, float sy) const; RefPtr cropped(Gfx::IntRect) const; - RefPtr to_bitmap_backed_by_anon_fd() const; + RefPtr to_bitmap_backed_by_anonymous_buffer() const; ByteBuffer serialize_to_byte_buffer() const; ShareableBitmap to_shareable_bitmap() const; @@ -234,7 +230,8 @@ public: void set_volatile(); [[nodiscard]] bool set_nonvolatile(); - int anon_fd() const { return m_anon_fd; } + Core::AnonymousBuffer& anonymous_buffer() { return m_buffer; } + const Core::AnonymousBuffer& anonymous_buffer() const { return m_buffer; } private: enum class Purgeable { @@ -243,7 +240,7 @@ private: }; Bitmap(BitmapFormat, const IntSize&, int, Purgeable, const BackingStore&); Bitmap(BitmapFormat, const IntSize&, int, size_t pitch, void*); - Bitmap(BitmapFormat, int anon_fd, const IntSize&, int, void*, const Vector& palette); + Bitmap(BitmapFormat, Core::AnonymousBuffer, const IntSize&, int, const Vector& palette); static Optional allocate_backing_store(BitmapFormat, const IntSize&, int, Purgeable); @@ -258,7 +255,7 @@ private: bool m_needs_munmap { false }; bool m_purgeable { false }; bool m_volatile { false }; - int m_anon_fd { -1 }; + Core::AnonymousBuffer m_buffer; }; inline u8* Bitmap::scanline_u8(int y) diff --git a/Userland/Libraries/LibGfx/ShareableBitmap.cpp b/Userland/Libraries/LibGfx/ShareableBitmap.cpp index a0c66527f8..76783d5e6c 100644 --- a/Userland/Libraries/LibGfx/ShareableBitmap.cpp +++ b/Userland/Libraries/LibGfx/ShareableBitmap.cpp @@ -14,7 +14,7 @@ namespace Gfx { ShareableBitmap::ShareableBitmap(const Bitmap& bitmap) - : m_bitmap(bitmap.to_bitmap_backed_by_anon_fd()) + : m_bitmap(bitmap.to_bitmap_backed_by_anonymous_buffer()) { } @@ -33,7 +33,7 @@ bool encode(Encoder& encoder, const Gfx::ShareableBitmap& shareable_bitmap) if (!shareable_bitmap.is_valid()) return true; auto& bitmap = *shareable_bitmap.bitmap(); - encoder << IPC::File(bitmap.anon_fd()); + encoder << IPC::File(bitmap.anonymous_buffer().fd()); encoder << bitmap.size(); encoder << bitmap.scale(); encoder << (u32)bitmap.format(); @@ -73,7 +73,10 @@ bool decode(Decoder& decoder, Gfx::ShareableBitmap& shareable_bitmap) if (!decoder.decode(palette)) return false; } - auto bitmap = Gfx::Bitmap::create_with_anon_fd(bitmap_format, anon_file.take_fd(), size, scale, palette, Gfx::Bitmap::ShouldCloseAnonymousFile::Yes); + auto buffer = Core::AnonymousBuffer::create_from_anon_fd(anon_file.take_fd(), Gfx::Bitmap::size_in_bytes(Gfx::Bitmap::minimum_pitch(size.width(), bitmap_format), size.height())); + if (!buffer.is_valid()) + return false; + auto bitmap = Gfx::Bitmap::create_with_anonymous_buffer(bitmap_format, buffer, size, scale, palette); if (!bitmap) return false; shareable_bitmap = Gfx::ShareableBitmap { bitmap.release_nonnull(), Gfx::ShareableBitmap::ConstructWithKnownGoodBitmap }; diff --git a/Userland/Services/WindowServer/ClientConnection.cpp b/Userland/Services/WindowServer/ClientConnection.cpp index 7eaed9ead4..f9bb148463 100644 --- a/Userland/Services/WindowServer/ClientConnection.cpp +++ b/Userland/Services/WindowServer/ClientConnection.cpp @@ -20,7 +20,6 @@ #include #include #include -#include #include #include @@ -587,13 +586,17 @@ void ClientConnection::set_window_backing_store(i32 window_id, [[maybe_unused]] window.swap_backing_stores(); } else { // FIXME: Plumb scale factor here eventually. - auto backing_store = Gfx::Bitmap::create_with_anon_fd( + Core::AnonymousBuffer buffer = Core::AnonymousBuffer::create_from_anon_fd(anon_file.take_fd(), pitch * size.height()); + if (!buffer.is_valid()) { + did_misbehave("SetWindowBackingStore: Failed to create anonymous buffer for window backing store"); + return; + } + auto backing_store = Gfx::Bitmap::create_with_anonymous_buffer( has_alpha_channel ? Gfx::BitmapFormat::BGRA8888 : Gfx::BitmapFormat::BGRx8888, - anon_file.take_fd(), + buffer, size, 1, - {}, - Gfx::Bitmap::ShouldCloseAnonymousFile::Yes); + {}); window.set_backing_store(move(backing_store), serial); }