#include "third_party/WebKit/public/web/WebCompositionUnderline.h"
#include "ui/events/event.h"
#include "ui/events/keycodes/keyboard_codes.h"
+#include "ui/gfx/geometry/vector2d_conversions.h"
#include "ui/gfx/size_conversions.h"
#include "ui/gfx/skbitmap_operations.h"
-#include "ui/gfx/vector2d_conversions.h"
#include "ui/snapshot/snapshot.h"
#if defined(OS_WIN)
bool g_check_for_pending_resize_ack = true;
+const size_t kBrowserCompositeLatencyHistorySize = 60;
+const double kBrowserCompositeLatencyEstimationPercentile = 90.0;
+const double kBrowserCompositeLatencyEstimationSlack = 1.1;
+
typedef std::pair<int32, int32> RenderWidgetHostID;
typedef base::hash_map<RenderWidgetHostID, RenderWidgetHostImpl*>
RoutingIDWidgetMap;
: current_index_(0) {
}
- virtual ~RenderWidgetHostIteratorImpl() {
- }
+ ~RenderWidgetHostIteratorImpl() override {}
void Add(RenderWidgetHost* host) {
hosts_.push_back(RenderWidgetHostID(host->GetProcess()->GetID(),
}
// RenderWidgetHostIterator:
- virtual RenderWidgetHost* GetNextHost() OVERRIDE {
+ RenderWidgetHost* GetNextHost() override {
RenderWidgetHost* host = NULL;
while (current_index_ < hosts_.size() && !host) {
RenderWidgetHostID id = hosts_[current_index_];
has_touch_handler_(false),
last_input_number_(static_cast<int64>(GetProcess()->GetID()) << 32),
next_browser_snapshot_id_(1),
+ browser_composite_latency_history_(kBrowserCompositeLatencyHistorySize),
weak_factory_(this) {
CHECK(delegate_);
if (routing_id_ == MSG_ROUTING_NONE) {
// Add only active RenderViewHosts.
RenderViewHost* rvh = RenderViewHost::From(widget);
- if (RenderViewHostImpl::IsRVHStateActive(
- static_cast<RenderViewHostImpl*>(rvh)->rvh_state()))
+ if (static_cast<RenderViewHostImpl*>(rvh)->is_active())
hosts->Add(widget);
}
IPC_MESSAGE_HANDLER(ViewHostMsg_WindowlessPluginDummyWindowDestroyed,
OnWindowlessPluginDummyWindowDestroyed)
#endif
-#if defined(OS_MACOSX) || defined(USE_AURA)
+#if defined(OS_MACOSX) || defined(USE_AURA) || defined(OS_ANDROID)
IPC_MESSAGE_HANDLER(InputHostMsg_ImeCompositionRangeChanged,
OnImeCompositionRangeChanged)
#endif
void RenderWidgetHostImpl::GotFocus() {
Focus();
+ if (delegate_)
+ delegate_->RenderWidgetGotFocus(this);
}
void RenderWidgetHostImpl::Focus() {
ui::LatencyInfo::InputCoordinate logical_coordinate(mouse_event.x,
mouse_event.y);
- ui::LatencyInfo latency_info = CreateRWHLatencyInfoIfNotExist(
+ ui::LatencyInfo latency_info = CreateInputEventLatencyInfoIfNotExist(
&ui_latency, mouse_event.type, &logical_coordinate, 1);
for (size_t i = 0; i < mouse_event_callbacks_.size(); ++i) {
ui::LatencyInfo::InputCoordinate logical_coordinate(wheel_event.x,
wheel_event.y);
- ui::LatencyInfo latency_info = CreateRWHLatencyInfoIfNotExist(
+ ui::LatencyInfo latency_info = CreateInputEventLatencyInfoIfNotExist(
&ui_latency, wheel_event.type, &logical_coordinate, 1);
if (IgnoreInputEvents())
ui::LatencyInfo::InputCoordinate logical_coordinate(gesture_event.x,
gesture_event.y);
- ui::LatencyInfo latency_info = CreateRWHLatencyInfoIfNotExist(
+ ui::LatencyInfo latency_info = CreateInputEventLatencyInfoIfNotExist(
&ui_latency, gesture_event.type, &logical_coordinate, 1);
if (gesture_event.type == blink::WebInputEvent::GestureScrollUpdate) {
touch_event.touches[i].position.x, touch_event.touches[i].position.y);
}
- ui::LatencyInfo latency_info = CreateRWHLatencyInfoIfNotExist(
+ ui::LatencyInfo latency_info = CreateInputEventLatencyInfoIfNotExist(
NULL, touch_event.type, logical_coordinates, logical_coordinates_size);
TouchEventWithLatencyInfo touch_with_latency(touch_event, latency_info);
input_router_->SendTouchEvent(touch_with_latency);
touch_event.touches[i].position.x, touch_event.touches[i].position.y);
}
- ui::LatencyInfo latency_info =
- CreateRWHLatencyInfoIfNotExist(&ui_latency,
- touch_event.type,
- logical_coordinates,
- logical_coordinates_size);
+ ui::LatencyInfo latency_info = CreateInputEventLatencyInfoIfNotExist(
+ &ui_latency,
+ touch_event.type,
+ logical_coordinates,
+ logical_coordinates_size);
TouchEventWithLatencyInfo touch_with_latency(touch_event, latency_info);
if (touch_emulator_ &&
input_router_->SendKeyboardEvent(
key_event,
- CreateRWHLatencyInfoIfNotExist(NULL, key_event.type, NULL, 0),
+ CreateInputEventLatencyInfoIfNotExist(NULL, key_event.type, NULL, 0),
is_shortcut);
}
Send(new InputMsg_CursorVisibilityChange(GetRoutingID(), is_visible));
}
-int64 RenderWidgetHostImpl::GetLatencyComponentId() {
+int64 RenderWidgetHostImpl::GetLatencyComponentId() const {
return GetRoutingID() | (static_cast<int64>(GetProcess()->GetID()) << 32);
}
g_check_for_pending_resize_ack = false;
}
-ui::LatencyInfo RenderWidgetHostImpl::CreateRWHLatencyInfoIfNotExist(
+ui::LatencyInfo RenderWidgetHostImpl::CreateInputEventLatencyInfoIfNotExist(
const ui::LatencyInfo* original,
WebInputEvent::Type type,
const ui::LatencyInfo::InputCoordinate* logical_coordinates,
input_router_->OnViewUpdated(
GetInputRouterViewFlagsFromCompositorFrameMetadata(frame->metadata));
+ for (size_t i = 0; i < frame->metadata.latency_info.size(); ++i) {
+ frame->metadata.latency_info[i].AddLatencyNumber(
+ ui::INPUT_EVENT_BROWSER_COMPOSITE_COMPONENT, 0, 0);
+ }
+
if (view_) {
view_->OnSwapCompositorFrame(output_surface_id, frame.Pass());
view_->DidReceiveRendererFrame();
void RenderWidgetHostImpl::OnTextInputTypeChanged(
ui::TextInputType type,
ui::TextInputMode input_mode,
- bool can_compose_inline) {
+ bool can_compose_inline,
+ int flags) {
if (view_)
- view_->TextInputTypeChanged(type, input_mode, can_compose_inline);
+ view_->TextInputTypeChanged(type, input_mode, can_compose_inline, flags);
}
-#if defined(OS_MACOSX) || defined(USE_AURA)
+#if defined(OS_MACOSX) || defined(USE_AURA) || defined(OS_ANDROID)
void RenderWidgetHostImpl::OnImeCompositionRangeChanged(
const gfx::Range& range,
const std::vector<gfx::Rect>& character_bounds) {
SkBitmap zoomed_bitmap;
zoomed_bitmap.installPixels(info, bitmap->pixels(), info.minRowBytes());
-#if defined(OS_ANDROID) || defined(TOOLKIT_VIEWS)
// Note that |rect| is in coordinates of pixels relative to the window origin.
// Aura-based systems will want to convert this to DIPs.
if (view_)
view_->ShowDisambiguationPopup(rect_pixels, zoomed_bitmap);
-#else
- NOTIMPLEMENTED();
-#endif
// It is assumed that the disambiguation popup will make a copy of the
// provided zoomed image, so we delete this one.
void RenderWidgetHostImpl::OnWheelEventAck(
const MouseWheelEventWithLatencyInfo& wheel_event,
InputEventAckState ack_result) {
+ ui::LatencyInfo latency = wheel_event.latency;
+ latency.AddLatencyNumber(
+ ui::INPUT_EVENT_LATENCY_ACK_RWH_COMPONENT, 0, 0);
if (!wheel_event.latency.FindLatency(
ui::INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_COMPONENT, 0, NULL)) {
// MouseWheelEvent latency ends when it is acked but does not cause any
// rendering scheduled.
- ui::LatencyInfo latency = wheel_event.latency;
latency.AddLatencyNumber(
ui::INPUT_EVENT_LATENCY_TERMINATED_MOUSE_COMPONENT, 0, 0);
}
+ ComputeInputLatencyHistograms(blink::WebInputEvent::MouseWheel, latency);
if (!is_hidden() && view_) {
if (ack_result != INPUT_EVENT_ACK_STATE_CONSUMED &&
InputEventAckState ack_result) {
TouchEventWithLatencyInfo touch_event = event;
touch_event.latency.AddLatencyNumber(
- ui::INPUT_EVENT_LATENCY_ACKED_TOUCH_COMPONENT, 0, 0);
+ ui::INPUT_EVENT_LATENCY_ACK_RWH_COMPONENT, 0, 0);
// TouchEvent latency ends at ack if it didn't cause any rendering.
if (!touch_event.latency.FindLatency(
ui::INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_COMPONENT, 0, NULL)) {
touch_event.latency.AddLatencyNumber(
ui::INPUT_EVENT_LATENCY_TERMINATED_TOUCH_COMPONENT, 0, 0);
}
- ComputeTouchLatency(touch_event.latency);
+ ComputeInputLatencyHistograms(
+ blink::WebInputEvent::TouchTypeFirst, touch_event.latency);
if (touch_emulator_ &&
touch_emulator_->HandleTouchEventAck(event.event, ack_result)) {
}
// static
-void RenderWidgetHostImpl::AcknowledgeBufferPresent(
- int32 route_id, int gpu_host_id,
- const AcceleratedSurfaceMsg_BufferPresented_Params& params) {
- GpuProcessHostUIShim* ui_shim = GpuProcessHostUIShim::FromID(gpu_host_id);
- if (ui_shim) {
- ui_shim->Send(new AcceleratedSurfaceMsg_BufferPresented(route_id,
- params));
- }
-}
-
-// static
void RenderWidgetHostImpl::SendSwapCompositorFrameAck(
int32 route_id,
uint32 output_surface_id,
delegate_ = NULL;
}
-void RenderWidgetHostImpl::ComputeTouchLatency(
- const ui::LatencyInfo& latency_info) {
- ui::LatencyInfo::LatencyComponent ui_component;
+void RenderWidgetHostImpl::ComputeInputLatencyHistograms(
+ blink::WebInputEvent::Type type,
+ const ui::LatencyInfo& latency_info) const {
ui::LatencyInfo::LatencyComponent rwh_component;
- ui::LatencyInfo::LatencyComponent acked_component;
-
- if (!latency_info.FindLatency(ui::INPUT_EVENT_LATENCY_UI_COMPONENT,
- 0,
- &ui_component) ||
- !latency_info.FindLatency(ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT,
+ if (!latency_info.FindLatency(ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT,
GetLatencyComponentId(),
&rwh_component))
return;
+ DCHECK_EQ(rwh_component.event_count, 1u);
- DCHECK(ui_component.event_count == 1);
- DCHECK(rwh_component.event_count == 1);
-
- base::TimeDelta ui_delta =
- rwh_component.event_time - ui_component.event_time;
- UMA_HISTOGRAM_CUSTOM_COUNTS(
- "Event.Latency.Browser.TouchUI",
- ui_delta.InMicroseconds(),
- 1,
- 20000,
- 100);
+ ui::LatencyInfo::LatencyComponent ui_component;
+ if (latency_info.FindLatency(ui::INPUT_EVENT_LATENCY_UI_COMPONENT,
+ 0,
+ &ui_component)) {
+ DCHECK_EQ(ui_component.event_count, 1u);
+ base::TimeDelta ui_delta =
+ rwh_component.event_time - ui_component.event_time;
+ switch (type) {
+ case blink::WebInputEvent::MouseWheel:
+ UMA_HISTOGRAM_CUSTOM_COUNTS(
+ "Event.Latency.Browser.WheelUI",
+ ui_delta.InMicroseconds(), 1, 20000, 100);
+ break;
+ case blink::WebInputEvent::TouchTypeFirst:
+ UMA_HISTOGRAM_CUSTOM_COUNTS(
+ "Event.Latency.Browser.TouchUI",
+ ui_delta.InMicroseconds(), 1, 20000, 100);
+ break;
+ default:
+ NOTREACHED();
+ break;
+ }
+ }
- if (latency_info.FindLatency(ui::INPUT_EVENT_LATENCY_ACKED_TOUCH_COMPONENT,
+ ui::LatencyInfo::LatencyComponent acked_component;
+ if (latency_info.FindLatency(ui::INPUT_EVENT_LATENCY_ACK_RWH_COMPONENT,
0,
&acked_component)) {
- DCHECK(acked_component.event_count == 1);
+ DCHECK_EQ(acked_component.event_count, 1u);
base::TimeDelta acked_delta =
acked_component.event_time - rwh_component.event_time;
- UMA_HISTOGRAM_CUSTOM_COUNTS(
- "Event.Latency.Browser.TouchAcked",
- acked_delta.InMicroseconds(),
- 1,
- 1000000,
- 100);
+ switch (type) {
+ case blink::WebInputEvent::MouseWheel:
+ UMA_HISTOGRAM_CUSTOM_COUNTS(
+ "Event.Latency.Browser.WheelAcked",
+ acked_delta.InMicroseconds(), 1, 1000000, 100);
+ break;
+ case blink::WebInputEvent::TouchTypeFirst:
+ UMA_HISTOGRAM_CUSTOM_COUNTS(
+ "Event.Latency.Browser.TouchAcked",
+ acked_delta.InMicroseconds(), 1, 1000000, 100);
+ break;
+ default:
+ NOTREACHED();
+ break;
+ }
}
}
100);
}
}
+
+ ui::LatencyInfo::LatencyComponent gpu_swap_component;
+ if (!latency_info.FindLatency(
+ ui::INPUT_EVENT_GPU_SWAP_BUFFER_COMPONENT, 0, &gpu_swap_component)) {
+ return;
+ }
+
+ ui::LatencyInfo::LatencyComponent composite_component;
+ if (latency_info.FindLatency(ui::INPUT_EVENT_BROWSER_COMPOSITE_COMPONENT,
+ 0,
+ &composite_component)) {
+ base::TimeDelta delta =
+ gpu_swap_component.event_time - composite_component.event_time;
+ browser_composite_latency_history_.InsertSample(delta);
+ }
}
void RenderWidgetHostImpl::DidReceiveRendererFrame() {
delegate_->GetOrCreateRootBrowserAccessibilityManager() : NULL;
}
+base::TimeDelta RenderWidgetHostImpl::GetEstimatedBrowserCompositeTime() {
+ // TODO(orglofch) remove lower bound on estimate once we're sure it won't
+ // cause regressions
+ return std::max(
+ browser_composite_latency_history_.Percentile(
+ kBrowserCompositeLatencyEstimationPercentile) *
+ kBrowserCompositeLatencyEstimationSlack,
+ base::TimeDelta::FromMicroseconds(
+ (1.0f * base::Time::kMicrosecondsPerSecond) / (3.0f * 60)));
+}
+
#if defined(OS_WIN)
gfx::NativeViewAccessible
RenderWidgetHostImpl::GetParentNativeViewAccessible() {