summaryrefslogtreecommitdiffstats
path: root/cc
diff options
context:
space:
mode:
authormiletus@chromium.org <miletus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-12-08 06:47:31 +0000
committermiletus@chromium.org <miletus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-12-08 06:47:31 +0000
commit6be422be283bff883a198254047ff23dc2f4baa0 (patch)
tree0d945e2cd10fdc1f15ab9c3bd6a212e379ea270c /cc
parent81ebff3b727b9e86317a235d4b97f9c718471fc0 (diff)
downloadchromium_src-6be422be283bff883a198254047ff23dc2f4baa0.zip
chromium_src-6be422be283bff883a198254047ff23dc2f4baa0.tar.gz
chromium_src-6be422be283bff883a198254047ff23dc2f4baa0.tar.bz2
For main thread event handling, if event causes
SetNeedsCommit, SetNeedsUpdateLayer or SetNeedsAnimate during event processing, then it is considered to cause rendering and its LatencyInfo is pushed into LayerTreeHost through LatencyInfoSwapPromise. For impl thread event handling, if event causes SetNeedsRedraw or SetNeedsRedrawRect during event processing, then it is considered to cause rendering and its LatencyInfo is pushed into LayerTreeHostImpl through LatencyInfoSwapPromise. BUG=246034, 271583 TEST=Manually tested on Pixel. The LatencyInfo for events that causes impl/main thread scrolling are correctly passed to LTH/LTHI. Review URL: https://codereview.chromium.org/55273003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@239375 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cc')
-rw-r--r--cc/base/latency_info_swap_promise_monitor.cc43
-rw-r--r--cc/base/latency_info_swap_promise_monitor.h36
-rw-r--r--cc/base/swap_promise_monitor.cc31
-rw-r--r--cc/base/swap_promise_monitor.h44
-rw-r--r--cc/cc.gyp4
-rw-r--r--cc/input/input_handler.h10
-rw-r--r--cc/trees/layer_tree_host.cc21
-rw-r--r--cc/trees/layer_tree_host.h12
-rw-r--r--cc/trees/layer_tree_host_impl.cc34
-rw-r--r--cc/trees/layer_tree_host_impl.h17
-rw-r--r--cc/trees/layer_tree_host_impl_unittest.cc76
-rw-r--r--cc/trees/layer_tree_host_unittest.cc82
12 files changed, 397 insertions, 13 deletions
diff --git a/cc/base/latency_info_swap_promise_monitor.cc b/cc/base/latency_info_swap_promise_monitor.cc
new file mode 100644
index 0000000..0f2ff74
--- /dev/null
+++ b/cc/base/latency_info_swap_promise_monitor.cc
@@ -0,0 +1,43 @@
+// Copyright 2013 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 "cc/base/latency_info_swap_promise_monitor.h"
+
+#include "cc/base/latency_info_swap_promise.h"
+#include "cc/trees/layer_tree_host.h"
+#include "cc/trees/layer_tree_host_impl.h"
+#include "cc/trees/layer_tree_impl.h"
+
+namespace cc {
+
+LatencyInfoSwapPromiseMonitor::LatencyInfoSwapPromiseMonitor(
+ ui::LatencyInfo* latency,
+ LayerTreeHost* layer_tree_host,
+ LayerTreeHostImpl* layer_tree_host_impl)
+ : SwapPromiseMonitor(layer_tree_host, layer_tree_host_impl),
+ latency_(latency) {}
+
+LatencyInfoSwapPromiseMonitor::~LatencyInfoSwapPromiseMonitor() {}
+
+void LatencyInfoSwapPromiseMonitor::OnSetNeedsCommitOnMain() {
+ if (!latency_->FindLatency(
+ ui::INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_COMPONENT, 0, 0)) {
+ latency_->AddLatencyNumber(
+ ui::INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_COMPONENT, 0, 0);
+ scoped_ptr<SwapPromise> swap_promise(new LatencyInfoSwapPromise(*latency_));
+ layer_tree_host_->QueueSwapPromise(swap_promise.Pass());
+ }
+}
+
+void LatencyInfoSwapPromiseMonitor::OnSetNeedsRedrawOnImpl() {
+ if (!latency_->FindLatency(
+ ui::INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_COMPONENT, 0, 0)) {
+ latency_->AddLatencyNumber(
+ ui::INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_COMPONENT, 0, 0);
+ scoped_ptr<SwapPromise> swap_promise(new LatencyInfoSwapPromise(*latency_));
+ layer_tree_host_impl_->active_tree()->QueueSwapPromise(swap_promise.Pass());
+ }
+}
+
+} // namespace cc
diff --git a/cc/base/latency_info_swap_promise_monitor.h b/cc/base/latency_info_swap_promise_monitor.h
new file mode 100644
index 0000000..a463fdb
--- /dev/null
+++ b/cc/base/latency_info_swap_promise_monitor.h
@@ -0,0 +1,36 @@
+// Copyright 2013 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 "base/compiler_specific.h"
+#include "cc/base/swap_promise_monitor.h"
+
+#ifndef CC_BASE_LATENCY_INFO_SWAP_PROMISE_MONITOR_H_
+#define CC_BASE_LATENCY_INFO_SWAP_PROMISE_MONITOR_H_
+
+namespace ui {
+struct LatencyInfo;
+} // namespace ui
+
+namespace cc {
+
+// A LatencyInfoSwapPromiseMonitor queues a LatencyInfoSwapPromise into
+// LayerTreeHost or LayerTreeHostImpl if there is compositor state change
+// while it is being mointored.
+class CC_EXPORT LatencyInfoSwapPromiseMonitor : public SwapPromiseMonitor {
+ public:
+ LatencyInfoSwapPromiseMonitor(ui::LatencyInfo* latency,
+ LayerTreeHost* layer_tree_host,
+ LayerTreeHostImpl* layer_tree_host_impl);
+ virtual ~LatencyInfoSwapPromiseMonitor();
+
+ virtual void OnSetNeedsCommitOnMain() OVERRIDE;
+ virtual void OnSetNeedsRedrawOnImpl() OVERRIDE;
+
+ private:
+ ui::LatencyInfo* latency_;
+};
+
+} // namespace cc
+
+#endif // CC_BASE_LATENCY_INFO_SWAP_PROMISE_MONITOR_H_
diff --git a/cc/base/swap_promise_monitor.cc b/cc/base/swap_promise_monitor.cc
new file mode 100644
index 0000000..0c04f35
--- /dev/null
+++ b/cc/base/swap_promise_monitor.cc
@@ -0,0 +1,31 @@
+// Copyright 2013 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 "base/logging.h"
+#include "cc/base/swap_promise_monitor.h"
+#include "cc/trees/layer_tree_host.h"
+#include "cc/trees/layer_tree_host_impl.h"
+
+namespace cc {
+
+SwapPromiseMonitor::SwapPromiseMonitor(LayerTreeHost* layer_tree_host,
+ LayerTreeHostImpl* layer_tree_host_impl)
+ : layer_tree_host_(layer_tree_host),
+ layer_tree_host_impl_(layer_tree_host_impl) {
+ DCHECK((layer_tree_host && !layer_tree_host_impl) ||
+ (!layer_tree_host && layer_tree_host_impl));
+ if (layer_tree_host_)
+ layer_tree_host_->InsertSwapPromiseMonitor(this);
+ if (layer_tree_host_impl_)
+ layer_tree_host_impl_->InsertSwapPromiseMonitor(this);
+}
+
+SwapPromiseMonitor::~SwapPromiseMonitor() {
+ if (layer_tree_host_)
+ layer_tree_host_->RemoveSwapPromiseMonitor(this);
+ if (layer_tree_host_impl_)
+ layer_tree_host_impl_->RemoveSwapPromiseMonitor(this);
+}
+
+} // namespace cc
diff --git a/cc/base/swap_promise_monitor.h b/cc/base/swap_promise_monitor.h
new file mode 100644
index 0000000..21a159a
--- /dev/null
+++ b/cc/base/swap_promise_monitor.h
@@ -0,0 +1,44 @@
+// Copyright 2013 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 CC_BASE_SWAP_PROMISE_MONITOR_H_
+#define CC_BASE_SWAP_PROMISE_MONITOR_H_
+
+#include "cc/base/cc_export.h"
+
+namespace cc {
+
+class LayerTreeHost;
+class LayerTreeHostImpl;
+
+// A SwapPromiseMonitor is used to monitor compositor state change that
+// should be associated with a SwapPromise, e.g. SetNeedsCommit() is
+// called on main thread or SetNeedsRedraw() is called on impl thread.
+// Creating a SwapPromiseMonitor will insert itself into a LayerTreeHost
+// or LayerTreeHostImpl. You must provide a pointer to the appropriate
+// structure to the monitor (and only one of the two). Notification of
+// compositor state change will be sent through OnSetNeedsCommitOnMain()
+// or OnSetNeedsRedrawOnImpl(). When SwapPromiseMonitor is destroyed, it
+// will unregister itself from LayerTreeHost or LayerTreeHostImpl.
+class CC_EXPORT SwapPromiseMonitor {
+ public:
+ // If the monitor lives on the main thread, pass in layer_tree_host
+ // and set layer_tree_host_impl to NULL.
+ // If the monitor lives on the impl thread, pass in layer_tree_host_impl
+ // and set layer_tree_host to NULL.
+ SwapPromiseMonitor(LayerTreeHost* layer_tree_host,
+ LayerTreeHostImpl* layer_tree_host_impl);
+ virtual ~SwapPromiseMonitor();
+
+ virtual void OnSetNeedsCommitOnMain() = 0;
+ virtual void OnSetNeedsRedrawOnImpl() = 0;
+
+ protected:
+ LayerTreeHost* layer_tree_host_;
+ LayerTreeHostImpl* layer_tree_host_impl_;
+};
+
+} // namespace cc
+
+#endif // CC_BASE_SWAP_PROMISE_MONITOR_H_
diff --git a/cc/cc.gyp b/cc/cc.gyp
index 93fc0d9..6c0e4b5 100644
--- a/cc/cc.gyp
+++ b/cc/cc.gyp
@@ -61,6 +61,8 @@
'base/invalidation_region.h',
'base/latency_info_swap_promise.cc',
'base/latency_info_swap_promise.h',
+ 'base/latency_info_swap_promise_monitor.cc',
+ 'base/latency_info_swap_promise_monitor.h',
'base/math_util.cc',
'base/math_util.h',
'base/ref_counted_managed.h',
@@ -70,6 +72,8 @@
'base/scoped_ptr_deque.h',
'base/scoped_ptr_vector.h',
'base/swap_promise.h',
+ 'base/swap_promise_monitor.cc',
+ 'base/swap_promise_monitor.h',
'base/switches.cc',
'base/switches.h',
'base/tiling_data.cc',
diff --git a/cc/input/input_handler.h b/cc/input/input_handler.h
index 00446b5..fde89d2 100644
--- a/cc/input/input_handler.h
+++ b/cc/input/input_handler.h
@@ -8,6 +8,7 @@
#include "base/basictypes.h"
#include "base/time/time.h"
#include "cc/base/cc_export.h"
+#include "cc/base/swap_promise_monitor.h"
#include "cc/input/scrollbar.h"
namespace gfx {
@@ -126,8 +127,13 @@ class CC_EXPORT InputHandler {
virtual bool HaveTouchEventHandlersAt(gfx::Point viewport_point) = 0;
- virtual void SetLatencyInfoForInputEvent(
- const ui::LatencyInfo& latency_info) = 0;
+ // Calling CreateLatencyInfoSwapPromiseMonitor() to get a scoped
+ // LatencyInfoSwapPromiseMonitor. During the life time of the
+ // LatencyInfoSwapPromiseMonitor, if SetNeedsRedraw() or SetNeedsRedrawRect()
+ // is called on LayerTreeHostImpl, the original latency info will be turned
+ // into a LatencyInfoSwapPromise.
+ virtual scoped_ptr<SwapPromiseMonitor> CreateLatencyInfoSwapPromiseMonitor(
+ ui::LatencyInfo* latency) = 0;
protected:
InputHandler() {}
diff --git a/cc/trees/layer_tree_host.cc b/cc/trees/layer_tree_host.cc
index 081d96b..7432197 100644
--- a/cc/trees/layer_tree_host.cc
+++ b/cc/trees/layer_tree_host.cc
@@ -521,9 +521,13 @@ const RendererCapabilities& LayerTreeHost::GetRendererCapabilities() const {
void LayerTreeHost::SetNeedsAnimate() {
proxy_->SetNeedsAnimate();
+ NotifySwapPromiseMonitorsOfSetNeedsCommit();
}
-void LayerTreeHost::SetNeedsUpdateLayers() { proxy_->SetNeedsUpdateLayers(); }
+void LayerTreeHost::SetNeedsUpdateLayers() {
+ proxy_->SetNeedsUpdateLayers();
+ NotifySwapPromiseMonitorsOfSetNeedsCommit();
+}
void LayerTreeHost::SetNeedsCommit() {
if (!prepaint_callback_.IsCancelled()) {
@@ -533,6 +537,7 @@ void LayerTreeHost::SetNeedsCommit() {
prepaint_callback_.Cancel();
}
proxy_->SetNeedsCommit();
+ NotifySwapPromiseMonitorsOfSetNeedsCommit();
}
void LayerTreeHost::SetNeedsFullTreeSync() {
@@ -1247,6 +1252,20 @@ bool LayerTreeHost::ScheduleMicroBenchmark(
benchmark_name, value.Pass(), callback);
}
+void LayerTreeHost::InsertSwapPromiseMonitor(SwapPromiseMonitor* monitor) {
+ swap_promise_monitor_.insert(monitor);
+}
+
+void LayerTreeHost::RemoveSwapPromiseMonitor(SwapPromiseMonitor* monitor) {
+ swap_promise_monitor_.erase(monitor);
+}
+
+void LayerTreeHost::NotifySwapPromiseMonitorsOfSetNeedsCommit() {
+ std::set<SwapPromiseMonitor*>::iterator it = swap_promise_monitor_.begin();
+ for (; it != swap_promise_monitor_.end(); it++)
+ (*it)->OnSetNeedsCommitOnMain();
+}
+
void LayerTreeHost::QueueSwapPromise(scoped_ptr<SwapPromise> swap_promise) {
DCHECK(swap_promise);
if (swap_promise_list_.size() > kMaxQueuedSwapPromiseNumber)
diff --git a/cc/trees/layer_tree_host.h b/cc/trees/layer_tree_host.h
index b1fb0c6..8b9c1cf 100644
--- a/cc/trees/layer_tree_host.h
+++ b/cc/trees/layer_tree_host.h
@@ -7,6 +7,7 @@
#include <limits>
#include <list>
+#include <set>
#include <string>
#include <vector>
@@ -22,6 +23,7 @@
#include "cc/base/cc_export.h"
#include "cc/base/scoped_ptr_vector.h"
#include "cc/base/swap_promise.h"
+#include "cc/base/swap_promise_monitor.h"
#include "cc/debug/micro_benchmark.h"
#include "cc/debug/micro_benchmark_controller.h"
#include "cc/input/input_handler.h"
@@ -284,6 +286,13 @@ class CC_EXPORT LayerTreeHost {
scoped_ptr<base::Value> value,
const MicroBenchmark::DoneCallback& callback);
+ // When a SwapPromiseMonitor is created on the main thread, it calls
+ // InsertSwapPromiseMonitor() to register itself with LayerTreeHost.
+ // When the monitor is destroyed, it calls RemoveSwapPromiseMonitor()
+ // to unregister itself.
+ void InsertSwapPromiseMonitor(SwapPromiseMonitor* monitor);
+ void RemoveSwapPromiseMonitor(SwapPromiseMonitor* monitor);
+
// Call this function when you expect there to be a swap buffer.
// See swap_promise.h for how to use SwapPromise.
void QueueSwapPromise(scoped_ptr<SwapPromise> swap_promise);
@@ -348,6 +357,8 @@ class CC_EXPORT LayerTreeHost {
void CalculateLCDTextMetricsCallback(Layer* layer);
+ void NotifySwapPromiseMonitorsOfSetNeedsCommit();
+
bool animating_;
bool needs_full_tree_sync_;
bool needs_filter_context_;
@@ -436,6 +447,7 @@ class CC_EXPORT LayerTreeHost {
SharedBitmapManager* shared_bitmap_manager_;
ScopedPtrVector<SwapPromise> swap_promise_list_;
+ std::set<SwapPromiseMonitor*> swap_promise_monitor_;
DISALLOW_COPY_AND_ASSIGN(LayerTreeHost);
};
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc
index 5e9df8f..bb493c8 100644
--- a/cc/trees/layer_tree_host_impl.cc
+++ b/cc/trees/layer_tree_host_impl.cc
@@ -15,7 +15,7 @@
#include "base/strings/stringprintf.h"
#include "cc/animation/scrollbar_animation_controller.h"
#include "cc/animation/timing_function.h"
-#include "cc/base/latency_info_swap_promise.h"
+#include "cc/base/latency_info_swap_promise_monitor.h"
#include "cc/base/math_util.h"
#include "cc/base/util.h"
#include "cc/debug/benchmark_instrumentation.h"
@@ -477,11 +477,11 @@ bool LayerTreeHostImpl::HaveTouchEventHandlersAt(gfx::Point viewport_point) {
return layer_impl != NULL;
}
-void LayerTreeHostImpl::SetLatencyInfoForInputEvent(
- const ui::LatencyInfo& latency_info) {
- scoped_ptr<SwapPromise> swap_promise(
- new LatencyInfoSwapPromise(latency_info));
- active_tree()->QueueSwapPromise(swap_promise.Pass());
+scoped_ptr<SwapPromiseMonitor>
+LayerTreeHostImpl::CreateLatencyInfoSwapPromiseMonitor(
+ ui::LatencyInfo* latency) {
+ return scoped_ptr<SwapPromiseMonitor>(
+ new LatencyInfoSwapPromiseMonitor(latency, NULL, this));
}
void LayerTreeHostImpl::TrackDamageForAllSurfaces(
@@ -1255,6 +1255,9 @@ void LayerTreeHostImpl::SetExternalDrawConstraints(
}
void LayerTreeHostImpl::SetNeedsRedrawRect(gfx::Rect damage_rect) {
+ if (damage_rect.IsEmpty())
+ return;
+ NotifySwapPromiseMonitorsOfSetNeedsRedraw();
client_->SetNeedsRedrawRectOnImplThread(damage_rect);
}
@@ -1629,6 +1632,11 @@ void LayerTreeHostImpl::SetVisible(bool visible) {
renderer_->SetVisible(visible);
}
+void LayerTreeHostImpl::SetNeedsRedraw() {
+ NotifySwapPromiseMonitorsOfSetNeedsRedraw();
+ client_->SetNeedsRedrawOnImplThread();
+}
+
ManagedMemoryPolicy LayerTreeHostImpl::ActualManagedMemoryPolicy() const {
ManagedMemoryPolicy actual = cached_managed_memory_policy_;
if (debug_state_.rasterize_only_visible_content) {
@@ -2900,4 +2908,18 @@ void LayerTreeHostImpl::ScheduleMicroBenchmark(
micro_benchmark_controller_.ScheduleRun(benchmark.Pass());
}
+void LayerTreeHostImpl::InsertSwapPromiseMonitor(SwapPromiseMonitor* monitor) {
+ swap_promise_monitor_.insert(monitor);
+}
+
+void LayerTreeHostImpl::RemoveSwapPromiseMonitor(SwapPromiseMonitor* monitor) {
+ swap_promise_monitor_.erase(monitor);
+}
+
+void LayerTreeHostImpl::NotifySwapPromiseMonitorsOfSetNeedsRedraw() {
+ std::set<SwapPromiseMonitor*>::iterator it = swap_promise_monitor_.begin();
+ for (; it != swap_promise_monitor_.end(); it++)
+ (*it)->OnSetNeedsRedrawOnImpl();
+}
+
} // namespace cc
diff --git a/cc/trees/layer_tree_host_impl.h b/cc/trees/layer_tree_host_impl.h
index 83ab7ce..5c0aba9 100644
--- a/cc/trees/layer_tree_host_impl.h
+++ b/cc/trees/layer_tree_host_impl.h
@@ -134,8 +134,8 @@ class CC_EXPORT LayerTreeHostImpl
base::TimeDelta duration) OVERRIDE;
virtual void ScheduleAnimation() OVERRIDE;
virtual bool HaveTouchEventHandlersAt(gfx::Point viewport_port) OVERRIDE;
- virtual void SetLatencyInfoForInputEvent(const ui::LatencyInfo& latency_info)
- OVERRIDE;
+ virtual scoped_ptr<SwapPromiseMonitor> CreateLatencyInfoSwapPromiseMonitor(
+ ui::LatencyInfo* latency) OVERRIDE;
// TopControlsManagerClient implementation.
virtual void DidChangeTopControlsPosition() OVERRIDE;
@@ -294,7 +294,7 @@ class CC_EXPORT LayerTreeHostImpl
bool visible() const { return visible_; }
void SetNeedsCommit() { client_->SetNeedsCommitOnImplThread(); }
- void SetNeedsRedraw() { client_->SetNeedsRedrawOnImplThread(); }
+ void SetNeedsRedraw();
ManagedMemoryPolicy ActualManagedMemoryPolicy() const;
@@ -419,6 +419,13 @@ class CC_EXPORT LayerTreeHostImpl
CompositorFrameMetadata MakeCompositorFrameMetadata() const;
+ // When a SwapPromiseMonitor is created on the impl thread, it calls
+ // InsertSwapPromiseMonitor() to register itself with LayerTreeHostImpl.
+ // When the monitor is destroyed, it calls RemoveSwapPromiseMonitor()
+ // to unregister itself.
+ void InsertSwapPromiseMonitor(SwapPromiseMonitor* monitor);
+ void RemoveSwapPromiseMonitor(SwapPromiseMonitor* monitor);
+
protected:
LayerTreeHostImpl(
const LayerTreeSettings& settings,
@@ -506,6 +513,8 @@ class CC_EXPORT LayerTreeHostImpl
void MarkUIResourceNotEvicted(UIResourceId uid);
+ void NotifySwapPromiseMonitorsOfSetNeedsRedraw();
+
typedef base::hash_map<UIResourceId, UIResourceData>
UIResourceMap;
UIResourceMap ui_resource_map_;
@@ -642,6 +651,8 @@ class CC_EXPORT LayerTreeHostImpl
SharedBitmapManager* shared_bitmap_manager_;
int id_;
+ std::set<SwapPromiseMonitor*> swap_promise_monitor_;
+
DISALLOW_COPY_AND_ASSIGN(LayerTreeHostImpl);
};
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc
index c3d0b19..276b114 100644
--- a/cc/trees/layer_tree_host_impl_unittest.cc
+++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -11,6 +11,7 @@
#include "base/containers/hash_tables.h"
#include "base/containers/scoped_ptr_hash_map.h"
#include "cc/animation/scrollbar_animation_controller_thinning.h"
+#include "cc/base/latency_info_swap_promise.h"
#include "cc/base/math_util.h"
#include "cc/input/top_controls_manager.h"
#include "cc/layers/delegated_renderer_layer_impl.h"
@@ -5360,7 +5361,10 @@ TEST_F(LayerTreeHostImplTest, LatencyInfoPassedToCompositorFrameMetadata) {
ui::LatencyInfo latency_info;
latency_info.AddLatencyNumber(
ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, 0, 0);
- host_impl_->SetLatencyInfoForInputEvent(latency_info);
+ scoped_ptr<SwapPromise> swap_promise(
+ new LatencyInfoSwapPromise(latency_info));
+ host_impl_->active_tree()->QueueSwapPromise(swap_promise.Pass());
+ host_impl_->SetNeedsRedraw();
gfx::Rect full_frame_damage(host_impl_->DrawViewportSize());
LayerTreeHostImpl::FrameData frame;
@@ -5375,5 +5379,75 @@ TEST_F(LayerTreeHostImplTest, LatencyInfoPassedToCompositorFrameMetadata) {
ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, 0, NULL));
}
+class SimpleSwapPromiseMonitor : public SwapPromiseMonitor {
+ public:
+ SimpleSwapPromiseMonitor(LayerTreeHost* layer_tree_host,
+ LayerTreeHostImpl* layer_tree_host_impl,
+ int* set_needs_commit_count,
+ int* set_needs_redraw_count)
+ : SwapPromiseMonitor(layer_tree_host, layer_tree_host_impl),
+ set_needs_commit_count_(set_needs_commit_count),
+ set_needs_redraw_count_(set_needs_redraw_count) {}
+
+ virtual ~SimpleSwapPromiseMonitor() {}
+
+ virtual void OnSetNeedsCommitOnMain() OVERRIDE {
+ (*set_needs_commit_count_)++;
+ }
+
+ virtual void OnSetNeedsRedrawOnImpl() OVERRIDE {
+ (*set_needs_redraw_count_)++;
+ }
+
+ private:
+ int* set_needs_commit_count_;
+ int* set_needs_redraw_count_;
+};
+
+TEST_F(LayerTreeHostImplTest, SimpleSwapPromiseMonitor) {
+ int set_needs_commit_count = 0;
+ int set_needs_redraw_count = 0;
+
+ {
+ scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor(
+ new SimpleSwapPromiseMonitor(NULL,
+ host_impl_.get(),
+ &set_needs_commit_count,
+ &set_needs_redraw_count));
+ host_impl_->SetNeedsRedraw();
+ EXPECT_EQ(0, set_needs_commit_count);
+ EXPECT_EQ(1, set_needs_redraw_count);
+ }
+
+ // Now the monitor is destroyed, SetNeedsRedraw() is no longer being
+ // monitored.
+ host_impl_->SetNeedsRedraw();
+ EXPECT_EQ(0, set_needs_commit_count);
+ EXPECT_EQ(1, set_needs_redraw_count);
+
+ {
+ scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor(
+ new SimpleSwapPromiseMonitor(NULL,
+ host_impl_.get(),
+ &set_needs_commit_count,
+ &set_needs_redraw_count));
+ host_impl_->SetNeedsRedrawRect(gfx::Rect(10, 10));
+ EXPECT_EQ(0, set_needs_commit_count);
+ EXPECT_EQ(2, set_needs_redraw_count);
+ }
+
+ {
+ scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor(
+ new SimpleSwapPromiseMonitor(NULL,
+ host_impl_.get(),
+ &set_needs_commit_count,
+ &set_needs_redraw_count));
+ // Empty damage rect won't signal the monitor.
+ host_impl_->SetNeedsRedrawRect(gfx::Rect());
+ EXPECT_EQ(0, set_needs_commit_count);
+ EXPECT_EQ(2, set_needs_redraw_count);
+ }
+}
+
} // namespace
} // namespace cc
diff --git a/cc/trees/layer_tree_host_unittest.cc b/cc/trees/layer_tree_host_unittest.cc
index 9b301e2..f6db62a 100644
--- a/cc/trees/layer_tree_host_unittest.cc
+++ b/cc/trees/layer_tree_host_unittest.cc
@@ -4682,4 +4682,86 @@ class LayerTreeHostTestBreakSwapPromise
MULTI_THREAD_TEST_F(LayerTreeHostTestBreakSwapPromise);
+
+class SimpleSwapPromiseMonitor : public SwapPromiseMonitor {
+ public:
+ SimpleSwapPromiseMonitor(LayerTreeHost* layer_tree_host,
+ LayerTreeHostImpl* layer_tree_host_impl,
+ int* set_needs_commit_count,
+ int* set_needs_redraw_count)
+ : SwapPromiseMonitor(layer_tree_host, layer_tree_host_impl),
+ set_needs_commit_count_(set_needs_commit_count),
+ set_needs_redraw_count_(set_needs_redraw_count) {}
+
+ virtual ~SimpleSwapPromiseMonitor() {}
+
+ virtual void OnSetNeedsCommitOnMain() OVERRIDE {
+ (*set_needs_commit_count_)++;
+ }
+
+ virtual void OnSetNeedsRedrawOnImpl() OVERRIDE {
+ (*set_needs_redraw_count_)++;
+ }
+
+ private:
+ int* set_needs_commit_count_;
+ int* set_needs_redraw_count_;
+};
+
+class LayerTreeHostTestSimpleSwapPromiseMonitor
+ : public LayerTreeHostTest {
+
+ virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
+
+ virtual void WillBeginMainFrame() OVERRIDE {
+ int set_needs_commit_count = 0;
+ int set_needs_redraw_count = 0;
+
+ {
+ scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor(
+ new SimpleSwapPromiseMonitor(layer_tree_host(),
+ NULL,
+ &set_needs_commit_count,
+ &set_needs_redraw_count));
+ layer_tree_host()->SetNeedsCommit();
+ EXPECT_EQ(1, set_needs_commit_count);
+ EXPECT_EQ(0, set_needs_redraw_count);
+ }
+
+ // Now the monitor is destroyed, SetNeedsCommit() is no longer being
+ // monitored.
+ layer_tree_host()->SetNeedsCommit();
+ EXPECT_EQ(1, set_needs_commit_count);
+ EXPECT_EQ(0, set_needs_redraw_count);
+
+ {
+ scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor(
+ new SimpleSwapPromiseMonitor(layer_tree_host(),
+ NULL,
+ &set_needs_commit_count,
+ &set_needs_redraw_count));
+ layer_tree_host()->SetNeedsUpdateLayers();
+ EXPECT_EQ(2, set_needs_commit_count);
+ EXPECT_EQ(0, set_needs_redraw_count);
+ }
+
+ {
+ scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor(
+ new SimpleSwapPromiseMonitor(layer_tree_host(),
+ NULL,
+ &set_needs_commit_count,
+ &set_needs_redraw_count));
+ layer_tree_host()->SetNeedsAnimate();
+ EXPECT_EQ(3, set_needs_commit_count);
+ EXPECT_EQ(0, set_needs_redraw_count);
+ }
+
+ EndTest();
+ }
+
+ virtual void AfterTest() OVERRIDE {}
+};
+
+MULTI_THREAD_TEST_F(LayerTreeHostTestSimpleSwapPromiseMonitor);
+
} // namespace cc