diff options
author | brettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-01-13 00:55:37 +0000 |
---|---|---|
committer | brettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-01-13 00:55:37 +0000 |
commit | c0fc094f4b95fc55baace5d1452b6110f68cf167 (patch) | |
tree | 16dc1253142393c4325055ef69971fa4f91187f0 /chrome/gpu/gpu_view_win.cc | |
parent | f0c7a263de099efa75d9f4122c16c0c0fcaa9677 (diff) | |
download | chromium_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.cc | 158 |
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; +} |