mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 08:37:45 +00:00
LibGfx: Allow creating a Gfx::Bitmap backed by an anonymous file
Gfx::Bitmap::create_with_anon_fd() creates such a Bitmap, and also optionally takes ownership of the file, making sure to close() it on destruction.
This commit is contained in:
parent
fb4993f067
commit
4d97b955e6
2 changed files with 50 additions and 0 deletions
|
@ -182,6 +182,29 @@ 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)
|
||||||
|
{
|
||||||
|
if (size_would_overflow(format, size))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
const auto pitch = minimum_pitch(size.width(), format);
|
||||||
|
const auto data_size_in_bytes = size_in_bytes(pitch, size.height());
|
||||||
|
|
||||||
|
auto* 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (should_close_anon_fd == ShouldCloseAnonymousFile::Yes) {
|
||||||
|
int rc = close(anon_fd);
|
||||||
|
ASSERT(rc == 0);
|
||||||
|
anon_fd = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return adopt(*new Bitmap(format, anon_fd, size, data));
|
||||||
|
}
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
if (size_would_overflow(format, size))
|
if (size_would_overflow(format, size))
|
||||||
|
@ -293,6 +316,19 @@ 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)
|
||||||
|
: m_size(size)
|
||||||
|
, m_data(data)
|
||||||
|
, m_pitch(minimum_pitch(size.width(), format))
|
||||||
|
, m_format(format)
|
||||||
|
, m_needs_munmap(true)
|
||||||
|
, m_purgeable(true)
|
||||||
|
, m_anon_fd(anon_fd)
|
||||||
|
{
|
||||||
|
ASSERT(!is_indexed());
|
||||||
|
ASSERT(!size_would_overflow(format, size));
|
||||||
|
}
|
||||||
|
|
||||||
RefPtr<Gfx::Bitmap> Bitmap::clone() const
|
RefPtr<Gfx::Bitmap> Bitmap::clone() const
|
||||||
{
|
{
|
||||||
RefPtr<Gfx::Bitmap> new_bitmap {};
|
RefPtr<Gfx::Bitmap> new_bitmap {};
|
||||||
|
@ -378,6 +414,10 @@ Bitmap::~Bitmap()
|
||||||
int rc = munmap(m_data, size_in_bytes());
|
int rc = munmap(m_data, size_in_bytes());
|
||||||
ASSERT(rc == 0);
|
ASSERT(rc == 0);
|
||||||
}
|
}
|
||||||
|
if (m_anon_fd != -1) {
|
||||||
|
int rc = close(m_anon_fd);
|
||||||
|
ASSERT(rc == 0);
|
||||||
|
}
|
||||||
m_data = nullptr;
|
m_data = nullptr;
|
||||||
delete[] m_palette;
|
delete[] m_palette;
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,11 +88,17 @@ enum RotationDirection {
|
||||||
|
|
||||||
class Bitmap : public RefCounted<Bitmap> {
|
class Bitmap : public RefCounted<Bitmap> {
|
||||||
public:
|
public:
|
||||||
|
enum class ShouldCloseAnonymousFile {
|
||||||
|
No,
|
||||||
|
Yes,
|
||||||
|
};
|
||||||
|
|
||||||
static RefPtr<Bitmap> create(BitmapFormat, const IntSize&);
|
static RefPtr<Bitmap> create(BitmapFormat, const IntSize&);
|
||||||
static RefPtr<Bitmap> create_shareable(BitmapFormat, const IntSize&);
|
static RefPtr<Bitmap> create_shareable(BitmapFormat, const IntSize&);
|
||||||
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_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);
|
||||||
|
@ -224,6 +230,8 @@ public:
|
||||||
void set_volatile();
|
void set_volatile();
|
||||||
[[nodiscard]] bool set_nonvolatile();
|
[[nodiscard]] bool set_nonvolatile();
|
||||||
|
|
||||||
|
int anon_fd() const { return m_anon_fd; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum class Purgeable {
|
enum class Purgeable {
|
||||||
No,
|
No,
|
||||||
|
@ -232,6 +240,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*);
|
||||||
|
|
||||||
static Optional<BackingStore> allocate_backing_store(BitmapFormat, const IntSize&, Purgeable);
|
static Optional<BackingStore> allocate_backing_store(BitmapFormat, const IntSize&, Purgeable);
|
||||||
|
|
||||||
|
@ -246,6 +255,7 @@ private:
|
||||||
bool m_purgeable { false };
|
bool m_purgeable { false };
|
||||||
bool m_volatile { false };
|
bool m_volatile { false };
|
||||||
RefPtr<SharedBuffer> m_shared_buffer;
|
RefPtr<SharedBuffer> m_shared_buffer;
|
||||||
|
int m_anon_fd { -1 };
|
||||||
};
|
};
|
||||||
|
|
||||||
inline u8* Bitmap::scanline_u8(int y)
|
inline u8* Bitmap::scanline_u8(int y)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue