summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2019-01-21 05:18:28 +0100
committerAndreas Kling <awesomekling@gmail.com>2019-01-21 05:18:28 +0100
commit76a28817931e6826a6f406a6b677082aa8c4f949 (patch)
tree58e294d5a6fc36de2bb89a1bc92645b3998a9b91
parentd1af5c97ca18d48700ccf7d939f9911a43a9c2eb (diff)
downloadserenity-76a28817931e6826a6f406a6b677082aa8c4f949.zip
Mark the two Regions used GraphicsBitmaps as explicitly shared.
This fixes a goofy problem where forking a GUI process would cowify the GraphicsBitmap for everyone making a hue confusing mess.
-rw-r--r--Kernel/MemoryManager.cpp7
-rw-r--r--Kernel/MemoryManager.h3
-rw-r--r--SharedGraphics/GraphicsBitmap.cpp2
3 files changed, 11 insertions, 1 deletions
diff --git a/Kernel/MemoryManager.cpp b/Kernel/MemoryManager.cpp
index e719243e2f..60d1a9c127 100644
--- a/Kernel/MemoryManager.cpp
+++ b/Kernel/MemoryManager.cpp
@@ -563,11 +563,16 @@ RetainPtr<Region> Region::clone()
{
InterruptDisabler disabler;
- if (is_readable && !is_writable) {
+ if (m_shared || (is_readable && !is_writable)) {
// Create a new region backed by the same VMObject.
return adopt(*new Region(linearAddress, size, m_vmo.copyRef(), m_offset_in_vmo, String(name), is_readable, is_writable));
}
+ dbgprintf("%s<%u> Region::clone(): cowing %s (L%x)\n",
+ current->name().characters(),
+ current->pid(),
+ name.characters(),
+ linearAddress.get());
// Set up a COW region. The parent (this) region becomes COW as well!
for (size_t i = 0; i < page_count(); ++i)
cow_map.set(i, true);
diff --git a/Kernel/MemoryManager.h b/Kernel/MemoryManager.h
index 17b99fcfe1..46cbe89edb 100644
--- a/Kernel/MemoryManager.h
+++ b/Kernel/MemoryManager.h
@@ -117,6 +117,8 @@ public:
const VMObject& vmo() const { return *m_vmo; }
VMObject& vmo() { return *m_vmo; }
+ void set_shared(bool shared) { m_shared = shared; }
+
RetainPtr<Region> clone();
bool contains(LinearAddress laddr) const
{
@@ -156,6 +158,7 @@ public:
String name;
bool is_readable { true };
bool is_writable { true };
+ bool m_shared { false };
Bitmap cow_map;
};
diff --git a/SharedGraphics/GraphicsBitmap.cpp b/SharedGraphics/GraphicsBitmap.cpp
index 00dcd3707a..3da6cce03c 100644
--- a/SharedGraphics/GraphicsBitmap.cpp
+++ b/SharedGraphics/GraphicsBitmap.cpp
@@ -21,12 +21,14 @@ GraphicsBitmap::GraphicsBitmap(Process& process, const Size& size)
size_t size_in_bytes = size.width() * size.height() * sizeof(RGBA32);
auto vmo = VMObject::create_anonymous(size_in_bytes);
m_client_region = process.allocate_region_with_vmo(LinearAddress(), size_in_bytes, vmo.copyRef(), 0, "GraphicsBitmap (client)", true, true);
+ m_client_region->set_shared(true);
m_client_region->commit(process);
{
auto& server = WSEventLoop::the().server_process();
InterruptDisabler disabler;
m_server_region = server.allocate_region_with_vmo(LinearAddress(), size_in_bytes, move(vmo), 0, "GraphicsBitmap (server)", true, true);
+ m_server_region->set_shared(true);
}
m_data = (RGBA32*)m_server_region->linearAddress.asPtr();
}