mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 20:57:35 +00:00
LibGfx+LibGUI: Make Gfx::ShareableBitmap transmit indexed palettes
This commit is contained in:
parent
b5d98c0945
commit
8a61aba1e5
5 changed files with 49 additions and 15 deletions
|
@ -728,7 +728,7 @@ OwnPtr<WindowBackingStore> Window::create_backing_store(const Gfx::IntSize& size
|
||||||
return {};
|
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)
|
if (!bitmap)
|
||||||
return {};
|
return {};
|
||||||
return make<WindowBackingStore>(bitmap.release_nonnull());
|
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);
|
auto anon_fd = anon_create(round_up_to_power_of_two(data_size, PAGE_SIZE), O_CLOEXEC);
|
||||||
if (anon_fd < 0)
|
if (anon_fd < 0)
|
||||||
return nullptr;
|
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
|
#endif
|
||||||
|
|
||||||
|
@ -190,7 +190,7 @@ static bool check_size(const IntSize& size, BitmapFormat format, unsigned actual
|
||||||
return true;
|
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;
|
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)
|
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);
|
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_size(size)
|
||||||
, m_data(data)
|
, m_data(data)
|
||||||
, m_pitch(minimum_pitch(size.width(), format))
|
, 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_purgeable(true)
|
||||||
, m_anon_fd(anon_fd)
|
, m_anon_fd(anon_fd)
|
||||||
{
|
{
|
||||||
ASSERT(!is_indexed());
|
ASSERT(!is_indexed() || !palette.is_empty());
|
||||||
ASSERT(!size_would_overflow(format, size));
|
ASSERT(!size_would_overflow(format, size));
|
||||||
|
|
||||||
|
if (is_indexed(m_format))
|
||||||
|
allocate_palette_from_format(m_format, palette);
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<Gfx::Bitmap> Bitmap::clone() const
|
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);
|
auto anon_fd = anon_create(round_up_to_power_of_two(size_in_bytes(), PAGE_SIZE), O_CLOEXEC);
|
||||||
if (anon_fd < 0)
|
if (anon_fd < 0)
|
||||||
return nullptr;
|
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)
|
if (!bitmap)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
memcpy(bitmap->scanline(0), scanline(0), size_in_bytes());
|
memcpy(bitmap->scanline(0), scanline(0), size_in_bytes());
|
||||||
|
|
|
@ -56,6 +56,21 @@ enum class BitmapFormat {
|
||||||
RGBA32,
|
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 {
|
enum class StorageFormat {
|
||||||
Indexed8,
|
Indexed8,
|
||||||
RGB32,
|
RGB32,
|
||||||
|
@ -98,7 +113,7 @@ public:
|
||||||
static RefPtr<Bitmap> create_purgeable(BitmapFormat, const IntSize&);
|
static RefPtr<Bitmap> create_purgeable(BitmapFormat, const IntSize&);
|
||||||
static RefPtr<Bitmap> create_wrapper(BitmapFormat, const IntSize&, size_t pitch, void*);
|
static RefPtr<Bitmap> create_wrapper(BitmapFormat, const IntSize&, size_t pitch, void*);
|
||||||
static RefPtr<Bitmap> load_from_file(const StringView& path);
|
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&);
|
||||||
static RefPtr<Bitmap> create_with_shared_buffer(BitmapFormat, NonnullRefPtr<SharedBuffer>&&, const IntSize&, const Vector<RGBA32>& palette);
|
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);
|
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&, Purgeable, const BackingStore&);
|
||||||
Bitmap(BitmapFormat, const IntSize&, size_t pitch, void*);
|
Bitmap(BitmapFormat, const IntSize&, size_t pitch, void*);
|
||||||
Bitmap(BitmapFormat, NonnullRefPtr<SharedBuffer>&&, const IntSize&, const Vector<RGBA32>& palette);
|
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);
|
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();
|
encoder << shareable_bitmap.is_valid();
|
||||||
if (!shareable_bitmap.is_valid())
|
if (!shareable_bitmap.is_valid())
|
||||||
return true;
|
return true;
|
||||||
encoder << IPC::File(shareable_bitmap.bitmap()->anon_fd());
|
auto& bitmap = *shareable_bitmap.bitmap();
|
||||||
encoder << shareable_bitmap.width();
|
encoder << IPC::File(bitmap.anon_fd());
|
||||||
encoder << shareable_bitmap.height();
|
encoder << bitmap.size();
|
||||||
|
encoder << (u32)bitmap.format();
|
||||||
|
if (bitmap.is_indexed()) {
|
||||||
|
auto palette = bitmap.palette_to_vector();
|
||||||
|
encoder << palette;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,13 +73,23 @@ bool decode(Decoder& decoder, Gfx::ShareableBitmap& shareable_bitmap)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
IPC::File anon_file;
|
IPC::File anon_file;
|
||||||
Gfx::IntSize size;
|
|
||||||
if (!decoder.decode(anon_file))
|
if (!decoder.decode(anon_file))
|
||||||
return false;
|
return false;
|
||||||
|
Gfx::IntSize size;
|
||||||
if (!decoder.decode(size))
|
if (!decoder.decode(size))
|
||||||
return false;
|
return false;
|
||||||
|
u32 raw_bitmap_format;
|
||||||
auto bitmap = Gfx::Bitmap::create_with_anon_fd(Gfx::BitmapFormat::RGBA32, anon_file.take_fd(), size, Gfx::Bitmap::ShouldCloseAnonymousFile::Yes);
|
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)
|
if (!bitmap)
|
||||||
return false;
|
return false;
|
||||||
shareable_bitmap = Gfx::ShareableBitmap { bitmap.release_nonnull(), Gfx::ShareableBitmap::ConstructWithKnownGoodBitmap };
|
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.has_alpha_channel() ? Gfx::BitmapFormat::RGBA32 : Gfx::BitmapFormat::RGB32,
|
||||||
message.anon_file().take_fd(),
|
message.anon_file().take_fd(),
|
||||||
message.size(),
|
message.size(),
|
||||||
|
{},
|
||||||
Gfx::Bitmap::ShouldCloseAnonymousFile::Yes);
|
Gfx::Bitmap::ShouldCloseAnonymousFile::Yes);
|
||||||
window.set_backing_store(move(backing_store), message.serial());
|
window.set_backing_store(move(backing_store), message.serial());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue