summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/renderer_host/backing_store.h9
-rw-r--r--chrome/browser/renderer_host/backing_store_mac.mm8
-rw-r--r--chrome/browser/renderer_host/backing_store_win.cc10
-rw-r--r--chrome/browser/renderer_host/backing_store_x.cc7
-rw-r--r--chrome/browser/renderer_host/browser_render_process_host.cc9
-rw-r--r--chrome/browser/renderer_host/browser_render_process_host.h6
-rw-r--r--chrome/browser/renderer_host/mock_render_process_host.cc6
-rw-r--r--chrome/browser/renderer_host/mock_render_process_host.h6
-rw-r--r--chrome/browser/renderer_host/render_process_host.h10
-rw-r--r--chrome/browser/renderer_host/render_widget_helper.cc40
-rw-r--r--chrome/browser/renderer_host/render_widget_helper.h48
-rw-r--r--chrome/browser/renderer_host/render_widget_host.cc95
-rw-r--r--chrome/browser/renderer_host/render_widget_host.h11
-rw-r--r--chrome/browser/renderer_host/render_widget_host_unittest.cc101
-rw-r--r--chrome/browser/renderer_host/render_widget_host_view.h5
-rw-r--r--chrome/browser/renderer_host/render_widget_host_view_gtk.cc20
-rw-r--r--chrome/browser/renderer_host/render_widget_host_view_gtk.h4
-rw-r--r--chrome/browser/renderer_host/render_widget_host_view_mac.h4
-rw-r--r--chrome/browser/renderer_host/render_widget_host_view_mac.mm33
-rw-r--r--chrome/browser/renderer_host/render_widget_host_view_win.cc95
-rw-r--r--chrome/browser/renderer_host/render_widget_host_view_win.h6
-rw-r--r--chrome/browser/renderer_host/resource_message_filter.cc4
-rw-r--r--chrome/browser/renderer_host/test/test_render_view_host.h6
-rw-r--r--chrome/common/render_messages.h111
-rw-r--r--chrome/common/render_messages_internal.h23
-rw-r--r--chrome/renderer/render_widget.cc187
-rw-r--r--chrome/renderer/render_widget.h26
27 files changed, 380 insertions, 510 deletions
diff --git a/chrome/browser/renderer_host/backing_store.h b/chrome/browser/renderer_host/backing_store.h
index 387a564..68514e4 100644
--- a/chrome/browser/renderer_host/backing_store.h
+++ b/chrome/browser/renderer_host/backing_store.h
@@ -98,12 +98,9 @@ class BackingStore {
const gfx::Rect& bitmap_rect,
const gfx::Rect& copy_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.
- void ScrollRect(base::ProcessHandle process,
- TransportDIB* bitmap, const gfx::Rect& bitmap_rect,
- int dx, int dy,
+ // Scrolls the contents of clip_rect in the backing store by dx or dy (but dx
+ // and dy cannot both be non-zero).
+ void ScrollRect(int dx, int dy,
const gfx::Rect& clip_rect,
const gfx::Size& view_size);
diff --git a/chrome/browser/renderer_host/backing_store_mac.mm b/chrome/browser/renderer_host/backing_store_mac.mm
index 1de83b2..0b8fa6e 100644
--- a/chrome/browser/renderer_host/backing_store_mac.mm
+++ b/chrome/browser/renderer_host/backing_store_mac.mm
@@ -99,10 +99,7 @@ void BackingStore::PaintRect(base::ProcessHandle process,
}
// Scroll the contents of our CGLayer
-void BackingStore::ScrollRect(base::ProcessHandle process,
- TransportDIB* bitmap,
- const gfx::Rect& bitmap_rect,
- int dx, int dy,
+void BackingStore::ScrollRect(int dx, int dy,
const gfx::Rect& clip_rect,
const gfx::Size& view_size) {
DCHECK_NE(static_cast<bool>(cg_layer()), static_cast<bool>(cg_bitmap()));
@@ -158,9 +155,6 @@ void BackingStore::ScrollRect(base::ProcessHandle process,
cg_bitmap_.swap(new_bitmap);
}
}
- // Now paint the new bitmap data
- PaintRect(process, bitmap, bitmap_rect, bitmap_rect);
- return;
}
CGLayerRef BackingStore::CreateCGLayer() {
diff --git a/chrome/browser/renderer_host/backing_store_win.cc b/chrome/browser/renderer_host/backing_store_win.cc
index 6cbaa34..ae772dc 100644
--- a/chrome/browser/renderer_host/backing_store_win.cc
+++ b/chrome/browser/renderer_host/backing_store_win.cc
@@ -146,10 +146,7 @@ void BackingStore::PaintRect(base::ProcessHandle process,
reinterpret_cast<BITMAPINFO*>(&hdr));
}
-void BackingStore::ScrollRect(base::ProcessHandle process,
- TransportDIB* bitmap,
- const gfx::Rect& bitmap_rect,
- int dx, int dy,
+void BackingStore::ScrollRect(int dx, int dy,
const gfx::Rect& clip_rect,
const gfx::Size& view_size) {
RECT damaged_rect, r = clip_rect.ToRECT();
@@ -157,9 +154,4 @@ void BackingStore::ScrollRect(base::ProcessHandle process,
// 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, bitmap_rect);
}
diff --git a/chrome/browser/renderer_host/backing_store_x.cc b/chrome/browser/renderer_host/backing_store_x.cc
index 74ea8ac..a1173b8 100644
--- a/chrome/browser/renderer_host/backing_store_x.cc
+++ b/chrome/browser/renderer_host/backing_store_x.cc
@@ -311,10 +311,7 @@ void BackingStore::PaintRect(base::ProcessHandle process,
XFreePixmap(display_, pixmap);
}
-void BackingStore::ScrollRect(base::ProcessHandle process,
- TransportDIB* bitmap,
- const gfx::Rect& bitmap_rect,
- int dx, int dy,
+void BackingStore::ScrollRect(int dx, int dy,
const gfx::Rect& clip_rect,
const gfx::Size& view_size) {
if (!display_)
@@ -346,8 +343,6 @@ void BackingStore::ScrollRect(base::ProcessHandle process,
clip_rect.y() /* dest x */);
}
}
-
- PaintRect(process, bitmap, bitmap_rect, bitmap_rect);
}
void BackingStore::ShowRect(const gfx::Rect& rect, XID target) {
diff --git a/chrome/browser/renderer_host/browser_render_process_host.cc b/chrome/browser/renderer_host/browser_render_process_host.cc
index a6f02a3..2d7d2f8 100644
--- a/chrome/browser/renderer_host/browser_render_process_host.cc
+++ b/chrome/browser/renderer_host/browser_render_process_host.cc
@@ -347,15 +347,16 @@ void BrowserRenderProcessHost::CrossSiteClosePageACK(
widget_helper_->CrossSiteClosePageACK(params);
}
-bool BrowserRenderProcessHost::WaitForPaintMsg(int render_widget_id,
- const base::TimeDelta& max_delay,
- IPC::Message* msg) {
+bool BrowserRenderProcessHost::WaitForUpdateMsg(
+ int render_widget_id,
+ const base::TimeDelta& max_delay,
+ IPC::Message* msg) {
// The post task to this thread with the process id could be in queue, and we
// don't want to dispatch a message before then since it will need the handle.
if (child_process_.get() && child_process_->IsStarting())
return false;
- return widget_helper_->WaitForPaintMsg(render_widget_id, max_delay, msg);
+ return widget_helper_->WaitForUpdateMsg(render_widget_id, max_delay, msg);
}
void BrowserRenderProcessHost::ReceivedBadMessage(uint32 msg_type) {
diff --git a/chrome/browser/renderer_host/browser_render_process_host.h b/chrome/browser/renderer_host/browser_render_process_host.h
index cd94bf5..3a6e83b 100644
--- a/chrome/browser/renderer_host/browser_render_process_host.h
+++ b/chrome/browser/renderer_host/browser_render_process_host.h
@@ -63,9 +63,9 @@ class BrowserRenderProcessHost : public RenderProcessHost,
virtual int GetNextRoutingID();
virtual void CancelResourceRequests(int render_widget_id);
virtual void CrossSiteClosePageACK(const ViewMsg_ClosePage_Params& params);
- virtual bool WaitForPaintMsg(int render_widget_id,
- const base::TimeDelta& max_delay,
- IPC::Message* msg);
+ virtual bool WaitForUpdateMsg(int render_widget_id,
+ const base::TimeDelta& max_delay,
+ IPC::Message* msg);
virtual void ReceivedBadMessage(uint32 msg_type);
virtual void WidgetRestored();
virtual void WidgetHidden();
diff --git a/chrome/browser/renderer_host/mock_render_process_host.cc b/chrome/browser/renderer_host/mock_render_process_host.cc
index 8be0416..b18cc50 100644
--- a/chrome/browser/renderer_host/mock_render_process_host.cc
+++ b/chrome/browser/renderer_host/mock_render_process_host.cc
@@ -31,9 +31,9 @@ void MockRenderProcessHost::CrossSiteClosePageACK(
const ViewMsg_ClosePage_Params& params) {
}
-bool MockRenderProcessHost::WaitForPaintMsg(int render_widget_id,
- const base::TimeDelta& max_delay,
- IPC::Message* msg) {
+bool MockRenderProcessHost::WaitForUpdateMsg(int render_widget_id,
+ const base::TimeDelta& max_delay,
+ IPC::Message* msg) {
return false;
}
diff --git a/chrome/browser/renderer_host/mock_render_process_host.h b/chrome/browser/renderer_host/mock_render_process_host.h
index aa04651..70ed985 100644
--- a/chrome/browser/renderer_host/mock_render_process_host.h
+++ b/chrome/browser/renderer_host/mock_render_process_host.h
@@ -35,9 +35,9 @@ class MockRenderProcessHost : public RenderProcessHost {
virtual int GetNextRoutingID();
virtual void CancelResourceRequests(int render_widget_id);
virtual void CrossSiteClosePageACK(const ViewMsg_ClosePage_Params& params);
- virtual bool WaitForPaintMsg(int render_widget_id,
- const base::TimeDelta& max_delay,
- IPC::Message* msg);
+ virtual bool WaitForUpdateMsg(int render_widget_id,
+ const base::TimeDelta& max_delay,
+ IPC::Message* msg);
virtual void ReceivedBadMessage(uint32 msg_type);
virtual void WidgetRestored();
virtual void WidgetHidden();
diff --git a/chrome/browser/renderer_host/render_process_host.h b/chrome/browser/renderer_host/render_process_host.h
index aad1f83..7979d24 100644
--- a/chrome/browser/renderer_host/render_process_host.h
+++ b/chrome/browser/renderer_host/render_process_host.h
@@ -165,12 +165,12 @@ class RenderProcessHost : public IPC::Channel::Sender,
virtual void CrossSiteClosePageACK(
const ViewMsg_ClosePage_Params& params) = 0;
- // Called on the UI thread to wait for the next PaintRect message for the
+ // Called on the UI thread to wait for the next UpdateRect message for the
// specified render widget. Returns true if successful, and the msg out-
- // param will contain a copy of the received PaintRect message.
- virtual bool WaitForPaintMsg(int render_widget_id,
- const base::TimeDelta& max_delay,
- IPC::Message* msg) = 0;
+ // param will contain a copy of the received UpdateRect message.
+ virtual bool WaitForUpdateMsg(int render_widget_id,
+ const base::TimeDelta& max_delay,
+ IPC::Message* msg) = 0;
// Called when a received message cannot be decoded.
virtual void ReceivedBadMessage(uint32 msg_type) = 0;
diff --git a/chrome/browser/renderer_host/render_widget_helper.cc b/chrome/browser/renderer_host/render_widget_helper.cc
index 8916c70..dffc9c5 100644
--- a/chrome/browser/renderer_host/render_widget_helper.cc
+++ b/chrome/browser/renderer_host/render_widget_helper.cc
@@ -14,24 +14,24 @@
// A Task used with InvokeLater that we hold a pointer to in pending_paints_.
// Instances are deleted by MessageLoop after it calls their Run method.
-class RenderWidgetHelper::PaintMsgProxy : public Task {
+class RenderWidgetHelper::UpdateMsgProxy : public Task {
public:
- PaintMsgProxy(RenderWidgetHelper* h, const IPC::Message& m)
+ UpdateMsgProxy(RenderWidgetHelper* h, const IPC::Message& m)
: helper(h),
message(m),
cancelled(false) {
}
- ~PaintMsgProxy() {
+ ~UpdateMsgProxy() {
// If the paint message was never dispatched, then we need to let the
// helper know that we are going away.
if (!cancelled && helper)
- helper->OnDiscardPaintMsg(this);
+ helper->OnDiscardUpdateMsg(this);
}
virtual void Run() {
if (!cancelled) {
- helper->OnDispatchPaintMsg(this);
+ helper->OnDispatchUpdateMsg(this);
helper = NULL;
}
}
@@ -40,7 +40,7 @@ class RenderWidgetHelper::PaintMsgProxy : public Task {
IPC::Message message;
bool cancelled; // If true, then the message will not be dispatched.
- DISALLOW_COPY_AND_ASSIGN(PaintMsgProxy);
+ DISALLOW_COPY_AND_ASSIGN(UpdateMsgProxy);
};
RenderWidgetHelper::RenderWidgetHelper()
@@ -94,17 +94,17 @@ void RenderWidgetHelper::CrossSiteClosePageACK(
params));
}
-bool RenderWidgetHelper::WaitForPaintMsg(int render_widget_id,
- const base::TimeDelta& max_delay,
- IPC::Message* msg) {
+bool RenderWidgetHelper::WaitForUpdateMsg(int render_widget_id,
+ const base::TimeDelta& max_delay,
+ IPC::Message* msg) {
base::TimeTicks time_start = base::TimeTicks::Now();
for (;;) {
- PaintMsgProxy* proxy = NULL;
+ UpdateMsgProxy* proxy = NULL;
{
AutoLock lock(pending_paints_lock_);
- PaintMsgProxyMap::iterator it = pending_paints_.find(render_widget_id);
+ UpdateMsgProxyMap::iterator it = pending_paints_.find(render_widget_id);
if (it != pending_paints_.end()) {
proxy = it->second;
@@ -134,25 +134,25 @@ bool RenderWidgetHelper::WaitForPaintMsg(int render_widget_id,
return false;
}
-void RenderWidgetHelper::DidReceivePaintMsg(const IPC::Message& msg) {
+void RenderWidgetHelper::DidReceiveUpdateMsg(const IPC::Message& msg) {
int render_widget_id = msg.routing_id();
- PaintMsgProxy* proxy = NULL;
+ UpdateMsgProxy* proxy = NULL;
{
AutoLock lock(pending_paints_lock_);
- PaintMsgProxyMap::value_type new_value(render_widget_id, NULL);
+ UpdateMsgProxyMap::value_type new_value(render_widget_id, NULL);
// We expect only a single PaintRect message at a time. Optimize for the
// case that we don't already have an entry by using the 'insert' method.
- std::pair<PaintMsgProxyMap::iterator, bool> result =
+ std::pair<UpdateMsgProxyMap::iterator, bool> result =
pending_paints_.insert(new_value);
if (!result.second) {
NOTREACHED() << "Unexpected PaintRect message!";
return;
}
- result.first->second = (proxy = new PaintMsgProxy(this, msg));
+ result.first->second = (proxy = new UpdateMsgProxy(this, msg));
}
// Notify anyone waiting on the UI thread that there is a new entry in the
@@ -164,14 +164,14 @@ void RenderWidgetHelper::DidReceivePaintMsg(const IPC::Message& msg) {
ChromeThread::PostTask(ChromeThread::UI, FROM_HERE, proxy);
}
-void RenderWidgetHelper::OnDiscardPaintMsg(PaintMsgProxy* proxy) {
+void RenderWidgetHelper::OnDiscardUpdateMsg(UpdateMsgProxy* proxy) {
const IPC::Message& msg = proxy->message;
// Remove the proxy from the map now that we are going to handle it normally.
{
AutoLock lock(pending_paints_lock_);
- PaintMsgProxyMap::iterator it = pending_paints_.find(msg.routing_id());
+ UpdateMsgProxyMap::iterator it = pending_paints_.find(msg.routing_id());
DCHECK(it != pending_paints_.end());
DCHECK(it->second == proxy);
@@ -179,8 +179,8 @@ void RenderWidgetHelper::OnDiscardPaintMsg(PaintMsgProxy* proxy) {
}
}
-void RenderWidgetHelper::OnDispatchPaintMsg(PaintMsgProxy* proxy) {
- OnDiscardPaintMsg(proxy);
+void RenderWidgetHelper::OnDispatchUpdateMsg(UpdateMsgProxy* proxy) {
+ OnDiscardUpdateMsg(proxy);
// It is reasonable for the host to no longer exist.
RenderProcessHost* host = RenderProcessHost::FromID(render_process_id_);
diff --git a/chrome/browser/renderer_host/render_widget_helper.h b/chrome/browser/renderer_host/render_widget_helper.h
index 1220970..d7e863e 100644
--- a/chrome/browser/renderer_host/render_widget_helper.h
+++ b/chrome/browser/renderer_host/render_widget_helper.h
@@ -37,20 +37,20 @@ struct ViewMsg_ClosePage_Params;
// RenderWidgetHelper is used to implement optimized resize. When the
// RenderWidgetHost is resized, it sends a Resize message to its RenderWidget
// counterpart in the renderer process. The RenderWidget generates a
-// PaintRect message in response to the Resize message, and it sets the
-// IS_RESIZE_ACK flag in the PaintRect message to true.
+// UpdateRect message in response to the Resize message, and it sets the
+// IS_RESIZE_ACK flag in the UpdateRect message to true.
//
// Back in the browser process, when the RenderProcessHost's MessageFilter
-// sees a PaintRect message, it directs it to the RenderWidgetHelper by
-// calling the DidReceivePaintMsg method. That method stores the data for
-// the PaintRect message in a map, where it can be directly accessed by the
+// sees a UpdateRect message, it directs it to the RenderWidgetHelper by
+// calling the DidReceiveUpdateMsg method. That method stores the data for
+// the UpdateRect message in a map, where it can be directly accessed by the
// RenderWidgetHost on the UI thread during a call to RenderWidgetHost's
// GetBackingStore method.
//
// When the RenderWidgetHost's GetBackingStore method is called, it first
// checks to see if it is waiting for a resize ack. If it is, then it calls
-// the RenderWidgetHelper's WaitForPaintMsg to check if there is already a
-// resulting PaintRect message (or to wait a short amount of time for one to
+// the RenderWidgetHelper's WaitForUpdateMsg to check if there is already a
+// resulting UpdateRect message (or to wait a short amount of time for one to
// arrive). The main goal of this mechanism is to short-cut the usual way in
// which IPC messages are proxied over to the UI thread via InvokeLater.
// This approach is necessary since window resize is followed up immediately
@@ -60,19 +60,19 @@ struct ViewMsg_ClosePage_Params;
// OPTIMIZED TAB SWITCHING
//
// When a RenderWidgetHost is in a background tab, it is flagged as hidden.
-// This causes the corresponding RenderWidget to stop sending PaintRect
+// This causes the corresponding RenderWidget to stop sending UpdateRect
// messages. The RenderWidgetHost also discards its backingstore when it is
// hidden, which helps free up memory. As a result, when a RenderWidgetHost
// is restored, it can be momentarily without a backingstore. (Restoring a
// RenderWidgetHost results in a WasRestored message being sent to the
-// RenderWidget, which triggers a full PaintRect message.) This can lead to
+// RenderWidget, which triggers a full UpdateRect message.) This can lead to
// an observed rendering glitch as the TabContents will just have to fill
// white overtop the RenderWidgetHost until the RenderWidgetHost receives a
-// PaintRect message to refresh its backingstore.
+// UpdateRect message to refresh its backingstore.
//
// To avoid this 'white flash', the RenderWidgetHost again makes use of the
-// RenderWidgetHelper's WaitForPaintMsg method. When the RenderWidgetHost's
-// GetBackingStore method is called, it will call WaitForPaintMsg if it has
+// RenderWidgetHelper's WaitForUpdateMsg method. When the RenderWidgetHost's
+// GetBackingStore method is called, it will call WaitForUpdateMsg if it has
// no backingstore.
//
// TRANSPORT DIB CREATION
@@ -103,9 +103,9 @@ class RenderWidgetHelper
// for documentation.
void CancelResourceRequests(int render_widget_id);
void CrossSiteClosePageACK(const ViewMsg_ClosePage_Params& params);
- bool WaitForPaintMsg(int render_widget_id,
- const base::TimeDelta& max_delay,
- IPC::Message* msg);
+ bool WaitForUpdateMsg(int render_widget_id,
+ const base::TimeDelta& max_delay,
+ IPC::Message* msg);
#if defined(OS_MACOSX)
// Given the id of a transport DIB, return a mapping to it or NULL on error.
@@ -115,8 +115,8 @@ class RenderWidgetHelper
// IO THREAD ONLY -----------------------------------------------------------
- // Called on the IO thread when a PaintRect message is received.
- void DidReceivePaintMsg(const IPC::Message& msg);
+ // Called on the IO thread when a UpdateRect message is received.
+ void DidReceiveUpdateMsg(const IPC::Message& msg);
void CreateNewWindow(int opener_id,
bool user_gesture,
@@ -135,20 +135,20 @@ class RenderWidgetHelper
private:
// A class used to proxy a paint message. PaintMsgProxy objects are created
// on the IO thread and destroyed on the UI thread.
- class PaintMsgProxy;
- friend class PaintMsgProxy;
+ class UpdateMsgProxy;
+ friend class UpdateMsgProxy;
friend class base::RefCountedThreadSafe<RenderWidgetHelper>;
// Map from render_widget_id to live PaintMsgProxy instance.
- typedef base::hash_map<int, PaintMsgProxy*> PaintMsgProxyMap;
+ typedef base::hash_map<int, UpdateMsgProxy*> UpdateMsgProxyMap;
~RenderWidgetHelper();
// Called on the UI thread to discard a paint message.
- void OnDiscardPaintMsg(PaintMsgProxy* proxy);
+ void OnDiscardUpdateMsg(UpdateMsgProxy* proxy);
// Called on the UI thread to dispatch a paint message if necessary.
- void OnDispatchPaintMsg(PaintMsgProxy* proxy);
+ void OnDispatchUpdateMsg(UpdateMsgProxy* proxy);
// Called on the UI thread to finish creating a window.
void OnCreateWindowOnUI(int opener_id,
@@ -179,12 +179,12 @@ class RenderWidgetHelper
// A map of live paint messages. Must hold pending_paints_lock_ to access.
// The PaintMsgProxy objects are not owned by this map. (See PaintMsgProxy
// for details about how the lifetime of instances are managed.)
- PaintMsgProxyMap pending_paints_;
+ UpdateMsgProxyMap pending_paints_;
Lock pending_paints_lock_;
int render_process_id_;
- // Event used to implement WaitForPaintMsg.
+ // Event used to implement WaitForUpdateMsg.
base::WaitableEvent event_;
// The next routing id to use.
diff --git a/chrome/browser/renderer_host/render_widget_host.cc b/chrome/browser/renderer_host/render_widget_host.cc
index c40bbf8..ad94aa6 100644
--- a/chrome/browser/renderer_host/render_widget_host.cc
+++ b/chrome/browser/renderer_host/render_widget_host.cc
@@ -124,8 +124,7 @@ void RenderWidgetHost::OnMessageReceived(const IPC::Message &msg) {
IPC_MESSAGE_HANDLER(ViewHostMsg_RenderViewGone, OnMsgRenderViewGone)
IPC_MESSAGE_HANDLER(ViewHostMsg_Close, OnMsgClose)
IPC_MESSAGE_HANDLER(ViewHostMsg_RequestMove, OnMsgRequestMove)
- IPC_MESSAGE_HANDLER(ViewHostMsg_PaintRect, OnMsgPaintRect)
- IPC_MESSAGE_HANDLER(ViewHostMsg_ScrollRect, OnMsgScrollRect)
+ IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateRect, OnMsgUpdateRect)
IPC_MESSAGE_HANDLER(ViewHostMsg_HandleInputEvent_ACK, OnMsgInputEventAck)
IPC_MESSAGE_HANDLER(ViewHostMsg_Focus, OnMsgFocus)
IPC_MESSAGE_HANDLER(ViewHostMsg_Blur, OnMsgBlur)
@@ -299,9 +298,9 @@ BackingStore* RenderWidgetHost::GetBackingStore(bool force_create) {
if (resize_ack_pending_ || !backing_store) {
IPC::Message msg;
TimeDelta max_delay = TimeDelta::FromMilliseconds(kPaintMsgTimeoutMS);
- if (process_->WaitForPaintMsg(routing_id_, max_delay, &msg)) {
- ViewHostMsg_PaintRect::Dispatch(
- &msg, this, &RenderWidgetHost::OnMsgPaintRect);
+ if (process_->WaitForUpdateMsg(routing_id_, max_delay, &msg)) {
+ ViewHostMsg_UpdateRect::Dispatch(
+ &msg, this, &RenderWidgetHost::OnMsgUpdateRect);
backing_store = BackingStoreManager::GetBackingStore(this, current_size_);
}
}
@@ -618,15 +617,15 @@ void RenderWidgetHost::OnMsgRequestMove(const gfx::Rect& pos) {
}
}
-void RenderWidgetHost::OnMsgPaintRect(
- const ViewHostMsg_PaintRect_Params& params) {
+void RenderWidgetHost::OnMsgUpdateRect(
+ const ViewHostMsg_UpdateRect_Params& params) {
TimeTicks paint_start = TimeTicks::Now();
// Update our knowledge of the RenderWidget's size.
current_size_ = params.view_size;
bool is_resize_ack =
- ViewHostMsg_PaintRect_Flags::is_resize_ack(params.flags);
+ ViewHostMsg_UpdateRect_Flags::is_resize_ack(params.flags);
// resize_ack_pending_ needs to be cleared before we call DidPaintRect, since
// that will end up reaching GetBackingStore.
@@ -637,7 +636,7 @@ void RenderWidgetHost::OnMsgPaintRect(
}
bool is_repaint_ack =
- ViewHostMsg_PaintRect_Flags::is_repaint_ack(params.flags);
+ ViewHostMsg_UpdateRect_Flags::is_repaint_ack(params.flags);
if (is_repaint_ack) {
repaint_ack_pending_ = false;
TimeDelta delta = TimeTicks::Now() - repaint_start_time_;
@@ -653,12 +652,19 @@ void RenderWidgetHost::OnMsgPaintRect(
if (dib) {
if (dib->size() < size) {
DLOG(WARNING) << "Transport DIB too small for given rectangle";
- process()->ReceivedBadMessage(ViewHostMsg_PaintRect__ID);
+ process()->ReceivedBadMessage(ViewHostMsg_UpdateRect__ID);
} else {
+ // Scroll the backing store.
+ if (!params.scroll_rect.IsEmpty()) {
+ ScrollBackingStoreRect(params.dx, params.dy,
+ params.scroll_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(dib, params.bitmap_rect, params.update_rects,
+ PaintBackingStoreRect(dib, params.bitmap_rect, params.copy_rects,
params.view_size);
}
}
@@ -667,7 +673,7 @@ void RenderWidgetHost::OnMsgPaintRect(
// 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_));
+ Send(new ViewMsg_UpdateRect_ACK(routing_id_));
// 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
@@ -679,7 +685,12 @@ void RenderWidgetHost::OnMsgPaintRect(
if (view_) {
view_->MovePluginWindows(params.plugin_window_moves);
view_being_painted_ = true;
- view_->DidPaintRect(params.bitmap_rect);
+ if (!params.scroll_rect.IsEmpty()) {
+ view_->DidScrollBackingStoreRect(params.scroll_rect,
+ params.dx,
+ params.dy);
+ }
+ view_->DidPaintBackingStoreRects(params.copy_rects);
view_being_painted_ = false;
}
@@ -700,56 +711,7 @@ void RenderWidgetHost::OnMsgPaintRect(
// Log the time delta for processing a paint message.
TimeDelta delta = TimeTicks::Now() - paint_start;
- UMA_HISTOGRAM_TIMES("MPArch.RWH_OnMsgPaintRect", delta);
-}
-
-void RenderWidgetHost::OnMsgScrollRect(
- const ViewHostMsg_ScrollRect_Params& params) {
- TimeTicks scroll_start = TimeTicks::Now();
-
- DCHECK(!params.view_size.IsEmpty());
-
- const size_t size = params.bitmap_rect.height() *
- params.bitmap_rect.width() * 4;
- TransportDIB* dib = process_->GetTransportDIB(params.bitmap);
- if (dib) {
- if (dib->size() < size) {
- LOG(WARNING) << "Transport DIB too small for given rectangle";
- process()->ReceivedBadMessage(ViewHostMsg_PaintRect__ID);
- } else {
- // Scroll the backing store.
- ScrollBackingStoreRect(dib, 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_));
-
- // 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;
-
- // 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;
- }
-
- if (painting_observer_)
- painting_observer_->WidgetDidUpdateBackingStore(this);
-
- // Log the time delta for processing a scroll message.
- TimeDelta delta = TimeTicks::Now() - scroll_start;
- UMA_HISTOGRAM_TIMES("MPArch.RWH_OnMsgScrollRect", delta);
+ UMA_HISTOGRAM_TIMES("MPArch.RWH_OnMsgUpdateRect", delta);
}
void RenderWidgetHost::OnMsgInputEventAck(const IPC::Message& message) {
@@ -891,9 +853,7 @@ void RenderWidgetHost::PaintBackingStoreRect(
}
}
-void RenderWidgetHost::ScrollBackingStoreRect(TransportDIB* bitmap,
- const gfx::Rect& bitmap_rect,
- int dx, int dy,
+void RenderWidgetHost::ScrollBackingStoreRect(int dx, int dy,
const gfx::Rect& clip_rect,
const gfx::Size& view_size) {
if (is_hidden_) {
@@ -910,8 +870,7 @@ void RenderWidgetHost::ScrollBackingStoreRect(TransportDIB* bitmap,
BackingStore* backing_store = BackingStoreManager::Lookup(this);
if (!backing_store || (backing_store->size() != view_size))
return;
- backing_store->ScrollRect(process_->GetHandle(), bitmap, bitmap_rect,
- dx, dy, clip_rect, view_size);
+ backing_store->ScrollRect(dx, dy, clip_rect, view_size);
}
void RenderWidgetHost::ToggleSpellPanel(bool is_currently_visible) {
diff --git a/chrome/browser/renderer_host/render_widget_host.h b/chrome/browser/renderer_host/render_widget_host.h
index dc425b0..d59fc4e 100644
--- a/chrome/browser/renderer_host/render_widget_host.h
+++ b/chrome/browser/renderer_host/render_widget_host.h
@@ -38,9 +38,8 @@ class RenderWidgetHostView;
class RenderWidgetHostPaintingObserver;
class TransportDIB;
class WebCursor;
-struct ViewHostMsg_PaintRect_Params;
-struct ViewHostMsg_ScrollRect_Params;
struct ViewHostMsg_ShowPopup_Params;
+struct ViewHostMsg_UpdateRect_Params;
// This class manages the browser side of a browser<->renderer HWND connection.
// The HWND lives in the browser process, and windows events are sent over
@@ -413,8 +412,7 @@ class RenderWidgetHost : public IPC::Channel::Listener,
void OnMsgRenderViewGone();
void OnMsgClose();
void OnMsgRequestMove(const gfx::Rect& pos);
- void OnMsgPaintRect(const ViewHostMsg_PaintRect_Params& params);
- void OnMsgScrollRect(const ViewHostMsg_ScrollRect_Params& params);
+ void OnMsgUpdateRect(const ViewHostMsg_UpdateRect_Params& params);
void OnMsgInputEventAck(const IPC::Message& message);
void OnMsgFocus();
void OnMsgBlur();
@@ -444,10 +442,7 @@ class RenderWidgetHost : public IPC::Channel::Listener,
// Scrolls the given |clip_rect| in the backing by the given dx/dy amount. The
// |dib| and its corresponding location |bitmap_rect| in the backing store
// is the newly painted pixels by the renderer.
- void ScrollBackingStoreRect(TransportDIB* dib,
- const gfx::Rect& bitmap_rect,
- int dx, int dy,
- const gfx::Rect& clip_rect,
+ void ScrollBackingStoreRect(int dx, int dy, const gfx::Rect& clip_rect,
const gfx::Size& view_size);
// 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 e3f4517..ba191fc 100644
--- a/chrome/browser/renderer_host/render_widget_host_unittest.cc
+++ b/chrome/browser/renderer_host/render_widget_host_unittest.cc
@@ -21,9 +21,9 @@ class RenderWidgetHostProcess : public MockRenderProcessHost {
public:
explicit RenderWidgetHostProcess(Profile* profile)
: MockRenderProcessHost(profile),
- current_paint_buf_(NULL),
- paint_msg_should_reply_(false),
- paint_msg_reply_flags_(0) {
+ current_update_buf_(NULL),
+ update_msg_should_reply_(false),
+ update_msg_reply_flags_(0) {
// DANGER! This is a hack. The RenderWidgetHost checks the channel to see
// if the process is still alive, but it doesn't actually dereference it.
// An IPC::SyncChannel is nontrivial, so we just fake it here. If you end up
@@ -34,64 +34,65 @@ class RenderWidgetHostProcess : public MockRenderProcessHost {
// We don't want to actually delete the channel, since it's not a real
// pointer.
channel_.release();
- if (current_paint_buf_)
- delete current_paint_buf_;
+ delete current_update_buf_;
}
- void set_paint_msg_should_reply(bool reply) {
- paint_msg_should_reply_ = reply;
+ void set_update_msg_should_reply(bool reply) {
+ update_msg_should_reply_ = reply;
}
- void set_paint_msg_reply_flags(int flags) {
- paint_msg_reply_flags_ = flags;
+ void set_update_msg_reply_flags(int flags) {
+ update_msg_reply_flags_ = flags;
}
// Fills the given paint parameters with resonable default values.
- void InitPaintRectParams(ViewHostMsg_PaintRect_Params* params);
+ void InitUpdateRectParams(ViewHostMsg_UpdateRect_Params* params);
protected:
- virtual bool WaitForPaintMsg(int render_widget_id,
- const base::TimeDelta& max_delay,
- IPC::Message* msg);
+ virtual bool WaitForUpdateMsg(int render_widget_id,
+ const base::TimeDelta& max_delay,
+ IPC::Message* msg);
- TransportDIB* current_paint_buf_;
+ TransportDIB* current_update_buf_;
// Set to true when WaitForPaintMsg should return a successful paint messaage
// reply. False implies timeout.
- bool paint_msg_should_reply_;
+ bool update_msg_should_reply_;
// Indicates the flags that should be sent with a the repaint request. This
// only has an effect when paint_msg_should_reply_ is true.
- int paint_msg_reply_flags_;
+ int update_msg_reply_flags_;
DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostProcess);
};
-void RenderWidgetHostProcess::InitPaintRectParams(
- ViewHostMsg_PaintRect_Params* params) {
+void RenderWidgetHostProcess::InitUpdateRectParams(
+ ViewHostMsg_UpdateRect_Params* params) {
// Create the shared backing store.
const int w = 100, h = 100;
const size_t pixel_size = w * h * 4;
- if (!current_paint_buf_)
- current_paint_buf_ = TransportDIB::Create(pixel_size, 0);
- params->bitmap = current_paint_buf_->id();
+ if (!current_update_buf_)
+ current_update_buf_ = TransportDIB::Create(pixel_size, 0);
+ params->bitmap = current_update_buf_->id();
params->bitmap_rect = gfx::Rect(0, 0, w, h);
- params->update_rects.push_back(params->bitmap_rect);
+ params->dx = 0;
+ params->dy = 0;
+ params->copy_rects.push_back(params->bitmap_rect);
params->view_size = gfx::Size(w, h);
- params->flags = paint_msg_reply_flags_;
+ params->flags = update_msg_reply_flags_;
}
-bool RenderWidgetHostProcess::WaitForPaintMsg(int render_widget_id,
- const base::TimeDelta& max_delay,
- IPC::Message* msg) {
- if (!paint_msg_should_reply_)
+bool RenderWidgetHostProcess::WaitForUpdateMsg(int render_widget_id,
+ const base::TimeDelta& max_delay,
+ IPC::Message* msg) {
+ if (!update_msg_should_reply_)
return false;
// Construct a fake paint reply.
- ViewHostMsg_PaintRect_Params params;
- InitPaintRectParams(&params);
+ ViewHostMsg_UpdateRect_Params params;
+ InitUpdateRectParams(&params);
- ViewHostMsg_PaintRect message(render_widget_id, params);
+ ViewHostMsg_UpdateRect message(render_widget_id, params);
*msg = message;
return true;
}
@@ -251,9 +252,9 @@ TEST_F(RenderWidgetHostTest, Resize) {
// Send out a paint that's not a resize ack. This should not clean the
// resize ack pending flag.
- ViewHostMsg_PaintRect_Params params;
- process_->InitPaintRectParams(&params);
- host_->OnMsgPaintRect(params);
+ ViewHostMsg_UpdateRect_Params params;
+ process_->InitUpdateRectParams(&params);
+ host_->OnMsgUpdateRect(params);
EXPECT_TRUE(host_->resize_ack_pending_);
EXPECT_EQ(original_size.size(), host_->in_flight_size_);
@@ -271,9 +272,9 @@ TEST_F(RenderWidgetHostTest, Resize) {
// this isn't the second_size, the message handler should immediately send
// a new resize message for the new size to the renderer.
process_->sink().ClearMessages();
- params.flags = ViewHostMsg_PaintRect_Flags::IS_RESIZE_ACK;
+ params.flags = ViewHostMsg_UpdateRect_Flags::IS_RESIZE_ACK;
params.view_size = original_size.size();
- host_->OnMsgPaintRect(params);
+ host_->OnMsgUpdateRect(params);
EXPECT_TRUE(host_->resize_ack_pending_);
EXPECT_EQ(second_size.size(), host_->in_flight_size_);
ASSERT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
@@ -281,7 +282,7 @@ TEST_F(RenderWidgetHostTest, Resize) {
// Send the resize ack for the latest size.
process_->sink().ClearMessages();
params.view_size = second_size.size();
- host_->OnMsgPaintRect(params);
+ host_->OnMsgUpdateRect(params);
EXPECT_FALSE(host_->resize_ack_pending_);
EXPECT_EQ(gfx::Size(), host_->in_flight_size_);
ASSERT_FALSE(process_->sink().GetFirstMessageMatching(ViewMsg_Resize::ID));
@@ -398,42 +399,42 @@ TEST_F(RenderWidgetHostTest, Background) {
TEST_F(RenderWidgetHostTest, GetBackingStore_NoRepaintAck) {
// We don't currently have a backing store, and if the renderer doesn't send
// one in time, we should get nothing.
- process_->set_paint_msg_should_reply(false);
+ process_->set_update_msg_should_reply(false);
BackingStore* backing = host_->GetBackingStore(true);
EXPECT_FALSE(backing);
// The widget host should have sent a request for a repaint, and there should
// be no paint ACK.
EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Repaint::ID));
EXPECT_FALSE(process_->sink().GetUniqueMessageMatching(
- ViewMsg_PaintRect_ACK::ID));
+ ViewMsg_UpdateRect_ACK::ID));
// Allowing the renderer to reply in time should give is a backing store.
process_->sink().ClearMessages();
- process_->set_paint_msg_should_reply(true);
- process_->set_paint_msg_reply_flags(0);
+ process_->set_update_msg_should_reply(true);
+ process_->set_update_msg_reply_flags(0);
backing = host_->GetBackingStore(true);
EXPECT_TRUE(backing);
// The widget host should NOT have sent a request for a repaint, since there
// was an ACK already pending.
EXPECT_FALSE(process_->sink().GetUniqueMessageMatching(ViewMsg_Repaint::ID));
EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
- ViewMsg_PaintRect_ACK::ID));
+ ViewMsg_UpdateRect_ACK::ID));
}
// Tests getting the backing store with the renderer sending a repaint ack.
TEST_F(RenderWidgetHostTest, GetBackingStore_RepaintAck) {
// Doing a request request with the paint message allowed should work and
// the repaint ack should work.
- process_->set_paint_msg_should_reply(true);
- process_->set_paint_msg_reply_flags(
- ViewHostMsg_PaintRect_Flags::IS_REPAINT_ACK);
+ process_->set_update_msg_should_reply(true);
+ process_->set_update_msg_reply_flags(
+ ViewHostMsg_UpdateRect_Flags::IS_REPAINT_ACK);
BackingStore* backing = host_->GetBackingStore(true);
EXPECT_TRUE(backing);
// We still should not have sent out a repaint request since the last flags
// didn't have the repaint ack set, and the pending flag will still be set.
EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Repaint::ID));
EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
- ViewMsg_PaintRect_ACK::ID));
+ ViewMsg_UpdateRect_ACK::ID));
// Asking again for the backing store should just re-use the existing one
// and not send any messagse.
@@ -442,7 +443,7 @@ TEST_F(RenderWidgetHostTest, GetBackingStore_RepaintAck) {
EXPECT_TRUE(backing);
EXPECT_FALSE(process_->sink().GetUniqueMessageMatching(ViewMsg_Repaint::ID));
EXPECT_FALSE(process_->sink().GetUniqueMessageMatching(
- ViewMsg_PaintRect_ACK::ID));
+ ViewMsg_UpdateRect_ACK::ID));
}
// Test that we don't paint when we're hidden, but we still send the ACK. Most
@@ -456,13 +457,13 @@ TEST_F(RenderWidgetHostTest, HiddenPaint) {
// Send it a paint as from the renderer.
process_->sink().ClearMessages();
- ViewHostMsg_PaintRect_Params params;
- process_->InitPaintRectParams(&params);
- host_->OnMsgPaintRect(params);
+ ViewHostMsg_UpdateRect_Params params;
+ process_->InitUpdateRectParams(&params);
+ host_->OnMsgUpdateRect(params);
// It should have sent out the ACK.
EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
- ViewMsg_PaintRect_ACK::ID));
+ ViewMsg_UpdateRect_ACK::ID));
// Now unhide.
process_->sink().ClearMessages();
diff --git a/chrome/browser/renderer_host/render_widget_host_view.h b/chrome/browser/renderer_host/render_widget_host_view.h
index 3a71011..2a87291 100644
--- a/chrome/browser/renderer_host/render_widget_host_view.h
+++ b/chrome/browser/renderer_host/render_widget_host_view.h
@@ -110,13 +110,14 @@ class RenderWidgetHostView {
// (Worse, we might recursively call RenderWidgetHost::GetBackingStore().)
// Thus implementers should generally paint as much of |rect| as possible
// synchronously with as little overpainting as possible.
- virtual void DidPaintRect(const gfx::Rect& rect) = 0;
+ virtual void DidPaintBackingStoreRects(
+ const std::vector<gfx::Rect>& rects) = 0;
// Informs the view that a portion of the widget's backing store was scrolled
// 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(
+ virtual void DidScrollBackingStoreRect(
const gfx::Rect& rect, int dx, int dy) = 0;
// Notifies the View that the renderer has ceased to exist.
diff --git a/chrome/browser/renderer_host/render_widget_host_view_gtk.cc b/chrome/browser/renderer_host/render_widget_host_view_gtk.cc
index cd38ec8..8ce8747 100644
--- a/chrome/browser/renderer_host/render_widget_host_view_gtk.cc
+++ b/chrome/browser/renderer_host/render_widget_host_view_gtk.cc
@@ -505,21 +505,27 @@ void RenderWidgetHostViewGtk::IMEUpdateStatus(int control,
key_bindings_handler_->set_enabled(control != IME_DISABLE);
}
-void RenderWidgetHostViewGtk::DidPaintRect(const gfx::Rect& rect) {
+void RenderWidgetHostViewGtk::DidPaintBackingStoreRects(
+ const std::vector<gfx::Rect>& rects) {
if (is_hidden_)
return;
- if (about_to_validate_and_paint_)
- invalid_rect_ = invalid_rect_.Union(rect);
- else
- Paint(rect);
+ for (size_t i = 0; i < rects.size(); ++i) {
+ if (about_to_validate_and_paint_) {
+ invalid_rect_ = invalid_rect_.Union(rects[i]);
+ } else {
+ Paint(rects[i]);
+ }
+ }
}
-void RenderWidgetHostViewGtk::DidScrollRect(const gfx::Rect& rect, int dx,
- int dy) {
+void RenderWidgetHostViewGtk::DidScrollBackingStoreRect(const gfx::Rect& rect,
+ int dx, int dy) {
if (is_hidden_)
return;
+ // TODO(darin): Implement the equivalent of Win32's ScrollWindowEX. Can that
+ // be done using XCopyArea? Perhaps similar to BackingStore::ScrollRect?
Paint(rect);
}
diff --git a/chrome/browser/renderer_host/render_widget_host_view_gtk.h b/chrome/browser/renderer_host/render_widget_host_view_gtk.h
index 94f4f1a..5c05094 100644
--- a/chrome/browser/renderer_host/render_widget_host_view_gtk.h
+++ b/chrome/browser/renderer_host/render_widget_host_view_gtk.h
@@ -60,8 +60,8 @@ class RenderWidgetHostViewGtk : public RenderWidgetHostView {
virtual void UpdateCursor(const WebCursor& cursor);
virtual void SetIsLoading(bool is_loading);
virtual void IMEUpdateStatus(int control, const gfx::Rect& caret_rect);
- virtual void DidPaintRect(const gfx::Rect& rect);
- virtual void DidScrollRect(const gfx::Rect& rect, int dx, int dy);
+ virtual void DidPaintBackingStoreRects(const std::vector<gfx::Rect>& rects);
+ virtual void DidScrollBackingStoreRect(const gfx::Rect& rect, int dx, int dy);
virtual void RenderViewGone();
virtual void Destroy();
virtual void WillDestroyRenderWidget(RenderWidgetHost* rwh) {}
diff --git a/chrome/browser/renderer_host/render_widget_host_view_mac.h b/chrome/browser/renderer_host/render_widget_host_view_mac.h
index c661578..3dc07b2 100644
--- a/chrome/browser/renderer_host/render_widget_host_view_mac.h
+++ b/chrome/browser/renderer_host/render_widget_host_view_mac.h
@@ -95,8 +95,8 @@ class RenderWidgetHostViewMac : public RenderWidgetHostView {
virtual void UpdateCursor(const WebCursor& cursor);
virtual void SetIsLoading(bool is_loading);
virtual void IMEUpdateStatus(int control, const gfx::Rect& caret_rect);
- virtual void DidPaintRect(const gfx::Rect& rect);
- virtual void DidScrollRect(const gfx::Rect& rect, int dx, int dy);
+ virtual void DidPaintBackingStoreRects(const std::vector<gfx::Rect>& rects);
+ virtual void DidScrollBackingStoreRect(const gfx::Rect& rect, int dx, int dy);
virtual void RenderViewGone();
virtual void WillDestroyRenderWidget(RenderWidgetHost* rwh) {};
virtual void Destroy();
diff --git a/chrome/browser/renderer_host/render_widget_host_view_mac.mm b/chrome/browser/renderer_host/render_widget_host_view_mac.mm
index 78d2736..55cfaef 100644
--- a/chrome/browser/renderer_host/render_widget_host_view_mac.mm
+++ b/chrome/browser/renderer_host/render_widget_host_view_mac.mm
@@ -275,26 +275,31 @@ void RenderWidgetHostViewMac::IMEUpdateStatus(int control,
caret_rect.width(), caret_rect.height());
}
-void RenderWidgetHostViewMac::DidPaintRect(const gfx::Rect& rect) {
+void RenderWidgetHostViewMac::DidPaintBackingStoreRects(
+ const std::vector<gfx::Rect>& rects) {
if (is_hidden_)
return;
- NSRect ns_rect = [cocoa_view_ RectToNSRect:rect];
+ for (size_t i = 0; i < rects.size(); ++i) {
+ NSRect ns_rect = [cocoa_view_ RectToNSRect:rects[i]];
+
+ if (about_to_validate_and_paint_) {
+ // As much as we'd like to use -setNeedsDisplayInRect: here, we can't.
+ // We're in the middle of executing a -drawRect:, and as soon as it
+ // returns Cocoa will clear its record of what needs display. If we want
+ // to handle the recursive drawing, we need to do it ourselves.
+ invalid_rect_ = NSUnionRect(invalid_rect_, ns_rect);
+ } else {
+ [cocoa_view_ setNeedsDisplayInRect:ns_rect];
+ }
+ }
- if (about_to_validate_and_paint_) {
- // As much as we'd like to use -setNeedsDisplayInRect: here, we can't. We're
- // in the middle of executing a -drawRect:, and as soon as it returns Cocoa
- // will clear its record of what needs display. If we want to handle the
- // recursive drawing, we need to do it ourselves.
- invalid_rect_ = NSUnionRect(invalid_rect_, ns_rect);
- } else {
- [cocoa_view_ setNeedsDisplayInRect:ns_rect];
+ if (!about_to_validate_and_paint_)
[cocoa_view_ displayIfNeeded];
- }
}
-void RenderWidgetHostViewMac::DidScrollRect(
- const gfx::Rect& rect, int dx, int dy) {
+void RenderWidgetHostViewMac::DidScrollBackingStoreRect(const gfx::Rect& rect,
+ int dx, int dy) {
if (is_hidden_)
return;
@@ -305,7 +310,7 @@ void RenderWidgetHostViewMac::DidScrollRect(
// TODO(rohitrao): Evaluate how slow this full redraw is. If it
// turns out to be a problem, consider scrolling only a portion of
// the view, based on where the findbar and blocked popups are.
- DidPaintRect(rect);
+ DidPaintBackingStoreRects(std::vector<gfx::Rect>(1, rect));
}
void RenderWidgetHostViewMac::RenderViewGone() {
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 e0b3832..8be4df5 100644
--- a/chrome/browser/renderer_host/render_widget_host_view_win.cc
+++ b/chrome/browser/renderer_host/render_widget_host_view_win.cc
@@ -568,7 +568,13 @@ BOOL CALLBACK EnumChildProc(HWND hwnd, LPARAM lparam) {
return TRUE;
}
-void RenderWidgetHostViewWin::Redraw(const gfx::Rect& rect) {
+void RenderWidgetHostViewWin::Redraw() {
+ RECT damage_bounds;
+ GetUpdateRect(&damage_bounds, FALSE);
+
+ ScopedGDIObject<HRGN> damage_region(CreateRectRgn(0, 0, 0, 0));
+ GetUpdateRgn(damage_region, FALSE);
+
// Paint the invalid region synchronously. Our caller will not paint again
// until we return, so by painting to the screen here, we ensure effective
// rate-limiting of backing store updates. This helps a lot on pages that
@@ -579,12 +585,11 @@ void RenderWidgetHostViewWin::Redraw(const gfx::Rect& rect) {
// message dispatching we allow scrolling to be smooth, and also avoid the
// browser process locking up if the plugin process is hung.
//
- RedrawWindow(
- &rect.ToRECT(), NULL, RDW_INVALIDATE | RDW_UPDATENOW | RDW_NOCHILDREN);
+ RedrawWindow(NULL, damage_region, RDW_UPDATENOW | RDW_NOCHILDREN);
// Send the invalid rect in screen coordinates.
gfx::Rect screen_rect = GetViewBounds();
- gfx::Rect invalid_screen_rect = rect;
+ gfx::Rect invalid_screen_rect(damage_bounds);
invalid_screen_rect.Offset(screen_rect.x(), screen_rect.y());
LPARAM lparam = reinterpret_cast<LPARAM>(&invalid_screen_rect);
@@ -619,31 +624,29 @@ void RenderWidgetHostViewWin::DrawResizeCorner(const gfx::Rect& paint_rect,
}
}
-void RenderWidgetHostViewWin::DidPaintRect(const gfx::Rect& rect) {
+void RenderWidgetHostViewWin::DidPaintBackingStoreRects(
+ const std::vector<gfx::Rect>& rects) {
if (is_hidden_)
return;
- if (about_to_validate_and_paint_)
- InvalidateRect(&rect.ToRECT(), false);
- else
- Redraw(rect);
+ for (size_t i = 0; i < rects.size(); ++i)
+ InvalidateRect(&rects[i].ToRECT(), false);
+
+ if (!about_to_validate_and_paint_)
+ Redraw();
}
-void RenderWidgetHostViewWin::DidScrollRect(
+void RenderWidgetHostViewWin::DidScrollBackingStoreRect(
const gfx::Rect& rect, int dx, int dy) {
if (is_hidden_)
return;
- // We need to pass in SW_INVALIDATE to ScrollWindowEx. The MSDN
- // documentation states that it only applies to the HRGN argument, which is
- // wrong. Not passing in this flag does not invalidate the region which was
- // scrolled from, thus causing painting issues.
+ // We need to pass in SW_INVALIDATE to ScrollWindowEx. The documentation on
+ // MSDN states that it only applies to the HRGN argument, which is wrong.
+ // Not passing in this flag does not invalidate the region which was scrolled
+ // from, thus causing painting issues.
RECT clip_rect = rect.ToRECT();
ScrollWindowEx(dx, dy, NULL, &clip_rect, NULL, NULL, SW_INVALIDATE);
-
- RECT invalid_rect = {0};
- GetUpdateRect(&invalid_rect);
- Redraw(gfx::Rect(invalid_rect));
}
void RenderWidgetHostViewWin::RenderViewGone() {
@@ -765,6 +768,12 @@ void RenderWidgetHostViewWin::OnPaint(HDC dc) {
// GetBackingStore(), so that if it updates the invalid rect we'll catch the
// changes and repaint them.
about_to_validate_and_paint_ = false;
+
+ // Grab the region to paint before creation of paint_dc since it clears the
+ // damage region.
+ ScopedGDIObject<HRGN> damage_region(CreateRectRgn(0, 0, 0, 0));
+ GetUpdateRgn(damage_region, FALSE);
+
CPaintDC paint_dc(m_hWnd);
gfx::Rect damaged_rect(paint_dc.m_ps.rcPaint);
@@ -772,28 +781,38 @@ void RenderWidgetHostViewWin::OnPaint(HDC dc) {
return;
if (backing_store) {
- gfx::Rect bitmap_rect(
- 0, 0, backing_store->size().width(), backing_store->size().height());
-
- gfx::Rect paint_rect = bitmap_rect.Intersect(damaged_rect);
- if (!paint_rect.IsEmpty()) {
- DrawResizeCorner(paint_rect, backing_store->hdc());
- bool manage_colors = BackingStore::ColorManagementEnabled();
- if (manage_colors)
- SetICMMode(paint_dc.m_hDC, ICM_ON);
- BitBlt(paint_dc.m_hDC,
- paint_rect.x(),
- paint_rect.y(),
- paint_rect.width(),
- paint_rect.height(),
- backing_store->hdc(),
- paint_rect.x(),
- paint_rect.y(),
- SRCCOPY);
- if (manage_colors)
- SetICMMode(paint_dc.m_hDC, ICM_OFF);
+ gfx::Rect bitmap_rect(gfx::Point(), backing_store->size());
+
+ bool manage_colors = BackingStore::ColorManagementEnabled();
+ if (manage_colors)
+ SetICMMode(paint_dc.m_hDC, ICM_ON);
+
+ // Blit only the damaged regions from the backing store.
+ DWORD data_size = GetRegionData(damage_region, 0, NULL);
+ scoped_array<char> region_data_buf(new char[data_size]);
+ RGNDATA* region_data = reinterpret_cast<RGNDATA*>(region_data_buf.get());
+ GetRegionData(damage_region, data_size, region_data);
+
+ RECT* region_rects = reinterpret_cast<RECT*>(region_data->Buffer);
+ for (DWORD i = 0; i < region_data->rdh.nCount; ++i) {
+ gfx::Rect paint_rect = bitmap_rect.Intersect(gfx::Rect(region_rects[i]));
+ if (!paint_rect.IsEmpty()) {
+ DrawResizeCorner(paint_rect, backing_store->hdc());
+ BitBlt(paint_dc.m_hDC,
+ paint_rect.x(),
+ paint_rect.y(),
+ paint_rect.width(),
+ paint_rect.height(),
+ backing_store->hdc(),
+ paint_rect.x(),
+ paint_rect.y(),
+ SRCCOPY);
+ }
}
+ if (manage_colors)
+ SetICMMode(paint_dc.m_hDC, ICM_OFF);
+
// Fill the remaining portion of the damaged_rect with the background
if (damaged_rect.right() > bitmap_rect.right()) {
RECT r;
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 57b220b..3b54064 100644
--- a/chrome/browser/renderer_host/render_widget_host_view_win.h
+++ b/chrome/browser/renderer_host/render_widget_host_view_win.h
@@ -125,8 +125,8 @@ class RenderWidgetHostViewWin
virtual void UpdateCursor(const WebCursor& cursor);
virtual void SetIsLoading(bool is_loading);
virtual void IMEUpdateStatus(int control, const gfx::Rect& caret_rect);
- virtual void DidPaintRect(const gfx::Rect& rect);
- virtual void DidScrollRect(const gfx::Rect& rect, int dx, int dy);
+ virtual void DidPaintBackingStoreRects(const std::vector<gfx::Rect>& rects);
+ virtual void DidScrollBackingStoreRect(const gfx::Rect& rect, int dx, int dy);
virtual void RenderViewGone();
virtual void WillDestroyRenderWidget(RenderWidgetHost* rwh);
virtual void Destroy();
@@ -207,7 +207,7 @@ class RenderWidgetHostViewWin
// Redraws the window synchronously, and any child windows (i.e. plugins)
// asynchronously.
- void Redraw(const gfx::Rect& invalid_rect);
+ void Redraw();
// Draw the resize corner bitmap on top of the given HDC, if it intersects the
// given paint rect.
diff --git a/chrome/browser/renderer_host/resource_message_filter.cc b/chrome/browser/renderer_host/resource_message_filter.cc
index 2bcccb2..c0cc742 100644
--- a/chrome/browser/renderer_host/resource_message_filter.cc
+++ b/chrome/browser/renderer_host/resource_message_filter.cc
@@ -326,8 +326,8 @@ bool ResourceMessageFilter::OnMessageReceived(const IPC::Message& msg) {
IPC_MESSAGE_HANDLER(ViewHostMsg_DnsPrefetch, OnDnsPrefetch)
IPC_MESSAGE_HANDLER(ViewHostMsg_RendererHistograms,
OnRendererHistograms)
- IPC_MESSAGE_HANDLER_GENERIC(ViewHostMsg_PaintRect,
- render_widget_helper_->DidReceivePaintMsg(msg))
+ IPC_MESSAGE_HANDLER_GENERIC(ViewHostMsg_UpdateRect,
+ render_widget_helper_->DidReceiveUpdateMsg(msg))
IPC_MESSAGE_HANDLER(ViewHostMsg_ClipboardWriteObjectsAsync,
OnClipboardWriteObjects)
IPC_MESSAGE_HANDLER(ViewHostMsg_ClipboardWriteObjectsSync,
diff --git a/chrome/browser/renderer_host/test/test_render_view_host.h b/chrome/browser/renderer_host/test/test_render_view_host.h
index b1458a1..9990fab 100644
--- a/chrome/browser/renderer_host/test/test_render_view_host.h
+++ b/chrome/browser/renderer_host/test/test_render_view_host.h
@@ -64,8 +64,10 @@ class TestRenderWidgetHostView : public RenderWidgetHostView {
virtual void UpdateCursor(const WebCursor& cursor) {}
virtual void UpdateCursorIfOverSelf() {}
virtual void IMEUpdateStatus(int control, const gfx::Rect& caret_rect) {}
- virtual void DidPaintRect(const gfx::Rect& rect) {}
- virtual void DidScrollRect(const gfx::Rect& rect, int dx, int dy) {}
+ virtual void DidPaintBackingStoreRects(
+ const std::vector<gfx::Rect>& rects) {}
+ virtual void DidScrollBackingStoreRect(
+ const gfx::Rect& rect, int dx, int dy) {}
virtual void RenderViewGone() { delete this; }
virtual void WillDestroyRenderWidget(RenderWidgetHost* rwh) { }
virtual void Destroy() {}
diff --git a/chrome/common/render_messages.h b/chrome/common/render_messages.h
index 9e2e6fc..c886522 100644
--- a/chrome/common/render_messages.h
+++ b/chrome/common/render_messages.h
@@ -176,8 +176,8 @@ struct ViewHostMsg_FrameNavigate_Params {
};
// Values that may be OR'd together to form the 'flags' parameter of a
-// ViewHostMsg_PaintRect message.
-struct ViewHostMsg_PaintRect_Flags {
+// ViewHostMsg_UpdateRect_Params structure.
+struct ViewHostMsg_UpdateRect_Flags {
enum {
IS_RESIZE_ACK = 1 << 0,
IS_RESTORE_ACK = 1 << 1,
@@ -189,13 +189,12 @@ struct ViewHostMsg_PaintRect_Flags {
static bool is_restore_ack(int flags) {
return (flags & IS_RESTORE_ACK) != 0;
}
-
static bool is_repaint_ack(int flags) {
return (flags & IS_REPAINT_ACK) != 0;
}
};
-struct ViewHostMsg_PaintRect_Params {
+struct ViewHostMsg_UpdateRect_Params {
// The bitmap to be painted into the view at the locations specified by
// update_rects.
TransportDIB::Id bitmap;
@@ -203,8 +202,18 @@ struct ViewHostMsg_PaintRect_Params {
// The position and size of the bitmap.
gfx::Rect bitmap_rect;
+ // The scroll offset. Only one of these can be non-zero, and if they are
+ // both zero, then it means there is no scrolling and the scroll_rect is
+ // ignored.
+ int dx;
+ int dy;
+
+ // The rectangular region to scroll.
+ gfx::Rect scroll_rect;
+
// The regions of the bitmap (in view coords) that contain updated pixels.
- std::vector<gfx::Rect> update_rects;
+ // In the case of scrolling, this includes the scroll damage rect.
+ std::vector<gfx::Rect> copy_rects;
// The size of the RenderView when this message was generated. This is
// included so the host knows how large the view is from the perspective of
@@ -217,42 +226,22 @@ struct ViewHostMsg_PaintRect_Params {
// The following describes the various bits that may be set in flags:
//
- // ViewHostMsg_PaintRect_Flags::IS_RESIZE_ACK
+ // ViewHostMsg_UpdateRect_Flags::IS_RESIZE_ACK
// Indicates that this is a response to a ViewMsg_Resize message.
//
- // ViewHostMsg_PaintRect_Flags::IS_RESTORE_ACK
+ // ViewHostMsg_UpdateRect_Flags::IS_RESTORE_ACK
// Indicates that this is a response to a ViewMsg_WasRestored message.
//
+ // ViewHostMsg_UpdateRect_Flags::IS_REPAINT_ACK
+ // Indicates that this is a response to a ViewMsg_Repaint message.
+ //
// If flags is zero, then this message corresponds to an unsoliticed paint
- // request by the render view. Both of the above bits may be set in flags,
+ // request by the render view. Any of the above bits may be set in flags,
// which would indicate that this paint message is an ACK for multiple
// request messages.
int flags;
};
-// Parameters structure for ViewHostMsg_ScrollRect, which has too many data
-// parameters to be reasonably put in a predefined IPC message.
-struct ViewHostMsg_ScrollRect_Params {
- // The bitmap to be painted into the rect exposed by scrolling.
- TransportDIB::Id bitmap;
-
- // The position and size of the bitmap.
- gfx::Rect bitmap_rect;
-
- // The scroll offset. Only one of these can be non-zero.
- int dx;
- int dy;
-
- // The rectangular region to scroll.
- gfx::Rect clip_rect;
-
- // The size of the RenderView when this message was generated.
- gfx::Size view_size;
-
- // New window locations for plugin child windows.
- std::vector<webkit_glue::WebPluginGeometry> plugin_window_moves;
-};
-
// Information on closing a tab. This is used both for ViewMsg_ClosePage, and
// the corresponding ViewHostMsg_ClosePage_ACK.
struct ViewMsg_ClosePage_Params {
@@ -978,56 +967,20 @@ struct ParamTraits<ContextMenuParams> {
}
};
-// Traits for ViewHostMsg_PaintRect_Params structure to pack/unpack.
+// Traits for ViewHostMsg_UpdateRect_Params structure to pack/unpack.
template <>
-struct ParamTraits<ViewHostMsg_PaintRect_Params> {
- typedef ViewHostMsg_PaintRect_Params param_type;
- static void Write(Message* m, const param_type& p) {
- WriteParam(m, p.bitmap);
- WriteParam(m, p.bitmap_rect);
- WriteParam(m, p.update_rects);
- WriteParam(m, p.view_size);
- WriteParam(m, p.plugin_window_moves);
- WriteParam(m, p.flags);
- }
- static bool Read(const Message* m, void** iter, param_type* p) {
- return
- ReadParam(m, iter, &p->bitmap) &&
- ReadParam(m, iter, &p->bitmap_rect) &&
- ReadParam(m, iter, &p->update_rects) &&
- ReadParam(m, iter, &p->view_size) &&
- ReadParam(m, iter, &p->plugin_window_moves) &&
- ReadParam(m, iter, &p->flags);
- }
- static void Log(const param_type& p, std::wstring* l) {
- l->append(L"(");
- LogParam(p.bitmap, l);
- l->append(L", ");
- LogParam(p.bitmap_rect, l);
- l->append(L", ");
- LogParam(p.update_rects, l);
- l->append(L", ");
- LogParam(p.view_size, l);
- l->append(L", ");
- LogParam(p.plugin_window_moves, l);
- l->append(L", ");
- LogParam(p.flags, l);
- l->append(L")");
- }
-};
-
-// Traits for ViewHostMsg_ScrollRect_Params structure to pack/unpack.
-template <>
-struct ParamTraits<ViewHostMsg_ScrollRect_Params> {
- typedef ViewHostMsg_ScrollRect_Params param_type;
+struct ParamTraits<ViewHostMsg_UpdateRect_Params> {
+ typedef ViewHostMsg_UpdateRect_Params param_type;
static void Write(Message* m, const param_type& p) {
WriteParam(m, p.bitmap);
WriteParam(m, p.bitmap_rect);
WriteParam(m, p.dx);
WriteParam(m, p.dy);
- WriteParam(m, p.clip_rect);
+ WriteParam(m, p.scroll_rect);
+ WriteParam(m, p.copy_rects);
WriteParam(m, p.view_size);
WriteParam(m, p.plugin_window_moves);
+ WriteParam(m, p.flags);
}
static bool Read(const Message* m, void** iter, param_type* p) {
return
@@ -1035,9 +988,11 @@ struct ParamTraits<ViewHostMsg_ScrollRect_Params> {
ReadParam(m, iter, &p->bitmap_rect) &&
ReadParam(m, iter, &p->dx) &&
ReadParam(m, iter, &p->dy) &&
- ReadParam(m, iter, &p->clip_rect) &&
+ ReadParam(m, iter, &p->scroll_rect) &&
+ ReadParam(m, iter, &p->copy_rects) &&
ReadParam(m, iter, &p->view_size) &&
- ReadParam(m, iter, &p->plugin_window_moves);
+ ReadParam(m, iter, &p->plugin_window_moves) &&
+ ReadParam(m, iter, &p->flags);
}
static void Log(const param_type& p, std::wstring* l) {
l->append(L"(");
@@ -1049,11 +1004,15 @@ struct ParamTraits<ViewHostMsg_ScrollRect_Params> {
l->append(L", ");
LogParam(p.dy, l);
l->append(L", ");
- LogParam(p.clip_rect, l);
+ LogParam(p.scroll_rect, l);
+ l->append(L", ");
+ LogParam(p.copy_rects, l);
l->append(L", ");
LogParam(p.view_size, l);
l->append(L", ");
LogParam(p.plugin_window_moves, l);
+ l->append(L", ");
+ LogParam(p.flags, l);
l->append(L")");
}
};
diff --git a/chrome/common/render_messages_internal.h b/chrome/common/render_messages_internal.h
index 3f9a1f1..ca3e80b 100644
--- a/chrome/common/render_messages_internal.h
+++ b/chrome/common/render_messages_internal.h
@@ -128,10 +128,6 @@ IPC_BEGIN_MESSAGES(View)
// render view responds with a ViewHostMsg_Thumbnail.
IPC_MESSAGE_ROUTED0(ViewMsg_CaptureThumbnail)
- // Tells the render view that a ViewHostMsg_PaintRect message was processed.
- // This signals the render view that it can send another PaintRect message.
- IPC_MESSAGE_ROUTED0(ViewMsg_PaintRect_ACK)
-
// Tells the render view to switch the CSS to print media type, renders every
// requested pages and switch back the CSS to display media type.
IPC_MESSAGE_ROUTED0(ViewMsg_PrintPages)
@@ -147,9 +143,9 @@ IPC_BEGIN_MESSAGES(View)
// JS garbage, not in purging irreplaceable objects.
IPC_MESSAGE_CONTROL0(ViewMsg_PurgeMemory)
- // Tells the render view that a ViewHostMsg_ScrollRect message was processed.
- // This signals the render view that it can send another ScrollRect message.
- IPC_MESSAGE_ROUTED0(ViewMsg_ScrollRect_ACK)
+ // Tells the render view that a ViewHostMsg_UpdateRect message was processed.
+ // This signals the render view that it can send another UpdateRect message.
+ IPC_MESSAGE_ROUTED0(ViewMsg_UpdateRect_ACK)
// Message payload includes:
// 1. A blob that should be cast to WebInputEvent
@@ -993,15 +989,10 @@ IPC_BEGIN_MESSAGES(ViewHost)
navigating to a POST again and we're going to
show the POST interstitial */ )
- // Sent to paint part of the view. In response to this message, the host
- // generates a ViewMsg_PaintRect_ACK message.
- IPC_MESSAGE_ROUTED1(ViewHostMsg_PaintRect,
- ViewHostMsg_PaintRect_Params)
-
- // Sent to scroll part of the view. In response to this message, the host
- // generates a ViewMsg_ScrollRect_ACK message.
- IPC_MESSAGE_ROUTED1(ViewHostMsg_ScrollRect,
- ViewHostMsg_ScrollRect_Params)
+ // Sent to update part of the view. In response to this message, the host
+ // generates a ViewMsg_UpdateRect_ACK message.
+ IPC_MESSAGE_ROUTED1(ViewHostMsg_UpdateRect,
+ ViewHostMsg_UpdateRect_Params)
// Acknowledges receipt of a ViewMsg_HandleInputEvent message.
// Payload is a WebInputEvent::Type which is the type of the event, followed
diff --git a/chrome/renderer/render_widget.cc b/chrome/renderer/render_widget.cc
index 27955bb..8a3513c 100644
--- a/chrome/renderer/render_widget.cc
+++ b/chrome/renderer/render_widget.cc
@@ -50,9 +50,8 @@ RenderWidget::RenderWidget(RenderThreadBase* render_thread, bool activatable)
render_thread_(render_thread),
host_window_(0),
current_paint_buf_(NULL),
- current_scroll_buf_(NULL),
next_paint_flags_(0),
- paint_reply_pending_(false),
+ update_reply_pending_(false),
did_show_(false),
is_hidden_(false),
needs_repainting_on_restore_(false),
@@ -79,10 +78,6 @@ RenderWidget::~RenderWidget() {
RenderProcess::current()->ReleaseTransportDIB(current_paint_buf_);
current_paint_buf_ = NULL;
}
- if (current_scroll_buf_) {
- RenderProcess::current()->ReleaseTransportDIB(current_scroll_buf_);
- current_scroll_buf_ = NULL;
- }
RenderProcess::current()->ReleaseProcess();
}
@@ -142,8 +137,7 @@ IPC_DEFINE_MESSAGE_MAP(RenderWidget)
IPC_MESSAGE_HANDLER(ViewMsg_Resize, OnResize)
IPC_MESSAGE_HANDLER(ViewMsg_WasHidden, OnWasHidden)
IPC_MESSAGE_HANDLER(ViewMsg_WasRestored, OnWasRestored)
- IPC_MESSAGE_HANDLER(ViewMsg_PaintRect_ACK, OnPaintRectAck)
- IPC_MESSAGE_HANDLER(ViewMsg_ScrollRect_ACK, OnScrollRectAck)
+ IPC_MESSAGE_HANDLER(ViewMsg_UpdateRect_ACK, OnUpdateRectAck)
IPC_MESSAGE_HANDLER(ViewMsg_HandleInputEvent, OnHandleInputEvent)
IPC_MESSAGE_HANDLER(ViewMsg_MouseCaptureLost, OnMouseCaptureLost)
IPC_MESSAGE_HANDLER(ViewMsg_SetFocus, OnSetFocus)
@@ -258,11 +252,17 @@ void RenderWidget::OnWasRestored(bool needs_repainting) {
didInvalidateRect(gfx::Rect(size_.width(), size_.height()));
}
-void RenderWidget::OnPaintRectAck() {
- DCHECK(paint_reply_pending());
- paint_reply_pending_ = false;
- // If we sent a PaintRect message with a zero-sized bitmap, then
- // we should have no current paint buf.
+void RenderWidget::OnRequestMoveAck() {
+ DCHECK(pending_window_rect_count_);
+ pending_window_rect_count_--;
+}
+
+void RenderWidget::OnUpdateRectAck() {
+ DCHECK(update_reply_pending());
+ update_reply_pending_ = false;
+
+ // If we sent an UpdateRect message with a zero-sized bitmap, then we should
+ // have no current update buf.
if (current_paint_buf_) {
RenderProcess::current()->ReleaseTransportDIB(current_paint_buf_);
current_paint_buf_ = NULL;
@@ -275,23 +275,6 @@ void RenderWidget::OnPaintRectAck() {
CallDoDeferredUpdate();
}
-void RenderWidget::OnRequestMoveAck() {
- DCHECK(pending_window_rect_count_);
- pending_window_rect_count_--;
-}
-
-void RenderWidget::OnScrollRectAck() {
- DCHECK(scroll_reply_pending());
-
- if (current_scroll_buf_) {
- RenderProcess::current()->ReleaseTransportDIB(current_scroll_buf_);
- current_scroll_buf_ = NULL;
- }
-
- // Continue scrolling if necessary...
- CallDoDeferredUpdate();
-}
-
void RenderWidget::OnHandleInputEvent(const IPC::Message& message) {
void* iter = NULL;
@@ -405,9 +388,17 @@ void RenderWidget::PaintDebugBorder(const gfx::Rect& rect,
if (!kPaintBorder)
return;
+ // Cycle through these colors to help distinguish new paint rects.
+ const SkColor colors[] = {
+ SkColorSetARGB(0x3F, 0xFF, 0, 0),
+ SkColorSetARGB(0x3F, 0xFF, 0, 0xFF),
+ SkColorSetARGB(0x3F, 0, 0, 0xFF),
+ };
+ static int color_selector = 0;
+
SkPaint paint;
paint.setStyle(SkPaint::kStroke_Style);
- paint.setColor(SkColorSetARGB(0x3F, 0xFF, 0, 0));
+ paint.setColor(colors[color_selector++ % arraysize(colors)]);
paint.setStrokeWidth(1);
SkIRect irect;
@@ -426,7 +417,7 @@ void RenderWidget::CallDoDeferredUpdate() {
void RenderWidget::DoDeferredUpdate() {
if (!webwidget_ || !paint_aggregator_.HasPendingUpdate() ||
- paint_reply_pending() || scroll_reply_pending())
+ update_reply_pending())
return;
// Suppress updating when we are hidden.
@@ -444,86 +435,56 @@ void RenderWidget::DoDeferredUpdate() {
PaintAggregator::PendingUpdate update = paint_aggregator_.GetPendingUpdate();
paint_aggregator_.ClearPendingUpdate();
- if (!update.scroll_rect.IsEmpty()) {
- // Optmized scrolling
-
- // Compute the region we will expose by scrolling, and paint that into a
- // shared memory section.
- gfx::Rect damaged_rect = update.GetScrollDamage();
-
- scoped_ptr<skia::PlatformCanvas> canvas(
- RenderProcess::current()->GetDrawingCanvas(&current_scroll_buf_,
- damaged_rect));
- if (!canvas.get()) {
- NOTREACHED();
- return;
- }
+ gfx::Rect scroll_damage = update.GetScrollDamage();
+ gfx::Rect bounds = update.GetPaintBounds().Union(scroll_damage);
- // We may get back a smaller canvas than we asked for.
- damaged_rect.set_width(canvas->getDevice()->width());
- damaged_rect.set_height(canvas->getDevice()->height());
-
- // Set these parameters before calling Paint, since that could result in
- // further invalidates (uncommon).
- ViewHostMsg_ScrollRect_Params params;
- params.bitmap_rect = damaged_rect;
- params.dx = update.scroll_delta.x();
- params.dy = update.scroll_delta.y();
- params.clip_rect = update.scroll_rect;
- params.view_size = size_;
- params.plugin_window_moves = plugin_window_moves_;
- params.bitmap = current_scroll_buf_->id();
-
- plugin_window_moves_.clear();
-
- PaintRect(damaged_rect, damaged_rect.origin(), canvas.get());
- Send(new ViewHostMsg_ScrollRect(routing_id_, params));
+ // Compute a buffer for painting and cache it.
+ scoped_ptr<skia::PlatformCanvas> canvas(
+ RenderProcess::current()->GetDrawingCanvas(&current_paint_buf_, bounds));
+ if (!canvas.get()) {
+ NOTREACHED();
+ return;
}
- if (!update.paint_rects.empty()) {
- // Normal painting
-
- gfx::Rect bounds = update.GetPaintBounds();
-
- // Compute a buffer for painting and cache it.
- scoped_ptr<skia::PlatformCanvas> canvas(
- RenderProcess::current()->GetDrawingCanvas(&current_paint_buf_,
- bounds));
- if (!canvas.get()) {
- NOTREACHED();
- return;
- }
-
- // We may get back a smaller canvas than we asked for.
- bounds.set_width(canvas->getDevice()->width());
- bounds.set_height(canvas->getDevice()->height());
-
- HISTOGRAM_COUNTS_100("MPArch.RW_PaintRectCount", update.paint_rects.size());
-
- // TODO(darin): Re-enable painting multiple damage rects once the
- // page-cycler regressions are resolved. See bug 29589.
- if (update.scroll_rect.IsEmpty()) {
- update.paint_rects.clear();
- update.paint_rects.push_back(bounds);
- }
-
- for (size_t i = 0; i < update.paint_rects.size(); ++i)
- PaintRect(update.paint_rects[i], bounds.origin(), canvas.get());
+ // We may get back a smaller canvas than we asked for.
+ // TODO(darin): This seems like it could cause painting problems!
+ DCHECK_EQ(bounds.width(), canvas->getDevice()->width());
+ DCHECK_EQ(bounds.height(), canvas->getDevice()->height());
+ bounds.set_width(canvas->getDevice()->width());
+ bounds.set_height(canvas->getDevice()->height());
+
+ HISTOGRAM_COUNTS_100("MPArch.RW_PaintRectCount", update.paint_rects.size());
+
+ // The scroll damage is just another rectangle to paint and copy.
+ std::vector<gfx::Rect> copy_rects;
+ copy_rects.swap(update.paint_rects);
+ if (!scroll_damage.IsEmpty())
+ copy_rects.push_back(scroll_damage);
+
+ // TODO(darin): Re-enable painting multiple damage rects once the
+ // page-cycler regressions are resolved. See bug 29589.
+ if (update.scroll_rect.IsEmpty()) {
+ update.paint_rects.clear();
+ update.paint_rects.push_back(bounds);
+ }
- ViewHostMsg_PaintRect_Params params;
- params.bitmap_rect = bounds;
- params.update_rects = update.paint_rects; // TODO(darin): clip to bounds?
- params.view_size = size_;
- params.plugin_window_moves = plugin_window_moves_;
- params.flags = next_paint_flags_;
- params.bitmap = current_paint_buf_->id();
+ for (size_t i = 0; i < copy_rects.size(); ++i)
+ PaintRect(copy_rects[i], bounds.origin(), canvas.get());
- plugin_window_moves_.clear();
+ ViewHostMsg_UpdateRect_Params params;
+ params.bitmap = current_paint_buf_->id();
+ params.bitmap_rect = bounds;
+ params.dx = update.scroll_delta.x();
+ params.dy = update.scroll_delta.y();
+ params.scroll_rect = update.scroll_rect;
+ params.copy_rects.swap(copy_rects); // TODO(darin): clip to bounds?
+ params.view_size = size_;
+ params.plugin_window_moves.swap(plugin_window_moves_);
+ params.flags = next_paint_flags_;
- paint_reply_pending_ = true;
- Send(new ViewHostMsg_PaintRect(routing_id_, params));
- next_paint_flags_ = 0;
- }
+ update_reply_pending_ = true;
+ Send(new ViewHostMsg_UpdateRect(routing_id_, params));
+ next_paint_flags_ = 0;
UpdateIME();
}
@@ -548,7 +509,7 @@ void RenderWidget::didInvalidateRect(const WebRect& rect) {
return;
if (!paint_aggregator_.HasPendingUpdate())
return;
- if (paint_reply_pending() || scroll_reply_pending())
+ if (update_reply_pending())
return;
// Perform updating asynchronously. This serves two purposes:
@@ -577,7 +538,7 @@ void RenderWidget::didScrollRect(int dx, int dy, const WebRect& clip_rect) {
return;
if (!paint_aggregator_.HasPendingUpdate())
return;
- if (paint_reply_pending() || scroll_reply_pending())
+ if (update_reply_pending())
return;
// Perform updating asynchronously. This serves two purposes:
@@ -773,23 +734,23 @@ void RenderWidget::SetBackground(const SkBitmap& background) {
}
bool RenderWidget::next_paint_is_resize_ack() const {
- return ViewHostMsg_PaintRect_Flags::is_resize_ack(next_paint_flags_);
+ return ViewHostMsg_UpdateRect_Flags::is_resize_ack(next_paint_flags_);
}
bool RenderWidget::next_paint_is_restore_ack() const {
- return ViewHostMsg_PaintRect_Flags::is_restore_ack(next_paint_flags_);
+ return ViewHostMsg_UpdateRect_Flags::is_restore_ack(next_paint_flags_);
}
void RenderWidget::set_next_paint_is_resize_ack() {
- next_paint_flags_ |= ViewHostMsg_PaintRect_Flags::IS_RESIZE_ACK;
+ next_paint_flags_ |= ViewHostMsg_UpdateRect_Flags::IS_RESIZE_ACK;
}
void RenderWidget::set_next_paint_is_restore_ack() {
- next_paint_flags_ |= ViewHostMsg_PaintRect_Flags::IS_RESTORE_ACK;
+ next_paint_flags_ |= ViewHostMsg_UpdateRect_Flags::IS_RESTORE_ACK;
}
void RenderWidget::set_next_paint_is_repaint_ack() {
- next_paint_flags_ |= ViewHostMsg_PaintRect_Flags::IS_REPAINT_ACK;
+ next_paint_flags_ |= ViewHostMsg_UpdateRect_Flags::IS_REPAINT_ACK;
}
void RenderWidget::UpdateIME() {
diff --git a/chrome/renderer/render_widget.h b/chrome/renderer/render_widget.h
index c25c99a..4cf033e 100644
--- a/chrome/renderer/render_widget.h
+++ b/chrome/renderer/render_widget.h
@@ -142,8 +142,7 @@ class RenderWidget : public IPC::Channel::Listener,
const gfx::Rect& resizer_rect);
void OnWasHidden();
void OnWasRestored(bool needs_repainting);
- void OnPaintRectAck();
- void OnScrollRectAck();
+ void OnUpdateRectAck();
void OnRequestMoveAck();
void OnHandleInputEvent(const IPC::Message& message);
void OnMouseCaptureLost();
@@ -167,14 +166,9 @@ class RenderWidget : public IPC::Channel::Listener,
bool is_hidden() const { return is_hidden_; }
- // True if a PaintRect_ACK message is pending.
- bool paint_reply_pending() const {
- return paint_reply_pending_;
- }
-
- // True if a ScrollRect_ACK message is pending.
- bool scroll_reply_pending() const {
- return current_scroll_buf_ != NULL;
+ // True if an UpdateRect_ACK message is pending.
+ bool update_reply_pending() const {
+ return update_reply_pending_;
}
bool next_paint_is_resize_ack() const;
@@ -238,22 +232,20 @@ class RenderWidget : public IPC::Channel::Listener,
// The size of the RenderWidget.
gfx::Size size_;
- // Transport DIBs that are currently in use to transfer an image to the
- // browser.
+ // The TransportDIB that is being used to transfer an image to the browser.
TransportDIB* current_paint_buf_;
- TransportDIB* current_scroll_buf_;
PaintAggregator paint_aggregator_;
// The area that must be reserved for drawing the resize corner.
gfx::Rect resizer_rect_;
- // Flags for the next ViewHostMsg_PaintRect message.
+ // Flags for the next ViewHostMsg_UpdateRect message.
int next_paint_flags_;
- // True if we are expecting a PaintRect_ACK message (i.e., that a PaintRect
- // message has been sent).
- bool paint_reply_pending_;
+ // True if we are expecting an UpdateRect_ACK message (i.e., that a
+ // UpdateRect message has been sent).
+ bool update_reply_pending_;
// Set to true if we should ignore RenderWidget::Show calls.
bool did_show_;