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

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 307 matching lines...) Expand 10 before | Expand all | Expand 10 after
699 Redraw(); 707 Redraw();
700 } 708 }
701 709
702 void RenderWidgetHostViewWin::RenderViewGone() { 710 void RenderWidgetHostViewWin::RenderViewGone() {
703 // TODO(darin): keep this around, and draw sad-tab into it. 711 // TODO(darin): keep this around, and draw sad-tab into it.
704 UpdateCursorIfOverSelf(); 712 UpdateCursorIfOverSelf();
705 being_destroyed_ = true; 713 being_destroyed_ = true;
706 DestroyWindow(); 714 DestroyWindow();
707 } 715 }
708 716
717 static BOOL CALLBACK AddChildWindowToVector(HWND hwnd, LPARAM lparam) {
718 std::vector<HWND>* vector = reinterpret_cast<std::vector<HWND>*>(lparam);
719 vector->push_back(hwnd);
720 return TRUE;
721 }
722
723 void RenderWidgetHostViewWin::WillWmDestroy() {
724 if (!compositor_host_window_)
725 return;
726
727 std::vector<HWND> all_child_windows;
728 ::EnumChildWindows(compositor_host_window_, AddChildWindowToVector,
729 reinterpret_cast<LPARAM>(&all_child_windows));
730 if (all_child_windows.size()) {
731 DCHECK(all_child_windows.size() == 1);
732 ::ShowWindow(all_child_windows[0], SW_HIDE);
733 ::SetParent(all_child_windows[0], NULL);
734 }
735 }
736
709 void RenderWidgetHostViewWin::WillDestroyRenderWidget(RenderWidgetHost* rwh) { 737 void RenderWidgetHostViewWin::WillDestroyRenderWidget(RenderWidgetHost* rwh) {
710 if (rwh == render_widget_host_) 738 if (rwh == render_widget_host_)
711 render_widget_host_ = NULL; 739 render_widget_host_ = NULL;
712 } 740 }
713 741
714 void RenderWidgetHostViewWin::Destroy() { 742 void RenderWidgetHostViewWin::Destroy() {
715 // We've been told to destroy. 743 // We've been told to destroy.
716 // By clearing close_on_deactivate_, we prevent further deactivations 744 // By clearing close_on_deactivate_, we prevent further deactivations
717 // (caused by windows messages resulting from the DestroyWindow) from 745 // (caused by windows messages resulting from the DestroyWindow) from
718 // triggering further destructions. The deletion of this is handled by 746 // triggering further destructions. The deletion of this is handled by
719 // OnFinalMessage(); 747 // OnFinalMessage();
720 close_on_deactivate_ = false; 748 close_on_deactivate_ = false;
721 being_destroyed_ = true; 749 being_destroyed_ = true;
750 WillWmDestroy();
722 DestroyWindow(); 751 DestroyWindow();
723 } 752 }
724 753
725 void RenderWidgetHostViewWin::SetTooltipText(const std::wstring& tooltip_text) { 754 void RenderWidgetHostViewWin::SetTooltipText(const std::wstring& tooltip_text) {
726 // Clamp the tooltip length to kMaxTooltipLength so that we don't 755 // Clamp the tooltip length to kMaxTooltipLength so that we don't
727 // accidentally DOS the user with a mega tooltip (since Windows doesn't seem 756 // accidentally DOS the user with a mega tooltip (since Windows doesn't seem
728 // to do this itself). 757 // to do this itself).
729 const std::wstring& new_tooltip_text = 758 const std::wstring& new_tooltip_text =
730 l10n_util::TruncateString(tooltip_text, kMaxTooltipLength); 759 l10n_util::TruncateString(tooltip_text, kMaxTooltipLength);
731 760
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
839 ResetTooltip(); 868 ResetTooltip();
840 TrackMouseLeave(false); 869 TrackMouseLeave(false);
841 } 870 }
842 871
843 void RenderWidgetHostViewWin::OnPaint(HDC unused_dc) { 872 void RenderWidgetHostViewWin::OnPaint(HDC unused_dc) {
844 DCHECK(render_widget_host_->process()->HasConnection()); 873 DCHECK(render_widget_host_->process()->HasConnection());
845 874
846 // If the GPU process is rendering directly into the View, 875 // If the GPU process is rendering directly into the View,
847 // call the compositor directly. 876 // call the compositor directly.
848 RenderWidgetHost* render_widget_host = GetRenderWidgetHost(); 877 RenderWidgetHost* render_widget_host = GetRenderWidgetHost();
849 if (render_widget_host->is_gpu_rendering_active()) { 878 if (render_widget_host->is_accelerated_compositing_active()) {
850 // We initialize paint_dc here so that BeginPaint()/EndPaint() 879 // We initialize paint_dc here so that BeginPaint()/EndPaint()
851 // get called to validate the region. 880 // get called to validate the region.
852 CPaintDC paint_dc(m_hWnd); 881 CPaintDC paint_dc(m_hWnd);
853 render_widget_host_->ScheduleComposite(); 882 render_widget_host_->ScheduleComposite();
854 return; 883 return;
855 } 884 }
856 885
857 about_to_validate_and_paint_ = true; 886 about_to_validate_and_paint_ = true;
858 BackingStoreWin* backing_store = static_cast<BackingStoreWin*>( 887 BackingStoreWin* backing_store = static_cast<BackingStoreWin*>(
859 render_widget_host_->GetBackingStore(true)); 888 render_widget_host_->GetBackingStore(true));
(...skipping 587 matching lines...) Expand 10 before | Expand all | Expand 10 after
1447 if (!render_widget_host_ || 1476 if (!render_widget_host_ ||
1448 render_process_host != render_widget_host_->process()) 1477 render_process_host != render_widget_host_->process())
1449 return; 1478 return;
1450 1479
1451 // If it was our RenderProcessHost that posted the notification, 1480 // If it was our RenderProcessHost that posted the notification,
1452 // clear the BrowserAccessibilityManager, because the renderer is 1481 // clear the BrowserAccessibilityManager, because the renderer is
1453 // dead and any accessibility information we have is now stale. 1482 // dead and any accessibility information we have is now stale.
1454 browser_accessibility_manager_.reset(NULL); 1483 browser_accessibility_manager_.reset(NULL);
1455 } 1484 }
1456 1485
1486 // Looks through the children windows of the CompositorHostWindow. If the
1487 // compositor child window is found, its size is checked against the host
1488 // window's size. If the child is smaller in either dimensions, we fill
1489 // the host window with white to avoid unseemly cracks.
1490 static void PaintCompositorHostWindow(HWND hWnd) {
1491 PAINTSTRUCT paint;
1492 BeginPaint(hWnd, &paint);
1493
1494 std::vector<HWND> child_windows;
1495 EnumChildWindows(hWnd, AddChildWindowToVector,
1496 reinterpret_cast<LPARAM>(&child_windows));
1497
1498 if (child_windows.size()) {
1499 HWND child = child_windows[0];
1500
1501 RECT host_rect, child_rect;
1502 GetClientRect(hWnd, &host_rect);
1503 if (GetClientRect(child, &child_rect)) {
1504 if (child_rect.right < host_rect.right ||
1505 child_rect.bottom != host_rect.bottom) {
1506 FillRect(paint.hdc, &host_rect,
1507 static_cast<HBRUSH>(GetStockObject(WHITE_BRUSH)));
1508 }
1509 }
1510 }
1511 EndPaint(hWnd, &paint);
1512 }
1513
1514 // WndProc for the compositor host window. We use this instead of Default so
1515 // we can drop WM_PAINT and WM_ERASEBKGD messages on the floor.
1516 static LRESULT CALLBACK CompositorHostWindowProc(HWND hWnd, UINT message,
1517 WPARAM wParam, LPARAM lParam) {
1518 switch (message) {
1519 case WM_ERASEBKGND:
1520 return 0;
1521 case WM_DESTROY:
1522 return 0;
1523 case WM_PAINT:
1524 PaintCompositorHostWindow(hWnd);
1525 return 0;
1526 default:
1527 return DefWindowProc(hWnd, message, wParam, lParam);
1528 }
1529 }
1530
1531 // Creates a HWND within the RenderWidgetHostView that will serve as a host
1532 // for a HWND that the GPU process will create. The host window is used
1533 // to Z-position the GPU's window relative to other plugin windows.
1534 gfx::PluginWindowHandle RenderWidgetHostViewWin::CreateCompositorHostWindow() {
1535 DCHECK(!compositor_host_window_);
1536 static ATOM window_class = 0;
1537 if (!window_class) {
1538 WNDCLASSEX wcex;
1539 wcex.cbSize = sizeof(WNDCLASSEX);
1540 wcex.style = 0;
1541 wcex.lpfnWndProc = CompositorHostWindowProc;
1542 wcex.cbClsExtra = 0;
1543 wcex.cbWndExtra = 0;
1544 wcex.hInstance = GetModuleHandle(NULL);
1545 wcex.hIcon = 0;
1546 wcex.hCursor = 0;
1547 wcex.hbrBackground = NULL;
1548 wcex.lpszMenuName = 0;
1549 wcex.lpszClassName = L"CompositorHostWindowClass";
1550 wcex.hIconSm = 0;
1551 window_class = RegisterClassEx(&wcex);
1552 DCHECK(window_class);
1553 }
1554
1555 compositor_host_window_ = CreateWindowEx(
1556 WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR,
1557 MAKEINTATOM(window_class), 0,
1558 WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_DISABLED,
1559 0, 0, 0, 0, m_hWnd, 0, GetModuleHandle(NULL), 0);
1560 DCHECK(compositor_host_window_);
1561
1562 // We need to not just "WM_SHOW" the new indow, but reparent it
1563 // below any existing plugin existing windows.
1564 ShowCompositorHostWindow(true);
1565
1566 return static_cast<gfx::PluginWindowHandle>(compositor_host_window_);
1567 }
1568
1569 void RenderWidgetHostViewWin::ShowCompositorHostWindow(bool show) {
1570 // When we first create the compositor, we will get a show request from
1571 // the renderer before we have gotten the create request from the GPU. In this
1572 // case, simply ignore the show request.
1573 if (compositor_host_window_ == NULL)
1574 return;
1575
1576 if (show) {
1577 UINT flags = SWP_NOSENDCHANGING | SWP_NOCOPYBITS | SWP_NOZORDER |
1578 SWP_NOACTIVATE | SWP_DEFERERASE | SWP_SHOWWINDOW;
1579 gfx::Rect rect = GetViewBounds();
1580 ::SetWindowPos(compositor_host_window_, NULL, 0, 0,
1581 rect.width(), rect.height(),
1582 flags);
1583
1584 // Get all the child windows of this view, including the compositor window.
1585 std::vector<HWND> all_child_windows;
1586 ::EnumChildWindows(m_hWnd, AddChildWindowToVector,
1587 reinterpret_cast<LPARAM>(&all_child_windows));
1588
1589 // Build a list of just the plugin window handles
1590 std::vector<HWND> plugin_windows;
1591 bool compositor_host_window_found = false;
1592 for (size_t i = 0; i < all_child_windows.size(); ++i) {
1593 if (all_child_windows[i] != compositor_host_window_)
1594 plugin_windows.push_back(all_child_windows[i]);
1595 else
1596 compositor_host_window_found = true;
1597 }
1598 DCHECK(compositor_host_window_found);
1599
1600 // Set all the plugin windows to be "after" the compositor window.
1601 // When the compositor window is created, gets placed above plugins.
1602 for (size_t i = 0; i < plugin_windows.size(); ++i) {
1603 HWND next;
1604 if (i + 1 < plugin_windows.size())
1605 next = plugin_windows[i+1];
1606 else
1607 next = compositor_host_window_;
1608 ::SetWindowPos(plugin_windows[i], next, 0, 0, 0, 0,
1609 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
1610 }
1611 } else {
1612 ::ShowWindow(compositor_host_window_, SW_HIDE);
1613 }
1614 }
1615
1457 void RenderWidgetHostViewWin::SetAccessibilityFocus(int acc_obj_id) { 1616 void RenderWidgetHostViewWin::SetAccessibilityFocus(int acc_obj_id) {
1458 if (!browser_accessibility_manager_.get() || 1617 if (!browser_accessibility_manager_.get() ||
1459 !render_widget_host_ || 1618 !render_widget_host_ ||
1460 !render_widget_host_->process() || 1619 !render_widget_host_->process() ||
1461 !render_widget_host_->process()->HasConnection()) { 1620 !render_widget_host_->process()->HasConnection()) {
1462 return; 1621 return;
1463 } 1622 }
1464 1623
1465 render_widget_host_->SetAccessibilityFocus(acc_obj_id); 1624 render_widget_host_->SetAccessibilityFocus(acc_obj_id);
1466 } 1625 }
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
1636 RenderWidgetHostView::GetRenderWidgetHostViewFromNativeView( 1795 RenderWidgetHostView::GetRenderWidgetHostViewFromNativeView(
1637 gfx::NativeView native_view) { 1796 gfx::NativeView native_view) {
1638 if (::IsWindow(native_view)) { 1797 if (::IsWindow(native_view)) {
1639 HANDLE raw_render_host_view = ::GetProp(native_view, 1798 HANDLE raw_render_host_view = ::GetProp(native_view,
1640 kRenderWidgetHostViewKey); 1799 kRenderWidgetHostViewKey);
1641 if (raw_render_host_view) 1800 if (raw_render_host_view)
1642 return reinterpret_cast<RenderWidgetHostView*>(raw_render_host_view); 1801 return reinterpret_cast<RenderWidgetHostView*>(raw_render_host_view);
1643 } 1802 }
1644 return NULL; 1803 return NULL;
1645 } 1804 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698