summaryrefslogtreecommitdiffstats
path: root/chrome/browser/renderer_host
diff options
context:
space:
mode:
authorgspencer@chromium.org <gspencer@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-04-28 17:26:49 +0000
committergspencer@chromium.org <gspencer@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-04-28 17:26:49 +0000
commitd65adb173f09a837c96f96fc24a258f439e46e58 (patch)
tree43605ab367e97389930c518c4e94bd3da5f20080 /chrome/browser/renderer_host
parent7cea56d943924d0c2196bdf4049f592b6182992c (diff)
downloadchromium_src-d65adb173f09a837c96f96fc24a258f439e46e58.zip
chromium_src-d65adb173f09a837c96f96fc24a258f439e46e58.tar.gz
chromium_src-d65adb173f09a837c96f96fc24a258f439e46e58.tar.bz2
This adds in the ability for Chrome to generate windows with snapshots
of all currently open tabs in all browsers. This is needed for overview mode on ChromeOS. BUG=http://code.google.com/p/chromium-os/issues/detail?id=1170 TEST=Ran Chrome under ChromeOS with updated window manager. Review URL: http://codereview.chromium.org/661237 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@45824 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/renderer_host')
-rw-r--r--chrome/browser/renderer_host/backing_store_x.cc17
-rw-r--r--chrome/browser/renderer_host/render_widget_helper.h2
-rw-r--r--chrome/browser/renderer_host/render_widget_host.cc16
-rw-r--r--chrome/browser/renderer_host/render_widget_host.h15
-rw-r--r--chrome/browser/renderer_host/render_widget_host_painting_observer.h14
-rw-r--r--chrome/browser/renderer_host/render_widget_host_unittest.cc50
6 files changed, 105 insertions, 9 deletions
diff --git a/chrome/browser/renderer_host/backing_store_x.cc b/chrome/browser/renderer_host/backing_store_x.cc
index d88dca7..f10e589 100644
--- a/chrome/browser/renderer_host/backing_store_x.cc
+++ b/chrome/browser/renderer_host/backing_store_x.cc
@@ -326,6 +326,7 @@ bool BackingStoreX::CopyFromBackingStore(const gfx::Rect& rect,
// TODO(jhawkins): Need to convert the image data if the image bits per pixel
// is not 32.
+ // Note that this also initializes the output bitmap as opaque.
if (!output->initialize(width, height, true) ||
image->bits_per_pixel != 32) {
if (shared_memory_support_ != x11_util::SHARED_MEMORY_NONE)
@@ -335,15 +336,19 @@ bool BackingStoreX::CopyFromBackingStore(const gfx::Rect& rect,
return false;
}
- // The X image might have a different row stride, so iterate through it and
- // copy each row out, only up to the pixels we're actually using.
- // This code assumes a visual mode where a pixel is represented using
- // a byte for each component.
+ // The X image might have a different row stride, so iterate through
+ // it and copy each row out, only up to the pixels we're actually
+ // using. This code assumes a visual mode where a pixel is
+ // represented using a 32-bit unsigned int, with a byte per component.
SkBitmap bitmap = output->getTopPlatformDevice().accessBitmap(true);
for (int y = 0; y < height; y++) {
+ const uint32* src_row = reinterpret_cast<uint32*>(
+ &image->data[image->bytes_per_line * y]);
uint32* dest_row = bitmap.getAddr32(0, y);
- const char* src_row = &image->data[image->bytes_per_line * y];
- memcpy(dest_row, src_row, width * 4);
+ for (int x = 0; x < width; ++x, ++dest_row) {
+ // Force alpha to be 0xff, because otherwise it causes rendering problems.
+ *dest_row = src_row[x] | 0xff000000;
+ }
}
if (shared_memory_support_ != x11_util::SHARED_MEMORY_NONE)
diff --git a/chrome/browser/renderer_host/render_widget_helper.h b/chrome/browser/renderer_host/render_widget_helper.h
index 53b336c..33ca744 100644
--- a/chrome/browser/renderer_host/render_widget_helper.h
+++ b/chrome/browser/renderer_host/render_widget_helper.h
@@ -188,7 +188,7 @@ class RenderWidgetHelper
#endif
// A map of live paint messages. Must hold pending_paints_lock_ to access.
- // The PaintMsgProxy objects are not owned by this map. (See PaintMsgProxy
+ // The UpdateMsgProxy objects are not owned by this map. (See UpdateMsgProxy
// for details about how the lifetime of instances are managed.)
UpdateMsgProxyMap pending_paints_;
Lock pending_paints_lock_;
diff --git a/chrome/browser/renderer_host/render_widget_host.cc b/chrome/browser/renderer_host/render_widget_host.cc
index 6b20935..59b2231 100644
--- a/chrome/browser/renderer_host/render_widget_host.cc
+++ b/chrome/browser/renderer_host/render_widget_host.cc
@@ -127,6 +127,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_PaintAtSize_ACK, OnMsgPaintAtSizeAck)
IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateRect, OnMsgUpdateRect)
IPC_MESSAGE_HANDLER(ViewHostMsg_CreateVideo, OnMsgCreateVideo)
IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateVideo, OnMsgUpdateVideo)
@@ -280,6 +281,14 @@ void RenderWidgetHost::SetIsLoading(bool is_loading) {
view_->SetIsLoading(is_loading);
}
+void RenderWidgetHost::PaintAtSize(TransportDIB::Handle dib_handle,
+ const gfx::Size& size) {
+ // Ask the renderer to create a bitmap regardless of whether it's
+ // hidden, being resized, redrawn, etc., and to scale it by the
+ // scale factor given.
+ Send(new ViewMsg_PaintAtSize(routing_id_, dib_handle, size));
+}
+
BackingStore* RenderWidgetHost::GetBackingStore(bool force_create) {
// 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. If we're not
@@ -676,6 +685,13 @@ void RenderWidgetHost::OnMsgRequestMove(const gfx::Rect& pos) {
}
}
+void RenderWidgetHost::OnMsgPaintAtSizeAck(
+ const TransportDIB::Handle& dib_handle, const gfx::Size& size) {
+ if (painting_observer_) {
+ painting_observer_->WidgetDidReceivePaintAtSizeAck(this, dib_handle, size);
+ }
+}
+
void RenderWidgetHost::OnMsgUpdateRect(
const ViewHostMsg_UpdateRect_Params& params) {
TimeTicks paint_start = TimeTicks::Now();
diff --git a/chrome/browser/renderer_host/render_widget_host.h b/chrome/browser/renderer_host/render_widget_host.h
index d57d8bc..7b87d13 100644
--- a/chrome/browser/renderer_host/render_widget_host.h
+++ b/chrome/browser/renderer_host/render_widget_host.h
@@ -205,6 +205,16 @@ class RenderWidgetHost : public IPC::Channel::Listener,
// Indicates if the page has finished loading.
void SetIsLoading(bool is_loading);
+ // This tells the renderer to paint into a bitmap and return it,
+ // regardless of whether the tab is hidden or not. It returns the
+ // bitmap scaled so it matches the requested size, so that the
+ // scaling happens on the rendering thread. When the bitmap is
+ // ready, the renderer sends a PaintAtSizeACK to this host, and the
+ // painting observer is notified. Note that this bypasses most of
+ // the update logic that is normally invoked, and doesn't put the
+ // results into the backing store.
+ void PaintAtSize(TransportDIB::Handle dib_handle, const gfx::Size& size);
+
// 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. If you pass |force_create| as true, then the backing
@@ -413,6 +423,7 @@ class RenderWidgetHost : public IPC::Channel::Listener,
FRIEND_TEST(RenderWidgetHostTest, Resize);
FRIEND_TEST(RenderWidgetHostTest, ResizeThenCrash);
FRIEND_TEST(RenderWidgetHostTest, HiddenPaint);
+ FRIEND_TEST(RenderWidgetHostTest, PaintAtSize);
// Tell this object to destroy itself.
void Destroy();
@@ -421,7 +432,7 @@ class RenderWidgetHost : public IPC::Channel::Listener,
// if it is.
void CheckRendererIsUnresponsive();
- // Called if we know the renderer is responsive. When we currently thing the
+ // Called if we know the renderer is responsive. When we currently think the
// renderer is unresponsive, this will clear that state and call
// NotifyRendererResponsive.
void RendererIsResponsive();
@@ -431,6 +442,8 @@ class RenderWidgetHost : public IPC::Channel::Listener,
void OnMsgRenderViewGone();
void OnMsgClose();
void OnMsgRequestMove(const gfx::Rect& pos);
+ void OnMsgPaintAtSizeAck(const TransportDIB::Handle& dib_handle,
+ const gfx::Size& size);
void OnMsgUpdateRect(const ViewHostMsg_UpdateRect_Params& params);
void OnMsgCreateVideo(const gfx::Size& size);
void OnMsgUpdateVideo(TransportDIB::Id bitmap, const gfx::Rect& bitmap_rect);
diff --git a/chrome/browser/renderer_host/render_widget_host_painting_observer.h b/chrome/browser/renderer_host/render_widget_host_painting_observer.h
index d24b61a..332e446 100644
--- a/chrome/browser/renderer_host/render_widget_host_painting_observer.h
+++ b/chrome/browser/renderer_host/render_widget_host_painting_observer.h
@@ -5,8 +5,15 @@
#ifndef CHROME_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_PAINTING_OBSERVER_H_
#define CHROME_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_PAINTING_OBSERVER_H_
+#include "app/surface/transport_dib.h"
+
class BackingStore;
class RenderWidgetHost;
+class SkBitmap;
+
+namespace gfx {
+class Size;
+}
// This class can be used to observe painting events for a RenderWidgetHost.
// Its primary goal in Chrome is to allow thumbnails to be generated.
@@ -19,6 +26,13 @@ class RenderWidgetHostPaintingObserver {
// Indicates that the RenderWidgetHost just updated the backing store.
virtual void WidgetDidUpdateBackingStore(RenderWidgetHost* widget) = 0;
+
+ // This notifies the painting observer that a PaintAtSizeACK was
+ // received.
+ virtual void WidgetDidReceivePaintAtSizeAck(
+ RenderWidgetHost* widget,
+ const TransportDIB::Handle& dib_handle,
+ const gfx::Size& size) = 0;
};
#endif // CHROME_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_PAINTING_OBSERVER_H_
diff --git a/chrome/browser/renderer_host/render_widget_host_unittest.cc b/chrome/browser/renderer_host/render_widget_host_unittest.cc
index e0ffe1a..28be917 100644
--- a/chrome/browser/renderer_host/render_widget_host_unittest.cc
+++ b/chrome/browser/renderer_host/render_widget_host_unittest.cc
@@ -9,6 +9,7 @@
#include "base/timer.h"
#include "build/build_config.h"
#include "chrome/browser/renderer_host/backing_store.h"
+#include "chrome/browser/renderer_host/render_widget_host_painting_observer.h"
#include "chrome/browser/renderer_host/test/test_render_view_host.h"
#include "chrome/common/render_messages.h"
#include "gfx/canvas.h"
@@ -19,6 +20,10 @@ using base::TimeDelta;
using WebKit::WebInputEvent;
using WebKit::WebMouseWheelEvent;
+namespace gfx {
+class Size;
+}
+
// RenderWidgetHostProcess -----------------------------------------------------
class RenderWidgetHostProcess : public MockRenderProcessHost {
@@ -191,6 +196,32 @@ class MockRenderWidgetHost : public RenderWidgetHost {
bool unresponsive_timer_fired_;
};
+// MockPaintingObserver --------------------------------------------------------
+
+class MockPaintingObserver : public RenderWidgetHostPaintingObserver {
+ public:
+ void WidgetWillDestroyBackingStore(RenderWidgetHost* widget,
+ BackingStore* backing_store) {}
+ void WidgetDidUpdateBackingStore(RenderWidgetHost* widget) {}
+ void WidgetDidReceivePaintAtSizeAck(RenderWidgetHost* host,
+ const TransportDIB::Handle& dib_handle,
+ const gfx::Size& size) {
+ host_ = reinterpret_cast<MockRenderWidgetHost*>(host);
+ dib_handle_ = dib_handle;
+ size_ = size;
+ }
+
+ MockRenderWidgetHost* host() const { return host_; }
+ TransportDIB::Handle dib_handle() const { return dib_handle_; }
+ gfx::Size size() const { return size_; }
+
+ private:
+ MockRenderWidgetHost* host_;
+ TransportDIB::Handle dib_handle_;
+ gfx::Size size_;
+};
+
+
// RenderWidgetHostTest --------------------------------------------------------
class RenderWidgetHostTest : public testing::Test {
@@ -504,6 +535,24 @@ TEST_F(RenderWidgetHostTest, HiddenPaint) {
EXPECT_TRUE(needs_repaint.a);
}
+TEST_F(RenderWidgetHostTest, PaintAtSize) {
+ host_->PaintAtSize(TransportDIB::GetFakeHandleForTest(), gfx::Size(20, 30));
+ EXPECT_TRUE(
+ process_->sink().GetUniqueMessageMatching(ViewMsg_PaintAtSize::ID));
+
+ MockPaintingObserver observer;
+ host_->set_painting_observer(&observer);
+
+ // Need to generate a fake handle value on all platforms.
+ TransportDIB::Handle handle = TransportDIB::GetFakeHandleForTest();
+ host_->OnMsgPaintAtSizeAck(handle, gfx::Size(20, 30));
+ EXPECT_TRUE(host_ == observer.host());
+ EXPECT_TRUE(handle == observer.dib_handle());
+ EXPECT_EQ(20, observer.size().width());
+ EXPECT_EQ(30, observer.size().height());
+ host_->set_painting_observer(NULL);
+}
+
TEST_F(RenderWidgetHostTest, HandleKeyEventsWeSent) {
// Simulate a keyboard event.
SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
@@ -649,4 +698,3 @@ TEST_F(RenderWidgetHostTest, StopAndStartHangMonitorTimeout) {
MessageLoop::current()->Run();
EXPECT_TRUE(host_->unresponsive_timer_fired());
}
-