summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormiletus@chromium.org <miletus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-05-27 16:56:43 +0000
committermiletus@chromium.org <miletus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-05-27 16:56:43 +0000
commit8062ab2643873f883e9655d506e1f91880b923ff (patch)
tree3b1031b6e7e592c11a0d9756ec5bd337c40c41cd
parent66bf7e2b99672c530495517abb88f5256af9d338 (diff)
downloadchromium_src-8062ab2643873f883e9655d506e1f91880b923ff.zip
chromium_src-8062ab2643873f883e9655d506e1f91880b923ff.tar.gz
chromium_src-8062ab2643873f883e9655d506e1f91880b923ff.tar.bz2
Track plugin input event latency
This CL uses LatencyInfo to track the plugin input event latency. 1.Each plugin input event has an associated LatencyInfo which includes some important components from its according ui::Event/WebInputEvent's LatencyInfo. To do that, during the scope of RenderWidget::OnHandleInputEvent(WebInputEvent, latency_info) we first cache the WebInputEvent's latency_info, then if the input event needs to be routed to plugin, we copy the important components from the cached latency_info into the plugin input event's LatencyInfo. 2.A private API InputEventPrivate::TraceInputLatency(bool has_damage) is exposed. 3.If the event is believed to cause rendering damage, private_event.TraceInputLatency(true) can be called, and the input event's LatencyInfo will be sent to renderer with next plugin frame and be tracked until it reaches screen. If the event is believed to not cause any rendering damage, private_event.TraceInputLatency(false) can be called, and the LatencyInfo tracking ends right at the call. BUG=355719 TEST=with custom test touch drawing plugin, input-to-swapbuffer latency is shown correctly in trace viewer. Review URL: https://codereview.chromium.org/252663002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@272990 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/component_updater/ppapi_utils.cc1
-rw-r--r--content/renderer/gpu/render_widget_compositor.cc5
-rw-r--r--content/renderer/gpu/render_widget_compositor.h4
-rw-r--r--content/renderer/pepper/pepper_graphics_2d_host.cc10
-rw-r--r--content/renderer/pepper/pepper_graphics_2d_host.h4
-rw-r--r--content/renderer/pepper/pepper_graphics_2d_host_unittest.cc4
-rw-r--r--content/renderer/pepper/pepper_plugin_instance_impl.cc55
-rw-r--r--content/renderer/pepper/pepper_plugin_instance_impl.h8
-rw-r--r--content/renderer/pepper/plugin_module.cc1
-rw-r--r--content/renderer/render_widget.cc4
-rw-r--r--content/renderer/render_widget.h7
-rw-r--r--mojo/examples/pepper_container_app/plugin_instance.cc4
-rw-r--r--mojo/examples/pepper_container_app/plugin_instance.h1
-rw-r--r--mojo/mojo_examples.gypi1
-rw-r--r--ppapi/api/private/ppb_input_event_private.idl54
-rw-r--r--ppapi/c/pp_macros.h4
-rw-r--r--ppapi/c/private/ppb_input_event_private.h78
-rw-r--r--ppapi/cpp/private/input_event_private.cc44
-rw-r--r--ppapi/cpp/private/input_event_private.h27
-rw-r--r--ppapi/native_client/native_client.gyp1
-rw-r--r--ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c4
-rw-r--r--ppapi/ppapi_internal.gyp7
-rw-r--r--ppapi/ppapi_proxy_nacl.gyp1
-rw-r--r--ppapi/ppapi_shared.gypi1
-rw-r--r--ppapi/ppapi_sources.gypi3
-rw-r--r--ppapi/proxy/DEPS1
-rw-r--r--ppapi/proxy/graphics_2d_resource.cc5
-rw-r--r--ppapi/proxy/interface_list.cc1
-rw-r--r--ppapi/proxy/ppapi_messages.h7
-rw-r--r--ppapi/proxy/ppb_instance_proxy.cc13
-rw-r--r--ppapi/proxy/ppb_instance_proxy.h2
-rw-r--r--ppapi/shared_impl/DEPS1
-rw-r--r--ppapi/shared_impl/ppapi_globals.cc11
-rw-r--r--ppapi/shared_impl/ppapi_globals.h15
-rw-r--r--ppapi/shared_impl/ppb_input_event_shared.cc15
-rw-r--r--ppapi/shared_impl/ppb_input_event_shared.h4
-rw-r--r--ppapi/tests/all_c_includes.h1
-rw-r--r--ppapi/tests/test_input_event.cc34
-rw-r--r--ppapi/tests/test_input_event.h5
-rw-r--r--ppapi/thunk/interfaces_ppb_private.h3
-rw-r--r--ppapi/thunk/ppb_input_event_api.h3
-rw-r--r--ppapi/thunk/ppb_input_event_private_thunk.cc42
-rw-r--r--ppapi/thunk/ppb_instance_api.h3
-rw-r--r--tools/metrics/histograms/histograms.xml1
-rw-r--r--ui/events/latency_info.cc6
-rw-r--r--ui/events/latency_info.h7
-rw-r--r--ui/events/latency_info_nacl.gyp38
47 files changed, 538 insertions, 13 deletions
diff --git a/chrome/browser/component_updater/ppapi_utils.cc b/chrome/browser/component_updater/ppapi_utils.cc
index cdd8363..f8f7dc4 100644
--- a/chrome/browser/component_updater/ppapi_utils.cc
+++ b/chrome/browser/component_updater/ppapi_utils.cc
@@ -87,6 +87,7 @@
#include "ppapi/c/private/ppb_flash_message_loop.h"
#include "ppapi/c/private/ppb_flash_print.h"
#include "ppapi/c/private/ppb_host_resolver_private.h"
+#include "ppapi/c/private/ppb_input_event_private.h"
#include "ppapi/c/private/ppb_isolated_file_system_private.h"
#include "ppapi/c/private/ppb_output_protection_private.h"
#include "ppapi/c/private/ppb_pdf.h"
diff --git a/content/renderer/gpu/render_widget_compositor.cc b/content/renderer/gpu/render_widget_compositor.cc
index 8479ccd..d2d0463 100644
--- a/content/renderer/gpu/render_widget_compositor.cc
+++ b/content/renderer/gpu/render_widget_compositor.cc
@@ -396,6 +396,11 @@ RenderWidgetCompositor::CreateLatencyInfoSwapPromiseMonitor(
latency, layer_tree_host_.get(), NULL));
}
+void RenderWidgetCompositor::QueueSwapPromise(
+ scoped_ptr<cc::SwapPromise> swap_promise) {
+ layer_tree_host_->QueueSwapPromise(swap_promise.Pass());
+}
+
int RenderWidgetCompositor::GetLayerTreeId() const {
return layer_tree_host_->id();
}
diff --git a/content/renderer/gpu/render_widget_compositor.h b/content/renderer/gpu/render_widget_compositor.h
index a97a36a..208108c 100644
--- a/content/renderer/gpu/render_widget_compositor.h
+++ b/content/renderer/gpu/render_widget_compositor.h
@@ -9,6 +9,7 @@
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
#include "base/values.h"
+#include "cc/base/swap_promise.h"
#include "cc/base/swap_promise_monitor.h"
#include "cc/input/top_controls_state.h"
#include "cc/trees/layer_tree_host_client.h"
@@ -63,6 +64,9 @@ class RenderWidgetCompositor : public blink::WebLayerTreeView,
// into a LatencyInfoSwapPromise.
scoped_ptr<cc::SwapPromiseMonitor> CreateLatencyInfoSwapPromiseMonitor(
ui::LatencyInfo* latency);
+ // Calling QueueSwapPromise() to directly queue a SwapPromise into
+ // LayerTreeHost.
+ void QueueSwapPromise(scoped_ptr<cc::SwapPromise> swap_promise);
int GetLayerTreeId() const;
void NotifyInputThrottledUntilCommit();
const cc::Layer* GetRootLayer() const;
diff --git a/content/renderer/pepper/pepper_graphics_2d_host.cc b/content/renderer/pepper/pepper_graphics_2d_host.cc
index 313110a..a33b994 100644
--- a/content/renderer/pepper/pepper_graphics_2d_host.cc
+++ b/content/renderer/pepper/pepper_graphics_2d_host.cc
@@ -228,8 +228,8 @@ int32_t PepperGraphics2DHost::OnResourceMessageReceived(
OnHostMsgScroll)
PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_Graphics2D_ReplaceContents,
OnHostMsgReplaceContents)
- PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_Graphics2D_Flush,
- OnHostMsgFlush)
+ PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_Graphics2D_Flush,
+ OnHostMsgFlush)
PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_Graphics2D_SetScale,
OnHostMsgSetScale)
PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_Graphics2D_ReadImageData,
@@ -500,11 +500,15 @@ int32_t PepperGraphics2DHost::OnHostMsgReplaceContents(
}
int32_t PepperGraphics2DHost::OnHostMsgFlush(
- ppapi::host::HostMessageContext* context) {
+ ppapi::host::HostMessageContext* context,
+ const std::vector<ui::LatencyInfo>& latency_info) {
// Don't allow more than one pending flush at a time.
if (HasPendingFlush())
return PP_ERROR_INPROGRESS;
+ if (bound_instance_)
+ bound_instance_->AddLatencyInfo(latency_info);
+
PP_Resource old_image_data = 0;
flush_reply_context_ = context->MakeReplyMessageContext();
if (is_running_in_process_)
diff --git a/content/renderer/pepper/pepper_graphics_2d_host.h b/content/renderer/pepper/pepper_graphics_2d_host.h
index 71eb59f..25df4d1 100644
--- a/content/renderer/pepper/pepper_graphics_2d_host.h
+++ b/content/renderer/pepper/pepper_graphics_2d_host.h
@@ -15,6 +15,7 @@
#include "ppapi/host/host_message_context.h"
#include "ppapi/host/resource_host.h"
#include "third_party/WebKit/public/platform/WebCanvas.h"
+#include "ui/events/latency_info.h"
#include "ui/gfx/point.h"
#include "ui/gfx/size.h"
@@ -105,7 +106,8 @@ class CONTENT_EXPORT PepperGraphics2DHost
const PP_Point& amount);
int32_t OnHostMsgReplaceContents(ppapi::host::HostMessageContext* context,
const ppapi::HostResource& image_data);
- int32_t OnHostMsgFlush(ppapi::host::HostMessageContext* context);
+ int32_t OnHostMsgFlush(ppapi::host::HostMessageContext* context,
+ const std::vector<ui::LatencyInfo>& latency_info);
int32_t OnHostMsgSetScale(ppapi::host::HostMessageContext* context,
float scale);
int32_t OnHostMsgReadImageData(ppapi::host::HostMessageContext* context,
diff --git a/content/renderer/pepper/pepper_graphics_2d_host_unittest.cc b/content/renderer/pepper/pepper_graphics_2d_host_unittest.cc
index d16c863..8914a3d 100644
--- a/content/renderer/pepper/pepper_graphics_2d_host_unittest.cc
+++ b/content/renderer/pepper/pepper_graphics_2d_host_unittest.cc
@@ -15,6 +15,7 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/WebKit/public/platform/WebCanvas.h"
#include "third_party/skia/include/core/SkCanvas.h"
+#include "ui/events/latency_info.h"
#include "ui/gfx/point.h"
#include "ui/gfx/rect.h"
@@ -64,7 +65,8 @@ class PepperGraphics2DHostTest : public testing::Test {
void Flush() {
ppapi::host::HostMessageContext context(
ppapi::proxy::ResourceMessageCallParams(host_->pp_resource(), 0));
- host_->OnHostMsgFlush(&context);
+ std::vector<ui::LatencyInfo> latency;
+ host_->OnHostMsgFlush(&context, latency);
host_->ViewFlushedPaint();
host_->SendOffscreenFlushAck();
}
diff --git a/content/renderer/pepper/pepper_plugin_instance_impl.cc b/content/renderer/pepper/pepper_plugin_instance_impl.cc
index 8f36f5d..c1bc651 100644
--- a/content/renderer/pepper/pepper_plugin_instance_impl.cc
+++ b/content/renderer/pepper/pepper_plugin_instance_impl.cc
@@ -16,11 +16,15 @@
#include "base/strings/utf_offset_string_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
+#include "cc/base/latency_info_swap_promise.h"
#include "cc/layers/texture_layer.h"
+#include "cc/trees/layer_tree_host.h"
#include "content/common/content_constants_internal.h"
+#include "content/common/input/web_input_event_traits.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/page_zoom.h"
#include "content/public/renderer/content_renderer_client.h"
+#include "content/renderer/gpu/render_widget_compositor.h"
#include "content/renderer/pepper/common.h"
#include "content/renderer/pepper/content_decryptor_delegate.h"
#include "content/renderer/pepper/event_conversion.h"
@@ -404,6 +408,23 @@ class PluginInstanceLockTarget : public MouseLockDispatcher::LockTarget {
PepperPluginInstanceImpl* plugin_;
};
+void InitLatencyInfo(ui::LatencyInfo* new_latency,
+ const ui::LatencyInfo* old_latency,
+ blink::WebInputEvent::Type type,
+ int64 input_sequence) {
+ new_latency->AddLatencyNumber(
+ ui::INPUT_EVENT_LATENCY_BEGIN_PLUGIN_COMPONENT,
+ 0,
+ input_sequence);
+ new_latency->TraceEventType(WebInputEventTraits::GetName(type));
+ if (old_latency) {
+ new_latency->CopyLatencyFrom(*old_latency,
+ ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT);
+ new_latency->CopyLatencyFrom(*old_latency,
+ ui::INPUT_EVENT_LATENCY_UI_COMPONENT);
+ }
+}
+
} // namespace
// static
@@ -538,6 +559,8 @@ PepperPluginInstanceImpl::PepperPluginInstanceImpl(
npp_(new NPP_t),
isolate_(v8::Isolate::GetCurrent()),
is_deleted_(false),
+ last_input_number_(0),
+ is_tracking_latency_(false),
view_change_weak_ptr_factory_(this),
weak_factory_(this) {
pp_instance_ = HostGlobals::Get()->AddInstance(this);
@@ -1099,8 +1122,20 @@ bool PepperPluginInstanceImpl::HandleInputEvent(
pending_user_gesture_token_.setOutOfProcess();
}
+ const ui::LatencyInfo* current_event_latency_info = NULL;
+ if (render_frame_->GetRenderWidget()) {
+ current_event_latency_info =
+ render_frame_->GetRenderWidget()->current_event_latency_info();
+ }
+
// Each input event may generate more than one PP_InputEvent.
for (size_t i = 0; i < events.size(); i++) {
+ if (is_tracking_latency_) {
+ InitLatencyInfo(&events[i].latency_info,
+ current_event_latency_info,
+ event.type,
+ last_input_number_++);
+ }
if (filtered_input_event_mask_ & event_class)
events[i].is_filtered = true;
else
@@ -1996,6 +2031,21 @@ bool PepperPluginInstanceImpl::PrepareTextureMailbox(
void PepperPluginInstanceImpl::OnDestruct() { render_frame_ = NULL; }
+void PepperPluginInstanceImpl::AddLatencyInfo(
+ const std::vector<ui::LatencyInfo>& latency_info) {
+ if (render_frame_ && render_frame_->GetRenderWidget()) {
+ RenderWidgetCompositor* compositor =
+ render_frame_->GetRenderWidget()->compositor();
+ if (compositor) {
+ for (size_t i = 0; i < latency_info.size(); i++) {
+ scoped_ptr<cc::SwapPromise> swap_promise(
+ new cc::LatencyInfoSwapPromise(latency_info[i]));
+ compositor->QueueSwapPromise(swap_promise.Pass());
+ }
+ }
+ }
+}
+
void PepperPluginInstanceImpl::AddPluginObject(PluginObject* plugin_object) {
DCHECK(live_plugin_objects_.find(plugin_object) ==
live_plugin_objects_.end());
@@ -2505,6 +2555,11 @@ void PepperPluginInstanceImpl::ClearInputEventRequest(PP_Instance instance,
RequestInputEventsHelper(event_classes);
}
+void PepperPluginInstanceImpl::StartTrackingLatency(PP_Instance instance) {
+ if (module_->permissions().HasPermission(ppapi::PERMISSION_PRIVATE))
+ is_tracking_latency_ = true;
+}
+
void PepperPluginInstanceImpl::ZoomChanged(PP_Instance instance,
double factor) {
// We only want to tell the page to change its zoom if the whole page is the
diff --git a/content/renderer/pepper/pepper_plugin_instance_impl.h b/content/renderer/pepper/pepper_plugin_instance_impl.h
index 68771ef..9d067a9 100644
--- a/content/renderer/pepper/pepper_plugin_instance_impl.h
+++ b/content/renderer/pepper/pepper_plugin_instance_impl.h
@@ -55,6 +55,7 @@
#include "third_party/WebKit/public/web/WebPlugin.h"
#include "third_party/WebKit/public/web/WebUserGestureToken.h"
#include "ui/base/ime/text_input_type.h"
+#include "ui/events/latency_info.h"
#include "ui/gfx/rect.h"
#include "url/gurl.h"
@@ -404,6 +405,7 @@ class CONTENT_EXPORT PepperPluginInstanceImpl
uint32_t event_classes) OVERRIDE;
virtual void ClearInputEventRequest(PP_Instance instance,
uint32_t event_classes) OVERRIDE;
+ virtual void StartTrackingLatency(PP_Instance instance) OVERRIDE;
virtual void ZoomChanged(PP_Instance instance, double factor) OVERRIDE;
virtual void ZoomLimitsChanged(PP_Instance instance,
double minimum_factor,
@@ -507,6 +509,8 @@ class CONTENT_EXPORT PepperPluginInstanceImpl
// RenderFrameObserver
virtual void OnDestruct() OVERRIDE;
+ void AddLatencyInfo(const std::vector<ui::LatencyInfo>& latency_info);
+
private:
friend class base::RefCounted<PepperPluginInstanceImpl>;
friend class PpapiUnittest;
@@ -864,6 +868,10 @@ class CONTENT_EXPORT PepperPluginInstanceImpl
// The text that is currently selected in the plugin.
base::string16 selected_text_;
+ int64 last_input_number_;
+
+ bool is_tracking_latency_;
+
// We use a weak ptr factory for scheduling DidChangeView events so that we
// can tell whether updates are pending and consolidate them. When there's
// already a weak ptr pending (HasWeakPtrs is true), code should update the
diff --git a/content/renderer/pepper/plugin_module.cc b/content/renderer/pepper/plugin_module.cc
index 9e9dc78..9d95fb5 100644
--- a/content/renderer/pepper/plugin_module.cc
+++ b/content/renderer/pepper/plugin_module.cc
@@ -110,6 +110,7 @@
#include "ppapi/c/private/ppb_flash_message_loop.h"
#include "ppapi/c/private/ppb_flash_print.h"
#include "ppapi/c/private/ppb_host_resolver_private.h"
+#include "ppapi/c/private/ppb_input_event_private.h"
#include "ppapi/c/private/ppb_instance_private.h"
#include "ppapi/c/private/ppb_isolated_file_system_private.h"
#include "ppapi/c/private/ppb_output_protection_private.h"
diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc
index 1803e49d..4eaa8ea 100644
--- a/content/renderer/render_widget.cc
+++ b/content/renderer/render_widget.cc
@@ -388,6 +388,7 @@ RenderWidget::RenderWidget(blink::WebPopupType popup_type,
screen_info_(screen_info),
device_scale_factor_(screen_info_.deviceScaleFactor),
is_threaded_compositing_enabled_(false),
+ current_event_latency_info_(NULL),
next_output_surface_id_(0),
#if defined(OS_ANDROID)
text_field_is_dirty_(false),
@@ -912,6 +913,9 @@ void RenderWidget::OnHandleInputEvent(const blink::WebInputEvent* input_event,
base::AutoReset<WebInputEvent::Type> handling_event_type_resetter(
&handling_event_type_, input_event->type);
+ base::AutoReset<const ui::LatencyInfo*> resetter(&current_event_latency_info_,
+ &latency_info);
+
base::TimeTicks start_time;
if (base::TimeTicks::IsHighResNowFastAndReliable())
start_time = base::TimeTicks::HighResNow();
diff --git a/content/renderer/render_widget.h b/content/renderer/render_widget.h
index 7841307..acdc7d4 100644
--- a/content/renderer/render_widget.h
+++ b/content/renderer/render_widget.h
@@ -8,6 +8,7 @@
#include <deque>
#include <map>
+#include "base/auto_reset.h"
#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/memory/ref_counted.h"
@@ -159,6 +160,10 @@ class CONTENT_EXPORT RenderWidget
RenderWidgetCompositor* compositor() const;
+ const ui::LatencyInfo* current_event_latency_info() const {
+ return current_event_latency_info_;
+ }
+
virtual scoped_ptr<cc::OutputSurface> CreateOutputSurface(bool fallback);
// Callback for use with synthetic gestures (e.g. BeginSmoothScroll).
@@ -667,6 +672,8 @@ class CONTENT_EXPORT RenderWidget
// Specified whether the compositor will run in its own thread.
bool is_threaded_compositing_enabled_;
+ const ui::LatencyInfo* current_event_latency_info_;
+
uint32 next_output_surface_id_;
#if defined(OS_ANDROID)
diff --git a/mojo/examples/pepper_container_app/plugin_instance.cc b/mojo/examples/pepper_container_app/plugin_instance.cc
index cb39240..d4b79625 100644
--- a/mojo/examples/pepper_container_app/plugin_instance.cc
+++ b/mojo/examples/pepper_container_app/plugin_instance.cc
@@ -218,6 +218,10 @@ void PluginInstance::ClearInputEventRequest(PP_Instance instance,
NOTIMPLEMENTED();
}
+void PluginInstance::StartTrackingLatency(PP_Instance instance) {
+ NOTIMPLEMENTED();
+}
+
void PluginInstance::PostMessage(PP_Instance instance, PP_Var message) {
NOTIMPLEMENTED();
}
diff --git a/mojo/examples/pepper_container_app/plugin_instance.h b/mojo/examples/pepper_container_app/plugin_instance.h
index 56bd73f..e7f3434 100644
--- a/mojo/examples/pepper_container_app/plugin_instance.h
+++ b/mojo/examples/pepper_container_app/plugin_instance.h
@@ -81,6 +81,7 @@ class PluginInstance : public ppapi::thunk::PPB_Instance_API {
uint32_t event_classes) OVERRIDE;
virtual void ClearInputEventRequest(PP_Instance instance,
uint32_t event_classes) OVERRIDE;
+ virtual void StartTrackingLatency(PP_Instance instance) OVERRIDE;
virtual void PostMessage(PP_Instance instance, PP_Var message) OVERRIDE;
virtual PP_Bool SetCursor(PP_Instance instance,
PP_MouseCursor_Type type,
diff --git a/mojo/mojo_examples.gypi b/mojo/mojo_examples.gypi
index da07826..d45037a 100644
--- a/mojo/mojo_examples.gypi
+++ b/mojo/mojo_examples.gypi
@@ -75,6 +75,7 @@
'../gpu/gpu.gyp:command_buffer_common',
'../ppapi/ppapi.gyp:ppapi_c',
'../ppapi/ppapi_internal.gyp:ppapi_example_gles2_spinning_cube',
+ '../ui/events/events.gyp:events_base',
'mojo_common_lib',
'mojo_environment_chromium',
'mojo_geometry_bindings',
diff --git a/ppapi/api/private/ppb_input_event_private.idl b/ppapi/api/private/ppb_input_event_private.idl
new file mode 100644
index 0000000..f06804f
--- /dev/null
+++ b/ppapi/api/private/ppb_input_event_private.idl
@@ -0,0 +1,54 @@
+/* Copyright 2014 The Chromium Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/**
+ * This file defines the PPB_InputEvent_Private interfaces.
+ */
+
+label Chrome {
+ M37 = 0.1
+};
+
+/**
+ * The <code>PPB_InputEvent_Private</code> interface contains pointers to several
+ * functions related to generic input events on the browser.
+ */
+
+interface PPB_InputEvent_Private {
+ /**
+ * TraceInputLatency() traces the latency of the input event. The input
+ * latency is shown in the trace viewer. The starting point of the input
+ * latency is when the input event is sent from renderer to plugin. If the
+ * input event does not cause any rendering damage, the end point of input
+ * latency is when TraceInputLatency() is called on the event. If the input
+ * event does cause rendering damage, the end point of input latency is when
+ * the resulted plugin frame eventually reaches screen.
+ *
+ * Notes: In the current version, only Graphics2D damage is considered as
+ * rendering damage. And it works only when the Graphics2Ds are bound to
+ * the plugin instance.
+ *
+ * @param[in] event A <code>PP_Resource</code> corresponding to an input
+ * event.
+ *
+ * @param[in] has_damage A bool indicating whether the event has caused any
+ * rendering damage.
+ *
+ * @return <code>PP_TRUE</code> if the latency for the given event is tracked.
+ */
+ PP_Bool TraceInputLatency([in] PP_Resource event,
+ [in] PP_Bool has_damage);
+
+ /**
+ * StartTrackingLatency() requests input latency to be tracked.
+ *
+ * Without calling StartTrackingLatency() first, TraceInputLatency() won't
+ * take effect.
+ *
+ * @param[in] instance The <code>PP_Instance</code> of the instance requesting
+ * to start tracking input latency.
+ */
+ void StartTrackingLatency([in] PP_Instance instance);
+};
diff --git a/ppapi/c/pp_macros.h b/ppapi/c/pp_macros.h
index ae27731..910ac4c 100644
--- a/ppapi/c/pp_macros.h
+++ b/ppapi/c/pp_macros.h
@@ -3,13 +3,13 @@
* found in the LICENSE file.
*/
-/* From pp_macros.idl modified Thu Jan 23 14:14:38 2014. */
+/* From pp_macros.idl modified Tue May 20 17:13:23 2014. */
#ifndef PPAPI_C_PP_MACROS_H_
#define PPAPI_C_PP_MACROS_H_
-#define PPAPI_RELEASE 36
+#define PPAPI_RELEASE 37
/**
* @file
diff --git a/ppapi/c/private/ppb_input_event_private.h b/ppapi/c/private/ppb_input_event_private.h
new file mode 100644
index 0000000..9ab2064
--- /dev/null
+++ b/ppapi/c/private/ppb_input_event_private.h
@@ -0,0 +1,78 @@
+/* Copyright 2014 The Chromium Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/* From private/ppb_input_event_private.idl,
+ * modified Tue May 20 18:31:39 2014.
+ */
+
+#ifndef PPAPI_C_PRIVATE_PPB_INPUT_EVENT_PRIVATE_H_
+#define PPAPI_C_PRIVATE_PPB_INPUT_EVENT_PRIVATE_H_
+
+#include "ppapi/c/pp_bool.h"
+#include "ppapi/c/pp_instance.h"
+#include "ppapi/c/pp_macros.h"
+#include "ppapi/c/pp_resource.h"
+#include "ppapi/c/pp_stdint.h"
+
+#define PPB_INPUTEVENT_PRIVATE_INTERFACE_0_1 "PPB_InputEvent_Private;0.1"
+#define PPB_INPUTEVENT_PRIVATE_INTERFACE PPB_INPUTEVENT_PRIVATE_INTERFACE_0_1
+
+/**
+ * @file
+ * This file defines the PPB_InputEvent_Private interfaces.
+ */
+
+
+/**
+ * @addtogroup Interfaces
+ * @{
+ */
+/**
+ * The <code>PPB_InputEvent_Private</code> interface contains pointers to
+ several
+ * functions related to generic input events on the browser.
+ */
+struct PPB_InputEvent_Private_0_1 {
+ /**
+ * TraceInputLatency() traces the latency of the input event. The input
+ * latency is shown in the trace viewer. The starting point of the input
+ * latency is when the input event is sent from renderer to plugin. If the
+ * input event does not cause any rendering damage, the end point of input
+ * latency is when TraceInputLatency() is called on the event. If the input
+ * event does cause rendering damage, the end point of input latency is when
+ * the resulted plugin frame eventually reaches screen.
+ *
+ * Notes: In the current version, only Graphics2D damage is considered as
+ * rendering damage. And it works only when the Graphics2Ds are bound to
+ * the plugin instance.
+ *
+ * @param[in] event A <code>PP_Resource</code> corresponding to an input
+ * event.
+ *
+ * @param[in] has_damage A bool indicating whether the event has caused any
+ * rendering damage.
+ *
+ * @return <code>PP_TRUE</code> if the latency for the given event is tracked.
+ */
+ PP_Bool (*TraceInputLatency)(PP_Resource event, PP_Bool has_damage);
+ /**
+ * StartTrackingLatency() requests input latency to be tracked.
+ *
+ * Without calling StartTrackingLatency() first, TraceInputLatency() won't
+ * take effect.
+ *
+ * @param[in] instance The <code>PP_Instance</code> of the instance requesting
+ * to start tracking input latency.
+ */
+ void (*StartTrackingLatency)(PP_Instance instance);
+};
+
+typedef struct PPB_InputEvent_Private_0_1 PPB_InputEvent_Private;
+/**
+ * @}
+ */
+
+#endif /* PPAPI_C_PRIVATE_PPB_INPUT_EVENT_PRIVATE_H_ */
+
diff --git a/ppapi/cpp/private/input_event_private.cc b/ppapi/cpp/private/input_event_private.cc
new file mode 100644
index 0000000..7b53358
--- /dev/null
+++ b/ppapi/cpp/private/input_event_private.cc
@@ -0,0 +1,44 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/cpp/private/input_event_private.h"
+
+#include "ppapi/cpp/module_impl.h"
+
+namespace pp {
+
+namespace {
+
+template <> const char* interface_name<PPB_InputEvent_Private>() {
+ return PPB_INPUTEVENT_PRIVATE_INTERFACE;
+}
+
+} // namespace
+
+InputEventPrivate::InputEventPrivate() : InputEvent() {
+}
+
+InputEventPrivate::InputEventPrivate(const InputEvent& event) : InputEvent() {
+ if (!has_interface<PPB_InputEvent_Private_0_1>())
+ return;
+ Module::Get()->core()->AddRefResource(event.pp_resource());
+ PassRefFromConstructor(event.pp_resource());
+}
+
+bool InputEventPrivate::TraceInputLatency(bool has_damage) {
+ if (!has_interface<PPB_InputEvent_Private_0_1>())
+ return false;
+ return PP_ToBool(
+ get_interface<PPB_InputEvent_Private_0_1>()->TraceInputLatency(
+ pp_resource(), PP_FromBool(has_damage)));
+}
+
+void InputEventPrivate::StartTrackingLatency(const InstanceHandle& instance) {
+ if (!has_interface<PPB_InputEvent_Private>())
+ return;
+ return get_interface<PPB_InputEvent_Private>()->StartTrackingLatency(
+ instance.pp_instance());
+}
+
+} // namespace pp
diff --git a/ppapi/cpp/private/input_event_private.h b/ppapi/cpp/private/input_event_private.h
new file mode 100644
index 0000000..3fb4e3a
--- /dev/null
+++ b/ppapi/cpp/private/input_event_private.h
@@ -0,0 +1,27 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_CPP_PRIVATE_INPUT_EVENT_PRIVATE_H_
+#define PPAPI_CPP_PRIVATE_INPUT_EVENT_PRIVATE_H_
+
+#include "ppapi/c/private/ppb_input_event_private.h"
+#include "ppapi/cpp/input_event.h"
+
+namespace pp {
+
+class InputEventPrivate : public InputEvent {
+ public:
+ InputEventPrivate();
+ explicit InputEventPrivate(const InputEvent& event);
+
+ bool TraceInputLatency(bool has_damage);
+
+ /// See PPB_InputEventPrivate.StartTrackingLatency.
+ static void StartTrackingLatency (const InstanceHandle& instance);
+
+};
+
+}
+
+#endif // PPAPI_CPP_PRIVATE_INPUT_EVENT_PRIVATE_H_
diff --git a/ppapi/native_client/native_client.gyp b/ppapi/native_client/native_client.gyp
index 97dc9c7..c0b8fc9 100644
--- a/ppapi/native_client/native_client.gyp
+++ b/ppapi/native_client/native_client.gyp
@@ -119,6 +119,7 @@
'link_flags': [
'-Wl,--start-group',
'-lirt_browser',
+ '-llatency_info_nacl',
'-lpnacl_irt_shim_for_irt',
'-lppapi_proxy_nacl',
'-lppapi_ipc_nacl',
diff --git a/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c b/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c
index 406c743..2444aa9 100644
--- a/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c
+++ b/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c
@@ -3160,6 +3160,8 @@ static PP_Bool Pnacl_M19_PPB_HostResolver_Private_GetNetAddress(PP_Resource host
/* End wrapper methods for PPB_HostResolver_Private_0_1 */
+/* Not generating wrapper methods for PPB_InputEvent_Private_0_1 */
+
/* Begin wrapper methods for PPB_Instance_Private_0_1 */
static void Pnacl_M13_PPB_Instance_Private_GetWindowObject(struct PP_Var* _struct_result, PP_Instance instance) {
@@ -5107,6 +5109,8 @@ static const struct PPB_HostResolver_Private_0_1 Pnacl_Wrappers_PPB_HostResolver
.GetNetAddress = (PP_Bool (*)(PP_Resource host_resolver, uint32_t index, struct PP_NetAddress_Private* addr))&Pnacl_M19_PPB_HostResolver_Private_GetNetAddress
};
+/* Not generating wrapper interface for PPB_InputEvent_Private_0_1 */
+
static const struct PPB_Instance_Private_0_1 Pnacl_Wrappers_PPB_Instance_Private_0_1 = {
.GetWindowObject = (struct PP_Var (*)(PP_Instance instance))&Pnacl_M13_PPB_Instance_Private_GetWindowObject,
.GetOwnerElementObject = (struct PP_Var (*)(PP_Instance instance))&Pnacl_M13_PPB_Instance_Private_GetOwnerElementObject,
diff --git a/ppapi/ppapi_internal.gyp b/ppapi/ppapi_internal.gyp
index 989a591..3a07317 100644
--- a/ppapi/ppapi_internal.gyp
+++ b/ppapi/ppapi_internal.gyp
@@ -52,6 +52,7 @@
'../media/media.gyp:shared_memory_support',
'../skia/skia.gyp:skia',
'../third_party/icu/icu.gyp:icuuc',
+ '../ui/events/events.gyp:events_base',
'../ui/surface/surface.gyp:surface',
'../url/url.gyp:url_lib',
'ppapi.gyp:ppapi_c',
@@ -102,6 +103,7 @@
'../gpu/gpu.gyp:gpu_ipc',
'../ipc/ipc.gyp:ipc',
'../skia/skia.gyp:skia',
+ '../ui/events/ipc/events_ipc.gyp:events_ipc',
'ppapi.gyp:ppapi_c',
'ppapi_shared',
],
@@ -127,6 +129,7 @@
'../skia/skia.gyp:skia',
'../third_party/icu/icu.gyp:icuuc',
'../third_party/icu/icu.gyp:icui18n',
+ '../ui/events/events.gyp:events_base',
'../ui/surface/surface.gyp:surface',
'ppapi.gyp:ppapi_c',
'ppapi_shared',
@@ -175,6 +178,8 @@
'../skia/skia.gyp:skia',
'../third_party/icu/icu.gyp:icuuc',
'../third_party/icu/icu.gyp:icui18n',
+ '../ui/events/events.gyp:events_base',
+ '../ui/events/ipc/events_ipc.gyp:events_ipc',
'../ui/surface/surface.gyp:surface',
'ppapi.gyp:ppapi_c',
'ppapi_shared',
@@ -227,6 +232,7 @@
'../base/base.gyp:base_win64',
'../base/third_party/dynamic_annotations/dynamic_annotations.gyp:dynamic_annotations_win64',
'../ipc/ipc.gyp:ipc_win64',
+ '../ui/events/latency_info_nacl.gyp:latency_info_nacl_win64',
],
'defines': [
'<@(nacl_win64_defines)',
@@ -251,6 +257,7 @@
'../base/base.gyp:base_win64',
'../ipc/ipc.gyp:ipc_win64',
'../gpu/gpu.gyp:gpu_ipc_win64',
+ '../ui/events/latency_info_nacl.gyp:latency_info_nacl_win64',
'ppapi.gyp:ppapi_c',
'ppapi_shared_win64',
],
diff --git a/ppapi/ppapi_proxy_nacl.gyp b/ppapi/ppapi_proxy_nacl.gyp
index 14deb4c..868465d 100644
--- a/ppapi/ppapi_proxy_nacl.gyp
+++ b/ppapi/ppapi_proxy_nacl.gyp
@@ -42,6 +42,7 @@
'../ppapi/ppapi_shared_nacl.gyp:ppapi_shared_nacl',
'../third_party/WebKit/public/blink_headers.gyp:blink_headers',
'../third_party/khronos/khronos.gyp:khronos_headers',
+ '../ui/events/latency_info_nacl.gyp:latency_info_nacl',
],
},
],
diff --git a/ppapi/ppapi_shared.gypi b/ppapi/ppapi_shared.gypi
index 94f88f9..035aedf 100644
--- a/ppapi/ppapi_shared.gypi
+++ b/ppapi/ppapi_shared.gypi
@@ -205,6 +205,7 @@
'thunk/ppb_image_data_thunk.cc',
'thunk/ppb_input_event_api.h',
'thunk/ppb_input_event_thunk.cc',
+ 'thunk/ppb_input_event_private_thunk.cc',
'thunk/ppb_instance_api.h',
'thunk/ppb_instance_private_thunk.cc',
'thunk/ppb_instance_thunk.cc',
diff --git a/ppapi/ppapi_sources.gypi b/ppapi/ppapi_sources.gypi
index 43a17dd..9675a4d 100644
--- a/ppapi/ppapi_sources.gypi
+++ b/ppapi/ppapi_sources.gypi
@@ -118,6 +118,7 @@
'c/private/ppb_flash_menu.h',
'c/private/ppb_flash_message_loop.h',
'c/private/ppb_host_resolver_private.h',
+ 'c/private/ppb_input_event_private.h',
'c/private/ppb_instance_private.h',
'c/private/ppb_isolated_file_system_private.h',
'c/private/ppb_nacl_private.h',
@@ -337,6 +338,8 @@
'cpp/private/flash_message_loop.h',
'cpp/private/host_resolver_private.cc',
'cpp/private/host_resolver_private.h',
+ 'cpp/private/input_event_private.cc',
+ 'cpp/private/input_event_private.h',
'cpp/private/instance_private.cc',
'cpp/private/instance_private.h',
'cpp/private/isolated_file_system_private.cc',
diff --git a/ppapi/proxy/DEPS b/ppapi/proxy/DEPS
index 0e60992..1d723b4 100644
--- a/ppapi/proxy/DEPS
+++ b/ppapi/proxy/DEPS
@@ -5,6 +5,7 @@ include_rules = [
"+media/audio",
"+skia",
"+ui/surface",
+ "+ui/events",
# We don't want the proxy to depend on the C++ layer, which is appropriate
# for plugins only. However, the completion callback factory is a very useful
diff --git a/ppapi/proxy/graphics_2d_resource.cc b/ppapi/proxy/graphics_2d_resource.cc
index 0cf7465..ea8a9c5 100644
--- a/ppapi/proxy/graphics_2d_resource.cc
+++ b/ppapi/proxy/graphics_2d_resource.cc
@@ -122,9 +122,12 @@ int32_t Graphics2DResource::Flush(scoped_refptr<TrackedCallback> callback) {
return PP_ERROR_INPROGRESS; // Can't have >1 flush pending.
current_flush_callback_ = callback;
+ std::vector<ui::LatencyInfo> latency_info;
+ PpapiGlobals::Get()->TransferLatencyInfoTo(&latency_info, pp_instance());
+
Call<PpapiPluginMsg_Graphics2D_FlushAck>(
RENDERER,
- PpapiHostMsg_Graphics2D_Flush(),
+ PpapiHostMsg_Graphics2D_Flush(latency_info),
base::Bind(&Graphics2DResource::OnPluginMsgFlushACK, this));
return PP_OK_COMPLETIONPENDING;
}
diff --git a/ppapi/proxy/interface_list.cc b/ppapi/proxy/interface_list.cc
index 3c45dfd..d9809f0 100644
--- a/ppapi/proxy/interface_list.cc
+++ b/ppapi/proxy/interface_list.cc
@@ -85,6 +85,7 @@
#include "ppapi/c/private/ppb_flash_message_loop.h"
#include "ppapi/c/private/ppb_flash_print.h"
#include "ppapi/c/private/ppb_host_resolver_private.h"
+#include "ppapi/c/private/ppb_input_event_private.h"
#include "ppapi/c/private/ppb_isolated_file_system_private.h"
#include "ppapi/c/private/ppb_net_address_private.h"
#include "ppapi/c/private/ppb_output_protection_private.h"
diff --git a/ppapi/proxy/ppapi_messages.h b/ppapi/proxy/ppapi_messages.h
index 95ac3d9..6cd36df 100644
--- a/ppapi/proxy/ppapi_messages.h
+++ b/ppapi/proxy/ppapi_messages.h
@@ -73,6 +73,7 @@
#include "ppapi/shared_impl/socket_option_data.h"
#include "ppapi/shared_impl/url_request_info_data.h"
#include "ppapi/shared_impl/url_response_info_data.h"
+#include "ui/events/ipc/latency_info_param_traits.h"
#undef IPC_MESSAGE_EXPORT
#define IPC_MESSAGE_EXPORT PPAPI_PROXY_EXPORT
@@ -300,6 +301,7 @@ IPC_STRUCT_TRAITS_BEGIN(ppapi::InputEventData)
IPC_STRUCT_TRAITS_MEMBER(touches)
IPC_STRUCT_TRAITS_MEMBER(changed_touches)
IPC_STRUCT_TRAITS_MEMBER(target_touches)
+ IPC_STRUCT_TRAITS_MEMBER(latency_info)
IPC_STRUCT_TRAITS_END()
IPC_STRUCT_TRAITS_BEGIN(ppapi::HostPortPair)
@@ -884,6 +886,8 @@ IPC_MESSAGE_ROUTED3(PpapiHostMsg_PPBInstance_RequestInputEvents,
IPC_MESSAGE_ROUTED2(PpapiHostMsg_PPBInstance_ClearInputEvents,
PP_Instance /* instance */,
uint32_t /* event_classes */)
+IPC_MESSAGE_ROUTED1(PpapiHostMsg_PPBInstance_StartTrackingLatency,
+ PP_Instance /* instance */)
IPC_MESSAGE_ROUTED2(PpapiHostMsg_PPBInstance_PostMessage,
PP_Instance /* instance */,
ppapi::proxy::SerializedVar /* message */)
@@ -1418,7 +1422,8 @@ IPC_MESSAGE_CONTROL1(PpapiHostMsg_Graphics2D_SetScale,
float /* scale */)
// Graphics2D, plugin -> host -> plugin
-IPC_MESSAGE_CONTROL0(PpapiHostMsg_Graphics2D_Flush)
+IPC_MESSAGE_CONTROL1(PpapiHostMsg_Graphics2D_Flush,
+ std::vector<ui::LatencyInfo> /* latency_info */)
IPC_MESSAGE_CONTROL0(PpapiPluginMsg_Graphics2D_FlushAck)
IPC_MESSAGE_CONTROL2(PpapiHostMsg_Graphics2D_ReadImageData,
diff --git a/ppapi/proxy/ppb_instance_proxy.cc b/ppapi/proxy/ppb_instance_proxy.cc
index 85f1f16..93e6660 100644
--- a/ppapi/proxy/ppb_instance_proxy.cc
+++ b/ppapi/proxy/ppb_instance_proxy.cc
@@ -145,6 +145,8 @@ bool PPB_Instance_Proxy::OnMessageReceived(const IPC::Message& msg) {
OnHostMsgRequestInputEvents)
IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_ClearInputEvents,
OnHostMsgClearInputEvents)
+ IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_StartTrackingLatency,
+ OnHostMsgStartTrackingLatency)
IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_LockMouse,
OnHostMsgLockMouse)
IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_UnlockMouse,
@@ -480,6 +482,11 @@ void PPB_Instance_Proxy::ClearInputEventRequest(PP_Instance instance,
API_ID_PPB_INSTANCE, instance, event_classes));
}
+void PPB_Instance_Proxy::StartTrackingLatency(PP_Instance instance) {
+ dispatcher()->Send(new PpapiHostMsg_PPBInstance_StartTrackingLatency(
+ API_ID_PPB_INSTANCE, instance));
+}
+
void PPB_Instance_Proxy::ZoomChanged(PP_Instance instance,
double factor) {
// Not proxied yet.
@@ -1004,6 +1011,12 @@ void PPB_Instance_Proxy::OnHostMsgClearInputEvents(PP_Instance instance,
enter.functions()->ClearInputEventRequest(instance, event_classes);
}
+void PPB_Instance_Proxy::OnHostMsgStartTrackingLatency(PP_Instance instance) {
+ EnterInstanceNoLock enter(instance);
+ if (enter.succeeded())
+ enter.functions()->StartTrackingLatency(instance);
+}
+
void PPB_Instance_Proxy::OnHostMsgPostMessage(
PP_Instance instance,
SerializedVarReceiveInput message) {
diff --git a/ppapi/proxy/ppb_instance_proxy.h b/ppapi/proxy/ppb_instance_proxy.h
index 40bb3f1..4a6d7f2 100644
--- a/ppapi/proxy/ppb_instance_proxy.h
+++ b/ppapi/proxy/ppb_instance_proxy.h
@@ -78,6 +78,7 @@ class PPB_Instance_Proxy : public InterfaceProxy,
uint32_t event_classes) OVERRIDE;
virtual int32_t RequestFilteringInputEvents(PP_Instance instance,
uint32_t event_classes) OVERRIDE;
+ virtual void StartTrackingLatency(PP_Instance instance) OVERRIDE;
virtual void ClearInputEventRequest(PP_Instance instance,
uint32_t event_classes) OVERRIDE;
virtual void ZoomChanged(PP_Instance instance, double factor) OVERRIDE;
@@ -193,6 +194,7 @@ class PPB_Instance_Proxy : public InterfaceProxy,
void OnHostMsgRequestInputEvents(PP_Instance instance,
bool is_filtering,
uint32_t event_classes);
+ void OnHostMsgStartTrackingLatency(PP_Instance instance);
void OnHostMsgClearInputEvents(PP_Instance instance,
uint32_t event_classes);
void OnHostMsgPostMessage(PP_Instance instance,
diff --git a/ppapi/shared_impl/DEPS b/ppapi/shared_impl/DEPS
index 6055a34..1877bfb 100644
--- a/ppapi/shared_impl/DEPS
+++ b/ppapi/shared_impl/DEPS
@@ -4,6 +4,7 @@ include_rules = [
"+media/audio",
"+media/base",
"+skia",
+ "+ui/events",
"+webkit/common/webpreferences.h",
"+webkit/common/fileapi/file_system_types.h",
diff --git a/ppapi/shared_impl/ppapi_globals.cc b/ppapi/shared_impl/ppapi_globals.cc
index 3e985cf..eef3f5c 100644
--- a/ppapi/shared_impl/ppapi_globals.cc
+++ b/ppapi/shared_impl/ppapi_globals.cc
@@ -67,6 +67,17 @@ bool PpapiGlobals::IsPluginGlobals() const { return false; }
void PpapiGlobals::MarkPluginIsActive() {}
+void PpapiGlobals::AddLatencyInfo(const ui::LatencyInfo& latency_info,
+ PP_Instance instance) {
+ latency_info_for_frame_[instance].push_back(latency_info);
+}
+
+void PpapiGlobals::TransferLatencyInfoTo(
+ std::vector<ui::LatencyInfo>* latency_info, PP_Instance instance) {
+ latency_info->swap(latency_info_for_frame_[instance]);
+ latency_info_for_frame_.erase(instance);
+}
+
// static
PpapiGlobals* PpapiGlobals::GetThreadLocalPointer() {
return tls_ppapi_globals_for_test.Pointer()->Get();
diff --git a/ppapi/shared_impl/ppapi_globals.h b/ppapi/shared_impl/ppapi_globals.h
index d9be0387..a98d897 100644
--- a/ppapi/shared_impl/ppapi_globals.h
+++ b/ppapi/shared_impl/ppapi_globals.h
@@ -5,7 +5,9 @@
#ifndef PPAPI_SHARED_IMPL_PPAPI_GLOBALS_H_
#define PPAPI_SHARED_IMPL_PPAPI_GLOBALS_H_
+#include <map>
#include <string>
+#include <vector>
#include "base/basictypes.h"
#include "base/memory/ref_counted.h"
@@ -15,6 +17,7 @@
#include "ppapi/c/ppb_console.h"
#include "ppapi/shared_impl/api_id.h"
#include "ppapi/shared_impl/ppapi_shared_export.h"
+#include "ui/events/latency_info.h"
namespace base {
class MessageLoopProxy;
@@ -134,6 +137,13 @@ class PPAPI_SHARED_EXPORT PpapiGlobals {
// renderer process will have no effect.
virtual void MarkPluginIsActive();
+ // Caches an input event's |latency_info| for the plugin |instance|.
+ void AddLatencyInfo(const ui::LatencyInfo& latency_info,
+ PP_Instance instance);
+ // Transfers plugin |instance|'s latency info into |latency_info|.
+ void TransferLatencyInfoTo(std::vector<ui::LatencyInfo>* latency_info,
+ PP_Instance instance);
+
private:
// Return the thread-local pointer which is used only for unit testing. It
// should always be NULL when running in production. It allows separate
@@ -142,6 +152,11 @@ class PPAPI_SHARED_EXPORT PpapiGlobals {
scoped_refptr<base::MessageLoopProxy> main_loop_proxy_;
+ // If an input event is believed to have caused rendering damage, its latency
+ // info is cached in |latency_info_for_frame_| indexed by instance. These
+ // latency info will be passed back to renderer with the next plugin frame.
+ std::map<PP_Instance, std::vector<ui::LatencyInfo> > latency_info_for_frame_;
+
DISALLOW_COPY_AND_ASSIGN(PpapiGlobals);
};
diff --git a/ppapi/shared_impl/ppb_input_event_shared.cc b/ppapi/shared_impl/ppb_input_event_shared.cc
index 3443759..ef4e719 100644
--- a/ppapi/shared_impl/ppb_input_event_shared.cc
+++ b/ppapi/shared_impl/ppb_input_event_shared.cc
@@ -4,6 +4,7 @@
#include "ppapi/shared_impl/ppb_input_event_shared.h"
+#include "ppapi/shared_impl/ppapi_globals.h"
#include "ppapi/shared_impl/var.h"
using ppapi::thunk::PPB_InputEvent_API;
@@ -191,6 +192,20 @@ PP_TouchPoint PPB_InputEvent_Shared::GetTouchById(PP_TouchListType list,
return PP_MakeTouchPoint();
}
+PP_Bool PPB_InputEvent_Shared::TraceInputLatency(PP_Bool has_damage) {
+ ui::LatencyInfo latency = data_.latency_info;
+ if (!latency.FindLatency(ui::INPUT_EVENT_LATENCY_BEGIN_PLUGIN_COMPONENT,
+ 0, NULL))
+ return PP_FALSE;
+ if (has_damage) {
+ PpapiGlobals::Get()->AddLatencyInfo(latency, pp_instance());
+ } else {
+ latency.AddLatencyNumber(
+ ui::INPUT_EVENT_LATENCY_TERMINATED_PLUGIN_COMPONENT, 0, 0);
+ }
+ return PP_TRUE;
+}
+
// static
PP_Resource PPB_InputEvent_Shared::CreateIMEInputEvent(
ResourceObjectType type,
diff --git a/ppapi/shared_impl/ppb_input_event_shared.h b/ppapi/shared_impl/ppb_input_event_shared.h
index ad467b4..ebfad86 100644
--- a/ppapi/shared_impl/ppb_input_event_shared.h
+++ b/ppapi/shared_impl/ppb_input_event_shared.h
@@ -13,6 +13,7 @@
#include "ppapi/c/ppb_input_event.h"
#include "ppapi/shared_impl/resource.h"
#include "ppapi/thunk/ppb_input_event_api.h"
+#include "ui/events/latency_info.h"
namespace ppapi {
@@ -56,6 +57,8 @@ struct PPAPI_SHARED_EXPORT InputEventData {
std::vector<PP_TouchPoint> touches;
std::vector<PP_TouchPoint> changed_touches;
std::vector<PP_TouchPoint> target_touches;
+
+ ui::LatencyInfo latency_info;
};
// This simple class implements the PPB_InputEvent_API in terms of the
@@ -97,6 +100,7 @@ class PPAPI_SHARED_EXPORT PPB_InputEvent_Shared
uint32_t index) OVERRIDE;
virtual PP_TouchPoint GetTouchById(PP_TouchListType list,
uint32_t id) OVERRIDE;
+ virtual PP_Bool TraceInputLatency(PP_Bool has_damage) OVERRIDE;
// Implementations for event creation.
static PP_Resource CreateIMEInputEvent(ResourceObjectType type,
diff --git a/ppapi/tests/all_c_includes.h b/ppapi/tests/all_c_includes.h
index abb6710..611d72c 100644
--- a/ppapi/tests/all_c_includes.h
+++ b/ppapi/tests/all_c_includes.h
@@ -115,6 +115,7 @@
#include "ppapi/c/private/ppb_flash_menu.h"
#include "ppapi/c/private/ppb_flash_message_loop.h"
#include "ppapi/c/private/ppb_host_resolver_private.h"
+#include "ppapi/c/private/ppb_input_event_private.h"
#include "ppapi/c/private/ppb_instance_private.h"
#include "ppapi/c/private/ppb_nacl_private.h"
#include "ppapi/c/private/ppb_net_address_private.h"
diff --git a/ppapi/tests/test_input_event.cc b/ppapi/tests/test_input_event.cc
index 4fd0eda..902d345 100644
--- a/ppapi/tests/test_input_event.cc
+++ b/ppapi/tests/test_input_event.cc
@@ -31,6 +31,7 @@ pp::Point GetCenter(const pp::Rect& rect) {
void TestInputEvent::RunTests(const std::string& filter) {
RUN_TEST(Events, filter);
+ RUN_TEST(EventsLatencyTracking, filter);
// The AcceptTouchEvent_N tests should not be run when the filter is empty;
// they can only be run one at a time.
@@ -55,7 +56,9 @@ TestInputEvent::TestInputEvent(TestingInstance* instance)
view_rect_(),
expected_input_event_(0),
received_expected_event_(false),
- received_finish_message_(false) {
+ received_finish_message_(false),
+ enable_latency_tracking_(false),
+ last_latency_tracking_successful_(false) {
}
TestInputEvent::~TestInputEvent() {
@@ -72,6 +75,8 @@ TestInputEvent::~TestInputEvent() {
bool TestInputEvent::Init() {
input_event_interface_ = static_cast<const PPB_InputEvent*>(
pp::Module::Get()->GetBrowserInterface(PPB_INPUT_EVENT_INTERFACE));
+ input_event_private_interface_ = static_cast<const PPB_InputEvent_Private*>(
+ pp::Module::Get()->GetBrowserInterface(PPB_INPUTEVENT_PRIVATE_INTERFACE));
mouse_input_event_interface_ = static_cast<const PPB_MouseInputEvent*>(
pp::Module::Get()->GetBrowserInterface(
PPB_MOUSE_INPUT_EVENT_INTERFACE));
@@ -87,6 +92,7 @@ bool TestInputEvent::Init() {
bool success =
input_event_interface_ &&
+ input_event_private_interface_ &&
mouse_input_event_interface_ &&
wheel_input_event_interface_ &&
keyboard_input_event_interface_ &&
@@ -305,6 +311,10 @@ bool TestInputEvent::HandleInputEvent(const pp::InputEvent& input_event) {
expected_input_event_.pp_resource());
}
// Handle all input events.
+ if (enable_latency_tracking_) {
+ pp::InputEventPrivate private_event(input_event);
+ last_latency_tracking_successful_ = private_event.TraceInputLatency(true);
+ }
return true;
}
@@ -321,6 +331,28 @@ void TestInputEvent::DidChangeView(const pp::View& view) {
view_rect_ = view.GetRect();
}
+std::string TestInputEvent::TestEventsLatencyTracking() {
+ enable_latency_tracking_ = true;
+ input_event_interface_->RequestInputEvents(instance_->pp_instance(),
+ PP_INPUTEVENT_CLASS_TOUCH);
+ PostMessageBarrier();
+
+ ASSERT_TRUE(SimulateInputEvent(CreateTouchEvent(PP_INPUTEVENT_TYPE_TOUCHSTART,
+ pp::FloatPoint(12, 23))));
+ // Without calling StartTrackingLatency() first, TraceInputLatency() won't
+ // take effect and will return false;
+ ASSERT_FALSE(last_latency_tracking_successful_);
+
+ input_event_private_interface_->StartTrackingLatency(
+ instance_->pp_instance());
+
+ ASSERT_TRUE(SimulateInputEvent(CreateTouchEvent(PP_INPUTEVENT_TYPE_TOUCHSTART,
+ pp::FloatPoint(12, 23))));
+ ASSERT_TRUE(last_latency_tracking_successful_);
+
+ PASS();
+}
+
std::string TestInputEvent::TestEvents() {
// Request all input event classes.
input_event_interface_->RequestInputEvents(instance_->pp_instance(),
diff --git a/ppapi/tests/test_input_event.h b/ppapi/tests/test_input_event.h
index 88e7388..1e5aeea 100644
--- a/ppapi/tests/test_input_event.h
+++ b/ppapi/tests/test_input_event.h
@@ -12,6 +12,7 @@
#include "ppapi/c/private/ppb_testing_private.h"
#include "ppapi/cpp/input_event.h"
#include "ppapi/cpp/point.h"
+#include "ppapi/cpp/private/input_event_private.h"
#include "ppapi/cpp/rect.h"
#include "ppapi/tests/test_case.h"
#include "ppapi/tests/test_utils.h"
@@ -44,12 +45,14 @@ class TestInputEvent : public TestCase {
bool AreEquivalentEvents(PP_Resource first, PP_Resource second);
std::string TestEvents();
+ std::string TestEventsLatencyTracking();
std::string TestAcceptTouchEvent_1();
std::string TestAcceptTouchEvent_2();
std::string TestAcceptTouchEvent_3();
std::string TestAcceptTouchEvent_4();
const PPB_InputEvent* input_event_interface_;
+ const PPB_InputEvent_Private* input_event_private_interface_;
const PPB_MouseInputEvent* mouse_input_event_interface_;
const PPB_WheelInputEvent* wheel_input_event_interface_;
const PPB_KeyboardInputEvent* keyboard_input_event_interface_;
@@ -61,6 +64,8 @@ class TestInputEvent : public TestCase {
pp::InputEvent expected_input_event_;
bool received_expected_event_;
bool received_finish_message_;
+ bool enable_latency_tracking_;
+ bool last_latency_tracking_successful_;
};
#endif // PPAPI_TESTS_TEST_INPUT_EVENT_H_
diff --git a/ppapi/thunk/interfaces_ppb_private.h b/ppapi/thunk/interfaces_ppb_private.h
index 7e3988e..01f175c 100644
--- a/ppapi/thunk/interfaces_ppb_private.h
+++ b/ppapi/thunk/interfaces_ppb_private.h
@@ -63,4 +63,7 @@ PROXIED_IFACE(PPB_FONT_DEV_INTERFACE_0_6,
PPB_BrowserFont_Trusted_1_0)
#endif // !defined(OS_NACL)
+PROXIED_IFACE(PPB_INPUTEVENT_PRIVATE_INTERFACE_0_1,
+ PPB_InputEvent_Private_0_1)
+
#include "ppapi/thunk/interfaces_postamble.h"
diff --git a/ppapi/thunk/ppb_input_event_api.h b/ppapi/thunk/ppb_input_event_api.h
index 00627353..9210c85 100644
--- a/ppapi/thunk/ppb_input_event_api.h
+++ b/ppapi/thunk/ppb_input_event_api.h
@@ -47,6 +47,9 @@ class PPAPI_THUNK_EXPORT PPB_InputEvent_API {
uint32_t index) = 0;
virtual PP_TouchPoint GetTouchById(PP_TouchListType list,
uint32_t id) = 0;
+
+ // Private API.
+ virtual PP_Bool TraceInputLatency(PP_Bool has_damage) = 0;
};
} // namespace thunk
diff --git a/ppapi/thunk/ppb_input_event_private_thunk.cc b/ppapi/thunk/ppb_input_event_private_thunk.cc
new file mode 100644
index 0000000..4bc7812
--- /dev/null
+++ b/ppapi/thunk/ppb_input_event_private_thunk.cc
@@ -0,0 +1,42 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/c/private/ppb_input_event_private.h"
+#include "ppapi/thunk/enter.h"
+#include "ppapi/thunk/ppb_input_event_api.h"
+#include "ppapi/thunk/thunk.h"
+
+namespace ppapi {
+namespace thunk {
+
+namespace {
+
+PP_Bool TraceInputLatency(PP_Resource event, PP_Bool has_damage) {
+ EnterResource<PPB_InputEvent_API> enter(event, true);
+ if (enter.failed())
+ return PP_FALSE;
+ return enter.object()->TraceInputLatency(has_damage);
+}
+
+void StartTrackingLatency(PP_Instance instance) {
+ EnterInstance enter(instance);
+ if (enter.failed())
+ return;
+ enter.functions()->StartTrackingLatency(instance);
+}
+
+const PPB_InputEvent_Private_0_1 g_ppb_input_event_private_thunk_0_1 = {
+ &TraceInputLatency,
+ &StartTrackingLatency
+};
+
+} // namespace
+
+const PPB_InputEvent_Private_0_1* GetPPB_InputEvent_Private_0_1_Thunk() {
+ return &g_ppb_input_event_private_thunk_0_1;
+}
+
+} // namespace thunk
+} // namespace ppapi
diff --git a/ppapi/thunk/ppb_instance_api.h b/ppapi/thunk/ppb_instance_api.h
index 23bf18c..db73979 100644
--- a/ppapi/thunk/ppb_instance_api.h
+++ b/ppapi/thunk/ppb_instance_api.h
@@ -109,6 +109,9 @@ class PPB_Instance_API {
virtual void ClearInputEventRequest(PP_Instance instance,
uint32_t event_classes) = 0;
+ // InputEventPrivate.
+ virtual void StartTrackingLatency(PP_Instance instance) = 0;
+
// Messaging.
virtual void PostMessage(PP_Instance instance, PP_Var message) = 0;
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index 896431e..dc615ac 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -40223,6 +40223,7 @@ Therefore, the affected-histogram name has to have at least one dot in it.
<int value="1519132417" label="PPB_FileSystem;1.0"/>
<int value="1520420939" label="PPB_MouseCursor;1.0"/>
<int value="1528832860" label="PPB_FileChooser(Dev);0.6"/>
+ <int value="1577776196" label="PPB_InputEvent_Private;0.1"/>
<int value="1641037564" label="PPB_VideoSource_Private;0.1"/>
<int value="1645591549" label="PPB_Widget(Dev);0.3"/>
<int value="1677958987" label="PPB_ImageData;1.0"/>
diff --git a/ui/events/latency_info.cc b/ui/events/latency_info.cc
index 2fbe2ec..3fedd67e 100644
--- a/ui/events/latency_info.cc
+++ b/ui/events/latency_info.cc
@@ -18,6 +18,7 @@ const char* GetComponentName(ui::LatencyComponentType type) {
#define CASE_TYPE(t) case ui::t: return #t
switch (type) {
CASE_TYPE(INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT);
+ CASE_TYPE(INPUT_EVENT_LATENCY_BEGIN_PLUGIN_COMPONENT);
CASE_TYPE(INPUT_EVENT_LATENCY_SCROLL_UPDATE_RWH_COMPONENT);
CASE_TYPE(INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL_COMPONENT);
CASE_TYPE(INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT);
@@ -32,6 +33,7 @@ const char* GetComponentName(ui::LatencyComponentType type) {
CASE_TYPE(INPUT_EVENT_LATENCY_TERMINATED_COMMIT_FAILED_COMPONENT);
CASE_TYPE(INPUT_EVENT_LATENCY_TERMINATED_SWAP_FAILED_COMPONENT);
CASE_TYPE(LATENCY_INFO_LIST_TERMINATED_OVERFLOW_COMPONENT);
+ CASE_TYPE(INPUT_EVENT_LATENCY_TERMINATED_PLUGIN_COMPONENT);
default:
DLOG(WARNING) << "Unhandled LatencyComponentType.\n";
break;
@@ -49,6 +51,7 @@ bool IsTerminalComponent(ui::LatencyComponentType type) {
case ui::INPUT_EVENT_LATENCY_TERMINATED_COMMIT_FAILED_COMPONENT:
case ui::INPUT_EVENT_LATENCY_TERMINATED_SWAP_FAILED_COMPONENT:
case ui::LATENCY_INFO_LIST_TERMINATED_OVERFLOW_COMPONENT:
+ case ui::INPUT_EVENT_LATENCY_TERMINATED_PLUGIN_COMPONENT:
return true;
default:
return false;
@@ -56,7 +59,8 @@ bool IsTerminalComponent(ui::LatencyComponentType type) {
}
bool IsBeginComponent(ui::LatencyComponentType type) {
- return (type == ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT);
+ return (type == ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT ||
+ type == ui::INPUT_EVENT_LATENCY_BEGIN_PLUGIN_COMPONENT);
}
// This class is for converting latency info to trace buffer friendly format.
diff --git a/ui/events/latency_info.h b/ui/events/latency_info.h
index 7220187..619b046 100644
--- a/ui/events/latency_info.h
+++ b/ui/events/latency_info.h
@@ -20,6 +20,8 @@ enum LatencyComponentType {
// BEGIN COMPONENT is when we show the latency begin in chrome://tracing.
// Timestamp when the input event is sent from RenderWidgetHost to renderer.
INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT,
+ // Timestamp when the input event is received in plugin.
+ INPUT_EVENT_LATENCY_BEGIN_PLUGIN_COMPONENT,
// ---------------------------NORMAL COMPONENT-------------------------------
// Timestamp when the scroll update gesture event is sent from RWH to
// renderer. In Aura, touch event's LatencyInfo is carried over to the gesture
@@ -65,7 +67,10 @@ enum LatencyComponentType {
// This component indicates that the cached LatencyInfo number exceeds the
// maximal allowed size.
LATENCY_INFO_LIST_TERMINATED_OVERFLOW_COMPONENT,
- LATENCY_COMPONENT_TYPE_LAST = LATENCY_INFO_LIST_TERMINATED_OVERFLOW_COMPONENT
+ // Timestamp when the input event is considered not cause any rendering
+ // damage in plugin and thus terminated.
+ INPUT_EVENT_LATENCY_TERMINATED_PLUGIN_COMPONENT,
+ LATENCY_COMPONENT_TYPE_LAST = INPUT_EVENT_LATENCY_TERMINATED_PLUGIN_COMPONENT
};
struct EVENTS_BASE_EXPORT LatencyInfo {
diff --git a/ui/events/latency_info_nacl.gyp b/ui/events/latency_info_nacl.gyp
index 2a00f40..e42dbf8 100644
--- a/ui/events/latency_info_nacl.gyp
+++ b/ui/events/latency_info_nacl.gyp
@@ -10,8 +10,9 @@
'targets': [
{
'target_name': 'latency_info_nacl',
- 'type': '<(component)',
+ 'type': 'none',
'defines': [
+ 'EVENTS_BASE_IMPLEMENTATION',
'EVENTS_IMPLEMENTATION',
],
'include_dirs': [
@@ -38,5 +39,40 @@
},
],
}],
+ ['disable_nacl!=1 and OS=="win" and target_arch=="ia32"', {
+ 'targets': [
+ {
+ 'target_name': 'latency_info_nacl_win64',
+ 'type' : '<(component)',
+ 'variables': {
+ 'nacl_win64_target': 1,
+ },
+ 'dependencies': [
+ '<(DEPTH)/base/base.gyp:base_win64',
+ '<(DEPTH)/ipc/ipc.gyp:ipc_win64',
+ ],
+ 'defines': [
+ 'EVENTS_BASE_IMPLEMENTATION',
+ 'EVENTS_IMPLEMENTATION',
+ '<@(nacl_win64_defines)',
+ ],
+ 'include_dirs': [
+ '../..',
+ ],
+ 'sources': [
+ 'latency_info.cc',
+ 'latency_info.h',
+ 'ipc/latency_info_param_traits.cc',
+ 'ipc/latency_info_param_traits.h',
+ ],
+ 'configurations': {
+ 'Common_Base': {
+ 'msvs_target_platform': 'x64',
+ },
+ },
+ },
+ ],
+ }],
],
}
+