summaryrefslogtreecommitdiffstats
path: root/chrome/gpu/gpu_view_win.cc
diff options
context:
space:
mode:
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;
+}