| 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 |