diff options
author | Zeno Albisser <zeno.albisser@theqtcompany.com> | 2014-12-05 15:04:29 +0100 |
---|---|---|
committer | Andras Becsi <andras.becsi@theqtcompany.com> | 2014-12-09 10:49:28 +0100 |
commit | af6588f8d723931a298c995fa97259bb7f7deb55 (patch) | |
tree | 060ca707847ba1735f01af2372e0d5e494dc0366 /chromium/cc/trees | |
parent | 2fff84d821cc7b1c785f6404e0f8091333283e74 (diff) | |
download | qtwebengine-chromium-af6588f8d723931a298c995fa97259bb7f7deb55.tar.gz |
BASELINE: Update chromium to 40.0.2214.28 and ninja to 1.5.3.
Change-Id: I759465284fd64d59ad120219cbe257f7402c4181
Reviewed-by: Andras Becsi <andras.becsi@theqtcompany.com>
Diffstat (limited to 'chromium/cc/trees')
59 files changed, 9605 insertions, 5874 deletions
diff --git a/chromium/cc/trees/blocking_task_runner.cc b/chromium/cc/trees/blocking_task_runner.cc index 5c33f40d4fc..1111e9bf4b7 100644 --- a/chromium/cc/trees/blocking_task_runner.cc +++ b/chromium/cc/trees/blocking_task_runner.cc @@ -6,49 +6,16 @@ #include <utility> +#include "base/callback.h" #include "base/logging.h" -#include "base/memory/singleton.h" #include "base/message_loop/message_loop_proxy.h" namespace cc { -struct TaskRunnerPairs { - static TaskRunnerPairs* GetInstance() { - return Singleton<TaskRunnerPairs>::get(); - } - - base::Lock lock; - std::vector<scoped_refptr<BlockingTaskRunner> > runners; - - private: - friend struct DefaultSingletonTraits<TaskRunnerPairs>; -}; - // static -scoped_refptr<BlockingTaskRunner> BlockingTaskRunner::current() { - TaskRunnerPairs* task_runners = TaskRunnerPairs::GetInstance(); - base::PlatformThreadId thread_id = base::PlatformThread::CurrentId(); - - base::AutoLock lock(task_runners->lock); - - scoped_refptr<BlockingTaskRunner> current_task_runner; - - for (size_t i = 0; i < task_runners->runners.size(); ++i) { - if (task_runners->runners[i]->thread_id_ == thread_id) { - current_task_runner = task_runners->runners[i]; - } else if (task_runners->runners[i]->HasOneRef()) { - task_runners->runners.erase(task_runners->runners.begin() + i); - i--; - } - } - - if (current_task_runner) - return current_task_runner; - - scoped_refptr<BlockingTaskRunner> runner = - new BlockingTaskRunner(base::MessageLoopProxy::current()); - task_runners->runners.push_back(runner); - return runner; +scoped_ptr<BlockingTaskRunner> BlockingTaskRunner::Create( + scoped_refptr<base::SingleThreadTaskRunner> task_runner) { + return make_scoped_ptr(new BlockingTaskRunner(task_runner)); } BlockingTaskRunner::BlockingTaskRunner( @@ -94,8 +61,9 @@ void BlockingTaskRunner::SetCapture(bool capture) { tasks[i].Run(); } -BlockingTaskRunner::CapturePostTasks::CapturePostTasks() - : blocking_runner_(BlockingTaskRunner::current()) { +BlockingTaskRunner::CapturePostTasks::CapturePostTasks( + BlockingTaskRunner* blocking_runner) + : blocking_runner_(blocking_runner) { blocking_runner_->SetCapture(true); } diff --git a/chromium/cc/trees/blocking_task_runner.h b/chromium/cc/trees/blocking_task_runner.h index 8388a881e60..eb43b91441c 100644 --- a/chromium/cc/trees/blocking_task_runner.h +++ b/chromium/cc/trees/blocking_task_runner.h @@ -8,7 +8,7 @@ #include <vector> #include "base/location.h" -#include "base/memory/ref_counted.h" +#include "base/memory/scoped_ptr.h" #include "base/single_thread_task_runner.h" #include "base/synchronization/lock.h" #include "base/threading/platform_thread.h" @@ -25,38 +25,43 @@ namespace cc { // to when they were posted. // // To use this class, post tasks to the task runner returned by -// BlockingTaskRunner::current() on the thread you want the tasks to run. -// Hold a reference to the BlockingTaskRunner as long as you intend to -// post tasks to it. +// BlockingTaskRunner::Create(). The thread it is created on identifies the +// thread you want the tasks to run on. The SingleThreadTaskRunner which is +// passed into Create() is used to run tasks that are posted when not in a +// capturing state. // -// Then, on the thread from which the BlockingTaskRunner was created, you -// may instantiate a BlockingTaskRunner::CapturePostTasks. While this object +// Then, on the thread that the given task runner belongs to, you may +// instantiate a BlockingTaskRunner::CapturePostTasks. While this object // exists, the task runner will collect any PostTasks called on it, posting // tasks to that thread from anywhere. This CapturePostTasks object provides // a window in time where tasks can shortcut past the MessageLoop. As soon // as the CapturePostTasks object is destroyed (goes out of scope), all -// tasks that had been posted to the thread during the window will be exectuted +// tasks that had been posted to the thread during the window will be executed // immediately. // // Beware of re-entrancy, make sure the CapturePostTasks object is destroyed at // a time when it makes sense for the embedder to call arbitrary things. -class CC_EXPORT BlockingTaskRunner - : public base::RefCountedThreadSafe<BlockingTaskRunner> { +class CC_EXPORT BlockingTaskRunner { public: - // Returns the BlockingTaskRunner for the current thread, creating one if - // necessary. - static scoped_refptr<BlockingTaskRunner> current(); + // Creates a BlockingTaskRunner for a given SingleThreadTaskRunner. + // |task_runner| will be used to run the tasks which are posted while we are + // not capturing. |task_runner| should belong to same the thread on which + // capturing is done. + static scoped_ptr<BlockingTaskRunner> Create( + scoped_refptr<base::SingleThreadTaskRunner> task_runner); + + ~BlockingTaskRunner(); // While an object of this type is held alive on a thread, any tasks // posted to the thread will be captured and run as soon as the object - // is destroyed, shortcutting past the MessageLoop. + // is destroyed, shortcutting past the task runner. class CC_EXPORT CapturePostTasks { public: - CapturePostTasks(); + explicit CapturePostTasks(BlockingTaskRunner* blocking_runner); ~CapturePostTasks(); private: - scoped_refptr<BlockingTaskRunner> blocking_runner_; + BlockingTaskRunner* blocking_runner_; DISALLOW_COPY_AND_ASSIGN(CapturePostTasks); }; @@ -73,11 +78,8 @@ class CC_EXPORT BlockingTaskRunner const base::Closure& task); private: - friend class base::RefCountedThreadSafe<BlockingTaskRunner>; - explicit BlockingTaskRunner( scoped_refptr<base::SingleThreadTaskRunner> task_runner); - virtual ~BlockingTaskRunner(); void SetCapture(bool capture); @@ -87,6 +89,8 @@ class CC_EXPORT BlockingTaskRunner base::Lock lock_; int capture_; std::vector<base::Closure> captured_tasks_; + + DISALLOW_COPY_AND_ASSIGN(BlockingTaskRunner); }; } // namespace cc diff --git a/chromium/cc/trees/blocking_task_runner_unittest.cc b/chromium/cc/trees/blocking_task_runner_unittest.cc new file mode 100644 index 00000000000..ba4f96a80d4 --- /dev/null +++ b/chromium/cc/trees/blocking_task_runner_unittest.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 "cc/trees/blocking_task_runner.h" + +#include "base/bind.h" +#include "base/run_loop.h" +#include "cc/test/ordered_simple_task_runner.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace cc { +namespace { + +void TestTask(bool* result) { + *result = true; +} + +TEST(BlockingTaskRunnerTest, NoCapture) { + bool did_run = false; + scoped_ptr<BlockingTaskRunner> runner( + BlockingTaskRunner::Create(base::MessageLoopProxy::current())); + runner->PostTask(FROM_HERE, base::Bind(&TestTask, &did_run)); + EXPECT_FALSE(did_run); + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(did_run); +} + +TEST(BlockingTaskRunnerTest, Capture) { + bool did_run = false; + scoped_ptr<BlockingTaskRunner> runner( + BlockingTaskRunner::Create(base::MessageLoopProxy::current())); + { + BlockingTaskRunner::CapturePostTasks capture(runner.get()); + runner->PostTask(FROM_HERE, base::Bind(&TestTask, &did_run)); + EXPECT_FALSE(did_run); + } + EXPECT_TRUE(did_run); +} + +} // namespace +} // namespace cc diff --git a/chromium/cc/trees/damage_tracker.h b/chromium/cc/trees/damage_tracker.h index 37c4c6ec9eb..aafbd033bcd 100644 --- a/chromium/cc/trees/damage_tracker.h +++ b/chromium/cc/trees/damage_tracker.h @@ -9,7 +9,7 @@ #include "base/memory/scoped_ptr.h" #include "cc/base/cc_export.h" #include "cc/layers/layer_lists.h" -#include "ui/gfx/rect.h" +#include "ui/gfx/geometry/rect.h" class SkImageFilter; diff --git a/chromium/cc/trees/damage_tracker_unittest.cc b/chromium/cc/trees/damage_tracker_unittest.cc index 169eea4cd5f..90b5b8a151e 100644 --- a/chromium/cc/trees/damage_tracker_unittest.cc +++ b/chromium/cc/trees/damage_tracker_unittest.cc @@ -30,6 +30,7 @@ void ExecuteCalculateDrawProperties(LayerImpl* root, ASSERT_TRUE(root->render_surface()); ASSERT_FALSE(render_surface_layer_list->size()); + FakeLayerTreeHostImpl::RecursiveUpdateNumChildren(root); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( root, root->bounds(), render_surface_layer_list); LayerTreeHostCommon::CalculateDrawProperties(&inputs); @@ -228,7 +229,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForUpdateRects) { // CASE 1: Setting the update rect should cause the corresponding damage to // the surface. ClearDamageForAllSurfaces(root.get()); - child->SetUpdateRect(gfx::RectF(10.f, 11.f, 12.f, 13.f)); + child->SetUpdateRect(gfx::Rect(10, 11, 12, 13)); EmulateDrawingOneFrame(root.get()); // Damage position on the surface should be: position of update_rect (10, 11) @@ -241,7 +242,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForUpdateRects) { // CASE 2: The same update rect twice in a row still produces the same // damage. ClearDamageForAllSurfaces(root.get()); - child->SetUpdateRect(gfx::RectF(10.f, 11.f, 12.f, 13.f)); + child->SetUpdateRect(gfx::Rect(10, 11, 12, 13)); EmulateDrawingOneFrame(root.get()); root_damage_rect = root->render_surface()->damage_tracker()->current_damage_rect(); @@ -251,7 +252,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForUpdateRects) { // CASE 3: Setting a different update rect should cause damage on the new // update region, but no additional exposed old region. ClearDamageForAllSurfaces(root.get()); - child->SetUpdateRect(gfx::RectF(20.f, 25.f, 1.f, 2.f)); + child->SetUpdateRect(gfx::Rect(20, 25, 1, 2)); EmulateDrawingOneFrame(root.get()); // Damage position on the surface should be: position of update_rect (20, 25) @@ -321,7 +322,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForLayerUpdateAndDamageRects) { // corresponding damage to the surface. ClearDamageForAllSurfaces(root.get()); child->AddDamageRect(gfx::RectF(5.f, 6.f, 12.f, 13.f)); - child->SetUpdateRect(gfx::RectF(15.f, 16.f, 14.f, 10.f)); + child->SetUpdateRect(gfx::Rect(15, 16, 14, 10)); EmulateDrawingOneFrame(root.get()); // Damage position on the surface should be: position of unified layer @@ -335,7 +336,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForLayerUpdateAndDamageRects) { // produces the same damage. ClearDamageForAllSurfaces(root.get()); child->AddDamageRect(gfx::RectF(10.f, 11.f, 12.f, 13.f)); - child->SetUpdateRect(gfx::RectF(10.f, 11.f, 14.f, 15.f)); + child->SetUpdateRect(gfx::Rect(10, 11, 14, 15)); EmulateDrawingOneFrame(root.get()); root_damage_rect = root->render_surface()->damage_tracker()->current_damage_rect(); @@ -345,7 +346,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForLayerUpdateAndDamageRects) { // damage on the new damaged region, but no additional exposed old region. ClearDamageForAllSurfaces(root.get()); child->AddDamageRect(gfx::RectF(20.f, 25.f, 2.f, 3.f)); - child->SetUpdateRect(gfx::RectF(5.f, 10.f, 7.f, 8.f)); + child->SetUpdateRect(gfx::Rect(5, 10, 7, 8)); EmulateDrawingOneFrame(root.get()); // Damage position on the surface should be: position of unified layer damage @@ -362,7 +363,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForPropertyChanges) { // CASE 1: The layer's property changed flag takes priority over update rect. // ClearDamageForAllSurfaces(root.get()); - child->SetUpdateRect(gfx::RectF(10.f, 11.f, 12.f, 13.f)); + child->SetUpdateRect(gfx::Rect(10, 11, 12, 13)); child->SetOpacity(0.5f); EmulateDrawingOneFrame(root.get()); @@ -510,7 +511,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForBlurredSurface) { // Setting the update rect should cause the corresponding damage to the // surface, blurred based on the size of the blur filter. ClearDamageForAllSurfaces(root.get()); - child->SetUpdateRect(gfx::RectF(1.f, 2.f, 3.f, 4.f)); + child->SetUpdateRect(gfx::Rect(1, 2, 3, 4)); EmulateDrawingOneFrame(root.get()); // Damage position on the surface should be: position of update_rect (1, 2) @@ -553,7 +554,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForImageFilter) { // CASE 1: Setting the update rect should damage the whole surface (for now) ClearDamageForAllSurfaces(root.get()); - child->SetUpdateRect(gfx::RectF(1.f, 1.f)); + child->SetUpdateRect(gfx::Rect(1, 1)); EmulateDrawingOneFrame(root.get()); root_damage_rect = @@ -587,7 +588,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForBackgroundBlurredChild) { // the surface, blurred based on the size of the child's background // blur filter. ClearDamageForAllSurfaces(root.get()); - root->SetUpdateRect(gfx::RectF(297.f, 297.f, 2.f, 2.f)); + root->SetUpdateRect(gfx::Rect(297, 297, 2, 2)); EmulateDrawingOneFrame(root.get()); gfx::Rect root_damage_rect = @@ -608,7 +609,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForBackgroundBlurredChild) { // blur filter. Since the damage extends to the right/bottom outside // of the blurred layer, only the left/top should end up expanded. ClearDamageForAllSurfaces(root.get()); - root->SetUpdateRect(gfx::RectF(297.f, 297.f, 30.f, 30.f)); + root->SetUpdateRect(gfx::Rect(297, 297, 30, 30)); EmulateDrawingOneFrame(root.get()); root_damage_rect = @@ -627,7 +628,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForBackgroundBlurredChild) { // CASE 3: Setting this update rect outside the blurred content_bounds of the // blurred child1 will not cause it to be expanded. ClearDamageForAllSurfaces(root.get()); - root->SetUpdateRect(gfx::RectF(30.f, 30.f, 2.f, 2.f)); + root->SetUpdateRect(gfx::Rect(30, 30, 2, 2)); EmulateDrawingOneFrame(root.get()); root_damage_rect = @@ -642,7 +643,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForBackgroundBlurredChild) { // outside the original content_bounds of the blurred child1 will // cause it to be expanded. ClearDamageForAllSurfaces(root.get()); - root->SetUpdateRect(gfx::RectF(99.f, 99.f, 1.f, 1.f)); + root->SetUpdateRect(gfx::Rect(99, 99, 1, 1)); EmulateDrawingOneFrame(root.get()); root_damage_rect = @@ -661,7 +662,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForBackgroundBlurredChild) { // CASE 5: Setting the update rect on child2, which is above child1, will // not get blurred by child1, so it does not need to get expanded. ClearDamageForAllSurfaces(root.get()); - child2->SetUpdateRect(gfx::RectF(0.f, 0.f, 1.f, 1.f)); + child2->SetUpdateRect(gfx::Rect(1, 1)); EmulateDrawingOneFrame(root.get()); root_damage_rect = @@ -676,7 +677,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForBackgroundBlurredChild) { // that any pixels needed for the blur are redrawn in the current // frame. ClearDamageForAllSurfaces(root.get()); - child1->SetUpdateRect(gfx::RectF(0.f, 0.f, 1.f, 1.f)); + child1->SetUpdateRect(gfx::Rect(1, 1)); EmulateDrawingOneFrame(root.get()); root_damage_rect = @@ -797,8 +798,8 @@ TEST_F(DamageTrackerTest, VerifyDamageForMultipleLayers) { // - child1 update rect in surface space: gfx::Rect(100, 100, 1, 2); // - child2 update rect in surface space: gfx::Rect(400, 380, 3, 4); ClearDamageForAllSurfaces(root.get()); - child1->SetUpdateRect(gfx::RectF(0.f, 0.f, 1.f, 2.f)); - child2->SetUpdateRect(gfx::RectF(0.f, 0.f, 3.f, 4.f)); + child1->SetUpdateRect(gfx::Rect(1, 2)); + child2->SetUpdateRect(gfx::Rect(3, 4)); EmulateDrawingOneFrame(root.get()); gfx::Rect root_damage_rect = root->render_surface()->damage_tracker()->current_damage_rect(); @@ -1009,7 +1010,7 @@ TEST_F(DamageTrackerTest, VerifyNoDamageForUpdateRectThatDoesNotDrawContent) { // In our specific tree, the update rect of child1 should not cause any // damage to any surface because it does not actually draw content. ClearDamageForAllSurfaces(root.get()); - child1->SetUpdateRect(gfx::RectF(0.f, 0.f, 1.f, 2.f)); + child1->SetUpdateRect(gfx::Rect(1, 2)); EmulateDrawingOneFrame(root.get()); child_damage_rect = child1->render_surface()->damage_tracker()->current_damage_rect(); @@ -1104,7 +1105,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForReplica) { // CASE 3: removing the reflection should cause the entire region including // reflection to damage the target surface. ClearDamageForAllSurfaces(root.get()); - grand_child1->SetReplicaLayer(scoped_ptr<LayerImpl>()); + grand_child1->SetReplicaLayer(nullptr); EmulateDrawingOneFrame(root.get()); ASSERT_EQ(old_content_rect.width(), child1->render_surface()->content_rect().width()); @@ -1162,7 +1163,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForMask) { // CASE 1: the update_rect on a mask layer should damage the entire target // surface. ClearDamageForAllSurfaces(root.get()); - mask_layer->SetUpdateRect(gfx::RectF(1.f, 2.f, 3.f, 4.f)); + mask_layer->SetUpdateRect(gfx::Rect(1, 2, 3, 4)); EmulateDrawingOneFrame(root.get()); gfx::Rect child_damage_rect = child->render_surface()->damage_tracker()->current_damage_rect(); @@ -1201,7 +1202,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForMask) { // Then test mask removal. ClearDamageForAllSurfaces(root.get()); - child->SetMaskLayer(scoped_ptr<LayerImpl>()); + child->SetMaskLayer(nullptr); ASSERT_TRUE(child->LayerPropertyChanged()); EmulateDrawingOneFrame(root.get()); @@ -1269,7 +1270,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForReplicaMask) { // target surface. // ClearDamageForAllSurfaces(root.get()); - grand_child1_replica->SetMaskLayer(scoped_ptr<LayerImpl>()); + grand_child1_replica->SetMaskLayer(nullptr); EmulateDrawingOneFrame(root.get()); grand_child_damage_rect = @@ -1349,7 +1350,7 @@ TEST_F(DamageTrackerTest, DamageWhenAddedExternally) { // it is included with any other partial damage. // ClearDamageForAllSurfaces(root.get()); - child->SetUpdateRect(gfx::RectF(10, 11, 12, 13)); + child->SetUpdateRect(gfx::Rect(10, 11, 12, 13)); root->render_surface()->damage_tracker()->AddDamageNextUpdate( gfx::Rect(15, 16, 32, 33)); EmulateDrawingOneFrame(root.get()); @@ -1412,7 +1413,7 @@ TEST_F(DamageTrackerTest, VerifyDamageAccumulatesUntilReset) { // New damage, without having cleared the previous damage, should be unioned // to the previous one. - child->SetUpdateRect(gfx::RectF(20.f, 25.f, 1.f, 2.f)); + child->SetUpdateRect(gfx::Rect(20, 25, 1, 2)); EmulateDrawingOneFrame(root.get()); root_damage_rect = root->render_surface()->damage_tracker()->current_damage_rect(); diff --git a/chromium/cc/trees/layer_sorter.h b/chromium/cc/trees/layer_sorter.h index c5aab7ca780..b783ded0c51 100644 --- a/chromium/cc/trees/layer_sorter.h +++ b/chromium/cc/trees/layer_sorter.h @@ -11,23 +11,10 @@ #include "base/containers/hash_tables.h" #include "cc/base/cc_export.h" #include "cc/layers/layer_impl.h" -#include "ui/gfx/point3_f.h" -#include "ui/gfx/quad_f.h" -#include "ui/gfx/rect_f.h" -#include "ui/gfx/vector3d_f.h" - -#if defined(COMPILER_GCC) -namespace cc { struct GraphEdge; } - -namespace BASE_HASH_NAMESPACE { -template <> -struct hash<cc::GraphEdge*> { - size_t operator()(cc::GraphEdge* ptr) const { - return hash<size_t>()(reinterpret_cast<size_t>(ptr)); - } -}; -} // namespace BASE_HASH_NAMESPACE -#endif // COMPILER +#include "ui/gfx/geometry/point3_f.h" +#include "ui/gfx/geometry/quad_f.h" +#include "ui/gfx/geometry/rect_f.h" +#include "ui/gfx/geometry/vector3d_f.h" namespace gfx { class Transform; diff --git a/chromium/cc/trees/layer_tree_host.cc b/chromium/cc/trees/layer_tree_host.cc index 51b9b4f2e33..af7eb5bc96e 100644 --- a/chromium/cc/trees/layer_tree_host.cc +++ b/chromium/cc/trees/layer_tree_host.cc @@ -12,6 +12,7 @@ #include "base/bind.h" #include "base/command_line.h" #include "base/debug/trace_event.h" +#include "base/debug/trace_event_argument.h" #include "base/message_loop/message_loop.h" #include "base/metrics/histogram.h" #include "base/stl_util.h" @@ -21,6 +22,7 @@ #include "cc/base/math_util.h" #include "cc/debug/devtools_instrumentation.h" #include "cc/debug/rendering_stats_instrumentation.h" +#include "cc/input/layer_selection_bound.h" #include "cc/input/top_controls_manager.h" #include "cc/layers/heads_up_display_layer.h" #include "cc/layers/heads_up_display_layer_impl.h" @@ -38,7 +40,7 @@ #include "cc/trees/single_thread_proxy.h" #include "cc/trees/thread_proxy.h" #include "cc/trees/tree_synchronizer.h" -#include "ui/gfx/size_conversions.h" +#include "ui/gfx/geometry/size_conversions.h" namespace { static base::StaticAtomicSequenceNumber s_layer_tree_host_sequence_number; @@ -65,33 +67,41 @@ RendererCapabilities::~RendererCapabilities() {} scoped_ptr<LayerTreeHost> LayerTreeHost::CreateThreaded( LayerTreeHostClient* client, - SharedBitmapManager* manager, + SharedBitmapManager* shared_bitmap_manager, + gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, const LayerTreeSettings& settings, + scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner) { - DCHECK(impl_task_runner); - scoped_ptr<LayerTreeHost> layer_tree_host( - new LayerTreeHost(client, manager, settings)); - layer_tree_host->InitializeThreaded(impl_task_runner); + DCHECK(main_task_runner.get()); + DCHECK(impl_task_runner.get()); + scoped_ptr<LayerTreeHost> layer_tree_host(new LayerTreeHost( + client, shared_bitmap_manager, gpu_memory_buffer_manager, settings)); + layer_tree_host->InitializeThreaded(main_task_runner, impl_task_runner); return layer_tree_host.Pass(); } scoped_ptr<LayerTreeHost> LayerTreeHost::CreateSingleThreaded( LayerTreeHostClient* client, LayerTreeHostSingleThreadClient* single_thread_client, - SharedBitmapManager* manager, - const LayerTreeSettings& settings) { - scoped_ptr<LayerTreeHost> layer_tree_host( - new LayerTreeHost(client, manager, settings)); - layer_tree_host->InitializeSingleThreaded(single_thread_client); + SharedBitmapManager* shared_bitmap_manager, + gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, + const LayerTreeSettings& settings, + scoped_refptr<base::SingleThreadTaskRunner> main_task_runner) { + scoped_ptr<LayerTreeHost> layer_tree_host(new LayerTreeHost( + client, shared_bitmap_manager, gpu_memory_buffer_manager, settings)); + layer_tree_host->InitializeSingleThreaded(single_thread_client, + main_task_runner); return layer_tree_host.Pass(); } -LayerTreeHost::LayerTreeHost(LayerTreeHostClient* client, - SharedBitmapManager* manager, - const LayerTreeSettings& settings) +LayerTreeHost::LayerTreeHost( + LayerTreeHostClient* client, + SharedBitmapManager* shared_bitmap_manager, + gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, + const LayerTreeSettings& settings) : micro_benchmark_controller_(this), next_ui_resource_id_(1), - animating_(false), + inside_begin_main_frame_(false), needs_full_tree_sync_(true), client_(client), source_frame_number_(0), @@ -100,7 +110,8 @@ LayerTreeHost::LayerTreeHost(LayerTreeHostClient* client, num_failed_recreate_attempts_(0), settings_(settings), debug_state_(settings.initial_debug_state), - overdraw_bottom_height_(0.f), + top_controls_layout_height_(0.f), + top_controls_content_offset_(0.f), device_scale_factor_(1.f), visible_(true), page_scale_factor_(1.f), @@ -116,7 +127,10 @@ LayerTreeHost::LayerTreeHost(LayerTreeHostClient* client, total_frames_used_for_lcd_text_metrics_(0), id_(s_layer_tree_host_sequence_number.GetNext() + 1), next_commit_forces_redraw_(false), - shared_bitmap_manager_(manager) { + shared_bitmap_manager_(shared_bitmap_manager), + gpu_memory_buffer_manager_(gpu_memory_buffer_manager), + surface_id_namespace_(0u), + next_surface_sequence_(1u) { if (settings_.accelerated_animation_enabled) animation_registrar_ = AnimationRegistrar::Create(); rendering_stats_instrumentation_->set_record_rendering_stats( @@ -124,13 +138,17 @@ LayerTreeHost::LayerTreeHost(LayerTreeHostClient* client, } void LayerTreeHost::InitializeThreaded( + scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner) { - InitializeProxy(ThreadProxy::Create(this, impl_task_runner)); + InitializeProxy( + ThreadProxy::Create(this, main_task_runner, impl_task_runner)); } void LayerTreeHost::InitializeSingleThreaded( - LayerTreeHostSingleThreadClient* single_thread_client) { - InitializeProxy(SingleThreadProxy::Create(this, single_thread_client)); + LayerTreeHostSingleThreadClient* single_thread_client, + scoped_refptr<base::SingleThreadTaskRunner> main_task_runner) { + InitializeProxy( + SingleThreadProxy::Create(this, single_thread_client, main_task_runner)); } void LayerTreeHost::InitializeForTesting(scoped_ptr<Proxy> proxy_for_testing) { @@ -142,16 +160,24 @@ void LayerTreeHost::InitializeProxy(scoped_ptr<Proxy> proxy) { proxy_ = proxy.Pass(); proxy_->Start(); + if (settings_.accelerated_animation_enabled) { + animation_registrar_->set_supports_scroll_animations( + proxy_->SupportsImplScrolling()); + } } LayerTreeHost::~LayerTreeHost() { TRACE_EVENT0("cc", "LayerTreeHost::~LayerTreeHost"); - overhang_ui_resource_.reset(); + overhang_ui_resource_ = nullptr; if (root_layer_.get()) root_layer_->SetLayerTreeHost(NULL); + DCHECK(swap_promise_monitor_.empty()); + + BreakSwapPromises(SwapPromise::COMMIT_FAILS); + if (proxy_) { DCHECK(proxy_->IsMainThread()); proxy_->Stop(); @@ -221,10 +247,10 @@ void LayerTreeHost::DidBeginMainFrame() { client_->DidBeginMainFrame(); } -void LayerTreeHost::UpdateClientAnimations(base::TimeTicks frame_begin_time) { - animating_ = true; - client_->Animate(frame_begin_time); - animating_ = false; +void LayerTreeHost::BeginMainFrame(const BeginFrameArgs& args) { + inside_begin_main_frame_ = true; + client_->BeginMainFrame(args); + inside_begin_main_frame_ = false; } void LayerTreeHost::DidStopFlinging() { @@ -283,9 +309,11 @@ void LayerTreeHost::FinishCommitOnImplThread(LayerTreeHostImpl* host_impl) { sync_tree->set_source_frame_number(source_frame_number()); - if (needs_full_tree_sync_) + if (needs_full_tree_sync_) { sync_tree->SetRootLayer(TreeSynchronizer::SynchronizeTrees( root_layer(), sync_tree->DetachLayerTree(), sync_tree)); + } + { TRACE_EVENT0("cc", "LayerTreeHost::PushProperties"); TreeSynchronizer::PushProperties(root_layer(), sync_tree->root_layer()); @@ -305,16 +333,18 @@ void LayerTreeHost::FinishCommitOnImplThread(LayerTreeHostImpl* host_impl) { sync_tree->set_background_color(background_color_); sync_tree->set_has_transparent_background(has_transparent_background_); - if (page_scale_layer_ && inner_viewport_scroll_layer_) { - sync_tree->SetViewportLayersFromIds( - page_scale_layer_->id(), - inner_viewport_scroll_layer_->id(), - outer_viewport_scroll_layer_ ? outer_viewport_scroll_layer_->id() - : Layer::INVALID_ID); + if (page_scale_layer_.get() && inner_viewport_scroll_layer_.get()) { + sync_tree->SetViewportLayersFromIds(page_scale_layer_->id(), + inner_viewport_scroll_layer_->id(), + outer_viewport_scroll_layer_.get() + ? outer_viewport_scroll_layer_->id() + : Layer::INVALID_ID); } else { sync_tree->ClearViewportLayers(); } + sync_tree->RegisterSelection(selection_start_, selection_end_); + float page_scale_delta = sync_tree->page_scale_delta() / sync_tree->sent_page_scale_delta(); sync_tree->SetPageScaleValues(page_scale_factor_, @@ -325,20 +355,25 @@ void LayerTreeHost::FinishCommitOnImplThread(LayerTreeHostImpl* host_impl) { sync_tree->PassSwapPromises(&swap_promise_list_); + sync_tree->set_top_controls_layout_height(top_controls_layout_height_); + sync_tree->set_top_controls_content_offset(top_controls_content_offset_); + sync_tree->set_top_controls_delta(sync_tree->top_controls_delta() - + sync_tree->sent_top_controls_delta()); + sync_tree->set_sent_top_controls_delta(0.f); + host_impl->SetUseGpuRasterization(UseGpuRasterization()); RecordGpuRasterizationHistogram(); host_impl->SetViewportSize(device_viewport_size_); - host_impl->SetOverdrawBottomHeight(overdraw_bottom_height_); host_impl->SetDeviceScaleFactor(device_scale_factor_); host_impl->SetDebugState(debug_state_); if (pending_page_scale_animation_) { - host_impl->StartPageScaleAnimation( + sync_tree->SetPageScaleAnimation( pending_page_scale_animation_->target_offset, pending_page_scale_animation_->use_anchor, pending_page_scale_animation_->scale, pending_page_scale_animation_->duration); - pending_page_scale_animation_.reset(); + pending_page_scale_animation_ = nullptr; } if (!ui_resource_request_queue_.empty()) { @@ -358,6 +393,8 @@ void LayerTreeHost::FinishCommitOnImplThread(LayerTreeHostImpl* host_impl) { sync_tree->ResetContentsTexturesPurged(); } + sync_tree->set_has_ever_been_drawn(false); + micro_benchmark_controller_.ScheduleImplBenchmarks(host_impl); } @@ -383,8 +420,12 @@ void LayerTreeHost::CommitComplete() { client_->DidCommit(); } -scoped_ptr<OutputSurface> LayerTreeHost::CreateOutputSurface() { - return client_->CreateOutputSurface(num_failed_recreate_attempts_ >= 4); +void LayerTreeHost::SetOutputSurface(scoped_ptr<OutputSurface> surface) { + proxy_->SetOutputSurface(surface.Pass()); +} + +void LayerTreeHost::RequestNewOutputSurface() { + client_->RequestNewOutputSurface(num_failed_recreate_attempts_ >= 4); } scoped_ptr<LayerTreeHostImpl> LayerTreeHost::CreateLayerTreeHostImpl( @@ -396,9 +437,11 @@ scoped_ptr<LayerTreeHostImpl> LayerTreeHost::CreateLayerTreeHostImpl( proxy_.get(), rendering_stats_instrumentation_.get(), shared_bitmap_manager_, + gpu_memory_buffer_manager_, id_); host_impl->SetUseGpuRasterization(UseGpuRasterization()); shared_bitmap_manager_ = NULL; + gpu_memory_buffer_manager_ = NULL; if (settings_.calculate_top_controls_position && host_impl->top_controls_manager()) { top_controls_manager_weak_ptr_ = @@ -603,11 +646,19 @@ void LayerTreeHost::SetViewportSize(const gfx::Size& device_viewport_size) { SetNeedsCommit(); } -void LayerTreeHost::SetOverdrawBottomHeight(float overdraw_bottom_height) { - if (overdraw_bottom_height_ == overdraw_bottom_height) +void LayerTreeHost::SetTopControlsLayoutHeight(float height) { + if (top_controls_layout_height_ == height) + return; + + top_controls_layout_height_ = height; + SetNeedsCommit(); +} + +void LayerTreeHost::SetTopControlsContentOffset(float offset) { + if (top_controls_content_offset_ == offset) return; - overdraw_bottom_height_ = overdraw_bottom_height; + top_controls_content_offset_ = offset; SetNeedsCommit(); } @@ -675,13 +726,11 @@ void LayerTreeHost::NotifyInputThrottledUntilCommit() { void LayerTreeHost::Composite(base::TimeTicks frame_begin_time) { DCHECK(!proxy_->HasImplThread()); + // This function is only valid when not using the scheduler. + DCHECK(!settings_.single_thread_proxy_scheduler); SingleThreadProxy* proxy = static_cast<SingleThreadProxy*>(proxy_.get()); - if (output_surface_lost_) - proxy->CreateAndInitializeOutputSurface(); - if (output_surface_lost_) - return; - + SetLayerTreeHostClientReady(); proxy->CompositeImmediately(frame_begin_time); } @@ -767,11 +816,11 @@ bool LayerTreeHost::UpdateLayers(Layer* root_layer, UpdateHudLayer(); Layer* root_scroll = FindFirstScrollableLayer(root_layer); - Layer* page_scale_layer = page_scale_layer_; + Layer* page_scale_layer = page_scale_layer_.get(); if (!page_scale_layer && root_scroll) page_scale_layer = root_scroll->parent(); - if (hud_layer_) { + if (hud_layer_.get()) { hud_layer_->PrepareForCalculateDrawProperties( device_viewport_size(), device_scale_factor_); } @@ -1010,57 +1059,77 @@ void LayerTreeHost::PaintLayerContents( in_paint_layer_contents_ = false; } -void LayerTreeHost::ApplyScrollAndScale(const ScrollAndScaleSet& info) { - if (!root_layer_.get()) - return; +void LayerTreeHost::ApplyScrollAndScale(ScrollAndScaleSet* info) { + ScopedPtrVector<SwapPromise>::iterator it = info->swap_promises.begin(); + for (; it != info->swap_promises.end(); ++it) { + scoped_ptr<SwapPromise> swap_promise(info->swap_promises.take(it)); + TRACE_EVENT_FLOW_STEP0("input", + "LatencyInfo.Flow", + TRACE_ID_DONT_MANGLE(swap_promise->TraceId()), + "Main thread scroll update"); + QueueSwapPromise(swap_promise.Pass()); + } gfx::Vector2d inner_viewport_scroll_delta; gfx::Vector2d outer_viewport_scroll_delta; - for (size_t i = 0; i < info.scrolls.size(); ++i) { - Layer* layer = - LayerTreeHostCommon::FindLayerInSubtree(root_layer_.get(), - info.scrolls[i].layer_id); - if (!layer) - continue; - if (layer == outer_viewport_scroll_layer_.get()) { - outer_viewport_scroll_delta += info.scrolls[i].scroll_delta; - } else if (layer == inner_viewport_scroll_layer_.get()) { - inner_viewport_scroll_delta += info.scrolls[i].scroll_delta; - } else { - layer->SetScrollOffsetFromImplSide(layer->scroll_offset() + - info.scrolls[i].scroll_delta); + if (root_layer_.get()) { + for (size_t i = 0; i < info->scrolls.size(); ++i) { + Layer* layer = LayerTreeHostCommon::FindLayerInSubtree( + root_layer_.get(), info->scrolls[i].layer_id); + if (!layer) + continue; + if (layer == outer_viewport_scroll_layer_.get()) { + outer_viewport_scroll_delta += info->scrolls[i].scroll_delta; + } else if (layer == inner_viewport_scroll_layer_.get()) { + inner_viewport_scroll_delta += info->scrolls[i].scroll_delta; + } else { + layer->SetScrollOffsetFromImplSide( + gfx::ScrollOffsetWithDelta(layer->scroll_offset(), + info->scrolls[i].scroll_delta)); + } } } if (!inner_viewport_scroll_delta.IsZero() || - !outer_viewport_scroll_delta.IsZero() || info.page_scale_delta != 1.f) { - // SetScrollOffsetFromImplSide above could have destroyed the tree, - // so re-get this layer before doing anything to it. - + !outer_viewport_scroll_delta.IsZero() || + info->page_scale_delta != 1.f || + info->top_controls_delta) { // Preemptively apply the scroll offset and scale delta here before sending // it to the client. If the client comes back and sets it to the same // value, then the layer can early out without needing a full commit. - DCHECK(inner_viewport_scroll_layer_); // We should always have this. + if (inner_viewport_scroll_layer_.get()) { + inner_viewport_scroll_layer_->SetScrollOffsetFromImplSide( + gfx::ScrollOffsetWithDelta( + inner_viewport_scroll_layer_->scroll_offset(), + inner_viewport_scroll_delta)); + } - inner_viewport_scroll_layer_->SetScrollOffsetFromImplSide( - inner_viewport_scroll_layer_->scroll_offset() + - inner_viewport_scroll_delta); - if (outer_viewport_scroll_layer_) { + if (outer_viewport_scroll_layer_.get()) { outer_viewport_scroll_layer_->SetScrollOffsetFromImplSide( - outer_viewport_scroll_layer_->scroll_offset() + - outer_viewport_scroll_delta); + gfx::ScrollOffsetWithDelta( + outer_viewport_scroll_layer_->scroll_offset(), + outer_viewport_scroll_delta)); } - ApplyPageScaleDeltaFromImplSide(info.page_scale_delta); - client_->ApplyScrollAndScale( - inner_viewport_scroll_delta + outer_viewport_scroll_delta, - info.page_scale_delta); + ApplyPageScaleDeltaFromImplSide(info->page_scale_delta); + if (!settings_.use_pinch_virtual_viewport) { + client_->ApplyViewportDeltas( + inner_viewport_scroll_delta + outer_viewport_scroll_delta, + info->page_scale_delta, + info->top_controls_delta); + } else { + client_->ApplyViewportDeltas( + inner_viewport_scroll_delta, + outer_viewport_scroll_delta, + info->page_scale_delta, + info->top_controls_delta); + } } } void LayerTreeHost::StartRateLimiter() { - if (animating_) + if (inside_begin_main_frame_) return; if (!rate_limit_timer_.IsRunning()) { @@ -1132,10 +1201,10 @@ void LayerTreeHost::UpdateTopControlsState(TopControlsState constraints, animate)); } -scoped_ptr<base::Value> LayerTreeHost::AsValue() const { - scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); - state->Set("proxy", proxy_->AsValue().release()); - return state.PassAs<base::Value>(); +void LayerTreeHost::AsValueInto(base::debug::TracedValue* state) const { + state->BeginDictionary("proxy"); + proxy_->AsValueInto(state); + state->EndDictionary(); } void LayerTreeHost::AnimateLayers(base::TimeTicks monotonic_time) { @@ -1221,6 +1290,16 @@ void LayerTreeHost::RegisterViewportLayers( outer_viewport_scroll_layer_ = outer_viewport_scroll_layer; } +void LayerTreeHost::RegisterSelection(const LayerSelectionBound& start, + const LayerSelectionBound& end) { + if (selection_start_ == start && selection_end_ == end) + return; + + selection_start_ = start; + selection_end_ = end; + SetNeedsCommit(); +} + int LayerTreeHost::ScheduleMicroBenchmark( const std::string& benchmark_name, scoped_ptr<base::Value> value, @@ -1250,8 +1329,6 @@ void LayerTreeHost::NotifySwapPromiseMonitorsOfSetNeedsCommit() { void LayerTreeHost::QueueSwapPromise(scoped_ptr<SwapPromise> swap_promise) { DCHECK(swap_promise); - if (swap_promise_list_.size() > kMaxQueuedSwapPromiseNumber) - BreakSwapPromises(SwapPromise::SWAP_PROMISE_LIST_OVERFLOW); swap_promise_list_.push_back(swap_promise.Pass()); } @@ -1261,4 +1338,12 @@ void LayerTreeHost::BreakSwapPromises(SwapPromise::DidNotSwapReason reason) { swap_promise_list_.clear(); } +void LayerTreeHost::set_surface_id_namespace(uint32_t id_namespace) { + surface_id_namespace_ = id_namespace; +} + +SurfaceSequence LayerTreeHost::CreateSurfaceSequence() { + return SurfaceSequence(surface_id_namespace_, next_surface_sequence_++); +} + } // namespace cc diff --git a/chromium/cc/trees/layer_tree_host.h b/chromium/cc/trees/layer_tree_host.h index ef6e74fabe0..a56a6cd43d5 100644 --- a/chromium/cc/trees/layer_tree_host.h +++ b/chromium/cc/trees/layer_tree_host.h @@ -27,21 +27,26 @@ #include "cc/debug/micro_benchmark.h" #include "cc/debug/micro_benchmark_controller.h" #include "cc/input/input_handler.h" +#include "cc/input/layer_selection_bound.h" #include "cc/input/scrollbar.h" #include "cc/input/top_controls_state.h" #include "cc/layers/layer_lists.h" #include "cc/output/output_surface.h" #include "cc/resources/resource_format.h" #include "cc/resources/scoped_ui_resource.h" +#include "cc/surfaces/surface_sequence.h" #include "cc/trees/layer_tree_host_client.h" #include "cc/trees/layer_tree_host_common.h" #include "cc/trees/layer_tree_settings.h" #include "cc/trees/proxy.h" #include "third_party/skia/include/core/SkColor.h" -#include "ui/gfx/rect.h" +#include "ui/gfx/geometry/rect.h" -namespace cc { +namespace gpu { +class GpuMemoryBufferManager; +} +namespace cc { class AnimationRegistrar; class HeadsUpDisplayLayer; class Layer; @@ -83,15 +88,19 @@ class CC_EXPORT LayerTreeHost { // The SharedBitmapManager will be used on the compositor thread. static scoped_ptr<LayerTreeHost> CreateThreaded( LayerTreeHostClient* client, - SharedBitmapManager* manager, + SharedBitmapManager* shared_bitmap_manager, + gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, const LayerTreeSettings& settings, + scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner); static scoped_ptr<LayerTreeHost> CreateSingleThreaded( LayerTreeHostClient* client, LayerTreeHostSingleThreadClient* single_thread_client, - SharedBitmapManager* manager, - const LayerTreeSettings& settings); + SharedBitmapManager* shared_bitmap_manager, + gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, + const LayerTreeSettings& settings, + scoped_refptr<base::SingleThreadTaskRunner> main_task_runner); virtual ~LayerTreeHost(); void SetLayerTreeHostClientReady(); @@ -101,7 +110,7 @@ class CC_EXPORT LayerTreeHost { client_->WillBeginMainFrame(source_frame_number_); } void DidBeginMainFrame(); - void UpdateClientAnimations(base::TimeTicks monotonic_frame_begin_time); + void BeginMainFrame(const BeginFrameArgs& args); void AnimateLayers(base::TimeTicks monotonic_frame_begin_time); void DidStopFlinging(); void Layout(); @@ -109,7 +118,8 @@ class CC_EXPORT LayerTreeHost { void FinishCommitOnImplThread(LayerTreeHostImpl* host_impl); void WillCommit(); void CommitComplete(); - scoped_ptr<OutputSurface> CreateOutputSurface(); + void SetOutputSurface(scoped_ptr<OutputSurface> output_surface); + void RequestNewOutputSurface(); virtual scoped_ptr<LayerTreeHostImpl> CreateLayerTreeHostImpl( LayerTreeHostImplClient* client); void DidLoseOutputSurface(); @@ -178,6 +188,9 @@ class CC_EXPORT LayerTreeHost { return outer_viewport_scroll_layer_.get(); } + void RegisterSelection(const LayerSelectionBound& start, + const LayerSelectionBound& end); + const LayerTreeSettings& settings() const { return settings_; } void SetDebugState(const LayerTreeDebugState& debug_state); @@ -190,10 +203,10 @@ class CC_EXPORT LayerTreeHost { bool UseGpuRasterization() const; void SetViewportSize(const gfx::Size& device_viewport_size); - void SetOverdrawBottomHeight(float overdraw_bottom_height); + void SetTopControlsLayoutHeight(float height); + void SetTopControlsContentOffset(float offset); gfx::Size device_viewport_size() const { return device_viewport_size_; } - float overdraw_bottom_height() const { return overdraw_bottom_height_; } void ApplyPageScaleDeltaFromImplSide(float page_scale_delta); void SetPageScaleFactorAndLimits(float page_scale_factor, @@ -222,7 +235,7 @@ class CC_EXPORT LayerTreeHost { float scale, base::TimeDelta duration); - void ApplyScrollAndScale(const ScrollAndScaleSet& info); + void ApplyScrollAndScale(ScrollAndScaleSet* info); void SetImplTransform(const gfx::Transform& transform); // Virtual for tests. @@ -251,7 +264,7 @@ class CC_EXPORT LayerTreeHost { } // Obtains a thorough dump of the LayerTreeHost as a value. - scoped_ptr<base::Value> AsValue() const; + void AsValueInto(base::debug::TracedValue* value) const; bool in_paint_layer_contents() const { return in_paint_layer_contents_; } @@ -293,14 +306,22 @@ class CC_EXPORT LayerTreeHost { void BreakSwapPromises(SwapPromise::DidNotSwapReason reason); + size_t num_queued_swap_promises() const { return swap_promise_list_.size(); } + + void set_surface_id_namespace(uint32_t id_namespace); + SurfaceSequence CreateSurfaceSequence(); + protected: LayerTreeHost(LayerTreeHostClient* client, - SharedBitmapManager* manager, + SharedBitmapManager* shared_bitmap_manager, + gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, const LayerTreeSettings& settings); void InitializeThreaded( + scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner); void InitializeSingleThreaded( - LayerTreeHostSingleThreadClient* single_thread_client); + LayerTreeHostSingleThreadClient* single_thread_client, + scoped_refptr<base::SingleThreadTaskRunner> main_task_runner); void InitializeForTesting(scoped_ptr<Proxy> proxy_for_testing); void SetOutputSurfaceLostForTesting(bool is_lost) { output_surface_lost_ = is_lost; @@ -353,7 +374,7 @@ class CC_EXPORT LayerTreeHost { void NotifySwapPromiseMonitorsOfSetNeedsCommit(); - bool animating_; + bool inside_begin_main_frame_; bool needs_full_tree_sync_; base::CancelableClosure prepaint_callback_; @@ -380,7 +401,8 @@ class CC_EXPORT LayerTreeHost { LayerTreeDebugState debug_state_; gfx::Size device_viewport_size_; - float overdraw_bottom_height_; + float top_controls_layout_height_; + float top_controls_content_offset_; float device_scale_factor_; bool visible_; @@ -390,8 +412,6 @@ class CC_EXPORT LayerTreeHost { float page_scale_factor_; float min_page_scale_factor_; float max_page_scale_factor_; - gfx::Transform impl_transform_; - bool trigger_idle_updates_; bool has_gpu_rasterization_trigger_; bool content_is_suitable_for_gpu_rasterization_; bool gpu_rasterization_histogram_recorded_; @@ -439,11 +459,18 @@ class CC_EXPORT LayerTreeHost { scoped_refptr<Layer> inner_viewport_scroll_layer_; scoped_refptr<Layer> outer_viewport_scroll_layer_; + LayerSelectionBound selection_start_; + LayerSelectionBound selection_end_; + SharedBitmapManager* shared_bitmap_manager_; + gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager_; ScopedPtrVector<SwapPromise> swap_promise_list_; std::set<SwapPromiseMonitor*> swap_promise_monitor_; + uint32_t surface_id_namespace_; + uint32_t next_surface_sequence_; + DISALLOW_COPY_AND_ASSIGN(LayerTreeHost); }; diff --git a/chromium/cc/trees/layer_tree_host_client.h b/chromium/cc/trees/layer_tree_host_client.h index 74dcbc0cff2..dca389da82d 100644 --- a/chromium/cc/trees/layer_tree_host_client.h +++ b/chromium/cc/trees/layer_tree_host_client.h @@ -17,20 +17,28 @@ namespace cc { class ContextProvider; class InputHandlerClient; class OutputSurface; +struct BeginFrameArgs; class LayerTreeHostClient { public: virtual void WillBeginMainFrame(int frame_id) = 0; // Marks finishing compositing-related tasks on the main thread. In threaded // mode, this corresponds to DidCommit(). + virtual void BeginMainFrame(const BeginFrameArgs& args) = 0; virtual void DidBeginMainFrame() = 0; - virtual void Animate(base::TimeTicks frame_begin_time) = 0; virtual void Layout() = 0; - virtual void ApplyScrollAndScale(const gfx::Vector2d& scroll_delta, - float page_scale) = 0; - // Creates an OutputSurface. If fallback is true, it should attempt to - // create an OutputSurface that is guaranteed to initialize correctly. - virtual scoped_ptr<OutputSurface> CreateOutputSurface(bool fallback) = 0; + virtual void ApplyViewportDeltas(const gfx::Vector2d& inner_delta, + const gfx::Vector2d& outer_delta, + float page_scale, + float top_controls_delta) = 0; + virtual void ApplyViewportDeltas(const gfx::Vector2d& scroll_delta, + float page_scale, + float top_controls_delta) = 0; + // Request an OutputSurface from the client. When the client has one it should + // call LayerTreeHost::SetOutputSurface. If fallback is true, it should + // attempt to create an OutputSurface that is guaranteed to initialize + // correctly. + virtual void RequestNewOutputSurface(bool fallback) = 0; virtual void DidInitializeOutputSurface() = 0; virtual void WillCommit() = 0; virtual void DidCommit() = 0; diff --git a/chromium/cc/trees/layer_tree_host_common.cc b/chromium/cc/trees/layer_tree_host_common.cc index 3bbbf6340b6..fd15b529989 100644 --- a/chromium/cc/trees/layer_tree_host_common.cc +++ b/chromium/cc/trees/layer_tree_host_common.cc @@ -16,12 +16,14 @@ #include "cc/layers/render_surface_impl.h" #include "cc/trees/layer_sorter.h" #include "cc/trees/layer_tree_impl.h" -#include "ui/gfx/rect_conversions.h" +#include "ui/gfx/geometry/rect_conversions.h" #include "ui/gfx/transform.h" namespace cc { -ScrollAndScaleSet::ScrollAndScaleSet() {} +ScrollAndScaleSet::ScrollAndScaleSet() + : page_scale_delta(1.f), top_controls_delta(0.f) { +} ScrollAndScaleSet::~ScrollAndScaleSet() {} @@ -52,13 +54,13 @@ static gfx::Vector2dF GetEffectiveScrollDelta(LayerType* layer) { } template <typename LayerType> -static gfx::Vector2dF GetEffectiveTotalScrollOffset(LayerType* layer) { - gfx::Vector2dF offset = layer->TotalScrollOffset(); +static gfx::ScrollOffset GetEffectiveTotalScrollOffset(LayerType* layer) { + gfx::ScrollOffset offset = layer->TotalScrollOffset(); // The scroll parent's total scroll offset (scroll offset + scroll delta) // can't be used because its scroll offset has already been applied to the // scroll children's positions by the main thread layer positioning code. if (layer->scroll_parent()) - offset += layer->scroll_parent()->ScrollDelta(); + offset += gfx::ScrollOffset(layer->scroll_parent()->ScrollDelta()); return offset; } @@ -240,7 +242,7 @@ template <typename LayerType> void UpdateAccumulatedSurfaceState( LayerType* layer, const gfx::Rect& drawable_content_rect, - std::vector<AccumulatedSurfaceState<LayerType> >* + std::vector<AccumulatedSurfaceState<LayerType>>* accumulated_surface_state) { if (IsRootLayer(layer)) return; @@ -282,7 +284,7 @@ void UpdateAccumulatedSurfaceState( // We must have at least one entry in the vector for the root. DCHECK_LT(0ul, accumulated_surface_state->size()); - typedef typename std::vector<AccumulatedSurfaceState<LayerType> > + typedef typename std::vector<AccumulatedSurfaceState<LayerType>> AccumulatedSurfaceStateVector; typedef typename AccumulatedSurfaceStateVector::reverse_iterator AccumulatedSurfaceStateIterator; @@ -583,7 +585,7 @@ static bool SubtreeShouldRenderToSeparateSurface( } int num_descendants_that_draw_content = - layer->draw_properties().num_descendants_that_draw_content; + layer->NumDescendantsThatDrawContent(); // If the layer flattens its subtree, but it is treated as a 3D object by its // parent (i.e. parent participates in a 3D rendering context). @@ -932,29 +934,14 @@ static inline void UpdateLayerScaleDrawProperties( layer->draw_properties().device_scale_factor = device_scale_factor; } -static inline void CalculateContentsScale( - LayerImpl* layer, - float contents_scale, - float device_scale_factor, - float page_scale_factor, - float maximum_animation_contents_scale, - bool animating_transform_to_screen) { +static inline void CalculateContentsScale(LayerImpl* layer, + float contents_scale) { // LayerImpl has all of its content scales and bounds pushed from the Main // thread during commit and just uses those values as-is. } -static inline void CalculateContentsScale( - Layer* layer, - float contents_scale, - float device_scale_factor, - float page_scale_factor, - float maximum_animation_contents_scale, - bool animating_transform_to_screen) { +static inline void CalculateContentsScale(Layer* layer, float contents_scale) { layer->CalculateContentsScale(contents_scale, - device_scale_factor, - page_scale_factor, - maximum_animation_contents_scale, - animating_transform_to_screen, &layer->draw_properties().contents_scale_x, &layer->draw_properties().contents_scale_y, &layer->draw_properties().content_bounds); @@ -963,10 +950,6 @@ static inline void CalculateContentsScale( if (mask_layer) { mask_layer->CalculateContentsScale( contents_scale, - device_scale_factor, - page_scale_factor, - maximum_animation_contents_scale, - animating_transform_to_screen, &mask_layer->draw_properties().contents_scale_x, &mask_layer->draw_properties().contents_scale_y, &mask_layer->draw_properties().content_bounds); @@ -977,10 +960,6 @@ static inline void CalculateContentsScale( if (replica_mask_layer) { replica_mask_layer->CalculateContentsScale( contents_scale, - device_scale_factor, - page_scale_factor, - maximum_animation_contents_scale, - animating_transform_to_screen, &replica_mask_layer->draw_properties().contents_scale_x, &replica_mask_layer->draw_properties().contents_scale_y, &replica_mask_layer->draw_properties().content_bounds); @@ -993,14 +972,8 @@ static inline void UpdateLayerContentsScale( float ideal_contents_scale, float device_scale_factor, float page_scale_factor, - float maximum_animation_contents_scale, bool animating_transform_to_screen) { - CalculateContentsScale(layer, - ideal_contents_scale, - device_scale_factor, - page_scale_factor, - maximum_animation_contents_scale, - animating_transform_to_screen); + CalculateContentsScale(layer, ideal_contents_scale); } static inline void UpdateLayerContentsScale( @@ -1009,7 +982,6 @@ static inline void UpdateLayerContentsScale( float ideal_contents_scale, float device_scale_factor, float page_scale_factor, - float maximum_animation_contents_scale, bool animating_transform_to_screen) { if (can_adjust_raster_scale) { float ideal_raster_scale = @@ -1042,12 +1014,7 @@ static inline void UpdateLayerContentsScale( float old_contents_scale_y = layer->contents_scale_y(); float contents_scale = raster_scale * device_scale_factor * page_scale_factor; - CalculateContentsScale(layer, - contents_scale, - device_scale_factor, - page_scale_factor, - maximum_animation_contents_scale, - animating_transform_to_screen); + CalculateContentsScale(layer, contents_scale); if (layer->content_bounds() != old_content_bounds || layer->contents_scale_x() != old_contents_scale_x || @@ -1129,7 +1096,7 @@ static inline void CalculateAnimationContentsScale( } float layer_maximum_animated_scale = 0.f; - if (!layer->layer_animation_controller()->MaximumScale( + if (!layer->layer_animation_controller()->MaximumTargetScale( &layer_maximum_animated_scale)) { *combined_maximum_animation_contents_scale = 0.f; return; @@ -1242,8 +1209,6 @@ template <typename LayerType> static void PreCalculateMetaInformation( LayerType* layer, PreCalculateMetaInformationRecursiveData* recursive_data) { - bool has_delegated_content = layer->HasDelegatedContent(); - int num_descendants_that_draw_content = 0; layer->draw_properties().sorted_for_recursion = false; layer->draw_properties().has_child_with_a_scroll_parent = false; @@ -1254,14 +1219,6 @@ static void PreCalculateMetaInformation( return; } - if (has_delegated_content) { - // Layers with delegated content need to be treated as if they have as - // many children as the number of layers they own delegated quads for. - // Since we don't know this number right now, we choose one that acts like - // infinity for our purposes. - num_descendants_that_draw_content = 1000; - } - if (layer->clip_parent()) recursive_data->num_unclipped_descendants++; @@ -1272,10 +1229,6 @@ static void PreCalculateMetaInformation( PreCalculateMetaInformationRecursiveData data_for_child; PreCalculateMetaInformation(child_layer, &data_for_child); - num_descendants_that_draw_content += child_layer->DrawsContent() ? 1 : 0; - num_descendants_that_draw_content += - child_layer->draw_properties().num_descendants_that_draw_content; - if (child_layer->scroll_parent()) layer->draw_properties().has_child_with_a_scroll_parent = true; recursive_data->Merge(data_for_child); @@ -1294,8 +1247,6 @@ static void PreCalculateMetaInformation( layer->have_wheel_event_handlers()) recursive_data->layer_or_descendant_has_input_handler = true; - layer->draw_properties().num_descendants_that_draw_content = - num_descendants_that_draw_content; layer->draw_properties().num_unclipped_descendants = recursive_data->num_unclipped_descendants; layer->draw_properties().layer_or_descendant_has_copy_request = @@ -1500,7 +1451,7 @@ static void CalculateDrawPropertiesInternal( const DataForRecursion<LayerType>& data_from_ancestor, typename LayerType::RenderSurfaceListType* render_surface_layer_list, typename LayerType::LayerListType* layer_list, - std::vector<AccumulatedSurfaceState<LayerType> >* accumulated_surface_state, + std::vector<AccumulatedSurfaceState<LayerType>>* accumulated_surface_state, int current_render_surface_layer_list_id) { // This function computes the new matrix transformations recursively for this // layer and all its descendants. It also computes the appropriate render @@ -1696,8 +1647,9 @@ static void CalculateDrawPropertiesInternal( layer->parent()->screen_space_transform_is_animating(); } gfx::Point3F transform_origin = layer->transform_origin(); - gfx::Vector2dF scroll_offset = GetEffectiveTotalScrollOffset(layer); - gfx::PointF position = layer->position() - scroll_offset; + gfx::ScrollOffset scroll_offset = GetEffectiveTotalScrollOffset(layer); + gfx::PointF position = + layer->position() - ScrollOffsetToVector2dF(scroll_offset); gfx::Transform combined_transform = data_from_ancestor.parent_matrix; if (!layer->transform().IsIdentity()) { // LT = Tr[origin] * Tr[origin2transformOrigin] @@ -1781,7 +1733,6 @@ static void CalculateDrawPropertiesInternal( data_from_ancestor.in_subtree_of_page_scale_application_layer ? globals.page_scale_factor : 1.f, - combined_maximum_animation_contents_scale, animating_transform_to_screen); UpdateLayerScaleDrawProperties( @@ -1997,8 +1948,11 @@ static void CalculateDrawPropertiesInternal( // here, or DCHECK that the transform is invertible. } + gfx::Rect surface_clip_rect_in_target_space = gfx::IntersectRects( + data_from_ancestor.clip_rect_of_target_surface_in_target_space, + ancestor_clip_rect_in_target_space); gfx::Rect projected_surface_rect = MathUtil::ProjectEnclosingClippedRect( - inverse_surface_draw_transform, ancestor_clip_rect_in_target_space); + inverse_surface_draw_transform, surface_clip_rect_in_target_space); if (layer_draw_properties.num_unclipped_descendants > 0) { // If we have unclipped descendants, we cannot count on the render @@ -2379,7 +2333,7 @@ static void CalculateDrawPropertiesInternal( layer->render_target()->render_surface()-> AddContributingDelegatedRenderPassLayer(layer); } -} +} // NOLINT(readability/fn_size) template <typename LayerType, typename RenderSurfaceLayerListType> static void ProcessCalcDrawPropsInputs( @@ -2444,7 +2398,7 @@ void LayerTreeHostCommon::CalculateDrawProperties( PreCalculateMetaInformationRecursiveData recursive_data; PreCalculateMetaInformation(inputs->root_layer, &recursive_data); - std::vector<AccumulatedSurfaceState<Layer> > accumulated_surface_state; + std::vector<AccumulatedSurfaceState<Layer>> accumulated_surface_state; CalculateDrawPropertiesInternal<Layer>( inputs->root_layer, globals, @@ -2473,8 +2427,7 @@ void LayerTreeHostCommon::CalculateDrawProperties( PreCalculateMetaInformationRecursiveData recursive_data; PreCalculateMetaInformation(inputs->root_layer, &recursive_data); - std::vector<AccumulatedSurfaceState<LayerImpl> > - accumulated_surface_state; + std::vector<AccumulatedSurfaceState<LayerImpl>> accumulated_surface_state; CalculateDrawPropertiesInternal<LayerImpl>( inputs->root_layer, globals, diff --git a/chromium/cc/trees/layer_tree_host_common.h b/chromium/cc/trees/layer_tree_host_common.h index 0e139471739..089fe2933f2 100644 --- a/chromium/cc/trees/layer_tree_host_common.h +++ b/chromium/cc/trees/layer_tree_host_common.h @@ -13,14 +13,15 @@ #include "cc/base/cc_export.h" #include "cc/base/scoped_ptr_vector.h" #include "cc/layers/layer_lists.h" -#include "ui/gfx/rect.h" +#include "ui/gfx/geometry/rect.h" +#include "ui/gfx/geometry/vector2d.h" #include "ui/gfx/transform.h" -#include "ui/gfx/vector2d.h" namespace cc { class LayerImpl; class Layer; +class SwapPromise; class CC_EXPORT LayerTreeHostCommon { public: @@ -129,6 +130,8 @@ class CC_EXPORT LayerTreeHostCommon { struct ScrollUpdateInfo { int layer_id; + // TODO(miletus) : Use ScrollOffset once LayerTreeHost/Blink fully supports + // franctional scroll offset. gfx::Vector2d scroll_delta; }; }; @@ -139,6 +142,8 @@ struct CC_EXPORT ScrollAndScaleSet { std::vector<LayerTreeHostCommon::ScrollUpdateInfo> scrolls; float page_scale_delta; + float top_controls_delta; + ScopedPtrVector<SwapPromise> swap_promises; }; template <typename LayerType> diff --git a/chromium/cc/trees/layer_tree_host_common_perftest.cc b/chromium/cc/trees/layer_tree_host_common_perftest.cc index 02b0770495b..12e7a5e2f9d 100644 --- a/chromium/cc/trees/layer_tree_host_common_perftest.cc +++ b/chromium/cc/trees/layer_tree_host_common_perftest.cc @@ -6,14 +6,20 @@ #include <sstream> -#include "base/file_util.h" #include "base/files/file_path.h" +#include "base/files/file_util.h" +#include "base/memory/scoped_ptr.h" #include "base/path_service.h" #include "base/strings/string_piece.h" #include "base/threading/thread.h" #include "base/time/time.h" +#include "cc/base/scoped_ptr_deque.h" +#include "cc/base/scoped_ptr_vector.h" #include "cc/debug/lap_timer.h" #include "cc/layers/layer.h" +#include "cc/output/bsp_tree.h" +#include "cc/quads/draw_polygon.h" +#include "cc/quads/draw_quad.h" #include "cc/test/fake_content_layer_client.h" #include "cc/test/fake_layer_tree_host_client.h" #include "cc/test/layer_tree_json_parser.h" @@ -44,7 +50,7 @@ class LayerTreeHostCommonPerfTest : public LayerTreeTest { ASSERT_TRUE(base::ReadFileToString(json_file, &json_)); } - virtual void SetupTree() OVERRIDE { + void SetupTree() override { gfx::Size viewport = gfx::Size(720, 1038); layer_tree_host()->SetViewportSize(viewport); scoped_refptr<Layer> root = @@ -55,7 +61,7 @@ class LayerTreeHostCommonPerfTest : public LayerTreeTest { void SetTestName(const std::string& name) { test_name_ = name; } - virtual void AfterTest() OVERRIDE { + void AfterTest() override { CHECK(!test_name_.empty()) << "Must SetTestName() before TearDown()."; perf_test::PrintResult("calc_draw_props_time", "", @@ -78,7 +84,7 @@ class CalcDrawPropsMainTest : public LayerTreeHostCommonPerfTest { RunTest(false, false, false); } - virtual void BeginTest() OVERRIDE { + void BeginTest() override { timer_.Reset(); do { @@ -115,11 +121,9 @@ class CalcDrawPropsImplTest : public LayerTreeHostCommonPerfTest { RunTestWithImplSidePainting(); } - virtual void BeginTest() OVERRIDE { - PostSetNeedsCommitToMainThread(); - } + void BeginTest() override { PostSetNeedsCommitToMainThread(); } - virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { + void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { timer_.Reset(); LayerTreeImpl* active_tree = host_impl->active_tree(); @@ -163,9 +167,9 @@ class LayerSorterMainTest : public CalcDrawPropsImplTest { public: void RunSortLayers() { RunTest(false, false, false); } - virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } + void BeginTest() override { PostSetNeedsCommitToMainThread(); } - virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { + void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { LayerTreeImpl* active_tree = host_impl->active_tree(); // First build the tree and then we'll start running tests on layersorter // itself @@ -197,7 +201,7 @@ class LayerSorterMainTest : public CalcDrawPropsImplTest { list->push_back(layer); } - for (unsigned int i = 0; i < layer->children().size(); i++) { + for (size_t i = 0; i < layer->children().size(); i++) { BuildLayerImplList(layer->children()[i], list); } } @@ -207,6 +211,61 @@ class LayerSorterMainTest : public CalcDrawPropsImplTest { LayerSorter layer_sorter_; }; +class BspTreePerfTest : public LayerSorterMainTest { + public: + void RunSortLayers() { RunTest(false, false, false); } + + void SetNumberOfDuplicates(int num_duplicates) { + num_duplicates_ = num_duplicates; + } + + void BeginTest() override { PostSetNeedsCommitToMainThread(); } + + void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { + LayerTreeImpl* active_tree = host_impl->active_tree(); + // First build the tree and then we'll start running tests on layersorter + // itself + bool can_render_to_separate_surface = true; + int max_texture_size = 8096; + DoCalcDrawPropertiesImpl(can_render_to_separate_surface, + max_texture_size, + active_tree, + host_impl); + + LayerImplList base_list; + BuildLayerImplList(active_tree->root_layer(), &base_list); + + int polygon_counter = 0; + ScopedPtrVector<DrawPolygon> polygon_list; + for (LayerImplList::iterator it = base_list.begin(); it != base_list.end(); + ++it) { + DrawPolygon* draw_polygon = + new DrawPolygon(NULL, + gfx::RectF((*it)->content_bounds()), + (*it)->draw_transform(), + polygon_counter++); + polygon_list.push_back(scoped_ptr<DrawPolygon>(draw_polygon)); + } + + timer_.Reset(); + do { + ScopedPtrDeque<DrawPolygon> test_list; + for (int i = 0; i < num_duplicates_; i++) { + for (size_t i = 0; i < polygon_list.size(); i++) { + test_list.push_back(polygon_list[i]->CreateCopy()); + } + } + BspTree bsp_tree(&test_list); + timer_.NextLap(); + } while (!timer_.HasTimeLimitExpired()); + + EndTest(); + } + + private: + int num_duplicates_; +}; + TEST_F(CalcDrawPropsMainTest, TenTen) { SetTestName("10_10_main_thread"); ReadTestFile("10_10_layer_tree"); @@ -267,5 +326,33 @@ TEST_F(LayerSorterMainTest, LayerSorterRubik) { RunSortLayers(); } +TEST_F(BspTreePerfTest, BspTreeCubes) { + SetTestName("bsp_tree_cubes"); + SetNumberOfDuplicates(1); + ReadTestFile("layer_sort_cubes"); + RunSortLayers(); +} + +TEST_F(BspTreePerfTest, BspTreeRubik) { + SetTestName("bsp_tree_rubik"); + SetNumberOfDuplicates(1); + ReadTestFile("layer_sort_rubik"); + RunSortLayers(); +} + +TEST_F(BspTreePerfTest, BspTreeCubes_2) { + SetTestName("bsp_tree_cubes_2"); + SetNumberOfDuplicates(2); + ReadTestFile("layer_sort_cubes"); + RunSortLayers(); +} + +TEST_F(BspTreePerfTest, BspTreeCubes_4) { + SetTestName("bsp_tree_cubes_4"); + SetNumberOfDuplicates(4); + ReadTestFile("layer_sort_cubes"); + RunSortLayers(); +} + } // namespace } // namespace cc diff --git a/chromium/cc/trees/layer_tree_host_common_unittest.cc b/chromium/cc/trees/layer_tree_host_common_unittest.cc index 8dcb6d7ad1e..e0436bad3cc 100644 --- a/chromium/cc/trees/layer_tree_host_common_unittest.cc +++ b/chromium/cc/trees/layer_tree_host_common_unittest.cc @@ -4,6 +4,7 @@ #include "cc/trees/layer_tree_host_common.h" +#include <algorithm> #include <set> #include "cc/animation/layer_animation_controller.h" @@ -23,6 +24,8 @@ #include "cc/test/fake_impl_proxy.h" #include "cc/test/fake_layer_tree_host.h" #include "cc/test/fake_layer_tree_host_impl.h" +#include "cc/test/fake_picture_layer.h" +#include "cc/test/fake_picture_layer_impl.h" #include "cc/test/geometry_test_utils.h" #include "cc/test/layer_tree_host_common_test.h" #include "cc/trees/layer_tree_impl.h" @@ -30,7 +33,7 @@ #include "cc/trees/single_thread_proxy.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -#include "ui/gfx/quad_f.h" +#include "ui/gfx/geometry/quad_f.h" #include "ui/gfx/transform.h" namespace cc { @@ -38,62 +41,36 @@ namespace { class LayerWithForcedDrawsContent : public Layer { public: - LayerWithForcedDrawsContent() : Layer(), last_device_scale_factor_(0.f) {} + LayerWithForcedDrawsContent() {} - virtual bool DrawsContent() const OVERRIDE; - virtual void CalculateContentsScale(float ideal_contents_scale, - float device_scale_factor, - float page_scale_factor, - float maximum_animation_contents_scale, - bool animating_transform_to_screen, - float* contents_scale_x, - float* contents_scale_y, - gfx::Size* content_bounds) OVERRIDE; - - float last_device_scale_factor() const { return last_device_scale_factor_; } + bool DrawsContent() const override; private: - virtual ~LayerWithForcedDrawsContent() {} - - // Parameters from last CalculateContentsScale. - float last_device_scale_factor_; + ~LayerWithForcedDrawsContent() override {} }; bool LayerWithForcedDrawsContent::DrawsContent() const { return true; } -void LayerWithForcedDrawsContent::CalculateContentsScale( - float ideal_contents_scale, - float device_scale_factor, - float page_scale_factor, - float maximum_animation_contents_scale, - bool animating_transform_to_screen, - float* contents_scale_x, - float* contents_scale_y, - gfx::Size* content_bounds) { - last_device_scale_factor_ = device_scale_factor; - Layer::CalculateContentsScale(ideal_contents_scale, - device_scale_factor, - page_scale_factor, - maximum_animation_contents_scale, - animating_transform_to_screen, - contents_scale_x, - contents_scale_y, - content_bounds); -} - class MockContentLayerClient : public ContentLayerClient { public: MockContentLayerClient() {} - virtual ~MockContentLayerClient() {} - virtual void PaintContents( + ~MockContentLayerClient() override {} + void PaintContents( SkCanvas* canvas, const gfx::Rect& clip, - gfx::RectF* opaque, - ContentLayerClient::GraphicsContextStatus gc_status) OVERRIDE {} - virtual void DidChangeLayerCanUseLCDText() OVERRIDE {} - virtual bool FillsBoundsCompletely() const OVERRIDE { return false; } + ContentLayerClient::GraphicsContextStatus gc_status) override {} + void DidChangeLayerCanUseLCDText() override {} + bool FillsBoundsCompletely() const override { return false; } }; +scoped_refptr<FakePictureLayer> CreateDrawablePictureLayer( + ContentLayerClient* delegate) { + scoped_refptr<FakePictureLayer> to_return = + FakePictureLayer::Create(delegate); + to_return->SetIsDrawable(true); + return to_return; +} + scoped_refptr<ContentLayer> CreateDrawableContentLayer( ContentLayerClient* delegate) { scoped_refptr<ContentLayer> to_return = ContentLayer::Create(delegate); @@ -107,6 +84,11 @@ scoped_refptr<ContentLayer> CreateDrawableContentLayer( EXPECT_FLOAT_EQ(expected, layer->contents_scale_y()); \ } while (false) +#define EXPECT_IDEAL_SCALE_EQ(expected, layer) \ + do { \ + EXPECT_FLOAT_EQ(expected, layer->draw_properties().ideal_contents_scale); \ + } while (false) + TEST_F(LayerTreeHostCommonTest, TransformsForNoOpLayer) { // Sanity check: For layers positioned at zero, with zero size, // and with identity transforms, then the draw transform, @@ -119,7 +101,7 @@ TEST_F(LayerTreeHostCommonTest, TransformsForNoOpLayer) { parent->AddChild(child); child->AddChild(grand_child); - scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); + scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost()); host->SetRootLayer(parent); gfx::Transform identity_matrix; @@ -163,7 +145,7 @@ TEST_F(LayerTreeHostCommonTest, DoNotSkipLayersWithHandlers) { parent->AddChild(child); child->AddChild(grand_child); - scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); + scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost()); host->SetRootLayer(parent); gfx::Transform identity_matrix; @@ -216,7 +198,7 @@ TEST_F(LayerTreeHostCommonTest, TransformsForSingleLayer) { false); root->AddChild(layer); - scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); + scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost()); host->SetRootLayer(root); // Case 2: Setting the bounds of the layer should not affect either the draw @@ -318,7 +300,7 @@ TEST_F(LayerTreeHostCommonTest, TransformsForSingleLayer) { } TEST_F(LayerTreeHostCommonTest, TransformsAboutScrollOffset) { - const gfx::Vector2d kScrollOffset(50, 100); + const gfx::ScrollOffset kScrollOffset(50, 100); const gfx::Vector2dF kScrollDelta(2.34f, 5.67f); const gfx::Vector2d kMaxScrollOffset(200, 200); const gfx::PointF kScrollLayerPosition(-kScrollOffset.x(), @@ -425,7 +407,7 @@ TEST_F(LayerTreeHostCommonTest, TransformsForSimpleHierarchy) { parent->AddChild(child); child->AddChild(grand_child); - scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); + scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost()); host->SetRootLayer(root); // One-time setup of root layer @@ -552,7 +534,7 @@ TEST_F(LayerTreeHostCommonTest, TransformsForSingleRenderSurface) { parent->AddChild(child); child->AddChild(grand_child); - scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); + scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost()); host->SetRootLayer(root); // One-time setup of root layer @@ -614,7 +596,7 @@ TEST_F(LayerTreeHostCommonTest, TransformsForSingleRenderSurface) { // Render surface should have been created now. ASSERT_TRUE(child->render_surface()); - ASSERT_EQ(child, child->render_target()); + ASSERT_EQ(child.get(), child->render_target()); // The child layer's draw transform should refer to its new render surface. // The screen-space transform, however, should still refer to the root. @@ -649,7 +631,7 @@ TEST_F(LayerTreeHostCommonTest, TransformsForReplica) { child->AddChild(grand_child); child->SetReplicaLayer(child_replica.get()); - scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); + scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost()); host->SetRootLayer(root); // One-time setup of root layer @@ -719,7 +701,7 @@ TEST_F(LayerTreeHostCommonTest, TransformsForReplica) { // Render surface should have been created now. ASSERT_TRUE(child->render_surface()); - ASSERT_EQ(child, child->render_target()); + ASSERT_EQ(child.get(), child->render_target()); EXPECT_TRANSFORMATION_MATRIX_EQ( replica_composite_transform, @@ -770,7 +752,7 @@ TEST_F(LayerTreeHostCommonTest, TransformsForRenderSurfaceHierarchy) { render_surface1->SetReplicaLayer(replica_of_rs1.get()); render_surface2->SetReplicaLayer(replica_of_rs2.get()); - scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); + scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost()); host->SetRootLayer(root); // In combination with descendant draws content, opacity != 1 forces the layer @@ -922,17 +904,17 @@ TEST_F(LayerTreeHostCommonTest, TransformsForRenderSurfaceHierarchy) { ASSERT_FALSE(grand_child_of_rs2->render_surface()); // Verify all render target accessors - EXPECT_EQ(root, parent->render_target()); - EXPECT_EQ(root, child_of_root->render_target()); - EXPECT_EQ(root, grand_child_of_root->render_target()); + EXPECT_EQ(root.get(), parent->render_target()); + EXPECT_EQ(root.get(), child_of_root->render_target()); + EXPECT_EQ(root.get(), grand_child_of_root->render_target()); - EXPECT_EQ(render_surface1, render_surface1->render_target()); - EXPECT_EQ(render_surface1, child_of_rs1->render_target()); - EXPECT_EQ(render_surface1, grand_child_of_rs1->render_target()); + EXPECT_EQ(render_surface1.get(), render_surface1->render_target()); + EXPECT_EQ(render_surface1.get(), child_of_rs1->render_target()); + EXPECT_EQ(render_surface1.get(), grand_child_of_rs1->render_target()); - EXPECT_EQ(render_surface2, render_surface2->render_target()); - EXPECT_EQ(render_surface2, child_of_rs2->render_target()); - EXPECT_EQ(render_surface2, grand_child_of_rs2->render_target()); + EXPECT_EQ(render_surface2.get(), render_surface2->render_target()); + EXPECT_EQ(render_surface2.get(), child_of_rs2->render_target()); + EXPECT_EQ(render_surface2.get(), grand_child_of_rs2->render_target()); // Verify layer draw transforms note that draw transforms are described with // respect to the nearest ancestor render surface but screen space transforms @@ -1065,7 +1047,7 @@ TEST_F(LayerTreeHostCommonTest, TransformsForFlatteningLayer) { child->AddChild(grand_child); child->SetForceRenderSurface(true); - scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); + scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost()); host->SetRootLayer(root); // No layers in this test should preserve 3d. @@ -1144,7 +1126,7 @@ TEST_F(LayerTreeHostCommonTest, TransformsForDegenerateIntermediateLayer) { child->AddChild(grand_child); child->SetForceRenderSurface(true); - scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); + scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost()); host->SetRootLayer(root); ExecuteCalculateDrawProperties(root.get()); @@ -1169,7 +1151,7 @@ TEST_F(LayerTreeHostCommonTest, TransformAboveRootLayer) { child->SetScrollClipLayerId(root->id()); root->AddChild(child); - scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); + scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost()); host->SetRootLayer(root); SetLayerPropertiesForTesting(root.get(), @@ -1198,8 +1180,8 @@ TEST_F(LayerTreeHostCommonTest, TransformAboveRootLayer) { EXPECT_EQ(translate, root->draw_properties().target_space_transform); EXPECT_EQ(translate, child->draw_properties().target_space_transform); EXPECT_EQ(identity_matrix, root->render_surface()->draw_transform()); - EXPECT_EQ(1.f, root->last_device_scale_factor()); - EXPECT_EQ(1.f, child->last_device_scale_factor()); + EXPECT_EQ(1.f, root->draw_properties().device_scale_factor); + EXPECT_EQ(1.f, child->draw_properties().device_scale_factor); } gfx::Transform scale; @@ -1213,8 +1195,8 @@ TEST_F(LayerTreeHostCommonTest, TransformAboveRootLayer) { EXPECT_EQ(scale, root->draw_properties().target_space_transform); EXPECT_EQ(scale, child->draw_properties().target_space_transform); EXPECT_EQ(identity_matrix, root->render_surface()->draw_transform()); - EXPECT_EQ(2.f, root->last_device_scale_factor()); - EXPECT_EQ(2.f, child->last_device_scale_factor()); + EXPECT_EQ(2.f, root->draw_properties().device_scale_factor); + EXPECT_EQ(2.f, child->draw_properties().device_scale_factor); } gfx::Transform rotate; @@ -1228,8 +1210,8 @@ TEST_F(LayerTreeHostCommonTest, TransformAboveRootLayer) { EXPECT_EQ(rotate, root->draw_properties().target_space_transform); EXPECT_EQ(rotate, child->draw_properties().target_space_transform); EXPECT_EQ(identity_matrix, root->render_surface()->draw_transform()); - EXPECT_EQ(1.f, root->last_device_scale_factor()); - EXPECT_EQ(1.f, child->last_device_scale_factor()); + EXPECT_EQ(1.f, root->draw_properties().device_scale_factor); + EXPECT_EQ(1.f, child->draw_properties().device_scale_factor); } gfx::Transform composite; @@ -1264,8 +1246,9 @@ TEST_F(LayerTreeHostCommonTest, TransformAboveRootLayer) { EXPECT_EQ(device_scaled_translate, child->draw_properties().target_space_transform); EXPECT_EQ(identity_matrix, root->render_surface()->draw_transform()); - EXPECT_EQ(device_scale_factor, root->last_device_scale_factor()); - EXPECT_EQ(device_scale_factor, child->last_device_scale_factor()); + EXPECT_EQ(device_scale_factor, root->draw_properties().device_scale_factor); + EXPECT_EQ(device_scale_factor, + child->draw_properties().device_scale_factor); } // Verify it composes correctly with page scale. @@ -1285,8 +1268,8 @@ TEST_F(LayerTreeHostCommonTest, TransformAboveRootLayer) { EXPECT_EQ(page_scaled_translate, child->draw_properties().target_space_transform); EXPECT_EQ(identity_matrix, root->render_surface()->draw_transform()); - EXPECT_EQ(1.f, root->last_device_scale_factor()); - EXPECT_EQ(1.f, child->last_device_scale_factor()); + EXPECT_EQ(1.f, root->draw_properties().device_scale_factor); + EXPECT_EQ(1.f, child->draw_properties().device_scale_factor); } // Verify that it composes correctly with transforms directly on root layer. @@ -1315,7 +1298,7 @@ TEST_F(LayerTreeHostCommonTest, scoped_refptr<LayerWithForcedDrawsContent> child = make_scoped_refptr(new LayerWithForcedDrawsContent()); - scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); + scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost()); host->SetRootLayer(parent); const gfx::Transform identity_matrix; @@ -1369,7 +1352,7 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceListForTransparentChild) { scoped_refptr<LayerWithForcedDrawsContent> child = make_scoped_refptr(new LayerWithForcedDrawsContent()); - scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); + scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost()); host->SetRootLayer(parent); const gfx::Transform identity_matrix; @@ -1416,7 +1399,7 @@ TEST_F(LayerTreeHostCommonTest, ForceRenderSurface) { make_scoped_refptr(new LayerWithForcedDrawsContent()); render_surface1->SetForceRenderSurface(true); - scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); + scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost()); host->SetRootLayer(parent); const gfx::Transform identity_matrix; @@ -1505,7 +1488,7 @@ TEST_F(LayerTreeHostCommonTest, ClipRectCullsRenderSurfaces) { child->AddChild(grand_child); grand_child->AddChild(great_grand_child); - scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); + scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost()); host->SetRootLayer(parent); // leaf_node1 ensures that parent and child are kept on the @@ -1603,7 +1586,7 @@ TEST_F(LayerTreeHostCommonTest, ClipRectCullsSurfaceWithoutVisibleContent) { child->AddChild(grand_child); grand_child->AddChild(leaf_node); - scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); + scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost()); host->SetRootLayer(parent); SetLayerPropertiesForTesting(parent.get(), @@ -1705,7 +1688,7 @@ TEST_F(LayerTreeHostCommonTest, IsClippedIsSetCorrectly) { child2->AddChild(leaf_node2); grand_child->AddChild(leaf_node1); - scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); + scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost()); host->SetRootLayer(root); child2->SetForceRenderSurface(true); @@ -1863,7 +1846,7 @@ TEST_F(LayerTreeHostCommonTest, DrawableContentRectForLayers) { child->AddChild(grand_child3); child->AddChild(grand_child4); - scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); + scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost()); host->SetRootLayer(parent); SetLayerPropertiesForTesting(parent.get(), @@ -1964,7 +1947,7 @@ TEST_F(LayerTreeHostCommonTest, ClipRectIsPropagatedCorrectlyToSurfaces) { child->AddChild(grand_child3); child->AddChild(grand_child4); - scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); + scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost()); host->SetRootLayer(parent); // the leaf nodes ensure that these grand_children become render surfaces for @@ -2101,7 +2084,7 @@ TEST_F(LayerTreeHostCommonTest, AnimationsForRenderSurfaceHierarchy) { child_of_rs1->AddChild(grand_child_of_rs1); child_of_rs2->AddChild(grand_child_of_rs2); - scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); + scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost()); host->SetRootLayer(parent); // Make our render surfaces. @@ -2211,17 +2194,17 @@ TEST_F(LayerTreeHostCommonTest, AnimationsForRenderSurfaceHierarchy) { ASSERT_FALSE(grand_child_of_rs2->render_surface()); // Verify all render target accessors - EXPECT_EQ(parent, parent->render_target()); - EXPECT_EQ(parent, child_of_root->render_target()); - EXPECT_EQ(parent, grand_child_of_root->render_target()); + EXPECT_EQ(parent.get(), parent->render_target()); + EXPECT_EQ(parent.get(), child_of_root->render_target()); + EXPECT_EQ(parent.get(), grand_child_of_root->render_target()); - EXPECT_EQ(render_surface1, render_surface1->render_target()); - EXPECT_EQ(render_surface1, child_of_rs1->render_target()); - EXPECT_EQ(render_surface1, grand_child_of_rs1->render_target()); + EXPECT_EQ(render_surface1.get(), render_surface1->render_target()); + EXPECT_EQ(render_surface1.get(), child_of_rs1->render_target()); + EXPECT_EQ(render_surface1.get(), grand_child_of_rs1->render_target()); - EXPECT_EQ(render_surface2, render_surface2->render_target()); - EXPECT_EQ(render_surface2, child_of_rs2->render_target()); - EXPECT_EQ(render_surface2, grand_child_of_rs2->render_target()); + EXPECT_EQ(render_surface2.get(), render_surface2->render_target()); + EXPECT_EQ(render_surface2.get(), child_of_rs2->render_target()); + EXPECT_EQ(render_surface2.get(), grand_child_of_rs2->render_target()); // Verify draw_opacity_is_animating values EXPECT_FALSE(parent->draw_opacity_is_animating()); @@ -2589,7 +2572,7 @@ TEST_F(LayerTreeHostCommonTest, DrawableAndVisibleContentRectsForSimpleLayers) { root->AddChild(child2); root->AddChild(child3); - scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); + scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost()); host->SetRootLayer(root); gfx::Transform identity_matrix; @@ -2657,7 +2640,7 @@ TEST_F(LayerTreeHostCommonTest, child->AddChild(grand_child2); child->AddChild(grand_child3); - scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); + scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost()); host->SetRootLayer(root); gfx::Transform identity_matrix; @@ -2738,7 +2721,7 @@ TEST_F(LayerTreeHostCommonTest, render_surface1->AddChild(child2); render_surface1->AddChild(child3); - scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); + scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost()); host->SetRootLayer(root); gfx::Transform identity_matrix; @@ -2814,7 +2797,7 @@ TEST_F(LayerTreeHostCommonTest, make_scoped_refptr(new LayerWithForcedDrawsContent()); root->AddChild(child); - scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); + scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost()); host->SetRootLayer(root); // Case 1: a truly degenerate matrix @@ -2888,7 +2871,7 @@ TEST_F(LayerTreeHostCommonTest, make_scoped_refptr(new LayerWithForcedDrawsContent()); root->AddChild(child); - scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); + scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost()); host->SetRootLayer(root); gfx::Transform identity_matrix; @@ -2932,7 +2915,7 @@ TEST_F(LayerTreeHostCommonTest, SingularNonAnimatingTransformDoesNotPreventClearingDrawProperties) { scoped_refptr<Layer> root = Layer::Create(); - scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); + scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost()); host->SetRootLayer(root); gfx::Transform identity_matrix; @@ -2971,7 +2954,7 @@ TEST_F(LayerTreeHostCommonTest, render_surface1->AddChild(child2); render_surface1->AddChild(child3); - scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); + scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost()); host->SetRootLayer(root); gfx::Transform identity_matrix; @@ -3061,7 +3044,7 @@ TEST_F(LayerTreeHostCommonTest, render_surface2->AddChild(child2); render_surface2->AddChild(child3); - scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); + scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost()); host->SetRootLayer(root); gfx::Transform identity_matrix; @@ -3161,7 +3144,7 @@ TEST_F(LayerTreeHostCommonTest, root->AddChild(render_surface1); render_surface1->AddChild(child1); - scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); + scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost()); host->SetRootLayer(root); gfx::Transform identity_matrix; @@ -3232,7 +3215,7 @@ TEST_F(LayerTreeHostCommonTest, root->AddChild(render_surface1); render_surface1->AddChild(child1); - scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); + scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost()); host->SetRootLayer(root); gfx::Transform identity_matrix; @@ -3294,20 +3277,20 @@ TEST_F(LayerTreeHostCommonTest, DrawableAndVisibleContentRectsInHighDPI) { MockContentLayerClient client; scoped_refptr<Layer> root = Layer::Create(); - scoped_refptr<ContentLayer> render_surface1 = - CreateDrawableContentLayer(&client); - scoped_refptr<ContentLayer> render_surface2 = - CreateDrawableContentLayer(&client); - scoped_refptr<ContentLayer> child1 = CreateDrawableContentLayer(&client); - scoped_refptr<ContentLayer> child2 = CreateDrawableContentLayer(&client); - scoped_refptr<ContentLayer> child3 = CreateDrawableContentLayer(&client); + scoped_refptr<FakePictureLayer> render_surface1 = + CreateDrawablePictureLayer(&client); + scoped_refptr<FakePictureLayer> render_surface2 = + CreateDrawablePictureLayer(&client); + scoped_refptr<FakePictureLayer> child1 = CreateDrawablePictureLayer(&client); + scoped_refptr<FakePictureLayer> child2 = CreateDrawablePictureLayer(&client); + scoped_refptr<FakePictureLayer> child3 = CreateDrawablePictureLayer(&client); root->AddChild(render_surface1); render_surface1->AddChild(render_surface2); render_surface2->AddChild(child1); render_surface2->AddChild(child2); render_surface2->AddChild(child3); - scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); + scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost()); host->SetRootLayer(root); gfx::Transform identity_matrix; @@ -3386,15 +3369,15 @@ TEST_F(LayerTreeHostCommonTest, DrawableAndVisibleContentRectsInHighDPI) { // The root layer does not actually draw content of its own. EXPECT_RECT_EQ(gfx::Rect(0, 0, 0, 0), root->visible_content_rect()); - // All layer visible content rects are expressed in content space of each - // layer, so they are also scaled by the device_scale_factor. - EXPECT_RECT_EQ(gfx::Rect(0, 0, 6, 8), + // All layer visible content rects are not expressed in content space of each + // layer, so they are not scaled by the device_scale_factor. + EXPECT_RECT_EQ(gfx::Rect(0, 0, 3, 4), render_surface1->visible_content_rect()); - EXPECT_RECT_EQ(gfx::Rect(0, 0, 14, 26), + EXPECT_RECT_EQ(gfx::Rect(0, 0, 7, 13), render_surface2->visible_content_rect()); - EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100), child1->visible_content_rect()); - EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100), child2->visible_content_rect()); - EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100), child3->visible_content_rect()); + EXPECT_RECT_EQ(gfx::Rect(0, 0, 50, 50), child1->visible_content_rect()); + EXPECT_RECT_EQ(gfx::Rect(0, 0, 50, 50), child2->visible_content_rect()); + EXPECT_RECT_EQ(gfx::Rect(0, 0, 50, 50), child3->visible_content_rect()); } TEST_F(LayerTreeHostCommonTest, BackFaceCullingWithoutPreserves3d) { @@ -3434,7 +3417,7 @@ TEST_F(LayerTreeHostCommonTest, BackFaceCullingWithoutPreserves3d) { back_facing_surface->AddChild(front_facing_child_of_back_facing_surface); back_facing_surface->AddChild(back_facing_child_of_back_facing_surface); - scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); + scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost()); host->SetRootLayer(parent); // Nothing is double-sided @@ -3640,7 +3623,7 @@ TEST_F(LayerTreeHostCommonTest, BackFaceCullingWithPreserves3d) { back_facing_surface->AddChild(front_facing_child_of_back_facing_surface); back_facing_surface->AddChild(back_facing_child_of_back_facing_surface); - scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); + scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost()); host->SetRootLayer(parent); // Nothing is double-sided @@ -3806,7 +3789,7 @@ TEST_F(LayerTreeHostCommonTest, BackFaceCullingWithAnimatingTransforms) { parent->AddChild(animating_child); parent->AddChild(child2); - scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); + scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost()); host->SetRootLayer(parent); // Nothing is double-sided @@ -3952,7 +3935,7 @@ TEST_F(LayerTreeHostCommonTest, front_facing_surface->AddChild(child1); back_facing_surface->AddChild(child2); - scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); + scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost()); host->SetRootLayer(parent); // RenderSurfaces are not double-sided @@ -4048,20 +4031,12 @@ class NoScaleContentLayer : public ContentLayer { return make_scoped_refptr(new NoScaleContentLayer(client)); } - virtual void CalculateContentsScale(float ideal_contents_scale, - float device_scale_factor, - float page_scale_factor, - float maximum_animation_contents_scale, - bool animating_transform_to_screen, - float* contents_scale_x, - float* contents_scale_y, - gfx::Size* content_bounds) OVERRIDE { + void CalculateContentsScale(float ideal_contents_scale, + float* contents_scale_x, + float* contents_scale_y, + gfx::Size* content_bounds) override { // Skip over the ContentLayer to the base Layer class. Layer::CalculateContentsScale(ideal_contents_scale, - device_scale_factor, - page_scale_factor, - maximum_animation_contents_scale, - animating_transform_to_screen, contents_scale_x, contents_scale_y, content_bounds); @@ -4070,7 +4045,7 @@ class NoScaleContentLayer : public ContentLayer { protected: explicit NoScaleContentLayer(ContentLayerClient* client) : ContentLayer(client) {} - virtual ~NoScaleContentLayer() {} + ~NoScaleContentLayer() override {} }; scoped_refptr<NoScaleContentLayer> CreateNoScaleDrawableContentLayer( @@ -4086,7 +4061,8 @@ TEST_F(LayerTreeHostCommonTest, LayerTransformsInHighDPI) { MockContentLayerClient delegate; gfx::Transform identity_matrix; - scoped_refptr<ContentLayer> parent = CreateDrawableContentLayer(&delegate); + scoped_refptr<FakePictureLayer> parent = + CreateDrawablePictureLayer(&delegate); SetLayerPropertiesForTesting(parent.get(), identity_matrix, gfx::Point3F(), @@ -4095,7 +4071,7 @@ TEST_F(LayerTreeHostCommonTest, LayerTransformsInHighDPI) { false, true); - scoped_refptr<ContentLayer> child = CreateDrawableContentLayer(&delegate); + scoped_refptr<FakePictureLayer> child = CreateDrawablePictureLayer(&delegate); SetLayerPropertiesForTesting(child.get(), identity_matrix, gfx::Point3F(), @@ -4104,8 +4080,8 @@ TEST_F(LayerTreeHostCommonTest, LayerTransformsInHighDPI) { false, true); - scoped_refptr<ContentLayer> child_empty = - CreateDrawableContentLayer(&delegate); + scoped_refptr<FakePictureLayer> child_empty = + CreateDrawablePictureLayer(&delegate); SetLayerPropertiesForTesting(child_empty.get(), identity_matrix, gfx::Point3F(), @@ -4114,21 +4090,10 @@ TEST_F(LayerTreeHostCommonTest, LayerTransformsInHighDPI) { false, true); - scoped_refptr<NoScaleContentLayer> child_no_scale = - CreateNoScaleDrawableContentLayer(&delegate); - SetLayerPropertiesForTesting(child_no_scale.get(), - identity_matrix, - gfx::Point3F(), - gfx::PointF(2.f, 2.f), - gfx::Size(10, 10), - false, - true); - parent->AddChild(child); parent->AddChild(child_empty); - parent->AddChild(child_no_scale); - scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); + scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost()); host->SetRootLayer(parent); float device_scale_factor = 2.5f; @@ -4142,16 +4107,16 @@ TEST_F(LayerTreeHostCommonTest, LayerTransformsInHighDPI) { inputs.can_adjust_raster_scales = true; LayerTreeHostCommon::CalculateDrawProperties(&inputs); - EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor, parent); - EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor, child); - EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor, - child_empty); - EXPECT_CONTENTS_SCALE_EQ(1, child_no_scale); + EXPECT_IDEAL_SCALE_EQ(device_scale_factor * page_scale_factor, parent); + EXPECT_IDEAL_SCALE_EQ(device_scale_factor * page_scale_factor, child); + EXPECT_IDEAL_SCALE_EQ(device_scale_factor * page_scale_factor, child_empty); EXPECT_EQ(1u, render_surface_layer_list.size()); // Verify parent transforms gfx::Transform expected_parent_transform; + expected_parent_transform.Scale(device_scale_factor * page_scale_factor, + device_scale_factor * page_scale_factor); EXPECT_TRANSFORMATION_MATRIX_EQ(expected_parent_transform, parent->screen_space_transform()); EXPECT_TRANSFORMATION_MATRIX_EQ(expected_parent_transform, @@ -4172,9 +4137,9 @@ TEST_F(LayerTreeHostCommonTest, LayerTransformsInHighDPI) { // Verify child and child_empty transforms. They should match. gfx::Transform expected_child_transform; - expected_child_transform.Translate( - device_scale_factor * child->position().x(), - device_scale_factor * child->position().y()); + expected_child_transform.Scale(device_scale_factor, device_scale_factor); + expected_child_transform.Translate(child->position().x(), + child->position().y()); EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform, child->draw_transform()); EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform, @@ -4204,17 +4169,6 @@ TEST_F(LayerTreeHostCommonTest, LayerTransformsInHighDPI) { EXPECT_FLOAT_RECT_EQ(expected_child_draw_rect, child_screen_space_rect); EXPECT_FLOAT_RECT_EQ(expected_child_draw_rect, child_empty_draw_rect); EXPECT_FLOAT_RECT_EQ(expected_child_draw_rect, child_empty_screen_space_rect); - - // Verify child_no_scale transforms - gfx::Transform expected_child_no_scale_transform = child->draw_transform(); - // All transforms operate on content rects. The child's content rect - // incorporates device scale, but the child_no_scale does not; add it here. - expected_child_no_scale_transform.Scale(device_scale_factor, - device_scale_factor); - EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_no_scale_transform, - child_no_scale->draw_transform()); - EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_no_scale_transform, - child_no_scale->screen_space_transform()); } TEST_F(LayerTreeHostCommonTest, SurfaceLayerTransformsInHighDPI) { @@ -4230,7 +4184,8 @@ TEST_F(LayerTreeHostCommonTest, SurfaceLayerTransformsInHighDPI) { scoped_refptr<Layer> root = Layer::Create(); - scoped_refptr<ContentLayer> parent = CreateDrawableContentLayer(&delegate); + scoped_refptr<FakePictureLayer> parent = + CreateDrawablePictureLayer(&delegate); SetLayerPropertiesForTesting(parent.get(), identity_matrix, gfx::Point3F(), @@ -4239,8 +4194,8 @@ TEST_F(LayerTreeHostCommonTest, SurfaceLayerTransformsInHighDPI) { false, true); - scoped_refptr<ContentLayer> perspective_surface = - CreateDrawableContentLayer(&delegate); + scoped_refptr<FakePictureLayer> perspective_surface = + CreateDrawablePictureLayer(&delegate); SetLayerPropertiesForTesting(perspective_surface.get(), perspective_matrix * scale_small_matrix, gfx::Point3F(), @@ -4249,8 +4204,8 @@ TEST_F(LayerTreeHostCommonTest, SurfaceLayerTransformsInHighDPI) { false, true); - scoped_refptr<ContentLayer> scale_surface = - CreateDrawableContentLayer(&delegate); + scoped_refptr<FakePictureLayer> scale_surface = + CreateDrawablePictureLayer(&delegate); SetLayerPropertiesForTesting(scale_surface.get(), scale_small_matrix, gfx::Point3F(), @@ -4266,7 +4221,7 @@ TEST_F(LayerTreeHostCommonTest, SurfaceLayerTransformsInHighDPI) { parent->AddChild(scale_surface); root->AddChild(parent); - scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); + scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost()); host->SetRootLayer(root); float device_scale_factor = 2.5f; @@ -4277,36 +4232,41 @@ TEST_F(LayerTreeHostCommonTest, SurfaceLayerTransformsInHighDPI) { root.get(), parent->bounds(), &render_surface_layer_list); inputs.device_scale_factor = device_scale_factor; inputs.page_scale_factor = page_scale_factor; - inputs.page_scale_application_layer = root; + inputs.page_scale_application_layer = root.get(); inputs.can_adjust_raster_scales = true; LayerTreeHostCommon::CalculateDrawProperties(&inputs); - EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor, parent); - EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor, - perspective_surface); - EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor, - scale_surface); + EXPECT_IDEAL_SCALE_EQ(device_scale_factor * page_scale_factor, parent); + EXPECT_IDEAL_SCALE_EQ(device_scale_factor * page_scale_factor, + perspective_surface); + // Ideal scale is the max 2d scale component of the combined transform up to + // the nearest render target. Here this includes the layer transform as well + // as the device and page scale factors. + gfx::Transform transform = scale_small_matrix; + transform.Scale(device_scale_factor * page_scale_factor, + device_scale_factor * page_scale_factor); + gfx::Vector2dF scales = + MathUtil::ComputeTransform2dScaleComponents(transform, 0.f); + float max_2d_scale = std::max(scales.x(), scales.y()); + EXPECT_IDEAL_SCALE_EQ(max_2d_scale, scale_surface); + + // The ideal scale will draw 1:1 with its render target space along + // the larger-scale axis. + gfx::Vector2dF target_space_transform_scales = + MathUtil::ComputeTransform2dScaleComponents( + scale_surface->draw_properties().target_space_transform, 0.f); + EXPECT_FLOAT_EQ(max_2d_scale, + std::max(target_space_transform_scales.x(), + target_space_transform_scales.y())); EXPECT_EQ(3u, render_surface_layer_list.size()); gfx::Transform expected_parent_draw_transform; + expected_parent_draw_transform.Scale(device_scale_factor * page_scale_factor, + device_scale_factor * page_scale_factor); EXPECT_TRANSFORMATION_MATRIX_EQ(expected_parent_draw_transform, parent->draw_transform()); - // The scaled surface is rendered at its appropriate scale, and drawn 1:1 - // into its target. - gfx::Transform expected_scale_surface_draw_transform; - expected_scale_surface_draw_transform.Translate( - device_scale_factor * page_scale_factor * scale_surface->position().x(), - device_scale_factor * page_scale_factor * scale_surface->position().y()); - EXPECT_TRANSFORMATION_MATRIX_EQ( - expected_scale_surface_draw_transform, - scale_surface->render_surface()->draw_transform()); - gfx::Transform expected_scale_surface_layer_draw_transform = - scale_small_matrix; - EXPECT_TRANSFORMATION_MATRIX_EQ(expected_scale_surface_layer_draw_transform, - scale_surface->draw_transform()); - // The scale for the perspective surface is not known, so it is rendered 1:1 // with the screen, and then scaled during drawing. gfx::Transform expected_perspective_surface_draw_transform; @@ -4320,6 +4280,9 @@ TEST_F(LayerTreeHostCommonTest, SurfaceLayerTransformsInHighDPI) { expected_perspective_surface_draw_transform.PreconcatTransform( scale_small_matrix); gfx::Transform expected_perspective_surface_layer_draw_transform; + expected_perspective_surface_layer_draw_transform.Scale( + device_scale_factor * page_scale_factor, + device_scale_factor * page_scale_factor); EXPECT_TRANSFORMATION_MATRIX_EQ( expected_perspective_surface_draw_transform, perspective_surface->render_surface()->draw_transform()); @@ -4328,6 +4291,7 @@ TEST_F(LayerTreeHostCommonTest, SurfaceLayerTransformsInHighDPI) { perspective_surface->draw_transform()); } +// TODO(sohanjg): Remove this test when ContentLayer is removed. TEST_F(LayerTreeHostCommonTest, LayerTransformsInHighDPIAccurateScaleZeroChildPosition) { // Verify draw and screen space transforms of layers not in a surface. @@ -4365,7 +4329,7 @@ TEST_F(LayerTreeHostCommonTest, parent->AddChild(child); parent->AddChild(child_no_scale); - scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); + scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost()); host->SetRootLayer(parent); float device_scale_factor = 1.7f; @@ -4443,6 +4407,7 @@ TEST_F(LayerTreeHostCommonTest, child_no_scale->screen_space_transform()); } +// TODO(sohanjg): Remove this test when ContentLayer is removed. TEST_F(LayerTreeHostCommonTest, ContentsScale) { MockContentLayerClient delegate; gfx::Transform identity_matrix; @@ -4503,7 +4468,7 @@ TEST_F(LayerTreeHostCommonTest, ContentsScale) { parent->AddChild(child_empty); parent->AddChild(child_no_scale); - scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); + scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost()); host->SetRootLayer(root); float device_scale_factor = 2.5f; @@ -4626,8 +4591,9 @@ TEST_F(LayerTreeHostCommonTest, ContentsScale) { } } +// TODO(sohanjg): Remove this test when ContentLayer is removed. TEST_F(LayerTreeHostCommonTest, - ContentsScale_LayerTransformsDontAffectContentsScale) { + ContentsScale_LayerTransformsDontAffectContentsScale) { MockContentLayerClient delegate; gfx::Transform identity_matrix; @@ -4687,7 +4653,7 @@ TEST_F(LayerTreeHostCommonTest, parent->AddChild(child_empty); parent->AddChild(child_no_scale); - scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); + scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost()); host->SetRootLayer(root); RenderSurfaceLayerList render_surface_layer_list; @@ -4731,7 +4697,7 @@ TEST_F(LayerTreeHostCommonTest, child_no_scale->draw_transform().matrix().get(1, 1)); } -TEST_F(LayerTreeHostCommonTest, SmallContentsScale) { +TEST_F(LayerTreeHostCommonTest, SmallIdealScale) { MockContentLayerClient delegate; gfx::Transform identity_matrix; @@ -4746,7 +4712,8 @@ TEST_F(LayerTreeHostCommonTest, SmallContentsScale) { scoped_refptr<Layer> root = Layer::Create(); root->SetBounds(gfx::Size(100, 100)); - scoped_refptr<ContentLayer> parent = CreateDrawableContentLayer(&delegate); + scoped_refptr<FakePictureLayer> parent = + CreateDrawablePictureLayer(&delegate); SetLayerPropertiesForTesting(parent.get(), parent_scale_matrix, gfx::Point3F(), @@ -4755,8 +4722,8 @@ TEST_F(LayerTreeHostCommonTest, SmallContentsScale) { false, true); - scoped_refptr<ContentLayer> child_scale = - CreateDrawableContentLayer(&delegate); + scoped_refptr<FakePictureLayer> child_scale = + CreateDrawablePictureLayer(&delegate); SetLayerPropertiesForTesting(child_scale.get(), child_scale_matrix, gfx::Point3F(), @@ -4769,7 +4736,7 @@ TEST_F(LayerTreeHostCommonTest, SmallContentsScale) { parent->AddChild(child_scale); - scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); + scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost()); host->SetRootLayer(root); float device_scale_factor = 2.5f; @@ -4785,38 +4752,16 @@ TEST_F(LayerTreeHostCommonTest, SmallContentsScale) { inputs.can_adjust_raster_scales = true; LayerTreeHostCommon::CalculateDrawProperties(&inputs); - EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor * - initial_parent_scale, - parent); - // The child's scale is < 1, so we should not save and use that scale - // factor. - EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor * 1, - child_scale); - } - - // When chilld's total scale becomes >= 1, we should save and use that scale - // factor. - child_scale_matrix.MakeIdentity(); - SkMScalar final_child_scale = 0.75; - child_scale_matrix.Scale(final_child_scale, final_child_scale); - child_scale->SetTransform(child_scale_matrix); - - { - RenderSurfaceLayerList render_surface_layer_list; - LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs( - root.get(), root->bounds(), &render_surface_layer_list); - inputs.device_scale_factor = device_scale_factor; - inputs.page_scale_factor = page_scale_factor; - inputs.page_scale_application_layer = root.get(); - inputs.can_adjust_raster_scales = true; - LayerTreeHostCommon::CalculateDrawProperties(&inputs); + // The ideal scale is able to go below 1. + float expected_ideal_scale = + device_scale_factor * page_scale_factor * initial_parent_scale; + EXPECT_LT(expected_ideal_scale, 1.f); + EXPECT_IDEAL_SCALE_EQ(expected_ideal_scale, parent); - EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor * - initial_parent_scale, - parent); - EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor * - initial_parent_scale * final_child_scale, - child_scale); + expected_ideal_scale = device_scale_factor * page_scale_factor * + initial_parent_scale * initial_child_scale; + EXPECT_LT(expected_ideal_scale, 1.f); + EXPECT_IDEAL_SCALE_EQ(expected_ideal_scale, child_scale); } } @@ -4917,7 +4862,7 @@ TEST_F(LayerTreeHostCommonTest, ContentsScaleForSurfaces) { surface_no_scale->AddChild(surface_no_scale_child_scale); surface_no_scale->AddChild(surface_no_scale_child_no_scale); - scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); + scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost()); host->SetRootLayer(root); SkMScalar device_scale_factor = 5; @@ -5020,8 +4965,9 @@ TEST_F(LayerTreeHostCommonTest, ContentsScaleForSurfaces) { surface_no_scale_child_no_scale->draw_transform().matrix().get(1, 1)); } +// TODO(sohanjg): Remove this test when ContentLayer is removed. TEST_F(LayerTreeHostCommonTest, - ContentsScaleForSurfaces_LayerTransformsDontAffectContentsScale) { + ContentsScaleForSurfaces_LayerTransformsDontAffectContentsScale) { MockContentLayerClient delegate; gfx::Transform identity_matrix; @@ -5118,7 +5064,7 @@ TEST_F(LayerTreeHostCommonTest, surface_no_scale->AddChild(surface_no_scale_child_scale); surface_no_scale->AddChild(surface_no_scale_child_no_scale); - scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); + scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost()); host->SetRootLayer(root); RenderSurfaceLayerList render_surface_layer_list; @@ -5223,7 +5169,7 @@ TEST_F(LayerTreeHostCommonTest, surface_no_scale_child_no_scale->draw_transform().matrix().get(1, 1)); } -TEST_F(LayerTreeHostCommonTest, ContentsScaleForAnimatingLayer) { +TEST_F(LayerTreeHostCommonTest, IdealScaleForAnimatingLayer) { MockContentLayerClient delegate; gfx::Transform identity_matrix; @@ -5238,7 +5184,8 @@ TEST_F(LayerTreeHostCommonTest, ContentsScaleForAnimatingLayer) { scoped_refptr<Layer> root = Layer::Create(); root->SetBounds(gfx::Size(100, 100)); - scoped_refptr<ContentLayer> parent = CreateDrawableContentLayer(&delegate); + scoped_refptr<FakePictureLayer> parent = + CreateDrawablePictureLayer(&delegate); SetLayerPropertiesForTesting(parent.get(), parent_scale_matrix, gfx::Point3F(), @@ -5247,8 +5194,8 @@ TEST_F(LayerTreeHostCommonTest, ContentsScaleForAnimatingLayer) { false, true); - scoped_refptr<ContentLayer> child_scale = - CreateDrawableContentLayer(&delegate); + scoped_refptr<FakePictureLayer> child_scale = + CreateDrawablePictureLayer(&delegate); SetLayerPropertiesForTesting(child_scale.get(), child_scale_matrix, gfx::Point3F(), @@ -5261,29 +5208,9 @@ TEST_F(LayerTreeHostCommonTest, ContentsScaleForAnimatingLayer) { parent->AddChild(child_scale); - scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); + scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost()); host->SetRootLayer(root); - // Now put an animating transform on child. - int animation_id = AddAnimatedTransformToController( - child_scale->layer_animation_controller(), 10.0, 30, 0); - - { - RenderSurfaceLayerList render_surface_layer_list; - LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs( - root.get(), root->bounds(), &render_surface_layer_list); - inputs.can_adjust_raster_scales = true; - LayerTreeHostCommon::CalculateDrawProperties(&inputs); - - EXPECT_CONTENTS_SCALE_EQ(initial_parent_scale, parent); - // The layers with animating transforms should not compute a contents scale - // other than 1 until they finish animating. - EXPECT_CONTENTS_SCALE_EQ(1, child_scale); - } - - // Remove the animation, now it can save a raster scale. - child_scale->layer_animation_controller()->RemoveAnimation(animation_id); - { RenderSurfaceLayerList render_surface_layer_list; LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs( @@ -5291,14 +5218,15 @@ TEST_F(LayerTreeHostCommonTest, ContentsScaleForAnimatingLayer) { inputs.can_adjust_raster_scales = true; LayerTreeHostCommon::CalculateDrawProperties(&inputs); - EXPECT_CONTENTS_SCALE_EQ(initial_parent_scale, parent); - // The layers with animating transforms should not compute a contents scale - // other than 1 until they finish animating. - EXPECT_CONTENTS_SCALE_EQ(initial_parent_scale * initial_child_scale, - child_scale); + EXPECT_IDEAL_SCALE_EQ(initial_parent_scale, parent); + // Animating layers compute ideal scale in the same way as when + // they are static. + EXPECT_IDEAL_SCALE_EQ(initial_child_scale * initial_parent_scale, + child_scale); } } +// TODO(sohanjg): Remove this test when ContentLayer is removed. TEST_F(LayerTreeHostCommonTest, ChangeInContentBoundsOrScaleTriggersPushProperties) { MockContentLayerClient delegate; @@ -5306,7 +5234,7 @@ TEST_F(LayerTreeHostCommonTest, scoped_refptr<Layer> child = CreateDrawableContentLayer(&delegate); root->AddChild(child); - scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); + scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost()); host->SetRootLayer(root); gfx::Transform identity_matrix; @@ -5355,7 +5283,8 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceTransformsInHighDPI) { MockContentLayerClient delegate; gfx::Transform identity_matrix; - scoped_refptr<ContentLayer> parent = CreateDrawableContentLayer(&delegate); + scoped_refptr<FakePictureLayer> parent = + CreateDrawablePictureLayer(&delegate); SetLayerPropertiesForTesting(parent.get(), identity_matrix, gfx::Point3F(), @@ -5364,7 +5293,7 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceTransformsInHighDPI) { false, true); - scoped_refptr<ContentLayer> child = CreateDrawableContentLayer(&delegate); + scoped_refptr<FakePictureLayer> child = CreateDrawablePictureLayer(&delegate); SetLayerPropertiesForTesting(child.get(), identity_matrix, gfx::Point3F(), @@ -5375,7 +5304,8 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceTransformsInHighDPI) { gfx::Transform replica_transform; replica_transform.Scale(1.0, -1.0); - scoped_refptr<ContentLayer> replica = CreateDrawableContentLayer(&delegate); + scoped_refptr<FakePictureLayer> replica = + CreateDrawablePictureLayer(&delegate); SetLayerPropertiesForTesting(replica.get(), replica_transform, gfx::Point3F(), @@ -5386,8 +5316,8 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceTransformsInHighDPI) { // This layer should end up in the same surface as child, with the same draw // and screen space transforms. - scoped_refptr<ContentLayer> duplicate_child_non_owner = - CreateDrawableContentLayer(&delegate); + scoped_refptr<FakePictureLayer> duplicate_child_non_owner = + CreateDrawablePictureLayer(&delegate); SetLayerPropertiesForTesting(duplicate_child_non_owner.get(), identity_matrix, gfx::Point3F(), @@ -5400,7 +5330,7 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceTransformsInHighDPI) { child->AddChild(duplicate_child_non_owner); child->SetReplicaLayer(replica.get()); - scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); + scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost()); host->SetRootLayer(parent); RenderSurfaceLayerList render_surface_layer_list; @@ -5417,19 +5347,22 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceTransformsInHighDPI) { EXPECT_EQ(2u, render_surface_layer_list.size()); gfx::Transform expected_parent_transform; + expected_parent_transform.Scale(device_scale_factor, device_scale_factor); EXPECT_TRANSFORMATION_MATRIX_EQ(expected_parent_transform, parent->screen_space_transform()); EXPECT_TRANSFORMATION_MATRIX_EQ(expected_parent_transform, parent->draw_transform()); gfx::Transform expected_draw_transform; + expected_draw_transform.Scale(device_scale_factor, device_scale_factor); EXPECT_TRANSFORMATION_MATRIX_EQ(expected_draw_transform, child->draw_transform()); gfx::Transform expected_screen_space_transform; - expected_screen_space_transform.Translate( - device_scale_factor * child->position().x(), - device_scale_factor * child->position().y()); + expected_screen_space_transform.Scale(device_scale_factor, + device_scale_factor); + expected_screen_space_transform.Translate(child->position().x(), + child->position().y()); EXPECT_TRANSFORMATION_MATRIX_EQ(expected_screen_space_transform, child->screen_space_transform()); @@ -5490,7 +5423,8 @@ TEST_F(LayerTreeHostCommonTest, MockContentLayerClient delegate; gfx::Transform identity_matrix; - scoped_refptr<ContentLayer> parent = CreateDrawableContentLayer(&delegate); + scoped_refptr<FakePictureLayer> parent = + CreateDrawablePictureLayer(&delegate); SetLayerPropertiesForTesting(parent.get(), identity_matrix, gfx::Point3F(), @@ -5499,7 +5433,7 @@ TEST_F(LayerTreeHostCommonTest, false, true); - scoped_refptr<ContentLayer> child = CreateDrawableContentLayer(&delegate); + scoped_refptr<FakePictureLayer> child = CreateDrawablePictureLayer(&delegate); SetLayerPropertiesForTesting(child.get(), identity_matrix, gfx::Point3F(), @@ -5510,7 +5444,8 @@ TEST_F(LayerTreeHostCommonTest, gfx::Transform replica_transform; replica_transform.Scale(1.0, -1.0); - scoped_refptr<ContentLayer> replica = CreateDrawableContentLayer(&delegate); + scoped_refptr<FakePictureLayer> replica = + CreateDrawablePictureLayer(&delegate); SetLayerPropertiesForTesting(replica.get(), replica_transform, gfx::Point3F(), @@ -5519,23 +5454,10 @@ TEST_F(LayerTreeHostCommonTest, false, true); - // This layer should end up in the same surface as child, with the same draw - // and screen space transforms. - scoped_refptr<ContentLayer> duplicate_child_non_owner = - CreateDrawableContentLayer(&delegate); - SetLayerPropertiesForTesting(duplicate_child_non_owner.get(), - identity_matrix, - gfx::Point3F(), - gfx::PointF(), - gfx::Size(13, 11), - false, - true); - parent->AddChild(child); - child->AddChild(duplicate_child_non_owner); child->SetReplicaLayer(replica.get()); - scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); + scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost()); host->SetRootLayer(parent); float device_scale_factor = 1.7f; @@ -5552,22 +5474,6 @@ TEST_F(LayerTreeHostCommonTest, EXPECT_EQ(2u, render_surface_layer_list.size()); gfx::Transform identity_transform; - - EXPECT_TRANSFORMATION_MATRIX_EQ(identity_transform, - parent->screen_space_transform()); - EXPECT_TRANSFORMATION_MATRIX_EQ(identity_transform, parent->draw_transform()); - EXPECT_TRANSFORMATION_MATRIX_EQ(identity_transform, child->draw_transform()); - EXPECT_TRANSFORMATION_MATRIX_EQ(identity_transform, - child->screen_space_transform()); - EXPECT_TRANSFORMATION_MATRIX_EQ(identity_transform, - duplicate_child_non_owner->draw_transform()); - EXPECT_TRANSFORMATION_MATRIX_EQ( - identity_transform, duplicate_child_non_owner->screen_space_transform()); - EXPECT_RECT_EQ(child->drawable_content_rect(), - duplicate_child_non_owner->drawable_content_rect()); - EXPECT_EQ(child->content_bounds(), - duplicate_child_non_owner->content_bounds()); - EXPECT_TRANSFORMATION_MATRIX_EQ(identity_transform, child->render_surface()->draw_transform()); EXPECT_TRANSFORMATION_MATRIX_EQ(identity_transform, @@ -5600,22 +5506,22 @@ TEST_F(LayerTreeHostCommonTest, SubtreeSearch) { child->SetMaskLayer(mask_layer.get()); root->AddChild(child.get()); - scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); + scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost()); host->SetRootLayer(root); int nonexistent_id = -1; - EXPECT_EQ(root, + EXPECT_EQ(root.get(), LayerTreeHostCommon::FindLayerInSubtree(root.get(), root->id())); - EXPECT_EQ(child, + EXPECT_EQ(child.get(), LayerTreeHostCommon::FindLayerInSubtree(root.get(), child->id())); EXPECT_EQ( - grand_child, + grand_child.get(), LayerTreeHostCommon::FindLayerInSubtree(root.get(), grand_child->id())); EXPECT_EQ( - mask_layer, + mask_layer.get(), LayerTreeHostCommon::FindLayerInSubtree(root.get(), mask_layer->id())); EXPECT_EQ( - replica_layer, + replica_layer.get(), LayerTreeHostCommon::FindLayerInSubtree(root.get(), replica_layer->id())); EXPECT_EQ( 0, LayerTreeHostCommon::FindLayerInSubtree(root.get(), nonexistent_id)); @@ -5654,7 +5560,7 @@ TEST_F(LayerTreeHostCommonTest, TransparentChildRenderSurfaceCreation) { child->AddChild(grand_child); child->SetOpacity(0.5f); - scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); + scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost()); host->SetRootLayer(root); ExecuteCalculateDrawProperties(root.get()); @@ -5747,7 +5653,7 @@ class LCDTextTest child_->SetForceRenderSurface(std::tr1::get<1>(GetParam())); - host_ = FakeLayerTreeHost::Create(); + host_ = CreateFakeLayerTreeHost(); host_->SetRootLayer(root_); } @@ -5903,7 +5809,7 @@ TEST_F(LayerTreeHostCommonTest, SubtreeHidden_SingleLayer) { child->AddChild(grand_child); root->AddChild(child); - scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); + scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost()); host->SetRootLayer(root); RenderSurfaceLayerList render_surface_layer_list; @@ -6017,7 +5923,7 @@ TEST_F(LayerTreeHostCommonTest, SubtreeHidden_TwoLayers) { child->AddChild(grand_child); root->AddChild(child); - scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); + scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost()); host->SetRootLayer(root); RenderSurfaceLayerList render_surface_layer_list; @@ -6175,7 +6081,7 @@ TEST_F(LayerTreeHostCommonTest, SubtreeHiddenWithCopyRequest) { root->AddChild(copy_grand_parent); root->AddChild(copy_grand_parent_sibling_after); - scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); + scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost()); host->SetRootLayer(root); // Hide the copy_grand_parent and its subtree. But make a copy request in that @@ -6289,7 +6195,7 @@ TEST_F(LayerTreeHostCommonTest, ClippedOutCopyRequest) { copy_parent->AddChild(copy_layer); root->AddChild(copy_parent); - scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); + scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost()); host->SetRootLayer(root); copy_layer->RequestCopyOfOutput(CopyOutputRequest::CreateRequest( @@ -6353,7 +6259,7 @@ TEST_F(LayerTreeHostCommonTest, VisibleContentRectInsideSurface) { surface->AddChild(surface_child); root->AddChild(surface); - scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); + scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost()); host->SetRootLayer(root); RenderSurfaceLayerList render_surface_layer_list; @@ -6440,7 +6346,7 @@ TEST_F(LayerTreeHostCommonTest, TransformedClipParent) { true, false); - scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); + scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost()); host->SetRootLayer(root); ExecuteCalculateDrawProperties(root.get()); @@ -6551,7 +6457,7 @@ TEST_F(LayerTreeHostCommonTest, ClipParentWithInterveningRenderSurface) { true, false); - scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); + scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost()); host->SetRootLayer(root); ExecuteCalculateDrawProperties(root.get()); @@ -6628,7 +6534,7 @@ TEST_F(LayerTreeHostCommonTest, ClipParentScrolledInterveningLayer) { intervening->SetMasksToBounds(true); clip_parent->SetMasksToBounds(true); intervening->SetScrollClipLayerId(clip_parent->id()); - intervening->SetScrollOffset(gfx::Vector2d(3, 3)); + intervening->SetScrollOffset(gfx::ScrollOffset(3, 3)); render_surface1->SetForceRenderSurface(true); render_surface2->SetForceRenderSurface(true); @@ -6680,7 +6586,7 @@ TEST_F(LayerTreeHostCommonTest, ClipParentScrolledInterveningLayer) { true, false); - scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); + scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost()); host->SetRootLayer(root); ExecuteCalculateDrawProperties(root.get()); @@ -6789,7 +6695,7 @@ TEST_F(LayerTreeHostCommonTest, DescendantsOfClipChildren) { true, false); - scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); + scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost()); host->SetRootLayer(root); ExecuteCalculateDrawProperties(root.get()); @@ -6886,7 +6792,7 @@ TEST_F(LayerTreeHostCommonTest, render_surface1->SetForceRenderSurface(true); render_surface2->SetForceRenderSurface(true); - scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); + scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost()); host->SetRootLayer(root); ExecuteCalculateDrawProperties(root.get()); @@ -6985,6 +6891,7 @@ TEST_F(LayerTreeHostCommonTest, CanRenderToSeparateSurface) { { LayerImplList render_surface_layer_list; + FakeLayerTreeHostImpl::RecursiveUpdateNumChildren(root.get()); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( root.get(), root->bounds(), &render_surface_layer_list); inputs.can_render_to_separate_surface = true; @@ -7041,7 +6948,7 @@ TEST_F(LayerTreeHostCommonTest, DoNotIncludeBackfaceInvisibleSurfaces) { render_surface->SetDoubleSided(false); render_surface->SetForceRenderSurface(true); - scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); + scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost()); host->SetRootLayer(root); ExecuteCalculateDrawProperties(root.get()); @@ -7132,7 +7039,7 @@ TEST_F(LayerTreeHostCommonTest, ClippedByScrollParent) { true, false); - scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); + scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost()); host->SetRootLayer(root); ExecuteCalculateDrawProperties(root.get()); @@ -7181,7 +7088,7 @@ TEST_F(LayerTreeHostCommonTest, SingularTransformSubtreesDoNotDraw) { true); child->SetForceRenderSurface(true); - scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); + scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost()); host->SetRootLayer(root); ExecuteCalculateDrawProperties(root.get()); @@ -7273,7 +7180,7 @@ TEST_F(LayerTreeHostCommonTest, ClippedByOutOfOrderScrollParent) { true, false); - scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); + scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost()); host->SetRootLayer(root); ExecuteCalculateDrawProperties(root.get()); @@ -7386,7 +7293,7 @@ TEST_F(LayerTreeHostCommonTest, ClippedByOutOfOrderScrollGrandparent) { true, false); - scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); + scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost()); host->SetRootLayer(root); ExecuteCalculateDrawProperties(root.get()); @@ -7401,11 +7308,11 @@ TEST_F(LayerTreeHostCommonTest, ClippedByOutOfOrderScrollGrandparent) { // correct clip, the layer lists should be unaffected. EXPECT_EQ(3u, root->render_surface()->layer_list().size()); EXPECT_EQ(scroll_child.get(), - root->render_surface()->layer_list().at(0)); + root->render_surface()->layer_list().at(0).get()); EXPECT_EQ(scroll_parent.get(), - root->render_surface()->layer_list().at(1)); + root->render_surface()->layer_list().at(1).get()); EXPECT_EQ(scroll_grandparent.get(), - root->render_surface()->layer_list().at(2)); + root->render_surface()->layer_list().at(2).get()); } TEST_F(LayerTreeHostCommonTest, OutOfOrderClippingRequiresRSLLSorting) { @@ -7535,7 +7442,7 @@ TEST_F(LayerTreeHostCommonTest, OutOfOrderClippingRequiresRSLLSorting) { true, false); - scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); + scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost()); host->SetRootLayer(root); RenderSurfaceLayerList render_surface_layer_list; @@ -7599,7 +7506,7 @@ TEST_F(LayerTreeHostCommonTest, DoNotClobberSorting) { scroll_parent_clip->SetMasksToBounds(true); scroll_child->SetScrollParent(scroll_parent.get()); - scoped_ptr<std::set<LayerImpl*> > scroll_children(new std::set<LayerImpl*>); + scoped_ptr<std::set<LayerImpl*>> scroll_children(new std::set<LayerImpl*>); scroll_children->insert(scroll_child.get()); scroll_parent->SetScrollChildren(scroll_children.release()); @@ -7864,7 +7771,7 @@ class AnimationScaleFactorTrackingLayerImpl : public LayerImpl { new AnimationScaleFactorTrackingLayerImpl(tree_impl, id)); } - virtual ~AnimationScaleFactorTrackingLayerImpl() {} + ~AnimationScaleFactorTrackingLayerImpl() override {} private: explicit AnimationScaleFactorTrackingLayerImpl(LayerTreeImpl* tree_impl, @@ -7892,9 +7799,9 @@ TEST_F(LayerTreeHostCommonTest, MaximumAnimationScaleFactor) { AnimationScaleFactorTrackingLayerImpl* child_raw = child.get(); AnimationScaleFactorTrackingLayerImpl* grand_child_raw = grand_child.get(); - child->AddChild(grand_child.PassAs<LayerImpl>()); - parent->AddChild(child.PassAs<LayerImpl>()); - grand_parent->AddChild(parent.PassAs<LayerImpl>()); + child->AddChild(grand_child.Pass()); + parent->AddChild(child.Pass()); + grand_parent->AddChild(parent.Pass()); SetLayerPropertiesForTesting(grand_parent.get(), identity_matrix, @@ -8598,5 +8505,62 @@ TEST_F(LayerTreeHostCommonTest, DrawPropertyScales) { EXPECT_FLOAT_EQ(4.f, child2_layer->draw_properties().device_scale_factor); } +TEST_F(LayerTreeHostCommonTest, VisibleContentRectInChildRenderSurface) { + scoped_refptr<Layer> root = Layer::Create(); + SetLayerPropertiesForTesting(root.get(), + gfx::Transform(), + gfx::Point3F(), + gfx::PointF(), + gfx::Size(768 / 2, 3000), + true, + false); + root->SetIsDrawable(true); + + scoped_refptr<Layer> clip = Layer::Create(); + SetLayerPropertiesForTesting(clip.get(), + gfx::Transform(), + gfx::Point3F(), + gfx::PointF(), + gfx::Size(768 / 2, 10000), + true, + false); + clip->SetMasksToBounds(true); + + scoped_refptr<Layer> content = Layer::Create(); + SetLayerPropertiesForTesting(content.get(), + gfx::Transform(), + gfx::Point3F(), + gfx::PointF(), + gfx::Size(768 / 2, 10000), + true, + false); + content->SetIsDrawable(true); + content->SetForceRenderSurface(true); + + root->AddChild(clip); + clip->AddChild(content); + + FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D); + scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(&client); + host->SetRootLayer(root); + + gfx::Size device_viewport_size(768, 582); + RenderSurfaceLayerList render_surface_layer_list; + LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs( + host->root_layer(), device_viewport_size, &render_surface_layer_list); + inputs.device_scale_factor = 2.f; + inputs.page_scale_factor = 1.f; + inputs.page_scale_application_layer = NULL; + LayerTreeHostCommon::CalculateDrawProperties(&inputs); + + // Layers in the root render surface have their visible content rect clipped + // by the viewport. + EXPECT_EQ(gfx::Rect(768 / 2, 582 / 2), root->visible_content_rect()); + + // Layers drawing to a child render surface should still have their visible + // content rect clipped by the viewport. + EXPECT_EQ(gfx::Rect(768 / 2, 582 / 2), content->visible_content_rect()); +} + } // namespace } // namespace cc diff --git a/chromium/cc/trees/layer_tree_host_impl.cc b/chromium/cc/trees/layer_tree_host_impl.cc index e35187e34df..9bee07e1118 100644 --- a/chromium/cc/trees/layer_tree_host_impl.cc +++ b/chromium/cc/trees/layer_tree_host_impl.cc @@ -9,10 +9,13 @@ #include "base/basictypes.h" #include "base/containers/hash_tables.h" +#include "base/debug/trace_event_argument.h" #include "base/json/json_writer.h" #include "base/metrics/histogram.h" #include "base/stl_util.h" #include "base/strings/stringprintf.h" +#include "cc/animation/animation_id_provider.h" +#include "cc/animation/scroll_offset_animation_curve.h" #include "cc/animation/scrollbar_animation_controller.h" #include "cc/animation/timing_function.h" #include "cc/base/latency_info_swap_promise_monitor.h" @@ -32,7 +35,6 @@ #include "cc/layers/layer_impl.h" #include "cc/layers/layer_iterator.h" #include "cc/layers/painted_scrollbar_layer_impl.h" -#include "cc/layers/quad_sink.h" #include "cc/layers/render_surface_impl.h" #include "cc/layers/scrollbar_layer_impl_base.h" #include "cc/output/compositor_frame_metadata.h" @@ -44,17 +46,20 @@ #include "cc/quads/shared_quad_state.h" #include "cc/quads/solid_color_draw_quad.h" #include "cc/quads/texture_draw_quad.h" -#include "cc/resources/direct_raster_worker_pool.h" -#include "cc/resources/image_copy_raster_worker_pool.h" -#include "cc/resources/image_raster_worker_pool.h" +#include "cc/resources/bitmap_raster_worker_pool.h" +#include "cc/resources/eviction_tile_priority_queue.h" +#include "cc/resources/gpu_raster_worker_pool.h" #include "cc/resources/memory_history.h" +#include "cc/resources/one_copy_raster_worker_pool.h" #include "cc/resources/picture_layer_tiling.h" #include "cc/resources/pixel_buffer_raster_worker_pool.h" #include "cc/resources/prioritized_resource_manager.h" +#include "cc/resources/raster_tile_priority_queue.h" #include "cc/resources/raster_worker_pool.h" #include "cc/resources/resource_pool.h" #include "cc/resources/texture_mailbox_deleter.h" #include "cc/resources/ui_resource_bitmap.h" +#include "cc/resources/zero_copy_raster_worker_pool.h" #include "cc/scheduler/delay_based_time_source.h" #include "cc/trees/damage_tracker.h" #include "cc/trees/layer_tree_host.h" @@ -63,14 +68,53 @@ #include "cc/trees/occlusion_tracker.h" #include "cc/trees/single_thread_proxy.h" #include "cc/trees/tree_synchronizer.h" +#include "gpu/command_buffer/client/gles2_interface.h" #include "gpu/GLES2/gl2extchromium.h" #include "ui/gfx/frame_time.h" -#include "ui/gfx/size_conversions.h" -#include "ui/gfx/vector2d_conversions.h" +#include "ui/gfx/geometry/rect_conversions.h" +#include "ui/gfx/geometry/size_conversions.h" +#include "ui/gfx/geometry/vector2d_conversions.h" +namespace cc { namespace { -void DidVisibilityChange(cc::LayerTreeHostImpl* id, bool visible) { +// Small helper class that saves the current viewport location as the user sees +// it and resets to the same location. +class ViewportAnchor { + public: + ViewportAnchor(LayerImpl* inner_scroll, LayerImpl* outer_scroll) + : inner_(inner_scroll), + outer_(outer_scroll) { + viewport_in_content_coordinates_ = inner_->TotalScrollOffset(); + + if (outer_) + viewport_in_content_coordinates_ += outer_->TotalScrollOffset(); + } + + void ResetViewportToAnchoredPosition() { + DCHECK(outer_); + + inner_->ClampScrollToMaxScrollOffset(); + outer_->ClampScrollToMaxScrollOffset(); + + gfx::ScrollOffset viewport_location = inner_->TotalScrollOffset() + + outer_->TotalScrollOffset(); + + gfx::Vector2dF delta = + viewport_in_content_coordinates_.DeltaFrom(viewport_location); + + delta = outer_->ScrollBy(delta); + inner_->ScrollBy(delta); + } + + private: + LayerImpl* inner_; + LayerImpl* outer_; + gfx::ScrollOffset viewport_in_content_coordinates_; +}; + + +void DidVisibilityChange(LayerTreeHostImpl* id, bool visible) { if (visible) { TRACE_EVENT_ASYNC_BEGIN1("webkit", "LayerTreeHostImpl::SetVisible", @@ -83,41 +127,51 @@ void DidVisibilityChange(cc::LayerTreeHostImpl* id, bool visible) { TRACE_EVENT_ASYNC_END0("webkit", "LayerTreeHostImpl::SetVisible", id); } -size_t GetMaxTransferBufferUsageBytes(cc::ContextProvider* context_provider) { - // Software compositing should not use this value in production. Just use a - // default value when testing uploads with the software compositor. - if (!context_provider) - return std::numeric_limits<size_t>::max(); - +size_t GetMaxTransferBufferUsageBytes( + const ContextProvider::Capabilities& context_capabilities, + double refresh_rate) { // We want to make sure the default transfer buffer size is equal to the // amount of data that can be uploaded by the compositor to avoid stalling // the pipeline. // For reference Chromebook Pixel can upload 1MB in about 0.5ms. const size_t kMaxBytesUploadedPerMs = 1024 * 1024 * 2; - // Assuming a two frame deep pipeline between CPU and GPU and we are - // drawing 60 frames per second which would require us to draw one - // frame in 16 milliseconds. - const size_t kMaxTransferBufferUsageBytes = 16 * 2 * kMaxBytesUploadedPerMs; - return std::min( - context_provider->ContextCapabilities().max_transfer_buffer_usage_bytes, - kMaxTransferBufferUsageBytes); -} - -unsigned GetMapImageTextureTarget(cc::ContextProvider* context_provider) { - if (!context_provider) - return GL_TEXTURE_2D; - if (context_provider->ContextCapabilities().gpu.egl_image_external) + // We need to upload at least enough work to keep the GPU process busy until + // the next time it can handle a request to start more uploads from the + // compositor. We assume that it will pick up any sent upload requests within + // the time of a vsync, since the browser will want to swap a frame within + // that time interval, and then uploads should have a chance to be processed. + size_t ms_per_frame = std::floor(1000.0 / refresh_rate); + size_t max_transfer_buffer_usage_bytes = + ms_per_frame * kMaxBytesUploadedPerMs; + + // The context may request a lower limit based on the device capabilities. + return std::min(context_capabilities.max_transfer_buffer_usage_bytes, + max_transfer_buffer_usage_bytes); +} + +unsigned GetMapImageTextureTarget( + const ContextProvider::Capabilities& context_capabilities) { +// TODO(reveman): This should be a setting passed to the compositor instead +// of hard-coded here. The target that need to be used depends on our choice +// of GpuMemoryBuffer type. Note: SURFACE_TEXTURE needs EXTERNAL_OES, +// IO_SURFACE needs RECTANGLE_ARB. crbug.com/431059 +#if defined(OS_ANDROID) + if (context_capabilities.gpu.egl_image_external) return GL_TEXTURE_EXTERNAL_OES; - if (context_provider->ContextCapabilities().gpu.texture_rectangle) +#endif + if (context_capabilities.gpu.texture_rectangle) return GL_TEXTURE_RECTANGLE_ARB; return GL_TEXTURE_2D; } -} // namespace +size_t GetMaxStagingResourceCount() { + // Upper bound for number of staging resource to allow. + return 32; +} -namespace cc { +} // namespace class LayerTreeHostImplTimeSourceAdapter : public TimeSourceClient { public: @@ -128,12 +182,12 @@ class LayerTreeHostImplTimeSourceAdapter : public TimeSourceClient { new LayerTreeHostImplTimeSourceAdapter(layer_tree_host_impl, time_source)); } - virtual ~LayerTreeHostImplTimeSourceAdapter() { + ~LayerTreeHostImplTimeSourceAdapter() override { time_source_->SetClient(NULL); time_source_->SetActive(false); } - virtual void OnTimerTick() OVERRIDE { + void OnTimerTick() override { // In single threaded mode we attempt to simulate changing the current // thread by maintaining a fake thread id. When we switch from one // thread to another, we construct DebugScopedSetXXXThread objects that @@ -155,7 +209,7 @@ class LayerTreeHostImplTimeSourceAdapter : public TimeSourceClient { } layer_tree_host_impl_->Animate( - layer_tree_host_impl_->CurrentFrameTimeTicks()); + layer_tree_host_impl_->CurrentBeginFrameArgs().frame_time); layer_tree_host_impl_->UpdateBackgroundAnimateTicking(true); bool start_ready_animations = true; layer_tree_host_impl_->UpdateAnimationState(start_ready_animations); @@ -165,7 +219,7 @@ class LayerTreeHostImplTimeSourceAdapter : public TimeSourceClient { layer_tree_host_impl_->ManageTiles(); } - layer_tree_host_impl_->ResetCurrentFrameTimeForNextFrame(); + layer_tree_host_impl_->ResetCurrentBeginFrameArgsForNextFrame(); } void SetActive(bool active) { @@ -200,10 +254,16 @@ scoped_ptr<LayerTreeHostImpl> LayerTreeHostImpl::Create( LayerTreeHostImplClient* client, Proxy* proxy, RenderingStatsInstrumentation* rendering_stats_instrumentation, - SharedBitmapManager* manager, + SharedBitmapManager* shared_bitmap_manager, + gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, int id) { - return make_scoped_ptr(new LayerTreeHostImpl( - settings, client, proxy, rendering_stats_instrumentation, manager, id)); + return make_scoped_ptr(new LayerTreeHostImpl(settings, + client, + proxy, + rendering_stats_instrumentation, + shared_bitmap_manager, + gpu_memory_buffer_manager, + id)); } LayerTreeHostImpl::LayerTreeHostImpl( @@ -211,12 +271,13 @@ LayerTreeHostImpl::LayerTreeHostImpl( LayerTreeHostImplClient* client, Proxy* proxy, RenderingStatsInstrumentation* rendering_stats_instrumentation, - SharedBitmapManager* manager, + SharedBitmapManager* shared_bitmap_manager, + gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, int id) - : client_(client), + : BeginFrameSourceMixIn(), + client_(client), proxy_(proxy), use_gpu_rasterization_(false), - on_demand_task_graph_runner_(NULL), input_handler_client_(NULL), did_lock_scrolling_layer_(false), should_bubble_scrolls_(false), @@ -244,38 +305,41 @@ LayerTreeHostImpl::LayerTreeHostImpl( zero_budget_(false), device_scale_factor_(1.f), overhang_ui_resource_id_(0), - overdraw_bottom_height_(0.f), - device_viewport_valid_for_tile_management_(true), + resourceless_software_draw_(false), begin_impl_frame_interval_(BeginFrameArgs::DefaultInterval()), animation_registrar_(AnimationRegistrar::Create()), rendering_stats_instrumentation_(rendering_stats_instrumentation), micro_benchmark_controller_(this), need_to_update_visible_tiles_before_draw_(false), -#if DCHECK_IS_ON - did_lose_called_(false), -#endif - shared_bitmap_manager_(manager), + shared_bitmap_manager_(shared_bitmap_manager), + gpu_memory_buffer_manager_(gpu_memory_buffer_manager), id_(id), - transfer_buffer_memory_limit_(0u) { + requires_high_res_to_draw_(false) { DCHECK(proxy_->IsImplThread()); DidVisibilityChange(this, visible_); + animation_registrar_->set_supports_scroll_animations( + proxy_->SupportsImplScrolling()); SetDebugState(settings.initial_debug_state); + // LTHI always has an active tree. + active_tree_ = LayerTreeImpl::create(this); + TRACE_EVENT_OBJECT_CREATED_WITH_ID( + TRACE_DISABLED_BY_DEFAULT("cc.debug"), "cc::LayerTreeHostImpl", id_); + if (settings.calculate_top_controls_position) { top_controls_manager_ = TopControlsManager::Create(this, settings.top_controls_height, settings.top_controls_show_threshold, settings.top_controls_hide_threshold); - } - SetDebugState(settings.initial_debug_state); - - // LTHI always has an active tree. - active_tree_ = LayerTreeImpl::create(this); - TRACE_EVENT_OBJECT_CREATED_WITH_ID( - TRACE_DISABLED_BY_DEFAULT("cc.debug"), "cc::LayerTreeHostImpl", id_); + // TODO(bokan): This is a quick fix. The browser should lock the top + // controls to shown on creation but this appears not to work. Tracked + // in crbug.com/417680. + // Initialize with top controls showing. + SetControlsTopOffset(0.f); + } } LayerTreeHostImpl::~LayerTreeHostImpl() { @@ -297,9 +361,9 @@ LayerTreeHostImpl::~LayerTreeHostImpl() { if (pending_tree_) pending_tree_->Shutdown(); active_tree_->Shutdown(); - recycle_tree_.reset(); - pending_tree_.reset(); - active_tree_.reset(); + recycle_tree_ = nullptr; + pending_tree_ = nullptr; + active_tree_ = nullptr; DestroyTileManager(); } @@ -316,36 +380,31 @@ void LayerTreeHostImpl::BeginMainFrameAborted(bool did_handle) { void LayerTreeHostImpl::BeginCommit() { TRACE_EVENT0("cc", "LayerTreeHostImpl::BeginCommit"); - if (settings_.impl_side_painting) + if (UsePendingTreeForSync()) CreatePendingTree(); } void LayerTreeHostImpl::CommitComplete() { TRACE_EVENT0("cc", "LayerTreeHostImpl::CommitComplete"); + if (pending_tree_) + pending_tree_->ApplyScrollDeltasSinceBeginMainFrame(); + sync_tree()->set_needs_update_draw_properties(); + if (settings_.impl_side_painting) { // Impl-side painting needs an update immediately post-commit to have the // opportunity to create tilings. Other paths can call UpdateDrawProperties // more lazily when needed prior to drawing. - pending_tree()->ApplyScrollDeltasSinceBeginMainFrame(); - pending_tree_->set_needs_update_draw_properties(); - pending_tree_->UpdateDrawProperties(); + sync_tree()->UpdateDrawProperties(); // Start working on newly created tiles immediately if needed. - if (!tile_manager_ || !tile_priorities_dirty_) - NotifyReadyToActivate(); - else + if (tile_manager_ && tile_priorities_dirty_) ManageTiles(); + else + NotifyReadyToActivate(); } else { // If we're not in impl-side painting, the tree is immediately considered // active. - active_tree_->ProcessUIResourceRequestQueue(); - active_tree_->DidBecomeActive(); - - ActivateAnimations(); - - active_tree_->set_needs_update_draw_properties(); - if (time_source_client_adapter_ && time_source_client_adapter_->Active()) - DCHECK(active_tree_->root_layer()); + ActivateSyncTree(); } micro_benchmark_controller_.DidCompleteCommit(); @@ -424,46 +483,6 @@ void LayerTreeHostImpl::ManageTiles() { client_->DidManageTiles(); } -void LayerTreeHostImpl::StartPageScaleAnimation( - const gfx::Vector2d& target_offset, - bool anchor_point, - float page_scale, - base::TimeDelta duration) { - if (!InnerViewportScrollLayer()) - return; - - gfx::Vector2dF scroll_total = active_tree_->TotalScrollOffset(); - gfx::SizeF scaled_scrollable_size = active_tree_->ScrollableSize(); - gfx::SizeF viewport_size = UnscaledScrollableViewportSize(); - - // Easing constants experimentally determined. - scoped_ptr<TimingFunction> timing_function = - CubicBezierTimingFunction::Create(.8, 0, .3, .9).PassAs<TimingFunction>(); - - page_scale_animation_ = - PageScaleAnimation::Create(scroll_total, - active_tree_->total_page_scale_factor(), - viewport_size, - scaled_scrollable_size, - timing_function.Pass()); - - if (anchor_point) { - gfx::Vector2dF anchor(target_offset); - page_scale_animation_->ZoomWithAnchor(anchor, - page_scale, - duration.InSecondsF()); - } else { - gfx::Vector2dF scaled_target_offset = target_offset; - page_scale_animation_->ZoomTo(scaled_target_offset, - page_scale, - duration.InSecondsF()); - } - - SetNeedsAnimate(); - client_->SetNeedsCommitOnImplThread(); - client_->RenewTreePriority(); -} - bool LayerTreeHostImpl::IsCurrentlyScrollingLayerAt( const gfx::Point& viewport_point, InputHandler::ScrollInputType type) { @@ -484,8 +503,6 @@ bool LayerTreeHostImpl::IsCurrentlyScrollingLayerAt( bool LayerTreeHostImpl::HaveTouchEventHandlersAt( const gfx::Point& viewport_point) { - if (!settings_.touch_hit_testing) - return true; gfx::PointF device_viewport_point = gfx::ScalePoint(viewport_point, device_scale_factor_); @@ -500,10 +517,15 @@ bool LayerTreeHostImpl::HaveTouchEventHandlersAt( scoped_ptr<SwapPromiseMonitor> LayerTreeHostImpl::CreateLatencyInfoSwapPromiseMonitor( ui::LatencyInfo* latency) { - return scoped_ptr<SwapPromiseMonitor>( + return make_scoped_ptr( new LatencyInfoSwapPromiseMonitor(latency, NULL, this)); } +void LayerTreeHostImpl::QueueSwapPromiseForMainThreadScrollUpdate( + scoped_ptr<SwapPromise> swap_promise) { + swap_promises_for_main_thread_scroll_update_.push_back(swap_promise.Pass()); +} + void LayerTreeHostImpl::TrackDamageForAllSurfaces( LayerImpl* root_draw_layer, const LayerImplList& render_surface_layer_list) { @@ -528,8 +550,8 @@ void LayerTreeHostImpl::TrackDamageForAllSurfaces( } } -scoped_ptr<base::Value> LayerTreeHostImpl::FrameData::AsValue() const { - scoped_ptr<base::DictionaryValue> value(new base::DictionaryValue()); +void LayerTreeHostImpl::FrameData::AsValueInto( + base::debug::TracedValue* value) const { value->SetBoolean("contains_incomplete_tile", contains_incomplete_tile); value->SetBoolean("has_no_damage", has_no_damage); @@ -539,12 +561,14 @@ scoped_ptr<base::Value> LayerTreeHostImpl::FrameData::AsValue() const { TRACE_EVENT_CATEGORY_GROUP_ENABLED( TRACE_DISABLED_BY_DEFAULT("cc.debug.quads"), &quads_enabled); if (quads_enabled) { - scoped_ptr<base::ListValue> render_pass_list(new base::ListValue()); - for (size_t i = 0; i < render_passes.size(); ++i) - render_pass_list->Append(render_passes[i]->AsValue().release()); - value->Set("render_passes", render_pass_list.release()); + value->BeginArray("render_passes"); + for (size_t i = 0; i < render_passes.size(); ++i) { + value->BeginDictionary(); + render_passes[i]->AsValueInto(value); + value->EndDictionary(); + } + value->EndArray(); } - return value.PassAs<base::Value>(); } void LayerTreeHostImpl::FrameData::AppendRenderPass( @@ -553,17 +577,17 @@ void LayerTreeHostImpl::FrameData::AppendRenderPass( render_passes.push_back(render_pass.Pass()); } -static DrawMode GetDrawMode(OutputSurface* output_surface) { - if (output_surface->ForcedDrawToSoftwareDevice()) { +DrawMode LayerTreeHostImpl::GetDrawMode() const { + if (resourceless_software_draw_) { return DRAW_MODE_RESOURCELESS_SOFTWARE; - } else if (output_surface->context_provider()) { + } else if (output_surface_->context_provider()) { return DRAW_MODE_HARDWARE; } else { - DCHECK_EQ(!output_surface->software_device(), - output_surface->capabilities().delegated_rendering && - !output_surface->capabilities().deferred_gl_initialization) - << output_surface->capabilities().delegated_rendering << " " - << output_surface->capabilities().deferred_gl_initialization; + DCHECK_EQ(!output_surface_->software_device(), + output_surface_->capabilities().delegated_rendering && + !output_surface_->capabilities().deferred_gl_initialization) + << output_surface_->capabilities().delegated_rendering << " " + << output_surface_->capabilities().deferred_gl_initialization; return DRAW_MODE_SOFTWARE; } } @@ -573,8 +597,10 @@ static void AppendQuadsForLayer( LayerImpl* layer, const OcclusionTracker<LayerImpl>& occlusion_tracker, AppendQuadsData* append_quads_data) { - QuadSink quad_culler(target_render_pass, &occlusion_tracker); - layer->AppendQuads(&quad_culler, append_quads_data); + layer->AppendQuads( + target_render_pass, + occlusion_tracker.GetCurrentOcclusionForLayer(layer->draw_transform()), + append_quads_data); } static void AppendQuadsForRenderSurfaceLayer( @@ -583,10 +609,9 @@ static void AppendQuadsForRenderSurfaceLayer( const RenderPass* contributing_render_pass, const OcclusionTracker<LayerImpl>& occlusion_tracker, AppendQuadsData* append_quads_data) { - QuadSink quad_culler(target_render_pass, &occlusion_tracker); - bool is_replica = false; - layer->render_surface()->AppendQuads(&quad_culler, + layer->render_surface()->AppendQuads(target_render_pass, + occlusion_tracker, append_quads_data, is_replica, contributing_render_pass->id); @@ -594,7 +619,8 @@ static void AppendQuadsForRenderSurfaceLayer( // Add replica after the surface so that it appears below the surface. if (layer->has_replica()) { is_replica = true; - layer->render_surface()->AppendQuads(&quad_culler, + layer->render_surface()->AppendQuads(target_render_pass, + occlusion_tracker, append_quads_data, is_replica, contributing_render_pass->id); @@ -626,8 +652,6 @@ static void AppendQuadsToFillScreen( screen_background_color_region.Intersect(root_scroll_layer_rect); } - QuadSink quad_culler(target_render_pass, &occlusion_tracker); - // Manually create the quad state for the gutter quads, as the root layer // doesn't have any bounds and so can't generate this itself. // TODO(danakj): Make the gutter quads generated by the solid color layer @@ -636,7 +660,8 @@ static void AppendQuadsToFillScreen( gfx::Rect root_target_rect = root_layer->render_surface()->content_rect(); float opacity = 1.f; int sorting_context_id = 0; - SharedQuadState* shared_quad_state = quad_culler.CreateSharedQuadState(); + SharedQuadState* shared_quad_state = + target_render_pass->CreateAndAppendSharedQuadState(); shared_quad_state->SetAll(gfx::Transform(), root_target_rect.size(), root_target_rect, @@ -653,13 +678,13 @@ static void AppendQuadsToFillScreen( gfx::Rect visible_screen_space_rect = screen_space_rect; // Skip the quad culler and just append the quads directly to avoid // occlusion checks. - scoped_ptr<SolidColorDrawQuad> quad = SolidColorDrawQuad::Create(); + SolidColorDrawQuad* quad = + target_render_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); quad->SetNew(shared_quad_state, screen_space_rect, visible_screen_space_rect, screen_background_color, false); - quad_culler.Append(quad.PassAs<DrawQuad>()); } for (Region::Iterator fill_rects(overhang_region); fill_rects.has_rect(); @@ -668,7 +693,8 @@ static void AppendQuadsToFillScreen( gfx::Rect screen_space_rect = fill_rects.rect(); gfx::Rect opaque_screen_space_rect = screen_space_rect; gfx::Rect visible_screen_space_rect = screen_space_rect; - scoped_ptr<TextureDrawQuad> tex_quad = TextureDrawQuad::Create(); + TextureDrawQuad* tex_quad = + target_render_pass->CreateAndAppendDrawQuad<TextureDrawQuad>(); const float vertex_opacity[4] = {1.f, 1.f, 1.f, 1.f}; tex_quad->SetNew( shared_quad_state, @@ -687,7 +713,6 @@ static void AppendQuadsToFillScreen( screen_background_color, vertex_opacity, false); - quad_culler.Append(tex_quad.PassAs<DrawQuad>()); } } @@ -784,7 +809,10 @@ DrawResult LayerTreeHostImpl::CalculateRenderPasses( int layers_drawn = 0; - const DrawMode draw_mode = GetDrawMode(output_surface_.get()); + const DrawMode draw_mode = GetDrawMode(); + + int num_missing_tiles = 0; + int num_incomplete_tiles = 0; LayerIteratorType end = LayerIteratorType::End(frame->render_surface_layer_list); @@ -792,8 +820,8 @@ DrawResult LayerTreeHostImpl::CalculateRenderPasses( LayerIteratorType::Begin(frame->render_surface_layer_list); it != end; ++it) { - RenderPass::Id target_render_pass_id = - it.target_render_surface_layer()->render_surface()->RenderPassId(); + RenderPassId target_render_pass_id = + it.target_render_surface_layer()->render_surface()->GetRenderPassId(); RenderPass* target_render_pass = frame->render_passes_by_id[target_render_pass_id]; @@ -809,8 +837,8 @@ DrawResult LayerTreeHostImpl::CalculateRenderPasses( } } else if (it.represents_contributing_render_surface() && it->render_surface()->contributes_to_drawn_surface()) { - RenderPass::Id contributing_render_pass_id = - it->render_surface()->RenderPassId(); + RenderPassId contributing_render_pass_id = + it->render_surface()->GetRenderPassId(); RenderPass* contributing_render_pass = frame->render_passes_by_id[contributing_render_pass_id]; AppendQuadsForRenderSurfaceLayer(target_render_pass, @@ -820,16 +848,16 @@ DrawResult LayerTreeHostImpl::CalculateRenderPasses( &append_quads_data); } else if (it.represents_itself() && !it->visible_content_rect().IsEmpty()) { - bool occluded = occlusion_tracker.Occluded(it->render_target(), - it->visible_content_rect(), - it->draw_transform()); + bool occluded = + occlusion_tracker.GetCurrentOcclusionForLayer(it->draw_transform()) + .IsOccluded(it->visible_content_rect()); if (!occluded && it->WillDraw(draw_mode, resource_provider_.get())) { DCHECK_EQ(active_tree_, it->layer_tree_impl()); frame->will_draw_layers.push_back(*it); if (it->HasContributingDelegatedRenderPasses()) { - RenderPass::Id contributing_render_pass_id = + RenderPassId contributing_render_pass_id = it->FirstContributingRenderPassId(); while (frame->render_passes_by_id.find(contributing_render_pass_id) != frame->render_passes_by_id.end()) { @@ -861,6 +889,9 @@ DrawResult LayerTreeHostImpl::CalculateRenderPasses( rendering_stats_instrumentation_->AddApproximatedVisibleContentArea( append_quads_data.approximated_visible_content_area); + num_missing_tiles += append_quads_data.num_missing_tiles; + num_incomplete_tiles += append_quads_data.num_incomplete_tiles; + if (append_quads_data.num_missing_tiles) { bool layer_has_animating_transform = it->screen_space_transform_is_animating() || @@ -869,9 +900,10 @@ DrawResult LayerTreeHostImpl::CalculateRenderPasses( draw_result = DRAW_ABORTED_CHECKERBOARD_ANIMATIONS; } - if (append_quads_data.had_incomplete_tile) { + if (append_quads_data.num_incomplete_tiles || + append_quads_data.num_missing_tiles) { frame->contains_incomplete_tile = true; - if (active_tree()->RequiresHighResToDraw()) + if (RequiresHighResToDraw()) draw_result = DRAW_ABORTED_MISSING_HIGH_RES_CONTENT; } @@ -883,11 +915,11 @@ DrawResult LayerTreeHostImpl::CalculateRenderPasses( draw_result = DRAW_SUCCESS; #if DCHECK_IS_ON - for (size_t i = 0; i < frame->render_passes.size(); ++i) { - for (size_t j = 0; j < frame->render_passes[i]->quad_list.size(); ++j) - DCHECK(frame->render_passes[i]->quad_list[j]->shared_quad_state); - DCHECK(frame->render_passes_by_id.find(frame->render_passes[i]->id) - != frame->render_passes_by_id.end()); + for (const auto& render_pass : frame->render_passes) { + for (const auto& quad : render_pass->quad_list) + DCHECK(quad->shared_quad_state); + DCHECK(frame->render_passes_by_id.find(render_pass->id) != + frame->render_passes_by_id.end()); } #endif DCHECK(frame->render_passes.back()->output_rect.origin().IsOrigin()); @@ -920,9 +952,19 @@ DrawResult LayerTreeHostImpl::CalculateRenderPasses( // If we're making a frame to draw, it better have at least one render pass. DCHECK(!frame->render_passes.empty()); + if (active_tree_->has_ever_been_drawn()) { + UMA_HISTOGRAM_COUNTS_100( + "Compositing.RenderPass.AppendQuadData.NumMissingTiles", + num_missing_tiles); + UMA_HISTOGRAM_COUNTS_100( + "Compositing.RenderPass.AppendQuadData.NumIncompleteTiles", + num_incomplete_tiles); + } + // Should only have one render pass in resourceless software mode. - if (output_surface_->ForcedDrawToSoftwareDevice()) - DCHECK_EQ(1u, frame->render_passes.size()); + DCHECK(draw_mode != DRAW_MODE_RESOURCELESS_SOFTWARE || + frame->render_passes.size() == 1u) + << frame->render_passes.size(); return draw_result; } @@ -964,14 +1006,14 @@ void LayerTreeHostImpl::SetViewportDamage(const gfx::Rect& damage_rect) { } static inline RenderPass* FindRenderPassById( - RenderPass::Id render_pass_id, + RenderPassId render_pass_id, const LayerTreeHostImpl::FrameData& frame) { RenderPassIdHashMap::const_iterator it = frame.render_passes_by_id.find(render_pass_id); return it != frame.render_passes_by_id.end() ? it->second : NULL; } -static void RemoveRenderPassesRecursive(RenderPass::Id remove_render_pass_id, +static void RemoveRenderPassesRecursive(RenderPassId remove_render_pass_id, LayerTreeHostImpl::FrameData* frame) { RenderPass* remove_render_pass = FindRenderPassById(remove_render_pass_id, *frame); @@ -993,15 +1035,14 @@ static void RemoveRenderPassesRecursive(RenderPass::Id remove_render_pass_id, // Now follow up for all RenderPass quads and remove their RenderPasses // recursively. const QuadList& quad_list = removed_pass->quad_list; - QuadList::ConstBackToFrontIterator quad_list_iterator = - quad_list.BackToFrontBegin(); - for (; quad_list_iterator != quad_list.BackToFrontEnd(); + for (auto quad_list_iterator = quad_list.BackToFrontBegin(); + quad_list_iterator != quad_list.BackToFrontEnd(); ++quad_list_iterator) { - DrawQuad* current_quad = (*quad_list_iterator); + const DrawQuad* current_quad = *quad_list_iterator; if (current_quad->material != DrawQuad::RENDER_PASS) continue; - RenderPass::Id next_remove_render_pass_id = + RenderPassId next_remove_render_pass_id = RenderPassDrawQuad::MaterialCast(current_quad)->render_pass_id; RemoveRenderPassesRecursive(next_remove_render_pass_id, frame); } @@ -1016,11 +1057,10 @@ bool LayerTreeHostImpl::CullRenderPassesWithNoQuads::ShouldRemoveRenderPass( // If any quad or RenderPass draws into this RenderPass, then keep it. const QuadList& quad_list = render_pass->quad_list; - for (QuadList::ConstBackToFrontIterator quad_list_iterator = - quad_list.BackToFrontBegin(); + for (auto quad_list_iterator = quad_list.BackToFrontBegin(); quad_list_iterator != quad_list.BackToFrontEnd(); ++quad_list_iterator) { - DrawQuad* current_quad = *quad_list_iterator; + const DrawQuad* current_quad = *quad_list_iterator; if (current_quad->material != DrawQuad::RENDER_PASS) return false; @@ -1047,12 +1087,11 @@ void LayerTreeHostImpl::RemoveRenderPasses(RenderPassCuller culler, it = culler.RenderPassListNext(it)) { const RenderPass* current_pass = frame->render_passes[it]; const QuadList& quad_list = current_pass->quad_list; - QuadList::ConstBackToFrontIterator quad_list_iterator = - quad_list.BackToFrontBegin(); - for (; quad_list_iterator != quad_list.BackToFrontEnd(); + for (auto quad_list_iterator = quad_list.BackToFrontBegin(); + quad_list_iterator != quad_list.BackToFrontEnd(); ++quad_list_iterator) { - DrawQuad* current_quad = *quad_list_iterator; + const DrawQuad* current_quad = *quad_list_iterator; if (current_quad->material != DrawQuad::RENDER_PASS) continue; @@ -1087,6 +1126,9 @@ DrawResult LayerTreeHostImpl::PrepareToDraw(FrameData* frame) { } need_to_update_visible_tiles_before_draw_ = true; + UMA_HISTOGRAM_CUSTOM_COUNTS( + "Compositing.NumActiveLayers", active_tree_->NumLayers(), 1, 400, 20); + bool ok = active_tree_->UpdateDrawProperties(); DCHECK(ok) << "UpdateDrawProperties failed during draw"; @@ -1138,10 +1180,10 @@ void LayerTreeHostImpl::ResetTreesForTesting() { active_tree_ = LayerTreeImpl::create(this); if (pending_tree_) pending_tree_->DetachLayerTree(); - pending_tree_.reset(); + pending_tree_ = nullptr; if (recycle_tree_) recycle_tree_->DetachLayerTree(); - recycle_tree_.reset(); + recycle_tree_ = nullptr; } void LayerTreeHostImpl::EnforceManagedMemoryPolicy( @@ -1196,7 +1238,7 @@ void LayerTreeHostImpl::UpdateTileManagerMemoryPolicy( 100); DCHECK(resource_pool_); - resource_pool_->CheckBusyResources(); + resource_pool_->CheckBusyResources(false); // Soft limit is used for resource pool such that memory returns to soft // limit after going over. resource_pool_->SetResourceUsageLimits( @@ -1204,14 +1246,13 @@ void LayerTreeHostImpl::UpdateTileManagerMemoryPolicy( unused_memory_limit_in_bytes, global_tile_state_.num_resources_limit); - // Staging pool resources are used as transfer buffers so we use - // |transfer_buffer_memory_limit_| as the memory limit for this resource pool. + // Release all staging resources when invisible. if (staging_resource_pool_) { - staging_resource_pool_->CheckBusyResources(); + staging_resource_pool_->CheckBusyResources(false); staging_resource_pool_->SetResourceUsageLimits( - visible_ ? transfer_buffer_memory_limit_ : 0, - transfer_buffer_memory_limit_, - std::numeric_limits<size_t>::max()); + std::numeric_limits<size_t>::max(), + std::numeric_limits<size_t>::max(), + visible_ ? GetMaxStagingResourceCount() : 0); } DidModifyTilePriorities(); @@ -1229,7 +1270,56 @@ void LayerTreeHostImpl::DidInitializeVisibleTile() { client_->DidInitializeVisibleTileOnImplThread(); } -const std::vector<PictureLayerImpl*>& LayerTreeHostImpl::GetPictureLayers() { +void LayerTreeHostImpl::GetPictureLayerImplPairs( + std::vector<PictureLayerImpl::Pair>* layer_pairs) const { + DCHECK(layer_pairs->empty()); + for (std::vector<PictureLayerImpl*>::const_iterator it = + picture_layers_.begin(); + it != picture_layers_.end(); + ++it) { + PictureLayerImpl* layer = *it; + + // TODO(vmpstr): Iterators and should handle this instead. crbug.com/381704 + if (!layer->HasValidTilePriorities()) + continue; + + PictureLayerImpl* twin_layer = layer->GetPendingOrActiveTwinLayer(); + + // Ignore the twin layer when tile priorities are invalid. + // TODO(vmpstr): Iterators should handle this instead. crbug.com/381704 + if (twin_layer && !twin_layer->HasValidTilePriorities()) + twin_layer = NULL; + + // If the current tree is ACTIVE_TREE, then always generate a layer_pair. + // If current tree is PENDING_TREE, then only generate a layer_pair if + // there is no twin layer. + if (layer->GetTree() == ACTIVE_TREE) { + DCHECK(!twin_layer || twin_layer->GetTree() == PENDING_TREE); + layer_pairs->push_back(PictureLayerImpl::Pair(layer, twin_layer)); + } else if (!twin_layer) { + layer_pairs->push_back(PictureLayerImpl::Pair(NULL, layer)); + } + } +} + +void LayerTreeHostImpl::BuildRasterQueue(RasterTilePriorityQueue* queue, + TreePriority tree_priority) { + TRACE_EVENT0("cc", "LayerTreeHostImpl::BuildRasterQueue"); + picture_layer_pairs_.clear(); + GetPictureLayerImplPairs(&picture_layer_pairs_); + queue->Build(picture_layer_pairs_, tree_priority); +} + +void LayerTreeHostImpl::BuildEvictionQueue(EvictionTilePriorityQueue* queue, + TreePriority tree_priority) { + TRACE_EVENT0("cc", "LayerTreeHostImpl::BuildEvictionQueue"); + picture_layer_pairs_.clear(); + GetPictureLayerImplPairs(&picture_layer_pairs_); + queue->Build(picture_layer_pairs_, tree_priority); +} + +const std::vector<PictureLayerImpl*>& LayerTreeHostImpl::GetPictureLayers() + const { return picture_layers_; } @@ -1311,15 +1401,33 @@ void LayerTreeHostImpl::SetExternalDrawConstraints( const gfx::Transform& transform, const gfx::Rect& viewport, const gfx::Rect& clip, - bool valid_for_tile_management) { - if (external_transform_ != transform || external_viewport_ != viewport) { + const gfx::Rect& viewport_rect_for_tile_priority, + const gfx::Transform& transform_for_tile_priority, + bool resourceless_software_draw) { + gfx::Rect viewport_rect_for_tile_priority_in_view_space; + if (!resourceless_software_draw) { + gfx::Transform screen_to_view(gfx::Transform::kSkipInitialization); + if (transform_for_tile_priority.GetInverse(&screen_to_view)) { + // Convert from screen space to view space. + viewport_rect_for_tile_priority_in_view_space = + gfx::ToEnclosingRect(MathUtil::ProjectClippedRect( + screen_to_view, viewport_rect_for_tile_priority)); + } + } + + if (external_transform_ != transform || external_viewport_ != viewport || + resourceless_software_draw_ != resourceless_software_draw || + viewport_rect_for_tile_priority_ != + viewport_rect_for_tile_priority_in_view_space) { active_tree_->set_needs_update_draw_properties(); } external_transform_ = transform; external_viewport_ = viewport; external_clip_ = clip; - device_viewport_valid_for_tile_management_ = valid_for_tile_management; + viewport_rect_for_tile_priority_ = + viewport_rect_for_tile_priority_in_view_space; + resourceless_software_draw_ = resourceless_software_draw; } void LayerTreeHostImpl::SetNeedsRedrawRect(const gfx::Rect& damage_rect) { @@ -1330,7 +1438,7 @@ void LayerTreeHostImpl::SetNeedsRedrawRect(const gfx::Rect& damage_rect) { } void LayerTreeHostImpl::BeginFrame(const BeginFrameArgs& args) { - client_->BeginFrame(args); + CallOnBeginFrame(args); } void LayerTreeHostImpl::DidSwapBuffers() { @@ -1352,14 +1460,15 @@ void LayerTreeHostImpl::ReclaimResources(const CompositorFrameAck* ack) { if (tile_manager_) { DCHECK(resource_pool_); - resource_pool_->CheckBusyResources(); + resource_pool_->CheckBusyResources(false); resource_pool_->ReduceResourceUsage(); } // If we're not visible, we likely released resources, so we want to // aggressively flush here to make sure those DeleteTextures make it to the // GPU process to free up the memory. - if (resource_provider_ && !visible_) - resource_provider_->ShallowFlushIfSupported(); + if (output_surface_->context_provider() && !visible_) { + output_surface_->context_provider()->ContextGL()->ShallowFlushCHROMIUM(); + } } void LayerTreeHostImpl::OnCanDrawStateChangedForTree() { @@ -1370,22 +1479,26 @@ CompositorFrameMetadata LayerTreeHostImpl::MakeCompositorFrameMetadata() const { CompositorFrameMetadata metadata; metadata.device_scale_factor = device_scale_factor_; metadata.page_scale_factor = active_tree_->total_page_scale_factor(); - metadata.viewport_size = active_tree_->ScrollableViewportSize(); + metadata.scrollable_viewport_size = active_tree_->ScrollableViewportSize(); metadata.root_layer_size = active_tree_->ScrollableSize(); metadata.min_page_scale_factor = active_tree_->min_page_scale_factor(); metadata.max_page_scale_factor = active_tree_->max_page_scale_factor(); if (top_controls_manager_) { metadata.location_bar_offset = - gfx::Vector2dF(0.f, top_controls_manager_->controls_top_offset()); + gfx::Vector2dF(0.f, top_controls_manager_->ControlsTopOffset()); metadata.location_bar_content_translation = - gfx::Vector2dF(0.f, top_controls_manager_->content_top_offset()); - metadata.overdraw_bottom_height = overdraw_bottom_height_; + gfx::Vector2dF(0.f, top_controls_manager_->ContentTopOffset()); } + active_tree_->GetViewportSelection(&metadata.selection_start, + &metadata.selection_end); + if (!InnerViewportScrollLayer()) return metadata; - metadata.root_scroll_offset = active_tree_->TotalScrollOffset(); + // TODO(miletus) : Change the metadata to hold ScrollOffset. + metadata.root_scroll_offset = gfx::ScrollOffsetToVector2dF( + active_tree_->TotalScrollOffset()); return metadata; } @@ -1410,9 +1523,7 @@ void LayerTreeHostImpl::DrawLayers(FrameData* frame, fps_counter_->SaveTimeStamp(frame_begin_time, !output_surface_->context_provider()); - bool on_main_thread = false; - rendering_stats_instrumentation_->IncrementFrameCount( - 1, on_main_thread); + rendering_stats_instrumentation_->IncrementFrameCount(1); if (tile_manager_) { memory_history_->SaveEntry( @@ -1448,26 +1559,31 @@ void LayerTreeHostImpl::DrawLayers(FrameData* frame, base::Bind(&LayerTreeHostImplDidBeginTracingCallback)); } - TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID( - TRACE_DISABLED_BY_DEFAULT("cc.debug") "," - TRACE_DISABLED_BY_DEFAULT("cc.debug.quads") "," - TRACE_DISABLED_BY_DEFAULT("devtools.timeline.layers"), - "cc::LayerTreeHostImpl", - id_, - TracedValue::FromValue(AsValueWithFrame(frame).release())); + { + TRACE_EVENT0("cc", "DrawLayers.FrameViewerTracing"); + TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID( + TRACE_DISABLED_BY_DEFAULT("cc.debug") "," + TRACE_DISABLED_BY_DEFAULT("cc.debug.quads") "," + TRACE_DISABLED_BY_DEFAULT("devtools.timeline.layers"), + "cc::LayerTreeHostImpl", + id_, + AsValueWithFrame(frame)); + } + + const DrawMode draw_mode = GetDrawMode(); // Because the contents of the HUD depend on everything else in the frame, the // contents of its texture are updated as the last thing before the frame is // drawn. if (active_tree_->hud_layer()) { TRACE_EVENT0("cc", "DrawLayers.UpdateHudTexture"); - active_tree_->hud_layer()->UpdateHudTexture( - GetDrawMode(output_surface_.get()), resource_provider_.get()); + active_tree_->hud_layer()->UpdateHudTexture(draw_mode, + resource_provider_.get()); } - if (output_surface_->ForcedDrawToSoftwareDevice()) { + if (draw_mode == DRAW_MODE_RESOURCELESS_SOFTWARE) { bool disable_picture_quad_image_filtering = - IsCurrentlyScrolling() || needs_animate_layers(); + IsActivelyScrolling() || needs_animate_layers(); scoped_ptr<SoftwareRenderer> temp_software_renderer = SoftwareRenderer::Create(this, &settings_, output_surface_.get(), NULL); @@ -1497,8 +1613,9 @@ void LayerTreeHostImpl::DrawLayers(FrameData* frame, } active_tree_->root_layer()->ResetAllChangeTrackingForSubtree(); + active_tree_->set_has_ever_been_drawn(true); devtools_instrumentation::DidDrawFrame(id_); - BenchmarkInstrumentation::IssueImplThreadRenderingStatsEvent( + benchmark_instrumentation::IssueImplThreadRenderingStatsEvent( rendering_stats_instrumentation_->impl_thread_rendering_stats()); rendering_stats_instrumentation_->AccumulateAndClearImplThreadStats(); } @@ -1517,11 +1634,6 @@ void LayerTreeHostImpl::FinishAllRendering() { renderer_->Finish(); } -bool LayerTreeHostImpl::IsContextLost() { - DCHECK(proxy_->IsImplThread()); - return renderer_ && renderer_->IsContextLost(); -} - void LayerTreeHostImpl::SetUseGpuRasterization(bool use_gpu) { if (use_gpu == use_gpu_rasterization_) return; @@ -1539,7 +1651,7 @@ void LayerTreeHostImpl::SetUseGpuRasterization(bool use_gpu) { // We have released tilings for both active and pending tree. // We would not have any content to draw until the pending tree is activated. // Prevent the active tree from drawing until activation. - active_tree_->SetRequiresHighResToDraw(); + SetRequiresHighResToDraw(); } const RendererCapabilitiesImpl& @@ -1548,7 +1660,7 @@ LayerTreeHostImpl::GetRendererCapabilities() const { } bool LayerTreeHostImpl::SwapBuffers(const LayerTreeHostImpl::FrameData& frame) { - active_tree()->ResetRequiresHighResToDraw(); + ResetRequiresHighResToDraw(); if (frame.has_no_damage) { active_tree()->BreakSwapPromises(SwapPromise::SWAP_FAILS); return false; @@ -1566,7 +1678,7 @@ bool LayerTreeHostImpl::SwapBuffers(const LayerTreeHostImpl::FrameData& frame) { return true; } -void LayerTreeHostImpl::SetNeedsBeginFrame(bool enable) { +void LayerTreeHostImpl::OnNeedsBeginFramesChange(bool enable) { if (output_surface_) output_surface_->SetNeedsBeginFrame(enable); else @@ -1576,64 +1688,67 @@ void LayerTreeHostImpl::SetNeedsBeginFrame(bool enable) { void LayerTreeHostImpl::WillBeginImplFrame(const BeginFrameArgs& args) { // Sample the frame time now. This time will be used for updating animations // when we draw. - UpdateCurrentFrameTime(); + UpdateCurrentBeginFrameArgs(args); // Cache the begin impl frame interval begin_impl_frame_interval_ = args.interval; } -gfx::SizeF LayerTreeHostImpl::ComputeInnerViewportContainerSize() const { - gfx::SizeF dip_size = - gfx::ScaleSize(device_viewport_size_, 1.f / device_scale_factor()); +void LayerTreeHostImpl::UpdateViewportContainerSizes() { + LayerImpl* inner_container = active_tree_->InnerViewportContainerLayer(); + LayerImpl* outer_container = active_tree_->OuterViewportContainerLayer(); + + if (!inner_container || !top_controls_manager_) + return; - float top_offset = - top_controls_manager_ ? top_controls_manager_->content_top_offset() : 0.f; + ViewportAnchor anchor(InnerViewportScrollLayer(), + OuterViewportScrollLayer()); - return gfx::SizeF(dip_size.width(), - dip_size.height() - top_offset - overdraw_bottom_height_); -} + // Adjust the inner viewport by shrinking/expanding the container to account + // for the change in top controls height since the last Resize from Blink. + inner_container->SetBoundsDelta( + gfx::Vector2dF(0, active_tree_->top_controls_layout_height() - + active_tree_->total_top_controls_content_offset())); -void LayerTreeHostImpl::UpdateInnerViewportContainerSize() { - LayerImpl* container_layer = active_tree_->InnerViewportContainerLayer(); - if (!container_layer) + if (!outer_container || outer_container->BoundsForScrolling().IsEmpty()) return; - // We pass the value returned from UnscaledScrollableViewportSize() here as - // it accounts for scrollbar dimensions when - // container_layer->masks_to_bounds() is set. - container_layer->SetTemporaryImplBounds(UnscaledScrollableViewportSize()); -} + // Adjust the outer viewport container as well, since adjusting only the + // inner may cause its bounds to exceed those of the outer, causing scroll + // clamping. We adjust it so it maintains the same aspect ratio as the + // inner viewport. + float aspect_ratio = inner_container->BoundsForScrolling().width() / + inner_container->BoundsForScrolling().height(); + float target_height = outer_container->BoundsForScrolling().width() / + aspect_ratio; + float current_outer_height = outer_container->BoundsForScrolling().height() - + outer_container->bounds_delta().y(); + gfx::Vector2dF delta(0, target_height - current_outer_height); -gfx::SizeF LayerTreeHostImpl::UnscaledScrollableViewportSize() const { - // Use the root container layer bounds if it clips to them, otherwise, the - // true viewport size should be used. - LayerImpl* container_layer = active_tree_->InnerViewportContainerLayer(); - if (container_layer && container_layer->masks_to_bounds()) { - DCHECK(!top_controls_manager_); - DCHECK_EQ(0, overdraw_bottom_height_); - return container_layer->bounds(); - } + outer_container->SetBoundsDelta(delta); + active_tree_->InnerViewportScrollLayer()->SetBoundsDelta(delta); - return ComputeInnerViewportContainerSize(); + anchor.ResetViewportToAnchoredPosition(); } -float LayerTreeHostImpl::VerticalAdjust() const { - if (!active_tree_->InnerViewportContainerLayer()) - return 0; +void LayerTreeHostImpl::SetTopControlsLayoutHeight(float height) { + if (active_tree_->top_controls_layout_height() == height) + return; - return active_tree_->InnerViewportContainerLayer()->BoundsDelta().y(); + active_tree_->set_top_controls_layout_height(height); + UpdateViewportContainerSizes(); + SetFullRootLayerDamage(); +} + +void LayerTreeHostImpl::SynchronouslyInitializeAllTiles() { + // Only valid for the single-threaded non-scheduled/synchronous case + // using the zero copy raster worker pool. + single_thread_synchronous_task_graph_runner_->RunUntilIdle(); } void LayerTreeHostImpl::DidLoseOutputSurface() { if (resource_provider_) resource_provider_->DidLoseOutputSurface(); - // TODO(jamesr): The renderer_ check is needed to make some of the - // LayerTreeHostContextTest tests pass, but shouldn't be necessary (or - // important) in production. We should adjust the test to not need this. - if (renderer_) - client_->DidLoseOutputSurfaceOnImplThread(); -#if DCHECK_IS_ON - did_lose_called_ = true; -#endif + client_->DidLoseOutputSurfaceOnImplThread(); } bool LayerTreeHostImpl::HaveRootScrollLayer() const { @@ -1656,8 +1771,8 @@ LayerImpl* LayerTreeHostImpl::CurrentlyScrollingLayer() const { return active_tree_->CurrentlyScrollingLayer(); } -bool LayerTreeHostImpl::IsCurrentlyScrolling() const { - return CurrentlyScrollingLayer() || +bool LayerTreeHostImpl::IsActivelyScrolling() const { + return (did_lock_scrolling_layer_ && CurrentlyScrollingLayer()) || (InnerViewportScrollLayer() && InnerViewportScrollLayer()->IsExternalFlingActive()) || (OuterViewportScrollLayer() && @@ -1692,8 +1807,12 @@ void LayerTreeHostImpl::CreatePendingTree() { // Update the delta from the active tree, which may have // adjusted its delta prior to the pending tree being created. DCHECK_EQ(1.f, pending_tree_->sent_page_scale_delta()); + DCHECK_EQ(0.f, pending_tree_->sent_top_controls_delta()); pending_tree_->SetPageScaleDelta(active_tree_->page_scale_delta() / active_tree_->sent_page_scale_delta()); + pending_tree_->set_top_controls_delta( + active_tree_->top_controls_delta() - + active_tree_->sent_top_controls_delta()); client_->OnCanDrawStateChanged(CanDraw()); TRACE_EVENT_ASYNC_BEGIN0("cc", "PendingTree:waiting", pending_tree_.get()); @@ -1705,60 +1824,80 @@ void LayerTreeHostImpl::UpdateVisibleTiles() { need_to_update_visible_tiles_before_draw_ = false; } -void LayerTreeHostImpl::ActivatePendingTree() { - CHECK(pending_tree_); - TRACE_EVENT_ASYNC_END0("cc", "PendingTree:waiting", pending_tree_.get()); - +void LayerTreeHostImpl::ActivateSyncTree() { need_to_update_visible_tiles_before_draw_ = true; - active_tree_->SetRootLayerScrollOffsetDelegate(NULL); - active_tree_->PushPersistedState(pending_tree_.get()); - if (pending_tree_->needs_full_tree_sync()) { - active_tree_->SetRootLayer( - TreeSynchronizer::SynchronizeTrees(pending_tree_->root_layer(), - active_tree_->DetachLayerTree(), - active_tree_.get())); - } - TreeSynchronizer::PushProperties(pending_tree_->root_layer(), - active_tree_->root_layer()); - DCHECK(!recycle_tree_); - - // Process any requests in the UI resource queue. The request queue is given - // in LayerTreeHost::FinishCommitOnImplThread. This must take place before - // the swap. - pending_tree_->ProcessUIResourceRequestQueue(); - - pending_tree_->PushPropertiesTo(active_tree_.get()); + if (pending_tree_) { + TRACE_EVENT_ASYNC_END0("cc", "PendingTree:waiting", pending_tree_.get()); + + active_tree_->SetRootLayerScrollOffsetDelegate(NULL); + active_tree_->PushPersistedState(pending_tree_.get()); + // Process any requests in the UI resource queue. The request queue is + // given in LayerTreeHost::FinishCommitOnImplThread. This must take place + // before the swap. + pending_tree_->ProcessUIResourceRequestQueue(); + + if (pending_tree_->needs_full_tree_sync()) { + active_tree_->SetRootLayer( + TreeSynchronizer::SynchronizeTrees(pending_tree_->root_layer(), + active_tree_->DetachLayerTree(), + active_tree_.get())); + } + TreeSynchronizer::PushProperties(pending_tree_->root_layer(), + active_tree_->root_layer()); + pending_tree_->PushPropertiesTo(active_tree_.get()); + + // Now that we've synced everything from the pending tree to the active + // tree, rename the pending tree the recycle tree so we can reuse it on the + // next sync. + DCHECK(!recycle_tree_); + pending_tree_.swap(recycle_tree_); + + active_tree_->SetRootLayerScrollOffsetDelegate( + root_layer_scroll_offset_delegate_); + + if (top_controls_manager_) { + top_controls_manager_->SetControlsTopOffset( + active_tree_->total_top_controls_content_offset() - + top_controls_manager_->top_controls_height()); + } - // Now that we've synced everything from the pending tree to the active - // tree, rename the pending tree the recycle tree so we can reuse it on the - // next sync. - pending_tree_.swap(recycle_tree_); + UpdateViewportContainerSizes(); + } else { + active_tree_->ProcessUIResourceRequestQueue(); + } active_tree_->DidBecomeActive(); - active_tree_->SetRootLayerScrollOffsetDelegate( - root_layer_scroll_offset_delegate_); ActivateAnimations(); + if (settings_.impl_side_painting) + client_->RenewTreePriority(); client_->OnCanDrawStateChanged(CanDraw()); - SetNeedsRedraw(); - client_->RenewTreePriority(); + client_->DidActivateSyncTree(); + if (!tree_activation_callback_.is_null()) + tree_activation_callback_.Run(); if (debug_state_.continuous_painting) { const RenderingStats& stats = rendering_stats_instrumentation_->GetRenderingStats(); - paint_time_counter_->SavePaintTime(stats.main_stats.paint_time + - stats.main_stats.record_time + - stats.impl_stats.rasterize_time); + // TODO(hendrikw): This requires a different metric when we commit directly + // to the active tree. See crbug.com/429311. + paint_time_counter_->SavePaintTime( + stats.impl_stats.commit_to_activate_duration.GetLastTimeDelta() + + stats.impl_stats.draw_duration.GetLastTimeDelta()); } - UpdateInnerViewportContainerSize(); - client_->DidActivatePendingTree(); - if (!tree_activation_callback_.is_null()) - tree_activation_callback_.Run(); - if (time_source_client_adapter_ && time_source_client_adapter_->Active()) DCHECK(active_tree_->root_layer()); + + scoped_ptr<PageScaleAnimation> page_scale_animation = + active_tree_->TakePageScaleAnimation(); + if (page_scale_animation) { + page_scale_animation_ = page_scale_animation.Pass(); + SetNeedsAnimate(); + client_->SetNeedsCommitOnImplThread(); + client_->RenewTreePriority(); + } } void LayerTreeHostImpl::SetVisible(bool visible) { @@ -1773,7 +1912,7 @@ void LayerTreeHostImpl::SetVisible(bool visible) { // If we just became visible, we have to ensure that we draw high res tiles, // to prevent checkerboard/low res flashes. if (visible_) - active_tree()->SetRequiresHighResToDraw(); + SetRequiresHighResToDraw(); else EvictAllUIResources(); @@ -1872,95 +2011,139 @@ void LayerTreeHostImpl::CreateAndSetTileManager() { DCHECK(settings_.impl_side_painting); DCHECK(output_surface_); DCHECK(resource_provider_); - DCHECK(proxy_->ImplThreadTaskRunner()); + + CreateResourceAndRasterWorkerPool( + &raster_worker_pool_, &resource_pool_, &staging_resource_pool_); + DCHECK(raster_worker_pool_); + DCHECK(resource_pool_); + + base::SingleThreadTaskRunner* task_runner = + proxy_->HasImplThread() ? proxy_->ImplThreadTaskRunner() + : proxy_->MainThreadTaskRunner(); + DCHECK(task_runner); + size_t scheduled_raster_task_limit = + IsSynchronousSingleThreaded() ? std::numeric_limits<size_t>::max() + : settings_.scheduled_raster_task_limit; + tile_manager_ = TileManager::Create(this, + task_runner, + resource_pool_.get(), + raster_worker_pool_->AsRasterizer(), + rendering_stats_instrumentation_, + scheduled_raster_task_limit); + + UpdateTileManagerMemoryPolicy(ActualManagedMemoryPolicy()); + need_to_update_visible_tiles_before_draw_ = false; +} + +void LayerTreeHostImpl::CreateResourceAndRasterWorkerPool( + scoped_ptr<RasterWorkerPool>* raster_worker_pool, + scoped_ptr<ResourcePool>* resource_pool, + scoped_ptr<ResourcePool>* staging_resource_pool) { + base::SingleThreadTaskRunner* task_runner = + proxy_->HasImplThread() ? proxy_->ImplThreadTaskRunner() + : proxy_->MainThreadTaskRunner(); + DCHECK(task_runner); ContextProvider* context_provider = output_surface_->context_provider(); - transfer_buffer_memory_limit_ = - GetMaxTransferBufferUsageBytes(context_provider); + bool should_use_zero_copy_rasterizer = + settings_.use_zero_copy || IsSynchronousSingleThreaded(); - if (use_gpu_rasterization_ && context_provider) { - resource_pool_ = + if (!context_provider) { + *resource_pool = ResourcePool::Create(resource_provider_.get(), GL_TEXTURE_2D, resource_provider_->best_texture_format()); - raster_worker_pool_ = - DirectRasterWorkerPool::Create(proxy_->ImplThreadTaskRunner(), - resource_provider_.get(), - context_provider); - on_demand_task_graph_runner_ = &synchronous_task_graph_runner_; - } else if (UseZeroCopyTextureUpload()) { - resource_pool_ = + *raster_worker_pool = + BitmapRasterWorkerPool::Create(task_runner, + RasterWorkerPool::GetTaskGraphRunner(), + resource_provider_.get()); + } else if (use_gpu_rasterization_) { + *resource_pool = ResourcePool::Create(resource_provider_.get(), - GetMapImageTextureTarget(context_provider), + GL_TEXTURE_2D, resource_provider_->best_texture_format()); - raster_worker_pool_ = - ImageRasterWorkerPool::Create(proxy_->ImplThreadTaskRunner(), - RasterWorkerPool::GetTaskGraphRunner(), - resource_provider_.get()); - on_demand_task_graph_runner_ = RasterWorkerPool::GetTaskGraphRunner(); - } else if (UseOneCopyTextureUpload()) { + *raster_worker_pool = + GpuRasterWorkerPool::Create(task_runner, + context_provider, + resource_provider_.get(), + settings_.use_distance_field_text); + } else if (should_use_zero_copy_rasterizer && CanUseZeroCopyRasterizer()) { + *resource_pool = ResourcePool::Create( + resource_provider_.get(), + GetMapImageTextureTarget(context_provider->ContextCapabilities()), + resource_provider_->best_texture_format()); + + TaskGraphRunner* task_graph_runner; + if (IsSynchronousSingleThreaded()) { + DCHECK(!single_thread_synchronous_task_graph_runner_); + single_thread_synchronous_task_graph_runner_.reset(new TaskGraphRunner); + task_graph_runner = single_thread_synchronous_task_graph_runner_.get(); + } else { + task_graph_runner = RasterWorkerPool::GetTaskGraphRunner(); + } + + *raster_worker_pool = ZeroCopyRasterWorkerPool::Create( + task_runner, task_graph_runner, resource_provider_.get()); + } else if (settings_.use_one_copy && CanUseOneCopyRasterizer()) { // We need to create a staging resource pool when using copy rasterizer. - staging_resource_pool_ = - ResourcePool::Create(resource_provider_.get(), - GetMapImageTextureTarget(context_provider), - resource_provider_->best_texture_format()); - resource_pool_ = + *staging_resource_pool = ResourcePool::Create( + resource_provider_.get(), + GetMapImageTextureTarget(context_provider->ContextCapabilities()), + resource_provider_->best_texture_format()); + *resource_pool = ResourcePool::Create(resource_provider_.get(), GL_TEXTURE_2D, resource_provider_->best_texture_format()); - raster_worker_pool_ = ImageCopyRasterWorkerPool::Create( - proxy_->ImplThreadTaskRunner(), - RasterWorkerPool::GetTaskGraphRunner(), - resource_provider_.get(), - staging_resource_pool_.get()); - on_demand_task_graph_runner_ = RasterWorkerPool::GetTaskGraphRunner(); + *raster_worker_pool = + OneCopyRasterWorkerPool::Create(task_runner, + RasterWorkerPool::GetTaskGraphRunner(), + context_provider, + resource_provider_.get(), + staging_resource_pool_.get()); } else { - resource_pool_ = ResourcePool::Create( + *resource_pool = ResourcePool::Create( resource_provider_.get(), GL_TEXTURE_2D, resource_provider_->memory_efficient_texture_format()); - raster_worker_pool_ = PixelBufferRasterWorkerPool::Create( - proxy_->ImplThreadTaskRunner(), + *raster_worker_pool = PixelBufferRasterWorkerPool::Create( + task_runner, RasterWorkerPool::GetTaskGraphRunner(), + context_provider, resource_provider_.get(), - transfer_buffer_memory_limit_); - on_demand_task_graph_runner_ = RasterWorkerPool::GetTaskGraphRunner(); + GetMaxTransferBufferUsageBytes(context_provider->ContextCapabilities(), + settings_.refresh_rate)); } +} - tile_manager_ = - TileManager::Create(this, - proxy_->ImplThreadTaskRunner(), - resource_pool_.get(), - raster_worker_pool_->AsRasterizer(), - rendering_stats_instrumentation_); +void LayerTreeHostImpl::DestroyTileManager() { + tile_manager_ = nullptr; + resource_pool_ = nullptr; + staging_resource_pool_ = nullptr; + raster_worker_pool_ = nullptr; + single_thread_synchronous_task_graph_runner_ = nullptr; +} - UpdateTileManagerMemoryPolicy(ActualManagedMemoryPolicy()); - need_to_update_visible_tiles_before_draw_ = false; - on_demand_task_namespace_ = on_demand_task_graph_runner_->GetNamespaceToken(); +bool LayerTreeHostImpl::UsePendingTreeForSync() const { + // In impl-side painting, synchronize to the pending tree so that it has + // time to raster before being displayed. + return settings_.impl_side_painting; } -void LayerTreeHostImpl::DestroyTileManager() { - tile_manager_.reset(); - resource_pool_.reset(); - staging_resource_pool_.reset(); - raster_worker_pool_.reset(); +bool LayerTreeHostImpl::IsSynchronousSingleThreaded() const { + return !proxy_->HasImplThread() && !settings_.single_thread_proxy_scheduler; } -bool LayerTreeHostImpl::UseZeroCopyTextureUpload() const { - // Note: we use zero-copy by default when the renderer is using - // shared memory resources. - return (settings_.use_zero_copy || - GetRendererCapabilities().using_shared_memory_resources) && - GetRendererCapabilities().using_map_image; +bool LayerTreeHostImpl::CanUseZeroCopyRasterizer() const { + return GetRendererCapabilities().using_image; } -bool LayerTreeHostImpl::UseOneCopyTextureUpload() const { +bool LayerTreeHostImpl::CanUseOneCopyRasterizer() const { // Sync query support is required by one-copy rasterizer. - return settings_.use_one_copy && GetRendererCapabilities().using_map_image && + return GetRendererCapabilities().using_image && resource_provider_->use_sync_query(); } @@ -1971,9 +2154,6 @@ void LayerTreeHostImpl::EnforceZeroBudget(bool zero_budget) { bool LayerTreeHostImpl::InitializeRenderer( scoped_ptr<OutputSurface> output_surface) { TRACE_EVENT0("cc", "LayerTreeHostImpl::InitializeRenderer"); -#if DCHECK_IS_ON - DCHECK(!renderer_ || did_lose_called_); -#endif // Since we will create a new resource provider, we cannot continue to use // the old resources (i.e. render_surfaces and texture IDs). Clear them @@ -1981,10 +2161,10 @@ bool LayerTreeHostImpl::InitializeRenderer( ReleaseTreeResources(); // Note: order is important here. - renderer_.reset(); + renderer_ = nullptr; DestroyTileManager(); - resource_provider_.reset(); - output_surface_.reset(); + resource_provider_ = nullptr; + output_surface_ = nullptr; if (!output_surface->BindToClient(this)) return false; @@ -1993,19 +2173,17 @@ bool LayerTreeHostImpl::InitializeRenderer( resource_provider_ = ResourceProvider::Create(output_surface_.get(), shared_bitmap_manager_, + gpu_memory_buffer_manager_, + proxy_->blocking_main_thread_task_runner(), settings_.highp_threshold_min, settings_.use_rgba_4444_textures, - settings_.texture_id_allocation_chunk_size, - settings_.use_distance_field_text); + settings_.texture_id_allocation_chunk_size); if (output_surface_->capabilities().deferred_gl_initialization) EnforceZeroBudget(true); CreateAndSetRenderer(); - transfer_buffer_memory_limit_ = - GetMaxTransferBufferUsageBytes(output_surface_->context_provider()); - if (settings_.impl_side_painting) CreateAndSetTileManager(); @@ -2029,6 +2207,11 @@ bool LayerTreeHostImpl::InitializeRenderer( client_->SetMaxSwapsPendingOnImplThread(max_frames_pending); client_->OnCanDrawStateChanged(CanDraw()); + // There will not be anything to draw here, so set high res + // to avoid checkerboards, typically when we are recovering + // from lost context. + SetRequiresHighResToDraw(); + return true; } @@ -2043,7 +2226,7 @@ void LayerTreeHostImpl::DeferredInitialize() { DCHECK(output_surface_->context_provider()); ReleaseTreeResources(); - renderer_.reset(); + renderer_ = nullptr; DestroyTileManager(); resource_provider_->InitializeGL(); @@ -2061,7 +2244,7 @@ void LayerTreeHostImpl::ReleaseGL() { DCHECK(output_surface_->context_provider()); ReleaseTreeResources(); - renderer_.reset(); + renderer_ = nullptr; DestroyTileManager(); resource_provider_->InitializeSoftware(); @@ -2083,21 +2266,12 @@ void LayerTreeHostImpl::SetViewportSize(const gfx::Size& device_viewport_size) { device_viewport_size_ = device_viewport_size; - UpdateInnerViewportContainerSize(); + UpdateViewportContainerSizes(); client_->OnCanDrawStateChanged(CanDraw()); SetFullRootLayerDamage(); active_tree_->set_needs_update_draw_properties(); } -void LayerTreeHostImpl::SetOverdrawBottomHeight(float overdraw_bottom_height) { - if (overdraw_bottom_height == overdraw_bottom_height_) - return; - overdraw_bottom_height_ = overdraw_bottom_height; - - UpdateInnerViewportContainerSize(); - SetFullRootLayerDamage(); -} - void LayerTreeHostImpl::SetOverhangUIResource( UIResourceId overhang_ui_resource_id, const gfx::Size& overhang_ui_resource_size) { @@ -2110,10 +2284,16 @@ void LayerTreeHostImpl::SetDeviceScaleFactor(float device_scale_factor) { return; device_scale_factor_ = device_scale_factor; - UpdateInnerViewportContainerSize(); SetFullRootLayerDamage(); } +const gfx::Rect LayerTreeHostImpl::ViewportRectForTilePriority() const { + if (viewport_rect_for_tile_priority_.IsEmpty()) + return DeviceViewport(); + + return viewport_rect_for_tile_priority_; +} + gfx::Size LayerTreeHostImpl::DrawViewportSize() const { return DeviceViewport().size(); } @@ -2137,13 +2317,24 @@ const gfx::Transform& LayerTreeHostImpl::DrawTransform() const { } void LayerTreeHostImpl::DidChangeTopControlsPosition() { - UpdateInnerViewportContainerSize(); + UpdateViewportContainerSizes(); SetNeedsRedraw(); SetNeedsAnimate(); active_tree_->set_needs_update_draw_properties(); SetFullRootLayerDamage(); } +void LayerTreeHostImpl::SetControlsTopOffset(float offset) { + float current_top_offset = active_tree_->top_controls_content_offset() - + top_controls_manager_->top_controls_height(); + active_tree_->set_top_controls_delta(offset - current_top_offset); +} + +float LayerTreeHostImpl::ControlsTopOffset() const { + return active_tree_->total_top_controls_content_offset() - + top_controls_manager_->top_controls_height(); +} + void LayerTreeHostImpl::BindToClient(InputHandlerClient* client) { DCHECK(input_handler_client_ == NULL); input_handler_client_ = client; @@ -2263,6 +2454,82 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollBegin( return ScrollIgnored; } +InputHandler::ScrollStatus LayerTreeHostImpl::ScrollAnimated( + const gfx::Point& viewport_point, + const gfx::Vector2dF& scroll_delta) { + if (LayerImpl* layer_impl = CurrentlyScrollingLayer()) { + Animation* animation = + layer_impl->layer_animation_controller()->GetAnimation( + Animation::ScrollOffset); + if (!animation) + return ScrollIgnored; + + ScrollOffsetAnimationCurve* curve = + animation->curve()->ToScrollOffsetAnimationCurve(); + + gfx::ScrollOffset new_target = + gfx::ScrollOffsetWithDelta(curve->target_value(), scroll_delta); + new_target.SetToMax(gfx::ScrollOffset()); + new_target.SetToMin(layer_impl->MaxScrollOffset()); + + curve->UpdateTarget(animation->TrimTimeToCurrentIteration( + CurrentBeginFrameArgs().frame_time), + new_target); + + return ScrollStarted; + } + // ScrollAnimated is only used for wheel scrolls. We use the same bubbling + // behavior as ScrollBy to determine which layer to animate, but we do not + // do the Android-specific things in ScrollBy like showing top controls. + InputHandler::ScrollStatus scroll_status = ScrollBegin(viewport_point, Wheel); + if (scroll_status == ScrollStarted) { + gfx::Vector2dF pending_delta = scroll_delta; + for (LayerImpl* layer_impl = CurrentlyScrollingLayer(); layer_impl; + layer_impl = layer_impl->parent()) { + if (!layer_impl->scrollable()) + continue; + + gfx::ScrollOffset current_offset = layer_impl->TotalScrollOffset(); + gfx::ScrollOffset target_offset = + ScrollOffsetWithDelta(current_offset, pending_delta); + target_offset.SetToMax(gfx::ScrollOffset()); + target_offset.SetToMin(layer_impl->MaxScrollOffset()); + gfx::Vector2dF actual_delta = target_offset.DeltaFrom(current_offset); + + const float kEpsilon = 0.1f; + bool can_layer_scroll = (std::abs(actual_delta.x()) > kEpsilon || + std::abs(actual_delta.y()) > kEpsilon); + + if (!can_layer_scroll) { + layer_impl->ScrollBy(actual_delta); + pending_delta -= actual_delta; + continue; + } + + active_tree_->SetCurrentlyScrollingLayer(layer_impl); + + scoped_ptr<ScrollOffsetAnimationCurve> curve = + ScrollOffsetAnimationCurve::Create(target_offset, + EaseInOutTimingFunction::Create()); + curve->SetInitialValue(current_offset); + + scoped_ptr<Animation> animation = + Animation::Create(curve.Pass(), + AnimationIdProvider::NextAnimationId(), + AnimationIdProvider::NextGroupId(), + Animation::ScrollOffset); + animation->set_is_impl_only(true); + + layer_impl->layer_animation_controller()->AddAnimation(animation.Pass()); + + SetNeedsAnimate(); + return ScrollStarted; + } + } + ScrollEnd(); + return scroll_status; +} + gfx::Vector2dF LayerTreeHostImpl::ScrollLayerWithViewportSpaceDelta( LayerImpl* layer_impl, float scale_from_viewport_to_screen_space, @@ -2346,49 +2613,77 @@ static gfx::Vector2dF ScrollLayerWithLocalDelta(LayerImpl* layer_impl, return layer_impl->ScrollDelta() - previous_delta; } -bool LayerTreeHostImpl::ScrollBy(const gfx::Point& viewport_point, - const gfx::Vector2dF& scroll_delta) { +bool LayerTreeHostImpl::ShouldTopControlsConsumeScroll( + const gfx::Vector2dF& scroll_delta) const { + DCHECK(CurrentlyScrollingLayer()); + + if (!top_controls_manager_) + return false; + + // Always consume if it's in the direction to show the top controls. + if (scroll_delta.y() < 0) + return true; + + if (CurrentlyScrollingLayer() != InnerViewportScrollLayer() && + CurrentlyScrollingLayer() != OuterViewportScrollLayer()) + return false; + + if (InnerViewportScrollLayer()->MaxScrollOffset().y() > 0) + return true; + + if (OuterViewportScrollLayer() && + OuterViewportScrollLayer()->MaxScrollOffset().y() > 0) + return true; + + return false; +} + +InputHandlerScrollResult LayerTreeHostImpl::ScrollBy( + const gfx::Point& viewport_point, + const gfx::Vector2dF& scroll_delta) { TRACE_EVENT0("cc", "LayerTreeHostImpl::ScrollBy"); if (!CurrentlyScrollingLayer()) - return false; + return InputHandlerScrollResult(); gfx::Vector2dF pending_delta = scroll_delta; gfx::Vector2dF unused_root_delta; bool did_scroll_x = false; bool did_scroll_y = false; bool did_scroll_top_controls = false; - // TODO(wjmaclean) Should we guard against CurrentlyScrollingLayer() == 0 - // here? - bool consume_by_top_controls = - top_controls_manager_ && - (((CurrentlyScrollingLayer() == InnerViewportScrollLayer() || - CurrentlyScrollingLayer() == OuterViewportScrollLayer()) && - InnerViewportScrollLayer()->MaxScrollOffset().y() > 0) || - scroll_delta.y() < 0); - for (LayerImpl* layer_impl = CurrentlyScrollingLayer(); + bool consume_by_top_controls = ShouldTopControlsConsumeScroll(scroll_delta); + + // There's an edge case where the outer viewport isn't scrollable when the + // scroll starts, however, as the top controls show the outer viewport becomes + // scrollable. Therefore, always try scrolling the outer viewport before the + // inner. + // TODO(bokan): Move the top controls logic out of the loop since the scroll + // that causes the outer viewport to become scrollable will still be applied + // to the inner viewport. + LayerImpl* start_layer = CurrentlyScrollingLayer(); + if (start_layer == InnerViewportScrollLayer() && OuterViewportScrollLayer()) + start_layer = OuterViewportScrollLayer(); + + for (LayerImpl* layer_impl = start_layer; layer_impl; layer_impl = layer_impl->parent()) { if (!layer_impl->scrollable()) continue; - if (layer_impl == InnerViewportScrollLayer()) { - // Only allow bubble scrolling when the scroll is in the direction to make - // the top controls visible. - gfx::Vector2dF applied_delta; - gfx::Vector2dF excess_delta; + if (layer_impl == InnerViewportScrollLayer() || + layer_impl == OuterViewportScrollLayer()) { if (consume_by_top_controls) { - excess_delta = top_controls_manager_->ScrollBy(pending_delta); - applied_delta = pending_delta - excess_delta; + gfx::Vector2dF excess_delta = + top_controls_manager_->ScrollBy(pending_delta); + gfx::Vector2dF applied_delta = pending_delta - excess_delta; pending_delta = excess_delta; // Force updating of vertical adjust values if needed. - if (applied_delta.y() != 0) { + if (applied_delta.y() != 0) did_scroll_top_controls = true; - layer_impl->ScrollbarParametersDidChange(); - } } // Track root layer deltas for reporting overscroll. - unused_root_delta = pending_delta; + if (layer_impl == InnerViewportScrollLayer()) + unused_root_delta = pending_delta; } gfx::Vector2dF applied_delta; @@ -2415,47 +2710,58 @@ bool LayerTreeHostImpl::ScrollBy(const gfx::Point& viewport_point, unused_root_delta.set_y(0.0f); // Disable overscroll on axes which is impossible to scroll. if (settings_.report_overscroll_only_for_scrollable_axes) { - if (std::abs(active_tree_->TotalMaxScrollOffset().x()) <= kEpsilon) + if (std::abs(active_tree_->TotalMaxScrollOffset().x()) <= kEpsilon || + !layer_impl->user_scrollable_horizontal()) unused_root_delta.set_x(0.0f); - if (std::abs(active_tree_->TotalMaxScrollOffset().y()) <= kEpsilon) + if (std::abs(active_tree_->TotalMaxScrollOffset().y()) <= kEpsilon || + !layer_impl->user_scrollable_vertical()) unused_root_delta.set_y(0.0f); } } + // Scrolls should bubble perfectly between the outer and inner viewports. + bool allow_unrestricted_bubbling_for_current_layer = + layer_impl == OuterViewportScrollLayer(); + bool allow_bubbling_for_current_layer = + allow_unrestricted_bubbling_for_current_layer || should_bubble_scrolls_; + // If the layer wasn't able to move, try the next one in the hierarchy. bool did_move_layer_x = std::abs(applied_delta.x()) > kEpsilon; bool did_move_layer_y = std::abs(applied_delta.y()) > kEpsilon; did_scroll_x |= did_move_layer_x; did_scroll_y |= did_move_layer_y; if (!did_move_layer_x && !did_move_layer_y) { - // Scrolls should always bubble between the outer and inner viewports - if (should_bubble_scrolls_ || !did_lock_scrolling_layer_ || - layer_impl == OuterViewportScrollLayer()) + if (allow_bubbling_for_current_layer || !did_lock_scrolling_layer_) continue; else break; } did_lock_scrolling_layer_ = true; - if (!should_bubble_scrolls_) { + if (!allow_bubbling_for_current_layer) { active_tree_->SetCurrentlyScrollingLayer(layer_impl); break; } - // If the applied delta is within 45 degrees of the input delta, bail out to - // make it easier to scroll just one layer in one direction without - // affecting any of its parents. - float angle_threshold = 45; - if (MathUtil::SmallestAngleBetweenVectors( - applied_delta, pending_delta) < angle_threshold) { - pending_delta = gfx::Vector2d(); - break; - } + if (allow_unrestricted_bubbling_for_current_layer) { + pending_delta -= applied_delta; + } else { + // If the applied delta is within 45 degrees of the input delta, bail out + // to make it easier to scroll just one layer in one direction without + // affecting any of its parents. + float angle_threshold = 45; + if (MathUtil::SmallestAngleBetweenVectors(applied_delta, pending_delta) < + angle_threshold) { + pending_delta = gfx::Vector2dF(); + break; + } - // Allow further movement only on an axis perpendicular to the direction in - // which the layer moved. - gfx::Vector2dF perpendicular_axis(-applied_delta.y(), applied_delta.x()); - pending_delta = MathUtil::ProjectVector(pending_delta, perpendicular_axis); + // Allow further movement only on an axis perpendicular to the direction + // in which the layer moved. + gfx::Vector2dF perpendicular_axis(-applied_delta.y(), applied_delta.x()); + pending_delta = + MathUtil::ProjectVector(pending_delta, perpendicular_axis); + } if (gfx::ToRoundedVector2d(pending_delta).IsZero()) break; @@ -2463,6 +2769,11 @@ bool LayerTreeHostImpl::ScrollBy(const gfx::Point& viewport_point, bool did_scroll_content = did_scroll_x || did_scroll_y; if (did_scroll_content) { + // If we are scrolling with an active scroll handler, forward latency + // tracking information to the main thread so the delay introduced by the + // handler is accounted for. + if (scroll_affects_scroll_handler()) + NotifySwapPromiseMonitorsOfForwardingToMainThread(); client_->SetNeedsCommitOnImplThread(); SetNeedsRedraw(); client_->RenewTreePriority(); @@ -2473,15 +2784,14 @@ bool LayerTreeHostImpl::ScrollBy(const gfx::Point& viewport_point, accumulated_root_overscroll_.set_x(0); if (did_scroll_y) accumulated_root_overscroll_.set_y(0); - accumulated_root_overscroll_ += unused_root_delta; - bool did_overscroll = !unused_root_delta.IsZero(); - if (did_overscroll && input_handler_client_) { - input_handler_client_->DidOverscroll(accumulated_root_overscroll_, - unused_root_delta); - } - return did_scroll_content || did_scroll_top_controls; + InputHandlerScrollResult scroll_result; + scroll_result.did_scroll = did_scroll_content || did_scroll_top_controls; + scroll_result.did_overscroll_root = !unused_root_delta.IsZero(); + scroll_result.accumulated_root_overscroll = accumulated_root_overscroll_; + scroll_result.unused_scroll_delta = unused_root_delta; + return scroll_result; } // This implements scrolling by page as described here: @@ -2533,8 +2843,10 @@ void LayerTreeHostImpl::SetRootLayerScrollOffsetDelegate( } void LayerTreeHostImpl::OnRootLayerDelegatedScrollOffsetChanged() { - DCHECK(root_layer_scroll_offset_delegate_ != NULL); + DCHECK(root_layer_scroll_offset_delegate_); client_->SetNeedsCommitOnImplThread(); + SetNeedsRedraw(); + active_tree_->OnRootLayerDelegatedScrollOffsetChanged(); active_tree_->set_needs_update_draw_properties(); } @@ -2737,6 +3049,14 @@ void LayerTreeHostImpl::PinchGestureEnd() { if (top_controls_manager_) top_controls_manager_->PinchEnd(); client_->SetNeedsCommitOnImplThread(); + // When a pinch ends, we may be displaying content cached at incorrect scales, + // so updating draw properties and drawing will ensure we are using the right + // scales that we want when we're not inside a pinch. + active_tree_->set_needs_update_draw_properties(); + SetNeedsRedraw(); + // TODO(danakj): Don't set root damage. Just updating draw properties and + // getting new tiles rastered should be enough! crbug.com/427423 + SetFullRootLayerDamage(); } static void CollectScrollDeltas(ScrollAndScaleSet* scroll_info, @@ -2764,6 +3084,9 @@ scoped_ptr<ScrollAndScaleSet> LayerTreeHostImpl::ProcessScrollDeltas() { CollectScrollDeltas(scroll_info.get(), active_tree_->root_layer()); scroll_info->page_scale_delta = active_tree_->page_scale_delta(); active_tree_->set_sent_page_scale_delta(scroll_info->page_scale_delta); + scroll_info->swap_promises.swap(swap_promises_for_main_thread_scroll_update_); + scroll_info->top_controls_delta = active_tree()->top_controls_delta(); + active_tree_->set_sent_top_controls_delta(scroll_info->top_controls_delta); return scroll_info.Pass(); } @@ -2772,32 +3095,13 @@ void LayerTreeHostImpl::SetFullRootLayerDamage() { SetViewportDamage(gfx::Rect(DrawViewportSize())); } -void LayerTreeHostImpl::RunOnDemandRasterTask(Task* on_demand_raster_task) { - DCHECK(on_demand_task_graph_runner_); - - // Construct a task graph that contains this single raster task. - TaskGraph graph; - graph.nodes.push_back( - TaskGraph::Node(on_demand_raster_task, - RasterWorkerPool::kOnDemandRasterTaskPriority, - 0u)); - - // Schedule task and wait for task graph runner to finish running it. - on_demand_task_graph_runner_->ScheduleTasks(on_demand_task_namespace_, - &graph); - - if (on_demand_task_graph_runner_ == &synchronous_task_graph_runner_) - on_demand_task_graph_runner_->RunUntilIdle(); - - on_demand_task_graph_runner_->WaitForTasksToFinishRunning( - on_demand_task_namespace_); +void LayerTreeHostImpl::ScrollViewportInnerFirst(gfx::Vector2dF scroll_delta) { + DCHECK(InnerViewportScrollLayer()); + LayerImpl* scroll_layer = InnerViewportScrollLayer(); - // Collect task now that it has finished running. - Task::Vector completed_tasks; - on_demand_task_graph_runner_->CollectCompletedTasks(on_demand_task_namespace_, - &completed_tasks); - DCHECK_EQ(1u, completed_tasks.size()); - DCHECK_EQ(completed_tasks[0], on_demand_raster_task); + gfx::Vector2dF unused_delta = scroll_layer->ScrollBy(scroll_delta); + if (!unused_delta.IsZero() && OuterViewportScrollLayer()) + OuterViewportScrollLayer()->ScrollBy(unused_delta); } void LayerTreeHostImpl::ScrollViewportBy(gfx::Vector2dF scroll_delta) { @@ -2816,7 +3120,7 @@ void LayerTreeHostImpl::AnimatePageScale(base::TimeTicks monotonic_time) { if (!page_scale_animation_) return; - gfx::Vector2dF scroll_total = active_tree_->TotalScrollOffset(); + gfx::ScrollOffset scroll_total = active_tree_->TotalScrollOffset(); if (!page_scale_animation_->IsAnimationStarted()) page_scale_animation_->StartAnimation(monotonic_time); @@ -2824,14 +3128,14 @@ void LayerTreeHostImpl::AnimatePageScale(base::TimeTicks monotonic_time) { active_tree_->SetPageScaleDelta( page_scale_animation_->PageScaleFactorAtTime(monotonic_time) / active_tree_->page_scale_factor()); - gfx::Vector2dF next_scroll = - page_scale_animation_->ScrollOffsetAtTime(monotonic_time); + gfx::ScrollOffset next_scroll = gfx::ScrollOffset( + page_scale_animation_->ScrollOffsetAtTime(monotonic_time)); - ScrollViewportBy(next_scroll - scroll_total); + ScrollViewportInnerFirst(next_scroll.DeltaFrom(scroll_total)); SetNeedsRedraw(); if (page_scale_animation_->IsAnimationCompleteAtTime(monotonic_time)) { - page_scale_animation_.reset(); + page_scale_animation_ = nullptr; client_->SetNeedsCommitOnImplThread(); client_->RenewTreePriority(); } else { @@ -2842,15 +3146,23 @@ void LayerTreeHostImpl::AnimatePageScale(base::TimeTicks monotonic_time) { void LayerTreeHostImpl::AnimateTopControls(base::TimeTicks time) { if (!top_controls_manager_ || !top_controls_manager_->animation()) return; + gfx::Vector2dF scroll = top_controls_manager_->Animate(time); + + if (top_controls_manager_->animation()) + SetNeedsAnimate(); + if (active_tree_->TotalScrollOffset().y() == 0.f) return; - if (!scroll.IsZero()) { - ScrollViewportBy(gfx::ScaleVector2d( - scroll, 1.f / active_tree_->total_page_scale_factor())); - SetNeedsRedraw(); - } - SetNeedsAnimate(); + + if (scroll.IsZero()) + return; + + ScrollViewportBy(gfx::ScaleVector2d( + scroll, 1.f / active_tree_->total_page_scale_factor())); + SetNeedsRedraw(); + client_->SetNeedsCommitOnImplThread(); + client_->RenewTreePriority(); } void LayerTreeHostImpl::AnimateLayers(base::TimeTicks monotonic_time) { @@ -2967,47 +3279,116 @@ void LayerTreeHostImpl::SetTreePriority(TreePriority priority) { DidModifyTilePriorities(); } -void LayerTreeHostImpl::UpdateCurrentFrameTime() { - DCHECK(current_frame_timeticks_.is_null()); - current_frame_timeticks_ = gfx::FrameTime::Now(); +TreePriority LayerTreeHostImpl::GetTreePriority() const { + return global_tile_state_.tree_priority; +} + +void LayerTreeHostImpl::UpdateCurrentBeginFrameArgs( + const BeginFrameArgs& args) { + DCHECK(!current_begin_frame_args_.IsValid()); + current_begin_frame_args_ = args; + // TODO(skyostil): Stop overriding the frame time once the usage of frame + // timing is unified. + current_begin_frame_args_.frame_time = gfx::FrameTime::Now(); } -void LayerTreeHostImpl::ResetCurrentFrameTimeForNextFrame() { - current_frame_timeticks_ = base::TimeTicks(); +void LayerTreeHostImpl::ResetCurrentBeginFrameArgsForNextFrame() { + current_begin_frame_args_ = BeginFrameArgs(); } -base::TimeTicks LayerTreeHostImpl::CurrentFrameTimeTicks() { +BeginFrameArgs LayerTreeHostImpl::CurrentBeginFrameArgs() const { // Try to use the current frame time to keep animations non-jittery. But if // we're not in a frame (because this is during an input event or a delayed // task), fall back to physical time. This should still be monotonic. - if (!current_frame_timeticks_.is_null()) - return current_frame_timeticks_; - return gfx::FrameTime::Now(); -} - -scoped_ptr<base::Value> LayerTreeHostImpl::AsValueWithFrame( - FrameData* frame) const { - scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); - if (this->pending_tree_) - state->Set("activation_state", ActivationStateAsValue().release()); - state->Set("device_viewport_size", - MathUtil::AsValue(device_viewport_size_).release()); - if (tile_manager_) - state->Set("tiles", tile_manager_->AllTilesAsValue().release()); - state->Set("active_tree", active_tree_->AsValue().release()); + if (current_begin_frame_args_.IsValid()) + return current_begin_frame_args_; + return BeginFrameArgs::Create(gfx::FrameTime::Now(), + base::TimeTicks(), + BeginFrameArgs::DefaultInterval()); +} + +void LayerTreeHostImpl::AsValueInto(base::debug::TracedValue* value) const { + return AsValueWithFrameInto(NULL, value); +} + +scoped_refptr<base::debug::ConvertableToTraceFormat> +LayerTreeHostImpl::AsValue() const { + return AsValueWithFrame(NULL); +} + +scoped_refptr<base::debug::ConvertableToTraceFormat> +LayerTreeHostImpl::AsValueWithFrame(FrameData* frame) const { + scoped_refptr<base::debug::TracedValue> state = + new base::debug::TracedValue(); + AsValueWithFrameInto(frame, state.get()); + return state; +} + +void LayerTreeHostImpl::AsValueWithFrameInto( + FrameData* frame, + base::debug::TracedValue* state) const { + if (this->pending_tree_) { + state->BeginDictionary("activation_state"); + ActivationStateAsValueInto(state); + state->EndDictionary(); + } + state->BeginDictionary("device_viewport_size"); + MathUtil::AddToTracedValue(device_viewport_size_, state); + state->EndDictionary(); + + std::set<const Tile*> tiles; + active_tree_->GetAllTilesForTracing(&tiles); if (pending_tree_) - state->Set("pending_tree", pending_tree_->AsValue().release()); - if (frame) - state->Set("frame", frame->AsValue().release()); - return state.PassAs<base::Value>(); + pending_tree_->GetAllTilesForTracing(&tiles); + + state->BeginArray("active_tiles"); + for (std::set<const Tile*>::const_iterator it = tiles.begin(); + it != tiles.end(); + ++it) { + const Tile* tile = *it; + + state->BeginDictionary(); + tile->AsValueInto(state); + state->EndDictionary(); + } + state->EndArray(); + + if (tile_manager_) { + state->BeginDictionary("tile_manager_basic_state"); + tile_manager_->BasicStateAsValueInto(state); + state->EndDictionary(); + } + state->BeginDictionary("active_tree"); + active_tree_->AsValueInto(state); + state->EndDictionary(); + if (pending_tree_) { + state->BeginDictionary("pending_tree"); + pending_tree_->AsValueInto(state); + state->EndDictionary(); + } + if (frame) { + state->BeginDictionary("frame"); + frame->AsValueInto(state); + state->EndDictionary(); + } } -scoped_ptr<base::Value> LayerTreeHostImpl::ActivationStateAsValue() const { - scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); - state->Set("lthi", TracedValue::CreateIDRef(this).release()); - if (tile_manager_) - state->Set("tile_manager", tile_manager_->BasicStateAsValue().release()); - return state.PassAs<base::Value>(); +scoped_refptr<base::debug::ConvertableToTraceFormat> +LayerTreeHostImpl::ActivationStateAsValue() const { + scoped_refptr<base::debug::TracedValue> state = + new base::debug::TracedValue(); + ActivationStateAsValueInto(state.get()); + return state; +} + +void LayerTreeHostImpl::ActivationStateAsValueInto( + base::debug::TracedValue* state) const { + TracedValue::SetIDRef(this, state, "lthi"); + if (tile_manager_) { + state->BeginDictionary("tile_manager"); + tile_manager_->BasicStateAsValueInto(state); + state->EndDictionary(); + } } void LayerTreeHostImpl::SetDebugState( @@ -3043,13 +3424,21 @@ void LayerTreeHostImpl::CreateUIResource(UIResourceId uid, DeleteUIResource(uid); ResourceFormat format = resource_provider_->best_texture_format(); - if (bitmap.GetFormat() == UIResourceBitmap::ETC1) - format = ETC1; - id = resource_provider_->CreateResource( - bitmap.GetSize(), - wrap_mode, - ResourceProvider::TextureUsageAny, - format); + switch (bitmap.GetFormat()) { + case UIResourceBitmap::RGBA8: + break; + case UIResourceBitmap::ALPHA_8: + format = ALPHA_8; + break; + case UIResourceBitmap::ETC1: + format = ETC1; + break; + } + id = + resource_provider_->CreateResource(bitmap.GetSize(), + wrap_mode, + ResourceProvider::TextureHintImmutable, + format); UIResourceData data; data.resource_id = id; @@ -3140,6 +3529,12 @@ void LayerTreeHostImpl::NotifySwapPromiseMonitorsOfSetNeedsRedraw() { (*it)->OnSetNeedsRedrawOnImpl(); } +void LayerTreeHostImpl::NotifySwapPromiseMonitorsOfForwardingToMainThread() { + std::set<SwapPromiseMonitor*>::iterator it = swap_promise_monitor_.begin(); + for (; it != swap_promise_monitor_.end(); it++) + (*it)->OnForwardScrollUpdateToMainThreadOnImpl(); +} + void LayerTreeHostImpl::RegisterPictureLayerImpl(PictureLayerImpl* layer) { DCHECK(std::find(picture_layers_.begin(), picture_layers_.end(), layer) == picture_layers_.end()); diff --git a/chromium/cc/trees/layer_tree_host_impl.h b/chromium/cc/trees/layer_tree_host_impl.h index fe9afc219e6..2309ef77d5f 100644 --- a/chromium/cc/trees/layer_tree_host_impl.h +++ b/chromium/cc/trees/layer_tree_host_impl.h @@ -31,16 +31,18 @@ #include "cc/quads/render_pass.h" #include "cc/resources/resource_provider.h" #include "cc/resources/tile_manager.h" +#include "cc/scheduler/begin_frame_source.h" #include "cc/scheduler/draw_result.h" #include "skia/ext/refptr.h" #include "third_party/skia/include/core/SkColor.h" -#include "ui/gfx/rect.h" +#include "ui/gfx/geometry/rect.h" namespace cc { class CompletionEvent; class CompositorFrameMetadata; class DebugRectHistory; +class EvictionTilePriorityQueue; class FrameRateCounter; class LayerImpl; class LayerTreeHostImplTimeSourceAdapter; @@ -49,6 +51,7 @@ class MemoryHistory; class PageScaleAnimation; class PaintTimeCounter; class PictureLayerImpl; +class RasterTilePriorityQueue; class RasterWorkerPool; class RenderPassDrawQuad; class RenderingStatsInstrumentation; @@ -71,7 +74,6 @@ class LayerTreeHostImplClient { virtual void SetMaxSwapsPendingOnImplThread(int max) = 0; virtual void DidSwapBuffersOnImplThread() = 0; virtual void DidSwapBuffersCompleteOnImplThread() = 0; - virtual void BeginFrame(const BeginFrameArgs& args) = 0; virtual void OnCanDrawStateChanged(bool can_draw) = 0; virtual void NotifyReadyToActivate() = 0; // Please call these 3 functions through @@ -94,7 +96,7 @@ class LayerTreeHostImplClient { virtual void PostDelayedScrollbarFadeOnImplThread( const base::Closure& start_fade, base::TimeDelta delay) = 0; - virtual void DidActivatePendingTree() = 0; + virtual void DidActivateSyncTree() = 0; virtual void DidManageTiles() = 0; protected: @@ -110,6 +112,7 @@ class CC_EXPORT LayerTreeHostImpl public OutputSurfaceClient, public TopControlsManagerClient, public ScrollbarAnimationControllerClient, + public BeginFrameSourceMixIn, public base::SupportsWeakPtr<LayerTreeHostImpl> { public: static scoped_ptr<LayerTreeHostImpl> Create( @@ -117,50 +120,54 @@ class CC_EXPORT LayerTreeHostImpl LayerTreeHostImplClient* client, Proxy* proxy, RenderingStatsInstrumentation* rendering_stats_instrumentation, - SharedBitmapManager* manager, + SharedBitmapManager* shared_bitmap_manager, + gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, int id); - virtual ~LayerTreeHostImpl(); + ~LayerTreeHostImpl() override; + + // BeginFrameSourceMixIn implementation + void OnNeedsBeginFramesChange(bool needs_begin_frames) override; // InputHandler implementation - virtual void BindToClient(InputHandlerClient* client) OVERRIDE; - virtual InputHandler::ScrollStatus ScrollBegin( + void BindToClient(InputHandlerClient* client) override; + InputHandler::ScrollStatus ScrollBegin( + const gfx::Point& viewport_point, + InputHandler::ScrollInputType type) override; + InputHandler::ScrollStatus ScrollAnimated( const gfx::Point& viewport_point, - InputHandler::ScrollInputType type) OVERRIDE; - virtual bool ScrollBy(const gfx::Point& viewport_point, - const gfx::Vector2dF& scroll_delta) OVERRIDE; - virtual bool ScrollVerticallyByPage(const gfx::Point& viewport_point, - ScrollDirection direction) OVERRIDE; - virtual void SetRootLayerScrollOffsetDelegate( - LayerScrollOffsetDelegate* root_layer_scroll_offset_delegate) OVERRIDE; - virtual void OnRootLayerDelegatedScrollOffsetChanged() OVERRIDE; - virtual void ScrollEnd() OVERRIDE; - virtual InputHandler::ScrollStatus FlingScrollBegin() OVERRIDE; - virtual void MouseMoveAt(const gfx::Point& viewport_point) OVERRIDE; - virtual void PinchGestureBegin() OVERRIDE; - virtual void PinchGestureUpdate(float magnify_delta, - const gfx::Point& anchor) OVERRIDE; - virtual void PinchGestureEnd() OVERRIDE; - virtual void StartPageScaleAnimation(const gfx::Vector2d& target_offset, - bool anchor_point, - float page_scale, - base::TimeDelta duration) OVERRIDE; - virtual void SetNeedsAnimate() OVERRIDE; - virtual bool IsCurrentlyScrollingLayerAt( + const gfx::Vector2dF& scroll_delta) override; + InputHandlerScrollResult ScrollBy( const gfx::Point& viewport_point, - InputHandler::ScrollInputType type) OVERRIDE; - virtual bool HaveTouchEventHandlersAt( - const gfx::Point& viewport_port) OVERRIDE; - virtual scoped_ptr<SwapPromiseMonitor> CreateLatencyInfoSwapPromiseMonitor( - ui::LatencyInfo* latency) OVERRIDE; + const gfx::Vector2dF& scroll_delta) override; + bool ScrollVerticallyByPage(const gfx::Point& viewport_point, + ScrollDirection direction) override; + void SetRootLayerScrollOffsetDelegate( + LayerScrollOffsetDelegate* root_layer_scroll_offset_delegate) override; + void OnRootLayerDelegatedScrollOffsetChanged() override; + void ScrollEnd() override; + InputHandler::ScrollStatus FlingScrollBegin() override; + void MouseMoveAt(const gfx::Point& viewport_point) override; + void PinchGestureBegin() override; + void PinchGestureUpdate(float magnify_delta, + const gfx::Point& anchor) override; + void PinchGestureEnd() override; + void SetNeedsAnimate() override; + bool IsCurrentlyScrollingLayerAt(const gfx::Point& viewport_point, + InputHandler::ScrollInputType type) override; + bool HaveTouchEventHandlersAt(const gfx::Point& viewport_port) override; + scoped_ptr<SwapPromiseMonitor> CreateLatencyInfoSwapPromiseMonitor( + ui::LatencyInfo* latency) override; // TopControlsManagerClient implementation. - virtual void DidChangeTopControlsPosition() OVERRIDE; - virtual bool HaveRootScrollLayer() const OVERRIDE; + void SetControlsTopOffset(float offset) override; + float ControlsTopOffset() const override; + void DidChangeTopControlsPosition() override; + bool HaveRootScrollLayer() const override; struct CC_EXPORT FrameData : public RenderPassSink { FrameData(); - virtual ~FrameData(); - scoped_ptr<base::Value> AsValue() const; + ~FrameData() override; + void AsValueInto(base::debug::TracedValue* value) const; std::vector<gfx::Rect> occluding_screen_space_rects; std::vector<gfx::Rect> non_occluding_screen_space_rects; @@ -172,7 +179,7 @@ class CC_EXPORT LayerTreeHostImpl bool has_no_damage; // RenderPassSink implementation. - virtual void AppendRenderPass(scoped_ptr<RenderPass> render_pass) OVERRIDE; + void AppendRenderPass(scoped_ptr<RenderPass> render_pass) override; }; virtual void BeginMainFrameAborted(bool did_handle); @@ -213,53 +220,53 @@ class CC_EXPORT LayerTreeHostImpl // Resets all of the trees to an empty state. void ResetTreesForTesting(); - bool device_viewport_valid_for_tile_management() const { - return device_viewport_valid_for_tile_management_; - } + DrawMode GetDrawMode() const; // Viewport size in draw space: this size is in physical pixels and is used // for draw properties, tilings, quads and render passes. gfx::Size DrawViewportSize() const; - // Viewport size for scrolling and fixed-position compensation. This value - // excludes the URL bar and non-overlay scrollbars and is in DIP (and - // invariant relative to page scale). - gfx::SizeF UnscaledScrollableViewportSize() const; - float VerticalAdjust() const; + // Viewport rect in view space used for tiling prioritization. + const gfx::Rect ViewportRectForTilePriority() const; // RendererClient implementation. - virtual void SetFullRootLayerDamage() OVERRIDE; - virtual void RunOnDemandRasterTask(Task* on_demand_raster_task) OVERRIDE; + void SetFullRootLayerDamage() override; // TileManagerClient implementation. - virtual const std::vector<PictureLayerImpl*>& GetPictureLayers() OVERRIDE; - virtual void NotifyReadyToActivate() OVERRIDE; - virtual void NotifyTileStateChanged(const Tile* tile) OVERRIDE; + const std::vector<PictureLayerImpl*>& GetPictureLayers() const override; + void NotifyReadyToActivate() override; + void NotifyTileStateChanged(const Tile* tile) override; + void BuildRasterQueue(RasterTilePriorityQueue* queue, + TreePriority tree_priority) override; + void BuildEvictionQueue(EvictionTilePriorityQueue* queue, + TreePriority tree_priority) override; // ScrollbarAnimationControllerClient implementation. - virtual void PostDelayedScrollbarFade(const base::Closure& start_fade, - base::TimeDelta delay) OVERRIDE; - virtual void SetNeedsScrollbarAnimationFrame() OVERRIDE; + void PostDelayedScrollbarFade(const base::Closure& start_fade, + base::TimeDelta delay) override; + void SetNeedsScrollbarAnimationFrame() override; // OutputSurfaceClient implementation. - virtual void DeferredInitialize() OVERRIDE; - virtual void ReleaseGL() OVERRIDE; - virtual void CommitVSyncParameters(base::TimeTicks timebase, - base::TimeDelta interval) OVERRIDE; - virtual void SetNeedsRedrawRect(const gfx::Rect& rect) OVERRIDE; - virtual void BeginFrame(const BeginFrameArgs& args) OVERRIDE; - virtual void SetExternalDrawConstraints( + void DeferredInitialize() override; + void ReleaseGL() override; + void CommitVSyncParameters(base::TimeTicks timebase, + base::TimeDelta interval) override; + void SetNeedsRedrawRect(const gfx::Rect& rect) override; + void BeginFrame(const BeginFrameArgs& args) override; + + void SetExternalDrawConstraints( const gfx::Transform& transform, const gfx::Rect& viewport, const gfx::Rect& clip, - bool valid_for_tile_management) OVERRIDE; - virtual void DidLoseOutputSurface() OVERRIDE; - virtual void DidSwapBuffers() OVERRIDE; - virtual void DidSwapBuffersComplete() OVERRIDE; - virtual void ReclaimResources(const CompositorFrameAck* ack) OVERRIDE; - virtual void SetMemoryPolicy(const ManagedMemoryPolicy& policy) OVERRIDE; - virtual void SetTreeActivationCallback(const base::Closure& callback) - OVERRIDE; + const gfx::Rect& viewport_rect_for_tile_priority, + const gfx::Transform& transform_for_tile_priority, + bool resourceless_software_draw) override; + void DidLoseOutputSurface() override; + void DidSwapBuffers() override; + void DidSwapBuffersComplete() override; + void ReclaimResources(const CompositorFrameAck* ack) override; + void SetMemoryPolicy(const ManagedMemoryPolicy& policy) override; + void SetTreeActivationCallback(const base::Closure& callback) override; // Called from LayerTreeImpl. void OnCanDrawStateChangedForTree(); @@ -275,7 +282,6 @@ class CC_EXPORT LayerTreeHostImpl int SourceAnimationFrameNumber() const; virtual bool InitializeRenderer(scoped_ptr<OutputSurface> output_surface); - bool IsContextLost(); TileManager* tile_manager() { return tile_manager_.get(); } void SetUseGpuRasterization(bool use_gpu); bool use_gpu_rasterization() const { return use_gpu_rasterization_; } @@ -287,7 +293,6 @@ class CC_EXPORT LayerTreeHostImpl const RendererCapabilitiesImpl& GetRendererCapabilities() const; virtual bool SwapBuffers(const FrameData& frame); - void SetNeedsBeginFrame(bool enable); virtual void WillBeginImplFrame(const BeginFrameArgs& args); void DidModifyTilePriorities(); @@ -295,17 +300,15 @@ class CC_EXPORT LayerTreeHostImpl const LayerTreeImpl* active_tree() const { return active_tree_.get(); } LayerTreeImpl* pending_tree() { return pending_tree_.get(); } const LayerTreeImpl* pending_tree() const { return pending_tree_.get(); } + LayerTreeImpl* recycle_tree() { return recycle_tree_.get(); } const LayerTreeImpl* recycle_tree() const { return recycle_tree_.get(); } // Returns the tree LTH synchronizes with. LayerTreeImpl* sync_tree() { - // In impl-side painting, synchronize to the pending tree so that it has - // time to raster before being displayed. - return settings_.impl_side_painting ? pending_tree_.get() - : active_tree_.get(); + return pending_tree_ ? pending_tree_.get() : active_tree_.get(); } virtual void CreatePendingTree(); virtual void UpdateVisibleTiles(); - virtual void ActivatePendingTree(); + virtual void ActivateSyncTree(); // Shortcuts to layers on the active tree. LayerImpl* RootLayer() const; @@ -319,8 +322,10 @@ class CC_EXPORT LayerTreeHostImpl bool scroll_affects_scroll_handler() const { return scroll_affects_scroll_handler_; } + void QueueSwapPromiseForMainThreadScrollUpdate( + scoped_ptr<SwapPromise> swap_promise); - bool IsCurrentlyScrolling() const; + bool IsActivelyScrolling() const; virtual void SetVisible(bool visible); bool visible() const { return visible_; } @@ -336,9 +341,6 @@ class CC_EXPORT LayerTreeHostImpl void SetViewportSize(const gfx::Size& device_viewport_size); gfx::Size device_viewport_size() const { return device_viewport_size_; } - void SetOverdrawBottomHeight(float overdraw_bottom_height); - float overdraw_bottom_height() const { return overdraw_bottom_height_; } - void SetOverhangUIResource(UIResourceId overhang_ui_resource_id, const gfx::Size& overhang_ui_resource_size); @@ -412,19 +414,26 @@ class CC_EXPORT LayerTreeHostImpl bool pinch_gesture_active() const { return pinch_gesture_active_; } void SetTreePriority(TreePriority priority); + TreePriority GetTreePriority() const; - void UpdateCurrentFrameTime(); - void ResetCurrentFrameTimeForNextFrame(); - virtual base::TimeTicks CurrentFrameTimeTicks(); + void UpdateCurrentBeginFrameArgs(const BeginFrameArgs& args); + void ResetCurrentBeginFrameArgsForNextFrame(); + virtual BeginFrameArgs CurrentBeginFrameArgs() const; // Expected time between two begin impl frame calls. base::TimeDelta begin_impl_frame_interval() const { return begin_impl_frame_interval_; } - scoped_ptr<base::Value> AsValue() const { return AsValueWithFrame(NULL); } - scoped_ptr<base::Value> AsValueWithFrame(FrameData* frame) const; - scoped_ptr<base::Value> ActivationStateAsValue() const; + void AsValueInto(base::debug::TracedValue* value) const override; + void AsValueWithFrameInto(FrameData* frame, + base::debug::TracedValue* value) const; + scoped_refptr<base::debug::ConvertableToTraceFormat> AsValue() const; + scoped_refptr<base::debug::ConvertableToTraceFormat> AsValueWithFrame( + FrameData* frame) const; + scoped_refptr<base::debug::ConvertableToTraceFormat> ActivationStateAsValue() + const; + void ActivationStateAsValueInto(base::debug::TracedValue* value) const; bool page_scale_animation_active() const { return !!page_scale_animation_; } @@ -465,22 +474,39 @@ class CC_EXPORT LayerTreeHostImpl void RegisterPictureLayerImpl(PictureLayerImpl* layer); void UnregisterPictureLayerImpl(PictureLayerImpl* layer); + void GetPictureLayerImplPairs( + std::vector<PictureLayerImpl::Pair>* layers) const; + + void SetTopControlsLayoutHeight(float height); + + void SetRequiresHighResToDraw() { requires_high_res_to_draw_ = true; } + void ResetRequiresHighResToDraw() { requires_high_res_to_draw_ = false; } + bool RequiresHighResToDraw() const { return requires_high_res_to_draw_; } + + // Only valid for synchronous (non-scheduled) single-threaded case. + void SynchronouslyInitializeAllTiles(); + + bool CanUseZeroCopyRasterizer() const; + bool CanUseOneCopyRasterizer() const; + virtual void CreateResourceAndRasterWorkerPool( + scoped_ptr<RasterWorkerPool>* raster_worker_pool, + scoped_ptr<ResourcePool>* resource_pool, + scoped_ptr<ResourcePool>* staging_resource_pool); + protected: LayerTreeHostImpl( const LayerTreeSettings& settings, LayerTreeHostImplClient* client, Proxy* proxy, RenderingStatsInstrumentation* rendering_stats_instrumentation, - SharedBitmapManager* manager, + SharedBitmapManager* shared_bitmap_manager, + gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, int id); - gfx::SizeF ComputeInnerViewportContainerSize() const; - void UpdateInnerViewportContainerSize(); + void UpdateViewportContainerSizes(); // Virtual for testing. virtual void AnimateLayers(base::TimeTicks monotonic_time); - - // Virtual for testing. virtual base::TimeDelta LowFrequencyAnimationInterval() const; const AnimationRegistrar::AnimationControllerMap& @@ -500,14 +526,21 @@ class CC_EXPORT LayerTreeHostImpl void ReleaseTreeResources(); void EnforceZeroBudget(bool zero_budget); - bool UseZeroCopyTextureUpload() const; - bool UseOneCopyTextureUpload() const; + bool UsePendingTreeForSync() const; + bool IsSynchronousSingleThreaded() const; + // Scroll by preferring to move the outer viewport first, only moving the + // inner if the outer is at its scroll extents. void ScrollViewportBy(gfx::Vector2dF scroll_delta); + // Scroll by preferring to move the inner viewport first, only moving the + // outer if the inner is at its scroll extents. + void ScrollViewportInnerFirst(gfx::Vector2dF scroll_delta); void AnimatePageScale(base::TimeTicks monotonic_time); void AnimateScrollbars(base::TimeTicks monotonic_time); void AnimateTopControls(base::TimeTicks monotonic_time); + bool ShouldTopControlsConsumeScroll(const gfx::Vector2dF& scroll_delta) const; + gfx::Vector2dF ScrollLayerWithViewportSpaceDelta( LayerImpl* layer_impl, float scale_from_viewport_to_screen_space, @@ -551,6 +584,7 @@ class CC_EXPORT LayerTreeHostImpl void MarkUIResourceNotEvicted(UIResourceId uid); void NotifySwapPromiseMonitorsOfSetNeedsRedraw(); + void NotifySwapPromiseMonitorsOfForwardingToMainThread(); typedef base::hash_map<UIResourceId, UIResourceData> UIResourceMap; @@ -562,7 +596,6 @@ class CC_EXPORT LayerTreeHostImpl std::set<UIResourceId> evicted_ui_resources_; scoped_ptr<OutputSurface> output_surface_; - scoped_refptr<ContextProvider> offscreen_context_provider_; // |resource_provider_| and |tile_manager_| can be NULL, e.g. when using tile- // free rendering - see OutputSurface::ForcedDrawToSoftwareDevice(). @@ -574,10 +607,6 @@ class CC_EXPORT LayerTreeHostImpl scoped_ptr<ResourcePool> staging_resource_pool_; scoped_ptr<Renderer> renderer_; - TaskGraphRunner synchronous_task_graph_runner_; - TaskGraphRunner* on_demand_task_graph_runner_; - NamespaceToken on_demand_task_namespace_; - GlobalStateThatImpactsTilePriority global_tile_state_; // Tree currently being drawn. @@ -597,6 +626,7 @@ class CC_EXPORT LayerTreeHostImpl bool wheel_scrolling_; bool scroll_affects_scroll_handler_; int scroll_layer_id_when_mouse_over_scrollbar_; + ScopedPtrVector<SwapPromise> swap_promises_for_main_thread_scroll_update_; bool tile_priorities_dirty_; @@ -647,25 +677,22 @@ class CC_EXPORT LayerTreeHostImpl UIResourceId overhang_ui_resource_id_; gfx::Size overhang_ui_resource_size_; - // Vertical amount of the viewport size that's known to covered by a - // browser-side UI element, such as an on-screen-keyboard. This affects - // scrollable size since we want to still be able to scroll to the bottom of - // the page when the keyboard is up. - float overdraw_bottom_height_; - // Optional top-level constraints that can be set by the OutputSurface. // - external_transform_ applies a transform above the root layer // - external_viewport_ is used DrawProperties, tile management and // glViewport/window projection matrix. // - external_clip_ specifies a top-level clip rect + // - viewport_rect_for_tile_priority_ is the rect in view space used for + // tiling priority. gfx::Transform external_transform_; gfx::Rect external_viewport_; gfx::Rect external_clip_; - bool device_viewport_valid_for_tile_management_; + gfx::Rect viewport_rect_for_tile_priority_; + bool resourceless_software_draw_; gfx::Rect viewport_damage_rect_; - base::TimeTicks current_frame_timeticks_; + BeginFrameArgs current_begin_frame_args_; // Expected time between two begin impl frame calls. base::TimeDelta begin_impl_frame_interval_; @@ -674,23 +701,23 @@ class CC_EXPORT LayerTreeHostImpl RenderingStatsInstrumentation* rendering_stats_instrumentation_; MicroBenchmarkControllerImpl micro_benchmark_controller_; + scoped_ptr<TaskGraphRunner> single_thread_synchronous_task_graph_runner_; bool need_to_update_visible_tiles_before_draw_; -#if DCHECK_IS_ON - bool did_lose_called_; -#endif // Optional callback to notify of new tree activations. base::Closure tree_activation_callback_; SharedBitmapManager* shared_bitmap_manager_; + gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager_; int id_; std::set<SwapPromiseMonitor*> swap_promise_monitor_; - size_t transfer_buffer_memory_limit_; - std::vector<PictureLayerImpl*> picture_layers_; + std::vector<PictureLayerImpl::Pair> picture_layer_pairs_; + + bool requires_high_res_to_draw_; DISALLOW_COPY_AND_ASSIGN(LayerTreeHostImpl); }; diff --git a/chromium/cc/trees/layer_tree_host_impl_unittest.cc b/chromium/cc/trees/layer_tree_host_impl_unittest.cc index 9ada4029bbd..adc11d0cdc7 100644 --- a/chromium/cc/trees/layer_tree_host_impl_unittest.cc +++ b/chromium/cc/trees/layer_tree_host_impl_unittest.cc @@ -4,6 +4,7 @@ #include "cc/trees/layer_tree_host_impl.h" +#include <algorithm> #include <cmath> #include "base/bind.h" @@ -13,6 +14,7 @@ #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/page_scale_animation.h" #include "cc/input/top_controls_manager.h" #include "cc/layers/append_quads_data.h" #include "cc/layers/delegated_renderer_layer_impl.h" @@ -20,7 +22,6 @@ #include "cc/layers/io_surface_layer_impl.h" #include "cc/layers/layer_impl.h" #include "cc/layers/painted_scrollbar_layer_impl.h" -#include "cc/layers/quad_sink.h" #include "cc/layers/render_surface_impl.h" #include "cc/layers/solid_color_layer_impl.h" #include "cc/layers/solid_color_scrollbar_layer_impl.h" @@ -39,17 +40,18 @@ #include "cc/quads/tile_draw_quad.h" #include "cc/resources/layer_tiling_data.h" #include "cc/test/animation_test_common.h" +#include "cc/test/begin_frame_args_test.h" #include "cc/test/fake_layer_tree_host_impl.h" #include "cc/test/fake_output_surface.h" #include "cc/test/fake_output_surface_client.h" #include "cc/test/fake_picture_layer_impl.h" #include "cc/test/fake_picture_pile_impl.h" #include "cc/test/fake_proxy.h" -#include "cc/test/fake_rendering_stats_instrumentation.h" #include "cc/test/fake_video_frame_provider.h" #include "cc/test/geometry_test_utils.h" #include "cc/test/layer_test_common.h" #include "cc/test/render_pass_test_common.h" +#include "cc/test/test_gpu_memory_buffer_manager.h" #include "cc/test/test_shared_bitmap_manager.h" #include "cc/test/test_web_graphics_context_3d.h" #include "cc/trees/layer_tree_impl.h" @@ -59,9 +61,9 @@ #include "testing/gtest/include/gtest/gtest.h" #include "third_party/skia/include/core/SkMallocPixelRef.h" #include "ui/gfx/frame_time.h" -#include "ui/gfx/rect_conversions.h" -#include "ui/gfx/size_conversions.h" -#include "ui/gfx/vector2d_conversions.h" +#include "ui/gfx/geometry/rect_conversions.h" +#include "ui/gfx/geometry/size_conversions.h" +#include "ui/gfx/geometry/vector2d_conversions.h" using ::testing::Mock; using ::testing::Return; @@ -77,10 +79,12 @@ class LayerTreeHostImplTest : public testing::Test, public LayerTreeHostImplClient { public: LayerTreeHostImplTest() - : proxy_(base::MessageLoopProxy::current()), + : proxy_(base::MessageLoopProxy::current(), + base::MessageLoopProxy::current()), always_impl_thread_(&proxy_), always_main_thread_blocked_(&proxy_), - shared_bitmap_manager_(new TestSharedBitmapManager()), + shared_bitmap_manager_(new TestSharedBitmapManager), + gpu_memory_buffer_manager_(new TestGpuMemoryBufferManager), on_can_draw_state_changed_called_(false), did_notify_ready_to_activate_(false), did_request_commit_(false), @@ -100,68 +104,60 @@ class LayerTreeHostImplTest : public testing::Test, settings.impl_side_painting = true; settings.texture_id_allocation_chunk_size = 1; settings.report_overscroll_only_for_scrollable_axes = true; + settings.use_pinch_virtual_viewport = true; return settings; } - virtual void SetUp() OVERRIDE { + virtual void SetUp() override { CreateHostImpl(DefaultSettings(), CreateOutputSurface()); } - virtual void TearDown() OVERRIDE {} + virtual void TearDown() override {} - virtual void UpdateRendererCapabilitiesOnImplThread() OVERRIDE {} - virtual void DidLoseOutputSurfaceOnImplThread() OVERRIDE {} - virtual void CommitVSyncParameters(base::TimeTicks timebase, - base::TimeDelta interval) OVERRIDE {} - virtual void SetEstimatedParentDrawTime(base::TimeDelta draw_time) OVERRIDE {} - virtual void SetMaxSwapsPendingOnImplThread(int max) OVERRIDE {} - virtual void DidSwapBuffersOnImplThread() OVERRIDE {} - virtual void DidSwapBuffersCompleteOnImplThread() OVERRIDE {} - virtual void BeginFrame(const BeginFrameArgs& args) OVERRIDE {} - virtual void OnCanDrawStateChanged(bool can_draw) OVERRIDE { + void UpdateRendererCapabilitiesOnImplThread() override {} + void DidLoseOutputSurfaceOnImplThread() override {} + void CommitVSyncParameters(base::TimeTicks timebase, + base::TimeDelta interval) override {} + void SetEstimatedParentDrawTime(base::TimeDelta draw_time) override {} + void SetMaxSwapsPendingOnImplThread(int max) override {} + void DidSwapBuffersOnImplThread() override {} + void DidSwapBuffersCompleteOnImplThread() override {} + void OnCanDrawStateChanged(bool can_draw) override { on_can_draw_state_changed_called_ = true; } - virtual void NotifyReadyToActivate() OVERRIDE { + void NotifyReadyToActivate() override { did_notify_ready_to_activate_ = true; - host_impl_->ActivatePendingTree(); + host_impl_->ActivateSyncTree(); } - virtual void SetNeedsRedrawOnImplThread() OVERRIDE { + void SetNeedsRedrawOnImplThread() override { did_request_redraw_ = true; } + void SetNeedsRedrawRectOnImplThread(const gfx::Rect& damage_rect) override { did_request_redraw_ = true; } - virtual void SetNeedsRedrawRectOnImplThread( - const gfx::Rect& damage_rect) OVERRIDE { - did_request_redraw_ = true; - } - virtual void SetNeedsAnimateOnImplThread() OVERRIDE { - did_request_animate_ = true; - } - virtual void SetNeedsManageTilesOnImplThread() OVERRIDE { + void SetNeedsAnimateOnImplThread() override { did_request_animate_ = true; } + void SetNeedsManageTilesOnImplThread() override { did_request_manage_tiles_ = true; } - virtual void DidInitializeVisibleTileOnImplThread() OVERRIDE { + void DidInitializeVisibleTileOnImplThread() override { did_upload_visible_tile_ = true; } - virtual void SetNeedsCommitOnImplThread() OVERRIDE { - did_request_commit_ = true; - } - virtual void PostAnimationEventsToMainThreadOnImplThread( - scoped_ptr<AnimationEventsVector> events) OVERRIDE {} - virtual bool ReduceContentsTextureMemoryOnImplThread( - size_t limit_bytes, int priority_cutoff) OVERRIDE { + void SetNeedsCommitOnImplThread() override { did_request_commit_ = true; } + void PostAnimationEventsToMainThreadOnImplThread( + scoped_ptr<AnimationEventsVector> events) override {} + bool ReduceContentsTextureMemoryOnImplThread(size_t limit_bytes, + int priority_cutoff) override { current_limit_bytes_ = limit_bytes; current_priority_cutoff_value_ = priority_cutoff; return reduce_memory_result_; } - virtual bool IsInsideDraw() OVERRIDE { return false; } - virtual void RenewTreePriority() OVERRIDE {} - virtual void PostDelayedScrollbarFadeOnImplThread( - const base::Closure& start_fade, - base::TimeDelta delay) OVERRIDE { + bool IsInsideDraw() override { return false; } + void RenewTreePriority() override {} + void PostDelayedScrollbarFadeOnImplThread(const base::Closure& start_fade, + base::TimeDelta delay) override { scrollbar_fade_start_ = start_fade; requested_scrollbar_animation_delay_ = delay; } - virtual void DidActivatePendingTree() OVERRIDE {} - virtual void DidManageTiles() OVERRIDE {} + void DidActivateSyncTree() override {} + void DidManageTiles() override {} void set_reduce_memory_result(bool reduce_memory_result) { reduce_memory_result_ = reduce_memory_result; @@ -174,6 +170,7 @@ class LayerTreeHostImplTest : public testing::Test, &proxy_, &stats_instrumentation_, shared_bitmap_manager_.get(), + gpu_memory_buffer_manager_.get(), 0); bool init = host_impl_->InitializeRenderer(output_surface.Pass()); host_impl_->SetViewportSize(gfx::Size(10, 10)); @@ -237,7 +234,7 @@ class LayerTreeHostImplTest : public testing::Test, LayerImpl::Create(layer_tree_impl, kInnerViewportScrollLayerId); LayerImpl* scroll_layer = scroll.get(); scroll->SetIsContainerForFixedPositionLayers(true); - scroll->SetScrollOffset(gfx::Vector2d()); + scroll->SetScrollOffset(gfx::ScrollOffset()); scoped_ptr<LayerImpl> clip = LayerImpl::Create(layer_tree_impl, kInnerViewportClipLayerId); @@ -322,7 +319,7 @@ class LayerTreeHostImplTest : public testing::Test, on_can_draw_state_changed_called_ = false; // Toggle the root layer to make sure it toggles can_draw - host_impl_->active_tree()->SetRootLayer(scoped_ptr<LayerImpl>()); + host_impl_->active_tree()->SetRootLayer(nullptr); EXPECT_FALSE(host_impl_->CanDraw()); EXPECT_TRUE(on_can_draw_state_changed_called_); on_can_draw_state_changed_called_ = false; @@ -378,7 +375,7 @@ class LayerTreeHostImplTest : public testing::Test, protected: virtual scoped_ptr<OutputSurface> CreateOutputSurface() { - return FakeOutputSurface::Create3d().PassAs<OutputSurface>(); + return FakeOutputSurface::Create3d(); } void DrawOneFrame() { @@ -391,7 +388,8 @@ class LayerTreeHostImplTest : public testing::Test, DebugScopedSetImplThread always_impl_thread_; DebugScopedSetMainThreadBlocked always_main_thread_blocked_; - scoped_ptr<SharedBitmapManager> shared_bitmap_manager_; + scoped_ptr<TestSharedBitmapManager> shared_bitmap_manager_; + scoped_ptr<TestGpuMemoryBufferManager> gpu_memory_buffer_manager_; scoped_ptr<LayerTreeHostImpl> host_impl_; FakeRenderingStatsInstrumentation stats_instrumentation_; bool on_can_draw_state_changed_called_; @@ -414,9 +412,8 @@ TEST_F(LayerTreeHostImplTest, NotifyIfCanDrawChanged) { } TEST_F(LayerTreeHostImplTest, CanDrawIncompleteFrames) { - scoped_ptr<FakeOutputSurface> output_surface( - FakeOutputSurface::CreateAlwaysDrawAndSwap3d()); - CreateHostImpl(DefaultSettings(), output_surface.PassAs<OutputSurface>()); + CreateHostImpl(DefaultSettings(), + FakeOutputSurface::CreateAlwaysDrawAndSwap3d()); bool always_draw = true; CheckNotifyCalledIfCanDrawChanged(always_draw); @@ -459,7 +456,7 @@ TEST_F(LayerTreeHostImplTest, ScrollDeltaTreeButNoChanges) { } TEST_F(LayerTreeHostImplTest, ScrollDeltaRepeatedScrolls) { - gfx::Vector2d scroll_offset(20, 30); + gfx::ScrollOffset scroll_offset(20, 30); gfx::Vector2d scroll_delta(11, -15); { scoped_ptr<LayerImpl> root_clip = @@ -515,6 +512,20 @@ TEST_F(LayerTreeHostImplTest, ScrollRootCallsCommitAndRedraw) { EXPECT_TRUE(did_request_commit_); } +TEST_F(LayerTreeHostImplTest, ScrollActiveOnlyAfterScrollMovement) { + SetupScrollAndContentsLayers(gfx::Size(100, 100)); + host_impl_->SetViewportSize(gfx::Size(50, 50)); + DrawFrame(); + + EXPECT_EQ(InputHandler::ScrollStarted, + host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel)); + EXPECT_FALSE(host_impl_->IsActivelyScrolling()); + host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10)); + EXPECT_TRUE(host_impl_->IsActivelyScrolling()); + host_impl_->ScrollEnd(); + EXPECT_FALSE(host_impl_->IsActivelyScrolling()); +} + TEST_F(LayerTreeHostImplTest, ScrollWithoutRootLayer) { // We should not crash when trying to scroll an empty layer tree. EXPECT_EQ(InputHandler::ScrollIgnored, @@ -526,12 +537,9 @@ TEST_F(LayerTreeHostImplTest, ScrollWithoutRenderer) { TestWebGraphicsContext3D::Create(); context_owned->set_context_lost(true); - scoped_ptr<FakeOutputSurface> output_surface(FakeOutputSurface::Create3d( - context_owned.Pass())); - // Initialization will fail. - EXPECT_FALSE(CreateHostImpl(DefaultSettings(), - output_surface.PassAs<OutputSurface>())); + EXPECT_FALSE(CreateHostImpl( + DefaultSettings(), FakeOutputSurface::Create3d(context_owned.Pass()))); SetupScrollAndContentsLayers(gfx::Size(100, 100)); @@ -769,27 +777,40 @@ TEST_F(LayerTreeHostImplTest, ScrollByReturnsCorrectValue) { host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture)); // Trying to scroll to the left/top will not succeed. - EXPECT_FALSE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(-10, 0))); - EXPECT_FALSE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, -10))); - EXPECT_FALSE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(-10, -10))); + EXPECT_FALSE( + host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(-10, 0)).did_scroll); + EXPECT_FALSE( + host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, -10)).did_scroll); + EXPECT_FALSE( + host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(-10, -10)).did_scroll); // Scrolling to the right/bottom will succeed. - EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(10, 0))); - EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10))); - EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(10, 10))); + EXPECT_TRUE( + host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(10, 0)).did_scroll); + EXPECT_TRUE( + host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10)).did_scroll); + EXPECT_TRUE( + host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(10, 10)).did_scroll); // Scrolling to left/top will now succeed. - EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(-10, 0))); - EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, -10))); - EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(-10, -10))); + EXPECT_TRUE( + host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(-10, 0)).did_scroll); + EXPECT_TRUE( + host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, -10)).did_scroll); + EXPECT_TRUE( + host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(-10, -10)).did_scroll); // Scrolling diagonally against an edge will succeed. - EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(10, -10))); - EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(-10, 0))); - EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(-10, 10))); + EXPECT_TRUE( + host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(10, -10)).did_scroll); + EXPECT_TRUE( + host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(-10, 0)).did_scroll); + EXPECT_TRUE( + host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(-10, 10)).did_scroll); // Trying to scroll more than the available space will also succeed. - EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(5000, 5000))); + EXPECT_TRUE( + host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(5000, 5000)).did_scroll); } TEST_F(LayerTreeHostImplTest, ScrollVerticallyByPageReturnsCorrectValue) { @@ -826,9 +847,7 @@ TEST_F(LayerTreeHostImplTest, ScrollVerticallyByPageReturnsCorrectValue) { gfx::Point(), SCROLL_BACKWARD)); } -// The user-scrollability breaks for zoomed-in pages. So disable this. -// http://crbug.com/322223 -TEST_F(LayerTreeHostImplTest, DISABLED_ScrollWithUserUnscrollableLayers) { +TEST_F(LayerTreeHostImplTest, ScrollWithUserUnscrollableLayers) { LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(200, 200)); host_impl_->SetViewportSize(gfx::Size(100, 100)); @@ -838,7 +857,7 @@ TEST_F(LayerTreeHostImplTest, DISABLED_ScrollWithUserUnscrollableLayers) { overflow->SetBounds(overflow_size); overflow->SetContentBounds(overflow_size); overflow->SetScrollClipLayer(scroll_layer->parent()->id()); - overflow->SetScrollOffset(gfx::Vector2d()); + overflow->SetScrollOffset(gfx::ScrollOffset()); overflow->SetPosition(gfx::PointF()); DrawFrame(); @@ -914,19 +933,10 @@ TEST_F(LayerTreeHostImplTest, ImplPinchZoom) { scroll_layer->SetScrollDelta(gfx::Vector2d()); float page_scale_delta = 2.f; - gfx::Vector2dF expected_container_size_delta( - container_layer->bounds().width(), container_layer->bounds().height()); - expected_container_size_delta.Scale((1.f - page_scale_delta) / - (page_scale_factor * page_scale_delta)); host_impl_->ScrollBegin(gfx::Point(50, 50), InputHandler::Gesture); host_impl_->PinchGestureBegin(); host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point(50, 50)); - // While the gesture is still active, the scroll layer should have a - // container size delta = container->bounds() * ((1.f - - // page_scale_delta)/()) - EXPECT_EQ(expected_container_size_delta, - scroll_layer->FixedContainerSizeDelta()); host_impl_->PinchGestureEnd(); host_impl_->ScrollEnd(); EXPECT_FALSE(did_request_animate_); @@ -938,7 +948,7 @@ TEST_F(LayerTreeHostImplTest, ImplPinchZoom) { host_impl_->ProcessScrollDeltas(); EXPECT_EQ(scroll_info->page_scale_delta, page_scale_delta); - EXPECT_EQ(gfx::Vector2d(75, 75).ToString(), + EXPECT_EQ(gfx::ScrollOffset(75.0, 75.0).ToString(), scroll_layer->MaxScrollOffset().ToString()); } @@ -972,59 +982,22 @@ TEST_F(LayerTreeHostImplTest, ImplPinchZoom) { } } -TEST_F(LayerTreeHostImplTest, MasksToBoundsDoesntClobberInnerContainerSize) { - SetupScrollAndContentsLayers(gfx::Size(100, 100)); - host_impl_->SetViewportSize(gfx::Size(50, 50)); - DrawFrame(); - - LayerImpl* scroll_layer = host_impl_->InnerViewportScrollLayer(); - LayerImpl* container_layer = scroll_layer->scroll_clip_layer(); - DCHECK(scroll_layer); - - float min_page_scale = 1.f; - float max_page_scale = 4.f; - host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f, - min_page_scale, - max_page_scale); - - // If the container's masks_to_bounds is false, the viewport size should - // overwrite the inner viewport container layer's size. - { - EXPECT_EQ(gfx::Size(50, 50), - container_layer->bounds()); - container_layer->SetMasksToBounds(false); - - container_layer->SetBounds(gfx::Size(30, 25)); - EXPECT_EQ(gfx::Size(30, 25), - container_layer->bounds()); - - // This should cause a reset of the inner viewport container layer's bounds. - host_impl_->DidChangeTopControlsPosition(); - - EXPECT_EQ(gfx::Size(50, 50), - container_layer->bounds()); - } - - host_impl_->SetViewportSize(gfx::Size(50, 50)); - container_layer->SetBounds(gfx::Size(50, 50)); - - // If the container's masks_to_bounds is true, the viewport size should - // *NOT* overwrite the inner viewport container layer's size. - { - EXPECT_EQ(gfx::Size(50, 50), - container_layer->bounds()); - container_layer->SetMasksToBounds(true); - - container_layer->SetBounds(gfx::Size(30, 25)); - EXPECT_EQ(gfx::Size(30, 25), - container_layer->bounds()); +TEST_F(LayerTreeHostImplTest, ScrollWithSwapPromises) { + ui::LatencyInfo latency_info; + latency_info.trace_id = 1234; + scoped_ptr<SwapPromise> swap_promise( + new LatencyInfoSwapPromise(latency_info)); - // This should cause a reset of the inner viewport container layer's bounds. - host_impl_->DidChangeTopControlsPosition(); + SetupScrollAndContentsLayers(gfx::Size(100, 100)); + EXPECT_EQ(InputHandler::ScrollStarted, + host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture)); + host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10)); + host_impl_->QueueSwapPromiseForMainThreadScrollUpdate(swap_promise.Pass()); + host_impl_->ScrollEnd(); - EXPECT_EQ(gfx::Size(30, 25), - container_layer->bounds()); - } + scoped_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); + EXPECT_EQ(1u, scroll_info->swap_promises.size()); + EXPECT_EQ(latency_info.trace_id, scroll_info->swap_promises[0]->TraceId()); } TEST_F(LayerTreeHostImplTest, PinchGesture) { @@ -1085,7 +1058,7 @@ TEST_F(LayerTreeHostImplTest, PinchGesture) { min_page_scale, max_page_scale); scroll_layer->SetScrollDelta(gfx::Vector2d()); - scroll_layer->SetScrollOffset(gfx::Vector2d(50, 50)); + scroll_layer->SetScrollOffset(gfx::ScrollOffset(50, 50)); float page_scale_delta = 0.1f; host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture); @@ -1107,7 +1080,7 @@ TEST_F(LayerTreeHostImplTest, PinchGesture) { min_page_scale, max_page_scale); scroll_layer->SetScrollDelta(gfx::Vector2d()); - scroll_layer->SetScrollOffset(gfx::Vector2d(20, 20)); + scroll_layer->SetScrollOffset(gfx::ScrollOffset(20, 20)); float page_scale_delta = 1.f; host_impl_->ScrollBegin(gfx::Point(10, 10), InputHandler::Gesture); @@ -1129,7 +1102,7 @@ TEST_F(LayerTreeHostImplTest, PinchGesture) { min_page_scale, max_page_scale); scroll_layer->SetScrollDelta(gfx::Vector2d()); - scroll_layer->SetScrollOffset(gfx::Vector2d(20, 20)); + scroll_layer->SetScrollOffset(gfx::ScrollOffset(20, 20)); float page_scale_delta = 1.f; host_impl_->ScrollBegin(gfx::Point(10, 10), InputHandler::Gesture); @@ -1152,7 +1125,7 @@ TEST_F(LayerTreeHostImplTest, PinchGesture) { 0.5f, 4.f); scroll_layer->SetScrollDelta(gfx::Vector2d()); - scroll_layer->SetScrollOffset(gfx::Vector2d(0, 0)); + scroll_layer->SetScrollOffset(gfx::ScrollOffset(0, 0)); host_impl_->ScrollBegin(gfx::Point(0, 0), InputHandler::Gesture); host_impl_->PinchGestureBegin(); @@ -1191,11 +1164,16 @@ TEST_F(LayerTreeHostImplTest, PageScaleAnimation) { host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f, min_page_scale, max_page_scale); - scroll_layer->SetScrollOffset(gfx::Vector2d(50, 50)); + scroll_layer->SetScrollOffset(gfx::ScrollOffset(50, 50)); did_request_redraw_ = false; did_request_animate_ = false; - host_impl_->StartPageScaleAnimation(gfx::Vector2d(), false, 2.f, duration); + host_impl_->active_tree()->SetPageScaleAnimation( + gfx::Vector2d(), + false, + 2.f, + duration); + host_impl_->ActivateSyncTree(); EXPECT_FALSE(did_request_redraw_); EXPECT_TRUE(did_request_animate_); @@ -1229,12 +1207,13 @@ TEST_F(LayerTreeHostImplTest, PageScaleAnimation) { host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f, min_page_scale, max_page_scale); - scroll_layer->SetScrollOffset(gfx::Vector2d(50, 50)); + scroll_layer->SetScrollOffset(gfx::ScrollOffset(50, 50)); did_request_redraw_ = false; did_request_animate_ = false; - host_impl_->StartPageScaleAnimation( + host_impl_->active_tree()->SetPageScaleAnimation( gfx::Vector2d(25, 25), true, min_page_scale, duration); + host_impl_->ActivateSyncTree(); EXPECT_FALSE(did_request_redraw_); EXPECT_TRUE(did_request_animate_); @@ -1281,9 +1260,14 @@ TEST_F(LayerTreeHostImplTest, PageScaleAnimationNoOp) { host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f, min_page_scale, max_page_scale); - scroll_layer->SetScrollOffset(gfx::Vector2d(50, 50)); - - host_impl_->StartPageScaleAnimation(gfx::Vector2d(), true, 1.f, duration); + scroll_layer->SetScrollOffset(gfx::ScrollOffset(50, 50)); + + host_impl_->active_tree()->SetPageScaleAnimation( + gfx::Vector2d(), + true, + 1.f, + duration); + host_impl_->ActivateSyncTree(); host_impl_->Animate(start_time); host_impl_->Animate(halfway_through_animation); EXPECT_TRUE(did_request_redraw_); @@ -1297,6 +1281,101 @@ TEST_F(LayerTreeHostImplTest, PageScaleAnimationNoOp) { } } +TEST_F(LayerTreeHostImplTest, PageScaleAnimationTransferedOnSyncTreeActivate) { + host_impl_->CreatePendingTree(); + CreateScrollAndContentsLayers( + host_impl_->pending_tree(), + gfx::Size(100, 100)); + host_impl_->ActivateSyncTree(); + DrawFrame(); + + LayerImpl* scroll_layer = host_impl_->InnerViewportScrollLayer(); + DCHECK(scroll_layer); + + float min_page_scale = 0.5f; + float max_page_scale = 4.f; + host_impl_->sync_tree()->SetPageScaleFactorAndLimits(1.f, + min_page_scale, + max_page_scale); + host_impl_->ActivateSyncTree(); + + base::TimeTicks start_time = base::TimeTicks() + + base::TimeDelta::FromSeconds(1); + base::TimeDelta duration = base::TimeDelta::FromMilliseconds(100); + base::TimeTicks third_through_animation = start_time + duration / 3; + base::TimeTicks halfway_through_animation = start_time + duration / 2; + base::TimeTicks end_time = start_time + duration; + float target_scale = 2.f; + + scroll_layer->SetScrollOffset(gfx::ScrollOffset(50, 50)); + + // Make sure TakePageScaleAnimation works properly. + host_impl_->sync_tree()->SetPageScaleAnimation( + gfx::Vector2d(), + false, + target_scale, + duration); + scoped_ptr<PageScaleAnimation> psa = + host_impl_->sync_tree()->TakePageScaleAnimation(); + EXPECT_EQ(target_scale, psa->target_page_scale_factor()); + EXPECT_EQ(duration, psa->duration()); + EXPECT_EQ(nullptr, host_impl_->sync_tree()->TakePageScaleAnimation()); + + // Recreate the PSA. Nothing should happen here since the tree containing the + // PSA hasn't been activated yet. + did_request_redraw_ = false; + did_request_animate_ = false; + host_impl_->sync_tree()->SetPageScaleAnimation( + gfx::Vector2d(), + false, + target_scale, + duration); + host_impl_->Animate(halfway_through_animation); + EXPECT_FALSE(did_request_animate_); + EXPECT_FALSE(did_request_redraw_); + + // Activate the sync tree. This should cause the animation to become enabled. + // It should also clear the pointer on the sync tree. + host_impl_->ActivateSyncTree(); + EXPECT_EQ(nullptr, host_impl_->sync_tree()->TakePageScaleAnimation().get()); + EXPECT_FALSE(did_request_redraw_); + EXPECT_TRUE(did_request_animate_); + + // From here on, make sure the animation runs as normal. + did_request_redraw_ = false; + did_request_animate_ = false; + host_impl_->Animate(start_time); + EXPECT_TRUE(did_request_redraw_); + EXPECT_TRUE(did_request_animate_); + + did_request_redraw_ = false; + did_request_animate_ = false; + host_impl_->Animate(third_through_animation); + EXPECT_TRUE(did_request_redraw_); + EXPECT_TRUE(did_request_animate_); + + // Another activation shouldn't have any effect on the animation. + host_impl_->ActivateSyncTree(); + + did_request_redraw_ = false; + did_request_animate_ = false; + host_impl_->Animate(halfway_through_animation); + EXPECT_TRUE(did_request_redraw_); + EXPECT_TRUE(did_request_animate_); + + did_request_redraw_ = false; + did_request_animate_ = false; + did_request_commit_ = false; + host_impl_->Animate(end_time); + EXPECT_TRUE(did_request_commit_); + EXPECT_FALSE(did_request_animate_); + + scoped_ptr<ScrollAndScaleSet> scroll_info = + host_impl_->ProcessScrollDeltas(); + EXPECT_EQ(scroll_info->page_scale_delta, target_scale); + ExpectContains(*scroll_info, scroll_layer->id(), gfx::Vector2d(-50, -50)); +} + class LayerTreeHostImplOverridePhysicalTime : public LayerTreeHostImpl { public: LayerTreeHostImplOverridePhysicalTime( @@ -1310,10 +1389,11 @@ class LayerTreeHostImplOverridePhysicalTime : public LayerTreeHostImpl { proxy, rendering_stats_instrumentation, manager, + NULL, 0) {} - virtual base::TimeTicks CurrentFrameTimeTicks() OVERRIDE { - return fake_current_physical_time_; + BeginFrameArgs CurrentBeginFrameArgs() const override { + return CreateBeginFrameArgsForTesting(fake_current_physical_time_); } void SetCurrentPhysicalTimeTicksForTest(base::TimeTicks fake_now) { @@ -1345,7 +1425,7 @@ class LayerTreeHostImplOverridePhysicalTime : public LayerTreeHostImpl { scoped_ptr<LayerImpl> scroll = \ LayerImpl::Create(host_impl_->active_tree(), 2); \ scroll->SetScrollClipLayer(root->id()); \ - scroll->SetScrollOffset(gfx::Vector2d()); \ + scroll->SetScrollOffset(gfx::ScrollOffset()); \ root->SetBounds(viewport_size); \ scroll->SetBounds(content_size); \ scroll->SetContentBounds(content_size); \ @@ -1361,12 +1441,11 @@ class LayerTreeHostImplOverridePhysicalTime : public LayerTreeHostImpl { SolidColorScrollbarLayerImpl::Create( \ host_impl_->active_tree(), 4, VERTICAL, 10, 0, false, true); \ EXPECT_FLOAT_EQ(0.f, scrollbar->opacity()); \ - scrollbar->SetScrollLayerById(2); \ - scrollbar->SetClipLayerById(1); \ \ scroll->AddChild(contents.Pass()); \ root->AddChild(scroll.Pass()); \ - root->AddChild(scrollbar.PassAs<LayerImpl>()); \ + scrollbar->SetScrollLayerAndClipLayerByIds(2, 1); \ + root->AddChild(scrollbar.Pass()); \ \ host_impl_->active_tree()->SetRootLayer(root.Pass()); \ host_impl_->active_tree()->SetViewportLayersFromIds( \ @@ -1396,7 +1475,7 @@ TEST_F(LayerTreeHostImplTest, ScrollbarLinearFadeScheduling) { // After a scroll, a fade animation should be scheduled about 20ms from now. host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel); - host_impl_->ScrollBy(gfx::Point(), gfx::Vector2dF(5, 0)); + host_impl_->ScrollBy(gfx::Point(), gfx::Vector2dF(0, 5)); host_impl_->ScrollEnd(); did_request_redraw_ = false; did_request_animate_ = false; @@ -1417,12 +1496,19 @@ TEST_F(LayerTreeHostImplTest, ScrollbarLinearFadeScheduling) { // Setting the scroll offset outside a scroll should also cause the scrollbar // to appear and to schedule a fade. - host_impl_->InnerViewportScrollLayer()->SetScrollOffset(gfx::Vector2d(5, 5)); + host_impl_->InnerViewportScrollLayer()->SetScrollOffset( + gfx::ScrollOffset(5, 5)); EXPECT_LT(base::TimeDelta::FromMilliseconds(19), requested_scrollbar_animation_delay_); EXPECT_FALSE(did_request_redraw_); EXPECT_FALSE(did_request_animate_); requested_scrollbar_animation_delay_ = base::TimeDelta(); + + // Unnecessarily Fade animation of solid color scrollbar is not triggered. + host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel); + host_impl_->ScrollBy(gfx::Point(), gfx::Vector2dF(5, 0)); + host_impl_->ScrollEnd(); + EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_); } TEST_F(LayerTreeHostImplTest, ScrollbarFadePinchZoomScrollbars) { @@ -1506,7 +1592,7 @@ void LayerTreeHostImplTest::SetupMouseMoveAtWithDeviceScale( scoped_ptr<LayerImpl> scroll = LayerImpl::Create(host_impl_->active_tree(), 2); scroll->SetScrollClipLayer(root->id()); - scroll->SetScrollOffset(gfx::Vector2d()); + scroll->SetScrollOffset(gfx::ScrollOffset()); scroll->SetBounds(content_size); scroll->SetContentBounds(content_size); scroll->SetIsContainerForFixedPositionLayers(true); @@ -1524,12 +1610,11 @@ void LayerTreeHostImplTest::SetupMouseMoveAtWithDeviceScale( scrollbar->SetBounds(gfx::Size(15, viewport_size.height())); scrollbar->SetContentBounds(gfx::Size(15, viewport_size.height())); scrollbar->SetPosition(gfx::Point(285, 0)); - scrollbar->SetClipLayerById(1); - scrollbar->SetScrollLayerById(2); scroll->AddChild(contents.Pass()); root->AddChild(scroll.Pass()); - root->AddChild(scrollbar.PassAs<LayerImpl>()); + scrollbar->SetScrollLayerAndClipLayerByIds(2, 1); + root->AddChild(scrollbar.Pass()); host_impl_->active_tree()->SetRootLayer(root.Pass()); host_impl_->active_tree()->SetViewportLayersFromIds(1, 2, Layer::INVALID_ID); @@ -1585,7 +1670,7 @@ TEST_F(LayerTreeHostImplTest, CompositorFrameMetadata) { host_impl_->MakeCompositorFrameMetadata(); EXPECT_EQ(gfx::Vector2dF(), metadata.root_scroll_offset); EXPECT_EQ(1.f, metadata.page_scale_factor); - EXPECT_EQ(gfx::SizeF(50.f, 50.f), metadata.viewport_size); + EXPECT_EQ(gfx::SizeF(50.f, 50.f), metadata.scrollable_viewport_size); EXPECT_EQ(gfx::SizeF(100.f, 100.f), metadata.root_layer_size); EXPECT_EQ(0.5f, metadata.min_page_scale_factor); EXPECT_EQ(4.f, metadata.max_page_scale_factor); @@ -1618,7 +1703,7 @@ TEST_F(LayerTreeHostImplTest, CompositorFrameMetadata) { host_impl_->MakeCompositorFrameMetadata(); EXPECT_EQ(gfx::Vector2dF(0.f, 10.f), metadata.root_scroll_offset); EXPECT_EQ(2.f, metadata.page_scale_factor); - EXPECT_EQ(gfx::SizeF(25.f, 25.f), metadata.viewport_size); + EXPECT_EQ(gfx::SizeF(25.f, 25.f), metadata.scrollable_viewport_size); EXPECT_EQ(gfx::SizeF(100.f, 100.f), metadata.root_layer_size); EXPECT_EQ(0.5f, metadata.min_page_scale_factor); EXPECT_EQ(4.f, metadata.max_page_scale_factor); @@ -1633,7 +1718,7 @@ TEST_F(LayerTreeHostImplTest, CompositorFrameMetadata) { host_impl_->MakeCompositorFrameMetadata(); EXPECT_EQ(gfx::Vector2dF(0.f, 10.f), metadata.root_scroll_offset); EXPECT_EQ(4.f, metadata.page_scale_factor); - EXPECT_EQ(gfx::SizeF(12.5f, 12.5f), metadata.viewport_size); + EXPECT_EQ(gfx::SizeF(12.5f, 12.5f), metadata.scrollable_viewport_size); EXPECT_EQ(gfx::SizeF(100.f, 100.f), metadata.root_layer_size); EXPECT_EQ(0.5f, metadata.min_page_scale_factor); EXPECT_EQ(4.f, metadata.max_page_scale_factor); @@ -1643,24 +1728,25 @@ TEST_F(LayerTreeHostImplTest, CompositorFrameMetadata) { class DidDrawCheckLayer : public LayerImpl { public: static scoped_ptr<LayerImpl> Create(LayerTreeImpl* tree_impl, int id) { - return scoped_ptr<LayerImpl>(new DidDrawCheckLayer(tree_impl, id)); + return make_scoped_ptr(new DidDrawCheckLayer(tree_impl, id)); } - virtual bool WillDraw(DrawMode draw_mode, ResourceProvider* provider) - OVERRIDE { + bool WillDraw(DrawMode draw_mode, ResourceProvider* provider) override { will_draw_called_ = true; if (will_draw_returns_false_) return false; return LayerImpl::WillDraw(draw_mode, provider); } - virtual void AppendQuads(QuadSink* quad_sink, - AppendQuadsData* append_quads_data) OVERRIDE { + void AppendQuads(RenderPass* render_pass, + const Occlusion& occlusion_in_content_space, + AppendQuadsData* append_quads_data) override { append_quads_called_ = true; - LayerImpl::AppendQuads(quad_sink, append_quads_data); + LayerImpl::AppendQuads( + render_pass, occlusion_in_content_space, append_quads_data); } - virtual void DidDraw(ResourceProvider* provider) OVERRIDE { + void DidDraw(ResourceProvider* provider) override { did_draw_called_ = true; LayerImpl::DidDraw(provider); } @@ -1846,6 +1932,8 @@ TEST_F(LayerTreeHostImplTest, DidDrawCalledOnAllLayers) { EXPECT_FALSE(layer2->did_draw_called()); LayerTreeHostImpl::FrameData frame; + FakeLayerTreeHostImpl::RecursiveUpdateNumChildren( + host_impl_->active_tree()->root_layer()); EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); host_impl_->DidDrawAllLayers(frame); @@ -1866,20 +1954,21 @@ class MissingTextureAnimatingLayer : public DidDrawCheckLayer { bool had_incomplete_tile, bool animating, ResourceProvider* resource_provider) { - return scoped_ptr<LayerImpl>( - new MissingTextureAnimatingLayer(tree_impl, - id, - tile_missing, - had_incomplete_tile, - animating, - resource_provider)); - } - - virtual void AppendQuads(QuadSink* quad_sink, - AppendQuadsData* append_quads_data) OVERRIDE { - LayerImpl::AppendQuads(quad_sink, append_quads_data); + return make_scoped_ptr(new MissingTextureAnimatingLayer(tree_impl, + id, + tile_missing, + had_incomplete_tile, + animating, + resource_provider)); + } + + void AppendQuads(RenderPass* render_pass, + const Occlusion& occlusion_in_content_space, + AppendQuadsData* append_quads_data) override { + LayerImpl::AppendQuads( + render_pass, occlusion_in_content_space, append_quads_data); if (had_incomplete_tile_) - append_quads_data->had_incomplete_tile = true; + append_quads_data->num_incomplete_tiles++; if (tile_missing_) append_quads_data->num_missing_tiles++; } @@ -1955,6 +2044,12 @@ TEST_F(LayerTreeHostImplTest, PrepareToDrawSucceedsWithMissingTiles) { DidDrawCheckLayer* root = static_cast<DidDrawCheckLayer*>(host_impl_->active_tree()->root_layer()); + LayerTreeHostImpl::FrameData frame; + EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); + host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); + host_impl_->DidDrawAllLayers(frame); + host_impl_->SwapBuffers(frame); + bool tile_missing = true; bool had_incomplete_tile = false; bool is_animating = false; @@ -1965,10 +2060,10 @@ TEST_F(LayerTreeHostImplTest, PrepareToDrawSucceedsWithMissingTiles) { had_incomplete_tile, is_animating, host_impl_->resource_provider())); - LayerTreeHostImpl::FrameData frame; - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); - host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); - host_impl_->DidDrawAllLayers(frame); + LayerTreeHostImpl::FrameData frame2; + EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame2)); + host_impl_->DrawLayers(&frame2, gfx::FrameTime::Now()); + host_impl_->DidDrawAllLayers(frame2); } TEST_F(LayerTreeHostImplTest, PrepareToDrawSucceedsWithIncompleteTile) { @@ -1977,6 +2072,12 @@ TEST_F(LayerTreeHostImplTest, PrepareToDrawSucceedsWithIncompleteTile) { DidDrawCheckLayer* root = static_cast<DidDrawCheckLayer*>(host_impl_->active_tree()->root_layer()); + LayerTreeHostImpl::FrameData frame; + EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); + host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); + host_impl_->DidDrawAllLayers(frame); + host_impl_->SwapBuffers(frame); + bool tile_missing = false; bool had_incomplete_tile = true; bool is_animating = false; @@ -1987,10 +2088,10 @@ TEST_F(LayerTreeHostImplTest, PrepareToDrawSucceedsWithIncompleteTile) { had_incomplete_tile, is_animating, host_impl_->resource_provider())); - LayerTreeHostImpl::FrameData frame; - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); - host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); - host_impl_->DidDrawAllLayers(frame); + LayerTreeHostImpl::FrameData frame2; + EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame2)); + host_impl_->DrawLayers(&frame2, gfx::FrameTime::Now()); + host_impl_->DidDrawAllLayers(frame2); } TEST_F(LayerTreeHostImplTest, @@ -1999,6 +2100,13 @@ TEST_F(LayerTreeHostImplTest, DidDrawCheckLayer::Create(host_impl_->active_tree(), 5)); DidDrawCheckLayer* root = static_cast<DidDrawCheckLayer*>(host_impl_->active_tree()->root_layer()); + + LayerTreeHostImpl::FrameData frame; + EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); + host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); + host_impl_->DidDrawAllLayers(frame); + host_impl_->SwapBuffers(frame); + bool tile_missing = true; bool had_incomplete_tile = false; bool is_animating = true; @@ -2009,11 +2117,11 @@ TEST_F(LayerTreeHostImplTest, had_incomplete_tile, is_animating, host_impl_->resource_provider())); - LayerTreeHostImpl::FrameData frame; + LayerTreeHostImpl::FrameData frame2; EXPECT_EQ(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS, - host_impl_->PrepareToDraw(&frame)); - host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); - host_impl_->DidDrawAllLayers(frame); + host_impl_->PrepareToDraw(&frame2)); + host_impl_->DrawLayers(&frame2, gfx::FrameTime::Now()); + host_impl_->DidDrawAllLayers(frame2); } TEST_F(LayerTreeHostImplTest, @@ -2022,6 +2130,13 @@ TEST_F(LayerTreeHostImplTest, DidDrawCheckLayer::Create(host_impl_->active_tree(), 5)); DidDrawCheckLayer* root = static_cast<DidDrawCheckLayer*>(host_impl_->active_tree()->root_layer()); + + LayerTreeHostImpl::FrameData frame; + EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); + host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); + host_impl_->DidDrawAllLayers(frame); + host_impl_->SwapBuffers(frame); + bool tile_missing = false; bool had_incomplete_tile = true; bool is_animating = true; @@ -2032,10 +2147,10 @@ TEST_F(LayerTreeHostImplTest, had_incomplete_tile, is_animating, host_impl_->resource_provider())); - LayerTreeHostImpl::FrameData frame; - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); - host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); - host_impl_->DidDrawAllLayers(frame); + LayerTreeHostImpl::FrameData frame2; + EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame2)); + host_impl_->DrawLayers(&frame2, gfx::FrameTime::Now()); + host_impl_->DidDrawAllLayers(frame2); } TEST_F(LayerTreeHostImplTest, PrepareToDrawSucceedsWhenHighResRequired) { @@ -2043,6 +2158,13 @@ TEST_F(LayerTreeHostImplTest, PrepareToDrawSucceedsWhenHighResRequired) { DidDrawCheckLayer::Create(host_impl_->active_tree(), 7)); DidDrawCheckLayer* root = static_cast<DidDrawCheckLayer*>(host_impl_->active_tree()->root_layer()); + + LayerTreeHostImpl::FrameData frame; + EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); + host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); + host_impl_->DidDrawAllLayers(frame); + host_impl_->SwapBuffers(frame); + bool tile_missing = false; bool had_incomplete_tile = false; bool is_animating = false; @@ -2053,11 +2175,11 @@ TEST_F(LayerTreeHostImplTest, PrepareToDrawSucceedsWhenHighResRequired) { had_incomplete_tile, is_animating, host_impl_->resource_provider())); - host_impl_->active_tree()->SetRequiresHighResToDraw(); - LayerTreeHostImpl::FrameData frame; - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); - host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); - host_impl_->DidDrawAllLayers(frame); + host_impl_->SetRequiresHighResToDraw(); + LayerTreeHostImpl::FrameData frame2; + EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame2)); + host_impl_->DrawLayers(&frame2, gfx::FrameTime::Now()); + host_impl_->DidDrawAllLayers(frame2); } TEST_F(LayerTreeHostImplTest, @@ -2066,6 +2188,13 @@ TEST_F(LayerTreeHostImplTest, DidDrawCheckLayer::Create(host_impl_->active_tree(), 7)); DidDrawCheckLayer* root = static_cast<DidDrawCheckLayer*>(host_impl_->active_tree()->root_layer()); + + LayerTreeHostImpl::FrameData frame; + EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); + host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); + host_impl_->DidDrawAllLayers(frame); + host_impl_->SwapBuffers(frame); + bool tile_missing = false; bool had_incomplete_tile = true; bool is_animating = false; @@ -2076,20 +2205,27 @@ TEST_F(LayerTreeHostImplTest, had_incomplete_tile, is_animating, host_impl_->resource_provider())); - host_impl_->active_tree()->SetRequiresHighResToDraw(); - LayerTreeHostImpl::FrameData frame; + host_impl_->SetRequiresHighResToDraw(); + LayerTreeHostImpl::FrameData frame2; EXPECT_EQ(DRAW_ABORTED_MISSING_HIGH_RES_CONTENT, - host_impl_->PrepareToDraw(&frame)); - host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); - host_impl_->DidDrawAllLayers(frame); + host_impl_->PrepareToDraw(&frame2)); + host_impl_->DrawLayers(&frame2, gfx::FrameTime::Now()); + host_impl_->DidDrawAllLayers(frame2); } TEST_F(LayerTreeHostImplTest, - PrepareToDrawSucceedsWhenHighResRequiredAndMissingTile) { + PrepareToDrawFailsWhenHighResRequiredAndMissingTile) { host_impl_->active_tree()->SetRootLayer( DidDrawCheckLayer::Create(host_impl_->active_tree(), 7)); DidDrawCheckLayer* root = static_cast<DidDrawCheckLayer*>(host_impl_->active_tree()->root_layer()); + + LayerTreeHostImpl::FrameData frame; + EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); + host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); + host_impl_->DidDrawAllLayers(frame); + host_impl_->SwapBuffers(frame); + bool tile_missing = true; bool had_incomplete_tile = false; bool is_animating = false; @@ -2100,11 +2236,12 @@ TEST_F(LayerTreeHostImplTest, had_incomplete_tile, is_animating, host_impl_->resource_provider())); - host_impl_->active_tree()->SetRequiresHighResToDraw(); - LayerTreeHostImpl::FrameData frame; - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); - host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); - host_impl_->DidDrawAllLayers(frame); + host_impl_->SetRequiresHighResToDraw(); + LayerTreeHostImpl::FrameData frame2; + EXPECT_EQ(DRAW_ABORTED_MISSING_HIGH_RES_CONTENT, + host_impl_->PrepareToDraw(&frame2)); + host_impl_->DrawLayers(&frame2, gfx::FrameTime::Now()); + host_impl_->DidDrawAllLayers(frame2); } TEST_F(LayerTreeHostImplTest, ScrollRootIgnored) { @@ -2120,6 +2257,7 @@ TEST_F(LayerTreeHostImplTest, ScrollRootIgnored) { EXPECT_FALSE(did_request_commit_); } +// TODO(bokan): Convert these tests to create inner and outer viewports. class LayerTreeHostImplTopControlsTest : public LayerTreeHostImplTest { public: LayerTreeHostImplTopControlsTest() @@ -2129,6 +2267,7 @@ class LayerTreeHostImplTopControlsTest : public LayerTreeHostImplTest { clip_size_(layer_size_) { settings_.calculate_top_controls_position = true; settings_.top_controls_height = 50; + settings_.use_pinch_virtual_viewport = true; viewport_size_ = gfx::Size(clip_size_.width(), @@ -2136,8 +2275,6 @@ class LayerTreeHostImplTopControlsTest : public LayerTreeHostImplTest { } void SetupTopControlsAndScrollLayer() { - CreateHostImpl(settings_, CreateOutputSurface()); - scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1); scoped_ptr<LayerImpl> root_clip = @@ -2158,8 +2295,88 @@ class LayerTreeHostImplTopControlsTest : public LayerTreeHostImplTest { // Set a viewport size that is large enough to contain both the top controls // and some content. host_impl_->SetViewportSize(viewport_size_); + host_impl_->SetTopControlsLayoutHeight( + settings_.top_controls_height); + + host_impl_->CreatePendingTree(); + root = + LayerImpl::Create(host_impl_->sync_tree(), 1); + root_clip = + LayerImpl::Create(host_impl_->sync_tree(), 2); + root_clip->SetBounds(clip_size_); + root->SetScrollClipLayer(root_clip->id()); + root->SetBounds(layer_size_); + root->SetContentBounds(layer_size_); + root->SetPosition(gfx::PointF()); + root->SetDrawsContent(false); + root->SetIsContainerForFixedPositionLayers(true); + inner_viewport_scroll_layer_id = root->id(); + page_scale_layer_id = root_clip->id(); + root_clip->AddChild(root.Pass()); + host_impl_->sync_tree()->SetRootLayer(root_clip.Pass()); + host_impl_->sync_tree()->SetViewportLayersFromIds( + page_scale_layer_id, inner_viewport_scroll_layer_id, Layer::INVALID_ID); + // Set a viewport size that is large enough to contain both the top controls + // and some content. + host_impl_->SetViewportSize(viewport_size_); + host_impl_->sync_tree()->set_top_controls_layout_height( + settings_.top_controls_height); + } + + void SetupTopControlsAndScrollLayerWithVirtualViewport( + const gfx::Size& inner_viewport_size, + const gfx::Size& outer_viewport_size, + const gfx::Size& scroll_layer_size) { + CreateHostImpl(settings_, CreateOutputSurface()); + host_impl_->SetTopControlsLayoutHeight( + settings_.top_controls_height); + + scoped_ptr<LayerImpl> root = + LayerImpl::Create(host_impl_->active_tree(), 1); + scoped_ptr<LayerImpl> root_clip = + LayerImpl::Create(host_impl_->active_tree(), 2); + scoped_ptr<LayerImpl> page_scale = + LayerImpl::Create(host_impl_->active_tree(), 3); + + scoped_ptr<LayerImpl> outer_scroll = + LayerImpl::Create(host_impl_->active_tree(), 4); + scoped_ptr<LayerImpl> outer_clip = + LayerImpl::Create(host_impl_->active_tree(), 5); + + root_clip->SetBounds(inner_viewport_size); + root->SetScrollClipLayer(root_clip->id()); + root->SetBounds(outer_viewport_size); + root->SetContentBounds(outer_viewport_size); + root->SetPosition(gfx::PointF()); + root->SetDrawsContent(false); + root->SetIsContainerForFixedPositionLayers(true); + + outer_clip->SetBounds(outer_viewport_size); + outer_scroll->SetScrollClipLayer(outer_clip->id()); + outer_scroll->SetBounds(scroll_layer_size); + outer_scroll->SetContentBounds(scroll_layer_size); + outer_scroll->SetPosition(gfx::PointF()); + outer_scroll->SetDrawsContent(false); + outer_scroll->SetIsContainerForFixedPositionLayers(true); + + int inner_viewport_scroll_layer_id = root->id(); + int outer_viewport_scroll_layer_id = outer_scroll->id(); + int page_scale_layer_id = page_scale->id(); + + outer_clip->AddChild(outer_scroll.Pass()); + root->AddChild(outer_clip.Pass()); + page_scale->AddChild(root.Pass()); + root_clip->AddChild(page_scale.Pass()); + + host_impl_->active_tree()->SetRootLayer(root_clip.Pass()); + host_impl_->active_tree()->SetViewportLayersFromIds( + page_scale_layer_id, + inner_viewport_scroll_layer_id, + outer_viewport_scroll_layer_id); + + host_impl_->SetViewportSize(inner_viewport_size); LayerImpl* root_clip_ptr = host_impl_->active_tree()->root_layer(); - EXPECT_EQ(clip_size_, root_clip_ptr->bounds()); + EXPECT_EQ(inner_viewport_size, root_clip_ptr->bounds()); } protected: @@ -2171,7 +2388,8 @@ class LayerTreeHostImplTopControlsTest : public LayerTreeHostImplTest { }; // class LayerTreeHostImplTopControlsTest TEST_F(LayerTreeHostImplTopControlsTest, ScrollTopControlsByFractionalAmount) { - SetupTopControlsAndScrollLayer(); + SetupTopControlsAndScrollLayerWithVirtualViewport( + gfx::Size(10, 10), gfx::Size(10, 10), gfx::Size(10, 10)); DrawFrame(); EXPECT_EQ(InputHandler::ScrollStarted, @@ -2193,39 +2411,388 @@ TEST_F(LayerTreeHostImplTopControlsTest, ScrollTopControlsByFractionalAmount) { inner_viewport_scroll_layer->FixedContainerSizeDelta()); } -TEST_F(LayerTreeHostImplTopControlsTest, ScrollTopControlsWithPageScale) { - SetupTopControlsAndScrollLayer(); +// In this test, the outer viewport is initially unscrollable. We test that a +// scroll initiated on the inner viewport, causing the top controls to show and +// thus making the outer viewport scrollable, still scrolls the outer viewport. +TEST_F(LayerTreeHostImplTopControlsTest, + TopControlsOuterViewportBecomesScrollable) { + SetupTopControlsAndScrollLayerWithVirtualViewport( + gfx::Size(10, 50), gfx::Size(10, 50), gfx::Size(10, 100)); DrawFrame(); + LayerImpl *inner_scroll = + host_impl_->active_tree()->InnerViewportScrollLayer(); + LayerImpl *inner_container = + host_impl_->active_tree()->InnerViewportContainerLayer(); + LayerImpl *outer_scroll = + host_impl_->active_tree()->OuterViewportScrollLayer(); + LayerImpl *outer_container = + host_impl_->active_tree()->OuterViewportContainerLayer(); + + // Need SetDrawsContent so ScrollBegin's hit test finds an actual layer. + outer_scroll->SetDrawsContent(true); + host_impl_->active_tree()->SetPageScaleFactorAndLimits(2.f, 1.f, 2.f); + EXPECT_EQ(InputHandler::ScrollStarted, host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture)); + host_impl_->ScrollBy(gfx::Point(), gfx::Vector2dF(0.f, 50.f)); + + // The entire scroll delta should have been used to hide the top controls. + // The viewport layers should be resized back to their full sizes. + EXPECT_EQ(0.f, + host_impl_->active_tree()->total_top_controls_content_offset()); + EXPECT_EQ(0.f, inner_scroll->TotalScrollOffset().y()); + EXPECT_EQ(100.f, inner_container->BoundsForScrolling().height()); + EXPECT_EQ(100.f, outer_container->BoundsForScrolling().height()); + + // The inner viewport should be scrollable by 50px * page_scale. + host_impl_->ScrollBy(gfx::Point(), gfx::Vector2dF(0.f, 100.f)); + EXPECT_EQ(50.f, inner_scroll->TotalScrollOffset().y()); + EXPECT_EQ(0.f, outer_scroll->TotalScrollOffset().y()); + EXPECT_EQ(gfx::ScrollOffset(), outer_scroll->MaxScrollOffset()); + + host_impl_->ScrollEnd(); + + EXPECT_EQ(InputHandler::ScrollStarted, + host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture)); + EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), inner_scroll); + + host_impl_->ScrollBy(gfx::Point(), gfx::Vector2dF(0.f, -50.f)); + + // The entire scroll delta should have been used to show the top controls. + // The outer viewport should be resized to accomodate and scrolled to the + // bottom of the document to keep the viewport in place. + EXPECT_EQ(50.f, + host_impl_->active_tree()->total_top_controls_content_offset()); + EXPECT_EQ(50.f, outer_container->BoundsForScrolling().height()); + EXPECT_EQ(50.f, inner_container->BoundsForScrolling().height()); + EXPECT_EQ(25.f, outer_scroll->TotalScrollOffset().y()); + EXPECT_EQ(25.f, inner_scroll->TotalScrollOffset().y()); + + // Now when we continue scrolling, make sure the outer viewport gets scrolled + // since it wasn't scrollable when the scroll began. + host_impl_->ScrollBy(gfx::Point(), gfx::Vector2dF(0.f, -20.f)); + EXPECT_EQ(15.f, outer_scroll->TotalScrollOffset().y()); + EXPECT_EQ(25.f, inner_scroll->TotalScrollOffset().y()); + + host_impl_->ScrollBy(gfx::Point(), gfx::Vector2dF(0.f, -30.f)); + EXPECT_EQ(0.f, outer_scroll->TotalScrollOffset().y()); + EXPECT_EQ(25.f, inner_scroll->TotalScrollOffset().y()); + + host_impl_->ScrollBy(gfx::Point(), gfx::Vector2dF(0.f, -50.f)); + host_impl_->ScrollEnd(); + + EXPECT_EQ(0.f, outer_scroll->TotalScrollOffset().y()); + EXPECT_EQ(0.f, inner_scroll->TotalScrollOffset().y()); +} + +// Test that the fixed position container delta is appropriately adjusted +// by the top controls showing/hiding and page scale doesn't affect it. +TEST_F(LayerTreeHostImplTopControlsTest, FixedContainerDelta) { + SetupTopControlsAndScrollLayerWithVirtualViewport( + gfx::Size(100, 100), gfx::Size(100, 100), gfx::Size(100, 100)); + DrawFrame(); float page_scale = 1.5f; + float top_controls_height = settings_.top_controls_height; + LayerImpl* outer_viewport_scroll_layer = + host_impl_->active_tree()->OuterViewportScrollLayer(); + + // Zoom in, since the fixed container is the outer viewport, the delta should + // not be scaled. host_impl_->active_tree()->SetPageScaleFactorAndLimits(page_scale, 1.f, 2.f); - gfx::Vector2dF top_controls_scroll_delta(0.f, 5.f); - gfx::Vector2dF expected_container_size_delta = - ScaleVector2d(top_controls_scroll_delta, 1.f / page_scale); + EXPECT_EQ(InputHandler::ScrollStarted, + host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture)); + + // Scroll down, the top controls hiding should expand the viewport size so + // the delta should be equal to the scroll distance. + gfx::Vector2dF top_controls_scroll_delta(0.f, 20.f); + host_impl_->top_controls_manager()->ScrollBegin(); + host_impl_->top_controls_manager()->ScrollBy(top_controls_scroll_delta); + EXPECT_EQ(top_controls_height - top_controls_scroll_delta.y(), + host_impl_->top_controls_manager()->ContentTopOffset()); + EXPECT_VECTOR_EQ(top_controls_scroll_delta, + outer_viewport_scroll_layer->FixedContainerSizeDelta()); + host_impl_->ScrollEnd(); + + // Scroll past the maximum extent. The delta shouldn't be greater than the + // top controls height. host_impl_->top_controls_manager()->ScrollBegin(); host_impl_->top_controls_manager()->ScrollBy(top_controls_scroll_delta); + host_impl_->top_controls_manager()->ScrollBy(top_controls_scroll_delta); + host_impl_->top_controls_manager()->ScrollBy(top_controls_scroll_delta); + EXPECT_EQ(0.f, host_impl_->top_controls_manager()->ContentTopOffset()); + EXPECT_VECTOR_EQ(gfx::Vector2dF(0, top_controls_height), + outer_viewport_scroll_layer->FixedContainerSizeDelta()); + host_impl_->ScrollEnd(); + + // Scroll in the direction to make the top controls show. + host_impl_->top_controls_manager()->ScrollBegin(); + host_impl_->top_controls_manager()->ScrollBy(-top_controls_scroll_delta); + EXPECT_EQ(top_controls_scroll_delta.y(), + host_impl_->top_controls_manager()->ContentTopOffset()); + EXPECT_VECTOR_EQ( + gfx::Vector2dF(0, top_controls_height - top_controls_scroll_delta.y()), + outer_viewport_scroll_layer->FixedContainerSizeDelta()); host_impl_->top_controls_manager()->ScrollEnd(); +} - LayerImpl* inner_viewport_scroll_layer = - host_impl_->active_tree()->InnerViewportScrollLayer(); - DCHECK(inner_viewport_scroll_layer); +// Ensure setting the top controls position explicitly using the setters on the +// TreeImpl correctly affects the top controls manager and viewport bounds. +TEST_F(LayerTreeHostImplTopControlsTest, PositionTopControlsExplicitly) { + CreateHostImpl(settings_, CreateOutputSurface()); + SetupTopControlsAndScrollLayer(); + DrawFrame(); + + host_impl_->active_tree()->set_top_controls_delta(0.f); + host_impl_->active_tree()->set_top_controls_content_offset(30.f); + EXPECT_EQ(30.f, host_impl_->top_controls_manager()->ContentTopOffset()); + EXPECT_EQ(-20.f, host_impl_->top_controls_manager()->ControlsTopOffset()); + + host_impl_->active_tree()->set_top_controls_delta(-30.f); + EXPECT_EQ(0.f, host_impl_->top_controls_manager()->ContentTopOffset()); + EXPECT_EQ(-50.f, host_impl_->top_controls_manager()->ControlsTopOffset()); + + host_impl_->DidChangeTopControlsPosition(); + + // Now that top controls have moved, expect the clip to resize. + LayerImpl* root_clip_ptr = host_impl_->active_tree()->root_layer(); + EXPECT_EQ(viewport_size_, root_clip_ptr->bounds()); +} + +// Test that the top_controls delta and sent delta are appropriately +// applied on sync tree activation. The total top controls offset shouldn't +// change after the activation. +TEST_F(LayerTreeHostImplTopControlsTest, ApplyDeltaOnTreeActivation) { + CreateHostImpl(settings_, CreateOutputSurface()); + SetupTopControlsAndScrollLayer(); + DrawFrame(); + + host_impl_->sync_tree()->set_top_controls_content_offset(15.f); + + host_impl_->active_tree()->set_top_controls_content_offset(20.f); + host_impl_->active_tree()->set_top_controls_delta(-20.f); + host_impl_->active_tree()->set_sent_top_controls_delta(-5.f); + + host_impl_->DidChangeTopControlsPosition(); + LayerImpl* root_clip_ptr = host_impl_->active_tree()->root_layer(); + EXPECT_EQ(viewport_size_, root_clip_ptr->bounds()); + EXPECT_EQ(0.f, host_impl_->top_controls_manager()->ContentTopOffset()); + EXPECT_EQ(0.f, + host_impl_->active_tree()->total_top_controls_content_offset()); + + host_impl_->ActivateSyncTree(); + + root_clip_ptr = host_impl_->active_tree()->root_layer(); + EXPECT_EQ(0.f, host_impl_->top_controls_manager()->ContentTopOffset()); + EXPECT_EQ(viewport_size_, root_clip_ptr->bounds()); + + EXPECT_EQ(0.f, host_impl_->active_tree()->sent_top_controls_delta()); + EXPECT_EQ(-15.f, host_impl_->active_tree()->top_controls_delta()); + EXPECT_EQ(15.f, host_impl_->active_tree()->top_controls_content_offset()); + EXPECT_EQ(0.f, + host_impl_->active_tree()->total_top_controls_content_offset()); +} + +// Test that changing the top controls layout height is correctly applied to +// the inner viewport container bounds. That is, the top controls layout +// height is the amount that the inner viewport container was shrunk outside +// the compositor to accommodate the top controls. +TEST_F(LayerTreeHostImplTopControlsTest, TopControlsLayoutHeightChanged) { + CreateHostImpl(settings_, CreateOutputSurface()); + SetupTopControlsAndScrollLayer(); + DrawFrame(); + + host_impl_->sync_tree()->set_top_controls_content_offset(15.f); + host_impl_->sync_tree()->set_top_controls_layout_height(15.f); + + host_impl_->active_tree()->set_top_controls_content_offset(20.f); + host_impl_->active_tree()->set_top_controls_delta(-20.f); + host_impl_->active_tree()->set_sent_top_controls_delta(-5.f); + + host_impl_->DidChangeTopControlsPosition(); + LayerImpl* root_clip_ptr = host_impl_->active_tree()->root_layer(); + EXPECT_EQ(viewport_size_, root_clip_ptr->bounds()); + EXPECT_EQ(0.f, host_impl_->top_controls_manager()->ContentTopOffset()); + + host_impl_->sync_tree()->root_layer()->SetBounds( + gfx::Size(root_clip_ptr->bounds().width(), + root_clip_ptr->bounds().height() - 15.f)); + + host_impl_->ActivateSyncTree(); + + root_clip_ptr = host_impl_->active_tree()->root_layer(); + EXPECT_EQ(0.f, host_impl_->top_controls_manager()->ContentTopOffset()); + + // The total bounds should remain unchanged since the bounds delta should + // account for the difference between the layout height and the current + // top controls offset. + EXPECT_EQ(viewport_size_, root_clip_ptr->bounds()); + EXPECT_VECTOR_EQ(gfx::Vector2dF(0.f, 15.f), root_clip_ptr->bounds_delta()); + + host_impl_->active_tree()->set_top_controls_delta(0.f); + host_impl_->DidChangeTopControlsPosition(); + + EXPECT_EQ(15.f, host_impl_->top_controls_manager()->ContentTopOffset()); + EXPECT_VECTOR_EQ(gfx::Vector2dF(0.f, 0.f), root_clip_ptr->bounds_delta()); + EXPECT_EQ(gfx::Size(viewport_size_.width(), viewport_size_.height()-15.f), + root_clip_ptr->bounds()); +} + +// Test that showing/hiding the top controls when the viewport is fully scrolled +// doesn't incorrectly change the viewport offset due to clamping from changing +// viewport bounds. +TEST_F(LayerTreeHostImplTopControlsTest, TopControlsViewportOffsetClamping) { + SetupTopControlsAndScrollLayerWithVirtualViewport( + gfx::Size(100, 100), gfx::Size(200, 200), gfx::Size(200, 400)); + DrawFrame(); + + EXPECT_EQ(settings_.top_controls_height, + host_impl_->active_tree()->total_top_controls_content_offset()); + + LayerImpl* outer_scroll = host_impl_->OuterViewportScrollLayer(); + LayerImpl* inner_scroll = host_impl_->InnerViewportScrollLayer(); + + // Scroll the viewports to max scroll offset. + outer_scroll->SetScrollDelta(gfx::Vector2dF(0, 200.f)); + inner_scroll->SetScrollDelta(gfx::Vector2dF(100, 100.f)); + + gfx::ScrollOffset viewport_offset = + host_impl_->active_tree()->TotalScrollOffset(); + EXPECT_EQ(host_impl_->active_tree()->TotalMaxScrollOffset(), viewport_offset); + + // Hide the top controls by 25px. + gfx::Vector2dF scroll_delta(0.f, 25.f); + EXPECT_EQ(InputHandler::ScrollStarted, + host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture)); + host_impl_->ScrollBy(gfx::Point(), scroll_delta); host_impl_->ScrollEnd(); - // Use a tolerance that requires the container size delta to be within 0.01 - // pixels. - double tolerance = 0.0001; - EXPECT_LT( - (expected_container_size_delta - - inner_viewport_scroll_layer->FixedContainerSizeDelta()).LengthSquared(), - tolerance); + EXPECT_EQ(scroll_delta.y(), + settings_.top_controls_height - + host_impl_->active_tree()->total_top_controls_content_offset()); + + inner_scroll->ClampScrollToMaxScrollOffset(); + outer_scroll->ClampScrollToMaxScrollOffset(); + + // We should still be fully scrolled. + EXPECT_EQ(host_impl_->active_tree()->TotalMaxScrollOffset(), + host_impl_->active_tree()->TotalScrollOffset()); + + viewport_offset = host_impl_->active_tree()->TotalScrollOffset(); + + // Bring the top controls down by 25px. + scroll_delta = gfx::Vector2dF(0.f, -25.f); + EXPECT_EQ(InputHandler::ScrollStarted, + host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture)); + host_impl_->ScrollBy(gfx::Point(), scroll_delta); + host_impl_->ScrollEnd(); + + // The viewport offset shouldn't have changed. + EXPECT_EQ(viewport_offset, + host_impl_->active_tree()->TotalScrollOffset()); + + // Scroll the viewports to max scroll offset. + outer_scroll->SetScrollDelta(gfx::Vector2dF(0, 200.f)); + inner_scroll->SetScrollDelta(gfx::Vector2dF(100, 100.f)); + EXPECT_EQ(host_impl_->active_tree()->TotalMaxScrollOffset(), + host_impl_->active_tree()->TotalScrollOffset()); +} + +// Test that the top controls coming in and out maintains the same aspect ratio +// between the inner and outer viewports. +TEST_F(LayerTreeHostImplTopControlsTest, TopControlsAspectRatio) { + SetupTopControlsAndScrollLayerWithVirtualViewport( + gfx::Size(100, 100), gfx::Size(200, 200), gfx::Size(200, 400)); + DrawFrame(); + + EXPECT_EQ(settings_.top_controls_height, + host_impl_->active_tree()->total_top_controls_content_offset()); + + gfx::Vector2dF scroll_delta(0.f, 25.f); + EXPECT_EQ(InputHandler::ScrollStarted, + host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture)); + host_impl_->ScrollBy(gfx::Point(), scroll_delta); + host_impl_->ScrollEnd(); + + EXPECT_EQ(scroll_delta.y(), + settings_.top_controls_height - + host_impl_->active_tree()->total_top_controls_content_offset()); + + // Top controls were hidden by 25px so the inner viewport should have expanded + // by that much. + LayerImpl* outer_container = + host_impl_->active_tree()->OuterViewportContainerLayer(); + LayerImpl* inner_container = + host_impl_->active_tree()->InnerViewportContainerLayer(); + EXPECT_EQ(gfx::Size(100, 100+25), inner_container->BoundsForScrolling()); + + // Outer viewport should match inner's aspect ratio. The bounds are ceiled. + float aspect_ratio = inner_container->BoundsForScrolling().width() / + inner_container->BoundsForScrolling().height(); + gfx::Size expected = gfx::ToCeiledSize(gfx::SizeF(200, 200 / aspect_ratio)); + EXPECT_EQ(expected, outer_container->BoundsForScrolling()); + EXPECT_EQ(expected, + host_impl_->InnerViewportScrollLayer()->BoundsForScrolling()); +} + +// Test that scrolling the outer viewport affects the top controls. +TEST_F(LayerTreeHostImplTopControlsTest, TopControlsScrollOuterViewport) { + SetupTopControlsAndScrollLayerWithVirtualViewport( + gfx::Size(100, 100), gfx::Size(200, 200), gfx::Size(200, 400)); + DrawFrame(); + + EXPECT_EQ(settings_.top_controls_height, + host_impl_->active_tree()->total_top_controls_content_offset()); + + // Send a gesture scroll that will scroll the outer viewport, make sure the + // top controls get scrolled. + gfx::Vector2dF scroll_delta(0.f, 15.f); + EXPECT_EQ(InputHandler::ScrollStarted, + host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture)); + host_impl_->ScrollBy(gfx::Point(), scroll_delta); + EXPECT_EQ(host_impl_->OuterViewportScrollLayer(), + host_impl_->CurrentlyScrollingLayer()); + host_impl_->ScrollEnd(); + + EXPECT_EQ(scroll_delta.y(), + settings_.top_controls_height - + host_impl_->active_tree()->total_top_controls_content_offset()); + + scroll_delta = gfx::Vector2dF(0.f, 50.f); + EXPECT_EQ(InputHandler::ScrollStarted, + host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture)); + host_impl_->ScrollBy(gfx::Point(), scroll_delta); + + EXPECT_EQ(0, host_impl_->active_tree()->total_top_controls_content_offset()); + EXPECT_EQ(host_impl_->OuterViewportScrollLayer(), + host_impl_->CurrentlyScrollingLayer()); + + host_impl_->ScrollEnd(); + + // Position the viewports such that the inner viewport will be scrolled. + gfx::Vector2dF inner_viewport_offset(0.f, 25.f); + host_impl_->OuterViewportScrollLayer()->SetScrollDelta(gfx::Vector2dF()); + host_impl_->InnerViewportScrollLayer()->SetScrollDelta(inner_viewport_offset); + + scroll_delta = gfx::Vector2dF(0.f, -65.f); + EXPECT_EQ(InputHandler::ScrollStarted, + host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture)); + host_impl_->ScrollBy(gfx::Point(), scroll_delta); + + EXPECT_EQ(settings_.top_controls_height, + host_impl_->active_tree()->total_top_controls_content_offset()); + EXPECT_EQ(inner_viewport_offset.y() + + (scroll_delta.y() + settings_.top_controls_height), + host_impl_->InnerViewportScrollLayer()->ScrollDelta().y()); + + host_impl_->ScrollEnd(); } TEST_F(LayerTreeHostImplTopControlsTest, ScrollNonScrollableRootWithTopControls) { + CreateHostImpl(settings_, CreateOutputSurface()); SetupTopControlsAndScrollLayer(); DrawFrame(); @@ -2235,7 +2802,7 @@ TEST_F(LayerTreeHostImplTopControlsTest, host_impl_->top_controls_manager()->ScrollBegin(); host_impl_->top_controls_manager()->ScrollBy(gfx::Vector2dF(0.f, 50.f)); host_impl_->top_controls_manager()->ScrollEnd(); - EXPECT_EQ(0.f, host_impl_->top_controls_manager()->content_top_offset()); + EXPECT_EQ(0.f, host_impl_->top_controls_manager()->ContentTopOffset()); // Now that top controls have moved, expect the clip to resize. LayerImpl* root_clip_ptr = host_impl_->active_tree()->root_layer(); EXPECT_EQ(viewport_size_, root_clip_ptr->bounds()); @@ -2250,7 +2817,7 @@ TEST_F(LayerTreeHostImplTopControlsTest, host_impl_->top_controls_manager()->ScrollBy( gfx::Vector2dF(0.f, scroll_increment_y)); EXPECT_EQ(-scroll_increment_y, - host_impl_->top_controls_manager()->content_top_offset()); + host_impl_->top_controls_manager()->ContentTopOffset()); // Now that top controls have moved, expect the clip to resize. EXPECT_EQ(gfx::Size(viewport_size_.width(), viewport_size_.height() + scroll_increment_y), @@ -2260,7 +2827,7 @@ TEST_F(LayerTreeHostImplTopControlsTest, gfx::Vector2dF(0.f, scroll_increment_y)); host_impl_->top_controls_manager()->ScrollEnd(); EXPECT_EQ(-2 * scroll_increment_y, - host_impl_->top_controls_manager()->content_top_offset()); + host_impl_->top_controls_manager()->ContentTopOffset()); // Now that top controls have moved, expect the clip to resize. EXPECT_EQ(clip_size_, root_clip_ptr->bounds()); @@ -2268,7 +2835,7 @@ TEST_F(LayerTreeHostImplTopControlsTest, // Verify the layer is once-again non-scrollable. EXPECT_EQ( - gfx::Vector2d(), + gfx::ScrollOffset(), host_impl_->active_tree()->InnerViewportScrollLayer()->MaxScrollOffset()); EXPECT_EQ(InputHandler::ScrollStarted, @@ -2431,7 +2998,7 @@ TEST_F(LayerTreeHostImplTest, ScrollRootAndChangePageScaleOnMainThread) { gfx::Vector2d scroll_delta(0, 10); gfx::Vector2d expected_scroll_delta = scroll_delta; - gfx::Vector2d expected_max_scroll = root_scroll->MaxScrollOffset(); + gfx::ScrollOffset expected_max_scroll = root_scroll->MaxScrollOffset(); EXPECT_EQ(InputHandler::ScrollStarted, host_impl_->ScrollBegin(gfx::Point(5, 5), InputHandler::Wheel)); @@ -2482,7 +3049,7 @@ TEST_F(LayerTreeHostImplTest, ScrollRootAndChangePageScaleOnImplThread) { gfx::Vector2d scroll_delta(0, 10); gfx::Vector2d expected_scroll_delta = scroll_delta; - gfx::Vector2d expected_max_scroll = root_scroll->MaxScrollOffset(); + gfx::ScrollOffset expected_max_scroll = root_scroll->MaxScrollOffset(); EXPECT_EQ(InputHandler::ScrollStarted, host_impl_->ScrollBegin(gfx::Point(5, 5), InputHandler::Wheel)); @@ -2592,7 +3159,7 @@ TEST_F(LayerTreeHostImplTest, ScrollChildAndChangePageScaleOnMainThread) { gfx::Vector2d scroll_delta(0, 10); gfx::Vector2d expected_scroll_delta(scroll_delta); - gfx::Vector2d expected_max_scroll(child->MaxScrollOffset()); + gfx::ScrollOffset expected_max_scroll(child->MaxScrollOffset()); EXPECT_EQ(InputHandler::ScrollStarted, host_impl_->ScrollBegin(gfx::Point(5, 5), InputHandler::Wheel)); @@ -2640,8 +3207,8 @@ TEST_F(LayerTreeHostImplTest, ScrollChildBeyondLimit) { host_impl_->active_tree()->SetRootLayer(root.Pass()); host_impl_->active_tree()->DidBecomeActive(); host_impl_->SetViewportSize(surface_size); - grand_child_layer->SetScrollOffset(gfx::Vector2d(0, 5)); - child_layer->SetScrollOffset(gfx::Vector2d(3, 0)); + grand_child_layer->SetScrollOffset(gfx::ScrollOffset(0, 5)); + child_layer->SetScrollOffset(gfx::ScrollOffset(3, 0)); DrawFrame(); { @@ -2692,8 +3259,8 @@ TEST_F(LayerTreeHostImplTest, ScrollWithoutBubbling) { host_impl_->active_tree()->DidBecomeActive(); host_impl_->SetViewportSize(viewport_size); - grand_child_layer->SetScrollOffset(gfx::Vector2d(0, 2)); - child_layer->SetScrollOffset(gfx::Vector2d(0, 3)); + grand_child_layer->SetScrollOffset(gfx::ScrollOffset(0, 2)); + child_layer->SetScrollOffset(gfx::ScrollOffset(0, 3)); DrawFrame(); { @@ -3019,6 +3586,22 @@ TEST_F(LayerTreeHostImplTest, ScrollScaledLayer) { wheel_scroll_delta); } +TEST_F(LayerTreeHostImplTest, ScrollViewportRounding) { + int width = 332; + int height = 20; + int scale = 3; + SetupScrollAndContentsLayers(gfx::Size(width, height)); + host_impl_->active_tree()->InnerViewportContainerLayer()->SetBounds( + gfx::Size(width * scale - 1, height * scale)); + host_impl_->SetDeviceScaleFactor(scale); + host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f, 0.5f, 4.f); + + LayerImpl* inner_viewport_scroll_layer = + host_impl_->active_tree()->InnerViewportScrollLayer(); + EXPECT_EQ(gfx::ScrollOffset(0, 0), + inner_viewport_scroll_layer->MaxScrollOffset()); +} + class TestScrollOffsetDelegate : public LayerScrollOffsetDelegate { public: TestScrollOffsetDelegate() @@ -3026,20 +3609,20 @@ class TestScrollOffsetDelegate : public LayerScrollOffsetDelegate { min_page_scale_factor_(-1.f), max_page_scale_factor_(-1.f) {} - virtual ~TestScrollOffsetDelegate() {} + ~TestScrollOffsetDelegate() override {} - virtual gfx::Vector2dF GetTotalScrollOffset() OVERRIDE { + gfx::ScrollOffset GetTotalScrollOffset() override { return getter_return_value_; } - virtual bool IsExternalFlingActive() const OVERRIDE { return false; } + bool IsExternalFlingActive() const override { return false; } - virtual void UpdateRootLayerState(const gfx::Vector2dF& total_scroll_offset, - const gfx::Vector2dF& max_scroll_offset, - const gfx::SizeF& scrollable_size, - float page_scale_factor, - float min_page_scale_factor, - float max_page_scale_factor) OVERRIDE { + void UpdateRootLayerState(const gfx::ScrollOffset& total_scroll_offset, + const gfx::ScrollOffset& max_scroll_offset, + const gfx::SizeF& scrollable_size, + float page_scale_factor, + float min_page_scale_factor, + float max_page_scale_factor) override { DCHECK(total_scroll_offset.x() <= max_scroll_offset.x()); DCHECK(total_scroll_offset.y() <= max_scroll_offset.y()); last_set_scroll_offset_ = total_scroll_offset; @@ -3050,15 +3633,15 @@ class TestScrollOffsetDelegate : public LayerScrollOffsetDelegate { max_page_scale_factor_ = max_page_scale_factor; } - gfx::Vector2dF last_set_scroll_offset() { + gfx::ScrollOffset last_set_scroll_offset() { return last_set_scroll_offset_; } - void set_getter_return_value(const gfx::Vector2dF& value) { + void set_getter_return_value(const gfx::ScrollOffset& value) { getter_return_value_ = value; } - gfx::Vector2dF max_scroll_offset() const { + gfx::ScrollOffset max_scroll_offset() const { return max_scroll_offset_; } @@ -3079,9 +3662,9 @@ class TestScrollOffsetDelegate : public LayerScrollOffsetDelegate { } private: - gfx::Vector2dF last_set_scroll_offset_; - gfx::Vector2dF getter_return_value_; - gfx::Vector2dF max_scroll_offset_; + gfx::ScrollOffset last_set_scroll_offset_; + gfx::ScrollOffset getter_return_value_; + gfx::ScrollOffset max_scroll_offset_; gfx::SizeF scrollable_size_; float page_scale_factor_; float min_page_scale_factor_; @@ -3097,7 +3680,7 @@ TEST_F(LayerTreeHostImplTest, RootLayerScrollOffsetDelegation) { // Setting the delegate results in the current scroll offset being set. gfx::Vector2dF initial_scroll_delta(10.f, 10.f); - scroll_layer->SetScrollOffset(gfx::Vector2d()); + scroll_layer->SetScrollOffset(gfx::ScrollOffset()); scroll_layer->SetScrollDelta(initial_scroll_delta); host_impl_->SetRootLayerScrollOffsetDelegate(&scroll_delegate); EXPECT_EQ(initial_scroll_delta.ToString(), @@ -3106,7 +3689,7 @@ TEST_F(LayerTreeHostImplTest, RootLayerScrollOffsetDelegation) { // Setting the delegate results in the scrollable_size, max_scroll_offset, // page_scale_factor and {min|max}_page_scale_factor being set. EXPECT_EQ(gfx::SizeF(100, 100), scroll_delegate.scrollable_size()); - EXPECT_EQ(gfx::Vector2dF(90, 80), scroll_delegate.max_scroll_offset()); + EXPECT_EQ(gfx::ScrollOffset(90, 80), scroll_delegate.max_scroll_offset()); EXPECT_EQ(1.f, scroll_delegate.page_scale_factor()); EXPECT_EQ(0.f, scroll_delegate.min_page_scale_factor()); EXPECT_EQ(0.f, scroll_delegate.max_page_scale_factor()); @@ -3138,35 +3721,35 @@ TEST_F(LayerTreeHostImplTest, RootLayerScrollOffsetDelegation) { // Scrolling should be relative to the offset as returned by the delegate. gfx::Vector2dF scroll_delta(0.f, 10.f); - gfx::Vector2dF current_offset(7.f, 8.f); + gfx::ScrollOffset current_offset(7.f, 8.f); scroll_delegate.set_getter_return_value(current_offset); EXPECT_EQ(InputHandler::ScrollStarted, host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture)); host_impl_->ScrollBy(gfx::Point(), scroll_delta); - EXPECT_EQ(current_offset + scroll_delta, + EXPECT_EQ(ScrollOffsetWithDelta(current_offset, scroll_delta), scroll_delegate.last_set_scroll_offset()); - current_offset = gfx::Vector2dF(42.f, 41.f); + current_offset = gfx::ScrollOffset(42.f, 41.f); scroll_delegate.set_getter_return_value(current_offset); host_impl_->ScrollBy(gfx::Point(), scroll_delta); - EXPECT_EQ(current_offset + scroll_delta, + EXPECT_EQ(current_offset + gfx::ScrollOffset(scroll_delta), scroll_delegate.last_set_scroll_offset()); host_impl_->ScrollEnd(); - scroll_delegate.set_getter_return_value(gfx::Vector2dF()); + scroll_delegate.set_getter_return_value(gfx::ScrollOffset()); // Forces a full tree synchronization and ensures that the scroll delegate // sees the correct size of the new tree. gfx::Size new_size(42, 24); host_impl_->CreatePendingTree(); CreateScrollAndContentsLayers(host_impl_->pending_tree(), new_size); - host_impl_->ActivatePendingTree(); + host_impl_->ActivateSyncTree(); EXPECT_EQ(new_size, scroll_delegate.scrollable_size()); // Un-setting the delegate should propagate the delegate's current offset to // the root scrollable layer. - current_offset = gfx::Vector2dF(13.f, 12.f); + current_offset = gfx::ScrollOffset(13.f, 12.f); scroll_delegate.set_getter_return_value(current_offset); host_impl_->SetRootLayerScrollOffsetDelegate(NULL); @@ -3199,18 +3782,23 @@ TEST_F(LayerTreeHostImplTest, EXPECT_FALSE(host_impl_->active_tree()->needs_update_draw_properties()); // Set external scroll delta on delegate and notify LayerTreeHost. - gfx::Vector2dF scroll_delta(10.f, 10.f); - scroll_delegate.set_getter_return_value(scroll_delta); + gfx::ScrollOffset scroll_offset(10.f, 10.f); + scroll_delegate.set_getter_return_value(scroll_offset); host_impl_->OnRootLayerDelegatedScrollOffsetChanged(); // Check scroll delta reflected in layer. - DrawFrame(); - CheckLayerScrollDelta(scroll_layer, scroll_delta); + LayerTreeHostImpl::FrameData frame; + EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); + host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); + host_impl_->DidDrawAllLayers(frame); + EXPECT_FALSE(frame.has_no_damage); + CheckLayerScrollDelta(scroll_layer, ScrollOffsetToVector2dF(scroll_offset)); host_impl_->SetRootLayerScrollOffsetDelegate(NULL); } TEST_F(LayerTreeHostImplTest, OverscrollRoot) { + InputHandlerScrollResult scroll_result; SetupScrollAndContentsLayers(gfx::Size(100, 100)); host_impl_->SetViewportSize(gfx::Size(50, 50)); host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f, 0.5f, 4.f); @@ -3220,38 +3808,105 @@ TEST_F(LayerTreeHostImplTest, OverscrollRoot) { // In-bounds scrolling does not affect overscroll. EXPECT_EQ(InputHandler::ScrollStarted, host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel)); - host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10)); + scroll_result = host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10)); + EXPECT_TRUE(scroll_result.did_scroll); + EXPECT_FALSE(scroll_result.did_overscroll_root); + EXPECT_EQ(gfx::Vector2dF(), scroll_result.unused_scroll_delta); EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll()); // Overscroll events are reflected immediately. - host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 50)); + scroll_result = host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 50)); + EXPECT_TRUE(scroll_result.did_scroll); + EXPECT_TRUE(scroll_result.did_overscroll_root); + EXPECT_EQ(gfx::Vector2dF(0, 10), scroll_result.unused_scroll_delta); EXPECT_EQ(gfx::Vector2dF(0, 10), host_impl_->accumulated_root_overscroll()); + EXPECT_EQ(scroll_result.accumulated_root_overscroll, + host_impl_->accumulated_root_overscroll()); // In-bounds scrolling resets accumulated overscroll for the scrolled axes. - host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, -50)); + scroll_result = host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, -50)); + EXPECT_TRUE(scroll_result.did_scroll); + EXPECT_FALSE(scroll_result.did_overscroll_root); + EXPECT_EQ(gfx::Vector2dF(), scroll_result.unused_scroll_delta); EXPECT_EQ(gfx::Vector2dF(0, 0), host_impl_->accumulated_root_overscroll()); - host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, -10)); + EXPECT_EQ(scroll_result.accumulated_root_overscroll, + host_impl_->accumulated_root_overscroll()); + + scroll_result = host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, -10)); + EXPECT_FALSE(scroll_result.did_scroll); + EXPECT_TRUE(scroll_result.did_overscroll_root); + EXPECT_EQ(gfx::Vector2dF(0, -10), scroll_result.unused_scroll_delta); EXPECT_EQ(gfx::Vector2dF(0, -10), host_impl_->accumulated_root_overscroll()); - host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(10, 0)); + EXPECT_EQ(scroll_result.accumulated_root_overscroll, + host_impl_->accumulated_root_overscroll()); + + scroll_result = host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(10, 0)); + EXPECT_TRUE(scroll_result.did_scroll); + EXPECT_FALSE(scroll_result.did_overscroll_root); + EXPECT_EQ(gfx::Vector2dF(0, 0), scroll_result.unused_scroll_delta); EXPECT_EQ(gfx::Vector2dF(0, -10), host_impl_->accumulated_root_overscroll()); - host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(-15, 0)); + EXPECT_EQ(scroll_result.accumulated_root_overscroll, + host_impl_->accumulated_root_overscroll()); + + scroll_result = host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(-15, 0)); + EXPECT_TRUE(scroll_result.did_scroll); + EXPECT_TRUE(scroll_result.did_overscroll_root); + EXPECT_EQ(gfx::Vector2dF(-5, 0), scroll_result.unused_scroll_delta); EXPECT_EQ(gfx::Vector2dF(-5, -10), host_impl_->accumulated_root_overscroll()); - host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 60)); + EXPECT_EQ(scroll_result.accumulated_root_overscroll, + host_impl_->accumulated_root_overscroll()); + + scroll_result = host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 60)); + EXPECT_TRUE(scroll_result.did_scroll); + EXPECT_TRUE(scroll_result.did_overscroll_root); + EXPECT_EQ(gfx::Vector2dF(0, 10), scroll_result.unused_scroll_delta); EXPECT_EQ(gfx::Vector2dF(-5, 10), host_impl_->accumulated_root_overscroll()); - host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(10, -60)); + EXPECT_EQ(scroll_result.accumulated_root_overscroll, + host_impl_->accumulated_root_overscroll()); + + scroll_result = host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(10, -60)); + EXPECT_TRUE(scroll_result.did_scroll); + EXPECT_TRUE(scroll_result.did_overscroll_root); + EXPECT_EQ(gfx::Vector2dF(0, -10), scroll_result.unused_scroll_delta); EXPECT_EQ(gfx::Vector2dF(0, -10), host_impl_->accumulated_root_overscroll()); + EXPECT_EQ(scroll_result.accumulated_root_overscroll, + host_impl_->accumulated_root_overscroll()); // Overscroll accumulates within the scope of ScrollBegin/ScrollEnd as long // as no scroll occurs. - host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, -20)); + scroll_result = host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, -20)); + EXPECT_FALSE(scroll_result.did_scroll); + EXPECT_TRUE(scroll_result.did_overscroll_root); + EXPECT_EQ(gfx::Vector2dF(0, -20), scroll_result.unused_scroll_delta); EXPECT_EQ(gfx::Vector2dF(0, -30), host_impl_->accumulated_root_overscroll()); - host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, -20)); + EXPECT_EQ(scroll_result.accumulated_root_overscroll, + host_impl_->accumulated_root_overscroll()); + + scroll_result = host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, -20)); + EXPECT_FALSE(scroll_result.did_scroll); + EXPECT_TRUE(scroll_result.did_overscroll_root); + EXPECT_EQ(gfx::Vector2dF(0, -20), scroll_result.unused_scroll_delta); EXPECT_EQ(gfx::Vector2dF(0, -50), host_impl_->accumulated_root_overscroll()); + EXPECT_EQ(scroll_result.accumulated_root_overscroll, + host_impl_->accumulated_root_overscroll()); + // Overscroll resets on valid scroll. - host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10)); + scroll_result = host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10)); + EXPECT_TRUE(scroll_result.did_scroll); + EXPECT_FALSE(scroll_result.did_overscroll_root); + EXPECT_EQ(gfx::Vector2dF(0, 0), scroll_result.unused_scroll_delta); EXPECT_EQ(gfx::Vector2dF(0, 0), host_impl_->accumulated_root_overscroll()); - host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, -20)); + EXPECT_EQ(scroll_result.accumulated_root_overscroll, + host_impl_->accumulated_root_overscroll()); + + scroll_result = host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, -20)); + EXPECT_TRUE(scroll_result.did_scroll); + EXPECT_TRUE(scroll_result.did_overscroll_root); + EXPECT_EQ(gfx::Vector2dF(0, -10), scroll_result.unused_scroll_delta); EXPECT_EQ(gfx::Vector2dF(0, -10), host_impl_->accumulated_root_overscroll()); + EXPECT_EQ(scroll_result.accumulated_root_overscroll, + host_impl_->accumulated_root_overscroll()); + host_impl_->ScrollEnd(); } @@ -3276,8 +3931,8 @@ TEST_F(LayerTreeHostImplTest, OverscrollChildWithoutBubbling) { LayerImpl* child_layer = child.get(); root->AddChild(child.Pass()); root_clip->AddChild(root.Pass()); - child_layer->SetScrollOffset(gfx::Vector2d(0, 3)); - grand_child_layer->SetScrollOffset(gfx::Vector2d(0, 2)); + child_layer->SetScrollOffset(gfx::ScrollOffset(0, 3)); + grand_child_layer->SetScrollOffset(gfx::ScrollOffset(0, 2)); host_impl_->active_tree()->SetRootLayer(root_clip.Pass()); host_impl_->active_tree()->DidBecomeActive(); host_impl_->SetViewportSize(surface_size); @@ -3477,13 +4132,13 @@ class BlendStateCheckLayer : public LayerImpl { static scoped_ptr<LayerImpl> Create(LayerTreeImpl* tree_impl, int id, ResourceProvider* resource_provider) { - return scoped_ptr<LayerImpl>(new BlendStateCheckLayer(tree_impl, - id, - resource_provider)); + return make_scoped_ptr( + new BlendStateCheckLayer(tree_impl, id, resource_provider)); } - virtual void AppendQuads(QuadSink* quad_sink, - AppendQuadsData* append_quads_data) OVERRIDE { + void AppendQuads(RenderPass* render_pass, + const Occlusion& occlusion_in_content_space, + AppendQuadsData* append_quads_data) override { quads_appended_ = true; gfx::Rect opaque_rect; @@ -3493,10 +4148,12 @@ class BlendStateCheckLayer : public LayerImpl { opaque_rect = opaque_content_rect_; gfx::Rect visible_quad_rect = quad_rect_; - SharedQuadState* shared_quad_state = quad_sink->CreateSharedQuadState(); + SharedQuadState* shared_quad_state = + render_pass->CreateAndAppendSharedQuadState(); PopulateSharedQuadState(shared_quad_state); - scoped_ptr<TileDrawQuad> test_blending_draw_quad = TileDrawQuad::Create(); + TileDrawQuad* test_blending_draw_quad = + render_pass->CreateAndAppendDrawQuad<TileDrawQuad>(); test_blending_draw_quad->SetNew(shared_quad_state, quad_rect_, opaque_rect, @@ -3508,7 +4165,6 @@ class BlendStateCheckLayer : public LayerImpl { test_blending_draw_quad->visible_rect = quad_visible_rect_; EXPECT_EQ(blend_, test_blending_draw_quad->ShouldDrawWithBlending()); EXPECT_EQ(has_render_surface_, !!render_surface()); - quad_sink->Append(test_blending_draw_quad.PassAs<DrawQuad>()); } void SetExpectation(bool blend, bool has_render_surface) { @@ -3538,7 +4194,7 @@ class BlendStateCheckLayer : public LayerImpl { resource_id_(resource_provider->CreateResource( gfx::Size(1, 1), GL_CLAMP_TO_EDGE, - ResourceProvider::TextureUsageAny, + ResourceProvider::TextureHintImmutable, RGBA_8888)) { resource_provider->AllocateForTesting(resource_id_); SetBounds(gfx::Size(10, 10)); @@ -3579,7 +4235,7 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) { // Opaque layer, drawn without blending. layer1->SetContentsOpaque(true); layer1->SetExpectation(false, false); - layer1->SetUpdateRect(gfx::RectF(layer1->content_bounds())); + layer1->SetUpdateRect(gfx::Rect(layer1->content_bounds())); EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); EXPECT_TRUE(layer1->quads_appended()); @@ -3588,7 +4244,7 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) { // Layer with translucent content and painting, so drawn with blending. layer1->SetContentsOpaque(false); layer1->SetExpectation(true, false); - layer1->SetUpdateRect(gfx::RectF(layer1->content_bounds())); + layer1->SetUpdateRect(gfx::Rect(layer1->content_bounds())); EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); EXPECT_TRUE(layer1->quads_appended()); @@ -3598,7 +4254,7 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) { layer1->SetContentsOpaque(true); layer1->SetOpacity(0.5f); layer1->SetExpectation(true, false); - layer1->SetUpdateRect(gfx::RectF(layer1->content_bounds())); + layer1->SetUpdateRect(gfx::Rect(layer1->content_bounds())); EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); EXPECT_TRUE(layer1->quads_appended()); @@ -3608,7 +4264,7 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) { layer1->SetContentsOpaque(true); layer1->SetOpacity(0.5f); layer1->SetExpectation(true, false); - layer1->SetUpdateRect(gfx::RectF(layer1->content_bounds())); + layer1->SetUpdateRect(gfx::Rect(layer1->content_bounds())); EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); EXPECT_TRUE(layer1->quads_appended()); @@ -3626,11 +4282,11 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) { layer1->SetContentsOpaque(true); layer1->SetOpacity(1.f); layer1->SetExpectation(false, false); - layer1->SetUpdateRect(gfx::RectF(layer1->content_bounds())); + layer1->SetUpdateRect(gfx::Rect(layer1->content_bounds())); layer2->SetContentsOpaque(true); layer2->SetOpacity(1.f); layer2->SetExpectation(false, false); - layer2->SetUpdateRect(gfx::RectF(layer1->content_bounds())); + layer2->SetUpdateRect(gfx::Rect(layer1->content_bounds())); EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); EXPECT_TRUE(layer1->quads_appended()); @@ -3641,9 +4297,9 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) { // Child layer with opaque content, drawn without blending. layer1->SetContentsOpaque(false); layer1->SetExpectation(true, false); - layer1->SetUpdateRect(gfx::RectF(layer1->content_bounds())); + layer1->SetUpdateRect(gfx::Rect(layer1->content_bounds())); layer2->SetExpectation(false, false); - layer2->SetUpdateRect(gfx::RectF(layer1->content_bounds())); + layer2->SetUpdateRect(gfx::Rect(layer1->content_bounds())); EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); EXPECT_TRUE(layer1->quads_appended()); @@ -3655,9 +4311,9 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) { // Child layer with opaque content, drawn without blending. layer1->SetContentsOpaque(true); layer1->SetExpectation(false, false); - layer1->SetUpdateRect(gfx::RectF(layer1->content_bounds())); + layer1->SetUpdateRect(gfx::Rect(layer1->content_bounds())); layer2->SetExpectation(false, false); - layer2->SetUpdateRect(gfx::RectF(layer1->content_bounds())); + layer2->SetUpdateRect(gfx::Rect(layer1->content_bounds())); EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); EXPECT_TRUE(layer1->quads_appended()); @@ -3672,9 +4328,11 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) { layer1->SetContentsOpaque(true); layer1->SetOpacity(0.5f); layer1->SetExpectation(false, true); - layer1->SetUpdateRect(gfx::RectF(layer1->content_bounds())); + layer1->SetUpdateRect(gfx::Rect(layer1->content_bounds())); layer2->SetExpectation(false, false); - layer2->SetUpdateRect(gfx::RectF(layer1->content_bounds())); + layer2->SetUpdateRect(gfx::Rect(layer1->content_bounds())); + FakeLayerTreeHostImpl::RecursiveUpdateNumChildren( + host_impl_->active_tree()->root_layer()); EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); EXPECT_TRUE(layer1->quads_appended()); @@ -3686,11 +4344,11 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) { layer1->SetContentsOpaque(true); layer1->SetOpacity(1.f); layer1->SetExpectation(false, false); - layer1->SetUpdateRect(gfx::RectF(layer1->content_bounds())); + layer1->SetUpdateRect(gfx::Rect(layer1->content_bounds())); layer2->SetContentsOpaque(true); layer2->SetOpacity(0.5f); layer2->SetExpectation(true, false); - layer2->SetUpdateRect(gfx::RectF(layer1->content_bounds())); + layer2->SetUpdateRect(gfx::Rect(layer1->content_bounds())); EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); EXPECT_TRUE(layer1->quads_appended()); @@ -3701,11 +4359,11 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) { layer1->SetContentsOpaque(true); layer1->SetOpacity(1.f); layer1->SetExpectation(false, false); - layer1->SetUpdateRect(gfx::RectF(layer1->content_bounds())); + layer1->SetUpdateRect(gfx::Rect(layer1->content_bounds())); layer2->SetContentsOpaque(false); layer2->SetOpacity(1.f); layer2->SetExpectation(true, false); - layer2->SetUpdateRect(gfx::RectF(layer1->content_bounds())); + layer2->SetUpdateRect(gfx::Rect(layer1->content_bounds())); EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); EXPECT_TRUE(layer1->quads_appended()); @@ -3717,11 +4375,11 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) { layer1->SetContentsOpaque(true); layer1->SetOpacity(1.f); layer1->SetExpectation(false, false); - layer1->SetUpdateRect(gfx::RectF(layer1->content_bounds())); + layer1->SetUpdateRect(gfx::Rect(layer1->content_bounds())); layer2->SetContentsOpaque(true); layer2->SetOpacity(1.f); layer2->SetExpectation(false, false); - layer2->SetUpdateRect(gfx::RectF(layer1->content_bounds())); + layer2->SetUpdateRect(gfx::Rect(layer1->content_bounds())); EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); EXPECT_TRUE(layer1->quads_appended()); @@ -3734,7 +4392,7 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) { layer1->SetQuadVisibleRect(gfx::Rect(5, 5, 5, 5)); layer1->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5)); layer1->SetExpectation(true, false); - layer1->SetUpdateRect(gfx::RectF(layer1->content_bounds())); + layer1->SetUpdateRect(gfx::Rect(layer1->content_bounds())); EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); EXPECT_TRUE(layer1->quads_appended()); @@ -3746,7 +4404,7 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) { layer1->SetQuadVisibleRect(gfx::Rect(5, 5, 5, 2)); layer1->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5)); layer1->SetExpectation(true, false); - layer1->SetUpdateRect(gfx::RectF(layer1->content_bounds())); + layer1->SetUpdateRect(gfx::Rect(layer1->content_bounds())); EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); EXPECT_TRUE(layer1->quads_appended()); @@ -3758,7 +4416,7 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) { layer1->SetQuadVisibleRect(gfx::Rect(7, 5, 3, 5)); layer1->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5)); layer1->SetExpectation(true, false); - layer1->SetUpdateRect(gfx::RectF(layer1->content_bounds())); + layer1->SetUpdateRect(gfx::Rect(layer1->content_bounds())); EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); EXPECT_TRUE(layer1->quads_appended()); @@ -3771,7 +4429,7 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) { layer1->SetQuadVisibleRect(gfx::Rect(5, 5, 2, 5)); layer1->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5)); layer1->SetExpectation(false, false); - layer1->SetUpdateRect(gfx::RectF(layer1->content_bounds())); + layer1->SetUpdateRect(gfx::Rect(layer1->content_bounds())); EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); EXPECT_TRUE(layer1->quads_appended()); @@ -3787,10 +4445,9 @@ class LayerTreeHostImplViewportCoveredTest : public LayerTreeHostImplTest { scoped_ptr<OutputSurface> CreateFakeOutputSurface(bool always_draw) { if (always_draw) { - return FakeOutputSurface::CreateAlwaysDrawAndSwap3d() - .PassAs<OutputSurface>(); + return FakeOutputSurface::CreateAlwaysDrawAndSwap3d(); } - return FakeOutputSurface::Create3d().PassAs<OutputSurface>(); + return FakeOutputSurface::Create3d(); } void SetupActiveTreeLayers() { @@ -3891,9 +4548,7 @@ class LayerTreeHostImplViewportCoveredTest : public LayerTreeHostImplTest { host_impl_->DidDrawAllLayers(frame); } - virtual void DidActivatePendingTree() OVERRIDE { - did_activate_pending_tree_ = true; - } + void DidActivateSyncTree() override { did_activate_pending_tree_ = true; } void set_gutter_quad_material(DrawQuad::Material material) { gutter_quad_material_ = material; @@ -3905,9 +4560,8 @@ class LayerTreeHostImplViewportCoveredTest : public LayerTreeHostImplTest { protected: size_t CountGutterQuads(const QuadList& quad_list) { size_t num_gutter_quads = 0; - for (size_t i = 0; i < quad_list.size(); ++i) { - num_gutter_quads += (quad_list[i]->material == - gutter_quad_material_) ? 1 : 0; + for (const auto& quad : quad_list) { + num_gutter_quads += (quad->material == gutter_quad_material_) ? 1 : 0; } return num_gutter_quads; } @@ -3919,20 +4573,22 @@ class LayerTreeHostImplViewportCoveredTest : public LayerTreeHostImplTest { // Make sure that the texture coordinates match their expectations. void ValidateTextureDrawQuads(const QuadList& quad_list) { - for (size_t i = 0; i < quad_list.size(); ++i) { - if (quad_list[i]->material != DrawQuad::TEXTURE_CONTENT) + for (const auto& quad : quad_list) { + if (quad->material != DrawQuad::TEXTURE_CONTENT) continue; - const TextureDrawQuad* quad = TextureDrawQuad::MaterialCast(quad_list[i]); + const TextureDrawQuad* texture_quad = TextureDrawQuad::MaterialCast(quad); gfx::SizeF gutter_texture_size_pixels = gfx::ScaleSize( gutter_texture_size_, host_impl_->device_scale_factor()); - EXPECT_EQ(quad->uv_top_left.x(), - quad->rect.x() / gutter_texture_size_pixels.width()); - EXPECT_EQ(quad->uv_top_left.y(), - quad->rect.y() / gutter_texture_size_pixels.height()); - EXPECT_EQ(quad->uv_bottom_right.x(), - quad->rect.right() / gutter_texture_size_pixels.width()); - EXPECT_EQ(quad->uv_bottom_right.y(), - quad->rect.bottom() / gutter_texture_size_pixels.height()); + EXPECT_EQ(texture_quad->uv_top_left.x(), + texture_quad->rect.x() / gutter_texture_size_pixels.width()); + EXPECT_EQ(texture_quad->uv_top_left.y(), + texture_quad->rect.y() / gutter_texture_size_pixels.height()); + EXPECT_EQ( + texture_quad->uv_bottom_right.x(), + texture_quad->rect.right() / gutter_texture_size_pixels.width()); + EXPECT_EQ( + texture_quad->uv_bottom_right.y(), + texture_quad->rect.bottom() / gutter_texture_size_pixels.height()); } } @@ -4049,7 +4705,7 @@ TEST_F(LayerTreeHostImplViewportCoveredTest, ActiveTreeShrinkViewportInvalid) { viewport_size_.height() + 100); host_impl_->SetViewportSize(DipSizeToPixelSize(larger_viewport)); EXPECT_TRUE(host_impl_->active_tree()->ViewportSizeInvalid()); - host_impl_->ActivatePendingTree(); + host_impl_->ActivateSyncTree(); EXPECT_TRUE(did_activate_pending_tree_); EXPECT_FALSE(host_impl_->active_tree()->ViewportSizeInvalid()); @@ -4067,7 +4723,7 @@ TEST_F(LayerTreeHostImplViewportCoveredTest, ActiveTreeShrinkViewportInvalid) { class FakeDrawableLayerImpl: public LayerImpl { public: static scoped_ptr<LayerImpl> Create(LayerTreeImpl* tree_impl, int id) { - return scoped_ptr<LayerImpl>(new FakeDrawableLayerImpl(tree_impl, id)); + return make_scoped_ptr(new FakeDrawableLayerImpl(tree_impl, id)); } protected: FakeDrawableLayerImpl(LayerTreeImpl* tree_impl, int id) @@ -4133,8 +4789,9 @@ TEST_F(LayerTreeHostImplTest, PartialSwapReceivesDamageRect) { context_provider->BindToCurrentThread(); context_provider->TestContext3d()->set_have_post_sub_buffer(true); - scoped_ptr<OutputSurface> output_surface( + scoped_ptr<FakeOutputSurface> output_surface( FakeOutputSurface::Create3d(context_provider)); + FakeOutputSurface* fake_output_surface = output_surface.get(); // This test creates its own LayerTreeHostImpl, so // that we can force partial swap enabled. @@ -4148,6 +4805,7 @@ TEST_F(LayerTreeHostImplTest, PartialSwapReceivesDamageRect) { &proxy_, &stats_instrumentation_, shared_bitmap_manager.get(), + NULL, 0); layer_tree_host_impl->InitializeRenderer(output_surface.Pass()); layer_tree_host_impl->SetViewportSize(gfx::Size(500, 500)); @@ -4173,8 +4831,9 @@ TEST_F(LayerTreeHostImplTest, PartialSwapReceivesDamageRect) { layer_tree_host_impl->DrawLayers(&frame, gfx::FrameTime::Now()); layer_tree_host_impl->DidDrawAllLayers(frame); layer_tree_host_impl->SwapBuffers(frame); - EXPECT_EQ(TestContextSupport::SWAP, - context_provider->support()->last_swap_type()); + gfx::Rect expected_swap_rect(0, 0, 500, 500); + EXPECT_EQ(expected_swap_rect.ToString(), + fake_output_surface->last_swap_rect().ToString()); // Second frame, only the damaged area should get swapped. Damage should be // the union of old and new child rects. @@ -4190,12 +4849,9 @@ TEST_F(LayerTreeHostImplTest, PartialSwapReceivesDamageRect) { // Make sure that partial swap is constrained to the viewport dimensions // expected damage rect: gfx::Rect(500, 500); // expected swap rect: flipped damage rect, but also clamped to viewport - EXPECT_EQ(TestContextSupport::PARTIAL_SWAP, - context_provider->support()->last_swap_type()); - gfx::Rect expected_swap_rect(0, 500-28, 26, 28); + expected_swap_rect = gfx::Rect(0, 500-28, 26, 28); EXPECT_EQ(expected_swap_rect.ToString(), - context_provider->support()-> - last_partial_swap_rect().ToString()); + fake_output_surface->last_swap_rect().ToString()); layer_tree_host_impl->SetViewportSize(gfx::Size(10, 10)); // This will damage everything. @@ -4206,8 +4862,9 @@ TEST_F(LayerTreeHostImplTest, PartialSwapReceivesDamageRect) { host_impl_->DidDrawAllLayers(frame); layer_tree_host_impl->SwapBuffers(frame); - EXPECT_EQ(TestContextSupport::SWAP, - context_provider->support()->last_swap_type()); + expected_swap_rect = gfx::Rect(0, 0, 10, 10); + EXPECT_EQ(expected_swap_rect.ToString(), + fake_output_surface->last_swap_rect().ToString()); } TEST_F(LayerTreeHostImplTest, RootLayerDoesntCreateExtraSurface) { @@ -4237,21 +4894,23 @@ TEST_F(LayerTreeHostImplTest, RootLayerDoesntCreateExtraSurface) { class FakeLayerWithQuads : public LayerImpl { public: static scoped_ptr<LayerImpl> Create(LayerTreeImpl* tree_impl, int id) { - return scoped_ptr<LayerImpl>(new FakeLayerWithQuads(tree_impl, id)); + return make_scoped_ptr(new FakeLayerWithQuads(tree_impl, id)); } - virtual void AppendQuads(QuadSink* quad_sink, - AppendQuadsData* append_quads_data) OVERRIDE { - SharedQuadState* shared_quad_state = quad_sink->CreateSharedQuadState(); + void AppendQuads(RenderPass* render_pass, + const Occlusion& occlusion_in_content_space, + AppendQuadsData* append_quads_data) override { + SharedQuadState* shared_quad_state = + render_pass->CreateAndAppendSharedQuadState(); PopulateSharedQuadState(shared_quad_state); SkColor gray = SkColorSetRGB(100, 100, 100); gfx::Rect quad_rect(content_bounds()); gfx::Rect visible_quad_rect(quad_rect); - scoped_ptr<SolidColorDrawQuad> my_quad = SolidColorDrawQuad::Create(); + SolidColorDrawQuad* my_quad = + render_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); my_quad->SetNew( shared_quad_state, quad_rect, visible_quad_rect, gray, false); - quad_sink->Append(my_quad.PassAs<DrawQuad>()); } private: @@ -4349,15 +5008,13 @@ class MockContextHarness { TEST_F(LayerTreeHostImplTest, NoPartialSwap) { scoped_ptr<MockContext> mock_context_owned(new MockContext); MockContext* mock_context = mock_context_owned.get(); - - scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d( - mock_context_owned.PassAs<TestWebGraphicsContext3D>())); MockContextHarness harness(mock_context); // Run test case LayerTreeSettings settings = DefaultSettings(); settings.partial_swap_enabled = false; - CreateHostImpl(settings, output_surface.Pass()); + CreateHostImpl(settings, + FakeOutputSurface::Create3d(mock_context_owned.Pass())); SetupRootLayerImpl(FakeLayerWithQuads::Create(host_impl_->active_tree(), 1)); // Without partial swap, and no clipping, no scissor is set. @@ -4388,13 +5045,11 @@ TEST_F(LayerTreeHostImplTest, NoPartialSwap) { TEST_F(LayerTreeHostImplTest, PartialSwap) { scoped_ptr<MockContext> context_owned(new MockContext); MockContext* mock_context = context_owned.get(); - scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d( - context_owned.PassAs<TestWebGraphicsContext3D>())); MockContextHarness harness(mock_context); LayerTreeSettings settings = DefaultSettings(); settings.partial_swap_enabled = true; - CreateHostImpl(settings, output_surface.Pass()); + CreateHostImpl(settings, FakeOutputSurface::Create3d(context_owned.Pass())); SetupRootLayerImpl(FakeLayerWithQuads::Create(host_impl_->active_tree(), 1)); // The first frame is not a partially-swapped one. @@ -4439,7 +5094,7 @@ static scoped_ptr<LayerTreeHostImpl> SetupLayersForOpacity( LayerTreeSettings settings; settings.partial_swap_enabled = partial_swap; scoped_ptr<LayerTreeHostImpl> my_host_impl = LayerTreeHostImpl::Create( - settings, client, proxy, stats_instrumentation, manager, 0); + settings, client, proxy, stats_instrumentation, manager, NULL, 0); my_host_impl->InitializeRenderer(output_surface.Pass()); my_host_impl->SetViewportSize(gfx::Size(100, 100)); @@ -4519,9 +5174,9 @@ TEST_F(LayerTreeHostImplTest, ContributingLayerEmptyScissorPartialSwap) { ASSERT_EQ(1U, frame.render_passes[0]->quad_list.size()); ASSERT_EQ(1U, frame.render_passes[1]->quad_list.size()); EXPECT_EQ(DrawQuad::SOLID_COLOR, - frame.render_passes[0]->quad_list[0]->material); + frame.render_passes[0]->quad_list.front()->material); EXPECT_EQ(DrawQuad::RENDER_PASS, - frame.render_passes[1]->quad_list[0]->material); + frame.render_passes[1]->quad_list.front()->material); my_host_impl->DrawLayers(&frame, gfx::FrameTime::Now()); my_host_impl->DidDrawAllLayers(frame); @@ -4546,9 +5201,9 @@ TEST_F(LayerTreeHostImplTest, ContributingLayerEmptyScissorNoPartialSwap) { ASSERT_EQ(1U, frame.render_passes[0]->quad_list.size()); ASSERT_EQ(1U, frame.render_passes[1]->quad_list.size()); EXPECT_EQ(DrawQuad::SOLID_COLOR, - frame.render_passes[0]->quad_list[0]->material); + frame.render_passes[0]->quad_list.front()->material); EXPECT_EQ(DrawQuad::RENDER_PASS, - frame.render_passes[1]->quad_list[0]->material); + frame.render_passes[1]->quad_list.front()->material); my_host_impl->DrawLayers(&frame, gfx::FrameTime::Now()); my_host_impl->DidDrawAllLayers(frame); @@ -4572,12 +5227,12 @@ TEST_F(LayerTreeHostImplTest, LayersFreeTextures) { gfx::Size(4, 4), 0x80, 0x80, 0x80, base::TimeDelta()); FakeVideoFrameProvider provider; provider.set_frame(softwareFrame); - scoped_ptr<VideoLayerImpl> video_layer = - VideoLayerImpl::Create(host_impl_->active_tree(), 4, &provider); + scoped_ptr<VideoLayerImpl> video_layer = VideoLayerImpl::Create( + host_impl_->active_tree(), 4, &provider, media::VIDEO_ROTATION_0); video_layer->SetBounds(gfx::Size(10, 10)); video_layer->SetContentBounds(gfx::Size(10, 10)); video_layer->SetDrawsContent(true); - root_layer->AddChild(video_layer.PassAs<LayerImpl>()); + root_layer->AddChild(video_layer.Pass()); scoped_ptr<IOSurfaceLayerImpl> io_surface_layer = IOSurfaceLayerImpl::Create(host_impl_->active_tree(), 5); @@ -4585,7 +5240,7 @@ TEST_F(LayerTreeHostImplTest, LayersFreeTextures) { io_surface_layer->SetContentBounds(gfx::Size(10, 10)); io_surface_layer->SetDrawsContent(true); io_surface_layer->SetIOSurfaceProperties(1, gfx::Size(10, 10)); - root_layer->AddChild(io_surface_layer.PassAs<LayerImpl>()); + root_layer->AddChild(io_surface_layer.Pass()); host_impl_->active_tree()->SetRootLayer(root_layer.Pass()); @@ -4620,13 +5275,11 @@ TEST_F(LayerTreeHostImplTest, HasTransparentBackground) { new MockDrawQuadsToFillScreenContext); MockDrawQuadsToFillScreenContext* mock_context = mock_context_owned.get(); - scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d( - mock_context_owned.PassAs<TestWebGraphicsContext3D>())); - // Run test case LayerTreeSettings settings = DefaultSettings(); settings.partial_swap_enabled = false; - CreateHostImpl(settings, output_surface.Pass()); + CreateHostImpl(settings, + FakeOutputSurface::Create3d(mock_context_owned.Pass())); SetupRootLayerImpl(LayerImpl::Create(host_impl_->active_tree(), 1)); host_impl_->active_tree()->set_background_color(SK_ColorWHITE); @@ -4694,8 +5347,8 @@ TEST_F(LayerTreeHostImplTest, ReleaseContentsTextureShouldTriggerCommit) { class LayerTreeHostImplTestWithDelegatingRenderer : public LayerTreeHostImplTest { protected: - virtual scoped_ptr<OutputSurface> CreateOutputSurface() OVERRIDE { - return FakeOutputSurface::CreateDelegating3d().PassAs<OutputSurface>(); + scoped_ptr<OutputSurface> CreateOutputSurface() override { + return FakeOutputSurface::CreateDelegating3d(); } void DrawFrameAndTestDamage(const gfx::RectF& expected_damage) { @@ -4721,12 +5374,12 @@ class LayerTreeHostImplTestWithDelegatingRenderer LayerImpl* child = host_impl_->active_tree()->root_layer()->children()[0]; gfx::RectF expected_child_visible_rect(child->content_bounds()); EXPECT_RECT_EQ(expected_child_visible_rect, - root_render_pass->quad_list[0]->visible_rect); + root_render_pass->quad_list.front()->visible_rect); LayerImpl* root = host_impl_->active_tree()->root_layer(); gfx::RectF expected_root_visible_rect(root->content_bounds()); EXPECT_RECT_EQ(expected_root_visible_rect, - root_render_pass->quad_list[1]->visible_rect); + root_render_pass->quad_list.ElementAt(1)->visible_rect); } host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); @@ -4750,9 +5403,9 @@ TEST_F(LayerTreeHostImplTestWithDelegatingRenderer, FrameIncludesDamageRect) { child->SetBounds(gfx::Size(1, 1)); child->SetContentBounds(gfx::Size(1, 1)); child->SetDrawsContent(true); - root->AddChild(child.PassAs<LayerImpl>()); + root->AddChild(child.Pass()); - host_impl_->active_tree()->SetRootLayer(root.PassAs<LayerImpl>()); + host_impl_->active_tree()->SetRootLayer(root.Pass()); // Draw a frame. In the first frame, the entire viewport should be damaged. gfx::Rect full_frame_damage(host_impl_->DrawViewportSize()); @@ -4784,8 +5437,9 @@ class FakeMaskLayerImpl : public LayerImpl { return make_scoped_ptr(new FakeMaskLayerImpl(tree_impl, id)); } - virtual ResourceProvider::ResourceId ContentsResourceId() const OVERRIDE { - return 0; + void GetContentsResourceId(ResourceProvider::ResourceId* resource_id, + gfx::Size* resource_size) const override { + *resource_id = 0; } private: @@ -4822,7 +5476,7 @@ TEST_F(LayerTreeHostImplTest, MaskLayerWithScaling) { scoped_ptr<FakeMaskLayerImpl> scoped_mask_layer = FakeMaskLayerImpl::Create(host_impl_->active_tree(), 4); FakeMaskLayerImpl* mask_layer = scoped_mask_layer.get(); - content_layer->SetMaskLayer(scoped_mask_layer.PassAs<LayerImpl>()); + content_layer->SetMaskLayer(scoped_mask_layer.Pass()); gfx::Size root_size(100, 100); root->SetBounds(root_size); @@ -4860,13 +5514,16 @@ TEST_F(LayerTreeHostImplTest, MaskLayerWithScaling) { ASSERT_EQ(1u, frame.render_passes.size()); ASSERT_EQ(1u, frame.render_passes[0]->quad_list.size()); ASSERT_EQ(DrawQuad::RENDER_PASS, - frame.render_passes[0]->quad_list[0]->material); + frame.render_passes[0]->quad_list.front()->material); const RenderPassDrawQuad* render_pass_quad = - RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[0]); + RenderPassDrawQuad::MaterialCast( + frame.render_passes[0]->quad_list.front()); EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), render_pass_quad->rect.ToString()); EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(), - render_pass_quad->mask_uv_rect.ToString()); + render_pass_quad->MaskUVRect().ToString()); + EXPECT_EQ(gfx::Vector2dF(1.f, 1.f).ToString(), + render_pass_quad->mask_uv_scale.ToString()); host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); host_impl_->DidDrawAllLayers(frame); @@ -4888,13 +5545,16 @@ TEST_F(LayerTreeHostImplTest, MaskLayerWithScaling) { ASSERT_EQ(1u, frame.render_passes.size()); ASSERT_EQ(1u, frame.render_passes[0]->quad_list.size()); ASSERT_EQ(DrawQuad::RENDER_PASS, - frame.render_passes[0]->quad_list[0]->material); + frame.render_passes[0]->quad_list.front()->material); const RenderPassDrawQuad* render_pass_quad = - RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[0]); + RenderPassDrawQuad::MaterialCast( + frame.render_passes[0]->quad_list.front()); EXPECT_EQ(gfx::Rect(0, 0, 200, 200).ToString(), render_pass_quad->rect.ToString()); EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(), - render_pass_quad->mask_uv_rect.ToString()); + render_pass_quad->MaskUVRect().ToString()); + EXPECT_EQ(gfx::Vector2dF(1.f, 1.f).ToString(), + render_pass_quad->mask_uv_scale.ToString()); host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); host_impl_->DidDrawAllLayers(frame); @@ -4918,13 +5578,16 @@ TEST_F(LayerTreeHostImplTest, MaskLayerWithScaling) { ASSERT_EQ(1u, frame.render_passes.size()); ASSERT_EQ(1u, frame.render_passes[0]->quad_list.size()); ASSERT_EQ(DrawQuad::RENDER_PASS, - frame.render_passes[0]->quad_list[0]->material); + frame.render_passes[0]->quad_list.front()->material); const RenderPassDrawQuad* render_pass_quad = - RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[0]); + RenderPassDrawQuad::MaterialCast( + frame.render_passes[0]->quad_list.front()); EXPECT_EQ(gfx::Rect(0, 0, 200, 200).ToString(), render_pass_quad->rect.ToString()); EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(), - render_pass_quad->mask_uv_rect.ToString()); + render_pass_quad->MaskUVRect().ToString()); + EXPECT_EQ(gfx::Vector2dF(1.f, 1.f).ToString(), + render_pass_quad->mask_uv_scale.ToString()); host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); host_impl_->DidDrawAllLayers(frame); @@ -4948,7 +5611,7 @@ TEST_F(LayerTreeHostImplTest, MaskLayerWithDifferentBounds) { scoped_ptr<FakeMaskLayerImpl> scoped_mask_layer = FakeMaskLayerImpl::Create(host_impl_->active_tree(), 4); FakeMaskLayerImpl* mask_layer = scoped_mask_layer.get(); - content_layer->SetMaskLayer(scoped_mask_layer.PassAs<LayerImpl>()); + content_layer->SetMaskLayer(scoped_mask_layer.Pass()); gfx::Size root_size(100, 100); root->SetBounds(root_size); @@ -4978,13 +5641,16 @@ TEST_F(LayerTreeHostImplTest, MaskLayerWithDifferentBounds) { ASSERT_EQ(1u, frame.render_passes.size()); ASSERT_EQ(1u, frame.render_passes[0]->quad_list.size()); ASSERT_EQ(DrawQuad::RENDER_PASS, - frame.render_passes[0]->quad_list[0]->material); + frame.render_passes[0]->quad_list.front()->material); const RenderPassDrawQuad* render_pass_quad = - RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[0]); + RenderPassDrawQuad::MaterialCast( + frame.render_passes[0]->quad_list.front()); EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(), render_pass_quad->rect.ToString()); EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(), - render_pass_quad->mask_uv_rect.ToString()); + render_pass_quad->MaskUVRect().ToString()); + EXPECT_EQ(gfx::Vector2dF(1.f, 1.f).ToString(), + render_pass_quad->mask_uv_scale.ToString()); host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); host_impl_->DidDrawAllLayers(frame); @@ -5005,13 +5671,16 @@ TEST_F(LayerTreeHostImplTest, MaskLayerWithDifferentBounds) { ASSERT_EQ(1u, frame.render_passes.size()); ASSERT_EQ(1u, frame.render_passes[0]->quad_list.size()); ASSERT_EQ(DrawQuad::RENDER_PASS, - frame.render_passes[0]->quad_list[0]->material); + frame.render_passes[0]->quad_list.front()->material); const RenderPassDrawQuad* render_pass_quad = - RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[0]); + RenderPassDrawQuad::MaterialCast( + frame.render_passes[0]->quad_list.front()); EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), render_pass_quad->rect.ToString()); EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(), - render_pass_quad->mask_uv_rect.ToString()); + render_pass_quad->MaskUVRect().ToString()); + EXPECT_EQ(gfx::Vector2dF(1.f, 1.f).ToString(), + render_pass_quad->mask_uv_scale.ToString()); host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); host_impl_->DidDrawAllLayers(frame); @@ -5035,13 +5704,16 @@ TEST_F(LayerTreeHostImplTest, MaskLayerWithDifferentBounds) { ASSERT_EQ(1u, frame.render_passes.size()); ASSERT_EQ(1u, frame.render_passes[0]->quad_list.size()); ASSERT_EQ(DrawQuad::RENDER_PASS, - frame.render_passes[0]->quad_list[0]->material); + frame.render_passes[0]->quad_list.front()->material); const RenderPassDrawQuad* render_pass_quad = - RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[0]); + RenderPassDrawQuad::MaterialCast( + frame.render_passes[0]->quad_list.front()); EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), render_pass_quad->rect.ToString()); EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(), - render_pass_quad->mask_uv_rect.ToString()); + render_pass_quad->MaskUVRect().ToString()); + EXPECT_EQ(gfx::Vector2dF(1.f, 1.f).ToString(), + render_pass_quad->mask_uv_scale.ToString()); host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); host_impl_->DidDrawAllLayers(frame); @@ -5060,13 +5732,16 @@ TEST_F(LayerTreeHostImplTest, MaskLayerWithDifferentBounds) { ASSERT_EQ(1u, frame.render_passes.size()); ASSERT_EQ(1u, frame.render_passes[0]->quad_list.size()); ASSERT_EQ(DrawQuad::RENDER_PASS, - frame.render_passes[0]->quad_list[0]->material); + frame.render_passes[0]->quad_list.front()->material); const RenderPassDrawQuad* render_pass_quad = - RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[0]); + RenderPassDrawQuad::MaterialCast( + frame.render_passes[0]->quad_list.front()); EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), render_pass_quad->rect.ToString()); EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(), - render_pass_quad->mask_uv_rect.ToString()); + render_pass_quad->MaskUVRect().ToString()); + EXPECT_EQ(gfx::Vector2dF(1.f, 1.f).ToString(), + render_pass_quad->mask_uv_scale.ToString()); host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); host_impl_->DidDrawAllLayers(frame); @@ -5095,7 +5770,7 @@ TEST_F(LayerTreeHostImplTest, ReflectionMaskLayerWithDifferentBounds) { scoped_ptr<FakeMaskLayerImpl> scoped_mask_layer = FakeMaskLayerImpl::Create(host_impl_->active_tree(), 4); FakeMaskLayerImpl* mask_layer = scoped_mask_layer.get(); - replica_layer->SetMaskLayer(scoped_mask_layer.PassAs<LayerImpl>()); + replica_layer->SetMaskLayer(scoped_mask_layer.Pass()); gfx::Size root_size(100, 100); root->SetBounds(root_size); @@ -5125,14 +5800,15 @@ TEST_F(LayerTreeHostImplTest, ReflectionMaskLayerWithDifferentBounds) { ASSERT_EQ(1u, frame.render_passes.size()); ASSERT_EQ(2u, frame.render_passes[0]->quad_list.size()); ASSERT_EQ(DrawQuad::RENDER_PASS, - frame.render_passes[0]->quad_list[1]->material); - const RenderPassDrawQuad* replica_quad = - RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[1]); - EXPECT_TRUE(replica_quad->is_replica); + frame.render_passes[0]->quad_list.ElementAt(1)->material); + const RenderPassDrawQuad* replica_quad = RenderPassDrawQuad::MaterialCast( + frame.render_passes[0]->quad_list.ElementAt(1)); EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(), replica_quad->rect.ToString()); EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(), - replica_quad->mask_uv_rect.ToString()); + replica_quad->MaskUVRect().ToString()); + EXPECT_EQ(gfx::Vector2dF(1.f, 1.f).ToString(), + replica_quad->mask_uv_scale.ToString()); host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); host_impl_->DidDrawAllLayers(frame); @@ -5153,14 +5829,15 @@ TEST_F(LayerTreeHostImplTest, ReflectionMaskLayerWithDifferentBounds) { ASSERT_EQ(1u, frame.render_passes.size()); ASSERT_EQ(2u, frame.render_passes[0]->quad_list.size()); ASSERT_EQ(DrawQuad::RENDER_PASS, - frame.render_passes[0]->quad_list[1]->material); - const RenderPassDrawQuad* replica_quad = - RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[1]); - EXPECT_TRUE(replica_quad->is_replica); + frame.render_passes[0]->quad_list.ElementAt(1)->material); + const RenderPassDrawQuad* replica_quad = RenderPassDrawQuad::MaterialCast( + frame.render_passes[0]->quad_list.ElementAt(1)); EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), replica_quad->rect.ToString()); EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(), - replica_quad->mask_uv_rect.ToString()); + replica_quad->MaskUVRect().ToString()); + EXPECT_EQ(gfx::Vector2dF(1.f, 1.f).ToString(), + replica_quad->mask_uv_scale.ToString()); host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); host_impl_->DidDrawAllLayers(frame); @@ -5184,14 +5861,15 @@ TEST_F(LayerTreeHostImplTest, ReflectionMaskLayerWithDifferentBounds) { ASSERT_EQ(1u, frame.render_passes.size()); ASSERT_EQ(2u, frame.render_passes[0]->quad_list.size()); ASSERT_EQ(DrawQuad::RENDER_PASS, - frame.render_passes[0]->quad_list[1]->material); - const RenderPassDrawQuad* replica_quad = - RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[1]); - EXPECT_TRUE(replica_quad->is_replica); + frame.render_passes[0]->quad_list.ElementAt(1)->material); + const RenderPassDrawQuad* replica_quad = RenderPassDrawQuad::MaterialCast( + frame.render_passes[0]->quad_list.ElementAt(1)); EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), replica_quad->rect.ToString()); EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(), - replica_quad->mask_uv_rect.ToString()); + replica_quad->MaskUVRect().ToString()); + EXPECT_EQ(gfx::Vector2dF(1.f, 1.f).ToString(), + replica_quad->mask_uv_scale.ToString()); host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); host_impl_->DidDrawAllLayers(frame); @@ -5210,14 +5888,15 @@ TEST_F(LayerTreeHostImplTest, ReflectionMaskLayerWithDifferentBounds) { ASSERT_EQ(1u, frame.render_passes.size()); ASSERT_EQ(2u, frame.render_passes[0]->quad_list.size()); ASSERT_EQ(DrawQuad::RENDER_PASS, - frame.render_passes[0]->quad_list[1]->material); - const RenderPassDrawQuad* replica_quad = - RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[1]); - EXPECT_TRUE(replica_quad->is_replica); + frame.render_passes[0]->quad_list.ElementAt(1)->material); + const RenderPassDrawQuad* replica_quad = RenderPassDrawQuad::MaterialCast( + frame.render_passes[0]->quad_list.ElementAt(1)); EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), replica_quad->rect.ToString()); EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(), - replica_quad->mask_uv_rect.ToString()); + replica_quad->MaskUVRect().ToString()); + EXPECT_EQ(gfx::Vector2dF(1.f, 1.f).ToString(), + replica_quad->mask_uv_scale.ToString()); host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); host_impl_->DidDrawAllLayers(frame); @@ -5251,7 +5930,7 @@ TEST_F(LayerTreeHostImplTest, ReflectionMaskLayerForSurfaceWithUnclippedChild) { scoped_ptr<FakeMaskLayerImpl> scoped_mask_layer = FakeMaskLayerImpl::Create(host_impl_->active_tree(), 5); FakeMaskLayerImpl* mask_layer = scoped_mask_layer.get(); - replica_layer->SetMaskLayer(scoped_mask_layer.PassAs<LayerImpl>()); + replica_layer->SetMaskLayer(scoped_mask_layer.Pass()); gfx::Size root_size(100, 100); root->SetBounds(root_size); @@ -5288,23 +5967,24 @@ TEST_F(LayerTreeHostImplTest, ReflectionMaskLayerForSurfaceWithUnclippedChild) { // The surface is 100x50. ASSERT_EQ(DrawQuad::RENDER_PASS, - frame.render_passes[0]->quad_list[0]->material); + frame.render_passes[0]->quad_list.front()->material); const RenderPassDrawQuad* render_pass_quad = - RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[0]); - EXPECT_FALSE(render_pass_quad->is_replica); + RenderPassDrawQuad::MaterialCast( + frame.render_passes[0]->quad_list.front()); EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(), render_pass_quad->rect.ToString()); // The mask covers the owning layer only. ASSERT_EQ(DrawQuad::RENDER_PASS, - frame.render_passes[0]->quad_list[1]->material); - const RenderPassDrawQuad* replica_quad = - RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[1]); - EXPECT_TRUE(replica_quad->is_replica); + frame.render_passes[0]->quad_list.ElementAt(1)->material); + const RenderPassDrawQuad* replica_quad = RenderPassDrawQuad::MaterialCast( + frame.render_passes[0]->quad_list.ElementAt(1)); EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(), replica_quad->rect.ToString()); EXPECT_EQ(gfx::RectF(0.f, 0.f, 2.f, 1.f).ToString(), - replica_quad->mask_uv_rect.ToString()); + replica_quad->MaskUVRect().ToString()); + EXPECT_EQ(gfx::Vector2dF(2.f, 1.f).ToString(), + replica_quad->mask_uv_scale.ToString()); host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); host_impl_->DidDrawAllLayers(frame); @@ -5322,23 +6002,24 @@ TEST_F(LayerTreeHostImplTest, ReflectionMaskLayerForSurfaceWithUnclippedChild) { // The surface is 100x50 with its origin at (-50, 0). ASSERT_EQ(DrawQuad::RENDER_PASS, - frame.render_passes[0]->quad_list[0]->material); + frame.render_passes[0]->quad_list.front()->material); const RenderPassDrawQuad* render_pass_quad = - RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[0]); - EXPECT_FALSE(render_pass_quad->is_replica); + RenderPassDrawQuad::MaterialCast( + frame.render_passes[0]->quad_list.front()); EXPECT_EQ(gfx::Rect(-50, 0, 100, 50).ToString(), render_pass_quad->rect.ToString()); // The mask covers the owning layer only. ASSERT_EQ(DrawQuad::RENDER_PASS, - frame.render_passes[0]->quad_list[1]->material); - const RenderPassDrawQuad* replica_quad = - RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[1]); - EXPECT_TRUE(replica_quad->is_replica); + frame.render_passes[0]->quad_list.ElementAt(1)->material); + const RenderPassDrawQuad* replica_quad = RenderPassDrawQuad::MaterialCast( + frame.render_passes[0]->quad_list.ElementAt(1)); EXPECT_EQ(gfx::Rect(-50, 0, 100, 50).ToString(), replica_quad->rect.ToString()); EXPECT_EQ(gfx::RectF(-1.f, 0.f, 2.f, 1.f).ToString(), - replica_quad->mask_uv_rect.ToString()); + replica_quad->MaskUVRect().ToString()); + EXPECT_EQ(gfx::Vector2dF(2.f, 1.f).ToString(), + replica_quad->mask_uv_scale.ToString()); host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); host_impl_->DidDrawAllLayers(frame); @@ -5373,7 +6054,7 @@ TEST_F(LayerTreeHostImplTest, MaskLayerForSurfaceWithClippedLayer) { scoped_ptr<FakeMaskLayerImpl> scoped_mask_layer = FakeMaskLayerImpl::Create(host_impl_->active_tree(), 6); FakeMaskLayerImpl* mask_layer = scoped_mask_layer.get(); - content_layer->SetMaskLayer(scoped_mask_layer.PassAs<LayerImpl>()); + content_layer->SetMaskLayer(scoped_mask_layer.Pass()); gfx::Size root_size(100, 100); root->SetBounds(root_size); @@ -5416,20 +6097,21 @@ TEST_F(LayerTreeHostImplTest, MaskLayerForSurfaceWithClippedLayer) { // The surface is clipped to 10x20. ASSERT_EQ(DrawQuad::RENDER_PASS, - frame.render_passes[0]->quad_list[0]->material); + frame.render_passes[0]->quad_list.front()->material); const RenderPassDrawQuad* render_pass_quad = - RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[0]); - EXPECT_FALSE(render_pass_quad->is_replica); + RenderPassDrawQuad::MaterialCast( + frame.render_passes[0]->quad_list.front()); EXPECT_EQ(gfx::Rect(20, 10, 10, 20).ToString(), render_pass_quad->rect.ToString()); - // The masked layer is 50x50, but the surface size is 10x20. So the texture // coords in the mask are scaled by 10/50 and 20/50. // The surface is clipped to (20,10) so the mask texture coords are offset // by 20/50 and 10/50 - EXPECT_EQ(gfx::ScaleRect(gfx::RectF(20.f, 10.f, 10.f, 20.f), - 1.f / 50.f).ToString(), - render_pass_quad->mask_uv_rect.ToString()); + EXPECT_EQ(gfx::ScaleRect(gfx::RectF(20.f, 10.f, 10.f, 20.f), 1.f / 50.f) + .ToString(), + render_pass_quad->MaskUVRect().ToString()); + EXPECT_EQ(gfx::Vector2dF(10.f / 50.f, 20.f / 50.f).ToString(), + render_pass_quad->mask_uv_scale.ToString()); host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); host_impl_->DidDrawAllLayers(frame); @@ -5438,7 +6120,7 @@ TEST_F(LayerTreeHostImplTest, MaskLayerForSurfaceWithClippedLayer) { class GLRendererWithSetupQuadForAntialiasing : public GLRenderer { public: - using GLRenderer::SetupQuadForAntialiasing; + using GLRenderer::ShouldAntialiasQuad; }; TEST_F(LayerTreeHostImplTest, FarAwayQuadsDontNeedAA) { @@ -5474,17 +6156,17 @@ TEST_F(LayerTreeHostImplTest, FarAwayQuadsDontNeedAA) { scoped_ptr<FakePictureLayerImpl> scoped_content_layer = FakePictureLayerImpl::CreateWithPile(host_impl_->pending_tree(), 3, pile); LayerImpl* content_layer = scoped_content_layer.get(); - scrolling_layer->AddChild(scoped_content_layer.PassAs<LayerImpl>()); + scrolling_layer->AddChild(scoped_content_layer.Pass()); content_layer->SetBounds(content_layer_bounds); content_layer->SetDrawsContent(true); root->SetBounds(root_size); - gfx::Vector2d scroll_offset(100000, 0); + gfx::ScrollOffset scroll_offset(100000, 0); scrolling_layer->SetScrollClipLayer(root->id()); scrolling_layer->SetScrollOffset(scroll_offset); - host_impl_->ActivatePendingTree(); + host_impl_->ActivateSyncTree(); host_impl_->active_tree()->UpdateDrawProperties(); ASSERT_EQ(1u, host_impl_->active_tree()->RenderSurfaceLayerList().size()); @@ -5494,13 +6176,11 @@ TEST_F(LayerTreeHostImplTest, FarAwayQuadsDontNeedAA) { ASSERT_EQ(1u, frame.render_passes.size()); ASSERT_LE(1u, frame.render_passes[0]->quad_list.size()); - const DrawQuad* quad = frame.render_passes[0]->quad_list[0]; + const DrawQuad* quad = frame.render_passes[0]->quad_list.front(); - float edge[24]; - gfx::QuadF device_layer_quad; bool antialiased = - GLRendererWithSetupQuadForAntialiasing::SetupQuadForAntialiasing( - quad->quadTransform(), quad, &device_layer_quad, edge); + GLRendererWithSetupQuadForAntialiasing::ShouldAntialiasQuad( + quad->quadTransform(), quad, false); EXPECT_FALSE(antialiased); host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); @@ -5513,7 +6193,7 @@ class CompositorFrameMetadataTest : public LayerTreeHostImplTest { CompositorFrameMetadataTest() : swap_buffers_complete_(0) {} - virtual void DidSwapBuffersCompleteOnImplThread() OVERRIDE { + void DidSwapBuffersCompleteOnImplThread() override { swap_buffers_complete_++; } @@ -5538,11 +6218,11 @@ class CountingSoftwareDevice : public SoftwareOutputDevice { public: CountingSoftwareDevice() : frames_began_(0), frames_ended_(0) {} - virtual SkCanvas* BeginPaint(const gfx::Rect& damage_rect) OVERRIDE { + SkCanvas* BeginPaint(const gfx::Rect& damage_rect) override { ++frames_began_; return SoftwareOutputDevice::BeginPaint(damage_rect); } - virtual void EndPaint(SoftwareFrameData* frame_data) OVERRIDE { + void EndPaint(SoftwareFrameData* frame_data) override { ++frames_ended_; SoftwareOutputDevice::EndPaint(frame_data); } @@ -5565,8 +6245,16 @@ TEST_F(LayerTreeHostImplTest, ForcedDrawToSoftwareDeviceBasicRender) { SetupScrollAndContentsLayers(gfx::Size(100, 100)); - output_surface->set_forced_draw_to_software_device(true); - EXPECT_TRUE(output_surface->ForcedDrawToSoftwareDevice()); + const gfx::Transform external_transform; + const gfx::Rect external_viewport; + const gfx::Rect external_clip; + const bool resourceless_software_draw = true; + host_impl_->SetExternalDrawConstraints(external_transform, + external_viewport, + external_clip, + external_viewport, + external_transform, + resourceless_software_draw); EXPECT_EQ(0, software_device->frames_began_); EXPECT_EQ(0, software_device->frames_ended_); @@ -5577,8 +6265,8 @@ TEST_F(LayerTreeHostImplTest, ForcedDrawToSoftwareDeviceBasicRender) { EXPECT_EQ(1, software_device->frames_ended_); // Call other API methods that are likely to hit NULL pointer in this mode. - EXPECT_TRUE(host_impl_->AsValue()); - EXPECT_TRUE(host_impl_->ActivationStateAsValue()); + EXPECT_TRUE(host_impl_->AsValue().get()); + EXPECT_TRUE(host_impl_->ActivationStateAsValue().get()); } TEST_F(LayerTreeHostImplTest, @@ -5592,8 +6280,16 @@ TEST_F(LayerTreeHostImplTest, EXPECT_TRUE(CreateHostImpl(DefaultSettings(), scoped_ptr<OutputSurface>(output_surface))); - output_surface->set_forced_draw_to_software_device(true); - EXPECT_TRUE(output_surface->ForcedDrawToSoftwareDevice()); + const gfx::Transform external_transform; + const gfx::Rect external_viewport; + const gfx::Rect external_clip; + const bool resourceless_software_draw = true; + host_impl_->SetExternalDrawConstraints(external_transform, + external_viewport, + external_clip, + external_viewport, + external_transform, + resourceless_software_draw); // SolidColorLayerImpl will be drawn. scoped_ptr<SolidColorLayerImpl> root_layer = @@ -5601,13 +6297,13 @@ TEST_F(LayerTreeHostImplTest, // VideoLayerImpl will not be drawn. FakeVideoFrameProvider provider; - scoped_ptr<VideoLayerImpl> video_layer = - VideoLayerImpl::Create(host_impl_->active_tree(), 2, &provider); + scoped_ptr<VideoLayerImpl> video_layer = VideoLayerImpl::Create( + host_impl_->active_tree(), 2, &provider, media::VIDEO_ROTATION_0); video_layer->SetBounds(gfx::Size(10, 10)); video_layer->SetContentBounds(gfx::Size(10, 10)); video_layer->SetDrawsContent(true); - root_layer->AddChild(video_layer.PassAs<LayerImpl>()); - SetupRootLayerImpl(root_layer.PassAs<LayerImpl>()); + root_layer->AddChild(video_layer.Pass()); + SetupRootLayerImpl(root_layer.Pass()); LayerTreeHostImpl::FrameData frame; EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); @@ -5620,7 +6316,7 @@ TEST_F(LayerTreeHostImplTest, class LayerTreeHostImplTestDeferredInitialize : public LayerTreeHostImplTest { protected: - virtual void SetUp() OVERRIDE { + virtual void SetUp() override { LayerTreeHostImplTest::SetUp(); set_reduce_memory_result(false); @@ -5632,17 +6328,16 @@ class LayerTreeHostImplTestDeferredInitialize : public LayerTreeHostImplTest { delegated_rendering)); output_surface_ = output_surface.get(); - EXPECT_TRUE(CreateHostImpl(DefaultSettings(), - output_surface.PassAs<OutputSurface>())); + EXPECT_TRUE(CreateHostImpl(DefaultSettings(), output_surface.Pass())); scoped_ptr<SolidColorLayerImpl> root_layer = SolidColorLayerImpl::Create(host_impl_->active_tree(), 1); - SetupRootLayerImpl(root_layer.PassAs<LayerImpl>()); + SetupRootLayerImpl(root_layer.Pass()); onscreen_context_provider_ = TestContextProvider::Create(); } - virtual void UpdateRendererCapabilitiesOnImplThread() OVERRIDE { + void UpdateRendererCapabilitiesOnImplThread() override { did_update_renderer_capabilities_ = true; } @@ -5662,7 +6357,7 @@ TEST_F(LayerTreeHostImplTestDeferredInitialize, Success) { did_update_renderer_capabilities_ = false; EXPECT_TRUE( output_surface_->InitializeAndSetContext3d(onscreen_context_provider_)); - EXPECT_EQ(onscreen_context_provider_, + EXPECT_EQ(onscreen_context_provider_.get(), host_impl_->output_surface()->context_provider()); EXPECT_TRUE(did_update_renderer_capabilities_); @@ -5709,6 +6404,7 @@ TEST_F(LayerTreeHostImplTest, DefaultMemoryAllocation) { &proxy_, &stats_instrumentation_, shared_bitmap_manager_.get(), + gpu_memory_buffer_manager_.get(), 0); scoped_ptr<OutputSurface> output_surface( @@ -5750,7 +6446,7 @@ TEST_F(LayerTreeHostImplTest, MemoryPolicy) { LayerTreeSettings settings; settings.gpu_rasterization_enabled = true; host_impl_ = LayerTreeHostImpl::Create( - settings, this, &proxy_, &stats_instrumentation_, NULL, 0); + settings, this, &proxy_, &stats_instrumentation_, NULL, NULL, 0); host_impl_->SetUseGpuRasterization(true); host_impl_->SetVisible(true); host_impl_->SetMemoryPolicy(policy1); @@ -5765,45 +6461,51 @@ TEST_F(LayerTreeHostImplTest, MemoryPolicy) { TEST_F(LayerTreeHostImplTest, RequireHighResWhenVisible) { ASSERT_TRUE(host_impl_->active_tree()); - EXPECT_FALSE(host_impl_->active_tree()->RequiresHighResToDraw()); + // RequiresHighResToDraw is set when new output surface is used. + EXPECT_TRUE(host_impl_->RequiresHighResToDraw()); + + host_impl_->ResetRequiresHighResToDraw(); + host_impl_->SetVisible(false); - EXPECT_FALSE(host_impl_->active_tree()->RequiresHighResToDraw()); + EXPECT_FALSE(host_impl_->RequiresHighResToDraw()); host_impl_->SetVisible(true); - EXPECT_TRUE(host_impl_->active_tree()->RequiresHighResToDraw()); + EXPECT_TRUE(host_impl_->RequiresHighResToDraw()); host_impl_->SetVisible(false); - EXPECT_TRUE(host_impl_->active_tree()->RequiresHighResToDraw()); + EXPECT_TRUE(host_impl_->RequiresHighResToDraw()); - host_impl_->CreatePendingTree(); - host_impl_->ActivatePendingTree(); + host_impl_->ResetRequiresHighResToDraw(); - EXPECT_FALSE(host_impl_->active_tree()->RequiresHighResToDraw()); + EXPECT_FALSE(host_impl_->RequiresHighResToDraw()); host_impl_->SetVisible(true); - EXPECT_TRUE(host_impl_->active_tree()->RequiresHighResToDraw()); + EXPECT_TRUE(host_impl_->RequiresHighResToDraw()); } TEST_F(LayerTreeHostImplTest, RequireHighResAfterGpuRasterizationToggles) { ASSERT_TRUE(host_impl_->active_tree()); EXPECT_FALSE(host_impl_->use_gpu_rasterization()); - EXPECT_FALSE(host_impl_->active_tree()->RequiresHighResToDraw()); + // RequiresHighResToDraw is set when new output surface is used. + EXPECT_TRUE(host_impl_->RequiresHighResToDraw()); + + host_impl_->ResetRequiresHighResToDraw(); + host_impl_->SetUseGpuRasterization(false); - EXPECT_FALSE(host_impl_->active_tree()->RequiresHighResToDraw()); + EXPECT_FALSE(host_impl_->RequiresHighResToDraw()); host_impl_->SetUseGpuRasterization(true); - EXPECT_TRUE(host_impl_->active_tree()->RequiresHighResToDraw()); + EXPECT_TRUE(host_impl_->RequiresHighResToDraw()); host_impl_->SetUseGpuRasterization(false); - EXPECT_TRUE(host_impl_->active_tree()->RequiresHighResToDraw()); + EXPECT_TRUE(host_impl_->RequiresHighResToDraw()); - host_impl_->CreatePendingTree(); - host_impl_->ActivatePendingTree(); + host_impl_->ResetRequiresHighResToDraw(); - EXPECT_FALSE(host_impl_->active_tree()->RequiresHighResToDraw()); + EXPECT_FALSE(host_impl_->RequiresHighResToDraw()); host_impl_->SetUseGpuRasterization(true); - EXPECT_TRUE(host_impl_->active_tree()->RequiresHighResToDraw()); + EXPECT_TRUE(host_impl_->RequiresHighResToDraw()); } class LayerTreeHostImplTestManageTiles : public LayerTreeHostImplTest { public: - virtual void SetUp() OVERRIDE { + virtual void SetUp() override { LayerTreeSettings settings; settings.impl_side_painting = true; @@ -5829,7 +6531,7 @@ TEST_F(LayerTreeHostImplTest, UIResourceManagement) { TestWebGraphicsContext3D::Create(); TestWebGraphicsContext3D* context3d = context.get(); scoped_ptr<FakeOutputSurface> output_surface = FakeOutputSurface::Create3d(); - CreateHostImpl(DefaultSettings(), output_surface.PassAs<OutputSurface>()); + CreateHostImpl(DefaultSettings(), output_surface.Pass()); EXPECT_EQ(0u, context3d->NumTextures()); @@ -5873,8 +6575,7 @@ TEST_F(LayerTreeHostImplTest, CreateETC1UIResource) { scoped_ptr<TestWebGraphicsContext3D> context = TestWebGraphicsContext3D::Create(); TestWebGraphicsContext3D* context3d = context.get(); - scoped_ptr<FakeOutputSurface> output_surface = FakeOutputSurface::Create3d(); - CreateHostImpl(DefaultSettings(), output_surface.PassAs<OutputSurface>()); + CreateHostImpl(DefaultSettings(), FakeOutputSurface::Create3d()); EXPECT_EQ(0u, context3d->NumTextures()); @@ -5903,9 +6604,8 @@ TEST_F(LayerTreeHostImplTest, ShutdownReleasesContext) { scoped_refptr<TestContextProvider> context_provider = TestContextProvider::Create(); - CreateHostImpl( - DefaultSettings(), - FakeOutputSurface::Create3d(context_provider).PassAs<OutputSurface>()); + CreateHostImpl(DefaultSettings(), + FakeOutputSurface::Create3d(context_provider)); SetupRootLayerImpl(LayerImpl::Create(host_impl_->active_tree(), 1)); @@ -5925,7 +6625,7 @@ TEST_F(LayerTreeHostImplTest, ShutdownReleasesContext) { EXPECT_FALSE(context_provider->HasOneRef()); EXPECT_EQ(1u, context_provider->TestContext3d()->NumTextures()); - host_impl_.reset(); + host_impl_ = nullptr; // The CopyOutputResult's callback was cancelled, the CopyOutputResult // released, and the texture deleted. @@ -5988,11 +6688,11 @@ TEST_F(LayerTreeHostImplTest, TouchFlingShouldLockToFirstScrolledLayer) { scoped_ptr<LayerImpl> grand_child = CreateScrollableLayer(4, surface_size, root.get()); - grand_child->SetScrollOffset(gfx::Vector2d(0, 2)); + grand_child->SetScrollOffset(gfx::ScrollOffset(0, 2)); scoped_ptr<LayerImpl> child = CreateScrollableLayer(3, surface_size, root.get()); - child->SetScrollOffset(gfx::Vector2d(0, 4)); + child->SetScrollOffset(gfx::ScrollOffset(0, 4)); child->AddChild(grand_child.Pass()); root_scrolling->AddChild(child.Pass()); @@ -6010,7 +6710,7 @@ TEST_F(LayerTreeHostImplTest, TouchFlingShouldLockToFirstScrolledLayer) { gfx::Vector2d scroll_delta(0, -2); EXPECT_EQ(InputHandler::ScrollStarted, host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture)); - EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), scroll_delta)); + EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), scroll_delta).did_scroll); // The grand child should have scrolled up to its limit. scroll_info = host_impl_->ProcessScrollDeltas(); @@ -6020,7 +6720,7 @@ TEST_F(LayerTreeHostImplTest, TouchFlingShouldLockToFirstScrolledLayer) { // The child should have received the bubbled delta, but the locked // scrolling layer should remain set as the grand child. - EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), scroll_delta)); + EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), scroll_delta).did_scroll); scroll_info = host_impl_->ProcessScrollDeltas(); ASSERT_EQ(2u, scroll_info->scrolls.size()); ExpectContains(*scroll_info, grand_child->id(), scroll_delta); @@ -6030,7 +6730,7 @@ TEST_F(LayerTreeHostImplTest, TouchFlingShouldLockToFirstScrolledLayer) { // The first |ScrollBy| after the fling should re-lock the scrolling // layer to the first layer that scrolled, which is the child. EXPECT_EQ(InputHandler::ScrollStarted, host_impl_->FlingScrollBegin()); - EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), scroll_delta)); + EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), scroll_delta).did_scroll); EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), child); // The child should have scrolled up to its limit. @@ -6040,7 +6740,7 @@ TEST_F(LayerTreeHostImplTest, TouchFlingShouldLockToFirstScrolledLayer) { ExpectContains(*scroll_info, child->id(), scroll_delta + scroll_delta); // As the locked layer is at it's limit, no further scrolling can occur. - EXPECT_FALSE(host_impl_->ScrollBy(gfx::Point(), scroll_delta)); + EXPECT_FALSE(host_impl_->ScrollBy(gfx::Point(), scroll_delta).did_scroll); EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), child); host_impl_->ScrollEnd(); } @@ -6222,7 +6922,7 @@ TEST_F(LayerTreeHostImplTest, ScrollInvisibleScrollerWithVisibleScrollChild) { scoped_ptr<LayerImpl> container = LayerImpl::Create(host_impl_->active_tree(), container_id); - scoped_ptr<std::set<LayerImpl*> > scroll_children(new std::set<LayerImpl*>()); + scoped_ptr<std::set<LayerImpl*>> scroll_children(new std::set<LayerImpl*>); scroll_children->insert(scroll_child.get()); invisible_scroll->SetScrollChildren(scroll_children.release()); @@ -6257,7 +6957,7 @@ TEST_F(LayerTreeHostImplTest, LatencyInfoPassedToCompositorFrameMetadata) { root->SetContentBounds(gfx::Size(10, 10)); root->SetDrawsContent(true); - host_impl_->active_tree()->SetRootLayer(root.PassAs<LayerImpl>()); + host_impl_->active_tree()->SetRootLayer(root.Pass()); FakeOutputSurface* fake_output_surface = static_cast<FakeOutputSurface*>(host_impl_->output_surface()); @@ -6288,44 +6988,105 @@ TEST_F(LayerTreeHostImplTest, LatencyInfoPassedToCompositorFrameMetadata) { ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, 0, NULL)); } +TEST_F(LayerTreeHostImplTest, SelectionBoundsPassedToCompositorFrameMetadata) { + int root_layer_id = 1; + scoped_ptr<SolidColorLayerImpl> root = + SolidColorLayerImpl::Create(host_impl_->active_tree(), root_layer_id); + root->SetPosition(gfx::PointF()); + root->SetBounds(gfx::Size(10, 10)); + root->SetContentBounds(gfx::Size(10, 10)); + root->SetDrawsContent(true); + + host_impl_->active_tree()->SetRootLayer(root.Pass()); + + // Ensure the default frame selection bounds are empty. + FakeOutputSurface* fake_output_surface = + static_cast<FakeOutputSurface*>(host_impl_->output_surface()); + const ViewportSelectionBound& selection_start_before = + fake_output_surface->last_sent_frame().metadata.selection_start; + const ViewportSelectionBound& selection_end_before = + fake_output_surface->last_sent_frame().metadata.selection_end; + EXPECT_EQ(ViewportSelectionBound(), selection_start_before); + EXPECT_EQ(ViewportSelectionBound(), selection_end_before); + + // Plumb the layer-local selection bounds. + gfx::PointF selection_top(5, 0); + gfx::PointF selection_bottom(5, 5); + LayerSelectionBound start, end; + start.type = SELECTION_BOUND_CENTER; + start.layer_id = root_layer_id; + start.edge_bottom = selection_bottom; + start.edge_top = selection_top; + end = start; + host_impl_->active_tree()->RegisterSelection(start, end); + + // Trigger a draw-swap sequence. + host_impl_->SetNeedsRedraw(); + + gfx::Rect full_frame_damage(host_impl_->DrawViewportSize()); + LayerTreeHostImpl::FrameData frame; + EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); + host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); + host_impl_->DidDrawAllLayers(frame); + EXPECT_TRUE(host_impl_->SwapBuffers(frame)); + + // Ensure the selection bounds have propagated to the frame metadata. + const ViewportSelectionBound& selection_start_after = + fake_output_surface->last_sent_frame().metadata.selection_start; + const ViewportSelectionBound& selection_end_after = + fake_output_surface->last_sent_frame().metadata.selection_end; + EXPECT_EQ(start.type, selection_start_after.type); + EXPECT_EQ(end.type, selection_end_after.type); + EXPECT_EQ(selection_bottom, selection_start_after.edge_bottom); + EXPECT_EQ(selection_top, selection_start_after.edge_top); + EXPECT_TRUE(selection_start_after.visible); + EXPECT_TRUE(selection_start_after.visible); +} + 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) + int* set_needs_redraw_count, + int* forward_to_main_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) {} + set_needs_redraw_count_(set_needs_redraw_count), + forward_to_main_count_(forward_to_main_count) {} - virtual ~SimpleSwapPromiseMonitor() {} + ~SimpleSwapPromiseMonitor() override {} - virtual void OnSetNeedsCommitOnMain() OVERRIDE { - (*set_needs_commit_count_)++; - } + void OnSetNeedsCommitOnMain() override { (*set_needs_commit_count_)++; } - virtual void OnSetNeedsRedrawOnImpl() OVERRIDE { - (*set_needs_redraw_count_)++; + void OnSetNeedsRedrawOnImpl() override { (*set_needs_redraw_count_)++; } + + void OnForwardScrollUpdateToMainThreadOnImpl() override { + (*forward_to_main_count_)++; } private: int* set_needs_commit_count_; int* set_needs_redraw_count_; + int* forward_to_main_count_; }; TEST_F(LayerTreeHostImplTest, SimpleSwapPromiseMonitor) { int set_needs_commit_count = 0; int set_needs_redraw_count = 0; + int forward_to_main_count = 0; { scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor( new SimpleSwapPromiseMonitor(NULL, host_impl_.get(), &set_needs_commit_count, - &set_needs_redraw_count)); + &set_needs_redraw_count, + &forward_to_main_count)); host_impl_->SetNeedsRedraw(); EXPECT_EQ(0, set_needs_commit_count); EXPECT_EQ(1, set_needs_redraw_count); + EXPECT_EQ(0, forward_to_main_count); } // Now the monitor is destroyed, SetNeedsRedraw() is no longer being @@ -6333,16 +7094,19 @@ TEST_F(LayerTreeHostImplTest, SimpleSwapPromiseMonitor) { host_impl_->SetNeedsRedraw(); EXPECT_EQ(0, set_needs_commit_count); EXPECT_EQ(1, set_needs_redraw_count); + EXPECT_EQ(0, forward_to_main_count); { scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor( new SimpleSwapPromiseMonitor(NULL, host_impl_.get(), &set_needs_commit_count, - &set_needs_redraw_count)); + &set_needs_redraw_count, + &forward_to_main_count)); host_impl_->SetNeedsRedrawRect(gfx::Rect(10, 10)); EXPECT_EQ(0, set_needs_commit_count); EXPECT_EQ(2, set_needs_redraw_count); + EXPECT_EQ(0, forward_to_main_count); } { @@ -6350,17 +7114,56 @@ TEST_F(LayerTreeHostImplTest, SimpleSwapPromiseMonitor) { new SimpleSwapPromiseMonitor(NULL, host_impl_.get(), &set_needs_commit_count, - &set_needs_redraw_count)); + &set_needs_redraw_count, + &forward_to_main_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); + EXPECT_EQ(0, forward_to_main_count); + } + + { + set_needs_commit_count = 0; + set_needs_redraw_count = 0; + forward_to_main_count = 0; + scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor( + new SimpleSwapPromiseMonitor(NULL, + host_impl_.get(), + &set_needs_commit_count, + &set_needs_redraw_count, + &forward_to_main_count)); + LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100)); + + // Scrolling normally should not trigger any forwarding. + EXPECT_EQ(InputHandler::ScrollStarted, + host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture)); + EXPECT_TRUE( + host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10)).did_scroll); + host_impl_->ScrollEnd(); + + EXPECT_EQ(0, set_needs_commit_count); + EXPECT_EQ(1, set_needs_redraw_count); + EXPECT_EQ(0, forward_to_main_count); + + // Scrolling with a scroll handler should defer the swap to the main + // thread. + scroll_layer->SetHaveScrollEventHandlers(true); + EXPECT_EQ(InputHandler::ScrollStarted, + host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture)); + EXPECT_TRUE( + host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10)).did_scroll); + host_impl_->ScrollEnd(); + + EXPECT_EQ(0, set_needs_commit_count); + EXPECT_EQ(2, set_needs_redraw_count); + EXPECT_EQ(1, forward_to_main_count); } } class LayerTreeHostImplWithTopControlsTest : public LayerTreeHostImplTest { public: - virtual void SetUp() OVERRIDE { + virtual void SetUp() override { LayerTreeSettings settings = DefaultSettings(); settings.calculate_top_controls_position = true; settings.top_controls_height = top_controls_height_; @@ -6375,14 +7178,14 @@ const int LayerTreeHostImplWithTopControlsTest::top_controls_height_ = 50; TEST_F(LayerTreeHostImplWithTopControlsTest, NoIdleAnimations) { SetupScrollAndContentsLayers(gfx::Size(100, 100)) - ->SetScrollOffset(gfx::Vector2d(0, 10)); + ->SetScrollOffset(gfx::ScrollOffset(0, 10)); host_impl_->Animate(base::TimeTicks()); EXPECT_FALSE(did_request_redraw_); } TEST_F(LayerTreeHostImplWithTopControlsTest, TopControlsAnimationScheduling) { SetupScrollAndContentsLayers(gfx::Size(100, 100)) - ->SetScrollOffset(gfx::Vector2d(0, 10)); + ->SetScrollOffset(gfx::ScrollOffset(0, 10)); host_impl_->DidChangeTopControlsPosition(); EXPECT_TRUE(did_request_animate_); EXPECT_TRUE(did_request_redraw_); @@ -6391,55 +7194,188 @@ TEST_F(LayerTreeHostImplWithTopControlsTest, TopControlsAnimationScheduling) { TEST_F(LayerTreeHostImplWithTopControlsTest, ScrollHandledByTopControls) { LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 200)); host_impl_->SetViewportSize(gfx::Size(100, 100)); + host_impl_->top_controls_manager()->UpdateTopControlsState( + BOTH, SHOWN, false); DrawFrame(); EXPECT_EQ(InputHandler::ScrollStarted, host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture)); - EXPECT_EQ(0, host_impl_->top_controls_manager()->controls_top_offset()); + EXPECT_EQ(0, host_impl_->top_controls_manager()->ControlsTopOffset()); EXPECT_EQ(gfx::Vector2dF().ToString(), scroll_layer->TotalScrollOffset().ToString()); // Scroll just the top controls and verify that the scroll succeeds. const float residue = 10; float offset = top_controls_height_ - residue; - EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, offset))); - EXPECT_EQ(-offset, host_impl_->top_controls_manager()->controls_top_offset()); + EXPECT_TRUE( + host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, offset)).did_scroll); + EXPECT_EQ(-offset, host_impl_->top_controls_manager()->ControlsTopOffset()); EXPECT_EQ(gfx::Vector2dF().ToString(), scroll_layer->TotalScrollOffset().ToString()); // Scroll across the boundary const float content_scroll = 20; offset = residue + content_scroll; - EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, offset))); + EXPECT_TRUE( + host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, offset)).did_scroll); EXPECT_EQ(-top_controls_height_, - host_impl_->top_controls_manager()->controls_top_offset()); + host_impl_->top_controls_manager()->ControlsTopOffset()); EXPECT_EQ(gfx::Vector2dF(0, content_scroll).ToString(), scroll_layer->TotalScrollOffset().ToString()); // Now scroll back to the top of the content offset = -content_scroll; - EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, offset))); + EXPECT_TRUE( + host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, offset)).did_scroll); EXPECT_EQ(-top_controls_height_, - host_impl_->top_controls_manager()->controls_top_offset()); + host_impl_->top_controls_manager()->ControlsTopOffset()); EXPECT_EQ(gfx::Vector2dF().ToString(), scroll_layer->TotalScrollOffset().ToString()); // And scroll the top controls completely into view offset = -top_controls_height_; - EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, offset))); - EXPECT_EQ(0, host_impl_->top_controls_manager()->controls_top_offset()); + EXPECT_TRUE( + host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, offset)).did_scroll); + EXPECT_EQ(0, host_impl_->top_controls_manager()->ControlsTopOffset()); EXPECT_EQ(gfx::Vector2dF().ToString(), scroll_layer->TotalScrollOffset().ToString()); // And attempt to scroll past the end - EXPECT_FALSE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, offset))); - EXPECT_EQ(0, host_impl_->top_controls_manager()->controls_top_offset()); + EXPECT_FALSE( + host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, offset)).did_scroll); + EXPECT_EQ(0, host_impl_->top_controls_manager()->ControlsTopOffset()); EXPECT_EQ(gfx::Vector2dF().ToString(), scroll_layer->TotalScrollOffset().ToString()); host_impl_->ScrollEnd(); } +TEST_F(LayerTreeHostImplWithTopControlsTest, TopControlsAnimationAtOrigin) { + LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 200)); + host_impl_->SetViewportSize(gfx::Size(100, 200)); + host_impl_->top_controls_manager()->UpdateTopControlsState( + BOTH, SHOWN, false); + DrawFrame(); + + EXPECT_EQ(InputHandler::ScrollStarted, + host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture)); + EXPECT_EQ(0, host_impl_->top_controls_manager()->ControlsTopOffset()); + EXPECT_EQ(gfx::Vector2dF().ToString(), + scroll_layer->TotalScrollOffset().ToString()); + + // Scroll the top controls partially. + const float residue = 35; + float offset = top_controls_height_ - residue; + EXPECT_TRUE( + host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, offset)).did_scroll); + EXPECT_EQ(-offset, host_impl_->top_controls_manager()->ControlsTopOffset()); + EXPECT_EQ(gfx::Vector2dF().ToString(), + scroll_layer->TotalScrollOffset().ToString()); + + did_request_redraw_ = false; + did_request_animate_ = false; + did_request_commit_ = false; + + // End the scroll while the controls are still offset from their limit. + host_impl_->ScrollEnd(); + ASSERT_TRUE(host_impl_->top_controls_manager()->animation()); + EXPECT_TRUE(did_request_animate_); + EXPECT_TRUE(did_request_redraw_); + EXPECT_FALSE(did_request_commit_); + + // The top controls should properly animate until finished, despite the scroll + // offset being at the origin. + base::TimeTicks animation_time = gfx::FrameTime::Now(); + while (did_request_animate_) { + did_request_redraw_ = false; + did_request_animate_ = false; + did_request_commit_ = false; + + float old_offset = + host_impl_->top_controls_manager()->ControlsTopOffset(); + + animation_time += base::TimeDelta::FromMilliseconds(5); + host_impl_->Animate(animation_time); + EXPECT_EQ(gfx::Vector2dF().ToString(), + scroll_layer->TotalScrollOffset().ToString()); + + float new_offset = + host_impl_->top_controls_manager()->ControlsTopOffset(); + + // No commit is needed as the controls are animating the content offset, + // not the scroll offset. + EXPECT_FALSE(did_request_commit_); + + if (new_offset != old_offset) + EXPECT_TRUE(did_request_redraw_); + + if (new_offset != 0) { + EXPECT_TRUE(host_impl_->top_controls_manager()->animation()); + EXPECT_TRUE(did_request_animate_); + } + } + EXPECT_FALSE(host_impl_->top_controls_manager()->animation()); +} + +TEST_F(LayerTreeHostImplWithTopControlsTest, TopControlsAnimationAfterScroll) { + LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 200)); + host_impl_->SetViewportSize(gfx::Size(100, 100)); + host_impl_->top_controls_manager()->UpdateTopControlsState( + BOTH, SHOWN, false); + float initial_scroll_offset = 50; + scroll_layer->SetScrollOffset(gfx::ScrollOffset(0, initial_scroll_offset)); + DrawFrame(); + + EXPECT_EQ(InputHandler::ScrollStarted, + host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture)); + EXPECT_EQ(0, host_impl_->top_controls_manager()->ControlsTopOffset()); + EXPECT_EQ(gfx::Vector2dF(0, initial_scroll_offset).ToString(), + scroll_layer->TotalScrollOffset().ToString()); + + // Scroll the top controls partially. + const float residue = 15; + float offset = top_controls_height_ - residue; + EXPECT_TRUE( + host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, offset)).did_scroll); + EXPECT_EQ(-offset, host_impl_->top_controls_manager()->ControlsTopOffset()); + EXPECT_EQ(gfx::Vector2dF(0, initial_scroll_offset).ToString(), + scroll_layer->TotalScrollOffset().ToString()); + + did_request_redraw_ = false; + did_request_animate_ = false; + did_request_commit_ = false; + + // End the scroll while the controls are still offset from the limit. + host_impl_->ScrollEnd(); + ASSERT_TRUE(host_impl_->top_controls_manager()->animation()); + EXPECT_TRUE(did_request_animate_); + EXPECT_TRUE(did_request_redraw_); + EXPECT_FALSE(did_request_commit_); + + // Animate the top controls to the limit. + base::TimeTicks animation_time = gfx::FrameTime::Now(); + while (did_request_animate_) { + did_request_redraw_ = false; + did_request_animate_ = false; + did_request_commit_ = false; + + float old_offset = + host_impl_->top_controls_manager()->ControlsTopOffset(); + + animation_time += base::TimeDelta::FromMilliseconds(5); + host_impl_->Animate(animation_time); + + float new_offset = + host_impl_->top_controls_manager()->ControlsTopOffset(); + + if (new_offset != old_offset) { + EXPECT_TRUE(did_request_redraw_); + EXPECT_TRUE(did_request_commit_); + } + } + EXPECT_FALSE(host_impl_->top_controls_manager()->animation()); +} + class LayerTreeHostImplVirtualViewportTest : public LayerTreeHostImplTest { public: void SetupVirtualViewportLayers(const gfx::Size& content_size, @@ -6455,7 +7391,7 @@ class LayerTreeHostImplVirtualViewportTest : public LayerTreeHostImplTest { scoped_ptr<LayerImpl> inner_scroll = LayerImpl::Create(layer_tree_impl, kInnerViewportScrollLayerId); inner_scroll->SetIsContainerForFixedPositionLayers(true); - inner_scroll->SetScrollOffset(gfx::Vector2d()); + inner_scroll->SetScrollOffset(gfx::ScrollOffset()); scoped_ptr<LayerImpl> inner_clip = LayerImpl::Create(layer_tree_impl, kInnerViewportClipLayerId); @@ -6477,7 +7413,7 @@ class LayerTreeHostImplVirtualViewportTest : public LayerTreeHostImplTest { scoped_ptr<LayerImpl> outer_scroll = LayerImpl::Create(layer_tree_impl, kOuterViewportScrollLayerId); outer_scroll->SetScrollClipLayer(outer_clip->id()); - outer_scroll->SetScrollOffset(gfx::Vector2d()); + outer_scroll->SetScrollOffset(gfx::ScrollOffset()); outer_scroll->SetBounds(content_size); outer_scroll->SetContentBounds(content_size); outer_scroll->SetPosition(gfx::PointF()); @@ -6551,9 +7487,52 @@ TEST_F(LayerTreeHostImplVirtualViewportTest, FlingScrollBubblesToInner) { } } +TEST_F(LayerTreeHostImplVirtualViewportTest, + DiagonalScrollBubblesPerfectlyToInner) { + gfx::Size content_size = gfx::Size(100, 160); + gfx::Size outer_viewport = gfx::Size(50, 80); + gfx::Size inner_viewport = gfx::Size(25, 40); + + SetupVirtualViewportLayers(content_size, outer_viewport, inner_viewport); + + LayerImpl* outer_scroll = host_impl_->OuterViewportScrollLayer(); + LayerImpl* inner_scroll = host_impl_->InnerViewportScrollLayer(); + DrawFrame(); + { + gfx::Vector2dF inner_expected; + gfx::Vector2dF outer_expected; + EXPECT_VECTOR_EQ(inner_expected, inner_scroll->TotalScrollOffset()); + EXPECT_VECTOR_EQ(outer_expected, outer_scroll->TotalScrollOffset()); + + // Make sure the scroll goes to the outer viewport first. + EXPECT_EQ(InputHandler::ScrollStarted, + host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture)); + EXPECT_EQ(InputHandler::ScrollStarted, host_impl_->FlingScrollBegin()); + + // Scroll near the edge of the outer viewport. + gfx::Vector2d scroll_delta(inner_viewport.width(), inner_viewport.height()); + host_impl_->ScrollBy(gfx::Point(), scroll_delta); + outer_expected += scroll_delta; + + EXPECT_VECTOR_EQ(inner_expected, inner_scroll->TotalScrollOffset()); + EXPECT_VECTOR_EQ(outer_expected, outer_scroll->TotalScrollOffset()); + + // Now diagonal scroll across the outer viewport boundary in a single event. + // The entirety of the scroll should be consumed, as bubbling between inner + // and outer viewport layers is perfect. + host_impl_->ScrollBy(gfx::Point(), gfx::ScaleVector2d(scroll_delta, 2)); + outer_expected += scroll_delta; + inner_expected += scroll_delta; + host_impl_->ScrollEnd(); + + EXPECT_VECTOR_EQ(inner_expected, inner_scroll->TotalScrollOffset()); + EXPECT_VECTOR_EQ(outer_expected, outer_scroll->TotalScrollOffset()); + } +} + class LayerTreeHostImplWithImplicitLimitsTest : public LayerTreeHostImplTest { public: - virtual void SetUp() OVERRIDE { + virtual void SetUp() override { LayerTreeSettings settings = DefaultSettings(); settings.max_memory_for_prepaint_percentage = 50; CreateHostImpl(settings, CreateOutputSurface()); @@ -6578,13 +7557,15 @@ TEST_F(LayerTreeHostImplTest, ExternalTransformReflectedInNextDraw) { gfx::Transform external_transform; const gfx::Rect external_viewport(layer_size); const gfx::Rect external_clip(layer_size); - const bool valid_for_tile_management = true; + const bool resourceless_software_draw = false; LayerImpl* layer = SetupScrollAndContentsLayers(layer_size); host_impl_->SetExternalDrawConstraints(external_transform, external_viewport, external_clip, - valid_for_tile_management); + external_viewport, + external_transform, + resourceless_software_draw); DrawFrame(); EXPECT_TRANSFORMATION_MATRIX_EQ( external_transform, layer->draw_properties().target_space_transform); @@ -6593,11 +7574,188 @@ TEST_F(LayerTreeHostImplTest, ExternalTransformReflectedInNextDraw) { host_impl_->SetExternalDrawConstraints(external_transform, external_viewport, external_clip, - valid_for_tile_management); + external_viewport, + external_transform, + resourceless_software_draw); DrawFrame(); EXPECT_TRANSFORMATION_MATRIX_EQ( external_transform, layer->draw_properties().target_space_transform); } +TEST_F(LayerTreeHostImplTest, ScrollAnimated) { + SetupScrollAndContentsLayers(gfx::Size(100, 200)); + DrawFrame(); + + base::TimeTicks start_time = + base::TimeTicks() + base::TimeDelta::FromMilliseconds(100); + + EXPECT_EQ(InputHandler::ScrollStarted, + host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(0, 50))); + + LayerImpl* scrolling_layer = host_impl_->CurrentlyScrollingLayer(); + + host_impl_->Animate(start_time); + host_impl_->UpdateAnimationState(true); + + EXPECT_EQ(gfx::ScrollOffset(), scrolling_layer->TotalScrollOffset()); + + host_impl_->Animate(start_time + base::TimeDelta::FromMilliseconds(50)); + host_impl_->UpdateAnimationState(true); + + float y = scrolling_layer->TotalScrollOffset().y(); + EXPECT_TRUE(y > 1 && y < 49); + + // Update target. + EXPECT_EQ(InputHandler::ScrollStarted, + host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(0, 50))); + + host_impl_->Animate(start_time + base::TimeDelta::FromMilliseconds(200)); + host_impl_->UpdateAnimationState(true); + + y = scrolling_layer->TotalScrollOffset().y(); + EXPECT_TRUE(y > 50 && y < 100); + EXPECT_EQ(scrolling_layer, host_impl_->CurrentlyScrollingLayer()); + + host_impl_->Animate(start_time + base::TimeDelta::FromMilliseconds(250)); + host_impl_->UpdateAnimationState(true); + + EXPECT_VECTOR_EQ(gfx::ScrollOffset(0, 100), + scrolling_layer->TotalScrollOffset()); + EXPECT_EQ(NULL, host_impl_->CurrentlyScrollingLayer()); +} + +TEST_F(LayerTreeHostImplTest, GetPictureLayerImplPairs) { + host_impl_->CreatePendingTree(); + host_impl_->pending_tree()->SetRootLayer( + PictureLayerImpl::Create(host_impl_->pending_tree(), 10)); + + LayerTreeImpl* pending_tree = host_impl_->pending_tree(); + LayerImpl* pending_layer = pending_tree->root_layer(); + + std::vector<PictureLayerImpl::Pair> layer_pairs; + host_impl_->GetPictureLayerImplPairs(&layer_pairs); + EXPECT_EQ(1u, layer_pairs.size()); + EXPECT_EQ(pending_layer, layer_pairs[0].pending); + EXPECT_EQ(nullptr, layer_pairs[0].active); + + host_impl_->ActivateSyncTree(); + + LayerTreeImpl* active_tree = host_impl_->active_tree(); + LayerImpl* active_layer = active_tree->root_layer(); + EXPECT_NE(active_tree, pending_tree); + EXPECT_NE(active_layer, pending_layer); + EXPECT_NE(nullptr, active_tree); + EXPECT_NE(nullptr, active_layer); + + host_impl_->CreatePendingTree(); + + layer_pairs.clear(); + host_impl_->GetPictureLayerImplPairs(&layer_pairs); + EXPECT_EQ(1u, layer_pairs.size()); + EXPECT_EQ(active_layer, layer_pairs[0].active); + EXPECT_EQ(pending_layer, layer_pairs[0].pending); + + // Activate, the active layer has no twin now. + host_impl_->ActivateSyncTree(); + + layer_pairs.clear(); + host_impl_->GetPictureLayerImplPairs(&layer_pairs); + EXPECT_EQ(1u, layer_pairs.size()); + EXPECT_EQ(active_layer, layer_pairs[0].active); + EXPECT_EQ(nullptr, layer_pairs[0].pending); + + // Create another layer in the pending tree that's not in the active tree. We + // should get two pairs. + host_impl_->CreatePendingTree(); + host_impl_->pending_tree()->root_layer()->AddChild( + PictureLayerImpl::Create(host_impl_->pending_tree(), 11)); + + LayerImpl* new_pending_layer = pending_tree->root_layer()->children()[0]; + + layer_pairs.clear(); + host_impl_->GetPictureLayerImplPairs(&layer_pairs); + EXPECT_EQ(2u, layer_pairs.size()); + + // The pair ordering is flaky, so make it consistent. + if (layer_pairs[0].active != active_layer) + std::swap(layer_pairs[0], layer_pairs[1]); + + EXPECT_EQ(active_layer, layer_pairs[0].active); + EXPECT_EQ(pending_layer, layer_pairs[0].pending); + EXPECT_EQ(new_pending_layer, layer_pairs[1].pending); + EXPECT_EQ(nullptr, layer_pairs[1].active); +} + +TEST_F(LayerTreeHostImplTest, DidBecomeActive) { + host_impl_->CreatePendingTree(); + host_impl_->ActivateSyncTree(); + host_impl_->CreatePendingTree(); + + LayerTreeImpl* pending_tree = host_impl_->pending_tree(); + + scoped_ptr<FakePictureLayerImpl> pending_layer = + FakePictureLayerImpl::Create(pending_tree, 10); + pending_layer->DoPostCommitInitializationIfNeeded(); + FakePictureLayerImpl* raw_pending_layer = pending_layer.get(); + pending_tree->SetRootLayer(pending_layer.Pass()); + ASSERT_EQ(raw_pending_layer, pending_tree->root_layer()); + + EXPECT_EQ(0u, raw_pending_layer->did_become_active_call_count()); + pending_tree->DidBecomeActive(); + EXPECT_EQ(1u, raw_pending_layer->did_become_active_call_count()); + + scoped_ptr<FakePictureLayerImpl> mask_layer = + FakePictureLayerImpl::Create(pending_tree, 11); + mask_layer->DoPostCommitInitializationIfNeeded(); + FakePictureLayerImpl* raw_mask_layer = mask_layer.get(); + raw_pending_layer->SetMaskLayer(mask_layer.Pass()); + ASSERT_EQ(raw_mask_layer, raw_pending_layer->mask_layer()); + + EXPECT_EQ(1u, raw_pending_layer->did_become_active_call_count()); + EXPECT_EQ(0u, raw_mask_layer->did_become_active_call_count()); + pending_tree->DidBecomeActive(); + EXPECT_EQ(2u, raw_pending_layer->did_become_active_call_count()); + EXPECT_EQ(1u, raw_mask_layer->did_become_active_call_count()); + + scoped_ptr<FakePictureLayerImpl> replica_layer = + FakePictureLayerImpl::Create(pending_tree, 12); + scoped_ptr<FakePictureLayerImpl> replica_mask_layer = + FakePictureLayerImpl::Create(pending_tree, 13); + replica_mask_layer->DoPostCommitInitializationIfNeeded(); + FakePictureLayerImpl* raw_replica_mask_layer = replica_mask_layer.get(); + replica_layer->SetMaskLayer(replica_mask_layer.Pass()); + raw_pending_layer->SetReplicaLayer(replica_layer.Pass()); + ASSERT_EQ(raw_replica_mask_layer, + raw_pending_layer->replica_layer()->mask_layer()); + + EXPECT_EQ(2u, raw_pending_layer->did_become_active_call_count()); + EXPECT_EQ(1u, raw_mask_layer->did_become_active_call_count()); + EXPECT_EQ(0u, raw_replica_mask_layer->did_become_active_call_count()); + pending_tree->DidBecomeActive(); + EXPECT_EQ(3u, raw_pending_layer->did_become_active_call_count()); + EXPECT_EQ(2u, raw_mask_layer->did_become_active_call_count()); + EXPECT_EQ(1u, raw_replica_mask_layer->did_become_active_call_count()); +} + +class LayerTreeHostImplCountingLostSurfaces : public LayerTreeHostImplTest { + public: + LayerTreeHostImplCountingLostSurfaces() : num_lost_surfaces_(0) {} + void DidLoseOutputSurfaceOnImplThread() override { num_lost_surfaces_++; } + + protected: + int num_lost_surfaces_; +}; + +TEST_F(LayerTreeHostImplCountingLostSurfaces, TwiceLostSurface) { + // Really we just need at least one client notification each time + // we go from having a valid output surface to not having a valid output + // surface. + EXPECT_EQ(0, num_lost_surfaces_); + host_impl_->DidLoseOutputSurface(); + EXPECT_EQ(1, num_lost_surfaces_); + host_impl_->DidLoseOutputSurface(); + EXPECT_LE(1, num_lost_surfaces_); +} + } // namespace } // namespace cc diff --git a/chromium/cc/trees/layer_tree_host_perftest.cc b/chromium/cc/trees/layer_tree_host_perftest.cc index 70b2a645236..b368c558eb2 100644 --- a/chromium/cc/trees/layer_tree_host_perftest.cc +++ b/chromium/cc/trees/layer_tree_host_perftest.cc @@ -6,8 +6,8 @@ #include <sstream> -#include "base/file_util.h" #include "base/files/file_path.h" +#include "base/files/file_util.h" #include "base/path_service.h" #include "base/strings/string_piece.h" #include "base/time/time.h" @@ -16,6 +16,7 @@ #include "cc/layers/nine_patch_layer.h" #include "cc/layers/solid_color_layer.h" #include "cc/layers/texture_layer.h" +#include "cc/resources/single_release_callback.h" #include "cc/resources/texture_mailbox.h" #include "cc/test/fake_content_layer_client.h" #include "cc/test/layer_tree_json_parser.h" @@ -39,39 +40,38 @@ class LayerTreeHostPerfTest : public LayerTreeTest { kTimeCheckInterval), commit_timer_(0, base::TimeDelta(), 1), full_damage_each_frame_(false), - animation_driven_drawing_(false), + begin_frame_driven_drawing_(false), measure_commit_cost_(false) { - fake_content_layer_client_.set_paint_all_opaque(true); } - virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE { + void InitializeSettings(LayerTreeSettings* settings) override { settings->throttle_frame_production = false; } - virtual void BeginTest() OVERRIDE { + void BeginTest() override { BuildTree(); PostSetNeedsCommitToMainThread(); } - virtual void Animate(base::TimeTicks monotonic_time) OVERRIDE { - if (animation_driven_drawing_ && !TestEnded()) { + void BeginMainFrame(const BeginFrameArgs& args) override { + if (begin_frame_driven_drawing_ && !TestEnded()) { layer_tree_host()->SetNeedsAnimate(); layer_tree_host()->SetNextCommitForcesRedraw(); } } - virtual void BeginCommitOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { + void BeginCommitOnThread(LayerTreeHostImpl* host_impl) override { if (measure_commit_cost_) commit_timer_.Start(); } - virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { + void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { if (measure_commit_cost_ && draw_timer_.IsWarmedUp()) { commit_timer_.NextLap(); } } - virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE { + void DrawLayersOnThread(LayerTreeHostImpl* impl) override { if (TestEnded() || CleanUpStarted()) return; draw_timer_.NextLap(); @@ -79,7 +79,7 @@ class LayerTreeHostPerfTest : public LayerTreeTest { CleanUpAndEndTest(impl); return; } - if (!animation_driven_drawing_) + if (!begin_frame_driven_drawing_) impl->SetNeedsRedraw(); if (full_damage_each_frame_) impl->SetFullRootLayerDamage(); @@ -91,7 +91,7 @@ class LayerTreeHostPerfTest : public LayerTreeTest { virtual void BuildTree() {} - virtual void AfterTest() OVERRIDE { + void AfterTest() override { CHECK(!test_name_.empty()) << "Must SetTestName() before AfterTest()."; perf_test::PrintResult("layer_tree_host_frame_time", "", test_name_, 1000 * draw_timer_.MsPerLap(), "us", true); @@ -108,7 +108,7 @@ class LayerTreeHostPerfTest : public LayerTreeTest { std::string test_name_; FakeContentLayerClient fake_content_layer_client_; bool full_damage_each_frame_; - bool animation_driven_drawing_; + bool begin_frame_driven_drawing_; bool measure_commit_cost_; }; @@ -131,7 +131,7 @@ class LayerTreeHostPerfTestJsonReader : public LayerTreeHostPerfTest { ASSERT_TRUE(base::ReadFileToString(json_file, &json_)); } - virtual void BuildTree() OVERRIDE { + void BuildTree() override { gfx::Size viewport = gfx::Size(720, 1038); layer_tree_host()->SetViewportSize(viewport); scoped_refptr<Layer> root = ParseTreeFromJson(json_, @@ -178,22 +178,22 @@ TEST_F(LayerTreeHostPerfTestJsonReader, class LayerTreeHostPerfTestLeafInvalidates : public LayerTreeHostPerfTestJsonReader { public: - virtual void BuildTree() OVERRIDE { + void BuildTree() override { LayerTreeHostPerfTestJsonReader::BuildTree(); // Find a leaf layer. for (layer_to_invalidate_ = layer_tree_host()->root_layer(); layer_to_invalidate_->children().size(); - layer_to_invalidate_ = layer_to_invalidate_->children()[0]) {} + layer_to_invalidate_ = layer_to_invalidate_->children()[0].get()) { + } } - virtual void DidCommitAndDrawFrame() OVERRIDE { + void DidCommitAndDrawFrame() override { if (TestEnded()) return; - static bool flip = true; - layer_to_invalidate_->SetOpacity(flip ? 1.f : 0.5f); - flip = !flip; + layer_to_invalidate_->SetOpacity( + layer_to_invalidate_->opacity() != 1.f ? 1.f : 0.5f); } protected: @@ -221,15 +221,18 @@ class ScrollingLayerTreePerfTest : public LayerTreeHostPerfTestJsonReader { : LayerTreeHostPerfTestJsonReader() { } - virtual void BuildTree() OVERRIDE { + void BuildTree() override { LayerTreeHostPerfTestJsonReader::BuildTree(); scrollable_ = layer_tree_host()->root_layer()->children()[1]; ASSERT_TRUE(scrollable_.get()); } - virtual void Layout() OVERRIDE { + void Layout() override { + if (TestEnded()) + return; static const gfx::Vector2d delta = gfx::Vector2d(0, 10); - scrollable_->SetScrollOffset(scrollable_->scroll_offset() + delta); + scrollable_->SetScrollOffset( + gfx::ScrollOffsetWithDelta(scrollable_->scroll_offset(), delta)); } private: @@ -259,7 +262,7 @@ class BrowserCompositorInvalidateLayerTreePerfTest next_sync_point_(1), clean_up_started_(false) {} - virtual void BuildTree() OVERRIDE { + void BuildTree() override { LayerTreeHostPerfTestJsonReader::BuildTree(); tab_contents_ = static_cast<TextureLayer*>( @@ -270,7 +273,7 @@ class BrowserCompositorInvalidateLayerTreePerfTest ASSERT_TRUE(tab_contents_.get()); } - virtual void WillCommit() OVERRIDE { + void WillCommit() override { if (CleanUpStarted()) return; gpu::Mailbox gpu_mailbox; @@ -286,13 +289,13 @@ class BrowserCompositorInvalidateLayerTreePerfTest tab_contents_->SetTextureMailbox(mailbox, callback.Pass()); } - virtual void DidCommit() OVERRIDE { + void DidCommit() override { if (CleanUpStarted()) return; layer_tree_host()->SetNeedsCommit(); } - virtual void CleanUpAndEndTest(LayerTreeHostImpl* host_impl) OVERRIDE { + void CleanUpAndEndTest(LayerTreeHostImpl* host_impl) override { clean_up_started_ = true; MainThreadTaskRunner()->PostTask( FROM_HERE, @@ -302,12 +305,11 @@ class BrowserCompositorInvalidateLayerTreePerfTest } void CleanUpAndEndTestOnMainThread() { - tab_contents_->SetTextureMailbox(TextureMailbox(), - scoped_ptr<SingleReleaseCallback>()); + tab_contents_->SetTextureMailbox(TextureMailbox(), nullptr); EndTest(); } - virtual bool CleanUpStarted() OVERRIDE { return clean_up_started_; } + bool CleanUpStarted() override { return clean_up_started_; } private: scoped_refptr<TextureLayer> tab_contents_; @@ -324,7 +326,7 @@ TEST_F(BrowserCompositorInvalidateLayerTreePerfTest, DenseBrowserUI) { // Simulates a page with several large, transformed and animated layers. TEST_F(LayerTreeHostPerfTestJsonReader, HeavyPageThreadedImplSide) { - animation_driven_drawing_ = true; + begin_frame_driven_drawing_ = true; measure_commit_cost_ = true; SetTestName("heavy_page"); ReadTestFile("heavy_layer_tree"); diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_blending.cc b/chromium/cc/trees/layer_tree_host_pixeltest_blending.cc index 7a492a1d5bf..7a9ef212383 100644 --- a/chromium/cc/trees/layer_tree_host_pixeltest_blending.cc +++ b/chromium/cc/trees/layer_tree_host_pixeltest_blending.cc @@ -2,9 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "cc/layers/image_layer.h" #include "cc/layers/solid_color_layer.h" -#include "cc/layers/texture_layer.h" #include "cc/test/layer_tree_pixel_test.h" +#include "cc/test/pixel_comparator.h" #if !defined(OS_ANDROID) @@ -21,9 +22,47 @@ SkXfermode::Mode const kBlendModes[] = { SkXfermode::kHue_Mode, SkXfermode::kSaturation_Mode, SkXfermode::kColor_Mode, SkXfermode::kLuminosity_Mode}; +SkColor kCSSTestColors[] = { + 0xffff0000, // red + 0xff00ff00, // lime + 0xff0000ff, // blue + 0xff00ffff, // aqua + 0xffff00ff, // fuchsia + 0xffffff00, // yellow + 0xff008000, // green + 0xff800000, // maroon + 0xff000080, // navy + 0xff800080, // purple + 0xff808000, // olive + 0xff008080, // teal + 0xfffa8072, // salmon + 0xffc0c0c0, // silver + 0xff000000, // black + 0xff808080, // gray + 0x80000000, // black with transparency + 0xffffffff, // white + 0x80ffffff, // white with transparency + 0x00000000 // transparent +}; + const int kBlendModesCount = arraysize(kBlendModes); +const int kCSSTestColorsCount = arraysize(kCSSTestColors); + +using RenderPassOptions = uint32; +const uint32 kUseMasks = 1 << 0; +const uint32 kUseAntialiasing = 1 << 1; +const uint32 kUseColorMatrix = 1 << 2; class LayerTreeHostBlendingPixelTest : public LayerTreePixelTest { + public: + LayerTreeHostBlendingPixelTest() { + pixel_comparator_.reset(new FuzzyPixelOffByOneComparator(true)); + } + + virtual void InitializeSettings(LayerTreeSettings* settings) override { + settings->force_antialiasing = force_antialiasing_; + } + protected: void RunBlendingWithRootPixelTestType(PixelTestType type) { const int kLaneWidth = 15; @@ -76,10 +115,179 @@ class LayerTreeHostBlendingPixelTest : public LayerTreePixelTest { root, base::FilePath(FILE_PATH_LITERAL("blending_transparent.png"))); } + + scoped_refptr<Layer> CreateColorfulBackdropLayer(int width, int height) { + // Draw the backdrop with horizontal lanes. + const int kLaneWidth = width; + const int kLaneHeight = height / kCSSTestColorsCount; + SkBitmap backing_store; + backing_store.allocN32Pixels(width, height); + SkCanvas canvas(backing_store); + canvas.clear(SK_ColorTRANSPARENT); + for (int i = 0; i < kCSSTestColorsCount; ++i) { + SkPaint paint; + paint.setColor(kCSSTestColors[i]); + canvas.drawRect( + SkRect::MakeXYWH(0, i * kLaneHeight, kLaneWidth, kLaneHeight), paint); + } + scoped_refptr<ImageLayer> layer = ImageLayer::Create(); + layer->SetIsDrawable(true); + layer->SetBounds(gfx::Size(width, height)); + layer->SetBitmap(backing_store); + return layer; + } + + void SetupMaskLayer(scoped_refptr<Layer> layer) { + const int kMaskOffset = 5; + gfx::Size bounds = layer->bounds(); + scoped_refptr<ImageLayer> mask = ImageLayer::Create(); + mask->SetIsDrawable(true); + mask->SetIsMask(true); + mask->SetBounds(bounds); + + SkBitmap bitmap; + bitmap.allocN32Pixels(bounds.width(), bounds.height()); + SkCanvas canvas(bitmap); + SkPaint paint; + paint.setColor(SK_ColorWHITE); + canvas.clear(SK_ColorTRANSPARENT); + canvas.drawRect(SkRect::MakeXYWH(kMaskOffset, + kMaskOffset, + bounds.width() - kMaskOffset * 2, + bounds.height() - kMaskOffset * 2), + paint); + mask->SetBitmap(bitmap); + layer->SetMaskLayer(mask.get()); + } + + void SetupColorMatrix(scoped_refptr<Layer> layer) { + FilterOperations filter_operations; + filter_operations.Append(FilterOperation::CreateSepiaFilter(1.f)); + layer->SetFilters(filter_operations); + } + + void CreateBlendingColorLayers(int width, + int height, + scoped_refptr<Layer> background, + RenderPassOptions flags) { + const int kLanesCount = kBlendModesCount + 4; + int lane_width = width / kLanesCount; + const SkColor kMiscOpaqueColor = 0xffc86464; + const SkColor kMiscTransparentColor = 0x80c86464; + const SkXfermode::Mode kCoeffBlendMode = SkXfermode::kScreen_Mode; + const SkXfermode::Mode kShaderBlendMode = SkXfermode::kColorBurn_Mode; + // add vertical lanes with each of the blend modes + for (int i = 0; i < kLanesCount; ++i) { + gfx::Rect child_rect(i * lane_width, 0, lane_width, height); + SkXfermode::Mode blend_mode = SkXfermode::kSrcOver_Mode; + float opacity = 1.f; + SkColor color = kMiscOpaqueColor; + + if (i < kBlendModesCount) { + blend_mode = kBlendModes[i]; + } else if (i == kBlendModesCount) { + blend_mode = kCoeffBlendMode; + opacity = 0.5f; + } else if (i == kBlendModesCount + 1) { + blend_mode = kCoeffBlendMode; + color = kMiscTransparentColor; + } else if (i == kBlendModesCount + 2) { + blend_mode = kShaderBlendMode; + opacity = 0.5f; + } else if (i == kBlendModesCount + 3) { + blend_mode = kShaderBlendMode; + color = kMiscTransparentColor; + } + + scoped_refptr<SolidColorLayer> lane = + CreateSolidColorLayer(child_rect, color); + lane->SetBlendMode(blend_mode); + lane->SetOpacity(opacity); + lane->SetForceRenderSurface(true); + if (flags & kUseMasks) + SetupMaskLayer(lane); + if (flags & kUseColorMatrix) { + SetupColorMatrix(lane); + } + background->AddChild(lane); + } + } + + void RunBlendingWithRenderPass(PixelTestType type, + const base::FilePath::CharType* expected_path, + RenderPassOptions flags) { + const int kRootSize = 400; + + scoped_refptr<SolidColorLayer> root = + CreateSolidColorLayer(gfx::Rect(kRootSize, kRootSize), SK_ColorWHITE); + scoped_refptr<Layer> background = + CreateColorfulBackdropLayer(kRootSize, kRootSize); + + background->SetIsRootForIsolatedGroup(true); + root->AddChild(background); + + CreateBlendingColorLayers(kRootSize, kRootSize, background.get(), flags); + + this->impl_side_painting_ = false; + this->force_antialiasing_ = (flags & kUseAntialiasing); + + if ((flags & kUseAntialiasing) && (type == PIXEL_TEST_GL)) { + // Anti aliasing causes differences up to 7 pixels at the edges. + // Several pixels have 9 units difference on the alpha channel. + int large_error_allowed = (flags & kUseMasks) ? 7 : 9; + // Blending results might differ with one pixel. + int small_error_allowed = 1; + // Most of the errors are one pixel errors. + float percentage_pixels_small_error = (flags & kUseMasks) ? 7.7f : 12.1f; + // Because of anti-aliasing, around 3% of pixels (at the edges) have + // bigger errors (from small_error_allowed + 1 to large_error_allowed). + float percentage_pixels_error = (flags & kUseMasks) ? 12.4f : 15.f; + // The average error is still close to 1. + float average_error_allowed_in_bad_pixels = + (flags & kUseMasks) ? 1.3f : 1.f; + + // The sepia filter generates more small errors, but the number of large + // errors remains around 3%. + if (flags & kUseColorMatrix) { + percentage_pixels_small_error = (flags & kUseMasks) ? 14.0f : 26.f; + percentage_pixels_error = (flags & kUseMasks) ? 18.5f : 29.f; + average_error_allowed_in_bad_pixels = (flags & kUseMasks) ? 0.9f : 0.7f; + } + + pixel_comparator_.reset( + new FuzzyPixelComparator(false, // discard_alpha + percentage_pixels_error, + percentage_pixels_small_error, + average_error_allowed_in_bad_pixels, + large_error_allowed, + small_error_allowed)); + } else if ((flags & kUseColorMatrix) && (type == PIXEL_TEST_GL)) { + float percentage_pixels_error = 100.f; + float percentage_pixels_small_error = 0.f; + float average_error_allowed_in_bad_pixels = 1.f; + int large_error_allowed = 2; + int small_error_allowed = 0; + pixel_comparator_.reset( + new FuzzyPixelComparator(false, // discard_alpha + percentage_pixels_error, + percentage_pixels_small_error, + average_error_allowed_in_bad_pixels, + large_error_allowed, + small_error_allowed)); + } + + RunPixelTest(type, root, base::FilePath(expected_path)); + } + + bool force_antialiasing_ = false; }; TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRoot_GL) { - RunBlendingWithRootPixelTestType(GL_WITH_BITMAP); + RunBlendingWithRootPixelTestType(PIXEL_TEST_GL); +} + +TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRoot_Software) { + RunBlendingWithRootPixelTestType(PIXEL_TEST_SOFTWARE); } TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithBackgroundFilter) { @@ -105,13 +313,124 @@ TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithBackgroundFilter) { green_lane->SetBlendMode(kBlendModes[i]); } - RunPixelTest(GL_WITH_BITMAP, + RunPixelTest(PIXEL_TEST_GL, background, base::FilePath(FILE_PATH_LITERAL("blending_and_filter.png"))); } TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithTransparent_GL) { - RunBlendingWithTransparentPixelTestType(GL_WITH_BITMAP); + RunBlendingWithTransparentPixelTestType(PIXEL_TEST_GL); +} + +TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithTransparent_Software) { + RunBlendingWithTransparentPixelTestType(PIXEL_TEST_SOFTWARE); +} + +// Tests for render passes +TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPass_GL) { + RunBlendingWithRenderPass( + PIXEL_TEST_GL, FILE_PATH_LITERAL("blending_render_pass.png"), 0); +} + +TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPass_Software) { + RunBlendingWithRenderPass( + PIXEL_TEST_SOFTWARE, FILE_PATH_LITERAL("blending_render_pass.png"), 0); +} + +TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassAA_GL) { + RunBlendingWithRenderPass(PIXEL_TEST_GL, + FILE_PATH_LITERAL("blending_render_pass.png"), + kUseAntialiasing); +} + +TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassAA_Software) { + RunBlendingWithRenderPass(PIXEL_TEST_SOFTWARE, + FILE_PATH_LITERAL("blending_render_pass.png"), + kUseAntialiasing); +} + +TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassWithMask_GL) { + RunBlendingWithRenderPass(PIXEL_TEST_GL, + FILE_PATH_LITERAL("blending_render_pass_mask.png"), + kUseMasks); +} + +TEST_F(LayerTreeHostBlendingPixelTest, + BlendingWithRenderPassWithMask_Software) { + RunBlendingWithRenderPass(PIXEL_TEST_SOFTWARE, + FILE_PATH_LITERAL("blending_render_pass_mask.png"), + kUseMasks); +} + +TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassWithMaskAA_GL) { + RunBlendingWithRenderPass(PIXEL_TEST_GL, + FILE_PATH_LITERAL("blending_render_pass_mask.png"), + kUseMasks | kUseAntialiasing); +} + +TEST_F(LayerTreeHostBlendingPixelTest, + BlendingWithRenderPassWithMaskAA_Software) { + RunBlendingWithRenderPass(PIXEL_TEST_SOFTWARE, + FILE_PATH_LITERAL("blending_render_pass_mask.png"), + kUseMasks | kUseAntialiasing); +} + +TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassColorMatrix_GL) { + RunBlendingWithRenderPass(PIXEL_TEST_GL, + FILE_PATH_LITERAL("blending_render_pass_cm.png"), + kUseColorMatrix); +} + +TEST_F(LayerTreeHostBlendingPixelTest, + BlendingWithRenderPassColorMatrix_Software) { + RunBlendingWithRenderPass(PIXEL_TEST_SOFTWARE, + FILE_PATH_LITERAL("blending_render_pass_cm.png"), + kUseColorMatrix); +} + +TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassColorMatrixAA_GL) { + RunBlendingWithRenderPass(PIXEL_TEST_GL, + FILE_PATH_LITERAL("blending_render_pass_cm.png"), + kUseAntialiasing | kUseColorMatrix); +} + +TEST_F(LayerTreeHostBlendingPixelTest, + BlendingWithRenderPassColorMatrixAA_Software) { + RunBlendingWithRenderPass(PIXEL_TEST_SOFTWARE, + FILE_PATH_LITERAL("blending_render_pass_cm.png"), + kUseAntialiasing | kUseColorMatrix); +} + +TEST_F(LayerTreeHostBlendingPixelTest, + BlendingWithRenderPassWithMaskColorMatrix_GL) { + RunBlendingWithRenderPass( + PIXEL_TEST_GL, + FILE_PATH_LITERAL("blending_render_pass_mask_cm.png"), + kUseMasks | kUseColorMatrix); +} + +TEST_F(LayerTreeHostBlendingPixelTest, + BlendingWithRenderPassWithMaskColorMatrix_Software) { + RunBlendingWithRenderPass( + PIXEL_TEST_SOFTWARE, + FILE_PATH_LITERAL("blending_render_pass_mask_cm.png"), + kUseMasks | kUseColorMatrix); +} + +TEST_F(LayerTreeHostBlendingPixelTest, + BlendingWithRenderPassWithMaskColorMatrixAA_GL) { + RunBlendingWithRenderPass( + PIXEL_TEST_GL, + FILE_PATH_LITERAL("blending_render_pass_mask_cm.png"), + kUseMasks | kUseAntialiasing | kUseColorMatrix); +} + +TEST_F(LayerTreeHostBlendingPixelTest, + BlendingWithRenderPassWithMaskColorMatrixAA_Software) { + RunBlendingWithRenderPass( + PIXEL_TEST_SOFTWARE, + FILE_PATH_LITERAL("blending_render_pass_mask_cm.png"), + kUseMasks | kUseAntialiasing | kUseColorMatrix); } } // namespace diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_filters.cc b/chromium/cc/trees/layer_tree_host_pixeltest_filters.cc index c8c8c7adf3f..40fa2c3e454 100644 --- a/chromium/cc/trees/layer_tree_host_pixeltest_filters.cc +++ b/chromium/cc/trees/layer_tree_host_pixeltest_filters.cc @@ -49,7 +49,7 @@ TEST_F(LayerTreeHostFiltersPixelTest, BackgroundFilterBlur) { small_error_allowed)); #endif - RunPixelTest(GL_WITH_BITMAP, + RunPixelTest(PIXEL_TEST_GL, background, base::FilePath(FILE_PATH_LITERAL("background_filter_blur.png"))); } @@ -90,10 +90,10 @@ TEST_F(LayerTreeHostFiltersPixelTest, BackgroundFilterBlurOutsets) { small_error_allowed)); #endif - RunPixelTest(GL_WITH_BITMAP, - background, - base::FilePath(FILE_PATH_LITERAL( - "background_filter_blur_outsets.png"))); + RunPixelTest( + PIXEL_TEST_GL, + background, + base::FilePath(FILE_PATH_LITERAL("background_filter_blur_outsets.png"))); } TEST_F(LayerTreeHostFiltersPixelTest, BackgroundFilterBlurOffAxis) { @@ -151,10 +151,76 @@ TEST_F(LayerTreeHostFiltersPixelTest, BackgroundFilterBlurOffAxis) { small_error_allowed)); #endif - RunPixelTest(GL_WITH_BITMAP, - background, - base::FilePath(FILE_PATH_LITERAL( - "background_filter_blur_off_axis.png"))); + RunPixelTest( + PIXEL_TEST_GL, + background, + base::FilePath(FILE_PATH_LITERAL("background_filter_blur_off_axis.png"))); +} + +class LayerTreeHostFiltersScaledPixelTest + : public LayerTreeHostFiltersPixelTest { + void InitializeSettings(LayerTreeSettings* settings) override { + // Required so that device scale is inherited by content scale. + settings->layer_transforms_should_scale_layer_contents = true; + } + + void SetupTree() override { + layer_tree_host()->SetDeviceScaleFactor(device_scale_factor_); + LayerTreePixelTest::SetupTree(); + } + + protected: + void RunPixelTestType(int content_size, + float device_scale_factor, + PixelTestType test_type) { + int half_content = content_size / 2; + + scoped_refptr<SolidColorLayer> root = CreateSolidColorLayer( + gfx::Rect(0, 0, content_size, content_size), SK_ColorWHITE); + + scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer( + gfx::Rect(0, 0, content_size, content_size), SK_ColorGREEN); + root->AddChild(background); + + // Add a blue layer that completely covers the green layer. + scoped_refptr<SolidColorLayer> foreground = CreateSolidColorLayer( + gfx::Rect(0, 0, content_size, content_size), SK_ColorBLUE); + background->AddChild(foreground); + + // Add an alpha threshold filter to the blue layer which will filter out + // everything except the lower right corner. + FilterOperations filters; + SkRegion alpha_region; + alpha_region.setRect( + half_content, half_content, content_size, content_size); + filters.Append( + FilterOperation::CreateAlphaThresholdFilter(alpha_region, 1.f, 0.f)); + foreground->SetFilters(filters); + + device_scale_factor_ = device_scale_factor; + RunPixelTest( + test_type, + background, + base::FilePath(FILE_PATH_LITERAL("green_small_with_blue_corner.png"))); + } + + float device_scale_factor_; +}; + +TEST_F(LayerTreeHostFiltersScaledPixelTest, StandardDpi_GL) { + RunPixelTestType(100, 1.f, PIXEL_TEST_GL); +} + +TEST_F(LayerTreeHostFiltersScaledPixelTest, StandardDpi_Software) { + RunPixelTestType(100, 1.f, PIXEL_TEST_SOFTWARE); +} + +TEST_F(LayerTreeHostFiltersScaledPixelTest, HiDpi_GL) { + RunPixelTestType(50, 2.f, PIXEL_TEST_GL); +} + +TEST_F(LayerTreeHostFiltersScaledPixelTest, HiDpi_Software) { + RunPixelTestType(50, 2.f, PIXEL_TEST_SOFTWARE); } class ImageFilterClippedPixelTest : public LayerTreeHostFiltersPixelTest { @@ -204,11 +270,11 @@ class ImageFilterClippedPixelTest : public LayerTreeHostFiltersPixelTest { }; TEST_F(ImageFilterClippedPixelTest, ImageFilterClipped_GL) { - RunPixelTestType(GL_WITH_BITMAP); + RunPixelTestType(PIXEL_TEST_GL); } TEST_F(ImageFilterClippedPixelTest, ImageFilterClipped_Software) { - RunPixelTestType(SOFTWARE_WITH_BITMAP); + RunPixelTestType(PIXEL_TEST_SOFTWARE); } } // namespace diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_masks.cc b/chromium/cc/trees/layer_tree_host_pixeltest_masks.cc index 9b386866ee3..f4f174c4981 100644 --- a/chromium/cc/trees/layer_tree_host_pixeltest_masks.cc +++ b/chromium/cc/trees/layer_tree_host_pixeltest_masks.cc @@ -3,11 +3,11 @@ // found in the LICENSE file. #include "build/build_config.h" -#include "cc/layers/content_layer.h" #include "cc/layers/content_layer_client.h" -#include "cc/layers/image_layer.h" +#include "cc/layers/picture_image_layer.h" +#include "cc/layers/picture_layer.h" #include "cc/layers/solid_color_layer.h" -#include "cc/test/layer_tree_pixel_test.h" +#include "cc/test/layer_tree_pixel_resource_test.h" #include "cc/test/pixel_comparator.h" #if !defined(OS_ANDROID) @@ -15,29 +15,30 @@ namespace cc { namespace { -class LayerTreeHostMasksPixelTest : public LayerTreePixelTest {}; +typedef ParameterizedPixelResourceTest LayerTreeHostMasksPixelTest; + +INSTANTIATE_PIXEL_RESOURCE_TEST_CASE_P(LayerTreeHostMasksPixelTest); class MaskContentLayerClient : public ContentLayerClient { public: - MaskContentLayerClient() {} - virtual ~MaskContentLayerClient() {} + explicit MaskContentLayerClient(const gfx::Size& bounds) : bounds_(bounds) {} + ~MaskContentLayerClient() override {} - virtual void DidChangeLayerCanUseLCDText() OVERRIDE {} + void DidChangeLayerCanUseLCDText() override {} - virtual bool FillsBoundsCompletely() const OVERRIDE { return false; } + bool FillsBoundsCompletely() const override { return false; } - virtual void PaintContents( + void PaintContents( SkCanvas* canvas, const gfx::Rect& rect, - gfx::RectF* opaque_rect, - ContentLayerClient::GraphicsContextStatus gc_status) OVERRIDE { + ContentLayerClient::GraphicsContextStatus gc_status) override { SkPaint paint; paint.setStyle(SkPaint::kStroke_Style); paint.setStrokeWidth(SkIntToScalar(2)); paint.setColor(SK_ColorWHITE); canvas->clear(SK_ColorTRANSPARENT); - gfx::Rect inset_rect(rect); + gfx::Rect inset_rect(bounds_); while (!inset_rect.IsEmpty()) { inset_rect.Inset(3, 3, 2, 2); canvas->drawRect( @@ -47,9 +48,12 @@ class MaskContentLayerClient : public ContentLayerClient { inset_rect.Inset(3, 3, 2, 2); } } + + private: + gfx::Size bounds_; }; -TEST_F(LayerTreeHostMasksPixelTest, MaskOfLayer) { +TEST_P(LayerTreeHostMasksPixelTest, MaskOfLayer) { scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer( gfx::Rect(200, 200), SK_ColorWHITE); @@ -57,36 +61,36 @@ TEST_F(LayerTreeHostMasksPixelTest, MaskOfLayer) { gfx::Rect(50, 50, 100, 100), kCSSGreen, 1, SK_ColorBLACK); background->AddChild(green); - MaskContentLayerClient client; - scoped_refptr<ContentLayer> mask = ContentLayer::Create(&client); - mask->SetBounds(gfx::Size(100, 100)); + gfx::Size mask_bounds(100, 100); + MaskContentLayerClient client(mask_bounds); + scoped_refptr<PictureLayer> mask = PictureLayer::Create(&client); + mask->SetBounds(mask_bounds); mask->SetIsDrawable(true); mask->SetIsMask(true); green->SetMaskLayer(mask.get()); - this->impl_side_painting_ = false; - RunPixelTest(GL_WITH_BITMAP, - background, - base::FilePath(FILE_PATH_LITERAL("mask_of_layer.png"))); + RunPixelResourceTest(background, + base::FilePath(FILE_PATH_LITERAL("mask_of_layer.png"))); } -TEST_F(LayerTreeHostMasksPixelTest, ImageMaskOfLayer) { +TEST_P(LayerTreeHostMasksPixelTest, ImageMaskOfLayer) { scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer( gfx::Rect(200, 200), SK_ColorWHITE); - scoped_refptr<ImageLayer> mask = ImageLayer::Create(); + gfx::Size mask_bounds(100, 100); + + scoped_refptr<PictureImageLayer> mask = PictureImageLayer::Create(); mask->SetIsDrawable(true); mask->SetIsMask(true); - mask->SetBounds(gfx::Size(100, 100)); + mask->SetBounds(mask_bounds); SkBitmap bitmap; bitmap.allocN32Pixels(400, 400); SkCanvas canvas(bitmap); canvas.scale(SkIntToScalar(4), SkIntToScalar(4)); - MaskContentLayerClient client; + MaskContentLayerClient client(mask_bounds); client.PaintContents(&canvas, - gfx::Rect(100, 100), - NULL, + gfx::Rect(mask_bounds), ContentLayerClient::GRAPHICS_CONTEXT_ENABLED); mask->SetBitmap(bitmap); @@ -95,13 +99,11 @@ TEST_F(LayerTreeHostMasksPixelTest, ImageMaskOfLayer) { green->SetMaskLayer(mask.get()); background->AddChild(green); - this->impl_side_painting_ = false; - RunPixelTest(GL_WITH_BITMAP, - background, - base::FilePath(FILE_PATH_LITERAL("image_mask_of_layer.png"))); + RunPixelResourceTest( + background, base::FilePath(FILE_PATH_LITERAL("image_mask_of_layer.png"))); } -TEST_F(LayerTreeHostMasksPixelTest, MaskOfClippedLayer) { +TEST_P(LayerTreeHostMasksPixelTest, MaskOfClippedLayer) { scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer( gfx::Rect(200, 200), SK_ColorWHITE); @@ -116,26 +118,27 @@ TEST_F(LayerTreeHostMasksPixelTest, MaskOfClippedLayer) { gfx::Rect(50, 50, 100, 100), kCSSGreen, 1, SK_ColorBLACK); clip->AddChild(green); - MaskContentLayerClient client; - scoped_refptr<ContentLayer> mask = ContentLayer::Create(&client); - mask->SetBounds(gfx::Size(100, 100)); + gfx::Size mask_bounds(100, 100); + MaskContentLayerClient client(mask_bounds); + scoped_refptr<PictureLayer> mask = PictureLayer::Create(&client); + mask->SetBounds(mask_bounds); mask->SetIsDrawable(true); mask->SetIsMask(true); green->SetMaskLayer(mask.get()); - this->impl_side_painting_ = false; - RunPixelTest(GL_WITH_BITMAP, - background, - base::FilePath(FILE_PATH_LITERAL("mask_of_clipped_layer.png"))); + RunPixelResourceTest( + background, + base::FilePath(FILE_PATH_LITERAL("mask_of_clipped_layer.png"))); } -TEST_F(LayerTreeHostMasksPixelTest, MaskWithReplica) { +TEST_P(LayerTreeHostMasksPixelTest, MaskWithReplica) { scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer( gfx::Rect(200, 200), SK_ColorWHITE); - MaskContentLayerClient client; - scoped_refptr<ContentLayer> mask = ContentLayer::Create(&client); - mask->SetBounds(gfx::Size(100, 100)); + gfx::Size mask_bounds(100, 100); + MaskContentLayerClient client(mask_bounds); + scoped_refptr<PictureLayer> mask = PictureLayer::Create(&client); + mask->SetBounds(mask_bounds); mask->SetIsDrawable(true); mask->SetIsMask(true); @@ -153,19 +156,18 @@ TEST_F(LayerTreeHostMasksPixelTest, MaskWithReplica) { replica->SetTransform(replica_transform); green->SetReplicaLayer(replica.get()); - this->impl_side_painting_ = false; - RunPixelTest(GL_WITH_BITMAP, - background, - base::FilePath(FILE_PATH_LITERAL("mask_with_replica.png"))); + RunPixelResourceTest( + background, base::FilePath(FILE_PATH_LITERAL("mask_with_replica.png"))); } -TEST_F(LayerTreeHostMasksPixelTest, MaskWithReplicaOfClippedLayer) { +TEST_P(LayerTreeHostMasksPixelTest, MaskWithReplicaOfClippedLayer) { scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer( gfx::Rect(200, 200), SK_ColorWHITE); - MaskContentLayerClient client; - scoped_refptr<ContentLayer> mask = ContentLayer::Create(&client); - mask->SetBounds(gfx::Size(100, 100)); + gfx::Size mask_bounds(100, 100); + MaskContentLayerClient client(mask_bounds); + scoped_refptr<PictureLayer> mask = PictureLayer::Create(&client); + mask->SetBounds(mask_bounds); mask->SetIsDrawable(true); mask->SetIsMask(true); @@ -191,20 +193,19 @@ TEST_F(LayerTreeHostMasksPixelTest, MaskWithReplicaOfClippedLayer) { replica->SetTransform(replica_transform); green->SetReplicaLayer(replica.get()); - this->impl_side_painting_ = false; - RunPixelTest(GL_WITH_BITMAP, - background, - base::FilePath(FILE_PATH_LITERAL( - "mask_with_replica_of_clipped_layer.png"))); + RunPixelResourceTest(background, + base::FilePath(FILE_PATH_LITERAL( + "mask_with_replica_of_clipped_layer.png"))); } -TEST_F(LayerTreeHostMasksPixelTest, MaskOfReplica) { +TEST_P(LayerTreeHostMasksPixelTest, MaskOfReplica) { scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer( gfx::Rect(200, 200), SK_ColorWHITE); - MaskContentLayerClient client; - scoped_refptr<ContentLayer> mask = ContentLayer::Create(&client); - mask->SetBounds(gfx::Size(100, 100)); + gfx::Size mask_bounds(100, 100); + MaskContentLayerClient client(mask_bounds); + scoped_refptr<PictureLayer> mask = PictureLayer::Create(&client); + mask->SetBounds(mask_bounds); mask->SetIsDrawable(true); mask->SetIsMask(true); @@ -227,19 +228,18 @@ TEST_F(LayerTreeHostMasksPixelTest, MaskOfReplica) { replica->SetMaskLayer(mask.get()); green->SetReplicaLayer(replica.get()); - this->impl_side_painting_ = false; - RunPixelTest(GL_WITH_BITMAP, - background, - base::FilePath(FILE_PATH_LITERAL("mask_of_replica.png"))); + RunPixelResourceTest( + background, base::FilePath(FILE_PATH_LITERAL("mask_of_replica.png"))); } -TEST_F(LayerTreeHostMasksPixelTest, MaskOfReplicaOfClippedLayer) { +TEST_P(LayerTreeHostMasksPixelTest, MaskOfReplicaOfClippedLayer) { scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer( gfx::Rect(200, 200), SK_ColorWHITE); - MaskContentLayerClient client; - scoped_refptr<ContentLayer> mask = ContentLayer::Create(&client); - mask->SetBounds(gfx::Size(100, 100)); + gfx::Size mask_bounds(100, 100); + MaskContentLayerClient client(mask_bounds); + scoped_refptr<PictureLayer> mask = PictureLayer::Create(&client); + mask->SetBounds(mask_bounds); mask->SetIsDrawable(true); mask->SetIsMask(true); @@ -269,11 +269,9 @@ TEST_F(LayerTreeHostMasksPixelTest, MaskOfReplicaOfClippedLayer) { replica->SetMaskLayer(mask.get()); green->SetReplicaLayer(replica.get()); - this->impl_side_painting_ = false; - RunPixelTest(GL_WITH_BITMAP, - background, - base::FilePath(FILE_PATH_LITERAL( - "mask_of_replica_of_clipped_layer.png"))); + RunPixelResourceTest(background, + base::FilePath(FILE_PATH_LITERAL( + "mask_of_replica_of_clipped_layer.png"))); } } // namespace diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_on_demand_raster.cc b/chromium/cc/trees/layer_tree_host_pixeltest_on_demand_raster.cc index b7eb516004a..d703e22a31c 100644 --- a/chromium/cc/trees/layer_tree_host_pixeltest_on_demand_raster.cc +++ b/chromium/cc/trees/layer_tree_host_pixeltest_on_demand_raster.cc @@ -8,12 +8,11 @@ #include "cc/layers/picture_layer_impl.h" #include "cc/quads/draw_quad.h" #include "cc/test/layer_tree_pixel_test.h" -#include "cc/test/mock_quad_culler.h" #include "cc/trees/layer_tree_impl.h" #include "third_party/skia/include/core/SkCanvas.h" #include "third_party/skia/include/core/SkColor.h" -#include "ui/gfx/rect.h" -#include "ui/gfx/rect_f.h" +#include "ui/gfx/geometry/rect.h" +#include "ui/gfx/geometry/rect_f.h" #if !defined(OS_ANDROID) @@ -22,34 +21,31 @@ namespace { class LayerTreeHostOnDemandRasterPixelTest : public LayerTreePixelTest { public: - virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE { + void InitializeSettings(LayerTreeSettings* settings) override { settings->impl_side_painting = true; } - virtual void BeginCommitOnThread(LayerTreeHostImpl* impl) OVERRIDE { + void BeginCommitOnThread(LayerTreeHostImpl* impl) override { // Not enough memory available. Enforce on-demand rasterization. impl->SetMemoryPolicy( ManagedMemoryPolicy(1, gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING, 1000)); } - virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, - bool result) OVERRIDE { + void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override { // Find the PictureLayerImpl ask it to append quads to check their material. // The PictureLayerImpl is assumed to be the first child of the root layer // in the active tree. PictureLayerImpl* picture_layer = static_cast<PictureLayerImpl*>( host_impl->active_tree()->root_layer()->child_at(0)); - MockOcclusionTracker<LayerImpl> occlusion_tracker; scoped_ptr<RenderPass> render_pass = RenderPass::Create(); - MockQuadCuller quad_culler(render_pass.get(), &occlusion_tracker); AppendQuadsData data; - picture_layer->AppendQuads(&quad_culler, &data); + picture_layer->AppendQuads(render_pass.get(), Occlusion(), &data); - for (size_t i = 0; i < render_pass->quad_list.size(); ++i) - EXPECT_EQ(render_pass->quad_list[i]->material, DrawQuad::PICTURE_CONTENT); + for (const auto& quad : render_pass->quad_list) + EXPECT_EQ(quad->material, DrawQuad::PICTURE_CONTENT); // Triggers pixel readback and ends the test. LayerTreePixelTest::SwapBuffersOnThread(host_impl, result); @@ -63,17 +59,14 @@ class BlueYellowLayerClient : public ContentLayerClient { explicit BlueYellowLayerClient(gfx::Rect layer_rect) : layer_rect_(layer_rect) {} - virtual void DidChangeLayerCanUseLCDText() OVERRIDE { } + void DidChangeLayerCanUseLCDText() override {} - virtual bool FillsBoundsCompletely() const OVERRIDE { return false; } + bool FillsBoundsCompletely() const override { return false; } - virtual void PaintContents( + void PaintContents( SkCanvas* canvas, const gfx::Rect& clip, - gfx::RectF* opaque, - ContentLayerClient::GraphicsContextStatus gc_status) OVERRIDE { - *opaque = gfx::RectF(layer_rect_.width(), layer_rect_.height()); - + ContentLayerClient::GraphicsContextStatus gc_status) override { SkPaint paint; paint.setColor(SK_ColorBLUE); canvas->drawRect(SkRect::MakeWH(layer_rect_.width(), @@ -104,7 +97,7 @@ void LayerTreeHostOnDemandRasterPixelTest::RunOnDemandRasterPixelTest() { layer->SetBounds(layer_rect.size()); layer->SetPosition(layer_rect.origin()); - RunPixelTest(GL_WITH_BITMAP, + RunPixelTest(PIXEL_TEST_GL, layer, base::FilePath(FILE_PATH_LITERAL("blue_yellow.png"))); } @@ -115,7 +108,7 @@ TEST_F(LayerTreeHostOnDemandRasterPixelTest, RasterPictureLayer) { class LayerTreeHostOnDemandRasterPixelTestWithGpuRasterizationForced : public LayerTreeHostOnDemandRasterPixelTest { - virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE { + void InitializeSettings(LayerTreeSettings* settings) override { LayerTreeHostOnDemandRasterPixelTest::InitializeSettings(settings); settings->gpu_rasterization_forced = true; } diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_readback.cc b/chromium/cc/trees/layer_tree_host_pixeltest_readback.cc index 4c808397eba..0a06144e87c 100644 --- a/chromium/cc/trees/layer_tree_host_pixeltest_readback.cc +++ b/chromium/cc/trees/layer_tree_host_pixeltest_readback.cc @@ -3,11 +3,12 @@ // found in the LICENSE file. #include "build/build_config.h" -#include "cc/layers/content_layer.h" #include "cc/layers/solid_color_layer.h" #include "cc/layers/texture_layer.h" #include "cc/output/copy_output_request.h" #include "cc/output/copy_output_result.h" +#include "cc/test/fake_picture_layer.h" +#include "cc/test/fake_picture_layer_impl.h" #include "cc/test/layer_tree_pixel_test.h" #include "cc/test/paths.h" #include "cc/test/solid_color_content_layer_client.h" @@ -21,28 +22,51 @@ namespace { class LayerTreeHostReadbackPixelTest : public LayerTreePixelTest { protected: LayerTreeHostReadbackPixelTest() - : insert_copy_request_after_frame_count_(0) {} + : readback_type_(READBACK_INVALID), + insert_copy_request_after_frame_count_(0) {} + + enum ReadbackType { + READBACK_INVALID, + READBACK_DEFAULT, + READBACK_BITMAP, + }; + + void RunReadbackTest(PixelTestType test_type, + ReadbackType readback_type, + scoped_refptr<Layer> content_root, + base::FilePath file_name) { + readback_type_ = readback_type; + RunPixelTest(test_type, content_root, file_name); + } + + void RunReadbackTestWithReadbackTarget(PixelTestType type, + ReadbackType readback_type, + scoped_refptr<Layer> content_root, + Layer* target, + base::FilePath file_name) { + readback_type_ = readback_type; + RunPixelTestWithReadbackTarget(type, content_root, target, file_name); + } - virtual scoped_ptr<CopyOutputRequest> CreateCopyOutputRequest() OVERRIDE { + scoped_ptr<CopyOutputRequest> CreateCopyOutputRequest() override { scoped_ptr<CopyOutputRequest> request; - switch (test_type_) { - case GL_WITH_BITMAP: - case SOFTWARE_WITH_BITMAP: - request = CopyOutputRequest::CreateBitmapRequest( - base::Bind(&LayerTreeHostReadbackPixelTest::ReadbackResultAsBitmap, - base::Unretained(this))); - break; - case SOFTWARE_WITH_DEFAULT: + if (readback_type_ == READBACK_BITMAP) { + request = CopyOutputRequest::CreateBitmapRequest( + base::Bind(&LayerTreeHostReadbackPixelTest::ReadbackResultAsBitmap, + base::Unretained(this))); + } else { + DCHECK_EQ(readback_type_, READBACK_DEFAULT); + if (test_type_ == PIXEL_TEST_SOFTWARE) { request = CopyOutputRequest::CreateRequest( base::Bind(&LayerTreeHostReadbackPixelTest::ReadbackResultAsBitmap, base::Unretained(this))); - break; - case GL_WITH_DEFAULT: + } else { + DCHECK_EQ(test_type_, PIXEL_TEST_GL); request = CopyOutputRequest::CreateRequest( base::Bind(&LayerTreeHostReadbackPixelTest::ReadbackResultAsTexture, base::Unretained(this))); - break; + } } if (!copy_subrect_.IsEmpty()) @@ -50,7 +74,7 @@ class LayerTreeHostReadbackPixelTest : public LayerTreePixelTest { return request.Pass(); } - virtual void BeginTest() OVERRIDE { + void BeginTest() override { if (insert_copy_request_after_frame_count_ == 0) { Layer* const target = readback_target_ ? readback_target_ : layer_tree_host()->root_layer(); @@ -59,7 +83,7 @@ class LayerTreeHostReadbackPixelTest : public LayerTreePixelTest { PostSetNeedsCommitToMainThread(); } - virtual void DidCommitAndDrawFrame() OVERRIDE { + void DidCommitAndDrawFrame() override { if (insert_copy_request_after_frame_count_ == layer_tree_host()->source_frame_number()) { Layer* const target = @@ -92,421 +116,438 @@ class LayerTreeHostReadbackPixelTest : public LayerTreePixelTest { ReadbackResultAsBitmap(CopyOutputResult::CreateBitmapResult(bitmap.Pass())); } + ReadbackType readback_type_; gfx::Rect copy_subrect_; int insert_copy_request_after_frame_count_; }; -void IgnoreReadbackResult(scoped_ptr<CopyOutputResult> result) {} +void IgnoreReadbackResult(scoped_ptr<CopyOutputResult> result) { +} TEST_F(LayerTreeHostReadbackPixelTest, ReadbackRootLayer_Software) { - scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer( - gfx::Rect(200, 200), SK_ColorWHITE); + scoped_refptr<SolidColorLayer> background = + CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorWHITE); - scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer( - gfx::Rect(200, 200), SK_ColorGREEN); + scoped_refptr<SolidColorLayer> green = + CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorGREEN); background->AddChild(green); - RunPixelTest(SOFTWARE_WITH_DEFAULT, - background, - base::FilePath(FILE_PATH_LITERAL( - "green.png"))); + RunReadbackTest(PIXEL_TEST_SOFTWARE, + READBACK_DEFAULT, + background, + base::FilePath(FILE_PATH_LITERAL("green.png"))); } TEST_F(LayerTreeHostReadbackPixelTest, ReadbackRootLayer_Software_Bitmap) { - scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer( - gfx::Rect(200, 200), SK_ColorWHITE); + scoped_refptr<SolidColorLayer> background = + CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorWHITE); - scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer( - gfx::Rect(200, 200), SK_ColorGREEN); + scoped_refptr<SolidColorLayer> green = + CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorGREEN); background->AddChild(green); - RunPixelTest(SOFTWARE_WITH_BITMAP, - background, - base::FilePath(FILE_PATH_LITERAL( - "green.png"))); + RunReadbackTest(PIXEL_TEST_SOFTWARE, + READBACK_BITMAP, + background, + base::FilePath(FILE_PATH_LITERAL("green.png"))); } TEST_F(LayerTreeHostReadbackPixelTest, ReadbackRootLayer_GL_Bitmap) { - scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer( - gfx::Rect(200, 200), SK_ColorWHITE); + scoped_refptr<SolidColorLayer> background = + CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorWHITE); - scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer( - gfx::Rect(200, 200), SK_ColorGREEN); + scoped_refptr<SolidColorLayer> green = + CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorGREEN); background->AddChild(green); - RunPixelTest(GL_WITH_BITMAP, - background, - base::FilePath(FILE_PATH_LITERAL( - "green.png"))); + RunReadbackTest(PIXEL_TEST_GL, + READBACK_BITMAP, + background, + base::FilePath(FILE_PATH_LITERAL("green.png"))); } TEST_F(LayerTreeHostReadbackPixelTest, ReadbackRootLayer_GL) { - scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer( - gfx::Rect(200, 200), SK_ColorWHITE); + scoped_refptr<SolidColorLayer> background = + CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorWHITE); - scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer( - gfx::Rect(200, 200), SK_ColorGREEN); + scoped_refptr<SolidColorLayer> green = + CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorGREEN); background->AddChild(green); - RunPixelTest(GL_WITH_DEFAULT, - background, - base::FilePath(FILE_PATH_LITERAL( - "green.png"))); + RunReadbackTest(PIXEL_TEST_GL, + READBACK_DEFAULT, + background, + base::FilePath(FILE_PATH_LITERAL("green.png"))); } -TEST_F(LayerTreeHostReadbackPixelTest, - ReadbackRootLayerWithChild_Software) { - scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer( - gfx::Rect(200, 200), SK_ColorWHITE); +TEST_F(LayerTreeHostReadbackPixelTest, ReadbackRootLayerWithChild_Software) { + scoped_refptr<SolidColorLayer> background = + CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorWHITE); - scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer( - gfx::Rect(200, 200), SK_ColorGREEN); + scoped_refptr<SolidColorLayer> green = + CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorGREEN); background->AddChild(green); - scoped_refptr<SolidColorLayer> blue = CreateSolidColorLayer( - gfx::Rect(150, 150, 50, 50), SK_ColorBLUE); + scoped_refptr<SolidColorLayer> blue = + CreateSolidColorLayer(gfx::Rect(150, 150, 50, 50), SK_ColorBLUE); green->AddChild(blue); - RunPixelTest(SOFTWARE_WITH_DEFAULT, - background, - base::FilePath(FILE_PATH_LITERAL( - "green_with_blue_corner.png"))); + RunReadbackTest( + PIXEL_TEST_SOFTWARE, + READBACK_DEFAULT, + background, + base::FilePath(FILE_PATH_LITERAL("green_with_blue_corner.png"))); } TEST_F(LayerTreeHostReadbackPixelTest, ReadbackRootLayerWithChild_GL_Bitmap) { - scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer( - gfx::Rect(200, 200), SK_ColorWHITE); + scoped_refptr<SolidColorLayer> background = + CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorWHITE); - scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer( - gfx::Rect(200, 200), SK_ColorGREEN); + scoped_refptr<SolidColorLayer> green = + CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorGREEN); background->AddChild(green); - scoped_refptr<SolidColorLayer> blue = CreateSolidColorLayer( - gfx::Rect(150, 150, 50, 50), SK_ColorBLUE); + scoped_refptr<SolidColorLayer> blue = + CreateSolidColorLayer(gfx::Rect(150, 150, 50, 50), SK_ColorBLUE); green->AddChild(blue); - RunPixelTest(GL_WITH_BITMAP, - background, - base::FilePath(FILE_PATH_LITERAL( - "green_with_blue_corner.png"))); + RunReadbackTest( + PIXEL_TEST_GL, + READBACK_BITMAP, + background, + base::FilePath(FILE_PATH_LITERAL("green_with_blue_corner.png"))); } TEST_F(LayerTreeHostReadbackPixelTest, ReadbackRootLayerWithChild_GL) { - scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer( - gfx::Rect(200, 200), SK_ColorWHITE); + scoped_refptr<SolidColorLayer> background = + CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorWHITE); - scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer( - gfx::Rect(200, 200), SK_ColorGREEN); + scoped_refptr<SolidColorLayer> green = + CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorGREEN); background->AddChild(green); - scoped_refptr<SolidColorLayer> blue = CreateSolidColorLayer( - gfx::Rect(150, 150, 50, 50), SK_ColorBLUE); + scoped_refptr<SolidColorLayer> blue = + CreateSolidColorLayer(gfx::Rect(150, 150, 50, 50), SK_ColorBLUE); green->AddChild(blue); - RunPixelTest(GL_WITH_DEFAULT, - background, - base::FilePath(FILE_PATH_LITERAL( - "green_with_blue_corner.png"))); + RunReadbackTest( + PIXEL_TEST_GL, + READBACK_DEFAULT, + background, + base::FilePath(FILE_PATH_LITERAL("green_with_blue_corner.png"))); } TEST_F(LayerTreeHostReadbackPixelTest, ReadbackNonRootLayer_Software) { - scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer( - gfx::Rect(200, 200), SK_ColorWHITE); + scoped_refptr<SolidColorLayer> background = + CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorWHITE); - scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer( - gfx::Rect(200, 200), SK_ColorGREEN); + scoped_refptr<SolidColorLayer> green = + CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorGREEN); background->AddChild(green); - RunPixelTestWithReadbackTarget(SOFTWARE_WITH_DEFAULT, - background, - green.get(), - base::FilePath(FILE_PATH_LITERAL( - "green.png"))); + RunReadbackTestWithReadbackTarget( + PIXEL_TEST_SOFTWARE, + READBACK_DEFAULT, + background, + green.get(), + base::FilePath(FILE_PATH_LITERAL("green.png"))); } TEST_F(LayerTreeHostReadbackPixelTest, ReadbackNonRootLayer_GL_Bitmap) { - scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer( - gfx::Rect(200, 200), SK_ColorWHITE); + scoped_refptr<SolidColorLayer> background = + CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorWHITE); - scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer( - gfx::Rect(200, 200), SK_ColorGREEN); + scoped_refptr<SolidColorLayer> green = + CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorGREEN); background->AddChild(green); - RunPixelTestWithReadbackTarget(GL_WITH_BITMAP, - background, - green.get(), - base::FilePath(FILE_PATH_LITERAL( - "green.png"))); + RunReadbackTestWithReadbackTarget( + PIXEL_TEST_GL, + READBACK_BITMAP, + background, + green.get(), + base::FilePath(FILE_PATH_LITERAL("green.png"))); } TEST_F(LayerTreeHostReadbackPixelTest, ReadbackNonRootLayer_GL) { - scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer( - gfx::Rect(200, 200), SK_ColorWHITE); + scoped_refptr<SolidColorLayer> background = + CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorWHITE); - scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer( - gfx::Rect(200, 200), SK_ColorGREEN); + scoped_refptr<SolidColorLayer> green = + CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorGREEN); background->AddChild(green); - RunPixelTestWithReadbackTarget(GL_WITH_DEFAULT, - background, - green.get(), - base::FilePath(FILE_PATH_LITERAL( - "green.png"))); + RunReadbackTestWithReadbackTarget( + PIXEL_TEST_GL, + READBACK_DEFAULT, + background, + green.get(), + base::FilePath(FILE_PATH_LITERAL("green.png"))); } -TEST_F(LayerTreeHostReadbackPixelTest, - ReadbackSmallNonRootLayer_Software) { - scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer( - gfx::Rect(200, 200), SK_ColorWHITE); +TEST_F(LayerTreeHostReadbackPixelTest, ReadbackSmallNonRootLayer_Software) { + scoped_refptr<SolidColorLayer> background = + CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorWHITE); - scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer( - gfx::Rect(100, 100, 100, 100), SK_ColorGREEN); + scoped_refptr<SolidColorLayer> green = + CreateSolidColorLayer(gfx::Rect(100, 100, 100, 100), SK_ColorGREEN); background->AddChild(green); - RunPixelTestWithReadbackTarget(SOFTWARE_WITH_DEFAULT, - background, - green.get(), - base::FilePath(FILE_PATH_LITERAL( - "green_small.png"))); + RunReadbackTestWithReadbackTarget( + PIXEL_TEST_SOFTWARE, + READBACK_DEFAULT, + background, + green.get(), + base::FilePath(FILE_PATH_LITERAL("green_small.png"))); } TEST_F(LayerTreeHostReadbackPixelTest, ReadbackSmallNonRootLayer_GL_Bitmap) { - scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer( - gfx::Rect(200, 200), SK_ColorWHITE); + scoped_refptr<SolidColorLayer> background = + CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorWHITE); - scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer( - gfx::Rect(100, 100, 100, 100), SK_ColorGREEN); + scoped_refptr<SolidColorLayer> green = + CreateSolidColorLayer(gfx::Rect(100, 100, 100, 100), SK_ColorGREEN); background->AddChild(green); - RunPixelTestWithReadbackTarget(GL_WITH_BITMAP, - background, - green.get(), - base::FilePath(FILE_PATH_LITERAL( - "green_small.png"))); + RunReadbackTestWithReadbackTarget( + PIXEL_TEST_GL, + READBACK_BITMAP, + background, + green.get(), + base::FilePath(FILE_PATH_LITERAL("green_small.png"))); } TEST_F(LayerTreeHostReadbackPixelTest, ReadbackSmallNonRootLayer_GL) { - scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer( - gfx::Rect(200, 200), SK_ColorWHITE); + scoped_refptr<SolidColorLayer> background = + CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorWHITE); - scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer( - gfx::Rect(100, 100, 100, 100), SK_ColorGREEN); + scoped_refptr<SolidColorLayer> green = + CreateSolidColorLayer(gfx::Rect(100, 100, 100, 100), SK_ColorGREEN); background->AddChild(green); - RunPixelTestWithReadbackTarget(GL_WITH_DEFAULT, - background, - green.get(), - base::FilePath(FILE_PATH_LITERAL( - "green_small.png"))); + RunReadbackTestWithReadbackTarget( + PIXEL_TEST_GL, + READBACK_DEFAULT, + background, + green.get(), + base::FilePath(FILE_PATH_LITERAL("green_small.png"))); } TEST_F(LayerTreeHostReadbackPixelTest, ReadbackSmallNonRootLayerWithChild_Software) { - scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer( - gfx::Rect(200, 200), SK_ColorWHITE); + scoped_refptr<SolidColorLayer> background = + CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorWHITE); - scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer( - gfx::Rect(100, 100, 100, 100), SK_ColorGREEN); + scoped_refptr<SolidColorLayer> green = + CreateSolidColorLayer(gfx::Rect(100, 100, 100, 100), SK_ColorGREEN); background->AddChild(green); - scoped_refptr<SolidColorLayer> blue = CreateSolidColorLayer( - gfx::Rect(50, 50, 50, 50), SK_ColorBLUE); + scoped_refptr<SolidColorLayer> blue = + CreateSolidColorLayer(gfx::Rect(50, 50, 50, 50), SK_ColorBLUE); green->AddChild(blue); - RunPixelTestWithReadbackTarget(SOFTWARE_WITH_DEFAULT, - background, - green.get(), - base::FilePath(FILE_PATH_LITERAL( - "green_small_with_blue_corner.png"))); + RunReadbackTestWithReadbackTarget( + PIXEL_TEST_SOFTWARE, + READBACK_DEFAULT, + background, + green.get(), + base::FilePath(FILE_PATH_LITERAL("green_small_with_blue_corner.png"))); } TEST_F(LayerTreeHostReadbackPixelTest, ReadbackSmallNonRootLayerWithChild_GL_Bitmap) { - scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer( - gfx::Rect(200, 200), SK_ColorWHITE); + scoped_refptr<SolidColorLayer> background = + CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorWHITE); - scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer( - gfx::Rect(100, 100, 100, 100), SK_ColorGREEN); + scoped_refptr<SolidColorLayer> green = + CreateSolidColorLayer(gfx::Rect(100, 100, 100, 100), SK_ColorGREEN); background->AddChild(green); - scoped_refptr<SolidColorLayer> blue = CreateSolidColorLayer( - gfx::Rect(50, 50, 50, 50), SK_ColorBLUE); + scoped_refptr<SolidColorLayer> blue = + CreateSolidColorLayer(gfx::Rect(50, 50, 50, 50), SK_ColorBLUE); green->AddChild(blue); - RunPixelTestWithReadbackTarget(GL_WITH_BITMAP, - background, - green.get(), - base::FilePath(FILE_PATH_LITERAL( - "green_small_with_blue_corner.png"))); + RunReadbackTestWithReadbackTarget( + PIXEL_TEST_GL, + READBACK_BITMAP, + background, + green.get(), + base::FilePath(FILE_PATH_LITERAL("green_small_with_blue_corner.png"))); } TEST_F(LayerTreeHostReadbackPixelTest, ReadbackSmallNonRootLayerWithChild_GL) { - scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer( - gfx::Rect(200, 200), SK_ColorWHITE); + scoped_refptr<SolidColorLayer> background = + CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorWHITE); - scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer( - gfx::Rect(100, 100, 100, 100), SK_ColorGREEN); + scoped_refptr<SolidColorLayer> green = + CreateSolidColorLayer(gfx::Rect(100, 100, 100, 100), SK_ColorGREEN); background->AddChild(green); - scoped_refptr<SolidColorLayer> blue = CreateSolidColorLayer( - gfx::Rect(50, 50, 50, 50), SK_ColorBLUE); + scoped_refptr<SolidColorLayer> blue = + CreateSolidColorLayer(gfx::Rect(50, 50, 50, 50), SK_ColorBLUE); green->AddChild(blue); - RunPixelTestWithReadbackTarget(GL_WITH_DEFAULT, - background, - green.get(), - base::FilePath(FILE_PATH_LITERAL( - "green_small_with_blue_corner.png"))); + RunReadbackTestWithReadbackTarget( + PIXEL_TEST_GL, + READBACK_DEFAULT, + background, + green.get(), + base::FilePath(FILE_PATH_LITERAL("green_small_with_blue_corner.png"))); } TEST_F(LayerTreeHostReadbackPixelTest, ReadbackSubtreeSurroundsTargetLayer_Software) { - scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer( - gfx::Rect(0, 0, 200, 200), SK_ColorWHITE); + scoped_refptr<SolidColorLayer> background = + CreateSolidColorLayer(gfx::Rect(0, 0, 200, 200), SK_ColorWHITE); - scoped_refptr<SolidColorLayer> target = CreateSolidColorLayer( - gfx::Rect(100, 100, 100, 100), SK_ColorRED); + scoped_refptr<SolidColorLayer> target = + CreateSolidColorLayer(gfx::Rect(100, 100, 100, 100), SK_ColorRED); background->AddChild(target); - scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer( - gfx::Rect(-100, -100, 300, 300), SK_ColorGREEN); + scoped_refptr<SolidColorLayer> green = + CreateSolidColorLayer(gfx::Rect(-100, -100, 300, 300), SK_ColorGREEN); target->AddChild(green); - scoped_refptr<SolidColorLayer> blue = CreateSolidColorLayer( - gfx::Rect(50, 50, 50, 50), SK_ColorBLUE); + scoped_refptr<SolidColorLayer> blue = + CreateSolidColorLayer(gfx::Rect(50, 50, 50, 50), SK_ColorBLUE); target->AddChild(blue); copy_subrect_ = gfx::Rect(0, 0, 100, 100); - RunPixelTestWithReadbackTarget(SOFTWARE_WITH_DEFAULT, - background, - target.get(), - base::FilePath(FILE_PATH_LITERAL( - "green_small_with_blue_corner.png"))); + RunReadbackTestWithReadbackTarget( + PIXEL_TEST_SOFTWARE, + READBACK_DEFAULT, + background, + target.get(), + base::FilePath(FILE_PATH_LITERAL("green_small_with_blue_corner.png"))); } TEST_F(LayerTreeHostReadbackPixelTest, ReadbackSubtreeSurroundsLayer_GL_Bitmap) { - scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer( - gfx::Rect(0, 0, 200, 200), SK_ColorWHITE); + scoped_refptr<SolidColorLayer> background = + CreateSolidColorLayer(gfx::Rect(0, 0, 200, 200), SK_ColorWHITE); - scoped_refptr<SolidColorLayer> target = CreateSolidColorLayer( - gfx::Rect(100, 100, 100, 100), SK_ColorRED); + scoped_refptr<SolidColorLayer> target = + CreateSolidColorLayer(gfx::Rect(100, 100, 100, 100), SK_ColorRED); background->AddChild(target); - scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer( - gfx::Rect(-100, -100, 300, 300), SK_ColorGREEN); + scoped_refptr<SolidColorLayer> green = + CreateSolidColorLayer(gfx::Rect(-100, -100, 300, 300), SK_ColorGREEN); target->AddChild(green); - scoped_refptr<SolidColorLayer> blue = CreateSolidColorLayer( - gfx::Rect(50, 50, 50, 50), SK_ColorBLUE); + scoped_refptr<SolidColorLayer> blue = + CreateSolidColorLayer(gfx::Rect(50, 50, 50, 50), SK_ColorBLUE); target->AddChild(blue); copy_subrect_ = gfx::Rect(0, 0, 100, 100); - RunPixelTestWithReadbackTarget(GL_WITH_BITMAP, - background, - target.get(), - base::FilePath(FILE_PATH_LITERAL( - "green_small_with_blue_corner.png"))); + RunReadbackTestWithReadbackTarget( + PIXEL_TEST_GL, + READBACK_BITMAP, + background, + target.get(), + base::FilePath(FILE_PATH_LITERAL("green_small_with_blue_corner.png"))); } -TEST_F(LayerTreeHostReadbackPixelTest, - ReadbackSubtreeSurroundsTargetLayer_GL) { - scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer( - gfx::Rect(0, 0, 200, 200), SK_ColorWHITE); +TEST_F(LayerTreeHostReadbackPixelTest, ReadbackSubtreeSurroundsTargetLayer_GL) { + scoped_refptr<SolidColorLayer> background = + CreateSolidColorLayer(gfx::Rect(0, 0, 200, 200), SK_ColorWHITE); - scoped_refptr<SolidColorLayer> target = CreateSolidColorLayer( - gfx::Rect(100, 100, 100, 100), SK_ColorRED); + scoped_refptr<SolidColorLayer> target = + CreateSolidColorLayer(gfx::Rect(100, 100, 100, 100), SK_ColorRED); background->AddChild(target); - scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer( - gfx::Rect(-100, -100, 300, 300), SK_ColorGREEN); + scoped_refptr<SolidColorLayer> green = + CreateSolidColorLayer(gfx::Rect(-100, -100, 300, 300), SK_ColorGREEN); target->AddChild(green); - scoped_refptr<SolidColorLayer> blue = CreateSolidColorLayer( - gfx::Rect(50, 50, 50, 50), SK_ColorBLUE); + scoped_refptr<SolidColorLayer> blue = + CreateSolidColorLayer(gfx::Rect(50, 50, 50, 50), SK_ColorBLUE); target->AddChild(blue); copy_subrect_ = gfx::Rect(0, 0, 100, 100); - RunPixelTestWithReadbackTarget(GL_WITH_DEFAULT, - background, - target.get(), - base::FilePath(FILE_PATH_LITERAL( - "green_small_with_blue_corner.png"))); + RunReadbackTestWithReadbackTarget( + PIXEL_TEST_GL, + READBACK_DEFAULT, + background, + target.get(), + base::FilePath(FILE_PATH_LITERAL("green_small_with_blue_corner.png"))); } TEST_F(LayerTreeHostReadbackPixelTest, ReadbackSubtreeExtendsBeyondTargetLayer_Software) { - scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer( - gfx::Rect(0, 0, 200, 200), SK_ColorWHITE); + scoped_refptr<SolidColorLayer> background = + CreateSolidColorLayer(gfx::Rect(0, 0, 200, 200), SK_ColorWHITE); - scoped_refptr<SolidColorLayer> target = CreateSolidColorLayer( - gfx::Rect(50, 50, 150, 150), SK_ColorRED); + scoped_refptr<SolidColorLayer> target = + CreateSolidColorLayer(gfx::Rect(50, 50, 150, 150), SK_ColorRED); background->AddChild(target); - scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer( - gfx::Rect(50, 50, 200, 200), SK_ColorGREEN); + scoped_refptr<SolidColorLayer> green = + CreateSolidColorLayer(gfx::Rect(50, 50, 200, 200), SK_ColorGREEN); target->AddChild(green); - scoped_refptr<SolidColorLayer> blue = CreateSolidColorLayer( - gfx::Rect(100, 100, 50, 50), SK_ColorBLUE); + scoped_refptr<SolidColorLayer> blue = + CreateSolidColorLayer(gfx::Rect(100, 100, 50, 50), SK_ColorBLUE); target->AddChild(blue); copy_subrect_ = gfx::Rect(50, 50, 100, 100); - RunPixelTestWithReadbackTarget(SOFTWARE_WITH_DEFAULT, - background, - target.get(), - base::FilePath(FILE_PATH_LITERAL( - "green_small_with_blue_corner.png"))); + RunReadbackTestWithReadbackTarget( + PIXEL_TEST_SOFTWARE, + READBACK_DEFAULT, + background, + target.get(), + base::FilePath(FILE_PATH_LITERAL("green_small_with_blue_corner.png"))); } TEST_F(LayerTreeHostReadbackPixelTest, ReadbackSubtreeExtendsBeyondTargetLayer_GL_Bitmap) { - scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer( - gfx::Rect(0, 0, 200, 200), SK_ColorWHITE); + scoped_refptr<SolidColorLayer> background = + CreateSolidColorLayer(gfx::Rect(0, 0, 200, 200), SK_ColorWHITE); - scoped_refptr<SolidColorLayer> target = CreateSolidColorLayer( - gfx::Rect(50, 50, 150, 150), SK_ColorRED); + scoped_refptr<SolidColorLayer> target = + CreateSolidColorLayer(gfx::Rect(50, 50, 150, 150), SK_ColorRED); background->AddChild(target); - scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer( - gfx::Rect(50, 50, 200, 200), SK_ColorGREEN); + scoped_refptr<SolidColorLayer> green = + CreateSolidColorLayer(gfx::Rect(50, 50, 200, 200), SK_ColorGREEN); target->AddChild(green); - scoped_refptr<SolidColorLayer> blue = CreateSolidColorLayer( - gfx::Rect(100, 100, 50, 50), SK_ColorBLUE); + scoped_refptr<SolidColorLayer> blue = + CreateSolidColorLayer(gfx::Rect(100, 100, 50, 50), SK_ColorBLUE); target->AddChild(blue); copy_subrect_ = gfx::Rect(50, 50, 100, 100); - RunPixelTestWithReadbackTarget(GL_WITH_BITMAP, - background, - target.get(), - base::FilePath(FILE_PATH_LITERAL( - "green_small_with_blue_corner.png"))); + RunReadbackTestWithReadbackTarget( + PIXEL_TEST_GL, + READBACK_BITMAP, + background, + target.get(), + base::FilePath(FILE_PATH_LITERAL("green_small_with_blue_corner.png"))); } TEST_F(LayerTreeHostReadbackPixelTest, ReadbackSubtreeExtendsBeyondTargetLayer_GL) { - scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer( - gfx::Rect(0, 0, 200, 200), SK_ColorWHITE); + scoped_refptr<SolidColorLayer> background = + CreateSolidColorLayer(gfx::Rect(0, 0, 200, 200), SK_ColorWHITE); - scoped_refptr<SolidColorLayer> target = CreateSolidColorLayer( - gfx::Rect(50, 50, 150, 150), SK_ColorRED); + scoped_refptr<SolidColorLayer> target = + CreateSolidColorLayer(gfx::Rect(50, 50, 150, 150), SK_ColorRED); background->AddChild(target); - scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer( - gfx::Rect(50, 50, 200, 200), SK_ColorGREEN); + scoped_refptr<SolidColorLayer> green = + CreateSolidColorLayer(gfx::Rect(50, 50, 200, 200), SK_ColorGREEN); target->AddChild(green); - scoped_refptr<SolidColorLayer> blue = CreateSolidColorLayer( - gfx::Rect(100, 100, 50, 50), SK_ColorBLUE); + scoped_refptr<SolidColorLayer> blue = + CreateSolidColorLayer(gfx::Rect(100, 100, 50, 50), SK_ColorBLUE); target->AddChild(blue); copy_subrect_ = gfx::Rect(50, 50, 100, 100); - RunPixelTestWithReadbackTarget(GL_WITH_DEFAULT, - background, - target.get(), - base::FilePath(FILE_PATH_LITERAL( - "green_small_with_blue_corner.png"))); + RunReadbackTestWithReadbackTarget( + PIXEL_TEST_GL, + READBACK_DEFAULT, + background, + target.get(), + base::FilePath(FILE_PATH_LITERAL("green_small_with_blue_corner.png"))); } TEST_F(LayerTreeHostReadbackPixelTest, ReadbackHiddenSubtree_Software) { @@ -522,8 +563,9 @@ TEST_F(LayerTreeHostReadbackPixelTest, ReadbackHiddenSubtree_Software) { CreateSolidColorLayer(gfx::Rect(150, 150, 50, 50), SK_ColorBLUE); hidden_target->AddChild(blue); - RunPixelTestWithReadbackTarget( - SOFTWARE_WITH_DEFAULT, + RunReadbackTestWithReadbackTarget( + PIXEL_TEST_SOFTWARE, + READBACK_DEFAULT, background, hidden_target.get(), base::FilePath(FILE_PATH_LITERAL("green_with_blue_corner.png"))); @@ -542,8 +584,9 @@ TEST_F(LayerTreeHostReadbackPixelTest, ReadbackHiddenSubtree_GL_Bitmap) { CreateSolidColorLayer(gfx::Rect(150, 150, 50, 50), SK_ColorBLUE); hidden_target->AddChild(blue); - RunPixelTestWithReadbackTarget( - GL_WITH_BITMAP, + RunReadbackTestWithReadbackTarget( + PIXEL_TEST_GL, + READBACK_BITMAP, background, hidden_target.get(), base::FilePath(FILE_PATH_LITERAL("green_with_blue_corner.png"))); @@ -562,8 +605,9 @@ TEST_F(LayerTreeHostReadbackPixelTest, ReadbackHiddenSubtree_GL) { CreateSolidColorLayer(gfx::Rect(150, 150, 50, 50), SK_ColorBLUE); hidden_target->AddChild(blue); - RunPixelTestWithReadbackTarget( - GL_WITH_DEFAULT, + RunReadbackTestWithReadbackTarget( + PIXEL_TEST_GL, + READBACK_DEFAULT, background, hidden_target.get(), base::FilePath(FILE_PATH_LITERAL("green_with_blue_corner.png"))); @@ -585,9 +629,10 @@ TEST_F(LayerTreeHostReadbackPixelTest, hidden_target->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest( base::Bind(&IgnoreReadbackResult))); - RunPixelTest(SOFTWARE_WITH_DEFAULT, - background, - base::FilePath(FILE_PATH_LITERAL("black.png"))); + RunReadbackTest(PIXEL_TEST_SOFTWARE, + READBACK_DEFAULT, + background, + base::FilePath(FILE_PATH_LITERAL("black.png"))); } TEST_F(LayerTreeHostReadbackPixelTest, @@ -606,9 +651,10 @@ TEST_F(LayerTreeHostReadbackPixelTest, hidden_target->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest( base::Bind(&IgnoreReadbackResult))); - RunPixelTest(GL_WITH_BITMAP, - background, - base::FilePath(FILE_PATH_LITERAL("black.png"))); + RunReadbackTest(PIXEL_TEST_GL, + READBACK_BITMAP, + background, + base::FilePath(FILE_PATH_LITERAL("black.png"))); } TEST_F(LayerTreeHostReadbackPixelTest, @@ -627,138 +673,145 @@ TEST_F(LayerTreeHostReadbackPixelTest, hidden_target->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest( base::Bind(&IgnoreReadbackResult))); - RunPixelTest(GL_WITH_DEFAULT, - background, - base::FilePath(FILE_PATH_LITERAL("black.png"))); + RunReadbackTest(PIXEL_TEST_GL, + READBACK_DEFAULT, + background, + base::FilePath(FILE_PATH_LITERAL("black.png"))); } TEST_F(LayerTreeHostReadbackPixelTest, ReadbackSubrect_Software) { - scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer( - gfx::Rect(200, 200), SK_ColorWHITE); + scoped_refptr<SolidColorLayer> background = + CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorWHITE); - scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer( - gfx::Rect(200, 200), SK_ColorGREEN); + scoped_refptr<SolidColorLayer> green = + CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorGREEN); background->AddChild(green); - scoped_refptr<SolidColorLayer> blue = CreateSolidColorLayer( - gfx::Rect(100, 100, 50, 50), SK_ColorBLUE); + scoped_refptr<SolidColorLayer> blue = + CreateSolidColorLayer(gfx::Rect(100, 100, 50, 50), SK_ColorBLUE); green->AddChild(blue); // Grab the middle of the root layer. copy_subrect_ = gfx::Rect(50, 50, 100, 100); - RunPixelTest(SOFTWARE_WITH_DEFAULT, - background, - base::FilePath(FILE_PATH_LITERAL( - "green_small_with_blue_corner.png"))); + RunReadbackTest( + PIXEL_TEST_SOFTWARE, + READBACK_DEFAULT, + background, + base::FilePath(FILE_PATH_LITERAL("green_small_with_blue_corner.png"))); } TEST_F(LayerTreeHostReadbackPixelTest, ReadbackSubrect_GL_Bitmap) { - scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer( - gfx::Rect(200, 200), SK_ColorWHITE); + scoped_refptr<SolidColorLayer> background = + CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorWHITE); - scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer( - gfx::Rect(200, 200), SK_ColorGREEN); + scoped_refptr<SolidColorLayer> green = + CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorGREEN); background->AddChild(green); - scoped_refptr<SolidColorLayer> blue = CreateSolidColorLayer( - gfx::Rect(100, 100, 50, 50), SK_ColorBLUE); + scoped_refptr<SolidColorLayer> blue = + CreateSolidColorLayer(gfx::Rect(100, 100, 50, 50), SK_ColorBLUE); green->AddChild(blue); // Grab the middle of the root layer. copy_subrect_ = gfx::Rect(50, 50, 100, 100); - RunPixelTest(GL_WITH_BITMAP, - background, - base::FilePath(FILE_PATH_LITERAL( - "green_small_with_blue_corner.png"))); + RunReadbackTest( + PIXEL_TEST_GL, + READBACK_BITMAP, + background, + base::FilePath(FILE_PATH_LITERAL("green_small_with_blue_corner.png"))); } TEST_F(LayerTreeHostReadbackPixelTest, ReadbackSubrect_GL) { - scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer( - gfx::Rect(200, 200), SK_ColorWHITE); + scoped_refptr<SolidColorLayer> background = + CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorWHITE); - scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer( - gfx::Rect(200, 200), SK_ColorGREEN); + scoped_refptr<SolidColorLayer> green = + CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorGREEN); background->AddChild(green); - scoped_refptr<SolidColorLayer> blue = CreateSolidColorLayer( - gfx::Rect(100, 100, 50, 50), SK_ColorBLUE); + scoped_refptr<SolidColorLayer> blue = + CreateSolidColorLayer(gfx::Rect(100, 100, 50, 50), SK_ColorBLUE); green->AddChild(blue); // Grab the middle of the root layer. copy_subrect_ = gfx::Rect(50, 50, 100, 100); - RunPixelTest(GL_WITH_DEFAULT, - background, - base::FilePath(FILE_PATH_LITERAL( - "green_small_with_blue_corner.png"))); + RunReadbackTest( + PIXEL_TEST_GL, + READBACK_DEFAULT, + background, + base::FilePath(FILE_PATH_LITERAL("green_small_with_blue_corner.png"))); } TEST_F(LayerTreeHostReadbackPixelTest, ReadbackNonRootLayerSubrect_Software) { - scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer( - gfx::Rect(200, 200), SK_ColorWHITE); + scoped_refptr<SolidColorLayer> background = + CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorWHITE); - scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer( - gfx::Rect(25, 25, 150, 150), SK_ColorGREEN); + scoped_refptr<SolidColorLayer> green = + CreateSolidColorLayer(gfx::Rect(25, 25, 150, 150), SK_ColorGREEN); background->AddChild(green); - scoped_refptr<SolidColorLayer> blue = CreateSolidColorLayer( - gfx::Rect(75, 75, 50, 50), SK_ColorBLUE); + scoped_refptr<SolidColorLayer> blue = + CreateSolidColorLayer(gfx::Rect(75, 75, 50, 50), SK_ColorBLUE); green->AddChild(blue); // Grab the middle of the green layer. copy_subrect_ = gfx::Rect(25, 25, 100, 100); - RunPixelTestWithReadbackTarget(SOFTWARE_WITH_DEFAULT, - background, - green.get(), - base::FilePath(FILE_PATH_LITERAL( - "green_small_with_blue_corner.png"))); + RunReadbackTestWithReadbackTarget( + PIXEL_TEST_SOFTWARE, + READBACK_DEFAULT, + background, + green.get(), + base::FilePath(FILE_PATH_LITERAL("green_small_with_blue_corner.png"))); } TEST_F(LayerTreeHostReadbackPixelTest, ReadbackNonRootLayerSubrect_GL_Bitmap) { - scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer( - gfx::Rect(200, 200), SK_ColorWHITE); + scoped_refptr<SolidColorLayer> background = + CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorWHITE); - scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer( - gfx::Rect(25, 25, 150, 150), SK_ColorGREEN); + scoped_refptr<SolidColorLayer> green = + CreateSolidColorLayer(gfx::Rect(25, 25, 150, 150), SK_ColorGREEN); background->AddChild(green); - scoped_refptr<SolidColorLayer> blue = CreateSolidColorLayer( - gfx::Rect(75, 75, 50, 50), SK_ColorBLUE); + scoped_refptr<SolidColorLayer> blue = + CreateSolidColorLayer(gfx::Rect(75, 75, 50, 50), SK_ColorBLUE); green->AddChild(blue); // Grab the middle of the green layer. copy_subrect_ = gfx::Rect(25, 25, 100, 100); - RunPixelTestWithReadbackTarget(GL_WITH_BITMAP, - background, - green.get(), - base::FilePath(FILE_PATH_LITERAL( - "green_small_with_blue_corner.png"))); + RunReadbackTestWithReadbackTarget( + PIXEL_TEST_GL, + READBACK_BITMAP, + background, + green.get(), + base::FilePath(FILE_PATH_LITERAL("green_small_with_blue_corner.png"))); } TEST_F(LayerTreeHostReadbackPixelTest, ReadbackNonRootLayerSubrect_GL) { - scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer( - gfx::Rect(200, 200), SK_ColorWHITE); + scoped_refptr<SolidColorLayer> background = + CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorWHITE); - scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer( - gfx::Rect(25, 25, 150, 150), SK_ColorGREEN); + scoped_refptr<SolidColorLayer> green = + CreateSolidColorLayer(gfx::Rect(25, 25, 150, 150), SK_ColorGREEN); background->AddChild(green); - scoped_refptr<SolidColorLayer> blue = CreateSolidColorLayer( - gfx::Rect(75, 75, 50, 50), SK_ColorBLUE); + scoped_refptr<SolidColorLayer> blue = + CreateSolidColorLayer(gfx::Rect(75, 75, 50, 50), SK_ColorBLUE); green->AddChild(blue); // Grab the middle of the green layer. copy_subrect_ = gfx::Rect(25, 25, 100, 100); - RunPixelTestWithReadbackTarget(GL_WITH_DEFAULT, - background, - green.get(), - base::FilePath(FILE_PATH_LITERAL( - "green_small_with_blue_corner.png"))); + RunReadbackTestWithReadbackTarget( + PIXEL_TEST_GL, + READBACK_DEFAULT, + background, + green.get(), + base::FilePath(FILE_PATH_LITERAL("green_small_with_blue_corner.png"))); } TEST_F(LayerTreeHostReadbackPixelTest, ReadbackWhenNoDamage_Software) { @@ -778,8 +831,9 @@ TEST_F(LayerTreeHostReadbackPixelTest, ReadbackWhenNoDamage_Software) { target->AddChild(blue); insert_copy_request_after_frame_count_ = 1; - RunPixelTestWithReadbackTarget( - SOFTWARE_WITH_DEFAULT, + RunReadbackTestWithReadbackTarget( + PIXEL_TEST_SOFTWARE, + READBACK_DEFAULT, background, target.get(), base::FilePath(FILE_PATH_LITERAL("green_small_with_blue_corner.png"))); @@ -802,8 +856,9 @@ TEST_F(LayerTreeHostReadbackPixelTest, ReadbackWhenNoDamage_GL_Bitmap) { target->AddChild(blue); insert_copy_request_after_frame_count_ = 1; - RunPixelTestWithReadbackTarget( - GL_WITH_BITMAP, + RunReadbackTestWithReadbackTarget( + PIXEL_TEST_GL, + READBACK_BITMAP, background, target.get(), base::FilePath(FILE_PATH_LITERAL("green_small_with_blue_corner.png"))); @@ -826,8 +881,9 @@ TEST_F(LayerTreeHostReadbackPixelTest, ReadbackWhenNoDamage_GL) { target->AddChild(blue); insert_copy_request_after_frame_count_ = 1; - RunPixelTestWithReadbackTarget( - GL_WITH_DEFAULT, + RunReadbackTestWithReadbackTarget( + PIXEL_TEST_GL, + READBACK_DEFAULT, background, target.get(), base::FilePath(FILE_PATH_LITERAL("green_small_with_blue_corner.png"))); @@ -852,8 +908,9 @@ TEST_F(LayerTreeHostReadbackPixelTest, target->AddChild(blue); insert_copy_request_after_frame_count_ = 1; - RunPixelTestWithReadbackTarget( - SOFTWARE_WITH_DEFAULT, + RunReadbackTestWithReadbackTarget( + PIXEL_TEST_SOFTWARE, + READBACK_DEFAULT, background, target.get(), base::FilePath(FILE_PATH_LITERAL("green_small_with_blue_corner.png"))); @@ -878,8 +935,9 @@ TEST_F(LayerTreeHostReadbackPixelTest, target->AddChild(blue); insert_copy_request_after_frame_count_ = 1; - RunPixelTestWithReadbackTarget( - GL_WITH_BITMAP, + RunReadbackTestWithReadbackTarget( + PIXEL_TEST_GL, + READBACK_BITMAP, background, target.get(), base::FilePath(FILE_PATH_LITERAL("green_small_with_blue_corner.png"))); @@ -903,8 +961,9 @@ TEST_F(LayerTreeHostReadbackPixelTest, ReadbackOutsideViewportWhenNoDamage_GL) { target->AddChild(blue); insert_copy_request_after_frame_count_ = 1; - RunPixelTestWithReadbackTarget( - GL_WITH_DEFAULT, + RunReadbackTestWithReadbackTarget( + PIXEL_TEST_GL, + READBACK_DEFAULT, background, target.get(), base::FilePath(FILE_PATH_LITERAL("green_small_with_blue_corner.png"))); @@ -919,30 +978,19 @@ class LayerTreeHostReadbackDeviceScalePixelTest green_client_(SK_ColorGREEN), blue_client_(SK_ColorBLUE) {} - virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE { + void InitializeSettings(LayerTreeSettings* settings) override { // Cause the device scale factor to be inherited by contents scales. settings->layer_transforms_should_scale_layer_contents = true; } - virtual void SetupTree() OVERRIDE { + void SetupTree() override { layer_tree_host()->SetDeviceScaleFactor(device_scale_factor_); LayerTreePixelTest::SetupTree(); } - virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { - LayerImpl* root_impl = host_impl->active_tree()->root_layer(); - - LayerImpl* background_impl = root_impl->children()[0]; - EXPECT_EQ(device_scale_factor_, background_impl->contents_scale_x()); - EXPECT_EQ(device_scale_factor_, background_impl->contents_scale_y()); - - LayerImpl* green_impl = background_impl->children()[0]; - EXPECT_EQ(device_scale_factor_, green_impl->contents_scale_x()); - EXPECT_EQ(device_scale_factor_, green_impl->contents_scale_y()); - - LayerImpl* blue_impl = green_impl->children()[0]; - EXPECT_EQ(device_scale_factor_, blue_impl->contents_scale_x()); - EXPECT_EQ(device_scale_factor_, blue_impl->contents_scale_y()); + void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { + EXPECT_EQ(device_scale_factor_, + host_impl->active_tree()->device_scale_factor()); } float device_scale_factor_; @@ -951,18 +999,20 @@ class LayerTreeHostReadbackDeviceScalePixelTest SolidColorContentLayerClient blue_client_; }; -TEST_F(LayerTreeHostReadbackDeviceScalePixelTest, - ReadbackSubrect_Software) { - scoped_refptr<ContentLayer> background = ContentLayer::Create(&white_client_); +TEST_F(LayerTreeHostReadbackDeviceScalePixelTest, ReadbackSubrect_Software) { + scoped_refptr<FakePictureLayer> background = + FakePictureLayer::Create(&white_client_); background->SetBounds(gfx::Size(100, 100)); background->SetIsDrawable(true); - scoped_refptr<ContentLayer> green = ContentLayer::Create(&green_client_); + scoped_refptr<FakePictureLayer> green = + FakePictureLayer::Create(&green_client_); green->SetBounds(gfx::Size(100, 100)); green->SetIsDrawable(true); background->AddChild(green); - scoped_refptr<ContentLayer> blue = ContentLayer::Create(&blue_client_); + scoped_refptr<FakePictureLayer> blue = + FakePictureLayer::Create(&blue_client_); blue->SetPosition(gfx::Point(50, 50)); blue->SetBounds(gfx::Size(25, 25)); blue->SetIsDrawable(true); @@ -971,26 +1021,27 @@ TEST_F(LayerTreeHostReadbackDeviceScalePixelTest, // Grab the middle of the root layer. copy_subrect_ = gfx::Rect(25, 25, 50, 50); device_scale_factor_ = 2.f; - - this->impl_side_painting_ = false; - RunPixelTest(SOFTWARE_WITH_DEFAULT, - background, - base::FilePath(FILE_PATH_LITERAL( - "green_small_with_blue_corner.png"))); + RunReadbackTest( + PIXEL_TEST_SOFTWARE, + READBACK_DEFAULT, + background, + base::FilePath(FILE_PATH_LITERAL("green_small_with_blue_corner.png"))); } -TEST_F(LayerTreeHostReadbackDeviceScalePixelTest, - ReadbackSubrect_GL) { - scoped_refptr<ContentLayer> background = ContentLayer::Create(&white_client_); +TEST_F(LayerTreeHostReadbackDeviceScalePixelTest, ReadbackSubrect_GL) { + scoped_refptr<FakePictureLayer> background = + FakePictureLayer::Create(&white_client_); background->SetBounds(gfx::Size(100, 100)); background->SetIsDrawable(true); - scoped_refptr<ContentLayer> green = ContentLayer::Create(&green_client_); + scoped_refptr<FakePictureLayer> green = + FakePictureLayer::Create(&green_client_); green->SetBounds(gfx::Size(100, 100)); green->SetIsDrawable(true); background->AddChild(green); - scoped_refptr<ContentLayer> blue = ContentLayer::Create(&blue_client_); + scoped_refptr<FakePictureLayer> blue = + FakePictureLayer::Create(&blue_client_); blue->SetPosition(gfx::Point(50, 50)); blue->SetBounds(gfx::Size(25, 25)); blue->SetIsDrawable(true); @@ -999,27 +1050,29 @@ TEST_F(LayerTreeHostReadbackDeviceScalePixelTest, // Grab the middle of the root layer. copy_subrect_ = gfx::Rect(25, 25, 50, 50); device_scale_factor_ = 2.f; - - this->impl_side_painting_ = false; - RunPixelTest(GL_WITH_DEFAULT, - background, - base::FilePath(FILE_PATH_LITERAL( - "green_small_with_blue_corner.png"))); + RunReadbackTest( + PIXEL_TEST_GL, + READBACK_DEFAULT, + background, + base::FilePath(FILE_PATH_LITERAL("green_small_with_blue_corner.png"))); } TEST_F(LayerTreeHostReadbackDeviceScalePixelTest, ReadbackNonRootLayerSubrect_Software) { - scoped_refptr<ContentLayer> background = ContentLayer::Create(&white_client_); + scoped_refptr<FakePictureLayer> background = + FakePictureLayer::Create(&white_client_); background->SetBounds(gfx::Size(100, 100)); background->SetIsDrawable(true); - scoped_refptr<ContentLayer> green = ContentLayer::Create(&green_client_); + scoped_refptr<FakePictureLayer> green = + FakePictureLayer::Create(&green_client_); green->SetPosition(gfx::Point(10, 20)); green->SetBounds(gfx::Size(90, 80)); green->SetIsDrawable(true); background->AddChild(green); - scoped_refptr<ContentLayer> blue = ContentLayer::Create(&blue_client_); + scoped_refptr<FakePictureLayer> blue = + FakePictureLayer::Create(&blue_client_); blue->SetPosition(gfx::Point(50, 50)); blue->SetBounds(gfx::Size(25, 25)); blue->SetIsDrawable(true); @@ -1028,28 +1081,30 @@ TEST_F(LayerTreeHostReadbackDeviceScalePixelTest, // Grab the green layer's content with blue in the bottom right. copy_subrect_ = gfx::Rect(25, 25, 50, 50); device_scale_factor_ = 2.f; - - this->impl_side_painting_ = false; - RunPixelTestWithReadbackTarget(SOFTWARE_WITH_DEFAULT, - background, - green.get(), - base::FilePath(FILE_PATH_LITERAL( - "green_small_with_blue_corner.png"))); + RunReadbackTestWithReadbackTarget( + PIXEL_TEST_SOFTWARE, + READBACK_DEFAULT, + background, + green.get(), + base::FilePath(FILE_PATH_LITERAL("green_small_with_blue_corner.png"))); } TEST_F(LayerTreeHostReadbackDeviceScalePixelTest, ReadbackNonRootLayerSubrect_GL) { - scoped_refptr<ContentLayer> background = ContentLayer::Create(&white_client_); + scoped_refptr<FakePictureLayer> background = + FakePictureLayer::Create(&white_client_); background->SetBounds(gfx::Size(100, 100)); background->SetIsDrawable(true); - scoped_refptr<ContentLayer> green = ContentLayer::Create(&green_client_); + scoped_refptr<FakePictureLayer> green = + FakePictureLayer::Create(&green_client_); green->SetPosition(gfx::Point(10, 20)); green->SetBounds(gfx::Size(90, 80)); green->SetIsDrawable(true); background->AddChild(green); - scoped_refptr<ContentLayer> blue = ContentLayer::Create(&blue_client_); + scoped_refptr<FakePictureLayer> blue = + FakePictureLayer::Create(&blue_client_); blue->SetPosition(gfx::Point(50, 50)); blue->SetBounds(gfx::Size(25, 25)); blue->SetIsDrawable(true); @@ -1058,35 +1113,35 @@ TEST_F(LayerTreeHostReadbackDeviceScalePixelTest, // Grab the green layer's content with blue in the bottom right. copy_subrect_ = gfx::Rect(25, 25, 50, 50); device_scale_factor_ = 2.f; - - this->impl_side_painting_ = false; - RunPixelTestWithReadbackTarget(GL_WITH_DEFAULT, - background, - green.get(), - base::FilePath(FILE_PATH_LITERAL( - "green_small_with_blue_corner.png"))); + RunReadbackTestWithReadbackTarget( + PIXEL_TEST_GL, + READBACK_DEFAULT, + background, + green.get(), + base::FilePath(FILE_PATH_LITERAL("green_small_with_blue_corner.png"))); } TEST_F(LayerTreeHostReadbackPixelTest, ReadbackNonRootLayerOutsideViewport) { - scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer( - gfx::Rect(200, 200), SK_ColorWHITE); + scoped_refptr<SolidColorLayer> background = + CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorWHITE); - scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer( - gfx::Rect(200, 200), SK_ColorGREEN); + scoped_refptr<SolidColorLayer> green = + CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorGREEN); // Only the top left quarter of the layer is inside the viewport, so the // blue layer is entirely outside. green->SetPosition(gfx::Point(100, 100)); background->AddChild(green); - scoped_refptr<SolidColorLayer> blue = CreateSolidColorLayer( - gfx::Rect(150, 150, 50, 50), SK_ColorBLUE); + scoped_refptr<SolidColorLayer> blue = + CreateSolidColorLayer(gfx::Rect(150, 150, 50, 50), SK_ColorBLUE); green->AddChild(blue); - RunPixelTestWithReadbackTarget(GL_WITH_DEFAULT, - background, - green.get(), - base::FilePath(FILE_PATH_LITERAL( - "green_with_blue_corner.png"))); + RunReadbackTestWithReadbackTarget( + PIXEL_TEST_GL, + READBACK_DEFAULT, + background, + green.get(), + base::FilePath(FILE_PATH_LITERAL("green_with_blue_corner.png"))); } } // namespace diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_synchronous.cc b/chromium/cc/trees/layer_tree_host_pixeltest_synchronous.cc new file mode 100644 index 00000000000..c22075f7682 --- /dev/null +++ b/chromium/cc/trees/layer_tree_host_pixeltest_synchronous.cc @@ -0,0 +1,50 @@ +// 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 "build/build_config.h" +#include "cc/layers/content_layer_client.h" +#include "cc/layers/picture_image_layer.h" +#include "cc/layers/picture_layer.h" +#include "cc/layers/solid_color_layer.h" +#include "cc/test/fake_content_layer_client.h" +#include "cc/test/layer_tree_pixel_test.h" +#include "cc/test/pixel_comparator.h" + +#if !defined(OS_ANDROID) + +namespace cc { +namespace { + +class LayerTreeHostSynchronousPixelTest : public LayerTreePixelTest { + public: + void InitializeSettings(LayerTreeSettings* settings) override { + LayerTreePixelTest::InitializeSettings(settings); + settings->single_thread_proxy_scheduler = false; + } + + void BeginTest() override { + LayerTreePixelTest::BeginTest(); + PostCompositeImmediatelyToMainThread(); + } +}; + +TEST_F(LayerTreeHostSynchronousPixelTest, OneContentLayer) { + gfx::Size bounds(200, 200); + + FakeContentLayerClient client; + SkPaint green_paint; + green_paint.setColor(SkColorSetARGB(255, 0, 255, 0)); + client.add_draw_rect(gfx::RectF(bounds), green_paint); + scoped_refptr<PictureLayer> root = PictureLayer::Create(&client); + root->SetBounds(bounds); + root->SetIsDrawable(true); + + RunSingleThreadedPixelTest( + PIXEL_TEST_GL, root, base::FilePath(FILE_PATH_LITERAL("green.png"))); +} + +} // namespace +} // namespace cc + +#endif // OS_ANDROID diff --git a/chromium/cc/trees/layer_tree_host_single_thread_client.h b/chromium/cc/trees/layer_tree_host_single_thread_client.h index cb6145048e6..dbca28cdf25 100644 --- a/chromium/cc/trees/layer_tree_host_single_thread_client.h +++ b/chromium/cc/trees/layer_tree_host_single_thread_client.h @@ -10,10 +10,10 @@ namespace cc { class LayerTreeHostSingleThreadClient { public: // Request that the client schedule a composite. - virtual void ScheduleComposite() = 0; + virtual void ScheduleComposite() {} // Request that the client schedule a composite now, and calculate appropriate // delay for potential future frame. - virtual void ScheduleAnimation() = 0; + virtual void ScheduleAnimation() {} // Called whenever the compositor posts a SwapBuffers (either full or // partial). After DidPostSwapBuffers(), exactly one of diff --git a/chromium/cc/trees/layer_tree_host_unittest.cc b/chromium/cc/trees/layer_tree_host_unittest.cc index 6b781cb60ef..aedd0d937a4 100644 --- a/chromium/cc/trees/layer_tree_host_unittest.cc +++ b/chromium/cc/trees/layer_tree_host_unittest.cc @@ -55,9 +55,9 @@ #include "third_party/khronos/GLES2/gl2ext.h" #include "third_party/skia/include/core/SkPicture.h" #include "ui/gfx/frame_time.h" -#include "ui/gfx/point_conversions.h" -#include "ui/gfx/size_conversions.h" -#include "ui/gfx/vector2d_conversions.h" +#include "ui/gfx/geometry/point_conversions.h" +#include "ui/gfx/geometry/size_conversions.h" +#include "ui/gfx/geometry/vector2d_conversions.h" using testing::_; using testing::AnyNumber; @@ -75,24 +75,24 @@ class LayerTreeHostTestSetNeedsCommit1 : public LayerTreeHostTest { public: LayerTreeHostTestSetNeedsCommit1() : num_commits_(0), num_draws_(0) {} - virtual void BeginTest() OVERRIDE { + void BeginTest() override { PostSetNeedsCommitToMainThread(); PostSetNeedsCommitToMainThread(); } - virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE { + void DrawLayersOnThread(LayerTreeHostImpl* impl) override { num_draws_++; if (!impl->active_tree()->source_frame_number()) EndTest(); } - virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE { + void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { num_commits_++; } - virtual void AfterTest() OVERRIDE { - EXPECT_GE(1, num_commits_); - EXPECT_GE(1, num_draws_); + void AfterTest() override { + EXPECT_LE(1, num_commits_); + EXPECT_LE(1, num_draws_); } private: @@ -108,13 +108,11 @@ class LayerTreeHostTestSetNeedsCommit2 : public LayerTreeHostTest { public: LayerTreeHostTestSetNeedsCommit2() : num_commits_(0), num_draws_(0) {} - virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } + void BeginTest() override { PostSetNeedsCommitToMainThread(); } - virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE { - ++num_draws_; - } + void DrawLayersOnThread(LayerTreeHostImpl* impl) override { ++num_draws_; } - virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE { + void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { ++num_commits_; switch (num_commits_) { case 1: @@ -128,7 +126,7 @@ class LayerTreeHostTestSetNeedsCommit2 : public LayerTreeHostTest { } } - virtual void AfterTest() OVERRIDE { + void AfterTest() override { EXPECT_EQ(2, num_commits_); EXPECT_LE(1, num_draws_); } @@ -143,7 +141,7 @@ MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsCommit2); // Verify that we pass property values in PushPropertiesTo. class LayerTreeHostTestPushPropertiesTo : public LayerTreeHostTest { protected: - virtual void SetupTree() OVERRIDE { + void SetupTree() override { scoped_refptr<Layer> root = Layer::Create(); root->SetBounds(gfx::Size(10, 10)); layer_tree_host()->SetRootLayer(root); @@ -158,16 +156,16 @@ class LayerTreeHostTestPushPropertiesTo : public LayerTreeHostTest { DONE, }; - virtual void BeginTest() OVERRIDE { + void BeginTest() override { index_ = STARTUP; PostSetNeedsCommitToMainThread(); } - virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE { + void DrawLayersOnThread(LayerTreeHostImpl* impl) override { VerifyAfterValues(impl->active_tree()->root_layer()); } - virtual void DidCommitAndDrawFrame() OVERRIDE { + void DidCommitAndDrawFrame() override { SetBeforeValues(layer_tree_host()->root_layer()); VerifyBeforeValues(layer_tree_host()->root_layer()); @@ -180,7 +178,7 @@ class LayerTreeHostTestPushPropertiesTo : public LayerTreeHostTest { SetAfterValues(layer_tree_host()->root_layer()); } - virtual void AfterTest() OVERRIDE {} + void AfterTest() override {} void VerifyBeforeValues(Layer* layer) { EXPECT_EQ(gfx::Size(10, 10).ToString(), layer->bounds().ToString()); @@ -239,9 +237,9 @@ class LayerTreeHostTestSetNeedsRedraw : public LayerTreeHostTest { public: LayerTreeHostTestSetNeedsRedraw() : num_commits_(0), num_draws_(0) {} - virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } + void BeginTest() override { PostSetNeedsCommitToMainThread(); } - virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE { + void DrawLayersOnThread(LayerTreeHostImpl* impl) override { EXPECT_EQ(0, impl->active_tree()->source_frame_number()); if (!num_draws_) { // Redraw again to verify that the second redraw doesn't commit. @@ -252,12 +250,12 @@ class LayerTreeHostTestSetNeedsRedraw : public LayerTreeHostTest { num_draws_++; } - virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE { + void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { EXPECT_EQ(0, num_draws_); num_commits_++; } - virtual void AfterTest() OVERRIDE { + void AfterTest() override { EXPECT_GE(2, num_draws_); EXPECT_EQ(1, num_commits_); } @@ -279,7 +277,7 @@ class LayerTreeHostTestSetNeedsRedrawRect : public LayerTreeHostTest { invalid_rect_(10, 10, 20, 20), root_layer_(ContentLayer::Create(&client_)) {} - virtual void BeginTest() OVERRIDE { + void BeginTest() override { root_layer_->SetIsDrawable(true); root_layer_->SetBounds(bounds_); layer_tree_host()->SetRootLayer(root_layer_); @@ -287,10 +285,9 @@ class LayerTreeHostTestSetNeedsRedrawRect : public LayerTreeHostTest { PostSetNeedsCommitToMainThread(); } - virtual DrawResult PrepareToDrawOnThread( - LayerTreeHostImpl* host_impl, - LayerTreeHostImpl::FrameData* frame_data, - DrawResult draw_result) OVERRIDE { + DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, + LayerTreeHostImpl::FrameData* frame_data, + DrawResult draw_result) override { EXPECT_EQ(DRAW_SUCCESS, draw_result); gfx::RectF root_damage_rect; @@ -308,7 +305,7 @@ class LayerTreeHostTestSetNeedsRedrawRect : public LayerTreeHostTest { return draw_result; } - virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE { + void DrawLayersOnThread(LayerTreeHostImpl* impl) override { if (!num_draws_) { PostSetNeedsRedrawRectToMainThread(invalid_rect_); } else { @@ -317,7 +314,7 @@ class LayerTreeHostTestSetNeedsRedrawRect : public LayerTreeHostTest { num_draws_++; } - virtual void AfterTest() OVERRIDE { EXPECT_EQ(2, num_draws_); } + void AfterTest() override { EXPECT_EQ(2, num_draws_); } private: int num_draws_; @@ -331,11 +328,11 @@ SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsRedrawRect); class LayerTreeHostTestNoExtraCommitFromInvalidate : public LayerTreeHostTest { public: - virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE { + void InitializeSettings(LayerTreeSettings* settings) override { settings->layer_transforms_should_scale_layer_contents = true; } - virtual void SetupTree() OVERRIDE { + void SetupTree() override { root_layer_ = Layer::Create(); root_layer_->SetBounds(gfx::Size(10, 20)); @@ -347,14 +344,14 @@ class LayerTreeHostTestNoExtraCommitFromInvalidate : public LayerTreeHostTest { LayerTreeHostTest::SetupTree(); } - virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } + void BeginTest() override { PostSetNeedsCommitToMainThread(); } - virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { + void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { if (host_impl->active_tree()->source_frame_number() == 1) EndTest(); } - virtual void DidCommit() OVERRIDE { + void DidCommit() override { switch (layer_tree_host()->source_frame_number()) { case 1: // Changing the device scale factor causes a commit. It also changes @@ -368,7 +365,7 @@ class LayerTreeHostTestNoExtraCommitFromInvalidate : public LayerTreeHostTest { } } - virtual void AfterTest() OVERRIDE { + void AfterTest() override { EXPECT_EQ(gfx::Size(4, 4).ToString(), scaled_layer_->content_bounds().ToString()); } @@ -384,11 +381,11 @@ SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestNoExtraCommitFromInvalidate); class LayerTreeHostTestNoExtraCommitFromScrollbarInvalidate : public LayerTreeHostTest { public: - virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE { + void InitializeSettings(LayerTreeSettings* settings) override { settings->layer_transforms_should_scale_layer_contents = true; } - virtual void SetupTree() OVERRIDE { + void SetupTree() override { root_layer_ = Layer::Create(); root_layer_->SetBounds(gfx::Size(10, 20)); @@ -405,14 +402,14 @@ class LayerTreeHostTestNoExtraCommitFromScrollbarInvalidate LayerTreeHostTest::SetupTree(); } - virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } + void BeginTest() override { PostSetNeedsCommitToMainThread(); } - virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { + void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { if (host_impl->active_tree()->source_frame_number() == 1) EndTest(); } - virtual void DidCommit() OVERRIDE { + void DidCommit() override { switch (layer_tree_host()->source_frame_number()) { case 1: // Changing the device scale factor causes a commit. It also changes @@ -426,7 +423,7 @@ class LayerTreeHostTestNoExtraCommitFromScrollbarInvalidate } } - virtual void AfterTest() OVERRIDE { + void AfterTest() override { EXPECT_EQ(gfx::Size(40, 40).ToString(), scrollbar_->content_bounds().ToString()); } @@ -448,7 +445,7 @@ class LayerTreeHostTestSetNextCommitForcesRedraw : public LayerTreeHostTest { invalid_rect_(10, 10, 20, 20), root_layer_(ContentLayer::Create(&client_)) {} - virtual void BeginTest() OVERRIDE { + void BeginTest() override { root_layer_->SetIsDrawable(true); root_layer_->SetBounds(bounds_); layer_tree_host()->SetRootLayer(root_layer_); @@ -456,15 +453,14 @@ class LayerTreeHostTestSetNextCommitForcesRedraw : public LayerTreeHostTest { PostSetNeedsCommitToMainThread(); } - virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { + void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { if (num_draws_ == 3 && host_impl->settings().impl_side_painting) host_impl->SetNeedsRedrawRect(invalid_rect_); } - virtual DrawResult PrepareToDrawOnThread( - LayerTreeHostImpl* host_impl, - LayerTreeHostImpl::FrameData* frame_data, - DrawResult draw_result) OVERRIDE { + DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, + LayerTreeHostImpl::FrameData* frame_data, + DrawResult draw_result) override { EXPECT_EQ(DRAW_SUCCESS, draw_result); gfx::RectF root_damage_rect; @@ -492,7 +488,7 @@ class LayerTreeHostTestSetNextCommitForcesRedraw : public LayerTreeHostTest { return draw_result; } - virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { + void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { switch (num_draws_) { case 0: case 1: @@ -519,7 +515,7 @@ class LayerTreeHostTestSetNextCommitForcesRedraw : public LayerTreeHostTest { num_draws_++; } - virtual void AfterTest() OVERRIDE { EXPECT_EQ(5, num_draws_); } + void AfterTest() override { EXPECT_EQ(5, num_draws_); } private: int num_draws_; @@ -529,7 +525,8 @@ class LayerTreeHostTestSetNextCommitForcesRedraw : public LayerTreeHostTest { scoped_refptr<ContentLayer> root_layer_; }; -SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSetNextCommitForcesRedraw); +SINGLE_AND_MULTI_THREAD_BLOCKNOTIFY_TEST_F( + LayerTreeHostTestSetNextCommitForcesRedraw); // Tests that if a layer is not drawn because of some reason in the parent then // its damage is preserved until the next time it is drawn. @@ -538,7 +535,7 @@ class LayerTreeHostTestUndrawnLayersDamageLater : public LayerTreeHostTest { LayerTreeHostTestUndrawnLayersDamageLater() : root_layer_(ContentLayer::Create(&client_)) {} - virtual void SetupTree() OVERRIDE { + void SetupTree() override { root_layer_->SetIsDrawable(true); root_layer_->SetBounds(gfx::Size(50, 50)); layer_tree_host()->SetRootLayer(root_layer_); @@ -557,12 +554,11 @@ class LayerTreeHostTestUndrawnLayersDamageLater : public LayerTreeHostTest { LayerTreeHostTest::SetupTree(); } - virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } + void BeginTest() override { PostSetNeedsCommitToMainThread(); } - virtual DrawResult PrepareToDrawOnThread( - LayerTreeHostImpl* host_impl, - LayerTreeHostImpl::FrameData* frame_data, - DrawResult draw_result) OVERRIDE { + DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, + LayerTreeHostImpl::FrameData* frame_data, + DrawResult draw_result) override { EXPECT_EQ(DRAW_SUCCESS, draw_result); gfx::RectF root_damage_rect; @@ -590,7 +586,7 @@ class LayerTreeHostTestUndrawnLayersDamageLater : public LayerTreeHostTest { return draw_result; } - virtual void DidCommitAndDrawFrame() OVERRIDE { + void DidCommitAndDrawFrame() override { switch (layer_tree_host()->source_frame_number()) { case 1: // Test not owning the surface. @@ -612,7 +608,7 @@ class LayerTreeHostTestUndrawnLayersDamageLater : public LayerTreeHostTest { } } - virtual void AfterTest() OVERRIDE {} + void AfterTest() override {} private: FakeContentLayerClient client_; @@ -632,7 +628,7 @@ class LayerTreeHostTestUndrawnLayersPushContentBoundsLater LayerTreeHostTestUndrawnLayersPushContentBoundsLater() : root_layer_(Layer::Create()) {} - virtual void SetupTree() OVERRIDE { + void SetupTree() override { root_layer_->SetIsDrawable(true); root_layer_->SetBounds(gfx::Size(20, 20)); layer_tree_host()->SetRootLayer(root_layer_); @@ -649,9 +645,9 @@ class LayerTreeHostTestUndrawnLayersPushContentBoundsLater LayerTreeHostTest::SetupTree(); } - virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } + void BeginTest() override { PostSetNeedsCommitToMainThread(); } - virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { + void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { LayerImpl* root = host_impl->active_tree()->root_layer(); LayerImpl* parent = root->children()[0]; LayerImpl* child = parent->children()[0]; @@ -671,7 +667,7 @@ class LayerTreeHostTestUndrawnLayersPushContentBoundsLater } } - virtual void DidCommit() OVERRIDE { + void DidCommit() override { switch (layer_tree_host()->source_frame_number()) { case 1: parent_layer_->SetOpacity(1.0f); @@ -683,7 +679,7 @@ class LayerTreeHostTestUndrawnLayersPushContentBoundsLater } } - virtual void AfterTest() OVERRIDE {} + void AfterTest() override {} private: scoped_refptr<Layer> root_layer_; @@ -694,52 +690,27 @@ class LayerTreeHostTestUndrawnLayersPushContentBoundsLater SINGLE_AND_MULTI_THREAD_TEST_F( LayerTreeHostTestUndrawnLayersPushContentBoundsLater); -class LayerTreeHostTestAbortFrameWhenInvisible : public LayerTreeHostTest { - public: - LayerTreeHostTestAbortFrameWhenInvisible() {} - - virtual void BeginTest() OVERRIDE { - // Request a commit (from the main thread), Which will trigger the commit - // flow from the impl side. - layer_tree_host()->SetNeedsCommit(); - // Then mark ourselves as not visible before processing any more messages - // on the main thread. - layer_tree_host()->SetVisible(false); - // If we make it without kicking a frame, we pass! - EndTestAfterDelay(1); - } - - virtual void Layout() OVERRIDE { - ASSERT_FALSE(true); - EndTest(); - } - - virtual void AfterTest() OVERRIDE {} -}; - -MULTI_THREAD_TEST_F(LayerTreeHostTestAbortFrameWhenInvisible); - // This test verifies that properties on the layer tree host are commited // to the impl side. class LayerTreeHostTestCommit : public LayerTreeHostTest { public: LayerTreeHostTestCommit() {} - virtual void BeginTest() OVERRIDE { + void BeginTest() override { layer_tree_host()->SetViewportSize(gfx::Size(20, 20)); layer_tree_host()->set_background_color(SK_ColorGRAY); PostSetNeedsCommitToMainThread(); } - virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE { + void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override { EXPECT_EQ(gfx::Size(20, 20), impl->DrawViewportSize()); EXPECT_EQ(SK_ColorGRAY, impl->active_tree()->background_color()); EndTest(); } - virtual void AfterTest() OVERRIDE {} + void AfterTest() override {} }; MULTI_THREAD_TEST_F(LayerTreeHostTestCommit); @@ -753,36 +724,38 @@ class LayerTreeHostTestFrameTimeUpdatesAfterActivationFails LayerTreeHostTestFrameTimeUpdatesAfterActivationFails() : frame_count_with_pending_tree_(0) {} - virtual void BeginTest() OVERRIDE { + void BeginTest() override { layer_tree_host()->SetViewportSize(gfx::Size(20, 20)); layer_tree_host()->set_background_color(SK_ColorGRAY); PostSetNeedsCommitToMainThread(); } - virtual void BeginCommitOnThread(LayerTreeHostImpl* impl) OVERRIDE { + void BeginCommitOnThread(LayerTreeHostImpl* impl) override { EXPECT_EQ(frame_count_with_pending_tree_, 0); - impl->BlockNotifyReadyToActivateForTesting(true); + if (impl->settings().impl_side_painting) + impl->BlockNotifyReadyToActivateForTesting(true); } - virtual void WillBeginImplFrameOnThread(LayerTreeHostImpl* impl, - const BeginFrameArgs& args) OVERRIDE { + void WillBeginImplFrameOnThread(LayerTreeHostImpl* impl, + const BeginFrameArgs& args) override { if (impl->pending_tree()) frame_count_with_pending_tree_++; if (frame_count_with_pending_tree_ == 1) { EXPECT_EQ(first_frame_time_.ToInternalValue(), 0); - first_frame_time_ = impl->CurrentFrameTimeTicks(); - } else if (frame_count_with_pending_tree_ == 2) { + first_frame_time_ = impl->CurrentBeginFrameArgs().frame_time; + } else if (frame_count_with_pending_tree_ == 2 && + impl->settings().impl_side_painting) { impl->BlockNotifyReadyToActivateForTesting(false); } } - virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE { + void DrawLayersOnThread(LayerTreeHostImpl* impl) override { if (frame_count_with_pending_tree_ > 1) { EXPECT_NE(first_frame_time_.ToInternalValue(), 0); EXPECT_NE(first_frame_time_.ToInternalValue(), - impl->CurrentFrameTimeTicks().ToInternalValue()); + impl->CurrentBeginFrameArgs().frame_time.ToInternalValue()); EndTest(); return; } @@ -790,19 +763,19 @@ class LayerTreeHostTestFrameTimeUpdatesAfterActivationFails EXPECT_FALSE(impl->settings().impl_side_painting); EndTest(); } - virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE { + void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override { if (impl->settings().impl_side_painting) EXPECT_NE(frame_count_with_pending_tree_, 1); } - virtual void AfterTest() OVERRIDE {} + void AfterTest() override {} private: int frame_count_with_pending_tree_; base::TimeTicks first_frame_time_; }; -SINGLE_AND_MULTI_THREAD_TEST_F( +SINGLE_AND_MULTI_THREAD_BLOCKNOTIFY_TEST_F( LayerTreeHostTestFrameTimeUpdatesAfterActivationFails); // This test verifies that LayerTreeHostImpl's current frame time gets @@ -811,17 +784,17 @@ class LayerTreeHostTestFrameTimeUpdatesAfterDraw : public LayerTreeHostTest { public: LayerTreeHostTestFrameTimeUpdatesAfterDraw() : frame_(0) {} - virtual void BeginTest() OVERRIDE { + void BeginTest() override { layer_tree_host()->SetViewportSize(gfx::Size(20, 20)); layer_tree_host()->set_background_color(SK_ColorGRAY); PostSetNeedsCommitToMainThread(); } - virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE { + void DrawLayersOnThread(LayerTreeHostImpl* impl) override { frame_++; if (frame_ == 1) { - first_frame_time_ = impl->CurrentFrameTimeTicks(); + first_frame_time_ = impl->CurrentBeginFrameArgs().frame_time; impl->SetNeedsRedraw(); // Since we might use a low-resolution clock on Windows, we need to @@ -832,11 +805,11 @@ class LayerTreeHostTestFrameTimeUpdatesAfterDraw : public LayerTreeHostTest { return; } - EXPECT_NE(first_frame_time_, impl->CurrentFrameTimeTicks()); + EXPECT_NE(first_frame_time_, impl->CurrentBeginFrameArgs().frame_time); EndTest(); } - virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { + void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { // Ensure there isn't a commit between the two draws, to ensure that a // commit isn't required for updating the current frame time. We can // only check for this in the multi-threaded case, since in the single- @@ -845,7 +818,7 @@ class LayerTreeHostTestFrameTimeUpdatesAfterDraw : public LayerTreeHostTest { EXPECT_EQ(0, frame_); } - virtual void AfterTest() OVERRIDE {} + void AfterTest() override {} private: int frame_; @@ -860,7 +833,7 @@ class LayerTreeHostTestStartPageScaleAnimation : public LayerTreeHostTest { public: LayerTreeHostTestStartPageScaleAnimation() {} - virtual void SetupTree() OVERRIDE { + void SetupTree() override { LayerTreeHostTest::SetupTree(); if (layer_tree_host()->settings().impl_side_painting) { @@ -877,7 +850,7 @@ class LayerTreeHostTestStartPageScaleAnimation : public LayerTreeHostTest { scroll_layer_->SetIsContainerForFixedPositionLayers(true); scroll_layer_->SetBounds(gfx::Size(2 * root_layer->bounds().width(), 2 * root_layer->bounds().height())); - scroll_layer_->SetScrollOffset(gfx::Vector2d()); + scroll_layer_->SetScrollOffset(gfx::ScrollOffset()); layer_tree_host()->root_layer()->AddChild(scroll_layer_); // This test requires the page_scale and inner viewport layers to be // identified. @@ -886,16 +859,18 @@ class LayerTreeHostTestStartPageScaleAnimation : public LayerTreeHostTest { layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.5f, 2.f); } - virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } + void BeginTest() override { PostSetNeedsCommitToMainThread(); } - virtual void ApplyScrollAndScale(const gfx::Vector2d& scroll_delta, - float scale) OVERRIDE { - gfx::Vector2d offset = scroll_layer_->scroll_offset(); - scroll_layer_->SetScrollOffset(offset + scroll_delta); + void ApplyViewportDeltas(const gfx::Vector2d& scroll_delta, + float scale, + float) override { + gfx::ScrollOffset offset = scroll_layer_->scroll_offset(); + scroll_layer_->SetScrollOffset(ScrollOffsetWithDelta(offset, + scroll_delta)); layer_tree_host()->SetPageScaleFactorAndLimits(scale, 0.5f, 2.f); } - virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE { + void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override { // We get one commit before the first draw, and the animation doesn't happen // until the second draw. switch (impl->active_tree()->source_frame_number()) { @@ -915,7 +890,7 @@ class LayerTreeHostTestStartPageScaleAnimation : public LayerTreeHostTest { } } - virtual void DidCommitAndDrawFrame() OVERRIDE { + void DidCommitAndDrawFrame() override { switch (layer_tree_host()->source_frame_number()) { case 1: layer_tree_host()->StartPageScaleAnimation( @@ -924,7 +899,7 @@ class LayerTreeHostTestStartPageScaleAnimation : public LayerTreeHostTest { } } - virtual void AfterTest() OVERRIDE {} + void AfterTest() override {} FakeContentLayerClient client_; scoped_refptr<Layer> scroll_layer_; @@ -936,7 +911,7 @@ class LayerTreeHostTestSetVisible : public LayerTreeHostTest { public: LayerTreeHostTestSetVisible() : num_draws_(0) {} - virtual void BeginTest() OVERRIDE { + void BeginTest() override { PostSetNeedsCommitToMainThread(); PostSetVisibleToMainThread(false); // This is suppressed while we're invisible. @@ -945,13 +920,13 @@ class LayerTreeHostTestSetVisible : public LayerTreeHostTest { PostSetVisibleToMainThread(true); } - virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE { + void DrawLayersOnThread(LayerTreeHostImpl* impl) override { EXPECT_TRUE(impl->visible()); ++num_draws_; EndTest(); } - virtual void AfterTest() OVERRIDE { EXPECT_EQ(1, num_draws_); } + void AfterTest() override { EXPECT_EQ(1, num_draws_); } private: int num_draws_; @@ -965,17 +940,16 @@ class TestOpacityChangeLayerDelegate : public ContentLayerClient { void SetTestLayer(Layer* test_layer) { test_layer_ = test_layer; } - virtual void PaintContents( + void PaintContents( SkCanvas* canvas, const gfx::Rect& clip, - gfx::RectF* opaque, - ContentLayerClient::GraphicsContextStatus gc_status) OVERRIDE { + ContentLayerClient::GraphicsContextStatus gc_status) override { // Set layer opacity to 0. if (test_layer_) test_layer_->SetOpacity(0.f); } - virtual void DidChangeLayerCanUseLCDText() OVERRIDE {} - virtual bool FillsBoundsCompletely() const OVERRIDE { return false; } + void DidChangeLayerCanUseLCDText() override {} + bool FillsBoundsCompletely() const override { return false; } private: Layer* test_layer_; @@ -991,8 +965,8 @@ class ContentLayerWithUpdateTracking : public ContentLayer { int PaintContentsCount() { return paint_contents_count_; } void ResetPaintContentsCount() { paint_contents_count_ = 0; } - virtual bool Update(ResourceUpdateQueue* queue, - const OcclusionTracker<Layer>* occlusion) OVERRIDE { + bool Update(ResourceUpdateQueue* queue, + const OcclusionTracker<Layer>* occlusion) override { bool updated = ContentLayer::Update(queue, occlusion); paint_contents_count_++; return updated; @@ -1004,7 +978,7 @@ class ContentLayerWithUpdateTracking : public ContentLayer { SetBounds(gfx::Size(10, 10)); SetIsDrawable(true); } - virtual ~ContentLayerWithUpdateTracking() {} + ~ContentLayerWithUpdateTracking() override {} int paint_contents_count_; }; @@ -1020,18 +994,16 @@ class LayerTreeHostTestOpacityChange : public LayerTreeHostTest { test_opacity_change_delegate_.SetTestLayer(update_check_layer_.get()); } - virtual void BeginTest() OVERRIDE { + void BeginTest() override { layer_tree_host()->SetViewportSize(gfx::Size(10, 10)); layer_tree_host()->root_layer()->AddChild(update_check_layer_); PostSetNeedsCommitToMainThread(); } - virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE { - EndTest(); - } + void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { EndTest(); } - virtual void AfterTest() OVERRIDE { + void AfterTest() override { // Update() should have been called once. EXPECT_EQ(1, update_check_layer_->PaintContentsCount()); } @@ -1049,20 +1021,12 @@ class NoScaleContentLayer : public ContentLayer { return make_scoped_refptr(new NoScaleContentLayer(client)); } - virtual void CalculateContentsScale(float ideal_contents_scale, - float device_scale_factor, - float page_scale_factor, - float maximum_animation_contents_scale, - bool animating_transform_to_screen, - float* contents_scale_x, - float* contents_scale_y, - gfx::Size* contentBounds) OVERRIDE { + void CalculateContentsScale(float ideal_contents_scale, + float* contents_scale_x, + float* contents_scale_y, + gfx::Size* contentBounds) override { // Skip over the ContentLayer's method to the base Layer class. Layer::CalculateContentsScale(ideal_contents_scale, - device_scale_factor, - page_scale_factor, - maximum_animation_contents_scale, - animating_transform_to_screen, contents_scale_x, contents_scale_y, contentBounds); @@ -1071,7 +1035,7 @@ class NoScaleContentLayer : public ContentLayer { private: explicit NoScaleContentLayer(ContentLayerClient* client) : ContentLayer(client) {} - virtual ~NoScaleContentLayer() {} + ~NoScaleContentLayer() override {} }; class LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers @@ -1081,7 +1045,7 @@ class LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers : root_layer_(NoScaleContentLayer::Create(&client_)), child_layer_(ContentLayer::Create(&client_)) {} - virtual void BeginTest() OVERRIDE { + void BeginTest() override { layer_tree_host()->SetViewportSize(gfx::Size(60, 60)); layer_tree_host()->SetDeviceScaleFactor(1.5); EXPECT_EQ(gfx::Size(60, 60), layer_tree_host()->device_viewport_size()); @@ -1100,7 +1064,7 @@ class LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers PostSetNeedsCommitToMainThread(); } - virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE { + void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override { // Should only do one commit. EXPECT_EQ(0, impl->active_tree()->source_frame_number()); // Device scale factor should come over to impl. @@ -1166,7 +1130,7 @@ class LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers EndTest(); } - virtual void AfterTest() OVERRIDE {} + void AfterTest() override {} private: FakeContentLayerClient client_; @@ -1179,7 +1143,7 @@ MULTI_THREAD_TEST_F(LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers); // Verify atomicity of commits and reuse of textures. class LayerTreeHostTestDirectRendererAtomicCommit : public LayerTreeHostTest { public: - virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE { + void InitializeSettings(LayerTreeSettings* settings) override { settings->texture_id_allocation_chunk_size = 1; // Make sure partial texture updates are turned off. settings->max_partial_texture_updates = 0; @@ -1187,7 +1151,7 @@ class LayerTreeHostTestDirectRendererAtomicCommit : public LayerTreeHostTest { settings->scrollbar_animator = LayerTreeSettings::NoAnimator; } - virtual void SetupTree() OVERRIDE { + void SetupTree() override { layer_ = FakeContentLayer::Create(&client_); layer_->SetBounds(gfx::Size(10, 20)); @@ -1204,12 +1168,12 @@ class LayerTreeHostTestDirectRendererAtomicCommit : public LayerTreeHostTest { LayerTreeHostTest::SetupTree(); } - virtual void BeginTest() OVERRIDE { + void BeginTest() override { drew_frame_ = -1; PostSetNeedsCommitToMainThread(); } - virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE { + void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override { ASSERT_EQ(0u, layer_tree_host()->settings().max_partial_texture_updates); TestWebGraphicsContext3D* context = TestContext(); @@ -1250,7 +1214,7 @@ class LayerTreeHostTestDirectRendererAtomicCommit : public LayerTreeHostTest { } } - virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE { + void DrawLayersOnThread(LayerTreeHostImpl* impl) override { TestWebGraphicsContext3D* context = TestContext(); if (drew_frame_ == impl->active_tree()->source_frame_number()) { @@ -1267,12 +1231,12 @@ class LayerTreeHostTestDirectRendererAtomicCommit : public LayerTreeHostTest { PostSetNeedsCommitToMainThread(); } - virtual void Layout() OVERRIDE { + void Layout() override { layer_->SetNeedsDisplay(); scrollbar_->SetNeedsDisplay(); } - virtual void AfterTest() OVERRIDE {} + void AfterTest() override {} protected: FakeContentLayerClient client_; @@ -1287,7 +1251,7 @@ MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F( class LayerTreeHostTestDelegatingRendererAtomicCommit : public LayerTreeHostTestDirectRendererAtomicCommit { public: - virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE { + void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override { ASSERT_EQ(0u, layer_tree_host()->settings().max_partial_texture_updates); TestWebGraphicsContext3D* context = TestContext(); @@ -1354,7 +1318,7 @@ static void SetLayerPropertiesForTesting(Layer* layer, class LayerTreeHostTestAtomicCommitWithPartialUpdate : public LayerTreeHostTest { public: - virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE { + void InitializeSettings(LayerTreeSettings* settings) override { settings->texture_id_allocation_chunk_size = 1; // Allow one partial texture update. settings->max_partial_texture_updates = 1; @@ -1362,7 +1326,7 @@ class LayerTreeHostTestAtomicCommitWithPartialUpdate settings->impl_side_painting = false; } - virtual void SetupTree() OVERRIDE { + void SetupTree() override { parent_ = FakeContentLayer::Create(&client_); parent_->SetBounds(gfx::Size(10, 20)); @@ -1376,9 +1340,9 @@ class LayerTreeHostTestAtomicCommitWithPartialUpdate LayerTreeHostTest::SetupTree(); } - virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } + void BeginTest() override { PostSetNeedsCommitToMainThread(); } - virtual void DidCommitAndDrawFrame() OVERRIDE { + void DidCommitAndDrawFrame() override { switch (layer_tree_host()->source_frame_number()) { case 1: parent_->SetNeedsDisplay(); @@ -1386,8 +1350,8 @@ class LayerTreeHostTestAtomicCommitWithPartialUpdate break; case 2: // Damage part of layers. - parent_->SetNeedsDisplayRect(gfx::RectF(0.f, 0.f, 5.f, 5.f)); - child_->SetNeedsDisplayRect(gfx::RectF(0.f, 0.f, 5.f, 5.f)); + parent_->SetNeedsDisplayRect(gfx::Rect(5, 5)); + child_->SetNeedsDisplayRect(gfx::Rect(5, 5)); break; case 3: child_->SetNeedsDisplay(); @@ -1405,7 +1369,7 @@ class LayerTreeHostTestAtomicCommitWithPartialUpdate } } - virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE { + void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { ASSERT_EQ(1u, layer_tree_host()->settings().max_partial_texture_updates); TestWebGraphicsContext3D* context = TestContext(); @@ -1495,7 +1459,7 @@ class LayerTreeHostTestAtomicCommitWithPartialUpdate } } - virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE { + void DrawLayersOnThread(LayerTreeHostImpl* impl) override { EXPECT_LT(impl->active_tree()->source_frame_number(), 5); TestWebGraphicsContext3D* context = TestContext(); @@ -1512,7 +1476,7 @@ class LayerTreeHostTestAtomicCommitWithPartialUpdate context->ResetUsedTextures(); } - virtual void AfterTest() OVERRIDE {} + void AfterTest() override {} private: FakeContentLayerClient client_; @@ -1527,7 +1491,7 @@ SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F( class LayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit : public LayerTreeHostTest { protected: - virtual void SetupTree() OVERRIDE { + void SetupTree() override { root_layer_ = FakeContentLayer::Create(&client_); root_layer_->SetBounds(gfx::Size(100, 100)); @@ -1553,21 +1517,21 @@ class LayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit LayerTreeHostTest::SetupTree(); } - virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } + void BeginTest() override { PostSetNeedsCommitToMainThread(); } - virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { + void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { Renderer* renderer = host_impl->renderer(); - RenderPass::Id surface1_render_pass_id = host_impl->active_tree() - ->root_layer() - ->children()[0] - ->render_surface() - ->RenderPassId(); - RenderPass::Id surface2_render_pass_id = host_impl->active_tree() - ->root_layer() - ->children()[0] - ->children()[0] - ->render_surface() - ->RenderPassId(); + RenderPassId surface1_render_pass_id = host_impl->active_tree() + ->root_layer() + ->children()[0] + ->render_surface() + ->GetRenderPassId(); + RenderPassId surface2_render_pass_id = host_impl->active_tree() + ->root_layer() + ->children()[0] + ->children()[0] + ->render_surface() + ->GetRenderPassId(); switch (host_impl->active_tree()->source_frame_number()) { case 0: @@ -1592,12 +1556,12 @@ class LayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit } } - virtual void DidCommitAndDrawFrame() OVERRIDE { + void DidCommitAndDrawFrame() override { if (layer_tree_host()->source_frame_number() < 2) root_layer_->SetNeedsDisplay(); } - virtual void AfterTest() OVERRIDE { + void AfterTest() override { EXPECT_LE(2u, root_layer_->update_count()); EXPECT_LE(2u, surface_layer1_->update_count()); EXPECT_LE(2u, surface_layer2_->update_count()); @@ -1621,14 +1585,12 @@ class EvictionTestLayer : public Layer { return make_scoped_refptr(new EvictionTestLayer()); } - virtual bool Update(ResourceUpdateQueue*, - const OcclusionTracker<Layer>*) OVERRIDE; - virtual bool DrawsContent() const OVERRIDE { return true; } + bool Update(ResourceUpdateQueue*, const OcclusionTracker<Layer>*) override; + bool DrawsContent() const override { return true; } - virtual scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) - OVERRIDE; - virtual void PushPropertiesTo(LayerImpl* impl) OVERRIDE; - virtual void SetTexturePriorities(const PriorityCalculator&) OVERRIDE; + scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override; + void PushPropertiesTo(LayerImpl* impl) override; + void SetTexturePriorities(const PriorityCalculator&) override; bool HaveBackingTexture() const { return texture_.get() ? texture_->have_backing_texture() : false; @@ -1636,7 +1598,7 @@ class EvictionTestLayer : public Layer { private: EvictionTestLayer() : Layer() {} - virtual ~EvictionTestLayer() {} + ~EvictionTestLayer() override {} void CreateTextureIfNeeded() { if (texture_) @@ -1657,10 +1619,11 @@ class EvictionTestLayerImpl : public LayerImpl { int id) { return make_scoped_ptr(new EvictionTestLayerImpl(tree_impl, id)); } - virtual ~EvictionTestLayerImpl() {} + ~EvictionTestLayerImpl() override {} - virtual void AppendQuads(QuadSink* quad_sink, - AppendQuadsData* append_quads_data) OVERRIDE { + void AppendQuads(RenderPass* render_pass, + const Occlusion& occlusion_in_content_space, + AppendQuadsData* append_quads_data) override { ASSERT_TRUE(has_texture_); ASSERT_NE(0u, layer_tree_impl()->resource_provider()->num_resources()); } @@ -1696,8 +1659,7 @@ bool EvictionTestLayer::Update(ResourceUpdateQueue* queue, scoped_ptr<LayerImpl> EvictionTestLayer::CreateLayerImpl( LayerTreeImpl* tree_impl) { - return EvictionTestLayerImpl::Create(tree_impl, layer_id_) - .PassAs<LayerImpl>(); + return EvictionTestLayerImpl::Create(tree_impl, layer_id_); } void EvictionTestLayer::PushPropertiesTo(LayerImpl* layer_impl) { @@ -1715,7 +1677,7 @@ class LayerTreeHostTestEvictTextures : public LayerTreeHostTest { impl_for_evict_textures_(0), num_commits_(0) {} - virtual void BeginTest() OVERRIDE { + void BeginTest() override { layer_tree_host()->SetRootLayer(layer_); layer_tree_host()->SetViewportSize(gfx::Size(10, 20)); @@ -1765,7 +1727,7 @@ class LayerTreeHostTestEvictTextures : public LayerTreeHostTest { // the beginFrame/commit pair. // Commits 5+6 test the path where an eviction happens during the eviction // recovery path. - virtual void DidCommit() OVERRIDE { + void DidCommit() override { switch (num_commits_) { case 1: EXPECT_TRUE(layer_->HaveBackingTexture()); @@ -1793,11 +1755,11 @@ class LayerTreeHostTestEvictTextures : public LayerTreeHostTest { } } - virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE { + void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { impl_for_evict_textures_ = impl; } - virtual void Layout() OVERRIDE { + void Layout() override { ++num_commits_; switch (num_commits_) { case 1: @@ -1826,7 +1788,7 @@ class LayerTreeHostTestEvictTextures : public LayerTreeHostTest { } } - virtual void AfterTest() OVERRIDE {} + void AfterTest() override {} private: FakeContentLayerClient client_; @@ -1837,53 +1799,12 @@ class LayerTreeHostTestEvictTextures : public LayerTreeHostTest { MULTI_THREAD_NOIMPL_TEST_F(LayerTreeHostTestEvictTextures); -class LayerTreeHostTestContinuousCommit : public LayerTreeHostTest { - public: - LayerTreeHostTestContinuousCommit() - : num_commit_complete_(0), num_draw_layers_(0) {} - - virtual void BeginTest() OVERRIDE { - layer_tree_host()->SetViewportSize(gfx::Size(10, 10)); - layer_tree_host()->root_layer()->SetBounds(gfx::Size(10, 10)); - - PostSetNeedsCommitToMainThread(); - } - - virtual void DidCommit() OVERRIDE { - if (num_draw_layers_ == 2) - return; - layer_tree_host()->SetNeedsCommit(); - } - - virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE { - if (num_draw_layers_ == 1) - num_commit_complete_++; - } - - virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE { - num_draw_layers_++; - if (num_draw_layers_ == 2) - EndTest(); - } - - virtual void AfterTest() OVERRIDE { - // Check that we didn't commit twice between first and second draw. - EXPECT_EQ(1, num_commit_complete_); - } - - private: - int num_commit_complete_; - int num_draw_layers_; -}; - -MULTI_THREAD_TEST_F(LayerTreeHostTestContinuousCommit); - class LayerTreeHostTestContinuousInvalidate : public LayerTreeHostTest { public: LayerTreeHostTestContinuousInvalidate() : num_commit_complete_(0), num_draw_layers_(0) {} - virtual void BeginTest() OVERRIDE { + void BeginTest() override { layer_tree_host()->SetViewportSize(gfx::Size(10, 10)); layer_tree_host()->root_layer()->SetBounds(gfx::Size(10, 10)); @@ -1896,24 +1817,24 @@ class LayerTreeHostTestContinuousInvalidate : public LayerTreeHostTest { PostSetNeedsCommitToMainThread(); } - virtual void DidCommitAndDrawFrame() OVERRIDE { + void DidCommitAndDrawFrame() override { if (num_draw_layers_ == 2) return; content_layer_->SetNeedsDisplay(); } - virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE { + void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { if (num_draw_layers_ == 1) num_commit_complete_++; } - virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE { + void DrawLayersOnThread(LayerTreeHostImpl* impl) override { num_draw_layers_++; if (num_draw_layers_ == 2) EndTest(); } - virtual void AfterTest() OVERRIDE { + void AfterTest() override { // Check that we didn't commit twice between first and second draw. EXPECT_EQ(1, num_commit_complete_); } @@ -1932,14 +1853,14 @@ class LayerTreeHostTestDeferCommits : public LayerTreeHostTest { LayerTreeHostTestDeferCommits() : num_commits_deferred_(0), num_complete_commits_(0) {} - virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } + void BeginTest() override { PostSetNeedsCommitToMainThread(); } - virtual void DidDeferCommit() OVERRIDE { + void DidDeferCommit() override { num_commits_deferred_++; layer_tree_host()->SetDeferCommits(false); } - virtual void DidCommit() OVERRIDE { + void DidCommit() override { num_complete_commits_++; switch (num_complete_commits_) { case 1: @@ -1956,7 +1877,7 @@ class LayerTreeHostTestDeferCommits : public LayerTreeHostTest { } } - virtual void AfterTest() OVERRIDE { + void AfterTest() override { EXPECT_EQ(1, num_commits_deferred_); EXPECT_EQ(2, num_complete_commits_); } @@ -1966,16 +1887,17 @@ class LayerTreeHostTestDeferCommits : public LayerTreeHostTest { int num_complete_commits_; }; -MULTI_THREAD_TEST_F(LayerTreeHostTestDeferCommits); +SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestDeferCommits); class LayerTreeHostWithProxy : public LayerTreeHost { public: LayerTreeHostWithProxy(FakeLayerTreeHostClient* client, const LayerTreeSettings& settings, scoped_ptr<FakeProxy> proxy) - : LayerTreeHost(client, NULL, settings) { + : LayerTreeHost(client, NULL, NULL, settings) { proxy->SetLayerTreeHost(this); - InitializeForTesting(proxy.PassAs<Proxy>()); + client->SetLayerTreeHost(this); + InitializeForTesting(proxy.Pass()); } }; @@ -2039,11 +1961,18 @@ TEST(LayerTreeHostTest, PartialUpdatesWithGLRenderer) { LayerTreeSettings settings; settings.max_partial_texture_updates = 4; + settings.single_thread_proxy_scheduler = false; scoped_ptr<SharedBitmapManager> shared_bitmap_manager( new TestSharedBitmapManager()); - scoped_ptr<LayerTreeHost> host = LayerTreeHost::CreateSingleThreaded( - &client, &client, shared_bitmap_manager.get(), settings); + scoped_ptr<LayerTreeHost> host = + LayerTreeHost::CreateSingleThreaded(&client, + &client, + shared_bitmap_manager.get(), + NULL, + settings, + base::MessageLoopProxy::current()); + client.SetLayerTreeHost(host.get()); host->Composite(base::TimeTicks::Now()); EXPECT_EQ(4u, host->settings().max_partial_texture_updates); @@ -2054,11 +1983,18 @@ TEST(LayerTreeHostTest, PartialUpdatesWithSoftwareRenderer) { LayerTreeSettings settings; settings.max_partial_texture_updates = 4; + settings.single_thread_proxy_scheduler = false; scoped_ptr<SharedBitmapManager> shared_bitmap_manager( new TestSharedBitmapManager()); - scoped_ptr<LayerTreeHost> host = LayerTreeHost::CreateSingleThreaded( - &client, &client, shared_bitmap_manager.get(), settings); + scoped_ptr<LayerTreeHost> host = + LayerTreeHost::CreateSingleThreaded(&client, + &client, + shared_bitmap_manager.get(), + NULL, + settings, + base::MessageLoopProxy::current()); + client.SetLayerTreeHost(host.get()); host->Composite(base::TimeTicks::Now()); EXPECT_EQ(4u, host->settings().max_partial_texture_updates); @@ -2069,11 +2005,18 @@ TEST(LayerTreeHostTest, PartialUpdatesWithDelegatingRendererAndGLContent) { LayerTreeSettings settings; settings.max_partial_texture_updates = 4; + settings.single_thread_proxy_scheduler = false; scoped_ptr<SharedBitmapManager> shared_bitmap_manager( new TestSharedBitmapManager()); - scoped_ptr<LayerTreeHost> host = LayerTreeHost::CreateSingleThreaded( - &client, &client, shared_bitmap_manager.get(), settings); + scoped_ptr<LayerTreeHost> host = + LayerTreeHost::CreateSingleThreaded(&client, + &client, + shared_bitmap_manager.get(), + NULL, + settings, + base::MessageLoopProxy::current()); + client.SetLayerTreeHost(host.get()); host->Composite(base::TimeTicks::Now()); EXPECT_EQ(0u, host->MaxPartialTextureUpdates()); @@ -2085,11 +2028,18 @@ TEST(LayerTreeHostTest, LayerTreeSettings settings; settings.max_partial_texture_updates = 4; + settings.single_thread_proxy_scheduler = false; scoped_ptr<SharedBitmapManager> shared_bitmap_manager( new TestSharedBitmapManager()); - scoped_ptr<LayerTreeHost> host = LayerTreeHost::CreateSingleThreaded( - &client, &client, shared_bitmap_manager.get(), settings); + scoped_ptr<LayerTreeHost> host = + LayerTreeHost::CreateSingleThreaded(&client, + &client, + shared_bitmap_manager.get(), + NULL, + settings, + base::MessageLoopProxy::current()); + client.SetLayerTreeHost(host.get()); host->Composite(base::TimeTicks::Now()); EXPECT_EQ(0u, host->MaxPartialTextureUpdates()); @@ -2104,7 +2054,7 @@ class LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted child_layer2_(FakeContentLayer::Create(&client_)), num_commits_(0) {} - virtual void BeginTest() OVERRIDE { + void BeginTest() override { layer_tree_host()->SetViewportSize(gfx::Size(100, 100)); root_layer_->SetBounds(gfx::Size(100, 100)); child_layer1_->SetBounds(gfx::Size(100, 100)); @@ -2115,8 +2065,8 @@ class LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted PostSetNeedsCommitToMainThread(); } - virtual void DidSetVisibleOnImplTree(LayerTreeHostImpl* host_impl, - bool visible) OVERRIDE { + void DidSetVisibleOnImplTree(LayerTreeHostImpl* host_impl, + bool visible) override { if (visible) { // One backing should remain unevicted. EXPECT_EQ( @@ -2134,7 +2084,7 @@ class LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted EndTest(); } - virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { + void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { ++num_commits_; switch (num_commits_) { case 1: @@ -2166,7 +2116,7 @@ class LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted } } - virtual void AfterTest() OVERRIDE {} + void AfterTest() override {} private: FakeContentLayerClient client_; @@ -2190,18 +2140,17 @@ class LayerTreeHostTestLCDNotification : public LayerTreeHostTest { int paint_count() const { return paint_count_; } int lcd_notification_count() const { return lcd_notification_count_; } - virtual void PaintContents( + void PaintContents( SkCanvas* canvas, const gfx::Rect& clip, - gfx::RectF* opaque, - ContentLayerClient::GraphicsContextStatus gc_status) OVERRIDE { + ContentLayerClient::GraphicsContextStatus gc_status) override { ++paint_count_; } - virtual void DidChangeLayerCanUseLCDText() OVERRIDE { + void DidChangeLayerCanUseLCDText() override { ++lcd_notification_count_; layer_->SetNeedsDisplay(); } - virtual bool FillsBoundsCompletely() const OVERRIDE { return false; } + bool FillsBoundsCompletely() const override { return false; } private: Layer* layer_; @@ -2209,7 +2158,7 @@ class LayerTreeHostTestLCDNotification : public LayerTreeHostTest { int lcd_notification_count_; }; - virtual void SetupTree() OVERRIDE { + void SetupTree() override { scoped_refptr<Layer> root_layer; if (layer_tree_host()->settings().impl_side_painting) root_layer = PictureLayer::Create(&client_); @@ -2229,10 +2178,10 @@ class LayerTreeHostTestLCDNotification : public LayerTreeHostTest { LayerTreeHostTest::SetupTree(); } - virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } - virtual void AfterTest() OVERRIDE {} + void BeginTest() override { PostSetNeedsCommitToMainThread(); } + void AfterTest() override {} - virtual void DidCommit() OVERRIDE { + void DidCommit() override { switch (layer_tree_host()->source_frame_number()) { case 1: // The first update consists of one LCD notification and one paint. @@ -2277,25 +2226,24 @@ SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestLCDNotification); // Verify that the BeginFrame notification is used to initiate rendering. class LayerTreeHostTestBeginFrameNotification : public LayerTreeHostTest { public: - virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE { + void InitializeSettings(LayerTreeSettings* settings) override { settings->begin_frame_scheduling_enabled = true; } - virtual void BeginTest() OVERRIDE { + void BeginTest() override { // This will trigger a SetNeedsBeginFrame which will trigger a // BeginFrame. PostSetNeedsCommitToMainThread(); } - virtual DrawResult PrepareToDrawOnThread( - LayerTreeHostImpl* host_impl, - LayerTreeHostImpl::FrameData* frame, - DrawResult draw_result) OVERRIDE { + DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, + LayerTreeHostImpl::FrameData* frame, + DrawResult draw_result) override { EndTest(); return DRAW_SUCCESS; } - virtual void AfterTest() OVERRIDE {} + void AfterTest() override {} private: base::TimeTicks frame_time_; @@ -2306,14 +2254,14 @@ MULTI_THREAD_TEST_F(LayerTreeHostTestBeginFrameNotification); class LayerTreeHostTestBeginFrameNotificationShutdownWhileEnabled : public LayerTreeHostTest { public: - virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE { + void InitializeSettings(LayerTreeSettings* settings) override { settings->begin_frame_scheduling_enabled = true; settings->using_synchronous_renderer_compositor = true; } - virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } + void BeginTest() override { PostSetNeedsCommitToMainThread(); } - virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { + void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { // The BeginFrame notification is turned off now but will get enabled // once we return. End test while it's enabled. ImplThreadTaskRunner()->PostTask( @@ -2322,7 +2270,7 @@ class LayerTreeHostTestBeginFrameNotificationShutdownWhileEnabled base::Unretained(this))); } - virtual void AfterTest() OVERRIDE {} + void AfterTest() override {} }; MULTI_THREAD_TEST_F( @@ -2333,13 +2281,13 @@ class LayerTreeHostTestAbortedCommitDoesntStall : public LayerTreeHostTest { LayerTreeHostTestAbortedCommitDoesntStall() : commit_count_(0), commit_abort_count_(0), commit_complete_count_(0) {} - virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE { + void InitializeSettings(LayerTreeSettings* settings) override { settings->begin_frame_scheduling_enabled = true; } - virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } + void BeginTest() override { PostSetNeedsCommitToMainThread(); } - virtual void DidCommit() OVERRIDE { + void DidCommit() override { commit_count_++; if (commit_count_ == 4) { // After two aborted commits, request a real commit now to make sure a @@ -2349,14 +2297,14 @@ class LayerTreeHostTestAbortedCommitDoesntStall : public LayerTreeHostTest { } } - virtual void BeginMainFrameAbortedOnThread(LayerTreeHostImpl* host_impl, - bool did_handle) OVERRIDE { + void BeginMainFrameAbortedOnThread(LayerTreeHostImpl* host_impl, + bool did_handle) override { commit_abort_count_++; // Initiate another abortable commit. host_impl->SetNeedsCommit(); } - virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { + void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { commit_complete_count_++; if (commit_complete_count_ == 1) { // Initiate an abortable commit after the first commit. @@ -2366,7 +2314,7 @@ class LayerTreeHostTestAbortedCommitDoesntStall : public LayerTreeHostTest { } } - virtual void AfterTest() OVERRIDE { + void AfterTest() override { EXPECT_EQ(commit_count_, 5); EXPECT_EQ(commit_abort_count_, 3); EXPECT_EQ(commit_complete_count_, 2); @@ -2379,7 +2327,7 @@ class LayerTreeHostTestAbortedCommitDoesntStall : public LayerTreeHostTest { class LayerTreeHostTestAbortedCommitDoesntStallSynchronousCompositor : public LayerTreeHostTestAbortedCommitDoesntStall { - virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE { + void InitializeSettings(LayerTreeSettings* settings) override { LayerTreeHostTestAbortedCommitDoesntStall::InitializeSettings(settings); settings->using_synchronous_renderer_compositor = true; } @@ -2390,7 +2338,7 @@ MULTI_THREAD_TEST_F( class LayerTreeHostTestAbortedCommitDoesntStallDisabledVsync : public LayerTreeHostTestAbortedCommitDoesntStall { - virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE { + void InitializeSettings(LayerTreeSettings* settings) override { LayerTreeHostTestAbortedCommitDoesntStall::InitializeSettings(settings); settings->throttle_frame_production = false; } @@ -2401,11 +2349,11 @@ MULTI_THREAD_TEST_F(LayerTreeHostTestAbortedCommitDoesntStallDisabledVsync); class LayerTreeHostTestUninvertibleTransformDoesNotBlockActivation : public LayerTreeHostTest { protected: - virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE { + void InitializeSettings(LayerTreeSettings* settings) override { settings->impl_side_painting = true; } - virtual void SetupTree() OVERRIDE { + void SetupTree() override { LayerTreeHostTest::SetupTree(); scoped_refptr<Layer> layer = PictureLayer::Create(&client_); @@ -2414,13 +2362,13 @@ class LayerTreeHostTestUninvertibleTransformDoesNotBlockActivation layer_tree_host()->root_layer()->AddChild(layer); } - virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } + void BeginTest() override { PostSetNeedsCommitToMainThread(); } - virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { + void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { EndTest(); } - virtual void AfterTest() OVERRIDE {} + void AfterTest() override {} FakeContentLayerClient client_; }; @@ -2437,17 +2385,16 @@ class LayerTreeHostTestChangeLayerPropertiesInPaintContents void set_layer(Layer* layer) { layer_ = layer; } - virtual void PaintContents( + void PaintContents( SkCanvas* canvas, const gfx::Rect& clip, - gfx::RectF* opaque, - ContentLayerClient::GraphicsContextStatus gc_status) OVERRIDE { + ContentLayerClient::GraphicsContextStatus gc_status) override { layer_->SetBounds(gfx::Size(2, 2)); } - virtual void DidChangeLayerCanUseLCDText() OVERRIDE {} + void DidChangeLayerCanUseLCDText() override {} - virtual bool FillsBoundsCompletely() const OVERRIDE { return false; } + bool FillsBoundsCompletely() const override { return false; } private: Layer* layer_; @@ -2455,21 +2402,27 @@ class LayerTreeHostTestChangeLayerPropertiesInPaintContents LayerTreeHostTestChangeLayerPropertiesInPaintContents() : num_commits_(0) {} - virtual void SetupTree() OVERRIDE { - scoped_refptr<ContentLayer> root_layer = ContentLayer::Create(&client_); + void SetupTree() override { + if (layer_tree_host()->settings().impl_side_painting) { + scoped_refptr<PictureLayer> root_layer = PictureLayer::Create(&client_); + layer_tree_host()->SetRootLayer(root_layer); + } else { + scoped_refptr<ContentLayer> root_layer = ContentLayer::Create(&client_); + layer_tree_host()->SetRootLayer(root_layer); + } + Layer* root_layer = layer_tree_host()->root_layer(); root_layer->SetIsDrawable(true); root_layer->SetBounds(gfx::Size(1, 1)); - layer_tree_host()->SetRootLayer(root_layer); - client_.set_layer(root_layer.get()); + client_.set_layer(root_layer); LayerTreeHostTest::SetupTree(); } - virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } - virtual void AfterTest() OVERRIDE {} + void BeginTest() override { PostSetNeedsCommitToMainThread(); } + void AfterTest() override {} - virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { + void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { num_commits_++; if (num_commits_ == 1) { LayerImpl* root_layer = host_impl->active_tree()->root_layer(); @@ -2486,7 +2439,8 @@ class LayerTreeHostTestChangeLayerPropertiesInPaintContents int num_commits_; }; -SINGLE_THREAD_TEST_F(LayerTreeHostTestChangeLayerPropertiesInPaintContents); +SINGLE_AND_MULTI_THREAD_TEST_F( + LayerTreeHostTestChangeLayerPropertiesInPaintContents); class MockIOSurfaceWebGraphicsContext3D : public TestWebGraphicsContext3D { public: @@ -2495,7 +2449,7 @@ class MockIOSurfaceWebGraphicsContext3D : public TestWebGraphicsContext3D { test_capabilities_.gpu.texture_rectangle = true; } - virtual GLuint createTexture() OVERRIDE { + virtual GLuint createTexture() override { return 1; } MOCK_METHOD1(activeTexture, void(GLenum texture)); @@ -2520,22 +2474,19 @@ class MockIOSurfaceWebGraphicsContext3D : public TestWebGraphicsContext3D { class LayerTreeHostTestIOSurfaceDrawing : public LayerTreeHostTest { protected: - virtual scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(bool fallback) - OVERRIDE { + scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface( + bool fallback) override { scoped_ptr<MockIOSurfaceWebGraphicsContext3D> mock_context_owned( new MockIOSurfaceWebGraphicsContext3D); mock_context_ = mock_context_owned.get(); - if (delegating_renderer()) { - return FakeOutputSurface::CreateDelegating3d( - mock_context_owned.PassAs<TestWebGraphicsContext3D>()); - } else { - return FakeOutputSurface::Create3d( - mock_context_owned.PassAs<TestWebGraphicsContext3D>()); - } + if (delegating_renderer()) + return FakeOutputSurface::CreateDelegating3d(mock_context_owned.Pass()); + else + return FakeOutputSurface::Create3d(mock_context_owned.Pass()); } - virtual void SetupTree() OVERRIDE { + void SetupTree() override { LayerTreeHostTest::SetupTree(); layer_tree_host()->root_layer()->SetIsDrawable(false); @@ -2551,9 +2502,9 @@ class LayerTreeHostTestIOSurfaceDrawing : public LayerTreeHostTest { layer_tree_host()->root_layer()->AddChild(io_surface_layer); } - virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } + void BeginTest() override { PostSetNeedsCommitToMainThread(); } - virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { + void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { EXPECT_EQ(0u, host_impl->resource_provider()->num_resources()); // In WillDraw, the IOSurfaceLayer sets up the io surface texture. @@ -2591,16 +2542,15 @@ class LayerTreeHostTestIOSurfaceDrawing : public LayerTreeHostTest { EXPECT_CALL(*mock_context_, bindTexture(_, 0)).Times(AnyNumber()); } - virtual DrawResult PrepareToDrawOnThread( - LayerTreeHostImpl* host_impl, - LayerTreeHostImpl::FrameData* frame, - DrawResult draw_result) OVERRIDE { + DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, + LayerTreeHostImpl::FrameData* frame, + DrawResult draw_result) override { Mock::VerifyAndClearExpectations(&mock_context_); ResourceProvider* resource_provider = host_impl->resource_provider(); EXPECT_EQ(1u, resource_provider->num_resources()); CHECK_EQ(1u, frame->render_passes.size()); CHECK_LE(1u, frame->render_passes[0]->quad_list.size()); - const DrawQuad* quad = frame->render_passes[0]->quad_list[0]; + const DrawQuad* quad = frame->render_passes[0]->quad_list.front(); CHECK_EQ(DrawQuad::IO_SURFACE_CONTENT, quad->material); const IOSurfaceDrawQuad* io_surface_draw_quad = IOSurfaceDrawQuad::MaterialCast(quad); @@ -2626,14 +2576,14 @@ class LayerTreeHostTestIOSurfaceDrawing : public LayerTreeHostTest { return draw_result; } - virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { + void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { Mock::VerifyAndClearExpectations(&mock_context_); EXPECT_CALL(*mock_context_, deleteTexture(1)).Times(AtLeast(1)); EndTest(); } - virtual void AfterTest() OVERRIDE {} + void AfterTest() override {} int io_surface_id_; MockIOSurfaceWebGraphicsContext3D* mock_context_; @@ -2644,7 +2594,7 @@ SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestIOSurfaceDrawing); class LayerTreeHostTestNumFramesPending : public LayerTreeHostTest { public: - virtual void BeginTest() OVERRIDE { + void BeginTest() override { frame_ = 0; PostSetNeedsCommitToMainThread(); } @@ -2653,7 +2603,7 @@ class LayerTreeHostTestNumFramesPending : public LayerTreeHostTest { // Round 2: commit only (no draw/swap) // Round 3: draw only (no commit) - virtual void DidCommit() OVERRIDE { + void DidCommit() override { int commit = layer_tree_host()->source_frame_number(); switch (commit) { case 2: @@ -2664,7 +2614,7 @@ class LayerTreeHostTestNumFramesPending : public LayerTreeHostTest { } } - virtual void DidCompleteSwapBuffers() OVERRIDE { + void DidCompleteSwapBuffers() override { int commit = layer_tree_host()->source_frame_number(); ++frame_; switch (frame_) { @@ -2681,7 +2631,7 @@ class LayerTreeHostTestNumFramesPending : public LayerTreeHostTest { } } - virtual void AfterTest() OVERRIDE {} + void AfterTest() override {} protected: int frame_; @@ -2698,12 +2648,12 @@ TEST_F(LayerTreeHostTestNumFramesPending, DISABLED_GLRenderer) { class LayerTreeHostTestDeferredInitialize : public LayerTreeHostTest { public: - virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE { + void InitializeSettings(LayerTreeSettings* settings) override { // PictureLayer can only be used with impl side painting enabled. settings->impl_side_painting = true; } - virtual void SetupTree() OVERRIDE { + void SetupTree() override { layer_ = FakePictureLayer::Create(&client_); // Force commits to not be aborted so new frames get drawn, otherwise // the renderer gets deferred initialized but nothing new needs drawing. @@ -2712,15 +2662,15 @@ class LayerTreeHostTestDeferredInitialize : public LayerTreeHostTest { LayerTreeHostTest::SetupTree(); } - virtual void BeginTest() OVERRIDE { + void BeginTest() override { did_initialize_gl_ = false; did_release_gl_ = false; last_source_frame_number_drawn_ = -1; // Never drawn. PostSetNeedsCommitToMainThread(); } - virtual scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(bool fallback) - OVERRIDE { + scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface( + bool fallback) override { scoped_ptr<TestWebGraphicsContext3D> context3d( TestWebGraphicsContext3D::Create()); @@ -2729,7 +2679,7 @@ class LayerTreeHostTestDeferredInitialize : public LayerTreeHostTest { delegating_renderer()); } - virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { + void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { ASSERT_TRUE(host_impl->RootLayer()); FakePictureLayerImpl* layer_impl = static_cast<FakePictureLayerImpl*>(host_impl->RootLayer()); @@ -2785,8 +2735,7 @@ class LayerTreeHostTestDeferredInitialize : public LayerTreeHostTest { did_release_gl_ = true; } - virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, - bool result) OVERRIDE { + void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override { ASSERT_TRUE(result); DelegatedFrameData* delegated_frame_data = output_surface()->last_sent_frame().delegated_frame_data.get(); @@ -2803,7 +2752,7 @@ class LayerTreeHostTestDeferredInitialize : public LayerTreeHostTest { host_impl->ReclaimResources(&ack); } - virtual void AfterTest() OVERRIDE { + void AfterTest() override { EXPECT_TRUE(did_initialize_gl_); EXPECT_TRUE(did_release_gl_); } @@ -2818,18 +2767,30 @@ class LayerTreeHostTestDeferredInitialize : public LayerTreeHostTest { MULTI_THREAD_TEST_F(LayerTreeHostTestDeferredInitialize); +class LayerTreeHostTestDeferredInitializeWithGpuRasterization + : public LayerTreeHostTestDeferredInitialize { + void InitializeSettings(LayerTreeSettings* settings) override { + // PictureLayer can only be used with impl side painting enabled. + settings->impl_side_painting = true; + settings->gpu_rasterization_enabled = true; + settings->gpu_rasterization_forced = true; + } +}; + +MULTI_THREAD_TEST_F(LayerTreeHostTestDeferredInitializeWithGpuRasterization); + // Test for UI Resource management. class LayerTreeHostTestUIResource : public LayerTreeHostTest { public: LayerTreeHostTestUIResource() : num_ui_resources_(0) {} - virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE { + void InitializeSettings(LayerTreeSettings* settings) override { settings->texture_id_allocation_chunk_size = 1; } - virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } + void BeginTest() override { PostSetNeedsCommitToMainThread(); } - virtual void DidCommit() OVERRIDE { + void DidCommit() override { int frame = layer_tree_host()->source_frame_number(); switch (frame) { case 1: @@ -2890,23 +2851,23 @@ class LayerTreeHostTestUIResource : public LayerTreeHostTest { } } - virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE { + void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { if (!layer_tree_host()->settings().impl_side_painting) PerformTest(impl); } - virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE { + void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override { if (layer_tree_host()->settings().impl_side_painting) PerformTest(impl); } - virtual void AfterTest() OVERRIDE {} + void AfterTest() override {} private: // Must clear all resources before exiting. void ClearResources() { for (int i = 0; i < num_ui_resources_; i++) - ui_resources_[i].reset(); + ui_resources_[i] = nullptr; } void CreateResource() { @@ -2927,9 +2888,9 @@ class PushPropertiesCountingLayerImpl : public LayerImpl { return make_scoped_ptr(new PushPropertiesCountingLayerImpl(tree_impl, id)); } - virtual ~PushPropertiesCountingLayerImpl() {} + ~PushPropertiesCountingLayerImpl() override {} - virtual void PushPropertiesTo(LayerImpl* layer) OVERRIDE { + void PushPropertiesTo(LayerImpl* layer) override { LayerImpl::PushPropertiesTo(layer); push_properties_count_++; // Push state to the active tree because we can only access it from there. @@ -2937,10 +2898,8 @@ class PushPropertiesCountingLayerImpl : public LayerImpl { layer)->push_properties_count_ = push_properties_count_; } - virtual scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) - OVERRIDE { - return PushPropertiesCountingLayerImpl::Create(tree_impl, id()). - PassAs<LayerImpl>(); + scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override { + return PushPropertiesCountingLayerImpl::Create(tree_impl, id()); } size_t push_properties_count() const { return push_properties_count_; } @@ -2962,19 +2921,19 @@ class PushPropertiesCountingLayer : public Layer { return new PushPropertiesCountingLayer(); } - virtual void PushPropertiesTo(LayerImpl* layer) OVERRIDE { + void PushPropertiesTo(LayerImpl* layer) override { Layer::PushPropertiesTo(layer); push_properties_count_++; if (persist_needs_push_properties_) needs_push_properties_ = true; } - virtual scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) - OVERRIDE { - return PushPropertiesCountingLayerImpl::Create(tree_impl, id()). - PassAs<LayerImpl>(); + scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override { + return PushPropertiesCountingLayerImpl::Create(tree_impl, id()); } + void SetDrawsContent(bool draws_content) { SetIsDrawable(draws_content); } + size_t push_properties_count() const { return push_properties_count_; } void reset_push_properties_count() { push_properties_count_ = 0; } @@ -2986,9 +2945,8 @@ class PushPropertiesCountingLayer : public Layer { PushPropertiesCountingLayer() : push_properties_count_(0), persist_needs_push_properties_(false) { SetBounds(gfx::Size(1, 1)); - SetIsDrawable(true); } - virtual ~PushPropertiesCountingLayer() {} + ~PushPropertiesCountingLayer() override {} size_t push_properties_count_; bool persist_needs_push_properties_; @@ -2996,7 +2954,7 @@ class PushPropertiesCountingLayer : public Layer { class LayerTreeHostTestLayersPushProperties : public LayerTreeHostTest { protected: - virtual void BeginTest() OVERRIDE { + void BeginTest() override { num_commits_ = 0; expected_push_properties_root_ = 0; expected_push_properties_child_ = 0; @@ -3007,7 +2965,7 @@ class LayerTreeHostTestLayersPushProperties : public LayerTreeHostTest { PostSetNeedsCommitToMainThread(); } - virtual void SetupTree() OVERRIDE { + void SetupTree() override { root_ = PushPropertiesCountingLayer::Create(); child_ = PushPropertiesCountingLayer::Create(); child2_ = PushPropertiesCountingLayer::Create(); @@ -3026,7 +2984,7 @@ class LayerTreeHostTestLayersPushProperties : public LayerTreeHostTest { LayerTreeHostTest::SetupTree(); } - virtual void DidCommitAndDrawFrame() OVERRIDE { + void DidCommitAndDrawFrame() override { ++num_commits_; EXPECT_EQ(expected_push_properties_root_, root_->push_properties_count()); @@ -3166,7 +3124,7 @@ class LayerTreeHostTestLayersPushProperties : public LayerTreeHostTest { ++expected_push_properties_leaf_layer_; } - virtual void AfterTest() OVERRIDE {} + void AfterTest() override {} int num_commits_; FakeContentLayerClient client_; @@ -3189,7 +3147,7 @@ MULTI_THREAD_TEST_F(LayerTreeHostTestLayersPushProperties); class LayerTreeHostTestImplLayersPushProperties : public LayerTreeHostTestLayersPushProperties { protected: - virtual void BeginTest() OVERRIDE { + void BeginTest() override { expected_push_properties_root_impl_ = 0; expected_push_properties_child_impl_ = 0; expected_push_properties_grandchild_impl_ = 0; @@ -3198,7 +3156,7 @@ class LayerTreeHostTestImplLayersPushProperties LayerTreeHostTestLayersPushProperties::BeginTest(); } - virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { + void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { // These commits are in response to the changes made in // LayerTreeHostTestLayersPushProperties::DidCommitAndDrawFrame() switch (num_commits_) { @@ -3389,9 +3347,9 @@ TEST_F(LayerTreeHostTestImplLayersPushProperties, DelegatingRenderer) { class LayerTreeHostTestPropertyChangesDuringUpdateArePushed : public LayerTreeHostTest { protected: - virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } + void BeginTest() override { PostSetNeedsCommitToMainThread(); } - virtual void SetupTree() OVERRIDE { + void SetupTree() override { root_ = Layer::Create(); root_->SetBounds(gfx::Size(1, 1)); @@ -3406,7 +3364,7 @@ class LayerTreeHostTestPropertyChangesDuringUpdateArePushed LayerTreeHostTest::SetupTree(); } - virtual void DidCommitAndDrawFrame() OVERRIDE { + void DidCommitAndDrawFrame() override { switch (layer_tree_host()->source_frame_number()) { case 0: break; @@ -3415,7 +3373,7 @@ class LayerTreeHostTestPropertyChangesDuringUpdateArePushed // avoid causing a second commit to be scheduled. If a property change // is made during this, however, it needs to be pushed in the upcoming // commit. - scoped_ptr<base::AutoReset<bool> > ignore = + scoped_ptr<base::AutoReset<bool>> ignore = scrollbar_layer_->IgnoreSetNeedsCommit(); scrollbar_layer_->SetBounds(gfx::Size(30, 30)); @@ -3435,7 +3393,7 @@ class LayerTreeHostTestPropertyChangesDuringUpdateArePushed } } - virtual void AfterTest() OVERRIDE {} + void AfterTest() override {} scoped_refptr<Layer> root_; scoped_refptr<FakePaintedScrollbarLayer> scrollbar_layer_; @@ -3443,10 +3401,63 @@ class LayerTreeHostTestPropertyChangesDuringUpdateArePushed MULTI_THREAD_TEST_F(LayerTreeHostTestPropertyChangesDuringUpdateArePushed); +class LayerTreeHostTestSetDrawableCausesCommit : public LayerTreeHostTest { + protected: + void BeginTest() override { PostSetNeedsCommitToMainThread(); } + + void SetupTree() override { + root_ = PushPropertiesCountingLayer::Create(); + child_ = PushPropertiesCountingLayer::Create(); + root_->AddChild(child_); + + layer_tree_host()->SetRootLayer(root_); + LayerTreeHostTest::SetupTree(); + } + + void DidCommitAndDrawFrame() override { + switch (layer_tree_host()->source_frame_number()) { + case 0: + break; + case 1: { + // During update, the ignore_set_needs_commit_ bit is set to true to + // avoid causing a second commit to be scheduled. If a property change + // is made during this, however, it needs to be pushed in the upcoming + // commit. + EXPECT_FALSE(root_->needs_push_properties()); + EXPECT_FALSE(child_->needs_push_properties()); + EXPECT_EQ(0, root_->NumDescendantsThatDrawContent()); + root_->reset_push_properties_count(); + child_->reset_push_properties_count(); + child_->SetDrawsContent(true); + EXPECT_EQ(1, root_->NumDescendantsThatDrawContent()); + EXPECT_EQ(0u, root_->push_properties_count()); + EXPECT_EQ(0u, child_->push_properties_count()); + EXPECT_TRUE(root_->needs_push_properties()); + EXPECT_TRUE(child_->needs_push_properties()); + break; + } + case 2: + EXPECT_EQ(1u, root_->push_properties_count()); + EXPECT_EQ(1u, child_->push_properties_count()); + EXPECT_FALSE(root_->needs_push_properties()); + EXPECT_FALSE(child_->needs_push_properties()); + EndTest(); + break; + } + } + + void AfterTest() override {} + + scoped_refptr<PushPropertiesCountingLayer> root_; + scoped_refptr<PushPropertiesCountingLayer> child_; +}; + +MULTI_THREAD_TEST_F(LayerTreeHostTestSetDrawableCausesCommit); + class LayerTreeHostTestCasePushPropertiesThreeGrandChildren : public LayerTreeHostTest { protected: - virtual void BeginTest() OVERRIDE { + void BeginTest() override { expected_push_properties_root_ = 0; expected_push_properties_child_ = 0; expected_push_properties_grandchild1_ = 0; @@ -3455,7 +3466,7 @@ class LayerTreeHostTestCasePushPropertiesThreeGrandChildren PostSetNeedsCommitToMainThread(); } - virtual void SetupTree() OVERRIDE { + void SetupTree() override { root_ = PushPropertiesCountingLayer::Create(); child_ = PushPropertiesCountingLayer::Create(); grandchild1_ = PushPropertiesCountingLayer::Create(); @@ -3471,7 +3482,7 @@ class LayerTreeHostTestCasePushPropertiesThreeGrandChildren LayerTreeHostTest::SetupTree(); } - virtual void AfterTest() OVERRIDE {} + void AfterTest() override {} FakeContentLayerClient client_; scoped_refptr<PushPropertiesCountingLayer> root_; @@ -3489,7 +3500,7 @@ class LayerTreeHostTestCasePushPropertiesThreeGrandChildren class LayerTreeHostTestPushPropertiesAddingToTreeRequiresPush : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren { protected: - virtual void DidCommitAndDrawFrame() OVERRIDE { + void DidCommitAndDrawFrame() override { int last_source_frame_number = layer_tree_host()->source_frame_number() - 1; switch (last_source_frame_number) { case 0: @@ -3529,7 +3540,7 @@ MULTI_THREAD_TEST_F(LayerTreeHostTestPushPropertiesAddingToTreeRequiresPush); class LayerTreeHostTestPushPropertiesRemovingChildStopsRecursion : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren { protected: - virtual void DidCommitAndDrawFrame() OVERRIDE { + void DidCommitAndDrawFrame() override { int last_source_frame_number = layer_tree_host()->source_frame_number() - 1; switch (last_source_frame_number) { case 0: @@ -3612,7 +3623,7 @@ MULTI_THREAD_TEST_F(LayerTreeHostTestPushPropertiesRemovingChildStopsRecursion); class LayerTreeHostTestPushPropertiesRemovingChildStopsRecursionWithPersistence : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren { protected: - virtual void DidCommitAndDrawFrame() OVERRIDE { + void DidCommitAndDrawFrame() override { int last_source_frame_number = layer_tree_host()->source_frame_number() - 1; switch (last_source_frame_number) { case 0: @@ -3660,7 +3671,7 @@ MULTI_THREAD_TEST_F( class LayerTreeHostTestPushPropertiesSetPropertiesWhileOutsideTree : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren { protected: - virtual void DidCommitAndDrawFrame() OVERRIDE { + void DidCommitAndDrawFrame() override { int last_source_frame_number = layer_tree_host()->source_frame_number() - 1; switch (last_source_frame_number) { case 0: @@ -3728,7 +3739,7 @@ MULTI_THREAD_TEST_F( class LayerTreeHostTestPushPropertiesSetPropertyInParentThenChild : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren { protected: - virtual void DidCommitAndDrawFrame() OVERRIDE { + void DidCommitAndDrawFrame() override { int last_source_frame_number = layer_tree_host()->source_frame_number() - 1; switch (last_source_frame_number) { case 0: @@ -3792,7 +3803,7 @@ MULTI_THREAD_TEST_F( class LayerTreeHostTestPushPropertiesSetPropertyInChildThenParent : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren { protected: - virtual void DidCommitAndDrawFrame() OVERRIDE { + void DidCommitAndDrawFrame() override { int last_source_frame_number = layer_tree_host()->source_frame_number() - 1; switch (last_source_frame_number) { case 0: @@ -3859,15 +3870,14 @@ class LayerTreeHostTestTreeActivationCallback : public LayerTreeHostTest { LayerTreeHostTestTreeActivationCallback() : num_commits_(0), callback_count_(0) {} - virtual void BeginTest() OVERRIDE { + void BeginTest() override { EXPECT_TRUE(HasImplThread()); PostSetNeedsCommitToMainThread(); } - virtual DrawResult PrepareToDrawOnThread( - LayerTreeHostImpl* host_impl, - LayerTreeHostImpl::FrameData* frame_data, - DrawResult draw_result) OVERRIDE { + DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, + LayerTreeHostImpl::FrameData* frame_data, + DrawResult draw_result) override { ++num_commits_; switch (num_commits_) { case 1: @@ -3896,7 +3906,7 @@ class LayerTreeHostTestTreeActivationCallback : public LayerTreeHostTest { host_impl, frame_data, draw_result); } - virtual void AfterTest() OVERRIDE { EXPECT_EQ(3, num_commits_); } + void AfterTest() override { EXPECT_EQ(3, num_commits_); } void SetCallback(bool enable) { output_surface()->SetTreeActivationCallback( @@ -3925,31 +3935,31 @@ class LayerInvalidateCausesDraw : public LayerTreeHostTest { public: LayerInvalidateCausesDraw() : num_commits_(0), num_draws_(0) {} - virtual void BeginTest() OVERRIDE { - ASSERT_TRUE(!!invalidate_layer_) + void BeginTest() override { + ASSERT_TRUE(!!invalidate_layer_.get()) << "Derived tests must set this in SetupTree"; // One initial commit. PostSetNeedsCommitToMainThread(); } - virtual void DidCommitAndDrawFrame() OVERRIDE { + void DidCommitAndDrawFrame() override { // After commit, invalidate the layer. This should cause a commit. if (layer_tree_host()->source_frame_number() == 1) invalidate_layer_->SetNeedsDisplay(); } - virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE { + void DrawLayersOnThread(LayerTreeHostImpl* impl) override { num_draws_++; if (impl->active_tree()->source_frame_number() == 1) EndTest(); } - virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE { + void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { num_commits_++; } - virtual void AfterTest() OVERRIDE { + void AfterTest() override { EXPECT_GE(2, num_commits_); EXPECT_GE(2, num_draws_); } @@ -3967,9 +3977,10 @@ class LayerInvalidateCausesDraw : public LayerTreeHostTest { // response to that invalidation. class LayerTreeHostTestVideoLayerInvalidate : public LayerInvalidateCausesDraw { public: - virtual void SetupTree() OVERRIDE { + void SetupTree() override { LayerTreeHostTest::SetupTree(); - scoped_refptr<VideoLayer> video_layer = VideoLayer::Create(&provider_); + scoped_refptr<VideoLayer> video_layer = + VideoLayer::Create(&provider_, media::VIDEO_ROTATION_0); video_layer->SetBounds(gfx::Size(10, 10)); video_layer->SetIsDrawable(true); layer_tree_host()->root_layer()->AddChild(video_layer); @@ -3989,7 +4000,7 @@ SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestVideoLayerInvalidate); class LayerTreeHostTestIOSurfaceLayerInvalidate : public LayerInvalidateCausesDraw { public: - virtual void SetupTree() OVERRIDE { + void SetupTree() override { LayerTreeHostTest::SetupTree(); scoped_refptr<IOSurfaceLayer> layer = IOSurfaceLayer::Create(); layer->SetBounds(gfx::Size(10, 10)); @@ -4008,7 +4019,7 @@ SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F( class LayerTreeHostTestPushHiddenLayer : public LayerTreeHostTest { protected: - virtual void SetupTree() OVERRIDE { + void SetupTree() override { root_layer_ = Layer::Create(); root_layer_->SetPosition(gfx::Point()); root_layer_->SetBounds(gfx::Size(10, 10)); @@ -4029,9 +4040,9 @@ class LayerTreeHostTestPushHiddenLayer : public LayerTreeHostTest { LayerTreeHostTest::SetupTree(); } - virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } + void BeginTest() override { PostSetNeedsCommitToMainThread(); } - virtual void DidCommitAndDrawFrame() OVERRIDE { + void DidCommitAndDrawFrame() override { switch (layer_tree_host()->source_frame_number()) { case 1: // The layer type used does not need to push properties every frame. @@ -4051,7 +4062,7 @@ class LayerTreeHostTestPushHiddenLayer : public LayerTreeHostTest { } } - virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE { + void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override { LayerImpl* root = impl->active_tree()->root_layer(); LayerImpl* parent = root->children()[0]; LayerImpl* child = parent->children()[0]; @@ -4063,7 +4074,7 @@ class LayerTreeHostTestPushHiddenLayer : public LayerTreeHostTest { } } - virtual void AfterTest() OVERRIDE {} + void AfterTest() override {} scoped_refptr<Layer> root_layer_; scoped_refptr<SolidColorLayer> parent_layer_; @@ -4074,11 +4085,11 @@ SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPushHiddenLayer); class LayerTreeHostTestUpdateLayerInEmptyViewport : public LayerTreeHostTest { protected: - virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE { + void InitializeSettings(LayerTreeSettings* settings) override { settings->impl_side_painting = true; } - virtual void SetupTree() OVERRIDE { + void SetupTree() override { root_layer_ = FakePictureLayer::Create(&client_); root_layer_->SetBounds(gfx::Size(10, 10)); @@ -4086,21 +4097,21 @@ class LayerTreeHostTestUpdateLayerInEmptyViewport : public LayerTreeHostTest { LayerTreeHostTest::SetupTree(); } - virtual void BeginTest() OVERRIDE { + void BeginTest() override { // The viewport is empty, but we still need to update layers on the main // thread. layer_tree_host()->SetViewportSize(gfx::Size(0, 0)); PostSetNeedsCommitToMainThread(); } - virtual void DidCommit() OVERRIDE { + void DidCommit() override { // The layer should be updated even though the viewport is empty, so we // are capable of drawing it on the impl tree. EXPECT_GT(root_layer_->update_count(), 0u); EndTest(); } - virtual void AfterTest() OVERRIDE {} + void AfterTest() override {} FakeContentLayerClient client_; scoped_refptr<FakePictureLayer> root_layer_; @@ -4114,7 +4125,7 @@ class LayerTreeHostTestAbortEvictedTextures : public LayerTreeHostTest { : num_will_begin_main_frames_(0), num_impl_commits_(0) {} protected: - virtual void SetupTree() OVERRIDE { + void SetupTree() override { scoped_refptr<SolidColorLayer> root_layer = SolidColorLayer::Create(); root_layer->SetBounds(gfx::Size(200, 200)); root_layer->SetIsDrawable(true); @@ -4123,9 +4134,9 @@ class LayerTreeHostTestAbortEvictedTextures : public LayerTreeHostTest { LayerTreeHostTest::SetupTree(); } - virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } + void BeginTest() override { PostSetNeedsCommitToMainThread(); } - virtual void WillBeginMainFrame() OVERRIDE { + void WillBeginMainFrame() override { num_will_begin_main_frames_++; switch (num_will_begin_main_frames_) { case 2: @@ -4136,11 +4147,11 @@ class LayerTreeHostTestAbortEvictedTextures : public LayerTreeHostTest { } } - virtual void BeginCommitOnThread(LayerTreeHostImpl* impl) OVERRIDE { + void BeginCommitOnThread(LayerTreeHostImpl* impl) override { num_impl_commits_++; } - virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE { + void DrawLayersOnThread(LayerTreeHostImpl* impl) override { switch (impl->SourceAnimationFrameNumber()) { case 1: // Prevent draws until commit. @@ -4155,7 +4166,7 @@ class LayerTreeHostTestAbortEvictedTextures : public LayerTreeHostTest { } } - virtual void AfterTest() OVERRIDE { + void AfterTest() override { // Ensure that the commit was truly aborted. EXPECT_EQ(2, num_will_begin_main_frames_); EXPECT_EQ(1, num_impl_commits_); @@ -4171,43 +4182,46 @@ MULTI_THREAD_TEST_F(LayerTreeHostTestAbortEvictedTextures); class LayerTreeHostTestMaxTransferBufferUsageBytes : public LayerTreeHostTest { protected: - virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE { + void InitializeSettings(LayerTreeSettings* settings) override { settings->impl_side_painting = true; + settings->use_zero_copy = false; + settings->use_one_copy = false; } - virtual scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(bool fallback) - OVERRIDE { + scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface( + bool fallback) override { scoped_refptr<TestContextProvider> context_provider = TestContextProvider::Create(); - context_provider->SetMaxTransferBufferUsageBytes(1024 * 1024); + context_provider->SetMaxTransferBufferUsageBytes(512 * 512); if (delegating_renderer()) return FakeOutputSurface::CreateDelegating3d(context_provider); else return FakeOutputSurface::Create3d(context_provider); } - virtual void SetupTree() OVERRIDE { + void SetupTree() override { + client_.set_fill_with_nonsolid_color(true); scoped_refptr<FakePictureLayer> root_layer = FakePictureLayer::Create(&client_); - root_layer->SetBounds(gfx::Size(6000, 6000)); + root_layer->SetBounds(gfx::Size(1024, 1024)); root_layer->SetIsDrawable(true); layer_tree_host()->SetRootLayer(root_layer); LayerTreeHostTest::SetupTree(); } - virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } + void BeginTest() override { PostSetNeedsCommitToMainThread(); } - virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE { + void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override { TestWebGraphicsContext3D* context = TestContext(); // Expect that the transfer buffer memory used is equal to the // MaxTransferBufferUsageBytes value set in CreateOutputSurface. - EXPECT_EQ(1024 * 1024u, context->max_used_transfer_buffer_usage_bytes()); + EXPECT_EQ(512 * 512u, context->max_used_transfer_buffer_usage_bytes()); EndTest(); } - virtual void AfterTest() OVERRIDE {} + void AfterTest() override {} private: FakeContentLayerClient client_; @@ -4222,14 +4236,14 @@ class LayerTreeHostTestMemoryLimits : public LayerTreeHostTest { public: LayerTreeHostTestMemoryLimits() : num_commits_(0) {} - virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } + void BeginTest() override { PostSetNeedsCommitToMainThread(); } - virtual void WillCommit() OVERRIDE { + void WillCommit() override { // Some commits are aborted, so increment number of attempted commits here. num_commits_++; } - virtual void DidCommit() OVERRIDE { + void DidCommit() override { switch (num_commits_) { case 1: // Verify default values. @@ -4274,7 +4288,7 @@ class LayerTreeHostTestMemoryLimits : public LayerTreeHostTest { } } - virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE { + void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { switch (num_commits_) { case 1: break; @@ -4299,7 +4313,7 @@ class LayerTreeHostTestMemoryLimits : public LayerTreeHostTest { } } - virtual void AfterTest() OVERRIDE {} + void AfterTest() override {} private: int num_commits_; @@ -4316,16 +4330,16 @@ class LayerTreeHostTestSetMemoryPolicyOnLostOutputSurface : first_output_surface_memory_limit_(4321234), second_output_surface_memory_limit_(1234321) {} - virtual scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(bool fallback) - OVERRIDE { - if (!first_context_provider_) { + scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface( + bool fallback) override { + if (!first_context_provider_.get()) { first_context_provider_ = TestContextProvider::Create(); } else { - EXPECT_FALSE(second_context_provider_); + EXPECT_FALSE(second_context_provider_.get()); second_context_provider_ = TestContextProvider::Create(); } - scoped_refptr<TestContextProvider> provider(second_context_provider_ + scoped_refptr<TestContextProvider> provider(second_context_provider_.get() ? second_context_provider_ : first_context_provider_); scoped_ptr<FakeOutputSurface> output_surface; @@ -4335,23 +4349,23 @@ class LayerTreeHostTestSetMemoryPolicyOnLostOutputSurface output_surface = FakeOutputSurface::Create3d(provider); output_surface->SetMemoryPolicyToSetAtBind( make_scoped_ptr(new ManagedMemoryPolicy( - second_context_provider_ ? second_output_surface_memory_limit_ - : first_output_surface_memory_limit_, + second_context_provider_.get() ? second_output_surface_memory_limit_ + : first_output_surface_memory_limit_, gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE, ManagedMemoryPolicy::kDefaultNumResourcesLimit))); return output_surface.Pass(); } - virtual void SetupTree() OVERRIDE { + void SetupTree() override { root_ = FakeContentLayer::Create(&client_); root_->SetBounds(gfx::Size(20, 20)); layer_tree_host()->SetRootLayer(root_); LayerTreeHostTest::SetupTree(); } - virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } + void BeginTest() override { PostSetNeedsCommitToMainThread(); } - virtual void DidCommitAndDrawFrame() OVERRIDE { + void DidCommitAndDrawFrame() override { // Lost context sometimes takes two frames to recreate. The third frame // is sometimes aborted, so wait until the fourth frame to verify that // the memory has been set, and the fifth frame to end the test. @@ -4362,8 +4376,7 @@ class LayerTreeHostTestSetMemoryPolicyOnLostOutputSurface } } - virtual void SwapBuffersOnThread(LayerTreeHostImpl* impl, - bool result) OVERRIDE { + void SwapBuffersOnThread(LayerTreeHostImpl* impl, bool result) override { switch (impl->active_tree()->source_frame_number()) { case 1: EXPECT_EQ(first_output_surface_memory_limit_, @@ -4379,7 +4392,7 @@ class LayerTreeHostTestSetMemoryPolicyOnLostOutputSurface } } - virtual void AfterTest() OVERRIDE {} + void AfterTest() override {} scoped_refptr<TestContextProvider> first_context_provider_; scoped_refptr<TestContextProvider> second_context_provider_; @@ -4411,19 +4424,19 @@ class TestSwapPromise : public SwapPromise { public: explicit TestSwapPromise(TestSwapPromiseResult* result) : result_(result) {} - virtual ~TestSwapPromise() { + ~TestSwapPromise() override { base::AutoLock lock(result_->lock); result_->dtor_called = true; } - virtual void DidSwap(CompositorFrameMetadata* metadata) OVERRIDE { + void DidSwap(CompositorFrameMetadata* metadata) override { base::AutoLock lock(result_->lock); EXPECT_FALSE(result_->did_swap_called); EXPECT_FALSE(result_->did_not_swap_called); result_->did_swap_called = true; } - virtual void DidNotSwap(DidNotSwapReason reason) OVERRIDE { + void DidNotSwap(DidNotSwapReason reason) override { base::AutoLock lock(result_->lock); EXPECT_FALSE(result_->did_swap_called); EXPECT_FALSE(result_->did_not_swap_called); @@ -4431,6 +4444,8 @@ class TestSwapPromise : public SwapPromise { result_->reason = reason; } + int64 TraceId() const override { return 0; } + private: // Not owned. TestSwapPromiseResult* result_; @@ -4441,16 +4456,16 @@ class LayerTreeHostTestBreakSwapPromise : public LayerTreeHostTest { LayerTreeHostTestBreakSwapPromise() : commit_count_(0), commit_complete_count_(0) {} - virtual void WillBeginMainFrame() OVERRIDE { + void WillBeginMainFrame() override { ASSERT_LE(commit_count_, 2); scoped_ptr<SwapPromise> swap_promise( new TestSwapPromise(&swap_promise_result_[commit_count_])); layer_tree_host()->QueueSwapPromise(swap_promise.Pass()); } - virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } + void BeginTest() override { PostSetNeedsCommitToMainThread(); } - virtual void DidCommit() OVERRIDE { + void DidCommit() override { commit_count_++; if (commit_count_ == 2) { // This commit will finish. @@ -4458,7 +4473,7 @@ class LayerTreeHostTestBreakSwapPromise : public LayerTreeHostTest { } } - virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { + void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { commit_complete_count_++; if (commit_complete_count_ == 1) { // This commit will be aborted because no actual update. @@ -4468,7 +4483,7 @@ class LayerTreeHostTestBreakSwapPromise : public LayerTreeHostTest { } } - virtual void AfterTest() OVERRIDE { + void AfterTest() override { // 3 commits are scheduled. 2 completes. 1 is aborted. EXPECT_EQ(commit_count_, 3); EXPECT_EQ(commit_complete_count_, 2); @@ -4483,11 +4498,11 @@ class LayerTreeHostTestBreakSwapPromise : public LayerTreeHostTest { } { - // The second commit aborts. + // The second commit is aborted since it contains no updates. base::AutoLock lock(swap_promise_result_[1].lock); EXPECT_FALSE(swap_promise_result_[1].did_swap_called); EXPECT_TRUE(swap_promise_result_[1].did_not_swap_called); - EXPECT_EQ(SwapPromise::COMMIT_FAILS, swap_promise_result_[1].reason); + EXPECT_EQ(SwapPromise::COMMIT_NO_UPDATE, swap_promise_result_[1].reason); EXPECT_TRUE(swap_promise_result_[1].dtor_called); } @@ -4509,6 +4524,96 @@ class LayerTreeHostTestBreakSwapPromise : public LayerTreeHostTest { MULTI_THREAD_TEST_F(LayerTreeHostTestBreakSwapPromise); +class LayerTreeHostTestBreakSwapPromiseForVisibilityAbortedCommit + : public LayerTreeHostTest { + protected: + void BeginTest() override { PostSetNeedsCommitToMainThread(); } + + void DidCommit() override { + layer_tree_host()->SetDeferCommits(true); + layer_tree_host()->SetNeedsCommit(); + } + + void DidDeferCommit() override { + layer_tree_host()->SetVisible(false); + scoped_ptr<SwapPromise> swap_promise( + new TestSwapPromise(&swap_promise_result_)); + layer_tree_host()->QueueSwapPromise(swap_promise.Pass()); + layer_tree_host()->SetDeferCommits(false); + } + + void BeginMainFrameAbortedOnThread(LayerTreeHostImpl* host_impl, + bool did_handle) override { + EndTest(); + } + + void AfterTest() override { + { + base::AutoLock lock(swap_promise_result_.lock); + EXPECT_FALSE(swap_promise_result_.did_swap_called); + EXPECT_TRUE(swap_promise_result_.did_not_swap_called); + EXPECT_EQ(SwapPromise::COMMIT_FAILS, swap_promise_result_.reason); + EXPECT_TRUE(swap_promise_result_.dtor_called); + } + } + + TestSwapPromiseResult swap_promise_result_; +}; + +SINGLE_AND_MULTI_THREAD_TEST_F( + LayerTreeHostTestBreakSwapPromiseForVisibilityAbortedCommit); + +class LayerTreeHostTestBreakSwapPromiseForContextAbortedCommit + : public LayerTreeHostTest { + protected: + void BeginTest() override { PostSetNeedsCommitToMainThread(); } + + void DidCommit() override { + if (TestEnded()) + return; + layer_tree_host()->SetDeferCommits(true); + layer_tree_host()->SetNeedsCommit(); + } + + void DidDeferCommit() override { + layer_tree_host()->DidLoseOutputSurface(); + scoped_ptr<SwapPromise> swap_promise( + new TestSwapPromise(&swap_promise_result_)); + layer_tree_host()->QueueSwapPromise(swap_promise.Pass()); + layer_tree_host()->SetDeferCommits(false); + } + + void BeginMainFrameAbortedOnThread(LayerTreeHostImpl* host_impl, + bool did_handle) override { + EndTest(); + // This lets the test finally commit and exit. + MainThreadTaskRunner()->PostTask( + FROM_HERE, + base::Bind(&LayerTreeHostTestBreakSwapPromiseForContextAbortedCommit:: + FindOutputSurface, + base::Unretained(this))); + } + + void FindOutputSurface() { + layer_tree_host()->OnCreateAndInitializeOutputSurfaceAttempted(true); + } + + void AfterTest() override { + { + base::AutoLock lock(swap_promise_result_.lock); + EXPECT_FALSE(swap_promise_result_.did_swap_called); + EXPECT_TRUE(swap_promise_result_.did_not_swap_called); + EXPECT_EQ(SwapPromise::COMMIT_FAILS, swap_promise_result_.reason); + EXPECT_TRUE(swap_promise_result_.dtor_called); + } + } + + TestSwapPromiseResult swap_promise_result_; +}; + +SINGLE_AND_MULTI_THREAD_TEST_F( + LayerTreeHostTestBreakSwapPromiseForContextAbortedCommit); + class SimpleSwapPromiseMonitor : public SwapPromiseMonitor { public: SimpleSwapPromiseMonitor(LayerTreeHost* layer_tree_host, @@ -4516,29 +4621,32 @@ class SimpleSwapPromiseMonitor : public SwapPromiseMonitor { 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) {} + set_needs_commit_count_(set_needs_commit_count) {} + + ~SimpleSwapPromiseMonitor() override {} - virtual ~SimpleSwapPromiseMonitor() {} + void OnSetNeedsCommitOnMain() override { (*set_needs_commit_count_)++; } - virtual void OnSetNeedsCommitOnMain() OVERRIDE { - (*set_needs_commit_count_)++; + void OnSetNeedsRedrawOnImpl() override { + ADD_FAILURE() << "Should not get called on main thread."; } - virtual void OnSetNeedsRedrawOnImpl() OVERRIDE { - (*set_needs_redraw_count_)++; + void OnForwardScrollUpdateToMainThreadOnImpl() override { + ADD_FAILURE() << "Should not get called on main thread."; } private: int* set_needs_commit_count_; - int* set_needs_redraw_count_; }; class LayerTreeHostTestSimpleSwapPromiseMonitor : public LayerTreeHostTest { public: - virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } + void BeginTest() override { PostSetNeedsCommitToMainThread(); } + + void WillBeginMainFrame() override { + if (TestEnded()) + return; - virtual void WillBeginMainFrame() OVERRIDE { int set_needs_commit_count = 0; int set_needs_redraw_count = 0; @@ -4584,66 +4692,66 @@ class LayerTreeHostTestSimpleSwapPromiseMonitor : public LayerTreeHostTest { EndTest(); } - virtual void AfterTest() OVERRIDE {} + void AfterTest() override {} }; -MULTI_THREAD_TEST_F(LayerTreeHostTestSimpleSwapPromiseMonitor); +SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSimpleSwapPromiseMonitor); class LayerTreeHostTestHighResRequiredAfterEvictingUIResources : public LayerTreeHostTest { protected: - virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE { + void InitializeSettings(LayerTreeSettings* settings) override { settings->impl_side_painting = true; } - virtual void SetupTree() OVERRIDE { + void SetupTree() override { LayerTreeHostTest::SetupTree(); ui_resource_ = FakeScopedUIResource::Create(layer_tree_host()); } - virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } + void BeginTest() override { PostSetNeedsCommitToMainThread(); } - virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { + void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { host_impl->EvictAllUIResources(); // Existence of evicted UI resources will trigger NEW_CONTENT_TAKES_PRIORITY // mode. Active tree should require high-res to draw after entering this // mode to ensure that high-res tiles are also required for a pending tree // to be activated. - EXPECT_TRUE(host_impl->active_tree()->RequiresHighResToDraw()); + EXPECT_TRUE(host_impl->RequiresHighResToDraw()); } - virtual void DidCommit() OVERRIDE { + void DidCommit() override { int frame = layer_tree_host()->source_frame_number(); switch (frame) { case 1: PostSetNeedsCommitToMainThread(); break; case 2: - ui_resource_.reset(); + ui_resource_ = nullptr; EndTest(); break; } } - virtual void AfterTest() OVERRIDE {} + void AfterTest() override {} FakeContentLayerClient client_; scoped_ptr<FakeScopedUIResource> ui_resource_; }; // This test is flaky, see http://crbug.com/386199 -//MULTI_THREAD_TEST_F(LayerTreeHostTestHighResRequiredAfterEvictingUIResources); +// MULTI_THREAD_TEST_F(LayerTreeHostTestHighResRequiredAfterEvictingUIResources) class LayerTreeHostTestGpuRasterizationDefault : public LayerTreeHostTest { protected: - virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE { + void InitializeSettings(LayerTreeSettings* settings) override { settings->impl_side_painting = true; EXPECT_FALSE(settings->gpu_rasterization_enabled); EXPECT_FALSE(settings->gpu_rasterization_forced); } - virtual void SetupTree() OVERRIDE { + void SetupTree() override { LayerTreeHostTest::SetupTree(); scoped_refptr<PictureLayer> layer = PictureLayer::Create(&layer_client_); @@ -4652,7 +4760,7 @@ class LayerTreeHostTestGpuRasterizationDefault : public LayerTreeHostTest { layer_tree_host()->root_layer()->AddChild(layer); } - virtual void BeginTest() OVERRIDE { + void BeginTest() override { Layer* root = layer_tree_host()->root_layer(); PictureLayer* layer = static_cast<PictureLayer*>(root->child_at(0)); PicturePile* pile = layer->GetPicturePileForTesting(); @@ -4672,18 +4780,18 @@ class LayerTreeHostTestGpuRasterizationDefault : public LayerTreeHostTest { PostSetNeedsCommitToMainThread(); } - virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { + void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { EXPECT_FALSE(host_impl->pending_tree()->use_gpu_rasterization()); EXPECT_FALSE(host_impl->use_gpu_rasterization()); } - virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { + void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { EXPECT_FALSE(host_impl->active_tree()->use_gpu_rasterization()); EXPECT_FALSE(host_impl->use_gpu_rasterization()); EndTest(); } - virtual void AfterTest() OVERRIDE {} + void AfterTest() override {} FakeContentLayerClient layer_client_; }; @@ -4692,14 +4800,14 @@ MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationDefault); class LayerTreeHostTestGpuRasterizationEnabled : public LayerTreeHostTest { protected: - virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE { + void InitializeSettings(LayerTreeSettings* settings) override { settings->impl_side_painting = true; EXPECT_FALSE(settings->gpu_rasterization_enabled); settings->gpu_rasterization_enabled = true; } - virtual void SetupTree() OVERRIDE { + void SetupTree() override { LayerTreeHostTest::SetupTree(); scoped_refptr<PictureLayer> layer = PictureLayer::Create(&layer_client_); @@ -4708,7 +4816,7 @@ class LayerTreeHostTestGpuRasterizationEnabled : public LayerTreeHostTest { layer_tree_host()->root_layer()->AddChild(layer); } - virtual void BeginTest() OVERRIDE { + void BeginTest() override { Layer* root = layer_tree_host()->root_layer(); PictureLayer* layer = static_cast<PictureLayer*>(root->child_at(0)); PicturePile* pile = layer->GetPicturePileForTesting(); @@ -4737,18 +4845,18 @@ class LayerTreeHostTestGpuRasterizationEnabled : public LayerTreeHostTest { PostSetNeedsCommitToMainThread(); } - virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { + void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { EXPECT_FALSE(host_impl->pending_tree()->use_gpu_rasterization()); EXPECT_FALSE(host_impl->use_gpu_rasterization()); } - virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { + void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { EXPECT_FALSE(host_impl->active_tree()->use_gpu_rasterization()); EXPECT_FALSE(host_impl->use_gpu_rasterization()); EndTest(); } - virtual void AfterTest() OVERRIDE {} + void AfterTest() override {} FakeContentLayerClient layer_client_; }; @@ -4757,14 +4865,14 @@ MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationEnabled); class LayerTreeHostTestGpuRasterizationForced : public LayerTreeHostTest { protected: - virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE { + void InitializeSettings(LayerTreeSettings* settings) override { settings->impl_side_painting = true; EXPECT_FALSE(settings->gpu_rasterization_forced); settings->gpu_rasterization_forced = true; } - virtual void SetupTree() OVERRIDE { + void SetupTree() override { LayerTreeHostTest::SetupTree(); scoped_refptr<PictureLayer> layer = PictureLayer::Create(&layer_client_); @@ -4773,7 +4881,7 @@ class LayerTreeHostTestGpuRasterizationForced : public LayerTreeHostTest { layer_tree_host()->root_layer()->AddChild(layer); } - virtual void BeginTest() OVERRIDE { + void BeginTest() override { Layer* root = layer_tree_host()->root_layer(); PictureLayer* layer = static_cast<PictureLayer*>(root->child_at(0)); PicturePile* pile = layer->GetPicturePileForTesting(); @@ -4802,18 +4910,18 @@ class LayerTreeHostTestGpuRasterizationForced : public LayerTreeHostTest { PostSetNeedsCommitToMainThread(); } - virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { + void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { EXPECT_TRUE(host_impl->pending_tree()->use_gpu_rasterization()); EXPECT_TRUE(host_impl->use_gpu_rasterization()); } - virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { + void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { EXPECT_TRUE(host_impl->active_tree()->use_gpu_rasterization()); EXPECT_TRUE(host_impl->use_gpu_rasterization()); EndTest(); } - virtual void AfterTest() OVERRIDE {} + void AfterTest() override {} FakeContentLayerClient layer_client_; }; @@ -4828,7 +4936,7 @@ class LayerTreeHostTestContinuousPainting : public LayerTreeHostTest { protected: enum { kExpectedNumCommits = 10 }; - virtual void SetupTree() OVERRIDE { + void SetupTree() override { scoped_refptr<Layer> root_layer = Layer::Create(); root_layer->SetBounds(bounds_); @@ -4848,36 +4956,43 @@ class LayerTreeHostTestContinuousPainting : public LayerTreeHostTest { LayerTreeHostTest::SetupTree(); } - virtual void BeginTest() OVERRIDE { - // Wait 50x longer than expected. - double milliseconds_per_frame = - 1000 / layer_tree_host()->settings().refresh_rate; - EndTestAfterDelay(50 * kExpectedNumCommits * milliseconds_per_frame); + void BeginTest() override { MainThreadTaskRunner()->PostTask( FROM_HERE, base::Bind( &LayerTreeHostTestContinuousPainting::EnableContinuousPainting, base::Unretained(this))); + // Wait 50x longer than expected. + double milliseconds_per_frame = + 1000.0 / layer_tree_host()->settings().refresh_rate; + MainThreadTaskRunner()->PostDelayedTask( + FROM_HERE, + base::Bind( + &LayerTreeHostTestContinuousPainting::DisableContinuousPainting, + base::Unretained(this)), + base::TimeDelta::FromMilliseconds(50 * kExpectedNumCommits * + milliseconds_per_frame)); } - virtual void Animate(base::TimeTicks monotonic_time) OVERRIDE { + void BeginMainFrame(const BeginFrameArgs& args) override { child_layer_->SetNeedsDisplay(); } - virtual void AfterTest() OVERRIDE { + void AfterTest() override { EXPECT_LE(kExpectedNumCommits, num_commits_); EXPECT_LE(kExpectedNumCommits, num_draws_); - int update_count = content_layer_ ? content_layer_->PaintContentsCount() - : picture_layer_->update_count(); + int update_count = content_layer_.get() + ? content_layer_->PaintContentsCount() + : picture_layer_->update_count(); EXPECT_LE(kExpectedNumCommits, update_count); } - virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE { + void DrawLayersOnThread(LayerTreeHostImpl* impl) override { if (++num_draws_ == kExpectedNumCommits) EndTest(); } - virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE { + void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { ++num_commits_; } @@ -4888,6 +5003,13 @@ class LayerTreeHostTestContinuousPainting : public LayerTreeHostTest { layer_tree_host()->SetDebugState(debug_state); } + void DisableContinuousPainting() { + LayerTreeDebugState debug_state = layer_tree_host()->debug_state(); + debug_state.continuous_painting = false; + layer_tree_host()->SetDebugState(debug_state); + EndTest(); + } + int num_commits_; int num_draws_; const gfx::Size bounds_; @@ -4899,4 +5021,188 @@ class LayerTreeHostTestContinuousPainting : public LayerTreeHostTest { MULTI_THREAD_TEST_F(LayerTreeHostTestContinuousPainting); +class LayerTreeHostTestActivateOnInvisible : public LayerTreeHostTest { + public: + LayerTreeHostTestActivateOnInvisible() + : activation_count_(0), visible_(true) {} + + void InitializeSettings(LayerTreeSettings* settings) override { + settings->impl_side_painting = true; + } + + void BeginTest() override { + // Kick off the test with a commit. + PostSetNeedsCommitToMainThread(); + } + + void BeginCommitOnThread(LayerTreeHostImpl* host_impl) override { + // Make sure we don't activate using the notify signal from tile manager. + host_impl->BlockNotifyReadyToActivateForTesting(true); + } + + void DidCommit() override { layer_tree_host()->SetVisible(false); } + + void DidSetVisibleOnImplTree(LayerTreeHostImpl* host_impl, + bool visible) override { + visible_ = visible; + + // Once invisible, we can go visible again. + if (!visible) { + PostSetVisibleToMainThread(true); + } else { + EXPECT_TRUE(host_impl->RequiresHighResToDraw()); + EndTest(); + } + } + + void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { + ++activation_count_; + EXPECT_FALSE(visible_); + } + + void AfterTest() override { + // Ensure we activated even though the signal was blocked. + EXPECT_EQ(1, activation_count_); + EXPECT_TRUE(visible_); + } + + private: + int activation_count_; + bool visible_; + + FakeContentLayerClient client_; + scoped_refptr<FakePictureLayer> picture_layer_; +}; + +// TODO(vmpstr): Enable with single thread impl-side painting. +MULTI_THREAD_TEST_F(LayerTreeHostTestActivateOnInvisible); + +// Do a synchronous composite and assert that the swap promise succeeds. +class LayerTreeHostTestSynchronousCompositeSwapPromise + : public LayerTreeHostTest { + public: + LayerTreeHostTestSynchronousCompositeSwapPromise() : commit_count_(0) {} + + void InitializeSettings(LayerTreeSettings* settings) override { + settings->single_thread_proxy_scheduler = false; + } + + void BeginTest() override { + // Successful composite. + scoped_ptr<SwapPromise> swap_promise0( + new TestSwapPromise(&swap_promise_result_[0])); + layer_tree_host()->QueueSwapPromise(swap_promise0.Pass()); + layer_tree_host()->Composite(gfx::FrameTime::Now()); + + // Fail to swap (no damage). + scoped_ptr<SwapPromise> swap_promise1( + new TestSwapPromise(&swap_promise_result_[1])); + layer_tree_host()->QueueSwapPromise(swap_promise1.Pass()); + layer_tree_host()->SetNeedsCommit(); + layer_tree_host()->Composite(gfx::FrameTime::Now()); + + // Fail to draw (not visible). + scoped_ptr<SwapPromise> swap_promise2( + new TestSwapPromise(&swap_promise_result_[2])); + layer_tree_host()->QueueSwapPromise(swap_promise2.Pass()); + layer_tree_host()->SetNeedsDisplayOnAllLayers(); + layer_tree_host()->SetVisible(false); + layer_tree_host()->Composite(gfx::FrameTime::Now()); + + EndTest(); + } + + void DidCommit() override { + commit_count_++; + ASSERT_LE(commit_count_, 3); + } + + void AfterTest() override { + EXPECT_EQ(3, commit_count_); + + // Initial swap promise should have succeded. + { + base::AutoLock lock(swap_promise_result_[0].lock); + EXPECT_TRUE(swap_promise_result_[0].did_swap_called); + EXPECT_FALSE(swap_promise_result_[0].did_not_swap_called); + EXPECT_TRUE(swap_promise_result_[0].dtor_called); + } + + // Second swap promise fails to swap. + { + base::AutoLock lock(swap_promise_result_[1].lock); + EXPECT_FALSE(swap_promise_result_[1].did_swap_called); + EXPECT_TRUE(swap_promise_result_[1].did_not_swap_called); + EXPECT_EQ(SwapPromise::SWAP_FAILS, swap_promise_result_[1].reason); + EXPECT_TRUE(swap_promise_result_[1].dtor_called); + } + + // Third swap promises also fails to swap (and draw). + { + base::AutoLock lock(swap_promise_result_[2].lock); + EXPECT_FALSE(swap_promise_result_[2].did_swap_called); + EXPECT_TRUE(swap_promise_result_[2].did_not_swap_called); + EXPECT_EQ(SwapPromise::SWAP_FAILS, swap_promise_result_[2].reason); + EXPECT_TRUE(swap_promise_result_[2].dtor_called); + } + } + + int commit_count_; + TestSwapPromiseResult swap_promise_result_[3]; +}; + +// Impl-side painting is not supported for synchronous compositing. +SINGLE_THREAD_NOIMPL_TEST_F(LayerTreeHostTestSynchronousCompositeSwapPromise); + +// Make sure page scale and top control deltas are applied to the client even +// when the LayerTreeHost doesn't have a root layer. +class LayerTreeHostAcceptsDeltasFromImplWithoutRootLayer + : public LayerTreeHostTest { + public: + LayerTreeHostAcceptsDeltasFromImplWithoutRootLayer() + : deltas_sent_to_client_(false) {} + + void BeginTest() override { + layer_tree_host()->SetRootLayer(nullptr); + info_.page_scale_delta = 3.14f; + info_.top_controls_delta = 2.73f; + + PostSetNeedsCommitToMainThread(); + } + + void BeginMainFrame(const BeginFrameArgs& args) override { + EXPECT_EQ(nullptr, layer_tree_host()->root_layer()); + + layer_tree_host()->ApplyScrollAndScale(&info_); + EndTest(); + } + + void ApplyViewportDeltas( + const gfx::Vector2d& inner, + const gfx::Vector2d& outer, + float scale_delta, + float top_controls_delta) override { + EXPECT_EQ(info_.page_scale_delta, scale_delta); + EXPECT_EQ(info_.top_controls_delta, top_controls_delta); + deltas_sent_to_client_ = true; + } + + void ApplyViewportDeltas( + const gfx::Vector2d& scroll, + float scale_delta, + float top_controls_delta) override { + EXPECT_EQ(info_.page_scale_delta, scale_delta); + EXPECT_EQ(info_.top_controls_delta, top_controls_delta); + deltas_sent_to_client_ = true; + } + + void AfterTest() override { + EXPECT_TRUE(deltas_sent_to_client_); + } + + ScrollAndScaleSet info_; + bool deltas_sent_to_client_; +}; + +MULTI_THREAD_TEST_F(LayerTreeHostAcceptsDeltasFromImplWithoutRootLayer); } // namespace cc diff --git a/chromium/cc/trees/layer_tree_host_unittest_animation.cc b/chromium/cc/trees/layer_tree_host_unittest_animation.cc index 1542a1417b4..cfd8a1489af 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_animation.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_animation.cc @@ -21,7 +21,7 @@ namespace { class LayerTreeHostAnimationTest : public LayerTreeTest { public: - virtual void SetupTree() OVERRIDE { + void SetupTree() override { LayerTreeTest::SetupTree(); layer_tree_host()->root_layer()->set_layer_animation_delegate(this); } @@ -35,12 +35,10 @@ class LayerTreeHostAnimationTestSetNeedsAnimateShouldNotSetCommitRequested LayerTreeHostAnimationTestSetNeedsAnimateShouldNotSetCommitRequested() : num_commits_(0) {} - virtual void BeginTest() OVERRIDE { - PostSetNeedsCommitToMainThread(); - } + void BeginTest() override { PostSetNeedsCommitToMainThread(); } - virtual void Animate(base::TimeTicks monotonic_time) OVERRIDE { - // We skip the first commit becasue its the commit that populates the + void BeginMainFrame(const BeginFrameArgs& args) override { + // We skip the first commit because its the commit that populates the // impl thread with a tree. After the second commit, the test is done. if (num_commits_ != 1) return; @@ -52,7 +50,7 @@ class LayerTreeHostAnimationTestSetNeedsAnimateShouldNotSetCommitRequested // verify that CommitRequested has gone back to false. } - virtual void DidCommit() OVERRIDE { + void DidCommit() override { if (!num_commits_) { EXPECT_FALSE(layer_tree_host()->CommitRequested()); layer_tree_host()->SetNeedsAnimate(); @@ -66,7 +64,7 @@ class LayerTreeHostAnimationTestSetNeedsAnimateShouldNotSetCommitRequested num_commits_++; } - virtual void AfterTest() OVERRIDE {} + void AfterTest() override {} private: int num_commits_; @@ -84,25 +82,23 @@ class LayerTreeHostAnimationTestSetNeedsAnimateInsideAnimationCallback : public LayerTreeHostAnimationTest { public: LayerTreeHostAnimationTestSetNeedsAnimateInsideAnimationCallback() - : num_animates_(0) {} + : num_begin_frames_(0) {} - virtual void BeginTest() OVERRIDE { - PostSetNeedsCommitToMainThread(); - } + void BeginTest() override { PostSetNeedsCommitToMainThread(); } - virtual void Animate(base::TimeTicks) OVERRIDE { - if (!num_animates_) { + void BeginMainFrame(const BeginFrameArgs& args) override { + if (!num_begin_frames_) { layer_tree_host()->SetNeedsAnimate(); - num_animates_++; + num_begin_frames_++; return; } EndTest(); } - virtual void AfterTest() OVERRIDE {} + void AfterTest() override {} private: - int num_animates_; + int num_begin_frames_; }; MULTI_THREAD_TEST_F( @@ -115,22 +111,19 @@ class LayerTreeHostAnimationTestAddAnimation : public LayerTreeHostAnimationTest { public: LayerTreeHostAnimationTestAddAnimation() - : num_animates_(0), - received_animation_started_notification_(false) { - } + : num_begin_frames_(0), received_animation_started_notification_(false) {} - virtual void BeginTest() OVERRIDE { + void BeginTest() override { PostAddInstantAnimationToMainThread(layer_tree_host()->root_layer()); } - virtual void UpdateAnimationState( - LayerTreeHostImpl* host_impl, - bool has_unfinished_animation) OVERRIDE { - if (!num_animates_) { + void UpdateAnimationState(LayerTreeHostImpl* host_impl, + bool has_unfinished_animation) override { + if (!num_begin_frames_) { // The animation had zero duration so LayerTreeHostImpl should no // longer need to animate its layers. EXPECT_FALSE(has_unfinished_animation); - num_animates_++; + num_begin_frames_++; return; } @@ -148,12 +141,12 @@ class LayerTreeHostAnimationTestAddAnimation } } - virtual void NotifyAnimationStarted( - base::TimeTicks monotonic_time, - Animation::TargetProperty target_property) OVERRIDE { + void NotifyAnimationStarted(base::TimeTicks monotonic_time, + Animation::TargetProperty target_property, + int group) override { received_animation_started_notification_ = true; start_time_ = monotonic_time; - if (num_animates_) { + if (num_begin_frames_) { EXPECT_LT(base::TimeTicks(), start_time_); LayerAnimationController* controller = @@ -167,10 +160,10 @@ class LayerTreeHostAnimationTestAddAnimation } } - virtual void AfterTest() OVERRIDE {} + void AfterTest() override {} private: - int num_animates_; + int num_begin_frames_; bool received_animation_started_notification_; base::TimeTicks start_time_; }; @@ -185,29 +178,27 @@ class LayerTreeHostAnimationTestCheckerboardDoesNotStarveDraws LayerTreeHostAnimationTestCheckerboardDoesNotStarveDraws() : started_animating_(false) {} - virtual void BeginTest() OVERRIDE { + void BeginTest() override { PostAddAnimationToMainThread(layer_tree_host()->root_layer()); } - virtual void AnimateLayers( - LayerTreeHostImpl* host_impl, - base::TimeTicks monotonic_time) OVERRIDE { + void AnimateLayers(LayerTreeHostImpl* host_impl, + base::TimeTicks monotonic_time) override { started_animating_ = true; } - virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { + void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { if (started_animating_) EndTest(); } - virtual DrawResult PrepareToDrawOnThread( - LayerTreeHostImpl* host_impl, - LayerTreeHostImpl::FrameData* frame, - DrawResult draw_result) OVERRIDE { + DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, + LayerTreeHostImpl::FrameData* frame, + DrawResult draw_result) override { return DRAW_ABORTED_CHECKERBOARD_ANIMATIONS; } - virtual void AfterTest() OVERRIDE { } + void AfterTest() override {} private: bool started_animating_; @@ -223,13 +214,12 @@ class LayerTreeHostAnimationTestAnimationsGetDeleted LayerTreeHostAnimationTestAnimationsGetDeleted() : started_animating_(false) {} - virtual void BeginTest() OVERRIDE { + void BeginTest() override { PostAddAnimationToMainThread(layer_tree_host()->root_layer()); } - virtual void AnimateLayers( - LayerTreeHostImpl* host_impl, - base::TimeTicks monotonic_time) OVERRIDE { + void AnimateLayers(LayerTreeHostImpl* host_impl, + base::TimeTicks monotonic_time) override { bool have_animations = !host_impl->animation_registrar()-> active_animation_controllers().empty(); if (!started_animating_ && have_animations) { @@ -241,15 +231,15 @@ class LayerTreeHostAnimationTestAnimationsGetDeleted EndTest(); } - virtual void NotifyAnimationFinished( - base::TimeTicks monotonic_time, - Animation::TargetProperty target_property) OVERRIDE { + void NotifyAnimationFinished(base::TimeTicks monotonic_time, + Animation::TargetProperty target_property, + int group) override { // Animations on the impl-side controller only get deleted during a commit, // so we need to schedule a commit. layer_tree_host()->SetNeedsCommit(); } - virtual void AfterTest() OVERRIDE {} + void AfterTest() override {} private: bool started_animating_; @@ -262,36 +252,35 @@ class LayerTreeHostAnimationTestTickAnimationWhileBackgrounded : public LayerTreeHostAnimationTest { public: LayerTreeHostAnimationTestTickAnimationWhileBackgrounded() - : num_animates_(0) {} + : num_begin_frames_(0) {} - virtual void BeginTest() OVERRIDE { + void BeginTest() override { PostAddLongAnimationToMainThread(layer_tree_host()->root_layer()); } // Use WillAnimateLayers to set visible false before the animation runs and // causes a commit, so we block the second visible animate in single-thread // mode. - virtual void WillAnimateLayers( - LayerTreeHostImpl* host_impl, - base::TimeTicks monotonic_time) OVERRIDE { + void WillAnimateLayers(LayerTreeHostImpl* host_impl, + base::TimeTicks monotonic_time) override { // Verify that the host can draw, it's just not visible. EXPECT_TRUE(host_impl->CanDraw()); - if (num_animates_ < 2) { - if (!num_animates_) { + if (num_begin_frames_ < 2) { + if (!num_begin_frames_) { // We have a long animation running. It should continue to tick even // if we are not visible. PostSetVisibleToMainThread(false); } - num_animates_++; + num_begin_frames_++; return; } EndTest(); } - virtual void AfterTest() OVERRIDE {} + void AfterTest() override {} private: - int num_animates_; + int num_begin_frames_; }; SINGLE_AND_MULTI_THREAD_TEST_F( @@ -306,18 +295,18 @@ class LayerTreeHostAnimationTestAnimationTickTimeIsMonotonic LayerTreeHostAnimationTestAnimationTickTimeIsMonotonic() : has_background_ticked_(false), num_foreground_animates_(0) {} - virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE { + void InitializeSettings(LayerTreeSettings* settings) override { // Make sure that drawing many times doesn't cause a checkerboarded // animation to start so we avoid flake in this test. settings->timeout_and_draw_when_animation_checkerboards = false; } - virtual void BeginTest() OVERRIDE { + void BeginTest() override { PostAddLongAnimationToMainThread(layer_tree_host()->root_layer()); } - virtual void AnimateLayers(LayerTreeHostImpl* host_impl, - base::TimeTicks monotonic_time) OVERRIDE { + void AnimateLayers(LayerTreeHostImpl* host_impl, + base::TimeTicks monotonic_time) override { EXPECT_GE(monotonic_time, last_tick_time_); last_tick_time_ = monotonic_time; if (host_impl->visible()) { @@ -332,16 +321,15 @@ class LayerTreeHostAnimationTestAnimationTickTimeIsMonotonic } } - virtual DrawResult PrepareToDrawOnThread( - LayerTreeHostImpl* host_impl, - LayerTreeHostImpl::FrameData* frame, - DrawResult draw_result) OVERRIDE { + DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, + LayerTreeHostImpl::FrameData* frame, + DrawResult draw_result) override { if (TestEnded()) return draw_result; return DRAW_ABORTED_CHECKERBOARD_ANIMATIONS; } - virtual void AfterTest() OVERRIDE {} + void AfterTest() override {} private: bool has_background_ticked_; @@ -360,22 +348,22 @@ class LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree() : active_tree_was_animated_(false) {} - virtual base::TimeDelta LowFrequencyAnimationInterval() const OVERRIDE { + base::TimeDelta LowFrequencyAnimationInterval() const override { return base::TimeDelta::FromMilliseconds(4); } - virtual void BeginTest() OVERRIDE { + void BeginTest() override { PostAddAnimationToMainThread(layer_tree_host()->root_layer()); } - virtual void NotifyAnimationFinished( - base::TimeTicks monotonic_time, - Animation::TargetProperty target_property) OVERRIDE { + void NotifyAnimationFinished(base::TimeTicks monotonic_time, + Animation::TargetProperty target_property, + int group) override { // Replace animated commits with an empty tree. layer_tree_host()->SetRootLayer(make_scoped_refptr<Layer>(NULL)); } - virtual void DidCommit() OVERRIDE { + void DidCommit() override { // This alternates setting an empty tree and a non-empty tree with an // animation. switch (layer_tree_host()->source_frame_number()) { @@ -396,14 +384,15 @@ class LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree } } - virtual void BeginCommitOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { + void BeginCommitOnThread(LayerTreeHostImpl* host_impl) override { // At the start of every commit, block activations and make sure // we are backgrounded. - host_impl->BlockNotifyReadyToActivateForTesting(true); + if (host_impl->settings().impl_side_painting) + host_impl->BlockNotifyReadyToActivateForTesting(true); PostSetVisibleToMainThread(false); } - virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { + void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { if (!host_impl->settings().impl_side_painting) { // There are no activations to block if we're not impl-side-painting, // so just advance the test immediately. @@ -428,10 +417,11 @@ class LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree } virtual void UnblockActivations(LayerTreeHostImpl* host_impl) { - host_impl->BlockNotifyReadyToActivateForTesting(false); + if (host_impl->settings().impl_side_painting) + host_impl->BlockNotifyReadyToActivateForTesting(false); } - virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { + void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { active_tree_was_animated_ = false; // Verify that commits are actually alternating with empty / non-empty @@ -464,8 +454,8 @@ class LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree } } - virtual void WillAnimateLayers(LayerTreeHostImpl* host_impl, - base::TimeTicks monotonic_time) OVERRIDE { + void WillAnimateLayers(LayerTreeHostImpl* host_impl, + base::TimeTicks monotonic_time) override { EXPECT_TRUE(host_impl->active_tree()->root_layer()); active_tree_was_animated_ = true; } @@ -479,12 +469,12 @@ class LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree PostSetVisibleToMainThread(true); } - virtual void AfterTest() OVERRIDE {} + void AfterTest() override {} bool active_tree_was_animated_; }; -SINGLE_AND_MULTI_THREAD_TEST_F( +SINGLE_AND_MULTI_THREAD_BLOCKNOTIFY_TEST_F( LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree); // Ensure that an animation's timing function is respected. @@ -493,20 +483,17 @@ class LayerTreeHostAnimationTestAddAnimationWithTimingFunction public: LayerTreeHostAnimationTestAddAnimationWithTimingFunction() {} - virtual void SetupTree() OVERRIDE { + void SetupTree() override { LayerTreeHostAnimationTest::SetupTree(); content_ = FakeContentLayer::Create(&client_); content_->SetBounds(gfx::Size(4, 4)); layer_tree_host()->root_layer()->AddChild(content_); } - virtual void BeginTest() OVERRIDE { - PostAddAnimationToMainThread(content_.get()); - } + void BeginTest() override { PostAddAnimationToMainThread(content_.get()); } - virtual void AnimateLayers( - LayerTreeHostImpl* host_impl, - base::TimeTicks monotonic_time) OVERRIDE { + void AnimateLayers(LayerTreeHostImpl* host_impl, + base::TimeTicks monotonic_time) override { LayerAnimationController* controller_impl = host_impl->active_tree()->root_layer()->children()[0]-> layer_animation_controller(); @@ -530,7 +517,7 @@ class LayerTreeHostAnimationTestAddAnimationWithTimingFunction EndTest(); } - virtual void AfterTest() OVERRIDE {} + void AfterTest() override {} FakeContentLayerClient client_; scoped_refptr<FakeContentLayer> content_; @@ -548,7 +535,7 @@ class LayerTreeHostAnimationTestSynchronizeAnimationStartTimes : main_start_time_(-1.0), impl_start_time_(-1.0) {} - virtual void SetupTree() OVERRIDE { + void SetupTree() override { LayerTreeHostAnimationTest::SetupTree(); content_ = FakeContentLayer::Create(&client_); content_->SetBounds(gfx::Size(4, 4)); @@ -556,13 +543,11 @@ class LayerTreeHostAnimationTestSynchronizeAnimationStartTimes layer_tree_host()->root_layer()->AddChild(content_); } - virtual void BeginTest() OVERRIDE { - PostAddAnimationToMainThread(content_.get()); - } + void BeginTest() override { PostAddAnimationToMainThread(content_.get()); } - virtual void NotifyAnimationStarted( - base::TimeTicks monotonic_time, - Animation::TargetProperty target_property) OVERRIDE { + void NotifyAnimationStarted(base::TimeTicks monotonic_time, + Animation::TargetProperty target_property, + int group) override { LayerAnimationController* controller = layer_tree_host()->root_layer()->children()[0]-> layer_animation_controller(); @@ -576,9 +561,8 @@ class LayerTreeHostAnimationTestSynchronizeAnimationStartTimes EndTest(); } - virtual void UpdateAnimationState( - LayerTreeHostImpl* impl_host, - bool has_unfinished_animation) OVERRIDE { + void UpdateAnimationState(LayerTreeHostImpl* impl_host, + bool has_unfinished_animation) override { LayerAnimationController* controller = impl_host->active_tree()->root_layer()->children()[0]-> layer_animation_controller(); @@ -595,7 +579,7 @@ class LayerTreeHostAnimationTestSynchronizeAnimationStartTimes EndTest(); } - virtual void AfterTest() OVERRIDE { + void AfterTest() override { EXPECT_FLOAT_EQ(impl_start_time_, main_start_time_); } @@ -615,13 +599,13 @@ class LayerTreeHostAnimationTestAnimationFinishedEvents public: LayerTreeHostAnimationTestAnimationFinishedEvents() {} - virtual void BeginTest() OVERRIDE { + void BeginTest() override { PostAddInstantAnimationToMainThread(layer_tree_host()->root_layer()); } - virtual void NotifyAnimationFinished( - base::TimeTicks monotonic_time, - Animation::TargetProperty target_property) OVERRIDE { + void NotifyAnimationFinished(base::TimeTicks monotonic_time, + Animation::TargetProperty target_property, + int group) override { LayerAnimationController* controller = layer_tree_host()->root_layer()->layer_animation_controller(); Animation* animation = @@ -631,7 +615,7 @@ class LayerTreeHostAnimationTestAnimationFinishedEvents EndTest(); } - virtual void AfterTest() OVERRIDE {} + void AfterTest() override {} }; SINGLE_AND_MULTI_THREAD_TEST_F( @@ -646,17 +630,17 @@ class LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity : update_check_layer_(FakeContentLayer::Create(&client_)) { } - virtual void SetupTree() OVERRIDE { + void SetupTree() override { update_check_layer_->SetOpacity(0.f); layer_tree_host()->SetRootLayer(update_check_layer_); LayerTreeHostAnimationTest::SetupTree(); } - virtual void BeginTest() OVERRIDE { + void BeginTest() override { PostAddAnimationToMainThread(update_check_layer_.get()); } - virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { + void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { LayerAnimationController* controller_impl = host_impl->active_tree()->root_layer()->layer_animation_controller(); Animation* animation_impl = @@ -665,7 +649,7 @@ class LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity EndTest(); } - virtual void AfterTest() OVERRIDE { + void AfterTest() override { // Update() should have been called once, proving that the layer was not // skipped. EXPECT_EQ(1u, update_check_layer_->update_count()); @@ -689,17 +673,15 @@ class LayerTreeHostAnimationTestLayerAddedWithAnimation public: LayerTreeHostAnimationTestLayerAddedWithAnimation() {} - virtual void BeginTest() OVERRIDE { - PostSetNeedsCommitToMainThread(); - } + void BeginTest() override { PostSetNeedsCommitToMainThread(); } - virtual void DidCommit() OVERRIDE { + void DidCommit() override { if (layer_tree_host()->source_frame_number() == 1) { scoped_refptr<Layer> layer = Layer::Create(); layer->set_layer_animation_delegate(this); // Any valid AnimationCurve will do here. - scoped_ptr<AnimationCurve> curve(EaseTimingFunction::Create()); + scoped_ptr<AnimationCurve> curve(new FakeFloatAnimationCurve()); scoped_ptr<Animation> animation( Animation::Create(curve.Pass(), 1, 1, Animation::Opacity)); @@ -710,84 +692,27 @@ class LayerTreeHostAnimationTestLayerAddedWithAnimation } } - virtual void AnimateLayers( - LayerTreeHostImpl* impl_host, - base::TimeTicks monotonic_time) OVERRIDE { + void AnimateLayers(LayerTreeHostImpl* impl_host, + base::TimeTicks monotonic_time) override { EndTest(); } - virtual void AfterTest() OVERRIDE {} + void AfterTest() override {} }; SINGLE_AND_MULTI_THREAD_TEST_F( LayerTreeHostAnimationTestLayerAddedWithAnimation); -class LayerTreeHostAnimationTestContinuousAnimate - : public LayerTreeHostAnimationTest { - public: - LayerTreeHostAnimationTestContinuousAnimate() - : num_commit_complete_(0), - num_draw_layers_(0) { - } - - virtual void SetupTree() OVERRIDE { - LayerTreeHostAnimationTest::SetupTree(); - // Create a fake content layer so we actually produce new content for every - // animation frame. - content_ = FakeContentLayer::Create(&client_); - content_->set_always_update_resources(true); - layer_tree_host()->root_layer()->AddChild(content_); - } - - virtual void BeginTest() OVERRIDE { - PostSetNeedsCommitToMainThread(); - } - - virtual void Animate(base::TimeTicks) OVERRIDE { - if (num_draw_layers_ == 2) - return; - layer_tree_host()->SetNeedsAnimate(); - } - - virtual void Layout() OVERRIDE { - layer_tree_host()->root_layer()->SetNeedsDisplay(); - } - - virtual void CommitCompleteOnThread(LayerTreeHostImpl* tree_impl) OVERRIDE { - if (num_draw_layers_ == 1) - num_commit_complete_++; - } - - virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE { - num_draw_layers_++; - if (num_draw_layers_ == 2) - EndTest(); - } - - virtual void AfterTest() OVERRIDE { - // Check that we didn't commit twice between first and second draw. - EXPECT_EQ(1, num_commit_complete_); - } - - private: - int num_commit_complete_; - int num_draw_layers_; - FakeContentLayerClient client_; - scoped_refptr<FakeContentLayer> content_; -}; - -MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestContinuousAnimate); - class LayerTreeHostAnimationTestCancelAnimateCommit : public LayerTreeHostAnimationTest { public: LayerTreeHostAnimationTestCancelAnimateCommit() - : num_animate_calls_(0), num_commit_calls_(0), num_draw_calls_(0) {} + : num_begin_frames_(0), num_commit_calls_(0), num_draw_calls_(0) {} - virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } + void BeginTest() override { PostSetNeedsCommitToMainThread(); } - virtual void Animate(base::TimeTicks) OVERRIDE { - num_animate_calls_++; + void BeginMainFrame(const BeginFrameArgs& args) override { + num_begin_frames_++; // No-op animate will cancel the commit. if (layer_tree_host()->source_frame_number() == 1) { EndTest(); @@ -796,26 +721,26 @@ class LayerTreeHostAnimationTestCancelAnimateCommit layer_tree_host()->SetNeedsAnimate(); } - virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE { + void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { num_commit_calls_++; if (impl->active_tree()->source_frame_number() > 1) FAIL() << "Commit should have been canceled."; } - virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE { + void DrawLayersOnThread(LayerTreeHostImpl* impl) override { num_draw_calls_++; if (impl->active_tree()->source_frame_number() > 1) FAIL() << "Draw should have been canceled."; } - virtual void AfterTest() OVERRIDE { - EXPECT_EQ(2, num_animate_calls_); + void AfterTest() override { + EXPECT_EQ(2, num_begin_frames_); EXPECT_EQ(1, num_commit_calls_); EXPECT_EQ(1, num_draw_calls_); } private: - int num_animate_calls_; + int num_begin_frames_; int num_commit_calls_; int num_draw_calls_; FakeContentLayerClient client_; @@ -830,23 +755,21 @@ class LayerTreeHostAnimationTestForceRedraw LayerTreeHostAnimationTestForceRedraw() : num_animate_(0), num_draw_layers_(0) {} - virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } + void BeginTest() override { PostSetNeedsCommitToMainThread(); } - virtual void Animate(base::TimeTicks) OVERRIDE { + void BeginMainFrame(const BeginFrameArgs& args) override { if (++num_animate_ < 2) layer_tree_host()->SetNeedsAnimate(); } - virtual void Layout() OVERRIDE { - layer_tree_host()->SetNextCommitForcesRedraw(); - } + void Layout() override { layer_tree_host()->SetNextCommitForcesRedraw(); } - virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE { + void DrawLayersOnThread(LayerTreeHostImpl* impl) override { if (++num_draw_layers_ == 2) EndTest(); } - virtual void AfterTest() OVERRIDE { + void AfterTest() override { // The first commit will always draw; make sure the second draw triggered // by the animation was not cancelled. EXPECT_EQ(2, num_draw_layers_); @@ -866,21 +789,21 @@ class LayerTreeHostAnimationTestAnimateAfterSetNeedsCommit LayerTreeHostAnimationTestAnimateAfterSetNeedsCommit() : num_animate_(0), num_draw_layers_(0) {} - virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } + void BeginTest() override { PostSetNeedsCommitToMainThread(); } - virtual void Animate(base::TimeTicks) OVERRIDE { + void BeginMainFrame(const BeginFrameArgs& args) override { if (++num_animate_ <= 2) { layer_tree_host()->SetNeedsCommit(); layer_tree_host()->SetNeedsAnimate(); } } - virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE { + void DrawLayersOnThread(LayerTreeHostImpl* impl) override { if (++num_draw_layers_ == 2) EndTest(); } - virtual void AfterTest() OVERRIDE { + void AfterTest() override { // The first commit will always draw; make sure the second draw triggered // by the SetNeedsCommit was not cancelled. EXPECT_EQ(2, num_draw_layers_); @@ -901,7 +824,7 @@ class LayerTreeHostAnimationTestRunAnimationWhenNotCanDraw public: LayerTreeHostAnimationTestRunAnimationWhenNotCanDraw() : started_times_(0) {} - virtual void SetupTree() OVERRIDE { + void SetupTree() override { LayerTreeHostAnimationTest::SetupTree(); content_ = FakeContentLayer::Create(&client_); content_->SetBounds(gfx::Size(4, 4)); @@ -909,26 +832,24 @@ class LayerTreeHostAnimationTestRunAnimationWhenNotCanDraw layer_tree_host()->root_layer()->AddChild(content_); } - virtual void BeginTest() OVERRIDE { + void BeginTest() override { layer_tree_host()->SetViewportSize(gfx::Size()); PostAddAnimationToMainThread(content_.get()); } - virtual void NotifyAnimationStarted( - base::TimeTicks monotonic_time, - Animation::TargetProperty target_property) OVERRIDE { + void NotifyAnimationStarted(base::TimeTicks monotonic_time, + Animation::TargetProperty target_property, + int group) override { started_times_++; } - virtual void NotifyAnimationFinished( - base::TimeTicks monotonic_time, - Animation::TargetProperty target_property) OVERRIDE { + void NotifyAnimationFinished(base::TimeTicks monotonic_time, + Animation::TargetProperty target_property, + int group) override { EndTest(); } - virtual void AfterTest() OVERRIDE { - EXPECT_EQ(1, started_times_); - } + void AfterTest() override { EXPECT_EQ(1, started_times_); } private: int started_times_; @@ -946,7 +867,7 @@ class LayerTreeHostAnimationTestRunAnimationWhenNotVisible public: LayerTreeHostAnimationTestRunAnimationWhenNotVisible() : started_times_(0) {} - virtual void SetupTree() OVERRIDE { + void SetupTree() override { LayerTreeHostAnimationTest::SetupTree(); content_ = FakeContentLayer::Create(&client_); content_->SetBounds(gfx::Size(4, 4)); @@ -954,32 +875,32 @@ class LayerTreeHostAnimationTestRunAnimationWhenNotVisible layer_tree_host()->root_layer()->AddChild(content_); } - virtual void BeginTest() OVERRIDE { + void BeginTest() override { visible_ = true; PostAddAnimationToMainThread(content_.get()); } - virtual void DidCommit() OVERRIDE { + void DidCommit() override { visible_ = false; layer_tree_host()->SetVisible(false); } - virtual void NotifyAnimationStarted( - base::TimeTicks monotonic_time, - Animation::TargetProperty target_property) OVERRIDE { + void NotifyAnimationStarted(base::TimeTicks monotonic_time, + Animation::TargetProperty target_property, + int group) override { EXPECT_FALSE(visible_); started_times_++; } - virtual void NotifyAnimationFinished( - base::TimeTicks monotonic_time, - Animation::TargetProperty target_property) OVERRIDE { + void NotifyAnimationFinished(base::TimeTicks monotonic_time, + Animation::TargetProperty target_property, + int group) override { EXPECT_FALSE(visible_); EXPECT_EQ(1, started_times_); EndTest(); } - virtual void AfterTest() OVERRIDE {} + void AfterTest() override {} private: bool visible_; @@ -995,7 +916,7 @@ SINGLE_AND_MULTI_THREAD_TEST_F( // checkerboard. class LayerTreeHostAnimationTestCheckerboardDoesntStartAnimations : public LayerTreeHostAnimationTest { - virtual void SetupTree() OVERRIDE { + void SetupTree() override { LayerTreeHostAnimationTest::SetupTree(); content_ = FakeContentLayer::Create(&client_); content_->SetBounds(gfx::Size(4, 4)); @@ -1003,13 +924,13 @@ class LayerTreeHostAnimationTestCheckerboardDoesntStartAnimations layer_tree_host()->root_layer()->AddChild(content_); } - virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE { + void InitializeSettings(LayerTreeSettings* settings) override { // Make sure that drawing many times doesn't cause a checkerboarded // animation to start so we avoid flake in this test. settings->timeout_and_draw_when_animation_checkerboards = false; } - virtual void BeginTest() OVERRIDE { + void BeginTest() override { prevented_draw_ = 0; added_animations_ = 0; started_times_ = 0; @@ -1017,10 +938,9 @@ class LayerTreeHostAnimationTestCheckerboardDoesntStartAnimations PostSetNeedsCommitToMainThread(); } - virtual DrawResult PrepareToDrawOnThread( - LayerTreeHostImpl* host_impl, - LayerTreeHostImpl::FrameData* frame_data, - DrawResult draw_result) OVERRIDE { + DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, + LayerTreeHostImpl::FrameData* frame_data, + DrawResult draw_result) override { if (added_animations_ < 2) return draw_result; if (TestEnded()) @@ -1032,7 +952,7 @@ class LayerTreeHostAnimationTestCheckerboardDoesntStartAnimations return DRAW_ABORTED_CHECKERBOARD_ANIMATIONS; } - virtual void DidCommitAndDrawFrame() OVERRIDE { + void DidCommitAndDrawFrame() override { switch (layer_tree_host()->source_frame_number()) { case 1: // The animation is longer than 1 BeginFrame interval. @@ -1047,15 +967,15 @@ class LayerTreeHostAnimationTestCheckerboardDoesntStartAnimations } } - virtual void NotifyAnimationStarted( - base::TimeTicks monotonic_time, - Animation::TargetProperty target_property) OVERRIDE { + void NotifyAnimationStarted(base::TimeTicks monotonic_time, + Animation::TargetProperty target_property, + int group) override { if (TestEnded()) return; started_times_++; } - virtual void AfterTest() OVERRIDE { + void AfterTest() override { // Make sure we tried to draw the second animation but failed. EXPECT_LT(0, prevented_draw_); // The first animation should be started, but the second should not because @@ -1073,38 +993,42 @@ class LayerTreeHostAnimationTestCheckerboardDoesntStartAnimations MULTI_THREAD_TEST_F( LayerTreeHostAnimationTestCheckerboardDoesntStartAnimations); -// Verifies that when scroll offset is animated on the impl thread, updates -// are sent back to the main thread. +// Verifies that scroll offset animations are only accepted when impl-scrolling +// is supported, and that when scroll offset animations are accepted, +// scroll offset updates are sent back to the main thread. class LayerTreeHostAnimationTestScrollOffsetChangesArePropagated : public LayerTreeHostAnimationTest { public: LayerTreeHostAnimationTestScrollOffsetChangesArePropagated() {} - virtual void SetupTree() OVERRIDE { + void SetupTree() override { LayerTreeHostAnimationTest::SetupTree(); scroll_layer_ = FakeContentLayer::Create(&client_); scroll_layer_->SetScrollClipLayerId(layer_tree_host()->root_layer()->id()); scroll_layer_->SetBounds(gfx::Size(1000, 1000)); - scroll_layer_->SetScrollOffset(gfx::Vector2d(10, 20)); + scroll_layer_->SetScrollOffset(gfx::ScrollOffset(10, 20)); layer_tree_host()->root_layer()->AddChild(scroll_layer_); } - virtual void BeginTest() OVERRIDE { - PostSetNeedsCommitToMainThread(); - } + void BeginTest() override { PostSetNeedsCommitToMainThread(); } - virtual void DidCommit() OVERRIDE { + void DidCommit() override { switch (layer_tree_host()->source_frame_number()) { case 1: { scoped_ptr<ScrollOffsetAnimationCurve> curve( ScrollOffsetAnimationCurve::Create( - gfx::Vector2dF(500.f, 550.f), + gfx::ScrollOffset(500.f, 550.f), EaseInOutTimingFunction::Create())); - scoped_ptr<Animation> animation(Animation::Create( - curve.PassAs<AnimationCurve>(), 1, 0, Animation::ScrollOffset)); + scoped_ptr<Animation> animation( + Animation::Create(curve.Pass(), 1, 0, Animation::ScrollOffset)); animation->set_needs_synchronized_start_time(true); - scroll_layer_->AddAnimation(animation.Pass()); + bool animation_added = scroll_layer_->AddAnimation(animation.Pass()); + bool impl_scrolling_supported = + layer_tree_host()->proxy()->SupportsImplScrolling(); + EXPECT_EQ(impl_scrolling_supported, animation_added); + if (!impl_scrolling_supported) + EndTest(); break; } default: @@ -1114,86 +1038,15 @@ class LayerTreeHostAnimationTestScrollOffsetChangesArePropagated } } - virtual void AfterTest() OVERRIDE {} + void AfterTest() override {} private: FakeContentLayerClient client_; scoped_refptr<FakeContentLayer> scroll_layer_; }; -// SingleThreadProxy doesn't send scroll updates from LayerTreeHostImpl to -// LayerTreeHost. -MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestScrollOffsetChangesArePropagated); - -// Ensure that animation time is correctly updated when animations are frozen -// because of checkerboarding. -class LayerTreeHostAnimationTestFrozenAnimationTickTime - : public LayerTreeHostAnimationTest { - public: - LayerTreeHostAnimationTestFrozenAnimationTickTime() - : started_animating_(false), num_commits_(0), num_draw_attempts_(2) {} - - virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE { - // Make sure that drawing many times doesn't cause a checkerboarded - // animation to start so we avoid flake in this test. - settings->timeout_and_draw_when_animation_checkerboards = false; - } - - virtual void BeginTest() OVERRIDE { - PostAddAnimationToMainThread(layer_tree_host()->root_layer()); - } - - virtual void Animate(base::TimeTicks monotonic_time) OVERRIDE { - last_main_thread_tick_time_ = monotonic_time; - } - - virtual void AnimateLayers(LayerTreeHostImpl* host_impl, - base::TimeTicks monotonic_time) OVERRIDE { - if (TestEnded()) - return; - if (!started_animating_) { - started_animating_ = true; - expected_impl_tick_time_ = monotonic_time; - } else { - EXPECT_EQ(expected_impl_tick_time_, monotonic_time); - if (num_commits_ > 2) - EndTest(); - } - } - - virtual DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, - LayerTreeHostImpl::FrameData* frame, - DrawResult draw_result) OVERRIDE { - if (TestEnded()) - return draw_result; - num_draw_attempts_++; - if (num_draw_attempts_ > 2) { - num_draw_attempts_ = 0; - PostSetNeedsCommitToMainThread(); - } - return DRAW_ABORTED_CHECKERBOARD_ANIMATIONS; - } - - virtual void BeginCommitOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { - if (!started_animating_) - return; - expected_impl_tick_time_ = - std::max(expected_impl_tick_time_, last_main_thread_tick_time_); - num_commits_++; - } - - virtual void AfterTest() OVERRIDE {} - - private: - bool started_animating_; - int num_commits_; - int num_draw_attempts_; - base::TimeTicks last_main_thread_tick_time_; - base::TimeTicks expected_impl_tick_time_; -}; - -// Only the non-impl-paint multi-threaded compositor freezes animations. -MULTI_THREAD_NOIMPL_TEST_F(LayerTreeHostAnimationTestFrozenAnimationTickTime); +SINGLE_AND_MULTI_THREAD_TEST_F( + LayerTreeHostAnimationTestScrollOffsetChangesArePropagated); // When animations are simultaneously added to an existing layer and to a new // layer, they should start at the same time, even when there's already a @@ -1204,9 +1057,9 @@ class LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers() : frame_count_with_pending_tree_(0) {} - virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } + void BeginTest() override { PostSetNeedsCommitToMainThread(); } - virtual void DidCommit() OVERRIDE { + void DidCommit() override { if (layer_tree_host()->source_frame_number() == 1) { AddAnimatedTransformToLayer(layer_tree_host()->root_layer(), 4, 1, 1); } else if (layer_tree_host()->source_frame_number() == 2) { @@ -1217,61 +1070,68 @@ class LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers layer_tree_host()->root_layer()->AddChild(layer); layer->set_layer_animation_delegate(this); layer->SetBounds(gfx::Size(4, 4)); - AddOpacityTransitionToLayer(layer, 1, 0.f, 0.5f, true); + AddOpacityTransitionToLayer(layer.get(), 1, 0.f, 0.5f, true); } } - virtual void BeginCommitOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { - host_impl->BlockNotifyReadyToActivateForTesting(true); + void BeginCommitOnThread(LayerTreeHostImpl* host_impl) override { + if (host_impl->settings().impl_side_painting) + host_impl->BlockNotifyReadyToActivateForTesting(true); } - virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { + void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { // For the commit that added animations to new and existing layers, keep // blocking activation. We want to verify that even with activation blocked, // the animation on the layer that's already in the active tree won't get a // head start. - if (!host_impl->settings().impl_side_painting || - host_impl->pending_tree()->source_frame_number() != 2) + if (host_impl->settings().impl_side_painting && + host_impl->pending_tree()->source_frame_number() != 2) { host_impl->BlockNotifyReadyToActivateForTesting(false); + } } - virtual void WillBeginImplFrameOnThread(LayerTreeHostImpl* host_impl, - const BeginFrameArgs& args) OVERRIDE { + void WillBeginImplFrameOnThread(LayerTreeHostImpl* host_impl, + const BeginFrameArgs& args) override { if (!host_impl->pending_tree() || host_impl->pending_tree()->source_frame_number() != 2) return; frame_count_with_pending_tree_++; - if (frame_count_with_pending_tree_ == 2) + if (frame_count_with_pending_tree_ == 2 && + host_impl->settings().impl_side_painting) { host_impl->BlockNotifyReadyToActivateForTesting(false); + } } - virtual void UpdateAnimationState(LayerTreeHostImpl* host_impl, - bool has_unfinished_animation) OVERRIDE { - Animation* root_animation = host_impl->active_tree() - ->root_layer() - ->layer_animation_controller() - ->GetAnimation(Animation::Opacity); + void UpdateAnimationState(LayerTreeHostImpl* host_impl, + bool has_unfinished_animation) override { + LayerAnimationController* root_controller_impl = + host_impl->active_tree()->root_layer()->layer_animation_controller(); + Animation* root_animation = + root_controller_impl->GetAnimation(Animation::Opacity); if (!root_animation || root_animation->run_state() != Animation::Running) return; - Animation* child_animation = host_impl->active_tree() - ->root_layer() - ->children()[0] - ->layer_animation_controller() - ->GetAnimation(Animation::Opacity); + LayerAnimationController* child_controller_impl = + host_impl->active_tree()->root_layer()->children() + [0]->layer_animation_controller(); + Animation* child_animation = + child_controller_impl->GetAnimation(Animation::Opacity); EXPECT_EQ(Animation::Running, child_animation->run_state()); EXPECT_EQ(root_animation->start_time(), child_animation->start_time()); + root_controller_impl->AbortAnimations(Animation::Opacity); + root_controller_impl->AbortAnimations(Animation::Transform); + child_controller_impl->AbortAnimations(Animation::Opacity); EndTest(); } - virtual void AfterTest() OVERRIDE {} + void AfterTest() override {} private: int frame_count_with_pending_tree_; }; -SINGLE_AND_MULTI_THREAD_TEST_F( +SINGLE_AND_MULTI_THREAD_BLOCKNOTIFY_TEST_F( LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers); class LayerTreeHostAnimationTestAddAnimationAfterAnimating @@ -1280,16 +1140,16 @@ class LayerTreeHostAnimationTestAddAnimationAfterAnimating LayerTreeHostAnimationTestAddAnimationAfterAnimating() : num_swap_buffers_(0) {} - virtual void SetupTree() OVERRIDE { + void SetupTree() override { LayerTreeHostAnimationTest::SetupTree(); content_ = Layer::Create(); content_->SetBounds(gfx::Size(4, 4)); layer_tree_host()->root_layer()->AddChild(content_); } - virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } + void BeginTest() override { PostSetNeedsCommitToMainThread(); } - virtual void DidCommit() OVERRIDE { + void DidCommit() override { switch (layer_tree_host()->source_frame_number()) { case 1: // First frame: add an animation to the root layer. @@ -1303,8 +1163,7 @@ class LayerTreeHostAnimationTestAddAnimationAfterAnimating } } - virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, - bool result) OVERRIDE { + void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override { // After both animations have started, verify that they have valid // start times. num_swap_buffers_++; @@ -1329,7 +1188,7 @@ class LayerTreeHostAnimationTestAddAnimationAfterAnimating } } - virtual void AfterTest() OVERRIDE {} + void AfterTest() override {} private: scoped_refptr<Layer> content_; diff --git a/chromium/cc/trees/layer_tree_host_unittest_context.cc b/chromium/cc/trees/layer_tree_host_unittest_context.cc index 879e5347e31..b12a8da62cb 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_context.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_context.cc @@ -18,6 +18,7 @@ #include "cc/layers/video_layer.h" #include "cc/layers/video_layer_impl.h" #include "cc/output/filter_operations.h" +#include "cc/resources/single_release_callback.h" #include "cc/test/fake_content_layer.h" #include "cc/test/fake_content_layer_client.h" #include "cc/test/fake_content_layer_impl.h" @@ -27,6 +28,8 @@ #include "cc/test/fake_output_surface.h" #include "cc/test/fake_output_surface_client.h" #include "cc/test/fake_painted_scrollbar_layer.h" +#include "cc/test/fake_picture_layer.h" +#include "cc/test/fake_picture_layer_impl.h" #include "cc/test/fake_scoped_ui_resource.h" #include "cc/test/fake_scrollbar.h" #include "cc/test/fake_video_frame_provider.h" @@ -60,11 +63,15 @@ class LayerTreeHostContextTest : public LayerTreeTest { times_create_failed_(0), committed_at_least_once_(false), context_should_support_io_surface_(false), - fallback_context_works_(false) { + fallback_context_works_(false), + async_output_surface_creation_(false) { media::InitializeMediaLibraryForTesting(); } void LoseContext() { + // For sanity-checking tests, they should only call this when the + // context is not lost. + CHECK(context3d_); context3d_->loseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB, GL_INNOCENT_CONTEXT_RESET_ARB); context3d_ = NULL; @@ -74,12 +81,12 @@ class LayerTreeHostContextTest : public LayerTreeTest { return TestWebGraphicsContext3D::Create(); } - virtual scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(bool fallback) - OVERRIDE { + scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface( + bool fallback) override { if (times_to_fail_create_) { --times_to_fail_create_; ExpectCreateToFail(); - return scoped_ptr<FakeOutputSurface>(); + return nullptr; } scoped_ptr<TestWebGraphicsContext3D> context3d = CreateContext3d(); @@ -96,10 +103,16 @@ class LayerTreeHostContextTest : public LayerTreeTest { return FakeOutputSurface::Create3d(context3d.Pass()); } - virtual DrawResult PrepareToDrawOnThread( - LayerTreeHostImpl* host_impl, - LayerTreeHostImpl::FrameData* frame, - DrawResult draw_result) OVERRIDE { + DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, + LayerTreeHostImpl::FrameData* frame, + DrawResult draw_result) override { + if (draw_result == DRAW_ABORTED_MISSING_HIGH_RES_CONTENT) { + // Only valid for single-threaded impl-side painting, which activates + // immediately and will try to draw again when content has finished. + DCHECK(!host_impl->proxy()->HasImplThread()); + DCHECK(layer_tree_host()->settings().impl_side_painting); + return draw_result; + } EXPECT_EQ(DRAW_SUCCESS, draw_result); if (!times_to_lose_during_draw_) return draw_result; @@ -113,7 +126,7 @@ class LayerTreeHostContextTest : public LayerTreeTest { return draw_result; } - virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { + void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { committed_at_least_once_ = true; if (!times_to_lose_during_commit_) @@ -125,11 +138,9 @@ class LayerTreeHostContextTest : public LayerTreeTest { times_to_fail_recreate_ = 0; } - virtual void DidFailToInitializeOutputSurface() OVERRIDE { - ++times_create_failed_; - } + void DidFailToInitializeOutputSurface() override { ++times_create_failed_; } - virtual void TearDown() OVERRIDE { + virtual void TearDown() override { LayerTreeTest::TearDown(); EXPECT_EQ(times_to_expect_create_failed_, times_create_failed_); } @@ -147,6 +158,7 @@ class LayerTreeHostContextTest : public LayerTreeTest { bool committed_at_least_once_; bool context_should_support_io_surface_; bool fallback_context_works_; + bool async_output_surface_creation_; }; class LayerTreeHostContextTestLostContextSucceeds @@ -160,9 +172,27 @@ class LayerTreeHostContextTestLostContextSucceeds recovered_context_(true), first_initialized_(false) {} - virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } + void BeginTest() override { PostSetNeedsCommitToMainThread(); } - virtual void DidInitializeOutputSurface() OVERRIDE { + void RequestNewOutputSurface(bool fallback) override { + if (async_output_surface_creation_) { + MainThreadTaskRunner()->PostTask( + FROM_HERE, + base::Bind(&LayerTreeHostContextTestLostContextSucceeds:: + CreateAndSetOutputSurface, + base::Unretained(this), + fallback)); + } else { + CreateAndSetOutputSurface(fallback); + } + } + + void CreateAndSetOutputSurface(bool fallback) { + layer_tree_host()->SetOutputSurface( + LayerTreeHostContextTest::CreateOutputSurface(fallback)); + } + + void DidInitializeOutputSurface() override { if (first_initialized_) ++num_losses_; else @@ -171,9 +201,9 @@ class LayerTreeHostContextTestLostContextSucceeds recovered_context_ = true; } - virtual void AfterTest() OVERRIDE { EXPECT_EQ(7u, test_case_); } + void AfterTest() override { EXPECT_EQ(11u, test_case_); } - virtual void DidCommitAndDrawFrame() OVERRIDE { + void DidCommitAndDrawFrame() override { // If the last frame had a context loss, then we'll commit again to // recover. if (!recovered_context_) @@ -200,45 +230,88 @@ class LayerTreeHostContextTestLostContextSucceeds static const TestCase kTests[] = { // Losing the context and failing to recreate it (or losing it again // immediately) a small number of times should succeed. - {1, // times_to_lose_during_commit + { + 1, // times_to_lose_during_commit 0, // times_to_lose_during_draw 0, // times_to_fail_recreate false, // fallback_context_works + false, // async_output_surface_creation }, - {0, // times_to_lose_during_commit + { + 0, // times_to_lose_during_commit 1, // times_to_lose_during_draw 0, // times_to_fail_recreate false, // fallback_context_works + false, // async_output_surface_creation }, - {1, // times_to_lose_during_commit + { + 1, // times_to_lose_during_commit 0, // times_to_lose_during_draw 3, // times_to_fail_recreate false, // fallback_context_works + false, // async_output_surface_creation + }, + { + 0, // times_to_lose_during_commit + 1, // times_to_lose_during_draw + 3, // times_to_fail_recreate + false, // fallback_context_works + false, // async_output_surface_creation }, - {0, // times_to_lose_during_commit + { + 0, // times_to_lose_during_commit 1, // times_to_lose_during_draw 3, // times_to_fail_recreate false, // fallback_context_works + true, // async_output_surface_creation }, // Losing the context and recreating it any number of times should // succeed. - {10, // times_to_lose_during_commit + { + 10, // times_to_lose_during_commit + 0, // times_to_lose_during_draw + 0, // times_to_fail_recreate + false, // fallback_context_works + false, // async_output_surface_creation + }, + { + 0, // times_to_lose_during_commit + 10, // times_to_lose_during_draw + 0, // times_to_fail_recreate + false, // fallback_context_works + false, // async_output_surface_creation + }, + { + 10, // times_to_lose_during_commit 0, // times_to_lose_during_draw 0, // times_to_fail_recreate false, // fallback_context_works + true, // async_output_surface_creation }, - {0, // times_to_lose_during_commit + { + 0, // times_to_lose_during_commit 10, // times_to_lose_during_draw 0, // times_to_fail_recreate false, // fallback_context_works + true, // async_output_surface_creation }, // Losing the context, failing to reinitialize it, and making a fallback // context should work. - {0, // times_to_lose_during_commit + { + 0, // times_to_lose_during_commit + 1, // times_to_lose_during_draw + 0, // times_to_fail_recreate + true, // fallback_context_works + false, // async_output_surface_creation + }, + { + 0, // times_to_lose_during_commit 1, // times_to_lose_during_draw 0, // times_to_fail_recreate true, // fallback_context_works - }, }; + true, // async_output_surface_creation + }, + }; if (test_case_ >= arraysize(kTests)) return false; @@ -252,6 +325,8 @@ class LayerTreeHostContextTestLostContextSucceeds times_to_lose_during_draw_ = kTests[test_case_].times_to_lose_during_draw; times_to_fail_recreate_ = kTests[test_case_].times_to_fail_recreate; fallback_context_works_ = kTests[test_case_].fallback_context_works; + async_output_surface_creation_ = + kTests[test_case_].async_output_surface_creation; ++test_case_; return true; } @@ -261,6 +336,7 @@ class LayerTreeHostContextTestLostContextSucceeds int times_to_lose_during_draw; int times_to_fail_recreate; bool fallback_context_works; + bool async_output_surface_creation; }; protected: @@ -279,72 +355,228 @@ class LayerTreeHostClientNotReadyDoesNotCreateOutputSurface LayerTreeHostClientNotReadyDoesNotCreateOutputSurface() : LayerTreeHostContextTest() {} - virtual void WillBeginTest() OVERRIDE { + void WillBeginTest() override { // Override and do not signal SetLayerTreeHostClientReady. } - virtual void BeginTest() OVERRIDE { + void BeginTest() override { PostSetNeedsCommitToMainThread(); EndTest(); } - virtual scoped_ptr<OutputSurface> CreateOutputSurface(bool fallback) - OVERRIDE { + scoped_ptr<OutputSurface> CreateOutputSurface(bool fallback) override { EXPECT_TRUE(false); - return scoped_ptr<OutputSurface>(); + return nullptr; + } + + void DidInitializeOutputSurface() override { EXPECT_TRUE(false); } + + void AfterTest() override {} +}; + +SINGLE_AND_MULTI_THREAD_TEST_F( + LayerTreeHostClientNotReadyDoesNotCreateOutputSurface); + +class MultipleCompositeDoesNotCreateOutputSurface + : public LayerTreeHostContextTest { + public: + MultipleCompositeDoesNotCreateOutputSurface() + : LayerTreeHostContextTest(), request_count_(0) {} + + void InitializeSettings(LayerTreeSettings* settings) override { + settings->single_thread_proxy_scheduler = false; + } + + void RequestNewOutputSurface(bool fallback) override { + EXPECT_GE(1, ++request_count_); + EndTest(); + } + + void BeginTest() override { + layer_tree_host()->Composite(base::TimeTicks()); + layer_tree_host()->Composite(base::TimeTicks()); + } + + scoped_ptr<OutputSurface> CreateOutputSurface(bool fallback) override { + EXPECT_TRUE(false); + return nullptr; + } + + void DidInitializeOutputSurface() override { EXPECT_TRUE(false); } + + void AfterTest() override {} + + int request_count_; +}; + +SINGLE_THREAD_NOIMPL_TEST_F(MultipleCompositeDoesNotCreateOutputSurface); + +class FailedCreateDoesNotCreateExtraOutputSurface + : public LayerTreeHostContextTest { + public: + FailedCreateDoesNotCreateExtraOutputSurface() + : LayerTreeHostContextTest(), request_count_(0) {} + + void InitializeSettings(LayerTreeSettings* settings) override { + settings->single_thread_proxy_scheduler = false; + } + + void RequestNewOutputSurface(bool fallback) override { + if (request_count_ == 0) { + ExpectCreateToFail(); + layer_tree_host()->SetOutputSurface(nullptr); + } + EXPECT_GE(2, ++request_count_); + EndTest(); + } + + void BeginTest() override { + layer_tree_host()->Composite(base::TimeTicks()); + layer_tree_host()->Composite(base::TimeTicks()); + } + + scoped_ptr<OutputSurface> CreateOutputSurface(bool fallback) override { + EXPECT_TRUE(false); + return nullptr; + } + + void DidInitializeOutputSurface() override { EXPECT_TRUE(false); } + + void AfterTest() override {} + + int request_count_; +}; + +SINGLE_THREAD_NOIMPL_TEST_F(FailedCreateDoesNotCreateExtraOutputSurface); + +class LayerTreeHostContextTestCommitAfterDelayedOutputSurface + : public LayerTreeHostContextTest { + public: + LayerTreeHostContextTestCommitAfterDelayedOutputSurface() + : LayerTreeHostContextTest(), creating_output_(false) {} + + void InitializeSettings(LayerTreeSettings* settings) override { + settings->single_thread_proxy_scheduler = false; + } + + void RequestNewOutputSurface(bool fallback) override { + MainThreadTaskRunner()->PostTask( + FROM_HERE, + base::Bind(&LayerTreeHostContextTestCommitAfterDelayedOutputSurface:: + CreateAndSetOutputSurface, + base::Unretained(this), + fallback)); + } + + void CreateAndSetOutputSurface(bool fallback) { + creating_output_ = true; + layer_tree_host()->SetOutputSurface( + LayerTreeHostContextTest::CreateOutputSurface(fallback)); + } + + void BeginTest() override { layer_tree_host()->Composite(base::TimeTicks()); } + + void ScheduleComposite() override { + if (creating_output_) + EndTest(); } - virtual void DidInitializeOutputSurface() OVERRIDE { EXPECT_TRUE(false); } + void AfterTest() override {} - virtual void AfterTest() OVERRIDE { + bool creating_output_; +}; + +SINGLE_THREAD_NOIMPL_TEST_F( + LayerTreeHostContextTestCommitAfterDelayedOutputSurface); + +class LayerTreeHostContextTestAvoidUnnecessaryComposite + : public LayerTreeHostContextTest { + public: + LayerTreeHostContextTestAvoidUnnecessaryComposite() + : LayerTreeHostContextTest(), in_composite_(false) {} + + void InitializeSettings(LayerTreeSettings* settings) override { + settings->single_thread_proxy_scheduler = false; + } + + void RequestNewOutputSurface(bool fallback) override { + layer_tree_host()->SetOutputSurface( + LayerTreeHostContextTest::CreateOutputSurface(fallback)); + EndTest(); + } + + void BeginTest() override { + in_composite_ = true; + layer_tree_host()->Composite(base::TimeTicks()); + in_composite_ = false; } + + void ScheduleComposite() override { EXPECT_FALSE(in_composite_); } + + void AfterTest() override {} + + bool in_composite_; }; -MULTI_THREAD_TEST_F(LayerTreeHostClientNotReadyDoesNotCreateOutputSurface); +SINGLE_THREAD_NOIMPL_TEST_F(LayerTreeHostContextTestAvoidUnnecessaryComposite); class LayerTreeHostContextTestLostContextSucceedsWithContent : public LayerTreeHostContextTestLostContextSucceeds { public: - virtual void SetupTree() OVERRIDE { + void SetupTree() override { root_ = Layer::Create(); root_->SetBounds(gfx::Size(10, 10)); root_->SetIsDrawable(true); - content_ = FakeContentLayer::Create(&client_); - content_->SetBounds(gfx::Size(10, 10)); - content_->SetIsDrawable(true); + // Paint non-solid color. + SkPaint paint; + paint.setColor(SkColorSetARGB(100, 80, 200, 200)); + client_.add_draw_rect(gfx::Rect(0, 0, 5, 5), paint); - root_->AddChild(content_); + if (layer_tree_host()->settings().impl_side_painting) + layer_ = FakePictureLayer::Create(&client_); + else + layer_ = FakeContentLayer::Create(&client_); + layer_->SetBounds(gfx::Size(10, 10)); + layer_->SetIsDrawable(true); + + root_->AddChild(layer_); layer_tree_host()->SetRootLayer(root_); LayerTreeHostContextTest::SetupTree(); } - virtual void InvalidateAndSetNeedsCommit() OVERRIDE { + void InvalidateAndSetNeedsCommit() override { // Invalidate the render surface so we don't try to use a cached copy of the // surface. We want to make sure to test the drawing paths for drawing to // a child surface. - content_->SetNeedsDisplay(); + layer_->SetNeedsDisplay(); LayerTreeHostContextTestLostContextSucceeds::InvalidateAndSetNeedsCommit(); } - virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { - FakeContentLayerImpl* content_impl = static_cast<FakeContentLayerImpl*>( - host_impl->active_tree()->root_layer()->children()[0]); - // Even though the context was lost, we should have a resource. The - // TestWebGraphicsContext3D ensures that this resource is created with - // the active context. - EXPECT_TRUE(content_impl->HaveResourceForTileAt(0, 0)); + void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { + if (!host_impl->settings().impl_side_painting) { + FakeContentLayerImpl* content_impl = static_cast<FakeContentLayerImpl*>( + host_impl->active_tree()->root_layer()->children()[0]); + // Even though the context was lost, we should have a resource. The + // TestWebGraphicsContext3D ensures that this resource is created with + // the active context. + EXPECT_TRUE(content_impl->HaveResourceForTileAt(0, 0)); + } else { + FakePictureLayerImpl* picture_impl = static_cast<FakePictureLayerImpl*>( + host_impl->active_tree()->root_layer()->children()[0]); + EXPECT_TRUE(picture_impl->HighResTiling()->TileAt(0, 0)->IsReadyToDraw()); + } } protected: FakeContentLayerClient client_; scoped_refptr<Layer> root_; - scoped_refptr<ContentLayer> content_; + scoped_refptr<Layer> layer_; }; -// This test uses TiledLayer to check for a working context. -SINGLE_AND_MULTI_THREAD_NOIMPL_TEST_F( +// This test uses TiledLayer and PictureLayer to check for a working context. +SINGLE_AND_MULTI_THREAD_TEST_F( LayerTreeHostContextTestLostContextSucceedsWithContent); class LayerTreeHostContextTestCreateOutputSurfaceFails @@ -358,15 +590,14 @@ class LayerTreeHostContextTestCreateOutputSurfaceFails : times_to_fail_(times_to_fail), expect_fallback_attempt_(expect_fallback_attempt), did_attempt_fallback_(false), - times_initialized_(0) {} - - virtual void BeginTest() OVERRIDE { + times_initialized_(0) { times_to_fail_create_ = times_to_fail_; - PostSetNeedsCommitToMainThread(); } - virtual scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(bool fallback) - OVERRIDE { + void BeginTest() override { PostSetNeedsCommitToMainThread(); } + + scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface( + bool fallback) override { scoped_ptr<FakeOutputSurface> surface = LayerTreeHostContextTest::CreateFakeOutputSurface(fallback); @@ -377,13 +608,11 @@ class LayerTreeHostContextTestCreateOutputSurfaceFails return surface.Pass(); } - virtual void DidInitializeOutputSurface() OVERRIDE { times_initialized_++; } + void DidInitializeOutputSurface() override { times_initialized_++; } - virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { - EndTest(); - } + void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { EndTest(); } - virtual void AfterTest() OVERRIDE { + void AfterTest() override { EXPECT_EQ(times_to_fail_, times_create_failed_); EXPECT_NE(0, times_initialized_); EXPECT_EQ(expect_fallback_attempt_, did_attempt_fallback_); @@ -423,17 +652,30 @@ class LayerTreeHostContextTestLostContextAndEvictTextures public: LayerTreeHostContextTestLostContextAndEvictTextures() : LayerTreeHostContextTest(), - layer_(FakeContentLayer::Create(&client_)), impl_host_(0), - num_commits_(0) {} + num_commits_(0), + lost_context_(false) {} + + void SetupTree() override { + // Paint non-solid color. + SkPaint paint; + paint.setColor(SkColorSetARGB(100, 80, 200, 200)); + client_.add_draw_rect(gfx::Rect(0, 0, 5, 5), paint); + + if (layer_tree_host()->settings().impl_side_painting) { + picture_layer_ = FakePictureLayer::Create(&client_); + picture_layer_->SetBounds(gfx::Size(10, 20)); + layer_tree_host()->SetRootLayer(picture_layer_); + } else { + content_layer_ = FakeContentLayer::Create(&client_); + content_layer_->SetBounds(gfx::Size(10, 20)); + layer_tree_host()->SetRootLayer(content_layer_); + } - virtual void SetupTree() OVERRIDE { - layer_->SetBounds(gfx::Size(10, 20)); - layer_tree_host()->SetRootLayer(layer_); LayerTreeHostContextTest::SetupTree(); } - virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } + void BeginTest() override { PostSetNeedsCommitToMainThread(); } void PostEvictTextures() { if (HasImplThread()) { @@ -450,37 +692,61 @@ class LayerTreeHostContextTestLostContextAndEvictTextures void EvictTexturesOnImplThread() { impl_host_->EvictTexturesForTesting(); - if (lose_after_evict_) + + if (lose_after_evict_) { LoseContext(); + lost_context_ = true; + } } - virtual void DidCommitAndDrawFrame() OVERRIDE { + void DidCommitAndDrawFrame() override { if (num_commits_ > 1) return; - EXPECT_TRUE(layer_->HaveBackingAt(0, 0)); + if (!layer_tree_host()->settings().impl_side_painting) { + EXPECT_TRUE(content_layer_->HaveBackingAt(0, 0)); + } PostEvictTextures(); } - virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE { + void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { LayerTreeHostContextTest::CommitCompleteOnThread(impl); if (num_commits_ > 1) return; ++num_commits_; - if (!lose_after_evict_) + if (!lose_after_evict_) { LoseContext(); + lost_context_ = true; + } + } + + void DrawLayersOnThread(LayerTreeHostImpl* impl) override { + if (impl->settings().impl_side_painting) { + FakePictureLayerImpl* picture_impl = + static_cast<FakePictureLayerImpl*>(impl->active_tree()->root_layer()); + EXPECT_TRUE(picture_impl->HighResTiling()->TileAt(0, 0)->IsReadyToDraw()); + } else { + FakeContentLayerImpl* content_impl = + static_cast<FakeContentLayerImpl*>(impl->active_tree()->root_layer()); + EXPECT_TRUE(content_impl->HaveResourceForTileAt(0, 0)); + } + impl_host_ = impl; + if (lost_context_) + EndTest(); } - virtual void DidInitializeOutputSurface() OVERRIDE { EndTest(); } + void DidInitializeOutputSurface() override {} - virtual void AfterTest() OVERRIDE {} + void AfterTest() override {} protected: bool lose_after_evict_; FakeContentLayerClient client_; - scoped_refptr<FakeContentLayer> layer_; + scoped_refptr<FakeContentLayer> content_layer_; + scoped_refptr<FakePictureLayer> picture_layer_; LayerTreeHostImpl* impl_host_; int num_commits_; + bool lost_context_; }; TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures, @@ -554,11 +820,9 @@ class LayerTreeHostContextTestLostContextWhileUpdatingResources : public LayerTreeHostContextTest { public: LayerTreeHostContextTestLostContextWhileUpdatingResources() - : parent_(FakeContentLayer::Create(&client_)), - num_children_(50), - times_to_lose_on_end_query_(3) {} + : num_children_(50), times_to_lose_on_end_query_(3) {} - virtual scoped_ptr<TestWebGraphicsContext3D> CreateContext3d() OVERRIDE { + scoped_ptr<TestWebGraphicsContext3D> CreateContext3d() override { scoped_ptr<TestWebGraphicsContext3D> context = LayerTreeHostContextTest::CreateContext3d(); if (times_to_lose_on_end_query_) { @@ -568,12 +832,20 @@ class LayerTreeHostContextTestLostContextWhileUpdatingResources return context.Pass(); } - virtual void SetupTree() OVERRIDE { + void SetupTree() override { + if (layer_tree_host()->settings().impl_side_painting) + parent_ = FakePictureLayer::Create(&client_); + else + parent_ = FakeContentLayer::Create(&client_); + parent_->SetBounds(gfx::Size(num_children_, 1)); for (int i = 0; i < num_children_; i++) { - scoped_refptr<FakeContentLayer> child = - FakeContentLayer::Create(&client_); + scoped_refptr<Layer> child; + if (layer_tree_host()->settings().impl_side_painting) + child = FakePictureLayer::Create(&client_); + else + child = FakeContentLayer::Create(&client_); child->SetPosition(gfx::PointF(i, 0.f)); child->SetBounds(gfx::Size(1, 1)); parent_->AddChild(child); @@ -583,20 +855,18 @@ class LayerTreeHostContextTestLostContextWhileUpdatingResources LayerTreeHostContextTest::SetupTree(); } - virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } + void BeginTest() override { PostSetNeedsCommitToMainThread(); } - virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { + void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { EXPECT_EQ(0, times_to_lose_on_end_query_); EndTest(); } - virtual void AfterTest() OVERRIDE { - EXPECT_EQ(0, times_to_lose_on_end_query_); - } + void AfterTest() override { EXPECT_EQ(0, times_to_lose_on_end_query_); } private: FakeContentLayerClient client_; - scoped_refptr<FakeContentLayer> parent_; + scoped_refptr<Layer> parent_; int num_children_; int times_to_lose_on_end_query_; }; @@ -609,10 +879,16 @@ class LayerTreeHostContextTestLayersNotified : public LayerTreeHostContextTest { LayerTreeHostContextTestLayersNotified() : LayerTreeHostContextTest(), num_commits_(0) {} - virtual void SetupTree() OVERRIDE { - root_ = FakeContentLayer::Create(&client_); - child_ = FakeContentLayer::Create(&client_); - grandchild_ = FakeContentLayer::Create(&client_); + void SetupTree() override { + if (layer_tree_host()->settings().impl_side_painting) { + root_ = FakePictureLayer::Create(&client_); + child_ = FakePictureLayer::Create(&client_); + grandchild_ = FakePictureLayer::Create(&client_); + } else { + root_ = FakeContentLayer::Create(&client_); + child_ = FakeContentLayer::Create(&client_); + grandchild_ = FakeContentLayer::Create(&client_); + } root_->AddChild(child_); child_->AddChild(grandchild_); @@ -621,32 +897,63 @@ class LayerTreeHostContextTestLayersNotified : public LayerTreeHostContextTest { LayerTreeHostContextTest::SetupTree(); } - virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } + void BeginTest() override { PostSetNeedsCommitToMainThread(); } - virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { + void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { LayerTreeHostContextTest::DidActivateTreeOnThread(host_impl); - FakeContentLayerImpl* root = static_cast<FakeContentLayerImpl*>( - host_impl->active_tree()->root_layer()); - FakeContentLayerImpl* child = - static_cast<FakeContentLayerImpl*>(root->children()[0]); - FakeContentLayerImpl* grandchild = - static_cast<FakeContentLayerImpl*>(child->children()[0]); + FakePictureLayerImpl* root_picture = NULL; + FakePictureLayerImpl* child_picture = NULL; + FakePictureLayerImpl* grandchild_picture = NULL; + FakeContentLayerImpl* root_content = NULL; + FakeContentLayerImpl* child_content = NULL; + FakeContentLayerImpl* grandchild_content = NULL; + + if (layer_tree_host()->settings().impl_side_painting) { + root_picture = static_cast<FakePictureLayerImpl*>( + host_impl->active_tree()->root_layer()); + child_picture = + static_cast<FakePictureLayerImpl*>(root_picture->children()[0]); + grandchild_picture = + static_cast<FakePictureLayerImpl*>(child_picture->children()[0]); + + } else { + root_content = static_cast<FakeContentLayerImpl*>( + host_impl->active_tree()->root_layer()); + child_content = + static_cast<FakeContentLayerImpl*>(root_content->children()[0]); + grandchild_content = + static_cast<FakeContentLayerImpl*>(child_content->children()[0]); + } ++num_commits_; switch (num_commits_) { case 1: - EXPECT_EQ(0u, root->lost_output_surface_count()); - EXPECT_EQ(0u, child->lost_output_surface_count()); - EXPECT_EQ(0u, grandchild->lost_output_surface_count()); + if (layer_tree_host()->settings().impl_side_painting) { + EXPECT_EQ(0u, root_picture->release_resources_count()); + EXPECT_EQ(0u, child_picture->release_resources_count()); + EXPECT_EQ(0u, grandchild_picture->release_resources_count()); + } else { + EXPECT_EQ(0u, root_content->lost_output_surface_count()); + EXPECT_EQ(0u, child_content->lost_output_surface_count()); + EXPECT_EQ(0u, grandchild_content->lost_output_surface_count()); + } + // Lose the context and struggle to recreate it. LoseContext(); times_to_fail_create_ = 1; break; case 2: - EXPECT_GE(1u, root->lost_output_surface_count()); - EXPECT_GE(1u, child->lost_output_surface_count()); - EXPECT_GE(1u, grandchild->lost_output_surface_count()); + if (layer_tree_host()->settings().impl_side_painting) { + EXPECT_TRUE(root_picture->release_resources_count()); + EXPECT_TRUE(child_picture->release_resources_count()); + EXPECT_TRUE(grandchild_picture->release_resources_count()); + } else { + EXPECT_TRUE(root_content->lost_output_surface_count()); + EXPECT_TRUE(child_content->lost_output_surface_count()); + EXPECT_TRUE(grandchild_content->lost_output_surface_count()); + } + EndTest(); break; default: @@ -654,15 +961,15 @@ class LayerTreeHostContextTestLayersNotified : public LayerTreeHostContextTest { } } - virtual void AfterTest() OVERRIDE {} + void AfterTest() override {} private: int num_commits_; FakeContentLayerClient client_; - scoped_refptr<FakeContentLayer> root_; - scoped_refptr<FakeContentLayer> child_; - scoped_refptr<FakeContentLayer> grandchild_; + scoped_refptr<Layer> root_; + scoped_refptr<Layer> child_; + scoped_refptr<Layer> grandchild_; }; SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostContextTestLayersNotified); @@ -676,14 +983,19 @@ class LayerTreeHostContextTestDontUseLostResources child_output_surface_ = FakeOutputSurface::Create3d(); child_output_surface_->BindToClient(&output_surface_client_); shared_bitmap_manager_.reset(new TestSharedBitmapManager()); - child_resource_provider_ = ResourceProvider::Create( - child_output_surface_.get(), shared_bitmap_manager_.get(), 0, false, 1, - false); + child_resource_provider_ = + ResourceProvider::Create(child_output_surface_.get(), + shared_bitmap_manager_.get(), + NULL, + NULL, + 0, + false, + 1); } static void EmptyReleaseCallback(unsigned sync_point, bool lost) {} - virtual void SetupTree() OVERRIDE { + void SetupTree() override { gpu::gles2::GLES2Interface* gl = child_output_surface_->context_provider()->ContextGL(); @@ -692,21 +1004,21 @@ class LayerTreeHostContextTestDontUseLostResources scoped_ptr<TestRenderPass> pass_for_quad = TestRenderPass::Create(); pass_for_quad->SetNew( // AppendOneOfEveryQuadType() makes a RenderPass quad with this id. - RenderPass::Id(2, 1), + RenderPassId(2, 1), gfx::Rect(0, 0, 10, 10), gfx::Rect(0, 0, 10, 10), gfx::Transform()); scoped_ptr<TestRenderPass> pass = TestRenderPass::Create(); - pass->SetNew(RenderPass::Id(1, 1), + pass->SetNew(RenderPassId(1, 1), gfx::Rect(0, 0, 10, 10), gfx::Rect(0, 0, 10, 10), gfx::Transform()); pass->AppendOneOfEveryQuadType(child_resource_provider_.get(), - RenderPass::Id(2, 1)); + RenderPassId(2, 1)); - frame_data->render_pass_list.push_back(pass_for_quad.PassAs<RenderPass>()); - frame_data->render_pass_list.push_back(pass.PassAs<RenderPass>()); + frame_data->render_pass_list.push_back(pass_for_quad.Pass()); + frame_data->render_pass_list.push_back(pass.Pass()); delegated_resource_collection_ = new DelegatedFrameResourceCollection; delegated_frame_provider_ = new DelegatedFrameProvider( @@ -716,7 +1028,7 @@ class LayerTreeHostContextTestDontUseLostResources child_resource_provider_->CreateResource( gfx::Size(4, 4), GL_CLAMP_TO_EDGE, - ResourceProvider::TextureUsageAny, + ResourceProvider::TextureHintImmutable, RGBA_8888); ResourceProvider::ScopedWriteLockGL lock(child_resource_provider_.get(), resource); @@ -735,10 +1047,14 @@ class LayerTreeHostContextTestDontUseLostResources delegated->SetIsDrawable(true); root->AddChild(delegated); - scoped_refptr<ContentLayer> content = ContentLayer::Create(&client_); - content->SetBounds(gfx::Size(10, 10)); - content->SetIsDrawable(true); - root->AddChild(content); + scoped_refptr<Layer> layer; + if (layer_tree_host()->settings().impl_side_painting) + layer = PictureLayer::Create(&client_); + else + layer = ContentLayer::Create(&client_); + layer->SetBounds(gfx::Size(10, 10)); + layer->SetIsDrawable(true); + root->AddChild(layer); scoped_refptr<TextureLayer> texture = TextureLayer::CreateForMailbox(NULL); texture->SetBounds(gfx::Size(10, 10)); @@ -750,30 +1066,37 @@ class LayerTreeHostContextTestDontUseLostResources EmptyReleaseCallback))); root->AddChild(texture); - scoped_refptr<ContentLayer> mask = ContentLayer::Create(&client_); + scoped_refptr<Layer> mask; + if (layer_tree_host()->settings().impl_side_painting) + mask = PictureLayer::Create(&client_); + else + mask = ContentLayer::Create(&client_); mask->SetBounds(gfx::Size(10, 10)); - scoped_refptr<ContentLayer> content_with_mask = - ContentLayer::Create(&client_); - content_with_mask->SetBounds(gfx::Size(10, 10)); - content_with_mask->SetIsDrawable(true); - content_with_mask->SetMaskLayer(mask.get()); - root->AddChild(content_with_mask); + scoped_refptr<Layer> layer_with_mask; + if (layer_tree_host()->settings().impl_side_painting) + layer_with_mask = PictureLayer::Create(&client_); + else + layer_with_mask = ContentLayer::Create(&client_); + layer_with_mask->SetBounds(gfx::Size(10, 10)); + layer_with_mask->SetIsDrawable(true); + layer_with_mask->SetMaskLayer(mask.get()); + root->AddChild(layer_with_mask); scoped_refptr<VideoLayer> video_color = - VideoLayer::Create(&color_frame_provider_); + VideoLayer::Create(&color_frame_provider_, media::VIDEO_ROTATION_0); video_color->SetBounds(gfx::Size(10, 10)); video_color->SetIsDrawable(true); root->AddChild(video_color); scoped_refptr<VideoLayer> video_hw = - VideoLayer::Create(&hw_frame_provider_); + VideoLayer::Create(&hw_frame_provider_, media::VIDEO_ROTATION_0); video_hw->SetBounds(gfx::Size(10, 10)); video_hw->SetIsDrawable(true); root->AddChild(video_hw); scoped_refptr<VideoLayer> video_scaled_hw = - VideoLayer::Create(&scaled_hw_frame_provider_); + VideoLayer::Create(&scaled_hw_frame_provider_, media::VIDEO_ROTATION_0); video_scaled_hw->SetBounds(gfx::Size(10, 10)); video_scaled_hw->SetIsDrawable(true); root->AddChild(video_scaled_hw); @@ -819,7 +1142,7 @@ class LayerTreeHostContextTestDontUseLostResources scoped_refptr<PaintedScrollbarLayer> scrollbar = PaintedScrollbarLayer::Create( - scoped_ptr<Scrollbar>(new FakeScrollbar).Pass(), content->id()); + scoped_ptr<Scrollbar>(new FakeScrollbar).Pass(), layer->id()); scrollbar->SetBounds(gfx::Size(10, 10)); scrollbar->SetIsDrawable(true); root->AddChild(scrollbar); @@ -828,9 +1151,9 @@ class LayerTreeHostContextTestDontUseLostResources LayerTreeHostContextTest::SetupTree(); } - virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } + void BeginTest() override { PostSetNeedsCommitToMainThread(); } - virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { + void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { LayerTreeHostContextTest::CommitCompleteOnThread(host_impl); if (host_impl->active_tree()->source_frame_number() == 3) { @@ -842,10 +1165,9 @@ class LayerTreeHostContextTestDontUseLostResources } } - virtual DrawResult PrepareToDrawOnThread( - LayerTreeHostImpl* host_impl, - LayerTreeHostImpl::FrameData* frame, - DrawResult draw_result) OVERRIDE { + DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, + LayerTreeHostImpl::FrameData* frame, + DrawResult draw_result) override { if (host_impl->active_tree()->source_frame_number() == 2) { // Lose the context during draw on the second commit. This will cause // a third commit to recover. @@ -854,8 +1176,8 @@ class LayerTreeHostContextTestDontUseLostResources return draw_result; } - virtual scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(bool fallback) - OVERRIDE { + scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface( + bool fallback) override { // This will get called twice: // First when we create the initial output surface... if (layer_tree_host()->source_frame_number() > 0) { @@ -865,7 +1187,7 @@ class LayerTreeHostContextTestDontUseLostResources return LayerTreeHostContextTest::CreateFakeOutputSurface(fallback); } - virtual void DidCommitAndDrawFrame() OVERRIDE { + void DidCommitAndDrawFrame() override { ASSERT_TRUE(layer_tree_host()->hud_layer()); // End the test once we know the 3nd frame drew. if (layer_tree_host()->source_frame_number() < 5) { @@ -876,7 +1198,7 @@ class LayerTreeHostContextTestDontUseLostResources } } - virtual void AfterTest() OVERRIDE { EXPECT_TRUE(lost_context_); } + void AfterTest() override { EXPECT_TRUE(lost_context_); } private: FakeContentLayerClient client_; @@ -905,7 +1227,7 @@ SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostContextTestDontUseLostResources); class ImplSidePaintingLayerTreeHostContextTest : public LayerTreeHostContextTest { public: - virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE { + void InitializeSettings(LayerTreeSettings* settings) override { settings->impl_side_painting = true; } }; @@ -913,7 +1235,7 @@ class ImplSidePaintingLayerTreeHostContextTest class LayerTreeHostContextTestImplSidePainting : public ImplSidePaintingLayerTreeHostContextTest { public: - virtual void SetupTree() OVERRIDE { + void SetupTree() override { scoped_refptr<Layer> root = Layer::Create(); root->SetBounds(gfx::Size(10, 10)); root->SetIsDrawable(true); @@ -927,14 +1249,14 @@ class LayerTreeHostContextTestImplSidePainting LayerTreeHostContextTest::SetupTree(); } - virtual void BeginTest() OVERRIDE { + void BeginTest() override { times_to_lose_during_commit_ = 1; PostSetNeedsCommitToMainThread(); } - virtual void AfterTest() OVERRIDE {} + void AfterTest() override {} - virtual void DidInitializeOutputSurface() OVERRIDE { EndTest(); } + void DidInitializeOutputSurface() override { EndTest(); } private: FakeContentLayerClient client_; @@ -946,7 +1268,7 @@ class ScrollbarLayerLostContext : public LayerTreeHostContextTest { public: ScrollbarLayerLostContext() : commits_(0) {} - virtual void BeginTest() OVERRIDE { + void BeginTest() override { scoped_refptr<Layer> scroll_layer = Layer::Create(); scrollbar_layer_ = FakePaintedScrollbarLayer::Create(false, true, scroll_layer->id()); @@ -956,9 +1278,9 @@ class ScrollbarLayerLostContext : public LayerTreeHostContextTest { PostSetNeedsCommitToMainThread(); } - virtual void AfterTest() OVERRIDE {} + void AfterTest() override {} - virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE { + void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { LayerTreeHostContextTest::CommitCompleteOnThread(impl); ++commits_; @@ -975,12 +1297,6 @@ class ScrollbarLayerLostContext : public LayerTreeHostContextTest { EXPECT_EQ(2, scrollbar_layer_->update_count()); EndTest(); break; - case 3: - // Single thread proxy issues extra commits after context lost. - // http://crbug.com/287250 - if (HasImplThread()) - NOTREACHED(); - break; default: NOTREACHED(); } @@ -996,11 +1312,11 @@ SINGLE_AND_MULTI_THREAD_TEST_F(ScrollbarLayerLostContext); class UIResourceLostTest : public LayerTreeHostContextTest { public: UIResourceLostTest() : time_step_(0) {} - virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE { + void InitializeSettings(LayerTreeSettings* settings) override { settings->texture_id_allocation_chunk_size = 1; } - virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } - virtual void AfterTest() OVERRIDE {} + void BeginTest() override { PostSetNeedsCommitToMainThread(); } + void AfterTest() override {} // This is called on the main thread after each commit and // DidActivateTreeOnThread, with the value of time_step_ at the time @@ -1024,12 +1340,10 @@ class UIResourceLostTest : public LayerTreeHostContextTest { void PostLoseContextToImplThread() { EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread()); - base::SingleThreadTaskRunner* task_runner = - HasImplThread() ? ImplThreadTaskRunner() - : base::MessageLoopProxy::current(); - task_runner->PostTask(FROM_HERE, - base::Bind(&LayerTreeHostContextTest::LoseContext, - base::Unretained(this))); + ImplThreadTaskRunner()->PostTask( + FROM_HERE, + base::Bind(&LayerTreeHostContextTest::LoseContext, + base::Unretained(this))); } protected: @@ -1049,7 +1363,7 @@ class UIResourceLostTestSimple : public UIResourceLostTest { // activated. virtual void StepCompleteOnImplThread(LayerTreeHostImpl* impl) = 0; - virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE { + void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { if (!layer_tree_host()->settings().impl_side_painting) { StepCompleteOnImplThread(impl); PostStepCompleteToMainThread(); @@ -1057,7 +1371,7 @@ class UIResourceLostTestSimple : public UIResourceLostTest { } } - virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE { + void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override { if (layer_tree_host()->settings().impl_side_painting) { StepCompleteOnImplThread(impl); PostStepCompleteToMainThread(); @@ -1069,7 +1383,7 @@ class UIResourceLostTestSimple : public UIResourceLostTest { // Losing context after an UI resource has been created. class UIResourceLostAfterCommit : public UIResourceLostTestSimple { public: - virtual void StepCompleteOnMainThread(int step) OVERRIDE { + void StepCompleteOnMainThread(int step) override { EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread()); switch (step) { case 0: @@ -1080,21 +1394,16 @@ class UIResourceLostAfterCommit : public UIResourceLostTestSimple { break; case 4: // Release resource before ending the test. - ui_resource_.reset(); + ui_resource_ = nullptr; EndTest(); break; case 5: - // Single thread proxy issues extra commits after context lost. - // http://crbug.com/287250 - if (HasImplThread()) - NOTREACHED(); - break; - case 6: NOTREACHED(); + break; } } - virtual void StepCompleteOnImplThread(LayerTreeHostImpl* impl) OVERRIDE { + void StepCompleteOnImplThread(LayerTreeHostImpl* impl) override { LayerTreeHostContextTest::CommitCompleteOnThread(impl); switch (time_step_) { case 1: @@ -1133,7 +1442,7 @@ class UIResourceLostBeforeCommit : public UIResourceLostTestSimple { public: UIResourceLostBeforeCommit() : test_id0_(0), test_id1_(0) {} - virtual void StepCompleteOnMainThread(int step) OVERRIDE { + void StepCompleteOnMainThread(int step) override { switch (step) { case 0: ui_resource_ = FakeScopedUIResource::Create(layer_tree_host()); @@ -1145,7 +1454,7 @@ class UIResourceLostBeforeCommit : public UIResourceLostTestSimple { // Currently one resource has been created. test_id0_ = ui_resource_->id(); // Delete this resource. - ui_resource_.reset(); + ui_resource_ = nullptr; // Create another resource. ui_resource_ = FakeScopedUIResource::Create(layer_tree_host()); test_id1_ = ui_resource_->id(); @@ -1156,7 +1465,7 @@ class UIResourceLostBeforeCommit : public UIResourceLostTestSimple { break; case 3: // Clear the manager of resources. - ui_resource_.reset(); + ui_resource_ = nullptr; PostSetNeedsCommitToMainThread(); break; case 4: @@ -1166,7 +1475,7 @@ class UIResourceLostBeforeCommit : public UIResourceLostTestSimple { // Sanity check the UIResourceId should not be 0. EXPECT_NE(0, test_id0_); // Usually ScopedUIResource are deleted from the manager in their - // destructor (so usually ui_resource_.reset()). But here we need + // destructor (so usually ui_resource_ = nullptr). But here we need // ui_resource_ for the next step, so call DeleteUIResource directly. layer_tree_host()->DeleteUIResource(test_id0_); // Delete the resouce and then lose the context. @@ -1174,21 +1483,16 @@ class UIResourceLostBeforeCommit : public UIResourceLostTestSimple { break; case 5: // Release resource before ending the test. - ui_resource_.reset(); + ui_resource_ = nullptr; EndTest(); break; case 6: - // Single thread proxy issues extra commits after context lost. - // http://crbug.com/287250 - if (HasImplThread()) - NOTREACHED(); - break; - case 8: NOTREACHED(); + break; } } - virtual void StepCompleteOnImplThread(LayerTreeHostImpl* impl) OVERRIDE { + void StepCompleteOnImplThread(LayerTreeHostImpl* impl) override { LayerTreeHostContextTest::CommitCompleteOnThread(impl); switch (time_step_) { case 1: @@ -1205,15 +1509,8 @@ class UIResourceLostBeforeCommit : public UIResourceLostTestSimple { // Sequence 2 (continued): // The previous resource should have been deleted. EXPECT_EQ(0u, impl->ResourceIdForUIResource(test_id0_)); - if (HasImplThread()) { - // The second resource should have been created. - EXPECT_NE(0u, impl->ResourceIdForUIResource(test_id1_)); - } else { - // The extra commit that happens at context lost in the single thread - // proxy changes the timing so that the resource has been destroyed. - // http://crbug.com/287250 - EXPECT_EQ(0u, impl->ResourceIdForUIResource(test_id1_)); - } + // The second resource should have been created. + EXPECT_NE(0u, impl->ResourceIdForUIResource(test_id1_)); // The second resource called the resource callback once and since the // context is lost, a "resource lost" callback was also issued. EXPECT_EQ(2, ui_resource_->resource_create_count); @@ -1241,7 +1538,7 @@ SINGLE_AND_MULTI_THREAD_TEST_F(UIResourceLostBeforeCommit); // Losing UI resource before the pending trees is activated but after the // commit. Impl-side-painting only. class UIResourceLostBeforeActivateTree : public UIResourceLostTest { - virtual void StepCompleteOnMainThread(int step) OVERRIDE { + void StepCompleteOnMainThread(int step) override { EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread()); switch (step) { case 0: @@ -1250,12 +1547,12 @@ class UIResourceLostBeforeActivateTree : public UIResourceLostTest { break; case 3: test_id_ = ui_resource_->id(); - ui_resource_.reset(); + ui_resource_ = nullptr; PostSetNeedsCommitToMainThread(); break; case 5: // Release resource before ending the test. - ui_resource_.reset(); + ui_resource_ = nullptr; EndTest(); break; case 6: @@ -1264,7 +1561,7 @@ class UIResourceLostBeforeActivateTree : public UIResourceLostTest { } } - virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE { + void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { LayerTreeHostContextTest::CommitCompleteOnThread(impl); switch (time_step_) { case 2: @@ -1276,7 +1573,7 @@ class UIResourceLostBeforeActivateTree : public UIResourceLostTest { } } - virtual void WillActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE { + void WillActivateTreeOnThread(LayerTreeHostImpl* impl) override { switch (time_step_) { case 1: // The resource creation callback has been called. @@ -1293,7 +1590,7 @@ class UIResourceLostBeforeActivateTree : public UIResourceLostTest { } } - virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE { + void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override { LayerTreeHostContextTest::DidActivateTreeOnThread(impl); switch (time_step_) { case 1: @@ -1332,7 +1629,7 @@ TEST_F(UIResourceLostBeforeActivateTree, // Resources evicted explicitly and by visibility changes. class UIResourceLostEviction : public UIResourceLostTestSimple { public: - virtual void StepCompleteOnMainThread(int step) OVERRIDE { + void StepCompleteOnMainThread(int step) override { EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread()); switch (step) { case 0: @@ -1346,7 +1643,7 @@ class UIResourceLostEviction : public UIResourceLostTestSimple { break; case 3: // Release resource before ending the test. - ui_resource_.reset(); + ui_resource_ = nullptr; EndTest(); break; case 4: @@ -1354,8 +1651,7 @@ class UIResourceLostEviction : public UIResourceLostTestSimple { } } - virtual void DidSetVisibleOnImplTree(LayerTreeHostImpl* impl, - bool visible) OVERRIDE { + void DidSetVisibleOnImplTree(LayerTreeHostImpl* impl, bool visible) override { TestWebGraphicsContext3D* context = TestContext(); if (!visible) { // All resources should have been evicted. @@ -1371,7 +1667,7 @@ class UIResourceLostEviction : public UIResourceLostTestSimple { } } - virtual void StepCompleteOnImplThread(LayerTreeHostImpl* impl) OVERRIDE { + void StepCompleteOnImplThread(LayerTreeHostImpl* impl) override { TestWebGraphicsContext3D* context = TestContext(); LayerTreeHostContextTest::CommitCompleteOnThread(impl); switch (time_step_) { @@ -1417,38 +1713,57 @@ class LayerTreeHostContextTestSurfaceCreateCallback : public LayerTreeHostContextTest { public: LayerTreeHostContextTestSurfaceCreateCallback() - : LayerTreeHostContextTest(), - layer_(FakeContentLayer::Create(&client_)) {} + : LayerTreeHostContextTest() {} + + void SetupTree() override { + if (layer_tree_host()->settings().impl_side_painting) { + picture_layer_ = FakePictureLayer::Create(&client_); + picture_layer_->SetBounds(gfx::Size(10, 20)); + layer_tree_host()->SetRootLayer(picture_layer_); + } else { + content_layer_ = FakeContentLayer::Create(&client_); + content_layer_->SetBounds(gfx::Size(10, 20)); + layer_tree_host()->SetRootLayer(content_layer_); + } - virtual void SetupTree() OVERRIDE { - layer_->SetBounds(gfx::Size(10, 20)); - layer_tree_host()->SetRootLayer(layer_); LayerTreeHostContextTest::SetupTree(); } - virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } + void BeginTest() override { PostSetNeedsCommitToMainThread(); } - virtual void DidCommit() OVERRIDE { + void DidCommit() override { switch (layer_tree_host()->source_frame_number()) { case 1: - EXPECT_EQ(1u, layer_->output_surface_created_count()); + if (layer_tree_host()->settings().impl_side_painting) + EXPECT_EQ(1u, picture_layer_->output_surface_created_count()); + else + EXPECT_EQ(1u, content_layer_->output_surface_created_count()); layer_tree_host()->SetNeedsCommit(); break; case 2: - EXPECT_EQ(1u, layer_->output_surface_created_count()); + if (layer_tree_host()->settings().impl_side_painting) + EXPECT_EQ(1u, picture_layer_->output_surface_created_count()); + else + EXPECT_EQ(1u, content_layer_->output_surface_created_count()); layer_tree_host()->SetNeedsCommit(); break; case 3: - EXPECT_EQ(1u, layer_->output_surface_created_count()); + if (layer_tree_host()->settings().impl_side_painting) + EXPECT_EQ(1u, picture_layer_->output_surface_created_count()); + else + EXPECT_EQ(1u, content_layer_->output_surface_created_count()); break; case 4: - EXPECT_EQ(2u, layer_->output_surface_created_count()); + if (layer_tree_host()->settings().impl_side_painting) + EXPECT_EQ(2u, picture_layer_->output_surface_created_count()); + else + EXPECT_EQ(2u, content_layer_->output_surface_created_count()); layer_tree_host()->SetNeedsCommit(); break; } } - virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE { + void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { LayerTreeHostContextTest::CommitCompleteOnThread(impl); switch (LastCommittedSourceFrameNumber(impl)) { case 0: @@ -1464,11 +1779,12 @@ class LayerTreeHostContextTestSurfaceCreateCallback } } - virtual void AfterTest() OVERRIDE {} + void AfterTest() override {} protected: FakeContentLayerClient client_; - scoped_refptr<FakeContentLayer> layer_; + scoped_refptr<FakePictureLayer> picture_layer_; + scoped_refptr<FakeContentLayer> content_layer_; }; SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostContextTestSurfaceCreateCallback); @@ -1476,12 +1792,12 @@ SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostContextTestSurfaceCreateCallback); class LayerTreeHostContextTestLoseAfterSendingBeginMainFrame : public LayerTreeHostContextTest { protected: - virtual void BeginTest() OVERRIDE { + void BeginTest() override { deferred_ = false; PostSetNeedsCommitToMainThread(); } - virtual void ScheduledActionWillSendBeginMainFrame() OVERRIDE { + void ScheduledActionWillSendBeginMainFrame() override { if (deferred_) return; deferred_ = true; @@ -1517,20 +1833,20 @@ class LayerTreeHostContextTestLoseAfterSendingBeginMainFrame layer_tree_host()->SetDeferCommits(defer_commits); } - virtual void WillBeginMainFrame() OVERRIDE { + void WillBeginMainFrame() override { // Don't begin a frame with a lost surface. EXPECT_FALSE(layer_tree_host()->output_surface_lost()); } - virtual void DidCommitAndDrawFrame() OVERRIDE { EndTest(); } + void DidCommitAndDrawFrame() override { EndTest(); } - virtual void AfterTest() OVERRIDE {} + void AfterTest() override {} bool deferred_; }; -// TODO(danakj): We don't use scheduler with SingleThreadProxy yet. -MULTI_THREAD_TEST_F(LayerTreeHostContextTestLoseAfterSendingBeginMainFrame); +SINGLE_AND_MULTI_THREAD_TEST_F( + LayerTreeHostContextTestLoseAfterSendingBeginMainFrame); } // namespace } // namespace cc diff --git a/chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc b/chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc index 12fc63128f0..1b68ccae1d6 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc @@ -21,7 +21,7 @@ class LayerTreeHostCopyRequestTest : public LayerTreeTest {}; class LayerTreeHostCopyRequestTestMultipleRequests : public LayerTreeHostCopyRequestTest { protected: - virtual void SetupTree() OVERRIDE { + void SetupTree() override { root = FakeContentLayer::Create(&client_); root->SetBounds(gfx::Size(20, 20)); @@ -33,9 +33,9 @@ class LayerTreeHostCopyRequestTestMultipleRequests LayerTreeHostCopyRequestTest::SetupTree(); } - virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } + void BeginTest() override { PostSetNeedsCommitToMainThread(); } - virtual void DidCommitAndDrawFrame() OVERRIDE { WaitForCallback(); } + void DidCommitAndDrawFrame() override { WaitForCallback(); } void WaitForCallback() { base::MessageLoop::current()->PostTask( @@ -101,10 +101,10 @@ class LayerTreeHostCopyRequestTestMultipleRequests callbacks_.push_back(result->size()); } - virtual void AfterTest() OVERRIDE { EXPECT_EQ(4u, callbacks_.size()); } + void AfterTest() override { EXPECT_EQ(4u, callbacks_.size()); } - virtual scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(bool fallback) - OVERRIDE { + scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface( + bool fallback) override { if (use_gl_renderer_) return FakeOutputSurface::Create3d(); return FakeOutputSurface::CreateSoftware( @@ -146,7 +146,7 @@ TEST_F(LayerTreeHostCopyRequestTestMultipleRequests, class LayerTreeHostCopyRequestTestLayerDestroyed : public LayerTreeHostCopyRequestTest { protected: - virtual void SetupTree() OVERRIDE { + void SetupTree() override { root_ = FakeContentLayer::Create(&client_); root_->SetBounds(gfx::Size(20, 20)); @@ -162,12 +162,12 @@ class LayerTreeHostCopyRequestTestLayerDestroyed LayerTreeHostCopyRequestTest::SetupTree(); } - virtual void BeginTest() OVERRIDE { + void BeginTest() override { callback_count_ = 0; PostSetNeedsCommitToMainThread(); } - virtual void DidCommit() OVERRIDE { + void DidCommit() override { int frame = layer_tree_host()->source_frame_number(); switch (frame) { case 1: @@ -224,7 +224,7 @@ class LayerTreeHostCopyRequestTestLayerDestroyed ++callback_count_; } - virtual void AfterTest() OVERRIDE {} + void AfterTest() override {} int callback_count_; FakeContentLayerClient client_; @@ -238,7 +238,7 @@ SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostCopyRequestTestLayerDestroyed); class LayerTreeHostCopyRequestTestInHiddenSubtree : public LayerTreeHostCopyRequestTest { protected: - virtual void SetupTree() OVERRIDE { + void SetupTree() override { root_ = FakeContentLayer::Create(&client_); root_->SetBounds(gfx::Size(20, 20)); @@ -267,7 +267,7 @@ class LayerTreeHostCopyRequestTestInHiddenSubtree base::Unretained(this)))); } - virtual void BeginTest() OVERRIDE { + void BeginTest() override { callback_count_ = 0; PostSetNeedsCommitToMainThread(); @@ -321,7 +321,7 @@ class LayerTreeHostCopyRequestTestInHiddenSubtree } } - virtual void AfterTest() OVERRIDE {} + void AfterTest() override {} int callback_count_; FakeContentLayerClient client_; @@ -337,7 +337,7 @@ SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F( class LayerTreeHostTestHiddenSurfaceNotAllocatedForSubtreeCopyRequest : public LayerTreeHostCopyRequestTest { protected: - virtual void SetupTree() OVERRIDE { + void SetupTree() override { root_ = FakeContentLayer::Create(&client_); root_->SetBounds(gfx::Size(20, 20)); @@ -360,7 +360,7 @@ class LayerTreeHostTestHiddenSurfaceNotAllocatedForSubtreeCopyRequest LayerTreeHostCopyRequestTest::SetupTree(); } - virtual void BeginTest() OVERRIDE { + void BeginTest() override { did_draw_ = false; PostSetNeedsCommitToMainThread(); @@ -377,7 +377,7 @@ class LayerTreeHostTestHiddenSurfaceNotAllocatedForSubtreeCopyRequest EndTest(); } - virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { + void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { Renderer* renderer = host_impl->renderer(); LayerImpl* root = host_impl->active_tree()->root_layer(); @@ -388,17 +388,17 @@ class LayerTreeHostTestHiddenSurfaceNotAllocatedForSubtreeCopyRequest // |parent| owns a surface, but it was hidden and not part of the copy // request so it should not allocate any resource. EXPECT_FALSE(renderer->HasAllocatedResourcesForTesting( - parent->render_surface()->RenderPassId())); + parent->render_surface()->GetRenderPassId())); // |copy_layer| should have been rendered to a texture since it was needed // for a copy request. EXPECT_TRUE(renderer->HasAllocatedResourcesForTesting( - copy_layer->render_surface()->RenderPassId())); + copy_layer->render_surface()->GetRenderPassId())); did_draw_ = true; } - virtual void AfterTest() OVERRIDE { EXPECT_TRUE(did_draw_); } + void AfterTest() override { EXPECT_TRUE(did_draw_); } FakeContentLayerClient client_; bool did_draw_; @@ -415,7 +415,7 @@ SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F( class LayerTreeHostCopyRequestTestClippedOut : public LayerTreeHostCopyRequestTest { protected: - virtual void SetupTree() OVERRIDE { + void SetupTree() override { root_ = FakeContentLayer::Create(&client_); root_->SetBounds(gfx::Size(20, 20)); @@ -433,7 +433,7 @@ class LayerTreeHostCopyRequestTestClippedOut LayerTreeHostCopyRequestTest::SetupTree(); } - virtual void BeginTest() OVERRIDE { + void BeginTest() override { PostSetNeedsCommitToMainThread(); copy_layer_->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest( @@ -449,7 +449,7 @@ class LayerTreeHostCopyRequestTestClippedOut EndTest(); } - virtual void AfterTest() OVERRIDE {} + void AfterTest() override {} FakeContentLayerClient client_; scoped_refptr<FakeContentLayer> root_; @@ -463,7 +463,7 @@ SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F( class LayerTreeHostTestAsyncTwoReadbacksWithoutDraw : public LayerTreeHostCopyRequestTest { protected: - virtual void SetupTree() OVERRIDE { + void SetupTree() override { root_ = FakeContentLayer::Create(&client_); root_->SetBounds(gfx::Size(20, 20)); @@ -482,7 +482,7 @@ class LayerTreeHostTestAsyncTwoReadbacksWithoutDraw base::Unretained(this)))); } - virtual void BeginTest() OVERRIDE { + void BeginTest() override { saw_copy_request_ = false; callback_count_ = 0; PostSetNeedsCommitToMainThread(); @@ -493,7 +493,7 @@ class LayerTreeHostTestAsyncTwoReadbacksWithoutDraw AddCopyRequest(copy_layer_.get()); } - virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE { + void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override { if (impl->active_tree()->source_frame_number() == 0) { LayerImpl* root = impl->active_tree()->root_layer(); EXPECT_TRUE(root->children()[0]->HasCopyRequest()); @@ -501,7 +501,7 @@ class LayerTreeHostTestAsyncTwoReadbacksWithoutDraw } } - virtual void DidCommit() OVERRIDE { + void DidCommit() override { if (layer_tree_host()->source_frame_number() == 1) { // Allow drawing. layer_tree_host()->SetViewportSize(gfx::Size(root_->bounds())); @@ -519,7 +519,7 @@ class LayerTreeHostTestAsyncTwoReadbacksWithoutDraw EndTest(); } - virtual void AfterTest() OVERRIDE { EXPECT_TRUE(saw_copy_request_); } + void AfterTest() override { EXPECT_TRUE(saw_copy_request_); } bool saw_copy_request_; int callback_count_; @@ -534,8 +534,8 @@ SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F( class LayerTreeHostCopyRequestTestLostOutputSurface : public LayerTreeHostCopyRequestTest { protected: - virtual scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(bool fallback) - OVERRIDE { + scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface( + bool fallback) override { if (!first_context_provider_.get()) { first_context_provider_ = TestContextProvider::Create(); return FakeOutputSurface::Create3d(first_context_provider_); @@ -546,7 +546,7 @@ class LayerTreeHostCopyRequestTestLostOutputSurface return FakeOutputSurface::Create3d(second_context_provider_); } - virtual void SetupTree() OVERRIDE { + void SetupTree() override { root_ = FakeContentLayer::Create(&client_); root_->SetBounds(gfx::Size(20, 20)); @@ -558,7 +558,7 @@ class LayerTreeHostCopyRequestTestLostOutputSurface LayerTreeHostCopyRequestTest::SetupTree(); } - virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } + void BeginTest() override { PostSetNeedsCommitToMainThread(); } void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) { EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread()); @@ -573,7 +573,7 @@ class LayerTreeHostCopyRequestTestLostOutputSurface layer_tree_host()->SetNeedsCommit(); } - virtual void DidCommitAndDrawFrame() OVERRIDE { + void DidCommitAndDrawFrame() override { switch (layer_tree_host()->source_frame_number()) { case 1: // The layers have been pushed to the impl side. The layer textures have @@ -592,7 +592,7 @@ class LayerTreeHostCopyRequestTestLostOutputSurface // Now destroy the CopyOutputResult, releasing the texture inside back // to the compositor. EXPECT_TRUE(result_); - result_.reset(); + result_ = nullptr; // Check that it is released. ImplThreadTaskRunner()->PostTask( @@ -605,8 +605,7 @@ class LayerTreeHostCopyRequestTestLostOutputSurface } } - virtual void SwapBuffersOnThread(LayerTreeHostImpl* impl, - bool result) OVERRIDE { + void SwapBuffersOnThread(LayerTreeHostImpl* impl, bool result) override { switch (impl->active_tree()->source_frame_number()) { case 0: // The layers have been drawn, so their textures have been allocated. @@ -646,7 +645,7 @@ class LayerTreeHostCopyRequestTestLostOutputSurface EndTest(); } - virtual void AfterTest() OVERRIDE {} + void AfterTest() override {} scoped_refptr<TestContextProvider> first_context_provider_; scoped_refptr<TestContextProvider> second_context_provider_; @@ -664,13 +663,13 @@ SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F( class LayerTreeHostCopyRequestTestCountTextures : public LayerTreeHostCopyRequestTest { protected: - virtual scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(bool fallback) - OVERRIDE { + scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface( + bool fallback) override { context_provider_ = TestContextProvider::Create(); return FakeOutputSurface::Create3d(context_provider_); } - virtual void SetupTree() OVERRIDE { + void SetupTree() override { root_ = FakeContentLayer::Create(&client_); root_->SetBounds(gfx::Size(20, 20)); @@ -682,7 +681,7 @@ class LayerTreeHostCopyRequestTestCountTextures LayerTreeHostCopyRequestTest::SetupTree(); } - virtual void BeginTest() OVERRIDE { + void BeginTest() override { num_textures_without_readback_ = 0; num_textures_with_readback_ = 0; waited_sync_point_after_readback_ = 0; @@ -691,7 +690,7 @@ class LayerTreeHostCopyRequestTestCountTextures virtual void RequestCopy(Layer* layer) = 0; - virtual void DidCommitAndDrawFrame() OVERRIDE { + void DidCommitAndDrawFrame() override { switch (layer_tree_host()->source_frame_number()) { case 1: // The layers have been pushed to the impl side. The layer textures have @@ -701,8 +700,7 @@ class LayerTreeHostCopyRequestTestCountTextures } } - virtual void SwapBuffersOnThread(LayerTreeHostImpl* impl, - bool result) OVERRIDE { + void SwapBuffersOnThread(LayerTreeHostImpl* impl, bool result) override { switch (impl->active_tree()->source_frame_number()) { case 0: // The layers have been drawn, so their textures have been allocated. @@ -738,7 +736,7 @@ class LayerTreeHostCopyRequestTestCountTextures class LayerTreeHostCopyRequestTestCreatesTexture : public LayerTreeHostCopyRequestTestCountTextures { protected: - virtual void RequestCopy(Layer* layer) OVERRIDE { + void RequestCopy(Layer* layer) override { // Request a normal texture copy. This should create a new texture. copy_layer_->RequestCopyOfOutput( CopyOutputRequest::CreateRequest(base::Bind( @@ -758,7 +756,7 @@ class LayerTreeHostCopyRequestTestCreatesTexture release->Run(0, false); } - virtual void AfterTest() OVERRIDE { + void AfterTest() override { // No sync point was needed. EXPECT_EQ(0u, waited_sync_point_after_readback_); // Except the copy to have made another texture. @@ -772,7 +770,7 @@ SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F( class LayerTreeHostCopyRequestTestProvideTexture : public LayerTreeHostCopyRequestTestCountTextures { protected: - virtual void BeginTest() OVERRIDE { + void BeginTest() override { external_context_provider_ = TestContextProvider::Create(); EXPECT_TRUE(external_context_provider_->BindToCurrentThread()); LayerTreeHostCopyRequestTestCountTextures::BeginTest(); @@ -788,7 +786,7 @@ class LayerTreeHostCopyRequestTestProvideTexture EXPECT_FALSE(release); } - virtual void RequestCopy(Layer* layer) OVERRIDE { + void RequestCopy(Layer* layer) override { // Request a copy to a provided texture. This should not create a new // texture. scoped_ptr<CopyOutputRequest> request = @@ -807,7 +805,7 @@ class LayerTreeHostCopyRequestTestProvideTexture copy_layer_->RequestCopyOfOutput(request.Pass()); } - virtual void AfterTest() OVERRIDE { + void AfterTest() override { // Expect the compositor to have waited for the sync point in the provided // TextureMailbox. EXPECT_EQ(sync_point_, waited_sync_point_after_readback_); @@ -825,7 +823,7 @@ SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_NOIMPL_TEST_F( class LayerTreeHostCopyRequestTestDestroyBeforeCopy : public LayerTreeHostCopyRequestTest { protected: - virtual void SetupTree() OVERRIDE { + void SetupTree() override { root_ = FakeContentLayer::Create(&client_); root_->SetBounds(gfx::Size(20, 20)); @@ -837,7 +835,7 @@ class LayerTreeHostCopyRequestTestDestroyBeforeCopy LayerTreeHostCopyRequestTest::SetupTree(); } - virtual void BeginTest() OVERRIDE { + void BeginTest() override { callback_count_ = 0; PostSetNeedsCommitToMainThread(); } @@ -847,7 +845,7 @@ class LayerTreeHostCopyRequestTestDestroyBeforeCopy ++callback_count_; } - virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE { + void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override { MainThreadTaskRunner()->PostTask( FROM_HERE, base::Bind(&LayerTreeHostCopyRequestTestDestroyBeforeCopy::DidActivate, @@ -888,7 +886,7 @@ class LayerTreeHostCopyRequestTestDestroyBeforeCopy } } - virtual void AfterTest() OVERRIDE {} + void AfterTest() override {} int callback_count_; FakeContentLayerClient client_; @@ -902,7 +900,7 @@ SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F( class LayerTreeHostCopyRequestTestShutdownBeforeCopy : public LayerTreeHostCopyRequestTest { protected: - virtual void SetupTree() OVERRIDE { + void SetupTree() override { root_ = FakeContentLayer::Create(&client_); root_->SetBounds(gfx::Size(20, 20)); @@ -914,7 +912,7 @@ class LayerTreeHostCopyRequestTestShutdownBeforeCopy LayerTreeHostCopyRequestTest::SetupTree(); } - virtual void BeginTest() OVERRIDE { + void BeginTest() override { callback_count_ = 0; PostSetNeedsCommitToMainThread(); } @@ -924,7 +922,7 @@ class LayerTreeHostCopyRequestTestShutdownBeforeCopy ++callback_count_; } - virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE { + void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override { MainThreadTaskRunner()->PostTask( FROM_HERE, base::Bind(&LayerTreeHostCopyRequestTestShutdownBeforeCopy::DidActivate, @@ -959,7 +957,7 @@ class LayerTreeHostCopyRequestTestShutdownBeforeCopy } } - virtual void AfterTest() OVERRIDE { EXPECT_EQ(1, callback_count_); } + void AfterTest() override { EXPECT_EQ(1, callback_count_); } int callback_count_; FakeContentLayerClient client_; diff --git a/chromium/cc/trees/layer_tree_host_unittest_damage.cc b/chromium/cc/trees/layer_tree_host_unittest_damage.cc index eab8ed6b60e..d541751e146 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_damage.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_damage.cc @@ -26,7 +26,7 @@ class LayerTreeHostDamageTest : public LayerTreeTest {}; // LayerTreeHost::SetNeedsRedraw should damage the whole viewport. class LayerTreeHostDamageTestSetNeedsRedraw : public LayerTreeHostDamageTest { - virtual void SetupTree() OVERRIDE { + void SetupTree() override { // Viewport is 10x10. scoped_refptr<FakeContentLayer> root = FakeContentLayer::Create(&client_); root->SetBounds(gfx::Size(10, 10)); @@ -35,12 +35,12 @@ class LayerTreeHostDamageTestSetNeedsRedraw LayerTreeHostDamageTest::SetupTree(); } - virtual void BeginTest() OVERRIDE { + void BeginTest() override { draw_count_ = 0; PostSetNeedsCommitToMainThread(); } - virtual void DidCommitAndDrawFrame() OVERRIDE { + void DidCommitAndDrawFrame() override { switch (layer_tree_host()->source_frame_number()) { case 1: layer_tree_host()->SetNeedsRedraw(); @@ -48,10 +48,9 @@ class LayerTreeHostDamageTestSetNeedsRedraw } } - virtual DrawResult PrepareToDrawOnThread( - LayerTreeHostImpl* impl, - LayerTreeHostImpl::FrameData* frame_data, - DrawResult draw_result) OVERRIDE { + DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* impl, + LayerTreeHostImpl::FrameData* frame_data, + DrawResult draw_result) override { EXPECT_EQ(DRAW_SUCCESS, draw_result); RenderSurfaceImpl* root_surface = @@ -77,7 +76,7 @@ class LayerTreeHostDamageTestSetNeedsRedraw return draw_result; } - virtual void AfterTest() OVERRIDE {} + void AfterTest() override {} int draw_count_; FakeContentLayerClient client_; @@ -88,7 +87,7 @@ SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDamageTestSetNeedsRedraw); // LayerTreeHost::SetViewportSize should damage the whole viewport. class LayerTreeHostDamageTestSetViewportSize : public LayerTreeHostDamageTest { - virtual void SetupTree() OVERRIDE { + void SetupTree() override { // Viewport is 10x10. scoped_refptr<FakeContentLayer> root = FakeContentLayer::Create(&client_); root->SetBounds(gfx::Size(10, 10)); @@ -97,12 +96,12 @@ class LayerTreeHostDamageTestSetViewportSize LayerTreeHostDamageTest::SetupTree(); } - virtual void BeginTest() OVERRIDE { + void BeginTest() override { draw_count_ = 0; PostSetNeedsCommitToMainThread(); } - virtual void DidCommitAndDrawFrame() OVERRIDE { + void DidCommitAndDrawFrame() override { switch (layer_tree_host()->source_frame_number()) { case 1: layer_tree_host()->SetViewportSize(gfx::Size(15, 15)); @@ -110,10 +109,9 @@ class LayerTreeHostDamageTestSetViewportSize } } - virtual DrawResult PrepareToDrawOnThread( - LayerTreeHostImpl* impl, - LayerTreeHostImpl::FrameData* frame_data, - DrawResult draw_result) OVERRIDE { + DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* impl, + LayerTreeHostImpl::FrameData* frame_data, + DrawResult draw_result) override { EXPECT_EQ(DRAW_SUCCESS, draw_result); RenderSurfaceImpl* root_surface = @@ -139,7 +137,7 @@ class LayerTreeHostDamageTestSetViewportSize return draw_result; } - virtual void AfterTest() OVERRIDE {} + void AfterTest() override {} int draw_count_; FakeContentLayerClient client_; @@ -149,14 +147,14 @@ SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDamageTestSetViewportSize); class LayerTreeHostDamageTestNoDamageDoesNotSwap : public LayerTreeHostDamageTest { - virtual void BeginTest() OVERRIDE { + void BeginTest() override { expect_swap_and_succeed_ = 0; did_swaps_ = 0; did_swap_and_succeed_ = 0; PostSetNeedsCommitToMainThread(); } - virtual void SetupTree() OVERRIDE { + void SetupTree() override { scoped_refptr<FakeContentLayer> root = FakeContentLayer::Create(&client_); root->SetBounds(gfx::Size(10, 10)); @@ -169,10 +167,9 @@ class LayerTreeHostDamageTestNoDamageDoesNotSwap LayerTreeHostDamageTest::SetupTree(); } - virtual DrawResult PrepareToDrawOnThread( - LayerTreeHostImpl* host_impl, - LayerTreeHostImpl::FrameData* frame_data, - DrawResult draw_result) OVERRIDE { + DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, + LayerTreeHostImpl::FrameData* frame_data, + DrawResult draw_result) override { EXPECT_EQ(DRAW_SUCCESS, draw_result); int source_frame = host_impl->active_tree()->source_frame_number(); @@ -197,15 +194,14 @@ class LayerTreeHostDamageTestNoDamageDoesNotSwap return draw_result; } - virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, - bool result) OVERRIDE { + void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override { ++did_swaps_; if (result) ++did_swap_and_succeed_; EXPECT_EQ(expect_swap_and_succeed_, did_swap_and_succeed_); } - virtual void DidCommit() OVERRIDE { + void DidCommit() override { int next_frame = layer_tree_host()->source_frame_number(); switch (next_frame) { case 1: @@ -224,7 +220,7 @@ class LayerTreeHostDamageTestNoDamageDoesNotSwap } } - virtual void AfterTest() OVERRIDE { + void AfterTest() override { EXPECT_EQ(4, did_swaps_); EXPECT_EQ(2, expect_swap_and_succeed_); EXPECT_EQ(expect_swap_and_succeed_, did_swap_and_succeed_); @@ -241,11 +237,9 @@ SINGLE_AND_MULTI_THREAD_NOIMPL_TEST_F( LayerTreeHostDamageTestNoDamageDoesNotSwap); class LayerTreeHostDamageTestForcedFullDamage : public LayerTreeHostDamageTest { - virtual void BeginTest() OVERRIDE { - PostSetNeedsCommitToMainThread(); - } + void BeginTest() override { PostSetNeedsCommitToMainThread(); } - virtual void SetupTree() OVERRIDE { + void SetupTree() override { root_ = FakeContentLayer::Create(&client_); child_ = FakeContentLayer::Create(&client_); @@ -258,10 +252,9 @@ class LayerTreeHostDamageTestForcedFullDamage : public LayerTreeHostDamageTest { LayerTreeHostDamageTest::SetupTree(); } - virtual DrawResult PrepareToDrawOnThread( - LayerTreeHostImpl* host_impl, - LayerTreeHostImpl::FrameData* frame_data, - DrawResult draw_result) OVERRIDE { + DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, + LayerTreeHostImpl::FrameData* frame_data, + DrawResult draw_result) override { EXPECT_EQ(DRAW_SUCCESS, draw_result); RenderSurfaceImpl* root_surface = @@ -293,7 +286,7 @@ class LayerTreeHostDamageTestForcedFullDamage : public LayerTreeHostDamageTest { EXPECT_FALSE(frame_data->has_no_damage); // Just a part of the next frame should be damaged. - child_damage_rect_ = gfx::RectF(10, 11, 12, 13); + child_damage_rect_ = gfx::Rect(10, 11, 12, 13); break; case 3: // The update rect in the child should be damaged and the damaged area @@ -319,7 +312,7 @@ class LayerTreeHostDamageTestForcedFullDamage : public LayerTreeHostDamageTest { // If we damage part of the frame, but also damage the full // frame, then the whole frame should be damaged. - child_damage_rect_ = gfx::RectF(10, 11, 12, 13); + child_damage_rect_ = gfx::Rect(10, 11, 12, 13); host_impl->SetFullRootLayerDamage(); break; case 4: @@ -334,28 +327,28 @@ class LayerTreeHostDamageTestForcedFullDamage : public LayerTreeHostDamageTest { return draw_result; } - virtual void DidCommitAndDrawFrame() OVERRIDE { + void DidCommitAndDrawFrame() override { if (!TestEnded()) layer_tree_host()->SetNeedsCommit(); if (!child_damage_rect_.IsEmpty()) { child_->SetNeedsDisplayRect(child_damage_rect_); - child_damage_rect_ = gfx::RectF(); + child_damage_rect_ = gfx::Rect(); } } - virtual void AfterTest() OVERRIDE {} + void AfterTest() override {} FakeContentLayerClient client_; scoped_refptr<FakeContentLayer> root_; scoped_refptr<FakeContentLayer> child_; - gfx::RectF child_damage_rect_; + gfx::Rect child_damage_rect_; }; SINGLE_AND_MULTI_THREAD_NOIMPL_TEST_F(LayerTreeHostDamageTestForcedFullDamage); class LayerTreeHostScrollbarDamageTest : public LayerTreeHostDamageTest { - virtual void SetupTree() OVERRIDE { + void SetupTree() override { scoped_refptr<Layer> root_layer = Layer::Create(); root_layer->SetBounds(gfx::Size(400, 400)); root_layer->SetMasksToBounds(true); @@ -364,7 +357,7 @@ class LayerTreeHostScrollbarDamageTest : public LayerTreeHostDamageTest { scoped_refptr<Layer> scroll_clip_layer = Layer::Create(); scoped_refptr<Layer> content_layer = FakeContentLayer::Create(&client_); content_layer->SetScrollClipLayerId(scroll_clip_layer->id()); - content_layer->SetScrollOffset(gfx::Vector2d(10, 20)); + content_layer->SetScrollOffset(gfx::ScrollOffset(10, 20)); content_layer->SetBounds(gfx::Size(100, 200)); scroll_clip_layer->SetBounds( gfx::Size(content_layer->bounds().width() - 30, @@ -395,15 +388,14 @@ class LayerTreeHostScrollbarDamageTest : public LayerTreeHostDamageTest { class LayerTreeHostDamageTestScrollbarDoesDamage : public LayerTreeHostScrollbarDamageTest { - virtual void BeginTest() OVERRIDE { + void BeginTest() override { did_swaps_ = 0; PostSetNeedsCommitToMainThread(); } - virtual DrawResult PrepareToDrawOnThread( - LayerTreeHostImpl* host_impl, - LayerTreeHostImpl::FrameData* frame_data, - DrawResult draw_result) OVERRIDE { + DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, + LayerTreeHostImpl::FrameData* frame_data, + DrawResult draw_result) override { EXPECT_EQ(DRAW_SUCCESS, draw_result); RenderSurfaceImpl* root_surface = host_impl->active_tree()->root_layer()->render_surface(); @@ -431,8 +423,7 @@ class LayerTreeHostDamageTestScrollbarDoesDamage return draw_result; } - virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, - bool result) OVERRIDE { + void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override { ++did_swaps_; EXPECT_TRUE(result); LayerImpl* root = host_impl->active_tree()->root_layer(); @@ -458,9 +449,7 @@ class LayerTreeHostDamageTestScrollbarDoesDamage } } - virtual void AfterTest() OVERRIDE { - EXPECT_EQ(4, did_swaps_); - } + void AfterTest() override { EXPECT_EQ(4, did_swaps_); } int did_swaps_; }; @@ -469,15 +458,14 @@ MULTI_THREAD_TEST_F(LayerTreeHostDamageTestScrollbarDoesDamage); class LayerTreeHostDamageTestScrollbarCommitDoesNoDamage : public LayerTreeHostScrollbarDamageTest { - virtual void BeginTest() OVERRIDE { + void BeginTest() override { did_swaps_ = 0; PostSetNeedsCommitToMainThread(); } - virtual DrawResult PrepareToDrawOnThread( - LayerTreeHostImpl* host_impl, - LayerTreeHostImpl::FrameData* frame_data, - DrawResult draw_result) OVERRIDE { + DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, + LayerTreeHostImpl::FrameData* frame_data, + DrawResult draw_result) override { EXPECT_EQ(DRAW_SUCCESS, draw_result); RenderSurfaceImpl* root_surface = host_impl->active_tree()->root_layer()->render_surface(); @@ -507,8 +495,7 @@ class LayerTreeHostDamageTestScrollbarCommitDoesNoDamage return draw_result; } - virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, - bool result) OVERRIDE { + void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override { ++did_swaps_; EXPECT_TRUE(result); LayerImpl* root = host_impl->active_tree()->root_layer(); @@ -535,9 +522,7 @@ class LayerTreeHostDamageTestScrollbarCommitDoesNoDamage } } - virtual void AfterTest() OVERRIDE { - EXPECT_EQ(3, did_swaps_); - } + void AfterTest() override { EXPECT_EQ(3, did_swaps_); } int did_swaps_; }; @@ -546,16 +531,13 @@ MULTI_THREAD_TEST_F(LayerTreeHostDamageTestScrollbarCommitDoesNoDamage); class LayerTreeHostDamageTestVisibleTilesStillTriggerDraws : public LayerTreeHostDamageTest { - - virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE { + void InitializeSettings(LayerTreeSettings* settings) override { settings->impl_side_painting = true; } - virtual void BeginTest() OVERRIDE { - PostSetNeedsCommitToMainThread(); - } + void BeginTest() override { PostSetNeedsCommitToMainThread(); } - virtual void SetupTree() OVERRIDE { + void SetupTree() override { scoped_refptr<FakePictureLayer> root = FakePictureLayer::Create(&client_); root->SetBounds(gfx::Size(500, 500)); layer_tree_host()->SetRootLayer(root); @@ -566,10 +548,9 @@ class LayerTreeHostDamageTestVisibleTilesStillTriggerDraws update_visible_tile_count_ = 0; } - virtual DrawResult PrepareToDrawOnThread( - LayerTreeHostImpl* host_impl, - LayerTreeHostImpl::FrameData* frame_data, - DrawResult draw_result) OVERRIDE { + DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, + LayerTreeHostImpl::FrameData* frame_data, + DrawResult draw_result) override { EXPECT_EQ(DRAW_SUCCESS, draw_result); prepare_to_draw_count_++; switch (prepare_to_draw_count_) { @@ -599,8 +580,7 @@ class LayerTreeHostDamageTestVisibleTilesStillTriggerDraws return draw_result; } - virtual void UpdateVisibleTilesOnThread( - LayerTreeHostImpl* host_impl) OVERRIDE { + void UpdateVisibleTilesOnThread(LayerTreeHostImpl* host_impl) override { // Simulate creating some visible tiles (that trigger prepare-to-draws). // The first we make into a no-damage-frame during prepare-to-draw (see // above). This is to ensure we still get UpdateVisibleTiles calls after @@ -617,14 +597,14 @@ class LayerTreeHostDamageTestVisibleTilesStillTriggerDraws } } - virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, - bool didSwap) OVERRIDE { + void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, + bool didSwap) override { if (!didSwap) return; ++swap_count_; } - virtual void AfterTest() OVERRIDE { + void AfterTest() override { // We should keep getting update-visible-tiles calls // until we report there are no more incomplete-tiles. EXPECT_EQ(update_visible_tile_count_, 6); diff --git a/chromium/cc/trees/layer_tree_host_unittest_delegated.cc b/chromium/cc/trees/layer_tree_host_unittest_delegated.cc index 37c928b9bd6..3aabeffd142 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_delegated.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_delegated.cc @@ -80,7 +80,7 @@ class LayerTreeHostDelegatedTest : public LayerTreeTest { scoped_ptr<DelegatedFrameData> frame(new DelegatedFrameData); scoped_ptr<RenderPass> root_pass(RenderPass::Create()); - root_pass->SetNew(RenderPass::Id(1, 1), + root_pass->SetNew(RenderPassId(1, 1), root_output_rect, root_damage_rect, gfx::Transform()); @@ -94,7 +94,7 @@ class LayerTreeHostDelegatedTest : public LayerTreeTest { scoped_ptr<DelegatedFrameData> frame(new DelegatedFrameData); scoped_ptr<RenderPass> root_pass(RenderPass::Create()); - root_pass->SetNew(RenderPass::Id(1, 1), + root_pass->SetNew(RenderPassId(1, 1), root_output_rect, root_damage_rect, gfx::Transform()); @@ -114,7 +114,8 @@ class LayerTreeHostDelegatedTest : public LayerTreeTest { float vertex_opacity[4] = {1.f, 1.f, 1.f, 1.f}; bool flipped = false; - scoped_ptr<TextureDrawQuad> invalid_draw_quad = TextureDrawQuad::Create(); + TextureDrawQuad* invalid_draw_quad = + root_pass->CreateAndAppendDrawQuad<TextureDrawQuad>(); invalid_draw_quad->SetNew(shared_quad_state, rect, opaque_rect, @@ -126,7 +127,6 @@ class LayerTreeHostDelegatedTest : public LayerTreeTest { background_color, vertex_opacity, flipped); - root_pass->quad_list.push_back(invalid_draw_quad.PassAs<DrawQuad>()); frame->render_pass_list.push_back(root_pass.Pass()); return frame.Pass(); @@ -147,9 +147,10 @@ class LayerTreeHostDelegatedTest : public LayerTreeTest { void AddTextureQuad(DelegatedFrameData* frame, ResourceProvider::ResourceId resource_id) { - SharedQuadState* sqs = - frame->render_pass_list[0]->CreateAndAppendSharedQuadState(); - scoped_ptr<TextureDrawQuad> quad = TextureDrawQuad::Create(); + RenderPass* render_pass = frame->render_pass_list[0]; + SharedQuadState* sqs = render_pass->CreateAndAppendSharedQuadState(); + TextureDrawQuad* quad = + render_pass->CreateAndAppendDrawQuad<TextureDrawQuad>(); float vertex_opacity[4] = { 1.f, 1.f, 1.f, 1.f }; quad->SetNew(sqs, gfx::Rect(0, 0, 10, 10), @@ -162,11 +163,10 @@ class LayerTreeHostDelegatedTest : public LayerTreeTest { SK_ColorTRANSPARENT, vertex_opacity, false); - frame->render_pass_list[0]->quad_list.push_back(quad.PassAs<DrawQuad>()); } void AddRenderPass(DelegatedFrameData* frame, - RenderPass::Id id, + RenderPassId id, const gfx::Rect& output_rect, const gfx::Rect& damage_rect, const FilterOperations& filters, @@ -181,21 +181,21 @@ class LayerTreeHostDelegatedTest : public LayerTreeTest { gfx::Transform()); frame->render_pass_list.push_back(pass.Pass()); - SharedQuadState* sqs = - frame->render_pass_list[0]->CreateAndAppendSharedQuadState(); - scoped_ptr<RenderPassDrawQuad> quad = RenderPassDrawQuad::Create(); + RenderPass* render_pass = frame->render_pass_list[0]; + SharedQuadState* sqs = render_pass->CreateAndAppendSharedQuadState(); + RenderPassDrawQuad* quad = + render_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>(); quad->SetNew(sqs, output_rect, output_rect, id, - false, // is_replica - 0, // mask_resource_id - damage_rect, - gfx::Rect(0, 0, 1, 1), // mask_uv_rect + 0, + gfx::Vector2dF(), + gfx::Size(), filters, + gfx::Vector2dF(), background_filters); - frame->render_pass_list[0]->quad_list.push_back(quad.PassAs<DrawQuad>()); } static ResourceProvider::ResourceId AppendResourceId( @@ -252,7 +252,7 @@ class LayerTreeHostDelegatedTestCaseSingleDelegatedLayer resource_collection_->SetClient(this); } - virtual void SetupTree() OVERRIDE { + void SetupTree() override { root_ = Layer::Create(); root_->SetBounds(gfx::Size(15, 15)); @@ -260,7 +260,7 @@ class LayerTreeHostDelegatedTestCaseSingleDelegatedLayer LayerTreeHostDelegatedTest::SetupTree(); } - virtual void BeginTest() OVERRIDE { + void BeginTest() override { resource_collection_->SetClient(this); PostSetNeedsCommitToMainThread(); } @@ -297,10 +297,10 @@ class LayerTreeHostDelegatedTestCaseSingleDelegatedLayer return delegated; } - virtual void AfterTest() OVERRIDE { resource_collection_->SetClient(NULL); } + void AfterTest() override { resource_collection_->SetClient(NULL); } // DelegatedFrameProviderClient implementation. - virtual void UnusedResourcesAreAvailable() OVERRIDE { available_ = true; } + void UnusedResourcesAreAvailable() override { available_ = true; } bool TestAndResetAvailable() { bool available = available_; @@ -324,13 +324,13 @@ class LayerTreeHostDelegatedTestCreateChildId num_activates_(0), did_reset_child_id_(false) {} - virtual void DidCommit() OVERRIDE { + void DidCommit() override { if (TestEnded()) return; SetFrameData(CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1))); } - virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { + void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { if (host_impl->active_tree()->source_frame_number() < 1) return; @@ -339,7 +339,7 @@ class LayerTreeHostDelegatedTestCreateChildId static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]); TestContextProvider* context_provider = static_cast<TestContextProvider*>( - host_impl->output_surface()->context_provider().get()); + host_impl->output_surface()->context_provider()); ++num_activates_; switch (num_activates_) { @@ -360,8 +360,8 @@ class LayerTreeHostDelegatedTestCreateChildId } } - virtual void InitializedRendererOnThread(LayerTreeHostImpl* host_impl, - bool success) OVERRIDE { + void InitializedRendererOnThread(LayerTreeHostImpl* host_impl, + bool success) override { EXPECT_TRUE(success); if (num_activates_ < 2) @@ -392,7 +392,7 @@ class LayerTreeHostDelegatedTestInvalidFrameAfterContextLost LayerTreeHostDelegatedTestInvalidFrameAfterContextLost() : num_activates_(0), num_output_surfaces_initialized_(0) {} - virtual void DidCommit() OVERRIDE { + void DidCommit() override { if (TestEnded()) return; scoped_ptr<DelegatedFrameData> frame1 = @@ -402,7 +402,7 @@ class LayerTreeHostDelegatedTestInvalidFrameAfterContextLost SetFrameData(frame1.Pass()); } - virtual void DidInitializeOutputSurface() OVERRIDE { + void DidInitializeOutputSurface() override { if (!num_output_surfaces_initialized_++) return; @@ -415,12 +415,12 @@ class LayerTreeHostDelegatedTestInvalidFrameAfterContextLost DCHECK(delegated_.get() == old_delegated.get()); } - virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { + void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { if (host_impl->active_tree()->source_frame_number() < 1) return; TestContextProvider* context_provider = static_cast<TestContextProvider*>( - host_impl->output_surface()->context_provider().get()); + host_impl->output_surface()->context_provider()); ++num_activates_; switch (num_activates_) { @@ -435,8 +435,8 @@ class LayerTreeHostDelegatedTestInvalidFrameAfterContextLost } } - virtual void InitializedRendererOnThread(LayerTreeHostImpl* host_impl, - bool success) OVERRIDE { + void InitializedRendererOnThread(LayerTreeHostImpl* host_impl, + bool success) override { EXPECT_TRUE(success); if (num_activates_ < 2) @@ -451,7 +451,7 @@ class LayerTreeHostDelegatedTestInvalidFrameAfterContextLost EXPECT_EQ(0U, delegated_impl->Resources().size()); } - virtual void AfterTest() OVERRIDE { + void AfterTest() override { LayerTreeHostDelegatedTestCaseSingleDelegatedLayer::AfterTest(); EXPECT_EQ(2, num_output_surfaces_initialized_); } @@ -471,7 +471,7 @@ class LayerTreeHostDelegatedTestLayerUsesFrameDamage : LayerTreeHostDelegatedTestCaseSingleDelegatedLayer(), first_draw_for_source_frame_(true) {} - virtual void DidCommit() OVERRIDE { + void DidCommit() override { int next_source_frame_number = layer_tree_host()->source_frame_number(); switch (next_source_frame_number) { case 1: @@ -564,7 +564,7 @@ class LayerTreeHostDelegatedTestLayerUsesFrameDamage case 17: // Make another layer that uses the same frame provider. The new layer // should be damaged. - delegated_copy_ = CreateDelegatedLayer(frame_provider_); + delegated_copy_ = CreateDelegatedLayer(frame_provider_.get()); delegated_copy_->SetPosition(gfx::Point(5, 0)); // Also set a new frame. @@ -581,10 +581,9 @@ class LayerTreeHostDelegatedTestLayerUsesFrameDamage first_draw_for_source_frame_ = true; } - virtual DrawResult PrepareToDrawOnThread( - LayerTreeHostImpl* host_impl, - LayerTreeHostImpl::FrameData* frame, - DrawResult draw_result) OVERRIDE { + DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, + LayerTreeHostImpl::FrameData* frame, + DrawResult draw_result) override { EXPECT_EQ(DRAW_SUCCESS, draw_result); if (!first_draw_for_source_frame_) @@ -675,7 +674,7 @@ SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestLayerUsesFrameDamage); class LayerTreeHostDelegatedTestMergeResources : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer { public: - virtual void BeginTest() OVERRIDE { + void BeginTest() override { // Push two frames to the delegated renderer layer with no commit between. // The first frame has resource 999. @@ -708,7 +707,7 @@ class LayerTreeHostDelegatedTestMergeResources PostSetNeedsCommitToMainThread(); } - virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { + void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { LayerImpl* root_impl = host_impl->active_tree()->root_layer(); FakeDelegatedRendererLayerImpl* delegated_impl = static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]); @@ -735,7 +734,7 @@ SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestMergeResources); class LayerTreeHostDelegatedTestRemapResourcesInQuads : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer { public: - virtual void BeginTest() OVERRIDE { + void BeginTest() override { // Generate a frame with two resources in it. scoped_ptr<DelegatedFrameData> frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1)); @@ -748,7 +747,7 @@ class LayerTreeHostDelegatedTestRemapResourcesInQuads PostSetNeedsCommitToMainThread(); } - virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { + void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { LayerImpl* root_impl = host_impl->active_tree()->root_layer(); FakeDelegatedRendererLayerImpl* delegated_impl = static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]); @@ -769,10 +768,10 @@ class LayerTreeHostDelegatedTestRemapResourcesInQuads // The resources in the quads should be remapped to the parent's namespace. const TextureDrawQuad* quad1 = TextureDrawQuad::MaterialCast( - delegated_impl->RenderPassesInDrawOrder()[0]->quad_list[0]); + delegated_impl->RenderPassesInDrawOrder()[0]->quad_list.ElementAt(0)); EXPECT_EQ(parent_resource_id1, quad1->resource_id); const TextureDrawQuad* quad2 = TextureDrawQuad::MaterialCast( - delegated_impl->RenderPassesInDrawOrder()[0]->quad_list[1]); + delegated_impl->RenderPassesInDrawOrder()[0]->quad_list.ElementAt(1)); EXPECT_EQ(parent_resource_id2, quad2->resource_id); EndTest(); @@ -784,11 +783,9 @@ SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestRemapResourcesInQuads); class LayerTreeHostDelegatedTestReturnUnusedResources : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer { public: - virtual void BeginTest() OVERRIDE { - PostSetNeedsCommitToMainThread(); - } + void BeginTest() override { PostSetNeedsCommitToMainThread(); } - virtual void DidCommitAndDrawFrame() OVERRIDE { + void DidCommitAndDrawFrame() override { scoped_ptr<DelegatedFrameData> frame; ReturnedResourceArray resources; @@ -856,8 +853,7 @@ class LayerTreeHostDelegatedTestReturnUnusedResources EXPECT_FALSE(TestAndResetAvailable()); } - virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, - bool result) OVERRIDE { + void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override { ReturnUnusedResourcesFromParent(host_impl); } }; @@ -868,11 +864,9 @@ SINGLE_AND_MULTI_THREAD_TEST_F( class LayerTreeHostDelegatedTestReusedResources : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer { public: - virtual void BeginTest() OVERRIDE { - PostSetNeedsCommitToMainThread(); - } + void BeginTest() override { PostSetNeedsCommitToMainThread(); } - virtual void DidCommitAndDrawFrame() OVERRIDE { + void DidCommitAndDrawFrame() override { scoped_ptr<DelegatedFrameData> frame; ReturnedResourceArray resources; @@ -928,8 +922,7 @@ class LayerTreeHostDelegatedTestReusedResources } } - virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, - bool result) OVERRIDE { + void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override { ReturnUnusedResourcesFromParent(host_impl); } }; @@ -939,11 +932,9 @@ SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestReusedResources); class LayerTreeHostDelegatedTestFrameBeforeAck : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer { public: - virtual void BeginTest() OVERRIDE { - PostSetNeedsCommitToMainThread(); - } + void BeginTest() override { PostSetNeedsCommitToMainThread(); } - virtual void DidCommitAndDrawFrame() OVERRIDE { + void DidCommitAndDrawFrame() override { scoped_ptr<DelegatedFrameData> frame; ReturnedResourceArray resources; @@ -998,7 +989,7 @@ class LayerTreeHostDelegatedTestFrameBeforeAck } } - virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { + void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { if (host_impl->active_tree()->source_frame_number() != 3) return; @@ -1021,15 +1012,14 @@ class LayerTreeHostDelegatedTestFrameBeforeAck const RenderPass* pass = delegated_impl->RenderPassesInDrawOrder()[0]; EXPECT_EQ(1u, pass->quad_list.size()); - const TextureDrawQuad* quad = TextureDrawQuad::MaterialCast( - pass->quad_list[0]); + const TextureDrawQuad* quad = + TextureDrawQuad::MaterialCast(pass->quad_list.front()); EXPECT_EQ(map.find(999)->second, quad->resource_id); EndTest(); } - virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, - bool result) OVERRIDE { + void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override { ReturnUnusedResourcesFromParent(host_impl); } }; @@ -1039,11 +1029,9 @@ SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestFrameBeforeAck); class LayerTreeHostDelegatedTestFrameBeforeTakeResources : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer { public: - virtual void BeginTest() OVERRIDE { - PostSetNeedsCommitToMainThread(); - } + void BeginTest() override { PostSetNeedsCommitToMainThread(); } - virtual void DidCommitAndDrawFrame() OVERRIDE { + void DidCommitAndDrawFrame() override { scoped_ptr<DelegatedFrameData> frame; ReturnedResourceArray resources; @@ -1110,7 +1098,7 @@ class LayerTreeHostDelegatedTestFrameBeforeTakeResources } } - virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { + void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { if (host_impl->active_tree()->source_frame_number() != 3) return; @@ -1136,19 +1124,18 @@ class LayerTreeHostDelegatedTestFrameBeforeTakeResources const RenderPass* pass = delegated_impl->RenderPassesInDrawOrder()[0]; EXPECT_EQ(3u, pass->quad_list.size()); - const TextureDrawQuad* quad1 = TextureDrawQuad::MaterialCast( - pass->quad_list[0]); + const TextureDrawQuad* quad1 = + TextureDrawQuad::MaterialCast(pass->quad_list.ElementAt(0)); EXPECT_EQ(map.find(999)->second, quad1->resource_id); - const TextureDrawQuad* quad2 = TextureDrawQuad::MaterialCast( - pass->quad_list[1]); + const TextureDrawQuad* quad2 = + TextureDrawQuad::MaterialCast(pass->quad_list.ElementAt(1)); EXPECT_EQ(map.find(555)->second, quad2->resource_id); - const TextureDrawQuad* quad3 = TextureDrawQuad::MaterialCast( - pass->quad_list[2]); + const TextureDrawQuad* quad3 = + TextureDrawQuad::MaterialCast(pass->quad_list.ElementAt(2)); EXPECT_EQ(map.find(444)->second, quad3->resource_id); } - virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, - bool result) OVERRIDE { + void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override { ReturnUnusedResourcesFromParent(host_impl); } }; @@ -1159,11 +1146,9 @@ SINGLE_AND_MULTI_THREAD_TEST_F( class LayerTreeHostDelegatedTestBadFrame : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer { public: - virtual void BeginTest() OVERRIDE { - PostSetNeedsCommitToMainThread(); - } + void BeginTest() override { PostSetNeedsCommitToMainThread(); } - virtual void DidCommitAndDrawFrame() OVERRIDE { + void DidCommitAndDrawFrame() override { scoped_ptr<DelegatedFrameData> frame; ReturnedResourceArray resources; @@ -1230,8 +1215,7 @@ class LayerTreeHostDelegatedTestBadFrame } } - virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, - bool result) OVERRIDE { + void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override { if (host_impl->active_tree()->source_frame_number() < 1) return; @@ -1259,11 +1243,11 @@ class LayerTreeHostDelegatedTestBadFrame const RenderPass* pass = delegated_impl->RenderPassesInDrawOrder()[0]; EXPECT_EQ(2u, pass->quad_list.size()); - const TextureDrawQuad* quad1 = TextureDrawQuad::MaterialCast( - pass->quad_list[0]); + const TextureDrawQuad* quad1 = + TextureDrawQuad::MaterialCast(pass->quad_list.ElementAt(0)); EXPECT_EQ(map.find(999)->second, quad1->resource_id); - const TextureDrawQuad* quad2 = TextureDrawQuad::MaterialCast( - pass->quad_list[1]); + const TextureDrawQuad* quad2 = + TextureDrawQuad::MaterialCast(pass->quad_list.ElementAt(1)); EXPECT_EQ(map.find(555)->second, quad2->resource_id); break; } @@ -1281,11 +1265,11 @@ class LayerTreeHostDelegatedTestBadFrame // 555 in it. const RenderPass* pass = delegated_impl->RenderPassesInDrawOrder()[0]; EXPECT_EQ(2u, pass->quad_list.size()); - const TextureDrawQuad* quad1 = TextureDrawQuad::MaterialCast( - pass->quad_list[0]); + const TextureDrawQuad* quad1 = + TextureDrawQuad::MaterialCast(pass->quad_list.ElementAt(0)); EXPECT_EQ(map.find(999)->second, quad1->resource_id); - const TextureDrawQuad* quad2 = TextureDrawQuad::MaterialCast( - pass->quad_list[1]); + const TextureDrawQuad* quad2 = + TextureDrawQuad::MaterialCast(pass->quad_list.ElementAt(1)); EXPECT_EQ(map.find(555)->second, quad2->resource_id); break; } @@ -1299,8 +1283,8 @@ class LayerTreeHostDelegatedTestBadFrame const RenderPass* pass = delegated_impl->RenderPassesInDrawOrder()[0]; EXPECT_EQ(1u, pass->quad_list.size()); - const TextureDrawQuad* quad1 = TextureDrawQuad::MaterialCast( - pass->quad_list[0]); + const TextureDrawQuad* quad1 = + TextureDrawQuad::MaterialCast(pass->quad_list.front()); EXPECT_EQ(map.find(999)->second, quad1->resource_id); break; } @@ -1313,11 +1297,9 @@ SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestBadFrame); class LayerTreeHostDelegatedTestUnnamedResource : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer { public: - virtual void BeginTest() OVERRIDE { - PostSetNeedsCommitToMainThread(); - } + void BeginTest() override { PostSetNeedsCommitToMainThread(); } - virtual void DidCommit() OVERRIDE { + void DidCommit() override { scoped_ptr<DelegatedFrameData> frame; ReturnedResourceArray resources; @@ -1353,7 +1335,7 @@ class LayerTreeHostDelegatedTestUnnamedResource } } - virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { + void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { if (host_impl->active_tree()->source_frame_number() != 1) return; @@ -1379,11 +1361,9 @@ SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestUnnamedResource); class LayerTreeHostDelegatedTestDontLeakResource : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer { public: - virtual void BeginTest() OVERRIDE { - PostSetNeedsCommitToMainThread(); - } + void BeginTest() override { PostSetNeedsCommitToMainThread(); } - virtual void DidCommitAndDrawFrame() OVERRIDE { + void DidCommitAndDrawFrame() override { scoped_ptr<DelegatedFrameData> frame; ReturnedResourceArray resources; @@ -1431,7 +1411,7 @@ class LayerTreeHostDelegatedTestDontLeakResource } } - virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { + void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { if (host_impl->active_tree()->source_frame_number() != 1) return; @@ -1451,8 +1431,7 @@ class LayerTreeHostDelegatedTestDontLeakResource EXPECT_EQ(1u, delegated_impl->Resources().count(555)); } - virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, - bool result) OVERRIDE { + void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override { ReturnUnusedResourcesFromParent(host_impl); } }; @@ -1462,7 +1441,7 @@ SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestDontLeakResource); class LayerTreeHostDelegatedTestResourceSentToParent : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer { public: - virtual void DidCommitAndDrawFrame() OVERRIDE { + void DidCommitAndDrawFrame() override { scoped_ptr<DelegatedFrameData> frame; ReturnedResourceArray resources; @@ -1517,7 +1496,7 @@ class LayerTreeHostDelegatedTestResourceSentToParent host_impl->ReclaimResources(&ack); } - virtual void UnusedResourcesAreAvailable() OVERRIDE { + void UnusedResourcesAreAvailable() override { EXPECT_EQ(3, layer_tree_host()->source_frame_number()); ReturnedResourceArray resources; @@ -1532,7 +1511,7 @@ class LayerTreeHostDelegatedTestResourceSentToParent EndTest(); } - virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { + void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { if (host_impl->active_tree()->source_frame_number() < 1) return; @@ -1593,13 +1572,13 @@ SINGLE_AND_MULTI_THREAD_DELEGATING_RENDERER_TEST_F( class LayerTreeHostDelegatedTestCommitWithoutTake : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer { public: - virtual void BeginTest() OVERRIDE { + void BeginTest() override { // Prevent drawing with resources that are sent to the grandparent. layer_tree_host()->SetViewportSize(gfx::Size()); PostSetNeedsCommitToMainThread(); } - virtual void DidCommit() OVERRIDE { + void DidCommit() override { scoped_ptr<DelegatedFrameData> frame; ReturnedResourceArray resources; @@ -1665,7 +1644,7 @@ class LayerTreeHostDelegatedTestCommitWithoutTake } } - virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { + void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { if (host_impl->active_tree()->source_frame_number() < 1) return; @@ -1715,7 +1694,7 @@ class DelegatedFrameIsActivatedDuringCommit protected: DelegatedFrameIsActivatedDuringCommit() : returned_resource_count_(0) {} - virtual void BeginTest() OVERRIDE { + void BeginTest() override { activate_count_ = 0; scoped_ptr<DelegatedFrameData> frame = @@ -1727,11 +1706,11 @@ class DelegatedFrameIsActivatedDuringCommit PostSetNeedsCommitToMainThread(); } - virtual void WillActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE { + void WillActivateTreeOnThread(LayerTreeHostImpl* impl) override { ++activate_count_; } - virtual void DidCommit() OVERRIDE { + void DidCommit() override { switch (layer_tree_host()->source_frame_number()) { case 1: { // The first frame has been activated. Set a new frame, and @@ -1758,27 +1737,35 @@ class DelegatedFrameIsActivatedDuringCommit } } - virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { + void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { switch (host_impl->active_tree()->source_frame_number()) { - case 2: { + case 0: { + // The activate for the 1st frame should have happened before now. + EXPECT_EQ(1, activate_count_); + break; + } + case 1: { // The activate for the 2nd frame should have happened before now. EXPECT_EQ(2, activate_count_); break; } - case 3: { + case 2: { // The activate to remove the layer should have happened before now. EXPECT_EQ(3, activate_count_); break; } + case 3: { + NOTREACHED(); + break; + } } } - virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, - bool result) OVERRIDE { + void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override { ReturnUnusedResourcesFromParent(host_impl); } - virtual void UnusedResourcesAreAvailable() OVERRIDE { + void UnusedResourcesAreAvailable() override { LayerTreeHostDelegatedTestCaseSingleDelegatedLayer:: UnusedResourcesAreAvailable(); ReturnedResourceArray resources; @@ -1799,9 +1786,9 @@ SINGLE_AND_MULTI_THREAD_TEST_F( class LayerTreeHostDelegatedTestTwoImplLayers : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer { public: - virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } + void BeginTest() override { PostSetNeedsCommitToMainThread(); } - virtual void DidCommitAndDrawFrame() OVERRIDE { + void DidCommitAndDrawFrame() override { scoped_ptr<DelegatedFrameData> frame; ReturnedResourceArray resources; @@ -1848,8 +1835,7 @@ class LayerTreeHostDelegatedTestTwoImplLayers } } - virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, - bool result) OVERRIDE { + void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override { ReturnUnusedResourcesFromParent(host_impl); } }; @@ -1859,9 +1845,9 @@ SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestTwoImplLayers); class LayerTreeHostDelegatedTestTwoImplLayersTwoFrames : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer { public: - virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } + void BeginTest() override { PostSetNeedsCommitToMainThread(); } - virtual void DidCommitAndDrawFrame() OVERRIDE { + void DidCommitAndDrawFrame() override { scoped_ptr<DelegatedFrameData> frame; ReturnedResourceArray resources; @@ -1917,8 +1903,7 @@ class LayerTreeHostDelegatedTestTwoImplLayersTwoFrames } } - virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, - bool result) OVERRIDE { + void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override { ReturnUnusedResourcesFromParent(host_impl); } }; @@ -1929,9 +1914,9 @@ SINGLE_AND_MULTI_THREAD_TEST_F( class LayerTreeHostDelegatedTestTwoLayers : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer { public: - virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } + void BeginTest() override { PostSetNeedsCommitToMainThread(); } - virtual void DidCommitAndDrawFrame() OVERRIDE { + void DidCommitAndDrawFrame() override { scoped_ptr<DelegatedFrameData> frame; ReturnedResourceArray resources; @@ -2004,8 +1989,7 @@ class LayerTreeHostDelegatedTestTwoLayers } } - virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, - bool result) OVERRIDE { + void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override { ReturnUnusedResourcesFromParent(host_impl); } @@ -2017,9 +2001,9 @@ SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestTwoLayers); class LayerTreeHostDelegatedTestRemoveAndAddToTree : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer { public: - virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } + void BeginTest() override { PostSetNeedsCommitToMainThread(); } - virtual void DidCommitAndDrawFrame() OVERRIDE { + void DidCommitAndDrawFrame() override { scoped_ptr<DelegatedFrameData> frame; ReturnedResourceArray resources; @@ -2096,8 +2080,7 @@ class LayerTreeHostDelegatedTestRemoveAndAddToTree } } - virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, - bool result) OVERRIDE { + void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override { ReturnUnusedResourcesFromParent(host_impl); } @@ -2109,9 +2092,9 @@ SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestRemoveAndAddToTree); class LayerTreeHostDelegatedTestRemoveAndChangeResources : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer { public: - virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } + void BeginTest() override { PostSetNeedsCommitToMainThread(); } - virtual void DidCommitAndDrawFrame() OVERRIDE { + void DidCommitAndDrawFrame() override { scoped_ptr<DelegatedFrameData> frame; ReturnedResourceArray resources; @@ -2178,8 +2161,7 @@ class LayerTreeHostDelegatedTestRemoveAndChangeResources } } - virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, - bool result) OVERRIDE { + void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override { ReturnUnusedResourcesFromParent(host_impl); } diff --git a/chromium/cc/trees/layer_tree_host_unittest_no_message_loop.cc b/chromium/cc/trees/layer_tree_host_unittest_no_message_loop.cc index 4c6796f3021..aa5a5080928 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_no_message_loop.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_no_message_loop.cc @@ -28,10 +28,10 @@ namespace { class NoMessageLoopOutputSurface : public OutputSurface { public: NoMessageLoopOutputSurface() : OutputSurface(TestContextProvider::Create()) {} - virtual ~NoMessageLoopOutputSurface() {} + ~NoMessageLoopOutputSurface() override {} // OutputSurface overrides. - virtual void SwapBuffers(CompositorFrame* frame) OVERRIDE { + void SwapBuffers(CompositorFrame* frame) override { DCHECK(client_); client_->DidSwapBuffers(); client_->DidSwapBuffersComplete(); @@ -53,31 +53,32 @@ class LayerTreeHostNoMessageLoopTest virtual ~LayerTreeHostNoMessageLoopTest() {} // LayerTreeHostClient overrides. - virtual void WillBeginMainFrame(int frame_id) OVERRIDE {} - virtual void DidBeginMainFrame() OVERRIDE {} - virtual void Animate(base::TimeTicks frame_begin_time) OVERRIDE {} - virtual void Layout() OVERRIDE {} - virtual void ApplyScrollAndScale(const gfx::Vector2d& scroll_delta, - float page_scale) OVERRIDE {} - virtual scoped_ptr<OutputSurface> CreateOutputSurface( - bool fallback) OVERRIDE { - return make_scoped_ptr<OutputSurface>(new NoMessageLoopOutputSurface); + void WillBeginMainFrame(int frame_id) override {} + void BeginMainFrame(const BeginFrameArgs& args) override {} + void DidBeginMainFrame() override {} + void Layout() override {} + void ApplyViewportDeltas(const gfx::Vector2d& inner_delta, + const gfx::Vector2d& outer_delta, + float page_scale, + float top_controls_delta) override {} + void ApplyViewportDeltas(const gfx::Vector2d& scroll_delta, + float page_scale, + float top_controls_delta) override {} + void RequestNewOutputSurface(bool fallback) override { + layer_tree_host_->SetOutputSurface( + make_scoped_ptr<OutputSurface>(new NoMessageLoopOutputSurface)); } - virtual void DidInitializeOutputSurface() OVERRIDE { + void DidInitializeOutputSurface() override { did_initialize_output_surface_ = true; } - virtual void WillCommit() OVERRIDE {} - virtual void DidCommit() OVERRIDE { did_commit_ = true; } - virtual void DidCommitAndDrawFrame() OVERRIDE { - did_commit_and_draw_frame_ = true; - } - virtual void DidCompleteSwapBuffers() OVERRIDE {} + void WillCommit() override {} + void DidCommit() override { did_commit_ = true; } + void DidCommitAndDrawFrame() override { did_commit_and_draw_frame_ = true; } + void DidCompleteSwapBuffers() override {} // LayerTreeHostSingleThreadClient overrides. - virtual void ScheduleComposite() OVERRIDE {} - virtual void ScheduleAnimation() OVERRIDE {} - virtual void DidPostSwapBuffers() OVERRIDE {} - virtual void DidAbortSwapBuffers() OVERRIDE {} + void DidPostSwapBuffers() override {} + void DidAbortSwapBuffers() override {} void RunTest() { no_loop_thread_.Start(); @@ -85,10 +86,10 @@ class LayerTreeHostNoMessageLoopTest } // base::DelegateSimpleThread::Delegate override. - virtual void Run() OVERRIDE { - ASSERT_FALSE(base::MessageLoopProxy::current()); + void Run() override { + ASSERT_FALSE(base::MessageLoopProxy::current().get()); RunTestWithoutMessageLoop(); - EXPECT_FALSE(base::MessageLoopProxy::current()); + EXPECT_FALSE(base::MessageLoopProxy::current().get()); } protected: @@ -96,8 +97,9 @@ class LayerTreeHostNoMessageLoopTest void SetupLayerTreeHost() { LayerTreeSettings settings; - layer_tree_host_ = - LayerTreeHost::CreateSingleThreaded(this, this, NULL, settings); + settings.single_thread_proxy_scheduler = false; + layer_tree_host_ = LayerTreeHost::CreateSingleThreaded( + this, this, NULL, NULL, settings, NULL); layer_tree_host_->SetViewportSize(size_); layer_tree_host_->SetRootLayer(root_layer_); } @@ -113,8 +115,8 @@ class LayerTreeHostNoMessageLoopTest void TearDownLayerTreeHost() { // Explicit teardown to make failures easier to debug. - layer_tree_host_.reset(); - root_layer_ = NULL; + layer_tree_host_ = nullptr; + root_layer_ = nullptr; } // All protected member variables are accessed only on |no_loop_thread_|. @@ -133,7 +135,7 @@ class LayerTreeHostNoMessageLoopTest class LayerTreeHostNoMessageLoopSmokeTest : public LayerTreeHostNoMessageLoopTest { protected: - virtual void RunTestWithoutMessageLoop() OVERRIDE { + void RunTestWithoutMessageLoop() override { gfx::Size size(100, 100); // Set up root layer. @@ -160,13 +162,14 @@ class LayerTreeHostNoMessageLoopDelegatedLayer : public LayerTreeHostNoMessageLoopTest, public DelegatedFrameResourceCollectionClient { protected: - virtual void RunTestWithoutMessageLoop() OVERRIDE { + void RunTestWithoutMessageLoop() override { resource_collection_ = new DelegatedFrameResourceCollection; frame_provider_ = new DelegatedFrameProvider( resource_collection_.get(), CreateFrameDataWithResource(998)); root_layer_ = Layer::Create(); - delegated_layer_ = FakeDelegatedRendererLayer::Create(frame_provider_); + delegated_layer_ = + FakeDelegatedRendererLayer::Create(frame_provider_.get()); delegated_layer_->SetBounds(size_); delegated_layer_->SetIsDrawable(true); root_layer_->AddChild(delegated_layer_); @@ -193,7 +196,7 @@ class LayerTreeHostNoMessageLoopDelegatedLayer } // DelegatedFrameResourceCollectionClient overrides. - virtual void UnusedResourcesAreAvailable() OVERRIDE {} + void UnusedResourcesAreAvailable() override {} private: scoped_ptr<DelegatedFrameData> CreateFrameDataWithResource( @@ -203,7 +206,7 @@ class LayerTreeHostNoMessageLoopDelegatedLayer scoped_ptr<RenderPass> root_pass(RenderPass::Create()); root_pass->SetNew( - RenderPass::Id(1, 1), frame_rect, frame_rect, gfx::Transform()); + RenderPassId(1, 1), frame_rect, frame_rect, gfx::Transform()); frame->render_pass_list.push_back(root_pass.Pass()); TransferableResource resource; diff --git a/chromium/cc/trees/layer_tree_host_unittest_occlusion.cc b/chromium/cc/trees/layer_tree_host_unittest_occlusion.cc index cb6a5d32819..fe87e44d667 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_occlusion.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_occlusion.cc @@ -19,34 +19,35 @@ class TestLayer : public Layer { return make_scoped_refptr(new TestLayer()); } - virtual bool Update(ResourceUpdateQueue* update_queue, - const OcclusionTracker<Layer>* occlusion) OVERRIDE { + bool Update(ResourceUpdateQueue* update_queue, + const OcclusionTracker<Layer>* occlusion) override { if (!occlusion) return false; - // Gain access to internals of the OcclusionTracker. const TestOcclusionTracker<Layer>* test_occlusion = static_cast<const TestOcclusionTracker<Layer>*>(occlusion); - occlusion_ = UnionRegions( + occlusion_ = UnionSimpleEnclosedRegions( test_occlusion->occlusion_from_inside_target(), test_occlusion->occlusion_from_outside_target()); return false; } - const Region& occlusion() const { return occlusion_; } - const Region& expected_occlusion() const { return expected_occlusion_; } - void set_expected_occlusion(const Region& occlusion) { - expected_occlusion_ = occlusion; + const SimpleEnclosedRegion& occlusion() const { return occlusion_; } + const SimpleEnclosedRegion& expected_occlusion() const { + return expected_occlusion_; + } + void set_expected_occlusion(const gfx::Rect& occlusion) { + expected_occlusion_ = SimpleEnclosedRegion(occlusion); } private: TestLayer() : Layer() { SetIsDrawable(true); } - virtual ~TestLayer() {} + ~TestLayer() override {} - Region occlusion_; - Region expected_occlusion_; + SimpleEnclosedRegion occlusion_; + SimpleEnclosedRegion expected_occlusion_; }; class LayerTreeHostOcclusionTest : public LayerTreeTest { @@ -59,18 +60,16 @@ class LayerTreeHostOcclusionTest : public LayerTreeTest { mask_(TestLayer::Create()) { } - virtual void BeginTest() OVERRIDE { - PostSetNeedsCommitToMainThread(); - } + void BeginTest() override { PostSetNeedsCommitToMainThread(); } - virtual void DidCommit() OVERRIDE { + void DidCommit() override { TestLayer* root = static_cast<TestLayer*>(layer_tree_host()->root_layer()); VerifyOcclusion(root); EndTest(); } - virtual void AfterTest() OVERRIDE {} + void AfterTest() override {} void VerifyOcclusion(TestLayer* layer) const { EXPECT_EQ(layer->expected_occlusion().ToString(), @@ -98,7 +97,7 @@ class LayerTreeHostOcclusionTest : public LayerTreeTest { } protected: - virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE { + void InitializeSettings(LayerTreeSettings* settings) override { settings->minimum_occlusion_tracking_size = gfx::Size(); } @@ -115,7 +114,7 @@ class LayerTreeHostOcclusionTest : public LayerTreeTest { class LayerTreeHostOcclusionTestOcclusionSurfaceClipping : public LayerTreeHostOcclusionTest { public: - virtual void SetupTree() OVERRIDE { + void SetupTree() override { // The child layer is a surface and the grand_child is opaque, but clipped // to the child and root SetLayerPropertiesForTesting( @@ -145,7 +144,7 @@ SINGLE_AND_MULTI_THREAD_TEST_F( class LayerTreeHostOcclusionTestOcclusionSurfaceClippingOpaque : public LayerTreeHostOcclusionTest { public: - virtual void SetupTree() OVERRIDE { + void SetupTree() override { // If the child layer is opaque, then it adds to the occlusion seen by the // root_. SetLayerPropertiesForTesting( @@ -175,7 +174,7 @@ SINGLE_AND_MULTI_THREAD_TEST_F( class LayerTreeHostOcclusionTestOcclusionTwoChildren : public LayerTreeHostOcclusionTest { public: - virtual void SetupTree() OVERRIDE { + void SetupTree() override { // Add a second child to the root layer and the regions should merge SetLayerPropertiesForTesting( root_.get(), NULL, identity_matrix_, @@ -208,7 +207,7 @@ SINGLE_AND_MULTI_THREAD_TEST_F( class LayerTreeHostOcclusionTestOcclusionMask : public LayerTreeHostOcclusionTest { public: - virtual void SetupTree() OVERRIDE { + void SetupTree() override { // If the child layer has a mask on it, then it shouldn't contribute to // occlusion on stuff below it. SetLayerPropertiesForTesting( @@ -241,7 +240,7 @@ SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostOcclusionTestOcclusionMask); class LayerTreeHostOcclusionTestOcclusionMaskBelowOcclusion : public LayerTreeHostOcclusionTest { public: - virtual void SetupTree() OVERRIDE { + void SetupTree() override { // If the child layer with a mask is below child2, then child2 should // contribute to occlusion on everything, and child shouldn't contribute // to the root_. @@ -277,7 +276,7 @@ SINGLE_AND_MULTI_THREAD_TEST_F( class LayerTreeHostOcclusionTestOcclusionOpacity : public LayerTreeHostOcclusionTest { public: - virtual void SetupTree() OVERRIDE { + void SetupTree() override { // If the child layer has a non-opaque opacity, then it shouldn't // contribute to occlusion on stuff below it SetLayerPropertiesForTesting( @@ -310,7 +309,7 @@ SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostOcclusionTestOcclusionOpacity); class LayerTreeHostOcclusionTestOcclusionOpacityBelowOcclusion : public LayerTreeHostOcclusionTest { public: - virtual void SetupTree() OVERRIDE { + void SetupTree() override { // If the child layer with non-opaque opacity is below child2, then // child2 should contribute to occlusion on everything, and child shouldn't // contribute to the root_. @@ -346,7 +345,7 @@ SINGLE_AND_MULTI_THREAD_TEST_F( class LayerTreeHostOcclusionTestOcclusionBlending : public LayerTreeHostOcclusionTest { public: - virtual void SetupTree() OVERRIDE { + void SetupTree() override { // If the child layer has a blend mode, then it shouldn't // contribute to occlusion on stuff below it SetLayerPropertiesForTesting( @@ -379,7 +378,7 @@ SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostOcclusionTestOcclusionBlending); class LayerTreeHostOcclusionTestOcclusionBlendingBelowOcclusion : public LayerTreeHostOcclusionTest { public: - virtual void SetupTree() OVERRIDE { + void SetupTree() override { // If the child layer with a blend mode is below child2, then // child2 should contribute to occlusion on everything, and child shouldn't // contribute to the root_. @@ -414,12 +413,7 @@ SINGLE_AND_MULTI_THREAD_TEST_F( class LayerTreeHostOcclusionTestOcclusionOpacityFilter : public LayerTreeHostOcclusionTest { public: - virtual void SetupTree() OVERRIDE { - gfx::Transform child_transform; - child_transform.Translate(250.0, 250.0); - child_transform.Rotate(90.0); - child_transform.Translate(-250.0, -250.0); - + void SetupTree() override { FilterOperations filters; filters.Append(FilterOperation::CreateOpacityFilter(0.5f)); @@ -429,23 +423,36 @@ class LayerTreeHostOcclusionTestOcclusionOpacityFilter SetLayerPropertiesForTesting( root_.get(), NULL, identity_matrix_, gfx::PointF(0.f, 0.f), gfx::Size(200, 200), true); - SetLayerPropertiesForTesting( - child_.get(), root_.get(), child_transform, - gfx::PointF(30.f, 30.f), gfx::Size(500, 500), true); - SetLayerPropertiesForTesting( - grand_child_.get(), child_.get(), identity_matrix_, - gfx::PointF(10.f, 10.f), gfx::Size(500, 500), true); - SetLayerPropertiesForTesting( - child2_.get(), root_.get(), identity_matrix_, - gfx::PointF(10.f, 70.f), gfx::Size(500, 500), true); + SetLayerPropertiesForTesting(child_.get(), + root_.get(), + identity_matrix_, + gfx::PointF(0.f, 0.f), + gfx::Size(500, 500), + true); + SetLayerPropertiesForTesting(grand_child_.get(), + child_.get(), + identity_matrix_, + gfx::PointF(0.f, 0.f), + gfx::Size(500, 500), + true); + SetLayerPropertiesForTesting(child2_.get(), + root_.get(), + identity_matrix_, + gfx::PointF(10.f, 10.f), + gfx::Size(30, 30), + true); child_->SetMasksToBounds(true); child_->SetFilters(filters); - grand_child_->set_expected_occlusion(gfx::Rect(40, 330, 130, 190)); - child_->set_expected_occlusion(UnionRegions( - gfx::Rect(10, 330, 160, 170), gfx::Rect(40, 500, 130, 20))); - root_->set_expected_occlusion(gfx::Rect(10, 70, 190, 130)); + // child2_ occludes grand_child_, showing it does occlude inside child_'s + // subtree. + grand_child_->set_expected_occlusion(gfx::Rect(10, 10, 30, 30)); + // grand_child_ occludes child_, showing there is more occlusion in + // child_'s subtree. + child_->set_expected_occlusion(gfx::Rect(0, 0, 200, 200)); + // child2_'s occlusion reaches the root, but child_'s subtree does not. + root_->set_expected_occlusion(gfx::Rect(10, 10, 30, 30)); layer_tree_host()->SetRootLayer(root_); LayerTreeTest::SetupTree(); @@ -458,7 +465,7 @@ SINGLE_AND_MULTI_THREAD_TEST_F( class LayerTreeHostOcclusionTestOcclusionBlurFilter : public LayerTreeHostOcclusionTest { public: - virtual void SetupTree() OVERRIDE { + void SetupTree() override { gfx::Transform child_transform; child_transform.Translate(250.0, 250.0); child_transform.Rotate(90.0); @@ -502,7 +509,7 @@ class LayerTreeHostOcclusionTestOcclusionCopyRequest public: static void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {} - virtual void SetupTree() OVERRIDE { + void SetupTree() override { // If the child layer has copy request, and is below child2, // then child should not inherit occlusion from outside its subtree. // The child layer will still receive occlusion from inside, and @@ -537,7 +544,7 @@ SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostOcclusionTestOcclusionCopyRequest); class LayerTreeHostOcclusionTestOcclusionReplica : public LayerTreeHostOcclusionTest { public: - virtual void SetupTree() OVERRIDE { + void SetupTree() override { // If the child layer has copy request, and is below child2, // then child should not inherit occlusion from outside its subtree. // The child layer will still receive occlusion from inside, and @@ -572,10 +579,10 @@ SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostOcclusionTestOcclusionReplica); class LayerTreeHostOcclusionTestManySurfaces : public LayerTreeHostOcclusionTest { public: - virtual void SetupTree() OVERRIDE { + void SetupTree() override { // We create enough RenderSurfaces that it will trigger Vector reallocation // while computing occlusion. - std::vector<scoped_refptr<TestLayer> > layers; + std::vector<scoped_refptr<TestLayer>> layers; int num_surfaces = 200; int root_width = 400; int root_height = 400; diff --git a/chromium/cc/trees/layer_tree_host_unittest_picture.cc b/chromium/cc/trees/layer_tree_host_unittest_picture.cc index 731f69214af..2d485b40f50 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_picture.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_picture.cc @@ -16,7 +16,7 @@ namespace { // These tests deal with picture layers. class LayerTreeHostPictureTest : public LayerTreeTest { protected: - virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE { + void InitializeSettings(LayerTreeSettings* settings) override { // PictureLayer can only be used with impl side painting enabled. settings->impl_side_painting = true; } @@ -24,7 +24,7 @@ class LayerTreeHostPictureTest : public LayerTreeTest { class LayerTreeHostPictureTestTwinLayer : public LayerTreeHostPictureTest { - virtual void SetupTree() OVERRIDE { + void SetupTree() override { LayerTreeHostPictureTest::SetupTree(); scoped_refptr<FakePictureLayer> picture = @@ -32,12 +32,12 @@ class LayerTreeHostPictureTestTwinLayer layer_tree_host()->root_layer()->AddChild(picture); } - virtual void BeginTest() OVERRIDE { + void BeginTest() override { activates_ = 0; PostSetNeedsCommitToMainThread(); } - virtual void DidCommit() OVERRIDE { + void DidCommit() override { switch (layer_tree_host()->source_frame_number()) { case 2: // Drop the picture layer from the tree. @@ -52,7 +52,7 @@ class LayerTreeHostPictureTestTwinLayer } } - virtual void WillActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE { + void WillActivateTreeOnThread(LayerTreeHostImpl* impl) override { LayerImpl* pending_root_impl = impl->pending_tree()->root_layer(); LayerImpl* active_root_impl = impl->active_tree()->root_layer(); @@ -66,13 +66,13 @@ class LayerTreeHostPictureTestTwinLayer if (!active_root_impl) { EXPECT_EQ(0, activates_); - EXPECT_EQ(NULL, pending_picture_impl->twin_layer()); + EXPECT_EQ(nullptr, pending_picture_impl->GetPendingOrActiveTwinLayer()); return; } if (active_root_impl->children().empty()) { EXPECT_EQ(3, activates_); - EXPECT_EQ(NULL, pending_picture_impl->twin_layer()); + EXPECT_EQ(nullptr, pending_picture_impl->GetPendingOrActiveTwinLayer()); return; } @@ -84,20 +84,28 @@ class LayerTreeHostPictureTestTwinLayer // and the next commit will have a pending and active twin again. EXPECT_TRUE(activates_ == 1 || activates_ == 4); - EXPECT_EQ(pending_picture_impl, active_picture_impl->twin_layer()); - EXPECT_EQ(active_picture_impl, pending_picture_impl->twin_layer()); + EXPECT_EQ(pending_picture_impl, + active_picture_impl->GetPendingOrActiveTwinLayer()); + EXPECT_EQ(active_picture_impl, + pending_picture_impl->GetPendingOrActiveTwinLayer()); + EXPECT_EQ(nullptr, active_picture_impl->GetRecycledTwinLayer()); } - virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE { + void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override { LayerImpl* active_root_impl = impl->active_tree()->root_layer(); + LayerImpl* recycle_root_impl = impl->recycle_tree()->root_layer(); if (active_root_impl->children().empty()) { EXPECT_EQ(2, activates_); } else { FakePictureLayerImpl* active_picture_impl = static_cast<FakePictureLayerImpl*>(active_root_impl->children()[0]); + FakePictureLayerImpl* recycle_picture_impl = + static_cast<FakePictureLayerImpl*>(recycle_root_impl->children()[0]); - EXPECT_EQ(NULL, active_picture_impl->twin_layer()); + EXPECT_EQ(nullptr, active_picture_impl->GetPendingOrActiveTwinLayer()); + EXPECT_EQ(recycle_picture_impl, + active_picture_impl->GetRecycledTwinLayer()); } ++activates_; @@ -107,7 +115,7 @@ class LayerTreeHostPictureTestTwinLayer EndTest(); } - virtual void AfterTest() OVERRIDE {} + void AfterTest() override {} FakeContentLayerClient client_; int activates_; diff --git a/chromium/cc/trees/layer_tree_host_unittest_proxy.cc b/chromium/cc/trees/layer_tree_host_unittest_proxy.cc index 4f79311f649..f27b553a625 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_proxy.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_proxy.cc @@ -37,8 +37,8 @@ class ProxyTest : public LayerTreeTest { RunTest(threaded, delegating_renderer, impl_side_painting); } - virtual void BeginTest() OVERRIDE {} - virtual void AfterTest() OVERRIDE {} + void BeginTest() override {} + void AfterTest() override {} private: DISALLOW_COPY_AND_ASSIGN(ProxyTest); @@ -46,30 +46,24 @@ class ProxyTest : public LayerTreeTest { class ProxyTestScheduledActionsBasic : public ProxyTest { protected: - virtual void BeginTest() OVERRIDE { - proxy()->SetNeedsCommit(); - } + void BeginTest() override { proxy()->SetNeedsCommit(); } - virtual void ScheduledActionBeginOutputSurfaceCreation() OVERRIDE { + void ScheduledActionBeginOutputSurfaceCreation() override { EXPECT_EQ(0, action_phase_++); } - virtual void ScheduledActionSendBeginMainFrame() OVERRIDE { + void ScheduledActionSendBeginMainFrame() override { EXPECT_EQ(1, action_phase_++); } - virtual void ScheduledActionCommit() OVERRIDE { - EXPECT_EQ(2, action_phase_++); - } + void ScheduledActionCommit() override { EXPECT_EQ(2, action_phase_++); } - virtual void ScheduledActionDrawAndSwapIfPossible() OVERRIDE { + void ScheduledActionDrawAndSwapIfPossible() override { EXPECT_EQ(3, action_phase_++); EndTest(); } - virtual void AfterTest() OVERRIDE { - EXPECT_EQ(4, action_phase_); - } + void AfterTest() override { EXPECT_EQ(4, action_phase_); } ProxyTestScheduledActionsBasic() : action_phase_(0) { } @@ -109,7 +103,7 @@ class ThreadProxyTestSetNeedsCommit : public ThreadProxyTest { ThreadProxyTestSetNeedsCommit() {} virtual ~ThreadProxyTestSetNeedsCommit() {} - virtual void BeginTest() OVERRIDE { + void BeginTest() override { EXPECT_FALSE(ThreadProxyMainOnly().commit_requested); EXPECT_FALSE(ThreadProxyMainOnly().commit_request_sent_to_impl_thread); @@ -119,7 +113,7 @@ class ThreadProxyTestSetNeedsCommit : public ThreadProxyTest { EXPECT_TRUE(ThreadProxyMainOnly().commit_request_sent_to_impl_thread); } - virtual void DidBeginMainFrame() OVERRIDE { + void DidBeginMainFrame() override { EXPECT_FALSE(ThreadProxyMainOnly().commit_requested); EXPECT_FALSE(ThreadProxyMainOnly().commit_request_sent_to_impl_thread); diff --git a/chromium/cc/trees/layer_tree_host_unittest_scroll.cc b/chromium/cc/trees/layer_tree_host_unittest_scroll.cc index 05a58764018..8e7d220d1ae 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_scroll.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_scroll.cc @@ -5,18 +5,20 @@ #include "cc/trees/layer_tree_host.h" #include "base/memory/weak_ptr.h" -#include "cc/layers/content_layer.h" #include "cc/layers/layer.h" #include "cc/layers/layer_impl.h" +#include "cc/layers/picture_layer.h" #include "cc/test/fake_content_layer_client.h" #include "cc/test/fake_layer_tree_host_client.h" +#include "cc/test/fake_picture_layer.h" +#include "cc/test/fake_picture_layer_impl.h" #include "cc/test/geometry_test_utils.h" #include "cc/test/layer_tree_test.h" #include "cc/test/test_shared_bitmap_manager.h" #include "cc/trees/layer_tree_impl.h" -#include "ui/gfx/point_conversions.h" -#include "ui/gfx/size_conversions.h" -#include "ui/gfx/vector2d_conversions.h" +#include "ui/gfx/geometry/point_conversions.h" +#include "ui/gfx/geometry/size_conversions.h" +#include "ui/gfx/geometry/vector2d_conversions.h" namespace cc { namespace { @@ -31,7 +33,7 @@ class LayerTreeHostScrollTestScrollSimple : public LayerTreeHostScrollTest { scroll_amount_(2, -1), num_scrolls_(0) {} - virtual void BeginTest() OVERRIDE { + void BeginTest() override { Layer* root_layer = layer_tree_host()->root_layer(); scoped_refptr<Layer> scroll_layer = Layer::Create(); root_layer->AddChild(scroll_layer); @@ -46,13 +48,14 @@ class LayerTreeHostScrollTestScrollSimple : public LayerTreeHostScrollTest { PostSetNeedsCommitToMainThread(); } - virtual void Layout() OVERRIDE { + void Layout() override { Layer* root = layer_tree_host()->root_layer(); - Layer* scroll_layer = root->children()[0]; + Layer* scroll_layer = root->children()[0].get(); if (!layer_tree_host()->source_frame_number()) { EXPECT_VECTOR_EQ(initial_scroll_, scroll_layer->scroll_offset()); } else { - EXPECT_VECTOR_EQ(initial_scroll_ + scroll_amount_, + EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(initial_scroll_, + scroll_amount_), scroll_layer->scroll_offset()); // Pretend like Javascript updated the scroll position itself. @@ -60,7 +63,7 @@ class LayerTreeHostScrollTestScrollSimple : public LayerTreeHostScrollTest { } } - virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE { + void DrawLayersOnThread(LayerTreeHostImpl* impl) override { LayerImpl* root = impl->active_tree()->root_layer(); LayerImpl* scroll_layer = root->children()[0]; EXPECT_VECTOR_EQ(gfx::Vector2d(), scroll_layer->ScrollDelta()); @@ -84,17 +87,18 @@ class LayerTreeHostScrollTestScrollSimple : public LayerTreeHostScrollTest { } } - virtual void ApplyScrollAndScale(const gfx::Vector2d& scroll_delta, - float scale) OVERRIDE { + void ApplyViewportDeltas(const gfx::Vector2d& scroll_delta, + float scale, + float top_controls_delta) override { num_scrolls_++; } - virtual void AfterTest() OVERRIDE { EXPECT_EQ(1, num_scrolls_); } + void AfterTest() override { EXPECT_EQ(1, num_scrolls_); } private: - gfx::Vector2d initial_scroll_; - gfx::Vector2d second_scroll_; - gfx::Vector2d scroll_amount_; + gfx::ScrollOffset initial_scroll_; + gfx::ScrollOffset second_scroll_; + gfx::Vector2dF scroll_amount_; int num_scrolls_; }; @@ -106,7 +110,7 @@ class LayerTreeHostScrollTestScrollMultipleRedraw LayerTreeHostScrollTestScrollMultipleRedraw() : initial_scroll_(40, 10), scroll_amount_(-3, 17), num_scrolls_(0) {} - virtual void BeginTest() OVERRIDE { + void BeginTest() override { Layer* root_layer = layer_tree_host()->root_layer(); scroll_layer_ = Layer::Create(); root_layer->AddChild(scroll_layer_); @@ -121,22 +125,26 @@ class LayerTreeHostScrollTestScrollMultipleRedraw PostSetNeedsCommitToMainThread(); } - virtual void BeginCommitOnThread(LayerTreeHostImpl* impl) OVERRIDE { + void BeginCommitOnThread(LayerTreeHostImpl* impl) override { switch (layer_tree_host()->source_frame_number()) { case 0: EXPECT_VECTOR_EQ(scroll_layer_->scroll_offset(), initial_scroll_); break; case 1: - EXPECT_VECTOR_EQ(scroll_layer_->scroll_offset(), - initial_scroll_ + scroll_amount_ + scroll_amount_); + EXPECT_VECTOR_EQ( + scroll_layer_->scroll_offset(), + gfx::ScrollOffsetWithDelta(initial_scroll_, + scroll_amount_ + scroll_amount_)); case 2: - EXPECT_VECTOR_EQ(scroll_layer_->scroll_offset(), - initial_scroll_ + scroll_amount_ + scroll_amount_); + EXPECT_VECTOR_EQ( + scroll_layer_->scroll_offset(), + gfx::ScrollOffsetWithDelta(initial_scroll_, + scroll_amount_ + scroll_amount_)); break; } } - virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE { + void DrawLayersOnThread(LayerTreeHostImpl* impl) override { LayerImpl* scroll_layer = impl->active_tree()->LayerById(scroll_layer_->id()); if (impl->active_tree()->source_frame_number() == 0 && @@ -162,22 +170,25 @@ class LayerTreeHostScrollTestScrollMultipleRedraw // Third or later draw after second commit. EXPECT_GE(impl->SourceAnimationFrameNumber(), 3); EXPECT_VECTOR_EQ(scroll_layer_->ScrollDelta(), gfx::Vector2d()); - EXPECT_VECTOR_EQ(scroll_layer_->scroll_offset(), - initial_scroll_ + scroll_amount_ + scroll_amount_); + EXPECT_VECTOR_EQ( + scroll_layer_->scroll_offset(), + gfx::ScrollOffsetWithDelta(initial_scroll_, + scroll_amount_ + scroll_amount_)); EndTest(); } } - virtual void ApplyScrollAndScale(const gfx::Vector2d& scroll_delta, - float scale) OVERRIDE { + void ApplyViewportDeltas(const gfx::Vector2d& scroll_delta, + float scale, + float top_controls_delta) override { num_scrolls_++; } - virtual void AfterTest() OVERRIDE { EXPECT_EQ(1, num_scrolls_); } + void AfterTest() override { EXPECT_EQ(1, num_scrolls_); } private: - gfx::Vector2d initial_scroll_; - gfx::Vector2d scroll_amount_; + gfx::ScrollOffset initial_scroll_; + gfx::Vector2dF scroll_amount_; int num_scrolls_; scoped_refptr<Layer> scroll_layer_; }; @@ -199,9 +210,9 @@ class LayerTreeHostScrollTestScrollAbortedCommit num_impl_commits_(0), num_impl_scrolls_(0) {} - virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } + void BeginTest() override { PostSetNeedsCommitToMainThread(); } - virtual void SetupTree() OVERRIDE { + void SetupTree() override { LayerTreeHostScrollTest::SetupTree(); Layer* root_layer = layer_tree_host()->root_layer(); scoped_refptr<Layer> root_scroll_layer = Layer::Create(); @@ -217,9 +228,10 @@ class LayerTreeHostScrollTestScrollAbortedCommit layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.01f, 100.f); } - virtual void WillBeginMainFrame() OVERRIDE { + void WillBeginMainFrame() override { num_will_begin_main_frames_++; - Layer* root_scroll_layer = layer_tree_host()->root_layer()->children()[0]; + Layer* root_scroll_layer = + layer_tree_host()->root_layer()->children()[0].get(); switch (num_will_begin_main_frames_) { case 1: // This will not be aborted because of the initial prop changes. @@ -233,8 +245,9 @@ class LayerTreeHostScrollTestScrollAbortedCommit // initiated from the redraw. EXPECT_EQ(1, num_impl_scrolls_); EXPECT_EQ(1, layer_tree_host()->source_frame_number()); - EXPECT_VECTOR_EQ(root_scroll_layer->scroll_offset(), - initial_scroll_ + impl_scroll_); + EXPECT_VECTOR_EQ( + root_scroll_layer->scroll_offset(), + gfx::ScrollOffsetWithDelta(initial_scroll_, impl_scroll_)); EXPECT_EQ(impl_scale_, layer_tree_host()->page_scale_factor()); PostSetNeedsRedrawToMainThread(); break; @@ -243,37 +256,41 @@ class LayerTreeHostScrollTestScrollAbortedCommit EXPECT_EQ(2, num_impl_scrolls_); // The source frame number still increases even with the abort. EXPECT_EQ(2, layer_tree_host()->source_frame_number()); - EXPECT_VECTOR_EQ(root_scroll_layer->scroll_offset(), - initial_scroll_ + impl_scroll_ + impl_scroll_); + EXPECT_VECTOR_EQ( + root_scroll_layer->scroll_offset(), + gfx::ScrollOffsetWithDelta(initial_scroll_, + impl_scroll_ + impl_scroll_)); EXPECT_EQ(impl_scale_ * impl_scale_, layer_tree_host()->page_scale_factor()); - root_scroll_layer->SetScrollOffset(root_scroll_layer->scroll_offset() + - second_main_scroll_); + root_scroll_layer->SetScrollOffset(gfx::ScrollOffsetWithDelta( + root_scroll_layer->scroll_offset(), second_main_scroll_)); break; case 4: // This commit will also be aborted. EXPECT_EQ(3, num_impl_scrolls_); EXPECT_EQ(3, layer_tree_host()->source_frame_number()); + gfx::Vector2dF delta = + impl_scroll_ + impl_scroll_ + impl_scroll_ + second_main_scroll_; EXPECT_VECTOR_EQ(root_scroll_layer->scroll_offset(), - initial_scroll_ + impl_scroll_ + impl_scroll_ + - impl_scroll_ + second_main_scroll_); + gfx::ScrollOffsetWithDelta(initial_scroll_, delta)); + // End the test by drawing to verify this commit is also aborted. PostSetNeedsRedrawToMainThread(); break; } } - virtual void DidBeginMainFrame() OVERRIDE { num_did_begin_main_frames_++; } + void DidBeginMainFrame() override { num_did_begin_main_frames_++; } - virtual void WillCommit() OVERRIDE { num_will_commits_++; } + void WillCommit() override { num_will_commits_++; } - virtual void DidCommit() OVERRIDE { num_did_commits_++; } + void DidCommit() override { num_did_commits_++; } - virtual void BeginCommitOnThread(LayerTreeHostImpl* impl) OVERRIDE { + void BeginCommitOnThread(LayerTreeHostImpl* impl) override { num_impl_commits_++; } - virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE { + void DrawLayersOnThread(LayerTreeHostImpl* impl) override { LayerImpl* root_scroll_layer = impl->active_tree()->root_layer()->children()[0]; @@ -301,8 +318,9 @@ class LayerTreeHostScrollTestScrollAbortedCommit EXPECT_VECTOR_EQ(root_scroll_layer->ScrollDelta(), gfx::Vector2d()); root_scroll_layer->ScrollBy(impl_scroll_); EXPECT_VECTOR_EQ(root_scroll_layer->ScrollDelta(), impl_scroll_); - EXPECT_VECTOR_EQ(root_scroll_layer->scroll_offset(), - initial_scroll_ + impl_scroll_); + EXPECT_VECTOR_EQ( + root_scroll_layer->scroll_offset(), + gfx::ScrollOffsetWithDelta(initial_scroll_, impl_scroll_)); EXPECT_EQ(1.f, impl->active_tree()->page_scale_delta()); EXPECT_EQ(impl_scale_, impl->active_tree()->total_page_scale_factor()); @@ -322,16 +340,17 @@ class LayerTreeHostScrollTestScrollAbortedCommit root_scroll_layer->ScrollBy(impl_scroll_); impl->SetNeedsCommit(); EXPECT_VECTOR_EQ(root_scroll_layer->ScrollDelta(), impl_scroll_); - EXPECT_VECTOR_EQ( - root_scroll_layer->scroll_offset(), - initial_scroll_ + impl_scroll_ + impl_scroll_ + second_main_scroll_); + gfx::Vector2dF delta = impl_scroll_ + impl_scroll_ + second_main_scroll_; + EXPECT_VECTOR_EQ(root_scroll_layer->scroll_offset(), + gfx::ScrollOffsetWithDelta(initial_scroll_, delta)); } else if (impl->active_tree()->source_frame_number() == 2 && impl->SourceAnimationFrameNumber() == 4) { // Final draw after the second aborted commit. EXPECT_VECTOR_EQ(root_scroll_layer->ScrollDelta(), gfx::Vector2d()); + gfx::Vector2dF delta = + impl_scroll_ + impl_scroll_ + impl_scroll_ + second_main_scroll_; EXPECT_VECTOR_EQ(root_scroll_layer->scroll_offset(), - initial_scroll_ + impl_scroll_ + impl_scroll_ + - impl_scroll_ + second_main_scroll_); + gfx::ScrollOffsetWithDelta(initial_scroll_, delta)); EndTest(); } else { // Commit for source frame 3 is aborted. @@ -339,12 +358,13 @@ class LayerTreeHostScrollTestScrollAbortedCommit } } - virtual void ApplyScrollAndScale(const gfx::Vector2d& scroll_delta, - float scale) OVERRIDE { + void ApplyViewportDeltas(const gfx::Vector2d& scroll_delta, + float scale, + float top_controls_delta) override { num_impl_scrolls_++; } - virtual void AfterTest() OVERRIDE { + void AfterTest() override { EXPECT_EQ(3, num_impl_scrolls_); // Verify that the embedder sees aborted commits as real commits. EXPECT_EQ(4, num_will_begin_main_frames_); @@ -356,9 +376,9 @@ class LayerTreeHostScrollTestScrollAbortedCommit } private: - gfx::Vector2d initial_scroll_; - gfx::Vector2d impl_scroll_; - gfx::Vector2d second_main_scroll_; + gfx::ScrollOffset initial_scroll_; + gfx::Vector2dF impl_scroll_; + gfx::Vector2dF second_main_scroll_; float impl_scale_; int num_will_begin_main_frames_; int num_did_begin_main_frames_; @@ -374,7 +394,7 @@ class LayerTreeHostScrollTestFractionalScroll : public LayerTreeHostScrollTest { public: LayerTreeHostScrollTestFractionalScroll() : scroll_amount_(1.75, 0) {} - virtual void SetupTree() OVERRIDE { + void SetupTree() override { LayerTreeHostScrollTest::SetupTree(); Layer* root_layer = layer_tree_host()->root_layer(); scoped_refptr<Layer> root_scroll_layer = Layer::Create(); @@ -391,11 +411,9 @@ class LayerTreeHostScrollTestFractionalScroll : public LayerTreeHostScrollTest { layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.01f, 100.f); } - virtual void BeginTest() OVERRIDE { - PostSetNeedsCommitToMainThread(); - } + void BeginTest() override { PostSetNeedsCommitToMainThread(); } - virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE { + void DrawLayersOnThread(LayerTreeHostImpl* impl) override { LayerImpl* root = impl->active_tree()->root_layer(); LayerImpl* scroll_layer = root->children()[0]; @@ -427,7 +445,7 @@ class LayerTreeHostScrollTestFractionalScroll : public LayerTreeHostScrollTest { scroll_layer->ScrollBy(scroll_amount_); } - virtual void AfterTest() OVERRIDE {} + void AfterTest() override {} private: gfx::Vector2dF scroll_amount_; @@ -443,13 +461,13 @@ class LayerTreeHostScrollTestCaseWithChild : public LayerTreeHostScrollTest { scroll_amount_(2, -1), num_scrolls_(0) {} - virtual void SetupTree() OVERRIDE { + void SetupTree() override { layer_tree_host()->SetDeviceScaleFactor(device_scale_factor_); scoped_refptr<Layer> root_layer = Layer::Create(); root_layer->SetBounds(gfx::Size(10, 10)); - root_scroll_layer_ = ContentLayer::Create(&fake_content_layer_client_); + root_scroll_layer_ = FakePictureLayer::Create(&fake_content_layer_client_); root_scroll_layer_->SetBounds(gfx::Size(110, 110)); root_scroll_layer_->SetPosition(gfx::Point()); @@ -459,7 +477,7 @@ class LayerTreeHostScrollTestCaseWithChild : public LayerTreeHostScrollTest { root_scroll_layer_->SetIsContainerForFixedPositionLayers(true); root_layer->AddChild(root_scroll_layer_); - child_layer_ = ContentLayer::Create(&fake_content_layer_client_); + child_layer_ = FakePictureLayer::Create(&fake_content_layer_client_); child_layer_->set_did_scroll_callback( base::Bind(&LayerTreeHostScrollTestCaseWithChild::DidScroll, base::Unretained(this))); @@ -496,9 +514,9 @@ class LayerTreeHostScrollTestCaseWithChild : public LayerTreeHostScrollTest { LayerTreeHostScrollTest::SetupTree(); } - virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } + void BeginTest() override { PostSetNeedsCommitToMainThread(); } - virtual void WillCommit() OVERRIDE { + void WillCommit() override { // Keep the test committing (otherwise the early out for no update // will stall the test). if (layer_tree_host()->source_frame_number() < 2) { @@ -510,12 +528,13 @@ class LayerTreeHostScrollTestCaseWithChild : public LayerTreeHostScrollTest { final_scroll_offset_ = expected_scroll_layer_->scroll_offset(); } - virtual void ApplyScrollAndScale(const gfx::Vector2d& scroll_delta, - float scale) OVERRIDE { + void ApplyViewportDeltas(const gfx::Vector2d& scroll_delta, + float scale, + float top_controls_delta) override { num_scrolls_++; } - virtual void Layout() OVERRIDE { + void Layout() override { EXPECT_VECTOR_EQ(gfx::Vector2d(), expected_no_scroll_layer_->scroll_offset()); @@ -525,23 +544,27 @@ class LayerTreeHostScrollTestCaseWithChild : public LayerTreeHostScrollTest { expected_scroll_layer_->scroll_offset()); break; case 1: - EXPECT_VECTOR_EQ(initial_offset_ + scroll_amount_, - expected_scroll_layer_->scroll_offset()); + EXPECT_VECTOR_EQ( + gfx::ScrollOffsetWithDelta(initial_offset_, scroll_amount_), + expected_scroll_layer_->scroll_offset()); // Pretend like Javascript updated the scroll position itself. expected_scroll_layer_->SetScrollOffset(javascript_scroll_); break; case 2: - EXPECT_VECTOR_EQ(javascript_scroll_ + scroll_amount_, + EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(javascript_scroll_, + scroll_amount_), expected_scroll_layer_->scroll_offset()); break; } } - virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE { + void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override { LayerImpl* root_impl = impl->active_tree()->root_layer(); - LayerImpl* root_scroll_layer_impl = root_impl->children()[0]; - LayerImpl* child_layer_impl = root_scroll_layer_impl->children()[0]; + FakePictureLayerImpl* root_scroll_layer_impl = + static_cast<FakePictureLayerImpl*>(root_impl->children()[0]); + FakePictureLayerImpl* child_layer_impl = static_cast<FakePictureLayerImpl*>( + root_scroll_layer_impl->children()[0]); LayerImpl* expected_scroll_layer_impl = NULL; LayerImpl* expected_no_scroll_layer_impl = NULL; @@ -557,16 +580,8 @@ class LayerTreeHostScrollTestCaseWithChild : public LayerTreeHostScrollTest { EXPECT_VECTOR_EQ(gfx::Vector2d(), expected_no_scroll_layer_impl->ScrollDelta()); - // Ensure device scale factor is affecting the layers. - gfx::Size expected_content_bounds = gfx::ToCeiledSize( - gfx::ScaleSize(root_scroll_layer_impl->bounds(), device_scale_factor_)); - EXPECT_SIZE_EQ(expected_content_bounds, - root_scroll_layer_->content_bounds()); - - expected_content_bounds = gfx::ToCeiledSize( - gfx::ScaleSize(child_layer_impl->bounds(), device_scale_factor_)); - EXPECT_SIZE_EQ(expected_content_bounds, child_layer_->content_bounds()); - + // Ensure device scale factor matches the active tree. + EXPECT_EQ(device_scale_factor_, impl->active_tree()->device_scale_factor()); switch (impl->active_tree()->source_frame_number()) { case 0: { // Gesture scroll on impl thread. @@ -604,7 +619,8 @@ class LayerTreeHostScrollTestCaseWithChild : public LayerTreeHostScrollTest { } case 2: - EXPECT_VECTOR_EQ(javascript_scroll_ + scroll_amount_, + EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(javascript_scroll_, + scroll_amount_), expected_scroll_layer_impl->scroll_offset()); EXPECT_VECTOR_EQ(gfx::Vector2d(), expected_scroll_layer_impl->ScrollDelta()); @@ -614,14 +630,15 @@ class LayerTreeHostScrollTestCaseWithChild : public LayerTreeHostScrollTest { } } - virtual void AfterTest() OVERRIDE { + void AfterTest() override { if (scroll_child_layer_) { EXPECT_EQ(0, num_scrolls_); - EXPECT_VECTOR_EQ(javascript_scroll_ + scroll_amount_, + EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(javascript_scroll_, + scroll_amount_), final_scroll_offset_); } else { EXPECT_EQ(2, num_scrolls_); - EXPECT_VECTOR_EQ(gfx::Vector2d(), final_scroll_offset_); + EXPECT_VECTOR_EQ(gfx::ScrollOffset(), final_scroll_offset_); } } @@ -629,11 +646,11 @@ class LayerTreeHostScrollTestCaseWithChild : public LayerTreeHostScrollTest { float device_scale_factor_; bool scroll_child_layer_; - gfx::Vector2d initial_offset_; - gfx::Vector2d javascript_scroll_; + gfx::ScrollOffset initial_offset_; + gfx::ScrollOffset javascript_scroll_; gfx::Vector2d scroll_amount_; int num_scrolls_; - gfx::Vector2d final_scroll_offset_; + gfx::ScrollOffset final_scroll_offset_; FakeContentLayerClient fake_content_layer_client_; @@ -644,28 +661,14 @@ class LayerTreeHostScrollTestCaseWithChild : public LayerTreeHostScrollTest { }; TEST_F(LayerTreeHostScrollTestCaseWithChild, - DeviceScaleFactor1_ScrollChild_DirectRenderer_MainThreadPaint) { - device_scale_factor_ = 1.f; - scroll_child_layer_ = true; - RunTest(true, false, false); -} - -TEST_F(LayerTreeHostScrollTestCaseWithChild, - DeviceScaleFactor1_ScrollChild_DirectRenderer_ImplSidePaint) { + DeviceScaleFactor1_ScrollChild_DirectRenderer) { device_scale_factor_ = 1.f; scroll_child_layer_ = true; RunTest(true, false, true); } TEST_F(LayerTreeHostScrollTestCaseWithChild, - DeviceScaleFactor1_ScrollChild_DelegatingRenderer_MainThreadPaint) { - device_scale_factor_ = 1.f; - scroll_child_layer_ = true; - RunTest(true, true, false); -} - -TEST_F(LayerTreeHostScrollTestCaseWithChild, - DeviceScaleFactor1_ScrollChild_DelegatingRenderer_ImplSidePaint) { + DeviceScaleFactor1_ScrollChild_DelegatingRenderer) { device_scale_factor_ = 1.f; scroll_child_layer_ = true; RunTest(true, true, true); @@ -728,14 +731,7 @@ TEST_F(LayerTreeHostScrollTestCaseWithChild, } TEST_F(LayerTreeHostScrollTestCaseWithChild, - DeviceScaleFactor2_ScrollRootScrollLayer_DirectRenderer_MainSidePaint) { - device_scale_factor_ = 2.f; - scroll_child_layer_ = false; - RunTest(true, false, false); -} - -TEST_F(LayerTreeHostScrollTestCaseWithChild, - DeviceScaleFactor2_ScrollRootScrollLayer_DirectRenderer_ImplSidePaint) { + DeviceScaleFactor2_ScrollRootScrollLayer_DirectRenderer) { device_scale_factor_ = 2.f; scroll_child_layer_ = false; RunTest(true, false, true); @@ -750,11 +746,11 @@ TEST_F(LayerTreeHostScrollTestCaseWithChild, class ImplSidePaintingScrollTest : public LayerTreeHostScrollTest { public: - virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE { + void InitializeSettings(LayerTreeSettings* settings) override { settings->impl_side_painting = true; } - virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE { + void DrawLayersOnThread(LayerTreeHostImpl* impl) override { if (impl->pending_tree()) impl->SetNeedsRedraw(); } @@ -769,7 +765,7 @@ class ImplSidePaintingScrollTestSimple : public ImplSidePaintingScrollTest { impl_thread_scroll2_(-3, 10), num_scrolls_(0) {} - virtual void SetupTree() OVERRIDE { + void SetupTree() override { LayerTreeHostScrollTest::SetupTree(); Layer* root_layer = layer_tree_host()->root_layer(); scoped_refptr<Layer> root_scroll_layer = Layer::Create(); @@ -787,34 +783,34 @@ class ImplSidePaintingScrollTestSimple : public ImplSidePaintingScrollTest { layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.01f, 100.f); } - virtual void BeginTest() OVERRIDE { - PostSetNeedsCommitToMainThread(); - } + void BeginTest() override { PostSetNeedsCommitToMainThread(); } - virtual void Layout() OVERRIDE { + void Layout() override { Layer* root = layer_tree_host()->root_layer(); - Layer* scroll_layer = root->children()[0]; + Layer* scroll_layer = root->children()[0].get(); if (!layer_tree_host()->source_frame_number()) { EXPECT_VECTOR_EQ(scroll_layer->scroll_offset(), initial_scroll_); } else { - EXPECT_VECTOR_EQ(scroll_layer->scroll_offset(), - initial_scroll_ + impl_thread_scroll1_); + EXPECT_VECTOR_EQ( + scroll_layer->scroll_offset(), + gfx::ScrollOffsetWithDelta(initial_scroll_, impl_thread_scroll1_)); // Pretend like Javascript updated the scroll position itself with a // change of main_thread_scroll. - scroll_layer->SetScrollOffset(initial_scroll_ + main_thread_scroll_ + - impl_thread_scroll1_); + scroll_layer->SetScrollOffset( + gfx::ScrollOffsetWithDelta( + initial_scroll_, main_thread_scroll_ + impl_thread_scroll1_)); } } - virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE { + void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { // We force a second draw here of the first commit before activating // the second commit. if (impl->active_tree()->source_frame_number() == 0) impl->SetNeedsRedraw(); } - virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE { + void DrawLayersOnThread(LayerTreeHostImpl* impl) override { ImplSidePaintingScrollTest::DrawLayersOnThread(impl); LayerImpl* root = impl->active_tree()->root_layer(); @@ -851,7 +847,8 @@ class ImplSidePaintingScrollTestSimple : public ImplSidePaintingScrollTest { LayerImpl* pending_scroll_layer = pending_root->children()[0]; EXPECT_VECTOR_EQ( pending_scroll_layer->scroll_offset(), - initial_scroll_ + main_thread_scroll_ + impl_thread_scroll1_); + gfx::ScrollOffsetWithDelta( + initial_scroll_, main_thread_scroll_ + impl_thread_scroll1_)); EXPECT_VECTOR_EQ(pending_scroll_layer->ScrollDelta(), impl_thread_scroll2_); EXPECT_VECTOR_EQ(pending_scroll_layer->sent_scroll_delta(), @@ -862,7 +859,8 @@ class ImplSidePaintingScrollTestSimple : public ImplSidePaintingScrollTest { EXPECT_FALSE(impl->pending_tree()); EXPECT_VECTOR_EQ( scroll_layer->scroll_offset(), - initial_scroll_ + main_thread_scroll_ + impl_thread_scroll1_); + gfx::ScrollOffsetWithDelta( + initial_scroll_, main_thread_scroll_ + impl_thread_scroll1_)); EXPECT_VECTOR_EQ(scroll_layer->ScrollDelta(), impl_thread_scroll2_); EXPECT_VECTOR_EQ(scroll_layer->sent_scroll_delta(), gfx::Vector2d()); EndTest(); @@ -870,18 +868,19 @@ class ImplSidePaintingScrollTestSimple : public ImplSidePaintingScrollTest { } } - virtual void ApplyScrollAndScale(const gfx::Vector2d& scroll_delta, - float scale) OVERRIDE { + void ApplyViewportDeltas(const gfx::Vector2d& scroll_delta, + float scale, + float top_controls_delta) override { num_scrolls_++; } - virtual void AfterTest() OVERRIDE { EXPECT_EQ(1, num_scrolls_); } + void AfterTest() override { EXPECT_EQ(1, num_scrolls_); } private: - gfx::Vector2d initial_scroll_; - gfx::Vector2d main_thread_scroll_; - gfx::Vector2d impl_thread_scroll1_; - gfx::Vector2d impl_thread_scroll2_; + gfx::ScrollOffset initial_scroll_; + gfx::Vector2dF main_thread_scroll_; + gfx::Vector2dF impl_thread_scroll1_; + gfx::Vector2dF impl_thread_scroll2_; int num_scrolls_; }; @@ -897,7 +896,7 @@ class ImplSidePaintingScrollTestImplOnlyScroll ImplSidePaintingScrollTestImplOnlyScroll() : initial_scroll_(20, 10), impl_thread_scroll_(-2, 3) {} - virtual void SetupTree() OVERRIDE { + void SetupTree() override { LayerTreeHostScrollTest::SetupTree(); Layer* root_layer = layer_tree_host()->root_layer(); scoped_refptr<Layer> root_scroll_layer = Layer::Create(); @@ -915,13 +914,11 @@ class ImplSidePaintingScrollTestImplOnlyScroll layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.01f, 100.f); } - virtual void BeginTest() OVERRIDE { - PostSetNeedsCommitToMainThread(); - } + void BeginTest() override { PostSetNeedsCommitToMainThread(); } - virtual void WillCommit() OVERRIDE { + void WillCommit() override { Layer* root = layer_tree_host()->root_layer(); - Layer* scroll_layer = root->children()[0]; + Layer* scroll_layer = root->children()[0].get(); switch (layer_tree_host()->source_frame_number()) { case 0: EXPECT_TRUE(scroll_layer->needs_push_properties()); @@ -935,7 +932,7 @@ class ImplSidePaintingScrollTestImplOnlyScroll } } - virtual void BeginCommitOnThread(LayerTreeHostImpl* impl) OVERRIDE { + void BeginCommitOnThread(LayerTreeHostImpl* impl) override { // Scroll after the 2nd commit has started. if (impl->active_tree()->source_frame_number() == 0) { LayerImpl* active_root = impl->active_tree()->root_layer(); @@ -946,7 +943,7 @@ class ImplSidePaintingScrollTestImplOnlyScroll } } - virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE { + void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { // We force a second draw here of the first commit before activating // the second commit. LayerImpl* active_root = impl->active_tree()->root_layer(); @@ -985,7 +982,8 @@ class ImplSidePaintingScrollTestImplOnlyScroll case 2: // On the next commit, this delta should have been sent and applied. EXPECT_VECTOR_EQ(pending_scroll_layer->scroll_offset(), - initial_scroll_ + impl_thread_scroll_); + gfx::ScrollOffsetWithDelta(initial_scroll_, + impl_thread_scroll_)); EXPECT_VECTOR_EQ(pending_scroll_layer->ScrollDelta(), gfx::Vector2d()); EXPECT_VECTOR_EQ(pending_scroll_layer->sent_scroll_delta(), gfx::Vector2d()); @@ -994,7 +992,7 @@ class ImplSidePaintingScrollTestImplOnlyScroll } } - virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE { + void DrawLayersOnThread(LayerTreeHostImpl* impl) override { ImplSidePaintingScrollTest::DrawLayersOnThread(impl); LayerImpl* root = impl->active_tree()->root_layer(); @@ -1016,11 +1014,11 @@ class ImplSidePaintingScrollTestImplOnlyScroll } } - virtual void AfterTest() OVERRIDE {} + void AfterTest() override {} private: - gfx::Vector2d initial_scroll_; - gfx::Vector2d impl_thread_scroll_; + gfx::ScrollOffset initial_scroll_; + gfx::Vector2dF impl_thread_scroll_; }; MULTI_THREAD_TEST_F(ImplSidePaintingScrollTestImplOnlyScroll); @@ -1030,15 +1028,15 @@ class LayerTreeHostScrollTestScrollZeroMaxScrollOffset public: LayerTreeHostScrollTestScrollZeroMaxScrollOffset() {} - virtual void SetupTree() OVERRIDE { + void SetupTree() override { LayerTreeTest::SetupTree(); scoped_refptr<Layer> scroll_layer = Layer::Create(); layer_tree_host()->root_layer()->AddChild(scroll_layer); } - virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } + void BeginTest() override { PostSetNeedsCommitToMainThread(); } - virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE { + void DrawLayersOnThread(LayerTreeHostImpl* impl) override { LayerImpl* root = impl->active_tree()->root_layer(); LayerImpl* scroll_layer = root->children()[0]; scroll_layer->SetScrollClipLayer(root->id()); @@ -1065,7 +1063,7 @@ class LayerTreeHostScrollTestScrollZeroMaxScrollOffset EndTest(); } - virtual void AfterTest() OVERRIDE {} + void AfterTest() override {} }; SINGLE_AND_MULTI_THREAD_TEST_F( @@ -1077,29 +1075,22 @@ class ThreadCheckingInputHandlerClient : public InputHandlerClient { bool* received_stop_flinging) : task_runner_(runner), received_stop_flinging_(received_stop_flinging) {} - virtual void WillShutdown() OVERRIDE { + void WillShutdown() override { if (!received_stop_flinging_) ADD_FAILURE() << "WillShutdown() called before fling stopped"; } - virtual void Animate(base::TimeTicks time) OVERRIDE { + void Animate(base::TimeTicks time) override { if (!task_runner_->BelongsToCurrentThread()) ADD_FAILURE() << "Animate called on wrong thread"; } - virtual void MainThreadHasStoppedFlinging() OVERRIDE { + void MainThreadHasStoppedFlinging() override { if (!task_runner_->BelongsToCurrentThread()) ADD_FAILURE() << "MainThreadHasStoppedFlinging called on wrong thread"; *received_stop_flinging_ = true; } - virtual void DidOverscroll(const gfx::Vector2dF& accumulated_overscroll, - const gfx::Vector2dF& latest_overscroll_delta) - OVERRIDE { - if (!task_runner_->BelongsToCurrentThread()) - ADD_FAILURE() << "DidOverscroll called on wrong thread"; - } - private: base::SingleThreadTaskRunner* task_runner_; bool* received_stop_flinging_; @@ -1128,7 +1119,9 @@ TEST(LayerTreeHostFlingTest, DidStopFlingingThread) { scoped_ptr<LayerTreeHost> layer_tree_host = LayerTreeHost::CreateThreaded(&client, shared_bitmap_manager.get(), + NULL, settings, + base::MessageLoopProxy::current(), impl_thread.message_loop_proxy()); impl_thread.message_loop_proxy() @@ -1138,7 +1131,7 @@ TEST(LayerTreeHostFlingTest, DidStopFlingingThread) { base::Unretained(&input_handler_client))); layer_tree_host->DidStopFlinging(); - layer_tree_host.reset(); + layer_tree_host = nullptr; impl_thread.Stop(); EXPECT_TRUE(received_stop_flinging); } @@ -1149,7 +1142,7 @@ class LayerTreeHostScrollTestLayerStructureChange LayerTreeHostScrollTestLayerStructureChange() : scroll_destroy_whole_tree_(false) {} - virtual void SetupTree() OVERRIDE { + void SetupTree() override { scoped_refptr<Layer> root_layer = Layer::Create(); root_layer->SetBounds(gfx::Size(10, 10)); @@ -1162,11 +1155,9 @@ class LayerTreeHostScrollTestLayerStructureChange LayerTreeHostScrollTest::SetupTree(); } - virtual void BeginTest() OVERRIDE { - PostSetNeedsCommitToMainThread(); - } + void BeginTest() override { PostSetNeedsCommitToMainThread(); } - virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE { + void DrawLayersOnThread(LayerTreeHostImpl* impl) override { LayerImpl* root = impl->active_tree()->root_layer(); switch (impl->active_tree()->source_frame_number()) { case 0: @@ -1181,7 +1172,7 @@ class LayerTreeHostScrollTestLayerStructureChange } } - virtual void AfterTest() OVERRIDE {} + void AfterTest() override {} virtual void DidScroll(Layer* layer) { if (scroll_destroy_whole_tree_) { @@ -1203,8 +1194,8 @@ class LayerTreeHostScrollTestLayerStructureChange }; Layer* CreateScrollLayer(Layer* parent, FakeLayerScrollClient* client) { - scoped_refptr<Layer> scroll_layer = - ContentLayer::Create(&fake_content_layer_client_); + scoped_refptr<PictureLayer> scroll_layer = + PictureLayer::Create(&fake_content_layer_client_); scroll_layer->SetBounds(gfx::Size(110, 110)); scroll_layer->SetPosition(gfx::Point(0, 0)); scroll_layer->SetIsDrawable(true); @@ -1229,12 +1220,12 @@ class LayerTreeHostScrollTestLayerStructureChange }; TEST_F(LayerTreeHostScrollTestLayerStructureChange, ScrollDestroyLayer) { - RunTest(true, false, false); + RunTest(true, false, true); } TEST_F(LayerTreeHostScrollTestLayerStructureChange, ScrollDestroyWholeTree) { - scroll_destroy_whole_tree_ = true; - RunTest(true, false, false); + scroll_destroy_whole_tree_ = true; + RunTest(true, false, true); } } // namespace diff --git a/chromium/cc/trees/layer_tree_host_unittest_video.cc b/chromium/cc/trees/layer_tree_host_unittest_video.cc index 5484e4c9163..ffeda727fe3 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_video.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_video.cc @@ -22,15 +22,15 @@ class LayerTreeHostVideoTest : public LayerTreeTest {}; class LayerTreeHostVideoTestSetNeedsDisplay : public LayerTreeHostVideoTest { public: - virtual void SetupTree() OVERRIDE { + void SetupTree() override { scoped_refptr<Layer> root = Layer::Create(); root->SetBounds(gfx::Size(10, 10)); root->SetIsDrawable(true); - scoped_refptr<VideoLayer> video = VideoLayer::Create( - &video_frame_provider_); + scoped_refptr<VideoLayer> video = + VideoLayer::Create(&video_frame_provider_, media::VIDEO_ROTATION_90); video->SetPosition(gfx::PointF(3.f, 3.f)); - video->SetBounds(gfx::Size(4, 4)); + video->SetBounds(gfx::Size(4, 5)); video->SetIsDrawable(true); root->AddChild(video); @@ -39,14 +39,14 @@ class LayerTreeHostVideoTestSetNeedsDisplay LayerTreeHostVideoTest::SetupTree(); } - virtual void BeginTest() OVERRIDE { + void BeginTest() override { num_draws_ = 0; PostSetNeedsCommitToMainThread(); } - virtual DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, - LayerTreeHostImpl::FrameData* frame, - DrawResult draw_result) OVERRIDE { + DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, + LayerTreeHostImpl::FrameData* frame, + DrawResult draw_result) override { LayerImpl* root_layer = host_impl->active_tree()->root_layer(); RenderSurfaceImpl* root_surface = root_layer->render_surface(); gfx::RectF damage_rect = @@ -60,7 +60,7 @@ class LayerTreeHostVideoTestSetNeedsDisplay break; case 1: // Second frame the video layer is damaged. - EXPECT_EQ(gfx::RectF(6.f, 6.f, 8.f, 8.f).ToString(), + EXPECT_EQ(gfx::RectF(6.f, 6.f, 8.f, 10.f).ToString(), damage_rect.ToString()); EndTest(); break; @@ -70,19 +70,19 @@ class LayerTreeHostVideoTestSetNeedsDisplay return draw_result; } - virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { + void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { VideoLayerImpl* video = static_cast<VideoLayerImpl*>( host_impl->active_tree()->root_layer()->children()[0]); + EXPECT_EQ(media::VIDEO_ROTATION_90, video->video_rotation()); + if (num_draws_ == 0) video->SetNeedsRedraw(); ++num_draws_; } - virtual void AfterTest() OVERRIDE { - EXPECT_EQ(2, num_draws_); - } + void AfterTest() override { EXPECT_EQ(2, num_draws_); } private: int num_draws_; diff --git a/chromium/cc/trees/layer_tree_impl.cc b/chromium/cc/trees/layer_tree_impl.cc index d5ec804eaa9..6b2b37f2c5f 100644 --- a/chromium/cc/trees/layer_tree_impl.cc +++ b/chromium/cc/trees/layer_tree_impl.cc @@ -8,6 +8,7 @@ #include <set> #include "base/debug/trace_event.h" +#include "base/debug/trace_event_argument.h" #include "cc/animation/keyframed_animation_curve.h" #include "cc/animation/scrollbar_animation_controller.h" #include "cc/animation/scrollbar_animation_controller_linear_fade.h" @@ -16,6 +17,7 @@ #include "cc/base/util.h" #include "cc/debug/devtools_instrumentation.h" #include "cc/debug/traced_value.h" +#include "cc/input/page_scale_animation.h" #include "cc/layers/heads_up_display_layer_impl.h" #include "cc/layers/layer.h" #include "cc/layers/layer_iterator.h" @@ -24,9 +26,10 @@ #include "cc/resources/ui_resource_request.h" #include "cc/trees/layer_tree_host_common.h" #include "cc/trees/layer_tree_host_impl.h" -#include "ui/gfx/point_conversions.h" -#include "ui/gfx/size_conversions.h" -#include "ui/gfx/vector2d_conversions.h" +#include "cc/trees/occlusion_tracker.h" +#include "ui/gfx/geometry/point_conversions.h" +#include "ui/gfx/geometry/size_conversions.h" +#include "ui/gfx/geometry/vector2d_conversions.h" namespace cc { @@ -41,29 +44,32 @@ class LayerScrollOffsetDelegateProxy : public LayerImpl::ScrollOffsetDelegate { : layer_(layer), delegate_(delegate), layer_tree_impl_(layer_tree) {} virtual ~LayerScrollOffsetDelegateProxy() {} - gfx::Vector2dF last_set_scroll_offset() const { + gfx::ScrollOffset last_set_scroll_offset() const { return last_set_scroll_offset_; } // LayerScrollOffsetDelegate implementation. - virtual void SetTotalScrollOffset(const gfx::Vector2dF& new_offset) OVERRIDE { + void SetTotalScrollOffset(const gfx::ScrollOffset& new_offset) override { last_set_scroll_offset_ = new_offset; - layer_tree_impl_->UpdateScrollOffsetDelegate(); } - virtual gfx::Vector2dF GetTotalScrollOffset() OVERRIDE { + gfx::ScrollOffset GetTotalScrollOffset() override { return layer_tree_impl_->GetDelegatedScrollOffset(layer_); } - virtual bool IsExternalFlingActive() const OVERRIDE { + bool IsExternalFlingActive() const override { return delegate_->IsExternalFlingActive(); } + void Update() const override { + layer_tree_impl_->UpdateScrollOffsetDelegate(); + } + private: LayerImpl* layer_; LayerScrollOffsetDelegate* delegate_; LayerTreeImpl* layer_tree_impl_; - gfx::Vector2dF last_set_scroll_offset_; + gfx::ScrollOffset last_set_scroll_offset_; }; LayerTreeImpl::LayerTreeImpl(LayerTreeHostImpl* layer_tree_host_impl) @@ -84,22 +90,30 @@ LayerTreeImpl::LayerTreeImpl(LayerTreeHostImpl* layer_tree_host_impl) max_page_scale_factor_(0), scrolling_layer_id_from_previous_tree_(0), contents_textures_purged_(false), - requires_high_res_to_draw_(false), viewport_size_invalid_(false), needs_update_draw_properties_(true), needs_full_tree_sync_(true), next_activation_forces_redraw_(false), - render_surface_layer_list_id_(0) { + has_ever_been_drawn_(false), + render_surface_layer_list_id_(0), + top_controls_layout_height_(0), + top_controls_content_offset_(0), + top_controls_delta_(0), + sent_top_controls_delta_(0) { } LayerTreeImpl::~LayerTreeImpl() { + BreakSwapPromises(SwapPromise::SWAP_FAILS); + // Need to explicitly clear the tree prior to destroying this so that // the LayerTreeImpl pointer is still valid in the LayerImpl dtor. DCHECK(!root_layer_); DCHECK(layers_with_copy_output_request_.empty()); } -void LayerTreeImpl::Shutdown() { root_layer_.reset(); } +void LayerTreeImpl::Shutdown() { + root_layer_ = nullptr; +} void LayerTreeImpl::ReleaseResources() { if (root_layer_) @@ -111,8 +125,8 @@ void LayerTreeImpl::SetRootLayer(scoped_ptr<LayerImpl> layer) { inner_viewport_scroll_layer_->SetScrollOffsetDelegate(NULL); if (outer_viewport_scroll_layer_) outer_viewport_scroll_layer_->SetScrollOffsetDelegate(NULL); - inner_viewport_scroll_delegate_proxy_.reset(); - outer_viewport_scroll_delegate_proxy_.reset(); + inner_viewport_scroll_delegate_proxy_ = nullptr; + outer_viewport_scroll_delegate_proxy_ = nullptr; root_layer_ = layer.Pass(); currently_scrolling_layer_ = NULL; @@ -131,8 +145,8 @@ LayerImpl* LayerTreeImpl::OuterViewportScrollLayer() const { return outer_viewport_scroll_layer_; } -gfx::Vector2dF LayerTreeImpl::TotalScrollOffset() const { - gfx::Vector2dF offset; +gfx::ScrollOffset LayerTreeImpl::TotalScrollOffset() const { + gfx::ScrollOffset offset; if (inner_viewport_scroll_layer_) offset += inner_viewport_scroll_layer_->TotalScrollOffset(); @@ -143,8 +157,8 @@ gfx::Vector2dF LayerTreeImpl::TotalScrollOffset() const { return offset; } -gfx::Vector2dF LayerTreeImpl::TotalMaxScrollOffset() const { - gfx::Vector2dF offset; +gfx::ScrollOffset LayerTreeImpl::TotalMaxScrollOffset() const { + gfx::ScrollOffset offset; if (inner_viewport_scroll_layer_) offset += inner_viewport_scroll_layer_->MaxScrollOffset(); @@ -172,8 +186,8 @@ scoped_ptr<LayerImpl> LayerTreeImpl::DetachLayerTree() { inner_viewport_scroll_layer_->SetScrollOffsetDelegate(NULL); if (outer_viewport_scroll_layer_) outer_viewport_scroll_layer_->SetScrollOffsetDelegate(NULL); - inner_viewport_scroll_delegate_proxy_.reset(); - outer_viewport_scroll_delegate_proxy_.reset(); + inner_viewport_scroll_delegate_proxy_ = nullptr; + outer_viewport_scroll_delegate_proxy_ = nullptr; inner_viewport_scroll_layer_ = NULL; outer_viewport_scroll_layer_ = NULL; page_scale_layer_ = NULL; @@ -195,11 +209,20 @@ void LayerTreeImpl::PushPropertiesTo(LayerTreeImpl* target_tree) { target_tree->PassSwapPromises(&swap_promise_list_); + target_tree->top_controls_layout_height_ = top_controls_layout_height_; + target_tree->top_controls_content_offset_ = top_controls_content_offset_; + target_tree->top_controls_delta_ = + target_tree->top_controls_delta_ - + target_tree->sent_top_controls_delta_; + target_tree->sent_top_controls_delta_ = 0.f; + target_tree->SetPageScaleValues( page_scale_factor(), min_page_scale_factor(), max_page_scale_factor(), target_tree->page_scale_delta() / target_tree->sent_page_scale_delta()); target_tree->set_sent_page_scale_delta(1); + target_tree->page_scale_animation_ = page_scale_animation_.Pass(); + if (page_scale_layer_ && inner_viewport_scroll_layer_) { target_tree->SetViewportLayersFromIds( page_scale_layer_->id(), @@ -209,6 +232,9 @@ void LayerTreeImpl::PushPropertiesTo(LayerTreeImpl* target_tree) { } else { target_tree->ClearViewportLayers(); } + + target_tree->RegisterSelection(selection_start_, selection_end_); + // This should match the property synchronization in // LayerTreeHost::finishCommitOnImplThread(). target_tree->set_source_frame_number(source_frame_number()); @@ -220,10 +246,6 @@ void LayerTreeImpl::PushPropertiesTo(LayerTreeImpl* target_tree) { else target_tree->ResetContentsTexturesPurged(); - // Always reset this flag on activation, as we would only have activated - // if we were in a good state. - target_tree->ResetRequiresHighResToDraw(); - if (ViewportSizeInvalid()) target_tree->SetViewportSizeInvalid(); else @@ -235,6 +257,8 @@ void LayerTreeImpl::PushPropertiesTo(LayerTreeImpl* target_tree) { target_tree->root_layer(), hud_layer()->id()))); else target_tree->set_hud_layer(NULL); + + target_tree->has_ever_been_drawn_ = false; } LayerImpl* LayerTreeImpl::InnerViewportContainerLayer() const { @@ -243,6 +267,12 @@ LayerImpl* LayerTreeImpl::InnerViewportContainerLayer() const { : NULL; } +LayerImpl* LayerTreeImpl::OuterViewportContainerLayer() const { + return outer_viewport_scroll_layer_ + ? outer_viewport_scroll_layer_->scroll_clip_layer() + : NULL; +} + LayerImpl* LayerTreeImpl::CurrentlyScrollingLayer() const { DCHECK(IsActiveTree()); return currently_scrolling_layer_; @@ -266,14 +296,6 @@ void LayerTreeImpl::ClearCurrentlyScrollingLayer() { scrolling_layer_id_from_previous_tree_ = 0; } -float LayerTreeImpl::VerticalAdjust(const int clip_layer_id) const { - LayerImpl* container_layer = InnerViewportContainerLayer(); - if (!container_layer || clip_layer_id != container_layer->id()) - return 0.f; - - return layer_tree_host_impl_->VerticalAdjust(); -} - namespace { void ForceScrollbarParameterUpdateAfterScaleChange(LayerImpl* current_layer) { @@ -281,7 +303,7 @@ void ForceScrollbarParameterUpdateAfterScaleChange(LayerImpl* current_layer) { return; while (current_layer) { - current_layer->ScrollbarParametersDidChange(); + current_layer->ScrollbarParametersDidChange(false); current_layer = current_layer->parent(); } } @@ -349,12 +371,11 @@ void LayerTreeImpl::SetPageScaleValues(float page_scale_factor, } gfx::SizeF LayerTreeImpl::ScrollableViewportSize() const { - if (outer_viewport_scroll_layer_) - return layer_tree_host_impl_->UnscaledScrollableViewportSize(); - else - return gfx::ScaleSize( - layer_tree_host_impl_->UnscaledScrollableViewportSize(), - 1.0f / total_page_scale_factor()); + if (!InnerViewportContainerLayer()) + return gfx::SizeF(); + + return gfx::ScaleSize(InnerViewportContainerLayer()->BoundsForScrolling(), + 1.0f / total_page_scale_factor()); } gfx::Rect LayerTreeImpl::RootScrollLayerDeviceViewportBounds() const { @@ -379,6 +400,10 @@ void LayerTreeImpl::ApplySentScrollAndScaleDeltasFromAbortedCommit() { page_scale_delta_ /= sent_page_scale_delta_; sent_page_scale_delta_ = 1.f; + top_controls_content_offset_ += sent_top_controls_delta_; + top_controls_delta_ -= sent_top_controls_delta_; + sent_top_controls_delta_ = 0.f; + if (!root_layer()) return; @@ -460,7 +485,8 @@ bool LayerTreeImpl::UpdateDrawProperties() { LayerImpl* page_scale_layer = page_scale_layer_ ? page_scale_layer_ : InnerViewportContainerLayer(); bool can_render_to_separate_surface = - !output_surface()->ForcedDrawToSoftwareDevice(); + (layer_tree_host_impl_->GetDrawMode() != + DRAW_MODE_RESOURCELESS_SOFTWARE); ++render_surface_layer_list_id_; LayerTreeHostCommon::CalcDrawPropsImplInputs inputs( @@ -470,7 +496,7 @@ bool LayerTreeImpl::UpdateDrawProperties() { device_scale_factor(), total_page_scale_factor(), page_scale_layer, - MaxTextureSize(), + resource_provider()->max_texture_size(), settings().can_use_lcd_text, can_render_to_separate_surface, settings().layer_transforms_should_scale_layer_contents, @@ -480,33 +506,68 @@ bool LayerTreeImpl::UpdateDrawProperties() { } { - TRACE_EVENT2("cc", - "LayerTreeImpl::UpdateTilePriorities", - "IsActive", - IsActiveTree(), - "SourceFrameNumber", - source_frame_number_); + TRACE_EVENT_BEGIN2("cc", "LayerTreeImpl::UpdateTilePriorities", "IsActive", + IsActiveTree(), "SourceFrameNumber", + source_frame_number_); + scoped_ptr<OcclusionTracker<LayerImpl>> occlusion_tracker; + if (settings().use_occlusion_for_tile_prioritization) { + occlusion_tracker.reset(new OcclusionTracker<LayerImpl>( + root_layer()->render_surface()->content_rect())); + occlusion_tracker->set_minimum_tracking_size( + settings().minimum_occlusion_tracking_size); + } + + bool resourceless_software_draw = (layer_tree_host_impl_->GetDrawMode() == + DRAW_MODE_RESOURCELESS_SOFTWARE); + // LayerIterator is used here instead of CallFunctionForSubtree to only // UpdateTilePriorities on layers that will be visible (and thus have valid // draw properties) and not because any ordering is required. typedef LayerIterator<LayerImpl> LayerIteratorType; LayerIteratorType end = LayerIteratorType::End(&render_surface_layer_list_); + size_t layers_updated_count = 0; for (LayerIteratorType it = LayerIteratorType::Begin(&render_surface_layer_list_); it != end; ++it) { + if (occlusion_tracker) + occlusion_tracker->EnterLayer(it); + LayerImpl* layer = *it; - if (it.represents_itself()) - layer->UpdateTiles(); + const Occlusion& occlusion_in_content_space = + occlusion_tracker ? occlusion_tracker->GetCurrentOcclusionForLayer( + layer->draw_transform()) + : Occlusion(); + + if (it.represents_itself()) { + layer->UpdateTiles(occlusion_in_content_space, + resourceless_software_draw); + ++layers_updated_count; + } - if (!it.represents_contributing_render_surface()) + if (!it.represents_contributing_render_surface()) { + if (occlusion_tracker) + occlusion_tracker->LeaveLayer(it); continue; + } + + if (layer->mask_layer()) { + layer->mask_layer()->UpdateTiles(occlusion_in_content_space, + resourceless_software_draw); + ++layers_updated_count; + } + if (layer->replica_layer() && layer->replica_layer()->mask_layer()) { + layer->replica_layer()->mask_layer()->UpdateTiles( + occlusion_in_content_space, resourceless_software_draw); + ++layers_updated_count; + } - if (layer->mask_layer()) - layer->mask_layer()->UpdateTiles(); - if (layer->replica_layer() && layer->replica_layer()->mask_layer()) - layer->replica_layer()->mask_layer()->UpdateTiles(); + if (occlusion_tracker) + occlusion_tracker->LeaveLayer(it); } + + TRACE_EVENT_END1("cc", "LayerTreeImpl::UpdateTilePriorities", + "layers_updated_count", layers_updated_count); } DCHECK(!needs_update_draw_properties_) << @@ -544,6 +605,10 @@ void LayerTreeImpl::UnregisterLayer(LayerImpl* layer) { layer_id_map_.erase(layer->id()); } +size_t LayerTreeImpl::NumLayers() { + return layer_id_map_.size(); +} + void LayerTreeImpl::PushPersistedState(LayerTreeImpl* pending_tree) { pending_tree->SetCurrentlyScrollingLayer( LayerTreeHostCommon::FindLayerInSubtree(pending_tree->root_layer(), @@ -552,14 +617,16 @@ void LayerTreeImpl::PushPersistedState(LayerTreeImpl* pending_tree) { static void DidBecomeActiveRecursive(LayerImpl* layer) { layer->DidBecomeActive(); + if (layer->mask_layer()) + layer->mask_layer()->DidBecomeActive(); + if (layer->replica_layer() && layer->replica_layer()->mask_layer()) + layer->replica_layer()->mask_layer()->DidBecomeActive(); + for (size_t i = 0; i < layer->children().size(); ++i) DidBecomeActiveRecursive(layer->children()[i]); } void LayerTreeImpl::DidBecomeActive() { - if (!root_layer()) - return; - if (next_activation_forces_redraw_) { layer_tree_host_impl_->SetFullRootLayerDamage(); next_activation_forces_redraw_ = false; @@ -567,10 +634,16 @@ void LayerTreeImpl::DidBecomeActive() { if (scrolling_layer_id_from_previous_tree_) { currently_scrolling_layer_ = LayerTreeHostCommon::FindLayerInSubtree( - root_layer_.get(), scrolling_layer_id_from_previous_tree_); + root_layer(), scrolling_layer_id_from_previous_tree_); } - DidBecomeActiveRecursive(root_layer()); + // Always reset this flag on activation, as we would only have activated + // if we were in a good state. + layer_tree_host_impl_->ResetRequiresHighResToDraw(); + + if (root_layer()) + DidBecomeActiveRecursive(root_layer()); + devtools_instrumentation::DidActivateLayerTree(layer_tree_host_impl_->id(), source_frame_number_); } @@ -593,16 +666,8 @@ void LayerTreeImpl::ResetContentsTexturesPurged() { layer_tree_host_impl_->OnCanDrawStateChangedForTree(); } -void LayerTreeImpl::SetRequiresHighResToDraw() { - requires_high_res_to_draw_ = true; -} - -void LayerTreeImpl::ResetRequiresHighResToDraw() { - requires_high_res_to_draw_ = false; -} - bool LayerTreeImpl::RequiresHighResToDraw() const { - return requires_high_res_to_draw_; + return layer_tree_host_impl_->RequiresHighResToDraw(); } bool LayerTreeImpl::ViewportSizeInvalid() const { @@ -659,10 +724,6 @@ MemoryHistory* LayerTreeImpl::memory_history() const { return layer_tree_host_impl_->memory_history(); } -bool LayerTreeImpl::device_viewport_valid_for_tile_management() const { - return layer_tree_host_impl_->device_viewport_valid_for_tile_management(); -} - gfx::Size LayerTreeImpl::device_viewport_size() const { return layer_tree_host_impl_->device_viewport_size(); } @@ -693,16 +754,12 @@ LayerImpl* LayerTreeImpl::FindPendingTreeLayerById(int id) { return tree->LayerById(id); } -int LayerTreeImpl::MaxTextureSize() const { - return layer_tree_host_impl_->GetRendererCapabilities().max_texture_size; -} - bool LayerTreeImpl::PinchGestureActive() const { return layer_tree_host_impl_->pinch_gesture_active(); } -base::TimeTicks LayerTreeImpl::CurrentFrameTimeTicks() const { - return layer_tree_host_impl_->CurrentFrameTimeTicks(); +BeginFrameArgs LayerTreeImpl::CurrentBeginFrameArgs() const { + return layer_tree_host_impl_->CurrentBeginFrameArgs(); } base::TimeDelta LayerTreeImpl::begin_impl_frame_interval() const { @@ -713,34 +770,49 @@ void LayerTreeImpl::SetNeedsCommit() { layer_tree_host_impl_->SetNeedsCommit(); } +gfx::Rect LayerTreeImpl::DeviceViewport() const { + return layer_tree_host_impl_->DeviceViewport(); +} + gfx::Size LayerTreeImpl::DrawViewportSize() const { return layer_tree_host_impl_->DrawViewportSize(); } +const gfx::Rect LayerTreeImpl::ViewportRectForTilePriority() const { + return layer_tree_host_impl_->ViewportRectForTilePriority(); +} + scoped_ptr<ScrollbarAnimationController> LayerTreeImpl::CreateScrollbarAnimationController(LayerImpl* scrolling_layer) { DCHECK(settings().scrollbar_fade_delay_ms); DCHECK(settings().scrollbar_fade_duration_ms); base::TimeDelta delay = base::TimeDelta::FromMilliseconds(settings().scrollbar_fade_delay_ms); + base::TimeDelta resize_delay = base::TimeDelta::FromMilliseconds( + settings().scrollbar_fade_resize_delay_ms); base::TimeDelta duration = base::TimeDelta::FromMilliseconds(settings().scrollbar_fade_duration_ms); switch (settings().scrollbar_animator) { case LayerTreeSettings::LinearFade: { return ScrollbarAnimationControllerLinearFade::Create( - scrolling_layer, layer_tree_host_impl_, delay, duration) - .PassAs<ScrollbarAnimationController>(); + scrolling_layer, + layer_tree_host_impl_, + delay, + resize_delay, + duration); } case LayerTreeSettings::Thinning: { - return ScrollbarAnimationControllerThinning::Create( - scrolling_layer, layer_tree_host_impl_, delay, duration) - .PassAs<ScrollbarAnimationController>(); + return ScrollbarAnimationControllerThinning::Create(scrolling_layer, + layer_tree_host_impl_, + delay, + resize_delay, + duration); } case LayerTreeSettings::NoAnimator: NOTREACHED(); break; } - return scoped_ptr<ScrollbarAnimationController>(); + return nullptr; } void LayerTreeImpl::DidAnimateScrollOffset() { @@ -775,26 +847,43 @@ AnimationRegistrar* LayerTreeImpl::animationRegistrar() const { return layer_tree_host_impl_->animation_registrar(); } -scoped_ptr<base::Value> LayerTreeImpl::AsValue() const { - scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); - TracedValue::MakeDictIntoImplicitSnapshot( - state.get(), "cc::LayerTreeImpl", this); +void LayerTreeImpl::GetAllTilesForTracing(std::set<const Tile*>* tiles) const { + typedef LayerIterator<LayerImpl> LayerIteratorType; + LayerIteratorType end = LayerIteratorType::End(&render_surface_layer_list_); + for (LayerIteratorType it = + LayerIteratorType::Begin(&render_surface_layer_list_); + it != end; + ++it) { + if (!it.represents_itself()) + continue; + LayerImpl* layer_impl = *it; + layer_impl->GetAllTilesForTracing(tiles); + } +} + +void LayerTreeImpl::AsValueInto(base::debug::TracedValue* state) const { + TracedValue::MakeDictIntoImplicitSnapshot(state, "cc::LayerTreeImpl", this); + state->SetInteger("source_frame_number", source_frame_number_); - state->Set("root_layer", root_layer_->AsValue().release()); + state->BeginDictionary("root_layer"); + root_layer_->AsValueInto(state); + state->EndDictionary(); - scoped_ptr<base::ListValue> render_surface_layer_list(new base::ListValue()); + state->BeginArray("render_surface_layer_list"); typedef LayerIterator<LayerImpl> LayerIteratorType; LayerIteratorType end = LayerIteratorType::End(&render_surface_layer_list_); for (LayerIteratorType it = LayerIteratorType::Begin( &render_surface_layer_list_); it != end; ++it) { if (!it.represents_itself()) continue; - render_surface_layer_list->Append(TracedValue::CreateIDRef(*it).release()); + TracedValue::AppendIDRef(*it, state); } + state->EndArray(); - state->Set("render_surface_layer_list", - render_surface_layer_list.release()); - return state.PassAs<base::Value>(); + state->BeginArray("swap_promise_trace_ids"); + for (size_t i = 0; i < swap_promise_list_.size(); i++) + state->AppendDouble(swap_promise_list_[i]->TraceId()); + state->EndArray(); } void LayerTreeImpl::SetRootLayerScrollOffsetDelegate( @@ -809,8 +898,8 @@ void LayerTreeImpl::SetRootLayerScrollOffsetDelegate( InnerViewportScrollLayer()->SetScrollOffsetDelegate(NULL); if (OuterViewportScrollLayer()) OuterViewportScrollLayer()->SetScrollOffsetDelegate(NULL); - inner_viewport_scroll_delegate_proxy_.reset(); - outer_viewport_scroll_delegate_proxy_.reset(); + inner_viewport_scroll_delegate_proxy_ = nullptr; + outer_viewport_scroll_delegate_proxy_ = nullptr; } root_layer_scroll_offset_delegate_ = root_layer_scroll_offset_delegate; @@ -841,14 +930,28 @@ void LayerTreeImpl::SetRootLayerScrollOffsetDelegate( outer_viewport_scroll_layer_->SetScrollOffsetDelegate( outer_viewport_scroll_delegate_proxy_.get()); } + + if (inner_viewport_scroll_layer_) + UpdateScrollOffsetDelegate(); + } +} + +void LayerTreeImpl::OnRootLayerDelegatedScrollOffsetChanged() { + DCHECK(root_layer_scroll_offset_delegate_); + if (inner_viewport_scroll_layer_) { + inner_viewport_scroll_layer_->DidScroll(); + } + if (outer_viewport_scroll_layer_) { + outer_viewport_scroll_layer_->DidScroll(); } } void LayerTreeImpl::UpdateScrollOffsetDelegate() { DCHECK(InnerViewportScrollLayer()); + DCHECK(!OuterViewportScrollLayer() || outer_viewport_scroll_delegate_proxy_); DCHECK(root_layer_scroll_offset_delegate_); - gfx::Vector2dF offset = + gfx::ScrollOffset offset = inner_viewport_scroll_delegate_proxy_->last_set_scroll_offset(); if (OuterViewportScrollLayer()) @@ -863,7 +966,7 @@ void LayerTreeImpl::UpdateScrollOffsetDelegate() { max_page_scale_factor()); } -gfx::Vector2dF LayerTreeImpl::GetDelegatedScrollOffset(LayerImpl* layer) { +gfx::ScrollOffset LayerTreeImpl::GetDelegatedScrollOffset(LayerImpl* layer) { DCHECK(root_layer_scroll_offset_delegate_); DCHECK(InnerViewportScrollLayer()); if (layer == InnerViewportScrollLayer() && !OuterViewportScrollLayer()) @@ -873,13 +976,13 @@ gfx::Vector2dF LayerTreeImpl::GetDelegatedScrollOffset(LayerImpl* layer) { // the scroll offset between them. DCHECK(inner_viewport_scroll_delegate_proxy_); DCHECK(outer_viewport_scroll_delegate_proxy_); - gfx::Vector2dF inner_viewport_offset = + gfx::ScrollOffset inner_viewport_offset = inner_viewport_scroll_delegate_proxy_->last_set_scroll_offset(); - gfx::Vector2dF outer_viewport_offset = + gfx::ScrollOffset outer_viewport_offset = outer_viewport_scroll_delegate_proxy_->last_set_scroll_offset(); // It may be nothing has changed. - gfx::Vector2dF delegate_offset = + gfx::ScrollOffset delegate_offset = root_layer_scroll_offset_delegate_->GetTotalScrollOffset(); if (inner_viewport_offset + outer_viewport_offset == delegate_offset) { if (layer == InnerViewportScrollLayer()) @@ -888,12 +991,12 @@ gfx::Vector2dF LayerTreeImpl::GetDelegatedScrollOffset(LayerImpl* layer) { return outer_viewport_offset; } - gfx::Vector2d max_outer_viewport_scroll_offset = + gfx::ScrollOffset max_outer_viewport_scroll_offset = OuterViewportScrollLayer()->MaxScrollOffset(); outer_viewport_offset = delegate_offset - inner_viewport_offset; outer_viewport_offset.SetToMin(max_outer_viewport_scroll_offset); - outer_viewport_offset.SetToMax(gfx::Vector2d()); + outer_viewport_offset.SetToMax(gfx::ScrollOffset()); if (layer == OuterViewportScrollLayer()) return outer_viewport_offset; @@ -905,15 +1008,13 @@ gfx::Vector2dF LayerTreeImpl::GetDelegatedScrollOffset(LayerImpl* layer) { void LayerTreeImpl::QueueSwapPromise(scoped_ptr<SwapPromise> swap_promise) { DCHECK(swap_promise); - if (swap_promise_list_.size() > kMaxQueuedSwapPromiseNumber) - BreakSwapPromises(SwapPromise::SWAP_PROMISE_LIST_OVERFLOW); swap_promise_list_.push_back(swap_promise.Pass()); } void LayerTreeImpl::PassSwapPromises( ScopedPtrVector<SwapPromise>* new_swap_promise) { swap_promise_list_.insert_and_take(swap_promise_list_.end(), - *new_swap_promise); + new_swap_promise); new_swap_promise->clear(); } @@ -1104,7 +1205,7 @@ static bool PointHitsRegion(const gfx::PointF& screen_space_point, gfx::ToRoundedPoint(hit_test_point_in_layer_space)); } -static LayerImpl* GetNextClippingLayer(LayerImpl* layer) { +static const LayerImpl* GetNextClippingLayer(const LayerImpl* layer) { if (layer->scroll_parent()) return layer->scroll_parent(); if (layer->clip_parent()) @@ -1114,7 +1215,7 @@ static LayerImpl* GetNextClippingLayer(LayerImpl* layer) { static bool PointIsClippedBySurfaceOrClipRect( const gfx::PointF& screen_space_point, - LayerImpl* layer) { + const LayerImpl* layer) { // Walk up the layer tree and hit-test any render_surfaces and any layer // clip rects that are active. for (; layer; layer = GetNextClippingLayer(layer)) { @@ -1138,7 +1239,7 @@ static bool PointIsClippedBySurfaceOrClipRect( return false; } -static bool PointHitsLayer(LayerImpl* layer, +static bool PointHitsLayer(const LayerImpl* layer, const gfx::PointF& screen_space_point, float* distance_to_intersection) { gfx::RectF content_rect(layer->content_bounds()); @@ -1290,6 +1391,79 @@ LayerImpl* LayerTreeImpl::FindLayerThatIsHitByPointInTouchHandlerRegion( return data_for_recursion.closest_match; } +void LayerTreeImpl::RegisterSelection(const LayerSelectionBound& start, + const LayerSelectionBound& end) { + selection_start_ = start; + selection_end_ = end; +} + +static ViewportSelectionBound ComputeViewportSelection( + const LayerSelectionBound& layer_bound, + LayerImpl* layer, + float device_scale_factor) { + ViewportSelectionBound viewport_bound; + viewport_bound.type = layer_bound.type; + + if (!layer || layer_bound.type == SELECTION_BOUND_EMPTY) + return viewport_bound; + + gfx::PointF layer_scaled_top = gfx::ScalePoint(layer_bound.edge_top, + layer->contents_scale_x(), + layer->contents_scale_y()); + gfx::PointF layer_scaled_bottom = gfx::ScalePoint(layer_bound.edge_bottom, + layer->contents_scale_x(), + layer->contents_scale_y()); + + bool clipped = false; + gfx::PointF screen_top = MathUtil::MapPoint( + layer->screen_space_transform(), layer_scaled_top, &clipped); + gfx::PointF screen_bottom = MathUtil::MapPoint( + layer->screen_space_transform(), layer_scaled_bottom, &clipped); + + const float inv_scale = 1.f / device_scale_factor; + viewport_bound.edge_top = gfx::ScalePoint(screen_top, inv_scale); + viewport_bound.edge_bottom = gfx::ScalePoint(screen_bottom, inv_scale); + + // The bottom edge point is used for visibility testing as it is the logical + // focal point for bound selection handles (this may change in the future). + // Shifting the visibility point fractionally inward ensures that neighboring + // or logically coincident layers aligned to integral DPI coordinates will not + // spuriously occlude the bound. + gfx::Vector2dF visibility_offset = layer_scaled_top - layer_scaled_bottom; + visibility_offset.Scale(device_scale_factor / visibility_offset.Length()); + gfx::PointF visibility_point = layer_scaled_bottom + visibility_offset; + if (visibility_point.x() <= 0) + visibility_point.set_x(visibility_point.x() + device_scale_factor); + visibility_point = MathUtil::MapPoint( + layer->screen_space_transform(), visibility_point, &clipped); + + float intersect_distance = 0.f; + viewport_bound.visible = + PointHitsLayer(layer, visibility_point, &intersect_distance); + + return viewport_bound; +} + +void LayerTreeImpl::GetViewportSelection(ViewportSelectionBound* start, + ViewportSelectionBound* end) { + DCHECK(start); + DCHECK(end); + + *start = ComputeViewportSelection( + selection_start_, + selection_start_.layer_id ? LayerById(selection_start_.layer_id) : NULL, + device_scale_factor()); + if (start->type == SELECTION_BOUND_CENTER || + start->type == SELECTION_BOUND_EMPTY) { + *end = *start; + } else { + *end = ComputeViewportSelection( + selection_end_, + selection_end_.layer_id ? LayerById(selection_end_.layer_id) : NULL, + device_scale_factor()); + } +} + void LayerTreeImpl::RegisterPictureLayerImpl(PictureLayerImpl* layer) { layer_tree_host_impl_->RegisterPictureLayerImpl(layer); } @@ -1298,4 +1472,57 @@ void LayerTreeImpl::UnregisterPictureLayerImpl(PictureLayerImpl* layer) { layer_tree_host_impl_->UnregisterPictureLayerImpl(layer); } +void LayerTreeImpl::InputScrollAnimationFinished() { + layer_tree_host_impl_->ScrollEnd(); +} + +bool LayerTreeImpl::SmoothnessTakesPriority() const { + return layer_tree_host_impl_->GetTreePriority() == SMOOTHNESS_TAKES_PRIORITY; +} + +BlockingTaskRunner* LayerTreeImpl::BlockingMainThreadTaskRunner() const { + return proxy()->blocking_main_thread_task_runner(); +} + +void LayerTreeImpl::SetPageScaleAnimation( + const gfx::Vector2d& target_offset, + bool anchor_point, + float page_scale, + base::TimeDelta duration) { + if (!InnerViewportScrollLayer()) + return; + + gfx::ScrollOffset scroll_total = TotalScrollOffset(); + gfx::SizeF scaled_scrollable_size = ScrollableSize(); + gfx::SizeF viewport_size = InnerViewportContainerLayer()->bounds(); + + // Easing constants experimentally determined. + scoped_ptr<TimingFunction> timing_function = + CubicBezierTimingFunction::Create(.8, 0, .3, .9); + + // TODO(miletus) : Pass in ScrollOffset. + page_scale_animation_ = + PageScaleAnimation::Create(ScrollOffsetToVector2dF(scroll_total), + total_page_scale_factor(), + viewport_size, + scaled_scrollable_size, + timing_function.Pass()); + + if (anchor_point) { + gfx::Vector2dF anchor(target_offset); + page_scale_animation_->ZoomWithAnchor(anchor, + page_scale, + duration.InSecondsF()); + } else { + gfx::Vector2dF scaled_target_offset = target_offset; + page_scale_animation_->ZoomTo(scaled_target_offset, + page_scale, + duration.InSecondsF()); + } +} + +scoped_ptr<PageScaleAnimation> LayerTreeImpl::TakePageScaleAnimation() { + return page_scale_animation_.Pass(); +} + } // namespace cc diff --git a/chromium/cc/trees/layer_tree_impl.h b/chromium/cc/trees/layer_tree_impl.h index 3b3c6cf5623..57e6ca129ca 100644 --- a/chromium/cc/trees/layer_tree_impl.h +++ b/chromium/cc/trees/layer_tree_impl.h @@ -6,6 +6,7 @@ #define CC_TREES_LAYER_TREE_IMPL_H_ #include <list> +#include <set> #include <string> #include <vector> @@ -17,16 +18,11 @@ #include "cc/output/renderer.h" #include "cc/resources/ui_resource_client.h" -#if defined(COMPILER_GCC) -namespace BASE_HASH_NAMESPACE { -template<> -struct hash<cc::LayerImpl*> { - size_t operator()(cc::LayerImpl* ptr) const { - return hash<size_t>()(reinterpret_cast<size_t>(ptr)); - } -}; -} // namespace BASE_HASH_NAMESPACE -#endif // COMPILER +namespace base { +namespace debug { +class TracedValue; +} +} namespace cc { @@ -41,6 +37,7 @@ class LayerTreeImpl; class LayerTreeSettings; class MemoryHistory; class OutputSurface; +class PageScaleAnimation; class PaintTimeCounter; class PictureLayerImpl; class Proxy; @@ -48,6 +45,7 @@ class ResourceProvider; class TileManager; class UIResourceRequest; struct RendererCapabilities; +struct SelectionHandle; typedef std::list<UIResourceRequest> UIResourceRequestQueue; @@ -73,24 +71,28 @@ class CC_EXPORT LayerTreeImpl { FrameRateCounter* frame_rate_counter() const; PaintTimeCounter* paint_time_counter() const; MemoryHistory* memory_history() const; - bool device_viewport_valid_for_tile_management() const; gfx::Size device_viewport_size() const; bool IsActiveTree() const; bool IsPendingTree() const; bool IsRecycleTree() const; LayerImpl* FindActiveTreeLayerById(int id); LayerImpl* FindPendingTreeLayerById(int id); - int MaxTextureSize() const; bool PinchGestureActive() const; - base::TimeTicks CurrentFrameTimeTicks() const; + BeginFrameArgs CurrentBeginFrameArgs() const; base::TimeDelta begin_impl_frame_interval() const; void SetNeedsCommit(); + gfx::Rect DeviceViewport() const; gfx::Size DrawViewportSize() const; + const gfx::Rect ViewportRectForTilePriority() const; scoped_ptr<ScrollbarAnimationController> CreateScrollbarAnimationController( LayerImpl* scrolling_layer); void DidAnimateScrollOffset(); + void InputScrollAnimationFinished(); bool use_gpu_rasterization() const; bool create_low_res_tiling() const; + BlockingTaskRunner* BlockingMainThreadTaskRunner() const; + bool RequiresHighResToDraw() const; + bool SmoothnessTakesPriority() const; // Tree specific methods exposed to layer-impl tree. // --------------------------------------------------------------------------- @@ -101,7 +103,8 @@ class CC_EXPORT LayerTreeImpl { const LayerTreeDebugState& debug_state() const; float device_scale_factor() const; DebugRectHistory* debug_rect_history() const; - scoped_ptr<base::Value> AsValue() const; + void GetAllTilesForTracing(std::set<const Tile*>* tiles) const; + void AsValueInto(base::debug::TracedValue* dict) const; // Other public methods // --------------------------------------------------------------------------- @@ -124,15 +127,15 @@ class CC_EXPORT LayerTreeImpl { LayerImpl* InnerViewportScrollLayer() const; // This function may return NULL, it is the caller's responsibility to check. LayerImpl* OuterViewportScrollLayer() const; - gfx::Vector2dF TotalScrollOffset() const; - gfx::Vector2dF TotalMaxScrollOffset() const; + gfx::ScrollOffset TotalScrollOffset() const; + gfx::ScrollOffset TotalMaxScrollOffset() const; gfx::Vector2dF TotalScrollDelta() const; LayerImpl* InnerViewportContainerLayer() const; + LayerImpl* OuterViewportContainerLayer() const; LayerImpl* CurrentlyScrollingLayer() const; void SetCurrentlyScrollingLayer(LayerImpl* layer); void ClearCurrentlyScrollingLayer(); - float VerticalAdjust(const int clip_layer_id) const; void SetViewportLayersFromIds(int page_scale_layer_id, int inner_viewport_scroll_layer_id, @@ -186,6 +189,11 @@ class CC_EXPORT LayerTreeImpl { void ForceRedrawNextActivation() { next_activation_forces_redraw_ = true; } + void set_has_ever_been_drawn(bool has_drawn) { + has_ever_been_drawn_ = has_drawn; + } + bool has_ever_been_drawn() const { return has_ever_been_drawn_; } + void set_ui_resource_request_queue(const UIResourceRequestQueue& queue); const LayerImplList& RenderSurfaceLayerList() const; @@ -203,6 +211,8 @@ class CC_EXPORT LayerTreeImpl { void RegisterLayer(LayerImpl* layer); void UnregisterLayer(LayerImpl* layer); + size_t NumLayers(); + AnimationRegistrar* animationRegistrar() const; void PushPersistedState(LayerTreeImpl* pending_tree); @@ -213,10 +223,6 @@ class CC_EXPORT LayerTreeImpl { void SetContentsTexturesPurged(); void ResetContentsTexturesPurged(); - void SetRequiresHighResToDraw(); - void ResetRequiresHighResToDraw(); - bool RequiresHighResToDraw() const; - // Set on the active tree when the viewport size recently changed // and the active tree's size is now out of date. bool ViewportSizeInvalid() const; @@ -228,8 +234,9 @@ class CC_EXPORT LayerTreeImpl { void SetRootLayerScrollOffsetDelegate( LayerScrollOffsetDelegate* root_layer_scroll_offset_delegate); + void OnRootLayerDelegatedScrollOffsetChanged(); void UpdateScrollOffsetDelegate(); - gfx::Vector2dF GetDelegatedScrollOffset(LayerImpl* layer); + gfx::ScrollOffset GetDelegatedScrollOffset(LayerImpl* layer); // Call this function when you expect there to be a swap buffer. // See swap_promise.h for how to use SwapPromise. @@ -263,9 +270,53 @@ class CC_EXPORT LayerTreeImpl { LayerImpl* FindLayerThatIsHitByPointInTouchHandlerRegion( const gfx::PointF& screen_space_point); + void RegisterSelection(const LayerSelectionBound& start, + const LayerSelectionBound& end); + + // Compute the current selection handle location and visbility with respect to + // the viewport. + void GetViewportSelection(ViewportSelectionBound* start, + ViewportSelectionBound* end); + void RegisterPictureLayerImpl(PictureLayerImpl* layer); void UnregisterPictureLayerImpl(PictureLayerImpl* layer); + void set_top_controls_layout_height(float height) { + top_controls_layout_height_ = height; + } + void set_top_controls_content_offset(float offset) { + top_controls_content_offset_ = offset; + } + void set_top_controls_delta(float delta) { + top_controls_delta_ = delta; + } + void set_sent_top_controls_delta(float sent_delta) { + sent_top_controls_delta_ = sent_delta; + } + + float top_controls_layout_height() const { + return top_controls_layout_height_; + } + float top_controls_content_offset() const { + return top_controls_content_offset_; + } + float top_controls_delta() const { + return top_controls_delta_; + } + float sent_top_controls_delta() const { + return sent_top_controls_delta_; + } + float total_top_controls_content_offset() const { + return top_controls_content_offset_ + top_controls_delta_; + } + + void SetPageScaleAnimation( + const gfx::Vector2d& target_offset, + bool anchor_point, + float page_scale, + base::TimeDelta duration); + scoped_ptr<PageScaleAnimation> TakePageScaleAnimation(); + protected: explicit LayerTreeImpl(LayerTreeHostImpl* layer_tree_host_impl); void ReleaseResourcesRecursive(LayerImpl* current); @@ -287,6 +338,9 @@ class CC_EXPORT LayerTreeImpl { LayerImpl* inner_viewport_scroll_layer_; LayerImpl* outer_viewport_scroll_layer_; + LayerSelectionBound selection_start_; + LayerSelectionBound selection_end_; + float page_scale_factor_; float page_scale_delta_; float sent_page_scale_delta_; @@ -305,7 +359,6 @@ class CC_EXPORT LayerTreeImpl { LayerImplList render_surface_layer_list_; bool contents_textures_purged_; - bool requires_high_res_to_draw_; bool viewport_size_invalid_; bool needs_update_draw_properties_; @@ -315,12 +368,27 @@ class CC_EXPORT LayerTreeImpl { bool next_activation_forces_redraw_; + bool has_ever_been_drawn_; + ScopedPtrVector<SwapPromise> swap_promise_list_; UIResourceRequestQueue ui_resource_request_queue_; int render_surface_layer_list_id_; + // The top controls content offset at the time of the last layout (and thus, + // viewport resize) in Blink. i.e. How much the viewport was shrunk by the top + // controls. + float top_controls_layout_height_; + + // The up-to-date content offset of the top controls, i.e. the amount that the + // web contents have been shifted down from the top of the device viewport. + float top_controls_content_offset_; + float top_controls_delta_; + float sent_top_controls_delta_; + + scoped_ptr<PageScaleAnimation> page_scale_animation_; + private: DISALLOW_COPY_AND_ASSIGN(LayerTreeImpl); }; diff --git a/chromium/cc/trees/layer_tree_impl_unittest.cc b/chromium/cc/trees/layer_tree_impl_unittest.cc index 006fc35997a..f8de8b06862 100644 --- a/chromium/cc/trees/layer_tree_impl_unittest.cc +++ b/chromium/cc/trees/layer_tree_impl_unittest.cc @@ -13,7 +13,7 @@ #include "cc/test/layer_tree_host_common_test.h" #include "cc/test/test_shared_bitmap_manager.h" #include "cc/trees/layer_tree_host_impl.h" -#include "ui/gfx/size_conversions.h" +#include "ui/gfx/geometry/size_conversions.h" namespace cc { namespace { @@ -25,8 +25,7 @@ class LayerTreeImplTest : public LayerTreeHostCommonTest { settings.layer_transforms_should_scale_layer_contents = true; host_impl_.reset( new FakeLayerTreeHostImpl(settings, &proxy_, &shared_bitmap_manager_)); - EXPECT_TRUE(host_impl_->InitializeRenderer( - FakeOutputSurface::Create3d().PassAs<OutputSurface>())); + EXPECT_TRUE(host_impl_->InitializeRenderer(FakeOutputSurface::Create3d())); } FakeLayerTreeHostImpl& host_impl() { return *host_impl_; } @@ -62,7 +61,7 @@ TEST_F(LayerTreeImplTest, HitTestingForSingleLayer) { host_impl().SetViewportSize(root->bounds()); host_impl().active_tree()->SetRootLayer(root.Pass()); - host_impl().active_tree()->UpdateDrawProperties(); + host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); // Sanity check the scenario we just created. ASSERT_EQ(1u, RenderSurfaceLayerList().size()); @@ -124,11 +123,11 @@ TEST_F(LayerTreeImplTest, HitTestingForSingleLayerAndHud) { hud->SetDrawsContent(true); host_impl().active_tree()->set_hud_layer(hud.get()); - root->AddChild(hud.PassAs<LayerImpl>()); + root->AddChild(hud.Pass()); host_impl().SetViewportSize(hud_bounds); host_impl().active_tree()->SetRootLayer(root.Pass()); - host_impl().active_tree()->UpdateDrawProperties(); + host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); // Sanity check the scenario we just created. ASSERT_EQ(1u, RenderSurfaceLayerList().size()); @@ -186,7 +185,7 @@ TEST_F(LayerTreeImplTest, HitTestingForUninvertibleTransform) { host_impl().SetViewportSize(root->bounds()); host_impl().active_tree()->SetRootLayer(root.Pass()); - host_impl().active_tree()->UpdateDrawProperties(); + host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); // Sanity check the scenario we just created. ASSERT_EQ(1u, RenderSurfaceLayerList().size()); ASSERT_EQ(1u, root_layer()->render_surface()->layer_list().size()); @@ -252,7 +251,7 @@ TEST_F(LayerTreeImplTest, HitTestingForSinglePositionedLayer) { host_impl().SetViewportSize(root->bounds()); host_impl().active_tree()->SetRootLayer(root.Pass()); - host_impl().active_tree()->UpdateDrawProperties(); + host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); // Sanity check the scenario we just created. ASSERT_EQ(1u, RenderSurfaceLayerList().size()); @@ -308,7 +307,7 @@ TEST_F(LayerTreeImplTest, HitTestingForSingleRotatedLayer) { host_impl().SetViewportSize(root->bounds()); host_impl().active_tree()->SetRootLayer(root.Pass()); - host_impl().active_tree()->UpdateDrawProperties(); + host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); // Sanity check the scenario we just created. ASSERT_EQ(1u, RenderSurfaceLayerList().size()); @@ -377,7 +376,7 @@ TEST_F(LayerTreeImplTest, HitTestingForSinglePerspectiveLayer) { host_impl().SetViewportSize(root->bounds()); host_impl().active_tree()->SetRootLayer(root.Pass()); - host_impl().active_tree()->UpdateDrawProperties(); + host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); // Sanity check the scenario we just created. ASSERT_EQ(1u, RenderSurfaceLayerList().size()); @@ -457,7 +456,7 @@ TEST_F(LayerTreeImplTest, HitTestingForSingleLayerWithScaledContents) { host_impl().SetViewportSize(root->bounds()); host_impl().active_tree()->SetRootLayer(root.Pass()); - host_impl().active_tree()->UpdateDrawProperties(); + host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); // Sanity check the scenario we just created. // The visible content rect for test_layer is actually 100x100, even though @@ -548,7 +547,7 @@ TEST_F(LayerTreeImplTest, HitTestingForSimpleClippedLayer) { host_impl().SetViewportSize(root->bounds()); host_impl().active_tree()->SetRootLayer(root.Pass()); - host_impl().active_tree()->UpdateDrawProperties(); + host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); // Sanity check the scenario we just created. ASSERT_EQ(1u, RenderSurfaceLayerList().size()); @@ -673,7 +672,7 @@ TEST_F(LayerTreeImplTest, HitTestingForMultiClippedRotatedLayer) { host_impl().SetViewportSize(root->bounds()); host_impl().active_tree()->SetRootLayer(root.Pass()); - host_impl().active_tree()->UpdateDrawProperties(); + host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); // Sanity check the scenario we just created. // The grand_child is expected to create a render surface because it @@ -796,7 +795,7 @@ TEST_F(LayerTreeImplTest, HitTestingForNonClippingIntermediateLayer) { host_impl().SetViewportSize(root->bounds()); host_impl().active_tree()->SetRootLayer(root.Pass()); - host_impl().active_tree()->UpdateDrawProperties(); + host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); // Sanity check the scenario we just created. ASSERT_EQ(1u, RenderSurfaceLayerList().size()); @@ -904,7 +903,7 @@ TEST_F(LayerTreeImplTest, HitTestingForMultipleLayers) { host_impl().SetViewportSize(root->bounds()); host_impl().active_tree()->SetRootLayer(root.Pass()); - host_impl().active_tree()->UpdateDrawProperties(); + host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); // Sanity check the scenario we just created. ASSERT_TRUE(child1); @@ -1052,7 +1051,7 @@ TEST_F(LayerTreeImplTest, HitTestingForMultipleLayersAtVaryingDepths) { host_impl().SetViewportSize(root->bounds()); host_impl().active_tree()->SetRootLayer(root.Pass()); - host_impl().active_tree()->UpdateDrawProperties(); + host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); // Sanity check the scenario we just created. ASSERT_TRUE(child1); @@ -1170,7 +1169,7 @@ TEST_F(LayerTreeImplTest, HitTestingRespectsClipParents) { host_impl().SetViewportSize(root->bounds()); host_impl().active_tree()->SetRootLayer(root.Pass()); - host_impl().active_tree()->UpdateDrawProperties(); + host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); gfx::Point test_point = gfx::Point(12, 52); LayerImpl* result_layer = @@ -1245,7 +1244,7 @@ TEST_F(LayerTreeImplTest, HitTestingRespectsScrollParents) { host_impl().SetViewportSize(root->bounds()); host_impl().active_tree()->SetRootLayer(root.Pass()); - host_impl().active_tree()->UpdateDrawProperties(); + host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); gfx::Point test_point = gfx::Point(12, 52); LayerImpl* result_layer = @@ -1338,7 +1337,7 @@ TEST_F(LayerTreeImplTest, HitTestingForMultipleLayerLists) { host_impl().SetViewportSize(root->bounds()); host_impl().active_tree()->SetRootLayer(root.Pass()); - host_impl().active_tree()->UpdateDrawProperties(); + host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); // Sanity check the scenario we just created. ASSERT_TRUE(child1); @@ -1428,7 +1427,7 @@ TEST_F(LayerTreeImplTest, HitCheckingTouchHandlerRegionsForSingleLayer) { host_impl().SetViewportSize(root->bounds()); host_impl().active_tree()->SetRootLayer(root.Pass()); - host_impl().active_tree()->UpdateDrawProperties(); + host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); // Sanity check the scenario we just created. ASSERT_EQ(1u, RenderSurfaceLayerList().size()); @@ -1517,7 +1516,7 @@ TEST_F(LayerTreeImplTest, host_impl().SetViewportSize(root->bounds()); host_impl().active_tree()->SetRootLayer(root.Pass()); - host_impl().active_tree()->UpdateDrawProperties(); + host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); // Sanity check the scenario we just created. ASSERT_EQ(1u, RenderSurfaceLayerList().size()); @@ -1595,7 +1594,7 @@ TEST_F(LayerTreeImplTest, host_impl().SetViewportSize(root->bounds()); host_impl().active_tree()->SetRootLayer(root.Pass()); - host_impl().active_tree()->UpdateDrawProperties(); + host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); // Sanity check the scenario we just created. ASSERT_EQ(1u, RenderSurfaceLayerList().size()); @@ -1691,7 +1690,7 @@ TEST_F(LayerTreeImplTest, host_impl().SetViewportSize(root->bounds()); host_impl().active_tree()->SetRootLayer(root.Pass()); - host_impl().active_tree()->UpdateDrawProperties(); + host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); // Sanity check the scenario we just created. // The visible content rect for test_layer is actually 100x100, even though @@ -1800,7 +1799,7 @@ TEST_F(LayerTreeImplTest, page_scale_factor, page_scale_factor, page_scale_factor); host_impl().active_tree()->SetRootLayer(root.Pass()); host_impl().active_tree()->SetViewportLayersFromIds(1, 1, Layer::INVALID_ID); - host_impl().active_tree()->UpdateDrawProperties(); + host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); // Sanity check the scenario we just created. // The visible content rect for test_layer is actually 100x100, even though @@ -1930,7 +1929,7 @@ TEST_F(LayerTreeImplTest, HitCheckingTouchHandlerRegionsForSimpleClippedLayer) { host_impl().SetViewportSize(root->bounds()); host_impl().active_tree()->SetRootLayer(root.Pass()); - host_impl().active_tree()->UpdateDrawProperties(); + host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); // Sanity check the scenario we just created. ASSERT_EQ(1u, RenderSurfaceLayerList().size()); @@ -2028,7 +2027,7 @@ TEST_F(LayerTreeImplTest, HitCheckingTouchHandlerOverlappingRegions) { host_impl().SetViewportSize(root->bounds()); host_impl().active_tree()->SetRootLayer(root.Pass()); - host_impl().active_tree()->UpdateDrawProperties(); + host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); // Sanity check the scenario we just created. ASSERT_EQ(1u, RenderSurfaceLayerList().size()); @@ -2070,5 +2069,297 @@ TEST_F(LayerTreeImplTest, HitCheckingTouchHandlerOverlappingRegions) { EXPECT_FALSE(result_layer); } +TEST_F(LayerTreeImplTest, SelectionBoundsForSingleLayer) { + int root_layer_id = 12345; + scoped_ptr<LayerImpl> root = + LayerImpl::Create(host_impl().active_tree(), root_layer_id); + + gfx::Transform identity_matrix; + gfx::Point3F transform_origin; + gfx::PointF position; + gfx::Size bounds(100, 100); + SetLayerPropertiesForTesting(root.get(), + identity_matrix, + transform_origin, + position, + bounds, + true, + false); + root->SetDrawsContent(true); + + host_impl().SetViewportSize(root->bounds()); + host_impl().active_tree()->SetRootLayer(root.Pass()); + host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); + + // Sanity check the scenario we just created. + ASSERT_EQ(1u, RenderSurfaceLayerList().size()); + ASSERT_EQ(1u, root_layer()->render_surface()->layer_list().size()); + + LayerSelectionBound left_input; + left_input.type = SELECTION_BOUND_LEFT; + left_input.edge_top = gfx::PointF(10, 10); + left_input.edge_bottom = gfx::PointF(10, 20); + left_input.layer_id = root_layer_id; + + LayerSelectionBound right_input; + right_input.type = SELECTION_BOUND_RIGHT; + right_input.edge_top = gfx::PointF(50, 10); + right_input.edge_bottom = gfx::PointF(50, 30); + right_input.layer_id = root_layer_id; + + ViewportSelectionBound left_output, right_output; + + // Empty input bounds should produce empty output bounds. + host_impl().active_tree()->GetViewportSelection(&left_output, &right_output); + EXPECT_EQ(ViewportSelectionBound(), left_output); + EXPECT_EQ(ViewportSelectionBound(), right_output); + + // Selection bounds should produce distinct left and right bounds. + host_impl().active_tree()->RegisterSelection(left_input, right_input); + host_impl().active_tree()->GetViewportSelection(&left_output, &right_output); + EXPECT_EQ(left_input.type, left_output.type); + EXPECT_EQ(left_input.edge_bottom, left_output.edge_bottom); + EXPECT_EQ(left_input.edge_top, left_output.edge_top); + EXPECT_TRUE(left_output.visible); + EXPECT_EQ(right_input.type, right_output.type); + EXPECT_EQ(right_input.edge_bottom, right_output.edge_bottom); + EXPECT_EQ(right_input.edge_top, right_output.edge_top); + EXPECT_TRUE(right_output.visible); + + // Insertion bounds should produce identical left and right bounds. + LayerSelectionBound insertion_input; + insertion_input.type = SELECTION_BOUND_CENTER; + insertion_input.edge_top = gfx::PointF(15, 10); + insertion_input.edge_bottom = gfx::PointF(15, 30); + insertion_input.layer_id = root_layer_id; + host_impl().active_tree()->RegisterSelection(insertion_input, + LayerSelectionBound()); + host_impl().active_tree()->GetViewportSelection(&left_output, &right_output); + EXPECT_EQ(insertion_input.type, left_output.type); + EXPECT_EQ(insertion_input.edge_bottom, left_output.edge_bottom); + EXPECT_EQ(insertion_input.edge_top, left_output.edge_top); + EXPECT_TRUE(left_output.visible); + EXPECT_EQ(left_output, right_output); +} + +TEST_F(LayerTreeImplTest, SelectionBoundsForPartialOccludedLayers) { + int root_layer_id = 12345; + int clip_layer_id = 1234; + int clipped_layer_id = 123; + scoped_ptr<LayerImpl> root = + LayerImpl::Create(host_impl().active_tree(), root_layer_id); + root->SetDrawsContent(true); + + gfx::Transform identity_matrix; + gfx::Point3F transform_origin; + gfx::PointF position; + gfx::Size bounds(100, 100); + SetLayerPropertiesForTesting(root.get(), + identity_matrix, + transform_origin, + position, + bounds, + true, + false); + + gfx::Vector2dF clipping_offset(10, 10); + { + scoped_ptr<LayerImpl> clipping_layer = + LayerImpl::Create(host_impl().active_tree(), clip_layer_id); + // The clipping layer should occlude the right selection bound. + gfx::PointF position = gfx::PointF() + clipping_offset; + gfx::Size bounds(50, 50); + SetLayerPropertiesForTesting(clipping_layer.get(), + identity_matrix, + transform_origin, + position, + bounds, + true, + false); + clipping_layer->SetMasksToBounds(true); + + scoped_ptr<LayerImpl> clipped_layer = + LayerImpl::Create(host_impl().active_tree(), clipped_layer_id); + position = gfx::PointF(); + bounds = gfx::Size(100, 100); + SetLayerPropertiesForTesting(clipped_layer.get(), + identity_matrix, + transform_origin, + position, + bounds, + true, + false); + clipped_layer->SetDrawsContent(true); + clipping_layer->AddChild(clipped_layer.Pass()); + root->AddChild(clipping_layer.Pass()); + } + + host_impl().SetViewportSize(root->bounds()); + host_impl().active_tree()->SetRootLayer(root.Pass()); + host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); + + // Sanity check the scenario we just created. + ASSERT_EQ(1u, RenderSurfaceLayerList().size()); + + LayerSelectionBound left_input; + left_input.type = SELECTION_BOUND_LEFT; + left_input.edge_top = gfx::PointF(25, 10); + left_input.edge_bottom = gfx::PointF(25, 30); + left_input.layer_id = clipped_layer_id; + + LayerSelectionBound right_input; + right_input.type = SELECTION_BOUND_RIGHT; + right_input.edge_top = gfx::PointF(75, 10); + right_input.edge_bottom = gfx::PointF(75, 30); + right_input.layer_id = clipped_layer_id; + host_impl().active_tree()->RegisterSelection(left_input, right_input); + + // The left bound should be occluded by the clip layer. + ViewportSelectionBound left_output, right_output; + host_impl().active_tree()->GetViewportSelection(&left_output, &right_output); + EXPECT_EQ(left_input.type, left_output.type); + gfx::PointF expected_left_output_top = left_input.edge_top; + gfx::PointF expected_left_output_bottom = left_input.edge_bottom; + expected_left_output_top.Offset(clipping_offset.x(), clipping_offset.y()); + expected_left_output_bottom.Offset(clipping_offset.x(), clipping_offset.y()); + EXPECT_EQ(expected_left_output_top, left_output.edge_top); + EXPECT_EQ(expected_left_output_bottom, left_output.edge_bottom); + EXPECT_TRUE(left_output.visible); + EXPECT_EQ(right_input.type, right_output.type); + gfx::PointF expected_right_output_top = right_input.edge_top; + gfx::PointF expected_right_output_bottom = right_input.edge_bottom; + expected_right_output_bottom.Offset(clipping_offset.x(), clipping_offset.y()); + expected_right_output_top.Offset(clipping_offset.x(), clipping_offset.y()); + EXPECT_EQ(expected_right_output_top, right_output.edge_top); + EXPECT_EQ(expected_right_output_bottom, right_output.edge_bottom); + EXPECT_FALSE(right_output.visible); + + // Handles outside the viewport bounds should be marked invisible. + left_input.edge_top = gfx::PointF(-25, 0); + left_input.edge_bottom = gfx::PointF(-25, 20); + host_impl().active_tree()->RegisterSelection(left_input, right_input); + host_impl().active_tree()->GetViewportSelection(&left_output, &right_output); + EXPECT_FALSE(left_output.visible); + + left_input.edge_top = gfx::PointF(0, -25); + left_input.edge_bottom = gfx::PointF(0, -5); + host_impl().active_tree()->RegisterSelection(left_input, right_input); + host_impl().active_tree()->GetViewportSelection(&left_output, &right_output); + EXPECT_FALSE(left_output.visible); + + // If the handle bottom is partially visible, the handle is marked visible. + left_input.edge_top = gfx::PointF(0, -20); + left_input.edge_bottom = gfx::PointF(0, 1); + host_impl().active_tree()->RegisterSelection(left_input, right_input); + host_impl().active_tree()->GetViewportSelection(&left_output, &right_output); + EXPECT_TRUE(left_output.visible); +} + +TEST_F(LayerTreeImplTest, SelectionBoundsForScaledLayers) { + int root_layer_id = 1; + int sub_layer_id = 2; + scoped_ptr<LayerImpl> root = + LayerImpl::Create(host_impl().active_tree(), root_layer_id); + root->SetDrawsContent(true); + + gfx::Transform identity_matrix; + gfx::Point3F transform_origin; + gfx::PointF position; + gfx::Size bounds(100, 100); + SetLayerPropertiesForTesting(root.get(), + identity_matrix, + transform_origin, + position, + bounds, + true, + false); + + gfx::Vector2dF sub_layer_offset(10, 0); + { + scoped_ptr<LayerImpl> sub_layer = + LayerImpl::Create(host_impl().active_tree(), sub_layer_id); + gfx::PointF position = gfx::PointF() + sub_layer_offset; + gfx::Size bounds(50, 50); + SetLayerPropertiesForTesting(sub_layer.get(), + identity_matrix, + transform_origin, + position, + bounds, + true, + false); + sub_layer->SetDrawsContent(true); + root->AddChild(sub_layer.Pass()); + } + + float device_scale_factor = 3.f; + float page_scale_factor = 5.f; + gfx::Size scaled_bounds_for_root = gfx::ToCeiledSize( + gfx::ScaleSize(root->bounds(), device_scale_factor * page_scale_factor)); + host_impl().SetViewportSize(scaled_bounds_for_root); + + host_impl().SetDeviceScaleFactor(device_scale_factor); + host_impl().active_tree()->SetPageScaleFactorAndLimits( + page_scale_factor, page_scale_factor, page_scale_factor); + host_impl().active_tree()->SetRootLayer(root.Pass()); + host_impl().active_tree()->SetViewportLayersFromIds(1, 1, Layer::INVALID_ID); + host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree(); + + // Sanity check the scenario we just created. + ASSERT_EQ(1u, RenderSurfaceLayerList().size()); + + LayerSelectionBound left_input; + left_input.type = SELECTION_BOUND_LEFT; + left_input.edge_top = gfx::PointF(10, 10); + left_input.edge_bottom = gfx::PointF(10, 30); + left_input.layer_id = root_layer_id; + + LayerSelectionBound right_input; + right_input.type = SELECTION_BOUND_RIGHT; + right_input.edge_top = gfx::PointF(0, 0); + right_input.edge_bottom = gfx::PointF(0, 20); + right_input.layer_id = sub_layer_id; + host_impl().active_tree()->RegisterSelection(left_input, right_input); + + // The viewport bounds should be properly scaled by the page scale, but should + // remain in DIP coordinates. + ViewportSelectionBound left_output, right_output; + host_impl().active_tree()->GetViewportSelection(&left_output, &right_output); + EXPECT_EQ(left_input.type, left_output.type); + gfx::PointF expected_left_output_top = left_input.edge_top; + gfx::PointF expected_left_output_bottom = left_input.edge_bottom; + expected_left_output_top.Scale(page_scale_factor); + expected_left_output_bottom.Scale(page_scale_factor); + EXPECT_EQ(left_input.edge_top, left_output.edge_top); + EXPECT_EQ(left_input.edge_bottom, left_output.edge_bottom); + EXPECT_TRUE(left_output.visible); + EXPECT_EQ(right_input.type, right_output.type); + + gfx::PointF expected_right_output_top = right_input.edge_top; + gfx::PointF expected_right_output_bottom = right_input.edge_bottom; + expected_right_output_top.Offset(sub_layer_offset.x(), sub_layer_offset.y()); + expected_right_output_bottom.Offset(sub_layer_offset.x(), + sub_layer_offset.y()); + expected_right_output_top.Scale(page_scale_factor); + expected_right_output_bottom.Scale(page_scale_factor); + EXPECT_EQ(expected_right_output_top, right_output.edge_top); + EXPECT_EQ(expected_right_output_bottom, right_output.edge_bottom); + EXPECT_TRUE(right_output.visible); +} + +TEST_F(LayerTreeImplTest, NumLayersTestOne) { + EXPECT_EQ(0u, host_impl().active_tree()->NumLayers()); + scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl().active_tree(), 1); + EXPECT_EQ(1u, host_impl().active_tree()->NumLayers()); +} + +TEST_F(LayerTreeImplTest, NumLayersSmallTree) { + EXPECT_EQ(0u, host_impl().active_tree()->NumLayers()); + scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl().active_tree(), 1); + root->AddChild(LayerImpl::Create(host_impl().active_tree(), 2)); + root->AddChild(LayerImpl::Create(host_impl().active_tree(), 3)); + root->child_at(1)->AddChild(LayerImpl::Create(host_impl().active_tree(), 4)); + EXPECT_EQ(4u, host_impl().active_tree()->NumLayers()); +} + } // namespace } // namespace cc diff --git a/chromium/cc/trees/layer_tree_settings.cc b/chromium/cc/trees/layer_tree_settings.cc index 1465325f5ba..1d5cf1bb2eb 100644 --- a/chromium/cc/trees/layer_tree_settings.cc +++ b/chromium/cc/trees/layer_tree_settings.cc @@ -15,23 +15,26 @@ namespace cc { LayerTreeSettings::LayerTreeSettings() : impl_side_painting(false), allow_antialiasing(true), + force_antialiasing(false), throttle_frame_production(true), + single_thread_proxy_scheduler(true), begin_frame_scheduling_enabled(false), - main_frame_before_draw_enabled(true), main_frame_before_activation_enabled(false), using_synchronous_renderer_compositor(false), + disable_hi_res_timer_tasks_on_battery(false), report_overscroll_only_for_scrollable_axes(false), per_tile_painting_enabled(false), partial_swap_enabled(false), accelerated_animation_enabled(true), can_use_lcd_text(true), + use_distance_field_text(false), should_clear_root_render_pass(true), gpu_rasterization_enabled(false), gpu_rasterization_forced(false), - recording_mode(RecordNormally), - create_low_res_tiling(true), + create_low_res_tiling(false), scrollbar_animator(NoAnimator), scrollbar_fade_delay_ms(0), + scrollbar_fade_resize_delay_ms(0), scrollbar_fade_duration_ms(0), solid_color_scrollbar_color(SK_ColorWHITE), calculate_top_controls_position(false), @@ -47,6 +50,7 @@ LayerTreeSettings::LayerTreeSettings() max_partial_texture_updates(std::numeric_limits<size_t>::max()), default_tile_size(gfx::Size(256, 256)), max_untiled_layer_size(gfx::Size(512, 512)), + default_tile_grid_size(gfx::Size(256, 256)), minimum_occlusion_tracking_size(gfx::Size(160, 160)), use_pinch_zoom_scrollbars(false), use_pinch_virtual_viewport(false), @@ -62,8 +66,9 @@ LayerTreeSettings::LayerTreeSettings() use_zero_copy(false), ignore_root_layer_flings(false), use_rgba_4444_textures(false), - touch_hit_testing(true), texture_id_allocation_chunk_size(64), + scheduled_raster_task_limit(32), + use_occlusion_for_tile_prioritization(false), record_full_layer(false) { } diff --git a/chromium/cc/trees/layer_tree_settings.h b/chromium/cc/trees/layer_tree_settings.h index ba39e3ca3ba..74a3b0c85bb 100644 --- a/chromium/cc/trees/layer_tree_settings.h +++ b/chromium/cc/trees/layer_tree_settings.h @@ -9,7 +9,7 @@ #include "cc/base/cc_export.h" #include "cc/debug/layer_tree_debug_state.h" #include "third_party/skia/include/core/SkColor.h" -#include "ui/gfx/size.h" +#include "ui/gfx/geometry/size.h" namespace cc { @@ -20,11 +20,13 @@ class CC_EXPORT LayerTreeSettings { bool impl_side_painting; bool allow_antialiasing; + bool force_antialiasing; bool throttle_frame_production; + bool single_thread_proxy_scheduler; bool begin_frame_scheduling_enabled; - bool main_frame_before_draw_enabled; bool main_frame_before_activation_enabled; bool using_synchronous_renderer_compositor; + bool disable_hi_res_timer_tasks_on_battery; bool report_overscroll_only_for_scrollable_axes; bool per_tile_painting_enabled; bool partial_swap_enabled; @@ -34,11 +36,6 @@ class CC_EXPORT LayerTreeSettings { bool should_clear_root_render_pass; bool gpu_rasterization_enabled; bool gpu_rasterization_forced; - enum RecordingMode { - RecordNormally, - RecordWithSkRecord, - }; - RecordingMode recording_mode; bool create_low_res_tiling; enum ScrollbarAnimator { @@ -48,6 +45,7 @@ class CC_EXPORT LayerTreeSettings { }; ScrollbarAnimator scrollbar_animator; int scrollbar_fade_delay_ms; + int scrollbar_fade_resize_delay_ms; int scrollbar_fade_duration_ms; SkColor solid_color_scrollbar_color; bool calculate_top_controls_position; @@ -63,6 +61,7 @@ class CC_EXPORT LayerTreeSettings { size_t max_partial_texture_updates; gfx::Size default_tile_size; gfx::Size max_untiled_layer_size; + gfx::Size default_tile_grid_size; gfx::Size minimum_occlusion_tracking_size; bool use_pinch_zoom_scrollbars; bool use_pinch_virtual_viewport; @@ -77,8 +76,9 @@ class CC_EXPORT LayerTreeSettings { bool use_zero_copy; bool ignore_root_layer_flings; bool use_rgba_4444_textures; - bool touch_hit_testing; size_t texture_id_allocation_chunk_size; + size_t scheduled_raster_task_limit; + bool use_occlusion_for_tile_prioritization; bool record_full_layer; LayerTreeDebugState initial_debug_state; diff --git a/chromium/cc/trees/occlusion.cc b/chromium/cc/trees/occlusion.cc new file mode 100644 index 00000000000..14168f9699f --- /dev/null +++ b/chromium/cc/trees/occlusion.cc @@ -0,0 +1,88 @@ +// 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 "cc/trees/occlusion.h" + +#include "cc/base/math_util.h" +#include "ui/gfx/geometry/rect.h" + +namespace cc { + +Occlusion::Occlusion() { +} + +Occlusion::Occlusion(const gfx::Transform& draw_transform, + const SimpleEnclosedRegion& occlusion_from_outside_target, + const SimpleEnclosedRegion& occlusion_from_inside_target) + : draw_transform_(draw_transform), + occlusion_from_outside_target_(occlusion_from_outside_target), + occlusion_from_inside_target_(occlusion_from_inside_target) { +} + +Occlusion Occlusion::GetOcclusionWithGivenDrawTransform( + const gfx::Transform& transform) const { + return Occlusion( + transform, occlusion_from_outside_target_, occlusion_from_inside_target_); +} + +bool Occlusion::HasOcclusion() const { + return !occlusion_from_inside_target_.IsEmpty() || + !occlusion_from_outside_target_.IsEmpty(); +} + +bool Occlusion::IsOccluded(const gfx::Rect& content_rect) const { + if (content_rect.IsEmpty()) + return true; + + if (!HasOcclusion()) + return false; + + gfx::Rect unoccluded_rect_in_target_surface = + GetUnoccludedRectInTargetSurface(content_rect); + return unoccluded_rect_in_target_surface.IsEmpty(); +} + +gfx::Rect Occlusion::GetUnoccludedContentRect( + const gfx::Rect& content_rect) const { + if (content_rect.IsEmpty()) + return content_rect; + + if (!HasOcclusion()) + return content_rect; + + gfx::Rect unoccluded_rect_in_target_surface = + GetUnoccludedRectInTargetSurface(content_rect); + if (unoccluded_rect_in_target_surface.IsEmpty()) + return gfx::Rect(); + + gfx::Transform inverse_draw_transform(gfx::Transform::kSkipInitialization); + bool ok = draw_transform_.GetInverse(&inverse_draw_transform); + DCHECK(ok); + + gfx::Rect unoccluded_rect = MathUtil::ProjectEnclosingClippedRect( + inverse_draw_transform, unoccluded_rect_in_target_surface); + unoccluded_rect.Intersect(content_rect); + + return unoccluded_rect; +} + +gfx::Rect Occlusion::GetUnoccludedRectInTargetSurface( + const gfx::Rect& content_rect) const { + // Take the ToEnclosingRect at each step, as we want to contain any unoccluded + // partial pixels in the resulting Rect. + gfx::Rect unoccluded_rect_in_target_surface = + MathUtil::MapEnclosingClippedRect(draw_transform_, content_rect); + DCHECK_LE(occlusion_from_inside_target_.GetRegionComplexity(), 1u); + DCHECK_LE(occlusion_from_outside_target_.GetRegionComplexity(), 1u); + // These subtract operations are more lossy than if we did both operations at + // once. + unoccluded_rect_in_target_surface.Subtract( + occlusion_from_inside_target_.bounds()); + unoccluded_rect_in_target_surface.Subtract( + occlusion_from_outside_target_.bounds()); + + return unoccluded_rect_in_target_surface; +} + +} // namespace cc diff --git a/chromium/cc/trees/occlusion.h b/chromium/cc/trees/occlusion.h new file mode 100644 index 00000000000..56f9962df8b --- /dev/null +++ b/chromium/cc/trees/occlusion.h @@ -0,0 +1,40 @@ +// 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 CC_TREES_OCCLUSION_H_ +#define CC_TREES_OCCLUSION_H_ + +#include "base/basictypes.h" +#include "cc/base/cc_export.h" +#include "cc/base/simple_enclosed_region.h" +#include "ui/gfx/geometry/rect.h" +#include "ui/gfx/transform.h" + +namespace cc { + +class CC_EXPORT Occlusion { + public: + Occlusion(); + Occlusion(const gfx::Transform& draw_transform, + const SimpleEnclosedRegion& occlusion_from_outside_target, + const SimpleEnclosedRegion& occlusion_from_inside_target); + Occlusion GetOcclusionWithGivenDrawTransform( + const gfx::Transform& transform) const; + + bool HasOcclusion() const; + bool IsOccluded(const gfx::Rect& content_rect) const; + gfx::Rect GetUnoccludedContentRect(const gfx::Rect& content_rect) const; + + private: + gfx::Rect GetUnoccludedRectInTargetSurface( + const gfx::Rect& content_rect) const; + + gfx::Transform draw_transform_; + SimpleEnclosedRegion occlusion_from_outside_target_; + SimpleEnclosedRegion occlusion_from_inside_target_; +}; + +} // namespace cc + +#endif // CC_TREES_OCCLUSION_H_ diff --git a/chromium/cc/trees/occlusion_tracker.cc b/chromium/cc/trees/occlusion_tracker.cc index f4a414f6de2..bce1fd514e8 100644 --- a/chromium/cc/trees/occlusion_tracker.cc +++ b/chromium/cc/trees/occlusion_tracker.cc @@ -7,12 +7,13 @@ #include <algorithm> #include "cc/base/math_util.h" +#include "cc/base/region.h" #include "cc/layers/layer.h" #include "cc/layers/layer_impl.h" #include "cc/layers/render_surface.h" #include "cc/layers/render_surface_impl.h" -#include "ui/gfx/quad_f.h" -#include "ui/gfx/rect_conversions.h" +#include "ui/gfx/geometry/quad_f.h" +#include "ui/gfx/geometry/rect_conversions.h" namespace cc { @@ -27,6 +28,16 @@ template <typename LayerType> OcclusionTracker<LayerType>::~OcclusionTracker() {} template <typename LayerType> +Occlusion OcclusionTracker<LayerType>::GetCurrentOcclusionForLayer( + const gfx::Transform& draw_transform) const { + DCHECK(!stack_.empty()); + const StackObject& back = stack_.back(); + return Occlusion(draw_transform, + back.occlusion_from_outside_target, + back.occlusion_from_inside_target); +} + +template <typename LayerType> void OcclusionTracker<LayerType>::EnterLayer( const LayerIteratorPosition<LayerType>& layer_iterator) { LayerType* render_target = layer_iterator.target_render_surface_layer; @@ -65,13 +76,13 @@ static gfx::Rect ScreenSpaceClipRectInTargetSurface( } template <typename RenderSurfaceType> -static Region TransformSurfaceOpaqueRegion( - const Region& region, +static SimpleEnclosedRegion TransformSurfaceOpaqueRegion( + const SimpleEnclosedRegion& region, bool have_clip_rect, const gfx::Rect& clip_rect_in_new_target, const gfx::Transform& transform) { if (region.IsEmpty()) - return Region(); + return region; // Verify that rects within the |surface| will remain rects in its target // surface after applying |transform|. If this is true, then apply |transform| @@ -79,18 +90,13 @@ static Region TransformSurfaceOpaqueRegion( // TODO(danakj): Find a rect interior to each transformed quad. if (!transform.Preserves2dAxisAlignment()) - return Region(); + return SimpleEnclosedRegion(); - // TODO(danakj): If the Region is too complex, degrade gracefully here by - // skipping rects in it. - Region transformed_region; - for (Region::Iterator rects(region); rects.has_rect(); rects.next()) { - bool clipped; - gfx::QuadF transformed_quad = - MathUtil::MapQuad(transform, gfx::QuadF(rects.rect()), &clipped); + SimpleEnclosedRegion transformed_region; + for (size_t i = 0; i < region.GetRegionComplexity(); ++i) { gfx::Rect transformed_rect = - gfx::ToEnclosedRect(transformed_quad.BoundingBox()); - DCHECK(!clipped); // We only map if the transform preserves axis alignment. + MathUtil::MapEnclosedRectWith2dAxisAlignedTransform(transform, + region.GetRect(i)); if (have_clip_rect) transformed_rect.Intersect(clip_rect_in_new_target); transformed_region.Union(transformed_rect); @@ -240,11 +246,12 @@ void OcclusionTracker<LayerType>::FinishedRenderTarget( } template <typename LayerType> -static void ReduceOcclusionBelowSurface(LayerType* contributing_layer, - const gfx::Rect& surface_rect, - const gfx::Transform& surface_transform, - LayerType* render_target, - Region* occlusion_from_inside_target) { +static void ReduceOcclusionBelowSurface( + LayerType* contributing_layer, + const gfx::Rect& surface_rect, + const gfx::Transform& surface_transform, + LayerType* render_target, + SimpleEnclosedRegion* occlusion_from_inside_target) { if (surface_rect.IsEmpty()) return; @@ -265,13 +272,12 @@ static void ReduceOcclusionBelowSurface(LayerType* contributing_layer, // to expand outside the clip. affected_area_in_target.Inset( -outset_left, -outset_top, -outset_right, -outset_bottom); - Region affected_occlusion = IntersectRegions(*occlusion_from_inside_target, - affected_area_in_target); - Region::Iterator affected_occlusion_rects(affected_occlusion); + SimpleEnclosedRegion affected_occlusion = *occlusion_from_inside_target; + affected_occlusion.Intersect(affected_area_in_target); occlusion_from_inside_target->Subtract(affected_area_in_target); - for (; affected_occlusion_rects.has_rect(); affected_occlusion_rects.next()) { - gfx::Rect occlusion_rect = affected_occlusion_rects.rect(); + for (size_t i = 0; i < affected_occlusion.GetRegionComplexity(); ++i) { + gfx::Rect occlusion_rect = affected_occlusion.GetRect(i); // Shrink the rect by expanding the non-opaque pixels outside the rect. @@ -309,7 +315,7 @@ void OcclusionTracker<LayerType>::LeaveToRenderTarget( const typename LayerType::RenderSurfaceType* old_surface = old_target->render_surface(); - Region old_occlusion_from_inside_target_in_new_target = + SimpleEnclosedRegion old_occlusion_from_inside_target_in_new_target = TransformSurfaceOpaqueRegion<typename LayerType::RenderSurfaceType>( stack_[last_index].occlusion_from_inside_target, old_surface->is_clipped(), @@ -324,7 +330,7 @@ void OcclusionTracker<LayerType>::LeaveToRenderTarget( old_surface->replica_draw_transform())); } - Region old_occlusion_from_outside_target_in_new_target = + SimpleEnclosedRegion old_occlusion_from_outside_target_in_new_target = TransformSurfaceOpaqueRegion<typename LayerType::RenderSurfaceType>( stack_[last_index].occlusion_from_outside_target, false, @@ -400,8 +406,6 @@ void OcclusionTracker<LayerType>::MarkOccludedBehindLayer( const LayerType* layer) { DCHECK(!stack_.empty()); DCHECK_EQ(layer->render_target(), stack_.back().target); - if (stack_.empty()) - return; if (!LayerOpacityKnown(layer) || layer->draw_opacity() < 1) return; @@ -415,7 +419,7 @@ void OcclusionTracker<LayerType>::MarkOccludedBehindLayer( if (!LayerTransformsToTargetKnown(layer)) return; - Region opaque_contents = layer->VisibleContentOpaqueRegion(); + SimpleEnclosedRegion opaque_contents = layer->VisibleContentOpaqueRegion(); if (opaque_contents.IsEmpty()) return; @@ -434,17 +438,10 @@ void OcclusionTracker<LayerType>::MarkOccludedBehindLayer( layer->render_target()->render_surface()->content_rect()); } - for (Region::Iterator opaque_content_rects(opaque_contents); - opaque_content_rects.has_rect(); - opaque_content_rects.next()) { - bool clipped; - gfx::QuadF transformed_quad = MathUtil::MapQuad( - layer->draw_transform(), - gfx::QuadF(opaque_content_rects.rect()), - &clipped); + for (size_t i = 0; i < opaque_contents.GetRegionComplexity(); ++i) { gfx::Rect transformed_rect = - gfx::ToEnclosedRect(transformed_quad.BoundingBox()); - DCHECK(!clipped); // We only map if the transform preserves axis alignment. + MathUtil::MapEnclosedRectWith2dAxisAlignedTransform( + layer->draw_transform(), opaque_contents.GetRect(i)); transformed_rect.Intersect(clip_rect_in_target); if (transformed_rect.width() < minimum_tracking_size_.width() && transformed_rect.height() < minimum_tracking_size_.height()) @@ -455,6 +452,7 @@ void OcclusionTracker<LayerType>::MarkOccludedBehindLayer( continue; // Save the occluding area in screen space for debug visualization. + bool clipped; gfx::QuadF screen_space_quad = MathUtil::MapQuad( layer->render_target()->render_surface()->screen_space_transform(), gfx::QuadF(transformed_rect), &clipped); @@ -468,16 +466,15 @@ void OcclusionTracker<LayerType>::MarkOccludedBehindLayer( if (!non_occluding_screen_space_rects_) return; - Region non_opaque_contents = - SubtractRegions(gfx::Rect(layer->content_bounds()), opaque_contents); + Region non_opaque_contents(gfx::Rect(layer->content_bounds())); + non_opaque_contents.Subtract(opaque_contents); + for (Region::Iterator non_opaque_content_rects(non_opaque_contents); non_opaque_content_rects.has_rect(); non_opaque_content_rects.next()) { - // We've already checked for clipping in the MapQuad call above, these calls - // should not clip anything further. - gfx::Rect transformed_rect = gfx::ToEnclosedRect( - MathUtil::MapClippedRect(layer->draw_transform(), - gfx::RectF(non_opaque_content_rects.rect()))); + gfx::Rect transformed_rect = + MathUtil::MapEnclosedRectWith2dAxisAlignedTransform( + layer->draw_transform(), non_opaque_content_rects.rect()); transformed_rect.Intersect(clip_rect_in_target); if (transformed_rect.IsEmpty()) continue; @@ -496,87 +493,6 @@ void OcclusionTracker<LayerType>::MarkOccludedBehindLayer( } template <typename LayerType> -bool OcclusionTracker<LayerType>::Occluded( - const LayerType* render_target, - const gfx::Rect& content_rect, - const gfx::Transform& draw_transform) const { - DCHECK(!stack_.empty()); - if (stack_.empty()) - return false; - if (content_rect.IsEmpty()) - return true; - - // For tests with no render target. - if (!render_target) - return false; - - DCHECK_EQ(render_target->render_target(), render_target); - DCHECK(render_target->render_surface()); - DCHECK_EQ(render_target, stack_.back().target); - - if (stack_.back().occlusion_from_inside_target.IsEmpty() && - stack_.back().occlusion_from_outside_target.IsEmpty()) { - return false; - } - - gfx::Transform inverse_draw_transform(gfx::Transform::kSkipInitialization); - if (!draw_transform.GetInverse(&inverse_draw_transform)) - return false; - - // Take the ToEnclosingRect at each step, as we want to contain any unoccluded - // partial pixels in the resulting Rect. - Region unoccluded_region_in_target_surface = - MathUtil::MapEnclosingClippedRect(draw_transform, content_rect); - unoccluded_region_in_target_surface.Subtract( - stack_.back().occlusion_from_inside_target); - gfx::RectF unoccluded_rect_in_target_surface_without_outside_occlusion = - unoccluded_region_in_target_surface.bounds(); - unoccluded_region_in_target_surface.Subtract( - stack_.back().occlusion_from_outside_target); - - gfx::RectF unoccluded_rect_in_target_surface = - unoccluded_region_in_target_surface.bounds(); - - return unoccluded_rect_in_target_surface.IsEmpty(); -} - -template <typename LayerType> -gfx::Rect OcclusionTracker<LayerType>::UnoccludedContentRect( - const gfx::Rect& content_rect, - const gfx::Transform& draw_transform) const { - if (stack_.empty()) - return content_rect; - if (content_rect.IsEmpty()) - return content_rect; - - if (stack_.back().occlusion_from_inside_target.IsEmpty() && - stack_.back().occlusion_from_outside_target.IsEmpty()) { - return content_rect; - } - - gfx::Transform inverse_draw_transform(gfx::Transform::kSkipInitialization); - if (!draw_transform.GetInverse(&inverse_draw_transform)) - return content_rect; - - // Take the ToEnclosingRect at each step, as we want to contain any unoccluded - // partial pixels in the resulting Rect. - Region unoccluded_region_in_target_surface = - MathUtil::MapEnclosingClippedRect(draw_transform, content_rect); - unoccluded_region_in_target_surface.Subtract( - stack_.back().occlusion_from_inside_target); - unoccluded_region_in_target_surface.Subtract( - stack_.back().occlusion_from_outside_target); - - gfx::Rect unoccluded_rect_in_target_surface = - unoccluded_region_in_target_surface.bounds(); - gfx::Rect unoccluded_rect = MathUtil::ProjectEnclosingClippedRect( - inverse_draw_transform, unoccluded_rect_in_target_surface); - unoccluded_rect.Intersect(content_rect); - - return unoccluded_rect; -} - -template <typename LayerType> gfx::Rect OcclusionTracker<LayerType>::UnoccludedContributingSurfaceContentRect( const gfx::Rect& content_rect, const gfx::Transform& draw_transform) const { @@ -591,26 +507,31 @@ gfx::Rect OcclusionTracker<LayerType>::UnoccludedContributingSurfaceContentRect( return content_rect; const StackObject& second_last = stack_[stack_.size() - 2]; - if (second_last.occlusion_from_inside_target.IsEmpty() && second_last.occlusion_from_outside_target.IsEmpty()) return content_rect; gfx::Transform inverse_draw_transform(gfx::Transform::kSkipInitialization); - if (!draw_transform.GetInverse(&inverse_draw_transform)) - return content_rect; + bool ok = draw_transform.GetInverse(&inverse_draw_transform); + DCHECK(ok); // Take the ToEnclosingRect at each step, as we want to contain any unoccluded // partial pixels in the resulting Rect. - Region unoccluded_region_in_target_surface = + gfx::Rect unoccluded_rect_in_target_surface = MathUtil::MapEnclosingClippedRect(draw_transform, content_rect); - unoccluded_region_in_target_surface.Subtract( - second_last.occlusion_from_inside_target); - unoccluded_region_in_target_surface.Subtract( - second_last.occlusion_from_outside_target); + DCHECK_LE(second_last.occlusion_from_inside_target.GetRegionComplexity(), 1u); + DCHECK_LE(second_last.occlusion_from_outside_target.GetRegionComplexity(), + 1u); + // These subtract operations are more lossy than if we did both operations at + // once. + unoccluded_rect_in_target_surface.Subtract( + second_last.occlusion_from_inside_target.bounds()); + unoccluded_rect_in_target_surface.Subtract( + second_last.occlusion_from_outside_target.bounds()); + + if (unoccluded_rect_in_target_surface.IsEmpty()) + return gfx::Rect(); - gfx::Rect unoccluded_rect_in_target_surface = - unoccluded_region_in_target_surface.bounds(); gfx::Rect unoccluded_rect = MathUtil::ProjectEnclosingClippedRect( inverse_draw_transform, unoccluded_rect_in_target_surface); unoccluded_rect.Intersect(content_rect); @@ -618,6 +539,17 @@ gfx::Rect OcclusionTracker<LayerType>::UnoccludedContributingSurfaceContentRect( return unoccluded_rect; } +template <typename LayerType> +Region OcclusionTracker<LayerType>::ComputeVisibleRegionInScreen() const { + DCHECK(!stack_.back().target->parent()); + const SimpleEnclosedRegion& occluded = + stack_.back().occlusion_from_inside_target; + Region visible_region(screen_space_clip_rect_); + for (size_t i = 0; i < occluded.GetRegionComplexity(); ++i) + visible_region.Subtract(occluded.GetRect(i)); + return visible_region; +} + // Instantiate (and export) templates here for the linker. template class OcclusionTracker<Layer>; template class OcclusionTracker<LayerImpl>; diff --git a/chromium/cc/trees/occlusion_tracker.h b/chromium/cc/trees/occlusion_tracker.h index 78b992cd1c5..4d6555a91e7 100644 --- a/chromium/cc/trees/occlusion_tracker.h +++ b/chromium/cc/trees/occlusion_tracker.h @@ -9,12 +9,14 @@ #include "base/basictypes.h" #include "cc/base/cc_export.h" -#include "cc/base/region.h" +#include "cc/base/simple_enclosed_region.h" #include "cc/layers/layer_iterator.h" -#include "ui/gfx/rect.h" +#include "cc/trees/occlusion.h" +#include "ui/gfx/geometry/rect.h" namespace cc { class LayerImpl; +class Region; class RenderSurfaceImpl; class Layer; class RenderSurface; @@ -23,9 +25,9 @@ class RenderSurface; // front-to-back order. As each layer is visited, one of the methods in this // class is called to notify it about the current target surface. Then, // occlusion in the content space of the current layer may be queried, via -// methods such as Occluded() and UnoccludedContentRect(). If the current layer -// owns a RenderSurfaceImpl, then occlusion on that RenderSurfaceImpl may also -// be queried via surfaceOccluded() and surfaceUnoccludedContentRect(). Finally, +// Occlusion from GetCurrentOcclusionForLayer(). If the current layer owns a +// RenderSurfaceImpl, then occlusion on that RenderSurfaceImpl may also be +// queried via surfaceOccluded() and surfaceUnoccludedContentRect(). Finally, // once finished with the layer, occlusion behind the layer should be marked by // calling MarkOccludedBehindLayer(). template <typename LayerType> @@ -34,6 +36,11 @@ class CC_EXPORT OcclusionTracker { explicit OcclusionTracker(const gfx::Rect& screen_space_clip_rect); ~OcclusionTracker(); + // Return an occlusion that retains the current state of the tracker + // and can be used outside of a layer walk to check occlusion. + Occlusion GetCurrentOcclusionForLayer( + const gfx::Transform& draw_transform) const; + // Called at the beginning of each step in the LayerIterator's front-to-back // traversal. void EnterLayer(const LayerIteratorPosition<LayerType>& layer_iterator); @@ -41,21 +48,6 @@ class CC_EXPORT OcclusionTracker { // traversal. void LeaveLayer(const LayerIteratorPosition<LayerType>& layer_iterator); - // Returns true if the given rect in content space for a layer is fully - // occluded in either screen space or the layer's target surface. - // |render_target| is the contributing layer's render target, and - // |draw_transform| and |impl_draw_transform_is_unknown| are relative to that. - bool Occluded(const LayerType* render_target, - const gfx::Rect& content_rect, - const gfx::Transform& draw_transform) const; - - // Gives an unoccluded sub-rect of |content_rect| in the content space of a - // layer. Used when considering occlusion for a layer that paints/draws - // something. |render_target| is the contributing layer's render target, and - // |draw_transform| and |impl_draw_transform_is_unknown| are relative to that. - gfx::Rect UnoccludedContentRect(const gfx::Rect& content_rect, - const gfx::Transform& draw_transform) const; - // Gives an unoccluded sub-rect of |content_rect| in the content space of the // render_target owned by the layer. Used when considering occlusion for a // contributing surface that is rendering into another target. @@ -64,11 +56,7 @@ class CC_EXPORT OcclusionTracker { const gfx::Transform& draw_transform) const; // Gives the region of the screen that is not occluded by something opaque. - Region ComputeVisibleRegionInScreen() const { - DCHECK(!stack_.back().target->parent()); - return SubtractRegions(screen_space_clip_rect_, - stack_.back().occlusion_from_inside_target); - } + Region ComputeVisibleRegionInScreen() const; void set_minimum_tracking_size(const gfx::Size& size) { minimum_tracking_size_ = size; @@ -89,8 +77,8 @@ class CC_EXPORT OcclusionTracker { StackObject() : target(0) {} explicit StackObject(const LayerType* target) : target(target) {} const LayerType* target; - Region occlusion_from_outside_target; - Region occlusion_from_inside_target; + SimpleEnclosedRegion occlusion_from_outside_target; + SimpleEnclosedRegion occlusion_from_inside_target; }; // The stack holds occluded regions for subtrees in the diff --git a/chromium/cc/trees/occlusion_tracker_perftest.cc b/chromium/cc/trees/occlusion_tracker_perftest.cc index d9130746de7..7346f2594de 100644 --- a/chromium/cc/trees/occlusion_tracker_perftest.cc +++ b/chromium/cc/trees/occlusion_tracker_perftest.cc @@ -36,10 +36,14 @@ class OcclusionTrackerPerfTest : public testing::Test { void CreateHost() { LayerTreeSettings settings; shared_bitmap_manager_.reset(new TestSharedBitmapManager()); - host_impl_ = LayerTreeHostImpl::Create( - settings, &client_, &proxy_, &stats_, shared_bitmap_manager_.get(), 1); - host_impl_->InitializeRenderer( - FakeOutputSurface::Create3d().PassAs<OutputSurface>()); + host_impl_ = LayerTreeHostImpl::Create(settings, + &client_, + &proxy_, + &stats_, + shared_bitmap_manager_.get(), + NULL, + 1); + host_impl_->InitializeRenderer(FakeOutputSurface::Create3d()); scoped_ptr<LayerImpl> root_layer = LayerImpl::Create(active_tree(), 1); active_tree()->SetRootLayer(root_layer.Pass()); @@ -86,7 +90,7 @@ TEST_F(OcclusionTrackerPerfTest, UnoccludedContentRect_FullyOccluded) { opaque_layer->SetDrawsContent(true); opaque_layer->SetBounds(viewport_rect.size()); opaque_layer->SetContentBounds(viewport_rect.size()); - active_tree()->root_layer()->AddChild(opaque_layer.PassAs<LayerImpl>()); + active_tree()->root_layer()->AddChild(opaque_layer.Pass()); active_tree()->UpdateDrawProperties(); const LayerImplList& rsll = active_tree()->RenderSurfaceLayerList(); @@ -106,11 +110,13 @@ TEST_F(OcclusionTrackerPerfTest, UnoccludedContentRect_FullyOccluded) { transform_to_target.Translate(0, 96); do { + Occlusion occlusion = + tracker.GetCurrentOcclusionForLayer(transform_to_target); for (int x = 0; x < viewport_rect.width(); x += 256) { for (int y = 0; y < viewport_rect.height(); y += 256) { gfx::Rect query_content_rect(x, y, 256, 256); - gfx::Rect unoccluded = tracker.UnoccludedContentRect( - query_content_rect, transform_to_target); + gfx::Rect unoccluded = + occlusion.GetUnoccludedContentRect(query_content_rect); // Sanity test that we're not hitting early outs. bool expect_empty = query_content_rect.right() <= viewport_rect.width() && @@ -154,7 +160,7 @@ TEST_F(OcclusionTrackerPerfTest, UnoccludedContentRect_10OpaqueLayers) { opaque_layer->SetContentBounds( gfx::Size(viewport_rect.width() / 2, viewport_rect.height() / 2)); opaque_layer->SetPosition(gfx::Point(i, i)); - active_tree()->root_layer()->AddChild(opaque_layer.PassAs<LayerImpl>()); + active_tree()->root_layer()->AddChild(opaque_layer.Pass()); } active_tree()->UpdateDrawProperties(); @@ -181,11 +187,13 @@ TEST_F(OcclusionTrackerPerfTest, UnoccludedContentRect_10OpaqueLayers) { transform_to_target.Translate(0, 96); do { + Occlusion occlusion = + tracker.GetCurrentOcclusionForLayer(transform_to_target); for (int x = 0; x < viewport_rect.width(); x += 256) { for (int y = 0; y < viewport_rect.height(); y += 256) { gfx::Rect query_content_rect(x, y, 256, 256); - gfx::Rect unoccluded = tracker.UnoccludedContentRect( - query_content_rect, transform_to_target); + gfx::Rect unoccluded = + occlusion.GetUnoccludedContentRect(query_content_rect); } } diff --git a/chromium/cc/trees/occlusion_tracker_unittest.cc b/chromium/cc/trees/occlusion_tracker_unittest.cc index 1a6529bc557..75cd2438a7b 100644 --- a/chromium/cc/trees/occlusion_tracker_unittest.cc +++ b/chromium/cc/trees/occlusion_tracker_unittest.cc @@ -33,9 +33,11 @@ class TestContentLayer : public Layer { SetIsDrawable(true); } - virtual Region VisibleContentOpaqueRegion() const OVERRIDE { - if (override_opaque_contents_rect_) - return gfx::IntersectRects(opaque_contents_rect_, visible_content_rect()); + SimpleEnclosedRegion VisibleContentOpaqueRegion() const override { + if (override_opaque_contents_rect_) { + return SimpleEnclosedRegion( + gfx::IntersectRects(opaque_contents_rect_, visible_content_rect())); + } return Layer::VisibleContentOpaqueRegion(); } void SetOpaqueContentsRect(const gfx::Rect& opaque_contents_rect) { @@ -44,7 +46,7 @@ class TestContentLayer : public Layer { } private: - virtual ~TestContentLayer() {} + ~TestContentLayer() override {} bool override_opaque_contents_rect_; gfx::Rect opaque_contents_rect_; @@ -57,9 +59,11 @@ class TestContentLayerImpl : public LayerImpl { SetDrawsContent(true); } - virtual Region VisibleContentOpaqueRegion() const OVERRIDE { - if (override_opaque_contents_rect_) - return gfx::IntersectRects(opaque_contents_rect_, visible_content_rect()); + SimpleEnclosedRegion VisibleContentOpaqueRegion() const override { + if (override_opaque_contents_rect_) { + return SimpleEnclosedRegion( + gfx::IntersectRects(opaque_contents_rect_, visible_content_rect())); + } return LayerImpl::VisibleContentOpaqueRegion(); } void SetOpaqueContentsRect(const gfx::Rect& opaque_contents_rect) { @@ -81,27 +85,24 @@ class TestOcclusionTrackerWithClip : public TestOcclusionTracker<LayerType> { bool OccludedLayer(const LayerType* layer, const gfx::Rect& content_rect) const { DCHECK(layer->visible_content_rect().Contains(content_rect)); - return this->Occluded( - layer->render_target(), content_rect, layer->draw_transform()); + return this->GetCurrentOcclusionForLayer(layer->draw_transform()) + .IsOccluded(content_rect); } // Gives an unoccluded sub-rect of |content_rect| in the content space of the - // layer. Simple wrapper around UnoccludedContentRect. + // layer. Simple wrapper around GetUnoccludedContentRect. gfx::Rect UnoccludedLayerContentRect(const LayerType* layer, const gfx::Rect& content_rect) const { DCHECK(layer->visible_content_rect().Contains(content_rect)); - return this->UnoccludedContentRect(content_rect, layer->draw_transform()); + return this->GetCurrentOcclusionForLayer(layer->draw_transform()) + .GetUnoccludedContentRect(content_rect); } gfx::Rect UnoccludedSurfaceContentRect(const LayerType* layer, - bool for_replica, const gfx::Rect& content_rect) const { typename LayerType::RenderSurfaceType* surface = layer->render_surface(); - gfx::Transform draw_transform = for_replica - ? surface->replica_draw_transform() - : surface->draw_transform(); - return this->UnoccludedContributingSurfaceContentRect(content_rect, - draw_transform); + return this->UnoccludedContributingSurfaceContentRect( + content_rect, surface->draw_transform()); } }; @@ -120,19 +121,16 @@ struct OcclusionTrackerTestMainThreadTypes { return make_scoped_refptr(new ContentLayerType()); } - static LayerPtrType PassLayerPtr(ContentLayerPtrType* layer) { - LayerPtrType ref(*layer); - *layer = NULL; - return ref; - } - - static LayerPtrType PassLayerPtr(LayerPtrType* layer) { + template <typename T> + static LayerPtrType PassLayerPtr(T* layer) { LayerPtrType ref(*layer); *layer = NULL; return ref; } static void DestroyLayer(LayerPtrType* layer) { *layer = NULL; } + + static void RecursiveUpdateNumChildren(LayerType* layerType) {} }; struct OcclusionTrackerTestImplThreadTypes { @@ -153,15 +151,16 @@ struct OcclusionTrackerTestImplThreadTypes { } static int next_layer_impl_id; - static LayerPtrType PassLayerPtr(LayerPtrType* layer) { + template <typename T> + static LayerPtrType PassLayerPtr(T* layer) { return layer->Pass(); } - static LayerPtrType PassLayerPtr(ContentLayerPtrType* layer) { - return layer->PassAs<LayerType>(); - } - static void DestroyLayer(LayerPtrType* layer) { layer->reset(); } + + static void RecursiveUpdateNumChildren(LayerType* layer) { + FakeLayerTreeHostImpl::RecursiveUpdateNumChildren(layer); + } }; int OcclusionTrackerTestImplThreadTypes::next_layer_impl_id = 1; @@ -169,17 +168,13 @@ int OcclusionTrackerTestImplThreadTypes::next_layer_impl_id = 1; template <typename Types> class OcclusionTrackerTest : public testing::Test { protected: explicit OcclusionTrackerTest(bool opaque_layers) - : opaque_layers_(opaque_layers), host_(FakeLayerTreeHost::Create()) {} + : opaque_layers_(opaque_layers), + client_(FakeLayerTreeHostClient::DIRECT_3D), + host_(FakeLayerTreeHost::Create(&client_)) {} virtual void RunMyTest() = 0; - virtual void TearDown() { - Types::DestroyLayer(&root_); - render_surface_layer_list_.reset(); - render_surface_layer_list_impl_.clear(); - replica_layers_.clear(); - mask_layers_.clear(); - } + virtual void TearDown() { DestroyLayers(); } typename Types::HostType* GetHost(); @@ -281,6 +276,14 @@ template <typename Types> class OcclusionTrackerTest : public testing::Test { return layer; } + void DestroyLayers() { + Types::DestroyLayer(&root_); + render_surface_layer_list_ = nullptr; + render_surface_layer_list_impl_.clear(); + replica_layers_.clear(); + mask_layers_.clear(); + ResetLayerIterator(); + } void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {} @@ -304,6 +307,7 @@ template <typename Types> class OcclusionTrackerTest : public testing::Test { DCHECK(root == root_.get()); DCHECK(!root->render_surface()); + Types::RecursiveUpdateNumChildren(root); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( root, root->bounds(), &render_surface_layer_list_impl_); inputs.can_adjust_raster_scales = true; @@ -329,14 +333,14 @@ template <typename Types> class OcclusionTrackerTest : public testing::Test { void EnterLayer(typename Types::LayerType* layer, typename Types::OcclusionTrackerType* occlusion) { - ASSERT_EQ(layer, *layer_iterator_); + ASSERT_EQ(*layer_iterator_, layer); ASSERT_TRUE(layer_iterator_.represents_itself()); occlusion->EnterLayer(layer_iterator_); } void LeaveLayer(typename Types::LayerType* layer, typename Types::OcclusionTrackerType* occlusion) { - ASSERT_EQ(layer, *layer_iterator_); + ASSERT_EQ(*layer_iterator_, layer); ASSERT_TRUE(layer_iterator_.represents_itself()); occlusion->LeaveLayer(layer_iterator_); ++layer_iterator_; @@ -351,7 +355,7 @@ template <typename Types> class OcclusionTrackerTest : public testing::Test { void EnterContributingSurface( typename Types::LayerType* layer, typename Types::OcclusionTrackerType* occlusion) { - ASSERT_EQ(layer, *layer_iterator_); + ASSERT_EQ(*layer_iterator_, layer); ASSERT_TRUE(layer_iterator_.represents_target_render_surface()); occlusion->EnterLayer(layer_iterator_); occlusion->LeaveLayer(layer_iterator_); @@ -363,7 +367,7 @@ template <typename Types> class OcclusionTrackerTest : public testing::Test { void LeaveContributingSurface( typename Types::LayerType* layer, typename Types::OcclusionTrackerType* occlusion) { - ASSERT_EQ(layer, *layer_iterator_); + ASSERT_EQ(*layer_iterator_, layer); ASSERT_TRUE(layer_iterator_.represents_contributing_render_surface()); occlusion->LeaveLayer(layer_iterator_); ++layer_iterator_; @@ -431,6 +435,7 @@ template <typename Types> class OcclusionTrackerTest : public testing::Test { } bool opaque_layers_; + FakeLayerTreeHostClient client_; scoped_ptr<FakeLayerTreeHost> host_; // These hold ownership of the layers for the duration of the test. typename Types::LayerPtrType root_; @@ -536,94 +541,12 @@ class OcclusionTrackerTestIdentityTransforms occlusion.occlusion_from_outside_target().ToString()); EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(), occlusion.occlusion_from_inside_target().ToString()); - - EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 30, 70, 70))); - EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(29, 30, 70, 70))); - EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 29, 70, 70))); - EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(31, 30, 69, 70))); - EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 31, 70, 69))); - - EXPECT_TRUE(occlusion.UnoccludedLayerContentRect( - parent, gfx::Rect(30, 30, 70, 70)).IsEmpty()); - EXPECT_RECT_EQ(gfx::Rect(29, 30, 1, 70), - occlusion.UnoccludedLayerContentRect( - parent, gfx::Rect(29, 30, 70, 70))); - EXPECT_RECT_EQ(gfx::Rect(29, 29, 70, 70), - occlusion.UnoccludedLayerContentRect( - parent, gfx::Rect(29, 29, 70, 70))); - EXPECT_RECT_EQ(gfx::Rect(30, 29, 70, 1), - occlusion.UnoccludedLayerContentRect( - parent, gfx::Rect(30, 29, 70, 70))); - EXPECT_RECT_EQ(gfx::Rect(31, 29, 69, 1), - occlusion.UnoccludedLayerContentRect( - parent, gfx::Rect(31, 29, 69, 70))); - EXPECT_RECT_EQ(gfx::Rect(), - occlusion.UnoccludedLayerContentRect( - parent, gfx::Rect(31, 30, 69, 70))); - EXPECT_RECT_EQ(gfx::Rect(), - occlusion.UnoccludedLayerContentRect( - parent, gfx::Rect(31, 31, 69, 69))); - EXPECT_RECT_EQ(gfx::Rect(), - occlusion.UnoccludedLayerContentRect( - parent, gfx::Rect(30, 31, 70, 69))); - EXPECT_RECT_EQ(gfx::Rect(29, 31, 1, 69), - occlusion.UnoccludedLayerContentRect( - parent, gfx::Rect(29, 31, 70, 69))); } }; ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestIdentityTransforms); template <class Types> -class OcclusionTrackerTestQuadsMismatchLayer - : public OcclusionTrackerTest<Types> { - protected: - explicit OcclusionTrackerTestQuadsMismatchLayer(bool opaque_layers) - : OcclusionTrackerTest<Types>(opaque_layers) {} - void RunMyTest() { - gfx::Transform layer_transform; - layer_transform.Translate(10.0, 10.0); - - typename Types::ContentLayerType* parent = this->CreateRoot( - this->identity_matrix, gfx::Point(0, 0), gfx::Size(100, 100)); - typename Types::ContentLayerType* layer1 = this->CreateDrawingLayer( - parent, layer_transform, gfx::PointF(), gfx::Size(90, 90), true); - typename Types::ContentLayerType* layer2 = this->CreateDrawingLayer( - layer1, layer_transform, gfx::PointF(), gfx::Size(50, 50), true); - this->CalcDrawEtc(parent); - - TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( - gfx::Rect(0, 0, 1000, 1000)); - - this->VisitLayer(layer2, &occlusion); - this->EnterLayer(layer1, &occlusion); - - EXPECT_EQ(gfx::Rect().ToString(), - occlusion.occlusion_from_outside_target().ToString()); - EXPECT_EQ(gfx::Rect(20, 20, 50, 50).ToString(), - occlusion.occlusion_from_inside_target().ToString()); - - // This checks cases where the quads don't match their "containing" - // layers, e.g. in terms of transforms or clip rect. This is typical for - // DelegatedRendererLayer. - - gfx::Transform quad_transform; - quad_transform.Translate(30.0, 30.0); - - EXPECT_TRUE(occlusion.UnoccludedContentRect(gfx::Rect(0, 0, 10, 10), - quad_transform).IsEmpty()); - EXPECT_RECT_EQ(gfx::Rect(40, 40, 10, 10), - occlusion.UnoccludedContentRect(gfx::Rect(40, 40, 10, 10), - quad_transform)); - EXPECT_RECT_EQ(gfx::Rect(40, 30, 5, 10), - occlusion.UnoccludedContentRect(gfx::Rect(35, 30, 10, 10), - quad_transform)); - } -}; - -ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestQuadsMismatchLayer); - -template <class Types> class OcclusionTrackerTestRotatedChild : public OcclusionTrackerTest<Types> { protected: explicit OcclusionTrackerTestRotatedChild(bool opaque_layers) @@ -657,39 +580,6 @@ class OcclusionTrackerTestRotatedChild : public OcclusionTrackerTest<Types> { occlusion.occlusion_from_outside_target().ToString()); EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(), occlusion.occlusion_from_inside_target().ToString()); - - EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 30, 70, 70))); - EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(29, 30, 70, 70))); - EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 29, 70, 70))); - EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(31, 30, 69, 70))); - EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 31, 70, 69))); - - EXPECT_TRUE(occlusion.UnoccludedLayerContentRect( - parent, gfx::Rect(30, 30, 70, 70)).IsEmpty()); - EXPECT_RECT_EQ(gfx::Rect(29, 30, 1, 70), - occlusion.UnoccludedLayerContentRect( - parent, gfx::Rect(29, 30, 69, 70))); - EXPECT_RECT_EQ(gfx::Rect(29, 29, 70, 70), - occlusion.UnoccludedLayerContentRect( - parent, gfx::Rect(29, 29, 70, 70))); - EXPECT_RECT_EQ(gfx::Rect(30, 29, 70, 1), - occlusion.UnoccludedLayerContentRect( - parent, gfx::Rect(30, 29, 70, 70))); - EXPECT_RECT_EQ(gfx::Rect(31, 29, 69, 1), - occlusion.UnoccludedLayerContentRect( - parent, gfx::Rect(31, 29, 69, 70))); - EXPECT_RECT_EQ(gfx::Rect(), - occlusion.UnoccludedLayerContentRect( - parent, gfx::Rect(31, 30, 69, 70))); - EXPECT_RECT_EQ(gfx::Rect(), - occlusion.UnoccludedLayerContentRect( - parent, gfx::Rect(31, 31, 69, 69))); - EXPECT_RECT_EQ(gfx::Rect(), - occlusion.UnoccludedLayerContentRect( - parent, gfx::Rect(30, 31, 70, 69))); - EXPECT_RECT_EQ(gfx::Rect(29, 31, 1, 69), - occlusion.UnoccludedLayerContentRect( - parent, gfx::Rect(29, 31, 70, 69))); } }; @@ -727,36 +617,6 @@ class OcclusionTrackerTestTranslatedChild : public OcclusionTrackerTest<Types> { occlusion.occlusion_from_outside_target().ToString()); EXPECT_EQ(gfx::Rect(50, 50, 50, 50).ToString(), occlusion.occlusion_from_inside_target().ToString()); - - EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(50, 50, 50, 50))); - EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(49, 50, 50, 50))); - EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(50, 49, 50, 50))); - EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(51, 50, 49, 50))); - EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(50, 51, 50, 49))); - - EXPECT_TRUE(occlusion.UnoccludedLayerContentRect( - parent, gfx::Rect(50, 50, 50, 50)).IsEmpty()); - EXPECT_RECT_EQ(gfx::Rect(49, 50, 1, 50), - occlusion.UnoccludedLayerContentRect( - parent, gfx::Rect(49, 50, 50, 50))); - EXPECT_RECT_EQ(gfx::Rect(49, 49, 50, 50), - occlusion.UnoccludedLayerContentRect( - parent, gfx::Rect(49, 49, 50, 50))); - EXPECT_RECT_EQ(gfx::Rect(50, 49, 50, 1), - occlusion.UnoccludedLayerContentRect( - parent, gfx::Rect(50, 49, 50, 50))); - EXPECT_RECT_EQ(gfx::Rect(51, 49, 49, 1), - occlusion.UnoccludedLayerContentRect( - parent, gfx::Rect(51, 49, 49, 50))); - EXPECT_TRUE(occlusion.UnoccludedLayerContentRect( - parent, gfx::Rect(51, 50, 49, 50)).IsEmpty()); - EXPECT_TRUE(occlusion.UnoccludedLayerContentRect( - parent, gfx::Rect(51, 51, 49, 49)).IsEmpty()); - EXPECT_TRUE(occlusion.UnoccludedLayerContentRect( - parent, gfx::Rect(50, 51, 50, 49)).IsEmpty()); - EXPECT_RECT_EQ(gfx::Rect(49, 51, 1, 49), - occlusion.UnoccludedLayerContentRect( - parent, gfx::Rect(49, 51, 50, 49))); } }; @@ -807,12 +667,6 @@ class OcclusionTrackerTestChildInRotatedChild EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(), occlusion.occlusion_from_inside_target().ToString()); - EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 40, 70, 60))); - EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(29, 40, 70, 60))); - EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 39, 70, 60))); - EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(31, 40, 69, 60))); - EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 41, 70, 59))); - /* Justification for the above occlusion from |layer|: 100 +---------------------+ @@ -904,18 +758,6 @@ class OcclusionTrackerTestScaledRenderSurface occlusion.occlusion_from_outside_target().ToString()); EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusion_from_inside_target().ToString()); - - EXPECT_RECT_EQ( - gfx::Rect(0, 0, 25, 25), - occlusion.UnoccludedLayerContentRect(layer2, gfx::Rect(0, 0, 25, 25))); - EXPECT_RECT_EQ(gfx::Rect(10, 25, 15, 25), - occlusion.UnoccludedLayerContentRect( - layer2, gfx::Rect(10, 25, 25, 25))); - EXPECT_RECT_EQ(gfx::Rect(25, 10, 25, 15), - occlusion.UnoccludedLayerContentRect( - layer2, gfx::Rect(25, 10, 25, 25))); - EXPECT_TRUE(occlusion.UnoccludedLayerContentRect( - layer2, gfx::Rect(25, 25, 25, 25)).IsEmpty()); } }; @@ -928,171 +770,60 @@ class OcclusionTrackerTestVisitTargetTwoTimes explicit OcclusionTrackerTestVisitTargetTwoTimes(bool opaque_layers) : OcclusionTrackerTest<Types>(opaque_layers) {} void RunMyTest() { - gfx::Transform child_transform; - child_transform.Translate(250.0, 250.0); - child_transform.Rotate(90.0); - child_transform.Translate(-250.0, -250.0); - typename Types::ContentLayerType* root = this->CreateRoot( this->identity_matrix, gfx::PointF(), gfx::Size(200, 200)); - typename Types::ContentLayerType* parent = this->CreateDrawingLayer( - root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true); - parent->SetMasksToBounds(true); - typename Types::LayerType* child = this->CreateSurface( - parent, child_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500)); - child->SetMasksToBounds(true); - typename Types::ContentLayerType* layer = - this->CreateDrawingLayer(child, + typename Types::LayerType* surface = this->CreateSurface( + root, this->identity_matrix, gfx::PointF(30.f, 30.f), gfx::Size()); + typename Types::ContentLayerType* surface_child = + this->CreateDrawingLayer(surface, this->identity_matrix, gfx::PointF(10.f, 10.f), - gfx::Size(500, 500), + gfx::Size(50, 50), true); - // |child2| makes |parent|'s surface get considered by OcclusionTracker - // first, instead of |child|'s. This exercises different code in - // LeaveToRenderTarget, as the target surface has already been seen. - typename Types::ContentLayerType* child2 = - this->CreateDrawingLayer(parent, + // |top_layer| makes |root|'s surface get considered by OcclusionTracker + // first, instead of |surface|'s. This exercises different code in + // LeaveToRenderTarget, as the target surface has already been seen when + // leaving |surface| later. + typename Types::ContentLayerType* top_layer = + this->CreateDrawingLayer(root, this->identity_matrix, - gfx::PointF(30.f, 30.f), - gfx::Size(60, 20), + gfx::PointF(40.f, 90.f), + gfx::Size(50, 20), true); this->CalcDrawEtc(root); TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( gfx::Rect(0, 0, 1000, 1000)); - this->VisitLayer(child2, &occlusion); + this->VisitLayer(top_layer, &occlusion); EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusion_from_outside_target().ToString()); - EXPECT_EQ(gfx::Rect(30, 30, 60, 20).ToString(), + EXPECT_EQ(gfx::Rect(40, 90, 50, 20).ToString(), occlusion.occlusion_from_inside_target().ToString()); - this->VisitLayer(layer, &occlusion); + this->VisitLayer(surface_child, &occlusion); - EXPECT_EQ(gfx::Rect(0, 440, 20, 60).ToString(), + EXPECT_EQ(gfx::Rect(10, 60, 50, 20).ToString(), occlusion.occlusion_from_outside_target().ToString()); - EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(), + EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(), occlusion.occlusion_from_inside_target().ToString()); - this->EnterContributingSurface(child, &occlusion); + this->EnterContributingSurface(surface, &occlusion); - EXPECT_EQ(gfx::Rect(0, 440, 20, 60).ToString(), + EXPECT_EQ(gfx::Rect(10, 60, 50, 20).ToString(), occlusion.occlusion_from_outside_target().ToString()); - EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(), + EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(), occlusion.occlusion_from_inside_target().ToString()); - // Occlusion in |child2| should get merged with the |child| surface we are - // leaving now. - this->LeaveContributingSurface(child, &occlusion); - this->EnterLayer(parent, &occlusion); - - EXPECT_EQ(gfx::Rect().ToString(), - occlusion.occlusion_from_outside_target().ToString()); - EXPECT_EQ(UnionRegions(gfx::Rect(30, 30, 60, 10), gfx::Rect(30, 40, 70, 60)) - .ToString(), - occlusion.occlusion_from_inside_target().ToString()); - - EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 30, 70, 70))); - EXPECT_RECT_EQ(gfx::Rect(90, 30, 10, 10), - occlusion.UnoccludedLayerContentRect( - parent, gfx::Rect(30, 30, 70, 70))); - - EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 30, 60, 10))); - EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(29, 30, 60, 10))); - EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 29, 60, 10))); - EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(31, 30, 60, 10))); - EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 31, 60, 10))); - - EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 40, 70, 60))); - EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(29, 40, 70, 60))); - EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 39, 70, 60))); - - EXPECT_TRUE(occlusion.UnoccludedLayerContentRect( - parent, gfx::Rect(30, 30, 60, 10)).IsEmpty()); - EXPECT_RECT_EQ(gfx::Rect(29, 30, 1, 10), - occlusion.UnoccludedLayerContentRect( - parent, gfx::Rect(29, 30, 60, 10))); - EXPECT_RECT_EQ(gfx::Rect(30, 29, 60, 1), - occlusion.UnoccludedLayerContentRect( - parent, gfx::Rect(30, 29, 60, 10))); - EXPECT_RECT_EQ(gfx::Rect(90, 30, 1, 10), - occlusion.UnoccludedLayerContentRect( - parent, gfx::Rect(31, 30, 60, 10))); - EXPECT_TRUE(occlusion.UnoccludedLayerContentRect( - parent, gfx::Rect(30, 31, 60, 10)).IsEmpty()); - - EXPECT_TRUE(occlusion.UnoccludedLayerContentRect( - parent, gfx::Rect(30, 40, 70, 60)).IsEmpty()); - EXPECT_RECT_EQ(gfx::Rect(29, 40, 1, 60), - occlusion.UnoccludedLayerContentRect( - parent, gfx::Rect(29, 40, 70, 60))); - // This rect is mostly occluded by |child2|. - EXPECT_RECT_EQ(gfx::Rect(90, 39, 10, 1), - occlusion.UnoccludedLayerContentRect( - parent, gfx::Rect(30, 39, 70, 60))); - // This rect extends past top/right ends of |child2|. - EXPECT_RECT_EQ(gfx::Rect(30, 29, 70, 11), - occlusion.UnoccludedLayerContentRect( - parent, gfx::Rect(30, 29, 70, 70))); - // This rect extends past left/right ends of |child2|. - EXPECT_RECT_EQ(gfx::Rect(20, 39, 80, 60), - occlusion.UnoccludedLayerContentRect( - parent, gfx::Rect(20, 39, 80, 60))); - EXPECT_RECT_EQ(gfx::Rect(), - occlusion.UnoccludedLayerContentRect( - parent, gfx::Rect(31, 40, 69, 60))); - EXPECT_RECT_EQ(gfx::Rect(), - occlusion.UnoccludedLayerContentRect( - parent, gfx::Rect(30, 41, 70, 59))); + // Occlusion from |top_layer| already in the root target should get merged + // with the occlusion from the |surface| we are leaving now. + this->LeaveContributingSurface(surface, &occlusion); + this->EnterLayer(root, &occlusion); - /* Justification for the above occlusion from |layer|: - 100 - +---------------------+ - | | - | 30 | rotate(90) - | 30 + ------------+--------------------+ - 100 | | 10 | | | ==> - | |10+----------|----------------------+ - | + ------------+ | | | - | | | | | | - | | | | | | - +----|--|-------------+ | | - | | | | - | | | | - | | | |500 - | | | | - | | | | - | | | | - | | | | - +--|-------------------------------+ | - | | - +---------------------------------+ - 500 - - - +---------------------+ - | |30 Visible region of |layer|: ///// - | 30 60 | |child2|: \\\\\ - | 30 +------------+--------------------+ - | |\\\\\\\\\\\\| |10 | - | +--|\\\\\\\\\\\\|-----------------+ | - | | +------------+//| 420 | | - | | |///////////////|60 | | - | | |///////////////| | | - +--|--|---------------+ | | - 20|10| 70 | | - | | | | - | | | | - | | | | - | | | | - | | | | - | | |10| - | +------------------------------|--+ - | 490 | - +---------------------------------+ - 500 - */ + EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); + EXPECT_EQ(gfx::Rect(40, 40, 50, 70).ToString(), + occlusion.occlusion_from_inside_target().ToString()); } }; @@ -1145,11 +876,6 @@ class OcclusionTrackerTestSurfaceRotatedOffAxis occlusion.occlusion_from_outside_target().ToString()); EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusion_from_inside_target().ToString()); - - EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(75, 55, 1, 1))); - EXPECT_RECT_EQ( - gfx::Rect(75, 55, 1, 1), - occlusion.UnoccludedLayerContentRect(parent, gfx::Rect(75, 55, 1, 1))); } }; @@ -1206,23 +932,6 @@ class OcclusionTrackerTestSurfaceWithTwoOpaqueChildren EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(), occlusion.occlusion_from_inside_target().ToString()); - EXPECT_TRUE(occlusion.OccludedLayer(child, gfx::Rect(10, 430, 60, 70))); - EXPECT_FALSE(occlusion.OccludedLayer(child, gfx::Rect(9, 430, 60, 70))); - EXPECT_TRUE(occlusion.OccludedLayer(child, gfx::Rect(11, 430, 59, 70))); - EXPECT_TRUE(occlusion.OccludedLayer(child, gfx::Rect(10, 431, 60, 69))); - - EXPECT_TRUE(occlusion.UnoccludedLayerContentRect( - child, gfx::Rect(10, 430, 60, 70)).IsEmpty()); - EXPECT_RECT_EQ( - gfx::Rect(9, 430, 1, 70), - occlusion.UnoccludedLayerContentRect(child, gfx::Rect(9, 430, 60, 70))); - EXPECT_RECT_EQ(gfx::Rect(), - occlusion.UnoccludedLayerContentRect( - child, gfx::Rect(11, 430, 59, 70))); - EXPECT_RECT_EQ(gfx::Rect(), - occlusion.UnoccludedLayerContentRect( - child, gfx::Rect(10, 431, 60, 69))); - this->LeaveContributingSurface(child, &occlusion); this->EnterLayer(parent, &occlusion); @@ -1231,25 +940,6 @@ class OcclusionTrackerTestSurfaceWithTwoOpaqueChildren EXPECT_EQ(gfx::Rect(30, 40, 70, 60).ToString(), occlusion.occlusion_from_inside_target().ToString()); - EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 40, 70, 60))); - EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(29, 40, 70, 60))); - EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 39, 70, 60))); - - EXPECT_TRUE(occlusion.UnoccludedLayerContentRect( - parent, gfx::Rect(30, 40, 70, 60)).IsEmpty()); - EXPECT_RECT_EQ(gfx::Rect(29, 40, 1, 60), - occlusion.UnoccludedLayerContentRect( - parent, gfx::Rect(29, 40, 70, 60))); - EXPECT_RECT_EQ(gfx::Rect(30, 39, 70, 1), - occlusion.UnoccludedLayerContentRect( - parent, gfx::Rect(30, 39, 70, 60))); - EXPECT_RECT_EQ(gfx::Rect(), - occlusion.UnoccludedLayerContentRect( - parent, gfx::Rect(31, 40, 69, 60))); - EXPECT_RECT_EQ(gfx::Rect(), - occlusion.UnoccludedLayerContentRect( - parent, gfx::Rect(30, 41, 70, 59))); - /* Justification for the above occlusion from |layer1| and |layer2|: +---------------------+ @@ -1286,29 +976,20 @@ class OcclusionTrackerTestOverlappingSurfaceSiblings explicit OcclusionTrackerTestOverlappingSurfaceSiblings(bool opaque_layers) : OcclusionTrackerTest<Types>(opaque_layers) {} void RunMyTest() { - gfx::Transform child_transform; - child_transform.Translate(250.0, 250.0); - child_transform.Rotate(90.0); - child_transform.Translate(-250.0, -250.0); - typename Types::ContentLayerType* parent = this->CreateRoot( this->identity_matrix, gfx::PointF(), gfx::Size(100, 100)); parent->SetMasksToBounds(true); typename Types::LayerType* child1 = this->CreateSurface( - parent, child_transform, gfx::PointF(30.f, 30.f), gfx::Size(10, 10)); + parent, this->identity_matrix, gfx::PointF(10.f, 0.f), gfx::Size()); typename Types::LayerType* child2 = this->CreateSurface( - parent, child_transform, gfx::PointF(20.f, 40.f), gfx::Size(10, 10)); - typename Types::ContentLayerType* layer1 = - this->CreateDrawingLayer(child1, - this->identity_matrix, - gfx::PointF(-10.f, -10.f), - gfx::Size(510, 510), - true); + parent, this->identity_matrix, gfx::PointF(30.f, 0.f), gfx::Size()); + typename Types::ContentLayerType* layer1 = this->CreateDrawingLayer( + child1, this->identity_matrix, gfx::PointF(), gfx::Size(40, 50), true); typename Types::ContentLayerType* layer2 = this->CreateDrawingLayer(child2, this->identity_matrix, - gfx::PointF(-10.f, -10.f), - gfx::Size(510, 510), + gfx::PointF(10.f, 0.f), + gfx::Size(40, 50), true); this->CalcDrawEtc(parent); @@ -1318,72 +999,30 @@ class OcclusionTrackerTestOverlappingSurfaceSiblings this->VisitLayer(layer2, &occlusion); this->EnterContributingSurface(child2, &occlusion); + // layer2's occlusion. EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusion_from_outside_target().ToString()); - EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(), + EXPECT_EQ(gfx::Rect(10, 0, 40, 50).ToString(), occlusion.occlusion_from_inside_target().ToString()); - // There is nothing above child2's surface in the z-order. - EXPECT_RECT_EQ(gfx::Rect(-10, 420, 70, 80), - occlusion.UnoccludedSurfaceContentRect( - child2, false, gfx::Rect(-10, 420, 70, 80))); - this->LeaveContributingSurface(child2, &occlusion); this->VisitLayer(layer1, &occlusion); this->EnterContributingSurface(child1, &occlusion); - EXPECT_EQ(gfx::Rect(0, 430, 70, 80).ToString(), + // layer2's occlusion in the target space of layer1. + EXPECT_EQ(gfx::Rect(30, 0, 40, 50).ToString(), occlusion.occlusion_from_outside_target().ToString()); - EXPECT_EQ(gfx::Rect(-10, 430, 80, 70).ToString(), + // layer1's occlusion. + EXPECT_EQ(gfx::Rect(0, 0, 40, 50).ToString(), occlusion.occlusion_from_inside_target().ToString()); - // child2's contents will occlude child1 below it. - EXPECT_RECT_EQ(gfx::Rect(-10, 430, 10, 70), - occlusion.UnoccludedSurfaceContentRect( - child1, false, gfx::Rect(-10, 430, 80, 70))); - this->LeaveContributingSurface(child1, &occlusion); this->EnterLayer(parent, &occlusion); - EXPECT_EQ(gfx::Rect().ToString(), - occlusion.occlusion_from_outside_target().ToString()); - EXPECT_EQ(UnionRegions(gfx::Rect(30, 20, 70, 10), gfx::Rect(20, 30, 80, 70)) - .ToString(), + // The occlusion from from layer1 and layer2 is merged. + EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); + EXPECT_EQ(gfx::Rect(10, 0, 70, 50).ToString(), occlusion.occlusion_from_inside_target().ToString()); - - EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(20, 20, 80, 80))); - - EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(30, 20, 70, 80))); - EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(29, 20, 70, 80))); - EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(30, 19, 70, 80))); - - EXPECT_TRUE(occlusion.OccludedLayer(parent, gfx::Rect(20, 30, 80, 70))); - EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(19, 30, 80, 70))); - EXPECT_FALSE(occlusion.OccludedLayer(parent, gfx::Rect(20, 29, 80, 70))); - - /* Justification for the above occlusion: - 100 - +---------------------+ - | 20 | layer1 - | 30+ ---------------------------------+ - 100 | 30| | layer2 | - |20+----------------------------------+ | - | | | | | | - | | | | | | - | | | | | | - +--|-|----------------+ | | - | | | | 510 - | | | | - | | | | - | | | | - | | | | - | | | | - | | | | - | +--------------------------------|-+ - | | - +----------------------------------+ - 510 - */ } }; @@ -1446,10 +1085,10 @@ class OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms this->LeaveLayer(child2, &occlusion); this->EnterContributingSurface(child2, &occlusion); - // There is nothing above child2's surface in the z-order. - EXPECT_RECT_EQ(gfx::Rect(-10, 420, 70, 80), - occlusion.UnoccludedSurfaceContentRect( - child2, false, gfx::Rect(-10, 420, 70, 80))); + EXPECT_EQ(gfx::Rect().ToString(), + occlusion.occlusion_from_outside_target().ToString()); + EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(), + occlusion.occlusion_from_inside_target().ToString()); this->LeaveContributingSurface(child2, &occlusion); this->VisitLayer(layer1, &occlusion); @@ -1460,14 +1099,6 @@ class OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms EXPECT_EQ(gfx::Rect(420, -20, 80, 90).ToString(), occlusion.occlusion_from_inside_target().ToString()); - // child2's contents will occlude child1 below it. - EXPECT_EQ(gfx::Rect(20, 30, 80, 70).ToString(), - occlusion.occlusion_on_contributing_surface_from_inside_target() - .ToString()); - EXPECT_EQ(gfx::Rect().ToString(), - occlusion.occlusion_on_contributing_surface_from_outside_target() - .ToString()); - this->LeaveContributingSurface(child1, &occlusion); this->EnterLayer(parent, &occlusion); @@ -1613,14 +1244,10 @@ class OcclusionTrackerTestReplicaDoesOcclude void RunMyTest() { typename Types::ContentLayerType* parent = this->CreateRoot( this->identity_matrix, gfx::PointF(), gfx::Size(100, 200)); - typename Types::LayerType* surface = - this->CreateDrawingSurface(parent, - this->identity_matrix, - gfx::PointF(0.f, 100.f), - gfx::Size(50, 50), - true); + typename Types::LayerType* surface = this->CreateDrawingSurface( + parent, this->identity_matrix, gfx::PointF(), gfx::Size(50, 50), true); this->CreateReplicaLayer( - surface, this->identity_matrix, gfx::PointF(50.f, 50.f), gfx::Size()); + surface, this->identity_matrix, gfx::PointF(0.f, 50.f), gfx::Size()); this->CalcDrawEtc(parent); TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( @@ -1635,10 +1262,8 @@ class OcclusionTrackerTestReplicaDoesOcclude this->EnterLayer(parent, &occlusion); // The surface and replica should both be occluding the parent. - EXPECT_EQ( - UnionRegions(gfx::Rect(0, 100, 50, 50), - gfx::Rect(50, 150, 50, 50)).ToString(), - occlusion.occlusion_from_inside_target().ToString()); + EXPECT_EQ(gfx::Rect(50, 100).ToString(), + occlusion.occlusion_from_inside_target().ToString()); } }; @@ -1661,7 +1286,7 @@ class OcclusionTrackerTestReplicaWithClipping gfx::Size(50, 50), true); this->CreateReplicaLayer( - surface, this->identity_matrix, gfx::PointF(50.f, 50.f), gfx::Size()); + surface, this->identity_matrix, gfx::PointF(0.f, 50.f), gfx::Size()); this->CalcDrawEtc(parent); TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( @@ -1669,17 +1294,19 @@ class OcclusionTrackerTestReplicaWithClipping this->VisitLayer(surface, &occlusion); + // The surface layer's occlusion in its own space. EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(), occlusion.occlusion_from_inside_target().ToString()); + EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); this->VisitContributingSurface(surface, &occlusion); this->EnterLayer(parent, &occlusion); - // The surface and replica should both be occluding the parent. - EXPECT_EQ( - UnionRegions(gfx::Rect(0, 100, 50, 50), - gfx::Rect(50, 150, 50, 20)).ToString(), - occlusion.occlusion_from_inside_target().ToString()); + // The surface and replica should both be occluding the parent, the + // replica's occlusion is clipped by the parent. + EXPECT_EQ(gfx::Rect(0, 100, 50, 70).ToString(), + occlusion.occlusion_from_inside_target().ToString()); + EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); } }; @@ -1745,16 +1372,15 @@ class OcclusionTrackerTestOpaqueContentsRegionEmpty gfx::Rect(0, 0, 1000, 1000)); this->EnterLayer(layer, &occlusion); - EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 100))); - EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(100, 0, 100, 100))); - EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 100, 100, 100))); - EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(100, 100, 100, 100))); + EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); + EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty()); this->LeaveLayer(layer, &occlusion); this->VisitContributingSurface(layer, &occlusion); this->EnterLayer(parent, &occlusion); EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); + EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty()); } }; @@ -1787,13 +1413,6 @@ class OcclusionTrackerTestOpaqueContentsRegionNonEmpty EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(), occlusion.occlusion_from_inside_target().ToString()); - - EXPECT_FALSE( - occlusion.OccludedLayer(parent, gfx::Rect(0, 100, 100, 100))); - EXPECT_TRUE( - occlusion.OccludedLayer(parent, gfx::Rect(100, 100, 100, 100))); - EXPECT_FALSE( - occlusion.OccludedLayer(parent, gfx::Rect(200, 200, 100, 100))); } { TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( @@ -1806,13 +1425,6 @@ class OcclusionTrackerTestOpaqueContentsRegionNonEmpty EXPECT_EQ(gfx::Rect(120, 120, 180, 180).ToString(), occlusion.occlusion_from_inside_target().ToString()); - - EXPECT_FALSE( - occlusion.OccludedLayer(parent, gfx::Rect(0, 100, 100, 100))); - EXPECT_FALSE( - occlusion.OccludedLayer(parent, gfx::Rect(100, 100, 100, 100))); - EXPECT_TRUE( - occlusion.OccludedLayer(parent, gfx::Rect(200, 200, 100, 100))); } { TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( @@ -1825,13 +1437,6 @@ class OcclusionTrackerTestOpaqueContentsRegionNonEmpty EXPECT_EQ(gfx::Rect(250, 250, 50, 50).ToString(), occlusion.occlusion_from_inside_target().ToString()); - - EXPECT_FALSE( - occlusion.OccludedLayer(parent, gfx::Rect(0, 100, 100, 100))); - EXPECT_FALSE( - occlusion.OccludedLayer(parent, gfx::Rect(100, 100, 100, 100))); - EXPECT_FALSE( - occlusion.OccludedLayer(parent, gfx::Rect(200, 200, 100, 100))); } } }; @@ -1839,41 +1444,6 @@ class OcclusionTrackerTestOpaqueContentsRegionNonEmpty MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTestOpaqueContentsRegionNonEmpty); template <class Types> -class OcclusionTrackerTest3dTransform : public OcclusionTrackerTest<Types> { - protected: - explicit OcclusionTrackerTest3dTransform(bool opaque_layers) - : OcclusionTrackerTest<Types>(opaque_layers) {} - void RunMyTest() { - gfx::Transform transform; - transform.RotateAboutYAxis(30.0); - - typename Types::ContentLayerType* parent = this->CreateRoot( - this->identity_matrix, gfx::PointF(), gfx::Size(300, 300)); - typename Types::LayerType* container = this->CreateLayer( - parent, this->identity_matrix, gfx::PointF(), gfx::Size(300, 300)); - typename Types::ContentLayerType* layer = - this->CreateDrawingLayer(container, - transform, - gfx::PointF(100.f, 100.f), - gfx::Size(200, 200), - true); - this->CalcDrawEtc(parent); - - TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( - gfx::Rect(0, 0, 1000, 1000)); - this->EnterLayer(layer, &occlusion); - - // The layer is rotated in 3d but without preserving 3d, so it only gets - // resized. - EXPECT_RECT_EQ( - gfx::Rect(0, 0, 200, 200), - occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(0, 0, 200, 200))); - } -}; - -MAIN_AND_IMPL_THREAD_TEST(OcclusionTrackerTest3dTransform); - -template <class Types> class OcclusionTrackerTestUnsorted3dLayers : public OcclusionTrackerTest<Types> { protected: @@ -1926,99 +1496,6 @@ class OcclusionTrackerTestUnsorted3dLayers MAIN_THREAD_TEST(OcclusionTrackerTestUnsorted3dLayers); template <class Types> -class OcclusionTrackerTestPerspectiveTransform - : public OcclusionTrackerTest<Types> { - protected: - explicit OcclusionTrackerTestPerspectiveTransform(bool opaque_layers) - : OcclusionTrackerTest<Types>(opaque_layers) {} - void RunMyTest() { - gfx::Transform transform; - transform.Translate(150.0, 150.0); - transform.ApplyPerspectiveDepth(400.0); - transform.RotateAboutXAxis(-30.0); - transform.Translate(-150.0, -150.0); - - typename Types::ContentLayerType* parent = this->CreateRoot( - this->identity_matrix, gfx::PointF(), gfx::Size(300, 300)); - typename Types::LayerType* container = this->CreateLayer( - parent, this->identity_matrix, gfx::PointF(), gfx::Size(300, 300)); - typename Types::ContentLayerType* layer = - this->CreateDrawingLayer(container, - transform, - gfx::PointF(100.f, 100.f), - gfx::Size(200, 200), - true); - container->SetShouldFlattenTransform(false); - container->Set3dSortingContextId(1); - layer->Set3dSortingContextId(1); - layer->SetShouldFlattenTransform(false); - - this->CalcDrawEtc(parent); - - TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( - gfx::Rect(0, 0, 1000, 1000)); - this->EnterLayer(layer, &occlusion); - - EXPECT_RECT_EQ( - gfx::Rect(0, 0, 200, 200), - occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(0, 0, 200, 200))); - } -}; - -// This test requires accumulating occlusion of 3d layers, which are skipped by -// the occlusion tracker on the main thread. So this test should run on the impl -// thread. -IMPL_THREAD_TEST(OcclusionTrackerTestPerspectiveTransform); -template <class Types> -class OcclusionTrackerTestPerspectiveTransformBehindCamera - : public OcclusionTrackerTest<Types> { - protected: - explicit OcclusionTrackerTestPerspectiveTransformBehindCamera( - bool opaque_layers) - : OcclusionTrackerTest<Types>(opaque_layers) {} - void RunMyTest() { - // This test is based on the platform/chromium/compositing/3d-corners.html - // layout test. - gfx::Transform transform; - transform.Translate(250.0, 50.0); - transform.ApplyPerspectiveDepth(10.0); - transform.Translate(-250.0, -50.0); - transform.Translate(250.0, 50.0); - transform.RotateAboutXAxis(-167.0); - transform.Translate(-250.0, -50.0); - - typename Types::ContentLayerType* parent = this->CreateRoot( - this->identity_matrix, gfx::PointF(), gfx::Size(500, 100)); - typename Types::LayerType* container = this->CreateLayer( - parent, this->identity_matrix, gfx::PointF(), gfx::Size(500, 500)); - typename Types::ContentLayerType* layer = this->CreateDrawingLayer( - container, transform, gfx::PointF(), gfx::Size(500, 500), true); - container->SetShouldFlattenTransform(false); - container->Set3dSortingContextId(1); - layer->SetShouldFlattenTransform(false); - layer->Set3dSortingContextId(1); - this->CalcDrawEtc(parent); - - TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( - gfx::Rect(0, 0, 1000, 1000)); - this->EnterLayer(layer, &occlusion); - - // The bottom 11 pixel rows of this layer remain visible inside the - // container, after translation to the target surface. When translated back, - // this will include many more pixels but must include at least the bottom - // 11 rows. - EXPECT_TRUE(occlusion.UnoccludedLayerContentRect( - layer, gfx::Rect(0, 26, 500, 474)). - Contains(gfx::Rect(0, 489, 500, 11))); - } -}; - -// This test requires accumulating occlusion of 3d layers, which are skipped by -// the occlusion tracker on the main thread. So this test should run on the impl -// thread. -IMPL_THREAD_TEST(OcclusionTrackerTestPerspectiveTransformBehindCamera); - -template <class Types> class OcclusionTrackerTestLayerBehindCameraDoesNotOcclude : public OcclusionTrackerTest<Types> { protected: @@ -2172,47 +1649,37 @@ class OcclusionTrackerTestAnimationOpacity1OnMainThread this->VisitLayer(topmost, &occlusion); this->EnterLayer(parent2, &occlusion); + // This occlusion will affect all surfaces. - EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(), - occlusion.occlusion_from_inside_target().ToString()); EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusion_from_outside_target().ToString()); - EXPECT_EQ(gfx::Rect(0, 0, 250, 300).ToString(), - occlusion.UnoccludedLayerContentRect( - parent2, gfx::Rect(0, 0, 300, 300)).ToString()); - this->LeaveLayer(parent2, &occlusion); + EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(), + occlusion.occlusion_from_inside_target().ToString()); + this->LeaveLayer(parent2, &occlusion); this->VisitLayer(surface_child2, &occlusion); this->EnterLayer(surface_child, &occlusion); - EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(), - occlusion.occlusion_from_inside_target().ToString()); EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(), occlusion.occlusion_from_outside_target().ToString()); - EXPECT_RECT_EQ(gfx::Rect(100, 0, 100, 300), - occlusion.UnoccludedLayerContentRect( - surface_child, gfx::Rect(0, 0, 200, 300))); + EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(), + occlusion.occlusion_from_inside_target().ToString()); + this->LeaveLayer(surface_child, &occlusion); this->EnterLayer(surface, &occlusion); - EXPECT_EQ(gfx::Rect(0, 0, 200, 300).ToString(), - occlusion.occlusion_from_inside_target().ToString()); EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(), occlusion.occlusion_from_outside_target().ToString()); - EXPECT_RECT_EQ(gfx::Rect(200, 0, 50, 300), - occlusion.UnoccludedLayerContentRect( - surface, gfx::Rect(0, 0, 300, 300))); - this->LeaveLayer(surface, &occlusion); + EXPECT_EQ(gfx::Rect(0, 0, 200, 300).ToString(), + occlusion.occlusion_from_inside_target().ToString()); + this->LeaveLayer(surface, &occlusion); this->EnterContributingSurface(surface, &occlusion); // Occlusion within the surface is lost when leaving the animating surface. EXPECT_EQ(gfx::Rect().ToString(), - occlusion.occlusion_from_inside_target().ToString()); - EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusion_from_outside_target().ToString()); - EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300), - occlusion.UnoccludedSurfaceContentRect( - surface, false, gfx::Rect(0, 0, 300, 300))); - this->LeaveContributingSurface(surface, &occlusion); + EXPECT_EQ(gfx::Rect().ToString(), + occlusion.occlusion_from_inside_target().ToString()); + this->LeaveContributingSurface(surface, &occlusion); // Occlusion from outside the animating surface still exists. EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(), occlusion.occlusion_from_inside_target().ToString()); @@ -2223,9 +1690,10 @@ class OcclusionTrackerTestAnimationOpacity1OnMainThread this->EnterLayer(parent, &occlusion); // Occlusion is not added for the animating |layer|. - EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300), - occlusion.UnoccludedLayerContentRect( - parent, gfx::Rect(0, 0, 300, 300))); + EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(), + occlusion.occlusion_from_inside_target().ToString()); + EXPECT_EQ(gfx::Rect().ToString(), + occlusion.occlusion_from_outside_target().ToString()); } }; @@ -2297,42 +1765,31 @@ class OcclusionTrackerTestAnimationOpacity0OnMainThread occlusion.occlusion_from_inside_target().ToString()); EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusion_from_outside_target().ToString()); - EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300), - occlusion.UnoccludedLayerContentRect( - parent, gfx::Rect(0, 0, 300, 300))); - this->LeaveLayer(parent2, &occlusion); + this->LeaveLayer(parent2, &occlusion); this->VisitLayer(surface_child2, &occlusion); this->EnterLayer(surface_child, &occlusion); EXPECT_EQ(gfx::Rect(0, 0, 100, 300).ToString(), occlusion.occlusion_from_inside_target().ToString()); EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(), occlusion.occlusion_from_outside_target().ToString()); - EXPECT_RECT_EQ(gfx::Rect(100, 0, 100, 300), - occlusion.UnoccludedLayerContentRect( - surface_child, gfx::Rect(0, 0, 200, 300))); + this->LeaveLayer(surface_child, &occlusion); this->EnterLayer(surface, &occlusion); EXPECT_EQ(gfx::Rect(0, 0, 200, 300).ToString(), occlusion.occlusion_from_inside_target().ToString()); EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(), occlusion.occlusion_from_outside_target().ToString()); - EXPECT_RECT_EQ(gfx::Rect(200, 0, 50, 300), - occlusion.UnoccludedLayerContentRect( - surface, gfx::Rect(0, 0, 300, 300))); - this->LeaveLayer(surface, &occlusion); + this->LeaveLayer(surface, &occlusion); this->EnterContributingSurface(surface, &occlusion); // Occlusion within the surface is lost when leaving the animating surface. EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusion_from_inside_target().ToString()); EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusion_from_outside_target().ToString()); - EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300), - occlusion.UnoccludedSurfaceContentRect( - surface, false, gfx::Rect(0, 0, 300, 300))); - this->LeaveContributingSurface(surface, &occlusion); + this->LeaveContributingSurface(surface, &occlusion); // Occlusion from outside the animating surface still exists. EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(), occlusion.occlusion_from_inside_target().ToString()); @@ -2343,9 +1800,10 @@ class OcclusionTrackerTestAnimationOpacity0OnMainThread this->EnterLayer(parent, &occlusion); // Occlusion is not added for the animating |layer|. - EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300), - occlusion.UnoccludedLayerContentRect( - parent, gfx::Rect(0, 0, 300, 300))); + EXPECT_EQ(gfx::Rect(250, 0, 50, 300).ToString(), + occlusion.occlusion_from_inside_target().ToString()); + EXPECT_EQ(gfx::Rect().ToString(), + occlusion.occlusion_from_outside_target().ToString()); } }; @@ -2520,8 +1978,8 @@ class OcclusionTrackerTestSurfaceOcclusionTranslatesToParent occlusion.occlusion_from_inside_target().ToString()); // Clear any stored occlusion. - occlusion.set_occlusion_from_outside_target(Region()); - occlusion.set_occlusion_from_inside_target(Region()); + occlusion.set_occlusion_from_outside_target(SimpleEnclosedRegion()); + occlusion.set_occlusion_from_inside_target(SimpleEnclosedRegion()); this->VisitLayer(surface, &occlusion); this->VisitContributingSurface(surface, &occlusion); @@ -2573,62 +2031,6 @@ MAIN_AND_IMPL_THREAD_TEST( OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping); template <class Types> -class OcclusionTrackerTestReplicaOccluded : public OcclusionTrackerTest<Types> { - protected: - explicit OcclusionTrackerTestReplicaOccluded(bool opaque_layers) - : OcclusionTrackerTest<Types>(opaque_layers) {} - void RunMyTest() { - typename Types::ContentLayerType* parent = this->CreateRoot( - this->identity_matrix, gfx::PointF(), gfx::Size(100, 200)); - typename Types::LayerType* surface = - this->CreateDrawingSurface(parent, - this->identity_matrix, - gfx::PointF(), - gfx::Size(100, 100), - true); - this->CreateReplicaLayer(surface, - this->identity_matrix, - gfx::PointF(0.f, 100.f), - gfx::Size(100, 100)); - typename Types::LayerType* topmost = - this->CreateDrawingLayer(parent, - this->identity_matrix, - gfx::PointF(0.f, 100.f), - gfx::Size(100, 100), - true); - this->CalcDrawEtc(parent); - - TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( - gfx::Rect(0, 0, 1000, 1000)); - - // |topmost| occludes the replica, but not the surface itself. - this->VisitLayer(topmost, &occlusion); - - EXPECT_EQ(gfx::Rect().ToString(), - occlusion.occlusion_from_outside_target().ToString()); - EXPECT_EQ(gfx::Rect(0, 100, 100, 100).ToString(), - occlusion.occlusion_from_inside_target().ToString()); - - this->VisitLayer(surface, &occlusion); - - // Render target with replica ignores occlusion from outside. - EXPECT_EQ(gfx::Rect().ToString(), - occlusion.occlusion_from_outside_target().ToString()); - EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), - occlusion.occlusion_from_inside_target().ToString()); - - this->EnterContributingSurface(surface, &occlusion); - - // Surface is not occluded so it shouldn't think it is. - EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100), - occlusion.UnoccludedSurfaceContentRect( - surface, false, gfx::Rect(0, 0, 100, 100))); - } -}; - -ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestReplicaOccluded); - -template <class Types> class OcclusionTrackerTestSurfaceWithReplicaUnoccluded : public OcclusionTrackerTest<Types> { protected: @@ -2676,84 +2078,17 @@ class OcclusionTrackerTestSurfaceWithReplicaUnoccluded this->EnterContributingSurface(surface, &occlusion); - // Surface is occluded, but only the top 10px of the replica. - EXPECT_RECT_EQ(gfx::Rect(0, 0, 0, 0), - occlusion.UnoccludedSurfaceContentRect( - surface, false, gfx::Rect(0, 0, 100, 100))); - EXPECT_RECT_EQ(gfx::Rect(0, 10, 100, 90), - occlusion.UnoccludedSurfaceContentRect( - surface, true, gfx::Rect(0, 0, 100, 100))); - } -}; - -ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceWithReplicaUnoccluded); - -template <class Types> -class OcclusionTrackerTestSurfaceAndReplicaOccludedDifferently - : public OcclusionTrackerTest<Types> { - protected: - explicit OcclusionTrackerTestSurfaceAndReplicaOccludedDifferently( - bool opaque_layers) - : OcclusionTrackerTest<Types>(opaque_layers) {} - void RunMyTest() { - typename Types::ContentLayerType* parent = this->CreateRoot( - this->identity_matrix, gfx::PointF(), gfx::Size(100, 200)); - typename Types::LayerType* surface = - this->CreateDrawingSurface(parent, - this->identity_matrix, - gfx::PointF(), - gfx::Size(100, 100), - true); - this->CreateReplicaLayer(surface, - this->identity_matrix, - gfx::PointF(0.f, 100.f), - gfx::Size(100, 100)); - typename Types::LayerType* over_surface = this->CreateDrawingLayer( - parent, this->identity_matrix, gfx::PointF(), gfx::Size(40, 100), true); - typename Types::LayerType* over_replica = - this->CreateDrawingLayer(parent, - this->identity_matrix, - gfx::PointF(0.f, 100.f), - gfx::Size(50, 100), - true); - this->CalcDrawEtc(parent); - - TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( - gfx::Rect(0, 0, 1000, 1000)); - - // These occlude the surface and replica differently, so we can test each - // one. - this->VisitLayer(over_replica, &occlusion); - this->VisitLayer(over_surface, &occlusion); - - EXPECT_EQ(gfx::Rect().ToString(), - occlusion.occlusion_from_outside_target().ToString()); - EXPECT_EQ(UnionRegions(gfx::Rect(0, 0, 40, 100), gfx::Rect(0, 100, 50, 100)) - .ToString(), - occlusion.occlusion_from_inside_target().ToString()); - - this->VisitLayer(surface, &occlusion); - - // Render target with replica ignores occlusion from outside. + // Only occlusion from outside the surface occludes the surface/replica. EXPECT_EQ(gfx::Rect().ToString(), - occlusion.occlusion_from_outside_target().ToString()); - EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), - occlusion.occlusion_from_inside_target().ToString()); - - this->EnterContributingSurface(surface, &occlusion); - - // Surface and replica are occluded different amounts. - EXPECT_RECT_EQ(gfx::Rect(40, 0, 60, 100), - occlusion.UnoccludedSurfaceContentRect( - surface, false, gfx::Rect(0, 0, 100, 100))); - EXPECT_RECT_EQ(gfx::Rect(50, 0, 50, 100), - occlusion.UnoccludedSurfaceContentRect( - surface, true, gfx::Rect(0, 0, 100, 100))); + occlusion.occlusion_on_contributing_surface_from_outside_target() + .ToString()); + EXPECT_EQ(gfx::Rect(0, 0, 100, 110).ToString(), + occlusion.occlusion_on_contributing_surface_from_inside_target() + .ToString()); } }; -ALL_OCCLUSIONTRACKER_TEST( - OcclusionTrackerTestSurfaceAndReplicaOccludedDifferently); +ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestSurfaceWithReplicaUnoccluded); template <class Types> class OcclusionTrackerTestSurfaceChildOfSurface @@ -2772,7 +2107,7 @@ class OcclusionTrackerTestSurfaceChildOfSurface this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), - true); + false); typename Types::LayerType* surface_child = this->CreateDrawingSurface(surface, this->identity_matrix, @@ -2811,16 +2146,18 @@ class OcclusionTrackerTestSurfaceChildOfSurface // have a clip rect. this->EnterContributingSurface(surface_child, &occlusion); - // The surface_child's parent does not have a clip rect as it owns a render - // surface. Make sure the unoccluded rect does not get clipped away - // inappropriately. - EXPECT_RECT_EQ(gfx::Rect(0, 40, 100, 10), - occlusion.UnoccludedSurfaceContentRect( - surface_child, false, gfx::Rect(0, 0, 100, 50))); + // The |surface_child| can't occlude its own surface, but occlusion from + // |topmost| can. + EXPECT_EQ(gfx::Rect().ToString(), + occlusion.occlusion_on_contributing_surface_from_outside_target() + .ToString()); + EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(), + occlusion.occlusion_on_contributing_surface_from_inside_target() + .ToString()); this->LeaveContributingSurface(surface_child, &occlusion); // When the surface_child's occlusion is transformed up to its parent, make - // sure it is not clipped away inappropriately also. + // sure it is not clipped away inappropriately. this->EnterLayer(surface, &occlusion); EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(), occlusion.occlusion_from_outside_target().ToString()); @@ -2829,10 +2166,22 @@ class OcclusionTrackerTestSurfaceChildOfSurface this->LeaveLayer(surface, &occlusion); this->EnterContributingSurface(surface, &occlusion); - // The surface's parent does have a clip rect as it is the root layer. - EXPECT_RECT_EQ(gfx::Rect(0, 50, 100, 50), - occlusion.UnoccludedSurfaceContentRect( - surface, false, gfx::Rect(0, 0, 100, 100))); + // The occlusion from inside |surface| can't affect the surface, but + // |topmost| can. + EXPECT_EQ(gfx::Rect().ToString(), + occlusion.occlusion_on_contributing_surface_from_outside_target() + .ToString()); + EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(), + occlusion.occlusion_on_contributing_surface_from_inside_target() + .ToString()); + + this->LeaveContributingSurface(surface, &occlusion); + this->EnterLayer(parent, &occlusion); + // The occlusion in |surface| and without are merged into the parent. + EXPECT_EQ(gfx::Rect().ToString(), + occlusion.occlusion_from_outside_target().ToString()); + EXPECT_EQ(gfx::Rect(0, 0, 100, 60).ToString(), + occlusion.occlusion_from_inside_target().ToString()); } }; @@ -2849,146 +2198,113 @@ class OcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter gfx::Transform scale_by_half; scale_by_half.Scale(0.5, 0.5); - // Make a 50x50 filtered surface that is completely surrounded by opaque - // layers which are above it in the z-order. The surface is scaled to test - // that the pixel moving is done in the target space, where the background - // filter is applied. - typename Types::ContentLayerType* parent = this->CreateRoot( - this->identity_matrix, gfx::PointF(), gfx::Size(200, 150)); - typename Types::LayerType* filtered_surface = - this->CreateDrawingLayer(parent, - scale_by_half, - gfx::PointF(50.f, 50.f), - gfx::Size(100, 100), - false); - typename Types::LayerType* occluding_layer1 = this->CreateDrawingLayer( - parent, this->identity_matrix, gfx::PointF(), gfx::Size(200, 50), true); - typename Types::LayerType* occluding_layer2 = - this->CreateDrawingLayer(parent, - this->identity_matrix, - gfx::PointF(0.f, 100.f), - gfx::Size(200, 50), - true); - typename Types::LayerType* occluding_layer3 = - this->CreateDrawingLayer(parent, - this->identity_matrix, - gfx::PointF(0.f, 50.f), - gfx::Size(50, 50), - true); - typename Types::LayerType* occluding_layer4 = - this->CreateDrawingLayer(parent, - this->identity_matrix, - gfx::PointF(100.f, 50.f), - gfx::Size(100, 50), - true); - - // Filters make the layer own a surface. FilterOperations filters; filters.Append(FilterOperation::CreateBlurFilter(10.f)); - filtered_surface->SetBackgroundFilters(filters); // Save the distance of influence for the blur effect. int outset_top, outset_right, outset_bottom, outset_left; filters.GetOutsets( &outset_top, &outset_right, &outset_bottom, &outset_left); - this->CalcDrawEtc(parent); - - TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( - gfx::Rect(0, 0, 1000, 1000)); - - // These layers occlude pixels directly beside the filtered_surface. Because - // filtered surface blends pixels in a radius, it will need to see some of - // the pixels (up to radius far) underneath the occluding layers. - this->VisitLayer(occluding_layer4, &occlusion); - this->VisitLayer(occluding_layer3, &occlusion); - this->VisitLayer(occluding_layer2, &occlusion); - this->VisitLayer(occluding_layer1, &occlusion); - - Region expected_occlusion; - expected_occlusion.Union(gfx::Rect(0, 0, 200, 50)); - expected_occlusion.Union(gfx::Rect(0, 50, 50, 50)); - expected_occlusion.Union(gfx::Rect(100, 50, 100, 50)); - expected_occlusion.Union(gfx::Rect(0, 100, 200, 50)); - - EXPECT_EQ(expected_occlusion.ToString(), - occlusion.occlusion_from_inside_target().ToString()); - EXPECT_EQ(gfx::Rect().ToString(), - occlusion.occlusion_from_outside_target().ToString()); - - this->VisitLayer(filtered_surface, &occlusion); - - // The filtered layer does not occlude. - Region expected_occlusion_outside_surface; - expected_occlusion_outside_surface.Union(gfx::Rect(-50, -50, 200, 50)); - expected_occlusion_outside_surface.Union(gfx::Rect(-50, 0, 50, 50)); - expected_occlusion_outside_surface.Union(gfx::Rect(50, 0, 100, 50)); - expected_occlusion_outside_surface.Union(gfx::Rect(-50, 50, 200, 50)); + enum Direction { + LEFT, + RIGHT, + TOP, + BOTTOM, + LAST_DIRECTION = BOTTOM, + }; + + for (int i = 0; i <= LAST_DIRECTION; ++i) { + SCOPED_TRACE(i); + + // Make a 50x50 filtered surface that is adjacent to occluding layers + // which are above it in the z-order in various configurations. The + // surface is scaled to test that the pixel moving is done in the target + // space, where the background filter is applied. + typename Types::ContentLayerType* parent = this->CreateRoot( + this->identity_matrix, gfx::PointF(), gfx::Size(200, 200)); + typename Types::LayerType* filtered_surface = + this->CreateDrawingLayer(parent, + scale_by_half, + gfx::PointF(50.f, 50.f), + gfx::Size(100, 100), + false); + filtered_surface->SetBackgroundFilters(filters); + + gfx::Rect occlusion_rect; + switch (i) { + case LEFT: + occlusion_rect = gfx::Rect(0, 0, 50, 200); + break; + case RIGHT: + occlusion_rect = gfx::Rect(100, 0, 50, 200); + break; + case TOP: + occlusion_rect = gfx::Rect(0, 0, 200, 50); + break; + case BOTTOM: + occlusion_rect = gfx::Rect(0, 100, 200, 50); + break; + } + + typename Types::LayerType* occluding_layer = + this->CreateDrawingLayer(parent, + this->identity_matrix, + occlusion_rect.origin(), + occlusion_rect.size(), + true); + this->CalcDrawEtc(parent); - EXPECT_EQ(expected_occlusion_outside_surface.ToString(), - occlusion.occlusion_from_outside_target().ToString()); - EXPECT_EQ(gfx::Rect().ToString(), - occlusion.occlusion_from_inside_target().ToString()); + TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( + gfx::Rect(0, 0, 200, 200)); - // The surface has a background blur, so it needs pixels that are currently - // considered occluded in order to be drawn. So the pixels it needs should - // be removed some the occluded area so that when we get to the parent they - // are drawn. - this->VisitContributingSurface(filtered_surface, &occlusion); + // This layer occludes pixels directly beside the filtered_surface. + // Because filtered surface blends pixels in a radius, it will need to see + // some of the pixels (up to radius far) underneath the occluding layers. + this->VisitLayer(occluding_layer, &occlusion); - this->EnterLayer(parent, &occlusion); + EXPECT_EQ(occlusion_rect.ToString(), + occlusion.occlusion_from_inside_target().ToString()); + EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); - Region expected_blurred_occlusion; - expected_blurred_occlusion.Union(gfx::Rect(0, 0, 200, 50 - outset_top)); - expected_blurred_occlusion.Union(gfx::Rect( - 0, 50 - outset_top, 50 - outset_left, 50 + outset_top + outset_bottom)); - expected_blurred_occlusion.Union( - gfx::Rect(100 + outset_right, - 50 - outset_top, - 100 - outset_right, - 50 + outset_top + outset_bottom)); - expected_blurred_occlusion.Union( - gfx::Rect(0, 100 + outset_bottom, 200, 50 - outset_bottom)); + this->VisitLayer(filtered_surface, &occlusion); - EXPECT_EQ(expected_blurred_occlusion.ToString(), - occlusion.occlusion_from_inside_target().ToString()); - EXPECT_EQ(gfx::Rect().ToString(), - occlusion.occlusion_from_outside_target().ToString()); + // The occlusion is used fully inside the surface. + gfx::Rect occlusion_inside_surface = + occlusion_rect - gfx::Vector2d(50, 50); + EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty()); + EXPECT_EQ(occlusion_inside_surface.ToString(), + occlusion.occlusion_from_outside_target().ToString()); - gfx::Rect outset_rect; - gfx::Rect test_rect; + // The surface has a background blur, so it needs pixels that are + // currently considered occluded in order to be drawn. So the pixels it + // needs should be removed some the occluded area so that when we get to + // the parent they are drawn. + this->VisitContributingSurface(filtered_surface, &occlusion); + this->EnterLayer(parent, &occlusion); - // Nothing in the blur outsets for the filtered_surface is occluded. - outset_rect = gfx::Rect(50 - outset_left, - 50 - outset_top, - 50 + outset_left + outset_right, - 50 + outset_top + outset_bottom); - test_rect = outset_rect; - EXPECT_EQ( - outset_rect.ToString(), - occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString()); + gfx::Rect expected_occlusion = occlusion_rect; + switch (i) { + case LEFT: + expected_occlusion.Inset(0, 0, outset_right, 0); + break; + case RIGHT: + expected_occlusion.Inset(outset_right, 0, 0, 0); + break; + case TOP: + expected_occlusion.Inset(0, 0, 0, outset_right); + break; + case BOTTOM: + expected_occlusion.Inset(0, outset_right, 0, 0); + break; + } + + EXPECT_EQ(expected_occlusion.ToString(), + occlusion.occlusion_from_inside_target().ToString()); + EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); - // Stuff outside the blur outsets is still occluded though. - test_rect = outset_rect; - test_rect.Inset(0, 0, -1, 0); - EXPECT_EQ( - outset_rect.ToString(), - occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString()); - test_rect = outset_rect; - test_rect.Inset(0, 0, 0, -1); - EXPECT_EQ( - outset_rect.ToString(), - occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString()); - test_rect = outset_rect; - test_rect.Inset(-1, 0, 0, 0); - EXPECT_EQ( - outset_rect.ToString(), - occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString()); - test_rect = outset_rect; - test_rect.Inset(0, -1, 0, 0); - EXPECT_EQ( - outset_rect.ToString(), - occlusion.UnoccludedLayerContentRect(parent, test_rect).ToString()); + this->DestroyLayers(); + } } }; @@ -3126,21 +2442,28 @@ class OcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter this->VisitContributingSurface(filtered_surface, &occlusion); this->VisitLayer(behind_replica_layer, &occlusion); - this->VisitLayer(behind_surface_layer, &occlusion); // The layers behind the surface are not blurred, and their occlusion does // not change, until we leave the surface. So it should not be modified by // the filter here. - gfx::Rect occlusion_behind_surface = gfx::Rect(60, 60, 30, 30); gfx::Rect occlusion_behind_replica = gfx::Rect(210, 60, 30, 30); - - Region expected_opaque_bounds = - UnionRegions(occlusion_behind_surface, occlusion_behind_replica); - EXPECT_EQ(expected_opaque_bounds.ToString(), + EXPECT_EQ(occlusion_behind_replica.ToString(), occlusion.occlusion_from_inside_target().ToString()); + EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); - EXPECT_EQ(gfx::Rect().ToString(), - occlusion.occlusion_from_outside_target().ToString()); + // Clear the occlusion so the |behind_surface_layer| can add its occlusion + // without existing occlusion interfering. + occlusion.set_occlusion_from_inside_target(SimpleEnclosedRegion()); + + this->VisitLayer(behind_surface_layer, &occlusion); + + // The layers behind the surface are not blurred, and their occlusion does + // not change, until we leave the surface. So it should not be modified by + // the filter here. + gfx::Rect occlusion_behind_surface = gfx::Rect(60, 60, 30, 30); + EXPECT_EQ(occlusion_behind_surface.ToString(), + occlusion.occlusion_from_inside_target().ToString()); + EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); } }; @@ -3311,24 +2634,21 @@ class OcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded gfx::Rect occlusion_beside_surface = gfx::Rect(90, 40, 10, 10); gfx::Rect occlusion_beside_replica = gfx::Rect(200, 40, 10, 10); - Region expected_occlusion; - expected_occlusion.Union(occlusion_above_surface); - expected_occlusion.Union(occlusion_above_replica); - expected_occlusion.Union(occlusion_beside_surface); + SimpleEnclosedRegion expected_occlusion; expected_occlusion.Union(occlusion_beside_replica); + expected_occlusion.Union(occlusion_beside_surface); + expected_occlusion.Union(occlusion_above_replica); + expected_occlusion.Union(occlusion_above_surface); - ASSERT_EQ(expected_occlusion.ToString(), + EXPECT_EQ(expected_occlusion.ToString(), occlusion.occlusion_from_inside_target().ToString()); - EXPECT_EQ(gfx::Rect().ToString(), - occlusion.occlusion_from_outside_target().ToString()); + EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); - Region::Iterator expected_rects(expected_occlusion); - Region::Iterator target_surface_rects( - occlusion.occlusion_from_inside_target()); - for (; expected_rects.has_rect(); - expected_rects.next(), target_surface_rects.next()) { - ASSERT_TRUE(target_surface_rects.has_rect()); - EXPECT_EQ(expected_rects.rect(), target_surface_rects.rect()); + const SimpleEnclosedRegion& actual_occlusion = + occlusion.occlusion_from_inside_target(); + for (size_t i = 0; i < expected_occlusion.GetRegionComplexity(); ++i) { + ASSERT_LT(i, actual_occlusion.GetRegionComplexity()); + EXPECT_EQ(expected_occlusion.GetRect(i), actual_occlusion.GetRect(i)); } } }; @@ -3554,5 +2874,437 @@ class OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude) +template <class Types> +class OcclusionTrackerTestOccludedLayer : public OcclusionTrackerTest<Types> { + protected: + explicit OcclusionTrackerTestOccludedLayer(bool opaque_layers) + : OcclusionTrackerTest<Types>(opaque_layers) {} + void RunMyTest() { + gfx::Transform translate; + translate.Translate(10.0, 20.0); + typename Types::ContentLayerType* root = this->CreateRoot( + this->identity_matrix, gfx::Point(), gfx::Size(200, 200)); + typename Types::LayerType* surface = this->CreateSurface( + root, this->identity_matrix, gfx::Point(), gfx::Size(200, 200)); + typename Types::LayerType* layer = this->CreateDrawingLayer( + surface, translate, gfx::Point(), gfx::Size(200, 200), false); + typename Types::ContentLayerType* outside_layer = this->CreateDrawingLayer( + root, this->identity_matrix, gfx::Point(), gfx::Size(200, 200), false); + this->CalcDrawEtc(root); + + TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( + gfx::Rect(0, 0, 200, 200)); + this->VisitLayer(outside_layer, &occlusion); + this->EnterLayer(layer, &occlusion); + + // No occlusion, is not occluded. + occlusion.set_occlusion_from_outside_target(SimpleEnclosedRegion()); + occlusion.set_occlusion_from_inside_target(SimpleEnclosedRegion()); + EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(100, 100))); + + // Partial occlusion from outside, is not occluded. + occlusion.set_occlusion_from_outside_target( + SimpleEnclosedRegion(50, 50, 100, 100)); + occlusion.set_occlusion_from_inside_target(SimpleEnclosedRegion()); + EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 100))); + EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(90, 30, 100, 100))); + EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(40, 0, 100, 100))); + EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(40, 80, 100, 100))); + EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 80, 100))); + EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(90, 80, 100, 100))); + EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 80, 100, 100))); + EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(90, 0, 100, 100))); + + // Full occlusion from outside, is occluded. + EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(40, 30, 100, 100))); + EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(40, 30, 10, 10))); + EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(130, 120, 10, 10))); + EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(80, 70, 50, 50))); + + // Partial occlusion from inside, is not occluded. + occlusion.set_occlusion_from_outside_target(SimpleEnclosedRegion()); + occlusion.set_occlusion_from_inside_target( + SimpleEnclosedRegion(50, 50, 100, 100)); + EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 100))); + EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(90, 30, 100, 100))); + EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(40, 0, 100, 100))); + EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(40, 80, 100, 100))); + EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 80, 100))); + EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(90, 80, 100, 100))); + EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 80, 100, 100))); + EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(90, 0, 100, 100))); + + // Full occlusion from inside, is occluded. + EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(40, 30, 100, 100))); + EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(40, 30, 10, 10))); + EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(130, 120, 10, 10))); + EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(80, 70, 50, 50))); + + // Partial occlusion from both, is not occluded. + occlusion.set_occlusion_from_outside_target( + SimpleEnclosedRegion(50, 50, 100, 50)); + occlusion.set_occlusion_from_inside_target( + SimpleEnclosedRegion(50, 100, 100, 50)); + EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 100, 100))); + EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(90, 30, 100, 100))); + EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(40, 0, 100, 100))); + EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(40, 80, 100, 100))); + EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 0, 80, 100))); + EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(90, 80, 100, 100))); + EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(0, 80, 100, 100))); + EXPECT_FALSE(occlusion.OccludedLayer(layer, gfx::Rect(90, 0, 100, 100))); + + // Full occlusion from both, is occluded. + EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(40, 30, 100, 100))); + EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(40, 30, 10, 10))); + EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(130, 120, 10, 10))); + EXPECT_TRUE(occlusion.OccludedLayer(layer, gfx::Rect(80, 70, 50, 50))); + } +}; + +ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestOccludedLayer) + +template <class Types> +class OcclusionTrackerTestUnoccludedLayerQuery + : public OcclusionTrackerTest<Types> { + protected: + explicit OcclusionTrackerTestUnoccludedLayerQuery(bool opaque_layers) + : OcclusionTrackerTest<Types>(opaque_layers) {} + void RunMyTest() { + gfx::Transform translate; + translate.Translate(10.0, 20.0); + typename Types::ContentLayerType* root = this->CreateRoot( + this->identity_matrix, gfx::Point(), gfx::Size(200, 200)); + typename Types::LayerType* surface = this->CreateSurface( + root, this->identity_matrix, gfx::Point(), gfx::Size(200, 200)); + typename Types::LayerType* layer = this->CreateDrawingLayer( + surface, translate, gfx::Point(), gfx::Size(200, 200), false); + typename Types::ContentLayerType* outside_layer = this->CreateDrawingLayer( + root, this->identity_matrix, gfx::Point(), gfx::Size(200, 200), false); + this->CalcDrawEtc(root); + + TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( + gfx::Rect(0, 0, 200, 200)); + this->VisitLayer(outside_layer, &occlusion); + this->EnterLayer(layer, &occlusion); + + // No occlusion, is not occluded. + occlusion.set_occlusion_from_outside_target(SimpleEnclosedRegion()); + occlusion.set_occlusion_from_inside_target(SimpleEnclosedRegion()); + EXPECT_EQ(gfx::Rect(100, 100), + occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(100, 100))); + + // Partial occlusion from outside. + occlusion.set_occlusion_from_outside_target( + SimpleEnclosedRegion(50, 50, 100, 100)); + occlusion.set_occlusion_from_inside_target(SimpleEnclosedRegion()); + EXPECT_EQ( + gfx::Rect(0, 0, 100, 100), + occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(0, 0, 100, 100))); + EXPECT_EQ(gfx::Rect(140, 30, 50, 100), + occlusion.UnoccludedLayerContentRect( + layer, gfx::Rect(90, 30, 100, 100))); + EXPECT_EQ(gfx::Rect(40, 0, 100, 30), + occlusion.UnoccludedLayerContentRect(layer, + gfx::Rect(40, 0, 100, 100))); + EXPECT_EQ(gfx::Rect(40, 130, 100, 50), + occlusion.UnoccludedLayerContentRect( + layer, gfx::Rect(40, 80, 100, 100))); + EXPECT_EQ( + gfx::Rect(0, 0, 80, 100), + occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(0, 0, 80, 100))); + EXPECT_EQ(gfx::Rect(90, 80, 100, 100), + occlusion.UnoccludedLayerContentRect( + layer, gfx::Rect(90, 80, 100, 100))); + EXPECT_EQ(gfx::Rect(0, 80, 100, 100), + occlusion.UnoccludedLayerContentRect(layer, + gfx::Rect(0, 80, 100, 100))); + EXPECT_EQ(gfx::Rect(90, 0, 100, 100), + occlusion.UnoccludedLayerContentRect(layer, + gfx::Rect(90, 0, 100, 100))); + + // Full occlusion from outside, is occluded. + EXPECT_EQ(gfx::Rect(), + occlusion.UnoccludedLayerContentRect( + layer, gfx::Rect(40, 30, 100, 100))); + EXPECT_EQ( + gfx::Rect(), + occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(40, 30, 10, 10))); + EXPECT_EQ(gfx::Rect(), + occlusion.UnoccludedLayerContentRect( + layer, gfx::Rect(130, 120, 10, 10))); + EXPECT_EQ( + gfx::Rect(), + occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(80, 70, 50, 50))); + + // Partial occlusion from inside, is not occluded. + occlusion.set_occlusion_from_outside_target(SimpleEnclosedRegion()); + occlusion.set_occlusion_from_inside_target( + SimpleEnclosedRegion(50, 50, 100, 100)); + EXPECT_EQ( + gfx::Rect(0, 0, 100, 100), + occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(0, 0, 100, 100))); + EXPECT_EQ(gfx::Rect(140, 30, 50, 100), + occlusion.UnoccludedLayerContentRect( + layer, gfx::Rect(90, 30, 100, 100))); + EXPECT_EQ(gfx::Rect(40, 0, 100, 30), + occlusion.UnoccludedLayerContentRect(layer, + gfx::Rect(40, 0, 100, 100))); + EXPECT_EQ(gfx::Rect(40, 130, 100, 50), + occlusion.UnoccludedLayerContentRect( + layer, gfx::Rect(40, 80, 100, 100))); + EXPECT_EQ( + gfx::Rect(0, 0, 80, 100), + occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(0, 0, 80, 100))); + EXPECT_EQ(gfx::Rect(90, 80, 100, 100), + occlusion.UnoccludedLayerContentRect( + layer, gfx::Rect(90, 80, 100, 100))); + EXPECT_EQ(gfx::Rect(0, 80, 100, 100), + occlusion.UnoccludedLayerContentRect(layer, + gfx::Rect(0, 80, 100, 100))); + EXPECT_EQ(gfx::Rect(90, 0, 100, 100), + occlusion.UnoccludedLayerContentRect(layer, + gfx::Rect(90, 0, 100, 100))); + + // Full occlusion from inside, is occluded. + EXPECT_EQ(gfx::Rect(), + occlusion.UnoccludedLayerContentRect( + layer, gfx::Rect(40, 30, 100, 100))); + EXPECT_EQ( + gfx::Rect(), + occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(40, 30, 10, 10))); + EXPECT_EQ(gfx::Rect(), + occlusion.UnoccludedLayerContentRect( + layer, gfx::Rect(130, 120, 10, 10))); + EXPECT_EQ( + gfx::Rect(), + occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(80, 70, 50, 50))); + + // Partial occlusion from both, is not occluded. + occlusion.set_occlusion_from_outside_target( + SimpleEnclosedRegion(50, 50, 100, 50)); + occlusion.set_occlusion_from_inside_target( + SimpleEnclosedRegion(50, 100, 100, 50)); + EXPECT_EQ( + gfx::Rect(0, 0, 100, 100), + occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(0, 0, 100, 100))); + // This could be (140, 30, 50, 100). But because we do a lossy subtract, + // it's larger. + EXPECT_EQ(gfx::Rect(90, 30, 100, 100), + occlusion.UnoccludedLayerContentRect( + layer, gfx::Rect(90, 30, 100, 100))); + EXPECT_EQ(gfx::Rect(40, 0, 100, 30), + occlusion.UnoccludedLayerContentRect(layer, + gfx::Rect(40, 0, 100, 100))); + EXPECT_EQ(gfx::Rect(40, 130, 100, 50), + occlusion.UnoccludedLayerContentRect( + layer, gfx::Rect(40, 80, 100, 100))); + EXPECT_EQ( + gfx::Rect(0, 0, 80, 100), + occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(0, 0, 80, 100))); + EXPECT_EQ(gfx::Rect(90, 80, 100, 100), + occlusion.UnoccludedLayerContentRect( + layer, gfx::Rect(90, 80, 100, 100))); + EXPECT_EQ(gfx::Rect(0, 80, 100, 100), + occlusion.UnoccludedLayerContentRect(layer, + gfx::Rect(0, 80, 100, 100))); + EXPECT_EQ(gfx::Rect(90, 0, 100, 100), + occlusion.UnoccludedLayerContentRect(layer, + gfx::Rect(90, 0, 100, 100))); + + // Full occlusion from both, is occluded. + EXPECT_EQ(gfx::Rect(), + occlusion.UnoccludedLayerContentRect( + layer, gfx::Rect(40, 30, 100, 100))); + EXPECT_EQ( + gfx::Rect(), + occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(40, 30, 10, 10))); + EXPECT_EQ(gfx::Rect(), + occlusion.UnoccludedLayerContentRect( + layer, gfx::Rect(130, 120, 10, 10))); + EXPECT_EQ( + gfx::Rect(), + occlusion.UnoccludedLayerContentRect(layer, gfx::Rect(80, 70, 50, 50))); + } +}; + +ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestUnoccludedLayerQuery) + +template <class Types> +class OcclusionTrackerTestUnoccludedSurfaceQuery + : public OcclusionTrackerTest<Types> { + protected: + explicit OcclusionTrackerTestUnoccludedSurfaceQuery(bool opaque_layers) + : OcclusionTrackerTest<Types>(opaque_layers) {} + void RunMyTest() { + gfx::Transform translate; + translate.Translate(10.0, 20.0); + typename Types::ContentLayerType* root = this->CreateRoot( + this->identity_matrix, gfx::Point(), gfx::Size(200, 200)); + typename Types::LayerType* surface = + this->CreateSurface(root, translate, gfx::Point(), gfx::Size(200, 200)); + typename Types::LayerType* layer = + this->CreateDrawingLayer(surface, + this->identity_matrix, + gfx::Point(), + gfx::Size(200, 200), + false); + typename Types::ContentLayerType* outside_layer = this->CreateDrawingLayer( + root, this->identity_matrix, gfx::Point(), gfx::Size(200, 200), false); + this->CalcDrawEtc(root); + + TestOcclusionTrackerWithClip<typename Types::LayerType> occlusion( + gfx::Rect(0, 0, 200, 200)); + this->VisitLayer(outside_layer, &occlusion); + this->VisitLayer(layer, &occlusion); + this->EnterContributingSurface(surface, &occlusion); + + // No occlusion, is not occluded. + occlusion.set_occlusion_on_contributing_surface_from_outside_target( + SimpleEnclosedRegion()); + occlusion.set_occlusion_on_contributing_surface_from_inside_target( + SimpleEnclosedRegion()); + EXPECT_EQ( + gfx::Rect(100, 100), + occlusion.UnoccludedSurfaceContentRect(surface, gfx::Rect(100, 100))); + + // Partial occlusion from outside. + occlusion.set_occlusion_on_contributing_surface_from_outside_target( + SimpleEnclosedRegion(50, 50, 100, 100)); + occlusion.set_occlusion_on_contributing_surface_from_inside_target( + SimpleEnclosedRegion()); + EXPECT_EQ(gfx::Rect(0, 0, 100, 100), + occlusion.UnoccludedSurfaceContentRect( + surface, gfx::Rect(0, 0, 100, 100))); + EXPECT_EQ(gfx::Rect(140, 30, 50, 100), + occlusion.UnoccludedSurfaceContentRect( + surface, gfx::Rect(90, 30, 100, 100))); + EXPECT_EQ(gfx::Rect(40, 0, 100, 30), + occlusion.UnoccludedSurfaceContentRect( + surface, gfx::Rect(40, 0, 100, 100))); + EXPECT_EQ(gfx::Rect(40, 130, 100, 50), + occlusion.UnoccludedSurfaceContentRect( + surface, gfx::Rect(40, 80, 100, 100))); + EXPECT_EQ(gfx::Rect(0, 0, 80, 100), + occlusion.UnoccludedSurfaceContentRect(surface, + gfx::Rect(0, 0, 80, 100))); + EXPECT_EQ(gfx::Rect(90, 80, 100, 100), + occlusion.UnoccludedSurfaceContentRect( + surface, gfx::Rect(90, 80, 100, 100))); + EXPECT_EQ(gfx::Rect(0, 80, 100, 100), + occlusion.UnoccludedSurfaceContentRect( + surface, gfx::Rect(0, 80, 100, 100))); + EXPECT_EQ(gfx::Rect(90, 0, 100, 100), + occlusion.UnoccludedSurfaceContentRect( + surface, gfx::Rect(90, 0, 100, 100))); + + // Full occlusion from outside, is occluded. + EXPECT_EQ(gfx::Rect(), + occlusion.UnoccludedSurfaceContentRect( + surface, gfx::Rect(40, 30, 100, 100))); + EXPECT_EQ(gfx::Rect(), + occlusion.UnoccludedSurfaceContentRect( + surface, gfx::Rect(40, 30, 10, 10))); + EXPECT_EQ(gfx::Rect(), + occlusion.UnoccludedSurfaceContentRect( + surface, gfx::Rect(130, 120, 10, 10))); + EXPECT_EQ(gfx::Rect(), + occlusion.UnoccludedSurfaceContentRect( + surface, gfx::Rect(80, 70, 50, 50))); + + // Partial occlusion from inside, is not occluded. + occlusion.set_occlusion_on_contributing_surface_from_outside_target( + SimpleEnclosedRegion()); + occlusion.set_occlusion_on_contributing_surface_from_inside_target( + SimpleEnclosedRegion(50, 50, 100, 100)); + EXPECT_EQ(gfx::Rect(0, 0, 100, 100), + occlusion.UnoccludedSurfaceContentRect( + surface, gfx::Rect(0, 0, 100, 100))); + EXPECT_EQ(gfx::Rect(140, 30, 50, 100), + occlusion.UnoccludedSurfaceContentRect( + surface, gfx::Rect(90, 30, 100, 100))); + EXPECT_EQ(gfx::Rect(40, 0, 100, 30), + occlusion.UnoccludedSurfaceContentRect( + surface, gfx::Rect(40, 0, 100, 100))); + EXPECT_EQ(gfx::Rect(40, 130, 100, 50), + occlusion.UnoccludedSurfaceContentRect( + surface, gfx::Rect(40, 80, 100, 100))); + EXPECT_EQ(gfx::Rect(0, 0, 80, 100), + occlusion.UnoccludedSurfaceContentRect(surface, + gfx::Rect(0, 0, 80, 100))); + EXPECT_EQ(gfx::Rect(90, 80, 100, 100), + occlusion.UnoccludedSurfaceContentRect( + surface, gfx::Rect(90, 80, 100, 100))); + EXPECT_EQ(gfx::Rect(0, 80, 100, 100), + occlusion.UnoccludedSurfaceContentRect( + surface, gfx::Rect(0, 80, 100, 100))); + EXPECT_EQ(gfx::Rect(90, 0, 100, 100), + occlusion.UnoccludedSurfaceContentRect( + surface, gfx::Rect(90, 0, 100, 100))); + + // Full occlusion from inside, is occluded. + EXPECT_EQ(gfx::Rect(), + occlusion.UnoccludedSurfaceContentRect( + surface, gfx::Rect(40, 30, 100, 100))); + EXPECT_EQ(gfx::Rect(), + occlusion.UnoccludedSurfaceContentRect( + surface, gfx::Rect(40, 30, 10, 10))); + EXPECT_EQ(gfx::Rect(), + occlusion.UnoccludedSurfaceContentRect( + surface, gfx::Rect(130, 120, 10, 10))); + EXPECT_EQ(gfx::Rect(), + occlusion.UnoccludedSurfaceContentRect( + surface, gfx::Rect(80, 70, 50, 50))); + + // Partial occlusion from both, is not occluded. + occlusion.set_occlusion_on_contributing_surface_from_outside_target( + SimpleEnclosedRegion(50, 50, 100, 50)); + occlusion.set_occlusion_on_contributing_surface_from_inside_target( + SimpleEnclosedRegion(50, 100, 100, 50)); + EXPECT_EQ(gfx::Rect(0, 0, 100, 100), + occlusion.UnoccludedSurfaceContentRect( + surface, gfx::Rect(0, 0, 100, 100))); + // This could be (140, 30, 50, 100). But because we do a lossy subtract, + // it's larger. + EXPECT_EQ(gfx::Rect(90, 30, 100, 100), + occlusion.UnoccludedSurfaceContentRect( + surface, gfx::Rect(90, 30, 100, 100))); + EXPECT_EQ(gfx::Rect(40, 0, 100, 30), + occlusion.UnoccludedSurfaceContentRect( + surface, gfx::Rect(40, 0, 100, 100))); + EXPECT_EQ(gfx::Rect(40, 130, 100, 50), + occlusion.UnoccludedSurfaceContentRect( + surface, gfx::Rect(40, 80, 100, 100))); + EXPECT_EQ(gfx::Rect(0, 0, 80, 100), + occlusion.UnoccludedSurfaceContentRect(surface, + gfx::Rect(0, 0, 80, 100))); + EXPECT_EQ(gfx::Rect(90, 80, 100, 100), + occlusion.UnoccludedSurfaceContentRect( + surface, gfx::Rect(90, 80, 100, 100))); + EXPECT_EQ(gfx::Rect(0, 80, 100, 100), + occlusion.UnoccludedSurfaceContentRect( + surface, gfx::Rect(0, 80, 100, 100))); + EXPECT_EQ(gfx::Rect(90, 0, 100, 100), + occlusion.UnoccludedSurfaceContentRect( + surface, gfx::Rect(90, 0, 100, 100))); + + // Full occlusion from both, is occluded. + EXPECT_EQ(gfx::Rect(), + occlusion.UnoccludedSurfaceContentRect( + surface, gfx::Rect(40, 30, 100, 100))); + EXPECT_EQ(gfx::Rect(), + occlusion.UnoccludedSurfaceContentRect( + surface, gfx::Rect(40, 30, 10, 10))); + EXPECT_EQ(gfx::Rect(), + occlusion.UnoccludedSurfaceContentRect( + surface, gfx::Rect(130, 120, 10, 10))); + EXPECT_EQ(gfx::Rect(), + occlusion.UnoccludedSurfaceContentRect( + surface, gfx::Rect(80, 70, 50, 50))); + } +}; + +ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestUnoccludedSurfaceQuery) + } // namespace } // namespace cc diff --git a/chromium/cc/trees/occlusion_unittest.cc b/chromium/cc/trees/occlusion_unittest.cc new file mode 100644 index 00000000000..becc7a3889c --- /dev/null +++ b/chromium/cc/trees/occlusion_unittest.cc @@ -0,0 +1,272 @@ +// 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 "cc/trees/occlusion.h" + +#include "testing/gtest/include/gtest/gtest.h" + +namespace cc { +namespace { + +TEST(OcclusionTest, HasOcclusion) { + Occlusion empty; + EXPECT_FALSE(empty.HasOcclusion()); + + empty = Occlusion( + gfx::Transform(), SimpleEnclosedRegion(), SimpleEnclosedRegion()); + EXPECT_FALSE(empty.HasOcclusion()); + + Occlusion outside_nonempty( + gfx::Transform(), SimpleEnclosedRegion(10, 10), SimpleEnclosedRegion()); + EXPECT_TRUE(outside_nonempty.HasOcclusion()); + + Occlusion inside_nonempty( + gfx::Transform(), SimpleEnclosedRegion(), SimpleEnclosedRegion(10, 10)); + EXPECT_TRUE(inside_nonempty.HasOcclusion()); + + Occlusion both_nonempty(gfx::Transform(), + SimpleEnclosedRegion(10, 10), + SimpleEnclosedRegion(10, 10)); + EXPECT_TRUE(both_nonempty.HasOcclusion()); +} + +#define EXPECT_OCCLUSION(occlusion, rects, ...) \ + { \ + bool expected[] = {__VA_ARGS__}; \ + ASSERT_EQ(arraysize(rects), arraysize(expected)); \ + for (size_t i = 0; i < arraysize(rects); ++i) \ + EXPECT_EQ(expected[i], occlusion.IsOccluded(rects[i])) \ + << "Test failed for index " << i << "."; \ + } + +TEST(OcclusionTest, IsOccludedNoTransform) { + gfx::Rect rects[] = {gfx::Rect(10, 10), + gfx::Rect(10, 0, 10, 10), + gfx::Rect(0, 10, 10, 10), + gfx::Rect(10, 10, 10, 10)}; + + Occlusion no_occlusion; + EXPECT_OCCLUSION(no_occlusion, rects, false, false, false, false); + + Occlusion all_occluded_outside( + gfx::Transform(), SimpleEnclosedRegion(20, 20), SimpleEnclosedRegion()); + EXPECT_OCCLUSION(all_occluded_outside, rects, true, true, true, true); + + Occlusion all_occluded_inside( + gfx::Transform(), SimpleEnclosedRegion(), SimpleEnclosedRegion(20, 20)); + EXPECT_OCCLUSION(all_occluded_inside, rects, true, true, true, true); + + Occlusion all_occluded_mixed(gfx::Transform(), + SimpleEnclosedRegion(10, 20), + SimpleEnclosedRegion(10, 0, 10, 20)); + EXPECT_OCCLUSION(all_occluded_mixed, rects, true, true, true, true); + + Occlusion some_occluded(gfx::Transform(), + SimpleEnclosedRegion(10, 10), + SimpleEnclosedRegion(10, 10, 10, 10)); + EXPECT_OCCLUSION(some_occluded, rects, true, false, false, true); +} + +TEST(OcclusionTest, IsOccludedScaled) { + gfx::Rect rects[] = {gfx::Rect(10, 10), + gfx::Rect(10, 0, 10, 10), + gfx::Rect(0, 10, 10, 10), + gfx::Rect(10, 10, 10, 10)}; + + gfx::Transform half_scale; + half_scale.Scale(0.5, 0.5); + + gfx::Transform double_scale; + double_scale.Scale(2, 2); + + Occlusion all_occluded_outside_half( + half_scale, SimpleEnclosedRegion(10, 10), SimpleEnclosedRegion()); + Occlusion all_occluded_outside_double( + double_scale, SimpleEnclosedRegion(40, 40), SimpleEnclosedRegion()); + EXPECT_OCCLUSION(all_occluded_outside_half, rects, true, true, true, true); + EXPECT_OCCLUSION(all_occluded_outside_double, rects, true, true, true, true); + + Occlusion all_occluded_inside_half( + half_scale, SimpleEnclosedRegion(), SimpleEnclosedRegion(10, 10)); + Occlusion all_occluded_inside_double( + double_scale, SimpleEnclosedRegion(), SimpleEnclosedRegion(40, 40)); + EXPECT_OCCLUSION(all_occluded_inside_half, rects, true, true, true, true); + EXPECT_OCCLUSION(all_occluded_inside_double, rects, true, true, true, true); + + Occlusion all_occluded_mixed_half(half_scale, + SimpleEnclosedRegion(5, 10), + SimpleEnclosedRegion(5, 0, 5, 10)); + Occlusion all_occluded_mixed_double(double_scale, + SimpleEnclosedRegion(20, 40), + SimpleEnclosedRegion(20, 0, 20, 40)); + EXPECT_OCCLUSION(all_occluded_mixed_half, rects, true, true, true, true); + EXPECT_OCCLUSION(all_occluded_mixed_double, rects, true, true, true, true); + + Occlusion some_occluded_half( + half_scale, SimpleEnclosedRegion(5, 5), SimpleEnclosedRegion(5, 5, 5, 5)); + Occlusion some_occluded_double(double_scale, + SimpleEnclosedRegion(20, 20), + SimpleEnclosedRegion(20, 20, 20, 20)); + EXPECT_OCCLUSION(some_occluded_half, rects, true, false, false, true); + EXPECT_OCCLUSION(some_occluded_double, rects, true, false, false, true); +} + +TEST(OcclusionTest, IsOccludedTranslated) { + gfx::Rect rects[] = {gfx::Rect(10, 10), + gfx::Rect(10, 0, 10, 10), + gfx::Rect(0, 10, 10, 10), + gfx::Rect(10, 10, 10, 10)}; + + gfx::Transform move_left; + move_left.Translate(-100, 0); + + gfx::Transform move_down; + move_down.Translate(0, 100); + + Occlusion all_occluded_outside_left( + move_left, SimpleEnclosedRegion(-100, 0, 20, 20), SimpleEnclosedRegion()); + Occlusion all_occluded_outside_down( + move_down, SimpleEnclosedRegion(0, 100, 20, 20), SimpleEnclosedRegion()); + EXPECT_OCCLUSION(all_occluded_outside_left, rects, true, true, true, true); + EXPECT_OCCLUSION(all_occluded_outside_down, rects, true, true, true, true); + + Occlusion all_occluded_inside_left( + move_left, SimpleEnclosedRegion(), SimpleEnclosedRegion(-100, 0, 20, 20)); + Occlusion all_occluded_inside_down( + move_down, SimpleEnclosedRegion(), SimpleEnclosedRegion(0, 100, 20, 20)); + EXPECT_OCCLUSION(all_occluded_inside_left, rects, true, true, true, true); + EXPECT_OCCLUSION(all_occluded_inside_down, rects, true, true, true, true); + + Occlusion all_occluded_mixed_left(move_left, + SimpleEnclosedRegion(-100, 0, 10, 20), + SimpleEnclosedRegion(-90, 0, 10, 20)); + Occlusion all_occluded_mixed_down(move_down, + SimpleEnclosedRegion(0, 100, 10, 20), + SimpleEnclosedRegion(10, 100, 10, 20)); + EXPECT_OCCLUSION(all_occluded_mixed_left, rects, true, true, true, true); + EXPECT_OCCLUSION(all_occluded_mixed_down, rects, true, true, true, true); + + Occlusion some_occluded_left(move_left, + SimpleEnclosedRegion(-100, 0, 10, 10), + SimpleEnclosedRegion(-90, 10, 10, 10)); + Occlusion some_occluded_down(move_down, + SimpleEnclosedRegion(0, 100, 10, 10), + SimpleEnclosedRegion(10, 110, 10, 10)); + EXPECT_OCCLUSION(some_occluded_left, rects, true, false, false, true); + EXPECT_OCCLUSION(some_occluded_down, rects, true, false, false, true); +} + +TEST(OcclusionTest, IsOccludedScaledAfterConstruction) { + gfx::Rect rects[] = {gfx::Rect(10, 10), + gfx::Rect(10, 0, 10, 10), + gfx::Rect(0, 10, 10, 10), + gfx::Rect(10, 10, 10, 10)}; + + gfx::Transform half_transform; + half_transform.Scale(0.5, 0.5); + + gfx::Transform double_transform; + double_transform.Scale(2, 2); + + Occlusion all_occluded_outside( + gfx::Transform(), SimpleEnclosedRegion(10, 10), SimpleEnclosedRegion()); + Occlusion all_occluded_outside_half = + all_occluded_outside.GetOcclusionWithGivenDrawTransform(half_transform); + + all_occluded_outside = Occlusion( + gfx::Transform(), SimpleEnclosedRegion(40, 40), SimpleEnclosedRegion()); + Occlusion all_occluded_outside_double = + all_occluded_outside.GetOcclusionWithGivenDrawTransform(double_transform); + + EXPECT_OCCLUSION(all_occluded_outside_half, rects, true, true, true, true); + EXPECT_OCCLUSION(all_occluded_outside_double, rects, true, true, true, true); + + Occlusion some_occluded(gfx::Transform(), + SimpleEnclosedRegion(5, 5), + SimpleEnclosedRegion(5, 5, 5, 5)); + Occlusion some_occluded_half = + some_occluded.GetOcclusionWithGivenDrawTransform(half_transform); + + some_occluded = Occlusion(gfx::Transform(), + SimpleEnclosedRegion(20, 20), + SimpleEnclosedRegion(20, 20, 20, 20)); + Occlusion some_occluded_double = + some_occluded.GetOcclusionWithGivenDrawTransform(double_transform); + + EXPECT_OCCLUSION(some_occluded_half, rects, true, false, false, true); + EXPECT_OCCLUSION(some_occluded_double, rects, true, false, false, true); +} + +TEST(OcclusionTest, GetUnoccludedContentRectNoTransform) { + Occlusion some_occluded(gfx::Transform(), + SimpleEnclosedRegion(10, 10), + SimpleEnclosedRegion(10, 10, 10, 10)); + + gfx::Rect full_query_result = + some_occluded.GetUnoccludedContentRect(gfx::Rect(20, 20)); + EXPECT_EQ(gfx::Rect(20, 20), full_query_result); + + gfx::Rect half_query_result = + some_occluded.GetUnoccludedContentRect(gfx::Rect(10, 0, 10, 20)); + EXPECT_EQ(gfx::Rect(10, 0, 10, 10), half_query_result); +} + +TEST(OcclusionTest, GetUnoccludedContentRectScaled) { + gfx::Transform half_scale; + half_scale.Scale(0.5, 0.5); + + gfx::Transform double_scale; + double_scale.Scale(2, 2); + + Occlusion some_occluded_half( + half_scale, SimpleEnclosedRegion(5, 5), SimpleEnclosedRegion(5, 5, 5, 5)); + Occlusion some_occluded_double(double_scale, + SimpleEnclosedRegion(20, 20), + SimpleEnclosedRegion(20, 20, 20, 20)); + gfx::Rect full_query_result_half = + some_occluded_half.GetUnoccludedContentRect(gfx::Rect(20, 20)); + gfx::Rect full_query_result_double = + some_occluded_double.GetUnoccludedContentRect(gfx::Rect(20, 20)); + EXPECT_EQ(gfx::Rect(20, 20), full_query_result_half); + EXPECT_EQ(gfx::Rect(20, 20), full_query_result_double); + + gfx::Rect half_query_result_half = + some_occluded_half.GetUnoccludedContentRect(gfx::Rect(10, 0, 10, 20)); + gfx::Rect half_query_result_double = + some_occluded_half.GetUnoccludedContentRect(gfx::Rect(10, 0, 10, 20)); + EXPECT_EQ(gfx::Rect(10, 0, 10, 10), half_query_result_half); + EXPECT_EQ(gfx::Rect(10, 0, 10, 10), half_query_result_double); +} + +TEST(OcclusionTest, GetUnoccludedContentRectTranslated) { + gfx::Transform move_left; + move_left.Translate(-100, 0); + + gfx::Transform move_down; + move_down.Translate(0, 100); + + Occlusion some_occluded_left(move_left, + SimpleEnclosedRegion(-100, 0, 10, 10), + SimpleEnclosedRegion(-90, 10, 10, 10)); + Occlusion some_occluded_down(move_down, + SimpleEnclosedRegion(0, 100, 0, 10), + SimpleEnclosedRegion(10, 110, 10, 10)); + + gfx::Rect full_query_result_left = + some_occluded_left.GetUnoccludedContentRect(gfx::Rect(20, 20)); + gfx::Rect full_query_result_down = + some_occluded_down.GetUnoccludedContentRect(gfx::Rect(20, 20)); + EXPECT_EQ(gfx::Rect(20, 20), full_query_result_left); + EXPECT_EQ(gfx::Rect(20, 20), full_query_result_down); + + gfx::Rect half_query_result_left = + some_occluded_left.GetUnoccludedContentRect(gfx::Rect(10, 0, 10, 20)); + gfx::Rect half_query_result_down = + some_occluded_down.GetUnoccludedContentRect(gfx::Rect(10, 0, 10, 20)); + EXPECT_EQ(gfx::Rect(10, 0, 10, 10), half_query_result_left); + EXPECT_EQ(gfx::Rect(10, 0, 10, 10), half_query_result_down); +} + +} // namespace +} // namespace cc diff --git a/chromium/cc/trees/proxy.cc b/chromium/cc/trees/proxy.cc index a8f7b26fb04..e981a722cad 100644 --- a/chromium/cc/trees/proxy.cc +++ b/chromium/cc/trees/proxy.cc @@ -6,6 +6,7 @@ #include "base/message_loop/message_loop_proxy.h" #include "base/single_thread_task_runner.h" +#include "cc/trees/blocking_task_runner.h" namespace cc { @@ -66,12 +67,18 @@ void Proxy::SetMainThreadBlocked(bool is_main_thread_blocked) { } #endif -Proxy::Proxy(scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner) - : main_task_runner_(base::MessageLoopProxy::current()), +Proxy::Proxy(scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner) #if !DCHECK_IS_ON - impl_task_runner_(impl_task_runner) { + : main_task_runner_(main_task_runner), + impl_task_runner_(impl_task_runner), + blocking_main_thread_task_runner_( + BlockingTaskRunner::Create(main_task_runner)) { #else + : main_task_runner_(main_task_runner), impl_task_runner_(impl_task_runner), + blocking_main_thread_task_runner_( + BlockingTaskRunner::Create(main_task_runner)), main_thread_id_(base::PlatformThread::CurrentId()), impl_thread_is_overridden_(false), is_main_thread_blocked_(false) { @@ -82,8 +89,4 @@ Proxy::~Proxy() { DCHECK(IsMainThread()); } -scoped_ptr<base::Value> Proxy::SchedulerAsValueForTesting() { - return make_scoped_ptr(base::Value::CreateNullValue()); -} - } // namespace cc diff --git a/chromium/cc/trees/proxy.h b/chromium/cc/trees/proxy.h index 4066513773c..feeab43b507 100644 --- a/chromium/cc/trees/proxy.h +++ b/chromium/cc/trees/proxy.h @@ -16,7 +16,12 @@ #include "base/values.h" #include "cc/base/cc_export.h" -namespace base { class SingleThreadTaskRunner; } +namespace base { +namespace debug { +class TracedValue; +} +class SingleThreadTaskRunner; +} namespace gfx { class Rect; @@ -24,7 +29,7 @@ class Vector2d; } namespace cc { - +class BlockingTaskRunner; class LayerTreeDebugState; class OutputSurface; struct RendererCapabilities; @@ -52,6 +57,10 @@ class CC_EXPORT Proxy { virtual bool IsStarted() const = 0; + // Will call LayerTreeHost::OnCreateAndInitializeOutputSurfaceAttempted + // with the result of this function. + virtual void SetOutputSurface(scoped_ptr<OutputSurface> output_surface) = 0; + // Indicates that the compositing surface associated with our context is // ready to use. virtual void SetLayerTreeHostClientReady() = 0; @@ -89,17 +98,22 @@ class CC_EXPORT Proxy { // Maximum number of sub-region texture updates supported for each commit. virtual size_t MaxPartialTextureUpdates() const = 0; - virtual scoped_ptr<base::Value> AsValue() const = 0; + virtual bool SupportsImplScrolling() const = 0; + + virtual void AsValueInto(base::debug::TracedValue* value) const = 0; virtual void SetDebugState(const LayerTreeDebugState& debug_state) = 0; // Testing hooks - virtual bool CommitPendingForTesting() = 0; - virtual scoped_ptr<base::Value> SchedulerAsValueForTesting(); + virtual bool MainFrameWillHappenForTesting() = 0; + + BlockingTaskRunner* blocking_main_thread_task_runner() const { + return blocking_main_thread_task_runner_.get(); + } protected: - explicit Proxy( - scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner); + Proxy(scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner); friend class DebugScopedSetImplThread; friend class DebugScopedSetMainThread; friend class DebugScopedSetMainThreadBlocked; @@ -107,6 +121,8 @@ class CC_EXPORT Proxy { private: scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_; scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner_; + scoped_ptr<BlockingTaskRunner> blocking_main_thread_task_runner_; + #if DCHECK_IS_ON const base::PlatformThreadId main_thread_id_; bool impl_thread_is_overridden_; diff --git a/chromium/cc/trees/proxy_timing_history.cc b/chromium/cc/trees/proxy_timing_history.cc index e920f285697..9020ad51ef1 100644 --- a/chromium/cc/trees/proxy_timing_history.cc +++ b/chromium/cc/trees/proxy_timing_history.cc @@ -4,6 +4,8 @@ #include "cc/trees/proxy_timing_history.h" +#include "base/metrics/histogram.h" + const size_t kDurationHistorySize = 60; const double kCommitAndActivationDurationEstimationPercentile = 50.0; const double kDrawDurationEstimationPercentile = 100.0; @@ -11,10 +13,13 @@ const int kDrawDurationEstimatePaddingInMicroseconds = 0; namespace cc { -ProxyTimingHistory::ProxyTimingHistory() +ProxyTimingHistory::ProxyTimingHistory( + RenderingStatsInstrumentation* rendering_stats_instrumentation) : draw_duration_history_(kDurationHistorySize), begin_main_frame_to_commit_duration_history_(kDurationHistorySize), - commit_to_activate_duration_history_(kDurationHistorySize) {} + commit_to_activate_duration_history_(kDurationHistorySize), + rendering_stats_instrumentation_(rendering_stats_instrumentation) { +} ProxyTimingHistory::~ProxyTimingHistory() {} @@ -43,24 +48,78 @@ void ProxyTimingHistory::DidBeginMainFrame() { void ProxyTimingHistory::DidCommit() { commit_complete_time_ = base::TimeTicks::HighResNow(); + base::TimeDelta begin_main_frame_to_commit_duration = + commit_complete_time_ - begin_main_frame_sent_time_; + + // Before adding the new data point to the timing history, see what we would + // have predicted for this frame. This allows us to keep track of the accuracy + // of our predictions. + rendering_stats_instrumentation_->AddBeginMainFrameToCommitDuration( + begin_main_frame_to_commit_duration, + BeginMainFrameToCommitDurationEstimate()); + begin_main_frame_to_commit_duration_history_.InsertSample( - commit_complete_time_ - begin_main_frame_sent_time_); + begin_main_frame_to_commit_duration); } -void ProxyTimingHistory::DidActivatePendingTree() { +void ProxyTimingHistory::DidActivateSyncTree() { + base::TimeDelta commit_to_activate_duration = + base::TimeTicks::HighResNow() - commit_complete_time_; + + // Before adding the new data point to the timing history, see what we would + // have predicted for this frame. This allows us to keep track of the accuracy + // of our predictions. + rendering_stats_instrumentation_->AddCommitToActivateDuration( + commit_to_activate_duration, CommitToActivateDurationEstimate()); + commit_to_activate_duration_history_.InsertSample( - base::TimeTicks::HighResNow() - commit_complete_time_); + commit_to_activate_duration); } void ProxyTimingHistory::DidStartDrawing() { start_draw_time_ = base::TimeTicks::HighResNow(); } -base::TimeDelta ProxyTimingHistory::DidFinishDrawing() { +void ProxyTimingHistory::DidFinishDrawing() { base::TimeDelta draw_duration = base::TimeTicks::HighResNow() - start_draw_time_; + + // Before adding the new data point to the timing history, see what we would + // have predicted for this frame. This allows us to keep track of the accuracy + // of our predictions. + base::TimeDelta draw_duration_estimate = DrawDurationEstimate(); + rendering_stats_instrumentation_->AddDrawDuration(draw_duration, + draw_duration_estimate); + + AddDrawDurationUMA(draw_duration, draw_duration_estimate); + draw_duration_history_.InsertSample(draw_duration); - return draw_duration; +} + +void ProxyTimingHistory::AddDrawDurationUMA( + base::TimeDelta draw_duration, + base::TimeDelta draw_duration_estimate) { + base::TimeDelta draw_duration_overestimate; + base::TimeDelta draw_duration_underestimate; + if (draw_duration > draw_duration_estimate) + draw_duration_underestimate = draw_duration - draw_duration_estimate; + else + draw_duration_overestimate = draw_duration_estimate - draw_duration; + UMA_HISTOGRAM_CUSTOM_TIMES("Renderer.DrawDuration", + draw_duration, + base::TimeDelta::FromMilliseconds(1), + base::TimeDelta::FromMilliseconds(100), + 50); + UMA_HISTOGRAM_CUSTOM_TIMES("Renderer.DrawDurationUnderestimate", + draw_duration_underestimate, + base::TimeDelta::FromMilliseconds(1), + base::TimeDelta::FromMilliseconds(100), + 50); + UMA_HISTOGRAM_CUSTOM_TIMES("Renderer.DrawDurationOverestimate", + draw_duration_overestimate, + base::TimeDelta::FromMilliseconds(1), + base::TimeDelta::FromMilliseconds(100), + 50); } } // namespace cc diff --git a/chromium/cc/trees/proxy_timing_history.h b/chromium/cc/trees/proxy_timing_history.h index 01a92d93a03..aa213b6bdb7 100644 --- a/chromium/cc/trees/proxy_timing_history.h +++ b/chromium/cc/trees/proxy_timing_history.h @@ -6,12 +6,14 @@ #define CC_TREES_PROXY_TIMING_HISTORY_H_ #include "cc/base/rolling_time_delta_history.h" +#include "cc/debug/rendering_stats_instrumentation.h" namespace cc { class ProxyTimingHistory { public: - ProxyTimingHistory(); + explicit ProxyTimingHistory( + RenderingStatsInstrumentation* rendering_stats_instrumentation); ~ProxyTimingHistory(); base::TimeDelta DrawDurationEstimate() const; @@ -20,12 +22,14 @@ class ProxyTimingHistory { void DidBeginMainFrame(); void DidCommit(); - void DidActivatePendingTree(); + void DidActivateSyncTree(); void DidStartDrawing(); - // Returns draw duration. - base::TimeDelta DidFinishDrawing(); + void DidFinishDrawing(); protected: + void AddDrawDurationUMA(base::TimeDelta draw_duration, + base::TimeDelta draw_duration_estimate); + RollingTimeDeltaHistory draw_duration_history_; RollingTimeDeltaHistory begin_main_frame_to_commit_duration_history_; RollingTimeDeltaHistory commit_to_activate_duration_history_; @@ -33,6 +37,8 @@ class ProxyTimingHistory { base::TimeTicks begin_main_frame_sent_time_; base::TimeTicks commit_complete_time_; base::TimeTicks start_draw_time_; + + RenderingStatsInstrumentation* rendering_stats_instrumentation_; }; } // namespace cc diff --git a/chromium/cc/trees/scoped_abort_remaining_swap_promises.h b/chromium/cc/trees/scoped_abort_remaining_swap_promises.h new file mode 100644 index 00000000000..f8dfc017e72 --- /dev/null +++ b/chromium/cc/trees/scoped_abort_remaining_swap_promises.h @@ -0,0 +1,30 @@ +// 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 CC_TREES_SCOPED_ABORT_REMAINING_SWAP_PROMISES_H_ +#define CC_TREES_SCOPED_ABORT_REMAINING_SWAP_PROMISES_H_ + +#include "cc/base/swap_promise.h" +#include "cc/trees/layer_tree_host.h" + +namespace cc { + +class ScopedAbortRemainingSwapPromises { + public: + explicit ScopedAbortRemainingSwapPromises(LayerTreeHost* layer_tree_host) + : layer_tree_host_(layer_tree_host) {} + + ~ScopedAbortRemainingSwapPromises() { + layer_tree_host_->BreakSwapPromises(SwapPromise::COMMIT_FAILS); + } + + private: + LayerTreeHost* layer_tree_host_; + + DISALLOW_COPY_AND_ASSIGN(ScopedAbortRemainingSwapPromises); +}; + +} // namespace cc + +#endif // CC_TREES_SCOPED_ABORT_REMAINING_SWAP_PROMISES_H_ diff --git a/chromium/cc/trees/single_thread_proxy.cc b/chromium/cc/trees/single_thread_proxy.cc index c254311a930..1af657a3d0e 100644 --- a/chromium/cc/trees/single_thread_proxy.cc +++ b/chromium/cc/trees/single_thread_proxy.cc @@ -12,35 +12,41 @@ #include "cc/quads/draw_quad.h" #include "cc/resources/prioritized_resource_manager.h" #include "cc/resources/resource_update_controller.h" -#include "cc/trees/blocking_task_runner.h" #include "cc/trees/layer_tree_host.h" #include "cc/trees/layer_tree_host_single_thread_client.h" #include "cc/trees/layer_tree_impl.h" +#include "cc/trees/scoped_abort_remaining_swap_promises.h" #include "ui/gfx/frame_time.h" namespace cc { scoped_ptr<Proxy> SingleThreadProxy::Create( LayerTreeHost* layer_tree_host, - LayerTreeHostSingleThreadClient* client) { + LayerTreeHostSingleThreadClient* client, + scoped_refptr<base::SingleThreadTaskRunner> main_task_runner) { return make_scoped_ptr( - new SingleThreadProxy(layer_tree_host, client)).PassAs<Proxy>(); + new SingleThreadProxy(layer_tree_host, client, main_task_runner)); } -SingleThreadProxy::SingleThreadProxy(LayerTreeHost* layer_tree_host, - LayerTreeHostSingleThreadClient* client) - : Proxy(NULL), +SingleThreadProxy::SingleThreadProxy( + LayerTreeHost* layer_tree_host, + LayerTreeHostSingleThreadClient* client, + scoped_refptr<base::SingleThreadTaskRunner> main_task_runner) + : Proxy(main_task_runner, NULL), layer_tree_host_(layer_tree_host), client_(client), + timing_history_(layer_tree_host->rendering_stats_instrumentation()), next_frame_is_newly_committed_frame_(false), - inside_draw_(false) { + inside_draw_(false), + defer_commits_(false), + commit_was_deferred_(false), + commit_requested_(false), + inside_synchronous_composite_(false), + output_surface_creation_requested_(false), + weak_factory_(this) { TRACE_EVENT0("cc", "SingleThreadProxy::SingleThreadProxy"); DCHECK(Proxy::IsMainThread()); DCHECK(layer_tree_host); - - // Impl-side painting not supported without threaded compositing. - CHECK(!layer_tree_host->settings().impl_side_painting) - << "Threaded compositing must be enabled to use impl-side painting."; } void SingleThreadProxy::Start() { @@ -73,26 +79,46 @@ void SingleThreadProxy::SetLayerTreeHostClientReady() { TRACE_EVENT0("cc", "SingleThreadProxy::SetLayerTreeHostClientReady"); // Scheduling is controlled by the embedder in the single thread case, so // nothing to do. + DCHECK(Proxy::IsMainThread()); + DebugScopedSetImplThread impl(this); + if (layer_tree_host_->settings().single_thread_proxy_scheduler && + !scheduler_on_impl_thread_) { + SchedulerSettings scheduler_settings(layer_tree_host_->settings()); + scheduler_on_impl_thread_ = Scheduler::Create(this, + scheduler_settings, + layer_tree_host_->id(), + MainThreadTaskRunner(), + base::PowerMonitor::Get()); + scheduler_on_impl_thread_->SetCanStart(); + scheduler_on_impl_thread_->SetVisible(layer_tree_host_impl_->visible()); + } } void SingleThreadProxy::SetVisible(bool visible) { TRACE_EVENT0("cc", "SingleThreadProxy::SetVisible"); DebugScopedSetImplThread impl(this); layer_tree_host_impl_->SetVisible(visible); - + if (scheduler_on_impl_thread_) + scheduler_on_impl_thread_->SetVisible(layer_tree_host_impl_->visible()); // Changing visibility could change ShouldComposite(). UpdateBackgroundAnimateTicking(); } -void SingleThreadProxy::CreateAndInitializeOutputSurface() { - TRACE_EVENT0( - "cc", "SingleThreadProxy::CreateAndInitializeOutputSurface"); +void SingleThreadProxy::RequestNewOutputSurface() { DCHECK(Proxy::IsMainThread()); DCHECK(layer_tree_host_->output_surface_lost()); + output_surface_creation_callback_.Cancel(); + if (output_surface_creation_requested_) + return; + output_surface_creation_requested_ = true; + layer_tree_host_->RequestNewOutputSurface(); +} - scoped_ptr<OutputSurface> output_surface = - layer_tree_host_->CreateOutputSurface(); - +void SingleThreadProxy::SetOutputSurface( + scoped_ptr<OutputSurface> output_surface) { + DCHECK(Proxy::IsMainThread()); + DCHECK(layer_tree_host_->output_surface_lost()); + output_surface_creation_requested_ = false; renderer_capabilities_for_main_thread_ = RendererCapabilities(); bool success = !!output_surface; @@ -106,9 +132,13 @@ void SingleThreadProxy::CreateAndInitializeOutputSurface() { layer_tree_host_->OnCreateAndInitializeOutputSurfaceAttempted(success); - if (!success) { - // Force another recreation attempt to happen by requesting another commit. - SetNeedsCommit(); + if (success) { + if (scheduler_on_impl_thread_) + scheduler_on_impl_thread_->DidCreateAndInitializeOutputSurface(); + else if (!inside_synchronous_composite_) + SetNeedsCommit(); + } else if (Proxy::MainThreadTaskRunner()) { + ScheduleRequestNewOutputSurface(); } } @@ -122,17 +152,22 @@ void SingleThreadProxy::SetNeedsAnimate() { TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsAnimate"); DCHECK(Proxy::IsMainThread()); client_->ScheduleAnimation(); + SetNeedsCommit(); } void SingleThreadProxy::SetNeedsUpdateLayers() { TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsUpdateLayers"); DCHECK(Proxy::IsMainThread()); - client_->ScheduleComposite(); + SetNeedsCommit(); } -void SingleThreadProxy::DoCommit(scoped_ptr<ResourceUpdateQueue> queue) { +void SingleThreadProxy::DoCommit() { TRACE_EVENT0("cc", "SingleThreadProxy::DoCommit"); DCHECK(Proxy::IsMainThread()); + + commit_requested_ = false; + layer_tree_host_->WillCommit(); + // Commit immediately. { DebugScopedSetMainThreadBlocked main_thread_blocked(this); @@ -141,7 +176,8 @@ void SingleThreadProxy::DoCommit(scoped_ptr<ResourceUpdateQueue> queue) { // This CapturePostTasks should be destroyed before CommitComplete() is // called since that goes out to the embedder, and we want the embedder // to receive its callbacks before that. - BlockingTaskRunner::CapturePostTasks blocked; + commit_blocking_task_runner_.reset(new BlockingTaskRunner::CapturePostTasks( + blocking_main_thread_task_runner())); layer_tree_host_impl_->BeginCommit(); @@ -154,8 +190,8 @@ void SingleThreadProxy::DoCommit(scoped_ptr<ResourceUpdateQueue> queue) { scoped_ptr<ResourceUpdateController> update_controller = ResourceUpdateController::Create( NULL, - Proxy::MainThreadTaskRunner(), - queue.Pass(), + MainThreadTaskRunner(), + queue_for_commit_.Pass(), layer_tree_host_impl_->resource_provider()); update_controller->Finalize(); @@ -166,6 +202,8 @@ void SingleThreadProxy::DoCommit(scoped_ptr<ResourceUpdateQueue> queue) { layer_tree_host_impl_->CommitComplete(); + UpdateBackgroundAnimateTicking(); + #if DCHECK_IS_ON // In the single-threaded case, the scale and scroll deltas should never be // touched on the impl layer tree. @@ -177,37 +215,93 @@ void SingleThreadProxy::DoCommit(scoped_ptr<ResourceUpdateQueue> queue) { RenderingStatsInstrumentation* stats_instrumentation = layer_tree_host_->rendering_stats_instrumentation(); - BenchmarkInstrumentation::IssueMainThreadRenderingStatsEvent( + benchmark_instrumentation::IssueMainThreadRenderingStatsEvent( stats_instrumentation->main_thread_rendering_stats()); stats_instrumentation->AccumulateAndClearMainThreadStats(); } + + if (layer_tree_host_->settings().impl_side_painting) { + // TODO(enne): just commit directly to the active tree. + // + // Synchronously activate during commit to satisfy any potential + // SetNextCommitWaitsForActivation calls. Unfortunately, the tree + // might not be ready to draw, so DidActivateSyncTree must set + // the flag to force the tree to not draw until textures are ready. + NotifyReadyToActivate(); + } else { + CommitComplete(); + } +} + +void SingleThreadProxy::CommitComplete() { + DCHECK(!layer_tree_host_impl_->pending_tree()) + << "Activation is expected to have synchronously occurred by now."; + DCHECK(commit_blocking_task_runner_); + + DebugScopedSetMainThread main(this); + commit_blocking_task_runner_.reset(); layer_tree_host_->CommitComplete(); + layer_tree_host_->DidBeginMainFrame(); + timing_history_.DidCommit(); + next_frame_is_newly_committed_frame_ = true; } void SingleThreadProxy::SetNeedsCommit() { DCHECK(Proxy::IsMainThread()); + DebugScopedSetImplThread impl(this); client_->ScheduleComposite(); + if (scheduler_on_impl_thread_) + scheduler_on_impl_thread_->SetNeedsCommit(); + commit_requested_ = true; } void SingleThreadProxy::SetNeedsRedraw(const gfx::Rect& damage_rect) { TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsRedraw"); - SetNeedsRedrawRectOnImplThread(damage_rect); + DCHECK(Proxy::IsMainThread()); + DebugScopedSetImplThread impl(this); client_->ScheduleComposite(); + SetNeedsRedrawRectOnImplThread(damage_rect); } void SingleThreadProxy::SetNextCommitWaitsForActivation() { - // There is no activation here other than commit. So do nothing. + // Activation always forced in commit, so nothing to do. + DCHECK(Proxy::IsMainThread()); } void SingleThreadProxy::SetDeferCommits(bool defer_commits) { - // Thread-only feature. - NOTREACHED(); + DCHECK(Proxy::IsMainThread()); + // Deferring commits only makes sense if there's a scheduler. + if (!scheduler_on_impl_thread_) + return; + if (defer_commits_ == defer_commits) + return; + + if (defer_commits) + TRACE_EVENT_ASYNC_BEGIN0("cc", "SingleThreadProxy::SetDeferCommits", this); + else + TRACE_EVENT_ASYNC_END0("cc", "SingleThreadProxy::SetDeferCommits", this); + + defer_commits_ = defer_commits; + if (!defer_commits_ && commit_was_deferred_) { + commit_was_deferred_ = false; + BeginMainFrame(); + } } -bool SingleThreadProxy::CommitRequested() const { return false; } +bool SingleThreadProxy::CommitRequested() const { + DCHECK(Proxy::IsMainThread()); + return commit_requested_; +} -bool SingleThreadProxy::BeginMainFrameRequested() const { return false; } +bool SingleThreadProxy::BeginMainFrameRequested() const { + DCHECK(Proxy::IsMainThread()); + // If there is no scheduler, then there can be no pending begin frame, + // as all frames are all manually initiated by the embedder of cc. + if (!scheduler_on_impl_thread_) + return false; + return commit_requested_; +} size_t SingleThreadProxy::MaxPartialTextureUpdates() const { return std::numeric_limits<size_t>::max(); @@ -220,10 +314,12 @@ void SingleThreadProxy::Stop() { DebugScopedSetMainThreadBlocked main_thread_blocked(this); DebugScopedSetImplThread impl(this); - BlockingTaskRunner::CapturePostTasks blocked; + BlockingTaskRunner::CapturePostTasks blocked( + blocking_main_thread_task_runner()); layer_tree_host_->DeleteContentsTexturesOnImplThread( layer_tree_host_impl_->resource_provider()); - layer_tree_host_impl_.reset(); + scheduler_on_impl_thread_ = nullptr; + layer_tree_host_impl_ = nullptr; } layer_tree_host_ = NULL; } @@ -233,15 +329,21 @@ void SingleThreadProxy::OnCanDrawStateChanged(bool can_draw) { "cc", "SingleThreadProxy::OnCanDrawStateChanged", "can_draw", can_draw); DCHECK(Proxy::IsImplThread()); UpdateBackgroundAnimateTicking(); + if (scheduler_on_impl_thread_) + scheduler_on_impl_thread_->SetCanDraw(can_draw); } void SingleThreadProxy::NotifyReadyToActivate() { - // Thread-only feature. - NOTREACHED(); + TRACE_EVENT0("cc", "SingleThreadProxy::NotifyReadyToActivate"); + DebugScopedSetImplThread impl(this); + if (scheduler_on_impl_thread_) + scheduler_on_impl_thread_->NotifyReadyToActivate(); } void SingleThreadProxy::SetNeedsRedrawOnImplThread() { client_->ScheduleComposite(); + if (scheduler_on_impl_thread_) + scheduler_on_impl_thread_->SetNeedsRedraw(); } void SingleThreadProxy::SetNeedsAnimateOnImplThread() { @@ -249,26 +351,27 @@ void SingleThreadProxy::SetNeedsAnimateOnImplThread() { } void SingleThreadProxy::SetNeedsManageTilesOnImplThread() { - // Thread-only/Impl-side-painting-only feature. - NOTREACHED(); + TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsManageTilesOnImplThread"); + if (scheduler_on_impl_thread_) + scheduler_on_impl_thread_->SetNeedsManageTiles(); } void SingleThreadProxy::SetNeedsRedrawRectOnImplThread( const gfx::Rect& damage_rect) { - // TODO(brianderson): Once we move render_widget scheduling into this class, - // we can treat redraw requests more efficiently than CommitAndRedraw - // requests. layer_tree_host_impl_->SetViewportDamage(damage_rect); - SetNeedsCommit(); + SetNeedsRedrawOnImplThread(); } void SingleThreadProxy::DidInitializeVisibleTileOnImplThread() { - // Impl-side painting only. - NOTREACHED(); + TRACE_EVENT0("cc", "SingleThreadProxy::DidInitializeVisibleTileOnImplThread"); + if (scheduler_on_impl_thread_) + scheduler_on_impl_thread_->SetNeedsRedraw(); } void SingleThreadProxy::SetNeedsCommitOnImplThread() { client_->ScheduleComposite(); + if (scheduler_on_impl_thread_) + scheduler_on_impl_thread_->SetNeedsCommit(); } void SingleThreadProxy::PostAnimationEventsToMainThreadOnImplThread( @@ -299,6 +402,35 @@ bool SingleThreadProxy::ReduceContentsTextureMemoryOnImplThread( bool SingleThreadProxy::IsInsideDraw() { return inside_draw_; } +void SingleThreadProxy::DidActivateSyncTree() { + // Non-impl-side painting finishes commit in DoCommit. Impl-side painting + // defers until here to simulate SetNextCommitWaitsForActivation. + if (layer_tree_host_impl_->settings().impl_side_painting) { + // This is required because NotifyReadyToActivate gets called when + // the pending tree is not actually ready in the SingleThreadProxy. + layer_tree_host_impl_->SetRequiresHighResToDraw(); + + // Since activation could cause tasks to run, post CommitComplete + // separately so that it runs after these tasks. This is the loose + // equivalent of blocking commit until activation and also running + // all tasks posted during commit/activation before CommitComplete. + MainThreadTaskRunner()->PostTask( + FROM_HERE, + base::Bind(&SingleThreadProxy::CommitComplete, + weak_factory_.GetWeakPtr())); + } + + UpdateBackgroundAnimateTicking(); + timing_history_.DidActivateSyncTree(); +} + +void SingleThreadProxy::DidManageTiles() { + DCHECK(layer_tree_host_impl_->settings().impl_side_painting); + DCHECK(Proxy::IsImplThread()); + if (scheduler_on_impl_thread_) + scheduler_on_impl_thread_->DidManageTiles(); +} + void SingleThreadProxy::UpdateRendererCapabilitiesOnImplThread() { DCHECK(IsImplThread()); renderer_capabilities_for_main_thread_ = @@ -307,78 +439,84 @@ void SingleThreadProxy::UpdateRendererCapabilitiesOnImplThread() { void SingleThreadProxy::DidLoseOutputSurfaceOnImplThread() { TRACE_EVENT0("cc", "SingleThreadProxy::DidLoseOutputSurfaceOnImplThread"); - // Cause a commit so we can notice the lost context. - SetNeedsCommitOnImplThread(); + { + DebugScopedSetMainThread main(this); + // This must happen before we notify the scheduler as it may try to recreate + // the output surface if already in BEGIN_IMPL_FRAME_STATE_IDLE. + layer_tree_host_->DidLoseOutputSurface(); + } client_->DidAbortSwapBuffers(); + if (scheduler_on_impl_thread_) + scheduler_on_impl_thread_->DidLoseOutputSurface(); } void SingleThreadProxy::DidSwapBuffersOnImplThread() { + TRACE_EVENT0("cc", "SingleThreadProxy::DidSwapBuffersOnImplThread"); + if (scheduler_on_impl_thread_) + scheduler_on_impl_thread_->DidSwapBuffers(); client_->DidPostSwapBuffers(); } void SingleThreadProxy::DidSwapBuffersCompleteOnImplThread() { TRACE_EVENT0("cc", "SingleThreadProxy::DidSwapBuffersCompleteOnImplThread"); - client_->DidCompleteSwapBuffers(); + if (scheduler_on_impl_thread_) + scheduler_on_impl_thread_->DidSwapBuffersComplete(); + layer_tree_host_->DidCompleteSwapBuffers(); } -// Called by the legacy scheduling path (e.g. where render_widget does the -// scheduling) void SingleThreadProxy::CompositeImmediately(base::TimeTicks frame_begin_time) { TRACE_EVENT0("cc", "SingleThreadProxy::CompositeImmediately"); DCHECK(Proxy::IsMainThread()); - DCHECK(!layer_tree_host_->output_surface_lost()); - - layer_tree_host_->AnimateLayers(frame_begin_time); - - if (PrioritizedResourceManager* contents_texture_manager = - layer_tree_host_->contents_texture_manager()) { - contents_texture_manager->UnlinkAndClearEvictedBackings(); - contents_texture_manager->SetMaxMemoryLimitBytes( - layer_tree_host_impl_->memory_allocation_limit_bytes()); - contents_texture_manager->SetExternalPriorityCutoff( - layer_tree_host_impl_->memory_allocation_priority_cutoff()); + base::AutoReset<bool> inside_composite(&inside_synchronous_composite_, true); + + if (layer_tree_host_->output_surface_lost()) { + RequestNewOutputSurface(); + // RequestNewOutputSurface could have synchronously created an output + // surface, so check again before returning. + if (layer_tree_host_->output_surface_lost()) + return; } - scoped_ptr<ResourceUpdateQueue> queue = - make_scoped_ptr(new ResourceUpdateQueue); - layer_tree_host_->UpdateLayers(queue.get()); - layer_tree_host_->WillCommit(); - DoCommit(queue.Pass()); - layer_tree_host_->DidBeginMainFrame(); - - LayerTreeHostImpl::FrameData frame; - if (DoComposite(frame_begin_time, &frame)) { - { - DebugScopedSetMainThreadBlocked main_thread_blocked(this); - DebugScopedSetImplThread impl(this); - - // This CapturePostTasks should be destroyed before - // DidCommitAndDrawFrame() is called since that goes out to the embedder, - // and we want the embedder to receive its callbacks before that. - // NOTE: This maintains consistent ordering with the ThreadProxy since - // the DidCommitAndDrawFrame() must be post-tasked from the impl thread - // there as the main thread is not blocked, so any posted tasks inside - // the swap buffers will execute first. - BlockingTaskRunner::CapturePostTasks blocked; - - layer_tree_host_impl_->SwapBuffers(frame); - } - DidSwapFrame(); + { + BeginFrameArgs begin_frame_args( + BeginFrameArgs::Create(frame_begin_time, + base::TimeTicks(), + BeginFrameArgs::DefaultInterval())); + DoBeginMainFrame(begin_frame_args); + DoCommit(); + + DCHECK_EQ(0u, layer_tree_host_->num_queued_swap_promises()) + << "Commit should always succeed and transfer promises."; } -} -scoped_ptr<base::Value> SingleThreadProxy::AsValue() const { - scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); { - // The following line casts away const modifiers because it is just - // setting debug state. We still want the AsValue() function and its - // call chain to be const throughout. DebugScopedSetImplThread impl(const_cast<SingleThreadProxy*>(this)); + if (layer_tree_host_impl_->settings().impl_side_painting) { + layer_tree_host_impl_->ActivateSyncTree(); + layer_tree_host_impl_->active_tree()->UpdateDrawProperties(); + layer_tree_host_impl_->ManageTiles(); + layer_tree_host_impl_->SynchronouslyInitializeAllTiles(); + } + + LayerTreeHostImpl::FrameData frame; + DoComposite(frame_begin_time, &frame); - state->Set("layer_tree_host_impl", - layer_tree_host_impl_->AsValue().release()); + // DoComposite could abort, but because this is a synchronous composite + // another draw will never be scheduled, so break remaining promises. + layer_tree_host_impl_->active_tree()->BreakSwapPromises( + SwapPromise::SWAP_FAILS); } - return state.PassAs<base::Value>(); +} + +void SingleThreadProxy::AsValueInto(base::debug::TracedValue* state) const { + // The following line casts away const modifiers because it is just + // setting debug state. We still want the AsValue() function and its + // call chain to be const throughout. + DebugScopedSetImplThread impl(const_cast<SingleThreadProxy*>(this)); + + state->BeginDictionary("layer_tree_host_impl"); + layer_tree_host_impl_->AsValueInto(state); + state->EndDictionary(); } void SingleThreadProxy::ForceSerializeOnSwapBuffers() { @@ -391,6 +529,10 @@ void SingleThreadProxy::ForceSerializeOnSwapBuffers() { } } +bool SingleThreadProxy::SupportsImplScrolling() const { + return false; +} + bool SingleThreadProxy::ShouldComposite() const { DCHECK(Proxy::IsImplThread()); return layer_tree_host_impl_->visible() && @@ -403,13 +545,24 @@ void SingleThreadProxy::UpdateBackgroundAnimateTicking() { !ShouldComposite() && layer_tree_host_impl_->active_tree()->root_layer()); } -bool SingleThreadProxy::DoComposite( - base::TimeTicks frame_begin_time, - LayerTreeHostImpl::FrameData* frame) { +void SingleThreadProxy::ScheduleRequestNewOutputSurface() { + if (output_surface_creation_callback_.IsCancelled() && + !output_surface_creation_requested_) { + output_surface_creation_callback_.Reset( + base::Bind(&SingleThreadProxy::RequestNewOutputSurface, + weak_factory_.GetWeakPtr())); + MainThreadTaskRunner()->PostTask( + FROM_HERE, output_surface_creation_callback_.callback()); + } +} + +DrawResult SingleThreadProxy::DoComposite(base::TimeTicks frame_begin_time, + LayerTreeHostImpl::FrameData* frame) { TRACE_EVENT0("cc", "SingleThreadProxy::DoComposite"); DCHECK(!layer_tree_host_->output_surface_lost()); - bool lost_output_surface = false; + DrawResult draw_result; + bool draw_frame; { DebugScopedSetImplThread impl(this); base::AutoReset<bool> mark_inside(&inside_draw_, true); @@ -420,41 +573,227 @@ bool SingleThreadProxy::DoComposite( // CanDraw() as well. if (!ShouldComposite()) { UpdateBackgroundAnimateTicking(); - return false; + return DRAW_ABORTED_CANT_DRAW; } + timing_history_.DidStartDrawing(); + layer_tree_host_impl_->Animate( - layer_tree_host_impl_->CurrentFrameTimeTicks()); + layer_tree_host_impl_->CurrentBeginFrameArgs().frame_time); UpdateBackgroundAnimateTicking(); - if (!layer_tree_host_impl_->IsContextLost()) { - layer_tree_host_impl_->PrepareToDraw(frame); + draw_result = layer_tree_host_impl_->PrepareToDraw(frame); + draw_frame = draw_result == DRAW_SUCCESS; + if (draw_frame) layer_tree_host_impl_->DrawLayers(frame, frame_begin_time); - layer_tree_host_impl_->DidDrawAllLayers(*frame); - } - lost_output_surface = layer_tree_host_impl_->IsContextLost(); + layer_tree_host_impl_->DidDrawAllLayers(*frame); - bool start_ready_animations = true; + bool start_ready_animations = draw_frame; layer_tree_host_impl_->UpdateAnimationState(start_ready_animations); + layer_tree_host_impl_->ResetCurrentBeginFrameArgsForNextFrame(); - layer_tree_host_impl_->ResetCurrentFrameTimeForNextFrame(); + timing_history_.DidFinishDrawing(); } - if (lost_output_surface) { - layer_tree_host_->DidLoseOutputSurface(); - return false; + if (draw_frame) { + DebugScopedSetImplThread impl(this); + + // This CapturePostTasks should be destroyed before + // DidCommitAndDrawFrame() is called since that goes out to the + // embedder, + // and we want the embedder to receive its callbacks before that. + // NOTE: This maintains consistent ordering with the ThreadProxy since + // the DidCommitAndDrawFrame() must be post-tasked from the impl thread + // there as the main thread is not blocked, so any posted tasks inside + // the swap buffers will execute first. + DebugScopedSetMainThreadBlocked main_thread_blocked(this); + + BlockingTaskRunner::CapturePostTasks blocked( + blocking_main_thread_task_runner()); + layer_tree_host_impl_->SwapBuffers(*frame); } + DidCommitAndDrawFrame(); - return true; + return draw_result; } -void SingleThreadProxy::DidSwapFrame() { +void SingleThreadProxy::DidCommitAndDrawFrame() { if (next_frame_is_newly_committed_frame_) { + DebugScopedSetMainThread main(this); next_frame_is_newly_committed_frame_ = false; layer_tree_host_->DidCommitAndDrawFrame(); } } -bool SingleThreadProxy::CommitPendingForTesting() { return false; } +bool SingleThreadProxy::MainFrameWillHappenForTesting() { + return false; +} + +BeginFrameSource* SingleThreadProxy::ExternalBeginFrameSource() { + return layer_tree_host_impl_.get(); +} + +void SingleThreadProxy::WillBeginImplFrame(const BeginFrameArgs& args) { + layer_tree_host_impl_->WillBeginImplFrame(args); +} + +void SingleThreadProxy::ScheduledActionSendBeginMainFrame() { + TRACE_EVENT0("cc", "SingleThreadProxy::ScheduledActionSendBeginMainFrame"); + // Although this proxy is single-threaded, it's problematic to synchronously + // have BeginMainFrame happen after ScheduledActionSendBeginMainFrame. This + // could cause a commit to occur in between a series of SetNeedsCommit calls + // (i.e. property modifications) causing some to fall on one frame and some to + // fall on the next. Doing it asynchronously instead matches the semantics of + // ThreadProxy::SetNeedsCommit where SetNeedsCommit will not cause a + // synchronous commit. + MainThreadTaskRunner()->PostTask( + FROM_HERE, + base::Bind(&SingleThreadProxy::BeginMainFrame, + weak_factory_.GetWeakPtr())); +} + +void SingleThreadProxy::BeginMainFrame() { + if (defer_commits_) { + DCHECK(!commit_was_deferred_); + commit_was_deferred_ = true; + layer_tree_host_->DidDeferCommit(); + return; + } + + // This checker assumes NotifyReadyToCommit in this stack causes a synchronous + // commit. + ScopedAbortRemainingSwapPromises swap_promise_checker(layer_tree_host_); + + if (!layer_tree_host_->visible()) { + TRACE_EVENT_INSTANT0("cc", "EarlyOut_NotVisible", TRACE_EVENT_SCOPE_THREAD); + BeginMainFrameAbortedOnImplThread(); + return; + } + + if (layer_tree_host_->output_surface_lost()) { + TRACE_EVENT_INSTANT0( + "cc", "EarlyOut_OutputSurfaceLost", TRACE_EVENT_SCOPE_THREAD); + BeginMainFrameAbortedOnImplThread(); + return; + } + + const BeginFrameArgs& begin_frame_args = + layer_tree_host_impl_->CurrentBeginFrameArgs(); + DoBeginMainFrame(begin_frame_args); +} + +void SingleThreadProxy::DoBeginMainFrame( + const BeginFrameArgs& begin_frame_args) { + layer_tree_host_->WillBeginMainFrame(); + layer_tree_host_->BeginMainFrame(begin_frame_args); + layer_tree_host_->AnimateLayers(begin_frame_args.frame_time); + layer_tree_host_->Layout(); + + if (PrioritizedResourceManager* contents_texture_manager = + layer_tree_host_->contents_texture_manager()) { + contents_texture_manager->UnlinkAndClearEvictedBackings(); + contents_texture_manager->SetMaxMemoryLimitBytes( + layer_tree_host_impl_->memory_allocation_limit_bytes()); + contents_texture_manager->SetExternalPriorityCutoff( + layer_tree_host_impl_->memory_allocation_priority_cutoff()); + } + + DCHECK(!queue_for_commit_); + queue_for_commit_ = make_scoped_ptr(new ResourceUpdateQueue); + + layer_tree_host_->UpdateLayers(queue_for_commit_.get()); + + timing_history_.DidBeginMainFrame(); + + if (scheduler_on_impl_thread_) { + scheduler_on_impl_thread_->NotifyBeginMainFrameStarted(); + scheduler_on_impl_thread_->NotifyReadyToCommit(); + } +} + +void SingleThreadProxy::BeginMainFrameAbortedOnImplThread() { + DebugScopedSetImplThread impl(this); + DCHECK(scheduler_on_impl_thread_->CommitPending()); + DCHECK(!layer_tree_host_impl_->pending_tree()); + + // TODO(enne): SingleThreadProxy does not support cancelling commits yet so + // did_handle is always false. + bool did_handle = false; + layer_tree_host_impl_->BeginMainFrameAborted(did_handle); + scheduler_on_impl_thread_->BeginMainFrameAborted(did_handle); +} + +DrawResult SingleThreadProxy::ScheduledActionDrawAndSwapIfPossible() { + DebugScopedSetImplThread impl(this); + LayerTreeHostImpl::FrameData frame; + return DoComposite(layer_tree_host_impl_->CurrentBeginFrameArgs().frame_time, + &frame); +} + +DrawResult SingleThreadProxy::ScheduledActionDrawAndSwapForced() { + NOTREACHED(); + return INVALID_RESULT; +} + +void SingleThreadProxy::ScheduledActionCommit() { + DebugScopedSetMainThread main(this); + DoCommit(); +} + +void SingleThreadProxy::ScheduledActionAnimate() { + TRACE_EVENT0("cc", "ScheduledActionAnimate"); + layer_tree_host_impl_->Animate( + layer_tree_host_impl_->CurrentBeginFrameArgs().frame_time); +} + +void SingleThreadProxy::ScheduledActionUpdateVisibleTiles() { + DebugScopedSetImplThread impl(this); + layer_tree_host_impl_->UpdateVisibleTiles(); +} + +void SingleThreadProxy::ScheduledActionActivateSyncTree() { + DebugScopedSetImplThread impl(this); + layer_tree_host_impl_->ActivateSyncTree(); +} + +void SingleThreadProxy::ScheduledActionBeginOutputSurfaceCreation() { + DebugScopedSetMainThread main(this); + DCHECK(scheduler_on_impl_thread_); + // If possible, create the output surface in a post task. Synchronously + // creating the output surface makes tests more awkward since this differs + // from the ThreadProxy behavior. However, sometimes there is no + // task runner. + if (Proxy::MainThreadTaskRunner()) { + ScheduleRequestNewOutputSurface(); + } else { + RequestNewOutputSurface(); + } +} + +void SingleThreadProxy::ScheduledActionManageTiles() { + TRACE_EVENT0("cc", "SingleThreadProxy::ScheduledActionManageTiles"); + DCHECK(layer_tree_host_impl_->settings().impl_side_painting); + DebugScopedSetImplThread impl(this); + layer_tree_host_impl_->ManageTiles(); +} + +void SingleThreadProxy::DidAnticipatedDrawTimeChange(base::TimeTicks time) { +} + +base::TimeDelta SingleThreadProxy::DrawDurationEstimate() { + return timing_history_.DrawDurationEstimate(); +} + +base::TimeDelta SingleThreadProxy::BeginMainFrameToCommitDurationEstimate() { + return timing_history_.BeginMainFrameToCommitDurationEstimate(); +} + +base::TimeDelta SingleThreadProxy::CommitToActivateDurationEstimate() { + return timing_history_.CommitToActivateDurationEstimate(); +} + +void SingleThreadProxy::DidBeginImplFrameDeadline() { + layer_tree_host_impl_->ResetCurrentBeginFrameArgsForNextFrame(); +} } // namespace cc diff --git a/chromium/cc/trees/single_thread_proxy.h b/chromium/cc/trees/single_thread_proxy.h index 7ad48b48bee..5b3766bce18 100644 --- a/chromium/cc/trees/single_thread_proxy.h +++ b/chromium/cc/trees/single_thread_proxy.h @@ -7,11 +7,15 @@ #include <limits> +#include "base/cancelable_callback.h" #include "base/time/time.h" #include "cc/animation/animation_events.h" #include "cc/output/begin_frame_args.h" +#include "cc/scheduler/scheduler.h" +#include "cc/trees/blocking_task_runner.h" #include "cc/trees/layer_tree_host_impl.h" #include "cc/trees/proxy.h" +#include "cc/trees/proxy_timing_history.h" namespace cc { @@ -20,87 +24,111 @@ class LayerTreeHost; class LayerTreeHostSingleThreadClient; class CC_EXPORT SingleThreadProxy : public Proxy, - NON_EXPORTED_BASE(LayerTreeHostImplClient) { + NON_EXPORTED_BASE(LayerTreeHostImplClient), + SchedulerClient { public: static scoped_ptr<Proxy> Create( LayerTreeHost* layer_tree_host, - LayerTreeHostSingleThreadClient* client); - virtual ~SingleThreadProxy(); + LayerTreeHostSingleThreadClient* client, + scoped_refptr<base::SingleThreadTaskRunner> main_task_runner); + ~SingleThreadProxy() override; // Proxy implementation - virtual void FinishAllRendering() OVERRIDE; - virtual bool IsStarted() const OVERRIDE; - virtual void SetLayerTreeHostClientReady() OVERRIDE; - virtual void SetVisible(bool visible) OVERRIDE; - virtual const RendererCapabilities& GetRendererCapabilities() const OVERRIDE; - virtual void SetNeedsAnimate() OVERRIDE; - virtual void SetNeedsUpdateLayers() OVERRIDE; - virtual void SetNeedsCommit() OVERRIDE; - virtual void SetNeedsRedraw(const gfx::Rect& damage_rect) OVERRIDE; - virtual void SetNextCommitWaitsForActivation() OVERRIDE; - virtual void NotifyInputThrottledUntilCommit() OVERRIDE {} - virtual void SetDeferCommits(bool defer_commits) OVERRIDE; - virtual bool CommitRequested() const OVERRIDE; - virtual bool BeginMainFrameRequested() const OVERRIDE; - virtual void MainThreadHasStoppedFlinging() OVERRIDE {} - virtual void Start() OVERRIDE; - virtual void Stop() OVERRIDE; - virtual size_t MaxPartialTextureUpdates() const OVERRIDE; - virtual void ForceSerializeOnSwapBuffers() OVERRIDE; - virtual scoped_ptr<base::Value> AsValue() const OVERRIDE; - virtual bool CommitPendingForTesting() OVERRIDE; + void FinishAllRendering() override; + bool IsStarted() const override; + void SetOutputSurface(scoped_ptr<OutputSurface>) override; + void SetLayerTreeHostClientReady() override; + void SetVisible(bool visible) override; + const RendererCapabilities& GetRendererCapabilities() const override; + void SetNeedsAnimate() override; + void SetNeedsUpdateLayers() override; + void SetNeedsCommit() override; + void SetNeedsRedraw(const gfx::Rect& damage_rect) override; + void SetNextCommitWaitsForActivation() override; + void NotifyInputThrottledUntilCommit() override {} + void SetDeferCommits(bool defer_commits) override; + bool CommitRequested() const override; + bool BeginMainFrameRequested() const override; + void MainThreadHasStoppedFlinging() override {} + void Start() override; + void Stop() override; + size_t MaxPartialTextureUpdates() const override; + void ForceSerializeOnSwapBuffers() override; + bool SupportsImplScrolling() const override; + void AsValueInto(base::debug::TracedValue* state) const override; + bool MainFrameWillHappenForTesting() override; + + // SchedulerClient implementation + BeginFrameSource* ExternalBeginFrameSource() override; + void WillBeginImplFrame(const BeginFrameArgs& args) override; + void ScheduledActionSendBeginMainFrame() override; + DrawResult ScheduledActionDrawAndSwapIfPossible() override; + DrawResult ScheduledActionDrawAndSwapForced() override; + void ScheduledActionCommit() override; + void ScheduledActionAnimate() override; + void ScheduledActionUpdateVisibleTiles() override; + void ScheduledActionActivateSyncTree() override; + void ScheduledActionBeginOutputSurfaceCreation() override; + void ScheduledActionManageTiles() override; + void DidAnticipatedDrawTimeChange(base::TimeTicks time) override; + base::TimeDelta DrawDurationEstimate() override; + base::TimeDelta BeginMainFrameToCommitDurationEstimate() override; + base::TimeDelta CommitToActivateDurationEstimate() override; + void DidBeginImplFrameDeadline() override; // LayerTreeHostImplClient implementation - virtual void UpdateRendererCapabilitiesOnImplThread() OVERRIDE; - virtual void DidLoseOutputSurfaceOnImplThread() OVERRIDE; - virtual void CommitVSyncParameters(base::TimeTicks timebase, - base::TimeDelta interval) OVERRIDE {} - virtual void SetEstimatedParentDrawTime(base::TimeDelta draw_time) OVERRIDE {} - virtual void SetMaxSwapsPendingOnImplThread(int max) OVERRIDE {} - virtual void DidSwapBuffersOnImplThread() OVERRIDE; - virtual void DidSwapBuffersCompleteOnImplThread() OVERRIDE; - virtual void BeginFrame(const BeginFrameArgs& args) OVERRIDE {} - virtual void OnCanDrawStateChanged(bool can_draw) OVERRIDE; - virtual void NotifyReadyToActivate() OVERRIDE; - virtual void SetNeedsRedrawOnImplThread() OVERRIDE; - virtual void SetNeedsRedrawRectOnImplThread( - const gfx::Rect& dirty_rect) OVERRIDE; - virtual void SetNeedsAnimateOnImplThread() OVERRIDE; - virtual void SetNeedsManageTilesOnImplThread() OVERRIDE; - virtual void DidInitializeVisibleTileOnImplThread() OVERRIDE; - virtual void SetNeedsCommitOnImplThread() OVERRIDE; - virtual void PostAnimationEventsToMainThreadOnImplThread( - scoped_ptr<AnimationEventsVector> events) OVERRIDE; - virtual bool ReduceContentsTextureMemoryOnImplThread( - size_t limit_bytes, - int priority_cutoff) OVERRIDE; - virtual bool IsInsideDraw() OVERRIDE; - virtual void RenewTreePriority() OVERRIDE {} - virtual void PostDelayedScrollbarFadeOnImplThread( - const base::Closure& start_fade, - base::TimeDelta delay) OVERRIDE {} - virtual void DidActivatePendingTree() OVERRIDE {} - virtual void DidManageTiles() OVERRIDE {} - virtual void SetDebugState(const LayerTreeDebugState& debug_state) OVERRIDE {} - - // Attempts to create the context and renderer synchronously. Calls - // LayerTreeHost::OnCreateAndInitializeOutputSurfaceAttempted with the result. - void CreateAndInitializeOutputSurface(); + void UpdateRendererCapabilitiesOnImplThread() override; + void DidLoseOutputSurfaceOnImplThread() override; + void CommitVSyncParameters(base::TimeTicks timebase, + base::TimeDelta interval) override {} + void SetEstimatedParentDrawTime(base::TimeDelta draw_time) override {} + void SetMaxSwapsPendingOnImplThread(int max) override {} + void DidSwapBuffersOnImplThread() override; + void DidSwapBuffersCompleteOnImplThread() override; + void OnCanDrawStateChanged(bool can_draw) override; + void NotifyReadyToActivate() override; + void SetNeedsRedrawOnImplThread() override; + void SetNeedsRedrawRectOnImplThread(const gfx::Rect& dirty_rect) override; + void SetNeedsAnimateOnImplThread() override; + void SetNeedsManageTilesOnImplThread() override; + void DidInitializeVisibleTileOnImplThread() override; + void SetNeedsCommitOnImplThread() override; + void PostAnimationEventsToMainThreadOnImplThread( + scoped_ptr<AnimationEventsVector> events) override; + bool ReduceContentsTextureMemoryOnImplThread(size_t limit_bytes, + int priority_cutoff) override; + bool IsInsideDraw() override; + void RenewTreePriority() override {} + void PostDelayedScrollbarFadeOnImplThread(const base::Closure& start_fade, + base::TimeDelta delay) override {} + void DidActivateSyncTree() override; + void DidManageTiles() override; + void SetDebugState(const LayerTreeDebugState& debug_state) override {} + + void RequestNewOutputSurface(); // Called by the legacy path where RenderWidget does the scheduling. void CompositeImmediately(base::TimeTicks frame_begin_time); private: - SingleThreadProxy(LayerTreeHost* layer_tree_host, - LayerTreeHostSingleThreadClient* client); - - void DoCommit(scoped_ptr<ResourceUpdateQueue> queue); - bool DoComposite(base::TimeTicks frame_begin_time, - LayerTreeHostImpl::FrameData* frame); - void DidSwapFrame(); + SingleThreadProxy( + LayerTreeHost* layer_tree_host, + LayerTreeHostSingleThreadClient* client, + scoped_refptr<base::SingleThreadTaskRunner> main_task_runner); + + void BeginMainFrame(); + void BeginMainFrameAbortedOnImplThread(); + void DoBeginMainFrame(const BeginFrameArgs& begin_frame_args); + void DoCommit(); + DrawResult DoComposite(base::TimeTicks frame_begin_time, + LayerTreeHostImpl::FrameData* frame); + void DoSwap(); + void DidCommitAndDrawFrame(); + void CommitComplete(); bool ShouldComposite() const; void UpdateBackgroundAnimateTicking(); + void ScheduleRequestNewOutputSurface(); // Accessed on main thread only. LayerTreeHost* layer_tree_host_; @@ -111,9 +139,28 @@ class CC_EXPORT SingleThreadProxy : public Proxy, scoped_ptr<LayerTreeHostImpl> layer_tree_host_impl_; RendererCapabilities renderer_capabilities_for_main_thread_; + // Accessed from both threads. + scoped_ptr<Scheduler> scheduler_on_impl_thread_; + ProxyTimingHistory timing_history_; + + scoped_ptr<BlockingTaskRunner::CapturePostTasks> commit_blocking_task_runner_; + scoped_ptr<ResourceUpdateQueue> queue_for_commit_; bool next_frame_is_newly_committed_frame_; bool inside_draw_; + bool defer_commits_; + bool commit_was_deferred_; + bool commit_requested_; + bool inside_synchronous_composite_; + + // True if a request to the LayerTreeHostClient to create an output surface + // is still outstanding. + bool output_surface_creation_requested_; + + // This is the callback for the scheduled RequestNewOutputSurface. + base::CancelableClosure output_surface_creation_callback_; + + base::WeakPtrFactory<SingleThreadProxy> weak_factory_; DISALLOW_COPY_AND_ASSIGN(SingleThreadProxy); }; diff --git a/chromium/cc/trees/thread_proxy.cc b/chromium/cc/trees/thread_proxy.cc index e16adb9a550..14e218194e0 100644 --- a/chromium/cc/trees/thread_proxy.cc +++ b/chromium/cc/trees/thread_proxy.cc @@ -10,8 +10,8 @@ #include "base/auto_reset.h" #include "base/bind.h" #include "base/debug/trace_event.h" +#include "base/debug/trace_event_argument.h" #include "base/debug/trace_event_synthetic_delay.h" -#include "base/metrics/histogram.h" #include "cc/base/swap_promise.h" #include "cc/debug/benchmark_instrumentation.h" #include "cc/debug/devtools_instrumentation.h" @@ -25,35 +25,21 @@ #include "cc/trees/blocking_task_runner.h" #include "cc/trees/layer_tree_host.h" #include "cc/trees/layer_tree_impl.h" +#include "cc/trees/scoped_abort_remaining_swap_promises.h" +#include "gpu/command_buffer/client/gles2_interface.h" #include "ui/gfx/frame_time.h" +namespace cc { + namespace { // Measured in seconds. const double kSmoothnessTakesPriorityExpirationDelay = 0.25; -class SwapPromiseChecker { - public: - explicit SwapPromiseChecker(cc::LayerTreeHost* layer_tree_host) - : layer_tree_host_(layer_tree_host) {} - - ~SwapPromiseChecker() { - layer_tree_host_->BreakSwapPromises(cc::SwapPromise::COMMIT_FAILS); - } - - private: - cc::LayerTreeHost* layer_tree_host_; -}; +unsigned int nextBeginFrameId = 0; } // namespace -namespace cc { - -struct ThreadProxy::CommitPendingRequest { - CompletionEvent completion; - bool commit_pending; -}; - struct ThreadProxy::SchedulerStateRequest { CompletionEvent completion; scoped_ptr<base::Value> state; @@ -61,18 +47,23 @@ struct ThreadProxy::SchedulerStateRequest { scoped_ptr<Proxy> ThreadProxy::Create( LayerTreeHost* layer_tree_host, + scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner) { - return make_scoped_ptr(new ThreadProxy(layer_tree_host, impl_task_runner)) - .PassAs<Proxy>(); + return make_scoped_ptr( + new ThreadProxy(layer_tree_host, main_task_runner, impl_task_runner)); } ThreadProxy::ThreadProxy( LayerTreeHost* layer_tree_host, + scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner) - : Proxy(impl_task_runner), + : Proxy(main_task_runner, impl_task_runner), main_thread_only_vars_unsafe_(this, layer_tree_host->id()), main_thread_or_blocked_vars_unsafe_(layer_tree_host), - compositor_thread_vars_unsafe_(this, layer_tree_host->id()) { + compositor_thread_vars_unsafe_( + this, + layer_tree_host->id(), + layer_tree_host->rendering_stats_instrumentation()) { TRACE_EVENT0("cc", "ThreadProxy::ThreadProxy"); DCHECK(IsMainThread()); DCHECK(this->layer_tree_host()); @@ -105,8 +96,10 @@ ThreadProxy::MainThreadOrBlockedMainThread::contents_texture_manager() { return layer_tree_host->contents_texture_manager(); } -ThreadProxy::CompositorThreadOnly::CompositorThreadOnly(ThreadProxy* proxy, - int layer_tree_host_id) +ThreadProxy::CompositorThreadOnly::CompositorThreadOnly( + ThreadProxy* proxy, + int layer_tree_host_id, + RenderingStatsInstrumentation* rendering_stats_instrumentation) : layer_tree_host_id(layer_tree_host_id), contents_texture_manager(NULL), commit_completion_event(NULL), @@ -114,13 +107,12 @@ ThreadProxy::CompositorThreadOnly::CompositorThreadOnly(ThreadProxy* proxy, next_frame_is_newly_committed_frame(false), inside_draw(false), input_throttled_until_commit(false), - animations_frozen_until_next_draw(false), - did_commit_after_animating(false), smoothness_priority_expiration_notifier( proxy->ImplThreadTaskRunner(), base::Bind(&ThreadProxy::RenewTreePriority, base::Unretained(proxy)), base::TimeDelta::FromMilliseconds( kSmoothnessTakesPriorityExpirationDelay * 1000)), + timing_history(rendering_stats_instrumentation), weak_factory(proxy) { } @@ -194,8 +186,6 @@ void ThreadProxy::UpdateBackgroundAnimateTicking() { impl().layer_tree_host_impl->active_tree()->root_layer(); impl().layer_tree_host_impl->UpdateBackgroundAnimateTicking( should_background_tick); - if (should_background_tick) - impl().animations_frozen_until_next_draw = false; } void ThreadProxy::DidLoseOutputSurface() { @@ -207,7 +197,8 @@ void ThreadProxy::DidLoseOutputSurface() { DebugScopedSetMainThreadBlocked main_thread_blocked(this); // Return lost resources to their owners immediately. - BlockingTaskRunner::CapturePostTasks blocked; + BlockingTaskRunner::CapturePostTasks blocked( + blocking_main_thread_task_runner()); CompletionEvent completion; Proxy::ImplThreadTaskRunner()->PostTask( @@ -219,13 +210,12 @@ void ThreadProxy::DidLoseOutputSurface() { } } -void ThreadProxy::CreateAndInitializeOutputSurface() { - TRACE_EVENT0("cc", "ThreadProxy::DoCreateAndInitializeOutputSurface"); +void ThreadProxy::RequestNewOutputSurface() { DCHECK(IsMainThread()); + layer_tree_host()->RequestNewOutputSurface(); +} - scoped_ptr<OutputSurface> output_surface = - layer_tree_host()->CreateOutputSurface(); - +void ThreadProxy::SetOutputSurface(scoped_ptr<OutputSurface> output_surface) { if (output_surface) { Proxy::ImplThreadTaskRunner()->PostTask( FROM_HERE, @@ -249,7 +239,7 @@ void ThreadProxy::DidInitializeOutputSurface( if (!success) { Proxy::MainThreadTaskRunner()->PostTask( FROM_HERE, - base::Bind(&ThreadProxy::CreateAndInitializeOutputSurface, + base::Bind(&ThreadProxy::RequestNewOutputSurface, main_thread_weak_ptr_)); } } @@ -323,14 +313,6 @@ void ThreadProxy::UpdateRendererCapabilitiesOnImplThread() { void ThreadProxy::DidLoseOutputSurfaceOnImplThread() { TRACE_EVENT0("cc", "ThreadProxy::DidLoseOutputSurfaceOnImplThread"); DCHECK(IsImplThread()); - CheckOutputSurfaceStatusOnImplThread(); -} - -void ThreadProxy::CheckOutputSurfaceStatusOnImplThread() { - TRACE_EVENT0("cc", "ThreadProxy::CheckOutputSurfaceStatusOnImplThread"); - DCHECK(IsImplThread()); - if (!impl().layer_tree_host_impl->IsContextLost()) - return; Proxy::MainThreadTaskRunner()->PostTask( FROM_HERE, base::Bind(&ThreadProxy::DidLoseOutputSurface, main_thread_weak_ptr_)); @@ -363,14 +345,8 @@ void ThreadProxy::DidSwapBuffersCompleteOnImplThread() { base::Bind(&ThreadProxy::DidCompleteSwapBuffers, main_thread_weak_ptr_)); } -void ThreadProxy::SetNeedsBeginFrame(bool enable) { - TRACE_EVENT1("cc", "ThreadProxy::SetNeedsBeginFrame", "enable", enable); - impl().layer_tree_host_impl->SetNeedsBeginFrame(enable); - UpdateBackgroundAnimateTicking(); -} - -void ThreadProxy::BeginFrame(const BeginFrameArgs& args) { - impl().scheduler->BeginFrame(args); +BeginFrameSource* ThreadProxy::ExternalBeginFrameSource() { + return impl().layer_tree_host_impl.get(); } void ThreadProxy::WillBeginImplFrame(const BeginFrameArgs& args) { @@ -454,20 +430,22 @@ void ThreadProxy::SetNextCommitWaitsForActivation() { void ThreadProxy::SetDeferCommits(bool defer_commits) { DCHECK(IsMainThread()); - DCHECK_NE(main().defer_commits, defer_commits); - main().defer_commits = defer_commits; + if (main().defer_commits == defer_commits) + return; + main().defer_commits = defer_commits; if (main().defer_commits) TRACE_EVENT_ASYNC_BEGIN0("cc", "ThreadProxy::SetDeferCommits", this); else TRACE_EVENT_ASYNC_END0("cc", "ThreadProxy::SetDeferCommits", this); - if (!main().defer_commits && main().pending_deferred_commit) + if (!main().defer_commits && main().pending_deferred_commit) { Proxy::MainThreadTaskRunner()->PostTask( FROM_HERE, base::Bind(&ThreadProxy::BeginMainFrame, main_thread_weak_ptr_, base::Passed(&main().pending_deferred_commit))); + } } bool ThreadProxy::CommitRequested() const { @@ -662,6 +640,10 @@ void ThreadProxy::ForceSerializeOnSwapBuffersOnImplThread( completion->Signal(); } +bool ThreadProxy::SupportsImplScrolling() const { + return true; +} + void ThreadProxy::SetDebugState(const LayerTreeDebugState& debug_state) { Proxy::ImplThreadTaskRunner()->PostTask( FROM_HERE, @@ -684,11 +666,14 @@ void ThreadProxy::FinishAllRenderingOnImplThread(CompletionEvent* completion) { } void ThreadProxy::ScheduledActionSendBeginMainFrame() { - TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionSendBeginMainFrame"); + unsigned int begin_frame_id = nextBeginFrameId++; + benchmark_instrumentation::ScopedBeginFrameTask begin_frame_task( + benchmark_instrumentation::kSendBeginFrame, begin_frame_id); scoped_ptr<BeginMainFrameAndCommitState> begin_main_frame_state( new BeginMainFrameAndCommitState); - begin_main_frame_state->monotonic_frame_begin_time = - impl().layer_tree_host_impl->CurrentFrameTimeTicks(); + begin_main_frame_state->begin_frame_id = begin_frame_id; + begin_main_frame_state->begin_frame_args = + impl().layer_tree_host_impl->CurrentBeginFrameArgs(); begin_main_frame_state->scroll_info = impl().layer_tree_host_impl->ProcessScrollDeltas(); @@ -713,7 +698,9 @@ void ThreadProxy::ScheduledActionSendBeginMainFrame() { void ThreadProxy::BeginMainFrame( scoped_ptr<BeginMainFrameAndCommitState> begin_main_frame_state) { - TRACE_EVENT0("cc", "ThreadProxy::BeginMainFrame"); + benchmark_instrumentation::ScopedBeginFrameTask begin_frame_task( + benchmark_instrumentation::kDoBeginFrame, + begin_main_frame_state->begin_frame_id); TRACE_EVENT_SYNTHETIC_DELAY_BEGIN("cc.BeginMainFrame"); DCHECK(IsMainThread()); @@ -726,9 +713,9 @@ void ThreadProxy::BeginMainFrame( } // If the commit finishes, LayerTreeHost will transfer its swap promises to - // LayerTreeImpl. The destructor of SwapPromiseChecker checks LayerTressHost's - // swap promises. - SwapPromiseChecker swap_promise_checker(layer_tree_host()); + // LayerTreeImpl. The destructor of ScopedSwapPromiseChecker aborts the + // remaining swap promises. + ScopedAbortRemainingSwapPromises swap_promise_checker(layer_tree_host()); main().commit_requested = false; main().commit_request_sent_to_impl_thread = false; @@ -768,16 +755,14 @@ void ThreadProxy::BeginMainFrame( main().commit_requested = true; main().commit_request_sent_to_impl_thread = true; - layer_tree_host()->ApplyScrollAndScale(*begin_main_frame_state->scroll_info); + layer_tree_host()->ApplyScrollAndScale( + begin_main_frame_state->scroll_info.get()); layer_tree_host()->WillBeginMainFrame(); - layer_tree_host()->UpdateClientAnimations( - begin_main_frame_state->monotonic_frame_begin_time); + layer_tree_host()->BeginMainFrame(begin_main_frame_state->begin_frame_args); layer_tree_host()->AnimateLayers( - begin_main_frame_state->monotonic_frame_begin_time); - blocked_main().last_monotonic_frame_begin_time = - begin_main_frame_state->monotonic_frame_begin_time; + begin_main_frame_state->begin_frame_args.frame_time); // Unlink any backings that the impl thread has evicted, so that we know to // re-paint them in UpdateLayers. @@ -839,6 +824,7 @@ void ThreadProxy::BeginMainFrame( // went through, and input should no longer be throttled, etc. layer_tree_host()->CommitComplete(); layer_tree_host()->DidBeginMainFrame(); + layer_tree_host()->BreakSwapPromises(SwapPromise::COMMIT_NO_UPDATE); return; } @@ -854,7 +840,8 @@ void ThreadProxy::BeginMainFrame( // This CapturePostTasks should be destroyed before CommitComplete() is // called since that goes out to the embedder, and we want the embedder // to receive its callbacks before that. - BlockingTaskRunner::CapturePostTasks blocked; + BlockingTaskRunner::CapturePostTasks blocked( + blocking_main_thread_task_runner()); CompletionEvent completion; Proxy::ImplThreadTaskRunner()->PostTask( @@ -867,7 +854,7 @@ void ThreadProxy::BeginMainFrame( RenderingStatsInstrumentation* stats_instrumentation = layer_tree_host()->rendering_stats_instrumentation(); - BenchmarkInstrumentation::IssueMainThreadRenderingStatsEvent( + benchmark_instrumentation::IssueMainThreadRenderingStatsEvent( stats_instrumentation->main_thread_rendering_stats()); stats_instrumentation->AccumulateAndClearMainThreadStats(); } @@ -946,12 +933,9 @@ void ThreadProxy::ScheduledActionAnimate() { TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionAnimate"); DCHECK(IsImplThread()); - if (!impl().animations_frozen_until_next_draw) { - impl().animation_time = - impl().layer_tree_host_impl->CurrentFrameTimeTicks(); - } + impl().animation_time = + impl().layer_tree_host_impl->CurrentBeginFrameArgs().frame_time; impl().layer_tree_host_impl->Animate(impl().animation_time); - impl().did_commit_after_animating = false; } void ThreadProxy::ScheduledActionCommit() { @@ -963,13 +947,7 @@ void ThreadProxy::ScheduledActionCommit() { // Complete all remaining texture updates. impl().current_resource_update_controller->Finalize(); - impl().current_resource_update_controller.reset(); - - if (impl().animations_frozen_until_next_draw) { - impl().animation_time = std::max( - impl().animation_time, blocked_main().last_monotonic_frame_begin_time); - } - impl().did_commit_after_animating = true; + impl().current_resource_update_controller = nullptr; blocked_main().main_thread_inside_commit = true; impl().layer_tree_host_impl->BeginCommit(); @@ -984,8 +962,8 @@ void ThreadProxy::ScheduledActionCommit() { if (hold_commit) { // For some layer types in impl-side painting, the commit is held until - // the pending tree is activated. It's also possible that the - // pending tree has already activated if there was no work to be done. + // the sync tree is activated. It's also possible that the + // sync tree has already activated if there was no work to be done. TRACE_EVENT_INSTANT0("cc", "HoldCommit", TRACE_EVENT_SCOPE_THREAD); impl().completion_event_for_commit_held_on_tree_activation = impl().commit_completion_event; @@ -1014,10 +992,10 @@ void ThreadProxy::ScheduledActionUpdateVisibleTiles() { impl().layer_tree_host_impl->UpdateVisibleTiles(); } -void ThreadProxy::ScheduledActionActivatePendingTree() { - TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionActivatePendingTree"); +void ThreadProxy::ScheduledActionActivateSyncTree() { + TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionActivateSyncTree"); DCHECK(IsImplThread()); - impl().layer_tree_host_impl->ActivatePendingTree(); + impl().layer_tree_host_impl->ActivateSyncTree(); } void ThreadProxy::ScheduledActionBeginOutputSurfaceCreation() { @@ -1025,8 +1003,7 @@ void ThreadProxy::ScheduledActionBeginOutputSurfaceCreation() { DCHECK(IsImplThread()); Proxy::MainThreadTaskRunner()->PostTask( FROM_HERE, - base::Bind(&ThreadProxy::CreateAndInitializeOutputSurface, - main_thread_weak_ptr_)); + base::Bind(&ThreadProxy::RequestNewOutputSurface, main_thread_weak_ptr_)); } DrawResult ThreadProxy::DrawSwapInternal(bool forced_draw) { @@ -1037,14 +1014,8 @@ DrawResult ThreadProxy::DrawSwapInternal(bool forced_draw) { DCHECK(impl().layer_tree_host_impl.get()); impl().timing_history.DidStartDrawing(); - base::TimeDelta draw_duration_estimate = DrawDurationEstimate(); base::AutoReset<bool> mark_inside(&impl().inside_draw, true); - if (impl().did_commit_after_animating) { - impl().layer_tree_host_impl->Animate(impl().animation_time); - impl().did_commit_after_animating = false; - } - if (impl().layer_tree_host_impl->pending_tree()) impl().layer_tree_host_impl->pending_tree()->UpdateDrawProperties(); @@ -1073,17 +1044,6 @@ DrawResult ThreadProxy::DrawSwapInternal(bool forced_draw) { impl().layer_tree_host_impl->DrawLayers( &frame, impl().scheduler->LastBeginImplFrameTime()); result = DRAW_SUCCESS; - impl().animations_frozen_until_next_draw = false; - } else if (result == DRAW_ABORTED_CHECKERBOARD_ANIMATIONS && - !impl().layer_tree_host_impl->settings().impl_side_painting) { - // Without impl-side painting, the animated layer that is checkerboarding - // will continue to checkerboard until the next commit. If this layer - // continues to move during the commit, it may continue to checkerboard - // after the commit since the region rasterized during the commit will not - // match the region that is currently visible; eventually this - // checkerboarding will be displayed when we force a draw. To avoid this, - // we freeze animations until we successfully draw. - impl().animations_frozen_until_next_draw = true; } else { DCHECK_NE(DRAW_SUCCESS, result); } @@ -1110,34 +1070,8 @@ DrawResult ThreadProxy::DrawSwapInternal(bool forced_draw) { base::Bind(&ThreadProxy::DidCommitAndDrawFrame, main_thread_weak_ptr_)); } - if (draw_frame) - CheckOutputSurfaceStatusOnImplThread(); - - if (result == DRAW_SUCCESS) { - base::TimeDelta draw_duration = impl().timing_history.DidFinishDrawing(); - - base::TimeDelta draw_duration_overestimate; - base::TimeDelta draw_duration_underestimate; - if (draw_duration > draw_duration_estimate) - draw_duration_underestimate = draw_duration - draw_duration_estimate; - else - draw_duration_overestimate = draw_duration_estimate - draw_duration; - UMA_HISTOGRAM_CUSTOM_TIMES("Renderer.DrawDuration", - draw_duration, - base::TimeDelta::FromMilliseconds(1), - base::TimeDelta::FromMilliseconds(100), - 50); - UMA_HISTOGRAM_CUSTOM_TIMES("Renderer.DrawDurationUnderestimate", - draw_duration_underestimate, - base::TimeDelta::FromMilliseconds(1), - base::TimeDelta::FromMilliseconds(100), - 50); - UMA_HISTOGRAM_CUSTOM_TIMES("Renderer.DrawDurationOverestimate", - draw_duration_overestimate, - base::TimeDelta::FromMilliseconds(1), - base::TimeDelta::FromMilliseconds(100), - 50); - } + if (result == DRAW_SUCCESS) + impl().timing_history.DidFinishDrawing(); DCHECK_NE(INVALID_RESULT, result); return result; @@ -1185,7 +1119,7 @@ base::TimeDelta ThreadProxy::CommitToActivateDurationEstimate() { } void ThreadProxy::DidBeginImplFrameDeadline() { - impl().layer_tree_host_impl->ResetCurrentFrameTimeForNextFrame(); + impl().layer_tree_host_impl->ResetCurrentBeginFrameArgsForNextFrame(); } void ThreadProxy::ReadyToFinalizeTextureUpdates() { @@ -1218,7 +1152,8 @@ void ThreadProxy::InitializeImplOnImplThread(CompletionEvent* completion) { impl().scheduler = Scheduler::Create(this, scheduler_settings, impl().layer_tree_host_id, - ImplThreadTaskRunner()); + ImplThreadTaskRunner(), + base::PowerMonitor::Get()); impl().scheduler->SetVisible(impl().layer_tree_host_impl->visible()); impl_thread_weak_ptr_ = impl().weak_factory.GetWeakPtr(); @@ -1262,8 +1197,12 @@ void ThreadProxy::InitializeOutputSurfaceOnImplThread( void ThreadProxy::FinishGLOnImplThread(CompletionEvent* completion) { TRACE_EVENT0("cc", "ThreadProxy::FinishGLOnImplThread"); DCHECK(IsImplThread()); - if (impl().layer_tree_host_impl->resource_provider()) - impl().layer_tree_host_impl->resource_provider()->Finish(); + if (impl().layer_tree_host_impl->output_surface()) { + ContextProvider* context_provider = + impl().layer_tree_host_impl->output_surface()->context_provider(); + if (context_provider) + context_provider->ContextGL()->Finish(); + } completion->Signal(); } @@ -1273,11 +1212,15 @@ void ThreadProxy::LayerTreeHostClosedOnImplThread(CompletionEvent* completion) { DCHECK(IsMainThreadBlocked()); layer_tree_host()->DeleteContentsTexturesOnImplThread( impl().layer_tree_host_impl->resource_provider()); - impl().current_resource_update_controller.reset(); - impl().layer_tree_host_impl->SetNeedsBeginFrame(false); - impl().scheduler.reset(); - impl().layer_tree_host_impl.reset(); + impl().current_resource_update_controller = nullptr; + impl().layer_tree_host_impl->SetNeedsBeginFrames(false); + impl().scheduler = nullptr; + impl().layer_tree_host_impl = nullptr; impl().weak_factory.InvalidateWeakPtrs(); + // We need to explicitly shutdown the notifier to destroy any weakptrs it is + // holding while still on the compositor thread. This also ensures any + // callbacks holding a ThreadProxy pointer are cancelled. + impl().smoothness_priority_expiration_notifier.Shutdown(); impl().contents_texture_manager = NULL; completion->Signal(); } @@ -1293,78 +1236,57 @@ ThreadProxy::BeginMainFrameAndCommitState::BeginMainFrameAndCommitState() ThreadProxy::BeginMainFrameAndCommitState::~BeginMainFrameAndCommitState() {} -scoped_ptr<base::Value> ThreadProxy::AsValue() const { - scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); - +void ThreadProxy::AsValueInto(base::debug::TracedValue* state) const { CompletionEvent completion; { DebugScopedSetMainThreadBlocked main_thread_blocked( const_cast<ThreadProxy*>(this)); + scoped_refptr<base::debug::TracedValue> state_refptr(state); Proxy::ImplThreadTaskRunner()->PostTask( FROM_HERE, base::Bind(&ThreadProxy::AsValueOnImplThread, impl_thread_weak_ptr_, &completion, - state.get())); + state_refptr)); completion.Wait(); } - return state.PassAs<base::Value>(); } void ThreadProxy::AsValueOnImplThread(CompletionEvent* completion, - base::DictionaryValue* state) const { - state->Set("layer_tree_host_impl", - impl().layer_tree_host_impl->AsValue().release()); + base::debug::TracedValue* state) const { + state->BeginDictionary("layer_tree_host_impl"); + impl().layer_tree_host_impl->AsValueInto(state); + state->EndDictionary(); completion->Signal(); } -bool ThreadProxy::CommitPendingForTesting() { +bool ThreadProxy::MainFrameWillHappenForTesting() { DCHECK(IsMainThread()); - CommitPendingRequest commit_pending_request; + CompletionEvent completion; + bool main_frame_will_happen = false; { DebugScopedSetMainThreadBlocked main_thread_blocked(this); Proxy::ImplThreadTaskRunner()->PostTask( FROM_HERE, - base::Bind(&ThreadProxy::CommitPendingOnImplThreadForTesting, + base::Bind(&ThreadProxy::MainFrameWillHappenOnImplThreadForTesting, impl_thread_weak_ptr_, - &commit_pending_request)); - commit_pending_request.completion.Wait(); + &completion, + &main_frame_will_happen)); + completion.Wait(); } - return commit_pending_request.commit_pending; + return main_frame_will_happen; } -void ThreadProxy::CommitPendingOnImplThreadForTesting( - CommitPendingRequest* request) { +void ThreadProxy::MainFrameWillHappenOnImplThreadForTesting( + CompletionEvent* completion, + bool* main_frame_will_happen) { DCHECK(IsImplThread()); - if (impl().layer_tree_host_impl->output_surface()) - request->commit_pending = impl().scheduler->CommitPending(); - else - request->commit_pending = false; - request->completion.Signal(); -} - -scoped_ptr<base::Value> ThreadProxy::SchedulerAsValueForTesting() { - if (IsImplThread()) - return impl().scheduler->AsValue().Pass(); - - SchedulerStateRequest scheduler_state_request; - { - DebugScopedSetMainThreadBlocked main_thread_blocked(this); - Proxy::ImplThreadTaskRunner()->PostTask( - FROM_HERE, - base::Bind(&ThreadProxy::SchedulerAsValueOnImplThreadForTesting, - impl_thread_weak_ptr_, - &scheduler_state_request)); - scheduler_state_request.completion.Wait(); + if (impl().layer_tree_host_impl->output_surface()) { + *main_frame_will_happen = impl().scheduler->MainFrameForTestingWillHappen(); + } else { + *main_frame_will_happen = false; } - return scheduler_state_request.state.Pass(); -} - -void ThreadProxy::SchedulerAsValueOnImplThreadForTesting( - SchedulerStateRequest* request) { - DCHECK(IsImplThread()); - request->state = impl().scheduler->AsValue(); - request->completion.Signal(); + completion->Signal(); } void ThreadProxy::RenewTreePriority() { @@ -1372,8 +1294,7 @@ void ThreadProxy::RenewTreePriority() { bool smoothness_takes_priority = impl().layer_tree_host_impl->pinch_gesture_active() || impl().layer_tree_host_impl->page_scale_animation_active() || - (impl().layer_tree_host_impl->IsCurrentlyScrolling() && - !impl().layer_tree_host_impl->scroll_affects_scroll_handler()); + impl().layer_tree_host_impl->IsActivelyScrolling(); // Schedule expiration if smoothness currently takes priority. if (smoothness_takes_priority) @@ -1395,13 +1316,19 @@ void ThreadProxy::RenewTreePriority() { // Once we enter NEW_CONTENTS_TAKES_PRIORITY mode, visible tiles on active // tree might be freed. We need to set RequiresHighResToDraw to ensure that // high res tiles will be required to activate pending tree. - impl().layer_tree_host_impl->active_tree()->SetRequiresHighResToDraw(); + impl().layer_tree_host_impl->SetRequiresHighResToDraw(); priority = NEW_CONTENT_TAKES_PRIORITY; } impl().layer_tree_host_impl->SetTreePriority(priority); - impl().scheduler->SetSmoothnessTakesPriority(priority == - SMOOTHNESS_TAKES_PRIORITY); + + // Only put the scheduler in impl latency prioritization mode if we don't + // have a scroll listener. This gives the scroll listener a better chance of + // handling scroll updates within the same frame. The tree itself is still + // kept in prefer smoothness mode to allow checkerboarding. + impl().scheduler->SetImplLatencyTakesPriority( + priority == SMOOTHNESS_TAKES_PRIORITY && + !impl().layer_tree_host_impl->scroll_affects_scroll_handler()); // Notify the the client of this compositor via the output surface. // TODO(epenner): Route this to compositor-thread instead of output-surface @@ -1419,10 +1346,9 @@ void ThreadProxy::PostDelayedScrollbarFadeOnImplThread( Proxy::ImplThreadTaskRunner()->PostDelayedTask(FROM_HERE, start_fade, delay); } -void ThreadProxy::DidActivatePendingTree() { - TRACE_EVENT0("cc", "ThreadProxy::DidActivatePendingTreeOnImplThread"); +void ThreadProxy::DidActivateSyncTree() { + TRACE_EVENT0("cc", "ThreadProxy::DidActivateSyncTreeOnImplThread"); DCHECK(IsImplThread()); - DCHECK(!impl().layer_tree_host_impl->pending_tree()); if (impl().completion_event_for_commit_held_on_tree_activation) { TRACE_EVENT_INSTANT0( @@ -1434,7 +1360,7 @@ void ThreadProxy::DidActivatePendingTree() { UpdateBackgroundAnimateTicking(); - impl().timing_history.DidActivatePendingTree(); + impl().timing_history.DidActivateSyncTree(); } void ThreadProxy::DidManageTiles() { diff --git a/chromium/cc/trees/thread_proxy.h b/chromium/cc/trees/thread_proxy.h index 8d4348e490d..2f3e7c56a67 100644 --- a/chromium/cc/trees/thread_proxy.h +++ b/chromium/cc/trees/thread_proxy.h @@ -39,15 +39,17 @@ class CC_EXPORT ThreadProxy : public Proxy, public: static scoped_ptr<Proxy> Create( LayerTreeHost* layer_tree_host, + scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner); - virtual ~ThreadProxy(); + ~ThreadProxy() override; struct BeginMainFrameAndCommitState { BeginMainFrameAndCommitState(); ~BeginMainFrameAndCommitState(); - base::TimeTicks monotonic_frame_begin_time; + unsigned int begin_frame_id; + BeginFrameArgs begin_frame_args; scoped_ptr<ScrollAndScaleSet> scroll_info; size_t memory_allocation_limit_bytes; int memory_allocation_priority_cutoff; @@ -88,14 +90,13 @@ class CC_EXPORT ThreadProxy : public Proxy, LayerTreeHost* layer_tree_host; bool commit_waits_for_activation; bool main_thread_inside_commit; - - base::TimeTicks last_monotonic_frame_begin_time; }; - struct ReadbackRequest; - struct CompositorThreadOnly { - CompositorThreadOnly(ThreadProxy* proxy, int layer_tree_host_id); + CompositorThreadOnly( + ThreadProxy* proxy, + int layer_tree_host_id, + RenderingStatsInstrumentation* rendering_stats_instrumentation); ~CompositorThreadOnly(); const int layer_tree_host_id; @@ -126,8 +127,6 @@ class CC_EXPORT ThreadProxy : public Proxy, bool input_throttled_until_commit; - // Set when we freeze animations to avoid checkerboarding. - bool animations_frozen_until_next_draw; base::TimeTicks animation_time; // Whether a commit has been completed since the last time animations were @@ -147,88 +146,86 @@ class CC_EXPORT ThreadProxy : public Proxy, const CompositorThreadOnly& impl() const; // Proxy implementation - virtual void FinishAllRendering() OVERRIDE; - virtual bool IsStarted() const OVERRIDE; - virtual void SetLayerTreeHostClientReady() OVERRIDE; - virtual void SetVisible(bool visible) OVERRIDE; - virtual const RendererCapabilities& GetRendererCapabilities() const OVERRIDE; - virtual void SetNeedsAnimate() OVERRIDE; - virtual void SetNeedsUpdateLayers() OVERRIDE; - virtual void SetNeedsCommit() OVERRIDE; - virtual void SetNeedsRedraw(const gfx::Rect& damage_rect) OVERRIDE; - virtual void SetNextCommitWaitsForActivation() OVERRIDE; - virtual void NotifyInputThrottledUntilCommit() OVERRIDE; - virtual void SetDeferCommits(bool defer_commits) OVERRIDE; - virtual bool CommitRequested() const OVERRIDE; - virtual bool BeginMainFrameRequested() const OVERRIDE; - virtual void MainThreadHasStoppedFlinging() OVERRIDE; - virtual void Start() OVERRIDE; - virtual void Stop() OVERRIDE; - virtual size_t MaxPartialTextureUpdates() const OVERRIDE; - virtual void ForceSerializeOnSwapBuffers() OVERRIDE; - virtual void SetDebugState(const LayerTreeDebugState& debug_state) OVERRIDE; - virtual scoped_ptr<base::Value> AsValue() const OVERRIDE; - virtual bool CommitPendingForTesting() OVERRIDE; - virtual scoped_ptr<base::Value> SchedulerAsValueForTesting() OVERRIDE; + void FinishAllRendering() override; + bool IsStarted() const override; + void SetOutputSurface(scoped_ptr<OutputSurface>) override; + void SetLayerTreeHostClientReady() override; + void SetVisible(bool visible) override; + const RendererCapabilities& GetRendererCapabilities() const override; + void SetNeedsAnimate() override; + void SetNeedsUpdateLayers() override; + void SetNeedsCommit() override; + void SetNeedsRedraw(const gfx::Rect& damage_rect) override; + void SetNextCommitWaitsForActivation() override; + void NotifyInputThrottledUntilCommit() override; + void SetDeferCommits(bool defer_commits) override; + bool CommitRequested() const override; + bool BeginMainFrameRequested() const override; + void MainThreadHasStoppedFlinging() override; + void Start() override; + void Stop() override; + size_t MaxPartialTextureUpdates() const override; + void ForceSerializeOnSwapBuffers() override; + bool SupportsImplScrolling() const override; + void SetDebugState(const LayerTreeDebugState& debug_state) override; + void AsValueInto(base::debug::TracedValue* value) const override; + bool MainFrameWillHappenForTesting() override; // LayerTreeHostImplClient implementation - virtual void UpdateRendererCapabilitiesOnImplThread() OVERRIDE; - virtual void DidLoseOutputSurfaceOnImplThread() OVERRIDE; - virtual void CommitVSyncParameters(base::TimeTicks timebase, - base::TimeDelta interval) OVERRIDE; - virtual void SetEstimatedParentDrawTime(base::TimeDelta draw_time) OVERRIDE; - virtual void BeginFrame(const BeginFrameArgs& args) OVERRIDE; - virtual void SetMaxSwapsPendingOnImplThread(int max) OVERRIDE; - virtual void DidSwapBuffersOnImplThread() OVERRIDE; - virtual void DidSwapBuffersCompleteOnImplThread() OVERRIDE; - virtual void OnCanDrawStateChanged(bool can_draw) OVERRIDE; - virtual void NotifyReadyToActivate() OVERRIDE; + void UpdateRendererCapabilitiesOnImplThread() override; + void DidLoseOutputSurfaceOnImplThread() override; + void CommitVSyncParameters(base::TimeTicks timebase, + base::TimeDelta interval) override; + void SetEstimatedParentDrawTime(base::TimeDelta draw_time) override; + void SetMaxSwapsPendingOnImplThread(int max) override; + void DidSwapBuffersOnImplThread() override; + void DidSwapBuffersCompleteOnImplThread() override; + void OnCanDrawStateChanged(bool can_draw) override; + void NotifyReadyToActivate() override; // Please call these 3 functions through // LayerTreeHostImpl's SetNeedsRedraw(), SetNeedsRedrawRect() and // SetNeedsAnimate(). - virtual void SetNeedsRedrawOnImplThread() OVERRIDE; - virtual void SetNeedsRedrawRectOnImplThread(const gfx::Rect& dirty_rect) - OVERRIDE; - virtual void SetNeedsAnimateOnImplThread() OVERRIDE; - virtual void SetNeedsManageTilesOnImplThread() OVERRIDE; - virtual void DidInitializeVisibleTileOnImplThread() OVERRIDE; - virtual void SetNeedsCommitOnImplThread() OVERRIDE; - virtual void PostAnimationEventsToMainThreadOnImplThread( - scoped_ptr<AnimationEventsVector> queue) OVERRIDE; - virtual bool ReduceContentsTextureMemoryOnImplThread(size_t limit_bytes, - int priority_cutoff) - OVERRIDE; - virtual bool IsInsideDraw() OVERRIDE; - virtual void RenewTreePriority() OVERRIDE; - virtual void PostDelayedScrollbarFadeOnImplThread( - const base::Closure& start_fade, - base::TimeDelta delay) OVERRIDE; - virtual void DidActivatePendingTree() OVERRIDE; - virtual void DidManageTiles() OVERRIDE; + void SetNeedsRedrawOnImplThread() override; + void SetNeedsRedrawRectOnImplThread(const gfx::Rect& dirty_rect) override; + void SetNeedsAnimateOnImplThread() override; + void SetNeedsManageTilesOnImplThread() override; + void DidInitializeVisibleTileOnImplThread() override; + void SetNeedsCommitOnImplThread() override; + void PostAnimationEventsToMainThreadOnImplThread( + scoped_ptr<AnimationEventsVector> queue) override; + bool ReduceContentsTextureMemoryOnImplThread(size_t limit_bytes, + int priority_cutoff) override; + bool IsInsideDraw() override; + void RenewTreePriority() override; + void PostDelayedScrollbarFadeOnImplThread(const base::Closure& start_fade, + base::TimeDelta delay) override; + void DidActivateSyncTree() override; + void DidManageTiles() override; // SchedulerClient implementation - virtual void SetNeedsBeginFrame(bool enable) OVERRIDE; - virtual void WillBeginImplFrame(const BeginFrameArgs& args) OVERRIDE; - virtual void ScheduledActionSendBeginMainFrame() OVERRIDE; - virtual DrawResult ScheduledActionDrawAndSwapIfPossible() OVERRIDE; - virtual DrawResult ScheduledActionDrawAndSwapForced() OVERRIDE; - virtual void ScheduledActionAnimate() OVERRIDE; - virtual void ScheduledActionCommit() OVERRIDE; - virtual void ScheduledActionUpdateVisibleTiles() OVERRIDE; - virtual void ScheduledActionActivatePendingTree() OVERRIDE; - virtual void ScheduledActionBeginOutputSurfaceCreation() OVERRIDE; - virtual void ScheduledActionManageTiles() OVERRIDE; - virtual void DidAnticipatedDrawTimeChange(base::TimeTicks time) OVERRIDE; - virtual base::TimeDelta DrawDurationEstimate() OVERRIDE; - virtual base::TimeDelta BeginMainFrameToCommitDurationEstimate() OVERRIDE; - virtual base::TimeDelta CommitToActivateDurationEstimate() OVERRIDE; - virtual void DidBeginImplFrameDeadline() OVERRIDE; + BeginFrameSource* ExternalBeginFrameSource() override; + void WillBeginImplFrame(const BeginFrameArgs& args) override; + void ScheduledActionSendBeginMainFrame() override; + DrawResult ScheduledActionDrawAndSwapIfPossible() override; + DrawResult ScheduledActionDrawAndSwapForced() override; + void ScheduledActionAnimate() override; + void ScheduledActionCommit() override; + void ScheduledActionUpdateVisibleTiles() override; + void ScheduledActionActivateSyncTree() override; + void ScheduledActionBeginOutputSurfaceCreation() override; + void ScheduledActionManageTiles() override; + void DidAnticipatedDrawTimeChange(base::TimeTicks time) override; + base::TimeDelta DrawDurationEstimate() override; + base::TimeDelta BeginMainFrameToCommitDurationEstimate() override; + base::TimeDelta CommitToActivateDurationEstimate() override; + void DidBeginImplFrameDeadline() override; // ResourceUpdateControllerClient implementation - virtual void ReadyToFinalizeTextureUpdates() OVERRIDE; + void ReadyToFinalizeTextureUpdates() override; protected: ThreadProxy(LayerTreeHost* layer_tree_host, + scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner); private: @@ -241,13 +238,12 @@ class CC_EXPORT ThreadProxy : public Proxy, void DidCompleteSwapBuffers(); void SetAnimationEvents(scoped_ptr<AnimationEventsVector> queue); void DidLoseOutputSurface(); - void CreateAndInitializeOutputSurface(); + void RequestNewOutputSurface(); void DidInitializeOutputSurface(bool success, const RendererCapabilities& capabilities); void SendCommitRequestToImplThreadIfNeeded(); // Called on impl thread. - struct CommitPendingRequest; struct SchedulerStateRequest; void StartCommitOnImplThread(CompletionEvent* completion, @@ -268,11 +264,10 @@ class CC_EXPORT ThreadProxy : public Proxy, void LayerTreeHostClosedOnImplThread(CompletionEvent* completion); DrawResult DrawSwapInternal(bool forced_draw); void ForceSerializeOnSwapBuffersOnImplThread(CompletionEvent* completion); - void CheckOutputSurfaceStatusOnImplThread(); - void CommitPendingOnImplThreadForTesting(CommitPendingRequest* request); - void SchedulerAsValueOnImplThreadForTesting(SchedulerStateRequest* request); + void MainFrameWillHappenOnImplThreadForTesting(CompletionEvent* completion, + bool* main_frame_will_happen); void AsValueOnImplThread(CompletionEvent* completion, - base::DictionaryValue* state) const; + base::debug::TracedValue* state) const; void SetSwapUsedIncompleteTileOnImplThread(bool used_incomplete_tile); void MainThreadHasStoppedFlingingOnImplThread(); void SetInputThrottledUntilCommitOnImplThread(bool is_throttled); diff --git a/chromium/cc/trees/tree_synchronizer.cc b/chromium/cc/trees/tree_synchronizer.cc index a54bd22efa1..d17f0175b9d 100644 --- a/chromium/cc/trees/tree_synchronizer.cc +++ b/chromium/cc/trees/tree_synchronizer.cc @@ -105,7 +105,7 @@ scoped_ptr<LayerImpl> SynchronizeTreesRecursiveInternal( LayerType* layer, LayerTreeImpl* tree_impl) { if (!layer) - return scoped_ptr<LayerImpl>(); + return nullptr; scoped_ptr<LayerImpl> layer_impl = ReuseOrCreateLayerImpl(new_layers, old_layers, layer, tree_impl); @@ -242,16 +242,23 @@ static void CheckScrollAndClipPointersRecursive(Layer* layer, if (!layer) return; - DCHECK_EQ(!!layer->scroll_parent(), !!layer_impl->scroll_parent()); - if (layer->scroll_parent()) + // Having a scroll parent on the impl thread implies having one the main + // thread, too. The main thread may have a scroll parent that is not in the + // tree because it's been removed but not deleted. In this case, the layer + // impl will have no scroll parent. Same argument applies for clip parents and + // scroll/clip children. + DCHECK(!layer_impl->scroll_parent() || !!layer->scroll_parent()); + DCHECK(!layer_impl->clip_parent() || !!layer->clip_parent()); + DCHECK(!layer_impl->scroll_children() || !!layer->scroll_children()); + DCHECK(!layer_impl->clip_children() || !!layer->clip_children()); + + if (layer_impl->scroll_parent()) DCHECK_EQ(layer->scroll_parent()->id(), layer_impl->scroll_parent()->id()); - DCHECK_EQ(!!layer->clip_parent(), !!layer_impl->clip_parent()); - if (layer->clip_parent()) + if (layer_impl->clip_parent()) DCHECK_EQ(layer->clip_parent()->id(), layer_impl->clip_parent()->id()); - DCHECK_EQ(!!layer->scroll_children(), !!layer_impl->scroll_children()); - if (layer->scroll_children()) { + if (layer_impl->scroll_children()) { for (std::set<Layer*>::iterator it = layer->scroll_children()->begin(); it != layer->scroll_children()->end(); ++it) { @@ -265,8 +272,7 @@ static void CheckScrollAndClipPointersRecursive(Layer* layer, } } - DCHECK_EQ(!!layer->clip_children(), !!layer_impl->clip_children()); - if (layer->clip_children()) { + if (layer_impl->clip_children()) { for (std::set<Layer*>::iterator it = layer->clip_children()->begin(); it != layer->clip_children()->end(); ++it) { diff --git a/chromium/cc/trees/tree_synchronizer_unittest.cc b/chromium/cc/trees/tree_synchronizer_unittest.cc index 46895541ab8..d48f8213c70 100644 --- a/chromium/cc/trees/tree_synchronizer_unittest.cc +++ b/chromium/cc/trees/tree_synchronizer_unittest.cc @@ -16,6 +16,7 @@ #include "cc/test/animation_test_common.h" #include "cc/test/fake_impl_proxy.h" #include "cc/test/fake_layer_tree_host.h" +#include "cc/test/fake_rendering_stats_instrumentation.h" #include "cc/test/test_shared_bitmap_manager.h" #include "cc/trees/proxy.h" #include "cc/trees/single_thread_proxy.h" @@ -30,7 +31,7 @@ class MockLayerImpl : public LayerImpl { int layer_id) { return make_scoped_ptr(new MockLayerImpl(tree_impl, layer_id)); } - virtual ~MockLayerImpl() { + ~MockLayerImpl() override { if (layer_impl_destruction_list_) layer_impl_destruction_list_->push_back(id()); } @@ -54,12 +55,11 @@ class MockLayer : public Layer { return make_scoped_refptr(new MockLayer(layer_impl_destruction_list)); } - virtual scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) - OVERRIDE { - return MockLayerImpl::Create(tree_impl, layer_id_).PassAs<LayerImpl>(); + scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override { + return MockLayerImpl::Create(tree_impl, layer_id_); } - virtual void PushPropertiesTo(LayerImpl* layer_impl) OVERRIDE { + void PushPropertiesTo(LayerImpl* layer_impl) override { Layer::PushPropertiesTo(layer_impl); MockLayerImpl* mock_layer_impl = static_cast<MockLayerImpl*>(layer_impl); @@ -69,7 +69,7 @@ class MockLayer : public Layer { private: explicit MockLayer(std::vector<int>* layer_impl_destruction_list) : Layer(), layer_impl_destruction_list_(layer_impl_destruction_list) {} - virtual ~MockLayer() {} + ~MockLayer() override {} std::vector<int>* layer_impl_destruction_list_; }; @@ -88,10 +88,10 @@ class FakeLayerAnimationController : public LayerAnimationController { : LayerAnimationController(1), synchronized_animations_(false) {} - virtual ~FakeLayerAnimationController() {} + ~FakeLayerAnimationController() override {} - virtual void PushAnimationUpdatesTo(LayerAnimationController* controller_impl) - OVERRIDE { + void PushAnimationUpdatesTo( + LayerAnimationController* controller_impl) override { LayerAnimationController::PushAnimationUpdatesTo(controller_impl); synchronized_animations_ = true; } @@ -189,9 +189,12 @@ void ExpectTreesAreIdentical(Layer* layer, class TreeSynchronizerTest : public testing::Test { public: - TreeSynchronizerTest() : host_(FakeLayerTreeHost::Create()) {} + TreeSynchronizerTest() + : client_(FakeLayerTreeHostClient::DIRECT_3D), + host_(FakeLayerTreeHost::Create(&client_)) {} protected: + FakeLayerTreeHostClient client_; scoped_ptr<FakeLayerTreeHost> host_; }; @@ -199,9 +202,8 @@ class TreeSynchronizerTest : public testing::Test { // return a null tree. TEST_F(TreeSynchronizerTest, SyncNullTree) { scoped_ptr<LayerImpl> layer_impl_tree_root = - TreeSynchronizer::SynchronizeTrees(static_cast<Layer*>(NULL), - scoped_ptr<LayerImpl>(), - host_->active_tree()); + TreeSynchronizer::SynchronizeTrees( + static_cast<Layer*>(NULL), nullptr, host_->active_tree()); EXPECT_TRUE(!layer_impl_tree_root.get()); } @@ -216,9 +218,8 @@ TEST_F(TreeSynchronizerTest, SyncSimpleTreeFromEmpty) { host_->SetRootLayer(layer_tree_root); scoped_ptr<LayerImpl> layer_impl_tree_root = - TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), - scoped_ptr<LayerImpl>(), - host_->active_tree()); + TreeSynchronizer::SynchronizeTrees( + layer_tree_root.get(), nullptr, host_->active_tree()); ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root.get(), @@ -238,9 +239,8 @@ TEST_F(TreeSynchronizerTest, SyncSimpleTreeReusingLayers) { host_->SetRootLayer(layer_tree_root); scoped_ptr<LayerImpl> layer_impl_tree_root = - TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), - scoped_ptr<LayerImpl>(), - host_->active_tree()); + TreeSynchronizer::SynchronizeTrees( + layer_tree_root.get(), nullptr, host_->active_tree()); ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root.get(), host_->active_tree()); @@ -286,9 +286,8 @@ TEST_F(TreeSynchronizerTest, SyncSimpleTreeAndTrackStackingOrderChange) { host_->SetRootLayer(layer_tree_root); scoped_ptr<LayerImpl> layer_impl_tree_root = - TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), - scoped_ptr<LayerImpl>(), - host_->active_tree()); + TreeSynchronizer::SynchronizeTrees( + layer_tree_root.get(), nullptr, host_->active_tree()); ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root.get(), host_->active_tree()); @@ -339,9 +338,8 @@ TEST_F(TreeSynchronizerTest, SyncSimpleTreeAndProperties) { layer_tree_root->children()[1]->SavePaintProperties(); scoped_ptr<LayerImpl> layer_impl_tree_root = - TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), - scoped_ptr<LayerImpl>(), - host_->active_tree()); + TreeSynchronizer::SynchronizeTrees( + layer_tree_root.get(), nullptr, host_->active_tree()); ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root.get(), host_->active_tree()); @@ -390,9 +388,8 @@ TEST_F(TreeSynchronizerTest, ReuseLayerImplsAfterStructuralChange) { host_->SetRootLayer(layer_tree_root); scoped_ptr<LayerImpl> layer_impl_tree_root = - TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), - scoped_ptr<LayerImpl>(), - host_->active_tree()); + TreeSynchronizer::SynchronizeTrees( + layer_tree_root.get(), nullptr, host_->active_tree()); ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root.get(), host_->active_tree()); @@ -447,9 +444,8 @@ TEST_F(TreeSynchronizerTest, SyncSimpleTreeThenDestroy) { int old_tree_second_child_layer_id = old_layer_tree_root->children()[1]->id(); scoped_ptr<LayerImpl> layer_impl_tree_root = - TreeSynchronizer::SynchronizeTrees(old_layer_tree_root.get(), - scoped_ptr<LayerImpl>(), - host_->active_tree()); + TreeSynchronizer::SynchronizeTrees( + old_layer_tree_root.get(), nullptr, host_->active_tree()); ExpectTreesAreIdentical(old_layer_tree_root.get(), layer_impl_tree_root.get(), host_->active_tree()); @@ -514,9 +510,8 @@ TEST_F(TreeSynchronizerTest, SyncMaskReplicaAndReplicaMaskLayers) { host_->SetRootLayer(layer_tree_root); scoped_ptr<LayerImpl> layer_impl_tree_root = - TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), - scoped_ptr<LayerImpl>(), - host_->active_tree()); + TreeSynchronizer::SynchronizeTrees( + layer_tree_root.get(), nullptr, host_->active_tree()); ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root.get(), @@ -566,6 +561,7 @@ TEST_F(TreeSynchronizerTest, SynchronizeAnimations) { &proxy, &stats_instrumentation, shared_bitmap_manager.get(), + NULL, 0); scoped_refptr<Layer> layer_tree_root = Layer::Create(); @@ -578,9 +574,8 @@ TEST_F(TreeSynchronizerTest, SynchronizeAnimations) { layer_tree_root->layer_animation_controller())->SynchronizedAnimations()); scoped_ptr<LayerImpl> layer_impl_tree_root = - TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), - scoped_ptr<LayerImpl>(), - host_->active_tree()); + TreeSynchronizer::SynchronizeTrees( + layer_tree_root.get(), nullptr, host_->active_tree()); TreeSynchronizer::PushProperties(layer_tree_root.get(), layer_impl_tree_root.get()); layer_impl_tree_root = @@ -605,6 +600,7 @@ TEST_F(TreeSynchronizerTest, SynchronizeScrollParent) { &proxy, &stats_instrumentation, shared_bitmap_manager.get(), + NULL, 0); scoped_refptr<Layer> layer_tree_root = Layer::Create(); @@ -616,13 +612,12 @@ TEST_F(TreeSynchronizerTest, SynchronizeScrollParent) { host_->SetRootLayer(layer_tree_root); // First child is the second and third child's scroll parent. - layer_tree_root->children()[1]->SetScrollParent(scroll_parent); - layer_tree_root->children()[2]->SetScrollParent(scroll_parent); + layer_tree_root->children()[1]->SetScrollParent(scroll_parent.get()); + layer_tree_root->children()[2]->SetScrollParent(scroll_parent.get()); scoped_ptr<LayerImpl> layer_impl_tree_root = - TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), - scoped_ptr<LayerImpl>(), - host_impl->active_tree()); + TreeSynchronizer::SynchronizeTrees( + layer_tree_root.get(), nullptr, host_impl->active_tree()); TreeSynchronizer::PushProperties(layer_tree_root.get(), layer_impl_tree_root.get()); { @@ -650,7 +645,7 @@ TEST_F(TreeSynchronizerTest, SynchronizeScrollParent) { // Add an additional scroll layer. scoped_refptr<Layer> additional_scroll_child = Layer::Create(); layer_tree_root->AddChild(additional_scroll_child); - additional_scroll_child->SetScrollParent(scroll_parent); + additional_scroll_child->SetScrollParent(scroll_parent.get()); layer_impl_tree_root = TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), layer_impl_tree_root.Pass(), @@ -678,6 +673,7 @@ TEST_F(TreeSynchronizerTest, SynchronizeClipParent) { &proxy, &stats_instrumentation, shared_bitmap_manager.get(), + NULL, 0); scoped_refptr<Layer> layer_tree_root = Layer::Create(); @@ -693,13 +689,12 @@ TEST_F(TreeSynchronizerTest, SynchronizeClipParent) { host_->SetRootLayer(layer_tree_root); // First child is the second and third child's scroll parent. - clip_child1->SetClipParent(clip_parent); - clip_child2->SetClipParent(clip_parent); + clip_child1->SetClipParent(clip_parent.get()); + clip_child2->SetClipParent(clip_parent.get()); scoped_ptr<LayerImpl> layer_impl_tree_root = - TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), - scoped_ptr<LayerImpl>(), - host_impl->active_tree()); + TreeSynchronizer::SynchronizeTrees( + layer_tree_root.get(), nullptr, host_impl->active_tree()); TreeSynchronizer::PushProperties(layer_tree_root.get(), layer_impl_tree_root.get()); ExpectTreesAreIdentical(layer_tree_root.get(), @@ -723,7 +718,7 @@ TEST_F(TreeSynchronizerTest, SynchronizeClipParent) { // Add an additional clip child. scoped_refptr<Layer> additional_clip_child = Layer::Create(); intervening->AddChild(additional_clip_child); - additional_clip_child->SetClipParent(clip_parent); + additional_clip_child->SetClipParent(clip_parent.get()); layer_impl_tree_root = TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), layer_impl_tree_root.Pass(), |