OLD | NEW |
| (Empty) |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "chrome/gpu/gpu_view_win.h" | |
6 | |
7 #include "chrome/common/gpu_messages.h" | |
8 #include "chrome/gpu/gpu_backing_store_win.h" | |
9 #include "chrome/gpu/gpu_thread.h" | |
10 #include "gfx/rect.h" | |
11 | |
12 namespace { | |
13 | |
14 void DrawBackground(const RECT& dirty_rect, CPaintDC* dc) { | |
15 HBRUSH white_brush = reinterpret_cast<HBRUSH>(GetStockObject(WHITE_BRUSH)); | |
16 dc->FillRect(&dirty_rect, white_brush); | |
17 } | |
18 | |
19 void DrawResizeCorner(const RECT& dirty_rect, HDC dc) { | |
20 // TODO(brettw): implement this. | |
21 } | |
22 | |
23 } // namespace | |
24 | |
25 GpuViewWin::GpuViewWin(GpuThread* gpu_thread, | |
26 HWND parent, | |
27 int32 routing_id) | |
28 : gpu_thread_(gpu_thread), | |
29 routing_id_(routing_id), | |
30 parent_(parent) { | |
31 gpu_thread_->AddRoute(routing_id_, this); | |
32 Create(parent_); | |
33 SetWindowText(L"GPU window"); | |
34 ShowWindow(SW_SHOW); | |
35 } | |
36 | |
37 GpuViewWin::~GpuViewWin() { | |
38 gpu_thread_->RemoveRoute(routing_id_); | |
39 // TODO(brettw) may want to delete any dangling backing stores, or perhaps | |
40 // assert if one still exists. | |
41 } | |
42 | |
43 void GpuViewWin::OnMessageReceived(const IPC::Message& msg) { | |
44 IPC_BEGIN_MESSAGE_MAP(GpuViewWin, msg) | |
45 IPC_MESSAGE_HANDLER(GpuMsg_NewBackingStore, OnNewBackingStore) | |
46 IPC_END_MESSAGE_MAP_EX() | |
47 } | |
48 | |
49 void GpuViewWin::OnChannelConnected(int32 peer_pid) { | |
50 } | |
51 | |
52 void GpuViewWin::OnChannelError() { | |
53 // TODO(brettw) do we need to delete ourselves now? | |
54 } | |
55 | |
56 void GpuViewWin::DidScrollBackingStoreRect(int dx, int dy, | |
57 const gfx::Rect& rect) { | |
58 // We need to pass in SW_INVALIDATE to ScrollWindowEx. The documentation on | |
59 // MSDN states that it only applies to the HRGN argument, which is wrong. | |
60 // Not passing in this flag does not invalidate the region which was scrolled | |
61 // from, thus causing painting issues. | |
62 RECT clip_rect = rect.ToRECT(); | |
63 ScrollWindowEx(dx, dy, NULL, &clip_rect, NULL, NULL, SW_INVALIDATE); | |
64 } | |
65 | |
66 void GpuViewWin::OnNewBackingStore(int32 routing_id, const gfx::Size& size) { | |
67 backing_store_.reset( | |
68 new GpuBackingStoreWin(this, gpu_thread_, routing_id, size)); | |
69 MoveWindow(0, 0, size.width(), size.height(), TRUE); | |
70 } | |
71 | |
72 void GpuViewWin::OnPaint(HDC unused_dc) { | |
73 // Grab the region to paint before creation of paint_dc since it clears the | |
74 // damage region. | |
75 ScopedGDIObject<HRGN> damage_region(CreateRectRgn(0, 0, 0, 0)); | |
76 GetUpdateRgn(damage_region, FALSE); | |
77 | |
78 CPaintDC paint_dc(m_hWnd); | |
79 | |
80 gfx::Rect damaged_rect(paint_dc.m_ps.rcPaint); | |
81 if (damaged_rect.IsEmpty()) | |
82 return; | |
83 | |
84 if (backing_store_.get()) { | |
85 gfx::Rect bitmap_rect(gfx::Point(), backing_store_->size()); | |
86 | |
87 // Blit only the damaged regions from the backing store. | |
88 DWORD data_size = GetRegionData(damage_region, 0, NULL); | |
89 // TODO(brettw) why is the "+1" necessary here? When I remove it, the | |
90 // page paints black, but according to the documentation, its not needed. | |
91 scoped_array<char> region_data_buf(new char[data_size + 1]); | |
92 RGNDATA* region_data = reinterpret_cast<RGNDATA*>(region_data_buf.get()); | |
93 GetRegionData(damage_region, data_size, region_data); | |
94 | |
95 RECT* region_rects = reinterpret_cast<RECT*>(region_data->Buffer); | |
96 for (DWORD i = 0; i < region_data->rdh.nCount; ++i) { | |
97 gfx::Rect paint_rect = bitmap_rect.Intersect(gfx::Rect(region_rects[i])); | |
98 if (!paint_rect.IsEmpty()) { | |
99 DrawResizeCorner(paint_rect.ToRECT(), backing_store_->hdc()); | |
100 BitBlt(paint_dc.m_hDC, | |
101 paint_rect.x(), | |
102 paint_rect.y(), | |
103 paint_rect.width(), | |
104 paint_rect.height(), | |
105 backing_store_->hdc(), | |
106 paint_rect.x(), | |
107 paint_rect.y(), | |
108 SRCCOPY); | |
109 } | |
110 } | |
111 | |
112 // Fill the remaining portion of the damaged_rect with the background | |
113 if (damaged_rect.right() > bitmap_rect.right()) { | |
114 RECT r; | |
115 r.left = std::max(bitmap_rect.right(), damaged_rect.x()); | |
116 r.right = damaged_rect.right(); | |
117 r.top = damaged_rect.y(); | |
118 r.bottom = std::min(bitmap_rect.bottom(), damaged_rect.bottom()); | |
119 DrawBackground(r, &paint_dc); | |
120 } | |
121 if (damaged_rect.bottom() > bitmap_rect.bottom()) { | |
122 RECT r; | |
123 r.left = damaged_rect.x(); | |
124 r.right = damaged_rect.right(); | |
125 r.top = std::max(bitmap_rect.bottom(), damaged_rect.y()); | |
126 r.bottom = damaged_rect.bottom(); | |
127 DrawBackground(r, &paint_dc); | |
128 } | |
129 } else { | |
130 DrawBackground(paint_dc.m_ps.rcPaint, &paint_dc); | |
131 } | |
132 } | |
OLD | NEW |