summaryrefslogtreecommitdiffstats
path: root/chrome/browser/renderer_host
diff options
context:
space:
mode:
authorbrettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-01-23 23:14:11 +0000
committerbrettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-01-23 23:14:11 +0000
commitbcfc90e8a909bbc199f4d80143f5eb24abda1544 (patch)
tree2ea9ba7885047e901fe55f2c4938c46633e0ee09 /chrome/browser/renderer_host
parent2a5af8a6e448b72044353b691ab7766e989db152 (diff)
downloadchromium_src-bcfc90e8a909bbc199f4d80143f5eb24abda1544.zip
chromium_src-bcfc90e8a909bbc199f4d80143f5eb24abda1544.tar.gz
chromium_src-bcfc90e8a909bbc199f4d80143f5eb24abda1544.tar.bz2
Separate out the backing store from the RenderWidgetHost into its own file to
make porting easier. I also did some cleanup in the scrolling and painting areas, collapsing the confusing ScrollRect call inside OnMsgScrollRect to just be inside the function and call a new function on the backing store to scroll it. Same for painting. This also moves plugin window moving to the view. Review URL: http://codereview.chromium.org/18702 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@8594 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/renderer_host')
-rw-r--r--chrome/browser/renderer_host/backing_store.cc243
-rw-r--r--chrome/browser/renderer_host/backing_store.h130
-rw-r--r--chrome/browser/renderer_host/render_widget_host.cc356
-rw-r--r--chrome/browser/renderer_host/render_widget_host.h66
-rw-r--r--chrome/browser/renderer_host/render_widget_host_view.h10
-rw-r--r--chrome/browser/renderer_host/render_widget_host_view_win.cc56
-rw-r--r--chrome/browser/renderer_host/render_widget_host_view_win.h2
7 files changed, 497 insertions, 366 deletions
diff --git a/chrome/browser/renderer_host/backing_store.cc b/chrome/browser/renderer_host/backing_store.cc
new file mode 100644
index 0000000..c12d0bd
--- /dev/null
+++ b/chrome/browser/renderer_host/backing_store.cc
@@ -0,0 +1,243 @@
+// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/renderer_host/backing_store.h"
+
+#include "chrome/browser/renderer_host/render_widget_host.h"
+#include "chrome/common/win_util.h"
+
+#if defined(OS_WIN)
+#include "base/gfx/gdi_util.h"
+#endif
+
+namespace {
+
+typedef OwningMRUCache<RenderWidgetHost*, BackingStore*> BackingStoreCache;
+static BackingStoreCache* cache = NULL;
+
+// Returns the size of the backing store cache.
+// TODO(iyengar) Make this dynamic, i.e. based on the available resources
+// on the machine.
+static int GetBackingStoreCacheSize() {
+ const int kMaxSize = 5;
+ return kMaxSize;
+}
+
+// Creates the backing store for the host based on the dimensions passed in.
+// Removes the existing backing store if there is one.
+BackingStore* CreateBackingStore(RenderWidgetHost* host,
+ const gfx::Rect& backing_store_rect) {
+ BackingStoreManager::RemoveBackingStore(host);
+
+ BackingStore* backing_store = new BackingStore(backing_store_rect.size());
+ int backing_store_cache_size = GetBackingStoreCacheSize();
+ if (backing_store_cache_size > 0) {
+ if (!cache)
+ cache = new BackingStoreCache(backing_store_cache_size);
+ cache->Put(host, backing_store);
+ }
+ return backing_store;
+}
+
+} // namespace
+
+#if defined(OS_WIN)
+
+// BackingStore (Windows) ------------------------------------------------------
+
+BackingStore::BackingStore(const gfx::Size& size)
+ : size_(size),
+ backing_store_dib_(NULL),
+ original_bitmap_(NULL) {
+ HDC screen_dc = ::GetDC(NULL);
+ hdc_ = CreateCompatibleDC(screen_dc);
+ ReleaseDC(NULL, screen_dc);
+}
+
+BackingStore::~BackingStore() {
+ DCHECK(hdc_);
+
+ DeleteDC(hdc_);
+
+ if (backing_store_dib_) {
+ DeleteObject(backing_store_dib_);
+ backing_store_dib_ = NULL;
+ }
+}
+
+bool BackingStore::PaintRect(base::ProcessHandle process,
+ HANDLE bitmap_section,
+ const gfx::Rect& bitmap_rect) {
+ // The bitmap received is valid only in the renderer process.
+ HANDLE valid_bitmap =
+ win_util::GetSectionFromProcess(bitmap_section, process, false);
+ if (!valid_bitmap)
+ return false;
+
+ if (!backing_store_dib_) {
+ backing_store_dib_ = CreateDIB(hdc_, size_.width(), size_.height(), true,
+ NULL);
+ DCHECK(backing_store_dib_ != NULL);
+ original_bitmap_ = SelectObject(hdc_, backing_store_dib_);
+ }
+
+ // TODO(darin): protect against integer overflow
+ DWORD size = 4 * bitmap_rect.width() * bitmap_rect.height();
+ void* backing_store_data = MapViewOfFile(valid_bitmap, FILE_MAP_READ, 0, 0,
+ size);
+ // These values are shared with gfx::PlatformDevice
+ BITMAPINFOHEADER hdr;
+ gfx::CreateBitmapHeader(bitmap_rect.width(), bitmap_rect.height(), &hdr);
+ // Account for a bitmap_rect that exceeds the bounds of our view
+ gfx::Rect view_rect(0, 0, size_.width(), size_.height());
+ gfx::Rect paint_rect = view_rect.Intersect(bitmap_rect);
+
+ StretchDIBits(hdc_,
+ paint_rect.x(),
+ paint_rect.y(),
+ paint_rect.width(),
+ paint_rect.height(),
+ 0, 0, // source x,y
+ paint_rect.width(),
+ paint_rect.height(),
+ backing_store_data,
+ reinterpret_cast<BITMAPINFO*>(&hdr),
+ DIB_RGB_COLORS,
+ SRCCOPY);
+
+ UnmapViewOfFile(backing_store_data);
+ CloseHandle(valid_bitmap);
+ return true;
+}
+
+void BackingStore::ScrollRect(base::ProcessHandle process,
+ HANDLE bitmap, const gfx::Rect& bitmap_rect,
+ int dx, int dy,
+ const gfx::Rect& clip_rect,
+ const gfx::Size& view_size) {
+ RECT damaged_rect, r = clip_rect.ToRECT();
+ ScrollDC(hdc_, dx, dy, NULL, &r, NULL, &damaged_rect);
+
+ // TODO(darin): this doesn't work if dx and dy are both non-zero!
+ DCHECK(dx == 0 || dy == 0);
+
+ // We expect that damaged_rect should equal bitmap_rect.
+ DCHECK(gfx::Rect(damaged_rect) == bitmap_rect);
+
+ PaintRect(process, bitmap, bitmap_rect);
+}
+
+HANDLE BackingStore::CreateDIB(HDC dc,
+ int width, int height,
+ bool use_system_color_depth,
+ HANDLE section) {
+ BITMAPINFOHEADER hdr;
+
+ if (use_system_color_depth) {
+ HDC screen_dc = ::GetDC(NULL);
+ int color_depth = GetDeviceCaps(screen_dc, BITSPIXEL);
+ ::ReleaseDC(NULL, screen_dc);
+
+ // Color depths less than 16 bpp require a palette to be specified in the
+ // BITMAPINFO structure passed to CreateDIBSection. Instead of creating
+ // the palette, we specify the desired color depth as 16 which allows the
+ // OS to come up with an approximation. Tested this with 8bpp.
+ if (color_depth < 16)
+ color_depth = 16;
+
+ gfx::CreateBitmapHeaderWithColorDepth(width, height, color_depth, &hdr);
+ } else {
+ gfx::CreateBitmapHeader(width, height, &hdr);
+ }
+ void* data = NULL;
+ HANDLE dib =
+ CreateDIBSection(hdc_, reinterpret_cast<BITMAPINFO*>(&hdr),
+ 0, &data, section, 0);
+ return dib;
+}
+
+#elif defined(OS_LINUX)
+
+// BackingStore (Linux) --------------------------------------------------------
+
+
+
+#elif defined(OS_MAC)
+
+// BackingStore (Mac) ----------------------------------------------------------
+
+
+
+#endif
+
+// BackingStoreManager ---------------------------------------------------------
+
+// static
+BackingStore* BackingStoreManager::GetBackingStore(
+ RenderWidgetHost* host,
+ const gfx::Size& desired_size) {
+ BackingStore* backing_store = Lookup(host);
+ if (backing_store) {
+ // If we already have a backing store, then make sure it is the correct
+ // size.
+ if (backing_store->size() == desired_size)
+ return backing_store;
+ backing_store = NULL;
+ }
+
+ return backing_store;
+}
+
+// static
+BackingStore* BackingStoreManager::PrepareBackingStore(
+ RenderWidgetHost* host,
+ const gfx::Rect& backing_store_rect,
+ HANDLE process_handle,
+ HANDLE bitmap_section,
+ const gfx::Rect& bitmap_rect,
+ bool* needs_full_paint) {
+ BackingStore* backing_store = GetBackingStore(host,
+ backing_store_rect.size());
+ if (!backing_store) {
+ // We need to get Webkit to generate a new paint here, as we
+ // don't have a previous snapshot.
+ if (bitmap_rect != backing_store_rect) {
+ DCHECK(needs_full_paint != NULL);
+ *needs_full_paint = true;
+ }
+ backing_store = CreateBackingStore(host, backing_store_rect);
+ }
+
+ DCHECK(backing_store != NULL);
+ backing_store->PaintRect(process_handle, bitmap_section, bitmap_rect);
+ return backing_store;
+}
+
+// static
+BackingStore* BackingStoreManager::Lookup(RenderWidgetHost* host) {
+ if (cache) {
+ BackingStoreCache::iterator it = cache->Peek(host);
+ if (it != cache->end())
+ return it->second;
+ }
+ return NULL;
+}
+
+// static
+void BackingStoreManager::RemoveBackingStore(RenderWidgetHost* host) {
+ if (!cache)
+ return;
+
+ BackingStoreCache::iterator it = cache->Peek(host);
+ if (it == cache->end())
+ return;
+
+ cache->Erase(it);
+
+ if (cache->empty()) {
+ delete cache;
+ cache = NULL;
+ }
+}
+
diff --git a/chrome/browser/renderer_host/backing_store.h b/chrome/browser/renderer_host/backing_store.h
new file mode 100644
index 0000000..07ed517
--- /dev/null
+++ b/chrome/browser/renderer_host/backing_store.h
@@ -0,0 +1,130 @@
+// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_RENDERER_HOST_BACKING_STORE_H_
+#define CHROME_BROWSER_RENDERER_HOST_BACKING_STORE_H_
+
+#include "base/basictypes.h"
+#include "base/gfx/rect.h"
+#include "base/gfx/size.h"
+#include "base/process.h"
+#include "build/build_config.h"
+#include "chrome/common/mru_cache.h"
+
+#if defined(OS_WIN)
+#include <windows.h>
+#endif
+
+class RenderWidgetHost;
+
+// BackingStore ----------------------------------------------------------------
+
+// Represents a backing store for the pixels in a RenderWidgetHost.
+class BackingStore {
+ public:
+ BackingStore(const gfx::Size& size);
+ ~BackingStore();
+
+ const gfx::Size& size() { return size_; }
+
+#if defined(OS_WIN)
+ HDC hdc() { return hdc_; }
+#endif
+
+ // Paints the bitmap from the renderer onto the backing store.
+ // TODO(port): The HANDLE is a shared section on Windows. Abstract this.
+ bool PaintRect(base::ProcessHandle process,
+ HANDLE bitmap_section,
+ const gfx::Rect& bitmap_rect);
+
+ // Scrolls the given rect in the backing store, replacing the given region
+ // identified by |bitmap_rect| by the bitmap in the file identified by the
+ // given file handle.
+ // TODO(port): The HANDLE is a shared section on Windows. Abstract this.
+ void ScrollRect(base::ProcessHandle process,
+ HANDLE bitmap, const gfx::Rect& bitmap_rect,
+ int dx, int dy,
+ const gfx::Rect& clip_rect,
+ const gfx::Size& view_size);
+
+ private:
+ // The size of the backing store.
+ gfx::Size size_;
+
+#if defined(OS_WIN)
+ // Creates a dib conforming to the height/width/section parameters passed
+ // in. The use_os_color_depth parameter controls whether we use the color
+ // depth to create an appropriate dib or not.
+ HANDLE CreateDIB(HDC dc,
+ int width, int height,
+ bool use_os_color_depth,
+ HANDLE section);
+
+ // The backing store dc.
+ HDC hdc_;
+
+ // Handle to the backing store dib.
+ HANDLE backing_store_dib_;
+
+ // Handle to the original bitmap in the dc.
+ HANDLE original_bitmap_;
+#endif
+
+ DISALLOW_COPY_AND_ASSIGN(BackingStore);
+};
+
+// BackingStoreManager ---------------------------------------------------------
+
+// This class manages backing stores in the browsr. Every RenderWidgetHost is
+// associated with a backing store which it requests from this class. The
+// hosts don't maintain any references to the backing stores. These backing
+// stores are maintained in a cache which can be trimmed as needed.
+class BackingStoreManager {
+ public:
+ // Returns a backing store which matches the desired dimensions.
+ //
+ // backing_store_rect
+ // The desired backing store dimensions.
+ // Returns a pointer to the backing store on success, NULL on failure.
+ static BackingStore* GetBackingStore(RenderWidgetHost* host,
+ const gfx::Size& desired_size);
+
+ // Returns a backing store which is fully ready for consumption, i.e. the
+ // bitmap from the renderer has been copied into the backing store dc, or the
+ // bitmap in the backing store dc references the renderer bitmap.
+ //
+ // backing_store_rect
+ // The desired backing store dimensions.
+ // process_handle
+ // The renderer process handle.
+ // bitmap_section
+ // The bitmap section from the renderer.
+ // bitmap_rect
+ // The rect to be painted into the backing store
+ // needs_full_paint
+ // Set if we need to send out a request to paint the view
+ // to the renderer.
+ // TODO(port): The HANDLE is a shared section on Windows. Abstract this.
+ static BackingStore* PrepareBackingStore(RenderWidgetHost* host,
+ const gfx::Rect& backing_store_rect,
+ base::ProcessHandle process_handle,
+ HANDLE bitmap_section,
+ const gfx::Rect& bitmap_rect,
+ bool* needs_full_paint);
+
+ // Returns a matching backing store for the host.
+ // Returns NULL if we fail to find one.
+ static BackingStore* Lookup(RenderWidgetHost* host);
+
+ // Removes the backing store for the host.
+ static void RemoveBackingStore(RenderWidgetHost* host);
+
+ private:
+ // Not intended for instantiation.
+ BackingStoreManager() {}
+
+ DISALLOW_COPY_AND_ASSIGN(BackingStoreManager);
+};
+
+#endif // CHROME_BROWSER_RENDERER_HOST_BACKING_STORE_H_
diff --git a/chrome/browser/renderer_host/render_widget_host.cc b/chrome/browser/renderer_host/render_widget_host.cc
index 354f54b..63dd0f3 100644
--- a/chrome/browser/renderer_host/render_widget_host.cc
+++ b/chrome/browser/renderer_host/render_widget_host.cc
@@ -7,10 +7,10 @@
#include "base/gfx/gdi_util.h"
#include "base/message_loop.h"
#include "chrome/app/chrome_dll_resource.h"
+#include "chrome/browser/renderer_host/backing_store.h"
#include "chrome/browser/renderer_host/render_process_host.h"
#include "chrome/browser/renderer_host/render_widget_helper.h"
#include "chrome/browser/renderer_host/render_widget_host_view.h"
-#include "chrome/common/mru_cache.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/win_util.h"
#include "chrome/views/view.h"
@@ -31,241 +31,6 @@ static const int kPaintMsgTimeoutMS = 40;
static const int kHungRendererDelayMs = 20000;
///////////////////////////////////////////////////////////////////////////////
-// RenderWidget::BackingStore
-
-RenderWidgetHost::BackingStore::BackingStore(const gfx::Size& size)
- : size_(size),
- backing_store_dib_(NULL),
- original_bitmap_(NULL) {
- HDC screen_dc = ::GetDC(NULL);
- hdc_ = CreateCompatibleDC(screen_dc);
- ReleaseDC(NULL, screen_dc);
-}
-
-RenderWidgetHost::BackingStore::~BackingStore() {
- DCHECK(hdc_);
-
- DeleteDC(hdc_);
-
- if (backing_store_dib_) {
- DeleteObject(backing_store_dib_);
- backing_store_dib_ = NULL;
- }
-}
-
-bool RenderWidgetHost::BackingStore::Refresh(HANDLE process,
- HANDLE bitmap_section,
- const gfx::Rect& bitmap_rect) {
- // The bitmap received is valid only in the renderer process.
- HANDLE valid_bitmap =
- win_util::GetSectionFromProcess(bitmap_section, process, false);
- if (!valid_bitmap)
- return false;
-
- if (!backing_store_dib_) {
- backing_store_dib_ = CreateDIB(hdc_, size_.width(), size_.height(), true,
- NULL);
- DCHECK(backing_store_dib_ != NULL);
- original_bitmap_ = SelectObject(hdc_, backing_store_dib_);
- }
-
- // TODO(darin): protect against integer overflow
- DWORD size = 4 * bitmap_rect.width() * bitmap_rect.height();
- void* backing_store_data = MapViewOfFile(valid_bitmap, FILE_MAP_READ, 0, 0,
- size);
- // These values are shared with gfx::PlatformDevice
- BITMAPINFOHEADER hdr;
- gfx::CreateBitmapHeader(bitmap_rect.width(), bitmap_rect.height(), &hdr);
- // Account for a bitmap_rect that exceeds the bounds of our view
- gfx::Rect view_rect(0, 0, size_.width(), size_.height());
- gfx::Rect paint_rect = view_rect.Intersect(bitmap_rect);
-
- StretchDIBits(hdc_,
- paint_rect.x(),
- paint_rect.y(),
- paint_rect.width(),
- paint_rect.height(),
- 0, 0, // source x,y
- paint_rect.width(),
- paint_rect.height(),
- backing_store_data,
- reinterpret_cast<BITMAPINFO*>(&hdr),
- DIB_RGB_COLORS,
- SRCCOPY);
-
- UnmapViewOfFile(backing_store_data);
- CloseHandle(valid_bitmap);
- return true;
-}
-
-HANDLE RenderWidgetHost::BackingStore::CreateDIB(HDC dc, int width, int height,
- bool use_system_color_depth,
- HANDLE section) {
- BITMAPINFOHEADER hdr;
-
- if (use_system_color_depth) {
- HDC screen_dc = ::GetDC(NULL);
- int color_depth = GetDeviceCaps(screen_dc, BITSPIXEL);
- ::ReleaseDC(NULL, screen_dc);
-
- // Color depths less than 16 bpp require a palette to be specified in the
- // BITMAPINFO structure passed to CreateDIBSection. Instead of creating
- // the palette, we specify the desired color depth as 16 which allows the
- // OS to come up with an approximation. Tested this with 8bpp.
- if (color_depth < 16)
- color_depth = 16;
-
- gfx::CreateBitmapHeaderWithColorDepth(width, height, color_depth, &hdr);
- } else {
- gfx::CreateBitmapHeader(width, height, &hdr);
- }
- void* data = NULL;
- HANDLE dib =
- CreateDIBSection(hdc_, reinterpret_cast<BITMAPINFO*>(&hdr),
- 0, &data, section, 0);
- return dib;
-}
-
-
-///////////////////////////////////////////////////////////////////////////////
-// RenderWidgetHost::BackingStoreManager
-
-// This class manages backing stores in the browsr. Every RenderWidgetHost
-// is associated with a backing store which it requests from this class.
-// The hosts don't maintain any references to the backing stores.
-// These backing stores are maintained in a cache which can be trimmed as
-// needed.
-class RenderWidgetHost::BackingStoreManager {
- public:
- // Returns a backing store which matches the desired dimensions.
- // Parameters:
- // host
- // A pointer to the RenderWidgetHost.
- // backing_store_rect
- // The desired backing store dimensions.
- // Returns a pointer to the backing store on success, NULL on failure.
- static BackingStore* GetBackingStore(RenderWidgetHost* host,
- const gfx::Size& desired_size) {
- BackingStore* backing_store = Lookup(host);
- if (backing_store) {
- // If we already have a backing store, then make sure it is the correct
- // size.
- if (backing_store->size() == desired_size)
- return backing_store;
- backing_store = NULL;
- }
-
- return backing_store;
- }
-
- // Returns a backing store which is fully ready for consumption,
- // i.e. the bitmap from the renderer has been copied into the
- // backing store dc, or the bitmap in the backing store dc references
- // the renderer bitmap.
- // Parameters:
- // host
- // A pointer to the RenderWidgetHost.
- // backing_store_rect
- // The desired backing store dimensions.
- // process_handle
- // The renderer process handle.
- // bitmap_section
- // The bitmap section from the renderer.
- // bitmap_rect
- // The rect to be painted into the backing store
- // needs_full_paint
- // Set if we need to send out a request to paint the view
- // to the renderer.
- static BackingStore* PrepareBackingStore(RenderWidgetHost* host,
- const gfx::Rect& backing_store_rect,
- HANDLE process_handle,
- HANDLE bitmap_section,
- const gfx::Rect& bitmap_rect,
- bool* needs_full_paint) {
- BackingStore* backing_store = GetBackingStore(host,
- backing_store_rect.size());
- if (!backing_store) {
- // We need to get Webkit to generate a new paint here, as we
- // don't have a previous snapshot.
- if (bitmap_rect != backing_store_rect) {
- DCHECK(needs_full_paint != NULL);
- *needs_full_paint = true;
- }
- backing_store = CreateBackingStore(host, backing_store_rect);
- }
-
- DCHECK(backing_store != NULL);
- backing_store->Refresh(process_handle, bitmap_section, bitmap_rect);
- return backing_store;
- }
-
- // Returns a matching backing store for the host.
- // Returns NULL if we fail to find one.
- static BackingStore* Lookup(RenderWidgetHost* host) {
- if (cache_) {
- BackingStoreCache::iterator it = cache_->Peek(host);
- if (it != cache_->end())
- return it->second;
- }
- return NULL;
- }
-
- // Removes the backing store for the host.
- static void RemoveBackingStore(RenderWidgetHost* host) {
- if (!cache_)
- return;
-
- BackingStoreCache::iterator it = cache_->Peek(host);
- if (it == cache_->end())
- return;
-
- cache_->Erase(it);
-
- if (cache_->empty()) {
- delete cache_;
- cache_ = NULL;
- }
- }
-
- private:
- // Not intended for instantiation.
- ~BackingStoreManager();
-
- typedef OwningMRUCache<RenderWidgetHost*, BackingStore*> BackingStoreCache;
- static BackingStoreCache* cache_;
-
- // Returns the size of the backing store cache.
- // TODO(iyengar) Make this dynamic, i.e. based on the available resources
- // on the machine.
- static int GetBackingStoreCacheSize() {
- const int kMaxSize = 5;
- return kMaxSize;
- }
-
- // Creates the backing store for the host based on the dimensions passed in.
- // Removes the existing backing store if there is one.
- static BackingStore* CreateBackingStore(
- RenderWidgetHost* host, const gfx::Rect& backing_store_rect) {
- RemoveBackingStore(host);
-
- BackingStore* backing_store = new BackingStore(backing_store_rect.size());
- int backing_store_cache_size = GetBackingStoreCacheSize();
- if (backing_store_cache_size > 0) {
- if (!cache_)
- cache_ = new BackingStoreCache(backing_store_cache_size);
- cache_->Put(host, backing_store);
- }
- return backing_store;
- }
-
- DISALLOW_EVIL_CONSTRUCTORS(BackingStoreManager);
-};
-
-RenderWidgetHost::BackingStoreManager::BackingStoreCache*
- RenderWidgetHost::BackingStoreManager::cache_ = NULL;
-
-
-///////////////////////////////////////////////////////////////////////////////
// RenderWidgetHost
RenderWidgetHost::RenderWidgetHost(RenderProcessHost* process,
@@ -375,17 +140,27 @@ void RenderWidgetHost::OnMsgPaintRect(
DCHECK(!params.bitmap_rect.IsEmpty());
DCHECK(!params.view_size.IsEmpty());
- PaintRect(params.bitmap, params.bitmap_rect, params.view_size);
+ // 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.bitmap, params.bitmap_rect, params.view_size);
// ACK early so we can prefetch the next PaintRect if there is a next one.
+ // This must be done AFTER we're done painting with the bitmap supplied by the
+ // renderer. This ACK is a signal to the renderer that the backing store can
+ // be re-used, so the bitmap may be invalid after this call.
Send(new ViewMsg_PaintRect_ACK(routing_id_));
- // TODO(darin): This should really be done by the view_!
- MovePluginWindows(params.plugin_window_moves);
+ // We don't need to update the view if the view is hidden. We must do this
+ // early return after the ACK is sent, however, or the renderer will not send
+ // is more data.
+ if (is_hidden_)
+ return;
- // The view might be destroyed already. Check for this case.
+ // Now paint the view. Watch out: it might be destroyed already.
if (view_ && !suppress_view_updating_) {
view_being_painted_ = true;
+ view_->MovePluginWindows(params.plugin_window_moves);
view_->DidPaintRect(params.bitmap_rect);
view_being_painted_ = false;
}
@@ -413,18 +188,27 @@ void RenderWidgetHost::OnMsgScrollRect(
DCHECK(!params.view_size.IsEmpty());
- ScrollRect(params.bitmap, params.bitmap_rect, params.dx, params.dy,
- params.clip_rect, params.view_size);
+ // Scroll the backing store.
+ ScrollBackingStoreRect(params.bitmap, params.bitmap_rect,
+ params.dx, params.dy,
+ params.clip_rect, params.view_size);
// ACK early so we can prefetch the next ScrollRect if there is a next one.
+ // This must be done AFTER we're done painting with the bitmap supplied by the
+ // renderer. This ACK is a signal to the renderer that the backing store can
+ // be re-used, so the bitmap may be invalid after this call.
Send(new ViewMsg_ScrollRect_ACK(routing_id_));
- // TODO(darin): This should really be done by the view_!
- MovePluginWindows(params.plugin_window_moves);
+ // We don't need to update the view if the view is hidden. We must do this
+ // early return after the ACK is sent, however, or the renderer will not send
+ // is more data.
+ if (is_hidden_)
+ return;
- // The view might be destroyed already. Check for this case
+ // Paint the view. Watch out: it might be destroyed already.
if (view_) {
view_being_painted_ = true;
+ view_->MovePluginWindows(params.plugin_window_moves);
view_->DidScrollRect(params.clip_rect, params.dx, params.dy);
view_being_painted_ = false;
}
@@ -434,53 +218,6 @@ void RenderWidgetHost::OnMsgScrollRect(
UMA_HISTOGRAM_TIMES(L"MPArch.RWH_OnMsgScrollRect", delta);
}
-void RenderWidgetHost::MovePluginWindows(
- const std::vector<WebPluginGeometry>& plugin_window_moves) {
- if (plugin_window_moves.empty())
- return;
-
- HDWP defer_window_pos_info =
- ::BeginDeferWindowPos(static_cast<int>(plugin_window_moves.size()));
-
- if (!defer_window_pos_info) {
- NOTREACHED();
- return;
- }
-
- for (size_t i = 0; i < plugin_window_moves.size(); ++i) {
- unsigned long flags = 0;
- const WebPluginGeometry& move = plugin_window_moves[i];
-
- if (move.visible)
- flags |= SWP_SHOWWINDOW;
- else
- flags |= SWP_HIDEWINDOW;
-
- HRGN hrgn = ::CreateRectRgn(move.clip_rect.x(),
- move.clip_rect.y(),
- move.clip_rect.right(),
- move.clip_rect.bottom());
- gfx::SubtractRectanglesFromRegion(hrgn, move.cutout_rects);
-
- // Note: System will own the hrgn after we call SetWindowRgn,
- // so we don't need to call DeleteObject(hrgn)
- ::SetWindowRgn(move.window, hrgn, !move.clip_rect.IsEmpty());
-
- defer_window_pos_info = ::DeferWindowPos(defer_window_pos_info,
- move.window, NULL,
- move.window_rect.x(),
- move.window_rect.y(),
- move.window_rect.width(),
- move.window_rect.height(), flags);
- if (!defer_window_pos_info) {
- DCHECK(false) << "DeferWindowPos given invalid window, so rest ignored.";
- return;
- }
- }
-
- ::EndDeferWindowPos(defer_window_pos_info);
-}
-
void RenderWidgetHost::OnMsgInputEventAck(const IPC::Message& message) {
// Log the time delta for processing an input event.
TimeDelta delta = TimeTicks::Now() - input_event_start_time_;
@@ -726,7 +463,7 @@ void RenderWidgetHost::SetIsLoading(bool is_loading) {
view_->SetIsLoading(is_loading);
}
-RenderWidgetHost::BackingStore* RenderWidgetHost::GetBackingStore() {
+BackingStore* RenderWidgetHost::GetBackingStore() {
// We should not be asked to paint while we are hidden. If we are hidden,
// then it means that our consumer failed to call WasRestored.
DCHECK(!is_hidden_) << "GetBackingStore called while hidden!";
@@ -761,9 +498,13 @@ RenderWidgetHost::BackingStore* RenderWidgetHost::GetBackingStore() {
return backing_store;
}
-void RenderWidgetHost::PaintRect(HANDLE bitmap, const gfx::Rect& bitmap_rect,
- const gfx::Size& view_size) {
+void RenderWidgetHost::PaintBackingStoreRect(HANDLE bitmap,
+ const gfx::Rect& bitmap_rect,
+ const gfx::Size& view_size) {
if (is_hidden_) {
+ // Don't bother updating the backing store when we're hidden. Just mark it
+ // as being totally invalid. This will cause a complete repaint when the
+ // view is restored.
needs_repainting_on_restore_ = true;
return;
}
@@ -786,10 +527,15 @@ void RenderWidgetHost::PaintRect(HANDLE bitmap, const gfx::Rect& bitmap_rect,
}
}
-void RenderWidgetHost::ScrollRect(HANDLE bitmap, const gfx::Rect& bitmap_rect,
- int dx, int dy, const gfx::Rect& clip_rect,
- const gfx::Size& view_size) {
+void RenderWidgetHost::ScrollBackingStoreRect(HANDLE bitmap,
+ const gfx::Rect& bitmap_rect,
+ int dx, int dy,
+ const gfx::Rect& clip_rect,
+ const gfx::Size& view_size) {
if (is_hidden_) {
+ // Don't bother updating the backing store when we're hidden. Just mark it
+ // as being totally invalid. This will cause a complete repaint when the
+ // view is restored.
needs_repainting_on_restore_ = true;
return;
}
@@ -800,19 +546,11 @@ void RenderWidgetHost::ScrollRect(HANDLE bitmap, const gfx::Rect& bitmap_rect,
BackingStore* backing_store = BackingStoreManager::Lookup(this);
if (!backing_store || (backing_store->size() != view_size))
return;
-
- RECT damaged_rect, r = clip_rect.ToRECT();
- ScrollDC(backing_store->dc(), dx, dy, NULL, &r, NULL, &damaged_rect);
-
- // TODO(darin): this doesn't work if dx and dy are both non-zero!
- DCHECK(dx == 0 || dy == 0);
-
- // We expect that damaged_rect should equal bitmap_rect.
- DCHECK(gfx::Rect(damaged_rect) == bitmap_rect);
-
- backing_store->Refresh(process_->process().handle(), bitmap, bitmap_rect);
+ backing_store->ScrollRect(process_->process().handle(), bitmap, bitmap_rect,
+ dx, dy, clip_rect, view_size);
}
+
void RenderWidgetHost::RestartHangMonitorTimeout() {
StartHangMonitorTimeout(TimeDelta::FromMilliseconds(kHungRendererDelayMs));
}
diff --git a/chrome/browser/renderer_host/render_widget_host.h b/chrome/browser/renderer_host/render_widget_host.h
index d683e84..5992b69 100644
--- a/chrome/browser/renderer_host/render_widget_host.h
+++ b/chrome/browser/renderer_host/render_widget_host.h
@@ -157,13 +157,6 @@ class RenderWidgetHost : public IPC::Channel::Listener {
// Indicates if the page has finished loading.
virtual void SetIsLoading(bool is_loading);
- // Represents a device-dependent drawing surface used to hold the rendering
- // of a RenderWidgetHost.
- class BackingStore;
-
- // Manages a set of backing stores.
- class BackingStoreManager;
-
// Get access to the widget's backing store. If a resize is in progress,
// then the current size of the backing store may be less than the size of
// the widget's view. This method returns NULL if the backing store could
@@ -226,9 +219,6 @@ class RenderWidgetHost : public IPC::Channel::Listener {
void OnMsgImeUpdateStatus(ViewHostMsg_ImeControl control,
const gfx::Rect& caret_rect);
- void MovePluginWindows(
- const std::vector<WebPluginGeometry>& plugin_window_moves);
-
// TODO(beng): (Cleanup) remove this friendship once we expose a clean API to
// RenderWidgetHost Views. This exists only to give RenderWidgetHostView
// access to Forward*Event.
@@ -239,14 +229,6 @@ class RenderWidgetHost : public IPC::Channel::Listener {
void ForwardWheelEvent(const WebMouseWheelEvent& wheel_event);
void ForwardInputEvent(const WebInputEvent& input_event, int event_size);
- // Called to paint a region of the backing store
- void PaintRect(HANDLE bitmap, const gfx::Rect& bitmap_rect,
- const gfx::Size& view_size);
-
- // Called to scroll a region of the backing store
- void ScrollRect(HANDLE bitmap, const gfx::Rect& bitmap_rect, int dx, int dy,
- const gfx::Rect& clip_rect, const gfx::Size& view_size);
-
// Tell this object to destroy itself.
void Destroy();
@@ -324,38 +306,22 @@ class RenderWidgetHost : public IPC::Channel::Listener {
// operation to finish.
base::TimeTicks repaint_start_time_;
- DISALLOW_EVIL_CONSTRUCTORS(RenderWidgetHost);
-};
-
-class RenderWidgetHost::BackingStore {
- public:
- BackingStore(const gfx::Size& size);
- ~BackingStore();
-
- HDC dc() { return hdc_; }
- const gfx::Size& size() { return size_; }
-
- // Paints the bitmap from the renderer onto the backing store.
- bool Refresh(HANDLE process, HANDLE bitmap_section,
- const gfx::Rect& bitmap_rect);
-
private:
- // Creates a dib conforming to the height/width/section parameters passed
- // in. The use_os_color_depth parameter controls whether we use the color
- // depth to create an appropriate dib or not.
- HANDLE CreateDIB(HDC dc, int width, int height, bool use_os_color_depth,
- HANDLE section);
-
- // The backing store dc.
- HDC hdc_;
- // The size of the backing store.
- gfx::Size size_;
- // Handle to the backing store dib.
- HANDLE backing_store_dib_;
- // Handle to the original bitmap in the dc.
- HANDLE original_bitmap_;
-
- DISALLOW_COPY_AND_ASSIGN(BackingStore);
+ // Paints the given bitmap to the current backing store at the given location.
+ void PaintBackingStoreRect(HANDLE bitmap,
+ const gfx::Rect& bitmap_rect,
+ const gfx::Size& view_size);
+
+ // Scrolls the given |clip_rect| in the backing by the given dx/dy amount. The
+ // |bitmap| and its corresponding location |bitmap_rect| in the backing store
+ // is the newly painted pixels by the renderer.
+ void ScrollBackingStoreRect(HANDLE bitmap,
+ const gfx::Rect& bitmap_rect,
+ int dx, int dy,
+ const gfx::Rect& clip_rect,
+ const gfx::Size& view_size);
+
+ DISALLOW_COPY_AND_ASSIGN(RenderWidgetHost);
};
class RenderWidgetHost::PaintObserver {
@@ -366,4 +332,4 @@ class RenderWidgetHost::PaintObserver {
virtual void RenderWidgetHostDidPaint(RenderWidgetHost* rwh) = 0;
};
-#endif // #ifndef CHROME_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_H_
+#endif // CHROME_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_H_
diff --git a/chrome/browser/renderer_host/render_widget_host_view.h b/chrome/browser/renderer_host/render_widget_host_view.h
index 8e6152f..1a3facfa 100644
--- a/chrome/browser/renderer_host/render_widget_host_view.h
+++ b/chrome/browser/renderer_host/render_widget_host_view.h
@@ -59,6 +59,10 @@ class RenderWidgetHostView {
// Retrieves the HWND used to contain plugin HWNDs.
virtual HWND GetPluginHWND() = 0;
+ // Moves all plugin windows as described in the given list.
+ virtual void MovePluginWindows(
+ const std::vector<WebPluginGeometry>& plugin_window_moves) = 0;
+
// Sends the specified mouse event to the renderer.
virtual void ForwardMouseEventToRenderer(UINT message,
WPARAM wparam,
@@ -92,10 +96,14 @@ class RenderWidgetHostView {
const gfx::Rect& caret_rect) = 0;
// Informs the view that a portion of the widget's backing store was painted.
+ // The view should copy the given rect from the backing store of the render
+ // widget onto the screen.
virtual void DidPaintRect(const gfx::Rect& rect) = 0;
// Informs the view that a portion of the widget's backing store was scrolled
- // by dx pixels horizontally and dy pixels vertically.
+ // by dx pixels horizontally and dy pixels vertically. The view should copy
+ // the exposed pixels from the backing store of the render widget (which has
+ // already been scrolled) onto the screen.
virtual void DidScrollRect(
const gfx::Rect& rect, int dx, int dy) = 0;
diff --git a/chrome/browser/renderer_host/render_widget_host_view_win.cc b/chrome/browser/renderer_host/render_widget_host_view_win.cc
index f628809..eacf329 100644
--- a/chrome/browser/renderer_host/render_widget_host_view_win.cc
+++ b/chrome/browser/renderer_host/render_widget_host_view_win.cc
@@ -12,10 +12,8 @@
#include "chrome/browser/browser_accessibility.h"
#include "chrome/browser/browser_accessibility_manager.h"
#include "chrome/browser/browser_trial.h"
+#include "chrome/browser/renderer_host/backing_store.h"
#include "chrome/browser/renderer_host/render_process_host.h"
-// TODO(beng): (Cleanup) we should not need to include this file... see comment
-// in |DidBecomeSelected|.
-#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/renderer_host/render_widget_host.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_switches.h"
@@ -143,6 +141,53 @@ HWND RenderWidgetHostViewWin::GetPluginHWND() {
return m_hWnd;
}
+void RenderWidgetHostViewWin::MovePluginWindows(
+ const std::vector<WebPluginGeometry>& plugin_window_moves) {
+ if (plugin_window_moves.empty())
+ return;
+
+ HDWP defer_window_pos_info =
+ ::BeginDeferWindowPos(static_cast<int>(plugin_window_moves.size()));
+
+ if (!defer_window_pos_info) {
+ NOTREACHED();
+ return;
+ }
+
+ for (size_t i = 0; i < plugin_window_moves.size(); ++i) {
+ unsigned long flags = 0;
+ const WebPluginGeometry& move = plugin_window_moves[i];
+
+ if (move.visible)
+ flags |= SWP_SHOWWINDOW;
+ else
+ flags |= SWP_HIDEWINDOW;
+
+ HRGN hrgn = ::CreateRectRgn(move.clip_rect.x(),
+ move.clip_rect.y(),
+ move.clip_rect.right(),
+ move.clip_rect.bottom());
+ gfx::SubtractRectanglesFromRegion(hrgn, move.cutout_rects);
+
+ // Note: System will own the hrgn after we call SetWindowRgn,
+ // so we don't need to call DeleteObject(hrgn)
+ ::SetWindowRgn(move.window, hrgn, !move.clip_rect.IsEmpty());
+
+ defer_window_pos_info = ::DeferWindowPos(defer_window_pos_info,
+ move.window, NULL,
+ move.window_rect.x(),
+ move.window_rect.y(),
+ move.window_rect.width(),
+ move.window_rect.height(), flags);
+ if (!defer_window_pos_info) {
+ DCHECK(false) << "DeferWindowPos given invalid window, so rest ignored.";
+ return;
+ }
+ }
+
+ ::EndDeferWindowPos(defer_window_pos_info);
+}
+
void RenderWidgetHostViewWin::ForwardMouseEventToRenderer(UINT message,
WPARAM wparam,
LPARAM lparam) {
@@ -401,8 +446,7 @@ void RenderWidgetHostViewWin::OnPaint(HDC dc) {
CPaintDC paint_dc(m_hWnd);
HBRUSH white_brush = reinterpret_cast<HBRUSH>(GetStockObject(WHITE_BRUSH));
- RenderWidgetHost::BackingStore* backing_store =
- render_widget_host_->GetBackingStore();
+ BackingStore* backing_store = render_widget_host_->GetBackingStore();
if (backing_store) {
gfx::Rect damaged_rect(paint_dc.m_ps.rcPaint);
@@ -417,7 +461,7 @@ void RenderWidgetHostViewWin::OnPaint(HDC dc) {
paint_rect.y(),
paint_rect.width(),
paint_rect.height(),
- backing_store->dc(),
+ backing_store->hdc(),
paint_rect.x(),
paint_rect.y(),
SRCCOPY);
diff --git a/chrome/browser/renderer_host/render_widget_host_view_win.h b/chrome/browser/renderer_host/render_widget_host_view_win.h
index a735ab0..e8456be 100644
--- a/chrome/browser/renderer_host/render_widget_host_view_win.h
+++ b/chrome/browser/renderer_host/render_widget_host_view_win.h
@@ -125,6 +125,8 @@ class RenderWidgetHostViewWin :
virtual void WasHidden();
virtual void SetSize(const gfx::Size& size);
virtual HWND GetPluginHWND();
+ virtual void MovePluginWindows(
+ const std::vector<WebPluginGeometry>& plugin_window_moves);
virtual void ForwardMouseEventToRenderer(UINT message,
WPARAM wparam,
LPARAM lparam);