blob: 9709d2e7b9312526056925a8eae95a22aca45457 [file] [log] [blame]
[email protected]60a50072012-01-11 02:05:351// Copyright (c) 2012 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit09911bf2008-07-26 23:55:294
[email protected]2cff0052011-03-18 16:51:445#include "content/renderer/render_widget.h"
initial.commit09911bf2008-07-26 23:55:296
dcheng07945f632015-12-26 07:59:327#include <utility>
8
[email protected]c27dd4f2014-05-22 18:05:199#include "base/auto_reset.h"
[email protected]32876ae2011-11-15 22:25:2110#include "base/bind.h"
[email protected]4fb66842009-12-04 21:41:0011#include "base/command_line.h"
initial.commit09911bf2008-07-26 23:55:2912#include "base/logging.h"
avi1023d012015-12-25 02:39:1413#include "base/macros.h"
[email protected]3b63f8f42011-03-28 01:54:1514#include "base/memory/scoped_ptr.h"
[email protected]b256eca2013-07-11 10:57:4015#include "base/memory/singleton.h"
[email protected]aaf68892013-07-18 00:11:3016#include "base/message_loop/message_loop.h"
[email protected]835d7c82010-10-14 04:38:3817#include "base/metrics/histogram.h"
[email protected]aa4117f2011-12-09 22:19:2118#include "base/stl_util.h"
[email protected]74ebfb12013-06-07 20:48:0019#include "base/strings/utf_string_conversions.h"
[email protected]35b4f0c2014-06-26 16:55:2720#include "base/sys_info.h"
primiano9e38d552015-01-28 04:18:0121#include "base/trace_event/trace_event.h"
22#include "base/trace_event/trace_event_synthetic_delay.h"
[email protected]661eb9d2009-02-03 02:11:4823#include "build/build_config.h"
[email protected]681ccff2013-03-18 06:13:5224#include "cc/base/switches.h"
[email protected]adbe30f2013-10-11 21:12:3325#include "cc/debug/benchmark_instrumentation.h"
[email protected]7f0d825f2013-03-18 07:24:3026#include "cc/output/output_surface.h"
fsamuel78f86e42016-01-20 04:10:2327#include "cc/scheduler/begin_frame_source.h"
[email protected]556fd292013-03-18 08:03:0428#include "cc/trees/layer_tree_host.h"
alexclarke7fa93942015-10-21 15:37:1129#include "components/scheduler/renderer/render_widget_scheduling_state.h"
alexclarke7819e2552015-06-03 11:17:2130#include "components/scheduler/renderer/renderer_scheduler.h"
[email protected]29e2fb42013-07-19 01:13:4731#include "content/child/npapi/webplugin.h"
oshima750cb4342015-10-31 00:59:0132#include "content/common/content_switches_internal.h"
[email protected]0634cdd42013-08-16 00:46:0933#include "content/common/gpu/client/context_provider_command_buffer.h"
[email protected]ed7defa2013-03-12 21:29:5934#include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h"
[email protected]96ab016c2013-10-23 00:50:2935#include "content/common/gpu/gpu_process_launch_causes.h"
[email protected]9017d7852013-11-21 17:47:3536#include "content/common/input/synthetic_gesture_packet.h"
[email protected]8e299aa2013-10-16 18:17:4437#include "content/common/input/web_input_event_traits.h"
[email protected]c084330e02013-04-27 01:08:1538#include "content/common/input_messages.h"
[email protected]992db4c2011-05-12 15:37:1539#include "content/common/swapped_out_messages.h"
[email protected]778574e2011-03-21 22:03:5040#include "content/common/view_messages.h"
[email protected]c08950d22011-10-13 22:20:2941#include "content/public/common/content_switches.h"
[email protected]a09d53ce2014-01-31 00:46:4242#include "content/public/common/context_menu_params.h"
[email protected]953bd0062013-08-01 00:58:4043#include "content/renderer/cursor_utils.h"
mfomitchev2600fd7c2016-02-17 20:53:3944#include "content/renderer/devtools/render_widget_screen_metrics_emulator.h"
[email protected]b2e4c70132013-10-03 02:07:5145#include "content/renderer/external_popup_menu.h"
[email protected]ed7defa2013-03-12 21:29:5946#include "content/renderer/gpu/compositor_output_surface.h"
[email protected]36e5ff12013-06-11 12:19:2947#include "content/renderer/gpu/delegated_compositor_output_surface.h"
[email protected]586871b2014-07-22 17:05:1148#include "content/renderer/gpu/frame_swap_message_queue.h"
[email protected]ed7defa2013-03-12 21:29:5949#include "content/renderer/gpu/mailbox_output_surface.h"
[email protected]586871b2014-07-22 17:05:1150#include "content/renderer/gpu/queue_message_swap_promise.h"
[email protected]ba91a792013-02-06 09:48:2851#include "content/renderer/gpu/render_widget_compositor.h"
[email protected]66fca5bc2013-05-23 06:58:2952#include "content/renderer/ime_event_guard.h"
[email protected]7a72d452013-12-13 10:01:1353#include "content/renderer/input/input_handler_manager.h"
[email protected]adab2332013-07-25 18:04:3254#include "content/renderer/pepper/pepper_plugin_instance_impl.h"
[email protected]bffc8302014-01-23 20:52:1655#include "content/renderer/render_frame_impl.h"
[email protected]e3244ed2014-06-20 20:04:2756#include "content/renderer/render_frame_proxy.h"
[email protected]8704f89b2011-04-15 00:30:0557#include "content/renderer/render_process.h"
[email protected]f1a29a02011-10-06 23:08:4458#include "content/renderer/render_thread_impl.h"
dcheng3ce04b62015-10-26 23:30:5559#include "content/renderer/render_view_impl.h"
tfarina556a7232014-10-05 01:02:0960#include "content/renderer/renderer_blink_platform_impl.h"
[email protected]5b45ad42013-10-25 00:42:0461#include "content/renderer/resizing_mode_selector.h"
[email protected]484955942010-08-19 16:13:1862#include "ipc/ipc_sync_message.h"
[email protected]661eb9d2009-02-03 02:11:4863#include "skia/ext/platform_canvas.h"
[email protected]ec173b522013-11-14 11:01:1864#include "third_party/WebKit/public/platform/WebCursorInfo.h"
[email protected]aaf68892013-07-18 00:11:3065#include "third_party/WebKit/public/platform/WebGraphicsContext3D.h"
donnda070f3c2015-01-16 19:54:1166#include "third_party/WebKit/public/platform/WebPoint.h"
[email protected]aaf68892013-07-18 00:11:3067#include "third_party/WebKit/public/platform/WebRect.h"
[email protected]ec173b522013-11-14 11:01:1868#include "third_party/WebKit/public/platform/WebScreenInfo.h"
[email protected]aaf68892013-07-18 00:11:3069#include "third_party/WebKit/public/platform/WebSize.h"
70#include "third_party/WebKit/public/platform/WebString.h"
[email protected]19193682014-04-03 15:01:4371#include "third_party/WebKit/public/web/WebDeviceEmulationParams.h"
kenrba7199832015-01-22 23:44:5972#include "third_party/WebKit/public/web/WebFrameWidget.h"
73#include "third_party/WebKit/public/web/WebLocalFrame.h"
donnda070f3c2015-01-16 19:54:1174#include "third_party/WebKit/public/web/WebNode.h"
[email protected]2255a9332013-06-17 05:12:3175#include "third_party/WebKit/public/web/WebPagePopup.h"
[email protected]2255a9332013-06-17 05:12:3176#include "third_party/WebKit/public/web/WebPopupMenuInfo.h"
77#include "third_party/WebKit/public/web/WebRange.h"
jddukeacf809e2014-09-23 20:38:3878#include "third_party/WebKit/public/web/WebRuntimeFeatures.h"
kenrba7199832015-01-22 23:44:5979#include "third_party/WebKit/public/web/WebView.h"
[email protected]d353541f2012-05-03 22:45:4180#include "third_party/skia/include/core/SkShader.h"
[email protected]faec7b12012-06-19 14:42:1381#include "ui/base/ui_base_switches.h"
tfarina655f81d2014-12-23 02:38:5082#include "ui/gfx/geometry/point_conversions.h"
tfarina3b0452d2014-12-31 15:20:0983#include "ui/gfx/geometry/rect_conversions.h"
tfarinaebe974f02015-01-03 04:25:3284#include "ui/gfx/geometry/size_conversions.h"
[email protected]1835b9e2012-02-28 13:12:4885#include "ui/gfx/skia_util.h"
[email protected]c9e2cbbb2012-05-12 21:17:2786#include "ui/gl/gl_switches.h"
[email protected]d353541f2012-05-03 22:45:4187#include "ui/surface/transport_dib.h"
[email protected]661eb9d2009-02-03 02:11:4888
[email protected]eeb93112013-05-01 19:41:1089#if defined(OS_ANDROID)
[email protected]cefe9b152014-03-27 18:16:1590#include <android/keycodes.h>
[email protected]913d99a2013-05-31 07:16:0791#include "content/renderer/android/synchronous_compositor_factory.h"
boliubee541f42015-11-05 00:52:5392#include "content/renderer/android/synchronous_compositor_filter.h"
93#include "content/renderer/android/synchronous_compositor_output_surface.h"
[email protected]eeb93112013-05-01 19:41:1094#endif
95
[email protected]661eb9d2009-02-03 02:11:4896#if defined(OS_POSIX)
[email protected]6b889fb2010-03-23 20:09:4997#include "ipc/ipc_channel_posix.h"
[email protected]d5282e72009-05-13 13:16:5298#include "third_party/skia/include/core/SkMallocPixelRef.h"
[email protected]d353541f2012-05-03 22:45:4199#include "third_party/skia/include/core/SkPixelRef.h"
[email protected]661eb9d2009-02-03 02:11:48100#endif // defined(OS_POSIX)
[email protected]8085dbc82008-09-26 22:53:44101
penghuang28a5fa22015-12-02 17:58:19102#if defined(MOJO_SHELL_CLIENT)
103#include "content/public/common/mojo_shell_connection.h"
fsamuel2545ecc2015-12-05 00:44:46104#include "content/renderer/mus/render_widget_mus_connection.h"
penghuang28a5fa22015-12-02 17:58:19105#endif
106
[email protected]2255a9332013-06-17 05:12:31107#include "third_party/WebKit/public/web/WebWidget.h"
initial.commit09911bf2008-07-26 23:55:29108
[email protected]180ef242013-11-07 06:50:46109using blink::WebCompositionUnderline;
110using blink::WebCursorInfo;
[email protected]19193682014-04-03 15:01:43111using blink::WebDeviceEmulationParams;
[email protected]180ef242013-11-07 06:50:46112using blink::WebGestureEvent;
113using blink::WebInputEvent;
dtapuska5d2e9c32015-12-03 16:39:49114using blink::WebInputEventResult;
[email protected]180ef242013-11-07 06:50:46115using blink::WebKeyboardEvent;
116using blink::WebMouseEvent;
117using blink::WebMouseWheelEvent;
118using blink::WebNavigationPolicy;
donnda070f3c2015-01-16 19:54:11119using blink::WebNode;
[email protected]180ef242013-11-07 06:50:46120using blink::WebPagePopup;
donnda070f3c2015-01-16 19:54:11121using blink::WebPoint;
[email protected]180ef242013-11-07 06:50:46122using blink::WebPopupType;
123using blink::WebRange;
124using blink::WebRect;
125using blink::WebScreenInfo;
126using blink::WebSize;
127using blink::WebTextDirection;
128using blink::WebTouchEvent;
[email protected]f8ed4722013-12-03 03:27:25129using blink::WebTouchPoint;
[email protected]180ef242013-11-07 06:50:46130using blink::WebVector;
131using blink::WebWidget;
[email protected]e9ff79c2012-10-19 21:31:26132
danakj365175c2016-02-06 00:37:37133#define STATIC_ASSERT_ENUM(a, b) \
134 static_assert(static_cast<int>(a) == static_cast<int>(b), \
135 "mismatching enums: " #a)
136
[email protected]6a4d7f62013-01-07 21:32:13137namespace {
[email protected]b256eca2013-07-11 10:57:40138
139typedef std::map<std::string, ui::TextInputMode> TextInputModeMap;
140
141class TextInputModeMapSingleton {
142 public:
143 static TextInputModeMapSingleton* GetInstance() {
olli.raula36aa8be2015-09-10 11:14:22144 return base::Singleton<TextInputModeMapSingleton>::get();
[email protected]b256eca2013-07-11 10:57:40145 }
[email protected]dd705d4d2013-11-27 08:14:41146 TextInputModeMapSingleton() {
147 map_["verbatim"] = ui::TEXT_INPUT_MODE_VERBATIM;
148 map_["latin"] = ui::TEXT_INPUT_MODE_LATIN;
149 map_["latin-name"] = ui::TEXT_INPUT_MODE_LATIN_NAME;
150 map_["latin-prose"] = ui::TEXT_INPUT_MODE_LATIN_PROSE;
151 map_["full-width-latin"] = ui::TEXT_INPUT_MODE_FULL_WIDTH_LATIN;
152 map_["kana"] = ui::TEXT_INPUT_MODE_KANA;
153 map_["katakana"] = ui::TEXT_INPUT_MODE_KATAKANA;
154 map_["numeric"] = ui::TEXT_INPUT_MODE_NUMERIC;
155 map_["tel"] = ui::TEXT_INPUT_MODE_TEL;
156 map_["email"] = ui::TEXT_INPUT_MODE_EMAIL;
157 map_["url"] = ui::TEXT_INPUT_MODE_URL;
[email protected]b256eca2013-07-11 10:57:40158 }
[email protected]dd705d4d2013-11-27 08:14:41159 const TextInputModeMap& map() const { return map_; }
[email protected]b256eca2013-07-11 10:57:40160 private:
[email protected]dd705d4d2013-11-27 08:14:41161 TextInputModeMap map_;
[email protected]b256eca2013-07-11 10:57:40162
olli.raula36aa8be2015-09-10 11:14:22163 friend struct base::DefaultSingletonTraits<TextInputModeMapSingleton>;
[email protected]b256eca2013-07-11 10:57:40164
165 DISALLOW_COPY_AND_ASSIGN(TextInputModeMapSingleton);
166};
167
[email protected]dd705d4d2013-11-27 08:14:41168ui::TextInputMode ConvertInputMode(const blink::WebString& input_mode) {
[email protected]b256eca2013-07-11 10:57:40169 static TextInputModeMapSingleton* singleton =
170 TextInputModeMapSingleton::GetInstance();
[email protected]dd705d4d2013-11-27 08:14:41171 TextInputModeMap::const_iterator it =
172 singleton->map().find(input_mode.utf8());
173 if (it == singleton->map().end())
[email protected]b256eca2013-07-11 10:57:40174 return ui::TEXT_INPUT_MODE_DEFAULT;
175 return it->second;
[email protected]6a4d7f62013-01-07 21:32:13176}
[email protected]b256eca2013-07-11 10:57:40177
fsamuel72464894f2015-12-15 06:59:31178bool IsDateTimeInput(ui::TextInputType type) {
179 return type == ui::TEXT_INPUT_TYPE_DATE ||
180 type == ui::TEXT_INPUT_TYPE_DATE_TIME ||
181 type == ui::TEXT_INPUT_TYPE_DATE_TIME_LOCAL ||
182 type == ui::TEXT_INPUT_TYPE_MONTH ||
183 type == ui::TEXT_INPUT_TYPE_TIME || type == ui::TEXT_INPUT_TYPE_WEEK;
dtapuskae7473612015-12-04 14:23:06184}
185
fsamuele8326c742016-01-12 00:49:39186content::RenderWidgetInputHandlerDelegate* GetRenderWidgetInputHandlerDelegate(
187 content::RenderWidget* widget) {
188#if defined(MOJO_SHELL_CLIENT)
penghuang639a1042016-01-14 21:25:29189 const base::CommandLine& cmdline = *base::CommandLine::ForCurrentProcess();
190 if (content::MojoShellConnection::Get() &&
191 cmdline.HasSwitch(switches::kUseMusInRenderer)) {
fsamuele8326c742016-01-12 00:49:39192 return content::RenderWidgetMusConnection::GetOrCreate(
193 widget->routing_id());
194 }
195#endif
196 // If we don't have a connection to the Mojo shell, then we want to route IPCs
197 // back to the browser process rather than Mus so we use the |widget| as the
198 // RenderWidgetInputHandlerDelegate.
199 return widget;
200}
201
[email protected]b256eca2013-07-11 10:57:40202} // namespace
203
[email protected]e9ff79c2012-10-19 21:31:26204namespace content {
[email protected]62cb33cae2009-03-27 23:30:22205
[email protected]b2e4c70132013-10-03 02:07:51206// RenderWidget ---------------------------------------------------------------
207
dcheng35d31c112015-07-22 00:17:36208RenderWidget::RenderWidget(CompositorDependencies* compositor_deps,
209 blink::WebPopupType popup_type,
[email protected]180ef242013-11-07 06:50:46210 const blink::WebScreenInfo& screen_info,
[email protected]1ac10dca2013-08-20 20:47:04211 bool swapped_out,
[email protected]7912e822014-04-16 02:37:03212 bool hidden,
213 bool never_visible)
initial.commit09911bf2008-07-26 23:55:29214 : routing_id_(MSG_ROUTING_NONE),
dcheng35d31c112015-07-22 00:17:36215 compositor_deps_(compositor_deps),
danakj6e3bf8012014-12-16 18:27:53216 webwidget_(nullptr),
initial.commit09911bf2008-07-26 23:55:29217 opener_id_(MSG_ROUTING_NONE),
dtrainorcb7779b82014-12-04 01:08:02218 top_controls_shrink_blink_size_(false),
219 top_controls_height_(0.f),
initial.commit09911bf2008-07-26 23:55:29220 next_paint_flags_(0),
[email protected]847a2582013-03-09 02:29:51221 auto_resize_mode_(false),
[email protected]ea3ee0a2012-05-15 03:43:09222 need_update_rect_for_auto_resize_(false),
initial.commit09911bf2008-07-26 23:55:29223 did_show_(false),
[email protected]1ac10dca2013-08-20 20:47:04224 is_hidden_(hidden),
sievers71c62dd52015-10-07 01:44:39225 compositor_never_visible_(never_visible),
mikhail.pozdnyakovf2c902a2015-04-14 08:09:12226 is_fullscreen_granted_(false),
mikhail.pozdnyakovc0e251b2015-04-15 06:51:12227 display_mode_(blink::WebDisplayModeUndefined),
changwanf2a707b2015-10-30 08:22:16228 ime_event_guard_(nullptr),
[email protected]661eb9d2009-02-03 02:11:48229 closing_(false),
[email protected]aeeedad2014-08-22 18:16:22230 host_closing_(false),
[email protected]14392a52012-05-02 20:28:44231 is_swapped_out_(swapped_out),
simonhong628f9812015-04-27 23:13:20232 for_oopif_(false),
[email protected]ad26ef42011-06-17 07:59:45233 text_input_type_(ui::TEXT_INPUT_TYPE_NONE),
[email protected]b256eca2013-07-11 10:57:40234 text_input_mode_(ui::TEXT_INPUT_MODE_DEFAULT),
shuchen82ce8c52014-10-23 01:55:20235 text_input_flags_(0),
[email protected]86ba5fcb2013-09-04 00:36:53236 can_compose_inline_(true),
[email protected]3e2b375b2010-04-07 17:03:12237 popup_type_(popup_type),
[email protected]867125a02009-12-10 06:01:48238 pending_window_rect_count_(0),
[email protected]842f10652012-06-06 01:54:04239 screen_info_(screen_info),
[email protected]3d779472012-11-15 20:49:52240 device_scale_factor_(screen_info_.deviceScaleFactor),
[email protected]53b4cc12013-07-18 23:02:30241 next_output_surface_id_(0),
[email protected]0d1ebed12013-08-05 22:01:13242#if defined(OS_ANDROID)
[email protected]90f24152014-04-09 12:41:36243 text_field_is_dirty_(false),
[email protected]0d1ebed12013-08-05 22:01:13244#endif
[email protected]b2e4c70132013-10-03 02:07:51245 popup_origin_scale_for_emulation_(0.f),
[email protected]586871b2014-07-22 17:05:11246 frame_swap_message_queue_(new FrameSwapMessageQueue()),
[email protected]a09d53ce2014-01-31 00:46:42247 resizing_mode_selector_(new ResizingModeSelector()),
[email protected]be1af0662014-07-29 19:55:51248 has_host_context_menu_location_(false) {
[email protected]8b3f0eb2012-05-03 19:15:05249 if (!swapped_out)
250 RenderProcess::current()->AddRefProcess();
[email protected]380244092011-10-07 17:26:27251 DCHECK(RenderThread::Get());
[email protected]3079c28a2014-06-24 03:38:53252 device_color_profile_.push_back('0');
changwan3a841162015-08-11 02:53:37253#if defined(OS_ANDROID)
254 text_input_info_history_.push_back(blink::WebTextInputInfo());
255#endif
alexclarke7fa93942015-10-21 15:37:11256
257 // In tests there may not be a RenderThreadImpl.
258 if (RenderThreadImpl::current()) {
259 render_widget_scheduling_state_ = RenderThreadImpl::current()
260 ->GetRendererScheduler()
dcheng07945f632015-12-26 07:59:32261 ->NewRenderWidgetSchedulingState();
alexclarke7fa93942015-10-21 15:37:11262 render_widget_scheduling_state_->SetHidden(is_hidden_);
263 }
initial.commit09911bf2008-07-26 23:55:29264}
265
266RenderWidget::~RenderWidget() {
[email protected]c5b3b5e2009-02-13 06:41:11267 DCHECK(!webwidget_) << "Leaking our WebWidget!";
[email protected]bffc8302014-01-23 20:52:16268
[email protected]992db4c2011-05-12 15:37:15269 // If we are swapped out, we have released already.
[email protected]d2e2f9ee2013-08-21 11:02:02270 if (!is_swapped_out_ && RenderProcess::current())
[email protected]992db4c2011-05-12 15:37:15271 RenderProcess::current()->ReleaseProcess();
initial.commit09911bf2008-07-26 23:55:29272}
273
[email protected]484955942010-08-19 16:13:18274// static
avi1023d012015-12-25 02:39:14275RenderWidget* RenderWidget::Create(int32_t opener_id,
danakj6e3bf8012014-12-16 18:27:53276 CompositorDependencies* compositor_deps,
[email protected]180ef242013-11-07 06:50:46277 blink::WebPopupType popup_type,
278 const blink::WebScreenInfo& screen_info) {
initial.commit09911bf2008-07-26 23:55:29279 DCHECK(opener_id != MSG_ROUTING_NONE);
dcheng35d31c112015-07-22 00:17:36280 scoped_refptr<RenderWidget> widget(new RenderWidget(
281 compositor_deps, popup_type, screen_info, false, false, false));
282 if (widget->Init(opener_id)) { // adds reference on success.
[email protected]fc72bb12013-06-02 21:13:46283 return widget.get();
[email protected]a635f942012-12-07 10:34:29284 }
285 return NULL;
initial.commit09911bf2008-07-26 23:55:29286}
287
[email protected]484955942010-08-19 16:13:18288// static
kenrba7199832015-01-22 23:44:59289RenderWidget* RenderWidget::CreateForFrame(
290 int routing_id,
kenrba7199832015-01-22 23:44:59291 bool hidden,
292 const blink::WebScreenInfo& screen_info,
293 CompositorDependencies* compositor_deps,
294 blink::WebLocalFrame* frame) {
295 CHECK_NE(routing_id, MSG_ROUTING_NONE);
dcheng3ce04b62015-10-26 23:30:55296 // TODO(avi): Before RenderViewImpl has-a RenderWidget, the browser passes the
297 // same routing ID for both the view routing ID and the main frame widget
298 // routing ID. https://crbug.com/545684
299 RenderViewImpl* view = RenderViewImpl::FromRoutingID(routing_id);
300 if (view) {
301 view->AttachWebFrameWidget(RenderWidget::CreateWebFrameWidget(view, frame));
302 return view;
303 }
dcheng35d31c112015-07-22 00:17:36304 scoped_refptr<RenderWidget> widget(
305 new RenderWidget(compositor_deps, blink::WebPopupTypeNone, screen_info,
306 false, hidden, false));
fsamuele8326c742016-01-12 00:49:39307 widget->SetRoutingID(routing_id);
simonhong628f9812015-04-27 23:13:20308 widget->for_oopif_ = true;
kenrba7199832015-01-22 23:44:59309 // DoInit increments the reference count on |widget|, keeping it alive after
310 // this function returns.
dcheng35d31c112015-07-22 00:17:36311 if (widget->DoInit(MSG_ROUTING_NONE,
kenrba7199832015-01-22 23:44:59312 RenderWidget::CreateWebFrameWidget(widget.get(), frame),
313 nullptr)) {
kenrba7199832015-01-22 23:44:59314 return widget.get();
315 }
316 return nullptr;
317}
318
319// static
dchengda9b4bb2015-07-20 20:58:08320blink::WebWidget* RenderWidget::CreateWebFrameWidget(
321 RenderWidget* render_widget,
322 blink::WebLocalFrame* frame) {
dcheng3ce04b62015-10-26 23:30:55323 if (!frame->parent()) {
324 // TODO(dcheng): The main frame widget currently has a special case.
325 // Eliminate this once WebView is no longer a WebWidget.
326 return blink::WebFrameWidget::create(render_widget, frame->view(), frame);
327 }
dchengda9b4bb2015-07-20 20:58:08328 return blink::WebFrameWidget::create(render_widget, frame);
329}
330
331// static
kenrba7199832015-01-22 23:44:59332blink::WebWidget* RenderWidget::CreateWebWidget(RenderWidget* render_widget) {
[email protected]484955942010-08-19 16:13:18333 switch (render_widget->popup_type_) {
[email protected]180ef242013-11-07 06:50:46334 case blink::WebPopupTypeNone: // Nothing to create.
[email protected]484955942010-08-19 16:13:18335 break;
[email protected]180ef242013-11-07 06:50:46336 case blink::WebPopupTypePage:
[email protected]a7547fb2012-03-08 04:43:44337 return WebPagePopup::create(render_widget);
[email protected]484955942010-08-19 16:13:18338 default:
339 NOTREACHED();
340 }
341 return NULL;
342}
343
dchengda9b4bb2015-07-20 20:58:08344void RenderWidget::CloseForFrame() {
dchengd96a27a2015-07-24 20:17:32345 OnClose();
kenrba7199832015-01-22 23:44:59346}
347
fsamuele8326c742016-01-12 00:49:39348void RenderWidget::SetRoutingID(int32_t routing_id) {
349 routing_id_ = routing_id;
350 input_handler_.reset(new RenderWidgetInputHandler(
351 GetRenderWidgetInputHandlerDelegate(this), this));
352}
353
avi1023d012015-12-25 02:39:14354bool RenderWidget::Init(int32_t opener_id) {
fsamuele8326c742016-01-12 00:49:39355 bool success = DoInit(
piman5d36dae2015-09-24 22:47:05356 opener_id, RenderWidget::CreateWebWidget(this),
357 new ViewHostMsg_CreateWidget(opener_id, popup_type_, &routing_id_));
fsamuele8326c742016-01-12 00:49:39358 if (success) {
359 SetRoutingID(routing_id_);
360 return true;
361 }
362 return false;
[email protected]484955942010-08-19 16:13:18363}
364
avi1023d012015-12-25 02:39:14365bool RenderWidget::DoInit(int32_t opener_id,
[email protected]6a8ddba52010-09-05 04:38:06366 WebWidget* web_widget,
[email protected]484955942010-08-19 16:13:18367 IPC::SyncMessage* create_widget_message) {
initial.commit09911bf2008-07-26 23:55:29368 DCHECK(!webwidget_);
369
370 if (opener_id != MSG_ROUTING_NONE)
371 opener_id_ = opener_id;
372
[email protected]484955942010-08-19 16:13:18373 webwidget_ = web_widget;
initial.commit09911bf2008-07-26 23:55:29374
kenrba7199832015-01-22 23:44:59375 bool result = true;
376 if (create_widget_message)
377 result = RenderThread::Get()->Send(create_widget_message);
378
initial.commit09911bf2008-07-26 23:55:29379 if (result) {
[email protected]380244092011-10-07 17:26:27380 RenderThread::Get()->AddRoute(routing_id_, this);
initial.commit09911bf2008-07-26 23:55:29381 // Take a reference on behalf of the RenderThread. This will be balanced
382 // when we receive ViewMsg_Close.
383 AddRef();
[email protected]b2db9272014-01-10 17:42:00384 if (RenderThreadImpl::current()) {
385 RenderThreadImpl::current()->WidgetCreated();
386 if (is_hidden_)
387 RenderThreadImpl::current()->WidgetHidden();
388 }
fsamuele8326c742016-01-12 00:49:39389
[email protected]a635f942012-12-07 10:34:29390 return true;
initial.commit09911bf2008-07-26 23:55:29391 } else {
[email protected]a635f942012-12-07 10:34:29392 // The above Send can fail when the tab is closing.
393 return false;
initial.commit09911bf2008-07-26 23:55:29394 }
395}
396
[email protected]992db4c2011-05-12 15:37:15397void RenderWidget::SetSwappedOut(bool is_swapped_out) {
398 // We should only toggle between states.
399 DCHECK(is_swapped_out_ != is_swapped_out);
400 is_swapped_out_ = is_swapped_out;
401
402 // If we are swapping out, we will call ReleaseProcess, allowing the process
403 // to exit if all of its RenderViews are swapped out. We wait until the
[email protected]949b6592014-08-20 13:17:52404 // WasSwappedOut call to do this, to allow the unload handler to finish.
[email protected]992db4c2011-05-12 15:37:15405 // If we are swapping in, we call AddRefProcess to prevent the process from
406 // exiting.
[email protected]949b6592014-08-20 13:17:52407 if (!is_swapped_out_)
[email protected]992db4c2011-05-12 15:37:15408 RenderProcess::current()->AddRefProcess();
409}
410
[email protected]949b6592014-08-20 13:17:52411void RenderWidget::WasSwappedOut() {
412 // If we have been swapped out and no one else is using this process,
413 // it's safe to exit now.
414 CHECK(is_swapped_out_);
415 RenderProcess::current()->ReleaseProcess();
416}
417
[email protected]b2e4c70132013-10-03 02:07:51418void RenderWidget::SetPopupOriginAdjustmentsForEmulation(
mfomitchev2600fd7c2016-02-17 20:53:39419 RenderWidgetScreenMetricsEmulator* emulator) {
[email protected]b2e4c70132013-10-03 02:07:51420 popup_origin_scale_for_emulation_ = emulator->scale();
[email protected]19193682014-04-03 15:01:43421 popup_view_origin_for_emulation_ = emulator->applied_widget_rect().origin();
[email protected]9a2d7ee32013-12-05 12:15:49422 popup_screen_origin_for_emulation_ = gfx::Point(
423 emulator->original_screen_rect().origin().x() + emulator->offset().x(),
424 emulator->original_screen_rect().origin().y() + emulator->offset().y());
[email protected]5f75aa42014-04-01 23:00:56425 screen_info_ = emulator->original_screen_info();
426 device_scale_factor_ = screen_info_.deviceScaleFactor;
[email protected]b2e4c70132013-10-03 02:07:51427}
428
[email protected]2d6836f42014-07-02 17:25:31429gfx::Rect RenderWidget::AdjustValidationMessageAnchor(const gfx::Rect& anchor) {
430 if (screen_metrics_emulator_)
431 return screen_metrics_emulator_->AdjustValidationMessageAnchor(anchor);
432 return anchor;
433}
434
[email protected]53907862014-03-25 15:42:40435#if defined(OS_MACOSX) || defined(OS_ANDROID)
[email protected]b2e4c70132013-10-03 02:07:51436void RenderWidget::SetExternalPopupOriginAdjustmentsForEmulation(
mfomitchev2600fd7c2016-02-17 20:53:39437 ExternalPopupMenu* popup,
438 RenderWidgetScreenMetricsEmulator* emulator) {
[email protected]9a2d7ee32013-12-05 12:15:49439 popup->SetOriginScaleAndOffsetForEmulation(
440 emulator->scale(), emulator->offset());
[email protected]b2e4c70132013-10-03 02:07:51441}
[email protected]53907862014-03-25 15:42:40442#endif
[email protected]b2e4c70132013-10-03 02:07:51443
444void RenderWidget::OnShowHostContextMenu(ContextMenuParams* params) {
445 if (screen_metrics_emulator_)
446 screen_metrics_emulator_->OnShowContextMenu(params);
447}
448
[email protected]a95986a82010-12-24 06:19:28449bool RenderWidget::OnMessageReceived(const IPC::Message& message) {
450 bool handled = true;
451 IPC_BEGIN_MESSAGE_MAP(RenderWidget, message)
[email protected]c084330e02013-04-27 01:08:15452 IPC_MESSAGE_HANDLER(InputMsg_HandleInputEvent, OnHandleInputEvent)
[email protected]34202de2013-05-06 23:36:22453 IPC_MESSAGE_HANDLER(InputMsg_CursorVisibilityChange,
454 OnCursorVisibilityChange)
[email protected]a2214eb2014-06-23 18:31:22455 IPC_MESSAGE_HANDLER(InputMsg_ImeSetComposition, OnImeSetComposition)
456 IPC_MESSAGE_HANDLER(InputMsg_ImeConfirmComposition, OnImeConfirmComposition)
[email protected]c084330e02013-04-27 01:08:15457 IPC_MESSAGE_HANDLER(InputMsg_MouseCaptureLost, OnMouseCaptureLost)
458 IPC_MESSAGE_HANDLER(InputMsg_SetFocus, OnSetFocus)
[email protected]9017d7852013-11-21 17:47:35459 IPC_MESSAGE_HANDLER(InputMsg_SyntheticGestureCompleted,
460 OnSyntheticGestureCompleted)
[email protected]a95986a82010-12-24 06:19:28461 IPC_MESSAGE_HANDLER(ViewMsg_Close, OnClose)
[email protected]a95986a82010-12-24 06:19:28462 IPC_MESSAGE_HANDLER(ViewMsg_Resize, OnResize)
dgozman9260b0a12015-03-16 13:45:20463 IPC_MESSAGE_HANDLER(ViewMsg_EnableDeviceEmulation,
464 OnEnableDeviceEmulation)
465 IPC_MESSAGE_HANDLER(ViewMsg_DisableDeviceEmulation,
466 OnDisableDeviceEmulation)
noel89949e62014-09-30 01:12:41467 IPC_MESSAGE_HANDLER(ViewMsg_ColorProfile, OnColorProfile)
[email protected]b5913d72012-02-07 22:26:54468 IPC_MESSAGE_HANDLER(ViewMsg_ChangeResizeRect, OnChangeResizeRect)
[email protected]a95986a82010-12-24 06:19:28469 IPC_MESSAGE_HANDLER(ViewMsg_WasHidden, OnWasHidden)
[email protected]9e2e4632012-07-27 16:38:41470 IPC_MESSAGE_HANDLER(ViewMsg_WasShown, OnWasShown)
[email protected]3d9ec5052013-01-02 22:05:25471 IPC_MESSAGE_HANDLER(ViewMsg_Repaint, OnRepaint)
[email protected]a95986a82010-12-24 06:19:28472 IPC_MESSAGE_HANDLER(ViewMsg_SetTextDirection, OnSetTextDirection)
473 IPC_MESSAGE_HANDLER(ViewMsg_Move_ACK, OnRequestMoveAck)
[email protected]80ad8622012-11-07 16:33:03474 IPC_MESSAGE_HANDLER(ViewMsg_UpdateScreenRects, OnUpdateScreenRects)
kenrbb4e2a3b2015-05-14 15:05:05475 IPC_MESSAGE_HANDLER(ViewMsg_SetSurfaceIdNamespace, OnSetSurfaceIdNamespace)
lfg43e08e62016-02-03 18:51:37476 IPC_MESSAGE_HANDLER(ViewMsg_WaitForNextFrameForTests,
477 OnWaitNextFrameForTests)
[email protected]105dffb42013-02-20 03:46:21478#if defined(OS_ANDROID)
changwan3a841162015-08-11 02:53:37479 IPC_MESSAGE_HANDLER(InputMsg_ImeEventAck, OnImeEventAck)
[email protected]2384b6c2013-02-28 23:58:51480 IPC_MESSAGE_HANDLER(ViewMsg_ShowImeIfNeeded, OnShowImeIfNeeded)
[email protected]105dffb42013-02-20 03:46:21481#endif
dtrainor5ef644e2015-11-19 00:12:47482 IPC_MESSAGE_HANDLER(ViewMsg_HandleCompositorProto, OnHandleCompositorProto)
[email protected]a95986a82010-12-24 06:19:28483 IPC_MESSAGE_UNHANDLED(handled = false)
484 IPC_END_MESSAGE_MAP()
485 return handled;
486}
initial.commit09911bf2008-07-26 23:55:29487
488bool RenderWidget::Send(IPC::Message* message) {
[email protected]992db4c2011-05-12 15:37:15489 // Don't send any messages after the browser has told us to close, and filter
490 // most outgoing messages while swapped out.
491 if ((is_swapped_out_ &&
[email protected]e9ff79c2012-10-19 21:31:26492 !SwappedOutMessages::CanSendWhileSwappedOut(message)) ||
[email protected]c6c921e92012-05-10 23:31:11493 closing_) {
initial.commit09911bf2008-07-26 23:55:29494 delete message;
495 return false;
496 }
497
498 // If given a messsage without a routing ID, then assign our routing ID.
499 if (message->routing_id() == MSG_ROUTING_NONE)
500 message->set_routing_id(routing_id_);
501
[email protected]380244092011-10-07 17:26:27502 return RenderThread::Get()->Send(message);
[email protected]8085dbc82008-09-26 22:53:44503}
504
bokanc007c3a2015-02-03 07:15:56505void RenderWidget::SetWindowRectSynchronously(
506 const gfx::Rect& new_window_rect) {
mfomitchev2600fd7c2016-02-17 20:53:39507 ResizeParams params;
508 params.screen_info = screen_info_;
509 params.new_size = new_window_rect.size();
510 params.physical_backing_size =
511 gfx::ScaleToCeiledSize(new_window_rect.size(), device_scale_factor_);
512 params.top_controls_shrink_blink_size = top_controls_shrink_blink_size_;
513 params.top_controls_height = top_controls_height_;
514 params.visible_viewport_size = new_window_rect.size();
515 params.resizer_rect = gfx::Rect();
516 params.is_fullscreen_granted = is_fullscreen_granted_;
517 params.display_mode = display_mode_;
518 params.needs_resize_ack = false;
519 Resize(params);
520
bokanc007c3a2015-02-03 07:15:56521 view_screen_rect_ = new_window_rect;
522 window_screen_rect_ = new_window_rect;
[email protected]92650162013-10-30 03:31:02523 if (!did_show_)
bokanc007c3a2015-02-03 07:15:56524 initial_rect_ = new_window_rect;
[email protected]92650162013-10-30 03:31:02525}
526
initial.commit09911bf2008-07-26 23:55:29527void RenderWidget::OnClose() {
dchengd96a27a2015-07-24 20:17:32528 DCHECK(content::RenderThread::Get());
529 if (closing_)
530 return;
531 NotifyOnClose();
532 closing_ = true;
533
534 // Browser correspondence is no longer needed at this point.
535 if (routing_id_ != MSG_ROUTING_NONE) {
536 RenderThread::Get()->RemoveRoute(routing_id_);
537 SetHidden(false);
538 if (RenderThreadImpl::current())
539 RenderThreadImpl::current()->WidgetDestroyed();
540 }
541
542 if (for_oopif_) {
543 // Widgets for frames may be created and closed at any time while the frame
544 // is alive. However, the closing process must happen synchronously. Frame
545 // widget and frames hold pointers to each other. If Close() is deferred to
546 // the message loop like in the non-frame widget case, WebWidget::close()
547 // can end up accessing members of an already-deleted frame.
548 Close();
549 } else {
550 // If there is a Send call on the stack, then it could be dangerous to close
551 // now. Post a task that only gets invoked when there are no nested message
552 // loops.
553 base::ThreadTaskRunnerHandle::Get()->PostNonNestableTask(
554 FROM_HERE, base::Bind(&RenderWidget::Close, this));
555 }
556
557 // Balances the AddRef taken when we called AddRoute.
558 Release();
initial.commit09911bf2008-07-26 23:55:29559}
560
fsamuel664e8b62016-01-20 19:54:01561void RenderWidget::OnResize(const ResizeParams& params) {
[email protected]5b45ad42013-10-25 00:42:04562 if (resizing_mode_selector_->ShouldAbortOnResize(this, params))
[email protected]03e88672013-10-22 21:31:32563 return;
564
[email protected]b2e4c70132013-10-03 02:07:51565 if (screen_metrics_emulator_) {
mfomitchev2600fd7c2016-02-17 20:53:39566 screen_metrics_emulator_->OnResize(params);
[email protected]b2e4c70132013-10-03 02:07:51567 return;
568 }
569
[email protected]fcdc5642014-05-09 14:32:24570 bool orientation_changed =
571 screen_info_.orientationAngle != params.screen_info.orientationAngle;
572
mfomitchev2600fd7c2016-02-17 20:53:39573 Resize(params);
[email protected]fcdc5642014-05-09 14:32:24574
575 if (orientation_changed)
576 OnOrientationChange();
initial.commit09911bf2008-07-26 23:55:29577}
578
dgozman9260b0a12015-03-16 13:45:20579void RenderWidget::OnEnableDeviceEmulation(
580 const blink::WebDeviceEmulationParams& params) {
mfomitchev2600fd7c2016-02-17 20:53:39581 if (!screen_metrics_emulator_) {
582 ResizeParams resize_params;
583 resize_params.screen_info = screen_info_;
584 resize_params.new_size = size_;
585 resize_params.physical_backing_size = physical_backing_size_;
586 resize_params.visible_viewport_size = visible_viewport_size_;
587 resize_params.top_controls_shrink_blink_size =
588 top_controls_shrink_blink_size_;
589 resize_params.top_controls_height = top_controls_height_;
590 resize_params.resizer_rect = resizer_rect_;
591 resize_params.is_fullscreen_granted = is_fullscreen_granted_;
592 resize_params.display_mode = display_mode_;
593 screen_metrics_emulator_.reset(new RenderWidgetScreenMetricsEmulator(
594 this, params, resize_params, view_screen_rect_, window_screen_rect_));
595 } else {
dgozman9260b0a12015-03-16 13:45:20596 screen_metrics_emulator_->ChangeEmulationParams(params);
mfomitchev2600fd7c2016-02-17 20:53:39597 }
dgozman9260b0a12015-03-16 13:45:20598}
599
600void RenderWidget::OnDisableDeviceEmulation() {
601 screen_metrics_emulator_.reset();
602}
603
noel89949e62014-09-30 01:12:41604void RenderWidget::OnColorProfile(const std::vector<char>& color_profile) {
605 SetDeviceColorProfile(color_profile);
606}
607
[email protected]b5913d72012-02-07 22:26:54608void RenderWidget::OnChangeResizeRect(const gfx::Rect& resizer_rect) {
[email protected]721e2302014-04-30 23:42:01609 if (resizer_rect_ == resizer_rect)
610 return;
611 resizer_rect_ = resizer_rect;
612 if (webwidget_)
613 webwidget_->didChangeWindowResizerRect();
[email protected]b5913d72012-02-07 22:26:54614}
615
initial.commit09911bf2008-07-26 23:55:29616void RenderWidget::OnWasHidden() {
[email protected]9c3085f2011-06-09 02:10:31617 TRACE_EVENT0("renderer", "RenderWidget::OnWasHidden");
initial.commit09911bf2008-07-26 23:55:29618 // Go into a mode where we stop generating paint and scrolling events.
[email protected]bee16aab2009-08-26 15:55:03619 SetHidden(true);
[email protected]de3c5d82014-05-28 22:12:59620 FOR_EACH_OBSERVER(RenderFrameImpl, render_frames_,
621 WasHidden());
initial.commit09911bf2008-07-26 23:55:29622}
623
[email protected]3399dd822014-08-09 11:14:24624void RenderWidget::OnWasShown(bool needs_repainting,
625 const ui::LatencyInfo& latency_info) {
[email protected]9e2e4632012-07-27 16:38:41626 TRACE_EVENT0("renderer", "RenderWidget::OnWasShown");
initial.commit09911bf2008-07-26 23:55:29627 // During shutdown we can just ignore this message.
628 if (!webwidget_)
629 return;
630
631 // See OnWasHidden
[email protected]bee16aab2009-08-26 15:55:03632 SetHidden(false);
[email protected]de3c5d82014-05-28 22:12:59633 FOR_EACH_OBSERVER(RenderFrameImpl, render_frames_,
634 WasShown());
initial.commit09911bf2008-07-26 23:55:29635
[email protected]8a23afb32014-04-30 22:40:23636 if (!needs_repainting)
initial.commit09911bf2008-07-26 23:55:29637 return;
initial.commit09911bf2008-07-26 23:55:29638
639 // Generate a full repaint.
[email protected]3399dd822014-08-09 11:14:24640 if (compositor_) {
641 ui::LatencyInfo swap_latency_info(latency_info);
642 scoped_ptr<cc::SwapPromiseMonitor> latency_info_swap_promise_monitor(
643 compositor_->CreateLatencyInfoSwapPromiseMonitor(&swap_latency_info));
[email protected]aca33f4f2014-05-17 17:08:05644 compositor_->SetNeedsForcedRedraw();
[email protected]3399dd822014-08-09 11:14:24645 }
jdduke491a3f0c2015-06-15 23:30:26646 ScheduleComposite();
initial.commit09911bf2008-07-26 23:55:29647}
648
[email protected]53d3f302009-12-21 04:42:05649void RenderWidget::OnRequestMoveAck() {
650 DCHECK(pending_window_rect_count_);
651 pending_window_rect_count_--;
652}
653
[email protected]ed7defa2013-03-12 21:29:59654GURL RenderWidget::GetURLForGraphicsContext3D() {
655 return GURL();
[email protected]65225772011-05-12 21:10:24656}
657
fsamuel78f86e42016-01-20 04:10:23658void RenderWidget::OnHandleInputEvent(const blink::WebInputEvent* input_event,
dtapuska0bd451a2016-02-18 17:08:10659 const ui::LatencyInfo& latency_info,
660 InputEventDispatchType dispatch_type) {
fsamuel78f86e42016-01-20 04:10:23661 if (!input_event)
662 return;
dtapuska0bd451a2016-02-18 17:08:10663 input_handler_->HandleInputEvent(*input_event, latency_info, dispatch_type);
fsamuel78f86e42016-01-20 04:10:23664}
665
666void RenderWidget::OnCursorVisibilityChange(bool is_visible) {
667 if (webwidget_)
668 webwidget_->setCursorVisibilityState(is_visible);
669}
670
671void RenderWidget::OnMouseCaptureLost() {
672 if (webwidget_)
673 webwidget_->mouseCaptureLost();
674}
675
676void RenderWidget::OnSetFocus(bool enable) {
677 if (webwidget_)
678 webwidget_->setFocus(enable);
679}
680
681///////////////////////////////////////////////////////////////////////////////
682// RenderWidgetCompositorDelegate
683
684void RenderWidget::ApplyViewportDeltas(
685 const gfx::Vector2dF& inner_delta,
686 const gfx::Vector2dF& outer_delta,
687 const gfx::Vector2dF& elastic_overscroll_delta,
688 float page_scale,
689 float top_controls_delta) {
690 webwidget_->applyViewportDeltas(inner_delta, outer_delta,
691 elastic_overscroll_delta, page_scale,
692 top_controls_delta);
693}
694
695void RenderWidget::BeginMainFrame(double frame_time_sec) {
696 webwidget_->beginFrame(frame_time_sec);
697}
698
[email protected]ebc0e1df2013-08-01 02:46:22699scoped_ptr<cc::OutputSurface> RenderWidget::CreateOutputSurface(bool fallback) {
piman990d8ea2016-01-12 15:35:31700 DCHECK(webwidget_);
[email protected]7912e822014-04-16 02:37:03701 // For widgets that are never visible, we don't start the compositor, so we
702 // never get a request for a cc::OutputSurface.
sievers71c62dd52015-10-07 01:44:39703 DCHECK(!compositor_never_visible_);
[email protected]a1811b8912013-05-09 15:35:19704
avi83883c82014-12-23 00:08:49705 const base::CommandLine& command_line =
706 *base::CommandLine::ForCurrentProcess();
[email protected]e09994a2014-03-26 19:59:33707 bool use_software = fallback;
708 if (command_line.HasSwitch(switches::kDisableGpuCompositing))
709 use_software = true;
710
penghuang28a5fa22015-12-02 17:58:19711#if defined(MOJO_SHELL_CLIENT)
712 if (MojoShellConnection::Get() && !use_software) {
713 RenderWidgetMusConnection* connection =
714 RenderWidgetMusConnection::GetOrCreate(routing_id());
715 return connection->CreateOutputSurface();
716 }
717#endif
718
piman990d8ea2016-01-12 15:35:31719 scoped_refptr<GpuChannelHost> gpu_channel_host;
720 if (!use_software) {
721 CauseForGpuLaunch cause =
722 CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE;
723 gpu_channel_host =
724 RenderThreadImpl::current()->EstablishGpuChannelSync(cause);
725 if (!gpu_channel_host.get()) {
726 // Cause the compositor to wait and try again.
727 return nullptr;
728 }
729 // We may get a valid channel, but with a software renderer. In that case,
730 // disable GPU compositing.
731 if (gpu_channel_host->gpu_info().software_rendering)
732 use_software = true;
733 }
734
[email protected]0634cdd42013-08-16 00:46:09735 scoped_refptr<ContextProviderCommandBuffer> context_provider;
vmiura78b69282015-02-14 00:01:17736 scoped_refptr<ContextProviderCommandBuffer> worker_context_provider;
[email protected]e09994a2014-03-26 19:59:33737 if (!use_software) {
[email protected]0634cdd42013-08-16 00:46:09738 context_provider = ContextProviderCommandBuffer::Create(
piman990d8ea2016-01-12 15:35:31739 CreateGraphicsContext3D(gpu_channel_host.get()),
740 RENDER_COMPOSITOR_CONTEXT);
741 DCHECK(context_provider);
revemand180dfc32015-09-24 00:19:43742 worker_context_provider =
743 RenderThreadImpl::current()->SharedWorkerContextProvider();
744 if (!worker_context_provider) {
vmiura78b69282015-02-14 00:01:17745 // Cause the compositor to wait and try again.
piman8944e1c2015-09-22 21:10:34746 return nullptr;
vmiura78b69282015-02-14 00:01:17747 }
boliu853d46052015-10-13 20:20:06748
749#if defined(OS_ANDROID)
750 if (SynchronousCompositorFactory* factory =
751 SynchronousCompositorFactory::GetInstance()) {
752 return factory->CreateOutputSurface(
753 routing_id(), frame_swap_message_queue_, context_provider,
754 worker_context_provider);
boliubee541f42015-11-05 00:52:53755 } else if (RenderThreadImpl::current()->sync_compositor_message_filter()) {
756 return make_scoped_ptr(new SynchronousCompositorOutputSurface(
757 context_provider, worker_context_provider, routing_id(),
758 content::RenderThreadImpl::current()
759 ->sync_compositor_message_filter(),
760 frame_swap_message_queue_));
boliu853d46052015-10-13 20:20:06761 }
762#endif
[email protected]0634cdd42013-08-16 00:46:09763 }
[email protected]ebc0e1df2013-08-01 02:46:22764
avi1023d012015-12-25 02:39:14765 uint32_t output_surface_id = next_output_surface_id_++;
piman8944e1c2015-09-22 21:10:34766 // Composite-to-mailbox is currently used for layout tests in order to cause
767 // them to draw inside in the renderer to do the readback there. This should
768 // no longer be the case when crbug.com/311404 is fixed.
769 if (!RenderThreadImpl::current() ||
770 !RenderThreadImpl::current()->layout_test_mode()) {
danakj6e3bf8012014-12-16 18:27:53771 DCHECK(compositor_deps_->GetCompositorImplThreadTaskRunner());
piman8944e1c2015-09-22 21:10:34772 return make_scoped_ptr(new DelegatedCompositorOutputSurface(
vmiura78b69282015-02-14 00:01:17773 routing_id(), output_surface_id, context_provider,
774 worker_context_provider, frame_swap_message_queue_));
[email protected]65a33ce2014-03-25 22:37:09775 }
piman8944e1c2015-09-22 21:10:34776
[email protected]0634cdd42013-08-16 00:46:09777 if (!context_provider.get()) {
[email protected]0634cdd42013-08-16 00:46:09778 scoped_ptr<cc::SoftwareOutputDevice> software_device(
jbauman7e15c6a2015-05-11 23:43:12779 new cc::SoftwareOutputDevice());
[email protected]0634cdd42013-08-16 00:46:09780
piman8944e1c2015-09-22 21:10:34781 return make_scoped_ptr(new CompositorOutputSurface(
caseqff9c74c2015-02-10 14:56:29782 routing_id(), output_surface_id, nullptr, nullptr,
dcheng07945f632015-12-26 07:59:32783 std::move(software_device), frame_swap_message_queue_, true));
[email protected]ebc0e1df2013-08-01 02:46:22784 }
[email protected]ed7defa2013-03-12 21:29:59785
piman8944e1c2015-09-22 21:10:34786 return make_scoped_ptr(new MailboxOutputSurface(
vmiura78b69282015-02-14 00:01:17787 routing_id(), output_surface_id, context_provider,
piman8944e1c2015-09-22 21:10:34788 worker_context_provider, frame_swap_message_queue_, cc::RGBA_8888));
[email protected]ba91a792013-02-06 09:48:28789}
790
fsamuel78f86e42016-01-20 04:10:23791scoped_ptr<cc::BeginFrameSource>
792RenderWidget::CreateExternalBeginFrameSource() {
793 return compositor_deps_->CreateExternalBeginFrameSource(routing_id_);
794}
795
796void RenderWidget::DidCommitAndDrawCompositorFrame() {
797 // NOTE: Tests may break if this event is renamed or moved. See
798 // tab_capture_performancetest.cc.
799 TRACE_EVENT0("gpu", "RenderWidget::DidCommitAndDrawCompositorFrame");
800 // Notify subclasses that we initiated the paint operation.
801 DidInitiatePaint();
802}
803
804void RenderWidget::DidCommitCompositorFrame() {
805 FOR_EACH_OBSERVER(RenderFrameImpl, render_frames_,
806 DidCommitCompositorFrame());
807 FOR_EACH_OBSERVER(RenderFrameProxy, render_frame_proxies_,
808 DidCommitCompositorFrame());
809#if defined(VIDEO_HOLE)
810 FOR_EACH_OBSERVER(RenderFrameImpl, video_hole_frames_,
811 DidCommitCompositorFrame());
812#endif // defined(VIDEO_HOLE)
813 input_handler_->FlushPendingInputEventAck();
814}
815
816void RenderWidget::DidCompletePageScaleAnimation() {}
817
818void RenderWidget::DidCompleteSwapBuffers() {
819 TRACE_EVENT0("renderer", "RenderWidget::DidCompleteSwapBuffers");
820
821 // Notify subclasses threaded composited rendering was flushed to the screen.
822 DidFlushPaint();
823
824 if (!next_paint_flags_ && !need_update_rect_for_auto_resize_ &&
825 !plugin_window_moves_.size()) {
826 return;
827 }
828
829 ViewHostMsg_UpdateRect_Params params;
830 params.view_size = size_;
831 params.plugin_window_moves.swap(plugin_window_moves_);
832 params.flags = next_paint_flags_;
833
834 Send(new ViewHostMsg_UpdateRect(routing_id_, params));
835 next_paint_flags_ = 0;
836 need_update_rect_for_auto_resize_ = false;
837}
838
839bool RenderWidget::ForOOPIF() const {
840 // TODO(simonhong): Remove this when we enable BeginFrame scheduling for
841 // OOPIF(crbug.com/471411).
842 return for_oopif_;
843}
844
845void RenderWidget::ForwardCompositorProto(const std::vector<uint8_t>& proto) {
846 Send(new ViewHostMsg_ForwardCompositorProto(routing_id_, proto));
847}
848
849bool RenderWidget::IsClosing() const {
850 return host_closing_;
851}
852
[email protected]4d7e46a2013-11-08 05:33:40853void RenderWidget::OnSwapBuffersAborted() {
[email protected]65225772011-05-12 21:10:24854 TRACE_EVENT0("renderer", "RenderWidget::OnSwapBuffersAborted");
[email protected]65225772011-05-12 21:10:24855 // Schedule another frame so the compositor learns about it.
jdduke491a3f0c2015-06-15 23:30:26856 ScheduleComposite();
[email protected]65225772011-05-12 21:10:24857}
858
[email protected]4d7e46a2013-11-08 05:33:40859void RenderWidget::OnSwapBuffersComplete() {
[email protected]65225772011-05-12 21:10:24860 TRACE_EVENT0("renderer", "RenderWidget::OnSwapBuffersComplete");
[email protected]29ed96a2012-02-04 18:12:16861
[email protected]404939f2012-06-01 04:06:18862 // Notify subclasses that composited rendering was flushed to the screen.
[email protected]29ed96a2012-02-04 18:12:16863 DidFlushPaint();
initial.commit09911bf2008-07-26 23:55:29864}
865
fsamuel78f86e42016-01-20 04:10:23866void RenderWidget::OnSwapBuffersPosted() {
867 TRACE_EVENT0("renderer", "RenderWidget::OnSwapBuffersPosted");
initial.commit09911bf2008-07-26 23:55:29868}
869
fsamuel78f86e42016-01-20 04:10:23870void RenderWidget::RecordFrameTimingEvents(
871 scoped_ptr<cc::FrameTimingTracker::CompositeTimingSet> composite_events,
872 scoped_ptr<cc::FrameTimingTracker::MainFrameTimingSet> main_frame_events) {
873 for (const auto& composite_event : *composite_events) {
874 int64_t frameId = composite_event.first;
875 const std::vector<cc::FrameTimingTracker::CompositeTimingEvent>& events =
876 composite_event.second;
877 std::vector<blink::WebFrameTimingEvent> webEvents;
878 for (size_t i = 0; i < events.size(); ++i) {
879 webEvents.push_back(blink::WebFrameTimingEvent(
880 events[i].frame_id,
881 (events[i].timestamp - base::TimeTicks()).InSecondsF()));
882 }
883 webwidget_->recordFrameTimingEvent(blink::WebWidget::CompositeEvent,
884 frameId, webEvents);
885 }
886 for (const auto& main_frame_event : *main_frame_events) {
887 int64_t frameId = main_frame_event.first;
888 const std::vector<cc::FrameTimingTracker::MainFrameTimingEvent>& events =
889 main_frame_event.second;
890 std::vector<blink::WebFrameTimingEvent> webEvents;
891 for (size_t i = 0; i < events.size(); ++i) {
892 webEvents.push_back(blink::WebFrameTimingEvent(
893 events[i].frame_id,
894 (events[i].timestamp - base::TimeTicks()).InSecondsF(),
895 (events[i].end_time - base::TimeTicks()).InSecondsF()));
896 }
897 webwidget_->recordFrameTimingEvent(blink::WebWidget::RenderEvent, frameId,
898 webEvents);
899 }
[email protected]34202de2013-05-06 23:36:22900}
901
fsamuel78f86e42016-01-20 04:10:23902void RenderWidget::ScheduleAnimation() {
903 scheduleAnimation();
initial.commit09911bf2008-07-26 23:55:29904}
905
fsamuel78f86e42016-01-20 04:10:23906void RenderWidget::UpdateVisualState() {
907 webwidget_->updateAllLifecyclePhases();
908}
909
910void RenderWidget::WillBeginCompositorFrame() {
911 TRACE_EVENT0("gpu", "RenderWidget::willBeginCompositorFrame");
912
913 // The UpdateTextInputState can result in further layout and possibly
914 // enable GPU acceleration so they need to be called before any painting
915 // is done.
916 UpdateTextInputState(ShowIme::HIDE_IME, ChangeSource::FROM_NON_IME);
917 UpdateSelectionBounds();
lfge6119aac2016-01-27 02:14:31918
919 FOR_EACH_OBSERVER(RenderFrameProxy, render_frame_proxies_,
920 WillBeginCompositorFrame());
initial.commit09911bf2008-07-26 23:55:29921}
922
fsamuel72464894f2015-12-15 06:59:31923///////////////////////////////////////////////////////////////////////////////
924// RenderWidgetInputHandlerDelegate
925
926void RenderWidget::FocusChangeComplete() {}
927
928bool RenderWidget::HasTouchEventHandlersAt(const gfx::Point& point) const {
929 return true;
930}
931
932void RenderWidget::ObserveWheelEventAndResult(
933 const blink::WebMouseWheelEvent& wheel_event,
934 const gfx::Vector2dF& wheel_unused_delta,
935 bool event_processed) {
936 if (!compositor_deps_->IsElasticOverscrollEnabled())
937 return;
938
939 cc::InputHandlerScrollResult scroll_result;
940 scroll_result.did_scroll = event_processed;
941 scroll_result.did_overscroll_root = !wheel_unused_delta.IsZero();
942 scroll_result.unused_scroll_delta = wheel_unused_delta;
943
944 RenderThreadImpl* render_thread = RenderThreadImpl::current();
945 InputHandlerManager* input_handler_manager =
946 render_thread ? render_thread->input_handler_manager() : NULL;
947 if (input_handler_manager) {
948 input_handler_manager->ObserveWheelEventAndResultOnMainThread(
949 routing_id_, wheel_event, scroll_result);
jddukefffb67c2015-01-07 22:32:29950 }
fsamuel72464894f2015-12-15 06:59:31951}
952
953void RenderWidget::OnDidHandleKeyEvent() {}
954
955void RenderWidget::OnDidOverscroll(const DidOverscrollParams& params) {
956 Send(new InputHostMsg_DidOverscroll(routing_id_, params));
957}
958
959void RenderWidget::OnInputEventAck(scoped_ptr<InputEventAck> input_event_ack) {
960 Send(new InputHostMsg_HandleInputEvent_ACK(routing_id_, *input_event_ack));
961}
962
dtapuska0bd451a2016-02-18 17:08:10963void RenderWidget::NonBlockingInputEventHandled(
964 blink::WebInputEvent::Type handled_type) {
965 RenderThreadImpl* render_thread = RenderThreadImpl::current();
966 InputHandlerManager* input_handler_manager =
967 render_thread ? render_thread->input_handler_manager() : NULL;
968 if (input_handler_manager) {
969 input_handler_manager->NonBlockingInputEventHandledOnMainThread(
970 routing_id_, handled_type);
971 }
972}
973
fsamuele8326c742016-01-12 00:49:39974void RenderWidget::SetInputHandler(RenderWidgetInputHandler* input_handler) {
975 // Nothing to do here. RenderWidget created the |input_handler| and will take
976 // ownership of it. We just verify here that we don't already have an input
977 // handler.
978 DCHECK(!input_handler_);
979}
980
fsamuel72464894f2015-12-15 06:59:31981void RenderWidget::UpdateTextInputState(ShowIme show_ime,
982 ChangeSource change_source) {
983 TRACE_EVENT0("renderer", "RenderWidget::UpdateTextInputState");
984 if (ime_event_guard_) {
985 // show_ime should still be effective even if it was set inside the IME
986 // event guard.
987 if (show_ime == ShowIme::IF_NEEDED) {
988 ime_event_guard_->set_show_ime(true);
989 }
990 return;
991 }
992
993 ui::TextInputType new_type = GetTextInputType();
994 if (IsDateTimeInput(new_type))
995 return; // Not considered as a text input field in WebKit/Chromium.
996
997 blink::WebTextInputInfo new_info;
998 if (webwidget_)
999 new_info = webwidget_->textInputInfo();
1000 const ui::TextInputMode new_mode = ConvertInputMode(new_info.inputMode);
1001
1002 bool new_can_compose_inline = CanComposeInline();
1003
1004 // Only sends text input params if they are changed or if the ime should be
1005 // shown.
1006 if (show_ime == ShowIme::IF_NEEDED ||
1007 (text_input_type_ != new_type || text_input_mode_ != new_mode ||
1008 text_input_info_ != new_info ||
1009 can_compose_inline_ != new_can_compose_inline)
1010#if defined(OS_ANDROID)
1011 || text_field_is_dirty_
1012#endif
1013 ) {
1014 ViewHostMsg_TextInputState_Params params;
1015 params.type = new_type;
1016 params.mode = new_mode;
1017 params.flags = new_info.flags;
1018 params.value = new_info.value.utf8();
1019 params.selection_start = new_info.selectionStart;
1020 params.selection_end = new_info.selectionEnd;
1021 params.composition_start = new_info.compositionStart;
1022 params.composition_end = new_info.compositionEnd;
1023 params.can_compose_inline = new_can_compose_inline;
1024 params.show_ime_if_needed = (show_ime == ShowIme::IF_NEEDED);
1025#if defined(USE_AURA)
1026 params.is_non_ime_change = true;
1027#endif
1028#if defined(OS_ANDROID)
1029 params.is_non_ime_change =
1030 (change_source == ChangeSource::FROM_NON_IME) || text_field_is_dirty_;
1031 if (params.is_non_ime_change)
1032 OnImeEventSentForAck(new_info);
1033 text_field_is_dirty_ = false;
1034#endif
1035 Send(new ViewHostMsg_TextInputStateChanged(routing_id(), params));
1036
1037 text_input_info_ = new_info;
1038 text_input_type_ = new_type;
1039 text_input_mode_ = new_mode;
1040 can_compose_inline_ = new_can_compose_inline;
1041 text_input_flags_ = new_info.flags;
1042 }
1043}
1044
1045bool RenderWidget::WillHandleGestureEvent(const blink::WebGestureEvent& event) {
1046 return false;
1047}
1048
1049bool RenderWidget::WillHandleMouseEvent(const blink::WebMouseEvent& event) {
1050 return false;
[email protected]fd847792013-10-24 17:12:351051}
1052
initial.commit09911bf2008-07-26 23:55:291053///////////////////////////////////////////////////////////////////////////////
mfomitchev2600fd7c2016-02-17 20:53:391054// RenderWidgetScreenMetricsDelegate
1055
1056void RenderWidget::Redraw() {
1057 set_next_paint_is_resize_ack();
1058 if (compositor_)
1059 compositor_->SetNeedsRedrawRect(gfx::Rect(size_));
1060}
1061
1062void RenderWidget::Resize(const ResizeParams& params) {
1063 screen_info_ = params.screen_info;
1064 SetDeviceScaleFactor(screen_info_.deviceScaleFactor);
1065
1066 if (resizing_mode_selector_->NeverUsesSynchronousResize()) {
1067 // A resize ack shouldn't be requested if we have not ACK'd the previous
1068 // one.
1069 DCHECK(!params.needs_resize_ack || !next_paint_is_resize_ack());
1070 }
1071
1072 // Ignore this during shutdown.
1073 if (!webwidget_)
1074 return;
1075
1076 if (compositor_)
1077 compositor_->setViewportSize(params.physical_backing_size);
1078
1079 bool resized = size_ != params.new_size ||
1080 physical_backing_size_ != params.physical_backing_size;
1081
1082 size_ = params.new_size;
1083 physical_backing_size_ = params.physical_backing_size;
1084
1085 top_controls_shrink_blink_size_ = params.top_controls_shrink_blink_size;
1086 top_controls_height_ = params.top_controls_height;
1087 visible_viewport_size_ = params.visible_viewport_size;
1088 resizer_rect_ = params.resizer_rect;
1089
1090 // NOTE: We may have entered fullscreen mode without changing our size.
1091 bool fullscreen_change =
1092 is_fullscreen_granted_ != params.is_fullscreen_granted;
1093 is_fullscreen_granted_ = params.is_fullscreen_granted;
1094 display_mode_ = params.display_mode;
1095
1096 webwidget_->setTopControlsHeight(params.top_controls_height,
1097 top_controls_shrink_blink_size_);
1098
1099 if (resized) {
1100 gfx::Size new_widget_size =
1101 IsUseZoomForDSFEnabled() ? physical_backing_size_ : size_;
1102 // When resizing, we want to wait to paint before ACK'ing the resize. This
1103 // ensures that we only resize as fast as we can paint. We only need to
1104 // send an ACK if we are resized to a non-empty rect.
1105 webwidget_->resize(new_widget_size);
1106 }
1107 WebSize visual_viewport_size;
1108
1109 if (IsUseZoomForDSFEnabled()) {
1110 visual_viewport_size = gfx::ScaleToCeiledSize(params.visible_viewport_size,
1111 device_scale_factor_);
1112 } else {
1113 visual_viewport_size = visible_viewport_size_;
1114 }
1115
1116 webwidget()->resizeVisualViewport(visual_viewport_size);
1117
1118 if (params.new_size.IsEmpty() || params.physical_backing_size.IsEmpty()) {
1119 // In this case there is no paint/composite and therefore no
1120 // ViewHostMsg_UpdateRect to send the resize ack with. We'd need to send the
1121 // ack through a fake ViewHostMsg_UpdateRect or a different message.
1122 DCHECK(!params.needs_resize_ack);
1123 }
1124
1125 // Send the Resize_ACK flag once we paint again if requested.
1126 if (params.needs_resize_ack)
1127 set_next_paint_is_resize_ack();
1128
1129 if (fullscreen_change)
1130 DidToggleFullscreen();
1131
1132 // If a resize ack is requested and it isn't set-up, then no more resizes will
1133 // come in and in general things will go wrong.
1134 DCHECK(!params.needs_resize_ack || next_paint_is_resize_ack());
1135}
1136
1137void RenderWidget::SetScreenMetricsEmulationParameters(
1138 bool enabled,
1139 const blink::WebDeviceEmulationParams& params) {
1140 // This is only supported in RenderView.
1141 NOTREACHED();
1142}
1143
1144void RenderWidget::SetScreenRects(const gfx::Rect& view_screen_rect,
1145 const gfx::Rect& window_screen_rect) {
1146 view_screen_rect_ = view_screen_rect;
1147 window_screen_rect_ = window_screen_rect;
1148}
1149
1150///////////////////////////////////////////////////////////////////////////////
[email protected]f98d7e3c2010-09-13 22:30:461151// WebWidgetClient
initial.commit09911bf2008-07-26 23:55:291152
[email protected]244ac1892011-12-02 17:04:471153void RenderWidget::didAutoResize(const WebSize& new_size) {
oshima33ec97cd2015-12-14 19:40:241154 WebRect new_size_in_window(0, 0, new_size.width, new_size.height);
1155 convertViewportToWindow(&new_size_in_window);
1156 if (size_.width() != new_size_in_window.width ||
1157 size_.height() != new_size_in_window.height) {
1158 size_ = gfx::Size(new_size_in_window.width, new_size_in_window.height);
[email protected]20fbfc22013-05-08 20:50:581159
[email protected]5b45ad42013-10-25 00:42:041160 if (resizing_mode_selector_->is_synchronous_mode()) {
oshima33ec97cd2015-12-14 19:40:241161 gfx::Rect new_pos(rootWindowRect().x,
1162 rootWindowRect().y,
1163 size_.width(),
1164 size_.height());
[email protected]eac2b362013-05-22 07:01:451165 view_screen_rect_ = new_pos;
1166 window_screen_rect_ = new_pos;
[email protected]8be1c582013-03-06 00:55:031167 }
[email protected]20fbfc22013-05-08 20:50:581168
[email protected]eac2b362013-05-22 07:01:451169 AutoResizeCompositor();
[email protected]20fbfc22013-05-08 20:50:581170
[email protected]5b45ad42013-10-25 00:42:041171 if (!resizing_mode_selector_->is_synchronous_mode())
[email protected]20fbfc22013-05-08 20:50:581172 need_update_rect_for_auto_resize_ = true;
[email protected]ea3ee0a2012-05-15 03:43:091173 }
[email protected]244ac1892011-12-02 17:04:471174}
1175
[email protected]3a1c8a8032013-03-18 22:35:321176void RenderWidget::AutoResizeCompositor() {
danakjddaec912015-09-25 19:38:401177 physical_backing_size_ = gfx::ScaleToCeiledSize(size_, device_scale_factor_);
[email protected]97e1bf72013-03-06 14:06:051178 if (compositor_)
oshima750cb4342015-10-31 00:59:011179 compositor_->setViewportSize(physical_backing_size_);
[email protected]97e1bf72013-03-06 14:06:051180}
1181
[email protected]e195e582013-03-08 01:32:591182void RenderWidget::initializeLayerTreeView() {
[email protected]aeeedad2014-08-22 18:16:221183 DCHECK(!host_closing_);
1184
fsamuel78f86e42016-01-20 04:10:231185 compositor_ = RenderWidgetCompositor::Create(this, device_scale_factor_,
1186 compositor_deps_);
oshima750cb4342015-10-31 00:59:011187 compositor_->setViewportSize(physical_backing_size_);
oshimad5279032015-12-16 18:22:331188 OnDeviceScaleFactorChanged();
sievers71c62dd52015-10-07 01:44:391189 // For background pages and certain tests, we don't want to trigger
1190 // OutputSurface creation.
1191 if (compositor_never_visible_ || !RenderThreadImpl::current())
1192 compositor_->SetNeverVisible();
1193
pimanc4af3072015-10-02 03:45:591194 StartCompositor();
[email protected]e195e582013-03-08 01:32:591195}
1196
ennef3c58142014-12-09 21:44:381197void RenderWidget::WillCloseLayerTreeView() {
1198 if (host_closing_)
1199 return;
1200
1201 // Prevent new compositors or output surfaces from being created.
1202 host_closing_ = true;
1203
[email protected]aeeedad2014-08-22 18:16:221204 // Always send this notification to prevent new layer tree views from
1205 // being created, even if one hasn't been created yet.
1206 if (webwidget_)
1207 webwidget_->willCloseLayerTreeView();
[email protected]aeeedad2014-08-22 18:16:221208}
1209
[email protected]180ef242013-11-07 06:50:461210blink::WebLayerTreeView* RenderWidget::layerTreeView() {
[email protected]ba91a792013-02-06 09:48:281211 return compositor_.get();
[email protected]8926c602013-01-23 05:32:061212}
1213
dglazkovf0e1d6d2015-10-10 02:13:481214void RenderWidget::didMeaningfulLayout(blink::WebMeaningfulLayout layout_type) {
1215 if (layout_type == blink::WebMeaningfulLayout::VisuallyNonEmpty) {
1216 QueueMessage(new ViewHostMsg_DidFirstVisuallyNonEmptyPaint(routing_id_),
1217 MESSAGE_DELIVERY_POLICY_WITH_VISUAL_STATE);
1218 }
dglazkov79c426102015-08-31 21:22:431219
dglazkovf0e1d6d2015-10-10 02:13:481220 FOR_EACH_OBSERVER(RenderFrameImpl, render_frames_,
1221 DidMeaningfulLayout(layout_type));
dglazkov79c426102015-08-31 21:22:431222}
1223
jdduke491a3f0c2015-06-15 23:30:261224void RenderWidget::ScheduleComposite() {
1225 if (compositor_ &&
1226 compositor_deps_->GetCompositorImplThreadTaskRunner().get()) {
1227 compositor_->setNeedsAnimate();
1228 }
1229}
1230
1231void RenderWidget::ScheduleCompositeWithForcedRedraw() {
1232 if (compositor_) {
1233 // Regardless of whether threaded compositing is enabled, always
1234 // use this mechanism to force the compositor to redraw. However,
1235 // the invalidation code path below is still needed for the
1236 // non-threaded case.
1237 compositor_->SetNeedsForcedRedraw();
1238 }
1239 ScheduleComposite();
[email protected]6fceb912013-02-15 06:24:151240}
1241
[email protected]586871b2014-07-22 17:05:111242// static
1243scoped_ptr<cc::SwapPromise> RenderWidget::QueueMessageImpl(
1244 IPC::Message* msg,
1245 MessageDeliveryPolicy policy,
1246 FrameSwapMessageQueue* frame_swap_message_queue,
1247 scoped_refptr<IPC::SyncMessageFilter> sync_message_filter,
[email protected]586871b2014-07-22 17:05:111248 int source_frame_number) {
[email protected]586871b2014-07-22 17:05:111249 bool first_message_for_frame = false;
1250 frame_swap_message_queue->QueueMessageForFrame(policy,
1251 source_frame_number,
1252 make_scoped_ptr(msg),
1253 &first_message_for_frame);
1254 if (first_message_for_frame) {
1255 scoped_ptr<cc::SwapPromise> promise(new QueueMessageSwapPromise(
1256 sync_message_filter, frame_swap_message_queue, source_frame_number));
dcheng4b6b5ff2014-10-16 00:42:061257 return promise;
[email protected]586871b2014-07-22 17:05:111258 }
dcheng4b6b5ff2014-10-16 00:42:061259 return nullptr;
[email protected]586871b2014-07-22 17:05:111260}
1261
1262void RenderWidget::QueueMessage(IPC::Message* msg,
1263 MessageDeliveryPolicy policy) {
1264 // RenderThreadImpl::current() is NULL in some tests.
1265 if (!compositor_ || !RenderThreadImpl::current()) {
1266 Send(msg);
1267 return;
1268 }
1269
1270 scoped_ptr<cc::SwapPromise> swap_promise =
1271 QueueMessageImpl(msg,
1272 policy,
dcheng58867a92014-08-26 02:50:221273 frame_swap_message_queue_.get(),
[email protected]586871b2014-07-22 17:05:111274 RenderThreadImpl::current()->sync_message_filter(),
[email protected]586871b2014-07-22 17:05:111275 compositor_->GetSourceFrameNumber());
1276
1277 if (swap_promise) {
dcheng07945f632015-12-26 07:59:321278 compositor_->QueueSwapPromise(std::move(swap_promise));
igsollaeab34cc2015-02-20 11:33:351279 // Request a commit. This might either A) request a commit ahead of time
1280 // or B) request a commit which is not needed because there are not
1281 // pending updates. If B) then the commit will be skipped and the swap
1282 // promises will be broken (see EarlyOut_NoUpdates). To achieve that we
1283 // call SetNeedsUpdateLayers instead of SetNeedsCommit so that
1284 // can_cancel_commit is not unset.
1285 compositor_->SetNeedsUpdateLayers();
[email protected]586871b2014-07-22 17:05:111286 }
1287}
1288
[email protected]4873c7d2009-07-16 06:36:281289void RenderWidget::didChangeCursor(const WebCursorInfo& cursor_info) {
[email protected]7c51b0ee2009-07-08 21:49:301290 // TODO(darin): Eliminate this temporary.
[email protected]9ec87712013-05-24 23:23:521291 WebCursor cursor;
tfarina75a0abf2015-10-06 15:07:181292 InitializeCursorFromWebCursorInfo(&cursor, cursor_info);
initial.commit09911bf2008-07-26 23:55:291293 // Only send a SetCursor message if we need to make a change.
1294 if (!current_cursor_.IsEqual(cursor)) {
1295 current_cursor_ = cursor;
1296 Send(new ViewHostMsg_SetCursor(routing_id_, cursor));
1297 }
1298}
1299
1300// We are supposed to get a single call to Show for a newly created RenderWidget
1301// that was created via RenderWidget::CreateWebView. So, we wait until this
1302// point to dispatch the ShowWidget message.
1303//
1304// This method provides us with the information about how to display the newly
[email protected]5f9de5882011-09-30 23:36:281305// created RenderWidget (i.e., as a blocked popup or as a new tab).
initial.commit09911bf2008-07-26 23:55:291306//
[email protected]4873c7d2009-07-16 06:36:281307void RenderWidget::show(WebNavigationPolicy) {
initial.commit09911bf2008-07-26 23:55:291308 DCHECK(!did_show_) << "received extraneous Show call";
1309 DCHECK(routing_id_ != MSG_ROUTING_NONE);
1310 DCHECK(opener_id_ != MSG_ROUTING_NONE);
1311
[email protected]8de12d942010-11-17 20:42:441312 if (did_show_)
1313 return;
1314
1315 did_show_ = true;
bokanc007c3a2015-02-03 07:15:561316 // NOTE: initial_rect_ may still have its default values at this point, but
[email protected]8de12d942010-11-17 20:42:441317 // that's okay. It'll be ignored if as_popup is false, or the browser
1318 // process will impose a default position otherwise.
bokanc007c3a2015-02-03 07:15:561319 Send(new ViewHostMsg_ShowWidget(opener_id_, routing_id_, initial_rect_));
1320 SetPendingWindowRect(initial_rect_);
initial.commit09911bf2008-07-26 23:55:291321}
1322
[email protected]4873c7d2009-07-16 06:36:281323void RenderWidget::didFocus() {
initial.commit09911bf2008-07-26 23:55:291324}
1325
[email protected]2533ce12009-05-09 00:02:241326void RenderWidget::DoDeferredClose() {
ennef3c58142014-12-09 21:44:381327 WillCloseLayerTreeView();
[email protected]2533ce12009-05-09 00:02:241328 Send(new ViewHostMsg_Close(routing_id_));
1329}
1330
dgozmancf9039cd2015-04-06 12:01:311331void RenderWidget::NotifyOnClose() {
1332 FOR_EACH_OBSERVER(RenderFrameImpl, render_frames_, WidgetWillClose());
1333}
1334
[email protected]4873c7d2009-07-16 06:36:281335void RenderWidget::closeWidgetSoon() {
skyostiled8969c2015-07-20 16:57:081336 DCHECK(content::RenderThread::Get());
[email protected]e1c3a552012-05-04 20:51:321337 if (is_swapped_out_) {
1338 // This widget is currently swapped out, and the active widget is in a
1339 // different process. Have the browser route the close request to the
1340 // active widget instead, so that the correct unload handlers are run.
1341 Send(new ViewHostMsg_RouteCloseEvent(routing_id_));
1342 return;
1343 }
1344
initial.commit09911bf2008-07-26 23:55:291345 // If a page calls window.close() twice, we'll end up here twice, but that's
1346 // OK. It is safe to send multiple Close messages.
1347
[email protected]2533ce12009-05-09 00:02:241348 // Ask the RenderWidgetHost to initiate close. We could be called from deep
1349 // in Javascript. If we ask the RendwerWidgetHost to close now, the window
1350 // could be closed before the JS finishes executing. So instead, post a
1351 // message back to the message loop, which won't run until the JS is
1352 // complete, and then the Close message can be sent.
skyostiled8969c2015-07-20 16:57:081353 base::ThreadTaskRunnerHandle::Get()->PostTask(
[email protected]32876ae2011-11-15 22:25:211354 FROM_HERE, base::Bind(&RenderWidget::DoDeferredClose, this));
initial.commit09911bf2008-07-26 23:55:291355}
1356
[email protected]9017d7852013-11-21 17:47:351357void RenderWidget::QueueSyntheticGesture(
1358 scoped_ptr<SyntheticGestureParams> gesture_params,
1359 const SyntheticGestureCompletionCallback& callback) {
1360 DCHECK(!callback.is_null());
1361
1362 pending_synthetic_gesture_callbacks_.push(callback);
1363
1364 SyntheticGesturePacket gesture_packet;
dcheng07945f632015-12-26 07:59:321365 gesture_packet.set_gesture_params(std::move(gesture_params));
[email protected]9017d7852013-11-21 17:47:351366
1367 Send(new InputHostMsg_QueueSyntheticGesture(routing_id_, gesture_packet));
1368}
1369
initial.commit09911bf2008-07-26 23:55:291370void RenderWidget::Close() {
[email protected]404630b2014-07-03 19:33:031371 screen_metrics_emulator_.reset();
ennef3c58142014-12-09 21:44:381372 WillCloseLayerTreeView();
1373 compositor_.reset();
initial.commit09911bf2008-07-26 23:55:291374 if (webwidget_) {
[email protected]4873c7d2009-07-16 06:36:281375 webwidget_->close();
initial.commit09911bf2008-07-26 23:55:291376 webwidget_ = NULL;
1377 }
1378}
1379
[email protected]4873c7d2009-07-16 06:36:281380WebRect RenderWidget::windowRect() {
1381 if (pending_window_rect_count_)
1382 return pending_window_rect_;
[email protected]2533ce12009-05-09 00:02:241383
[email protected]80ad8622012-11-07 16:33:031384 return view_screen_rect_;
initial.commit09911bf2008-07-26 23:55:291385}
1386
[email protected]180ef242013-11-07 06:50:461387void RenderWidget::setToolTipText(const blink::WebString& text,
[email protected]8a9d6ca32011-06-06 20:11:301388 WebTextDirection hint) {
[email protected]5a395b72011-08-08 19:13:541389 Send(new ViewHostMsg_SetTooltipText(routing_id_, text, hint));
[email protected]8a9d6ca32011-06-06 20:11:301390}
1391
oshima33ec97cd2015-12-14 19:40:241392void RenderWidget::setWindowRect(const WebRect& rect_in_screen) {
1393 WebRect window_rect = rect_in_screen;
[email protected]b2e4c70132013-10-03 02:07:511394 if (popup_origin_scale_for_emulation_) {
1395 float scale = popup_origin_scale_for_emulation_;
bokanc007c3a2015-02-03 07:15:561396 window_rect.x = popup_screen_origin_for_emulation_.x() +
1397 (window_rect.x - popup_view_origin_for_emulation_.x()) * scale;
1398 window_rect.y = popup_screen_origin_for_emulation_.y() +
1399 (window_rect.y - popup_view_origin_for_emulation_.y()) * scale;
[email protected]b2e4c70132013-10-03 02:07:511400 }
1401
[email protected]5b45ad42013-10-25 00:42:041402 if (!resizing_mode_selector_->is_synchronous_mode()) {
[email protected]ec951b9d2013-10-20 06:21:201403 if (did_show_) {
bokanc007c3a2015-02-03 07:15:561404 Send(new ViewHostMsg_RequestMove(routing_id_, window_rect));
1405 SetPendingWindowRect(window_rect);
[email protected]8be1c582013-03-06 00:55:031406 } else {
bokanc007c3a2015-02-03 07:15:561407 initial_rect_ = window_rect;
[email protected]8be1c582013-03-06 00:55:031408 }
initial.commit09911bf2008-07-26 23:55:291409 } else {
bokanc007c3a2015-02-03 07:15:561410 SetWindowRectSynchronously(window_rect);
initial.commit09911bf2008-07-26 23:55:291411 }
1412}
1413
[email protected]2533ce12009-05-09 00:02:241414void RenderWidget::SetPendingWindowRect(const WebRect& rect) {
1415 pending_window_rect_ = rect;
1416 pending_window_rect_count_++;
1417}
1418
[email protected]4873c7d2009-07-16 06:36:281419WebRect RenderWidget::rootWindowRect() {
[email protected]2533ce12009-05-09 00:02:241420 if (pending_window_rect_count_) {
1421 // NOTE(mbelshe): If there is a pending_window_rect_, then getting
1422 // the RootWindowRect is probably going to return wrong results since the
1423 // browser may not have processed the Move yet. There isn't really anything
1424 // good to do in this case, and it shouldn't happen - since this size is
1425 // only really needed for windowToScreen, which is only used for Popups.
[email protected]4873c7d2009-07-16 06:36:281426 return pending_window_rect_;
[email protected]2533ce12009-05-09 00:02:241427 }
1428
[email protected]80ad8622012-11-07 16:33:031429 return window_screen_rect_;
[email protected]d4547452008-08-28 18:36:371430}
1431
[email protected]4873c7d2009-07-16 06:36:281432WebRect RenderWidget::windowResizerRect() {
1433 return resizer_rect_;
[email protected]c04b6362008-11-21 18:54:191434}
1435
[email protected]fa7b1dc2010-06-23 17:53:041436void RenderWidget::OnImeSetComposition(
[email protected]fcf75d42013-12-03 20:11:261437 const base::string16& text,
[email protected]fa7b1dc2010-06-23 17:53:041438 const std::vector<WebCompositionUnderline>& underlines,
chongz7eb752802016-01-27 21:28:071439 const gfx::Range& replacement_range,
[email protected]fa7b1dc2010-06-23 17:53:041440 int selection_start, int selection_end) {
[email protected]0d1ebed12013-08-05 22:01:131441 if (!ShouldHandleImeEvent())
[email protected]4873c7d2009-07-16 06:36:281442 return;
[email protected]66fca5bc2013-05-23 06:58:291443 ImeEventGuard guard(this);
[email protected]88dbe32f2013-06-20 23:31:361444 if (!webwidget_->setComposition(
[email protected]fa7b1dc2010-06-23 17:53:041445 text, WebVector<WebCompositionUnderline>(underlines),
1446 selection_start, selection_end)) {
1447 // If we failed to set the composition text, then we need to let the browser
1448 // process to cancel the input method's ongoing composition session, to make
1449 // sure we are in a consistent state.
[email protected]a2214eb2014-06-23 18:31:221450 Send(new InputHostMsg_ImeCancelComposition(routing_id()));
[email protected]7f00efa2010-04-15 05:01:261451 }
[email protected]88dbe32f2013-06-20 23:31:361452 UpdateCompositionInfo(true);
[email protected]fa7b1dc2010-06-23 17:53:041453}
1454
[email protected]fcf75d42013-12-03 20:11:261455void RenderWidget::OnImeConfirmComposition(const base::string16& text,
[email protected]db4fc1e2013-09-06 20:01:511456 const gfx::Range& replacement_range,
[email protected]0e45bd02013-07-12 20:20:021457 bool keep_selection) {
[email protected]0d1ebed12013-08-05 22:01:131458 if (!ShouldHandleImeEvent())
[email protected]d0be63772011-12-20 23:18:041459 return;
[email protected]66fca5bc2013-05-23 06:58:291460 ImeEventGuard guard(this);
fsamuele8326c742016-01-12 00:49:391461 input_handler_->set_handling_input_event(true);
[email protected]0e45bd02013-07-12 20:20:021462 if (text.length())
1463 webwidget_->confirmComposition(text);
1464 else if (keep_selection)
1465 webwidget_->confirmComposition(WebWidget::KeepSelection);
1466 else
1467 webwidget_->confirmComposition(WebWidget::DoNotKeepSelection);
fsamuele8326c742016-01-12 00:49:391468 input_handler_->set_handling_input_event(false);
[email protected]88dbe32f2013-06-20 23:31:361469 UpdateCompositionInfo(true);
initial.commit09911bf2008-07-26 23:55:291470}
1471
oshimad5279032015-12-16 18:22:331472void RenderWidget::OnDeviceScaleFactorChanged() {
1473 if (!compositor_)
1474 return;
1475
1476 if (IsUseZoomForDSFEnabled())
1477 compositor_->SetPaintedDeviceScaleFactor(device_scale_factor_);
1478 else
1479 compositor_->setDeviceScaleFactor(device_scale_factor_);
1480}
1481
[email protected]0bc1f572013-04-17 01:46:311482void RenderWidget::OnRepaint(gfx::Size size_to_paint) {
[email protected]ec7dc112008-08-06 05:30:121483 // During shutdown we can just ignore this message.
1484 if (!webwidget_)
1485 return;
1486
[email protected]0bc1f572013-04-17 01:46:311487 // Even if the browser provides an empty damage rect, it's still expecting to
1488 // receive a repaint ack so just damage the entire widget bounds.
1489 if (size_to_paint.IsEmpty()) {
1490 size_to_paint = size_;
1491 }
1492
[email protected]ec7dc112008-08-06 05:30:121493 set_next_paint_is_repaint_ack();
[email protected]aca33f4f2014-05-17 17:08:051494 if (compositor_)
[email protected]0bc1f572013-04-17 01:46:311495 compositor_->SetNeedsRedrawRect(gfx::Rect(size_to_paint));
[email protected]ec7dc112008-08-06 05:30:121496}
1497
[email protected]79fa22e2013-08-23 15:18:121498void RenderWidget::OnSyntheticGestureCompleted() {
[email protected]9017d7852013-11-21 17:47:351499 DCHECK(!pending_synthetic_gesture_callbacks_.empty());
1500
1501 pending_synthetic_gesture_callbacks_.front().Run();
1502 pending_synthetic_gesture_callbacks_.pop();
[email protected]0e241b4b2012-08-18 09:06:271503}
1504
[email protected]4873c7d2009-07-16 06:36:281505void RenderWidget::OnSetTextDirection(WebTextDirection direction) {
[email protected]07f953332009-03-25 04:31:111506 if (!webwidget_)
1507 return;
[email protected]4873c7d2009-07-16 06:36:281508 webwidget_->setTextDirection(direction);
[email protected]07f953332009-03-25 04:31:111509}
1510
[email protected]80ad8622012-11-07 16:33:031511void RenderWidget::OnUpdateScreenRects(const gfx::Rect& view_screen_rect,
1512 const gfx::Rect& window_screen_rect) {
[email protected]b2e4c70132013-10-03 02:07:511513 if (screen_metrics_emulator_) {
mfomitchev2600fd7c2016-02-17 20:53:391514 screen_metrics_emulator_->OnUpdateScreenRects(view_screen_rect,
1515 window_screen_rect);
[email protected]b2e4c70132013-10-03 02:07:511516 } else {
mfomitchev2600fd7c2016-02-17 20:53:391517 SetScreenRects(view_screen_rect, window_screen_rect);
[email protected]b2e4c70132013-10-03 02:07:511518 }
[email protected]80ad8622012-11-07 16:33:031519 Send(new ViewHostMsg_UpdateScreenRects_ACK(routing_id()));
1520}
1521
kenrbb4e2a3b2015-05-14 15:05:051522void RenderWidget::OnSetSurfaceIdNamespace(uint32_t surface_id_namespace) {
1523 if (compositor_)
1524 compositor_->SetSurfaceIdNamespace(surface_id_namespace);
1525}
1526
dtrainor5ef644e2015-11-19 00:12:471527void RenderWidget::OnHandleCompositorProto(const std::vector<uint8_t>& proto) {
1528 if (compositor_)
1529 compositor_->OnHandleCompositorProto(proto);
1530}
1531
[email protected]adb362312014-06-28 06:04:241532void RenderWidget::showImeIfNeeded() {
1533 OnShowImeIfNeeded();
[email protected]0d1ebed12013-08-05 22:01:131534}
1535
fsamuel72464894f2015-12-15 06:59:311536ui::TextInputType RenderWidget::GetTextInputType() {
1537 if (webwidget_)
1538 return WebKitToUiTextInputType(webwidget_->textInputType());
1539 return ui::TEXT_INPUT_TYPE_NONE;
1540}
1541
1542void RenderWidget::UpdateCompositionInfo(bool should_update_range) {
1543#if defined(OS_ANDROID)
1544// TODO(yukawa): Start sending character bounds when the browser side
1545// implementation becomes ready (crbug.com/424866).
1546#else
1547 TRACE_EVENT0("renderer", "RenderWidget::UpdateCompositionInfo");
1548 gfx::Range range = gfx::Range();
1549 if (should_update_range) {
1550 GetCompositionRange(&range);
1551 } else {
1552 range = composition_range_;
1553 }
1554 std::vector<gfx::Rect> character_bounds;
1555 GetCompositionCharacterBounds(&character_bounds);
1556
1557 if (!ShouldUpdateCompositionInfo(range, character_bounds))
1558 return;
1559 composition_character_bounds_ = character_bounds;
1560 composition_range_ = range;
1561 Send(new InputHostMsg_ImeCompositionRangeChanged(
1562 routing_id(), composition_range_, composition_character_bounds_));
1563#endif
1564}
1565
oshimaf866dab2015-12-05 00:41:541566void RenderWidget::convertViewportToWindow(blink::WebRect* rect) {
1567 if (IsUseZoomForDSFEnabled()) {
1568 float reverse = 1 / device_scale_factor_;
oshimad5279032015-12-16 18:22:331569 // TODO(oshima): We may need to allow pixel precision here as the the
oshimaf866dab2015-12-05 00:41:541570 // anchor element can be placed at half pixel.
1571 gfx::Rect window_rect =
1572 gfx::ScaleToEnclosedRect(gfx::Rect(*rect), reverse);
1573 rect->x = window_rect.x();
1574 rect->y = window_rect.y();
1575 rect->width = window_rect.width();
1576 rect->height = window_rect.height();
1577 }
1578}
1579
oshimaa6985b62016-01-27 08:58:301580void RenderWidget::convertWindowToViewport(blink::WebFloatRect* rect) {
1581 if (IsUseZoomForDSFEnabled()) {
1582 rect->x *= device_scale_factor_;
1583 rect->y *= device_scale_factor_;
1584 rect->width *= device_scale_factor_;
1585 rect->height *= device_scale_factor_;
1586 }
1587}
1588
[email protected]adb362312014-06-28 06:04:241589void RenderWidget::OnShowImeIfNeeded() {
1590#if defined(OS_ANDROID) || defined(USE_AURA)
fsamuel72464894f2015-12-15 06:59:311591 UpdateTextInputState(ShowIme::IF_NEEDED, ChangeSource::FROM_NON_IME);
[email protected]adb362312014-06-28 06:04:241592#endif
rouslanf7ebd8832015-01-22 01:54:141593
1594// TODO(rouslan): Fix ChromeOS and Windows 8 behavior of autofill popup with
1595// virtual keyboard.
1596#if !defined(OS_ANDROID)
1597 FocusChangeComplete();
1598#endif
[email protected]adb362312014-06-28 06:04:241599}
1600
1601#if defined(OS_ANDROID)
changwan3a841162015-08-11 02:53:371602void RenderWidget::OnImeEventSentForAck(const blink::WebTextInputInfo& info) {
1603 text_input_info_history_.push_back(info);
[email protected]0d1ebed12013-08-05 22:01:131604}
1605
1606void RenderWidget::OnImeEventAck() {
changwan3a841162015-08-11 02:53:371607 DCHECK_GE(text_input_info_history_.size(), 1u);
1608 text_input_info_history_.pop_front();
[email protected]2384b6c2013-02-28 23:58:511609}
[email protected]105dffb42013-02-20 03:46:211610#endif
1611
[email protected]0d1ebed12013-08-05 22:01:131612bool RenderWidget::ShouldHandleImeEvent() {
1613#if defined(OS_ANDROID)
changwan3a841162015-08-11 02:53:371614 if (!webwidget_)
1615 return false;
1616
1617 // We cannot handle IME events if there is any chance that the event we are
1618 // receiving here from the browser is based on the state that is different
1619 // from our current one as indicated by |text_input_info_|.
1620 // The states the browser might be in are:
1621 // text_input_info_history_[0] - current state ack'd by browser
1622 // text_input_info_history_[1...N] - pending state changes
1623 for (size_t i = 0u; i < text_input_info_history_.size() - 1u; ++i) {
1624 if (text_input_info_history_[i] != text_input_info_)
1625 return false;
1626 }
1627 return true;
[email protected]0d1ebed12013-08-05 22:01:131628#else
1629 return !!webwidget_;
1630#endif
1631}
1632
[email protected]468ac582012-11-20 00:53:191633void RenderWidget::SetDeviceScaleFactor(float device_scale_factor) {
1634 if (device_scale_factor_ == device_scale_factor)
1635 return;
1636
1637 device_scale_factor_ = device_scale_factor;
oshimad5279032015-12-16 18:22:331638
1639 OnDeviceScaleFactorChanged();
1640
jdduke491a3f0c2015-06-15 23:30:261641 ScheduleComposite();
[email protected]468ac582012-11-20 00:53:191642}
1643
[email protected]28ed6b32014-06-08 02:16:271644bool RenderWidget::SetDeviceColorProfile(
1645 const std::vector<char>& color_profile) {
1646 if (device_color_profile_ == color_profile)
1647 return false;
1648
1649 device_color_profile_ = color_profile;
1650 return true;
1651}
1652
noeldb4df152014-09-16 17:45:201653void RenderWidget::ResetDeviceColorProfileForTesting() {
1654 if (!device_color_profile_.empty())
1655 device_color_profile_.clear();
1656 device_color_profile_.push_back('0');
1657}
1658
[email protected]fcdc5642014-05-09 14:32:241659void RenderWidget::OnOrientationChange() {
1660}
1661
[email protected]ceb36f7d2012-10-31 18:33:241662gfx::Vector2d RenderWidget::GetScrollOffset() {
[email protected]d54169e92011-01-21 09:19:521663 // Bare RenderWidgets don't support scroll offset.
[email protected]ceb36f7d2012-10-31 18:33:241664 return gfx::Vector2d();
[email protected]d54169e92011-01-21 09:19:521665}
1666
[email protected]bee16aab2009-08-26 15:55:031667void RenderWidget::SetHidden(bool hidden) {
1668 if (is_hidden_ == hidden)
1669 return;
1670
jdduke8fac9d102014-12-20 02:40:131671 // The status has changed. Tell the RenderThread about it and ensure
1672 // throttled acks are released in case frame production ceases.
[email protected]bee16aab2009-08-26 15:55:031673 is_hidden_ = hidden;
fsamuele8326c742016-01-12 00:49:391674 input_handler_->FlushPendingInputEventAck();
jdduke8fac9d102014-12-20 02:40:131675
[email protected]bee16aab2009-08-26 15:55:031676 if (is_hidden_)
[email protected]b2db9272014-01-10 17:42:001677 RenderThreadImpl::current()->WidgetHidden();
[email protected]bee16aab2009-08-26 15:55:031678 else
[email protected]b2db9272014-01-10 17:42:001679 RenderThreadImpl::current()->WidgetRestored();
alexclarke7fa93942015-10-21 15:37:111680
1681 if (render_widget_scheduling_state_)
1682 render_widget_scheduling_state_->SetHidden(hidden);
[email protected]bee16aab2009-08-26 15:55:031683}
1684
[email protected]2b624c562011-10-27 22:58:261685void RenderWidget::DidToggleFullscreen() {
[email protected]2b624c562011-10-27 22:58:261686 if (!webwidget_)
1687 return;
1688
mikhail.pozdnyakovf2c902a2015-04-14 08:09:121689 if (is_fullscreen_granted_) {
[email protected]2b624c562011-10-27 22:58:261690 webwidget_->didEnterFullScreen();
1691 } else {
1692 webwidget_->didExitFullScreen();
1693 }
[email protected]2b624c562011-10-27 22:58:261694}
1695
[email protected]674741932009-02-04 23:44:461696bool RenderWidget::next_paint_is_resize_ack() const {
[email protected]53d3f302009-12-21 04:42:051697 return ViewHostMsg_UpdateRect_Flags::is_resize_ack(next_paint_flags_);
[email protected]674741932009-02-04 23:44:461698}
1699
[email protected]674741932009-02-04 23:44:461700void RenderWidget::set_next_paint_is_resize_ack() {
[email protected]53d3f302009-12-21 04:42:051701 next_paint_flags_ |= ViewHostMsg_UpdateRect_Flags::IS_RESIZE_ACK;
[email protected]674741932009-02-04 23:44:461702}
1703
[email protected]674741932009-02-04 23:44:461704void RenderWidget::set_next_paint_is_repaint_ack() {
[email protected]53d3f302009-12-21 04:42:051705 next_paint_flags_ |= ViewHostMsg_UpdateRect_Flags::IS_REPAINT_ACK;
[email protected]674741932009-02-04 23:44:461706}
1707
changwanf2a707b2015-10-30 08:22:161708void RenderWidget::OnImeEventGuardStart(ImeEventGuard* guard) {
1709 if (!ime_event_guard_)
1710 ime_event_guard_ = guard;
[email protected]66fca5bc2013-05-23 06:58:291711}
1712
changwanf2a707b2015-10-30 08:22:161713void RenderWidget::OnImeEventGuardFinish(ImeEventGuard* guard) {
1714 if (ime_event_guard_ != guard) {
1715#if defined(OS_ANDROID)
1716 // In case a from-IME event (e.g. touch) ends up in not-from-IME event
1717 // (e.g. long press gesture), we want to treat it as not-from-IME event
1718 // so that AdapterInputConnection can make changes to its Editable model.
1719 // Therefore, we want to mark this text state update as 'from IME' only
1720 // when all the nested events are all originating from IME.
1721 ime_event_guard_->set_from_ime(
1722 ime_event_guard_->from_ime() && guard->from_ime());
1723#endif
1724 return;
1725 }
1726 ime_event_guard_ = nullptr;
1727
[email protected]66fca5bc2013-05-23 06:58:291728 // While handling an ime event, text input state and selection bounds updates
1729 // are ignored. These must explicitly be updated once finished handling the
1730 // ime event.
1731 UpdateSelectionBounds();
[email protected]cb9e2632013-06-18 11:26:471732#if defined(OS_ANDROID)
changwanf2a707b2015-10-30 08:22:161733 UpdateTextInputState(
fsamuel72464894f2015-12-15 06:59:311734 guard->show_ime() ? ShowIme::IF_NEEDED : ShowIme::HIDE_IME,
1735 guard->from_ime() ? ChangeSource::FROM_IME : ChangeSource::FROM_NON_IME);
[email protected]cb9e2632013-06-18 11:26:471736#endif
[email protected]66fca5bc2013-05-23 06:58:291737}
1738
[email protected]7c8873e2013-02-05 08:03:011739void RenderWidget::GetSelectionBounds(gfx::Rect* focus, gfx::Rect* anchor) {
1740 WebRect focus_webrect;
1741 WebRect anchor_webrect;
1742 webwidget_->selectionBounds(focus_webrect, anchor_webrect);
oshima33ec97cd2015-12-14 19:40:241743 convertViewportToWindow(&focus_webrect);
1744 convertViewportToWindow(&anchor_webrect);
1745 *focus = focus_webrect;
1746 *anchor = anchor_webrect;
[email protected]73bf95812011-10-12 11:38:321747}
1748
[email protected]e99ef6f2011-10-16 01:13:001749void RenderWidget::UpdateSelectionBounds() {
jdduke1aebad8e2015-07-22 23:25:081750 TRACE_EVENT0("renderer", "RenderWidget::UpdateSelectionBounds");
[email protected]e99ef6f2011-10-16 01:13:001751 if (!webwidget_)
1752 return;
changwanf2a707b2015-10-30 08:22:161753 if (ime_event_guard_)
[email protected]66fca5bc2013-05-23 06:58:291754 return;
[email protected]e99ef6f2011-10-16 01:13:001755
mohsenb0eeba72015-08-09 06:20:081756#if defined(USE_AURA)
1757 // TODO(mohsen): For now, always send explicit selection IPC notifications for
1758 // Aura beucause composited selection updates are not working for webview tags
1759 // which regresses IME inside webview. Remove this when composited selection
1760 // updates are fixed for webviews. See, http://crbug.com/510568.
1761 bool send_ipc = true;
1762#else
jddukeacf809e2014-09-23 20:38:381763 // With composited selection updates, the selection bounds will be reported
1764 // directly by the compositor, in which case explicit IPC selection
1765 // notifications should be suppressed.
mohsenb0eeba72015-08-09 06:20:081766 bool send_ipc =
1767 !blink::WebRuntimeFeatures::isCompositedSelectionUpdateEnabled();
1768#endif
1769 if (send_ipc) {
jddukeacf809e2014-09-23 20:38:381770 ViewHostMsg_SelectionBounds_Params params;
1771 GetSelectionBounds(&params.anchor_rect, &params.focus_rect);
1772 if (selection_anchor_rect_ != params.anchor_rect ||
1773 selection_focus_rect_ != params.focus_rect) {
1774 selection_anchor_rect_ = params.anchor_rect;
1775 selection_focus_rect_ = params.focus_rect;
1776 webwidget_->selectionTextDirection(params.focus_dir, params.anchor_dir);
1777 params.is_anchor_first = webwidget_->isSelectionAnchorFirst();
1778 Send(new ViewHostMsg_SelectionBoundsChanged(routing_id_, params));
1779 }
[email protected]58b48a0d2012-06-13 07:01:351780 }
jddukeacf809e2014-09-23 20:38:381781
[email protected]88dbe32f2013-06-20 23:31:361782 UpdateCompositionInfo(false);
[email protected]e99ef6f2011-10-16 01:13:001783}
1784
[email protected]180ef242013-11-07 06:50:461785// Check blink::WebTextInputType and ui::TextInputType is kept in sync.
danakj365175c2016-02-06 00:37:371786STATIC_ASSERT_ENUM(blink::WebTextInputTypeNone, ui::TEXT_INPUT_TYPE_NONE);
1787STATIC_ASSERT_ENUM(blink::WebTextInputTypeText, ui::TEXT_INPUT_TYPE_TEXT);
1788STATIC_ASSERT_ENUM(blink::WebTextInputTypePassword,
1789 ui::TEXT_INPUT_TYPE_PASSWORD);
1790STATIC_ASSERT_ENUM(blink::WebTextInputTypeSearch, ui::TEXT_INPUT_TYPE_SEARCH);
1791STATIC_ASSERT_ENUM(blink::WebTextInputTypeEmail, ui::TEXT_INPUT_TYPE_EMAIL);
1792STATIC_ASSERT_ENUM(blink::WebTextInputTypeNumber, ui::TEXT_INPUT_TYPE_NUMBER);
1793STATIC_ASSERT_ENUM(blink::WebTextInputTypeTelephone,
1794 ui::TEXT_INPUT_TYPE_TELEPHONE);
1795STATIC_ASSERT_ENUM(blink::WebTextInputTypeURL, ui::TEXT_INPUT_TYPE_URL);
1796STATIC_ASSERT_ENUM(blink::WebTextInputTypeDate, ui::TEXT_INPUT_TYPE_DATE);
1797STATIC_ASSERT_ENUM(blink::WebTextInputTypeDateTime,
1798 ui::TEXT_INPUT_TYPE_DATE_TIME);
1799STATIC_ASSERT_ENUM(blink::WebTextInputTypeDateTimeLocal,
1800 ui::TEXT_INPUT_TYPE_DATE_TIME_LOCAL);
1801STATIC_ASSERT_ENUM(blink::WebTextInputTypeMonth, ui::TEXT_INPUT_TYPE_MONTH);
1802STATIC_ASSERT_ENUM(blink::WebTextInputTypeTime, ui::TEXT_INPUT_TYPE_TIME);
1803STATIC_ASSERT_ENUM(blink::WebTextInputTypeWeek, ui::TEXT_INPUT_TYPE_WEEK);
1804STATIC_ASSERT_ENUM(blink::WebTextInputTypeTextArea,
1805 ui::TEXT_INPUT_TYPE_TEXT_AREA);
1806STATIC_ASSERT_ENUM(blink::WebTextInputTypeContentEditable,
1807 ui::TEXT_INPUT_TYPE_CONTENT_EDITABLE);
1808STATIC_ASSERT_ENUM(blink::WebTextInputTypeDateTimeField,
1809 ui::TEXT_INPUT_TYPE_DATE_TIME_FIELD);
[email protected]ad26ef42011-06-17 07:59:451810
[email protected]5b739cb2012-08-21 20:35:211811ui::TextInputType RenderWidget::WebKitToUiTextInputType(
[email protected]180ef242013-11-07 06:50:461812 blink::WebTextInputType type) {
[email protected]5b739cb2012-08-21 20:35:211813 // Check the type is in the range representable by ui::TextInputType.
1814 DCHECK_LE(type, static_cast<int>(ui::TEXT_INPUT_TYPE_MAX)) <<
[email protected]180ef242013-11-07 06:50:461815 "blink::WebTextInputType and ui::TextInputType not synchronized";
[email protected]5b739cb2012-08-21 20:35:211816 return static_cast<ui::TextInputType>(type);
1817}
1818
[email protected]58b48a0d2012-06-13 07:01:351819void RenderWidget::GetCompositionCharacterBounds(
1820 std::vector<gfx::Rect>* bounds) {
1821 DCHECK(bounds);
1822 bounds->clear();
1823}
1824
[email protected]db4fc1e2013-09-06 20:01:511825void RenderWidget::GetCompositionRange(gfx::Range* range) {
[email protected]88dbe32f2013-06-20 23:31:361826 size_t location, length;
1827 if (webwidget_->compositionRange(&location, &length)) {
1828 range->set_start(location);
1829 range->set_end(location + length);
1830 } else if (webwidget_->caretOrSelectionRange(&location, &length)) {
1831 range->set_start(location);
1832 range->set_end(location + length);
1833 } else {
[email protected]db4fc1e2013-09-06 20:01:511834 *range = gfx::Range::InvalidRange();
[email protected]88dbe32f2013-06-20 23:31:361835 }
1836}
1837
[email protected]501ea13d2013-07-09 17:03:291838bool RenderWidget::ShouldUpdateCompositionInfo(
[email protected]db4fc1e2013-09-06 20:01:511839 const gfx::Range& range,
[email protected]501ea13d2013-07-09 17:03:291840 const std::vector<gfx::Rect>& bounds) {
1841 if (composition_range_ != range)
1842 return true;
1843 if (bounds.size() != composition_character_bounds_.size())
1844 return true;
1845 for (size_t i = 0; i < bounds.size(); ++i) {
1846 if (bounds[i] != composition_character_bounds_[i])
1847 return true;
1848 }
1849 return false;
1850}
[email protected]501ea13d2013-07-09 17:03:291851
[email protected]ad26ef42011-06-17 07:59:451852bool RenderWidget::CanComposeInline() {
1853 return true;
[email protected]56ea1a62011-05-30 07:05:571854}
1855
[email protected]4873c7d2009-07-16 06:36:281856WebScreenInfo RenderWidget::screenInfo() {
[email protected]842f10652012-06-06 01:54:041857 return screen_info_;
[email protected]4873c7d2009-07-16 06:36:281858}
1859
[email protected]fa7b1dc2010-06-23 17:53:041860void RenderWidget::resetInputMethod() {
[email protected]0e45bd02013-07-12 20:20:021861 ImeEventGuard guard(this);
[email protected]fa7b1dc2010-06-23 17:53:041862 // If the last text input type is not None, then we should finish any
1863 // ongoing composition regardless of the new text input type.
[email protected]ad26ef42011-06-17 07:59:451864 if (text_input_type_ != ui::TEXT_INPUT_TYPE_NONE) {
[email protected]fa7b1dc2010-06-23 17:53:041865 // If a composition text exists, then we need to let the browser process
1866 // to cancel the input method's ongoing composition session.
1867 if (webwidget_->confirmComposition())
[email protected]a2214eb2014-06-23 18:31:221868 Send(new InputHostMsg_ImeCancelComposition(routing_id()));
[email protected]fa7b1dc2010-06-23 17:53:041869 }
[email protected]d4cff272011-05-02 15:46:011870
[email protected]88dbe32f2013-06-20 23:31:361871 UpdateCompositionInfo(true);
[email protected]fa7b1dc2010-06-23 17:53:041872}
1873
donnda070f3c2015-01-16 19:54:111874#if defined(OS_ANDROID)
1875void RenderWidget::showUnhandledTapUIIfNeeded(
1876 const WebPoint& tapped_position,
1877 const WebNode& tapped_node,
1878 bool page_changed) {
fsamuele8326c742016-01-12 00:49:391879 DCHECK(input_handler_->handling_input_event());
donnda070f3c2015-01-16 19:54:111880 bool should_trigger = !page_changed && tapped_node.isTextNode() &&
donnd57e54f52015-02-26 19:03:371881 !tapped_node.isContentEditable() &&
1882 !tapped_node.isInsideFocusableElementOrARIAWidget();
donnda070f3c2015-01-16 19:54:111883 if (should_trigger) {
1884 Send(new ViewHostMsg_ShowUnhandledTapUIIfNeeded(routing_id_,
1885 tapped_position.x, tapped_position.y));
1886 }
1887}
1888#endif
1889
[email protected]c68c3e4e2013-01-24 00:36:561890void RenderWidget::didHandleGestureEvent(
1891 const WebGestureEvent& event,
1892 bool event_cancelled) {
[email protected]183e28d2014-01-20 18:18:021893#if defined(OS_ANDROID) || defined(USE_AURA)
[email protected]c68c3e4e2013-01-24 00:36:561894 if (event_cancelled)
1895 return;
[email protected]07c70d22014-08-21 08:33:461896 if (event.type == WebInputEvent::GestureTap) {
fsamuel72464894f2015-12-15 06:59:311897 UpdateTextInputState(ShowIme::IF_NEEDED, ChangeSource::FROM_NON_IME);
[email protected]07c70d22014-08-21 08:33:461898 } else if (event.type == WebInputEvent::GestureLongPress) {
1899 DCHECK(webwidget_);
1900 if (webwidget_->textInputInfo().value.isEmpty())
fsamuel72464894f2015-12-15 06:59:311901 UpdateTextInputState(ShowIme::HIDE_IME, ChangeSource::FROM_NON_IME);
[email protected]07c70d22014-08-21 08:33:461902 else
fsamuel72464894f2015-12-15 06:59:311903 UpdateTextInputState(ShowIme::IF_NEEDED, ChangeSource::FROM_NON_IME);
[email protected]c68c3e4e2013-01-24 00:36:561904 }
1905#endif
1906}
1907
sataya.m582c9ce2015-06-09 08:03:421908void RenderWidget::didOverscroll(
1909 const blink::WebFloatSize& unusedDelta,
1910 const blink::WebFloatSize& accumulatedRootOverScroll,
1911 const blink::WebFloatPoint& position,
1912 const blink::WebFloatSize& velocity) {
fsamuele8326c742016-01-12 00:49:391913 input_handler_->DidOverscrollFromBlink(unusedDelta, accumulatedRootOverScroll,
1914 position, velocity);
sataya.m582c9ce2015-06-09 08:03:421915}
1916
[email protected]7912e822014-04-16 02:37:031917void RenderWidget::StartCompositor() {
sievers71c62dd52015-10-07 01:44:391918 if (!is_hidden())
1919 compositor_->setVisible(true);
[email protected]7912e822014-04-16 02:37:031920}
1921
[email protected]29e2fb42013-07-19 01:13:471922void RenderWidget::SchedulePluginMove(const WebPluginGeometry& move) {
initial.commit09911bf2008-07-26 23:55:291923 size_t i = 0;
1924 for (; i < plugin_window_moves_.size(); ++i) {
1925 if (plugin_window_moves_[i].window == move.window) {
[email protected]16f89d02009-08-26 17:17:581926 if (move.rects_valid) {
1927 plugin_window_moves_[i] = move;
1928 } else {
1929 plugin_window_moves_[i].visible = move.visible;
1930 }
initial.commit09911bf2008-07-26 23:55:291931 break;
1932 }
1933 }
1934
1935 if (i == plugin_window_moves_.size())
1936 plugin_window_moves_.push_back(move);
1937}
[email protected]268654772009-08-06 23:02:041938
1939void RenderWidget::CleanupWindowInPluginMoves(gfx::PluginWindowHandle window) {
1940 for (WebPluginGeometryVector::iterator i = plugin_window_moves_.begin();
1941 i != plugin_window_moves_.end(); ++i) {
1942 if (i->window == window) {
1943 plugin_window_moves_.erase(i);
1944 break;
1945 }
1946 }
1947}
[email protected]67bfb83f2011-09-22 03:36:371948
[email protected]63b465922012-09-06 02:04:521949
[email protected]24ed0432013-04-24 07:50:311950RenderWidgetCompositor* RenderWidget::compositor() const {
1951 return compositor_.get();
1952}
1953
fsamuel72464894f2015-12-15 06:59:311954void RenderWidget::SetHandlingInputEventForTesting(bool handling_input_event) {
fsamuele8326c742016-01-12 00:49:391955 input_handler_->set_handling_input_event(handling_input_event);
[email protected]67bfb83f2011-09-22 03:36:371956}
[email protected]c3d45532011-10-07 19:20:401957
fsamuel72464894f2015-12-15 06:59:311958bool RenderWidget::SendAckForMouseMoveFromDebugger() {
fsamuele8326c742016-01-12 00:49:391959 return input_handler_->SendAckForMouseMoveFromDebugger();
[email protected]41d86852012-11-07 12:23:241960}
1961
fsamuel72464894f2015-12-15 06:59:311962void RenderWidget::IgnoreAckForMouseMoveFromDebugger() {
fsamuele8326c742016-01-12 00:49:391963 input_handler_->IgnoreAckForMouseMoveFromDebugger();
ccamerond4ba47902014-12-17 07:20:311964}
1965
[email protected]ce6689f2013-03-29 12:52:551966void RenderWidget::hasTouchEventHandlers(bool has_handlers) {
alexclarke7fa93942015-10-21 15:37:111967 if (render_widget_scheduling_state_)
1968 render_widget_scheduling_state_->SetHasTouchHandler(has_handlers);
[email protected]ce6689f2013-03-29 12:52:551969 Send(new ViewHostMsg_HasTouchEventHandlers(routing_id_, has_handlers));
1970}
1971
danakj365175c2016-02-06 00:37:371972// Check blink::WebTouchAction and content::TouchAction is kept in sync.
1973STATIC_ASSERT_ENUM(blink::WebTouchActionNone, TOUCH_ACTION_NONE);
1974STATIC_ASSERT_ENUM(blink::WebTouchActionPanLeft, TOUCH_ACTION_PAN_LEFT);
1975STATIC_ASSERT_ENUM(blink::WebTouchActionPanRight, TOUCH_ACTION_PAN_RIGHT);
1976STATIC_ASSERT_ENUM(blink::WebTouchActionPanX, TOUCH_ACTION_PAN_X);
1977STATIC_ASSERT_ENUM(blink::WebTouchActionPanUp, TOUCH_ACTION_PAN_UP);
1978STATIC_ASSERT_ENUM(blink::WebTouchActionPanDown, TOUCH_ACTION_PAN_DOWN);
1979STATIC_ASSERT_ENUM(blink::WebTouchActionPanY, TOUCH_ACTION_PAN_Y);
1980STATIC_ASSERT_ENUM(blink::WebTouchActionPan, TOUCH_ACTION_PAN);
1981STATIC_ASSERT_ENUM(blink::WebTouchActionPinchZoom, TOUCH_ACTION_PINCH_ZOOM);
1982STATIC_ASSERT_ENUM(blink::WebTouchActionManipulation,
1983 TOUCH_ACTION_MANIPULATION);
1984STATIC_ASSERT_ENUM(blink::WebTouchActionDoubleTapZoom,
1985 TOUCH_ACTION_DOUBLE_TAP_ZOOM);
1986STATIC_ASSERT_ENUM(blink::WebTouchActionAuto, TOUCH_ACTION_AUTO);
mostynbe29b6882015-01-13 09:59:171987
[email protected]5d0bbdfa92013-12-10 00:35:511988void RenderWidget::setTouchAction(
1989 blink::WebTouchAction web_touch_action) {
1990
1991 // Ignore setTouchAction calls that result from synthetic touch events (eg.
1992 // when blink is emulating touch with mouse).
fsamuele8326c742016-01-12 00:49:391993 if (input_handler_->handling_event_type() != WebInputEvent::TouchStart)
[email protected]5d0bbdfa92013-12-10 00:35:511994 return;
1995
[email protected]a18f67a2013-12-20 19:44:361996 content::TouchAction content_touch_action =
1997 static_cast<content::TouchAction>(web_touch_action);
[email protected]5d0bbdfa92013-12-10 00:35:511998 Send(new InputHostMsg_SetTouchAction(routing_id_, content_touch_action));
1999}
2000
[email protected]90f24152014-04-09 12:41:362001void RenderWidget::didUpdateTextOfFocusedElementByNonUserInput() {
2002#if defined(OS_ANDROID)
2003 text_field_is_dirty_ = true;
2004#endif
2005}
2006
[email protected]0634cdd42013-08-16 00:46:092007scoped_ptr<WebGraphicsContext3DCommandBufferImpl>
piman990d8ea2016-01-12 15:35:312008RenderWidget::CreateGraphicsContext3D(GpuChannelHost* gpu_channel_host) {
[email protected]828a3932014-04-02 14:43:132009 // Explicitly disable antialiasing for the compositor. As of the time of
2010 // this writing, the only platform that supported antialiasing for the
2011 // compositor was Mac OS X, because the on-screen OpenGL context creation
2012 // code paths on Windows and Linux didn't yet have multisampling support.
2013 // Mac OS X essentially always behaves as though it's rendering offscreen.
2014 // Multisampling has a heavy cost especially on devices with relatively low
2015 // fill rate like most notebooks, and the Mac implementation would need to
2016 // be optimized to resolve directly into the IOSurface shared between the
2017 // GPU and browser processes. For these reasons and to avoid platform
2018 // disparities we explicitly disable antialiasing.
2019 blink::WebGraphicsContext3D::Attributes attributes;
2020 attributes.antialias = false;
2021 attributes.shareResources = true;
2022 attributes.noAutomaticFlushes = true;
2023 attributes.depth = false;
2024 attributes.stencil = false;
[email protected]828a3932014-04-02 14:43:132025 bool lose_context_when_out_of_memory = true;
[email protected]96ab016c2013-10-23 00:50:292026 WebGraphicsContext3DCommandBufferImpl::SharedMemoryLimits limits;
[email protected]b6eb8e332013-09-10 00:51:012027#if defined(OS_ANDROID)
boliu853d46052015-10-13 20:20:062028 bool using_synchronous_compositing =
boliubee541f42015-11-05 00:52:532029 SynchronousCompositorFactory::GetInstance() ||
2030 base::CommandLine::ForCurrentProcess()->HasSwitch(
2031 switches::kIPCSyncCompositing);
[email protected]b6eb8e332013-09-10 00:51:012032 // If we raster too fast we become upload bound, and pending
2033 // uploads consume memory. For maximum upload throughput, we would
2034 // want to allow for upload_throughput * pipeline_time of pending
2035 // uploads, after which we are just wasting memory. Since we don't
2036 // know our upload throughput yet, this just caps our memory usage.
boliu853d46052015-10-13 20:20:062037 // Synchronous compositor uses half because synchronous compositor
2038 // pipeline is only one frame deep. But twice of half for low end
2039 // because 16bit texture is not supported.
2040 size_t divider = using_synchronous_compositing ? 2 : 1;
[email protected]35b4f0c2014-06-26 16:55:272041 if (base::SysInfo::IsLowEndDevice())
[email protected]657be322013-09-20 08:50:032042 divider = 6;
[email protected]b6eb8e332013-09-10 00:51:012043 // For reference Nexus10 can upload 1MB in about 2.5ms.
[email protected]657be322013-09-20 08:50:032044 const double max_mb_uploaded_per_ms = 2.0 / (5 * divider);
[email protected]b6eb8e332013-09-10 00:51:012045 // Deadline to draw a frame to achieve 60 frames per second.
2046 const size_t kMillisecondsPerFrame = 16;
2047 // Assuming a two frame deep pipeline between the CPU and the GPU.
[email protected]657be322013-09-20 08:50:032048 size_t max_transfer_buffer_usage_mb =
2049 static_cast<size_t>(2 * kMillisecondsPerFrame * max_mb_uploaded_per_ms);
2050 static const size_t kBytesPerMegabyte = 1024 * 1024;
[email protected]b6eb8e332013-09-10 00:51:012051 // We keep the MappedMemoryReclaimLimit the same as the upload limit
2052 // to avoid unnecessarily stalling the compositor thread.
[email protected]96ab016c2013-10-23 00:50:292053 limits.mapped_memory_reclaim_limit =
[email protected]657be322013-09-20 08:50:032054 max_transfer_buffer_usage_mb * kBytesPerMegabyte;
[email protected]b6eb8e332013-09-10 00:51:012055#endif
piman990d8ea2016-01-12 15:35:312056 limits.command_buffer_size = 64 * 1024;
2057 limits.start_transfer_buffer_size = 64 * 1024;
2058 limits.min_transfer_buffer_size = 64 * 1024;
[email protected]96ab016c2013-10-23 00:50:292059
piman990d8ea2016-01-12 15:35:312060 return make_scoped_ptr(new WebGraphicsContext3DCommandBufferImpl(
2061 0, GetURLForGraphicsContext3D(), gpu_channel_host, attributes,
piman08f75532015-10-05 18:58:012062 lose_context_when_out_of_memory, limits, NULL));
[email protected]ed7defa2013-03-12 21:29:592063}
2064
[email protected]e3244ed2014-06-20 20:04:272065void RenderWidget::RegisterRenderFrameProxy(RenderFrameProxy* proxy) {
2066 render_frame_proxies_.AddObserver(proxy);
[email protected]bffc8302014-01-23 20:52:162067}
2068
[email protected]e3244ed2014-06-20 20:04:272069void RenderWidget::UnregisterRenderFrameProxy(RenderFrameProxy* proxy) {
2070 render_frame_proxies_.RemoveObserver(proxy);
[email protected]bffc8302014-01-23 20:52:162071}
2072
[email protected]de3c5d82014-05-28 22:12:592073void RenderWidget::RegisterRenderFrame(RenderFrameImpl* frame) {
2074 render_frames_.AddObserver(frame);
2075}
2076
2077void RenderWidget::UnregisterRenderFrame(RenderFrameImpl* frame) {
2078 render_frames_.RemoveObserver(frame);
2079}
2080
[email protected]a017938b2014-05-27 21:17:172081#if defined(VIDEO_HOLE)
2082void RenderWidget::RegisterVideoHoleFrame(RenderFrameImpl* frame) {
2083 video_hole_frames_.AddObserver(frame);
2084}
2085
2086void RenderWidget::UnregisterVideoHoleFrame(RenderFrameImpl* frame) {
2087 video_hole_frames_.RemoveObserver(frame);
2088}
2089#endif // defined(VIDEO_HOLE)
2090
lfg43e08e62016-02-03 18:51:372091void RenderWidget::OnWaitNextFrameForTests(int routing_id) {
2092 QueueMessage(new ViewHostMsg_WaitForNextFrameForTests_ACK(routing_id),
2093 MESSAGE_DELIVERY_POLICY_WITH_VISUAL_STATE);
2094}
2095
[email protected]e9ff79c2012-10-19 21:31:262096} // namespace content