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

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_,
385 NULL,
386 0, 0,
387 size.width(), size.height(),
388 SWP_NOSENDCHANGING | SWP_NOCOPYBITS | SWP_NOZORDER | SWP_NOACTIVATE);
389 }
382 render_widget_host_->WasResized(); 390 render_widget_host_->WasResized();
383 EnsureTooltip(); 391 EnsureTooltip();
384 } 392 }
385 393
386 gfx::NativeView RenderWidgetHostViewWin::GetNativeView() { 394 gfx::NativeView RenderWidgetHostViewWin::GetNativeView() {
387 return m_hWnd; 395 return m_hWnd;
388 } 396 }
389 397
390 void RenderWidgetHostViewWin::MovePluginWindows( 398 void RenderWidgetHostViewWin::MovePluginWindows(
391 const std::vector<WebPluginGeometry>& plugin_window_moves) { 399 const std::vector<WebPluginGeometry>& plugin_window_moves) {
(...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after
733 Redraw(); 741 Redraw();
734 } 742 }
735 743
736 void RenderWidgetHostViewWin::RenderViewGone() { 744 void RenderWidgetHostViewWin::RenderViewGone() {
737 // TODO(darin): keep this around, and draw sad-tab into it. 745 // TODO(darin): keep this around, and draw sad-tab into it.
738 UpdateCursorIfOverSelf(); 746 UpdateCursorIfOverSelf();
739 being_destroyed_ = true; 747 being_destroyed_ = true;
740 DestroyWindow(); 748 DestroyWindow();
741 } 749 }
742 750
751 static BOOL CALLBACK AddChildWindowToVector(HWND hwnd, LPARAM lparam) {
752 std::vector<HWND>* vector = reinterpret_cast<std::vector<HWND>*>(lparam);
753 vector->push_back(hwnd);
754 return TRUE;
755 }
756
757 void RenderWidgetHostViewWin::WillWmDestroy() {
758 if (!compositor_host_window_)
759 return;
760
761 std::vector<HWND> all_child_windows;
762 ::EnumChildWindows(compositor_host_window_, AddChildWindowToVector,
763 reinterpret_cast<LPARAM>(&all_child_windows));
764 if (all_child_windows.size()) {
765 DCHECK(all_child_windows.size() == 1);
766 ::ShowWindow(all_child_windows[0], SW_HIDE);
767 ::SetParent(all_child_windows[0], NULL);
768 }
769 }
770
743 void RenderWidgetHostViewWin::WillDestroyRenderWidget(RenderWidgetHost* rwh) { 771 void RenderWidgetHostViewWin::WillDestroyRenderWidget(RenderWidgetHost* rwh) {
744 if (rwh == render_widget_host_) 772 if (rwh == render_widget_host_)
745 render_widget_host_ = NULL; 773 render_widget_host_ = NULL;
746 } 774 }
747 775
748 void RenderWidgetHostViewWin::Destroy() { 776 void RenderWidgetHostViewWin::Destroy() {
749 // We've been told to destroy. 777 // We've been told to destroy.
750 // By clearing close_on_deactivate_, we prevent further deactivations 778 // By clearing close_on_deactivate_, we prevent further deactivations
751 // (caused by windows messages resulting from the DestroyWindow) from 779 // (caused by windows messages resulting from the DestroyWindow) from
752 // triggering further destructions. The deletion of this is handled by 780 // triggering further destructions. The deletion of this is handled by
753 // OnFinalMessage(); 781 // OnFinalMessage();
754 close_on_deactivate_ = false; 782 close_on_deactivate_ = false;
755 being_destroyed_ = true; 783 being_destroyed_ = true;
784 WillWmDestroy();
756 DestroyWindow(); 785 DestroyWindow();
757 } 786 }
758 787
759 void RenderWidgetHostViewWin::SetTooltipText(const std::wstring& tooltip_text) { 788 void RenderWidgetHostViewWin::SetTooltipText(const std::wstring& tooltip_text) {
760 // Clamp the tooltip length to kMaxTooltipLength so that we don't 789 // 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 790 // accidentally DOS the user with a mega tooltip (since Windows doesn't seem
762 // to do this itself). 791 // to do this itself).
763 const std::wstring& new_tooltip_text = 792 const std::wstring& new_tooltip_text =
764 l10n_util::TruncateString(tooltip_text, kMaxTooltipLength); 793 l10n_util::TruncateString(tooltip_text, kMaxTooltipLength);
765 794
(...skipping 731 matching lines...) Expand 10 before | Expand all | Expand 10 after
1497 if (!render_widget_host_ || 1526 if (!render_widget_host_ ||
1498 render_process_host != render_widget_host_->process()) 1527 render_process_host != render_widget_host_->process())
1499 return; 1528 return;
1500 1529
1501 // If it was our RenderProcessHost that posted the notification, 1530 // If it was our RenderProcessHost that posted the notification,
1502 // clear the BrowserAccessibilityManager, because the renderer is 1531 // clear the BrowserAccessibilityManager, because the renderer is
1503 // dead and any accessibility information we have is now stale. 1532 // dead and any accessibility information we have is now stale.
1504 browser_accessibility_manager_.reset(NULL); 1533 browser_accessibility_manager_.reset(NULL);
1505 } 1534 }
1506 1535
1536 // Looks through the children windows of the CompositorHostWindow. If the
1537 // compositor child window is found, its size is checked against the host
1538 // window's size. If the child is smaller in either dimensions, we fill
1539 // the host window with white to avoid unseemly cracks.
1540 static void PaintCompositorHostWindow(HWND hWnd) {
1541 PAINTSTRUCT paint;
1542 BeginPaint(hWnd, &paint);
1543
1544 std::vector<HWND> child_windows;
1545 EnumChildWindows(hWnd, AddChildWindowToVector,
1546 reinterpret_cast<LPARAM>(&child_windows));
1547
1548 if (child_windows.size()) {
1549 HWND child = child_windows[1];
1550
1551 RECT host_rect, child_rect;
1552 GetClientRect(hWnd, &host_rect);
1553 if (GetClientRect(child, &child_rect)) {
1554 if (child_rect.right < host_rect.right ||
1555 child_rect.bottom != host_rect.bottom) {
1556 FillRect(paint.hdc, &host_rect,
1557 static_cast<HBRUSH>(GetStockObject(WHITE_BRUSH)));
1558 }
1559 }
1560 }
1561 EndPaint(hWnd, &paint);
1562 }
1563
1564 // WndProc for the compositor host window. We use this instead of Default so
1565 // we can drop WM_PAINT and WM_ERASEBKGD messages on the floor.
1566 static LRESULT CALLBACK CompositorHostWindowProc(HWND hWnd, UINT message,
1567 WPARAM wParam, LPARAM lParam) {
1568 switch (message) {
1569 case WM_ERASEBKGND:
1570 return 0;
1571 case WM_DESTROY:
1572 return 0;
1573 case WM_PAINT:
1574 PaintCompositorHostWindow(hWnd);
1575 return 0;
1576 default:
1577 return DefWindowProc(hWnd, message, wParam, lParam);
1578 }
1579 }
1580
1581 // Creates a HWND within the RenderWidgetHostView that will serve as a host
1582 // for a HWND that the GPU process will create. The host window is used
1583 // to Z-position the GPU's window relative to other plugin windows.
1584 gfx::PluginWindowHandle RenderWidgetHostViewWin::CreateCompositorHostWindow() {
1585 DCHECK(!compositor_host_window_);
1586 static ATOM window_class = 0;
1587 if (!window_class) {
1588 WNDCLASSEX wcex;
1589 wcex.cbSize = sizeof(WNDCLASSEX);
1590 wcex.style = 0;
1591 wcex.lpfnWndProc = CompositorHostWindowProc;
1592 wcex.cbClsExtra = 0;
1593 wcex.cbWndExtra = 0;
1594 wcex.hInstance = GetModuleHandle(NULL);
1595 wcex.hIcon = 0;
1596 wcex.hCursor = 0;
1597 wcex.hbrBackground = NULL;
1598 wcex.lpszMenuName = 0;
1599 wcex.lpszClassName = L"CompositorHostWindowClass";
1600 wcex.hIconSm = 0;
1601 window_class = RegisterClassEx(&wcex);
1602 DCHECK(window_class);
1603 }
1604
1605 compositor_host_window_ = CreateWindowEx(
1606 WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR,
1607 MAKEINTATOM(window_class), 0,
1608 WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_DISABLED,
1609 0, 0, 0, 0, m_hWnd, 0, GetModuleHandle(NULL), 0);
1610 DCHECK(compositor_host_window_);
1611
1612 // We need to not just "WM_SHOW" the new indow, but reparent it
1613 // below any existing plugin existing windows.
1614 ShowCompositorHostWindow(true);
1615
1616 return static_cast<gfx::PluginWindowHandle>(compositor_host_window_);
1617 }
1618
1619 void RenderWidgetHostViewWin::ShowCompositorHostWindow(bool show) {
1620 // When we first create the compositor, we will get a show request from
1621 // the renderer before we have gotten the create request from the GPU. In this
1622 // case, simply ignore the show request.
1623 if (compositor_host_window_ == NULL)
1624 return;
1625
1626 if (show) {
1627 UINT flags = SWP_NOSENDCHANGING | SWP_NOCOPYBITS | SWP_NOZORDER |
1628 SWP_NOACTIVATE | SWP_DEFERERASE | SWP_SHOWWINDOW;
1629 gfx::Rect rect = GetViewBounds();
1630 ::SetWindowPos(compositor_host_window_, NULL, 0, 0,
1631 rect.width(), rect.height(),
1632 flags);
1633
1634 // Get all the child windows of this view, including the compositor window.
1635 std::vector<HWND> all_child_windows;
1636 ::EnumChildWindows(m_hWnd, AddChildWindowToVector,
1637 reinterpret_cast<LPARAM>(&all_child_windows));
1638
1639 // Build a list of just the plugin window handles
1640 std::vector<HWND> plugin_windows;
1641 bool compositor_host_window_found = false;
1642 for (size_t i = 0; i < all_child_windows.size(); ++i) {
1643 if (all_child_windows[i] != compositor_host_window_)
1644 plugin_windows.push_back(all_child_windows[i]);
1645 else
1646 compositor_host_window_found = true;
1647 }
1648 DCHECK(compositor_host_window_found);
1649
1650 // Set all the plugin windows to be "after" the compositor window.
1651 // When the compositor window is created, gets placed above plugins.
1652 for (size_t i = 0; i < plugin_windows.size(); ++i) {
1653 HWND next;
1654 if (i + 1 < plugin_windows.size())
1655 next = plugin_windows[i+1];
1656 else
1657 next = compositor_host_window_;
1658 ::SetWindowPos(plugin_windows[i], next, 0, 0, 0, 0,
1659 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
1660 }
1661 } else {
1662 ::ShowWindow(compositor_host_window_, SW_HIDE);
1663 }
1664 }
1665
1507 void RenderWidgetHostViewWin::SetAccessibilityFocus(int acc_obj_id) { 1666 void RenderWidgetHostViewWin::SetAccessibilityFocus(int acc_obj_id) {
1508 if (!browser_accessibility_manager_.get() || 1667 if (!browser_accessibility_manager_.get() ||
1509 !render_widget_host_ || 1668 !render_widget_host_ ||
1510 !render_widget_host_->process() || 1669 !render_widget_host_->process() ||
1511 !render_widget_host_->process()->HasConnection()) { 1670 !render_widget_host_->process()->HasConnection()) {
1512 return; 1671 return;
1513 } 1672 }
1514 1673
1515 render_widget_host_->SetAccessibilityFocus(acc_obj_id); 1674 render_widget_host_->SetAccessibilityFocus(acc_obj_id);
1516 } 1675 }
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
1686 RenderWidgetHostView::GetRenderWidgetHostViewFromNativeView( 1845 RenderWidgetHostView::GetRenderWidgetHostViewFromNativeView(
1687 gfx::NativeView native_view) { 1846 gfx::NativeView native_view) {
1688 if (::IsWindow(native_view)) { 1847 if (::IsWindow(native_view)) {
1689 HANDLE raw_render_host_view = ::GetProp(native_view, 1848 HANDLE raw_render_host_view = ::GetProp(native_view,
1690 kRenderWidgetHostViewKey); 1849 kRenderWidgetHostViewKey);
1691 if (raw_render_host_view) 1850 if (raw_render_host_view)
1692 return reinterpret_cast<RenderWidgetHostView*>(raw_render_host_view); 1851 return reinterpret_cast<RenderWidgetHostView*>(raw_render_host_view);
1693 } 1852 }
1694 return NULL; 1853 return NULL;
1695 } 1854 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698