diff options
47 files changed, 321 insertions, 441 deletions
diff --git a/app/surface/transport_dib.h b/app/surface/transport_dib.h index 9c0982e..6606c2b 100644 --- a/app/surface/transport_dib.h +++ b/app/surface/transport_dib.h @@ -7,7 +7,6 @@ #pragma once #include "base/basictypes.h" -#include "base/process.h" #if defined(OS_WIN) || defined(OS_MACOSX) #include "base/shared_memory.h" @@ -32,48 +31,13 @@ class TransportDIB { public: ~TransportDIB(); - // Two typedefs are defined. A |Handle| can be sent over the wire so that the - // remote side can map the |TransportDIB|. These handles may be reused from - // previous DIBs. An |Id| is unique and never reused, but it is not sufficient - // to map the DIB. + // Two typedefs are defined. A Handle is the type which can be sent over + // the wire so that the remote side can map the transport DIB. The Id typedef + // is sufficient to identify the transport DIB when you know that the remote + // side already may have it mapped. #if defined(OS_WIN) - // On Windows, a |Handle| is a combination of the section (i.e., file mapping) - // handle and the ID of the corresponding process. When the DIB is mapped in - // a remote process, the section handle is duplicated for use in that process. - // However, if the remote process does not have permission to duplicate the - // handle, the first process must duplicate the handle before sending it. - // E.g., this is necessary if the DIB is created in the browser and will be - // mapped in the sandboxed renderer. - class TransferrableSectionHandle { - public: - TransferrableSectionHandle() - : section_(NULL), owner_id_(NULL), should_dup_on_map_(false) { - } - - TransferrableSectionHandle(HANDLE section, base::ProcessId owner_id, - bool should_dup_on_map) - : section_(section), - owner_id_(owner_id), - should_dup_on_map_(should_dup_on_map) { - } - - // Duplicates the handle for use in the given process. - TransferrableSectionHandle DupForProcess( - base::ProcessHandle new_owner) const; - - HANDLE section() const { return section_; } - base::ProcessId owner_id() const { return owner_id_; } - bool should_dup_on_map() const { return should_dup_on_map_; } - - private: - HANDLE section_; - base::ProcessId owner_id_; - // Whether the handle should be duplicated when the DIB is mapped. - bool should_dup_on_map_; - }; - typedef TransferrableSectionHandle Handle; - - // On Windows, the Id type is a sequence number (epoch) to solve an ABA + typedef HANDLE Handle; + // On Windows, the Id type includes a sequence number (epoch) to solve an ABA // issue: // 1) Process A creates a transport DIB with HANDLE=1 and sends to B. // 2) Process B maps the transport DIB and caches 1 -> DIB. @@ -81,17 +45,38 @@ class TransportDIB { // is also assigned HANDLE=1. // 4) Process A sends the Handle to B, but B incorrectly believes that it // already has it cached. - typedef uint32 Id; + struct HandleAndSequenceNum { + HandleAndSequenceNum() + : handle(NULL), + sequence_num(0) { + } + + HandleAndSequenceNum(HANDLE h, uint32 seq_num) + : handle(h), + sequence_num(seq_num) { + } + + bool operator< (const HandleAndSequenceNum& other) const { + // Use the lexicographic order on the tuple <handle, sequence_num>. + if (other.handle != handle) + return other.handle < handle; + return other.sequence_num < sequence_num; + } + + HANDLE handle; + uint32 sequence_num; + }; + typedef HandleAndSequenceNum Id; // Returns a default, invalid handle, that is meant to indicate a missing // Transport DIB. - static Handle DefaultHandleValue() { return Handle(); } + static Handle DefaultHandleValue() { return NULL; } // Returns a value that is ONLY USEFUL FOR TESTS WHERE IT WON'T BE // ACTUALLY USED AS A REAL HANDLE. static Handle GetFakeHandleForTest() { static int fake_handle = 10; - return Handle(reinterpret_cast<HANDLE>(fake_handle++), 1, false); + return reinterpret_cast<Handle>(fake_handle++); } #elif defined(OS_MACOSX) typedef base::SharedMemoryHandle Handle; @@ -124,7 +109,7 @@ class TransportDIB { } #endif - // Create a new |TransportDIB|, returning NULL on failure. + // Create a new TransportDIB, returning NULL on failure. // // The size is the minimum size in bytes of the memory backing the transport // DIB (we may actually allocate more than that to give us better reuse when @@ -133,18 +118,12 @@ class TransportDIB { // The sequence number is used to uniquely identify the transport DIB. It // should be unique for all transport DIBs ever created in the same // renderer. - // - // On Linux, this will also map the DIB into the current process. static TransportDIB* Create(size_t size, uint32 sequence_num); - // Map the referenced transport DIB. The caller owns the returned object. + // Map the referenced transport DIB. The caller owns the returned object. // Returns NULL on failure. static TransportDIB* Map(Handle transport_dib); - // Create a new |TransportDIB| with a handle to the shared memory. This - // always returns a valid pointer. The DIB is not mapped. - static TransportDIB* CreateWithHandle(Handle handle); - // Returns true if the handle is valid. static bool is_valid(Handle dib); @@ -152,31 +131,11 @@ class TransportDIB { // pointer will be owned by the caller. The bitmap will be of the given size, // which should fit inside this memory. // - // On POSIX, this |TransportDIB| will be mapped if not already. On Windows, - // this |TransportDIB| will NOT be mapped and should not be mapped prior, - // because PlatformCanvas will map the file internally. - // // Will return NULL on allocation failure. This could be because the image // is too large to map into the current process' address space. skia::PlatformCanvas* GetPlatformCanvas(int w, int h); - // Map the DIB into the current process if it is not already. This is used to - // map a DIB that has already been created. Returns true if the DIB is mapped. - bool Map(); - - // Return a handle for use in a specific process. On POSIX, this simply - // returns the handle as in the |handle| accessor below. On Windows, this - // returns a duplicate handle for use in the given process. This should be - // used instead of the |handle| accessor only if the process that will map - // this DIB does not have permission to duplicate the handle from the - // first process. - // - // Note: On Windows, if the duplicated handle is not closed by the other side - // (or this process fails to transmit the handle), the shared memory will be - // leaked. - Handle GetHandleForProcess(base::ProcessHandle process_handle) const; - - // Return a pointer to the shared memory. + // Return a pointer to the shared memory void* memory() const; // Return the maximum size of the shared memory. This is not the amount of diff --git a/app/surface/transport_dib_linux.cc b/app/surface/transport_dib_linux.cc index 69282c3..26cad3f 100644 --- a/app/surface/transport_dib_linux.cc +++ b/app/surface/transport_dib_linux.cc @@ -65,57 +65,34 @@ TransportDIB* TransportDIB::Create(size_t size, uint32 sequence_num) { return dib; } -// static -TransportDIB* TransportDIB::Map(Handle handle) { - scoped_ptr<TransportDIB> dib(CreateWithHandle(handle)); - if (!dib->Map()) +TransportDIB* TransportDIB::Map(Handle shmkey) { + struct shmid_ds shmst; + if (shmctl(shmkey, IPC_STAT, &shmst) == -1) + return NULL; + + void* address = shmat(shmkey, NULL /* desired address */, 0 /* flags */); + if (address == kInvalidAddress) return NULL; - return dib.release(); -} -// static -TransportDIB* TransportDIB::CreateWithHandle(Handle shmkey) { TransportDIB* dib = new TransportDIB; + + dib->address_ = address; + dib->size_ = shmst.shm_segsz; dib->key_ = shmkey; return dib; } -// static bool TransportDIB::is_valid(Handle dib) { return dib >= 0; } skia::PlatformCanvas* TransportDIB::GetPlatformCanvas(int w, int h) { - if (address_ == kInvalidAddress && !Map()) - return NULL; scoped_ptr<skia::PlatformCanvas> canvas(new skia::PlatformCanvas); if (!canvas->initialize(w, h, true, reinterpret_cast<uint8_t*>(memory()))) return NULL; return canvas.release(); } -bool TransportDIB::Map() { - if (address_ != kInvalidAddress) - return true; - - struct shmid_ds shmst; - if (shmctl(key_, IPC_STAT, &shmst) == -1) - return false; - - void* address = shmat(key_, NULL /* desired address */, 0 /* flags */); - if (address == kInvalidAddress) - return false; - - address_ = address; - size_ = shmst.shm_segsz; - return true; -} - -TransportDIB::Handle TransportDIB::GetHandleForProcess( - base::ProcessHandle process_handle) const { - return handle(); -} - void* TransportDIB::memory() const { DCHECK_NE(address_, kInvalidAddress); return address_; diff --git a/app/surface/transport_dib_mac.cc b/app/surface/transport_dib_mac.cc index ba64ac4..a3eb0bb 100644 --- a/app/surface/transport_dib_mac.cc +++ b/app/surface/transport_dib_mac.cc @@ -34,56 +34,46 @@ TransportDIB* TransportDIB::Create(size_t size, uint32 sequence_num) { return NULL; } + if (!dib->shared_memory_.Map(size)) { + delete dib; + return NULL; + } + dib->size_ = size; return dib; } // static -TransportDIB* TransportDIB::Map(Handle handle) { - scoped_ptr<TransportDIB> dib(CreateWithHandle(handle)); - if (!dib->Map()) +TransportDIB* TransportDIB::Map(TransportDIB::Handle handle) { + if (!is_valid(handle)) return NULL; - return dib.release(); -} -// static -TransportDIB* TransportDIB::CreateWithHandle(Handle handle) { - return new TransportDIB(handle); + TransportDIB* dib = new TransportDIB(handle); + struct stat st; + if ((fstat(handle.fd, &st) != 0) || + (!dib->shared_memory_.Map(st.st_size))) { + delete dib; + if (HANDLE_EINTR(close(handle.fd)) < 0) + PLOG(ERROR) << "close"; + return NULL; + } + + dib->size_ = st.st_size; + + return dib; } -// static bool TransportDIB::is_valid(Handle dib) { return dib.fd >= 0; } skia::PlatformCanvas* TransportDIB::GetPlatformCanvas(int w, int h) { - if (!memory() && !Map()) - return NULL; scoped_ptr<skia::PlatformCanvas> canvas(new skia::PlatformCanvas); if (!canvas->initialize(w, h, true, reinterpret_cast<uint8_t*>(memory()))) return NULL; return canvas.release(); } -bool TransportDIB::Map() { - if (memory()) - return true; - - struct stat st; - if ((fstat(shared_memory_.handle().fd, &st) != 0) || - (!shared_memory_.Map(st.st_size))) { - return false; - } - - size_ = st.st_size; - return true; -} - -TransportDIB::Handle TransportDIB::GetHandleForProcess( - base::ProcessHandle process_handle) const { - return handle(); -} - void* TransportDIB::memory() const { return shared_memory_.memory(); } diff --git a/app/surface/transport_dib_win.cc b/app/surface/transport_dib_win.cc index 86bf92e..f7746e3 100644 --- a/app/surface/transport_dib_win.cc +++ b/app/surface/transport_dib_win.cc @@ -2,47 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include <windows.h> - #include <limits> +#include <windows.h> #include "app/surface/transport_dib.h" #include "base/logging.h" -#include "base/scoped_handle_win.h" #include "base/scoped_ptr.h" #include "base/sys_info.h" #include "skia/ext/platform_canvas.h" -TransportDIB::Handle TransportDIB::Handle::DupForProcess( - base::ProcessHandle new_owner_process) const { - base::ProcessId new_owner_id = ::GetProcessId(new_owner_process); - if (!new_owner_id) { - LOG(WARNING) << "Could not get process id from handle" - << " handle:" << new_owner_process - << " error:" << ::GetLastError(); - return Handle(); - } - HANDLE owner_process = ::OpenProcess(PROCESS_DUP_HANDLE, FALSE, owner_id_); - if (!owner_process) { - LOG(WARNING) << "Could not open process" - << " id:" << owner_id_ - << " error:" << ::GetLastError(); - return Handle(); - } - ScopedHandle scoped_owner_process(owner_process); - HANDLE new_section = NULL; - ::DuplicateHandle(owner_process, section_, - new_owner_process, &new_section, - STANDARD_RIGHTS_REQUIRED | FILE_MAP_ALL_ACCESS, - FALSE, 0); - if (!new_section) { - LOG(WARNING) << "Could not duplicate handle for process" - << " error:" << ::GetLastError(); - return Handle(); - } - return TransportDIB::Handle(new_section, new_owner_id, false); -} - TransportDIB::TransportDIB() { } @@ -74,73 +42,44 @@ TransportDIB* TransportDIB::Create(size_t size, uint32 sequence_num) { } // static -TransportDIB* TransportDIB::Map(Handle handle) { - scoped_ptr<TransportDIB> dib(CreateWithHandle(handle)); - if (!dib->Map()) +TransportDIB* TransportDIB::Map(TransportDIB::Handle handle) { + TransportDIB* dib = new TransportDIB(handle); + if (!dib->shared_memory_.Map(0 /* map whole shared memory segment */)) { + LOG(ERROR) << "Failed to map transport DIB" + << " handle:" << handle + << " error:" << GetLastError(); + delete dib; return NULL; - return dib.release(); -} + } -// static -TransportDIB* TransportDIB::CreateWithHandle(Handle handle) { - // It is not sufficient to compare the current process ID and the ID in the - // handle here to see if a duplication is required because they will always - // be the same in single process mode. - if (handle.should_dup_on_map()) - handle = handle.DupForProcess(::GetCurrentProcess()); - return new TransportDIB(handle.section()); + // There doesn't seem to be any way to find the size of the shared memory + // region! GetFileSize indicates that the handle is invalid. Thus, we + // conservatively set the size to the maximum and hope that the renderer + // isn't about to ask us to read off the end of the array. + dib->size_ = std::numeric_limits<size_t>::max(); + + return dib; } -// static bool TransportDIB::is_valid(Handle dib) { - return dib.section() != NULL && dib.owner_id() != NULL; + return dib != NULL; } skia::PlatformCanvas* TransportDIB::GetPlatformCanvas(int w, int h) { - // This DIB already mapped the file into this process, but PlatformCanvas - // will map it again. - DCHECK(!memory()) << "Mapped file twice in the same process."; - scoped_ptr<skia::PlatformCanvas> canvas(new skia::PlatformCanvas); - if (!canvas->initialize(w, h, true, shared_memory_.handle())) + if (!canvas->initialize(w, h, true, handle())) return NULL; return canvas.release(); } -bool TransportDIB::Map() { - if (memory()) - return true; - - if (!shared_memory_.Map(0 /* map whole shared memory segment */)) { - LOG(ERROR) << "Failed to map transport DIB" - << " handle:" << shared_memory_.handle() - << " error:" << ::GetLastError(); - return false; - } - - // There doesn't seem to be any way to find the size of the shared memory - // region! GetFileSize indicates that the handle is invalid. Thus, we - // conservatively set the size to the maximum and hope that the renderer - // isn't about to ask us to read off the end of the array. - size_ = std::numeric_limits<size_t>::max(); - return true; -} - -TransportDIB::Handle TransportDIB::GetHandleForProcess( - base::ProcessHandle process_handle) const { - return handle().DupForProcess(process_handle); -} - void* TransportDIB::memory() const { return shared_memory_.memory(); } TransportDIB::Handle TransportDIB::handle() const { - return TransferrableSectionHandle(shared_memory_.handle(), - ::GetCurrentProcessId(), - true); + return shared_memory_.handle(); } TransportDIB::Id TransportDIB::id() const { - return sequence_num_; + return Id(shared_memory_.handle(), sequence_num_); } diff --git a/chrome/browser/renderer_host/backing_store.h b/chrome/browser/renderer_host/backing_store.h index 4bcbd19..53d0288 100644 --- a/chrome/browser/renderer_host/backing_store.h +++ b/chrome/browser/renderer_host/backing_store.h @@ -48,8 +48,7 @@ class BackingStore { // DonePaintingToBackingStore(). virtual void PaintToBackingStore( RenderProcessHost* process, - TransportDIB::Id dib_id, - TransportDIB::Handle dib_handle, + TransportDIB::Id bitmap, const gfx::Rect& bitmap_rect, const std::vector<gfx::Rect>& copy_rects, bool* painted_synchronously) = 0; diff --git a/chrome/browser/renderer_host/backing_store_mac.h b/chrome/browser/renderer_host/backing_store_mac.h index 0504f68..0c1e4a7 100644 --- a/chrome/browser/renderer_host/backing_store_mac.h +++ b/chrome/browser/renderer_host/backing_store_mac.h @@ -26,8 +26,7 @@ class BackingStoreMac : public BackingStore { // BackingStore implementation. virtual void PaintToBackingStore( RenderProcessHost* process, - TransportDIB::Id dib_id, - TransportDIB::Handle dib_handle, + TransportDIB::Id bitmap, const gfx::Rect& bitmap_rect, const std::vector<gfx::Rect>& copy_rects, bool* painted_synchronously); diff --git a/chrome/browser/renderer_host/backing_store_mac.mm b/chrome/browser/renderer_host/backing_store_mac.mm index 981023ea..f793395 100644 --- a/chrome/browser/renderer_host/backing_store_mac.mm +++ b/chrome/browser/renderer_host/backing_store_mac.mm @@ -53,8 +53,7 @@ BackingStoreMac::~BackingStoreMac() { void BackingStoreMac::PaintToBackingStore( RenderProcessHost* process, - TransportDIB::Id dib_id, - TransportDIB::Handle dib_handle, + TransportDIB::Id bitmap, const gfx::Rect& bitmap_rect, const std::vector<gfx::Rect>& copy_rects, bool* painted_synchronously) { @@ -64,7 +63,7 @@ void BackingStoreMac::PaintToBackingStore( DCHECK_NE(static_cast<bool>(cg_layer()), static_cast<bool>(cg_bitmap())); - TransportDIB* dib = process->GetTransportDIB(dib_id, dib_handle); + TransportDIB* dib = process->GetTransportDIB(bitmap); if (!dib) return; diff --git a/chrome/browser/renderer_host/backing_store_manager.cc b/chrome/browser/renderer_host/backing_store_manager.cc index 745020f..4325f31 100644 --- a/chrome/browser/renderer_host/backing_store_manager.cc +++ b/chrome/browser/renderer_host/backing_store_manager.cc @@ -193,8 +193,7 @@ BackingStore* BackingStoreManager::GetBackingStore( void BackingStoreManager::PrepareBackingStore( RenderWidgetHost* host, const gfx::Size& backing_store_size, - TransportDIB::Id dib_id, - TransportDIB::Handle dib_handle, + TransportDIB::Id bitmap, const gfx::Rect& bitmap_rect, const std::vector<gfx::Rect>& copy_rects, bool* needs_full_paint, @@ -218,11 +217,8 @@ void BackingStoreManager::PrepareBackingStore( backing_store = CreateBackingStore(host, backing_store_size); } - backing_store->PaintToBackingStore(host->process(), - dib_id, - dib_handle, - bitmap_rect, - copy_rects, + backing_store->PaintToBackingStore(host->process(), bitmap, + bitmap_rect, copy_rects, painted_synchronously); } diff --git a/chrome/browser/renderer_host/backing_store_manager.h b/chrome/browser/renderer_host/backing_store_manager.h index 48e7924..1ab78cc 100644 --- a/chrome/browser/renderer_host/backing_store_manager.h +++ b/chrome/browser/renderer_host/backing_store_manager.h @@ -51,8 +51,7 @@ class BackingStoreManager { static void PrepareBackingStore( RenderWidgetHost* host, const gfx::Size& backing_store_size, - TransportDIB::Id dib_id, - TransportDIB::Handle dib_handle, + TransportDIB::Id bitmap, const gfx::Rect& bitmap_rect, const std::vector<gfx::Rect>& copy_rects, bool* needs_full_paint, diff --git a/chrome/browser/renderer_host/backing_store_proxy.cc b/chrome/browser/renderer_host/backing_store_proxy.cc index 18d6acf..ba3538b 100644 --- a/chrome/browser/renderer_host/backing_store_proxy.cc +++ b/chrome/browser/renderer_host/backing_store_proxy.cc @@ -12,6 +12,10 @@ #include "chrome/common/render_messages.h" #include "gfx/rect.h" +#if defined(OS_WIN) +#include <windows.h> +#endif + BackingStoreProxy::BackingStoreProxy(RenderWidgetHost* widget, const gfx::Size& size, GpuProcessHostUIShim* process_shim, @@ -29,15 +33,21 @@ BackingStoreProxy::~BackingStoreProxy() { void BackingStoreProxy::PaintToBackingStore( RenderProcessHost* process, - TransportDIB::Id dib_id, - TransportDIB::Handle dib_handle, + TransportDIB::Id bitmap, const gfx::Rect& bitmap_rect, const std::vector<gfx::Rect>& copy_rects, bool* painted_synchronously) { DCHECK(!waiting_for_paint_ack_); + base::ProcessId process_id; +#if defined(OS_WIN) + process_id = ::GetProcessId(process->GetHandle()); +#elif defined(OS_POSIX) + process_id = process->GetHandle(); +#endif + if (process_shim_->Send(new GpuMsg_PaintToBackingStore( - routing_id_, dib_handle, bitmap_rect, copy_rects))) { + routing_id_, process_id, bitmap, bitmap_rect, copy_rects))) { // Message sent successfully, so the caller can not destroy the // TransportDIB. OnDonePaintingToBackingStore will free it later. *painted_synchronously = false; diff --git a/chrome/browser/renderer_host/backing_store_proxy.h b/chrome/browser/renderer_host/backing_store_proxy.h index a9a3c3e..610f7ef 100644 --- a/chrome/browser/renderer_host/backing_store_proxy.h +++ b/chrome/browser/renderer_host/backing_store_proxy.h @@ -21,8 +21,7 @@ class BackingStoreProxy : public BackingStore, // BackingStore implementation. virtual void PaintToBackingStore(RenderProcessHost* process, - TransportDIB::Id dib_id, - TransportDIB::Handle dib_handle, + TransportDIB::Id bitmap, const gfx::Rect& bitmap_rect, const std::vector<gfx::Rect>& copy_rects, bool* painted_synchronously); diff --git a/chrome/browser/renderer_host/backing_store_win.cc b/chrome/browser/renderer_host/backing_store_win.cc index 02de158..94d9cbf 100644 --- a/chrome/browser/renderer_host/backing_store_win.cc +++ b/chrome/browser/renderer_host/backing_store_win.cc @@ -69,8 +69,7 @@ void CallStretchDIBits(HDC hdc, int dest_x, int dest_y, int dest_w, int dest_h, } // namespace -BackingStoreWin::BackingStoreWin(RenderWidgetHost* widget, - const gfx::Size& size) +BackingStoreWin::BackingStoreWin(RenderWidgetHost* widget, const gfx::Size& size) : BackingStore(widget, size), backing_store_dib_(NULL), original_bitmap_(NULL) { @@ -115,8 +114,7 @@ size_t BackingStoreWin::MemorySize() { void BackingStoreWin::PaintToBackingStore( RenderProcessHost* process, - TransportDIB::Id dib_id, - TransportDIB::Handle dib_handle, + TransportDIB::Id bitmap, const gfx::Rect& bitmap_rect, const std::vector<gfx::Rect>& copy_rects, bool* painted_synchronously) { @@ -134,7 +132,7 @@ void BackingStoreWin::PaintToBackingStore( original_bitmap_ = SelectObject(hdc_, backing_store_dib_); } - TransportDIB* dib = process->GetTransportDIB(dib_id, dib_handle); + TransportDIB* dib = process->GetTransportDIB(bitmap); if (!dib) return; diff --git a/chrome/browser/renderer_host/backing_store_win.h b/chrome/browser/renderer_host/backing_store_win.h index a99c835..221e0aa 100644 --- a/chrome/browser/renderer_host/backing_store_win.h +++ b/chrome/browser/renderer_host/backing_store_win.h @@ -24,8 +24,7 @@ class BackingStoreWin : public BackingStore { // BackingStore implementation. virtual size_t MemorySize(); virtual void PaintToBackingStore(RenderProcessHost* process, - TransportDIB::Id dib_id, - TransportDIB::Handle dib_handle, + TransportDIB::Id bitmap, const gfx::Rect& bitmap_rect, const std::vector<gfx::Rect>& copy_rects, bool* painted_synchronously); diff --git a/chrome/browser/renderer_host/backing_store_x.cc b/chrome/browser/renderer_host/backing_store_x.cc index 6c38088..f2704c8 100644 --- a/chrome/browser/renderer_host/backing_store_x.cc +++ b/chrome/browser/renderer_host/backing_store_x.cc @@ -158,8 +158,7 @@ void BackingStoreX::PaintRectWithoutXrender( void BackingStoreX::PaintToBackingStore( RenderProcessHost* process, - TransportDIB::Id dib_id, - TransportDIB::Handle dib_handle, + TransportDIB::Id bitmap, const gfx::Rect& bitmap_rect, const std::vector<gfx::Rect>& copy_rects, bool* painted_synchronously) { @@ -180,7 +179,7 @@ void BackingStoreX::PaintToBackingStore( height <= 0 || height > kMaxVideoLayerSize) return; - TransportDIB* dib = process->GetTransportDIB(dib_id, dib_handle); + TransportDIB* dib = process->GetTransportDIB(bitmap); if (!dib) return; diff --git a/chrome/browser/renderer_host/backing_store_x.h b/chrome/browser/renderer_host/backing_store_x.h index 2fce04f..283c19f 100644 --- a/chrome/browser/renderer_host/backing_store_x.h +++ b/chrome/browser/renderer_host/backing_store_x.h @@ -51,8 +51,7 @@ class BackingStoreX : public BackingStore { virtual size_t MemorySize(); virtual void PaintToBackingStore( RenderProcessHost* process, - TransportDIB::Id dib_id, - TransportDIB::Handle dib_handle, + TransportDIB::Id bitmap, const gfx::Rect& bitmap_rect, const std::vector<gfx::Rect>& copy_rects, bool* painted_synchronously); diff --git a/chrome/browser/renderer_host/browser_render_process_host.cc b/chrome/browser/renderer_host/browser_render_process_host.cc index 58418eb..905d8de 100644 --- a/chrome/browser/renderer_host/browser_render_process_host.cc +++ b/chrome/browser/renderer_host/browser_render_process_host.cc @@ -766,18 +766,23 @@ bool BrowserRenderProcessHost::SendWithTimeout(IPC::Message* msg, // This is a platform specific function for mapping a transport DIB given its id TransportDIB* BrowserRenderProcessHost::MapTransportDIB( - TransportDIB::Id dib_id, TransportDIB::Handle dib_handle) { -#if defined(OS_MACOSX) + TransportDIB::Id dib_id) { +#if defined(OS_WIN) + // On Windows we need to duplicate the handle from the remote process + HANDLE section = win_util::GetSectionFromProcess( + dib_id.handle, GetHandle(), false /* read write */); + return TransportDIB::Map(section); +#elif defined(OS_MACOSX) // On OSX, the browser allocates all DIBs and keeps a file descriptor around // for each. return widget_helper_->MapTransportDIB(dib_id); -#else - return TransportDIB::Map(dib_handle); -#endif +#elif defined(OS_POSIX) + return TransportDIB::Map(dib_id); +#endif // defined(OS_POSIX) } TransportDIB* BrowserRenderProcessHost::GetTransportDIB( - TransportDIB::Id dib_id, TransportDIB::Handle dib_handle) { + TransportDIB::Id dib_id) { const std::map<TransportDIB::Id, TransportDIB*>::iterator i = cached_dibs_.find(dib_id); if (i != cached_dibs_.end()) { @@ -785,7 +790,7 @@ TransportDIB* BrowserRenderProcessHost::GetTransportDIB( return i->second; } - TransportDIB* dib = MapTransportDIB(dib_id, dib_handle); + TransportDIB* dib = MapTransportDIB(dib_id); if (!dib) return NULL; diff --git a/chrome/browser/renderer_host/browser_render_process_host.h b/chrome/browser/renderer_host/browser_render_process_host.h index 16a5cac..9983c84 100644 --- a/chrome/browser/renderer_host/browser_render_process_host.h +++ b/chrome/browser/renderer_host/browser_render_process_host.h @@ -78,8 +78,7 @@ class BrowserRenderProcessHost : public RenderProcessHost, virtual bool FastShutdownIfPossible(); virtual bool SendWithTimeout(IPC::Message* msg, int timeout_ms); virtual base::ProcessHandle GetHandle(); - virtual TransportDIB* GetTransportDIB(TransportDIB::Id dib_id, - TransportDIB::Handle dib_handle); + virtual TransportDIB* GetTransportDIB(TransportDIB::Id dib_id); // IPC::Channel::Sender via RenderProcessHost. virtual bool Send(IPC::Message* msg); @@ -186,10 +185,8 @@ class BrowserRenderProcessHost : public RenderProcessHost, MAX_MAPPED_TRANSPORT_DIBS = 3, }; - // Map a transport DIB from its handle. On Mac, the ID is necessary to find - // the appropriate file descriptor. Returns NULL on error. - TransportDIB* MapTransportDIB(TransportDIB::Id dib_id, - TransportDIB::Handle dib_handle); + // Map a transport DIB from its Id and return it. Returns NULL on error. + TransportDIB* MapTransportDIB(TransportDIB::Id dib_id); void ClearTransportDIBCache(); // This is used to clear our cache five seconds after the last use. diff --git a/chrome/browser/renderer_host/mock_render_process_host.cc b/chrome/browser/renderer_host/mock_render_process_host.cc index 2764142..cdecb6f 100644 --- a/chrome/browser/renderer_host/mock_render_process_host.cc +++ b/chrome/browser/renderer_host/mock_render_process_host.cc @@ -94,16 +94,20 @@ bool MockRenderProcessHost::Send(IPC::Message* msg) { return true; } -TransportDIB* MockRenderProcessHost::GetTransportDIB( - TransportDIB::Id dib_id, TransportDIB::Handle dib_handle) { +TransportDIB* MockRenderProcessHost::GetTransportDIB(TransportDIB::Id dib_id) { if (transport_dib_) return transport_dib_; -#if defined(OS_MACOSX) +#if defined(OS_WIN) + HANDLE duped; + DuplicateHandle(GetCurrentProcess(), dib_id.handle, GetCurrentProcess(), + &duped, 0, TRUE, DUPLICATE_SAME_ACCESS); + transport_dib_ = TransportDIB::Map(duped); +#elif defined(OS_MACOSX) // On Mac, TransportDIBs are always created in the browser, so we cannot map // one from a dib_id. transport_dib_ = TransportDIB::Create(100 * 100 * 4, 0); -#else - transport_dib_ = TransportDIB::Map(dib_handle); +#elif defined(OS_POSIX) + transport_dib_ = TransportDIB::Map(dib_id); #endif return transport_dib_; diff --git a/chrome/browser/renderer_host/mock_render_process_host.h b/chrome/browser/renderer_host/mock_render_process_host.h index 2a52183..33a6516 100644 --- a/chrome/browser/renderer_host/mock_render_process_host.h +++ b/chrome/browser/renderer_host/mock_render_process_host.h @@ -55,8 +55,7 @@ class MockRenderProcessHost : public RenderProcessHost { return base::kNullProcessHandle; } - virtual TransportDIB* GetTransportDIB(TransportDIB::Id dib_id, - TransportDIB::Handle dib_handle); + virtual TransportDIB* GetTransportDIB(TransportDIB::Id dib_id); // IPC::Channel::Sender via RenderProcessHost. virtual bool Send(IPC::Message* msg); diff --git a/chrome/browser/renderer_host/render_process_host.h b/chrome/browser/renderer_host/render_process_host.h index 3e622ef..19911f0 100644 --- a/chrome/browser/renderer_host/render_process_host.h +++ b/chrome/browser/renderer_host/render_process_host.h @@ -216,12 +216,12 @@ class RenderProcessHost : public IPC::Channel::Sender, // Transport DIB functions --------------------------------------------------- - // Return the TransportDIB for the given id. On Windows and Linux, this may - // involve mapping the TransportDIB. On Mac, the shared memory is created in - // the browser process and the cached metadata is returned. The - // RenderProcessHost still owns the returned DIB. - virtual TransportDIB* GetTransportDIB(TransportDIB::Id dib_id, - TransportDIB::Handle dib_handle) = 0; + // Return the TransportDIB for the given id. On Linux, this can involve + // mapping shared memory. On Mac, the shared memory is created in the browser + // process and the cached metadata is returned. On Windows, this involves + // duplicating the handle from the remote process. The RenderProcessHost + // still owns the returned DIB. + virtual TransportDIB* GetTransportDIB(TransportDIB::Id dib_id) = 0; // Static management functions ----------------------------------------------- diff --git a/chrome/browser/renderer_host/render_widget_host.cc b/chrome/browser/renderer_host/render_widget_host.cc index f5b1a3e..7cafc63 100644 --- a/chrome/browser/renderer_host/render_widget_host.cc +++ b/chrome/browser/renderer_host/render_widget_host.cc @@ -795,8 +795,7 @@ void RenderWidgetHost::OnMsgUpdateRect( if (!is_gpu_rendering_active_) { const size_t size = params.bitmap_rect.height() * params.bitmap_rect.width() * 4; - TransportDIB* dib = process_->GetTransportDIB(params.dib_id, - params.dib_handle); + TransportDIB* dib = process_->GetTransportDIB(params.bitmap); // If gpu process does painting, scroll_rect and copy_rects are always empty // and backing store is never used. @@ -815,11 +814,8 @@ void RenderWidgetHost::OnMsgUpdateRect( // Paint the backing store. This will update it with the // renderer-supplied bits. The view will read out of the backing store // later to actually draw to the screen. - PaintBackingStoreRect(params.dib_id, - params.dib_handle, - params.bitmap_rect, - params.copy_rects, - params.view_size, + PaintBackingStoreRect(params.bitmap, params.bitmap_rect, + params.copy_rects, params.view_size, &painted_synchronously); } } @@ -883,10 +879,9 @@ void RenderWidgetHost::OnMsgCreateVideo(const gfx::Size& size) { Send(new ViewMsg_CreateVideo_ACK(routing_id_, -1)); } -void RenderWidgetHost::OnMsgUpdateVideo(TransportDIB::Id dib_id, - TransportDIB::Handle dib_handle, +void RenderWidgetHost::OnMsgUpdateVideo(TransportDIB::Id bitmap, const gfx::Rect& bitmap_rect) { - PaintVideoLayer(dib_id, dib_handle, bitmap_rect); + PaintVideoLayer(bitmap, bitmap_rect); // TODO(scherkus): support actual video ids! Send(new ViewMsg_UpdateVideo_ACK(routing_id_, -1)); @@ -1084,8 +1079,7 @@ void RenderWidgetHost::OnMsgDestroyPluginContainer(gfx::PluginWindowHandle id) { #endif void RenderWidgetHost::PaintBackingStoreRect( - TransportDIB::Id dib_id, - TransportDIB::Handle dib_handle, + TransportDIB::Id bitmap, const gfx::Rect& bitmap_rect, const std::vector<gfx::Rect>& copy_rects, const gfx::Size& view_size, @@ -1107,13 +1101,8 @@ void RenderWidgetHost::PaintBackingStoreRect( } bool needs_full_paint = false; - BackingStoreManager::PrepareBackingStore(this, - view_size, - dib_id, - dib_handle, - bitmap_rect, - copy_rects, - &needs_full_paint, + BackingStoreManager::PrepareBackingStore(this, view_size, bitmap, bitmap_rect, + copy_rects, &needs_full_paint, painted_synchronously); if (needs_full_paint) { repaint_start_time_ = TimeTicks::Now(); @@ -1142,13 +1131,12 @@ void RenderWidgetHost::ScrollBackingStoreRect(int dx, int dy, backing_store->ScrollBackingStore(dx, dy, clip_rect, view_size); } -void RenderWidgetHost::PaintVideoLayer(TransportDIB::Id dib_id, - TransportDIB::Handle dib_handle, +void RenderWidgetHost::PaintVideoLayer(TransportDIB::Id bitmap, const gfx::Rect& bitmap_rect) { if (is_hidden_ || !video_layer_.get()) return; - video_layer_->CopyTransportDIB(process(), dib_id, dib_handle, bitmap_rect); + video_layer_->CopyTransportDIB(process(), bitmap, bitmap_rect); // Don't update the view if we're hidden or if the view has been destroyed. if (is_hidden_ || !view_) diff --git a/chrome/browser/renderer_host/render_widget_host.h b/chrome/browser/renderer_host/render_widget_host.h index c587ccb..f4e0b96 100644 --- a/chrome/browser/renderer_host/render_widget_host.h +++ b/chrome/browser/renderer_host/render_widget_host.h @@ -480,9 +480,7 @@ class RenderWidgetHost : public IPC::Channel::Listener, void OnMsgPaintAtSizeAck(int tag, const gfx::Size& size); void OnMsgUpdateRect(const ViewHostMsg_UpdateRect_Params& params); void OnMsgCreateVideo(const gfx::Size& size); - void OnMsgUpdateVideo(TransportDIB::Id dib_id, - TransportDIB::Handle dib_handle, - const gfx::Rect& bitmap_rect); + void OnMsgUpdateVideo(TransportDIB::Id bitmap, const gfx::Rect& bitmap_rect); void OnMsgDestroyVideo(); void OnMsgInputEventAck(const IPC::Message& message); virtual void OnMsgFocus(); @@ -524,8 +522,7 @@ class RenderWidgetHost : public IPC::Channel::Listener, // synchronously, and the bitmap is done being used. False means that the // backing store will paint the bitmap at a later time and that the DIB can't // be freed (it will be the backing store's job to free it later). - void PaintBackingStoreRect(TransportDIB::Id dib_id, - TransportDIB::Handle dib_handle, + void PaintBackingStoreRect(TransportDIB::Id bitmap, const gfx::Rect& bitmap_rect, const std::vector<gfx::Rect>& copy_rects, const gfx::Size& view_size, @@ -540,8 +537,7 @@ class RenderWidgetHost : public IPC::Channel::Listener, // Paints the entire given bitmap into the current video layer, if it exists. // |bitmap_rect| specifies the destination size and absolute location of the // bitmap on the backing store. - void PaintVideoLayer(TransportDIB::Id dib_id, - TransportDIB::Handle dib_handle, + void PaintVideoLayer(TransportDIB::Id bitmap, const gfx::Rect& bitmap_rect); // Called by OnMsgInputEventAck() to process a keyboard event ack message. diff --git a/chrome/browser/renderer_host/render_widget_host_unittest.cc b/chrome/browser/renderer_host/render_widget_host_unittest.cc index 02b3bd8..1c5bb17 100644 --- a/chrome/browser/renderer_host/render_widget_host_unittest.cc +++ b/chrome/browser/renderer_host/render_widget_host_unittest.cc @@ -84,8 +84,7 @@ void RenderWidgetHostProcess::InitUpdateRectParams( if (!current_update_buf_) current_update_buf_ = TransportDIB::Create(pixel_size, 0); - params->dib_id = current_update_buf_->id(); - params->dib_handle = current_update_buf_->handle(); + params->bitmap = current_update_buf_->id(); params->bitmap_rect = gfx::Rect(0, 0, w, h); params->dx = 0; params->dy = 0; diff --git a/chrome/browser/renderer_host/test/test_backing_store.cc b/chrome/browser/renderer_host/test/test_backing_store.cc index 01dc7d8..d90c7fd 100644 --- a/chrome/browser/renderer_host/test/test_backing_store.cc +++ b/chrome/browser/renderer_host/test/test_backing_store.cc @@ -14,8 +14,7 @@ TestBackingStore::~TestBackingStore() { void TestBackingStore::PaintToBackingStore( RenderProcessHost* process, - TransportDIB::Id dib_id, - TransportDIB::Handle dib_handle, + TransportDIB::Id bitmap, const gfx::Rect& bitmap_rect, const std::vector<gfx::Rect>& copy_rects, bool* painted_synchronously) { diff --git a/chrome/browser/renderer_host/test/test_backing_store.h b/chrome/browser/renderer_host/test/test_backing_store.h index d532dc1..f9db76e 100644 --- a/chrome/browser/renderer_host/test/test_backing_store.h +++ b/chrome/browser/renderer_host/test/test_backing_store.h @@ -16,8 +16,7 @@ class TestBackingStore : public BackingStore { // BackingStore implementation. virtual void PaintToBackingStore(RenderProcessHost* process, - TransportDIB::Id dib_id, - TransportDIB::Handle dib_handle, + TransportDIB::Id bitmap, const gfx::Rect& bitmap_rect, const std::vector<gfx::Rect>& copy_rects, bool* painted_synchronously); diff --git a/chrome/browser/renderer_host/video_layer.h b/chrome/browser/renderer_host/video_layer.h index 4bcc245..0d7d4f8 100644 --- a/chrome/browser/renderer_host/video_layer.h +++ b/chrome/browser/renderer_host/video_layer.h @@ -26,13 +26,12 @@ class VideoLayer { RenderWidgetHost* render_widget_host() const { return render_widget_host_; } const gfx::Size& size() { return size_; } - // Copy the incoming bitmap into this video layer. The given DIB contains YUV + // Copy the incoming bitmap into this video layer. |bitmap| contains YUV // pixel data in YV12 format and must be the same dimensions as this video // layer. |bitmap_rect| specifies the absolute position and destination size // of the bitmap on the backing store. virtual void CopyTransportDIB(RenderProcessHost* process, - TransportDIB::Id dib_id, - TransportDIB::Handle dib_handle, + TransportDIB::Id bitmap, const gfx::Rect& bitmap_rect) = 0; protected: diff --git a/chrome/browser/renderer_host/video_layer_proxy.cc b/chrome/browser/renderer_host/video_layer_proxy.cc index ffb7546..3df1d25 100644 --- a/chrome/browser/renderer_host/video_layer_proxy.cc +++ b/chrome/browser/renderer_host/video_layer_proxy.cc @@ -5,6 +5,7 @@ #include "chrome/browser/renderer_host/video_layer_proxy.h" #include "chrome/browser/gpu_process_host_ui_shim.h" +#include "chrome/browser/renderer_host/render_process_host.h" #include "chrome/common/gpu_messages.h" #include "gfx/rect.h" @@ -23,11 +24,17 @@ VideoLayerProxy::~VideoLayerProxy() { } void VideoLayerProxy::CopyTransportDIB(RenderProcessHost* process, - TransportDIB::Id dib_id, - TransportDIB::Handle dib_handle, + TransportDIB::Id bitmap, const gfx::Rect& bitmap_rect) { + base::ProcessId process_id; +#if defined(OS_WIN) + process_id = ::GetProcessId(process->GetHandle()); +#elif defined(OS_POSIX) + process_id = process->GetHandle(); +#endif + if (process_shim_->Send(new GpuMsg_PaintToVideoLayer( - routing_id_, dib_handle, bitmap_rect))) { + routing_id_, process_id, bitmap, bitmap_rect))) { } else { // TODO(scherkus): what to do ?!?! } diff --git a/chrome/browser/renderer_host/video_layer_proxy.h b/chrome/browser/renderer_host/video_layer_proxy.h index 4d3b1f2f..4a4cc71 100644 --- a/chrome/browser/renderer_host/video_layer_proxy.h +++ b/chrome/browser/renderer_host/video_layer_proxy.h @@ -20,8 +20,7 @@ class VideoLayerProxy : public VideoLayer, public IPC::Channel::Listener { // VideoLayer implementation. virtual void CopyTransportDIB(RenderProcessHost* process, - TransportDIB::Id dib_id, - TransportDIB::Handle dib_handle, + TransportDIB::Id bitmap, const gfx::Rect& bitmap_rect); // IPC::Channel::Listener implementation. diff --git a/chrome/browser/renderer_host/video_layer_x.cc b/chrome/browser/renderer_host/video_layer_x.cc index b4a6cb0..09891b3 100644 --- a/chrome/browser/renderer_host/video_layer_x.cc +++ b/chrome/browser/renderer_host/video_layer_x.cc @@ -44,8 +44,7 @@ VideoLayerX::~VideoLayerX() { } void VideoLayerX::CopyTransportDIB(RenderProcessHost* process, - TransportDIB::Id dib_id, - TransportDIB::Handle dib_handle, + TransportDIB::Id bitmap, const gfx::Rect& bitmap_rect) { if (!display_) return; @@ -77,7 +76,7 @@ void VideoLayerX::CopyTransportDIB(RenderProcessHost* process, rgb_frame_size_ = new_rgb_frame_size; } - TransportDIB* dib = process->GetTransportDIB(dib_id, dib_handle); + TransportDIB* dib = process->GetTransportDIB(bitmap); if (!dib) return; diff --git a/chrome/browser/renderer_host/video_layer_x.h b/chrome/browser/renderer_host/video_layer_x.h index 8c3a66f..a12c7b4 100644 --- a/chrome/browser/renderer_host/video_layer_x.h +++ b/chrome/browser/renderer_host/video_layer_x.h @@ -20,8 +20,7 @@ class VideoLayerX : public VideoLayer { // VideoLayer implementation. virtual void CopyTransportDIB(RenderProcessHost* process, - TransportDIB::Id dib_id, - TransportDIB::Handle dib_handle, + TransportDIB::Id bitmap, const gfx::Rect& bitmap_rect); // Copy from the server-side video layer to the target window. diff --git a/chrome/browser/tab_contents/thumbnail_generator.cc b/chrome/browser/tab_contents/thumbnail_generator.cc index def3895..4d5826a 100644 --- a/chrome/browser/tab_contents/thumbnail_generator.cc +++ b/chrome/browser/tab_contents/thumbnail_generator.cc @@ -11,7 +11,6 @@ #include "base/time.h" #include "build/build_config.h" #include "chrome/browser/renderer_host/backing_store.h" -#include "chrome/browser/renderer_host/render_process_host.h" #include "chrome/browser/renderer_host/render_view_host.h" #include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/common/notification_service.h" @@ -209,8 +208,7 @@ void ThumbnailGenerator::AskForSnapshot(RenderWidgetHost* renderer, } renderer->PaintAtSize( - thumbnail_dib->GetHandleForProcess(renderer->process()->GetHandle()), - sequence_num, page_size, desired_size); + thumbnail_dib->handle(), sequence_num, page_size, desired_size); } SkBitmap ThumbnailGenerator::GetThumbnailForRenderer( @@ -301,7 +299,7 @@ void ThumbnailGenerator::WidgetDidReceivePaintAtSizeAck( if (item != callback_map_.end()) { TransportDIB* dib = item->second->thumbnail_dib.get(); DCHECK(dib); - if (!dib || !dib->Map()) { + if (!dib) { return; } diff --git a/chrome/common/common_param_traits.h b/chrome/common/common_param_traits.h index 27a86d1..a2c5dca 100644 --- a/chrome/common/common_param_traits.h +++ b/chrome/common/common_param_traits.h @@ -12,10 +12,6 @@ #define CHROME_COMMON_COMMON_PARAM_TRAITS_H_ #pragma once -#if defined(OS_WIN) -#include <windows.h> -#endif - #include <vector> #include "app/surface/transport_dib.h" @@ -242,33 +238,22 @@ struct ParamTraits<webkit_glue::WebApplicationInfo> { #if defined(OS_WIN) -template <> -struct ParamTraits<TransportDIB::Handle> { - typedef TransportDIB::Handle param_type; +template<> +struct ParamTraits<TransportDIB::Id> { + typedef TransportDIB::Id param_type; static void Write(Message* m, const param_type& p) { - WriteParam(m, p.section()); - WriteParam(m, p.owner_id()); - WriteParam(m, p.should_dup_on_map()); + WriteParam(m, p.handle); + WriteParam(m, p.sequence_num); } static bool Read(const Message* m, void** iter, param_type* r) { - HANDLE section; - base::ProcessId owner_id; - bool should_dup_on_map; - bool success = ReadParam(m, iter, §ion) && - ReadParam(m, iter, &owner_id) && - ReadParam(m, iter, &should_dup_on_map); - if (success) { - *r = TransportDIB::Handle(section, owner_id, should_dup_on_map); - } - return success; + return (ReadParam(m, iter, &r->handle) && + ReadParam(m, iter, &r->sequence_num)); } static void Log(const param_type& p, std::string* l) { - l->append("TransportDIB::Handle("); - LogParam(p.section(), l); - l->append(", "); - LogParam(p.owner_id(), l); + l->append("TransportDIB("); + LogParam(p.handle, l); l->append(", "); - LogParam(p.should_dup_on_map(), l); + LogParam(p.sequence_num, l); l->append(")"); } }; diff --git a/chrome/common/gpu_messages_internal.h b/chrome/common/gpu_messages_internal.h index 22ce601..9a6896b 100644 --- a/chrome/common/gpu_messages_internal.h +++ b/chrome/common/gpu_messages_internal.h @@ -72,11 +72,13 @@ IPC_BEGIN_MESSAGES(Gpu) // Updates the backing store with the given bitmap. The GPU process will send // back a GpuHostMsg_PaintToBackingStore_ACK after the paint is complete to // let the caller know the TransportDIB can be freed or reused. - IPC_MESSAGE_ROUTED3(GpuMsg_PaintToBackingStore, - TransportDIB::Handle, /* bitmap_handle */ + IPC_MESSAGE_ROUTED4(GpuMsg_PaintToBackingStore, + base::ProcessId, /* process */ + TransportDIB::Id, /* bitmap */ gfx::Rect, /* bitmap_rect */ std::vector<gfx::Rect>) /* copy_rects */ + IPC_MESSAGE_ROUTED4(GpuMsg_ScrollBackingStore, int, /* dx */ int, /* dy */ @@ -91,8 +93,9 @@ IPC_BEGIN_MESSAGES(Gpu) // Updates the video layer with the given YUV data. The GPU process will send // back a GpuHostMsg_PaintToVideoLayer_ACK after the paint is complete to // let the caller know the TransportDIB can be freed or reused. - IPC_MESSAGE_ROUTED2(GpuMsg_PaintToVideoLayer, - TransportDIB::Handle, /* bitmap_handle */ + IPC_MESSAGE_ROUTED3(GpuMsg_PaintToVideoLayer, + base::ProcessId, /* process */ + TransportDIB::Id, /* bitmap */ gfx::Rect) /* bitmap_rect */ IPC_END_MESSAGES(Gpu) diff --git a/chrome/common/render_messages_internal.h b/chrome/common/render_messages_internal.h index f5643af..1d6cd4f 100644 --- a/chrome/common/render_messages_internal.h +++ b/chrome/common/render_messages_internal.h @@ -1259,9 +1259,8 @@ IPC_BEGIN_MESSAGES(ViewHost) // Sent to create, update and destroy video layers. IPC_MESSAGE_ROUTED1(ViewHostMsg_CreateVideo, gfx::Size /* size */) - IPC_MESSAGE_ROUTED3(ViewHostMsg_UpdateVideo, - TransportDIB::Id /* bitmap_id */, - TransportDIB::Handle /* bitmap_handle */, + IPC_MESSAGE_ROUTED2(ViewHostMsg_UpdateVideo, + TransportDIB::Id /* bitmap */, gfx::Rect /* bitmap_rect */) IPC_MESSAGE_ROUTED0(ViewHostMsg_DestroyVideo) diff --git a/chrome/common/render_messages_params.cc b/chrome/common/render_messages_params.cc index 6f6b791..c5b4aa3 100644 --- a/chrome/common/render_messages_params.cc +++ b/chrome/common/render_messages_params.cc @@ -38,11 +38,11 @@ ViewHostMsg_FrameNavigate_Params::~ViewHostMsg_FrameNavigate_Params() { } ViewHostMsg_UpdateRect_Params::ViewHostMsg_UpdateRect_Params() - : dib_id(0), - dib_handle(TransportDIB::DefaultHandleValue()), - dx(0), + : dx(0), dy(0), flags(0) { + // On windows, bitmap is of type "struct HandleAndSequenceNum" + memset(&bitmap, 0, sizeof(bitmap)); } ViewHostMsg_UpdateRect_Params::~ViewHostMsg_UpdateRect_Params() { @@ -799,8 +799,7 @@ void ParamTraits<ViewHostMsg_FrameNavigate_Params>::Log(const param_type& p, void ParamTraits<ViewHostMsg_UpdateRect_Params>::Write( Message* m, const param_type& p) { - WriteParam(m, p.dib_id); - WriteParam(m, p.dib_handle); + WriteParam(m, p.bitmap); WriteParam(m, p.bitmap_rect); WriteParam(m, p.dx); WriteParam(m, p.dy); @@ -814,8 +813,7 @@ void ParamTraits<ViewHostMsg_UpdateRect_Params>::Write( bool ParamTraits<ViewHostMsg_UpdateRect_Params>::Read( const Message* m, void** iter, param_type* p) { return - ReadParam(m, iter, &p->dib_id) && - ReadParam(m, iter, &p->dib_handle) && + ReadParam(m, iter, &p->bitmap) && ReadParam(m, iter, &p->bitmap_rect) && ReadParam(m, iter, &p->dx) && ReadParam(m, iter, &p->dy) && @@ -829,9 +827,7 @@ bool ParamTraits<ViewHostMsg_UpdateRect_Params>::Read( void ParamTraits<ViewHostMsg_UpdateRect_Params>::Log(const param_type& p, std::string* l) { l->append("("); - LogParam(p.dib_id, l); - l->append(", "); - LogParam(p.dib_handle, l); + LogParam(p.bitmap, l); l->append(", "); LogParam(p.bitmap_rect, l); l->append(", "); diff --git a/chrome/common/render_messages_params.h b/chrome/common/render_messages_params.h index 7181b1b..2b0c0d0 100644 --- a/chrome/common/render_messages_params.h +++ b/chrome/common/render_messages_params.h @@ -285,12 +285,9 @@ struct ViewHostMsg_UpdateRect_Params { ViewHostMsg_UpdateRect_Params(); ~ViewHostMsg_UpdateRect_Params(); - // The ID of the bitmap to be painted into the view at the locations specified - // by update_rects. - TransportDIB::Id dib_id; - - // The handle to the bitmap, in case it needs to be mapped on the browser. - TransportDIB::Handle dib_handle; + // The bitmap to be painted into the view at the locations specified by + // update_rects. + TransportDIB::Id bitmap; // The position and size of the bitmap. gfx::Rect bitmap_rect; diff --git a/chrome/gpu/gpu_backing_store_glx.cc b/chrome/gpu/gpu_backing_store_glx.cc index ba5fa20..916a1db 100644 --- a/chrome/gpu/gpu_backing_store_glx.cc +++ b/chrome/gpu/gpu_backing_store_glx.cc @@ -60,10 +60,11 @@ void GpuBackingStoreGLX::OnChannelError() { } void GpuBackingStoreGLX::OnPaintToBackingStore( - TransportDIB::Handle dib_handle, + base::ProcessId source_process_id, + TransportDIB::Id id, const gfx::Rect& bitmap_rect, const std::vector<gfx::Rect>& copy_rects) { - scoped_ptr<TransportDIB> dib(TransportDIB::Map(dib_handle)); + scoped_ptr<TransportDIB> dib(TransportDIB::Map(id)); view_->BindContext(); scoped_ptr<skia::PlatformCanvas> canvas( diff --git a/chrome/gpu/gpu_backing_store_glx.h b/chrome/gpu/gpu_backing_store_glx.h index af1ced5..14b1f5f 100644 --- a/chrome/gpu/gpu_backing_store_glx.h +++ b/chrome/gpu/gpu_backing_store_glx.h @@ -36,7 +36,8 @@ class GpuBackingStoreGLX : public IPC::Channel::Listener { private: // Message handlers. - void OnPaintToBackingStore(TransportDIB::Handle dib_handle, + void OnPaintToBackingStore(base::ProcessId source_process_id, + TransportDIB::Id id, const gfx::Rect& bitmap_rect, const std::vector<gfx::Rect>& copy_rects); void OnScrollBackingStore(int dx, int dy, diff --git a/chrome/gpu/gpu_backing_store_win.cc b/chrome/gpu/gpu_backing_store_win.cc index 2b22369..d5af441 100644 --- a/chrome/gpu/gpu_backing_store_win.cc +++ b/chrome/gpu/gpu_backing_store_win.cc @@ -116,10 +116,21 @@ void GpuBackingStoreWin::OnChannelError() { } void GpuBackingStoreWin::OnPaintToBackingStore( - TransportDIB::Handle dib_handle, + base::ProcessId source_process_id, + TransportDIB::Id id, const gfx::Rect& bitmap_rect, const std::vector<gfx::Rect>& copy_rects) { - scoped_ptr<TransportDIB> dib(TransportDIB::Map(dib_handle)); + HANDLE source_process_handle = OpenProcess(PROCESS_ALL_ACCESS, + FALSE, source_process_id); + CHECK(source_process_handle); + + // On Windows we need to duplicate the handle from the remote process. + // See BrowserRenderProcessHost::MapTransportDIB for how to do this on other + // platforms. + HANDLE section = win_util::GetSectionFromProcess( + id.handle, source_process_handle, false /* read write */); + CHECK(section); + scoped_ptr<TransportDIB> dib(TransportDIB::Map(section)); CHECK(dib.get()); if (!backing_store_dib_) { @@ -157,6 +168,7 @@ void GpuBackingStoreWin::OnPaintToBackingStore( view_->InvalidateRect(&paint_rect.ToRECT()); } + CloseHandle(source_process_handle); gpu_thread_->Send(new GpuHostMsg_PaintToBackingStore_ACK(routing_id_)); } diff --git a/chrome/gpu/gpu_backing_store_win.h b/chrome/gpu/gpu_backing_store_win.h index 2899e93..fc4bfd9 100644 --- a/chrome/gpu/gpu_backing_store_win.h +++ b/chrome/gpu/gpu_backing_store_win.h @@ -42,7 +42,8 @@ class GpuBackingStoreWin : public IPC::Channel::Listener { private: // Message handlers. - void OnPaintToBackingStore(TransportDIB::Handle dib_handle, + void OnPaintToBackingStore(base::ProcessId source_process_id, + TransportDIB::Id id, const gfx::Rect& bitmap_rect, const std::vector<gfx::Rect>& copy_rects); void OnScrollBackingStore(int dx, int dy, diff --git a/chrome/gpu/gpu_video_layer_glx.cc b/chrome/gpu/gpu_video_layer_glx.cc index a90b387..d0578ad 100644 --- a/chrome/gpu/gpu_video_layer_glx.cc +++ b/chrome/gpu/gpu_video_layer_glx.cc @@ -251,7 +251,8 @@ void GpuVideoLayerGLX::OnChannelError() { NOTIMPLEMENTED(); } -void GpuVideoLayerGLX::OnPaintToVideoLayer(TransportDIB::Handle dib_handle, +void GpuVideoLayerGLX::OnPaintToVideoLayer(base::ProcessId source_process_id, + TransportDIB::Id id, const gfx::Rect& bitmap_rect) { // TODO(scherkus): |native_size_| is set in constructor, so perhaps this check // should be a DCHECK(). @@ -263,7 +264,7 @@ void GpuVideoLayerGLX::OnPaintToVideoLayer(TransportDIB::Handle dib_handle, height <= 0 || height > kMaxVideoLayerSize) return; - TransportDIB* dib = TransportDIB::Map(dib_handle); + TransportDIB* dib = TransportDIB::Map(id); if (!dib) return; diff --git a/chrome/gpu/gpu_video_layer_glx.h b/chrome/gpu/gpu_video_layer_glx.h index 89d00b1..4b3497f 100644 --- a/chrome/gpu/gpu_video_layer_glx.h +++ b/chrome/gpu/gpu_video_layer_glx.h @@ -40,7 +40,8 @@ class GpuVideoLayerGLX : public IPC::Channel::Listener { private: // Message handlers. - void OnPaintToVideoLayer(TransportDIB::Handle dib_handle, + void OnPaintToVideoLayer(base::ProcessId source_process_id, + TransportDIB::Id id, const gfx::Rect& bitmap_rect); // Calculates vertices for |object| relative to |world|, where |world| is diff --git a/chrome/plugin/webplugin_proxy.cc b/chrome/plugin/webplugin_proxy.cc index 4f3ecd3..5ec1b43 100644 --- a/chrome/plugin/webplugin_proxy.cc +++ b/chrome/plugin/webplugin_proxy.cc @@ -218,8 +218,7 @@ NPObject* WebPluginProxy::GetPluginElement() { int npobject_route_id = channel_->GenerateRouteID(); bool success = false; - Send(new PluginHostMsg_GetPluginElement(route_id_, npobject_route_id, - &success)); + Send(new PluginHostMsg_GetPluginElement(route_id_, npobject_route_id, &success)); if (!success) return NULL; @@ -518,31 +517,61 @@ void WebPluginProxy::UpdateGeometry( #endif } +#if defined(OS_WIN) void WebPluginProxy::SetWindowlessBuffer( const TransportDIB::Handle& windowless_buffer, const TransportDIB::Handle& background_buffer, const gfx::Rect& window_rect) { - // We have to handle errors here since we're mapping a large amount of memory - // that may not fit in our address space. Also, the renderer may have already - // destroyed the TransportDIB by the time we receive the handle, e.g. in case - // of multiple resizes. -#if defined(OS_MACOSX) + // Create a canvas that will reference the shared bits. We have to handle + // errors here since we're mapping a large amount of memory that may not fit + // in our address space, or go wrong in some other way. + windowless_canvas_.reset(new skia::PlatformCanvas); + if (!windowless_canvas_->initialize( + window_rect.width(), + window_rect.height(), + true, + win_util::GetSectionFromProcess(windowless_buffer, + channel_->renderer_handle(), false))) { + windowless_canvas_.reset(); + background_canvas_.reset(); + return; + } + + if (background_buffer) { + background_canvas_.reset(new skia::PlatformCanvas); + if (!background_canvas_->initialize( + window_rect.width(), + window_rect.height(), + true, + win_util::GetSectionFromProcess(background_buffer, + channel_->renderer_handle(), false))) { + windowless_canvas_.reset(); + background_canvas_.reset(); + return; + } + } +} + +#elif defined(OS_MACOSX) + +void WebPluginProxy::SetWindowlessBuffer( + const TransportDIB::Handle& windowless_buffer, + const TransportDIB::Handle& background_buffer, + const gfx::Rect& window_rect) { + // Convert the shared memory handle to a handle that works in our process, + // and then use that to create a CGContextRef. windowless_dib_.reset(TransportDIB::Map(windowless_buffer)); background_dib_.reset(TransportDIB::Map(background_buffer)); - if (windowless_dib_.get()) { - windowless_context_.reset(CGBitmapContextCreate( - windowless_dib_->memory(), - window_rect.width(), - window_rect.height(), - 8, 4 * window_rect.width(), - mac_util::GetSystemColorSpace(), - kCGImageAlphaPremultipliedFirst | - kCGBitmapByteOrder32Host)); - CGContextTranslateCTM(windowless_context_, 0, window_rect.height()); - CGContextScaleCTM(windowless_context_, 1, -1); - } else { - windowless_context_.reset(); - } + windowless_context_.reset(CGBitmapContextCreate( + windowless_dib_->memory(), + window_rect.width(), + window_rect.height(), + 8, 4 * window_rect.width(), + mac_util::GetSystemColorSpace(), + kCGImageAlphaPremultipliedFirst | + kCGBitmapByteOrder32Host)); + CGContextTranslateCTM(windowless_context_, 0, window_rect.height()); + CGContextScaleCTM(windowless_context_, 1, -1); if (background_dib_.get()) { background_context_.reset(CGBitmapContextCreate( background_dib_->memory(), @@ -554,28 +583,32 @@ void WebPluginProxy::SetWindowlessBuffer( kCGBitmapByteOrder32Host)); CGContextTranslateCTM(background_context_, 0, window_rect.height()); CGContextScaleCTM(background_context_, 1, -1); - } else { - background_context_.reset(); } -#else +} + +#elif defined(USE_X11) + +void WebPluginProxy::SetWindowlessBuffer( + const TransportDIB::Handle& windowless_buffer, + const TransportDIB::Handle& background_buffer, + const gfx::Rect& window_rect) { int width = window_rect.width(); int height = window_rect.height(); - windowless_dib_.reset(TransportDIB::CreateWithHandle(windowless_buffer)); - background_dib_.reset(TransportDIB::CreateWithHandle(background_buffer)); - windowless_canvas_.reset(windowless_dib_->GetPlatformCanvas(width, height)); - background_canvas_.reset(background_dib_->GetPlatformCanvas(width, height)); - if (!windowless_canvas_.get() || !background_canvas_.get()) { + windowless_dib_.reset(TransportDIB::Map(windowless_buffer)); + if (windowless_dib_.get()) { + windowless_canvas_.reset(windowless_dib_->GetPlatformCanvas(width, height)); + } else { + // This can happen if the renderer has already destroyed the TransportDIB + // by the time we receive the handle, e.g. in case of multiple resizes. windowless_canvas_.reset(); + } + background_dib_.reset(TransportDIB::Map(background_buffer)); + if (background_dib_.get()) { + background_canvas_.reset(background_dib_->GetPlatformCanvas(width, height)); + } else { background_canvas_.reset(); - // Destroy the TransportDIB if the canvas was not created successfully. - // Otherwise we may have an unnecessary handle which is keeping the shared - // memory open. - windowless_dib_.reset(); - background_dib_.reset(); } -#endif -#if defined(USE_X11) // If SHM pixmaps support is available, create a SHM pixmap and // pass it to the delegate for windowless plugin painting. if (delegate_->IsWindowless() && use_shm_pixmap_ && windowless_dib_.get()) { @@ -595,9 +628,10 @@ void WebPluginProxy::SetWindowlessBuffer( delegate_->SetWindowlessShmPixmap(windowless_shm_pixmap_); } -#endif } +#endif + void WebPluginProxy::CancelDocumentLoad() { Send(new PluginHostMsg_CancelDocumentLoad(route_id_)); } diff --git a/chrome/plugin/webplugin_proxy.h b/chrome/plugin/webplugin_proxy.h index f25fc70..2134bf3 100644 --- a/chrome/plugin/webplugin_proxy.h +++ b/chrome/plugin/webplugin_proxy.h @@ -203,9 +203,9 @@ class WebPluginProxy : public webkit_glue::WebPlugin { // Variables used for desynchronized windowless plugin painting. See note in // webplugin_delegate_proxy.h for how this works. bool transparent_; +#if defined(OS_MACOSX) scoped_ptr<TransportDIB> windowless_dib_; scoped_ptr<TransportDIB> background_dib_; -#if defined(OS_MACOSX) scoped_cftyperef<CGContextRef> windowless_context_; scoped_cftyperef<CGContextRef> background_context_; scoped_ptr<WebPluginAcceleratedSurfaceProxy> accelerated_surface_; @@ -214,6 +214,8 @@ class WebPluginProxy : public webkit_glue::WebPlugin { scoped_ptr<skia::PlatformCanvas> background_canvas_; #if defined(USE_X11) + scoped_ptr<TransportDIB> windowless_dib_; + scoped_ptr<TransportDIB> background_dib_; // If we can use SHM pixmaps for windowless plugin painting or not. bool use_shm_pixmap_; // The SHM pixmap for windowless plugin painting. diff --git a/chrome/renderer/media/ipc_video_renderer.cc b/chrome/renderer/media/ipc_video_renderer.cc index 15d05e6..d9a194d 100644 --- a/chrome/renderer/media/ipc_video_renderer.cc +++ b/chrome/renderer/media/ipc_video_renderer.cc @@ -160,7 +160,6 @@ void IPCVideoRenderer::DoUpdateVideo() { Send(new ViewHostMsg_UpdateVideo(routing_id_, transport_dib_->id(), - transport_dib_->handle(), video_rect_)); } diff --git a/chrome/renderer/nacl_desc_wrapper_chrome.cc b/chrome/renderer/nacl_desc_wrapper_chrome.cc index 45a5a36..a4efc70 100644 --- a/chrome/renderer/nacl_desc_wrapper_chrome.cc +++ b/chrome/renderer/nacl_desc_wrapper_chrome.cc @@ -33,7 +33,7 @@ DescWrapper* DescWrapperFactory::ImportPepper2DSharedMemory(intptr_t shm_int) { return ImportShmHandle(dib->handle().fd, dib->size()); #elif defined(OS_WIN) // TransportDIBs use MapViewOfFile shared memory on Windows. - return ImportShmHandle(dib->handle().section(), dib->size()); + return ImportShmHandle(dib->handle(), dib->size()); #else # error "What platform?" #endif diff --git a/chrome/renderer/render_widget.cc b/chrome/renderer/render_widget.cc index 5e66a06..f5a7ebe 100644 --- a/chrome/renderer/render_widget.cc +++ b/chrome/renderer/render_widget.cc @@ -508,7 +508,6 @@ void RenderWidget::DoDeferredUpdate() { // A plugin may be able to do an optimized paint. First check this, in which // case we can skip all of the bitmap generation and regular paint code. TransportDIB::Id dib_id = TransportDIB::Id(); - TransportDIB::Handle dib_handle = TransportDIB::DefaultHandleValue(); TransportDIB* dib = NULL; std::vector<gfx::Rect> copy_rects; gfx::Rect optimized_copy_rect, optimized_copy_location; @@ -519,7 +518,6 @@ void RenderWidget::DoDeferredUpdate() { bounds = optimized_copy_location; copy_rects.push_back(optimized_copy_rect); dib_id = dib->id(); - dib_handle = dib->handle(); } else if (!is_gpu_rendering_active_) { // Compute a buffer for painting and cache it. scoped_ptr<skia::PlatformCanvas> canvas( @@ -555,7 +553,6 @@ void RenderWidget::DoDeferredUpdate() { PaintRect(copy_rects[i], bounds.origin(), canvas.get()); dib_id = current_paint_buf_->id(); - dib_handle = current_paint_buf_->handle(); } else { // Accelerated compositing path // Begin painting. bool finish = next_paint_is_resize_ack(); @@ -564,8 +561,7 @@ void RenderWidget::DoDeferredUpdate() { // sending an ack to browser process that the paint is complete... ViewHostMsg_UpdateRect_Params params; - params.dib_id = dib_id; - params.dib_handle = dib_handle; + params.bitmap = dib_id; params.bitmap_rect = bounds; params.dx = update.scroll_delta.x(); params.dy = update.scroll_delta.y(); @@ -823,7 +819,7 @@ void RenderWidget::OnMsgPaintAtSize(const TransportDIB::Handle& dib_handle, int tag, const gfx::Size& page_size, const gfx::Size& desired_size) { - if (!webwidget_ || !TransportDIB::is_valid(dib_handle)) + if (!webwidget_ || dib_handle == TransportDIB::DefaultHandleValue()) return; if (page_size.IsEmpty() || desired_size.IsEmpty()) { @@ -835,17 +831,13 @@ void RenderWidget::OnMsgPaintAtSize(const TransportDIB::Handle& dib_handle, // Map the given DIB ID into this process, and unmap it at the end // of this function. - scoped_ptr<TransportDIB> paint_at_size_buffer( - TransportDIB::CreateWithHandle(dib_handle)); - gfx::Size canvas_size = page_size; - scoped_ptr<skia::PlatformCanvas> canvas( - paint_at_size_buffer->GetPlatformCanvas(canvas_size.width(), - canvas_size.height())); - if (!canvas.get()) { - NOTREACHED(); + scoped_ptr<TransportDIB> paint_at_size_buffer(TransportDIB::Map(dib_handle)); + + DCHECK(paint_at_size_buffer.get()); + if (!paint_at_size_buffer.get()) return; - } + gfx::Size canvas_size = page_size; float x_scale = static_cast<float>(desired_size.width()) / static_cast<float>(canvas_size.width()); float y_scale = static_cast<float>(desired_size.height()) / @@ -856,6 +848,14 @@ void RenderWidget::OnMsgPaintAtSize(const TransportDIB::Handle& dib_handle, canvas_size.set_height(static_cast<int>(canvas_size.height() * y_scale)); gfx::Rect bounds(canvas_size); + scoped_ptr<skia::PlatformCanvas> canvas( + paint_at_size_buffer->GetPlatformCanvas(canvas_size.width(), + canvas_size.height())); + if (!canvas.get()) { + NOTREACHED(); + return; + } + // Reset bounds to what we actually received, but they should be the // same. DCHECK_EQ(bounds.width(), canvas->getDevice()->width()); |