diff options
author | agl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-02-20 02:00:04 +0000 |
---|---|---|
committer | agl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-02-20 02:00:04 +0000 |
commit | e68e62fa169c45bd779bfe890aa4fcdaa24d267d (patch) | |
tree | efdb18adec880e7f780d8cde4e12893d3a20234f /chrome/renderer/render_process.h | |
parent | 7fe07d0726bad485fa40150aa9f7cecb1318217e (diff) | |
download | chromium_src-e68e62fa169c45bd779bfe890aa4fcdaa24d267d.zip chromium_src-e68e62fa169c45bd779bfe890aa4fcdaa24d267d.tar.gz chromium_src-e68e62fa169c45bd779bfe890aa4fcdaa24d267d.tar.bz2 |
Bitmap transport
This patch reworks bitmap transport on all platforms. Linux and Mac
are switched from serialising bitmaps over the IPC channel to using
shared memory. All platforms gain a shared memory mapping cache on the
host side.
The concept of a TransportDIB (device independent bitmap) is added to
encapsulate most of the platform specifics.
On Linux, we use SysV shared memory. This is because X shared pixmaps,
which predate POSIX SHM, can only use SysV. By using SysV between
renderer and browser, we open up the possibility to map the shared
memory directly from the renderer to the X server.
On Mac, we use POSIX shared memory. However, since this needs
filesystem access and the Mac renderer is sandboxed from the
filesystem, we add two new messages from renderer -> browser:
The first, AllocTransportDIB, synchronously creates a transport DIB in
the browser and passes a handle back to the renderer. The second,
FreeTransportDIB, asynchronously, notifies the browser that it may
close its handle to the shared memory region.
On Mac, the shared memory regions are identified by their inode
numbers on the wire. This means that the browser must keep handles
open to all the allocated shared memory regions (since an inode number
is insufficient to map the region). The alternative design is that the
renderer passes the file descriptor with each paint operation. Since
passing file descriptors is special case in the code, I felt that it
would be best to minimise their use. Creating and freeing transport
DIBs are relatively rare operations relative to paints and scrolls.
On Windows, most of the code remains the same, except that Windows now
uses the mapping cache added in this patch. This allows the browser to
maintain a shared memory mapping for a transport DIB over several
paints. Previously it mapped and unmapped for every operation, causing
lots of TLB and VM churn.
Review URL: http://codereview.chromium.org/21485
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@10071 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/renderer/render_process.h')
-rw-r--r-- | chrome/renderer/render_process.h | 64 |
1 files changed, 39 insertions, 25 deletions
diff --git a/chrome/renderer/render_process.h b/chrome/renderer/render_process.h index 6ba0905..9c4cabe 100644 --- a/chrome/renderer/render_process.h +++ b/chrome/renderer/render_process.h @@ -5,13 +5,17 @@ #ifndef CHROME_RENDERER_RENDER_PROCESS_H__ #define CHROME_RENDERER_RENDER_PROCESS_H__ +#include "base/timer.h" #include "chrome/common/child_process.h" #include "chrome/renderer/render_thread.h" +#include "skia/ext/platform_canvas.h" -namespace base { - class SharedMemory; +namespace gfx { +class Rect; } +class TransportDIB; + // Represents the renderer end of the browser<->renderer connection. The // opposite end is the RenderProcessHost. This is a singleton object for // each renderer. @@ -23,19 +27,19 @@ class RenderProcess : public ChildProcess { // Returns true if plugins should be loaded in-process. static bool ShouldLoadPluginsInProcess(); - // Allocates shared memory. When no longer needed, you should pass the - // SharedMemory pointer to FreeSharedMemory so it can be recycled. The size - // reported in the resulting SharedMemory object will be greater than or - // equal to the requested size. This method returns NULL if unable to - // allocate memory for some reason. - static base::SharedMemory* AllocSharedMemory(size_t size); + // Get a canvas suitable for drawing and transporting to the browser + // memory: (output) the transport DIB memory + // rect: the rectangle which will be painted, use for sizing the canvas + // returns: NULL on error + // + // When no longer needed, you should pass the TransportDIB to + // ReleaseTransportDIB so that it can be recycled. + static skia::PlatformCanvas* GetDrawingCanvas( + TransportDIB** memory, const gfx::Rect& rect); // Frees shared memory allocated by AllocSharedMemory. You should only use // this function to free the SharedMemory object. - static void FreeSharedMemory(base::SharedMemory* mem); - - // Deletes the shared memory allocated by AllocSharedMemory. - static void DeleteSharedMem(base::SharedMemory* mem); + static void ReleaseTransportDIB(TransportDIB* memory); private: friend class ChildProcessFactory<RenderProcess>; @@ -50,21 +54,28 @@ class RenderProcess : public ChildProcess { static ChildProcess* ClassFactory(const std::wstring& channel_name); - // Look in the shared memory cache for a suitable object to reuse. Returns - // NULL if there is none. - base::SharedMemory* GetSharedMemFromCache(size_t size); + // Look in the shared memory cache for a suitable object to reuse. + // result: (output) the memory found + // size: the resulting memory will be >= this size, in bytes + // returns: false if a suitable DIB memory could not be found + bool GetTransportDIBFromCache(TransportDIB** result, size_t size); - // Maybe put the given shared memory into the shared memory cache. Returns + // Maybe put the given shared memory into the shared memory cache. Returns // true if the SharedMemory object was stored in the cache; otherwise, false // is returned. - bool PutSharedMemInCache(base::SharedMemory* mem); + bool PutSharedMemInCache(TransportDIB* memory); - void ClearSharedMemCache(); + void ClearTransportDIBCache(); - // We want to lazily clear the shared memory cache if no one has requested - // memory. This methods are used to schedule a deferred call to - // RenderProcess::ClearSharedMemCache. - void ScheduleCacheClearer(); + // Return the index of a free cache slot in which to install a transport DIB + // of the given size. If all entries in the cache are larger than the given + // size, this doesn't free any slots and returns -1. + int FindFreeCacheSlot(size_t size); + + // Create a new transport DIB of, at least, the given size. Return NULL on + // error. + TransportDIB* CreateTransportDIB(size_t size); + void FreeTransportDIB(TransportDIB*); // ChildProcess implementation virtual void Cleanup(); @@ -74,10 +85,13 @@ class RenderProcess : public ChildProcess { // A very simplistic and small cache. If an entry in this array is non-null, // then it points to a SharedMemory object that is available for reuse. - base::SharedMemory* shared_mem_cache_[2]; + TransportDIB* shared_mem_cache_[2]; + + // This DelayTimer cleans up our cache 5 seconds after the last use. + base::DelayTimer<RenderProcess> shared_mem_cache_cleaner_; - // This factory is used to lazily invoke ClearSharedMemCache. - ScopedRunnableMethodFactory<RenderProcess> clearer_factory_; + // TransportDIB sequence number + uint32 sequence_number_; static bool load_plugins_in_process_; |