LibGfx+LibGUI: Make Gfx::ShareableBitmap transmit indexed palettes
This commit is contained in:
parent
b5d98c0945
commit
8a61aba1e5
Notes:
sideshowbarker
2024-07-18 23:09:37 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/8a61aba1e53
5 changed files with 49 additions and 15 deletions
Userland
Libraries
Services/WindowServer
|
@ -728,7 +728,7 @@ OwnPtr<WindowBackingStore> Window::create_backing_store(const Gfx::IntSize& size
|
|||
return {};
|
||||
}
|
||||
|
||||
auto bitmap = Gfx::Bitmap::create_with_anon_fd(format, anon_fd, size, Gfx::Bitmap::ShouldCloseAnonymousFile::No);
|
||||
auto bitmap = Gfx::Bitmap::create_with_anon_fd(format, anon_fd, size, {}, Gfx::Bitmap::ShouldCloseAnonymousFile::No);
|
||||
if (!bitmap)
|
||||
return {};
|
||||
return make<WindowBackingStore>(bitmap.release_nonnull());
|
||||
|
|
|
@ -115,7 +115,7 @@ RefPtr<Bitmap> Bitmap::create_shareable(BitmapFormat format, const IntSize& size
|
|||
auto anon_fd = anon_create(round_up_to_power_of_two(data_size, PAGE_SIZE), O_CLOEXEC);
|
||||
if (anon_fd < 0)
|
||||
return nullptr;
|
||||
return Bitmap::create_with_anon_fd(format, anon_fd, size, ShouldCloseAnonymousFile::No);
|
||||
return Bitmap::create_with_anon_fd(format, anon_fd, size, {}, ShouldCloseAnonymousFile::No);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -190,7 +190,7 @@ static bool check_size(const IntSize& size, BitmapFormat format, unsigned actual
|
|||
return true;
|
||||
}
|
||||
|
||||
RefPtr<Bitmap> Bitmap::create_with_anon_fd(BitmapFormat format, int anon_fd, const IntSize& size, ShouldCloseAnonymousFile should_close_anon_fd)
|
||||
RefPtr<Bitmap> Bitmap::create_with_anon_fd(BitmapFormat format, int anon_fd, const IntSize& size, const Vector<RGBA32>& palette, ShouldCloseAnonymousFile should_close_anon_fd)
|
||||
{
|
||||
void* data = nullptr;
|
||||
{
|
||||
|
@ -216,7 +216,7 @@ RefPtr<Bitmap> Bitmap::create_with_anon_fd(BitmapFormat format, int anon_fd, con
|
|||
}
|
||||
}
|
||||
|
||||
return adopt(*new Bitmap(format, anon_fd, size, data));
|
||||
return adopt(*new Bitmap(format, anon_fd, size, data, palette));
|
||||
}
|
||||
|
||||
RefPtr<Bitmap> Bitmap::create_with_shared_buffer(BitmapFormat format, NonnullRefPtr<SharedBuffer>&& shared_buffer, const IntSize& size, const Vector<RGBA32>& palette)
|
||||
|
@ -330,7 +330,7 @@ Bitmap::Bitmap(BitmapFormat format, NonnullRefPtr<SharedBuffer>&& shared_buffer,
|
|||
allocate_palette_from_format(m_format, palette);
|
||||
}
|
||||
|
||||
Bitmap::Bitmap(BitmapFormat format, int anon_fd, const IntSize& size, void* data)
|
||||
Bitmap::Bitmap(BitmapFormat format, int anon_fd, const IntSize& size, void* data, const Vector<RGBA32>& palette)
|
||||
: m_size(size)
|
||||
, m_data(data)
|
||||
, m_pitch(minimum_pitch(size.width(), format))
|
||||
|
@ -339,8 +339,11 @@ Bitmap::Bitmap(BitmapFormat format, int anon_fd, const IntSize& size, void* data
|
|||
, m_purgeable(true)
|
||||
, m_anon_fd(anon_fd)
|
||||
{
|
||||
ASSERT(!is_indexed());
|
||||
ASSERT(!is_indexed() || !palette.is_empty());
|
||||
ASSERT(!size_would_overflow(format, size));
|
||||
|
||||
if (is_indexed(m_format))
|
||||
allocate_palette_from_format(m_format, palette);
|
||||
}
|
||||
|
||||
RefPtr<Gfx::Bitmap> Bitmap::clone() const
|
||||
|
@ -430,7 +433,7 @@ RefPtr<Bitmap> Bitmap::to_bitmap_backed_by_anon_fd() const
|
|||
auto anon_fd = anon_create(round_up_to_power_of_two(size_in_bytes(), PAGE_SIZE), O_CLOEXEC);
|
||||
if (anon_fd < 0)
|
||||
return nullptr;
|
||||
auto bitmap = Bitmap::create_with_anon_fd(m_format, anon_fd, m_size, ShouldCloseAnonymousFile::No);
|
||||
auto bitmap = Bitmap::create_with_anon_fd(m_format, anon_fd, m_size, palette_to_vector(), ShouldCloseAnonymousFile::No);
|
||||
if (!bitmap)
|
||||
return nullptr;
|
||||
memcpy(bitmap->scanline(0), scanline(0), size_in_bytes());
|
||||
|
|
|
@ -56,6 +56,21 @@ enum class BitmapFormat {
|
|||
RGBA32,
|
||||
};
|
||||
|
||||
inline bool is_valid_bitmap_format(unsigned format)
|
||||
{
|
||||
switch (format) {
|
||||
case (unsigned)BitmapFormat::Invalid:
|
||||
case (unsigned)BitmapFormat::Indexed1:
|
||||
case (unsigned)BitmapFormat::Indexed2:
|
||||
case (unsigned)BitmapFormat::Indexed4:
|
||||
case (unsigned)BitmapFormat::Indexed8:
|
||||
case (unsigned)BitmapFormat::RGB32:
|
||||
case (unsigned)BitmapFormat::RGBA32:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
enum class StorageFormat {
|
||||
Indexed8,
|
||||
RGB32,
|
||||
|
@ -98,7 +113,7 @@ public:
|
|||
static RefPtr<Bitmap> create_purgeable(BitmapFormat, const IntSize&);
|
||||
static RefPtr<Bitmap> create_wrapper(BitmapFormat, const IntSize&, size_t pitch, void*);
|
||||
static RefPtr<Bitmap> load_from_file(const StringView& path);
|
||||
static RefPtr<Bitmap> create_with_anon_fd(BitmapFormat, int anon_fd, const IntSize&, ShouldCloseAnonymousFile);
|
||||
static RefPtr<Bitmap> create_with_anon_fd(BitmapFormat, int anon_fd, const IntSize&, const Vector<RGBA32>& palette, ShouldCloseAnonymousFile);
|
||||
static RefPtr<Bitmap> create_with_shared_buffer(BitmapFormat, NonnullRefPtr<SharedBuffer>&&, const IntSize&);
|
||||
static RefPtr<Bitmap> create_with_shared_buffer(BitmapFormat, NonnullRefPtr<SharedBuffer>&&, const IntSize&, const Vector<RGBA32>& palette);
|
||||
static RefPtr<Bitmap> create_from_serialized_byte_buffer(ByteBuffer&& buffer);
|
||||
|
@ -241,7 +256,7 @@ private:
|
|||
Bitmap(BitmapFormat, const IntSize&, Purgeable, const BackingStore&);
|
||||
Bitmap(BitmapFormat, const IntSize&, size_t pitch, void*);
|
||||
Bitmap(BitmapFormat, NonnullRefPtr<SharedBuffer>&&, const IntSize&, const Vector<RGBA32>& palette);
|
||||
Bitmap(BitmapFormat, int anon_fd, const IntSize&, void*);
|
||||
Bitmap(BitmapFormat, int anon_fd, const IntSize&, void*, const Vector<RGBA32>& palette);
|
||||
|
||||
static Optional<BackingStore> allocate_backing_store(BitmapFormat, const IntSize&, Purgeable);
|
||||
|
||||
|
|
|
@ -52,9 +52,14 @@ bool encode(Encoder& encoder, const Gfx::ShareableBitmap& shareable_bitmap)
|
|||
encoder << shareable_bitmap.is_valid();
|
||||
if (!shareable_bitmap.is_valid())
|
||||
return true;
|
||||
encoder << IPC::File(shareable_bitmap.bitmap()->anon_fd());
|
||||
encoder << shareable_bitmap.width();
|
||||
encoder << shareable_bitmap.height();
|
||||
auto& bitmap = *shareable_bitmap.bitmap();
|
||||
encoder << IPC::File(bitmap.anon_fd());
|
||||
encoder << bitmap.size();
|
||||
encoder << (u32)bitmap.format();
|
||||
if (bitmap.is_indexed()) {
|
||||
auto palette = bitmap.palette_to_vector();
|
||||
encoder << palette;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -68,13 +73,23 @@ bool decode(Decoder& decoder, Gfx::ShareableBitmap& shareable_bitmap)
|
|||
return true;
|
||||
}
|
||||
IPC::File anon_file;
|
||||
Gfx::IntSize size;
|
||||
if (!decoder.decode(anon_file))
|
||||
return false;
|
||||
Gfx::IntSize size;
|
||||
if (!decoder.decode(size))
|
||||
return false;
|
||||
|
||||
auto bitmap = Gfx::Bitmap::create_with_anon_fd(Gfx::BitmapFormat::RGBA32, anon_file.take_fd(), size, Gfx::Bitmap::ShouldCloseAnonymousFile::Yes);
|
||||
u32 raw_bitmap_format;
|
||||
if (!decoder.decode(raw_bitmap_format))
|
||||
return false;
|
||||
if (!Gfx::is_valid_bitmap_format(raw_bitmap_format))
|
||||
return false;
|
||||
auto bitmap_format = (Gfx::BitmapFormat)raw_bitmap_format;
|
||||
Vector<Gfx::RGBA32> palette;
|
||||
if (Gfx::Bitmap::is_indexed(bitmap_format)) {
|
||||
if (!decoder.decode(palette))
|
||||
return false;
|
||||
}
|
||||
auto bitmap = Gfx::Bitmap::create_with_anon_fd(bitmap_format, anon_file.take_fd(), size, palette, Gfx::Bitmap::ShouldCloseAnonymousFile::Yes);
|
||||
if (!bitmap)
|
||||
return false;
|
||||
shareable_bitmap = Gfx::ShareableBitmap { bitmap.release_nonnull(), Gfx::ShareableBitmap::ConstructWithKnownGoodBitmap };
|
||||
|
|
|
@ -571,6 +571,7 @@ OwnPtr<Messages::WindowServer::SetWindowBackingStoreResponse> ClientConnection::
|
|||
message.has_alpha_channel() ? Gfx::BitmapFormat::RGBA32 : Gfx::BitmapFormat::RGB32,
|
||||
message.anon_file().take_fd(),
|
||||
message.size(),
|
||||
{},
|
||||
Gfx::Bitmap::ShouldCloseAnonymousFile::Yes);
|
||||
window.set_backing_store(move(backing_store), message.serial());
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue