Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(522)

Side by Side Diff: chrome/browser/renderer_host/render_widget_host_view_win.cc

Issue 4815001: Use inner HWND for accelerated rendering on windows (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 10 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/renderer_host/render_widget_host_view_win.h" 5 #include "chrome/browser/renderer_host/render_widget_host_view_win.h"
6 6
7 #include "app/l10n_util.h" 7 #include "app/l10n_util.h"
8 #include "app/l10n_util_win.h" 8 #include "app/l10n_util_win.h"
9 #include "app/resource_bundle.h" 9 #include "app/resource_bundle.h"
10 #include "app/win/scoped_prop.h" 10 #include "app/win/scoped_prop.h"
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after
272 RenderWidgetHostView* RenderWidgetHostView::CreateViewForWidget( 272 RenderWidgetHostView* RenderWidgetHostView::CreateViewForWidget(
273 RenderWidgetHost* widget) { 273 RenderWidgetHost* widget) {
274 return new RenderWidgetHostViewWin(widget); 274 return new RenderWidgetHostViewWin(widget);
275 } 275 }
276 276
277 /////////////////////////////////////////////////////////////////////////////// 277 ///////////////////////////////////////////////////////////////////////////////
278 // RenderWidgetHostViewWin, public: 278 // RenderWidgetHostViewWin, public:
279 279
280 RenderWidgetHostViewWin::RenderWidgetHostViewWin(RenderWidgetHost* widget) 280 RenderWidgetHostViewWin::RenderWidgetHostViewWin(RenderWidgetHost* widget)
281 : render_widget_host_(widget), 281 : render_widget_host_(widget),
282 compositor_host_window_(NULL),
282 track_mouse_leave_(false), 283 track_mouse_leave_(false),
283 ime_notification_(false), 284 ime_notification_(false),
284 capture_enter_key_(false), 285 capture_enter_key_(false),
285 is_hidden_(false), 286 is_hidden_(false),
286 about_to_validate_and_paint_(false), 287 about_to_validate_and_paint_(false),
287 close_on_deactivate_(false), 288 close_on_deactivate_(false),
288 being_destroyed_(false), 289 being_destroyed_(false),
289 tooltip_hwnd_(NULL), 290 tooltip_hwnd_(NULL),
290 tooltip_showing_(false), 291 tooltip_showing_(false),
291 shutdown_factory_(this), 292 shutdown_factory_(this),
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
372 373
373 void RenderWidgetHostViewWin::SetSize(const gfx::Size& size) { 374 void RenderWidgetHostViewWin::SetSize(const gfx::Size& size) {
374 if (is_hidden_) 375 if (is_hidden_)
375 return; 376 return;
376 377
377 // No SWP_NOREDRAW as autofill popups can resize and the underneath window 378 // No SWP_NOREDRAW as autofill popups can resize and the underneath window
378 // should redraw in that case. 379 // should redraw in that case.
379 UINT swp_flags = SWP_NOSENDCHANGING | SWP_NOOWNERZORDER | SWP_NOCOPYBITS | 380 UINT swp_flags = SWP_NOSENDCHANGING | SWP_NOOWNERZORDER | SWP_NOCOPYBITS |
380 SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_DEFERERASE; 381 SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_DEFERERASE;
381 SetWindowPos(NULL, 0, 0, size.width(), size.height(), swp_flags); 382 SetWindowPos(NULL, 0, 0, size.width(), size.height(), swp_flags);
383 if (compositor_host_window_) {
384 ::SetWindowPos(compositor_host_window_, NULL, 0, 0, size
385 .width(), size.height(),
jam 2010/11/12 18:08:00 nit: size.width() should be on the same line
nduca 2010/11/12 19:45:32 Done.
386 SWP_NOSENDCHANGING | SWP_NOCOPYBITS | SWP_NOZORDER | SWP_NOACTIVATE);
387 }
382 render_widget_host_->WasResized(); 388 render_widget_host_->WasResized();
383 EnsureTooltip(); 389 EnsureTooltip();
384 } 390 }
385 391
386 gfx::NativeView RenderWidgetHostViewWin::GetNativeView() { 392 gfx::NativeView RenderWidgetHostViewWin::GetNativeView() {
387 return m_hWnd; 393 return m_hWnd;
388 } 394 }
389 395
390 void RenderWidgetHostViewWin::MovePluginWindows( 396 void RenderWidgetHostViewWin::MovePluginWindows(
391 const std::vector<WebPluginGeometry>& plugin_window_moves) { 397 const std::vector<WebPluginGeometry>& plugin_window_moves) {
(...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after
733 Redraw(); 739 Redraw();
734 } 740 }
735 741
736 void RenderWidgetHostViewWin::RenderViewGone() { 742 void RenderWidgetHostViewWin::RenderViewGone() {
737 // TODO(darin): keep this around, and draw sad-tab into it. 743 // TODO(darin): keep this around, and draw sad-tab into it.
738 UpdateCursorIfOverSelf(); 744 UpdateCursorIfOverSelf();
739 being_destroyed_ = true; 745 being_destroyed_ = true;
740 DestroyWindow(); 746 DestroyWindow();
741 } 747 }
742 748
749 static BOOL CALLBACK AddChildWindowToVector(HWND hwnd, LPARAM lparam) {
750 std::vector<HWND>* vector = reinterpret_cast<std::vector<HWND>*>(lparam);
751 vector->push_back(hwnd);
752 return TRUE;
753 }
754
755 void RenderWidgetHostViewWin::WillWmDestroy() {
756 std::vector<HWND> all_child_windows;
757 if (compositor_host_window_) {
jam 2010/11/12 18:08:00 nit: can you just early return if compositor_host_
nduca 2010/11/12 19:45:32 Done.
758 ::EnumChildWindows(compositor_host_window_, AddChildWindowToVector,
759 reinterpret_cast<LPARAM>(&all_child_windows));
760 if (all_child_windows.size()) {
761 DCHECK(all_child_windows.size() == 1);
762 ::ShowWindow(all_child_windows[0], SW_HIDE);
763 ::SetParent(all_child_windows[0], NULL);
764 }
765 }
766 BOOL b;
jam 2010/11/12 18:08:00 what's the point of b, it's not used?
nduca 2010/11/12 19:45:32 Oops. Leftover debugging. I fail. ;) On 2010/11/12
767 if (compositor_host_window_ && all_child_windows.size() == 1) {
768 RECT rect;
769 b = ::GetWindowRect(all_child_windows[0], &rect);
770 }
771 }
772
743 void RenderWidgetHostViewWin::WillDestroyRenderWidget(RenderWidgetHost* rwh) { 773 void RenderWidgetHostViewWin::WillDestroyRenderWidget(RenderWidgetHost* rwh) {
744 if (rwh == render_widget_host_) 774 if (rwh == render_widget_host_)
745 render_widget_host_ = NULL; 775 render_widget_host_ = NULL;
746 } 776 }
747 777
778
jam 2010/11/12 18:08:00 nit: extra line
nduca 2010/11/12 19:45:32 Done.
748 void RenderWidgetHostViewWin::Destroy() { 779 void RenderWidgetHostViewWin::Destroy() {
749 // We've been told to destroy. 780 // We've been told to destroy.
750 // By clearing close_on_deactivate_, we prevent further deactivations 781 // By clearing close_on_deactivate_, we prevent further deactivations
751 // (caused by windows messages resulting from the DestroyWindow) from 782 // (caused by windows messages resulting from the DestroyWindow) from
752 // triggering further destructions. The deletion of this is handled by 783 // triggering further destructions. The deletion of this is handled by
753 // OnFinalMessage(); 784 // OnFinalMessage();
754 close_on_deactivate_ = false; 785 close_on_deactivate_ = false;
755 being_destroyed_ = true; 786 being_destroyed_ = true;
787 WillWmDestroy();
756 DestroyWindow(); 788 DestroyWindow();
757 } 789 }
758 790
759 void RenderWidgetHostViewWin::SetTooltipText(const std::wstring& tooltip_text) { 791 void RenderWidgetHostViewWin::SetTooltipText(const std::wstring& tooltip_text) {
760 // Clamp the tooltip length to kMaxTooltipLength so that we don't 792 // Clamp the tooltip length to kMaxTooltipLength so that we don't
761 // accidentally DOS the user with a mega tooltip (since Windows doesn't seem 793 // accidentally DOS the user with a mega tooltip (since Windows doesn't seem
762 // to do this itself). 794 // to do this itself).
763 const std::wstring& new_tooltip_text = 795 const std::wstring& new_tooltip_text =
764 l10n_util::TruncateString(tooltip_text, kMaxTooltipLength); 796 l10n_util::TruncateString(tooltip_text, kMaxTooltipLength);
765 797
(...skipping 731 matching lines...) Expand 10 before | Expand all | Expand 10 after
1497 if (!render_widget_host_ || 1529 if (!render_widget_host_ ||
1498 render_process_host != render_widget_host_->process()) 1530 render_process_host != render_widget_host_->process())
1499 return; 1531 return;
1500 1532
1501 // If it was our RenderProcessHost that posted the notification, 1533 // If it was our RenderProcessHost that posted the notification,
1502 // clear the BrowserAccessibilityManager, because the renderer is 1534 // clear the BrowserAccessibilityManager, because the renderer is
1503 // dead and any accessibility information we have is now stale. 1535 // dead and any accessibility information we have is now stale.
1504 browser_accessibility_manager_.reset(NULL); 1536 browser_accessibility_manager_.reset(NULL);
1505 } 1537 }
1506 1538
1539 // Looks through the children windows of the CompositorHostWindow. If the
1540 // compositor child window is found, its size is checked against the host
1541 // window's size. If the child is smaller in either dimensions, we fill
1542 // the host window with white to avoid unseemly cracks.
1543 static void PaintCompositorHostWindow(HWND hWnd) {
1544 PAINTSTRUCT paint;
1545 BeginPaint(hWnd, &paint);
1546
1547 std::vector<HWND> child_windows;
1548 EnumChildWindows(hWnd, AddChildWindowToVector,
1549 reinterpret_cast<LPARAM>(&child_windows));
1550
1551 if (child_windows.size()) {
1552 HWND child = child_windows[1];
1553
1554 RECT host_rect, child_rect;
1555 GetClientRect(hWnd, &host_rect);
1556 if (GetClientRect(child, &child_rect)) {
1557 if (child_rect.right < host_rect.right ||
1558 child_rect.bottom != host_rect.bottom) {
1559 FillRect(paint.hdc, &host_rect,
1560 static_cast<HBRUSH>(GetStockObject(WHITE_BRUSH)));
1561 }
1562 }
1563 }
1564 EndPaint(hWnd, &paint);
1565 }
1566
1567 // WndProc for the compositor host window. We use this instead of Default so
1568 // we can drop WM_PAINT and WM_ERASEBKGD messages on the floor.
1569 static LRESULT CALLBACK CompositorHostWindowProc(HWND hWnd, UINT message,
1570 WPARAM wParam, LPARAM lParam) {
1571 switch (message) {
1572 case WM_ERASEBKGND:
1573 return 0;
1574 case WM_DESTROY:
1575 return 0;
1576 case WM_PAINT:
1577 PaintCompositorHostWindow(hWnd);
1578 return 0;
1579 default:
1580 return DefWindowProc(hWnd, message, wParam, lParam);
1581 }
1582 }
1583
1584 // Creates a HWND within the RenderWidgetHostView that will serve as a host
1585 // for a HWND that the GPU process will create. The host window is used
1586 // to Z-position the GPU's window relative to other plugin windows.
1587 gfx::PluginWindowHandle RenderWidgetHostViewWin::CreateCompositorHostWindow() {
1588 DCHECK(!compositor_host_window_);
1589 static ATOM window_class = 0;
1590 if (!window_class) {
1591 WNDCLASSEX wcex;
1592 wcex.cbSize = sizeof(WNDCLASSEX);
1593 wcex.style = 0;
1594 wcex.lpfnWndProc = CompositorHostWindowProc;
1595 wcex.cbClsExtra = 0;
1596 wcex.cbWndExtra = 0;
1597 wcex.hInstance = GetModuleHandle(NULL);
1598 wcex.hIcon = 0;
1599 wcex.hCursor = 0;
1600 wcex.hbrBackground = NULL;
1601 wcex.lpszMenuName = 0;
1602 wcex.lpszClassName = L"CompositorHostWindowClass";
1603 wcex.hIconSm = 0;
1604 window_class = RegisterClassEx(&wcex);
1605 DCHECK(window_class);
1606 }
1607
1608 compositor_host_window_ = CreateWindowEx(
1609 WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR,
1610 MAKEINTATOM(window_class), 0,
1611 WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_DISABLED,
1612 0, 0, 0, 0, m_hWnd, 0, GetModuleHandle(NULL), 0);
1613 DCHECK(compositor_host_window_);
1614
1615 // We need to not just "WM_SHOW" the new indow, but reparent it
1616 // below any existing plugin existing windows.
1617 ShowCompositorHostWindow(true);
1618
1619 return static_cast<gfx::PluginWindowHandle>(compositor_host_window_);
1620 }
1621
1622 void RenderWidgetHostViewWin::ShowCompositorHostWindow(bool show) {
1623 // When we first create the compositor, we will get a show request from
1624 // the renderer before we have gotten the create request from the GPU. In this
1625 // case, simply ignore the show request.
1626 if (compositor_host_window_ == NULL)
1627 return;
1628
1629 if (show) {
1630 UINT flags = SWP_NOSENDCHANGING | SWP_NOCOPYBITS | SWP_NOZORDER |
1631 SWP_NOACTIVATE | SWP_DEFERERASE | SWP_SHOWWINDOW;
1632 gfx::Rect rect = GetViewBounds();
1633 ::SetWindowPos(compositor_host_window_, NULL, 0, 0,
1634 rect.width(), rect.height(),
1635 flags);
1636
1637 // Get all the child windows of this view, including the compositor window.
1638 std::vector<HWND> all_child_windows;
1639 ::EnumChildWindows(m_hWnd, AddChildWindowToVector,
1640 reinterpret_cast<LPARAM>(&all_child_windows));
1641
1642 // Build a list of just the plugin window handles
1643 std::vector<HWND> plugin_windows;
1644 bool compositor_host_window_found = false;
1645 for (size_t i = 0; i < all_child_windows.size(); ++i) {
1646 if (all_child_windows[i] != compositor_host_window_)
1647 plugin_windows.push_back(all_child_windows[i]);
1648 else
1649 compositor_host_window_found = true;
1650 }
1651 DCHECK(compositor_host_window_found);
1652
1653 // Set all the plugin windows to be "after" the compositor window.
1654 // When the compositor window is created, gets placed above plugins.
1655 for (size_t i = 0; i < plugin_windows.size(); ++i) {
1656 HWND next;
1657 if (i + 1 < plugin_windows.size())
1658 next = plugin_windows[i+1];
1659 else
1660 next = compositor_host_window_;
1661 ::SetWindowPos(plugin_windows[i], next, 0, 0, 0, 0,
1662 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
1663 }
1664 } else {
1665 ::ShowWindow(compositor_host_window_, SW_HIDE);
1666 }
1667 }
1668
1507 void RenderWidgetHostViewWin::SetAccessibilityFocus(int acc_obj_id) { 1669 void RenderWidgetHostViewWin::SetAccessibilityFocus(int acc_obj_id) {
1508 if (!browser_accessibility_manager_.get() || 1670 if (!browser_accessibility_manager_.get() ||
1509 !render_widget_host_ || 1671 !render_widget_host_ ||
1510 !render_widget_host_->process() || 1672 !render_widget_host_->process() ||
1511 !render_widget_host_->process()->HasConnection()) { 1673 !render_widget_host_->process()->HasConnection()) {
1512 return; 1674 return;
1513 } 1675 }
1514 1676
1515 render_widget_host_->SetAccessibilityFocus(acc_obj_id); 1677 render_widget_host_->SetAccessibilityFocus(acc_obj_id);
1516 } 1678 }
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
1686 RenderWidgetHostView::GetRenderWidgetHostViewFromNativeView( 1848 RenderWidgetHostView::GetRenderWidgetHostViewFromNativeView(
1687 gfx::NativeView native_view) { 1849 gfx::NativeView native_view) {
1688 if (::IsWindow(native_view)) { 1850 if (::IsWindow(native_view)) {
1689 HANDLE raw_render_host_view = ::GetProp(native_view, 1851 HANDLE raw_render_host_view = ::GetProp(native_view,
1690 kRenderWidgetHostViewKey); 1852 kRenderWidgetHostViewKey);
1691 if (raw_render_host_view) 1853 if (raw_render_host_view)
1692 return reinterpret_cast<RenderWidgetHostView*>(raw_render_host_view); 1854 return reinterpret_cast<RenderWidgetHostView*>(raw_render_host_view);
1693 } 1855 }
1694 return NULL; 1856 return NULL;
1695 } 1857 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698