summaryrefslogtreecommitdiff
path: root/Libraries/LibGfx
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2020-03-29 19:04:05 +0200
committerAndreas Kling <kling@serenityos.org>2020-03-29 19:37:23 +0200
commit7cfe712f4d0298cb645a602afe116698ab0fcd67 (patch)
tree51a964bf210be086634bc69bd48d3ed11debffe5 /Libraries/LibGfx
parent24a0354ce84c6c839930788bc772736f7c56ae18 (diff)
downloadserenity-7cfe712f4d0298cb645a602afe116698ab0fcd67.zip
LibGfx+LibIPC: Add Gfx::ShareableBitmap, a bitmap for easy IPC usage
With this patch, it's now possible to pass a Gfx::ShareableBitmap in an IPC message. As long as the message itself is synchronous, the bitmap will be adopted by the receiving end, and disowned by the sender nicely without any accounting effort like we've had to do in the past. Use this in NotificationServer to allow sending arbitrary bitmaps as icons instead of paths-to-icons.
Diffstat (limited to 'Libraries/LibGfx')
-rw-r--r--Libraries/LibGfx/Bitmap.cpp11
-rw-r--r--Libraries/LibGfx/Bitmap.h5
-rw-r--r--Libraries/LibGfx/Forward.h1
-rw-r--r--Libraries/LibGfx/Makefile1
-rw-r--r--Libraries/LibGfx/ShareableBitmap.cpp40
-rw-r--r--Libraries/LibGfx/ShareableBitmap.h35
6 files changed, 91 insertions, 2 deletions
diff --git a/Libraries/LibGfx/Bitmap.cpp b/Libraries/LibGfx/Bitmap.cpp
index cda0ad656b..962ea59ba9 100644
--- a/Libraries/LibGfx/Bitmap.cpp
+++ b/Libraries/LibGfx/Bitmap.cpp
@@ -29,6 +29,7 @@
#include <AK/String.h>
#include <LibGfx/Bitmap.h>
#include <LibGfx/PNGLoader.h>
+#include <LibGfx/ShareableBitmap.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
@@ -97,7 +98,7 @@ Bitmap::Bitmap(BitmapFormat format, NonnullRefPtr<SharedBuffer>&& shared_buffer,
ASSERT(format != BitmapFormat::Indexed8);
}
-NonnullRefPtr<Bitmap> Bitmap::to_shareable_bitmap() const
+NonnullRefPtr<Bitmap> Bitmap::to_bitmap_backed_by_shared_buffer() const
{
if (m_shared_buffer)
return *this;
@@ -164,4 +165,12 @@ int Bitmap::shbuf_id() const
return m_shared_buffer ? m_shared_buffer->shbuf_id() : -1;
}
+ShareableBitmap Bitmap::to_shareable_bitmap(pid_t peer_pid) const
+{
+ auto bitmap = to_bitmap_backed_by_shared_buffer();
+ if (peer_pid > 0)
+ bitmap->shared_buffer()->share_with(peer_pid);
+ return ShareableBitmap(*bitmap);
+}
+
}
diff --git a/Libraries/LibGfx/Bitmap.h b/Libraries/LibGfx/Bitmap.h
index be05d08cdb..7fdec97e65 100644
--- a/Libraries/LibGfx/Bitmap.h
+++ b/Libraries/LibGfx/Bitmap.h
@@ -30,6 +30,7 @@
#include <AK/RefCounted.h>
#include <AK/RefPtr.h>
#include <LibGfx/Color.h>
+#include <LibGfx/Forward.h>
#include <LibGfx/Rect.h>
namespace Gfx {
@@ -49,7 +50,9 @@ public:
static RefPtr<Bitmap> load_from_file(const StringView& path);
static NonnullRefPtr<Bitmap> create_with_shared_buffer(BitmapFormat, NonnullRefPtr<SharedBuffer>&&, const Size&);
- NonnullRefPtr<Bitmap> to_shareable_bitmap() const;
+ NonnullRefPtr<Bitmap> to_bitmap_backed_by_shared_buffer() const;
+
+ ShareableBitmap to_shareable_bitmap(pid_t peer_pid = -1) const;
~Bitmap();
diff --git a/Libraries/LibGfx/Forward.h b/Libraries/LibGfx/Forward.h
index c41c7bc21a..37946b3b43 100644
--- a/Libraries/LibGfx/Forward.h
+++ b/Libraries/LibGfx/Forward.h
@@ -44,6 +44,7 @@ class Palette;
class PaletteImpl;
class Point;
class Rect;
+class ShareableBitmap;
class Size;
class StylePainter;
struct SystemTheme;
diff --git a/Libraries/LibGfx/Makefile b/Libraries/LibGfx/Makefile
index e02371bfe9..4c538660c7 100644
--- a/Libraries/LibGfx/Makefile
+++ b/Libraries/LibGfx/Makefile
@@ -12,6 +12,7 @@ OBJS = \
Palette.o \
Point.o \
Rect.o \
+ ShareableBitmap.o \
Size.o \
StylePainter.o \
SystemTheme.o \
diff --git a/Libraries/LibGfx/ShareableBitmap.cpp b/Libraries/LibGfx/ShareableBitmap.cpp
new file mode 100644
index 0000000000..ad5fe8dacd
--- /dev/null
+++ b/Libraries/LibGfx/ShareableBitmap.cpp
@@ -0,0 +1,40 @@
+#include <AK/SharedBuffer.h>
+#include <LibGfx/Bitmap.h>
+#include <LibGfx/ShareableBitmap.h>
+#include <LibIPC/Decoder.h>
+
+namespace Gfx {
+
+ShareableBitmap::ShareableBitmap(const Bitmap& bitmap)
+ : m_bitmap(bitmap.to_bitmap_backed_by_shared_buffer())
+{
+}
+
+}
+
+namespace IPC {
+
+bool decode(Decoder& decoder, Gfx::ShareableBitmap& shareable_bitmap)
+{
+ i32 shbuf_id = 0;
+ Gfx::Size size;
+ if (!decoder.decode(shbuf_id))
+ return false;
+ if (!decoder.decode(size))
+ return false;
+
+ if (shbuf_id == -1)
+ return true;
+
+ dbg() << "Decoding a ShareableBitmap with shbuf_id=" << shbuf_id << ", size=" << size;
+
+ auto shared_buffer = SharedBuffer::create_from_shbuf_id(shbuf_id);
+ if (!shared_buffer)
+ return false;
+
+ auto bitmap = Gfx::Bitmap::create_with_shared_buffer(Gfx::BitmapFormat::RGBA32, shared_buffer.release_nonnull(), size);
+ shareable_bitmap = bitmap->to_shareable_bitmap();
+ return true;
+}
+
+}
diff --git a/Libraries/LibGfx/ShareableBitmap.h b/Libraries/LibGfx/ShareableBitmap.h
new file mode 100644
index 0000000000..498ab64c37
--- /dev/null
+++ b/Libraries/LibGfx/ShareableBitmap.h
@@ -0,0 +1,35 @@
+#pragma once
+
+#include <AK/RefPtr.h>
+#include <LibGfx/Bitmap.h>
+#include <LibGfx/Size.h>
+
+namespace Gfx {
+
+class ShareableBitmap {
+public:
+ ShareableBitmap() {}
+ explicit ShareableBitmap(const Gfx::Bitmap&);
+
+ bool is_valid() const { return m_bitmap; }
+
+ i32 shbuf_id() const { return m_bitmap ? m_bitmap->shbuf_id() : -1; }
+
+ const Bitmap* bitmap() const { return m_bitmap; }
+ Bitmap* bitmap() { return m_bitmap; }
+
+ Size size() const { return m_bitmap ? m_bitmap->size() : Size(); }
+ Rect rect() const { return m_bitmap ? m_bitmap->rect() : Rect(); }
+
+ int width() const { return size().width(); }
+ int height() const { return size().height(); }
+
+private:
+ RefPtr<Bitmap> m_bitmap;
+};
+
+}
+
+namespace IPC {
+bool decode(Decoder&, Gfx::ShareableBitmap&);
+}