summaryrefslogtreecommitdiffstats
path: root/chrome/gpu/gpu_view_win.cc
diff options
context:
space:
mode:
authorbrettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-01-13 00:55:37 +0000
committerbrettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-01-13 00:55:37 +0000
commitc0fc094f4b95fc55baace5d1452b6110f68cf167 (patch)
tree16dc1253142393c4325055ef69971fa4f91187f0 /chrome/gpu/gpu_view_win.cc
parentf0c7a263de099efa75d9f4122c16c0c0fcaa9677 (diff)
downloadchromium_src-c0fc094f4b95fc55baace5d1452b6110f68cf167.zip
chromium_src-c0fc094f4b95fc55baace5d1452b6110f68cf167.tar.gz
chromium_src-c0fc094f4b95fc55baace5d1452b6110f68cf167.tar.bz2
Add the ability for the GPU process to be used to paint the backing store of a
tab. This is the first pass and is currently a bit buggy and incomplete. This patch refactors the backing store to make it a virtual interface which is then implemented by the platform-specific backing stores. This cleans up the multi-platform aspects of the old code, and also makes it possible to create different backing stores (such as ones in another process). This renames the BackingStore::PaintRect function to PaintToBackingStore which clears up what it does. I would often get confused and think that it paints the backing store to the screen. This makes a common way to capture backing store information and adds it to the backing store API. This removed a bunch of ugly ifdefs. This adds the ability for a backing store to specify that the TransportDIB should not be freed by RenderWidgetHost when painting is complete. This is necessary since the out-of-process version needs to use it after the RenderWidget paint function has returned. This pushes up the vector of copy_rect from RenderWidgetHost to the actual BackingStores. This prevents us from sending duplicate data over IPC. It also makes the common non-IPC case more efficient, since we end up setting up various surfaces only once when there are multiple update rects. BUG=none TEST=none Review URL: http://codereview.chromium.org/523028 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@36075 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/gpu/gpu_view_win.cc')
-rw-r--r--chrome/gpu/gpu_view_win.cc158
1 files changed, 158 insertions, 0 deletions
diff --git a/chrome/gpu/gpu_view_win.cc b/chrome/gpu/gpu_view_win.cc
new file mode 100644
index 0000000..e94c695
--- /dev/null
+++ b/chrome/gpu/gpu_view_win.cc
@@ -0,0 +1,158 @@
+// Copyright (c) 2010 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/gpu/gpu_view_win.h"
+
+#include "chrome/common/gpu_messages.h"
+#include "chrome/gpu/gpu_backing_store.h"
+#include "chrome/gpu/gpu_thread.h"
+
+namespace {
+
+void DrawBackground(const RECT& dirty_rect, CPaintDC* dc) {
+ HBRUSH white_brush = reinterpret_cast<HBRUSH>(GetStockObject(WHITE_BRUSH));
+ dc->FillRect(&dirty_rect, white_brush);
+}
+
+void DrawResizeCorner(const RECT& dirty_rect, HDC dc) {
+ // TODO(brettw): implement this.
+}
+
+} // namespace
+
+GpuViewWin::GpuViewWin(GpuThread* gpu_thread,
+ gfx::NativeViewId parent_window,
+ int32 routing_id)
+ : gpu_thread_(gpu_thread),
+ routing_id_(routing_id),
+ parent_window_(gfx::NativeViewFromId(parent_window)) {
+ gpu_thread_->AddRoute(routing_id_, this);
+ Create(gfx::NativeViewFromId(parent_window));
+ SetWindowText(L"GPU window");
+ ShowWindow(SW_SHOW);
+}
+
+GpuViewWin::~GpuViewWin() {
+ gpu_thread_->RemoveRoute(routing_id_);
+ // TODO(brettw) may want to delete any dangling backing stores, or perhaps
+ // assert if one still exists.
+}
+
+void GpuViewWin::OnMessageReceived(const IPC::Message& msg) {
+ IPC_BEGIN_MESSAGE_MAP(GpuViewWin, msg)
+ IPC_MESSAGE_HANDLER(GpuMsg_NewBackingStore, OnNewBackingStore)
+ IPC_END_MESSAGE_MAP_EX()
+}
+
+void GpuViewWin::OnChannelConnected(int32 peer_pid) {
+}
+
+void GpuViewWin::OnChannelError() {
+ // TODO(brettw) do we need to delete ourselves now?
+}
+
+void GpuViewWin::DidScrollBackingStoreRect(int dx, int dy,
+ const gfx::Rect& rect) {
+ // 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);
+}
+
+void GpuViewWin::OnNewBackingStore(int32 routing_id, const gfx::Size& size) {
+ backing_store_.reset(
+ new GpuBackingStore(this, gpu_thread_, routing_id, size));
+ MoveWindow(0, 0, size.width(), size.height(), TRUE);
+}
+
+void GpuViewWin::OnPaint(HDC unused_dc) {
+ // 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);
+ if (damaged_rect.IsEmpty())
+ return;
+
+ if (backing_store_.get()) {
+ gfx::Rect bitmap_rect(gfx::Point(), backing_store_->size());
+
+ // Blit only the damaged regions from the backing store.
+ DWORD data_size = GetRegionData(damage_region, 0, NULL);
+ // TODO(brettw) why is the "+1" necessary here? When I remove it, the
+ // page paints black, but according to the documentation, its not needed.
+ scoped_array<char> region_data_buf(new char[data_size + 1]);
+ 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.ToRECT(), 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);
+ }
+ }
+
+ // Fill the remaining portion of the damaged_rect with the background
+ if (damaged_rect.right() > bitmap_rect.right()) {
+ RECT r;
+ r.left = std::max(bitmap_rect.right(), damaged_rect.x());
+ r.right = damaged_rect.right();
+ r.top = damaged_rect.y();
+ r.bottom = std::min(bitmap_rect.bottom(), damaged_rect.bottom());
+ DrawBackground(r, &paint_dc);
+ }
+ if (damaged_rect.bottom() > bitmap_rect.bottom()) {
+ RECT r;
+ r.left = damaged_rect.x();
+ r.right = damaged_rect.right();
+ r.top = std::max(bitmap_rect.bottom(), damaged_rect.y());
+ r.bottom = damaged_rect.bottom();
+ DrawBackground(r, &paint_dc);
+ }
+ } else {
+ DrawBackground(paint_dc.m_ps.rcPaint, &paint_dc);
+ }
+}
+
+LRESULT GpuViewWin::OnMouseEvent(UINT message,
+ WPARAM wparam,
+ LPARAM lparam,
+ BOOL& handled) {
+ handled = true;
+ ::PostMessage(GetParent(), message, wparam, lparam);
+ return 0;
+}
+
+LRESULT GpuViewWin::OnKeyEvent(UINT message,
+ WPARAM wparam,
+ LPARAM lparam,
+ BOOL& handled) {
+ handled = true;
+ ::PostMessage(GetParent(), message, wparam, lparam);
+ return 0;
+}
+
+LRESULT GpuViewWin::OnWheelEvent(UINT message,
+ WPARAM wparam,
+ LPARAM lparam,
+ BOOL& handled) {
+ handled = true;
+ ::PostMessage(GetParent(), message, wparam, lparam);
+ return 0;
+}