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 | |
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')
-rw-r--r-- | chrome/gpu/gpu_backing_store.cc | 185 | ||||
-rw-r--r-- | chrome/gpu/gpu_backing_store.h | 74 | ||||
-rw-r--r-- | chrome/gpu/gpu_main.cc | 38 | ||||
-rw-r--r-- | chrome/gpu/gpu_process.cc | 11 | ||||
-rw-r--r-- | chrome/gpu/gpu_process.h | 19 | ||||
-rw-r--r-- | chrome/gpu/gpu_thread.cc | 38 | ||||
-rw-r--r-- | chrome/gpu/gpu_thread.h | 28 | ||||
-rw-r--r-- | chrome/gpu/gpu_view_win.cc | 158 | ||||
-rw-r--r-- | chrome/gpu/gpu_view_win.h | 102 |
9 files changed, 653 insertions, 0 deletions
diff --git a/chrome/gpu/gpu_backing_store.cc b/chrome/gpu/gpu_backing_store.cc new file mode 100644 index 0000000..a5fafe2 --- /dev/null +++ b/chrome/gpu/gpu_backing_store.cc @@ -0,0 +1,185 @@ +// 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_backing_store.h" + +#include "app/gfx/gdi_util.h" +#include "app/win_util.h" +#include "base/logging.h" +#include "chrome/common/gpu_messages.h" +#include "chrome/gpu/gpu_view_win.h" +#include "chrome/gpu/gpu_thread.h" + +namespace { + +// Creates a dib conforming to the height/width/section parameters passed in. +HANDLE CreateDIB(HDC dc, int width, int height, int color_depth) { + BITMAPV5HEADER hdr = {0}; + ZeroMemory(&hdr, sizeof(BITMAPV5HEADER)); + + // These values are shared with gfx::PlatformDevice + hdr.bV5Size = sizeof(BITMAPINFOHEADER); + hdr.bV5Width = width; + hdr.bV5Height = -height; // minus means top-down bitmap + hdr.bV5Planes = 1; + hdr.bV5BitCount = color_depth; + hdr.bV5Compression = BI_RGB; // no compression + hdr.bV5SizeImage = 0; + hdr.bV5XPelsPerMeter = 1; + hdr.bV5YPelsPerMeter = 1; + hdr.bV5ClrUsed = 0; + hdr.bV5ClrImportant = 0; + + + void* data = NULL; + HANDLE dib = CreateDIBSection(dc, reinterpret_cast<BITMAPINFO*>(&hdr), + 0, &data, NULL, 0); + DCHECK(data); + return dib; +} + +void CallStretchDIBits(HDC hdc, int dest_x, int dest_y, int dest_w, int dest_h, + int src_x, int src_y, int src_w, int src_h, void* pixels, + const BITMAPINFO* bitmap_info) { + // When blitting a rectangle that touches the bottom, left corner of the + // bitmap, StretchDIBits looks at it top-down! For more details, see + // http://wiki.allegro.cc/index.php?title=StretchDIBits. + int rv; + int bitmap_h = -bitmap_info->bmiHeader.biHeight; + int bottom_up_src_y = bitmap_h - src_y - src_h; + if (bottom_up_src_y == 0 && src_x == 0 && src_h != bitmap_h) { + rv = StretchDIBits(hdc, + dest_x, dest_h + dest_y - 1, dest_w, -dest_h, + src_x, bitmap_h - src_y + 1, src_w, -src_h, + pixels, bitmap_info, DIB_RGB_COLORS, SRCCOPY); + } else { + rv = StretchDIBits(hdc, + dest_x, dest_y, dest_w, dest_h, + src_x, bottom_up_src_y, src_w, src_h, + pixels, bitmap_info, DIB_RGB_COLORS, SRCCOPY); + } + DCHECK(rv != GDI_ERROR); +} + +} // namespace + + +GpuBackingStore::GpuBackingStore(GpuViewWin* view, + GpuThread* gpu_thread, + int32 routing_id, + const gfx::Size& size) + : view_(view), + gpu_thread_(gpu_thread), + routing_id_(routing_id), + size_(size) { + gpu_thread_->AddRoute(routing_id_, this); + + HDC screen_dc = ::GetDC(NULL); + color_depth_ = ::GetDeviceCaps(screen_dc, BITSPIXEL); + // Color depths less than 16 bpp require a palette to be specified. Instead, + // we specify the desired color depth as 16 which lets the OS to come up + // with an approximation. + if (color_depth_ < 16) + color_depth_ = 16; + hdc_ = CreateCompatibleDC(screen_dc); + ReleaseDC(NULL, screen_dc); +} + +GpuBackingStore::~GpuBackingStore() { + gpu_thread_->RemoveRoute(routing_id_); + + DCHECK(hdc_); + if (original_bitmap_) { + SelectObject(hdc_, original_bitmap_); + } + if (backing_store_dib_) { + DeleteObject(backing_store_dib_); + backing_store_dib_ = NULL; + } + DeleteDC(hdc_); +} + +void GpuBackingStore::OnMessageReceived(const IPC::Message& msg) { + IPC_BEGIN_MESSAGE_MAP(GpuBackingStore, msg) + IPC_MESSAGE_HANDLER(GpuMsg_PaintToBackingStore, OnPaintToBackingStore) + IPC_MESSAGE_HANDLER(GpuMsg_ScrollBackingStore, OnScrollBackingStore) + IPC_END_MESSAGE_MAP_EX() +} + +void GpuBackingStore::OnChannelConnected(int32 peer_pid) { +} + +void GpuBackingStore::OnChannelError() { + // FIXME(brettw) does this mean we aren't getting any more messages and we + // should delete outselves? +} + +void GpuBackingStore::OnPaintToBackingStore( + base::ProcessId source_process_id, + TransportDIB::Id id, + const gfx::Rect& bitmap_rect, + const std::vector<gfx::Rect>& copy_rects) { + HANDLE source_process_handle = OpenProcess(PROCESS_ALL_ACCESS, + FALSE, source_process_id); + CHECK(source_process_handle); + + // On Windows we need to duplicate the handle from the remote process. + // See BrowserRenderProcessHost::MapTransportDIB for how to do this on other + // platforms. + HANDLE section = win_util::GetSectionFromProcess( + id.handle, source_process_handle, false /* read write */); + CHECK(section); + TransportDIB* dib = TransportDIB::Map(section); + CHECK(dib); + + if (!backing_store_dib_) { + backing_store_dib_ = CreateDIB(hdc_, size_.width(), + size_.height(), color_depth_); + if (!backing_store_dib_) { + NOTREACHED(); + + // TODO(brettw): do this in such a way that we can't forget to + // send the ACK. + gpu_thread_->Send(new GpuHostMsg_PaintToBackingStore_ACK(routing_id_)); + return; + } + original_bitmap_ = SelectObject(hdc_, backing_store_dib_); + } + + BITMAPINFOHEADER hdr; + gfx::CreateBitmapHeader(bitmap_rect.width(), bitmap_rect.height(), &hdr); + // Account for a bitmap_rect that exceeds the bounds of our view + gfx::Rect view_rect(0, 0, size_.width(), size_.height()); + + for (size_t i = 0; i < copy_rects.size(); i++) { + gfx::Rect paint_rect = view_rect.Intersect(copy_rects[i]); + CallStretchDIBits(hdc_, + paint_rect.x(), + paint_rect.y(), + paint_rect.width(), + paint_rect.height(), + paint_rect.x() - bitmap_rect.x(), + paint_rect.y() - bitmap_rect.y(), + paint_rect.width(), + paint_rect.height(), + dib->memory(), + reinterpret_cast<BITMAPINFO*>(&hdr)); + view_->InvalidateRect(&paint_rect.ToRECT()); + } + + CloseHandle(source_process_handle); + gpu_thread_->Send(new GpuHostMsg_PaintToBackingStore_ACK(routing_id_)); +} + +void GpuBackingStore::OnScrollBackingStore(int dx, int dy, + const gfx::Rect& clip_rect, + const gfx::Size& view_size) { + RECT damaged_rect, r = clip_rect.ToRECT(); + ScrollDC(hdc_, dx, dy, NULL, &r, NULL, &damaged_rect); + + // TODO(darin): this doesn't work if dx and dy are both non-zero! + DCHECK(dx == 0 || dy == 0); + + view_->DidScrollBackingStoreRect(dx, dy, clip_rect); +} diff --git a/chrome/gpu/gpu_backing_store.h b/chrome/gpu/gpu_backing_store.h new file mode 100644 index 0000000..bfe9941 --- /dev/null +++ b/chrome/gpu/gpu_backing_store.h @@ -0,0 +1,74 @@ +// 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. + +#ifndef CHROME_GPU_GPU_BACKING_STORE_H_ +#define CHROME_GPU_GPU_BACKING_STORE_H_ + +#include <windows.h> + +#include <vector> + +#include "app/gfx/native_widget_types.h" +#include "base/basictypes.h" +#include "base/gfx/size.h" +#include "chrome/common/transport_dib.h" +#include "ipc/ipc_channel.h" + +class GpuThread; +class GpuViewWin; + +namespace gfx { +class Rect; +class Size; +} + +class GpuBackingStore : public IPC::Channel::Listener { + public: + GpuBackingStore(GpuViewWin* view, + GpuThread* gpu_thread, + int32 routing_id, + const gfx::Size& size); + ~GpuBackingStore(); + + gfx::Size size() const { return size_; } + HDC hdc() const { return hdc_; } + + // IPC::Channel::Listener implementation. + virtual void OnMessageReceived(const IPC::Message& message); + virtual void OnChannelConnected(int32 peer_pid); + virtual void OnChannelError(); + + private: + // Message handlers. + void OnPaintToBackingStore(base::ProcessId source_process_id, + TransportDIB::Id id, + const gfx::Rect& bitmap_rect, + const std::vector<gfx::Rect>& copy_rects); + void OnScrollBackingStore(int dx, int dy, + const gfx::Rect& clip_rect, + const gfx::Size& view_size); + + GpuViewWin* view_; + + GpuThread* gpu_thread_; + int32 routing_id_; + + gfx::Size size_; + + // The backing store dc. + HDC hdc_; + + // Handle to the backing store dib. + HANDLE backing_store_dib_; + + // Handle to the original bitmap in the dc. + HANDLE original_bitmap_; + + // Number of bits per pixel of the screen. + int color_depth_; + + DISALLOW_COPY_AND_ASSIGN(GpuBackingStore); +}; + +#endif // CHROME_GPU_GPU_BACKING_STORE_H_ diff --git a/chrome/gpu/gpu_main.cc b/chrome/gpu/gpu_main.cc new file mode 100644 index 0000000..e60cffa --- /dev/null +++ b/chrome/gpu/gpu_main.cc @@ -0,0 +1,38 @@ +// 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 "base/message_loop.h" +#include "build/build_config.h" +#include "chrome/common/chrome_constants.h" +#include "chrome/common/main_function_params.h" +#include "chrome/gpu/gpu_process.h" +#include "chrome/gpu/gpu_thread.h" + +#if defined(OS_WIN) +#include "app/win_util.h" +#endif + +// Main function for starting the Gpu process. +int GpuMain(const MainFunctionParams& parameters) { +#if defined(USE_LINUX_BREAKPAD) + // Needs to be called after we have chrome::DIR_USER_DATA. + InitCrashReporter(); +#endif + + MessageLoop main_message_loop(MessageLoop::TYPE_UI); + std::wstring app_name = chrome::kBrowserAppName; + PlatformThread::SetName(WideToASCII(app_name + L"_GpuMain").c_str()); + +#if defined(OS_WIN) + win_util::ScopedCOMInitializer com_initializer; +#endif + + GpuProcess gpu_process; + gpu_process.set_main_thread(new GpuThread()); + + main_message_loop.Run(); + + return 0; +} + diff --git a/chrome/gpu/gpu_process.cc b/chrome/gpu/gpu_process.cc new file mode 100644 index 0000000..ada83c8 --- /dev/null +++ b/chrome/gpu/gpu_process.cc @@ -0,0 +1,11 @@ +// 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_process.h" + +GpuProcess::GpuProcess() { +} + +GpuProcess::~GpuProcess() { +} diff --git a/chrome/gpu/gpu_process.h b/chrome/gpu/gpu_process.h new file mode 100644 index 0000000..92c73a6 --- /dev/null +++ b/chrome/gpu/gpu_process.h @@ -0,0 +1,19 @@ +// 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. + +#ifndef CHROME_GPU_GPU_PROCESS_H_ +#define CHROME_GPU_GPU_PROCESS_H_ + +#include "chrome/common/child_process.h" + +class GpuProcess : public ChildProcess { + public: + GpuProcess(); + ~GpuProcess(); + + private: + DISALLOW_COPY_AND_ASSIGN(GpuProcess); +}; + +#endif // CHROME_GPU_GPU_PROCESS_H_ diff --git a/chrome/gpu/gpu_thread.cc b/chrome/gpu/gpu_thread.cc new file mode 100644 index 0000000..d143cbc --- /dev/null +++ b/chrome/gpu/gpu_thread.cc @@ -0,0 +1,38 @@ +// 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_thread.h" + +#include "build/build_config.h" +#include "chrome/common/gpu_messages.h" + +#if defined(OS_WIN) +#include "chrome/gpu/gpu_view_win.h" +#endif + +GpuThread::GpuThread() { +} + +GpuThread::~GpuThread() { +} + +void GpuThread::OnControlMessageReceived(const IPC::Message& msg) { + bool msg_is_ok = true; + IPC_BEGIN_MESSAGE_MAP_EX(GpuThread, msg, msg_is_ok) + IPC_MESSAGE_HANDLER(GpuMsg_NewRenderWidgetHostView, + OnNewRenderWidgetHostView) + IPC_END_MESSAGE_MAP_EX() +} + +void GpuThread::OnNewRenderWidgetHostView(gfx::NativeViewId parent_window, + int32 routing_id) { +#if defined(OS_WIN) + // The class' lifetime is controlled by the host, which will send a message to + // destroy the GpuRWHView when necessary. So we don't manage the lifetime + // of this object. + new GpuViewWin(this, parent_window, routing_id); +#else + NOTIMPLEMENTED(); +#endif +} diff --git a/chrome/gpu/gpu_thread.h b/chrome/gpu/gpu_thread.h new file mode 100644 index 0000000..3f25b00 --- /dev/null +++ b/chrome/gpu/gpu_thread.h @@ -0,0 +1,28 @@ +// 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. + +#ifndef CHROME_GPU_GPU_THREAD_H_ +#define CHROME_GPU_GPU_THREAD_H_ + +#include "app/gfx/native_widget_types.h" +#include "base/basictypes.h" +#include "chrome/common/child_thread.h" + +class GpuThread : public ChildThread { + public: + GpuThread(); + ~GpuThread(); + + private: + // ChildThread overrides. + virtual void OnControlMessageReceived(const IPC::Message& msg); + + // Message handlers. + void OnNewRenderWidgetHostView(gfx::NativeViewId parent_window, + int32 routing_id); + + DISALLOW_COPY_AND_ASSIGN(GpuThread); +}; + +#endif // CHROME_GPU_GPU_THREAD_H_ 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; +} diff --git a/chrome/gpu/gpu_view_win.h b/chrome/gpu/gpu_view_win.h new file mode 100644 index 0000000..30efeac8 --- /dev/null +++ b/chrome/gpu/gpu_view_win.h @@ -0,0 +1,102 @@ +// 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. + +#ifndef CHROME_GPU_GPU_VIEW_WIN_H_ +#define CHROME_GPU_GPU_VIEW_WIN_H_ + +#include <atlbase.h> +#include <atlapp.h> +#include <atlcrack.h> +#include <atlmisc.h> + +#include "app/gfx/native_widget_types.h" +#include "base/basictypes.h" +#include "base/scoped_ptr.h" +#include "ipc/ipc_channel.h" + +class GpuBackingStore; +class GpuThread; + +namespace gfx { +class Rect; +class Size; +} + +typedef CWinTraits<WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, 0> + GpuRenderWidgetHostViewWinTraits; + +class GpuViewWin + : public IPC::Channel::Listener, + public CWindowImpl<GpuViewWin, + CWindow, + GpuRenderWidgetHostViewWinTraits> { + public: + GpuViewWin(GpuThread* gpu_thread, + gfx::NativeViewId parent_window, + int32 routing_id); + ~GpuViewWin(); + + // IPC::Channel::Listener implementation. + virtual void OnMessageReceived(const IPC::Message& message); + virtual void OnChannelConnected(int32 peer_pid); + virtual void OnChannelError(); + + void DidScrollBackingStoreRect(int dx, int dy, const gfx::Rect& rect); + + BEGIN_MSG_MAP(GpuViewWin) + MSG_WM_PAINT(OnPaint) + MESSAGE_HANDLER(WM_MOUSEMOVE, OnMouseEvent) + MESSAGE_HANDLER(WM_MOUSELEAVE, OnMouseEvent) + MESSAGE_HANDLER(WM_LBUTTONDOWN, OnMouseEvent) + MESSAGE_HANDLER(WM_MBUTTONDOWN, OnMouseEvent) + MESSAGE_HANDLER(WM_RBUTTONDOWN, OnMouseEvent) + MESSAGE_HANDLER(WM_LBUTTONUP, OnMouseEvent) + MESSAGE_HANDLER(WM_MBUTTONUP, OnMouseEvent) + MESSAGE_HANDLER(WM_RBUTTONUP, OnMouseEvent) + MESSAGE_HANDLER(WM_LBUTTONDBLCLK, OnMouseEvent) + MESSAGE_HANDLER(WM_MBUTTONDBLCLK, OnMouseEvent) + MESSAGE_HANDLER(WM_RBUTTONDBLCLK, OnMouseEvent) + MESSAGE_HANDLER(WM_SYSKEYDOWN, OnKeyEvent) + MESSAGE_HANDLER(WM_SYSKEYUP, OnKeyEvent) + MESSAGE_HANDLER(WM_KEYDOWN, OnKeyEvent) + MESSAGE_HANDLER(WM_KEYUP, OnKeyEvent) + MESSAGE_HANDLER(WM_MOUSEWHEEL, OnWheelEvent) + MESSAGE_HANDLER(WM_MOUSEHWHEEL, OnWheelEvent) + MESSAGE_HANDLER(WM_HSCROLL, OnWheelEvent) + MESSAGE_HANDLER(WM_VSCROLL, OnWheelEvent) + MESSAGE_HANDLER(WM_CHAR, OnKeyEvent) + MESSAGE_HANDLER(WM_SYSCHAR, OnKeyEvent) + MESSAGE_HANDLER(WM_IME_CHAR, OnKeyEvent) + END_MSG_MAP() + + private: + // IPC message handlers. + void OnNewBackingStore(int32 routing_id, const gfx::Size& size); + + // Windows message handlers. + void OnPaint(HDC unused_dc); + LRESULT OnMouseEvent(UINT message, + WPARAM wparam, + LPARAM lparam, + BOOL& handled); + LRESULT OnKeyEvent(UINT message, + WPARAM wparam, + LPARAM lparam, + BOOL& handled); + LRESULT OnWheelEvent(UINT message, + WPARAM wparam, + LPARAM lparam, + BOOL& handled); + + GpuThread* gpu_thread_; + int32 routing_id_; + + HWND parent_window_; + + scoped_ptr<GpuBackingStore> backing_store_; + + DISALLOW_COPY_AND_ASSIGN(GpuViewWin); +}; + +#endif // CHROME_GPU_GPU_VIEW_WIN_H_ |