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

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(),
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_) {
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;
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
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 for (size_t i = 0;i < child_windows.size(); ++i) {
1552 HWND child = child_windows[i];
1553 if (!IsWindow(child))
1554 continue;
1555 if (GetProp(child, L"CompositorWindowGpuCommandBufferStub")) {
1556
1557 RECT host_rect, child_rect;
1558 GetClientRect(hWnd, &host_rect);
1559 if (!GetClientRect(child, &child_rect))
1560 continue;
1561
1562 if (child_rect.right < host_rect.right ||
1563 child_rect.bottom != host_rect.bottom) {
1564 FillRect(paint.hdc, &host_rect,
1565 static_cast<HBRUSH>(GetStockObject(WHITE_BRUSH)));
1566 }
1567 }
1568 }
1569 EndPaint(hWnd, &paint);
1570 }
1571
1572 // WndProc for the compositor host window. We use this instead of Default so
1573 // we can drop WM_PAINT and WM_ERASEBKGD messages on the floor.
1574 static LRESULT CALLBACK CompositorHostWindowProc(HWND hWnd, UINT message,
1575 WPARAM wParam, LPARAM lParam) {
1576 switch (message) {
1577 case WM_ERASEBKGND:
1578 return 0;
1579 case WM_DESTROY:
1580 return 0;
1581 case WM_PAINT:
1582 PaintCompositorHostWindow(hWnd);
1583 return 0;
1584 default:
1585 return DefWindowProc(hWnd, message, wParam, lParam);
1586 }
1587 }
1588
1589 // Creates a HWND within the RenderWidgetHostView that will serve as a host
1590 // for a HWND that the GPU process will create. The host window is used
1591 // to Z-position the GPU's window relative to other plugin windows.
1592 gfx::PluginWindowHandle RenderWidgetHostViewWin::CreateCompositorHostWindow() {
1593 DCHECK(!compositor_host_window_);
1594 static ATOM window_class = 0;
1595 if (!window_class) {
1596 WNDCLASSEX wcex;
1597 wcex.cbSize = sizeof(WNDCLASSEX);
1598 wcex.style = 0;
1599 wcex.lpfnWndProc = CompositorHostWindowProc;
1600 wcex.cbClsExtra = 0;
1601 wcex.cbWndExtra = 0;
1602 wcex.hInstance = GetModuleHandle(NULL);
1603 wcex.hIcon = 0;
1604 wcex.hCursor = 0;
1605 wcex.hbrBackground = NULL;
1606 wcex.lpszMenuName = 0;
1607 wcex.lpszClassName = L"CompositorHostWindowClass";
1608 wcex.hIconSm = 0;
1609 window_class = RegisterClassEx(&wcex);
1610 DCHECK(window_class);
1611 }
1612
1613 compositor_host_window_ = CreateWindowEx(
1614 WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR,
1615 MAKEINTATOM(window_class), 0,
1616 WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_DISABLED,
1617 0, 0, 0, 0, m_hWnd, 0, GetModuleHandle(NULL), 0);
1618 DCHECK(compositor_host_window_);
1619
1620 // We need to not just "WM_SHOW" the new indow, but reparent it
1621 // below any existing plugin existing windows.
1622 ShowCompositorHostWindow(true);
1623
1624 return static_cast<gfx::PluginWindowHandle>(compositor_host_window_);
1625 }
1626
1627 void RenderWidgetHostViewWin::ShowCompositorHostWindow(bool show) {
1628 // When we first create the compositor, we will get a show request from
1629 // the renderer before we have gotten the create request from the GPU. In this
1630 // case, simply ignore the show request.
1631 if (compositor_host_window_ == NULL)
1632 return;
1633
1634 if (show) {
1635 UINT flags = SWP_NOSENDCHANGING | SWP_NOCOPYBITS | SWP_NOZORDER |
1636 SWP_NOACTIVATE | SWP_DEFERERASE | SWP_SHOWWINDOW;
1637 gfx::Rect rect = GetViewBounds();
1638 ::SetWindowPos(compositor_host_window_, NULL, 0, 0,
1639 rect.width(), rect.height(),
1640 flags);
1641
1642 // Get all the child windows of this view, including the compositor window.
1643 std::vector<HWND> all_child_windows;
1644 ::EnumChildWindows(m_hWnd, AddChildWindowToVector,
1645 reinterpret_cast<LPARAM>(&all_child_windows));
1646
1647 // Build a list of just the plugin window handles
1648 std::vector<HWND> plugin_windows;
1649 bool compositor_host_window_found = false;
1650 for (size_t i = 0; i < all_child_windows.size(); ++i) {
1651 if (all_child_windows[i] != compositor_host_window_)
1652 plugin_windows.push_back(all_child_windows[i]);
1653 else
1654 compositor_host_window_found = true;
1655 }
1656 DCHECK(compositor_host_window_found);
1657
1658 // Set all the plugin windows to be "after" the compositor window.
1659 // When the compositor window is created, gets placed above plugins.
1660 for (size_t i = 0; i < plugin_windows.size(); ++i) {
1661 HWND next;
1662 if (i + 1 < plugin_windows.size())
1663 next = plugin_windows[i+1];
1664 else
1665 next = compositor_host_window_;
1666 ::SetWindowPos(plugin_windows[i], next, 0, 0, 0, 0,
1667 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
1668 }
1669 } else {
1670 ::ShowWindow(compositor_host_window_, SW_HIDE);
1671 }
1672 }
1673
1507 void RenderWidgetHostViewWin::SetAccessibilityFocus(int acc_obj_id) { 1674 void RenderWidgetHostViewWin::SetAccessibilityFocus(int acc_obj_id) {
1508 if (!browser_accessibility_manager_.get() || 1675 if (!browser_accessibility_manager_.get() ||
1509 !render_widget_host_ || 1676 !render_widget_host_ ||
1510 !render_widget_host_->process() || 1677 !render_widget_host_->process() ||
1511 !render_widget_host_->process()->HasConnection()) { 1678 !render_widget_host_->process()->HasConnection()) {
1512 return; 1679 return;
1513 } 1680 }
1514 1681
1515 render_widget_host_->SetAccessibilityFocus(acc_obj_id); 1682 render_widget_host_->SetAccessibilityFocus(acc_obj_id);
1516 } 1683 }
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
1686 RenderWidgetHostView::GetRenderWidgetHostViewFromNativeView( 1853 RenderWidgetHostView::GetRenderWidgetHostViewFromNativeView(
1687 gfx::NativeView native_view) { 1854 gfx::NativeView native_view) {
1688 if (::IsWindow(native_view)) { 1855 if (::IsWindow(native_view)) {
1689 HANDLE raw_render_host_view = ::GetProp(native_view, 1856 HANDLE raw_render_host_view = ::GetProp(native_view,
1690 kRenderWidgetHostViewKey); 1857 kRenderWidgetHostViewKey);
1691 if (raw_render_host_view) 1858 if (raw_render_host_view)
1692 return reinterpret_cast<RenderWidgetHostView*>(raw_render_host_view); 1859 return reinterpret_cast<RenderWidgetHostView*>(raw_render_host_view);
1693 } 1860 }
1694 return NULL; 1861 return NULL;
1695 } 1862 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698