OLD | NEW |
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_gtk.h" | 5 #include "chrome/browser/renderer_host/render_widget_host_view_gtk.h" |
6 | 6 |
7 // If this gets included after the gtk headers, then a bunch of compiler | 7 // If this gets included after the gtk headers, then a bunch of compiler |
8 // errors happen because of a "#define Status int" in Xlib.h, which interacts | 8 // errors happen because of a "#define Status int" in Xlib.h, which interacts |
9 // badly with URLRequestStatus::Status. | 9 // badly with URLRequestStatus::Status. |
10 #include "chrome/common/render_messages.h" | 10 #include "chrome/common/render_messages.h" |
(...skipping 11 matching lines...) Expand all Loading... |
22 #include "app/x11_util.h" | 22 #include "app/x11_util.h" |
23 #include "base/command_line.h" | 23 #include "base/command_line.h" |
24 #include "base/logging.h" | 24 #include "base/logging.h" |
25 #include "base/message_loop.h" | 25 #include "base/message_loop.h" |
26 #include "base/metrics/histogram.h" | 26 #include "base/metrics/histogram.h" |
27 #include "base/string_number_conversions.h" | 27 #include "base/string_number_conversions.h" |
28 #include "base/time.h" | 28 #include "base/time.h" |
29 #include "base/utf_string_conversions.h" | 29 #include "base/utf_string_conversions.h" |
30 #include "chrome/browser/gtk/gtk_util.h" | 30 #include "chrome/browser/gtk/gtk_util.h" |
31 #include "chrome/browser/renderer_host/backing_store_x.h" | 31 #include "chrome/browser/renderer_host/backing_store_x.h" |
32 #include "chrome/browser/renderer_host/gpu_view_host.h" | |
33 #include "chrome/browser/renderer_host/gtk_im_context_wrapper.h" | 32 #include "chrome/browser/renderer_host/gtk_im_context_wrapper.h" |
34 #include "chrome/browser/renderer_host/gtk_key_bindings_handler.h" | 33 #include "chrome/browser/renderer_host/gtk_key_bindings_handler.h" |
35 #include "chrome/browser/renderer_host/render_view_host.h" | 34 #include "chrome/browser/renderer_host/render_view_host.h" |
36 #include "chrome/browser/renderer_host/render_view_host_delegate.h" | 35 #include "chrome/browser/renderer_host/render_view_host_delegate.h" |
37 #include "chrome/browser/renderer_host/render_widget_host.h" | 36 #include "chrome/browser/renderer_host/render_widget_host.h" |
38 #include "chrome/browser/renderer_host/video_layer_x.h" | |
39 #include "chrome/common/chrome_switches.h" | 37 #include "chrome/common/chrome_switches.h" |
40 #include "chrome/common/native_web_keyboard_event.h" | 38 #include "chrome/common/native_web_keyboard_event.h" |
41 #include "gfx/gtk_preserve_window.h" | 39 #include "gfx/gtk_preserve_window.h" |
42 #include "third_party/WebKit/WebKit/chromium/public/gtk/WebInputEventFactory.h" | 40 #include "third_party/WebKit/WebKit/chromium/public/gtk/WebInputEventFactory.h" |
43 #include "webkit/glue/plugins/webplugin.h" | 41 #include "webkit/glue/plugins/webplugin.h" |
44 #include "webkit/glue/webaccessibility.h" | 42 #include "webkit/glue/webaccessibility.h" |
45 #include "webkit/glue/webcursor_gtk_data.h" | 43 #include "webkit/glue/webcursor_gtk_data.h" |
46 | 44 |
47 #if defined(OS_CHROMEOS) | 45 #if defined(OS_CHROMEOS) |
48 #include "views/widget/tooltip_window_gtk.h" | 46 #include "views/widget/tooltip_window_gtk.h" |
(...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
467 }; | 465 }; |
468 | 466 |
469 // static | 467 // static |
470 RenderWidgetHostView* RenderWidgetHostView::CreateViewForWidget( | 468 RenderWidgetHostView* RenderWidgetHostView::CreateViewForWidget( |
471 RenderWidgetHost* widget) { | 469 RenderWidgetHost* widget) { |
472 return new RenderWidgetHostViewGtk(widget); | 470 return new RenderWidgetHostViewGtk(widget); |
473 } | 471 } |
474 | 472 |
475 RenderWidgetHostViewGtk::RenderWidgetHostViewGtk(RenderWidgetHost* widget_host) | 473 RenderWidgetHostViewGtk::RenderWidgetHostViewGtk(RenderWidgetHost* widget_host) |
476 : host_(widget_host), | 474 : host_(widget_host), |
477 enable_gpu_rendering_(false), | |
478 about_to_validate_and_paint_(false), | 475 about_to_validate_and_paint_(false), |
479 is_hidden_(false), | 476 is_hidden_(false), |
480 is_loading_(false), | 477 is_loading_(false), |
481 is_showing_context_menu_(false), | 478 is_showing_context_menu_(false), |
482 visually_deemphasized_(false), | 479 visually_deemphasized_(false), |
483 parent_host_view_(NULL), | 480 parent_host_view_(NULL), |
484 parent_(NULL), | 481 parent_(NULL), |
485 is_popup_first_mouse_release_(true), | 482 is_popup_first_mouse_release_(true), |
486 was_focused_before_grab_(false), | 483 was_focused_before_grab_(false), |
487 do_x_grab_(false), | 484 do_x_grab_(false), |
488 dragged_at_horizontal_edge_(0), | 485 dragged_at_horizontal_edge_(0), |
489 dragged_at_vertical_edge_(0) { | 486 dragged_at_vertical_edge_(0) { |
490 host_->set_view(this); | 487 host_->set_view(this); |
491 | |
492 // Enable experimental out-of-process GPU rendering. | |
493 CommandLine* command_line = CommandLine::ForCurrentProcess(); | |
494 enable_gpu_rendering_ = | |
495 command_line->HasSwitch(switches::kEnableGPURendering); | |
496 } | 488 } |
497 | 489 |
498 RenderWidgetHostViewGtk::~RenderWidgetHostViewGtk() { | 490 RenderWidgetHostViewGtk::~RenderWidgetHostViewGtk() { |
499 view_.Destroy(); | 491 view_.Destroy(); |
500 } | 492 } |
501 | 493 |
502 void RenderWidgetHostViewGtk::InitAsChild() { | 494 void RenderWidgetHostViewGtk::InitAsChild() { |
503 view_.Own(RenderWidgetHostViewGtkWidget::CreateNewWidget(this)); | 495 view_.Own(RenderWidgetHostViewGtkWidget::CreateNewWidget(this)); |
504 // |im_context_| must be created after creating |view_| widget. | 496 // |im_context_| must be created after creating |view_| widget. |
505 im_context_.reset(new GtkIMContextWrapper(this)); | 497 im_context_.reset(new GtkIMContextWrapper(this)); |
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
745 bool RenderWidgetHostViewGtk::NeedsInputGrab() { | 737 bool RenderWidgetHostViewGtk::NeedsInputGrab() { |
746 return popup_type_ == WebKit::WebPopupTypeSelect; | 738 return popup_type_ == WebKit::WebPopupTypeSelect; |
747 } | 739 } |
748 | 740 |
749 bool RenderWidgetHostViewGtk::IsPopup() { | 741 bool RenderWidgetHostViewGtk::IsPopup() { |
750 return popup_type_ != WebKit::WebPopupTypeNone; | 742 return popup_type_ != WebKit::WebPopupTypeNone; |
751 } | 743 } |
752 | 744 |
753 BackingStore* RenderWidgetHostViewGtk::AllocBackingStore( | 745 BackingStore* RenderWidgetHostViewGtk::AllocBackingStore( |
754 const gfx::Size& size) { | 746 const gfx::Size& size) { |
755 if (enable_gpu_rendering_) { | |
756 // Use a special GPU accelerated backing store. | |
757 if (!gpu_view_host_.get()) { | |
758 // Here we lazily make the GpuViewHost. This must be allocated when we | |
759 // have a native view realized, which happens sometime after creation | |
760 // when our owner puts us in the parent window. | |
761 DCHECK(GetNativeView()); | |
762 XID window_xid = x11_util::GetX11WindowFromGtkWidget(GetNativeView()); | |
763 gpu_view_host_.reset(new GpuViewHost(host_, window_xid)); | |
764 } | |
765 return gpu_view_host_->CreateBackingStore(size); | |
766 } | |
767 | |
768 return new BackingStoreX(host_, size, | 747 return new BackingStoreX(host_, size, |
769 x11_util::GetVisualFromGtkWidget(view_.get()), | 748 x11_util::GetVisualFromGtkWidget(view_.get()), |
770 gtk_widget_get_visual(view_.get())->depth); | 749 gtk_widget_get_visual(view_.get())->depth); |
771 } | 750 } |
772 | 751 |
773 VideoLayer* RenderWidgetHostViewGtk::AllocVideoLayer(const gfx::Size& size) { | |
774 if (enable_gpu_rendering_) { | |
775 // TODO(scherkus): is it possible for a video layer to be allocated before a | |
776 // backing store? | |
777 DCHECK(gpu_view_host_.get()) | |
778 << "AllocVideoLayer() called before AllocBackingStore()"; | |
779 return gpu_view_host_->CreateVideoLayer(size); | |
780 } | |
781 | |
782 return new VideoLayerX(host_, size, | |
783 x11_util::GetVisualFromGtkWidget(view_.get()), | |
784 gtk_widget_get_visual(view_.get())->depth); | |
785 } | |
786 | |
787 void RenderWidgetHostViewGtk::SetBackground(const SkBitmap& background) { | 752 void RenderWidgetHostViewGtk::SetBackground(const SkBitmap& background) { |
788 RenderWidgetHostView::SetBackground(background); | 753 RenderWidgetHostView::SetBackground(background); |
789 host_->Send(new ViewMsg_SetBackground(host_->routing_id(), background)); | 754 host_->Send(new ViewMsg_SetBackground(host_->routing_id(), background)); |
790 } | 755 } |
791 | 756 |
792 void RenderWidgetHostViewGtk::ModifyEventForEdgeDragging( | 757 void RenderWidgetHostViewGtk::ModifyEventForEdgeDragging( |
793 GtkWidget* widget, GdkEventMotion* event) { | 758 GtkWidget* widget, GdkEventMotion* event) { |
794 // If the widget is aligned with an edge of the monitor its on and the user | 759 // If the widget is aligned with an edge of the monitor its on and the user |
795 // attempts to drag past that edge we track the number of times it has | 760 // attempts to drag past that edge we track the number of times it has |
796 // occurred, so that we can force the widget to scroll when it otherwise | 761 // occurred, so that we can force the widget to scroll when it otherwise |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
835 event->y += new_dragged_at_vertical_edge; | 800 event->y += new_dragged_at_vertical_edge; |
836 } else { | 801 } else { |
837 // Clear whenever we get a non-drag mouse move. | 802 // Clear whenever we get a non-drag mouse move. |
838 drag_monitor_size.SetSize(0, 0); | 803 drag_monitor_size.SetSize(0, 0); |
839 } | 804 } |
840 dragged_at_horizontal_edge_ = new_dragged_at_horizontal_edge; | 805 dragged_at_horizontal_edge_ = new_dragged_at_horizontal_edge; |
841 dragged_at_vertical_edge_ = new_dragged_at_vertical_edge; | 806 dragged_at_vertical_edge_ = new_dragged_at_vertical_edge; |
842 } | 807 } |
843 | 808 |
844 void RenderWidgetHostViewGtk::Paint(const gfx::Rect& damage_rect) { | 809 void RenderWidgetHostViewGtk::Paint(const gfx::Rect& damage_rect) { |
845 if (enable_gpu_rendering_) { | |
846 // When we're proxying painting, we don't actually display the web page | |
847 // ourselves. | |
848 if (gpu_view_host_.get()) | |
849 gpu_view_host_->OnWindowPainted(); | |
850 | |
851 // Erase the background. This will prevent a flash of black when resizing | |
852 // or exposing the window. White is usually better than black. | |
853 return; | |
854 } | |
855 | |
856 // If the GPU process is rendering directly into the View, | 810 // If the GPU process is rendering directly into the View, |
857 // call the compositor directly. | 811 // call the compositor directly. |
858 RenderWidgetHost* render_widget_host = GetRenderWidgetHost(); | 812 RenderWidgetHost* render_widget_host = GetRenderWidgetHost(); |
859 if (render_widget_host->is_gpu_rendering_active()) { | 813 if (render_widget_host->is_gpu_rendering_active()) { |
860 host_->ScheduleComposite(); | 814 host_->ScheduleComposite(); |
861 return; | 815 return; |
862 } | 816 } |
863 | 817 |
864 GdkWindow* window = view_.get()->window; | 818 GdkWindow* window = view_.get()->window; |
865 DCHECK(!about_to_validate_and_paint_); | 819 DCHECK(!about_to_validate_and_paint_); |
(...skipping 11 matching lines...) Expand all Loading... |
877 if (backing_store) { | 831 if (backing_store) { |
878 // Only render the widget if it is attached to a window; there's a short | 832 // Only render the widget if it is attached to a window; there's a short |
879 // period where this object isn't attached to a window but hasn't been | 833 // period where this object isn't attached to a window but hasn't been |
880 // Destroy()ed yet and it receives paint messages... | 834 // Destroy()ed yet and it receives paint messages... |
881 if (window) { | 835 if (window) { |
882 if (!visually_deemphasized_) { | 836 if (!visually_deemphasized_) { |
883 // In the common case, use XCopyArea. We don't draw more than once, so | 837 // In the common case, use XCopyArea. We don't draw more than once, so |
884 // we don't need to double buffer. | 838 // we don't need to double buffer. |
885 backing_store->XShowRect( | 839 backing_store->XShowRect( |
886 paint_rect, x11_util::GetX11WindowFromGtkWidget(view_.get())); | 840 paint_rect, x11_util::GetX11WindowFromGtkWidget(view_.get())); |
887 | |
888 // Paint the video layer using XCopyArea. | |
889 // TODO(scherkus): implement VideoLayerX::CairoShow() for grey | |
890 // blending. | |
891 VideoLayerX* video_layer = static_cast<VideoLayerX*>( | |
892 host_->video_layer()); | |
893 if (video_layer) | |
894 video_layer->XShow(x11_util::GetX11WindowFromGtkWidget(view_.get())); | |
895 } else { | 841 } else { |
896 // If the grey blend is showing, we make two drawing calls. Use double | 842 // If the grey blend is showing, we make two drawing calls. Use double |
897 // buffering to prevent flicker. Use CairoShowRect because XShowRect | 843 // buffering to prevent flicker. Use CairoShowRect because XShowRect |
898 // shortcuts GDK's double buffering. We won't be able to draw outside | 844 // shortcuts GDK's double buffering. We won't be able to draw outside |
899 // of |damage_rect|, so invalidate the difference between |paint_rect| | 845 // of |damage_rect|, so invalidate the difference between |paint_rect| |
900 // and |damage_rect|. | 846 // and |damage_rect|. |
901 if (paint_rect != damage_rect) { | 847 if (paint_rect != damage_rect) { |
902 GdkRectangle extra_gdk_rect = | 848 GdkRectangle extra_gdk_rect = |
903 paint_rect.Subtract(damage_rect).ToGdkRectangle(); | 849 paint_rect.Subtract(damage_rect).ToGdkRectangle(); |
904 gdk_window_invalidate_rect(window, &extra_gdk_rect, false); | 850 gdk_window_invalidate_rect(window, &extra_gdk_rect, false); |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1116 } | 1062 } |
1117 | 1063 |
1118 // static | 1064 // static |
1119 RenderWidgetHostView* | 1065 RenderWidgetHostView* |
1120 RenderWidgetHostView::GetRenderWidgetHostViewFromNativeView( | 1066 RenderWidgetHostView::GetRenderWidgetHostViewFromNativeView( |
1121 gfx::NativeView widget) { | 1067 gfx::NativeView widget) { |
1122 gpointer user_data = g_object_get_data(G_OBJECT(widget), | 1068 gpointer user_data = g_object_get_data(G_OBJECT(widget), |
1123 kRenderWidgetHostViewKey); | 1069 kRenderWidgetHostViewKey); |
1124 return reinterpret_cast<RenderWidgetHostView*>(user_data); | 1070 return reinterpret_cast<RenderWidgetHostView*>(user_data); |
1125 } | 1071 } |
OLD | NEW |