diff options
author | Andreas Kling <awesomekling@gmail.com> | 2019-12-18 20:50:05 +0100 |
---|---|---|
committer | Andreas Kling <awesomekling@gmail.com> | 2019-12-18 20:50:05 +0100 |
commit | 77ae98a9b69802ff6f7c0aacc08352d76dec7439 (patch) | |
tree | aad764799a64b90fa7ab0d7ba69e330f8f78c9ff | |
parent | 72ec2fae6ef6d577ea030f77a769cc147e8a983e (diff) | |
download | serenity-77ae98a9b69802ff6f7c0aacc08352d76dec7439.zip |
LibDraw: Add GraphicsBitmap::create_purgeable()
This allows you to create a process-private purgeable GraphicsBitmap.
The volatile flag is controlled via set_volatile() / set_nonvolatile().
-rw-r--r-- | Libraries/LibDraw/GraphicsBitmap.cpp | 40 | ||||
-rw-r--r-- | Libraries/LibDraw/GraphicsBitmap.h | 11 |
2 files changed, 47 insertions, 4 deletions
diff --git a/Libraries/LibDraw/GraphicsBitmap.cpp b/Libraries/LibDraw/GraphicsBitmap.cpp index 736f9702d6..39e3708b91 100644 --- a/Libraries/LibDraw/GraphicsBitmap.cpp +++ b/Libraries/LibDraw/GraphicsBitmap.cpp @@ -9,17 +9,24 @@ NonnullRefPtr<GraphicsBitmap> GraphicsBitmap::create(Format format, const Size& size) { - return adopt(*new GraphicsBitmap(format, size)); + return adopt(*new GraphicsBitmap(format, size, Purgeable::No)); } -GraphicsBitmap::GraphicsBitmap(Format format, const Size& size) +NonnullRefPtr<GraphicsBitmap> GraphicsBitmap::create_purgeable(Format format, const Size& size) +{ + return adopt(*new GraphicsBitmap(format, size, Purgeable::Yes)); +} + +GraphicsBitmap::GraphicsBitmap(Format format, const Size& size, Purgeable purgeable) : m_size(size) , m_pitch(round_up_to_power_of_two(size.width() * sizeof(RGBA32), 16)) , m_format(format) + , m_purgeable(purgeable == Purgeable::Yes) { if (format == Format::Indexed8) m_palette = new RGBA32[256]; - m_data = (RGBA32*)mmap_with_name(nullptr, size_in_bytes(), PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0, String::format("GraphicsBitmap [%dx%d]", width(), height()).characters()); + int map_flags = purgeable == Purgeable::Yes ? (MAP_PURGEABLE | MAP_PRIVATE) : (MAP_ANONYMOUS | MAP_PRIVATE); + m_data = (RGBA32*)mmap_with_name(nullptr, size_in_bytes(), PROT_READ | PROT_WRITE, map_flags, 0, 0, String::format("GraphicsBitmap [%dx%d]", width(), height()).characters()); ASSERT(m_data && m_data != (void*)-1); m_needs_munmap = true; } @@ -111,3 +118,30 @@ void GraphicsBitmap::fill(Color color) fast_u32_fill(scanline, color.value(), width()); } } + +void GraphicsBitmap::set_volatile() +{ + ASSERT(m_purgeable); + if (m_volatile) + return; + int rc = madvise(m_data, size_in_bytes(), MADV_SET_VOLATILE); + if (rc < 0) { + perror("madvise(MADV_SET_VOLATILE)"); + ASSERT_NOT_REACHED(); + } + m_volatile = true; +} + +[[nodiscard]] bool GraphicsBitmap::set_nonvolatile() +{ + ASSERT(m_purgeable); + if (!m_volatile) + return true; + int rc = madvise(m_data, size_in_bytes(), MADV_SET_NONVOLATILE); + if (rc < 0) { + perror("madvise(MADV_SET_NONVOLATILE)"); + ASSERT_NOT_REACHED(); + } + m_volatile = false; + return rc == 0; +} diff --git a/Libraries/LibDraw/GraphicsBitmap.h b/Libraries/LibDraw/GraphicsBitmap.h index 47371ca02f..42695ed887 100644 --- a/Libraries/LibDraw/GraphicsBitmap.h +++ b/Libraries/LibDraw/GraphicsBitmap.h @@ -20,6 +20,7 @@ public: }; static NonnullRefPtr<GraphicsBitmap> create(Format, const Size&); + static NonnullRefPtr<GraphicsBitmap> create_purgeable(Format, const Size&); static NonnullRefPtr<GraphicsBitmap> create_wrapper(Format, const Size&, size_t pitch, RGBA32*); static RefPtr<GraphicsBitmap> load_from_file(const StringView& path); static RefPtr<GraphicsBitmap> load_from_file(Format, const StringView& path, const Size&); @@ -98,8 +99,14 @@ public: set_pixel(position.x(), position.y(), color); } + bool is_purgeable() const { return m_purgeable; } + bool is_volatile() const { return m_volatile; } + void set_volatile(); + [[nodiscard]] bool set_nonvolatile(); + private: - GraphicsBitmap(Format, const Size&); + enum class Purgeable { No, Yes }; + GraphicsBitmap(Format, const Size&, Purgeable); GraphicsBitmap(Format, const Size&, size_t pitch, RGBA32*); GraphicsBitmap(Format, const Size&, MappedFile&&); GraphicsBitmap(Format, NonnullRefPtr<SharedBuffer>&&, const Size&); @@ -110,6 +117,8 @@ private: size_t m_pitch { 0 }; Format m_format { Format::Invalid }; bool m_needs_munmap { false }; + bool m_purgeable { false }; + bool m_volatile { false }; MappedFile m_mapped_file; RefPtr<SharedBuffer> m_shared_buffer; }; |