summaryrefslogtreecommitdiff
path: root/cc
diff options
context:
space:
mode:
authorTorne (Richard Coles) <torne@google.com>2013-10-31 11:16:26 +0000
committerTorne (Richard Coles) <torne@google.com>2013-10-31 11:16:26 +0000
commit1e9bf3e0803691d0a228da41fc608347b6db4340 (patch)
treeab2e5565f71b4219b3da406e19f16fe306704ef5 /cc
parentf10b58d5bc6ae3e74076fc4ccca14cbc57ef805c (diff)
downloadchromium_org-1e9bf3e0803691d0a228da41fc608347b6db4340.tar.gz
Merge from Chromium at DEPS revision 232015
This commit was generated by merge_to_master.py. Change-Id: If86767ad396b9e2e1a4c1e9df1427daea29703ef
Diffstat (limited to 'cc')
-rw-r--r--cc/DEPS1
-rw-r--r--cc/PRESUBMIT.py4
-rw-r--r--cc/animation/animation.cc3
-rw-r--r--cc/animation/animation.h1
-rw-r--r--cc/animation/animation_curve.cc7
-rw-r--r--cc/animation/animation_curve.h14
-rw-r--r--cc/animation/keyframed_animation_curve.cc91
-rw-r--r--cc/animation/keyframed_animation_curve.h46
-rw-r--r--cc/animation/keyframed_animation_curve_unittest.cc94
-rw-r--r--cc/animation/layer_animation_controller.cc18
-rw-r--r--cc/animation/layer_animation_controller.h1
-rw-r--r--cc/animation/layer_animation_controller_unittest.cc12
-rw-r--r--cc/animation/scrollbar_animation_controller_thinning.cc123
-rw-r--r--cc/animation/scrollbar_animation_controller_thinning.h24
-rw-r--r--cc/animation/scrollbar_animation_controller_thinning_unittest.cc212
-rw-r--r--cc/animation/transform_operation.cc18
-rw-r--r--cc/animation/transform_operations_unittest.cc37
-rw-r--r--cc/base/math_util.cc7
-rw-r--r--cc/base/switches.cc12
-rw-r--r--cc/base/switches.h1
-rw-r--r--cc/cc.gyp3
-rw-r--r--cc/cc.target.darwin-arm.mk9
-rw-r--r--cc/cc.target.darwin-mips.mk9
-rw-r--r--cc/cc.target.darwin-x86.mk9
-rw-r--r--cc/cc.target.linux-arm.mk9
-rw-r--r--cc/cc.target.linux-mips.mk9
-rw-r--r--cc/cc.target.linux-x86.mk9
-rw-r--r--cc/cc_tests.gyp7
-rw-r--r--cc/debug/fake_web_graphics_context_3d.cc63
-rw-r--r--cc/debug/fake_web_graphics_context_3d.h22
-rw-r--r--cc/debug/test_context_support.cc4
-rw-r--r--cc/debug/test_context_support.h2
-rw-r--r--cc/debug/test_web_graphics_context_3d.cc129
-rw-r--r--cc/debug/test_web_graphics_context_3d.h33
-rw-r--r--cc/input/top_controls_manager.cc27
-rw-r--r--cc/input/top_controls_manager.h7
-rw-r--r--cc/input/top_controls_manager_unittest.cc96
-rw-r--r--cc/layers/delegated_frame_resource_collection.cc23
-rw-r--r--cc/layers/delegated_frame_resource_collection.h6
-rw-r--r--cc/layers/delegated_frame_resource_collection_unittest.cc159
-rw-r--r--cc/layers/delegated_renderer_layer_impl.cc14
-rw-r--r--cc/layers/delegated_renderer_layer_impl_unittest.cc110
-rw-r--r--cc/layers/layer.cc11
-rw-r--r--cc/layers/layer.h1
-rw-r--r--cc/layers/layer_impl.cc9
-rw-r--r--cc/layers/layer_impl.h2
-rw-r--r--cc/layers/layer_unittest.cc7
-rw-r--r--cc/layers/nine_patch_layer_unittest.cc2
-rw-r--r--cc/layers/picture_layer.cc16
-rw-r--r--cc/layers/picture_layer.h2
-rw-r--r--cc/layers/picture_layer_impl.cc4
-rw-r--r--cc/layers/picture_layer_impl_unittest.cc35
-rw-r--r--cc/layers/picture_layer_unittest.cc69
-rw-r--r--cc/layers/scrollbar_layer_impl_base.cc7
-rw-r--r--cc/layers/scrollbar_layer_impl_base.h4
-rw-r--r--cc/layers/scrollbar_layer_unittest.cc2
-rw-r--r--cc/layers/texture_layer.cc27
-rw-r--r--cc/layers/texture_layer.h5
-rw-r--r--cc/layers/texture_layer_unittest.cc105
-rw-r--r--cc/layers/tiled_layer_unittest.cc3
-rw-r--r--cc/layers/ui_resource_layer_impl.cc5
-rw-r--r--cc/layers/ui_resource_layer_impl_unittest.cc31
-rw-r--r--cc/layers/ui_resource_layer_unittest.cc2
-rw-r--r--cc/output/begin_frame_args.cc7
-rw-r--r--cc/output/context_provider.cc1
-rw-r--r--cc/output/context_provider.h1
-rw-r--r--cc/output/delegating_renderer.cc18
-rw-r--r--cc/output/direct_renderer.cc28
-rw-r--r--cc/output/direct_renderer.h1
-rw-r--r--cc/output/filter_operation.cc73
-rw-r--r--cc/output/filter_operations_unittest.cc5
-rw-r--r--cc/output/gl_renderer.cc13
-rw-r--r--cc/output/gl_renderer_unittest.cc30
-rw-r--r--cc/output/managed_memory_policy.cc40
-rw-r--r--cc/output/managed_memory_policy.h29
-rw-r--r--cc/output/output_surface.cc104
-rw-r--r--cc/output/output_surface.h37
-rw-r--r--cc/output/output_surface_client.h2
-rw-r--r--cc/output/output_surface_unittest.cc204
-rw-r--r--cc/output/software_renderer_unittest.cc2
-rw-r--r--cc/quads/render_pass.cc7
-rw-r--r--cc/quads/render_pass_unittest.cc116
-rw-r--r--cc/resources/bitmap_skpicture_content_layer_updater.cc4
-rw-r--r--cc/resources/image_raster_worker_pool.cc4
-rw-r--r--cc/resources/picture.cc31
-rw-r--r--cc/resources/picture.h8
-rw-r--r--cc/resources/picture_layer_tiling_perftest.cc5
-rw-r--r--cc/resources/picture_layer_tiling_set_unittest.cc2
-rw-r--r--cc/resources/picture_pile.cc166
-rw-r--r--cc/resources/picture_pile.h6
-rw-r--r--cc/resources/picture_pile_base.cc96
-rw-r--r--cc/resources/picture_pile_base.h23
-rw-r--r--cc/resources/picture_pile_impl.cc246
-rw-r--r--cc/resources/picture_pile_impl.h14
-rw-r--r--cc/resources/picture_pile_impl_unittest.cc79
-rw-r--r--cc/resources/picture_pile_unittest.cc81
-rw-r--r--cc/resources/pixel_buffer_raster_worker_pool.cc4
-rw-r--r--cc/resources/prioritized_resource.cc7
-rw-r--r--cc/resources/prioritized_resource.h5
-rw-r--r--cc/resources/prioritized_resource_manager.cc20
-rw-r--r--cc/resources/prioritized_resource_manager.h10
-rw-r--r--cc/resources/prioritized_resource_unittest.cc222
-rw-r--r--cc/resources/prioritized_tile_set_unittest.cc6
-rw-r--r--cc/resources/raster_worker_pool.cc1
-rw-r--r--cc/resources/raster_worker_pool_unittest.cc2
-rw-r--r--cc/resources/resource.h3
-rw-r--r--cc/resources/resource_format.cc1
-rw-r--r--cc/resources/resource_format.h3
-rw-r--r--cc/resources/resource_provider.cc204
-rw-r--r--cc/resources/resource_provider.h48
-rw-r--r--cc/resources/resource_provider_unittest.cc1064
-rw-r--r--cc/resources/resource_update_controller.cc3
-rw-r--r--cc/resources/resource_update_controller_unittest.cc2
-rw-r--r--cc/resources/scoped_resource_unittest.cc8
-rw-r--r--cc/resources/shared_bitmap.cc17
-rw-r--r--cc/resources/shared_bitmap.h51
-rw-r--r--cc/resources/shared_bitmap_manager.h32
-rw-r--r--cc/resources/tile_manager.cc2
-rw-r--r--cc/resources/tile_manager_perftest.cc2
-rw-r--r--cc/resources/tile_manager_unittest.cc2
-rw-r--r--cc/resources/transferable_resource.cc7
-rw-r--r--cc/resources/transferable_resource.h1
-rw-r--r--cc/resources/ui_resource_bitmap.cc18
-rw-r--r--cc/resources/ui_resource_bitmap.h15
-rw-r--r--cc/resources/video_resource_updater.cc28
-rw-r--r--cc/resources/video_resource_updater_unittest.cc2
-rw-r--r--cc/scheduler/delay_based_time_source.cc21
-rw-r--r--cc/scheduler/delay_based_time_source.h19
-rw-r--r--cc/scheduler/frame_rate_controller.cc3
-rw-r--r--cc/scheduler/scheduler.cc8
-rw-r--r--cc/scheduler/scheduler.h2
-rw-r--r--cc/scheduler/scheduler_settings.cc2
-rw-r--r--cc/scheduler/scheduler_state_machine.cc31
-rw-r--r--cc/scheduler/scheduler_state_machine.h5
-rw-r--r--cc/scheduler/scheduler_state_machine_unittest.cc26
-rw-r--r--cc/scheduler/texture_uploader.cc29
-rw-r--r--cc/scheduler/texture_uploader.h1
-rw-r--r--cc/test/data/background_filter_blur_off_axis.pngbin7292 -> 7289 bytes
-rw-r--r--cc/test/data/touch_region_heavy.json515
-rw-r--r--cc/test/data/touch_region_light.json67
-rw-r--r--cc/test/fake_layer_tree_host.h2
-rw-r--r--cc/test/fake_layer_tree_host_client.h4
-rw-r--r--cc/test/fake_layer_tree_host_impl.cc11
-rw-r--r--cc/test/fake_layer_tree_host_impl_client.h3
-rw-r--r--cc/test/fake_output_surface.cc18
-rw-r--r--cc/test/fake_output_surface.h10
-rw-r--r--cc/test/fake_output_surface_client.cc4
-rw-r--r--cc/test/fake_output_surface_client.h10
-rw-r--r--cc/test/fake_picture_layer_impl.h1
-rw-r--r--cc/test/fake_picture_pile_impl.cc11
-rw-r--r--cc/test/fake_picture_pile_impl.h5
-rw-r--r--cc/test/fake_proxy.cc2
-rw-r--r--cc/test/fake_proxy.h1
-rw-r--r--cc/test/fake_ui_resource_layer_tree_host_impl.cc16
-rw-r--r--cc/test/fake_ui_resource_layer_tree_host_impl.h4
-rw-r--r--cc/test/layer_tree_json_parser.cc24
-rw-r--r--cc/test/layer_tree_json_parser_unittest.cc116
-rw-r--r--cc/test/layer_tree_pixel_test.cc7
-rw-r--r--cc/test/layer_tree_test.cc22
-rw-r--r--cc/test/layer_tree_test.h4
-rw-r--r--cc/test/pixel_test.cc15
-rw-r--r--cc/test/run_all_perftests.cc16
-rw-r--r--cc/trees/layer_tree_host.cc30
-rw-r--r--cc/trees/layer_tree_host.h15
-rw-r--r--cc/trees/layer_tree_host_client.h4
-rw-r--r--cc/trees/layer_tree_host_common.cc75
-rw-r--r--cc/trees/layer_tree_host_common.h4
-rw-r--r--cc/trees/layer_tree_host_common_perftest.cc204
-rw-r--r--cc/trees/layer_tree_host_common_unittest.cc197
-rw-r--r--cc/trees/layer_tree_host_impl.cc107
-rw-r--r--cc/trees/layer_tree_host_impl.h18
-rw-r--r--cc/trees/layer_tree_host_impl_unittest.cc213
-rw-r--r--cc/trees/layer_tree_host_perftest.cc4
-rw-r--r--cc/trees/layer_tree_host_pixeltest_on_demand_raster.cc4
-rw-r--r--cc/trees/layer_tree_host_unittest.cc168
-rw-r--r--cc/trees/layer_tree_host_unittest_animation.cc9
-rw-r--r--cc/trees/layer_tree_host_unittest_context.cc13
-rw-r--r--cc/trees/layer_tree_host_unittest_damage.cc4
-rw-r--r--cc/trees/layer_tree_host_unittest_scroll.cc22
-rw-r--r--cc/trees/layer_tree_impl.cc12
-rw-r--r--cc/trees/layer_tree_impl.h4
-rw-r--r--cc/trees/layer_tree_settings.cc4
-rw-r--r--cc/trees/layer_tree_settings.h2
-rw-r--r--cc/trees/occlusion_tracker.cc6
-rw-r--r--cc/trees/proxy.h1
-rw-r--r--cc/trees/single_thread_proxy.cc12
-rw-r--r--cc/trees/single_thread_proxy.h4
-rw-r--r--cc/trees/thread_proxy.cc148
-rw-r--r--cc/trees/thread_proxy.h34
-rw-r--r--cc/trees/tree_synchronizer_unittest.cc21
190 files changed, 5353 insertions, 2128 deletions
diff --git a/cc/DEPS b/cc/DEPS
index 165444f254..4e1cc74d6c 100644
--- a/cc/DEPS
+++ b/cc/DEPS
@@ -1,6 +1,7 @@
include_rules = [
"+gpu/GLES2",
"+gpu/command_buffer/client/context_support.h",
+ "+gpu/command_buffer/common/gpu_memory_allocation.h",
"+gpu/command_buffer/common/mailbox.h",
"+media",
"+skia/ext",
diff --git a/cc/PRESUBMIT.py b/cc/PRESUBMIT.py
index 9e84e3f660..76358f39b0 100644
--- a/cc/PRESUBMIT.py
+++ b/cc/PRESUBMIT.py
@@ -196,4 +196,8 @@ def CheckChangeOnUpload(input_api, output_api):
def GetPreferredTrySlaves(project, change):
return [
'linux_layout_rel',
+ 'win_gpu',
+ 'linux_gpu',
+ 'mac_gpu',
+ 'mac_gpu_retina',
]
diff --git a/cc/animation/animation.cc b/cc/animation/animation.cc
index 6b4591797e..6b5966be29 100644
--- a/cc/animation/animation.cc
+++ b/cc/animation/animation.cc
@@ -33,7 +33,8 @@ COMPILE_ASSERT(static_cast<int>(cc::Animation::RunStateEnumSize) ==
static const char* const s_targetPropertyNames[] = {
"Transform",
"Opacity",
- "Filter"
+ "Filter",
+ "BackgroundColor"
};
COMPILE_ASSERT(static_cast<int>(cc::Animation::TargetPropertyEnumSize) ==
diff --git a/cc/animation/animation.h b/cc/animation/animation.h
index 9946298a8e..f640318a51 100644
--- a/cc/animation/animation.h
+++ b/cc/animation/animation.h
@@ -47,6 +47,7 @@ class CC_EXPORT Animation {
Transform = 0,
Opacity,
Filter,
+ BackgroundColor,
// This sentinel must be last.
TargetPropertyEnumSize
};
diff --git a/cc/animation/animation_curve.cc b/cc/animation/animation_curve.cc
index cf04da7f39..65c21db556 100644
--- a/cc/animation/animation_curve.cc
+++ b/cc/animation/animation_curve.cc
@@ -8,6 +8,13 @@
namespace cc {
+const ColorAnimationCurve* AnimationCurve::ToColorAnimationCurve() const {
+ DCHECK(Type() == AnimationCurve::Color);
+ return static_cast<const ColorAnimationCurve*>(this);
+}
+
+AnimationCurve::CurveType ColorAnimationCurve::Type() const { return Color; }
+
const FloatAnimationCurve* AnimationCurve::ToFloatAnimationCurve() const {
DCHECK(Type() == AnimationCurve::Float);
return static_cast<const FloatAnimationCurve*>(this);
diff --git a/cc/animation/animation_curve.h b/cc/animation/animation_curve.h
index f4cdb10560..f84bb1ab4f 100644
--- a/cc/animation/animation_curve.h
+++ b/cc/animation/animation_curve.h
@@ -16,6 +16,7 @@ class BoxF;
namespace cc {
+class ColorAnimationCurve;
class FilterAnimationCurve;
class FloatAnimationCurve;
class TransformAnimationCurve;
@@ -24,7 +25,7 @@ class TransformOperations;
// An animation curve is a function that returns a value given a time.
class CC_EXPORT AnimationCurve {
public:
- enum CurveType { Float, Transform, Filter };
+ enum CurveType { Color, Float, Transform, Filter };
virtual ~AnimationCurve() {}
@@ -32,11 +33,22 @@ class CC_EXPORT AnimationCurve {
virtual CurveType Type() const = 0;
virtual scoped_ptr<AnimationCurve> Clone() const = 0;
+ const ColorAnimationCurve* ToColorAnimationCurve() const;
const FloatAnimationCurve* ToFloatAnimationCurve() const;
const TransformAnimationCurve* ToTransformAnimationCurve() const;
const FilterAnimationCurve* ToFilterAnimationCurve() const;
};
+class CC_EXPORT ColorAnimationCurve : public AnimationCurve {
+ public:
+ virtual ~ColorAnimationCurve() {}
+
+ virtual SkColor GetValue(double t) const = 0;
+
+ // Partial Animation implementation.
+ virtual CurveType Type() const OVERRIDE;
+};
+
class CC_EXPORT FloatAnimationCurve : public AnimationCurve {
public:
virtual ~FloatAnimationCurve() {}
diff --git a/cc/animation/keyframed_animation_curve.cc b/cc/animation/keyframed_animation_curve.cc
index 14dfd9c844..d855decbaf 100644
--- a/cc/animation/keyframed_animation_curve.cc
+++ b/cc/animation/keyframed_animation_curve.cc
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include "cc/animation/keyframed_animation_curve.h"
+#include "ui/gfx/animation/tween.h"
#include "ui/gfx/box_f.h"
namespace cc {
@@ -26,6 +27,17 @@ void InsertKeyframe(scoped_ptr<Keyframe> keyframe,
keyframes.push_back(keyframe.Pass());
}
+template <class Keyframes>
+float GetProgress(double t, size_t i, const Keyframes& keyframes) {
+ float progress =
+ static_cast<float>((t - keyframes[i]->Time()) /
+ (keyframes[i + 1]->Time() - keyframes[i]->Time()));
+
+ if (keyframes[i]->timing_function())
+ progress = keyframes[i]->timing_function()->GetValue(progress);
+ return progress;
+}
+
scoped_ptr<TimingFunction> CloneTimingFunction(
const TimingFunction* timing_function) {
DCHECK(timing_function);
@@ -46,6 +58,31 @@ double Keyframe::Time() const {
return time_;
}
+scoped_ptr<ColorKeyframe> ColorKeyframe::Create(
+ double time,
+ SkColor value,
+ scoped_ptr<TimingFunction> timing_function) {
+ return make_scoped_ptr(
+ new ColorKeyframe(time, value, timing_function.Pass()));
+}
+
+ColorKeyframe::ColorKeyframe(double time,
+ SkColor value,
+ scoped_ptr<TimingFunction> timing_function)
+ : Keyframe(time, timing_function.Pass()),
+ value_(value) {}
+
+ColorKeyframe::~ColorKeyframe() {}
+
+SkColor ColorKeyframe::Value() const { return value_; }
+
+scoped_ptr<ColorKeyframe> ColorKeyframe::Clone() const {
+ scoped_ptr<TimingFunction> func;
+ if (timing_function())
+ func = CloneTimingFunction(timing_function());
+ return ColorKeyframe::Create(Time(), Value(), func.Pass());
+}
+
scoped_ptr<FloatKeyframe> FloatKeyframe::Create(
double time,
float value,
@@ -127,6 +164,53 @@ scoped_ptr<FilterKeyframe> FilterKeyframe::Clone() const {
return FilterKeyframe::Create(Time(), Value(), func.Pass());
}
+scoped_ptr<KeyframedColorAnimationCurve> KeyframedColorAnimationCurve::
+ Create() {
+ return make_scoped_ptr(new KeyframedColorAnimationCurve);
+}
+
+KeyframedColorAnimationCurve::KeyframedColorAnimationCurve() {}
+
+KeyframedColorAnimationCurve::~KeyframedColorAnimationCurve() {}
+
+void KeyframedColorAnimationCurve::AddKeyframe(
+ scoped_ptr<ColorKeyframe> keyframe) {
+ InsertKeyframe(keyframe.Pass(), keyframes_);
+}
+
+double KeyframedColorAnimationCurve::Duration() const {
+ return keyframes_.back()->Time() - keyframes_.front()->Time();
+}
+
+scoped_ptr<AnimationCurve> KeyframedColorAnimationCurve::Clone() const {
+ scoped_ptr<KeyframedColorAnimationCurve> to_return(
+ KeyframedColorAnimationCurve::Create());
+ for (size_t i = 0; i < keyframes_.size(); ++i)
+ to_return->AddKeyframe(keyframes_[i]->Clone());
+ return to_return.PassAs<AnimationCurve>();
+}
+
+SkColor KeyframedColorAnimationCurve::GetValue(double t) const {
+ if (t <= keyframes_.front()->Time())
+ return keyframes_.front()->Value();
+
+ if (t >= keyframes_.back()->Time())
+ return keyframes_.back()->Value();
+
+ size_t i = 0;
+ for (; i < keyframes_.size() - 1; ++i) {
+ if (t < keyframes_[i + 1]->Time())
+ break;
+ }
+
+ float progress = GetProgress(t, i, keyframes_);
+
+ return gfx::Tween::ColorValueBetween(
+ progress, keyframes_[i]->Value(), keyframes_[i + 1]->Value());
+}
+
+// KeyframedFloatAnimationCurve
+
scoped_ptr<KeyframedFloatAnimationCurve> KeyframedFloatAnimationCurve::
Create() {
return make_scoped_ptr(new KeyframedFloatAnimationCurve);
@@ -166,12 +250,7 @@ float KeyframedFloatAnimationCurve::GetValue(double t) const {
break;
}
- float progress =
- static_cast<float>((t - keyframes_[i]->Time()) /
- (keyframes_[i+1]->Time() - keyframes_[i]->Time()));
-
- if (keyframes_[i]->timing_function())
- progress = keyframes_[i]->timing_function()->GetValue(progress);
+ float progress = GetProgress(t, i, keyframes_);
return keyframes_[i]->Value() +
(keyframes_[i+1]->Value() - keyframes_[i]->Value()) * progress;
diff --git a/cc/animation/keyframed_animation_curve.h b/cc/animation/keyframed_animation_curve.h
index 5892dc70e5..4b5ac3bf30 100644
--- a/cc/animation/keyframed_animation_curve.h
+++ b/cc/animation/keyframed_animation_curve.h
@@ -31,6 +31,26 @@ class CC_EXPORT Keyframe {
DISALLOW_COPY_AND_ASSIGN(Keyframe);
};
+class CC_EXPORT ColorKeyframe : public Keyframe {
+ public:
+ static scoped_ptr<ColorKeyframe> Create(
+ double time,
+ SkColor value,
+ scoped_ptr<TimingFunction> timing_function);
+ virtual ~ColorKeyframe();
+
+ SkColor Value() const;
+
+ scoped_ptr<ColorKeyframe> Clone() const;
+
+ private:
+ ColorKeyframe(double time,
+ SkColor value,
+ scoped_ptr<TimingFunction> timing_function);
+
+ SkColor value_;
+};
+
class CC_EXPORT FloatKeyframe : public Keyframe {
public:
static scoped_ptr<FloatKeyframe> Create(
@@ -93,6 +113,32 @@ class CC_EXPORT FilterKeyframe : public Keyframe {
FilterOperations value_;
};
+class CC_EXPORT KeyframedColorAnimationCurve : public ColorAnimationCurve {
+ public:
+ // It is required that the keyframes be sorted by time.
+ static scoped_ptr<KeyframedColorAnimationCurve> Create();
+
+ virtual ~KeyframedColorAnimationCurve();
+
+ void AddKeyframe(scoped_ptr<ColorKeyframe> keyframe);
+
+ // AnimationCurve implementation
+ virtual double Duration() const OVERRIDE;
+ virtual scoped_ptr<AnimationCurve> Clone() const OVERRIDE;
+
+ // BackgrounColorAnimationCurve implementation
+ virtual SkColor GetValue(double t) const OVERRIDE;
+
+ private:
+ KeyframedColorAnimationCurve();
+
+ // Always sorted in order of increasing time. No two keyframes have the
+ // same time.
+ ScopedPtrVector<ColorKeyframe> keyframes_;
+
+ DISALLOW_COPY_AND_ASSIGN(KeyframedColorAnimationCurve);
+};
+
class CC_EXPORT KeyframedFloatAnimationCurve : public FloatAnimationCurve {
public:
// It is required that the keyframes be sorted by time.
diff --git a/cc/animation/keyframed_animation_curve_unittest.cc b/cc/animation/keyframed_animation_curve_unittest.cc
index 7eb3b1c5b5..63e9866802 100644
--- a/cc/animation/keyframed_animation_curve_unittest.cc
+++ b/cc/animation/keyframed_animation_curve_unittest.cc
@@ -7,7 +7,9 @@
#include "cc/animation/transform_operations.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/gfx/animation/tween.h"
#include "ui/gfx/box_f.h"
+#include "ui/gfx/test/color_util.h"
namespace cc {
namespace {
@@ -22,6 +24,98 @@ void ExpectBrightness(double brightness, const FilterOperations& filter) {
EXPECT_FLOAT_EQ(brightness, filter.at(0).amount());
}
+// Tests that a color animation with one keyframe works as expected.
+TEST(KeyframedAnimationCurveTest, OneColorKeyFrame) {
+ SkColor color = SkColorSetARGB(255, 255, 255, 255);
+ scoped_ptr<KeyframedColorAnimationCurve> curve(
+ KeyframedColorAnimationCurve::Create());
+ curve->AddKeyframe(
+ ColorKeyframe::Create(0.0, color, scoped_ptr<TimingFunction>()));
+
+ EXPECT_SKCOLOR_EQ(color, curve->GetValue(-1.f));
+ EXPECT_SKCOLOR_EQ(color, curve->GetValue(0.f));
+ EXPECT_SKCOLOR_EQ(color, curve->GetValue(0.5f));
+ EXPECT_SKCOLOR_EQ(color, curve->GetValue(1.f));
+ EXPECT_SKCOLOR_EQ(color, curve->GetValue(2.f));
+}
+
+// Tests that a color animation with two keyframes works as expected.
+TEST(KeyframedAnimationCurveTest, TwoColorKeyFrame) {
+ SkColor color_a = SkColorSetARGB(255, 255, 0, 0);
+ SkColor color_b = SkColorSetARGB(255, 0, 255, 0);
+ SkColor color_midpoint = gfx::Tween::ColorValueBetween(0.5, color_a, color_b);
+ scoped_ptr<KeyframedColorAnimationCurve> curve(
+ KeyframedColorAnimationCurve::Create());
+ curve->AddKeyframe(
+ ColorKeyframe::Create(0.0, color_a, scoped_ptr<TimingFunction>()));
+ curve->AddKeyframe(
+ ColorKeyframe::Create(1.0, color_b, scoped_ptr<TimingFunction>()));
+
+ EXPECT_SKCOLOR_EQ(color_a, curve->GetValue(-1.f));
+ EXPECT_SKCOLOR_EQ(color_a, curve->GetValue(0.f));
+ EXPECT_SKCOLOR_EQ(color_midpoint, curve->GetValue(0.5f));
+ EXPECT_SKCOLOR_EQ(color_b, curve->GetValue(1.f));
+ EXPECT_SKCOLOR_EQ(color_b, curve->GetValue(2.f));
+}
+
+// Tests that a color animation with three keyframes works as expected.
+TEST(KeyframedAnimationCurveTest, ThreeColorKeyFrame) {
+ SkColor color_a = SkColorSetARGB(255, 255, 0, 0);
+ SkColor color_b = SkColorSetARGB(255, 0, 255, 0);
+ SkColor color_c = SkColorSetARGB(255, 0, 0, 255);
+ SkColor color_midpoint1 =
+ gfx::Tween::ColorValueBetween(0.5, color_a, color_b);
+ SkColor color_midpoint2 =
+ gfx::Tween::ColorValueBetween(0.5, color_b, color_c);
+ scoped_ptr<KeyframedColorAnimationCurve> curve(
+ KeyframedColorAnimationCurve::Create());
+ curve->AddKeyframe(
+ ColorKeyframe::Create(0.0, color_a, scoped_ptr<TimingFunction>()));
+ curve->AddKeyframe(
+ ColorKeyframe::Create(1.0, color_b, scoped_ptr<TimingFunction>()));
+ curve->AddKeyframe(
+ ColorKeyframe::Create(2.0, color_c, scoped_ptr<TimingFunction>()));
+
+ EXPECT_SKCOLOR_EQ(color_a, curve->GetValue(-1.f));
+ EXPECT_SKCOLOR_EQ(color_a, curve->GetValue(0.f));
+ EXPECT_SKCOLOR_EQ(color_midpoint1, curve->GetValue(0.5f));
+ EXPECT_SKCOLOR_EQ(color_b, curve->GetValue(1.f));
+ EXPECT_SKCOLOR_EQ(color_midpoint2, curve->GetValue(1.5f));
+ EXPECT_SKCOLOR_EQ(color_c, curve->GetValue(2.f));
+ EXPECT_SKCOLOR_EQ(color_c, curve->GetValue(3.f));
+}
+
+// Tests that a colro animation with multiple keys at a given time works sanely.
+TEST(KeyframedAnimationCurveTest, RepeatedColorKeyFrame) {
+ SkColor color_a = SkColorSetARGB(255, 64, 0, 0);
+ SkColor color_b = SkColorSetARGB(255, 192, 0, 0);
+
+ scoped_ptr<KeyframedColorAnimationCurve> curve(
+ KeyframedColorAnimationCurve::Create());
+ curve->AddKeyframe(
+ ColorKeyframe::Create(0.0, color_a, scoped_ptr<TimingFunction>()));
+ curve->AddKeyframe(
+ ColorKeyframe::Create(1.0, color_a, scoped_ptr<TimingFunction>()));
+ curve->AddKeyframe(
+ ColorKeyframe::Create(1.0, color_b, scoped_ptr<TimingFunction>()));
+ curve->AddKeyframe(
+ ColorKeyframe::Create(2.0, color_b, scoped_ptr<TimingFunction>()));
+
+ EXPECT_SKCOLOR_EQ(color_a, curve->GetValue(-1.f));
+ EXPECT_SKCOLOR_EQ(color_a, curve->GetValue(0.f));
+ EXPECT_SKCOLOR_EQ(color_a, curve->GetValue(0.5f));
+
+ SkColor value = curve->GetValue(1.0f);
+ EXPECT_EQ(255u, SkColorGetA(value));
+ int red_value = SkColorGetR(value);
+ EXPECT_LE(64, red_value);
+ EXPECT_GE(192, red_value);
+
+ EXPECT_SKCOLOR_EQ(color_b, curve->GetValue(1.5f));
+ EXPECT_SKCOLOR_EQ(color_b, curve->GetValue(2.f));
+ EXPECT_SKCOLOR_EQ(color_b, curve->GetValue(3.f));
+}
+
// Tests that a float animation with one keyframe works as expected.
TEST(KeyframedAnimationCurveTest, OneFloatKeyframe) {
scoped_ptr<KeyframedFloatAnimationCurve> curve(
diff --git a/cc/animation/layer_animation_controller.cc b/cc/animation/layer_animation_controller.cc
index 995a393109..f720229152 100644
--- a/cc/animation/layer_animation_controller.cc
+++ b/cc/animation/layer_animation_controller.cc
@@ -92,7 +92,7 @@ void LayerAnimationController::RemoveAnimation(
UpdateActivation(NormalActivation);
}
-// According to render layer backing, these are for testing only.
+// For testing only.
void LayerAnimationController::SuspendAnimations(double monotonic_time) {
for (size_t i = 0; i < active_animations_.size(); ++i) {
if (!active_animations_[i]->is_finished())
@@ -100,15 +100,6 @@ void LayerAnimationController::SuspendAnimations(double monotonic_time) {
}
}
-// Looking at GraphicsLayerCA, this appears to be the analog to
-// SuspendAnimations, which is for testing.
-void LayerAnimationController::ResumeAnimations(double monotonic_time) {
- for (size_t i = 0; i < active_animations_.size(); ++i) {
- if (active_animations_[i]->run_state() == Animation::Paused)
- active_animations_[i]->SetRunState(Animation::Running, monotonic_time);
- }
-}
-
// Ensures that the list of active animations on the main thread and the impl
// thread are kept in sync.
void LayerAnimationController::PushAnimationUpdatesTo(
@@ -196,6 +187,8 @@ void LayerAnimationController::AccumulatePropertyUpdates(
break;
}
+ case Animation::BackgroundColor: { break; }
+
case Animation::TargetPropertyEnumSize:
NOTREACHED();
}
@@ -719,6 +712,11 @@ void LayerAnimationController::TickAnimations(double monotonic_time) {
break;
}
+ case Animation::BackgroundColor: {
+ // Not yet implemented.
+ break;
+ }
+
// Do nothing for sentinel value.
case Animation::TargetPropertyEnumSize:
NOTREACHED();
diff --git a/cc/animation/layer_animation_controller.h b/cc/animation/layer_animation_controller.h
index e397794016..4861e2515b 100644
--- a/cc/animation/layer_animation_controller.h
+++ b/cc/animation/layer_animation_controller.h
@@ -45,7 +45,6 @@ class CC_EXPORT LayerAnimationController
virtual void RemoveAnimation(int animation_id,
Animation::TargetProperty target_property);
virtual void SuspendAnimations(double monotonic_time);
- virtual void ResumeAnimations(double monotonic_time);
// Ensures that the list of active animations on the main thread and the impl
// thread are kept in sync. This function does not take ownership of the impl
diff --git a/cc/animation/layer_animation_controller_unittest.cc b/cc/animation/layer_animation_controller_unittest.cc
index 0a88bfd3a5..32252f1da7 100644
--- a/cc/animation/layer_animation_controller_unittest.cc
+++ b/cc/animation/layer_animation_controller_unittest.cc
@@ -138,18 +138,6 @@ TEST(LayerAnimationControllerTest, SyncPauseAndResume) {
EXPECT_EQ(Animation::Paused,
controller_impl->GetAnimation(group_id,
Animation::Opacity)->run_state());
-
- // Resume the main-thread animation.
- controller->ResumeAnimations(2.0);
- EXPECT_EQ(Animation::Running,
- controller->GetAnimation(group_id,
- Animation::Opacity)->run_state());
-
- // The pause run state change should make it to the impl thread controller.
- controller->PushAnimationUpdatesTo(controller_impl.get());
- EXPECT_EQ(Animation::Running,
- controller_impl->GetAnimation(group_id,
- Animation::Opacity)->run_state());
}
TEST(LayerAnimationControllerTest, DoNotSyncFinishedAnimation) {
diff --git a/cc/animation/scrollbar_animation_controller_thinning.cc b/cc/animation/scrollbar_animation_controller_thinning.cc
index ce196fbf95..3de75989d0 100644
--- a/cc/animation/scrollbar_animation_controller_thinning.cc
+++ b/cc/animation/scrollbar_animation_controller_thinning.cc
@@ -10,14 +10,22 @@
#include "cc/layers/layer_impl.h"
#include "cc/layers/scrollbar_layer_impl_base.h"
+namespace {
+const float kIdleThicknessScale = 0.4f;
+const float kIdleOpacity = 0.7f;
+const float kDefaultMouseMoveDistanceToTriggerAnimation = 25.f;
+const int kDefaultAnimationDelay = 500;
+const int kDefaultAnimationDuration = 300;
+}
+
namespace cc {
scoped_ptr<ScrollbarAnimationControllerThinning>
ScrollbarAnimationControllerThinning::Create(LayerImpl* scroll_layer) {
return make_scoped_ptr(new ScrollbarAnimationControllerThinning(
scroll_layer,
- base::TimeDelta::FromMilliseconds(500),
- base::TimeDelta::FromMilliseconds(300)));
+ base::TimeDelta::FromMilliseconds(kDefaultAnimationDelay),
+ base::TimeDelta::FromMilliseconds(kDefaultAnimationDuration)));
}
scoped_ptr<ScrollbarAnimationControllerThinning>
@@ -33,11 +41,17 @@ ScrollbarAnimationControllerThinning::ScrollbarAnimationControllerThinning(
base::TimeDelta animation_duration)
: ScrollbarAnimationController(),
scroll_layer_(scroll_layer),
- scroll_gesture_in_progress_(false),
mouse_is_over_scrollbar_(false),
+ mouse_is_near_scrollbar_(false),
+ thickness_change_(NONE),
+ opacity_change_(NONE),
+ should_delay_animation_(false),
animation_delay_(animation_delay),
animation_duration_(animation_duration),
- mouse_move_distance_to_trigger_animation_(100.f) {}
+ mouse_move_distance_to_trigger_animation_(
+ kDefaultMouseMoveDistanceToTriggerAnimation) {
+ ApplyOpacityAndThumbThicknessScale(kIdleOpacity, kIdleThicknessScale);
+}
ScrollbarAnimationControllerThinning::~ScrollbarAnimationControllerThinning() {
}
@@ -48,92 +62,120 @@ bool ScrollbarAnimationControllerThinning::IsAnimating() const {
base::TimeDelta ScrollbarAnimationControllerThinning::DelayBeforeStart(
base::TimeTicks now) const {
+ if (!should_delay_animation_)
+ return base::TimeDelta();
if (now > last_awaken_time_ + animation_delay_)
return base::TimeDelta();
return animation_delay_ - (now - last_awaken_time_);
}
bool ScrollbarAnimationControllerThinning::Animate(base::TimeTicks now) {
- if (mouse_is_over_scrollbar_) {
- ApplyOpacityAndThumbThicknessScale(1, 1);
- return false;
- }
float progress = AnimationProgressAtTime(now);
float opacity = OpacityAtAnimationProgress(progress);
float thumb_thickness_scale = ThumbThicknessScaleAtAnimationProgress(
progress);
ApplyOpacityAndThumbThicknessScale(opacity, thumb_thickness_scale);
- if (progress == 1.f)
+ if (progress == 1.f) {
+ opacity_change_ = NONE;
+ thickness_change_ = NONE;
last_awaken_time_ = base::TimeTicks();
+ }
return IsAnimating() && DelayBeforeStart(now) == base::TimeDelta();
}
void ScrollbarAnimationControllerThinning::DidScrollGestureBegin() {
- ApplyOpacityAndThumbThicknessScale(1, 1);
- last_awaken_time_ = base::TimeTicks();
- scroll_gesture_in_progress_ = true;
}
void ScrollbarAnimationControllerThinning::DidScrollGestureEnd(
base::TimeTicks now) {
- last_awaken_time_ = now;
- scroll_gesture_in_progress_ = false;
}
void ScrollbarAnimationControllerThinning::DidMouseMoveOffScrollbar(
base::TimeTicks now) {
mouse_is_over_scrollbar_ = false;
- DidScrollUpdate(now);
+ mouse_is_near_scrollbar_ = false;
+ last_awaken_time_ = now;
+ should_delay_animation_ = false;
+ opacity_change_ = DECREASE;
+ thickness_change_ = DECREASE;
}
bool ScrollbarAnimationControllerThinning::DidScrollUpdate(
base::TimeTicks now) {
- ApplyOpacityAndThumbThicknessScale(1, 1);
+ ApplyOpacityAndThumbThicknessScale(
+ 1, mouse_is_near_scrollbar_ ? 1.f : kIdleThicknessScale);
last_awaken_time_ = now;
+ should_delay_animation_ = true;
+ if (!mouse_is_over_scrollbar_)
+ opacity_change_ = DECREASE;
return true;
}
bool ScrollbarAnimationControllerThinning::DidMouseMoveNear(
base::TimeTicks now, float distance) {
- if (distance == 0.0) {
- mouse_is_over_scrollbar_ = true;
+ bool mouse_is_over_scrollbar = distance == 0.0;
+ bool mouse_is_near_scrollbar =
+ distance < mouse_move_distance_to_trigger_animation_;
+
+ if (mouse_is_over_scrollbar == mouse_is_over_scrollbar_ &&
+ mouse_is_near_scrollbar == mouse_is_near_scrollbar_)
return false;
+
+ if (mouse_is_over_scrollbar_ != mouse_is_over_scrollbar) {
+ mouse_is_over_scrollbar_ = mouse_is_over_scrollbar;
+ opacity_change_ = mouse_is_over_scrollbar_ ? INCREASE : DECREASE;
}
- if (distance < mouse_move_distance_to_trigger_animation_)
- return DidScrollUpdate(now);
+ if (mouse_is_near_scrollbar_ != mouse_is_near_scrollbar) {
+ mouse_is_near_scrollbar_ = mouse_is_near_scrollbar;
+ thickness_change_ = mouse_is_near_scrollbar_ ? INCREASE : DECREASE;
+ }
- return false;
+ last_awaken_time_ = now;
+ should_delay_animation_ = false;
+ return true;
}
float ScrollbarAnimationControllerThinning::AnimationProgressAtTime(
base::TimeTicks now) {
- if (scroll_gesture_in_progress_)
- return 0;
-
if (last_awaken_time_.is_null())
return 1;
base::TimeDelta delta = now - last_awaken_time_;
- float progress = (delta - animation_delay_).InSecondsF() /
- animation_duration_.InSecondsF();
+ if (should_delay_animation_)
+ delta -= animation_delay_;
+ float progress = delta.InSecondsF() / animation_duration_.InSecondsF();
return std::max(std::min(progress, 1.f), 0.f);
}
float ScrollbarAnimationControllerThinning::OpacityAtAnimationProgress(
float progress) {
- const float kIdleOpacity = 0.7f;
-
- return ((1.f - kIdleOpacity) * (1.f - progress)) + kIdleOpacity;
+ if (opacity_change_ == NONE)
+ return mouse_is_over_scrollbar_ ? 1.f : kIdleOpacity;
+ float factor = opacity_change_ == INCREASE ? progress : (1.f - progress);
+ float ret = ((1.f - kIdleOpacity) * factor) + kIdleOpacity;
+ return ret;
}
float
ScrollbarAnimationControllerThinning::ThumbThicknessScaleAtAnimationProgress(
float progress) {
- const float kIdleThicknessScale = 0.4f;
+ if (thickness_change_ == NONE)
+ return mouse_is_near_scrollbar_ ? 1.f : kIdleThicknessScale;
+ float factor = thickness_change_ == INCREASE ? progress : (1.f - progress);
+ return ((1.f - kIdleThicknessScale) * factor) + kIdleThicknessScale;
+}
- return ((1.f - kIdleThicknessScale) * (1.f - progress)) + kIdleThicknessScale;
+float ScrollbarAnimationControllerThinning::AdjustScale(
+ float new_value,
+ float current_value,
+ AnimationChange animation_change) {
+ if (animation_change == INCREASE && current_value > new_value)
+ return current_value;
+ if (animation_change == DECREASE && current_value < new_value)
+ return current_value;
+ return new_value;
}
void ScrollbarAnimationControllerThinning::ApplyOpacityAndThumbThicknessScale(
@@ -141,16 +183,25 @@ void ScrollbarAnimationControllerThinning::ApplyOpacityAndThumbThicknessScale(
ScrollbarLayerImplBase* horizontal_scrollbar =
scroll_layer_->horizontal_scrollbar_layer();
if (horizontal_scrollbar) {
- horizontal_scrollbar->SetOpacity(opacity);
- horizontal_scrollbar->set_thumb_thickness_scale_factor(
- thumb_thickness_scale);
+ horizontal_scrollbar->SetOpacity(
+ AdjustScale(opacity, horizontal_scrollbar->opacity(), opacity_change_));
+ horizontal_scrollbar->SetThumbThicknessScaleFactor(
+ AdjustScale(
+ thumb_thickness_scale,
+ horizontal_scrollbar->thumb_thickness_scale_factor(),
+ thickness_change_));
}
ScrollbarLayerImplBase* vertical_scrollbar =
scroll_layer_->vertical_scrollbar_layer();
if (vertical_scrollbar) {
- vertical_scrollbar->SetOpacity(opacity);
- vertical_scrollbar->set_thumb_thickness_scale_factor(thumb_thickness_scale);
+ vertical_scrollbar->SetOpacity(
+ AdjustScale(opacity, vertical_scrollbar->opacity(), opacity_change_));
+ vertical_scrollbar->SetThumbThicknessScaleFactor(
+ AdjustScale(
+ thumb_thickness_scale,
+ vertical_scrollbar->thumb_thickness_scale_factor(),
+ thickness_change_));
}
}
diff --git a/cc/animation/scrollbar_animation_controller_thinning.h b/cc/animation/scrollbar_animation_controller_thinning.h
index 8038745369..07b4515ec3 100644
--- a/cc/animation/scrollbar_animation_controller_thinning.h
+++ b/cc/animation/scrollbar_animation_controller_thinning.h
@@ -29,6 +29,8 @@ class CC_EXPORT ScrollbarAnimationControllerThinning
void set_mouse_move_distance_for_test(float distance) {
mouse_move_distance_to_trigger_animation_ = distance;
}
+ bool mouse_is_over_scrollbar() const { return mouse_is_over_scrollbar_; }
+ bool mouse_is_near_scrollbar() const { return mouse_is_near_scrollbar_; }
// ScrollbarAnimationController overrides.
virtual bool IsAnimating() const OVERRIDE;
@@ -47,22 +49,40 @@ class CC_EXPORT ScrollbarAnimationControllerThinning
base::TimeDelta animation_duration);
private:
+ // Describes whether the current animation should INCREASE (darken / thicken)
+ // a bar or DECREASE it (lighten / thin).
+ enum AnimationChange {
+ NONE,
+ INCREASE,
+ DECREASE
+ };
// Returns how far through the animation we are as a progress value from
// 0 to 1.
float AnimationProgressAtTime(base::TimeTicks now);
float OpacityAtAnimationProgress(float progress);
float ThumbThicknessScaleAtAnimationProgress(float progress);
+ float AdjustScale(float new_value,
+ float current_value,
+ AnimationChange animation_change);
void ApplyOpacityAndThumbThicknessScale(float opacity,
float thumb_thickness_scale);
LayerImpl* scroll_layer_;
base::TimeTicks last_awaken_time_;
- bool scroll_gesture_in_progress_;
bool mouse_is_over_scrollbar_;
-
+ bool mouse_is_near_scrollbar_;
+ // Are we narrowing or thickening the bars.
+ AnimationChange thickness_change_;
+ // Are we darkening or lightening the bars.
+ AnimationChange opacity_change_;
+ // Should the animation be delayed or start immediately.
+ bool should_delay_animation_;
+ // If |should_delay_animation_| is true, delay the animation by this amount.
base::TimeDelta animation_delay_;
+ // The time for the animation to run.
base::TimeDelta animation_duration_;
+ // How close should the mouse be to the scrollbar before we thicken it.
float mouse_move_distance_to_trigger_animation_;
DISALLOW_COPY_AND_ASSIGN(ScrollbarAnimationControllerThinning);
diff --git a/cc/animation/scrollbar_animation_controller_thinning_unittest.cc b/cc/animation/scrollbar_animation_controller_thinning_unittest.cc
index 7bb507614e..c915632f2f 100644
--- a/cc/animation/scrollbar_animation_controller_thinning_unittest.cc
+++ b/cc/animation/scrollbar_animation_controller_thinning_unittest.cc
@@ -43,128 +43,194 @@ class ScrollbarAnimationControllerThinningTest : public testing::Test {
scoped_ptr<SolidColorScrollbarLayerImpl> scrollbar_layer_;
};
+// Check initialization of scrollbar.
TEST_F(ScrollbarAnimationControllerThinningTest, Idle) {
scrollbar_controller_->Animate(base::TimeTicks());
EXPECT_FLOAT_EQ(0.7f, scrollbar_layer_->opacity());
EXPECT_FLOAT_EQ(0.4f, scrollbar_layer_->thumb_thickness_scale_factor());
}
-TEST_F(ScrollbarAnimationControllerThinningTest, AwakenByScrollGesture) {
+// Scroll content. Confirm the scrollbar gets dark and then becomes light
+// after stopping.
+TEST_F(ScrollbarAnimationControllerThinningTest, AwakenByProgrammaticScroll) {
base::TimeTicks time;
time += base::TimeDelta::FromSeconds(1);
- scrollbar_controller_->DidScrollGestureBegin();
- EXPECT_FALSE(scrollbar_controller_->IsAnimating());
+ EXPECT_TRUE(scrollbar_controller_->DidScrollUpdate(time));
+ EXPECT_TRUE(scrollbar_controller_->IsAnimating());
+ EXPECT_EQ(2, scrollbar_controller_->DelayBeforeStart(time).InSeconds());
EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity());
- EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor());
+ // Scrollbar doesn't change size if triggered by scroll.
+ EXPECT_FLOAT_EQ(0.4f, scrollbar_layer_->thumb_thickness_scale_factor());
- time += base::TimeDelta::FromSeconds(100);
+ time += base::TimeDelta::FromSeconds(1);
+ EXPECT_EQ(1, scrollbar_controller_->DelayBeforeStart(time).InSeconds());
scrollbar_controller_->Animate(time);
EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity());
- EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor());
- scrollbar_controller_->DidScrollGestureEnd(time);
+ EXPECT_FLOAT_EQ(0.4f, scrollbar_layer_->thumb_thickness_scale_factor());
- EXPECT_TRUE(scrollbar_controller_->IsAnimating());
+ // Subsequent scroll restarts animation.
+ EXPECT_TRUE(scrollbar_controller_->DidScrollUpdate(time));
EXPECT_EQ(2, scrollbar_controller_->DelayBeforeStart(time).InSeconds());
time += base::TimeDelta::FromSeconds(1);
+ EXPECT_EQ(1, scrollbar_controller_->DelayBeforeStart(time).InSeconds());
scrollbar_controller_->Animate(time);
EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity());
- EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor());
+ EXPECT_FLOAT_EQ(0.4f, scrollbar_layer_->thumb_thickness_scale_factor());
time += base::TimeDelta::FromSeconds(1);
+ EXPECT_EQ(0, scrollbar_controller_->DelayBeforeStart(time).InSeconds());
scrollbar_controller_->Animate(time);
EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity());
- EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor());
+ EXPECT_FLOAT_EQ(0.4f, scrollbar_layer_->thumb_thickness_scale_factor());
time += base::TimeDelta::FromSeconds(1);
scrollbar_controller_->Animate(time);
EXPECT_FLOAT_EQ(0.9f, scrollbar_layer_->opacity());
- EXPECT_FLOAT_EQ(0.8f, scrollbar_layer_->thumb_thickness_scale_factor());
+ EXPECT_FLOAT_EQ(0.4f, scrollbar_layer_->thumb_thickness_scale_factor());
time += base::TimeDelta::FromSeconds(1);
scrollbar_controller_->Animate(time);
EXPECT_FLOAT_EQ(0.8f, scrollbar_layer_->opacity());
- EXPECT_FLOAT_EQ(0.6f, scrollbar_layer_->thumb_thickness_scale_factor());
+ EXPECT_FLOAT_EQ(0.4f, scrollbar_layer_->thumb_thickness_scale_factor());
time += base::TimeDelta::FromSeconds(1);
+ scrollbar_controller_->Animate(time);
+ EXPECT_FLOAT_EQ(0.7f, scrollbar_layer_->opacity());
+ EXPECT_FLOAT_EQ(0.4f, scrollbar_layer_->thumb_thickness_scale_factor());
- scrollbar_controller_->DidScrollGestureBegin();
- scrollbar_controller_->DidScrollGestureEnd(time);
+ EXPECT_FALSE(scrollbar_controller_->IsAnimating());
+}
+// Initiate a scroll when the pointer is already near the scrollbar. It should
+// remain thick.
+TEST_F(ScrollbarAnimationControllerThinningTest, ScrollWithMouseNear) {
+ base::TimeTicks time;
time += base::TimeDelta::FromSeconds(1);
+
+ scrollbar_controller_->DidMouseMoveNear(time, 1);
+ time += base::TimeDelta::FromSeconds(3);
scrollbar_controller_->Animate(time);
+ EXPECT_FALSE(scrollbar_controller_->IsAnimating());
+ EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor());
+
+ EXPECT_TRUE(scrollbar_controller_->DidScrollUpdate(time));
+ EXPECT_TRUE(scrollbar_controller_->IsAnimating());
+ EXPECT_EQ(2, scrollbar_controller_->DelayBeforeStart(time).InSeconds());
EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity());
+ // Scrollbar should still be thick.
EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor());
- time += base::TimeDelta::FromSeconds(1);
+ time += base::TimeDelta::FromSeconds(5);
scrollbar_controller_->Animate(time);
- EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity());
+ EXPECT_FALSE(scrollbar_controller_->IsAnimating());
+ EXPECT_FLOAT_EQ(0.7f, scrollbar_layer_->opacity());
EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor());
+}
+// Move the pointer near the scrollbar. Confirm it gets thick and narrow when
+// moved away.
+TEST_F(ScrollbarAnimationControllerThinningTest, MouseNear) {
+ base::TimeTicks time;
time += base::TimeDelta::FromSeconds(1);
- scrollbar_controller_->Animate(time);
- EXPECT_FLOAT_EQ(0.9f, scrollbar_layer_->opacity());
- EXPECT_FLOAT_EQ(0.8f, scrollbar_layer_->thumb_thickness_scale_factor());
+ scrollbar_controller_->DidMouseMoveNear(time, 1);
+ EXPECT_TRUE(scrollbar_controller_->IsAnimating());
+ EXPECT_EQ(0, scrollbar_controller_->DelayBeforeStart(time).InSeconds());
+ EXPECT_FLOAT_EQ(0.7f, scrollbar_layer_->opacity());
+ EXPECT_FLOAT_EQ(0.4f, scrollbar_layer_->thumb_thickness_scale_factor());
+ // Should animate to thickened but not darken.
time += base::TimeDelta::FromSeconds(1);
scrollbar_controller_->Animate(time);
- EXPECT_FLOAT_EQ(0.8f, scrollbar_layer_->opacity());
+ EXPECT_FLOAT_EQ(0.7f, scrollbar_layer_->opacity());
EXPECT_FLOAT_EQ(0.6f, scrollbar_layer_->thumb_thickness_scale_factor());
time += base::TimeDelta::FromSeconds(1);
scrollbar_controller_->Animate(time);
EXPECT_FLOAT_EQ(0.7f, scrollbar_layer_->opacity());
- EXPECT_FLOAT_EQ(0.4f, scrollbar_layer_->thumb_thickness_scale_factor());
-}
+ EXPECT_FLOAT_EQ(0.8f, scrollbar_layer_->thumb_thickness_scale_factor());
-TEST_F(ScrollbarAnimationControllerThinningTest, AwakenByProgrammaticScroll) {
- base::TimeTicks time;
time += base::TimeDelta::FromSeconds(1);
- EXPECT_TRUE(scrollbar_controller_->DidScrollUpdate(time));
- EXPECT_TRUE(scrollbar_controller_->IsAnimating());
- EXPECT_EQ(2, scrollbar_controller_->DelayBeforeStart(time).InSeconds());
scrollbar_controller_->Animate(time);
- EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity());
+ EXPECT_FLOAT_EQ(0.7f, scrollbar_layer_->opacity());
EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor());
+ EXPECT_FALSE(scrollbar_controller_->IsAnimating());
+ // Subsequent moves should not change anything.
+ scrollbar_controller_->DidMouseMoveNear(time, 1);
+ EXPECT_FLOAT_EQ(0.7f, scrollbar_layer_->opacity());
+ EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor());
+ EXPECT_FALSE(scrollbar_controller_->IsAnimating());
+
+ // Now move away from bar.
time += base::TimeDelta::FromSeconds(1);
- scrollbar_controller_->Animate(time);
- EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity());
+ scrollbar_controller_->DidMouseMoveNear(time, 26);
+ EXPECT_TRUE(scrollbar_controller_->IsAnimating());
+ EXPECT_EQ(0, scrollbar_controller_->DelayBeforeStart(time).InSeconds());
+ EXPECT_FLOAT_EQ(0.7f, scrollbar_layer_->opacity());
EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor());
- EXPECT_TRUE(scrollbar_controller_->DidScrollUpdate(time));
+ // Animate to narrow.
time += base::TimeDelta::FromSeconds(1);
scrollbar_controller_->Animate(time);
- EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity());
- EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor());
+ EXPECT_FLOAT_EQ(0.7f, scrollbar_layer_->opacity());
+ EXPECT_FLOAT_EQ(0.8f, scrollbar_layer_->thumb_thickness_scale_factor());
time += base::TimeDelta::FromSeconds(1);
scrollbar_controller_->Animate(time);
- EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity());
- EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor());
+ EXPECT_FLOAT_EQ(0.7f, scrollbar_layer_->opacity());
+ EXPECT_FLOAT_EQ(0.6f, scrollbar_layer_->thumb_thickness_scale_factor());
time += base::TimeDelta::FromSeconds(1);
scrollbar_controller_->Animate(time);
- EXPECT_FLOAT_EQ(0.9f, scrollbar_layer_->opacity());
- EXPECT_FLOAT_EQ(0.8f, scrollbar_layer_->thumb_thickness_scale_factor());
+ EXPECT_FLOAT_EQ(0.7f, scrollbar_layer_->opacity());
+ EXPECT_FLOAT_EQ(0.4f, scrollbar_layer_->thumb_thickness_scale_factor());
+ EXPECT_FALSE(scrollbar_controller_->IsAnimating());
+}
+// Move the pointer over the scrollbar. Make sure it gets thick and dark
+// and that it gets thin and light when moved away.
+TEST_F(ScrollbarAnimationControllerThinningTest, MouseOver) {
+ base::TimeTicks time;
+ time += base::TimeDelta::FromSeconds(1);
+ scrollbar_controller_->DidMouseMoveNear(time, 0);
+ EXPECT_TRUE(scrollbar_controller_->IsAnimating());
+ EXPECT_EQ(0, scrollbar_controller_->DelayBeforeStart(time).InSeconds());
+ EXPECT_FLOAT_EQ(0.7f, scrollbar_layer_->opacity());
+ EXPECT_FLOAT_EQ(0.4f, scrollbar_layer_->thumb_thickness_scale_factor());
+
+ // Should animate to thickened and darkened.
time += base::TimeDelta::FromSeconds(1);
scrollbar_controller_->Animate(time);
EXPECT_FLOAT_EQ(0.8f, scrollbar_layer_->opacity());
EXPECT_FLOAT_EQ(0.6f, scrollbar_layer_->thumb_thickness_scale_factor());
time += base::TimeDelta::FromSeconds(1);
- EXPECT_TRUE(scrollbar_controller_->DidScrollUpdate(time));
+ scrollbar_controller_->Animate(time);
+ EXPECT_FLOAT_EQ(0.9f, scrollbar_layer_->opacity());
+ EXPECT_FLOAT_EQ(0.8f, scrollbar_layer_->thumb_thickness_scale_factor());
+
time += base::TimeDelta::FromSeconds(1);
scrollbar_controller_->Animate(time);
EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity());
EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor());
+ EXPECT_FALSE(scrollbar_controller_->IsAnimating());
+
+ // Subsequent moves should not change anything.
+ scrollbar_controller_->DidMouseMoveNear(time, 0);
+ EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity());
+ EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor());
+ EXPECT_FALSE(scrollbar_controller_->IsAnimating());
+ // Now move away from bar.
time += base::TimeDelta::FromSeconds(1);
- scrollbar_controller_->Animate(time);
+ scrollbar_controller_->DidMouseMoveNear(time, 26);
+ EXPECT_TRUE(scrollbar_controller_->IsAnimating());
+ EXPECT_EQ(0, scrollbar_controller_->DelayBeforeStart(time).InSeconds());
EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity());
EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor());
+ // Animate to narrow.
time += base::TimeDelta::FromSeconds(1);
scrollbar_controller_->Animate(time);
EXPECT_FLOAT_EQ(0.9f, scrollbar_layer_->opacity());
@@ -179,47 +245,87 @@ TEST_F(ScrollbarAnimationControllerThinningTest, AwakenByProgrammaticScroll) {
scrollbar_controller_->Animate(time);
EXPECT_FLOAT_EQ(0.7f, scrollbar_layer_->opacity());
EXPECT_FLOAT_EQ(0.4f, scrollbar_layer_->thumb_thickness_scale_factor());
+ EXPECT_FALSE(scrollbar_controller_->IsAnimating());
}
-TEST_F(ScrollbarAnimationControllerThinningTest, MouseOverAndOut) {
+// First move the pointer near the scrollbar, then over it, then back near
+// then far away. Confirm that first the bar gets thick, then dark, then light,
+// then narrow.
+TEST_F(ScrollbarAnimationControllerThinningTest, MouseNearThenOver) {
base::TimeTicks time;
time += base::TimeDelta::FromSeconds(1);
- EXPECT_TRUE(scrollbar_controller_->DidScrollUpdate(time));
+ scrollbar_controller_->DidMouseMoveNear(time, 1);
EXPECT_TRUE(scrollbar_controller_->IsAnimating());
- EXPECT_EQ(2, scrollbar_controller_->DelayBeforeStart(time).InSeconds());
+ EXPECT_EQ(0, scrollbar_controller_->DelayBeforeStart(time).InSeconds());
+ EXPECT_FLOAT_EQ(0.7f, scrollbar_layer_->opacity());
+ EXPECT_FLOAT_EQ(0.4f, scrollbar_layer_->thumb_thickness_scale_factor());
+
+ // Should animate to thickened but not darken.
+ time += base::TimeDelta::FromSeconds(3);
scrollbar_controller_->Animate(time);
- EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity());
+ EXPECT_FLOAT_EQ(0.7f, scrollbar_layer_->opacity());
EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor());
+ EXPECT_FALSE(scrollbar_controller_->IsAnimating());
- time += base::TimeDelta::FromSeconds(4);
+ // Now move over.
+ scrollbar_controller_->DidMouseMoveNear(time, 0);
+ EXPECT_TRUE(scrollbar_controller_->IsAnimating());
+ EXPECT_EQ(0, scrollbar_controller_->DelayBeforeStart(time).InSeconds());
+
+ // Should animate to darkened.
+ time += base::TimeDelta::FromSeconds(1);
scrollbar_controller_->Animate(time);
EXPECT_FLOAT_EQ(0.8f, scrollbar_layer_->opacity());
- EXPECT_FLOAT_EQ(0.6f, scrollbar_layer_->thumb_thickness_scale_factor());
+ EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor());
- scrollbar_controller_->DidMouseMoveNear(time, 0);
+ time += base::TimeDelta::FromSeconds(1);
scrollbar_controller_->Animate(time);
- EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity());
+ EXPECT_FLOAT_EQ(0.9f, scrollbar_layer_->opacity());
EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor());
- time += base::TimeDelta::FromSeconds(4);
+ time += base::TimeDelta::FromSeconds(1);
scrollbar_controller_->Animate(time);
EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity());
EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor());
+ EXPECT_FALSE(scrollbar_controller_->IsAnimating());
+ // This is tricky. The DidMouseMoveOffScrollbar() is sent before the
+ // subsequent DidMouseMoveNear(), if the mouse moves in that direction.
+ // This results in the thumb thinning. We want to make sure that when the
+ // thumb starts expanding it doesn't first narrow to the idle thinness.
+ time += base::TimeDelta::FromSeconds(1);
scrollbar_controller_->DidMouseMoveOffScrollbar(time);
+ EXPECT_TRUE(scrollbar_controller_->IsAnimating());
+
+ time += base::TimeDelta::FromSeconds(1);
scrollbar_controller_->Animate(time);
- EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity());
- EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor());
+ EXPECT_FLOAT_EQ(0.9f, scrollbar_layer_->opacity());
+ EXPECT_FLOAT_EQ(0.8f, scrollbar_layer_->thumb_thickness_scale_factor());
- time += base::TimeDelta::FromSeconds(4);
+ scrollbar_controller_->DidMouseMoveNear(time, 1);
+ // A new animation is kicked off.
+ EXPECT_TRUE(scrollbar_controller_->IsAnimating());
+
+ time += base::TimeDelta::FromSeconds(1);
+ scrollbar_controller_->Animate(time);
+ // We will initiate the narrowing again, but it won't get decremented until
+ // the new animation catches up to it.
+ EXPECT_FLOAT_EQ(0.9f, scrollbar_layer_->opacity());
+ // Now the thickness should be increasing, but it shouldn't happen until the
+ // animation catches up.
+ EXPECT_FLOAT_EQ(0.8f, scrollbar_layer_->thumb_thickness_scale_factor());
+
+ time += base::TimeDelta::FromSeconds(1);
scrollbar_controller_->Animate(time);
EXPECT_FLOAT_EQ(0.8f, scrollbar_layer_->opacity());
- EXPECT_FLOAT_EQ(0.6f, scrollbar_layer_->thumb_thickness_scale_factor());
+ // The thickness now gets big again.
+ EXPECT_FLOAT_EQ(0.8f, scrollbar_layer_->thumb_thickness_scale_factor());
time += base::TimeDelta::FromSeconds(1);
scrollbar_controller_->Animate(time);
EXPECT_FLOAT_EQ(0.7f, scrollbar_layer_->opacity());
- EXPECT_FLOAT_EQ(0.4f, scrollbar_layer_->thumb_thickness_scale_factor());
+ // The thickness now gets big again.
+ EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor());
}
} // namespace
diff --git a/cc/animation/transform_operation.cc b/cc/animation/transform_operation.cc
index 5ede71b6e6..889f7bd410 100644
--- a/cc/animation/transform_operation.cc
+++ b/cc/animation/transform_operation.cc
@@ -163,11 +163,19 @@ bool TransformOperation::BlendTransformOperations(
SkMScalar from_perspective_depth =
IsOperationIdentity(from) ? std::numeric_limits<SkMScalar>::max()
: from->perspective_depth;
- SkMScalar to_perspective_depth = IsOperationIdentity(to)
- ? std::numeric_limits<SkMScalar>::max()
- : to->perspective_depth;
- result->ApplyPerspectiveDepth(BlendSkMScalars(
- from_perspective_depth, to_perspective_depth, progress));
+ SkMScalar to_perspective_depth =
+ IsOperationIdentity(to) ? std::numeric_limits<SkMScalar>::max()
+ : to->perspective_depth;
+ if (from_perspective_depth == 0.f || to_perspective_depth == 0.f)
+ return false;
+
+ SkMScalar blended_perspective_depth = BlendSkMScalars(
+ 1.f / from_perspective_depth, 1.f / to_perspective_depth, progress);
+
+ if (blended_perspective_depth == 0.f)
+ return false;
+
+ result->ApplyPerspectiveDepth(1.f / blended_perspective_depth);
break;
}
case TransformOperation::TransformOperationMatrix: {
diff --git a/cc/animation/transform_operations_unittest.cc b/cc/animation/transform_operations_unittest.cc
index 6bc9e03976..49b208e128 100644
--- a/cc/animation/transform_operations_unittest.cc
+++ b/cc/animation/transform_operations_unittest.cc
@@ -570,8 +570,7 @@ TEST(TransformOperationTest, BlendPerspectiveFromIdentity) {
SkMScalar progress = 0.5f;
gfx::Transform expected;
- expected.ApplyPerspectiveDepth(500 +
- 0.5 * std::numeric_limits<SkMScalar>::max());
+ expected.ApplyPerspectiveDepth(2000);
EXPECT_TRANSFORMATION_MATRIX_EQ(
expected, operations.Blend(*identity_operations[i], progress));
@@ -662,8 +661,7 @@ TEST(TransformOperationTest, BlendPerspectiveToIdentity) {
SkMScalar progress = 0.5f;
gfx::Transform expected;
- expected.ApplyPerspectiveDepth(500 +
- 0.5 * std::numeric_limits<SkMScalar>::max());
+ expected.ApplyPerspectiveDepth(2000);
EXPECT_TRANSFORMATION_MATRIX_EQ(
expected, identity_operations[i]->Blend(operations, progress));
@@ -678,13 +676,13 @@ TEST(TransformOperationTest, ExtrapolatePerspectiveBlending) {
operations2.AppendPerspective(500);
gfx::Transform expected;
- expected.ApplyPerspectiveDepth(250);
+ expected.ApplyPerspectiveDepth(400);
EXPECT_TRANSFORMATION_MATRIX_EQ(
expected, operations1.Blend(operations2, -0.5));
expected.MakeIdentity();
- expected.ApplyPerspectiveDepth(1250);
+ expected.ApplyPerspectiveDepth(2000);
EXPECT_TRANSFORMATION_MATRIX_EQ(
expected, operations1.Blend(operations2, 1.5));
@@ -1072,6 +1070,33 @@ TEST(TransformOperationsTest, BlendedBoundsForRotationEmpiricalTests) {
}
}
+TEST(TransformOperationTest, PerspectiveMatrixAndTransformBlendingEquivalency) {
+ TransformOperations from_operations;
+ from_operations.AppendPerspective(200);
+
+ TransformOperations to_operations;
+ to_operations.AppendPerspective(1000);
+
+ gfx::Transform from_transform;
+ from_transform.ApplyPerspectiveDepth(200);
+
+ gfx::Transform to_transform;
+ to_transform.ApplyPerspectiveDepth(1000);
+
+ static const int steps = 20;
+ for (int i = 0; i < steps; ++i) {
+ double progress = static_cast<double>(i) / (steps - 1);
+
+ gfx::Transform blended_matrix = to_transform;
+ EXPECT_TRUE(blended_matrix.Blend(from_transform, progress));
+
+ gfx::Transform blended_transform =
+ to_operations.Blend(from_operations, progress);
+
+ EXPECT_TRANSFORMATION_MATRIX_EQ(blended_matrix, blended_transform);
+ }
+}
+
TEST(TransformOperationTest, BlendedBoundsForSequence) {
TransformOperations operations_from;
operations_from.AppendTranslate(2.0, 4.0, -1.0);
diff --git a/cc/base/math_util.cc b/cc/base/math_util.cc
index eeb1523db4..76b2bb93cc 100644
--- a/cc/base/math_util.cc
+++ b/cc/base/math_util.cc
@@ -466,6 +466,13 @@ gfx::RectF MathUtil::ScaleRectProportional(const gfx::RectF& input_outer_rect,
}
static inline float ScaleOnAxis(double a, double b, double c) {
+ if (!b && !c)
+ return a;
+ if (!a && !c)
+ return b;
+ if (!a && !b)
+ return c;
+
// Do the sqrt as a double to not lose precision.
return static_cast<float>(std::sqrt(a * a + b * b + c * c));
}
diff --git a/cc/base/switches.cc b/cc/base/switches.cc
index 5dbb2960a2..be4a2c55ad 100644
--- a/cc/base/switches.cc
+++ b/cc/base/switches.cc
@@ -141,6 +141,9 @@ const char kDisableMapImage[] = "disable-map-image";
// Prevents the layer tree unit tests from timing out.
const char kCCLayerTreeTestNoTimeout[] = "cc-layer-tree-test-no-timeout";
+// Makes pixel tests write their output instead of read it.
+const char kCCRebaselinePixeltests[] = "cc-rebaseline-pixeltests";
+
// Disable textures using RGBA_4444 layout.
const char kDisable4444Textures[] = "disable-4444-textures";
@@ -162,7 +165,8 @@ bool IsLCDTextEnabled() {
#endif
}
-bool IsImplSidePaintingEnabled() {
+namespace {
+bool CheckImplSidePaintingStatus() {
const CommandLine& command_line = *CommandLine::ForCurrentProcess();
if (command_line.HasSwitch(cc::switches::kDisableImplSidePainting))
@@ -176,6 +180,12 @@ bool IsImplSidePaintingEnabled() {
return false;
#endif
}
+} // namespace
+
+bool IsImplSidePaintingEnabled() {
+ static bool enabled = CheckImplSidePaintingStatus();
+ return enabled;
+}
bool IsMapImageEnabled() {
const CommandLine& command_line = *CommandLine::ForCurrentProcess();
diff --git a/cc/base/switches.h b/cc/base/switches.h
index ed6555a6e6..e92eb2e31c 100644
--- a/cc/base/switches.h
+++ b/cc/base/switches.h
@@ -69,6 +69,7 @@ CC_EXPORT extern const char kUIShowNonOccludingRects[];
// Unit test related.
CC_EXPORT extern const char kCCLayerTreeTestNoTimeout[];
+CC_EXPORT extern const char kCCRebaselinePixeltests[];
CC_EXPORT bool IsLCDTextEnabled();
CC_EXPORT bool IsImplSidePaintingEnabled();
diff --git a/cc/cc.gyp b/cc/cc.gyp
index df268ee2f5..deb2fbdee3 100644
--- a/cc/cc.gyp
+++ b/cc/cc.gyp
@@ -360,6 +360,9 @@
'resources/scoped_resource.h',
'resources/scoped_ui_resource.cc',
'resources/scoped_ui_resource.h',
+ 'resources/shared_bitmap.cc',
+ 'resources/shared_bitmap.h',
+ 'resources/shared_bitmap_manager.h',
'resources/single_release_callback.cc',
'resources/single_release_callback.h',
'resources/skpicture_content_layer_updater.cc',
diff --git a/cc/cc.target.darwin-arm.mk b/cc/cc.target.darwin-arm.mk
index 9c23ae0168..570ebfd0d5 100644
--- a/cc/cc.target.darwin-arm.mk
+++ b/cc/cc.target.darwin-arm.mk
@@ -180,6 +180,7 @@ LOCAL_SRC_FILES := \
cc/resources/resource_update_queue.cc \
cc/resources/scoped_resource.cc \
cc/resources/scoped_ui_resource.cc \
+ cc/resources/shared_bitmap.cc \
cc/resources/single_release_callback.cc \
cc/resources/skpicture_content_layer_updater.cc \
cc/resources/texture_mailbox.cc \
@@ -253,13 +254,13 @@ MY_DEFS_Debug := \
'-DANGLE_DX11' \
'-D_FILE_OFFSET_BITS=64' \
'-DNO_TCMALLOC' \
- '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
- '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
'-DDISABLE_NACL' \
'-DCHROMIUM_BUILD' \
'-DUSE_LIBJPEG_TURBO=1' \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
'-DUSE_OPENSSL=1' \
'-DENABLE_EGLIMAGE=1' \
'-DCLD_VERSION=1' \
@@ -363,13 +364,13 @@ MY_DEFS_Release := \
'-DANGLE_DX11' \
'-D_FILE_OFFSET_BITS=64' \
'-DNO_TCMALLOC' \
- '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
- '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
'-DDISABLE_NACL' \
'-DCHROMIUM_BUILD' \
'-DUSE_LIBJPEG_TURBO=1' \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
'-DUSE_OPENSSL=1' \
'-DENABLE_EGLIMAGE=1' \
'-DCLD_VERSION=1' \
diff --git a/cc/cc.target.darwin-mips.mk b/cc/cc.target.darwin-mips.mk
index 20fcbe3e92..c0d84f746f 100644
--- a/cc/cc.target.darwin-mips.mk
+++ b/cc/cc.target.darwin-mips.mk
@@ -180,6 +180,7 @@ LOCAL_SRC_FILES := \
cc/resources/resource_update_queue.cc \
cc/resources/scoped_resource.cc \
cc/resources/scoped_ui_resource.cc \
+ cc/resources/shared_bitmap.cc \
cc/resources/single_release_callback.cc \
cc/resources/skpicture_content_layer_updater.cc \
cc/resources/texture_mailbox.cc \
@@ -252,13 +253,13 @@ MY_DEFS_Debug := \
'-DANGLE_DX11' \
'-D_FILE_OFFSET_BITS=64' \
'-DNO_TCMALLOC' \
- '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
- '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
'-DDISABLE_NACL' \
'-DCHROMIUM_BUILD' \
'-DUSE_LIBJPEG_TURBO=1' \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
'-DUSE_OPENSSL=1' \
'-DENABLE_EGLIMAGE=1' \
'-DCLD_VERSION=1' \
@@ -361,13 +362,13 @@ MY_DEFS_Release := \
'-DANGLE_DX11' \
'-D_FILE_OFFSET_BITS=64' \
'-DNO_TCMALLOC' \
- '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
- '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
'-DDISABLE_NACL' \
'-DCHROMIUM_BUILD' \
'-DUSE_LIBJPEG_TURBO=1' \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
'-DUSE_OPENSSL=1' \
'-DENABLE_EGLIMAGE=1' \
'-DCLD_VERSION=1' \
diff --git a/cc/cc.target.darwin-x86.mk b/cc/cc.target.darwin-x86.mk
index d358842a7d..585967d466 100644
--- a/cc/cc.target.darwin-x86.mk
+++ b/cc/cc.target.darwin-x86.mk
@@ -180,6 +180,7 @@ LOCAL_SRC_FILES := \
cc/resources/resource_update_queue.cc \
cc/resources/scoped_resource.cc \
cc/resources/scoped_ui_resource.cc \
+ cc/resources/shared_bitmap.cc \
cc/resources/single_release_callback.cc \
cc/resources/skpicture_content_layer_updater.cc \
cc/resources/texture_mailbox.cc \
@@ -255,13 +256,13 @@ MY_DEFS_Debug := \
'-DANGLE_DX11' \
'-D_FILE_OFFSET_BITS=64' \
'-DNO_TCMALLOC' \
- '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
- '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
'-DDISABLE_NACL' \
'-DCHROMIUM_BUILD' \
'-DUSE_LIBJPEG_TURBO=1' \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
'-DUSE_OPENSSL=1' \
'-DENABLE_EGLIMAGE=1' \
'-DCLD_VERSION=1' \
@@ -368,13 +369,13 @@ MY_DEFS_Release := \
'-DANGLE_DX11' \
'-D_FILE_OFFSET_BITS=64' \
'-DNO_TCMALLOC' \
- '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
- '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
'-DDISABLE_NACL' \
'-DCHROMIUM_BUILD' \
'-DUSE_LIBJPEG_TURBO=1' \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
'-DUSE_OPENSSL=1' \
'-DENABLE_EGLIMAGE=1' \
'-DCLD_VERSION=1' \
diff --git a/cc/cc.target.linux-arm.mk b/cc/cc.target.linux-arm.mk
index 9c23ae0168..570ebfd0d5 100644
--- a/cc/cc.target.linux-arm.mk
+++ b/cc/cc.target.linux-arm.mk
@@ -180,6 +180,7 @@ LOCAL_SRC_FILES := \
cc/resources/resource_update_queue.cc \
cc/resources/scoped_resource.cc \
cc/resources/scoped_ui_resource.cc \
+ cc/resources/shared_bitmap.cc \
cc/resources/single_release_callback.cc \
cc/resources/skpicture_content_layer_updater.cc \
cc/resources/texture_mailbox.cc \
@@ -253,13 +254,13 @@ MY_DEFS_Debug := \
'-DANGLE_DX11' \
'-D_FILE_OFFSET_BITS=64' \
'-DNO_TCMALLOC' \
- '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
- '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
'-DDISABLE_NACL' \
'-DCHROMIUM_BUILD' \
'-DUSE_LIBJPEG_TURBO=1' \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
'-DUSE_OPENSSL=1' \
'-DENABLE_EGLIMAGE=1' \
'-DCLD_VERSION=1' \
@@ -363,13 +364,13 @@ MY_DEFS_Release := \
'-DANGLE_DX11' \
'-D_FILE_OFFSET_BITS=64' \
'-DNO_TCMALLOC' \
- '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
- '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
'-DDISABLE_NACL' \
'-DCHROMIUM_BUILD' \
'-DUSE_LIBJPEG_TURBO=1' \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
'-DUSE_OPENSSL=1' \
'-DENABLE_EGLIMAGE=1' \
'-DCLD_VERSION=1' \
diff --git a/cc/cc.target.linux-mips.mk b/cc/cc.target.linux-mips.mk
index 20fcbe3e92..c0d84f746f 100644
--- a/cc/cc.target.linux-mips.mk
+++ b/cc/cc.target.linux-mips.mk
@@ -180,6 +180,7 @@ LOCAL_SRC_FILES := \
cc/resources/resource_update_queue.cc \
cc/resources/scoped_resource.cc \
cc/resources/scoped_ui_resource.cc \
+ cc/resources/shared_bitmap.cc \
cc/resources/single_release_callback.cc \
cc/resources/skpicture_content_layer_updater.cc \
cc/resources/texture_mailbox.cc \
@@ -252,13 +253,13 @@ MY_DEFS_Debug := \
'-DANGLE_DX11' \
'-D_FILE_OFFSET_BITS=64' \
'-DNO_TCMALLOC' \
- '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
- '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
'-DDISABLE_NACL' \
'-DCHROMIUM_BUILD' \
'-DUSE_LIBJPEG_TURBO=1' \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
'-DUSE_OPENSSL=1' \
'-DENABLE_EGLIMAGE=1' \
'-DCLD_VERSION=1' \
@@ -361,13 +362,13 @@ MY_DEFS_Release := \
'-DANGLE_DX11' \
'-D_FILE_OFFSET_BITS=64' \
'-DNO_TCMALLOC' \
- '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
- '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
'-DDISABLE_NACL' \
'-DCHROMIUM_BUILD' \
'-DUSE_LIBJPEG_TURBO=1' \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
'-DUSE_OPENSSL=1' \
'-DENABLE_EGLIMAGE=1' \
'-DCLD_VERSION=1' \
diff --git a/cc/cc.target.linux-x86.mk b/cc/cc.target.linux-x86.mk
index d358842a7d..585967d466 100644
--- a/cc/cc.target.linux-x86.mk
+++ b/cc/cc.target.linux-x86.mk
@@ -180,6 +180,7 @@ LOCAL_SRC_FILES := \
cc/resources/resource_update_queue.cc \
cc/resources/scoped_resource.cc \
cc/resources/scoped_ui_resource.cc \
+ cc/resources/shared_bitmap.cc \
cc/resources/single_release_callback.cc \
cc/resources/skpicture_content_layer_updater.cc \
cc/resources/texture_mailbox.cc \
@@ -255,13 +256,13 @@ MY_DEFS_Debug := \
'-DANGLE_DX11' \
'-D_FILE_OFFSET_BITS=64' \
'-DNO_TCMALLOC' \
- '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
- '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
'-DDISABLE_NACL' \
'-DCHROMIUM_BUILD' \
'-DUSE_LIBJPEG_TURBO=1' \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
'-DUSE_OPENSSL=1' \
'-DENABLE_EGLIMAGE=1' \
'-DCLD_VERSION=1' \
@@ -368,13 +369,13 @@ MY_DEFS_Release := \
'-DANGLE_DX11' \
'-D_FILE_OFFSET_BITS=64' \
'-DNO_TCMALLOC' \
- '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
- '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
'-DDISABLE_NACL' \
'-DCHROMIUM_BUILD' \
'-DUSE_LIBJPEG_TURBO=1' \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
+ '-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
'-DUSE_OPENSSL=1' \
'-DENABLE_EGLIMAGE=1' \
'-DCLD_VERSION=1' \
diff --git a/cc/cc_tests.gyp b/cc/cc_tests.gyp
index d48a4aefd8..49e82fcbae 100644
--- a/cc/cc_tests.gyp
+++ b/cc/cc_tests.gyp
@@ -24,6 +24,7 @@
'layers/content_layer_unittest.cc',
'layers/contents_scaling_layer_unittest.cc',
'layers/delegated_frame_provider_unittest.cc',
+ 'layers/delegated_frame_resource_collection_unittest.cc',
'layers/delegated_renderer_layer_impl_unittest.cc',
'layers/heads_up_display_unittest.cc',
'layers/heads_up_display_layer_impl_unittest.cc',
@@ -35,6 +36,7 @@
'layers/nine_patch_layer_unittest.cc',
'layers/picture_image_layer_impl_unittest.cc',
'layers/picture_layer_impl_unittest.cc',
+ 'layers/picture_layer_unittest.cc',
'layers/render_surface_unittest.cc',
'layers/scrollbar_layer_unittest.cc',
'layers/solid_color_layer_impl_unittest.cc',
@@ -76,6 +78,7 @@
'scheduler/scheduler_unittest.cc',
'scheduler/texture_uploader_unittest.cc',
'test/fake_web_graphics_context_3d_unittest.cc',
+ 'test/layer_tree_json_parser_unittest.cc',
'trees/damage_tracker_unittest.cc',
'trees/layer_sorter_unittest.cc',
'trees/layer_tree_host_common_unittest.cc',
@@ -259,7 +262,8 @@
'resources/worker_pool_perftest.cc',
'test/cc_test_suite.cc',
'test/lap_timer.cc',
- 'test/run_all_unittests.cc',
+ 'test/run_all_perftests.cc',
+ 'trees/layer_tree_host_common_perftest.cc',
'trees/layer_tree_host_perftest.cc',
],
'include_dirs': [
@@ -324,6 +328,7 @@
'dependencies': [
'../skia/skia.gyp:skia',
'../ui/gfx/gfx.gyp:gfx',
+ '../ui/ui_unittests.gyp:ui_test_support',
],
},
],
diff --git a/cc/debug/fake_web_graphics_context_3d.cc b/cc/debug/fake_web_graphics_context_3d.cc
index 25157bfe49..eab653b360 100644
--- a/cc/debug/fake_web_graphics_context_3d.cc
+++ b/cc/debug/fake_web_graphics_context_3d.cc
@@ -9,6 +9,7 @@
using WebKit::WGC3Dboolean;
using WebKit::WGC3Denum;
+using WebKit::WGC3Dsizei;
using WebKit::WebGLId;
using WebKit::WebGraphicsContext3D;
@@ -234,46 +235,82 @@ WGC3Dboolean FakeWebGraphicsContext3D::isTexture(
return false;
}
-WebGLId FakeWebGraphicsContext3D::createBuffer() {
- return 1;
+void FakeWebGraphicsContext3D::genBuffers(WGC3Dsizei count, WebGLId* ids) {
+ for (int i = 0; i < count; ++i)
+ ids[i] = 1;
}
-void FakeWebGraphicsContext3D::deleteBuffer(WebKit::WebGLId id) {
+void FakeWebGraphicsContext3D::genFramebuffers(
+ WGC3Dsizei count, WebGLId* ids) {
+ for (int i = 0; i < count; ++i)
+ ids[i] = 1;
}
-WebGLId FakeWebGraphicsContext3D::createFramebuffer() {
- return 1;
+void FakeWebGraphicsContext3D::genRenderbuffers(
+ WGC3Dsizei count, WebGLId* ids) {
+ for (int i = 0; i < count; ++i)
+ ids[i] = 1;
}
-void FakeWebGraphicsContext3D::deleteFramebuffer(WebKit::WebGLId id) {
+void FakeWebGraphicsContext3D::genTextures(WGC3Dsizei count, WebGLId* ids) {
+ for (int i = 0; i < count; ++i)
+ ids[i] = 1;
}
-WebGLId FakeWebGraphicsContext3D::createProgram() {
+void FakeWebGraphicsContext3D::deleteBuffers(WGC3Dsizei count, WebGLId* ids) {
+}
+
+void FakeWebGraphicsContext3D::deleteFramebuffers(
+ WGC3Dsizei count, WebGLId* ids) {
+}
+
+void FakeWebGraphicsContext3D::deleteRenderbuffers(
+ WGC3Dsizei count, WebGLId* ids) {
+}
+
+void FakeWebGraphicsContext3D::deleteTextures(WGC3Dsizei count, WebGLId* ids) {
+}
+
+WebGLId FakeWebGraphicsContext3D::createBuffer() {
return 1;
}
-void FakeWebGraphicsContext3D::deleteProgram(WebKit::WebGLId id) {
+WebGLId FakeWebGraphicsContext3D::createFramebuffer() {
+ return 1;
}
WebGLId FakeWebGraphicsContext3D::createRenderbuffer() {
return 1;
}
+WebGLId FakeWebGraphicsContext3D::createTexture() {
+ return 1;
+}
+
+void FakeWebGraphicsContext3D::deleteBuffer(WebKit::WebGLId id) {
+}
+
+void FakeWebGraphicsContext3D::deleteFramebuffer(WebKit::WebGLId id) {
+}
+
void FakeWebGraphicsContext3D::deleteRenderbuffer(WebKit::WebGLId id) {
}
-WebGLId FakeWebGraphicsContext3D::createShader(WGC3Denum) {
- return 1;
+void FakeWebGraphicsContext3D::deleteTexture(WebGLId texture_id) {
}
-void FakeWebGraphicsContext3D::deleteShader(WebKit::WebGLId id) {
+WebGLId FakeWebGraphicsContext3D::createProgram() {
+ return 1;
}
-WebGLId FakeWebGraphicsContext3D::createTexture() {
+WebGLId FakeWebGraphicsContext3D::createShader(WGC3Denum) {
return 1;
}
-void FakeWebGraphicsContext3D::deleteTexture(WebGLId texture_id) {
+void FakeWebGraphicsContext3D::deleteProgram(WebKit::WebGLId id) {
+}
+
+void FakeWebGraphicsContext3D::deleteShader(WebKit::WebGLId id) {
}
void FakeWebGraphicsContext3D::attachShader(WebGLId program, WebGLId shader) {
diff --git a/cc/debug/fake_web_graphics_context_3d.h b/cc/debug/fake_web_graphics_context_3d.h
index 1bd3647276..f923f71409 100644
--- a/cc/debug/fake_web_graphics_context_3d.h
+++ b/cc/debug/fake_web_graphics_context_3d.h
@@ -530,19 +530,33 @@ class CC_EXPORT FakeWebGraphicsContext3D
WebKit::WGC3Dsizei width,
WebKit::WGC3Dsizei height) {}
+ virtual void genBuffers(WebKit::WGC3Dsizei count, WebKit::WebGLId* ids);
+ virtual void genFramebuffers(WebKit::WGC3Dsizei count, WebKit::WebGLId* ids);
+ virtual void genRenderbuffers(WebKit::WGC3Dsizei count, WebKit::WebGLId* ids);
+ virtual void genTextures(WebKit::WGC3Dsizei count, WebKit::WebGLId* ids);
+
+ virtual void deleteBuffers(WebKit::WGC3Dsizei count, WebKit::WebGLId* ids);
+ virtual void deleteFramebuffers(
+ WebKit::WGC3Dsizei count, WebKit::WebGLId* ids);
+ virtual void deleteRenderbuffers(
+ WebKit::WGC3Dsizei count, WebKit::WebGLId* ids);
+ virtual void deleteTextures(WebKit::WGC3Dsizei count, WebKit::WebGLId* ids);
+
virtual WebKit::WebGLId createBuffer();
virtual WebKit::WebGLId createFramebuffer();
- virtual WebKit::WebGLId createProgram();
virtual WebKit::WebGLId createRenderbuffer();
- virtual WebKit::WebGLId createShader(WebKit::WGC3Denum);
virtual WebKit::WebGLId createTexture();
virtual void deleteBuffer(WebKit::WebGLId id);
virtual void deleteFramebuffer(WebKit::WebGLId id);
- virtual void deleteProgram(WebKit::WebGLId id);
virtual void deleteRenderbuffer(WebKit::WebGLId id);
+ virtual void deleteTexture(WebKit::WebGLId id);
+
+ virtual WebKit::WebGLId createProgram();
+ virtual WebKit::WebGLId createShader(WebKit::WGC3Denum);
+
+ virtual void deleteProgram(WebKit::WebGLId id);
virtual void deleteShader(WebKit::WebGLId id);
- virtual void deleteTexture(WebKit::WebGLId texture_id);
virtual void texStorage2DEXT(
WebKit::WGC3Denum target,
diff --git a/cc/debug/test_context_support.cc b/cc/debug/test_context_support.cc
index edbbd72977..e5a0b93cef 100644
--- a/cc/debug/test_context_support.cc
+++ b/cc/debug/test_context_support.cc
@@ -21,6 +21,10 @@ void TestContextSupport::SignalQuery(uint32 query,
sync_point_callbacks_.push_back(callback);
}
+void TestContextSupport::SendManagedMemoryStats(
+ const gpu::ManagedMemoryStats& stats) {
+}
+
void TestContextSupport::CallAllSyncPointCallbacks() {
for (size_t i = 0; i < sync_point_callbacks_.size(); ++i) {
base::MessageLoop::current()->PostTask(
diff --git a/cc/debug/test_context_support.h b/cc/debug/test_context_support.h
index 4c092e902b..067bcaf4f5 100644
--- a/cc/debug/test_context_support.h
+++ b/cc/debug/test_context_support.h
@@ -21,6 +21,8 @@ class TestContextSupport : public gpu::ContextSupport {
const base::Closure& callback) OVERRIDE;
virtual void SignalQuery(uint32 query,
const base::Closure& callback) OVERRIDE;
+ virtual void SendManagedMemoryStats(const gpu::ManagedMemoryStats& stats)
+ OVERRIDE;
void CallAllSyncPointCallbacks();
diff --git a/cc/debug/test_web_graphics_context_3d.cc b/cc/debug/test_web_graphics_context_3d.cc
index 22f7602a3c..4135ba0217 100644
--- a/cc/debug/test_web_graphics_context_3d.cc
+++ b/cc/debug/test_web_graphics_context_3d.cc
@@ -188,56 +188,109 @@ WGC3Dboolean TestWebGraphicsContext3D::isTexture(
return false;
}
-WebGLId TestWebGraphicsContext3D::createBuffer() {
- return NextBufferId();
+void TestWebGraphicsContext3D::genBuffers(WGC3Dsizei count, WebGLId* ids) {
+ for (int i = 0; i < count; ++i)
+ ids[i] = NextBufferId();
}
-void TestWebGraphicsContext3D::deleteBuffer(WebGLId id) {
+void TestWebGraphicsContext3D::genFramebuffers(
+ WGC3Dsizei count, WebGLId* ids) {
+ for (int i = 0; i < count; ++i)
+ ids[i] = kFramebufferId | context_id_ << 16;
+}
+
+void TestWebGraphicsContext3D::genRenderbuffers(
+ WGC3Dsizei count, WebGLId* ids) {
+ for (int i = 0; i < count; ++i)
+ ids[i] = kRenderbufferId | context_id_ << 16;
+}
+
+void TestWebGraphicsContext3D::genTextures(WGC3Dsizei count, WebGLId* ids) {
+ for (int i = 0; i < count; ++i) {
+ ids[i] = NextTextureId();
+ DCHECK_NE(ids[i], kExternalTextureId);
+ }
base::AutoLock lock(namespace_->lock);
- unsigned context_id = id >> 17;
- unsigned buffer_id = id & 0x1ffff;
- DCHECK(buffer_id && buffer_id < namespace_->next_buffer_id);
- DCHECK_EQ(context_id, context_id_);
+ for (int i = 0; i < count; ++i)
+ namespace_->textures.Append(ids[i], new TestTexture());
}
-WebGLId TestWebGraphicsContext3D::createFramebuffer() {
- return kFramebufferId | context_id_ << 16;
+void TestWebGraphicsContext3D::deleteBuffers(WGC3Dsizei count, WebGLId* ids) {
+ base::AutoLock lock(namespace_->lock);
+ for (int i = 0; i < count; ++i) {
+ unsigned context_id = ids[i] >> 17;
+ unsigned buffer_id = ids[i] & 0x1ffff;
+ DCHECK(buffer_id && buffer_id < namespace_->next_buffer_id);
+ DCHECK_EQ(context_id, context_id_);
+ }
}
-void TestWebGraphicsContext3D::deleteFramebuffer(WebGLId id) {
- DCHECK_EQ(kFramebufferId | context_id_ << 16, id);
+void TestWebGraphicsContext3D::deleteFramebuffers(
+ WGC3Dsizei count, WebGLId* ids) {
+ for (int i = 0; i < count; ++i)
+ DCHECK_EQ(kFramebufferId | context_id_ << 16, ids[i]);
}
-WebGLId TestWebGraphicsContext3D::createProgram() {
- return kProgramId | context_id_ << 16;
+void TestWebGraphicsContext3D::deleteRenderbuffers(
+ WGC3Dsizei count, WebGLId* ids) {
+ for (int i = 0; i < count; ++i)
+ DCHECK_EQ(kRenderbufferId | context_id_ << 16, ids[i]);
}
-void TestWebGraphicsContext3D::deleteProgram(WebGLId id) {
- DCHECK_EQ(kProgramId | context_id_ << 16, id);
+void TestWebGraphicsContext3D::deleteTextures(WGC3Dsizei count, WebGLId* ids) {
+ base::AutoLock lock(namespace_->lock);
+ for (int i = 0; i < count; ++i) {
+ namespace_->textures.Remove(ids[i]);
+ texture_targets_.UnbindTexture(ids[i]);
+ }
+}
+
+WebGLId TestWebGraphicsContext3D::createBuffer() {
+ WebGLId id;
+ genBuffers(1, &id);
+ return id;
+}
+
+WebGLId TestWebGraphicsContext3D::createFramebuffer() {
+ WebGLId id;
+ genFramebuffers(1, &id);
+ return id;
}
WebGLId TestWebGraphicsContext3D::createRenderbuffer() {
- return kRenderbufferId | context_id_ << 16;
+ WebGLId id;
+ genRenderbuffers(1, &id);
+ return id;
+}
+
+WebGLId TestWebGraphicsContext3D::createTexture() {
+ WebGLId id;
+ genTextures(1, &id);
+ return id;
+}
+
+void TestWebGraphicsContext3D::deleteBuffer(WebGLId id) {
+ deleteBuffers(1, &id);
+}
+
+void TestWebGraphicsContext3D::deleteFramebuffer(WebGLId id) {
+ deleteFramebuffers(1, &id);
}
void TestWebGraphicsContext3D::deleteRenderbuffer(WebGLId id) {
- DCHECK_EQ(kRenderbufferId | context_id_ << 16, id);
+ deleteRenderbuffers(1, &id);
}
-WebGLId TestWebGraphicsContext3D::createShader(WGC3Denum) {
- return kShaderId | context_id_ << 16;
+void TestWebGraphicsContext3D::deleteTexture(WebGLId id) {
+ deleteTextures(1, &id);
}
-void TestWebGraphicsContext3D::deleteShader(WebGLId id) {
- DCHECK_EQ(kShaderId | context_id_ << 16, id);
+WebGLId TestWebGraphicsContext3D::createProgram() {
+ return kProgramId | context_id_ << 16;
}
-WebGLId TestWebGraphicsContext3D::createTexture() {
- WebGLId texture_id = NextTextureId();
- DCHECK_NE(texture_id, kExternalTextureId);
- base::AutoLock lock(namespace_->lock);
- namespace_->textures.Append(texture_id, new TestTexture());
- return texture_id;
+WebGLId TestWebGraphicsContext3D::createShader(WGC3Denum) {
+ return kShaderId | context_id_ << 16;
}
WebGLId TestWebGraphicsContext3D::createExternalTexture() {
@@ -246,10 +299,12 @@ WebGLId TestWebGraphicsContext3D::createExternalTexture() {
return kExternalTextureId;
}
-void TestWebGraphicsContext3D::deleteTexture(WebGLId texture_id) {
- base::AutoLock lock(namespace_->lock);
- namespace_->textures.Remove(texture_id);
- texture_targets_.UnbindTexture(texture_id);
+void TestWebGraphicsContext3D::deleteProgram(WebGLId id) {
+ DCHECK_EQ(kProgramId | context_id_ << 16, id);
+}
+
+void TestWebGraphicsContext3D::deleteShader(WebGLId id) {
+ DCHECK_EQ(kShaderId | context_id_ << 16, id);
}
void TestWebGraphicsContext3D::attachShader(WebGLId program, WebGLId shader) {
@@ -370,18 +425,6 @@ void TestWebGraphicsContext3D::loseContextCHROMIUM(WGC3Denum current,
shared_contexts_.clear();
}
-void TestWebGraphicsContext3D::signalSyncPoint(
- unsigned sync_point,
- WebGraphicsSyncPointCallback* callback) {
- NOTREACHED();
-}
-
-void TestWebGraphicsContext3D::signalQuery(
- WebKit::WebGLId query,
- WebGraphicsSyncPointCallback* callback) {
- NOTREACHED();
-}
-
void TestWebGraphicsContext3D::setSwapBuffersCompleteCallbackCHROMIUM(
WebGraphicsSwapBuffersCompleteCallbackCHROMIUM* callback) {
if (test_capabilities_.swapbuffers_complete_callback)
diff --git a/cc/debug/test_web_graphics_context_3d.h b/cc/debug/test_web_graphics_context_3d.h
index 574a6bd3c2..48ee70fac1 100644
--- a/cc/debug/test_web_graphics_context_3d.h
+++ b/cc/debug/test_web_graphics_context_3d.h
@@ -70,20 +70,34 @@ class CC_EXPORT TestWebGraphicsContext3D : public FakeWebGraphicsContext3D {
virtual void useProgram(WebKit::WebGLId program);
+ virtual void genBuffers(WebKit::WGC3Dsizei count, WebKit::WebGLId* ids);
+ virtual void genFramebuffers(WebKit::WGC3Dsizei count, WebKit::WebGLId* ids);
+ virtual void genRenderbuffers(WebKit::WGC3Dsizei count, WebKit::WebGLId* ids);
+ virtual void genTextures(WebKit::WGC3Dsizei count, WebKit::WebGLId* ids);
+
+ virtual void deleteBuffers(WebKit::WGC3Dsizei count, WebKit::WebGLId* ids);
+ virtual void deleteFramebuffers(
+ WebKit::WGC3Dsizei count, WebKit::WebGLId* ids);
+ virtual void deleteRenderbuffers(
+ WebKit::WGC3Dsizei count, WebKit::WebGLId* ids);
+ virtual void deleteTextures(WebKit::WGC3Dsizei count, WebKit::WebGLId* ids);
+
virtual WebKit::WebGLId createBuffer();
virtual WebKit::WebGLId createFramebuffer();
- virtual WebKit::WebGLId createProgram();
virtual WebKit::WebGLId createRenderbuffer();
- virtual WebKit::WebGLId createShader(WebKit::WGC3Denum);
virtual WebKit::WebGLId createTexture();
- virtual WebKit::WebGLId createExternalTexture();
virtual void deleteBuffer(WebKit::WebGLId id);
virtual void deleteFramebuffer(WebKit::WebGLId id);
- virtual void deleteProgram(WebKit::WebGLId id);
virtual void deleteRenderbuffer(WebKit::WebGLId id);
+ virtual void deleteTexture(WebKit::WebGLId id);
+
+ virtual WebKit::WebGLId createProgram();
+ virtual WebKit::WebGLId createShader(WebKit::WGC3Denum);
+ virtual WebKit::WebGLId createExternalTexture();
+
+ virtual void deleteProgram(WebKit::WebGLId id);
virtual void deleteShader(WebKit::WebGLId id);
- virtual void deleteTexture(WebKit::WebGLId texture_id);
virtual void endQueryEXT(WebKit::WGC3Denum target);
virtual void getQueryObjectuivEXT(
@@ -107,11 +121,6 @@ class CC_EXPORT TestWebGraphicsContext3D : public FakeWebGraphicsContext3D {
virtual void loseContextCHROMIUM(WebKit::WGC3Denum current,
WebKit::WGC3Denum other);
- virtual void signalSyncPoint(unsigned sync_point,
- WebGraphicsSyncPointCallback* callback);
- virtual void signalQuery(WebKit::WebGLId query,
- WebGraphicsSyncPointCallback* callback);
-
virtual void setSwapBuffersCompleteCallbackCHROMIUM(
WebGraphicsSwapBuffersCompleteCallbackCHROMIUM* callback);
@@ -194,6 +203,9 @@ class CC_EXPORT TestWebGraphicsContext3D : public FakeWebGraphicsContext3D {
void set_have_discard_framebuffer(bool have) {
test_capabilities_.discard_framebuffer = have;
}
+ void set_support_compressed_texture_etc1(bool support) {
+ test_capabilities_.texture_format_etc1 = support;
+ }
// When this context is lost, all contexts in its share group are also lost.
void add_share_group_context(WebKit::WebGraphicsContext3D* context3d) {
@@ -290,7 +302,6 @@ class CC_EXPORT TestWebGraphicsContext3D : public FakeWebGraphicsContext3D {
int times_map_buffer_chromium_succeeds_;
WebGraphicsContextLostCallback* context_lost_callback_;
WebGraphicsSwapBuffersCompleteCallbackCHROMIUM* swap_buffers_callback_;
- std::vector<WebGraphicsSyncPointCallback*> sync_point_callbacks_;
base::hash_set<WebKit::WebGLId> used_textures_;
std::vector<WebKit::WebGraphicsContext3D*> shared_contexts_;
int max_texture_size_;
diff --git a/cc/input/top_controls_manager.cc b/cc/input/top_controls_manager.cc
index 925830cf40..871d9e6f69 100644
--- a/cc/input/top_controls_manager.cc
+++ b/cc/input/top_controls_manager.cc
@@ -7,11 +7,12 @@
#include <algorithm>
#include "base/logging.h"
-#include "base/time/time.h"
#include "cc/animation/keyframed_animation_curve.h"
#include "cc/animation/timing_function.h"
#include "cc/input/top_controls_manager_client.h"
+#include "cc/output/begin_frame_args.h"
#include "cc/trees/layer_tree_impl.h"
+#include "ui/gfx/frame_time.h"
#include "ui/gfx/transform.h"
#include "ui/gfx/vector2d_f.h"
@@ -48,7 +49,8 @@ TopControlsManager::TopControlsManager(TopControlsManagerClient* client,
top_controls_show_height_(
top_controls_height * top_controls_hide_threshold),
top_controls_hide_height_(
- top_controls_height * (1.f - top_controls_show_threshold)) {
+ top_controls_height * (1.f - top_controls_show_threshold)),
+ pinch_gesture_active_(false) {
CHECK(client_);
}
@@ -89,6 +91,7 @@ void TopControlsManager::UpdateTopControlsState(TopControlsState constraints,
}
void TopControlsManager::ScrollBegin() {
+ DCHECK(!pinch_gesture_active_);
ResetAnimations();
current_scroll_delta_ = 0.f;
controls_scroll_begin_offset_ = controls_top_offset_;
@@ -96,6 +99,9 @@ void TopControlsManager::ScrollBegin() {
gfx::Vector2dF TopControlsManager::ScrollBy(
const gfx::Vector2dF pending_delta) {
+ if (pinch_gesture_active_)
+ return pending_delta;
+
if (permitted_state_ == SHOWN && pending_delta.y() > 0)
return pending_delta;
else if (permitted_state_ == HIDDEN && pending_delta.y() < 0)
@@ -120,9 +126,24 @@ gfx::Vector2dF TopControlsManager::ScrollBy(
}
void TopControlsManager::ScrollEnd() {
+ DCHECK(!pinch_gesture_active_);
StartAnimationIfNecessary();
}
+void TopControlsManager::PinchBegin() {
+ DCHECK(!pinch_gesture_active_);
+ pinch_gesture_active_ = true;
+ StartAnimationIfNecessary();
+}
+
+void TopControlsManager::PinchEnd() {
+ DCHECK(pinch_gesture_active_);
+ // Pinch{Begin,End} will always occur within the scope of Scroll{Begin,End},
+ // so return to a state expected by the remaining scroll sequence.
+ pinch_gesture_active_ = false;
+ ScrollBegin();
+}
+
void TopControlsManager::SetControlsTopOffset(float controls_top_offset) {
controls_top_offset = std::max(controls_top_offset, -top_controls_height_);
controls_top_offset = std::min(controls_top_offset, 0.f);
@@ -174,7 +195,7 @@ void TopControlsManager::SetupAnimation(AnimationDirection direction) {
top_controls_animation_ = KeyframedFloatAnimationCurve::Create();
double start_time =
- (base::TimeTicks::Now() - base::TimeTicks()).InMillisecondsF();
+ (gfx::FrameTime::Now() - base::TimeTicks()).InMillisecondsF();
top_controls_animation_->AddKeyframe(
FloatKeyframe::Create(start_time, controls_top_offset_,
scoped_ptr<TimingFunction>()));
diff --git a/cc/input/top_controls_manager.h b/cc/input/top_controls_manager.h
index 9bc3040d31..246efba5b9 100644
--- a/cc/input/top_controls_manager.h
+++ b/cc/input/top_controls_manager.h
@@ -56,6 +56,11 @@ class CC_EXPORT TopControlsManager
gfx::Vector2dF ScrollBy(const gfx::Vector2dF pending_delta);
void ScrollEnd();
+ // The caller should ensure that |Pinch{Begin,End}| are called within
+ // the scope of |Scroll{Begin,End}|.
+ void PinchBegin();
+ void PinchEnd();
+
gfx::Vector2dF Animate(base::TimeTicks monotonic_time);
protected:
@@ -91,6 +96,8 @@ class CC_EXPORT TopControlsManager
// the user stops the scroll.
float top_controls_hide_height_;
+ bool pinch_gesture_active_;
+
DISALLOW_COPY_AND_ASSIGN(TopControlsManager);
};
diff --git a/cc/input/top_controls_manager_unittest.cc b/cc/input/top_controls_manager_unittest.cc
index da7475f576..74687adfac 100644
--- a/cc/input/top_controls_manager_unittest.cc
+++ b/cc/input/top_controls_manager_unittest.cc
@@ -12,6 +12,7 @@
#include "cc/test/fake_layer_tree_host_impl.h"
#include "cc/trees/layer_tree_impl.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/gfx/frame_time.h"
#include "ui/gfx/vector2d_f.h"
namespace cc {
@@ -131,7 +132,7 @@ TEST(TopControlsManagerTest, PartialShownHideAnimation) {
EXPECT_TRUE(manager->animation());
- base::TimeTicks time = base::TimeTicks::Now();
+ base::TimeTicks time = gfx::FrameTime::Now();
float previous_offset = manager->controls_top_offset();
while (manager->animation()) {
time = base::TimeDelta::FromMicroseconds(100) + time;
@@ -161,7 +162,7 @@ TEST(TopControlsManagerTest, PartialShownShowAnimation) {
EXPECT_TRUE(manager->animation());
- base::TimeTicks time = base::TimeTicks::Now();
+ base::TimeTicks time = gfx::FrameTime::Now();
float previous_offset = manager->controls_top_offset();
while (manager->animation()) {
time = base::TimeDelta::FromMicroseconds(100) + time;
@@ -187,7 +188,7 @@ TEST(TopControlsManagerTest, PartialHiddenWithAmbiguousThresholdShows) {
manager->ScrollEnd();
EXPECT_TRUE(manager->animation());
- base::TimeTicks time = base::TimeTicks::Now();
+ base::TimeTicks time = gfx::FrameTime::Now();
float previous_offset = manager->controls_top_offset();
while (manager->animation()) {
time = base::TimeDelta::FromMicroseconds(100) + time;
@@ -213,7 +214,7 @@ TEST(TopControlsManagerTest, PartialHiddenWithAmbiguousThresholdHides) {
manager->ScrollEnd();
EXPECT_TRUE(manager->animation());
- base::TimeTicks time = base::TimeTicks::Now();
+ base::TimeTicks time = gfx::FrameTime::Now();
float previous_offset = manager->controls_top_offset();
while (manager->animation()) {
time = base::TimeDelta::FromMicroseconds(100) + time;
@@ -243,7 +244,7 @@ TEST(TopControlsManagerTest, PartialShownWithAmbiguousThresholdHides) {
manager->ScrollEnd();
EXPECT_TRUE(manager->animation());
- base::TimeTicks time = base::TimeTicks::Now();
+ base::TimeTicks time = gfx::FrameTime::Now();
float previous_offset = manager->controls_top_offset();
while (manager->animation()) {
time = base::TimeDelta::FromMicroseconds(100) + time;
@@ -273,7 +274,7 @@ TEST(TopControlsManagerTest, PartialShownWithAmbiguousThresholdShows) {
manager->ScrollEnd();
EXPECT_TRUE(manager->animation());
- base::TimeTicks time = base::TimeTicks::Now();
+ base::TimeTicks time = gfx::FrameTime::Now();
float previous_offset = manager->controls_top_offset();
while (manager->animation()) {
time = base::TimeDelta::FromMicroseconds(100) + time;
@@ -286,5 +287,88 @@ TEST(TopControlsManagerTest, PartialShownWithAmbiguousThresholdShows) {
EXPECT_EQ(100.f, manager->content_top_offset());
}
+TEST(TopControlsManagerTest, PinchIgnoresScroll) {
+ MockTopControlsManagerClient client(0.5f, 0.5f);
+ TopControlsManager* manager = client.manager();
+
+ // Hide the controls.
+ manager->ScrollBegin();
+ EXPECT_EQ(0.f, manager->controls_top_offset());
+
+ manager->ScrollBy(gfx::Vector2dF(0.f, 300.f));
+ EXPECT_EQ(-100.f, manager->controls_top_offset());
+
+ manager->PinchBegin();
+ EXPECT_EQ(-100.f, manager->controls_top_offset());
+
+ // Scrolls are ignored during pinch.
+ manager->ScrollBy(gfx::Vector2dF(0.f, -15.f));
+ EXPECT_EQ(-100.f, manager->controls_top_offset());
+ manager->PinchEnd();
+ EXPECT_EQ(-100.f, manager->controls_top_offset());
+
+ // Scrolls should no long be ignored.
+ manager->ScrollBy(gfx::Vector2dF(0.f, -15.f));
+ EXPECT_EQ(-85.f, manager->controls_top_offset());
+ EXPECT_EQ(15.f, manager->content_top_offset());
+ manager->ScrollEnd();
+
+ EXPECT_TRUE(manager->animation());
+}
+
+TEST(TopControlsManagerTest, PinchBeginStartsAnimationIfNecessary) {
+ MockTopControlsManagerClient client(0.5f, 0.5f);
+ TopControlsManager* manager = client.manager();
+
+ manager->ScrollBegin();
+ manager->ScrollBy(gfx::Vector2dF(0.f, 300.f));
+ EXPECT_EQ(-100.f, manager->controls_top_offset());
+
+ manager->PinchBegin();
+ EXPECT_FALSE(manager->animation());
+
+ manager->PinchEnd();
+ EXPECT_FALSE(manager->animation());
+
+ manager->ScrollBy(gfx::Vector2dF(0.f, -15.f));
+ EXPECT_EQ(-85.f, manager->controls_top_offset());
+ EXPECT_EQ(15.f, manager->content_top_offset());
+
+ manager->PinchBegin();
+ EXPECT_TRUE(manager->animation());
+
+ base::TimeTicks time = base::TimeTicks::Now();
+ float previous_offset = manager->controls_top_offset();
+ while (manager->animation()) {
+ time = base::TimeDelta::FromMicroseconds(100) + time;
+ manager->Animate(time);
+ EXPECT_LT(manager->controls_top_offset(), previous_offset);
+ previous_offset = manager->controls_top_offset();
+ }
+ EXPECT_FALSE(manager->animation());
+
+ manager->PinchEnd();
+ EXPECT_FALSE(manager->animation());
+
+ manager->ScrollBy(gfx::Vector2dF(0.f, -55.f));
+ EXPECT_EQ(-45.f, manager->controls_top_offset());
+ EXPECT_EQ(55.f, manager->content_top_offset());
+ EXPECT_FALSE(manager->animation());
+
+ manager->ScrollEnd();
+ EXPECT_TRUE(manager->animation());
+
+ time = base::TimeTicks::Now();
+ previous_offset = manager->controls_top_offset();
+ while (manager->animation()) {
+ time = base::TimeDelta::FromMicroseconds(100) + time;
+ manager->Animate(time);
+ EXPECT_GT(manager->controls_top_offset(), previous_offset);
+ previous_offset = manager->controls_top_offset();
+ }
+ EXPECT_FALSE(manager->animation());
+ EXPECT_EQ(0.f, manager->controls_top_offset());
+}
+
} // namespace
} // namespace cc
diff --git a/cc/layers/delegated_frame_resource_collection.cc b/cc/layers/delegated_frame_resource_collection.cc
index cd2633dc2a..5ca4eda57d 100644
--- a/cc/layers/delegated_frame_resource_collection.cc
+++ b/cc/layers/delegated_frame_resource_collection.cc
@@ -12,7 +12,8 @@ namespace cc {
DelegatedFrameResourceCollection::DelegatedFrameResourceCollection()
: client_(NULL),
main_thread_runner_(BlockingTaskRunner::current()),
- lost_all_resources_(false) {
+ lost_all_resources_(false),
+ weak_ptr_factory_(this) {
DCHECK(main_thread_checker_.CalledOnValidThread());
}
@@ -112,21 +113,21 @@ void DelegatedFrameResourceCollection::RefResources(
resource_id_ref_count_map_[resources[i].id].refs_to_wait_for++;
}
-ReturnCallback
-DelegatedFrameResourceCollection::GetReturnResourcesCallbackForImplThread() {
- return base::Bind(
- &DelegatedFrameResourceCollection::UnrefResourcesOnImplThread,
- this,
- main_thread_runner_);
-}
-
-void DelegatedFrameResourceCollection::UnrefResourcesOnImplThread(
+static void UnrefResourcesOnImplThread(
+ base::WeakPtr<DelegatedFrameResourceCollection> self,
scoped_refptr<BlockingTaskRunner> main_thread_runner,
const ReturnedResourceArray& returned) {
main_thread_runner->PostTask(
FROM_HERE,
base::Bind(
- &DelegatedFrameResourceCollection::UnrefResources, this, returned));
+ &DelegatedFrameResourceCollection::UnrefResources, self, returned));
+}
+
+ReturnCallback
+DelegatedFrameResourceCollection::GetReturnResourcesCallbackForImplThread() {
+ return base::Bind(&UnrefResourcesOnImplThread,
+ weak_ptr_factory_.GetWeakPtr(),
+ main_thread_runner_);
}
} // namespace cc
diff --git a/cc/layers/delegated_frame_resource_collection.h b/cc/layers/delegated_frame_resource_collection.h
index 68ee11a1c1..9a5d336749 100644
--- a/cc/layers/delegated_frame_resource_collection.h
+++ b/cc/layers/delegated_frame_resource_collection.h
@@ -7,6 +7,7 @@
#include "base/containers/hash_tables.h"
#include "base/memory/ref_counted.h"
+#include "base/memory/weak_ptr.h"
#include "base/threading/thread_checker.h"
#include "cc/base/cc_export.h"
#include "cc/resources/return_callback.h"
@@ -46,10 +47,6 @@ class CC_EXPORT DelegatedFrameResourceCollection
friend class base::RefCounted<DelegatedFrameResourceCollection>;
~DelegatedFrameResourceCollection();
- void UnrefResourcesOnImplThread(
- scoped_refptr<BlockingTaskRunner> main_thread_runner,
- const ReturnedResourceArray& returned);
-
DelegatedFrameResourceCollectionClient* client_;
scoped_refptr<BlockingTaskRunner> main_thread_runner_;
@@ -64,6 +61,7 @@ class CC_EXPORT DelegatedFrameResourceCollection
ResourceIdRefCountMap resource_id_ref_count_map_;
base::ThreadChecker main_thread_checker_;
+ base::WeakPtrFactory<DelegatedFrameResourceCollection> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(DelegatedFrameResourceCollection);
};
diff --git a/cc/layers/delegated_frame_resource_collection_unittest.cc b/cc/layers/delegated_frame_resource_collection_unittest.cc
new file mode 100644
index 0000000000..ace3def592
--- /dev/null
+++ b/cc/layers/delegated_frame_resource_collection_unittest.cc
@@ -0,0 +1,159 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/bind.h"
+#include "base/run_loop.h"
+#include "base/synchronization/waitable_event.h"
+#include "base/threading/thread.h"
+#include "cc/layers/delegated_frame_resource_collection.h"
+#include "cc/resources/returned_resource.h"
+#include "cc/resources/transferable_resource.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace cc {
+namespace {
+
+class DelegatedFrameResourceCollectionTest
+ : public testing::Test,
+ public DelegatedFrameResourceCollectionClient {
+ protected:
+ DelegatedFrameResourceCollectionTest() : resources_available_(false) {}
+
+ virtual void SetUp() OVERRIDE { CreateResourceCollection(); }
+
+ virtual void TearDown() OVERRIDE { DestroyResourceCollection(); }
+
+ void CreateResourceCollection() {
+ DCHECK(!resource_collection_);
+ resource_collection_ = new DelegatedFrameResourceCollection;
+ resource_collection_->SetClient(this);
+ }
+
+ void DestroyResourceCollection() {
+ if (resource_collection_) {
+ resource_collection_->SetClient(NULL);
+ resource_collection_ = NULL;
+ }
+ }
+
+ TransferableResourceArray CreateResourceArray() {
+ TransferableResourceArray resources;
+ TransferableResource resource;
+ resource.id = 444;
+ resources.push_back(resource);
+ return resources;
+ }
+
+ virtual void UnusedResourcesAreAvailable() OVERRIDE {
+ resources_available_ = true;
+ resource_collection_->TakeUnusedResourcesForChildCompositor(
+ &returned_resources_);
+ if (!resources_available_closure_.is_null())
+ resources_available_closure_.Run();
+ }
+
+ bool ReturnAndResetResourcesAvailable() {
+ bool r = resources_available_;
+ resources_available_ = false;
+ return r;
+ }
+
+ scoped_refptr<DelegatedFrameResourceCollection> resource_collection_;
+ bool resources_available_;
+ ReturnedResourceArray returned_resources_;
+ base::Closure resources_available_closure_;
+};
+
+// This checks that taking the return callback doesn't take extra refcounts,
+// since it's sent to other threads.
+TEST_F(DelegatedFrameResourceCollectionTest, NoRef) {
+ // Start with one ref.
+ EXPECT_TRUE(resource_collection_->HasOneRef());
+
+ ReturnCallback return_callback =
+ resource_collection_->GetReturnResourcesCallbackForImplThread();
+
+ // Callback shouldn't take a ref since it's sent to other threads.
+ EXPECT_TRUE(resource_collection_->HasOneRef());
+}
+
+void ReturnResourcesOnThread(ReturnCallback callback,
+ const ReturnedResourceArray& resources,
+ base::WaitableEvent* event) {
+ callback.Run(resources);
+ event->Wait();
+}
+
+// Tests that the ReturnCallback can run safely on threads even after the
+// last references to the collection were dropped.
+// Flaky: crbug.com/313441
+TEST_F(DelegatedFrameResourceCollectionTest, DISABLED_Thread) {
+ base::Thread thread("test thread");
+ thread.Start();
+
+ TransferableResourceArray resources = CreateResourceArray();
+ resource_collection_->ReceivedResources(resources);
+ resource_collection_->RefResources(resources);
+
+ ReturnedResourceArray returned_resources;
+ TransferableResource::ReturnResources(resources, &returned_resources);
+
+ base::WaitableEvent event(false, false);
+
+ {
+ base::RunLoop run_loop;
+ resources_available_closure_ = run_loop.QuitClosure();
+
+ thread.message_loop()->PostTask(
+ FROM_HERE,
+ base::Bind(
+ &ReturnResourcesOnThread,
+ resource_collection_->GetReturnResourcesCallbackForImplThread(),
+ returned_resources,
+ &event));
+
+ run_loop.Run();
+ }
+ EXPECT_TRUE(ReturnAndResetResourcesAvailable());
+ EXPECT_EQ(1u, returned_resources_.size());
+ EXPECT_EQ(444u, returned_resources_[0].id);
+ EXPECT_EQ(1, returned_resources_[0].count);
+ returned_resources_.clear();
+
+ // The event prevents the return resources callback from being deleted.
+ // Destroy the last reference from this thread to the collection before
+ // signaling the event, to ensure any reference taken by the callback, if any,
+ // would be the last one.
+ DestroyResourceCollection();
+ event.Signal();
+
+ CreateResourceCollection();
+ resource_collection_->ReceivedResources(resources);
+ resource_collection_->RefResources(resources);
+
+ // Destroy the collection before we have a chance to run the return callback.
+ ReturnCallback return_callback =
+ resource_collection_->GetReturnResourcesCallbackForImplThread();
+ resource_collection_->LoseAllResources();
+ DestroyResourceCollection();
+
+ EXPECT_TRUE(ReturnAndResetResourcesAvailable());
+ EXPECT_EQ(1u, returned_resources_.size());
+ EXPECT_EQ(444u, returned_resources_[0].id);
+ EXPECT_EQ(1, returned_resources_[0].count);
+ EXPECT_TRUE(returned_resources_[0].lost);
+ returned_resources_.clear();
+
+ thread.message_loop()->PostTask(FROM_HERE,
+ base::Bind(&ReturnResourcesOnThread,
+ return_callback,
+ returned_resources,
+ &event));
+ event.Signal();
+
+ thread.Stop();
+}
+
+} // namespace
+} // namespace cc
diff --git a/cc/layers/delegated_renderer_layer_impl.cc b/cc/layers/delegated_renderer_layer_impl.cc
index 35bd0b7f1b..25a27afeb4 100644
--- a/cc/layers/delegated_renderer_layer_impl.cc
+++ b/cc/layers/delegated_renderer_layer_impl.cc
@@ -237,6 +237,13 @@ void DelegatedRendererLayerImpl::AppendContributingRenderPasses(
RenderPassSink* render_pass_sink) {
DCHECK(HasContributingDelegatedRenderPasses());
+ const RenderPass* root_delegated_render_pass =
+ render_passes_in_draw_order_.back();
+ gfx::Size frame_size = root_delegated_render_pass->output_rect.size();
+ gfx::Transform delegated_frame_to_root_transform =
+ screen_space_transform() *
+ DelegatedFrameToLayerSpaceTransform(frame_size);
+
for (size_t i = 0; i < render_passes_in_draw_order_.size() - 1; ++i) {
RenderPass::Id output_render_pass_id(-1, -1);
bool present =
@@ -248,8 +255,11 @@ void DelegatedRendererLayerImpl::AppendContributingRenderPasses(
<< render_passes_in_draw_order_[i]->id.index;
DCHECK_GT(output_render_pass_id.index, 0);
- render_pass_sink->AppendRenderPass(
- render_passes_in_draw_order_[i]->Copy(output_render_pass_id));
+ scoped_ptr<RenderPass> copy_pass =
+ render_passes_in_draw_order_[i]->Copy(output_render_pass_id);
+ copy_pass->transform_to_root_target.ConcatTransform(
+ delegated_frame_to_root_transform);
+ render_pass_sink->AppendRenderPass(copy_pass.Pass());
}
}
diff --git a/cc/layers/delegated_renderer_layer_impl_unittest.cc b/cc/layers/delegated_renderer_layer_impl_unittest.cc
index 58fa36692e..05e8513d29 100644
--- a/cc/layers/delegated_renderer_layer_impl_unittest.cc
+++ b/cc/layers/delegated_renderer_layer_impl_unittest.cc
@@ -25,6 +25,7 @@
#include "cc/trees/layer_tree_impl.h"
#include "cc/trees/single_thread_proxy.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/gfx/frame_time.h"
#include "ui/gfx/transform.h"
namespace cc {
@@ -88,24 +89,21 @@ class DelegatedRendererLayerImplTestSimple
delegated_renderer_layer->SetTransform(transform);
ScopedPtrVector<RenderPass> delegated_render_passes;
- TestRenderPass* pass1 = AddRenderPass(
- &delegated_render_passes,
- RenderPass::Id(9, 6),
- gfx::Rect(6, 6, 6, 6),
- gfx::Transform());
+ TestRenderPass* pass1 = AddRenderPass(&delegated_render_passes,
+ RenderPass::Id(9, 6),
+ gfx::Rect(6, 6, 6, 6),
+ gfx::Transform(1, 0, 0, 1, 5, 6));
AddQuad(pass1, gfx::Rect(0, 0, 6, 6), 33u);
- TestRenderPass* pass2 = AddRenderPass(
- &delegated_render_passes,
- RenderPass::Id(9, 7),
- gfx::Rect(7, 7, 7, 7),
- gfx::Transform());
+ TestRenderPass* pass2 = AddRenderPass(&delegated_render_passes,
+ RenderPass::Id(9, 7),
+ gfx::Rect(7, 7, 7, 7),
+ gfx::Transform(1, 0, 0, 1, 7, 8));
AddQuad(pass2, gfx::Rect(0, 0, 7, 7), 22u);
AddRenderPassQuad(pass2, pass1);
- TestRenderPass* pass3 = AddRenderPass(
- &delegated_render_passes,
- RenderPass::Id(9, 8),
- gfx::Rect(0, 0, 8, 8),
- gfx::Transform());
+ TestRenderPass* pass3 = AddRenderPass(&delegated_render_passes,
+ RenderPass::Id(9, 8),
+ gfx::Rect(0, 0, 8, 8),
+ gfx::Transform(1, 0, 0, 1, 9, 10));
AddRenderPassQuad(pass3, pass2);
delegated_renderer_layer->SetFrameDataForRenderPasses(
&delegated_render_passes);
@@ -165,7 +163,7 @@ TEST_F(DelegatedRendererLayerImplTestSimple, AddsContributingRenderPasses) {
EXPECT_EQ(gfx::Rect(7, 7, 7, 7).ToString(),
frame.render_passes[2]->output_rect.ToString());
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
host_impl_->DidDrawAllLayers(frame);
}
@@ -201,7 +199,7 @@ TEST_F(DelegatedRendererLayerImplTestSimple,
EXPECT_EQ(gfx::Rect(0, 0, 6, 6).ToString(),
frame.render_passes[1]->quad_list[0]->rect.ToString());
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
host_impl_->DidDrawAllLayers(frame);
}
@@ -228,7 +226,7 @@ TEST_F(DelegatedRendererLayerImplTestSimple, AddsQuadsToTargetRenderPass) {
EXPECT_EQ(gfx::Rect(0, 0, 15, 15).ToString(),
frame.render_passes[3]->quad_list[1]->rect.ToString());
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
host_impl_->DidDrawAllLayers(frame);
}
@@ -262,6 +260,42 @@ TEST_F(DelegatedRendererLayerImplTestSimple,
EXPECT_TRANSFORMATION_MATRIX_EQ(
gfx::Transform(), frame.render_passes[1]->quad_list[0]->quadTransform());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
+ host_impl_->DidDrawAllLayers(frame);
+}
+
+TEST_F(DelegatedRendererLayerImplTestSimple, RenderPassTransformIsModified) {
+ LayerTreeHostImpl::FrameData frame;
+ EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
+
+ // The delegated layer has a surface between it and the root.
+ EXPECT_TRUE(delegated_renderer_layer_->render_target()->parent());
+
+ // Each non-DelegatedRendererLayer added one RenderPass. The
+ // DelegatedRendererLayer added two contributing passes.
+ ASSERT_EQ(5u, frame.render_passes.size());
+
+ // The DelegatedRendererLayer is at position 9,9 compared to the root, so all
+ // render pass' transforms to the root should be shifted by this amount.
+ // The DelegatedRendererLayer has a size of 10x10, but the root delegated
+ // RenderPass has a size of 8x8, so any render passes should be scaled by
+ // 10/8.
+ gfx::Transform transform;
+ transform.Translate(9.0, 9.0);
+ transform.Scale(10.0 / 8.0, 10.0 / 8.0);
+
+ // The first contributing surface has a translation of 5, 6.
+ gfx::Transform five_six(1, 0, 0, 1, 5, 6);
+
+ // The second contributing surface has a translation of 7, 8.
+ gfx::Transform seven_eight(1, 0, 0, 1, 7, 8);
+
+ EXPECT_TRANSFORMATION_MATRIX_EQ(
+ transform * five_six, frame.render_passes[1]->transform_to_root_target);
+ EXPECT_TRANSFORMATION_MATRIX_EQ(
+ transform * seven_eight,
+ frame.render_passes[2]->transform_to_root_target);
+
host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
host_impl_->DidDrawAllLayers(frame);
}
@@ -274,7 +308,7 @@ TEST_F(DelegatedRendererLayerImplTestSimple, DoesNotOwnARenderSurface) {
// has no need to be a RenderSurface for the quads it carries.
EXPECT_FALSE(delegated_renderer_layer_->render_surface());
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
host_impl_->DidDrawAllLayers(frame);
}
@@ -289,7 +323,7 @@ TEST_F(DelegatedRendererLayerImplTestSimple, DoesOwnARenderSurfaceForOpacity) {
// render surface.
EXPECT_TRUE(delegated_renderer_layer_->render_surface());
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
host_impl_->DidDrawAllLayers(frame);
}
@@ -307,7 +341,7 @@ TEST_F(DelegatedRendererLayerImplTestSimple,
// render surface.
EXPECT_TRUE(delegated_renderer_layer_->render_surface());
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
host_impl_->DidDrawAllLayers(frame);
}
@@ -354,7 +388,7 @@ TEST_F(DelegatedRendererLayerImplTestOwnSurface, AddsRenderPasses) {
EXPECT_EQ(gfx::Rect(7, 7, 7, 7).ToString(),
frame.render_passes[2]->output_rect.ToString());
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
host_impl_->DidDrawAllLayers(frame);
}
@@ -391,7 +425,7 @@ TEST_F(DelegatedRendererLayerImplTestOwnSurface,
EXPECT_EQ(gfx::Rect(0, 0, 6, 6).ToString(),
frame.render_passes[1]->quad_list[0]->rect.ToString());
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
host_impl_->DidDrawAllLayers(frame);
}
@@ -416,7 +450,7 @@ TEST_F(DelegatedRendererLayerImplTestOwnSurface, AddsQuadsToTargetRenderPass) {
EXPECT_EQ(gfx::Rect(7, 7, 7, 7).ToString(),
frame.render_passes[3]->quad_list[0]->rect.ToString());
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
host_impl_->DidDrawAllLayers(frame);
}
@@ -448,7 +482,7 @@ TEST_F(DelegatedRendererLayerImplTestOwnSurface,
EXPECT_TRANSFORMATION_MATRIX_EQ(
gfx::Transform(), frame.render_passes[1]->quad_list[0]->quadTransform());
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
host_impl_->DidDrawAllLayers(frame);
}
@@ -682,7 +716,7 @@ TEST_F(DelegatedRendererLayerImplTestTransform, QuadsUnclipped_NoSurface) {
expected,
contrib_delegated_shared_quad_state->content_to_target_transform);
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
host_impl_->DidDrawAllLayers(frame);
}
@@ -745,7 +779,7 @@ TEST_F(DelegatedRendererLayerImplTestTransform, QuadsClipped_NoSurface) {
expected,
contrib_delegated_shared_quad_state->content_to_target_transform);
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
host_impl_->DidDrawAllLayers(frame);
}
@@ -801,7 +835,7 @@ TEST_F(DelegatedRendererLayerImplTestTransform, QuadsUnclipped_Surface) {
expected,
contrib_delegated_shared_quad_state->content_to_target_transform);
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
host_impl_->DidDrawAllLayers(frame);
}
@@ -856,7 +890,7 @@ TEST_F(DelegatedRendererLayerImplTestTransform, QuadsClipped_Surface) {
expected,
contrib_delegated_shared_quad_state->content_to_target_transform);
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
host_impl_->DidDrawAllLayers(frame);
}
@@ -1032,7 +1066,7 @@ TEST_F(DelegatedRendererLayerImplTestClip,
// Quads are clipped to the delegated renderer layer.
EXPECT_TRUE(root_delegated_shared_quad_state->is_clipped);
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
host_impl_->DidDrawAllLayers(frame);
}
@@ -1061,7 +1095,7 @@ TEST_F(DelegatedRendererLayerImplTestClip,
// Quads came with a clip rect.
EXPECT_TRUE(root_delegated_shared_quad_state->is_clipped);
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
host_impl_->DidDrawAllLayers(frame);
}
@@ -1091,7 +1125,7 @@ TEST_F(DelegatedRendererLayerImplTestClip,
// Quads are clipped to the delegated renderer layer.
EXPECT_TRUE(root_delegated_shared_quad_state->is_clipped);
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
host_impl_->DidDrawAllLayers(frame);
}
@@ -1120,7 +1154,7 @@ TEST_F(DelegatedRendererLayerImplTestClip,
// Quads came with a clip rect.
EXPECT_TRUE(root_delegated_shared_quad_state->is_clipped);
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
host_impl_->DidDrawAllLayers(frame);
}
@@ -1149,7 +1183,7 @@ TEST_F(DelegatedRendererLayerImplTestClip,
// clip rect is ignored, and they are not set as clipped.
EXPECT_FALSE(root_delegated_shared_quad_state->is_clipped);
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
host_impl_->DidDrawAllLayers(frame);
}
@@ -1179,7 +1213,7 @@ TEST_F(DelegatedRendererLayerImplTestClip,
// Quads came with a clip rect.
EXPECT_TRUE(root_delegated_shared_quad_state->is_clipped);
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
host_impl_->DidDrawAllLayers(frame);
}
@@ -1208,7 +1242,7 @@ TEST_F(DelegatedRendererLayerImplTestClip,
// clip rect is ignored, and they are not set as clipped.
EXPECT_FALSE(root_delegated_shared_quad_state->is_clipped);
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
host_impl_->DidDrawAllLayers(frame);
}
@@ -1239,7 +1273,7 @@ TEST_F(DelegatedRendererLayerImplTestClip, QuadsClipped_LayerClipped_Surface) {
// Quads came with a clip rect.
EXPECT_TRUE(root_delegated_shared_quad_state->is_clipped);
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
host_impl_->DidDrawAllLayers(frame);
}
@@ -1292,7 +1326,7 @@ TEST_F(DelegatedRendererLayerImplTest, InvalidRenderPassDrawQuad) {
EXPECT_EQ(DrawQuad::SOLID_COLOR,
frame.render_passes[0]->quad_list[0]->material);
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
host_impl_->DidDrawAllLayers(frame);
}
diff --git a/cc/layers/layer.cc b/cc/layers/layer.cc
index 80fad6a551..b10112afd1 100644
--- a/cc/layers/layer.cc
+++ b/cc/layers/layer.cc
@@ -619,7 +619,7 @@ void Layer::SetScrollOffset(gfx::Vector2d scroll_offset) {
void Layer::SetScrollOffsetFromImplSide(gfx::Vector2d scroll_offset) {
DCHECK(IsPropertyChangeAllowed());
- // This function only gets called during a begin frame, so there
+ // This function only gets called during a BeginMainFrame, so there
// is no need to call SetNeedsUpdate here.
DCHECK(layer_tree_host_ && layer_tree_host_->CommitRequested());
if (scroll_offset_ == scroll_offset)
@@ -881,8 +881,8 @@ void Layer::PushPropertiesTo(LayerImpl* layer) {
}
// Adjust the scroll delta to be just the scrolls that have happened since
- // the begin frame was sent. This happens for impl-side painting
- // in LayerImpl::ApplyScrollDeltasSinceBeginFrame in a separate tree walk.
+ // the BeginMainFrame was sent. This happens for impl-side painting
+ // in LayerImpl::ApplyScrollDeltasSinceBeginMainFrame in a separate tree walk.
if (layer->layer_tree_impl()->settings().impl_side_painting) {
layer->SetScrollOffset(scroll_offset_);
} else {
@@ -1028,11 +1028,6 @@ void Layer::SuspendAnimations(double monotonic_time) {
SetNeedsCommit();
}
-void Layer::ResumeAnimations(double monotonic_time) {
- layer_animation_controller_->ResumeAnimations(monotonic_time);
- SetNeedsCommit();
-}
-
void Layer::SetLayerAnimationControllerForTest(
scoped_refptr<LayerAnimationController> controller) {
layer_animation_controller_->RemoveValueObserver(this);
diff --git a/cc/layers/layer.h b/cc/layers/layer.h
index 1328b071b9..274e82fc7c 100644
--- a/cc/layers/layer.h
+++ b/cc/layers/layer.h
@@ -376,7 +376,6 @@ class CC_EXPORT Layer : public base::RefCounted<Layer>,
void RemoveAnimation(int animation_id);
void SuspendAnimations(double monotonic_time);
- void ResumeAnimations(double monotonic_time);
bool AnimatedBoundsForBox(const gfx::BoxF& box, gfx::BoxF* bounds) {
return layer_animation_controller_->AnimatedBoundsForBox(box, bounds);
diff --git a/cc/layers/layer_impl.cc b/cc/layers/layer_impl.cc
index 14f3e2afe1..894daf1a27 100644
--- a/cc/layers/layer_impl.cc
+++ b/cc/layers/layer_impl.cc
@@ -385,7 +385,7 @@ void LayerImpl::ApplySentScrollDeltasFromAbortedCommit() {
sent_scroll_delta_ = gfx::Vector2d();
}
-void LayerImpl::ApplyScrollDeltasSinceBeginFrame() {
+void LayerImpl::ApplyScrollDeltasSinceBeginMainFrame() {
// Only the pending tree can have missing scrolls.
DCHECK(layer_tree_impl()->IsPendingTree());
if (!scrollable())
@@ -614,6 +614,13 @@ base::DictionaryValue* LayerImpl::LayerTreeAsJson() const {
if (scrollable_)
result->SetBoolean("Scrollable", scrollable_);
+ if (have_wheel_event_handlers_)
+ result->SetBoolean("WheelHandler", have_wheel_event_handlers_);
+ if (!touch_event_handler_region_.IsEmpty()) {
+ scoped_ptr<base::Value> region = touch_event_handler_region_.AsValue();
+ result->Set("TouchRegion", region.release());
+ }
+
list = new base::ListValue;
for (size_t i = 0; i < children_.size(); ++i)
list->Append(children_[i]->LayerTreeAsJson());
diff --git a/cc/layers/layer_impl.h b/cc/layers/layer_impl.h
index 4bd91da0a2..9d3951b78a 100644
--- a/cc/layers/layer_impl.h
+++ b/cc/layers/layer_impl.h
@@ -382,7 +382,7 @@ class CC_EXPORT LayerImpl : LayerAnimationValueObserver {
}
void ApplySentScrollDeltasFromAbortedCommit();
- void ApplyScrollDeltasSinceBeginFrame();
+ void ApplyScrollDeltasSinceBeginMainFrame();
void SetShouldScrollOnMainThread(bool should_scroll_on_main_thread) {
should_scroll_on_main_thread_ = should_scroll_on_main_thread;
diff --git a/cc/layers/layer_unittest.cc b/cc/layers/layer_unittest.cc
index 3a7a1c1b2d..c66eb8551e 100644
--- a/cc/layers/layer_unittest.cc
+++ b/cc/layers/layer_unittest.cc
@@ -39,7 +39,7 @@ namespace {
class MockLayerTreeHost : public LayerTreeHost {
public:
explicit MockLayerTreeHost(LayerTreeHostClient* client)
- : LayerTreeHost(client, LayerTreeSettings()) {
+ : LayerTreeHost(client, NULL, LayerTreeSettings()) {
Initialize(NULL);
}
@@ -803,11 +803,12 @@ class LayerTreeHostFactory {
: client_(FakeLayerTreeHostClient::DIRECT_3D) {}
scoped_ptr<LayerTreeHost> Create() {
- return LayerTreeHost::Create(&client_, LayerTreeSettings(), NULL).Pass();
+ return LayerTreeHost::Create(&client_, NULL, LayerTreeSettings(), NULL)
+ .Pass();
}
scoped_ptr<LayerTreeHost> Create(LayerTreeSettings settings) {
- return LayerTreeHost::Create(&client_, settings, NULL).Pass();
+ return LayerTreeHost::Create(&client_, NULL, settings, NULL).Pass();
}
private:
diff --git a/cc/layers/nine_patch_layer_unittest.cc b/cc/layers/nine_patch_layer_unittest.cc
index f616560c85..7213a51e09 100644
--- a/cc/layers/nine_patch_layer_unittest.cc
+++ b/cc/layers/nine_patch_layer_unittest.cc
@@ -32,7 +32,7 @@ namespace {
class MockLayerTreeHost : public LayerTreeHost {
public:
explicit MockLayerTreeHost(LayerTreeHostClient* client)
- : LayerTreeHost(client, LayerTreeSettings()) {
+ : LayerTreeHost(client, NULL, LayerTreeSettings()) {
Initialize(NULL);
}
};
diff --git a/cc/layers/picture_layer.cc b/cc/layers/picture_layer.cc
index ef17a0924b..bc311a36c0 100644
--- a/cc/layers/picture_layer.cc
+++ b/cc/layers/picture_layer.cc
@@ -20,7 +20,8 @@ PictureLayer::PictureLayer(ContentLayerClient* client)
: client_(client),
pile_(make_scoped_refptr(new PicturePile())),
instrumentation_object_tracker_(id()),
- is_mask_(false) {
+ is_mask_(false),
+ update_source_frame_number_(-1) {
}
PictureLayer::~PictureLayer() {
@@ -38,6 +39,18 @@ void PictureLayer::PushPropertiesTo(LayerImpl* base_layer) {
Layer::PushPropertiesTo(base_layer);
PictureLayerImpl* layer_impl = static_cast<PictureLayerImpl*>(base_layer);
+ if (layer_impl->bounds().IsEmpty()) {
+ // Update may not get called for an empty layer, so resize here instead.
+ // Using layer_impl because either bounds() or paint_properties().bounds
+ // may disagree and either one could have been pushed to layer_impl.
+ pile_->Resize(gfx::Size());
+ pile_->UpdateRecordedRegion();
+ } else if (update_source_frame_number_ ==
+ layer_tree_host()->source_frame_number()) {
+ // If update called, then pile size must match bounds pushed to impl layer.
+ DCHECK_EQ(layer_impl->bounds().ToString(), pile_->size().ToString());
+ }
+
layer_impl->SetIsMask(is_mask_);
// Unlike other properties, invalidation must always be set on layer_impl.
// See PictureLayerImpl::PushPropertiesTo for more details.
@@ -78,6 +91,7 @@ bool PictureLayer::Update(ResourceUpdateQueue* queue,
"source_frame_number",
layer_tree_host()->source_frame_number());
+ update_source_frame_number_ = layer_tree_host()->source_frame_number();
bool updated = Layer::Update(queue, occlusion);
pile_->Resize(paint_properties().bounds);
diff --git a/cc/layers/picture_layer.h b/cc/layers/picture_layer.h
index f67ca91eb4..e1e4a9cc68 100644
--- a/cc/layers/picture_layer.h
+++ b/cc/layers/picture_layer.h
@@ -56,6 +56,8 @@ class CC_EXPORT PictureLayer : public Layer {
Region pile_invalidation_;
bool is_mask_;
+ int update_source_frame_number_;
+
DISALLOW_COPY_AND_ASSIGN(PictureLayer);
};
diff --git a/cc/layers/picture_layer_impl.cc b/cc/layers/picture_layer_impl.cc
index 36b2ba9eec..d2ef7d08ae 100644
--- a/cc/layers/picture_layer_impl.cc
+++ b/cc/layers/picture_layer_impl.cc
@@ -553,6 +553,7 @@ void PictureLayerImpl::SyncFromActiveLayer(const PictureLayerImpl* other) {
if (!DrawsContent()) {
ResetRasterScale();
+ tilings_->RemoveAllTilings();
return;
}
@@ -611,7 +612,8 @@ void PictureLayerImpl::SyncTiling(
// get updated prior to drawing or activation. If this tree does not
// need update draw properties, then its transforms are up to date and
// we can create tiles for this tiling immediately.
- if (!layer_tree_impl()->needs_update_draw_properties())
+ if (!layer_tree_impl()->needs_update_draw_properties() &&
+ should_update_tile_priorities_)
UpdateTilePriorities();
}
diff --git a/cc/layers/picture_layer_impl_unittest.cc b/cc/layers/picture_layer_impl_unittest.cc
index f9dfb9907b..7493e382e3 100644
--- a/cc/layers/picture_layer_impl_unittest.cc
+++ b/cc/layers/picture_layer_impl_unittest.cc
@@ -1106,6 +1106,41 @@ TEST_F(PictureLayerImplTest, ActivateUninitializedLayer) {
EXPECT_FALSE(active_layer_->needs_post_commit_initialization());
}
+TEST_F(PictureLayerImplTest, SyncTilingAfterReleaseResource) {
+ SetupDefaultTrees(gfx::Size(10, 10));
+ host_impl_.active_tree()->UpdateDrawProperties();
+ EXPECT_FALSE(host_impl_.active_tree()->needs_update_draw_properties());
+
+ // Contrived unit test of a real crash. A layer is transparent during a
+ // context loss, and later becomes opaque, causing active layer SyncTiling to
+ // be called.
+ const float tile_scale = 2.f;
+ active_layer_->DidLoseOutputSurface();
+ EXPECT_FALSE(active_layer_->tilings()->TilingAtScale(tile_scale));
+ pending_layer_->AddTiling(2.f);
+ EXPECT_TRUE(active_layer_->tilings()->TilingAtScale(tile_scale));
+}
+
+TEST_F(PictureLayerImplTest, NoTilingIfDoesNotDrawContent) {
+ // Set up layers with tilings.
+ SetupDefaultTrees(gfx::Size(10, 10));
+ SetContentsScaleOnBothLayers(1.f, 1.f, 1.f, false);
+ pending_layer_->PushPropertiesTo(active_layer_);
+ EXPECT_TRUE(pending_layer_->DrawsContent());
+ EXPECT_TRUE(pending_layer_->CanHaveTilings());
+ EXPECT_GE(pending_layer_->num_tilings(), 0u);
+ EXPECT_GE(active_layer_->num_tilings(), 0u);
+
+ // Set content to false, which should make CanHaveTilings return false.
+ pending_layer_->SetDrawsContent(false);
+ EXPECT_FALSE(pending_layer_->DrawsContent());
+ EXPECT_FALSE(pending_layer_->CanHaveTilings());
+
+ // No tilings should be pushed to active layer.
+ pending_layer_->PushPropertiesTo(active_layer_);
+ EXPECT_EQ(0u, active_layer_->num_tilings());
+}
+
class DeferredInitPictureLayerImplTest : public PictureLayerImplTest {
public:
DeferredInitPictureLayerImplTest()
diff --git a/cc/layers/picture_layer_unittest.cc b/cc/layers/picture_layer_unittest.cc
new file mode 100644
index 0000000000..c3dd244c2e
--- /dev/null
+++ b/cc/layers/picture_layer_unittest.cc
@@ -0,0 +1,69 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cc/layers/picture_layer.h"
+
+#include "cc/layers/content_layer_client.h"
+#include "cc/layers/picture_layer_impl.h"
+#include "cc/resources/resource_update_queue.h"
+#include "cc/test/fake_layer_tree_host.h"
+#include "cc/test/fake_picture_layer_impl.h"
+#include "cc/test/fake_proxy.h"
+#include "cc/test/impl_side_painting_settings.h"
+#include "cc/trees/occlusion_tracker.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace cc {
+namespace {
+
+class MockContentLayerClient : public ContentLayerClient {
+ public:
+ virtual void PaintContents(SkCanvas* canvas,
+ gfx::Rect clip,
+ gfx::RectF* opaque) OVERRIDE {}
+ virtual void DidChangeLayerCanUseLCDText() OVERRIDE {}
+};
+
+TEST(PictureLayerTest, NoTilesIfEmptyBounds) {
+ MockContentLayerClient client;
+ scoped_refptr<PictureLayer> layer = PictureLayer::Create(&client);
+ layer->SetBounds(gfx::Size(10, 10));
+
+ scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create();
+ host->SetRootLayer(layer);
+ layer->SetIsDrawable(true);
+ layer->SavePaintProperties();
+
+ OcclusionTracker occlusion(gfx::Rect(0, 0, 1000, 1000), false);
+ scoped_ptr<ResourceUpdateQueue> queue(new ResourceUpdateQueue);
+ layer->Update(queue.get(), &occlusion);
+
+ layer->SetBounds(gfx::Size(0, 0));
+ layer->SavePaintProperties();
+ // Intentionally skipping Update since it would normally be skipped on
+ // a layer with empty bounds.
+
+ FakeProxy proxy;
+#ifndef NDEBUG
+ proxy.SetCurrentThreadIsImplThread(true);
+#endif
+ {
+ FakeLayerTreeHostImpl host_impl(ImplSidePaintingSettings(), &proxy);
+ host_impl.CreatePendingTree();
+ scoped_ptr<FakePictureLayerImpl> layer_impl =
+ FakePictureLayerImpl::Create(host_impl.pending_tree(), 1);
+
+ layer->PushPropertiesTo(layer_impl.get());
+ EXPECT_FALSE(layer_impl->CanHaveTilings());
+ EXPECT_TRUE(layer_impl->bounds() == gfx::Size(0, 0));
+ EXPECT_TRUE(layer_impl->pile()->size() == gfx::Size(0, 0));
+ EXPECT_TRUE(layer_impl->pile()->recorded_region().IsEmpty());
+ }
+#ifndef NDEBUG
+ proxy.SetCurrentThreadIsImplThread(false);
+#endif
+}
+
+} // namespace
+} // namespace cc
diff --git a/cc/layers/scrollbar_layer_impl_base.cc b/cc/layers/scrollbar_layer_impl_base.cc
index c1e7126ff5..362465be3b 100644
--- a/cc/layers/scrollbar_layer_impl_base.cc
+++ b/cc/layers/scrollbar_layer_impl_base.cc
@@ -72,6 +72,13 @@ void ScrollbarLayerImplBase::SetVisibleToTotalLengthRatio(float ratio) {
NoteLayerPropertyChanged();
}
+void ScrollbarLayerImplBase::SetThumbThicknessScaleFactor(float factor) {
+ if (thumb_thickness_scale_factor_ == factor)
+ return;
+ thumb_thickness_scale_factor_ = factor;
+ NoteLayerPropertyChanged();
+}
+
gfx::Rect ScrollbarLayerImplBase::ComputeThumbQuadRect() const {
// Thumb extent is the length of the thumb in the scrolling direction, thumb
// thickness is in the perpendicular direction. Here's an example of a
diff --git a/cc/layers/scrollbar_layer_impl_base.h b/cc/layers/scrollbar_layer_impl_base.h
index 55ade6ab04..360ef97089 100644
--- a/cc/layers/scrollbar_layer_impl_base.h
+++ b/cc/layers/scrollbar_layer_impl_base.h
@@ -44,9 +44,7 @@ class CC_EXPORT ScrollbarLayerImplBase : public LayerImpl {
float thumb_thickness_scale_factor() {
return thumb_thickness_scale_factor_;
}
- void set_thumb_thickness_scale_factor(float thumb_thickness_scale_factor) {
- thumb_thickness_scale_factor_ = thumb_thickness_scale_factor;
- }
+ void SetThumbThicknessScaleFactor(float thumb_thickness_scale_factor);
protected:
ScrollbarLayerImplBase(LayerTreeImpl* tree_impl,
diff --git a/cc/layers/scrollbar_layer_unittest.cc b/cc/layers/scrollbar_layer_unittest.cc
index 250d610b0a..0423cdc067 100644
--- a/cc/layers/scrollbar_layer_unittest.cc
+++ b/cc/layers/scrollbar_layer_unittest.cc
@@ -514,7 +514,7 @@ class MockLayerTreeHost : public LayerTreeHost {
public:
MockLayerTreeHost(LayerTreeHostClient* client,
const LayerTreeSettings& settings)
- : LayerTreeHost(client, settings),
+ : LayerTreeHost(client, NULL, settings),
next_id_(1),
total_ui_resource_created_(0),
total_ui_resource_deleted_(0) {
diff --git a/cc/layers/texture_layer.cc b/cc/layers/texture_layer.cc
index 18410fb5de..45a456e523 100644
--- a/cc/layers/texture_layer.cc
+++ b/cc/layers/texture_layer.cc
@@ -132,9 +132,10 @@ void TextureLayer::SetTextureId(unsigned id) {
SetNextCommitWaitsForActivation();
}
-void TextureLayer::SetTextureMailbox(
+void TextureLayer::SetTextureMailboxInternal(
const TextureMailbox& mailbox,
- scoped_ptr<SingleReleaseCallback> release_callback) {
+ scoped_ptr<SingleReleaseCallback> release_callback,
+ bool requires_commit) {
DCHECK(uses_mailbox_);
DCHECK(!mailbox.IsValid() || !holder_ref_ ||
!mailbox.Equals(holder_ref_->holder()->mailbox()));
@@ -146,12 +147,26 @@ void TextureLayer::SetTextureMailbox(
else
holder_ref_.reset();
needs_set_mailbox_ = true;
- SetNeedsCommit();
+ // If we are within a commit, no need to do it again immediately after.
+ if (requires_commit)
+ SetNeedsCommit();
+ else
+ SetNeedsPushProperties();
+
// The active frame needs to be replaced and the mailbox returned before the
// commit is called complete.
SetNextCommitWaitsForActivation();
}
+void TextureLayer::SetTextureMailbox(
+ const TextureMailbox& mailbox,
+ scoped_ptr<SingleReleaseCallback> release_callback) {
+ SetTextureMailboxInternal(
+ mailbox,
+ release_callback.Pass(),
+ true /* requires_commit */);
+}
+
void TextureLayer::WillModifyTexture() {
if (layer_tree_host() && (DrawsContent() || content_committed_)) {
layer_tree_host()->AcquireLayerTextures();
@@ -209,7 +224,11 @@ bool TextureLayer::Update(ResourceUpdateQueue* queue,
&mailbox,
&release_callback,
layer_tree_host()->UsingSharedMemoryResources())) {
- SetTextureMailbox(mailbox, release_callback.Pass());
+ // Already within a commit, no need to do another one immediately.
+ SetTextureMailboxInternal(
+ mailbox,
+ release_callback.Pass(),
+ false /* requires_commit */);
updated = true;
}
} else {
diff --git a/cc/layers/texture_layer.h b/cc/layers/texture_layer.h
index b0edb22ba1..0a7fd4e32e 100644
--- a/cc/layers/texture_layer.h
+++ b/cc/layers/texture_layer.h
@@ -148,6 +148,11 @@ class CC_EXPORT TextureLayer : public Layer {
virtual ~TextureLayer();
private:
+ void SetTextureMailboxInternal(
+ const TextureMailbox& mailbox,
+ scoped_ptr<SingleReleaseCallback> release_callback,
+ bool requires_commit);
+
TextureLayerClient* client_;
bool uses_mailbox_;
diff --git a/cc/layers/texture_layer_unittest.cc b/cc/layers/texture_layer_unittest.cc
index bdb1358ae6..63cf132ae8 100644
--- a/cc/layers/texture_layer_unittest.cc
+++ b/cc/layers/texture_layer_unittest.cc
@@ -44,7 +44,7 @@ namespace {
class MockLayerTreeHost : public LayerTreeHost {
public:
explicit MockLayerTreeHost(LayerTreeHostClient* client)
- : LayerTreeHost(client, LayerTreeSettings()) {
+ : LayerTreeHost(client, NULL, LayerTreeSettings()) {
Initialize(NULL);
}
@@ -1695,6 +1695,109 @@ class TextureLayerChangeInvisibleTest
// delegating renderer.
SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(TextureLayerChangeInvisibleTest);
+// Checks that TextureLayer::Update does not cause an extra commit when setting
+// the texture mailbox.
+class TextureLayerNoExtraCommitForMailboxTest
+ : public LayerTreeTest,
+ public TextureLayerClient {
+ public:
+ TextureLayerNoExtraCommitForMailboxTest()
+ : prepare_mailbox_count_(0) {}
+
+ // TextureLayerClient implementation.
+ virtual unsigned PrepareTexture() OVERRIDE {
+ NOTREACHED();
+ return 0;
+ }
+
+ // TextureLayerClient implementation.
+ virtual WebKit::WebGraphicsContext3D* Context3d() OVERRIDE {
+ NOTREACHED();
+ return NULL;
+ }
+
+ virtual bool PrepareTextureMailbox(
+ cc::TextureMailbox* mailbox,
+ scoped_ptr<SingleReleaseCallback>* release_callback,
+ bool use_shared_memory) OVERRIDE {
+ prepare_mailbox_count_++;
+ // Alternate between two mailboxes to ensure that the TextureLayer updates
+ // and commits.
+ if (prepare_mailbox_count_ % 2 == 0)
+ *mailbox = MakeMailbox('1');
+ else
+ *mailbox = MakeMailbox('2');
+
+ // Non-zero mailboxes need a callback.
+ *release_callback = SingleReleaseCallback::Create(
+ base::Bind(&TextureLayerNoExtraCommitForMailboxTest::MailboxReleased,
+ base::Unretained(this)));
+ // If the test fails, this would cause an infinite number of commits.
+ return true;
+ }
+
+ TextureMailbox MakeMailbox(char name) {
+ return TextureMailbox(std::string(64, name));
+ }
+
+ void MailboxReleased(unsigned sync_point, bool lost_resource) {
+ }
+
+ virtual void SetupTree() OVERRIDE {
+ scoped_refptr<Layer> root = Layer::Create();
+ root->SetBounds(gfx::Size(10, 10));
+ root->SetAnchorPoint(gfx::PointF());
+ root->SetIsDrawable(true);
+
+ solid_layer_ = SolidColorLayer::Create();
+ solid_layer_->SetBounds(gfx::Size(10, 10));
+ solid_layer_->SetIsDrawable(true);
+ solid_layer_->SetBackgroundColor(SK_ColorWHITE);
+ root->AddChild(solid_layer_);
+
+ parent_layer_ = Layer::Create();
+ parent_layer_->SetBounds(gfx::Size(10, 10));
+ parent_layer_->SetIsDrawable(true);
+ root->AddChild(parent_layer_);
+
+ texture_layer_ = TextureLayer::CreateForMailbox(this);
+ texture_layer_->SetBounds(gfx::Size(10, 10));
+ texture_layer_->SetAnchorPoint(gfx::PointF());
+ texture_layer_->SetIsDrawable(true);
+ parent_layer_->AddChild(texture_layer_);
+
+ layer_tree_host()->SetRootLayer(root);
+ LayerTreeTest::SetupTree();
+ }
+
+ virtual void BeginTest() OVERRIDE {
+ PostSetNeedsCommitToMainThread();
+ }
+
+
+ virtual void DidCommit() OVERRIDE {
+ switch (layer_tree_host()->source_frame_number()) {
+ case 1:
+ EndTest();
+ break;
+ default:
+ NOTREACHED();
+ break;
+ }
+ }
+
+ virtual void AfterTest() OVERRIDE {}
+
+ private:
+ scoped_refptr<SolidColorLayer> solid_layer_;
+ scoped_refptr<Layer> parent_layer_;
+ scoped_refptr<TextureLayer> texture_layer_;
+
+ int prepare_mailbox_count_;
+};
+
+SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerNoExtraCommitForMailboxTest);
+
// Checks that changing a mailbox in the client for a TextureLayer that's
// invisible correctly works and uses the new mailbox as soon as the layer
// becomes visible (and returns the old one).
diff --git a/cc/layers/tiled_layer_unittest.cc b/cc/layers/tiled_layer_unittest.cc
index 47d694b137..9bdb9078c7 100644
--- a/cc/layers/tiled_layer_unittest.cc
+++ b/cc/layers/tiled_layer_unittest.cc
@@ -60,6 +60,7 @@ class TiledLayerTest : public testing::Test {
virtual void SetUp() {
impl_thread_.Start();
layer_tree_host_ = LayerTreeHost::Create(&fake_layer_tree_host_client_,
+ NULL,
settings_,
impl_thread_.message_loop_proxy());
proxy_ = layer_tree_host_->proxy();
@@ -73,7 +74,7 @@ class TiledLayerTest : public testing::Test {
DebugScopedSetImplThreadAndMainThreadBlocked
impl_thread_and_main_thread_blocked(proxy_);
resource_provider_ =
- ResourceProvider::Create(output_surface_.get(), 0, false);
+ ResourceProvider::Create(output_surface_.get(), NULL, 0, false);
host_impl_ = make_scoped_ptr(new FakeLayerTreeHostImpl(proxy_));
}
diff --git a/cc/layers/ui_resource_layer_impl.cc b/cc/layers/ui_resource_layer_impl.cc
index 23e33f9035..2c9a28681c 100644
--- a/cc/layers/ui_resource_layer_impl.cc
+++ b/cc/layers/ui_resource_layer_impl.cc
@@ -113,8 +113,9 @@ void UIResourceLayerImpl::AppendQuads(QuadSink* quad_sink,
gfx::Rect quad_rect(bounds());
- // TODO(clholgat): Properly calculate opacity: crbug.com/300027
- gfx::Rect opaque_rect(contents_opaque() ? quad_rect : gfx::Rect());
+ bool opaque = layer_tree_impl()->IsUIResourceOpaque(ui_resource_id_) ||
+ contents_opaque();
+ gfx::Rect opaque_rect(opaque ? quad_rect : gfx::Rect());
scoped_ptr<TextureDrawQuad> quad;
quad = TextureDrawQuad::Create();
diff --git a/cc/layers/ui_resource_layer_impl_unittest.cc b/cc/layers/ui_resource_layer_impl_unittest.cc
index 383b8a3301..35ff05bacf 100644
--- a/cc/layers/ui_resource_layer_impl_unittest.cc
+++ b/cc/layers/ui_resource_layer_impl_unittest.cc
@@ -23,6 +23,7 @@ scoped_ptr<UIResourceLayerImpl> GenerateUIResourceLayer(
FakeUIResourceLayerTreeHostImpl* host_impl,
gfx::Size bitmap_size,
gfx::Size layer_size,
+ bool opaque,
UIResourceId uid) {
gfx::Rect visible_content_rect(layer_size);
scoped_ptr<UIResourceLayerImpl> layer =
@@ -38,6 +39,7 @@ scoped_ptr<UIResourceLayerImpl> GenerateUIResourceLayer(
SkBitmap::kARGB_8888_Config, bitmap_size.width(), bitmap_size.height());
skbitmap.allocPixels();
skbitmap.setImmutable();
+ skbitmap.setIsOpaque(opaque);
UIResourceBitmap bitmap(skbitmap);
host_impl->CreateUIResource(uid, bitmap);
@@ -64,10 +66,12 @@ TEST(UIResourceLayerImplTest, VerifyDrawQuads) {
gfx::Size bitmap_size(100, 100);
gfx::Size layer_size(100, 100);;
size_t expected_quad_size = 1;
+ bool opaque = true;
UIResourceId uid = 1;
scoped_ptr<UIResourceLayerImpl> layer = GenerateUIResourceLayer(&host_impl,
bitmap_size,
layer_size,
+ opaque,
uid);
QuadSizeTest(layer.Pass(), expected_quad_size);
@@ -77,6 +81,7 @@ TEST(UIResourceLayerImplTest, VerifyDrawQuads) {
layer = GenerateUIResourceLayer(&host_impl,
bitmap_size,
layer_size,
+ opaque,
uid);
QuadSizeTest(layer.Pass(), expected_quad_size);
}
@@ -94,26 +99,48 @@ void OpaqueBoundsTest(scoped_ptr<UIResourceLayerImpl> layer,
EXPECT_EQ(expected_opaque_bounds, opaque_rect);
}
-TEST(UIResourceLayerImplTest, VerifyOpaqueBounds) {
+TEST(UIResourceLayerImplTest, VerifySetOpaqueOnSkBitmap) {
FakeImplProxy proxy;
FakeUIResourceLayerTreeHostImpl host_impl(&proxy);
gfx::Size bitmap_size(100, 100);
gfx::Size layer_size(100, 100);;
+ bool opaque = false;
UIResourceId uid = 1;
scoped_ptr<UIResourceLayerImpl> layer = GenerateUIResourceLayer(&host_impl,
bitmap_size,
layer_size,
+ opaque,
uid);
- layer->SetContentsOpaque(false);
gfx::Rect expected_opaque_bounds;
OpaqueBoundsTest(layer.Pass(), expected_opaque_bounds);
+ opaque = true;
layer = GenerateUIResourceLayer(&host_impl,
bitmap_size,
layer_size,
+ opaque,
uid);
+ expected_opaque_bounds = gfx::Rect(layer->bounds());
+ OpaqueBoundsTest(layer.Pass(), expected_opaque_bounds);
+}
+
+TEST(UIResourceLayerImplTest, VerifySetOpaqueOnLayer) {
+ FakeImplProxy proxy;
+ FakeUIResourceLayerTreeHostImpl host_impl(&proxy);
+
+ gfx::Size bitmap_size(100, 100);
+ gfx::Size layer_size(100, 100);
+ bool skbitmap_opaque = false;
+ UIResourceId uid = 1;
+ scoped_ptr<UIResourceLayerImpl> layer = GenerateUIResourceLayer(
+ &host_impl, bitmap_size, layer_size, skbitmap_opaque, uid);
+ layer->SetContentsOpaque(false);
+ gfx::Rect expected_opaque_bounds;
+ OpaqueBoundsTest(layer.Pass(), expected_opaque_bounds);
+ layer = GenerateUIResourceLayer(
+ &host_impl, bitmap_size, layer_size, skbitmap_opaque, uid);
layer->SetContentsOpaque(true);
expected_opaque_bounds = gfx::Rect(layer->bounds());
OpaqueBoundsTest(layer.Pass(), expected_opaque_bounds);
diff --git a/cc/layers/ui_resource_layer_unittest.cc b/cc/layers/ui_resource_layer_unittest.cc
index 1720b8176a..a2c75c16d0 100644
--- a/cc/layers/ui_resource_layer_unittest.cc
+++ b/cc/layers/ui_resource_layer_unittest.cc
@@ -32,7 +32,7 @@ namespace {
class MockLayerTreeHost : public LayerTreeHost {
public:
explicit MockLayerTreeHost(LayerTreeHostClient* client)
- : LayerTreeHost(client, LayerTreeSettings()) {
+ : LayerTreeHost(client, NULL, LayerTreeSettings()) {
Initialize(NULL);
}
};
diff --git a/cc/output/begin_frame_args.cc b/cc/output/begin_frame_args.cc
index d7da76c3bc..92901afb1f 100644
--- a/cc/output/begin_frame_args.cc
+++ b/cc/output/begin_frame_args.cc
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include "cc/output/begin_frame_args.h"
+#include "ui/gfx/frame_time.h"
namespace cc {
@@ -29,20 +30,20 @@ BeginFrameArgs BeginFrameArgs::Create(base::TimeTicks frame_time,
BeginFrameArgs BeginFrameArgs::CreateForSynchronousCompositor() {
// For WebView/SynchronousCompositor, we always want to draw immediately,
// so we set the deadline to 0 and guess that the interval is 16 milliseconds.
- return BeginFrameArgs(base::TimeTicks::Now(),
+ return BeginFrameArgs(gfx::FrameTime::Now(),
base::TimeTicks(),
DefaultInterval());
}
BeginFrameArgs BeginFrameArgs::CreateForTesting() {
- base::TimeTicks now = base::TimeTicks::Now();
+ base::TimeTicks now = gfx::FrameTime::Now();
return BeginFrameArgs(now,
now + (DefaultInterval() / 2),
DefaultInterval());
}
BeginFrameArgs BeginFrameArgs::CreateExpiredForTesting() {
- base::TimeTicks now = base::TimeTicks::Now();
+ base::TimeTicks now = gfx::FrameTime::Now();
return BeginFrameArgs(now,
now - DefaultInterval(),
DefaultInterval());
diff --git a/cc/output/context_provider.cc b/cc/output/context_provider.cc
index 7f46f7ccc6..a823fa29f3 100644
--- a/cc/output/context_provider.cc
+++ b/cc/output/context_provider.cc
@@ -21,6 +21,7 @@ ContextProvider::Capabilities::Capabilities()
shallow_flush(false),
swapbuffers_complete_callback(false),
texture_format_bgra8888(false),
+ texture_format_etc1(false),
texture_rectangle(false),
texture_storage(false),
texture_usage(false),
diff --git a/cc/output/context_provider.h b/cc/output/context_provider.h
index 01ba0d816e..6db326d7f9 100644
--- a/cc/output/context_provider.h
+++ b/cc/output/context_provider.h
@@ -41,6 +41,7 @@ class ContextProvider : public base::RefCountedThreadSafe<ContextProvider> {
bool shallow_flush;
bool swapbuffers_complete_callback;
bool texture_format_bgra8888;
+ bool texture_format_etc1;
bool texture_rectangle;
bool texture_storage;
bool texture_usage;
diff --git a/cc/output/delegating_renderer.cc b/cc/output/delegating_renderer.cc
index 772a16ac65..678d21ab27 100644
--- a/cc/output/delegating_renderer.cc
+++ b/cc/output/delegating_renderer.cc
@@ -22,6 +22,8 @@
#include "cc/quads/tile_draw_quad.h"
#include "cc/quads/yuv_video_draw_quad.h"
#include "cc/resources/resource_provider.h"
+#include "gpu/command_buffer/client/context_support.h"
+#include "gpu/command_buffer/common/gpu_memory_allocation.h"
#include "third_party/WebKit/public/platform/WebGraphicsContext3D.h"
#include "third_party/khronos/GLES2/gl2ext.h"
@@ -60,7 +62,8 @@ bool DelegatingRenderer::Initialize() {
capabilities_.using_offscreen_context3d = false;
if (!output_surface_->context_provider()) {
- // TODO(danakj): Make software compositing work.
+ capabilities_.using_shared_memory_resources = true;
+ capabilities_.using_map_image = settings_->use_map_image;
return true;
}
@@ -180,12 +183,13 @@ void DelegatingRenderer::SendManagedMemoryStats(size_t bytes_visible,
NOTIMPLEMENTED();
return;
}
- WebKit::WebGraphicsManagedMemoryStats stats;
- stats.bytesVisible = bytes_visible;
- stats.bytesVisibleAndNearby = bytes_visible_and_nearby;
- stats.bytesAllocated = bytes_allocated;
- stats.backbufferRequested = false;
- context_provider->Context3d()->sendManagedMemoryStatsCHROMIUM(&stats);
+ gpu::ManagedMemoryStats stats;
+ stats.bytes_required = bytes_visible;
+ stats.bytes_nice_to_have = bytes_visible_and_nearby;
+ stats.bytes_allocated = bytes_allocated;
+ stats.backbuffer_requested = false;
+
+ context_provider->ContextSupport()->SendManagedMemoryStats(stats);
}
void DelegatingRenderer::SetDiscardBackBufferWhenNotVisible(bool discard) {
diff --git a/cc/output/direct_renderer.cc b/cc/output/direct_renderer.cc
index c02200dfd6..24c3fc2795 100644
--- a/cc/output/direct_renderer.cc
+++ b/cc/output/direct_renderer.cc
@@ -148,10 +148,11 @@ void DirectRenderer::DecideRenderPassAllocationsForFrame(
if (!resource_provider_)
return;
- base::hash_map<RenderPass::Id, const RenderPass*> render_passes_in_frame;
+ base::hash_map<RenderPass::Id, gfx::Size> render_passes_in_frame;
for (size_t i = 0; i < render_passes_in_draw_order.size(); ++i)
- render_passes_in_frame.insert(std::pair<RenderPass::Id, const RenderPass*>(
- render_passes_in_draw_order[i]->id, render_passes_in_draw_order[i]));
+ render_passes_in_frame.insert(std::pair<RenderPass::Id, gfx::Size>(
+ render_passes_in_draw_order[i]->id,
+ RenderPassTextureSize(render_passes_in_draw_order[i])));
std::vector<RenderPass::Id> passes_to_delete;
base::ScopedPtrHashMap<RenderPass::Id, ScopedResource>::const_iterator
@@ -159,24 +160,20 @@ void DirectRenderer::DecideRenderPassAllocationsForFrame(
for (pass_iter = render_pass_textures_.begin();
pass_iter != render_pass_textures_.end();
++pass_iter) {
- base::hash_map<RenderPass::Id, const RenderPass*>::const_iterator it =
+ base::hash_map<RenderPass::Id, gfx::Size>::const_iterator it =
render_passes_in_frame.find(pass_iter->first);
if (it == render_passes_in_frame.end()) {
passes_to_delete.push_back(pass_iter->first);
continue;
}
- const RenderPass* render_pass_in_frame = it->second;
- gfx::Size required_size = RenderPassTextureSize(render_pass_in_frame);
- ResourceFormat required_format =
- RenderPassTextureFormat(render_pass_in_frame);
+ gfx::Size required_size = it->second;
ScopedResource* texture = pass_iter->second;
DCHECK(texture);
bool size_appropriate = texture->size().width() >= required_size.width() &&
texture->size().height() >= required_size.height();
- if (texture->id() &&
- (!size_appropriate || texture->format() != required_format))
+ if (texture->id() && !size_appropriate)
texture->Free();
}
@@ -410,9 +407,8 @@ bool DirectRenderer::UseRenderPass(DrawingFrame* frame,
size.Enlarge(enlarge_pass_texture_amount_.x(),
enlarge_pass_texture_amount_.y());
if (!texture->id() &&
- !texture->Allocate(size,
- ResourceProvider::TextureUsageFramebuffer,
- RenderPassTextureFormat(render_pass)))
+ !texture->Allocate(
+ size, ResourceProvider::TextureUsageFramebuffer, RGBA_8888))
return false;
return BindFramebufferToTexture(frame, texture, render_pass->output_rect);
@@ -429,10 +425,4 @@ gfx::Size DirectRenderer::RenderPassTextureSize(const RenderPass* render_pass) {
return render_pass->output_rect.size();
}
-// static
-ResourceFormat DirectRenderer::RenderPassTextureFormat(
- const RenderPass* render_pass) {
- return RGBA_8888;
-}
-
} // namespace cc
diff --git a/cc/output/direct_renderer.h b/cc/output/direct_renderer.h
index f55cc595be..6be6707a71 100644
--- a/cc/output/direct_renderer.h
+++ b/cc/output/direct_renderer.h
@@ -86,7 +86,6 @@ class CC_EXPORT DirectRenderer : public Renderer {
gfx::RectF draw_space_rect);
static gfx::Size RenderPassTextureSize(const RenderPass* render_pass);
- static ResourceFormat RenderPassTextureFormat(const RenderPass* render_pass);
void DrawRenderPass(DrawingFrame* frame,
const RenderPass* render_pass,
diff --git a/cc/output/filter_operation.cc b/cc/output/filter_operation.cc
index 672dba79d5..50f111fc2d 100644
--- a/cc/output/filter_operation.cc
+++ b/cc/output/filter_operation.cc
@@ -8,6 +8,7 @@
#include "cc/base/math_util.h"
#include "cc/output/filter_operation.h"
#include "third_party/skia/include/core/SkMath.h"
+#include "ui/gfx/animation/tween.h"
namespace cc {
@@ -97,52 +98,6 @@ FilterOperation::FilterOperation(const FilterOperation& other)
FilterOperation::~FilterOperation() {
}
-// TODO(ajuma): Define a version of gfx::Tween::ValueBetween for floats, and use
-// that instead.
-static float BlendFloats(float from, float to, double progress) {
- return from * (1.0 - progress) + to * progress;
-}
-
-static int BlendInts(int from, int to, double progress) {
- return static_cast<int>(
- MathUtil::Round(from * (1.0 - progress) + to * progress));
-}
-
-static uint8_t BlendColorComponents(uint8_t from,
- uint8_t to,
- uint8_t from_alpha,
- uint8_t to_alpha,
- uint8_t blended_alpha,
- double progress) {
- // Since progress can be outside [0, 1], blending can produce a value outside
- // [0, 255].
- int blended_premultiplied = BlendInts(SkMulDiv255Round(from, from_alpha),
- SkMulDiv255Round(to, to_alpha),
- progress);
- int blended = static_cast<int>(
- MathUtil::Round(blended_premultiplied * 255.f / blended_alpha));
- return static_cast<uint8_t>(MathUtil::ClampToRange(blended, 0, 255));
-}
-
-static SkColor BlendSkColors(SkColor from, SkColor to, double progress) {
- int from_a = SkColorGetA(from);
- int to_a = SkColorGetA(to);
- int blended_a = BlendInts(from_a, to_a, progress);
- if (blended_a <= 0)
- return SkColorSetARGB(0, 0, 0, 0);
- blended_a = std::min(blended_a, 255);
-
- // TODO(ajuma): Use SkFourByteInterp once http://crbug.com/260369 is fixed.
- uint8_t blended_r = BlendColorComponents(
- SkColorGetR(from), SkColorGetR(to), from_a, to_a, blended_a, progress);
- uint8_t blended_g = BlendColorComponents(
- SkColorGetG(from), SkColorGetG(to), from_a, to_a, blended_a, progress);
- uint8_t blended_b = BlendColorComponents(
- SkColorGetB(from), SkColorGetB(to), from_a, to_a, blended_a, progress);
-
- return SkColorSetARGB(blended_a, blended_r, blended_g, blended_b);
-}
-
static FilterOperation CreateNoOpFilter(FilterOperation::FilterType type) {
switch (type) {
case FilterOperation::GRAYSCALE:
@@ -239,21 +194,25 @@ FilterOperation FilterOperation::Blend(const FilterOperation* from,
}
blended_filter.set_amount(ClampAmountForFilterType(
- BlendFloats(from_op.amount(), to_op.amount(), progress), to_op.type()));
+ gfx::Tween::FloatValueBetween(progress, from_op.amount(), to_op.amount()),
+ to_op.type()));
if (to_op.type() == FilterOperation::DROP_SHADOW) {
- gfx::Point blended_offset(BlendInts(from_op.drop_shadow_offset().x(),
- to_op.drop_shadow_offset().x(),
- progress),
- BlendInts(from_op.drop_shadow_offset().y(),
- to_op.drop_shadow_offset().y(),
- progress));
+ gfx::Point blended_offset(
+ gfx::Tween::LinearIntValueBetween(progress,
+ from_op.drop_shadow_offset().x(),
+ to_op.drop_shadow_offset().x()),
+ gfx::Tween::LinearIntValueBetween(progress,
+ from_op.drop_shadow_offset().y(),
+ to_op.drop_shadow_offset().y()));
blended_filter.set_drop_shadow_offset(blended_offset);
- blended_filter.set_drop_shadow_color(BlendSkColors(
- from_op.drop_shadow_color(), to_op.drop_shadow_color(), progress));
+ blended_filter.set_drop_shadow_color(gfx::Tween::ColorValueBetween(
+ progress, from_op.drop_shadow_color(), to_op.drop_shadow_color()));
} else if (to_op.type() == FilterOperation::ZOOM) {
- blended_filter.set_zoom_inset(std::max(
- BlendInts(from_op.zoom_inset(), to_op.zoom_inset(), progress), 0));
+ blended_filter.set_zoom_inset(
+ std::max(gfx::Tween::LinearIntValueBetween(
+ from_op.zoom_inset(), to_op.zoom_inset(), progress),
+ 0));
}
return blended_filter;
diff --git a/cc/output/filter_operations_unittest.cc b/cc/output/filter_operations_unittest.cc
index e975ed509f..7f439b9f15 100644
--- a/cc/output/filter_operations_unittest.cc
+++ b/cc/output/filter_operations_unittest.cc
@@ -412,6 +412,11 @@ TEST(FilterOperationsTest, BlendDropShadowFilters) {
gfx::Point(-2, -4), 0.f, SkColorSetARGB(0, 0, 0, 0));
EXPECT_EQ(expected, blended);
+ blended = FilterOperation::Blend(&from, &to, 0.25);
+ expected = FilterOperation::CreateDropShadowFilter(
+ gfx::Point(1, 1), 3.f, SkColorSetARGB(24, 32, 64, 128));
+ EXPECT_EQ(expected, blended);
+
blended = FilterOperation::Blend(&from, &to, 0.75);
expected = FilterOperation::CreateDropShadowFilter(
gfx::Point(2, 4), 5.f, SkColorSetARGB(42, 30, 61, 121));
diff --git a/cc/output/gl_renderer.cc b/cc/output/gl_renderer.cc
index 6e8bd752c6..35f8684914 100644
--- a/cc/output/gl_renderer.cc
+++ b/cc/output/gl_renderer.cc
@@ -38,6 +38,7 @@
#include "cc/trees/single_thread_proxy.h"
#include "gpu/GLES2/gl2extchromium.h"
#include "gpu/command_buffer/client/context_support.h"
+#include "gpu/command_buffer/common/gpu_memory_allocation.h"
#include "third_party/WebKit/public/platform/WebGraphicsContext3D.h"
#include "third_party/khronos/GLES2/gl2.h"
#include "third_party/khronos/GLES2/gl2ext.h"
@@ -278,12 +279,12 @@ void GLRenderer::SetVisible(bool visible) {
void GLRenderer::SendManagedMemoryStats(size_t bytes_visible,
size_t bytes_visible_and_nearby,
size_t bytes_allocated) {
- WebKit::WebGraphicsManagedMemoryStats stats;
- stats.bytesVisible = bytes_visible;
- stats.bytesVisibleAndNearby = bytes_visible_and_nearby;
- stats.bytesAllocated = bytes_allocated;
- stats.backbufferRequested = !is_backbuffer_discarded_;
- context_->sendManagedMemoryStatsCHROMIUM(&stats);
+ gpu::ManagedMemoryStats stats;
+ stats.bytes_required = bytes_visible;
+ stats.bytes_nice_to_have = bytes_visible_and_nearby;
+ stats.bytes_allocated = bytes_allocated;
+ stats.backbuffer_requested = !is_backbuffer_discarded_;
+ context_support_->SendManagedMemoryStats(stats);
}
void GLRenderer::ReleaseRenderPassTextures() { render_pass_textures_.clear(); }
diff --git a/cc/output/gl_renderer_unittest.cc b/cc/output/gl_renderer_unittest.cc
index 7f60c2d817..8b71ca403b 100644
--- a/cc/output/gl_renderer_unittest.cc
+++ b/cc/output/gl_renderer_unittest.cc
@@ -221,7 +221,7 @@ class GLRendererTest : public testing::Test {
CHECK(output_surface_->BindToClient(&output_surface_client_));
resource_provider_ =
- ResourceProvider::Create(output_surface_.get(), 0, false).Pass();
+ ResourceProvider::Create(output_surface_.get(), NULL, 0, false).Pass();
renderer_ = make_scoped_ptr(new FakeRendererGL(&renderer_client_,
&settings_,
output_surface_.get(),
@@ -312,8 +312,8 @@ class GLRendererShaderTest : public testing::Test {
new ShaderCreatorMockGraphicsContext())).Pass();
CHECK(output_surface_->BindToClient(&output_surface_client_));
- resource_provider_ = ResourceProvider::Create(
- output_surface_.get(), 0, false).Pass();
+ resource_provider_ =
+ ResourceProvider::Create(output_surface_.get(), NULL, 0, false).Pass();
renderer_.reset(new FakeRendererGL(&renderer_client_,
&settings_,
output_surface_.get(),
@@ -634,7 +634,7 @@ TEST(GLRendererTest2, InitializationDoesNotMakeSynchronousCalls) {
CHECK(output_surface->BindToClient(&output_surface_client));
scoped_ptr<ResourceProvider> resource_provider(
- ResourceProvider::Create(output_surface.get(), 0, false));
+ ResourceProvider::Create(output_surface.get(), NULL, 0, false));
LayerTreeSettings settings;
FakeRendererClient renderer_client;
@@ -679,7 +679,7 @@ TEST(GLRendererTest2, InitializationWithQuicklyLostContextDoesNotAssert) {
CHECK(output_surface->BindToClient(&output_surface_client));
scoped_ptr<ResourceProvider> resource_provider(
- ResourceProvider::Create(output_surface.get(), 0, false));
+ ResourceProvider::Create(output_surface.get(), NULL, 0, false));
LayerTreeSettings settings;
FakeRendererClient renderer_client;
@@ -714,7 +714,7 @@ TEST(GLRendererTest2, OpaqueBackground) {
CHECK(output_surface->BindToClient(&output_surface_client));
scoped_ptr<ResourceProvider> resource_provider(
- ResourceProvider::Create(output_surface.get(), 0, false));
+ ResourceProvider::Create(output_surface.get(), NULL, 0, false));
LayerTreeSettings settings;
FakeRendererClient renderer_client;
@@ -752,7 +752,7 @@ TEST(GLRendererTest2, TransparentBackground) {
CHECK(output_surface->BindToClient(&output_surface_client));
scoped_ptr<ResourceProvider> resource_provider(
- ResourceProvider::Create(output_surface.get(), 0, false));
+ ResourceProvider::Create(output_surface.get(), NULL, 0, false));
LayerTreeSettings settings;
FakeRendererClient renderer_client;
@@ -784,7 +784,7 @@ TEST(GLRendererTest2, OffscreenOutputSurface) {
CHECK(output_surface->BindToClient(&output_surface_client));
scoped_ptr<ResourceProvider> resource_provider(
- ResourceProvider::Create(output_surface.get(), 0, false));
+ ResourceProvider::Create(output_surface.get(), NULL, 0, false));
LayerTreeSettings settings;
FakeRendererClient renderer_client;
@@ -860,7 +860,7 @@ TEST(GLRendererTest2, VisibilityChangeIsLastCall) {
CHECK(output_surface->BindToClient(&output_surface_client));
scoped_ptr<ResourceProvider> resource_provider(
- ResourceProvider::Create(output_surface.get(), 0, false));
+ ResourceProvider::Create(output_surface.get(), NULL, 0, false));
LayerTreeSettings settings;
FakeRendererClient renderer_client;
@@ -920,7 +920,7 @@ TEST(GLRendererTest2, ActiveTextureState) {
CHECK(output_surface->BindToClient(&output_surface_client));
scoped_ptr<ResourceProvider> resource_provider(
- ResourceProvider::Create(output_surface.get(), 0, false));
+ ResourceProvider::Create(output_surface.get(), NULL, 0, false));
LayerTreeSettings settings;
FakeRendererClient renderer_client;
@@ -1007,7 +1007,7 @@ TEST(GLRendererTest2, ShouldClearRootRenderPass) {
CHECK(output_surface->BindToClient(&output_surface_client));
scoped_ptr<ResourceProvider> resource_provider(
- ResourceProvider::Create(output_surface.get(), 0, false));
+ ResourceProvider::Create(output_surface.get(), NULL, 0, false));
LayerTreeSettings settings;
settings.should_clear_root_render_pass = false;
@@ -1095,7 +1095,7 @@ TEST(GLRendererTest2, ScissorTestWhenClearing) {
CHECK(output_surface->BindToClient(&output_surface_client));
scoped_ptr<ResourceProvider> resource_provider(
- ResourceProvider::Create(output_surface.get(), 0, false));
+ ResourceProvider::Create(output_surface.get(), NULL, 0, false));
LayerTreeSettings settings;
FakeRendererClient renderer_client;
@@ -1181,7 +1181,7 @@ TEST(GLRendererTest2, NoDiscardOnPartialUpdates) {
output_surface->set_fixed_size(gfx::Size(100, 100));
scoped_ptr<ResourceProvider> resource_provider(
- ResourceProvider::Create(output_surface.get(), 0, false));
+ ResourceProvider::Create(output_surface.get(), NULL, 0, false));
LayerTreeSettings settings;
settings.partial_swap_enabled = true;
@@ -1360,7 +1360,7 @@ TEST(GLRendererTest2, ScissorAndViewportWithinNonreshapableSurface) {
CHECK(output_surface->BindToClient(&output_surface_client));
scoped_ptr<ResourceProvider> resource_provider(
- ResourceProvider::Create(output_surface.get(), 0, false));
+ ResourceProvider::Create(output_surface.get(), NULL, 0, false));
LayerTreeSettings settings;
FakeRendererClient renderer_client;
@@ -1714,7 +1714,7 @@ class MockOutputSurfaceTest : public testing::Test, public FakeRendererClient {
CHECK(output_surface_.BindToClient(&output_surface_client_));
resource_provider_ =
- ResourceProvider::Create(&output_surface_, 0, false).Pass();
+ ResourceProvider::Create(&output_surface_, NULL, 0, false).Pass();
renderer_.reset(new FakeRendererGL(
this, &settings_, &output_surface_, resource_provider_.get()));
diff --git a/cc/output/managed_memory_policy.cc b/cc/output/managed_memory_policy.cc
index 7e837662c2..ade2a27f9e 100644
--- a/cc/output/managed_memory_policy.cc
+++ b/cc/output/managed_memory_policy.cc
@@ -11,18 +11,29 @@ namespace cc {
const size_t ManagedMemoryPolicy::kDefaultNumResourcesLimit = 10 * 1000 * 1000;
+using gpu::MemoryAllocation;
+
ManagedMemoryPolicy::ManagedMemoryPolicy(size_t bytes_limit_when_visible)
: bytes_limit_when_visible(bytes_limit_when_visible),
- priority_cutoff_when_visible(CUTOFF_ALLOW_EVERYTHING),
+ priority_cutoff_when_visible(MemoryAllocation::CUTOFF_ALLOW_EVERYTHING),
bytes_limit_when_not_visible(0),
- priority_cutoff_when_not_visible(CUTOFF_ALLOW_NOTHING),
+ priority_cutoff_when_not_visible(MemoryAllocation::CUTOFF_ALLOW_NOTHING),
+ num_resources_limit(kDefaultNumResourcesLimit) {}
+
+ManagedMemoryPolicy::ManagedMemoryPolicy(
+ const gpu::MemoryAllocation& allocation)
+ : bytes_limit_when_visible(allocation.bytes_limit_when_visible),
+ priority_cutoff_when_visible(allocation.priority_cutoff_when_visible),
+ bytes_limit_when_not_visible(allocation.bytes_limit_when_not_visible),
+ priority_cutoff_when_not_visible(
+ allocation.priority_cutoff_when_not_visible),
num_resources_limit(kDefaultNumResourcesLimit) {}
ManagedMemoryPolicy::ManagedMemoryPolicy(
size_t bytes_limit_when_visible,
- PriorityCutoff priority_cutoff_when_visible,
+ MemoryAllocation::PriorityCutoff priority_cutoff_when_visible,
size_t bytes_limit_when_not_visible,
- PriorityCutoff priority_cutoff_when_not_visible,
+ MemoryAllocation::PriorityCutoff priority_cutoff_when_not_visible,
size_t num_resources_limit)
: bytes_limit_when_visible(bytes_limit_when_visible),
priority_cutoff_when_visible(priority_cutoff_when_visible),
@@ -44,15 +55,16 @@ bool ManagedMemoryPolicy::operator!=(const ManagedMemoryPolicy& other) const {
}
// static
-int ManagedMemoryPolicy::PriorityCutoffToValue(PriorityCutoff priority_cutoff) {
+int ManagedMemoryPolicy::PriorityCutoffToValue(
+ MemoryAllocation::PriorityCutoff priority_cutoff) {
switch (priority_cutoff) {
- case CUTOFF_ALLOW_NOTHING:
+ case MemoryAllocation::CUTOFF_ALLOW_NOTHING:
return PriorityCalculator::AllowNothingCutoff();
- case CUTOFF_ALLOW_REQUIRED_ONLY:
+ case MemoryAllocation::CUTOFF_ALLOW_REQUIRED_ONLY:
return PriorityCalculator::AllowVisibleOnlyCutoff();
- case CUTOFF_ALLOW_NICE_TO_HAVE:
+ case MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE:
return PriorityCalculator::AllowVisibleAndNearbyCutoff();
- case CUTOFF_ALLOW_EVERYTHING:
+ case MemoryAllocation::CUTOFF_ALLOW_EVERYTHING:
return PriorityCalculator::AllowEverythingCutoff();
}
NOTREACHED();
@@ -62,15 +74,15 @@ int ManagedMemoryPolicy::PriorityCutoffToValue(PriorityCutoff priority_cutoff) {
// static
TileMemoryLimitPolicy
ManagedMemoryPolicy::PriorityCutoffToTileMemoryLimitPolicy(
- PriorityCutoff priority_cutoff) {
+ gpu::MemoryAllocation::PriorityCutoff priority_cutoff) {
switch (priority_cutoff) {
- case CUTOFF_ALLOW_NOTHING:
+ case MemoryAllocation::CUTOFF_ALLOW_NOTHING:
return ALLOW_NOTHING;
- case CUTOFF_ALLOW_REQUIRED_ONLY:
+ case MemoryAllocation::CUTOFF_ALLOW_REQUIRED_ONLY:
return ALLOW_ABSOLUTE_MINIMUM;
- case CUTOFF_ALLOW_NICE_TO_HAVE:
+ case MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE:
return ALLOW_PREPAINT_ONLY;
- case CUTOFF_ALLOW_EVERYTHING:
+ case MemoryAllocation::CUTOFF_ALLOW_EVERYTHING:
return ALLOW_ANYTHING;
}
NOTREACHED();
diff --git a/cc/output/managed_memory_policy.h b/cc/output/managed_memory_policy.h
index 5a607a7a1f..1a234f7da5 100644
--- a/cc/output/managed_memory_policy.h
+++ b/cc/output/managed_memory_policy.h
@@ -8,36 +8,35 @@
#include "base/basictypes.h"
#include "cc/base/cc_export.h"
#include "cc/resources/tile_priority.h"
+#include "gpu/command_buffer/common/gpu_memory_allocation.h"
namespace cc {
struct CC_EXPORT ManagedMemoryPolicy {
- enum PriorityCutoff {
- CUTOFF_ALLOW_NOTHING,
- CUTOFF_ALLOW_REQUIRED_ONLY,
- CUTOFF_ALLOW_NICE_TO_HAVE,
- CUTOFF_ALLOW_EVERYTHING,
- };
static const size_t kDefaultNumResourcesLimit;
explicit ManagedMemoryPolicy(size_t bytes_limit_when_visible);
- ManagedMemoryPolicy(size_t bytes_limit_when_visible,
- PriorityCutoff priority_cutoff_when_visible,
- size_t bytes_limit_when_not_visible,
- PriorityCutoff priority_cutoff_when_not_visible,
- size_t num_resources_limit);
+ explicit ManagedMemoryPolicy(
+ const gpu::MemoryAllocation& allocation);
+ ManagedMemoryPolicy(
+ size_t bytes_limit_when_visible,
+ gpu::MemoryAllocation::PriorityCutoff priority_cutoff_when_visible,
+ size_t bytes_limit_when_not_visible,
+ gpu::MemoryAllocation::PriorityCutoff priority_cutoff_when_not_visible,
+ size_t num_resources_limit);
bool operator==(const ManagedMemoryPolicy&) const;
bool operator!=(const ManagedMemoryPolicy&) const;
size_t bytes_limit_when_visible;
- PriorityCutoff priority_cutoff_when_visible;
+ gpu::MemoryAllocation::PriorityCutoff priority_cutoff_when_visible;
size_t bytes_limit_when_not_visible;
- PriorityCutoff priority_cutoff_when_not_visible;
+ gpu::MemoryAllocation::PriorityCutoff priority_cutoff_when_not_visible;
size_t num_resources_limit;
- static int PriorityCutoffToValue(PriorityCutoff priority_cutoff);
+ static int PriorityCutoffToValue(
+ gpu::MemoryAllocation::PriorityCutoff priority_cutoff);
static TileMemoryLimitPolicy PriorityCutoffToTileMemoryLimitPolicy(
- PriorityCutoff priority_cutoff);
+ gpu::MemoryAllocation::PriorityCutoff priority_cutoff);
};
} // namespace cc
diff --git a/cc/output/output_surface.cc b/cc/output/output_surface.cc
index bcebeab429..002a44a37e 100644
--- a/cc/output/output_surface.cc
+++ b/cc/output/output_surface.cc
@@ -25,6 +25,7 @@
#include "third_party/WebKit/public/platform/WebGraphicsContext3D.h"
#include "third_party/khronos/GLES2/gl2.h"
#include "third_party/khronos/GLES2/gl2ext.h"
+#include "ui/gfx/frame_time.h"
#include "ui/gfx/rect.h"
#include "ui/gfx/size.h"
@@ -48,10 +49,10 @@ OutputSurface::OutputSurface(scoped_refptr<ContextProvider> context_provider)
device_scale_factor_(-1),
max_frames_pending_(0),
pending_swap_buffers_(0),
- needs_begin_frame_(false),
- client_ready_for_begin_frame_(true),
+ needs_begin_impl_frame_(false),
+ client_ready_for_begin_impl_frame_(true),
client_(NULL),
- check_for_retroactive_begin_frame_pending_(false),
+ check_for_retroactive_begin_impl_frame_pending_(false),
external_stencil_test_enabled_(false),
weak_ptr_factory_(this),
gpu_latency_history_(kGpuLatencyHistorySize) {}
@@ -64,10 +65,10 @@ OutputSurface::OutputSurface(
device_scale_factor_(-1),
max_frames_pending_(0),
pending_swap_buffers_(0),
- needs_begin_frame_(false),
- client_ready_for_begin_frame_(true),
+ needs_begin_impl_frame_(false),
+ client_ready_for_begin_impl_frame_(true),
client_(NULL),
- check_for_retroactive_begin_frame_pending_(false),
+ check_for_retroactive_begin_impl_frame_pending_(false),
external_stencil_test_enabled_(false),
weak_ptr_factory_(this),
gpu_latency_history_(kGpuLatencyHistorySize) {}
@@ -82,22 +83,25 @@ OutputSurface::OutputSurface(
device_scale_factor_(-1),
max_frames_pending_(0),
pending_swap_buffers_(0),
- needs_begin_frame_(false),
- client_ready_for_begin_frame_(true),
+ needs_begin_impl_frame_(false),
+ client_ready_for_begin_impl_frame_(true),
client_(NULL),
- check_for_retroactive_begin_frame_pending_(false),
+ check_for_retroactive_begin_impl_frame_pending_(false),
external_stencil_test_enabled_(false),
weak_ptr_factory_(this),
gpu_latency_history_(kGpuLatencyHistorySize) {}
-void OutputSurface::InitializeBeginFrameEmulation(
+void OutputSurface::InitializeBeginImplFrameEmulation(
base::SingleThreadTaskRunner* task_runner,
bool throttle_frame_production,
base::TimeDelta interval) {
if (throttle_frame_production) {
- frame_rate_controller_.reset(
- new FrameRateController(
- DelayBasedTimeSource::Create(interval, task_runner)));
+ scoped_refptr<DelayBasedTimeSource> time_source;
+ if (gfx::FrameTime::TimestampsAreHighRes())
+ time_source = DelayBasedTimeSourceHighRes::Create(interval, task_runner);
+ else
+ time_source = DelayBasedTimeSource::Create(interval, task_runner);
+ frame_rate_controller_.reset(new FrameRateController(time_source));
} else {
frame_rate_controller_.reset(new FrameRateController(task_runner));
}
@@ -133,9 +137,9 @@ void OutputSurface::FrameRateControllerTick(bool throttled,
const BeginFrameArgs& args) {
DCHECK(frame_rate_controller_);
if (throttled)
- skipped_begin_frame_args_ = args;
+ skipped_begin_impl_frame_args_ = args;
else
- BeginFrame(args);
+ BeginImplFrame(args);
}
// Forwarded to OutputSurfaceClient
@@ -144,62 +148,64 @@ void OutputSurface::SetNeedsRedrawRect(gfx::Rect damage_rect) {
client_->SetNeedsRedrawRect(damage_rect);
}
-void OutputSurface::SetNeedsBeginFrame(bool enable) {
- TRACE_EVENT1("cc", "OutputSurface::SetNeedsBeginFrame", "enable", enable);
- needs_begin_frame_ = enable;
- client_ready_for_begin_frame_ = true;
+void OutputSurface::SetNeedsBeginImplFrame(bool enable) {
+ TRACE_EVENT1("cc", "OutputSurface::SetNeedsBeginImplFrame", "enable", enable);
+ needs_begin_impl_frame_ = enable;
+ client_ready_for_begin_impl_frame_ = true;
if (frame_rate_controller_) {
BeginFrameArgs skipped = frame_rate_controller_->SetActive(enable);
if (skipped.IsValid())
- skipped_begin_frame_args_ = skipped;
+ skipped_begin_impl_frame_args_ = skipped;
}
- if (needs_begin_frame_)
- PostCheckForRetroactiveBeginFrame();
+ if (needs_begin_impl_frame_)
+ PostCheckForRetroactiveBeginImplFrame();
}
-void OutputSurface::BeginFrame(const BeginFrameArgs& args) {
- TRACE_EVENT2("cc", "OutputSurface::BeginFrame",
- "client_ready_for_begin_frame_", client_ready_for_begin_frame_,
+void OutputSurface::BeginImplFrame(const BeginFrameArgs& args) {
+ TRACE_EVENT2("cc", "OutputSurface::BeginImplFrame",
+ "client_ready_for_begin_impl_frame_",
+ client_ready_for_begin_impl_frame_,
"pending_swap_buffers_", pending_swap_buffers_);
- if (!needs_begin_frame_ || !client_ready_for_begin_frame_ ||
+ if (!needs_begin_impl_frame_ || !client_ready_for_begin_impl_frame_ ||
(pending_swap_buffers_ >= max_frames_pending_ &&
max_frames_pending_ > 0)) {
- skipped_begin_frame_args_ = args;
+ skipped_begin_impl_frame_args_ = args;
} else {
- client_ready_for_begin_frame_ = false;
- client_->BeginFrame(args);
- // args might be an alias for skipped_begin_frame_args_.
- // Do not reset it before calling BeginFrame!
- skipped_begin_frame_args_ = BeginFrameArgs();
+ client_ready_for_begin_impl_frame_ = false;
+ client_->BeginImplFrame(args);
+ // args might be an alias for skipped_begin_impl_frame_args_.
+ // Do not reset it before calling BeginImplFrame!
+ skipped_begin_impl_frame_args_ = BeginFrameArgs();
}
}
-base::TimeTicks OutputSurface::RetroactiveBeginFrameDeadline() {
+base::TimeTicks OutputSurface::RetroactiveBeginImplFrameDeadline() {
// TODO(brianderson): Remove the alternative deadline once we have better
// deadline estimations.
base::TimeTicks alternative_deadline =
- skipped_begin_frame_args_.frame_time +
+ skipped_begin_impl_frame_args_.frame_time +
BeginFrameArgs::DefaultRetroactiveBeginFramePeriod();
- return std::max(skipped_begin_frame_args_.deadline, alternative_deadline);
+ return std::max(skipped_begin_impl_frame_args_.deadline,
+ alternative_deadline);
}
-void OutputSurface::PostCheckForRetroactiveBeginFrame() {
- if (!skipped_begin_frame_args_.IsValid() ||
- check_for_retroactive_begin_frame_pending_)
+void OutputSurface::PostCheckForRetroactiveBeginImplFrame() {
+ if (!skipped_begin_impl_frame_args_.IsValid() ||
+ check_for_retroactive_begin_impl_frame_pending_)
return;
base::MessageLoop::current()->PostTask(
FROM_HERE,
- base::Bind(&OutputSurface::CheckForRetroactiveBeginFrame,
+ base::Bind(&OutputSurface::CheckForRetroactiveBeginImplFrame,
weak_ptr_factory_.GetWeakPtr()));
- check_for_retroactive_begin_frame_pending_ = true;
+ check_for_retroactive_begin_impl_frame_pending_ = true;
}
-void OutputSurface::CheckForRetroactiveBeginFrame() {
- TRACE_EVENT0("cc", "OutputSurface::CheckForRetroactiveBeginFrame");
- check_for_retroactive_begin_frame_pending_ = false;
- if (base::TimeTicks::Now() < RetroactiveBeginFrameDeadline())
- BeginFrame(skipped_begin_frame_args_);
+void OutputSurface::CheckForRetroactiveBeginImplFrame() {
+ TRACE_EVENT0("cc", "OutputSurface::CheckForRetroactiveBeginImplFrame");
+ check_for_retroactive_begin_impl_frame_pending_ = false;
+ if (gfx::FrameTime::Now() < RetroactiveBeginImplFrameDeadline())
+ BeginImplFrame(skipped_begin_impl_frame_args_);
}
void OutputSurface::DidSwapBuffers() {
@@ -208,7 +214,7 @@ void OutputSurface::DidSwapBuffers() {
"pending_swap_buffers_", pending_swap_buffers_);
if (frame_rate_controller_)
frame_rate_controller_->DidSwapBuffers();
- PostCheckForRetroactiveBeginFrame();
+ PostCheckForRetroactiveBeginImplFrame();
}
void OutputSurface::OnSwapBuffersComplete() {
@@ -218,7 +224,7 @@ void OutputSurface::OnSwapBuffersComplete() {
client_->OnSwapBuffersComplete();
if (frame_rate_controller_)
frame_rate_controller_->DidSwapBuffersComplete();
- PostCheckForRetroactiveBeginFrame();
+ PostCheckForRetroactiveBeginImplFrame();
}
void OutputSurface::ReclaimResources(const CompositorFrameAck* ack) {
@@ -227,9 +233,9 @@ void OutputSurface::ReclaimResources(const CompositorFrameAck* ack) {
void OutputSurface::DidLoseOutputSurface() {
TRACE_EVENT0("cc", "OutputSurface::DidLoseOutputSurface");
- client_ready_for_begin_frame_ = true;
+ client_ready_for_begin_impl_frame_ = true;
pending_swap_buffers_ = 0;
- skipped_begin_frame_args_ = BeginFrameArgs();
+ skipped_begin_impl_frame_args_ = BeginFrameArgs();
if (frame_rate_controller_)
frame_rate_controller_->SetActive(false);
pending_gpu_latency_query_ids_.clear();
diff --git a/cc/output/output_surface.h b/cc/output/output_surface.h
index 97e5744e8d..2887e80eb8 100644
--- a/cc/output/output_surface.h
+++ b/cc/output/output_surface.h
@@ -68,7 +68,7 @@ class CC_EXPORT OutputSurface : public FrameRateControllerClient {
int max_frames_pending;
bool deferred_gl_initialization;
bool draw_and_swap_full_viewport_every_frame;
- // This doesn't handle the <webview> case, but once BeginFrame is
+ // This doesn't handle the <webview> case, but once BeginImplFrame is
// supported natively, we shouldn't need adjust_deadline_for_parent.
bool adjust_deadline_for_parent;
// Whether this output surface renders to the default OpenGL zero
@@ -104,7 +104,7 @@ class CC_EXPORT OutputSurface : public FrameRateControllerClient {
// thread.
virtual bool BindToClient(OutputSurfaceClient* client);
- void InitializeBeginFrameEmulation(
+ void InitializeBeginImplFrameEmulation(
base::SingleThreadTaskRunner* task_runner,
bool throttle_frame_production,
base::TimeDelta interval);
@@ -128,10 +128,10 @@ class CC_EXPORT OutputSurface : public FrameRateControllerClient {
// processing should be stopped, or lowered in priority.
virtual void UpdateSmoothnessTakesPriority(bool prefer_smoothness) {}
- // Requests a BeginFrame notification from the output surface. The
+ // Requests a BeginImplFrame notification from the output surface. The
// notification will be delivered by calling
- // OutputSurfaceClient::BeginFrame until the callback is disabled.
- virtual void SetNeedsBeginFrame(bool enable);
+ // OutputSurfaceClient::BeginImplFrame until the callback is disabled.
+ virtual void SetNeedsBeginImplFrame(bool enable);
bool HasClient() { return !!client_; }
@@ -160,7 +160,7 @@ class CC_EXPORT OutputSurface : public FrameRateControllerClient {
float device_scale_factor_;
// The FrameRateController is deprecated.
- // Platforms should move to native BeginFrames instead.
+ // Platforms should move to native BeginImplFrames instead.
void OnVSyncParametersChanged(base::TimeTicks timebase,
base::TimeDelta interval);
virtual void FrameRateControllerTick(bool throttled,
@@ -168,17 +168,17 @@ class CC_EXPORT OutputSurface : public FrameRateControllerClient {
scoped_ptr<FrameRateController> frame_rate_controller_;
int max_frames_pending_;
int pending_swap_buffers_;
- bool needs_begin_frame_;
- bool client_ready_for_begin_frame_;
+ bool needs_begin_impl_frame_;
+ bool client_ready_for_begin_impl_frame_;
- // This stores a BeginFrame that we couldn't process immediately, but might
- // process retroactively in the near future.
- BeginFrameArgs skipped_begin_frame_args_;
+ // This stores a BeginImplFrame that we couldn't process immediately,
+ // but might process retroactively in the near future.
+ BeginFrameArgs skipped_begin_impl_frame_args_;
// Forwarded to OutputSurfaceClient but threaded through OutputSurface
// first so OutputSurface has a chance to update the FrameRateController
void SetNeedsRedrawRect(gfx::Rect damage_rect);
- void BeginFrame(const BeginFrameArgs& args);
+ void BeginImplFrame(const BeginFrameArgs& args);
void DidSwapBuffers();
void OnSwapBuffersComplete();
void ReclaimResources(const CompositorFrameAck* ack);
@@ -190,13 +190,12 @@ class CC_EXPORT OutputSurface : public FrameRateControllerClient {
bool valid_for_tile_management);
// virtual for testing.
- virtual base::TimeTicks RetroactiveBeginFrameDeadline();
- virtual void PostCheckForRetroactiveBeginFrame();
- void CheckForRetroactiveBeginFrame();
+ virtual base::TimeTicks RetroactiveBeginImplFrameDeadline();
+ virtual void PostCheckForRetroactiveBeginImplFrame();
+ void CheckForRetroactiveBeginImplFrame();
private:
OutputSurfaceClient* client_;
- friend class OutputSurfaceCallbacks;
void SetUpContext3d();
void ResetContext3d();
@@ -204,9 +203,9 @@ class CC_EXPORT OutputSurface : public FrameRateControllerClient {
bool discard_backbuffer_when_not_visible);
void UpdateAndMeasureGpuLatency();
- // check_for_retroactive_begin_frame_pending_ is used to avoid posting
- // redundant checks for a retroactive BeginFrame.
- bool check_for_retroactive_begin_frame_pending_;
+ // check_for_retroactive_begin_impl_frame_pending_ is used to avoid posting
+ // redundant checks for a retroactive BeginImplFrame.
+ bool check_for_retroactive_begin_impl_frame_pending_;
bool external_stencil_test_enabled_;
diff --git a/cc/output/output_surface_client.h b/cc/output/output_surface_client.h
index c0e2e4554b..192400c67d 100644
--- a/cc/output/output_surface_client.h
+++ b/cc/output/output_surface_client.h
@@ -31,7 +31,7 @@ class CC_EXPORT OutputSurfaceClient {
scoped_refptr<ContextProvider> offscreen_context_provider) = 0;
virtual void ReleaseGL() = 0;
virtual void SetNeedsRedrawRect(gfx::Rect damage_rect) = 0;
- virtual void BeginFrame(const BeginFrameArgs& args) = 0;
+ virtual void BeginImplFrame(const BeginFrameArgs& args) = 0;
virtual void OnSwapBuffersComplete() = 0;
virtual void ReclaimResources(const CompositorFrameAck* ack) = 0;
virtual void DidLoseOutputSurface() = 0;
diff --git a/cc/output/output_surface_unittest.cc b/cc/output/output_surface_unittest.cc
index 91e7c39d0b..1a1db29d88 100644
--- a/cc/output/output_surface_unittest.cc
+++ b/cc/output/output_surface_unittest.cc
@@ -15,6 +15,7 @@
#include "cc/test/scheduler_test_common.h"
#include "gpu/GLES2/gl2extchromium.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/gfx/frame_time.h"
namespace cc {
namespace {
@@ -23,19 +24,19 @@ class TestOutputSurface : public OutputSurface {
public:
explicit TestOutputSurface(scoped_refptr<ContextProvider> context_provider)
: OutputSurface(context_provider),
- retroactive_begin_frame_deadline_enabled_(false),
+ retroactive_begin_impl_frame_deadline_enabled_(false),
override_retroactive_period_(false) {}
explicit TestOutputSurface(
scoped_ptr<cc::SoftwareOutputDevice> software_device)
: OutputSurface(software_device.Pass()),
- retroactive_begin_frame_deadline_enabled_(false),
+ retroactive_begin_impl_frame_deadline_enabled_(false),
override_retroactive_period_(false) {}
TestOutputSurface(scoped_refptr<ContextProvider> context_provider,
scoped_ptr<cc::SoftwareOutputDevice> software_device)
: OutputSurface(context_provider, software_device.Pass()),
- retroactive_begin_frame_deadline_enabled_(false),
+ retroactive_begin_impl_frame_deadline_enabled_(false),
override_retroactive_period_(false) {}
bool InitializeNewContext3d(
@@ -51,8 +52,8 @@ class TestOutputSurface : public OutputSurface {
OnVSyncParametersChanged(timebase, interval);
}
- void BeginFrameForTesting() {
- OutputSurface::BeginFrame(BeginFrameArgs::CreateExpiredForTesting());
+ void BeginImplFrameForTesting() {
+ OutputSurface::BeginImplFrame(BeginFrameArgs::CreateExpiredForTesting());
}
void DidSwapBuffersForTesting() {
@@ -67,33 +68,34 @@ class TestOutputSurface : public OutputSurface {
OnSwapBuffersComplete();
}
- void EnableRetroactiveBeginFrameDeadline(bool enable,
- bool override_retroactive_period,
- base::TimeDelta period_override) {
- retroactive_begin_frame_deadline_enabled_ = enable;
+ void EnableRetroactiveBeginImplFrameDeadline(
+ bool enable,
+ bool override_retroactive_period,
+ base::TimeDelta period_override) {
+ retroactive_begin_impl_frame_deadline_enabled_ = enable;
override_retroactive_period_ = override_retroactive_period;
retroactive_period_override_ = period_override;
}
protected:
- virtual void PostCheckForRetroactiveBeginFrame() OVERRIDE {
+ virtual void PostCheckForRetroactiveBeginImplFrame() OVERRIDE {
// For testing purposes, we check immediately rather than posting a task.
- CheckForRetroactiveBeginFrame();
+ CheckForRetroactiveBeginImplFrame();
}
- virtual base::TimeTicks RetroactiveBeginFrameDeadline() OVERRIDE {
- if (retroactive_begin_frame_deadline_enabled_) {
+ virtual base::TimeTicks RetroactiveBeginImplFrameDeadline() OVERRIDE {
+ if (retroactive_begin_impl_frame_deadline_enabled_) {
if (override_retroactive_period_) {
- return skipped_begin_frame_args_.frame_time +
+ return skipped_begin_impl_frame_args_.frame_time +
retroactive_period_override_;
} else {
- return OutputSurface::RetroactiveBeginFrameDeadline();
+ return OutputSurface::RetroactiveBeginImplFrameDeadline();
}
}
return base::TimeTicks();
}
- bool retroactive_begin_frame_deadline_enabled_;
+ bool retroactive_begin_impl_frame_deadline_enabled_;
bool override_retroactive_period_;
base::TimeDelta retroactive_period_override_;
};
@@ -218,7 +220,7 @@ TEST_F(OutputSurfaceTestInitializeNewContext3d, ClientDeferredInitializeFails) {
InitializeNewContextExpectFail();
}
-TEST(OutputSurfaceTest, BeginFrameEmulation) {
+TEST(OutputSurfaceTest, BeginImplFrameEmulation) {
TestOutputSurface output_surface(TestContextProvider::Create());
EXPECT_FALSE(output_surface.HasClient());
@@ -227,84 +229,86 @@ TEST(OutputSurfaceTest, BeginFrameEmulation) {
EXPECT_TRUE(output_surface.HasClient());
EXPECT_FALSE(client.deferred_initialize_called());
- // Initialize BeginFrame emulation
+ // Initialize BeginImplFrame emulation
scoped_refptr<base::TestSimpleTaskRunner> task_runner =
new base::TestSimpleTaskRunner;
bool throttle_frame_production = true;
const base::TimeDelta display_refresh_interval =
BeginFrameArgs::DefaultInterval();
- output_surface.InitializeBeginFrameEmulation(
+ output_surface.InitializeBeginImplFrameEmulation(
task_runner.get(),
throttle_frame_production,
display_refresh_interval);
output_surface.SetMaxFramesPending(2);
- output_surface.EnableRetroactiveBeginFrameDeadline(
+ output_surface.EnableRetroactiveBeginImplFrameDeadline(
false, false, base::TimeDelta());
- // We should start off with 0 BeginFrames
- EXPECT_EQ(client.begin_frame_count(), 0);
+ // We should start off with 0 BeginImplFrames
+ EXPECT_EQ(client.begin_impl_frame_count(), 0);
EXPECT_EQ(output_surface.pending_swap_buffers(), 0);
- // We should not have a pending task until a BeginFrame has been requested.
+ // We should not have a pending task until a BeginImplFrame has been
+ // requested.
EXPECT_FALSE(task_runner->HasPendingTask());
- output_surface.SetNeedsBeginFrame(true);
+ output_surface.SetNeedsBeginImplFrame(true);
EXPECT_TRUE(task_runner->HasPendingTask());
- // BeginFrame should be called on the first tick.
+ // BeginImplFrame should be called on the first tick.
task_runner->RunPendingTasks();
- EXPECT_EQ(client.begin_frame_count(), 1);
+ EXPECT_EQ(client.begin_impl_frame_count(), 1);
EXPECT_EQ(output_surface.pending_swap_buffers(), 0);
- // BeginFrame should not be called when there is a pending BeginFrame.
+ // BeginImplFrame should not be called when there is a pending BeginImplFrame.
task_runner->RunPendingTasks();
- EXPECT_EQ(client.begin_frame_count(), 1);
+ EXPECT_EQ(client.begin_impl_frame_count(), 1);
EXPECT_EQ(output_surface.pending_swap_buffers(), 0);
- // SetNeedsBeginFrame should clear the pending BeginFrame after
+ // SetNeedsBeginImplFrame should clear the pending BeginImplFrame after
// a SwapBuffers.
output_surface.DidSwapBuffersForTesting();
- output_surface.SetNeedsBeginFrame(true);
- EXPECT_EQ(client.begin_frame_count(), 1);
+ output_surface.SetNeedsBeginImplFrame(true);
+ EXPECT_EQ(client.begin_impl_frame_count(), 1);
EXPECT_EQ(output_surface.pending_swap_buffers(), 1);
task_runner->RunPendingTasks();
- EXPECT_EQ(client.begin_frame_count(), 2);
+ EXPECT_EQ(client.begin_impl_frame_count(), 2);
EXPECT_EQ(output_surface.pending_swap_buffers(), 1);
- // BeginFrame should be throttled by pending swap buffers.
+ // BeginImplFrame should be throttled by pending swap buffers.
output_surface.DidSwapBuffersForTesting();
- output_surface.SetNeedsBeginFrame(true);
- EXPECT_EQ(client.begin_frame_count(), 2);
+ output_surface.SetNeedsBeginImplFrame(true);
+ EXPECT_EQ(client.begin_impl_frame_count(), 2);
EXPECT_EQ(output_surface.pending_swap_buffers(), 2);
task_runner->RunPendingTasks();
- EXPECT_EQ(client.begin_frame_count(), 2);
+ EXPECT_EQ(client.begin_impl_frame_count(), 2);
EXPECT_EQ(output_surface.pending_swap_buffers(), 2);
- // SwapAck should decrement pending swap buffers and unblock BeginFrame again.
+ // SwapAck should decrement pending swap buffers and unblock BeginImplFrame
+ // again.
output_surface.OnSwapBuffersCompleteForTesting();
- EXPECT_EQ(client.begin_frame_count(), 2);
+ EXPECT_EQ(client.begin_impl_frame_count(), 2);
EXPECT_EQ(output_surface.pending_swap_buffers(), 1);
task_runner->RunPendingTasks();
- EXPECT_EQ(client.begin_frame_count(), 3);
+ EXPECT_EQ(client.begin_impl_frame_count(), 3);
EXPECT_EQ(output_surface.pending_swap_buffers(), 1);
- // Calling SetNeedsBeginFrame again indicates a swap did not occur but
- // the client still wants another BeginFrame.
- output_surface.SetNeedsBeginFrame(true);
+ // Calling SetNeedsBeginImplFrame again indicates a swap did not occur but
+ // the client still wants another BeginImplFrame.
+ output_surface.SetNeedsBeginImplFrame(true);
task_runner->RunPendingTasks();
- EXPECT_EQ(client.begin_frame_count(), 4);
+ EXPECT_EQ(client.begin_impl_frame_count(), 4);
EXPECT_EQ(output_surface.pending_swap_buffers(), 1);
- // Disabling SetNeedsBeginFrame should prevent further BeginFrames.
- output_surface.SetNeedsBeginFrame(false);
+ // Disabling SetNeedsBeginImplFrame should prevent further BeginImplFrames.
+ output_surface.SetNeedsBeginImplFrame(false);
task_runner->RunPendingTasks();
EXPECT_FALSE(task_runner->HasPendingTask());
- EXPECT_EQ(client.begin_frame_count(), 4);
+ EXPECT_EQ(client.begin_impl_frame_count(), 4);
EXPECT_EQ(output_surface.pending_swap_buffers(), 1);
}
-TEST(OutputSurfaceTest, OptimisticAndRetroactiveBeginFrames) {
+TEST(OutputSurfaceTest, OptimisticAndRetroactiveBeginImplFrames) {
TestOutputSurface output_surface(TestContextProvider::Create());
EXPECT_FALSE(output_surface.HasClient());
@@ -314,47 +318,48 @@ TEST(OutputSurfaceTest, OptimisticAndRetroactiveBeginFrames) {
EXPECT_FALSE(client.deferred_initialize_called());
output_surface.SetMaxFramesPending(2);
- output_surface.EnableRetroactiveBeginFrameDeadline(
+ output_surface.EnableRetroactiveBeginImplFrameDeadline(
true, false, base::TimeDelta());
- // Optimistically injected BeginFrames should be throttled if
- // SetNeedsBeginFrame is false...
- output_surface.SetNeedsBeginFrame(false);
- output_surface.BeginFrameForTesting();
- EXPECT_EQ(client.begin_frame_count(), 0);
- // ...and retroactively triggered by a SetNeedsBeginFrame.
- output_surface.SetNeedsBeginFrame(true);
- EXPECT_EQ(client.begin_frame_count(), 1);
-
- // Optimistically injected BeginFrames should be throttled by pending
- // BeginFrames...
- output_surface.BeginFrameForTesting();
- EXPECT_EQ(client.begin_frame_count(), 1);
- // ...and retroactively triggered by a SetNeedsBeginFrame.
- output_surface.SetNeedsBeginFrame(true);
- EXPECT_EQ(client.begin_frame_count(), 2);
+ // Optimistically injected BeginImplFrames should be throttled if
+ // SetNeedsBeginImplFrame is false...
+ output_surface.SetNeedsBeginImplFrame(false);
+ output_surface.BeginImplFrameForTesting();
+ EXPECT_EQ(client.begin_impl_frame_count(), 0);
+ // ...and retroactively triggered by a SetNeedsBeginImplFrame.
+ output_surface.SetNeedsBeginImplFrame(true);
+ EXPECT_EQ(client.begin_impl_frame_count(), 1);
+
+ // Optimistically injected BeginImplFrames should be throttled by pending
+ // BeginImplFrames...
+ output_surface.BeginImplFrameForTesting();
+ EXPECT_EQ(client.begin_impl_frame_count(), 1);
+ // ...and retroactively triggered by a SetNeedsBeginImplFrame.
+ output_surface.SetNeedsBeginImplFrame(true);
+ EXPECT_EQ(client.begin_impl_frame_count(), 2);
// ...or retroactively triggered by a Swap.
- output_surface.BeginFrameForTesting();
- EXPECT_EQ(client.begin_frame_count(), 2);
+ output_surface.BeginImplFrameForTesting();
+ EXPECT_EQ(client.begin_impl_frame_count(), 2);
output_surface.DidSwapBuffersForTesting();
- output_surface.SetNeedsBeginFrame(true);
- EXPECT_EQ(client.begin_frame_count(), 3);
+ output_surface.SetNeedsBeginImplFrame(true);
+ EXPECT_EQ(client.begin_impl_frame_count(), 3);
EXPECT_EQ(output_surface.pending_swap_buffers(), 1);
- // Optimistically injected BeginFrames should be by throttled by pending
+ // Optimistically injected BeginImplFrames should be by throttled by pending
// swap buffers...
output_surface.DidSwapBuffersForTesting();
- output_surface.SetNeedsBeginFrame(true);
- EXPECT_EQ(client.begin_frame_count(), 3);
+ output_surface.SetNeedsBeginImplFrame(true);
+ EXPECT_EQ(client.begin_impl_frame_count(), 3);
EXPECT_EQ(output_surface.pending_swap_buffers(), 2);
- output_surface.BeginFrameForTesting();
- EXPECT_EQ(client.begin_frame_count(), 3);
+ output_surface.BeginImplFrameForTesting();
+ EXPECT_EQ(client.begin_impl_frame_count(), 3);
// ...and retroactively triggered by OnSwapBuffersComplete
output_surface.OnSwapBuffersCompleteForTesting();
- EXPECT_EQ(client.begin_frame_count(), 4);
+ EXPECT_EQ(client.begin_impl_frame_count(), 4);
}
-TEST(OutputSurfaceTest, RetroactiveBeginFrameDoesNotDoubleTickWhenEmulating) {
+TEST(OutputSurfaceTest,
+ RetroactiveBeginImplFrameDoesNotDoubleTickWhenEmulating) {
scoped_refptr<TestContextProvider> context_provider =
TestContextProvider::Create();
@@ -368,13 +373,13 @@ TEST(OutputSurfaceTest, RetroactiveBeginFrameDoesNotDoubleTickWhenEmulating) {
base::TimeDelta big_interval = base::TimeDelta::FromSeconds(10);
- // Initialize BeginFrame emulation
+ // Initialize BeginImplFrame emulation
scoped_refptr<base::TestSimpleTaskRunner> task_runner =
new base::TestSimpleTaskRunner;
bool throttle_frame_production = true;
const base::TimeDelta display_refresh_interval = big_interval;
- output_surface.InitializeBeginFrameEmulation(
+ output_surface.InitializeBeginImplFrameEmulation(
task_runner.get(),
throttle_frame_production,
display_refresh_interval);
@@ -382,31 +387,34 @@ TEST(OutputSurfaceTest, RetroactiveBeginFrameDoesNotDoubleTickWhenEmulating) {
// We need to subtract an epsilon from Now() because some platforms have
// a slow clock.
output_surface.OnVSyncParametersChangedForTesting(
- base::TimeTicks::Now() - base::TimeDelta::FromSeconds(1), big_interval);
+ gfx::FrameTime::Now() - base::TimeDelta::FromSeconds(1), big_interval);
output_surface.SetMaxFramesPending(2);
- output_surface.EnableRetroactiveBeginFrameDeadline(true, true, big_interval);
+ output_surface.EnableRetroactiveBeginImplFrameDeadline(
+ true, true, big_interval);
- // We should start off with 0 BeginFrames
- EXPECT_EQ(client.begin_frame_count(), 0);
+ // We should start off with 0 BeginImplFrames
+ EXPECT_EQ(client.begin_impl_frame_count(), 0);
EXPECT_EQ(output_surface.pending_swap_buffers(), 0);
- // The first SetNeedsBeginFrame(true) should start a retroactive BeginFrame.
+ // The first SetNeedsBeginImplFrame(true) should start a retroactive
+ // BeginImplFrame.
EXPECT_FALSE(task_runner->HasPendingTask());
- output_surface.SetNeedsBeginFrame(true);
+ output_surface.SetNeedsBeginImplFrame(true);
EXPECT_TRUE(task_runner->HasPendingTask());
EXPECT_GT(task_runner->NextPendingTaskDelay(), big_interval / 2);
- EXPECT_EQ(client.begin_frame_count(), 1);
+ EXPECT_EQ(client.begin_impl_frame_count(), 1);
- output_surface.SetNeedsBeginFrame(false);
+ output_surface.SetNeedsBeginImplFrame(false);
EXPECT_TRUE(task_runner->HasPendingTask());
- EXPECT_EQ(client.begin_frame_count(), 1);
+ EXPECT_EQ(client.begin_impl_frame_count(), 1);
- // The second SetNeedBeginFrame(true) should not retroactively start a
- // BeginFrame if the timestamp would be the same as the previous BeginFrame.
- output_surface.SetNeedsBeginFrame(true);
+ // The second SetNeedBeginImplFrame(true) should not retroactively start a
+ // BeginImplFrame if the timestamp would be the same as the previous
+ // BeginImplFrame.
+ output_surface.SetNeedsBeginImplFrame(true);
EXPECT_TRUE(task_runner->HasPendingTask());
- EXPECT_EQ(client.begin_frame_count(), 1);
+ EXPECT_EQ(client.begin_impl_frame_count(), 1);
}
TEST(OutputSurfaceTest, MemoryAllocation) {
@@ -421,20 +429,20 @@ TEST(OutputSurfaceTest, MemoryAllocation) {
ManagedMemoryPolicy policy(0);
policy.bytes_limit_when_visible = 1234;
policy.priority_cutoff_when_visible =
- ManagedMemoryPolicy::CUTOFF_ALLOW_REQUIRED_ONLY;
+ gpu::MemoryAllocation::CUTOFF_ALLOW_REQUIRED_ONLY;
policy.bytes_limit_when_not_visible = 4567;
policy.priority_cutoff_when_not_visible =
- ManagedMemoryPolicy::CUTOFF_ALLOW_NOTHING;
+ gpu::MemoryAllocation::CUTOFF_ALLOW_NOTHING;
bool discard_backbuffer_when_not_visible = false;
context_provider->SetMemoryAllocation(policy,
discard_backbuffer_when_not_visible);
EXPECT_EQ(1234u, client.memory_policy().bytes_limit_when_visible);
- EXPECT_EQ(ManagedMemoryPolicy::CUTOFF_ALLOW_REQUIRED_ONLY,
+ EXPECT_EQ(gpu::MemoryAllocation::CUTOFF_ALLOW_REQUIRED_ONLY,
client.memory_policy().priority_cutoff_when_visible);
EXPECT_EQ(4567u, client.memory_policy().bytes_limit_when_not_visible);
- EXPECT_EQ(ManagedMemoryPolicy::CUTOFF_ALLOW_NOTHING,
+ EXPECT_EQ(gpu::MemoryAllocation::CUTOFF_ALLOW_NOTHING,
client.memory_policy().priority_cutoff_when_not_visible);
EXPECT_FALSE(client.discard_backbuffer_when_not_visible());
@@ -444,14 +452,14 @@ TEST(OutputSurfaceTest, MemoryAllocation) {
EXPECT_TRUE(client.discard_backbuffer_when_not_visible());
policy.priority_cutoff_when_visible =
- ManagedMemoryPolicy::CUTOFF_ALLOW_EVERYTHING;
+ gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING;
policy.priority_cutoff_when_not_visible =
- ManagedMemoryPolicy::CUTOFF_ALLOW_NICE_TO_HAVE;
+ gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE;
context_provider->SetMemoryAllocation(policy,
discard_backbuffer_when_not_visible);
- EXPECT_EQ(ManagedMemoryPolicy::CUTOFF_ALLOW_EVERYTHING,
+ EXPECT_EQ(gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING,
client.memory_policy().priority_cutoff_when_visible);
- EXPECT_EQ(ManagedMemoryPolicy::CUTOFF_ALLOW_NICE_TO_HAVE,
+ EXPECT_EQ(gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE,
client.memory_policy().priority_cutoff_when_not_visible);
// 0 bytes limit should be ignored.
diff --git a/cc/output/software_renderer_unittest.cc b/cc/output/software_renderer_unittest.cc
index f88a9ee082..450d1fe32f 100644
--- a/cc/output/software_renderer_unittest.cc
+++ b/cc/output/software_renderer_unittest.cc
@@ -34,7 +34,7 @@ class SoftwareRendererTest : public testing::Test, public RendererClient {
CHECK(output_surface_->BindToClient(&output_surface_client_));
resource_provider_ =
- ResourceProvider::Create(output_surface_.get(), 0, false);
+ ResourceProvider::Create(output_surface_.get(), NULL, 0, false);
renderer_ = SoftwareRenderer::Create(
this, &settings_, output_surface_.get(), resource_provider());
}
diff --git a/cc/quads/render_pass.cc b/cc/quads/render_pass.cc
index e61a463f33..6d6c430be3 100644
--- a/cc/quads/render_pass.cc
+++ b/cc/quads/render_pass.cc
@@ -65,10 +65,11 @@ void RenderPass::CopyAll(const ScopedPtrVector<RenderPass>& in,
source->shared_quad_state_list[i]->Copy());
}
for (size_t i = 0, sqs_i = 0; i < source->quad_list.size(); ++i) {
- if (source->quad_list[i]->shared_quad_state !=
- source->shared_quad_state_list[sqs_i])
+ while (source->quad_list[i]->shared_quad_state !=
+ source->shared_quad_state_list[sqs_i]) {
++sqs_i;
- DCHECK(sqs_i < source->shared_quad_state_list.size());
+ DCHECK_LT(sqs_i, source->shared_quad_state_list.size());
+ }
DCHECK(source->quad_list[i]->shared_quad_state ==
source->shared_quad_state_list[sqs_i]);
diff --git a/cc/quads/render_pass_unittest.cc b/cc/quads/render_pass_unittest.cc
index 259ecad746..394a3ec56a 100644
--- a/cc/quads/render_pass_unittest.cc
+++ b/cc/quads/render_pass_unittest.cc
@@ -33,6 +33,35 @@ struct RenderPassSize {
ScopedPtrVector<CopyOutputRequest> copy_callbacks;
};
+static void CompareRenderPassLists(const RenderPassList& expected_list,
+ const RenderPassList& actual_list) {
+ EXPECT_EQ(expected_list.size(), actual_list.size());
+ for (size_t i = 0; i < actual_list.size(); ++i) {
+ RenderPass* expected = expected_list[i];
+ RenderPass* actual = actual_list[i];
+
+ EXPECT_EQ(expected->id, actual->id);
+ EXPECT_RECT_EQ(expected->output_rect, actual->output_rect);
+ EXPECT_EQ(expected->transform_to_root_target,
+ actual->transform_to_root_target);
+ EXPECT_RECT_EQ(expected->damage_rect, actual->damage_rect);
+ EXPECT_EQ(expected->has_transparent_background,
+ actual->has_transparent_background);
+
+ EXPECT_EQ(expected->shared_quad_state_list.size(),
+ actual->shared_quad_state_list.size());
+ EXPECT_EQ(expected->quad_list.size(), actual->quad_list.size());
+
+ for (size_t i = 0; i < expected->quad_list.size(); ++i) {
+ EXPECT_EQ(expected->quad_list[i]->rect.ToString(),
+ actual->quad_list[i]->rect.ToString());
+ EXPECT_EQ(
+ expected->quad_list[i]->shared_quad_state->content_bounds.ToString(),
+ actual->quad_list[i]->shared_quad_state->content_bounds.ToString());
+ }
+ }
+}
+
TEST(RenderPassTest, CopyShouldBeIdenticalExceptIdAndQuads) {
RenderPass::Id id(3, 2);
gfx::Rect output_rect(45, 22, 120, 13);
@@ -177,30 +206,69 @@ TEST(RenderPassTest, CopyAllShouldBeIdentical) {
RenderPassList copy_list;
RenderPass::CopyAll(pass_list, &copy_list);
- EXPECT_EQ(pass_list.size(), copy_list.size());
- for (size_t i = 0; i < copy_list.size(); ++i) {
- RenderPass* pass = pass_list[i];
- RenderPass* copy = copy_list[i];
-
- EXPECT_EQ(pass->id, copy->id);
- EXPECT_RECT_EQ(pass->output_rect, copy->output_rect);
- EXPECT_EQ(pass->transform_to_root_target, copy->transform_to_root_target);
- EXPECT_RECT_EQ(pass->damage_rect, copy->damage_rect);
- EXPECT_EQ(pass->has_transparent_background,
- copy->has_transparent_background);
-
- EXPECT_EQ(pass->shared_quad_state_list.size(),
- copy->shared_quad_state_list.size());
- EXPECT_EQ(pass->quad_list.size(), copy->quad_list.size());
-
- for (size_t i = 0; i < pass->quad_list.size(); ++i) {
- EXPECT_EQ(pass->quad_list[i]->rect.ToString(),
- copy->quad_list[i]->rect.ToString());
- EXPECT_EQ(
- pass->quad_list[i]->shared_quad_state->content_bounds.ToString(),
- copy->quad_list[i]->shared_quad_state->content_bounds.ToString());
- }
- }
+ CompareRenderPassLists(pass_list, copy_list);
+}
+
+TEST(RenderPassTest, CopyAllWithCulledQuads) {
+ RenderPassList pass_list;
+
+ RenderPass::Id id(3, 2);
+ gfx::Rect output_rect(45, 22, 120, 13);
+ gfx::Transform transform_to_root =
+ gfx::Transform(1.0, 0.5, 0.5, -0.5, -1.0, 0.0);
+ gfx::Rect damage_rect(56, 123, 19, 43);
+ bool has_transparent_background = true;
+
+ scoped_ptr<TestRenderPass> pass = TestRenderPass::Create();
+ pass->SetAll(id,
+ output_rect,
+ damage_rect,
+ transform_to_root,
+ has_transparent_background);
+
+ // A shared state with a quad.
+ scoped_ptr<SharedQuadState> shared_state1 = SharedQuadState::Create();
+ shared_state1->SetAll(
+ gfx::Transform(), gfx::Size(1, 1), gfx::Rect(), gfx::Rect(), false, 1);
+ pass->AppendSharedQuadState(shared_state1.Pass());
+
+ scoped_ptr<CheckerboardDrawQuad> checkerboard_quad1 =
+ CheckerboardDrawQuad::Create();
+ checkerboard_quad1->SetNew(
+ pass->shared_quad_state_list.back(), gfx::Rect(1, 1, 1, 1), SkColor());
+ pass->quad_list.push_back(checkerboard_quad1.PassAs<DrawQuad>());
+
+ // A shared state with no quads, they were culled.
+ scoped_ptr<SharedQuadState> shared_state2 = SharedQuadState::Create();
+ shared_state2->SetAll(
+ gfx::Transform(), gfx::Size(2, 2), gfx::Rect(), gfx::Rect(), false, 1);
+ pass->AppendSharedQuadState(shared_state2.Pass());
+
+ // A second shared state with no quads.
+ scoped_ptr<SharedQuadState> shared_state3 = SharedQuadState::Create();
+ shared_state3->SetAll(
+ gfx::Transform(), gfx::Size(2, 2), gfx::Rect(), gfx::Rect(), false, 1);
+ pass->AppendSharedQuadState(shared_state3.Pass());
+
+ // A last shared state with a quad again.
+ scoped_ptr<SharedQuadState> shared_state4 = SharedQuadState::Create();
+ shared_state4->SetAll(
+ gfx::Transform(), gfx::Size(2, 2), gfx::Rect(), gfx::Rect(), false, 1);
+ pass->AppendSharedQuadState(shared_state4.Pass());
+
+ scoped_ptr<CheckerboardDrawQuad> checkerboard_quad2 =
+ CheckerboardDrawQuad::Create();
+ checkerboard_quad2->SetNew(
+ pass->shared_quad_state_list.back(), gfx::Rect(3, 3, 3, 3), SkColor());
+ pass->quad_list.push_back(checkerboard_quad2.PassAs<DrawQuad>());
+
+ pass_list.push_back(pass.PassAs<RenderPass>());
+
+ // Make a copy with CopyAll().
+ RenderPassList copy_list;
+ RenderPass::CopyAll(pass_list, &copy_list);
+
+ CompareRenderPassLists(pass_list, copy_list);
}
} // namespace
diff --git a/cc/resources/bitmap_skpicture_content_layer_updater.cc b/cc/resources/bitmap_skpicture_content_layer_updater.cc
index 6b6cd9f439..cc839a60ee 100644
--- a/cc/resources/bitmap_skpicture_content_layer_updater.cc
+++ b/cc/resources/bitmap_skpicture_content_layer_updater.cc
@@ -25,9 +25,9 @@ void BitmapSkPictureContentLayerUpdater::Resource::Update(
gfx::Vector2d dest_offset,
bool partial_update) {
bitmap_.setConfig(
- SkBitmap::kARGB_8888_Config, source_rect.width(), source_rect.height());
+ SkBitmap::kARGB_8888_Config, source_rect.width(), source_rect.height(), 0,
+ updater_->layer_is_opaque() ? kOpaque_SkAlphaType : kPremul_SkAlphaType);
bitmap_.allocPixels();
- bitmap_.setIsOpaque(updater_->layer_is_opaque());
SkBitmapDevice device(bitmap_);
SkCanvas canvas(&device);
updater_->PaintContentsRect(&canvas, source_rect);
diff --git a/cc/resources/image_raster_worker_pool.cc b/cc/resources/image_raster_worker_pool.cc
index 30add2ad2e..e665837a81 100644
--- a/cc/resources/image_raster_worker_pool.cc
+++ b/cc/resources/image_raster_worker_pool.cc
@@ -149,7 +149,7 @@ void ImageRasterWorkerPool::ScheduleTasks(RasterTask::Queue* queue) {
set_raster_required_for_activation_finished_task(
new_raster_required_for_activation_finished_task);
- TRACE_EVENT_ASYNC_STEP1(
+ TRACE_EVENT_ASYNC_STEP_INTO1(
"cc", "ScheduledTasks", this, "rasterizing",
"state", TracedValue::FromValue(StateAsValue().release()));
}
@@ -169,7 +169,7 @@ void ImageRasterWorkerPool::OnRasterTasksFinished() {
void ImageRasterWorkerPool::OnRasterTasksRequiredForActivationFinished() {
DCHECK(raster_tasks_required_for_activation_pending_);
raster_tasks_required_for_activation_pending_ = false;
- TRACE_EVENT_ASYNC_STEP1(
+ TRACE_EVENT_ASYNC_STEP_INTO1(
"cc", "ScheduledTasks", this, "rasterizing",
"state", TracedValue::FromValue(StateAsValue().release()));
client()->DidFinishRunningTasksRequiredForActivation();
diff --git a/cc/resources/picture.cc b/cc/resources/picture.cc
index 8083050aca..7e278f8de5 100644
--- a/cc/resources/picture.cc
+++ b/cc/resources/picture.cc
@@ -86,7 +86,8 @@ scoped_refptr<Picture> Picture::Create(gfx::Rect layer_rect) {
}
Picture::Picture(gfx::Rect layer_rect)
- : layer_rect_(layer_rect) {
+ : layer_rect_(layer_rect),
+ cell_size_(layer_rect.size()) {
// Instead of recording a trace event for object creation here, we wait for
// the picture to be recorded in Picture::Record.
}
@@ -155,7 +156,8 @@ Picture::Picture(SkPicture* picture,
gfx::Rect opaque_rect) :
layer_rect_(layer_rect),
opaque_rect_(opaque_rect),
- picture_(skia::AdoptRef(picture)) {
+ picture_(skia::AdoptRef(picture)),
+ cell_size_(layer_rect.size()) {
}
Picture::Picture(const skia::RefPtr<SkPicture>& picture,
@@ -165,7 +167,8 @@ Picture::Picture(const skia::RefPtr<SkPicture>& picture,
layer_rect_(layer_rect),
opaque_rect_(opaque_rect),
picture_(picture),
- pixel_refs_(pixel_refs) {
+ pixel_refs_(pixel_refs),
+ cell_size_(layer_rect.size()) {
}
Picture::~Picture() {
@@ -294,16 +297,21 @@ void Picture::GatherPixelRefs(
int Picture::Raster(
SkCanvas* canvas,
SkDrawPictureCallback* callback,
- gfx::Rect content_rect,
+ const Region& negated_content_region,
float contents_scale) {
TRACE_EVENT_BEGIN1(
- "cc", "Picture::Raster",
- "data", AsTraceableRasterData(content_rect, contents_scale));
+ "cc",
+ "Picture::Raster",
+ "data",
+ AsTraceableRasterData(contents_scale));
DCHECK(picture_);
canvas->save();
- canvas->clipRect(gfx::RectToSkRect(content_rect));
+
+ for (Region::Iterator it(negated_content_region); it.has_rect(); it.next())
+ canvas->clipRect(gfx::RectToSkRect(it.rect()), SkRegion::kDifference_Op);
+
canvas->scale(contents_scale, contents_scale);
canvas->translate(layer_rect_.x(), layer_rect_.y());
picture_->draw(canvas, callback);
@@ -382,8 +390,9 @@ Picture::PixelRefIterator::PixelRefIterator(
current_index_(0) {
gfx::Rect layer_rect = picture->layer_rect_;
gfx::Size cell_size = picture->cell_size_;
+ DCHECK(!cell_size.IsEmpty());
- // Early out if the query rect doesn't intersect this picture
+ // Early out if the query rect doesn't intersect this picture.
if (!query_rect.Intersects(layer_rect)) {
min_point_ = gfx::Point(0, 0);
max_point_ = gfx::Point(0, 0);
@@ -460,14 +469,10 @@ Picture::PixelRefIterator& Picture::PixelRefIterator::operator++() {
}
scoped_refptr<base::debug::ConvertableToTraceFormat>
- Picture::AsTraceableRasterData(gfx::Rect rect, float scale) const {
+ Picture::AsTraceableRasterData(float scale) const {
scoped_ptr<base::DictionaryValue> raster_data(new base::DictionaryValue());
raster_data->Set("picture_id", TracedValue::CreateIDRef(this).release());
raster_data->SetDouble("scale", scale);
- raster_data->SetDouble("rect_x", rect.x());
- raster_data->SetDouble("rect_y", rect.y());
- raster_data->SetDouble("rect_width", rect.width());
- raster_data->SetDouble("rect_height", rect.height());
return TracedValue::FromValue(raster_data.release());
}
diff --git a/cc/resources/picture.h b/cc/resources/picture.h
index 8210e86318..4eb238ab63 100644
--- a/cc/resources/picture.h
+++ b/cc/resources/picture.h
@@ -17,6 +17,7 @@
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "cc/base/cc_export.h"
+#include "cc/base/region.h"
#include "skia/ext/lazy_pixel_ref.h"
#include "skia/ext/refptr.h"
#include "third_party/skia/include/core/SkPixelRef.h"
@@ -67,10 +68,11 @@ class CC_EXPORT Picture
// Has Record() been called yet?
bool HasRecording() const { return picture_.get() != NULL; }
- // Apply this contents scale and raster the content rect into the canvas.
+ // Apply this scale and raster the negated region into the canvas. See comment
+ // in PicturePileImpl::RasterCommon for explanation on negated content region.
int Raster(SkCanvas* canvas,
SkDrawPictureCallback* callback,
- gfx::Rect content_rect,
+ const Region& negated_content_region,
float contents_scale);
// Draw the picture directly into the given canvas, without applying any
@@ -142,7 +144,7 @@ class CC_EXPORT Picture
gfx::Size cell_size_;
scoped_refptr<base::debug::ConvertableToTraceFormat>
- AsTraceableRasterData(gfx::Rect rect, float scale) const;
+ AsTraceableRasterData(float scale) const;
scoped_refptr<base::debug::ConvertableToTraceFormat>
AsTraceableRecordData() const;
diff --git a/cc/resources/picture_layer_tiling_perftest.cc b/cc/resources/picture_layer_tiling_perftest.cc
index 655603d2e8..7a9b8dff4b 100644
--- a/cc/resources/picture_layer_tiling_perftest.cc
+++ b/cc/resources/picture_layer_tiling_perftest.cc
@@ -153,7 +153,12 @@ TEST_F(PictureLayerTilingPerfTest, Invalidate) {
RunInvalidateTest("50x50", full_region);
}
+#if defined(OS_ANDROID)
+// TODO(vmpstr): Investigate why this is noisy (crbug.com/310220).
+TEST_F(PictureLayerTilingPerfTest, DISABLED_UpdateTilePriorities) {
+#else
TEST_F(PictureLayerTilingPerfTest, UpdateTilePriorities) {
+#endif // defined(OS_ANDROID)
gfx::Transform transform;
RunUpdateTilePrioritiesStationaryTest("no_transform", transform);
RunUpdateTilePrioritiesScrollingTest("no_transform", transform);
diff --git a/cc/resources/picture_layer_tiling_set_unittest.cc b/cc/resources/picture_layer_tiling_set_unittest.cc
index 231e378fbd..c0d6f0d2ef 100644
--- a/cc/resources/picture_layer_tiling_set_unittest.cc
+++ b/cc/resources/picture_layer_tiling_set_unittest.cc
@@ -66,7 +66,7 @@ class PictureLayerTilingSetTestWithResources : public testing::Test {
CHECK(output_surface->BindToClient(&output_surface_client));
scoped_ptr<ResourceProvider> resource_provider =
- ResourceProvider::Create(output_surface.get(), 0, false);
+ ResourceProvider::Create(output_surface.get(), NULL, 0, false);
FakePictureLayerTilingClient client;
client.SetTileSize(gfx::Size(256, 256));
diff --git a/cc/resources/picture_pile.cc b/cc/resources/picture_pile.cc
index d1cb0e17e4..9f485b8296 100644
--- a/cc/resources/picture_pile.cc
+++ b/cc/resources/picture_pile.cc
@@ -13,12 +13,6 @@
#include "cc/resources/picture_pile_impl.h"
namespace {
-// Maximum number of pictures that can overlap before we collapse them into
-// a larger one.
-const size_t kMaxOverlapping = 2;
-// Maximum percentage area of the base picture another picture in the picture
-// list can be. If higher, we destroy the list and recreate from scratch.
-const float kResetThreshold = 0.7f;
// Layout pixel buffer around the visible layer rect to record. Any base
// picture that intersects the visible layer rect expanded by this distance
// will be recorded.
@@ -49,138 +43,74 @@ bool PicturePile::Update(
-kPixelDistanceToRecord,
-kPixelDistanceToRecord,
-kPixelDistanceToRecord);
- bool modified_pile = false;
+
+ bool invalidated = false;
for (Region::Iterator i(invalidation); i.has_rect(); i.next()) {
gfx::Rect invalidation = i.rect();
// Split this inflated invalidation across tile boundaries and apply it
// to all tiles that it touches.
for (TilingData::Iterator iter(&tiling_, invalidation);
iter; ++iter) {
- gfx::Rect tile =
- tiling_.TileBoundsWithBorder(iter.index_x(), iter.index_y());
- if (!tile.Intersects(interest_rect)) {
- // This invalidation touches a tile outside the interest rect, so
- // just remove the entire picture list.
- picture_list_map_.erase(iter.index());
- modified_pile = true;
- continue;
- }
+ const PictureMapKey& key = iter.index();
- gfx::Rect tile_invalidation = gfx::IntersectRects(invalidation, tile);
- if (tile_invalidation.IsEmpty())
- continue;
- PictureListMap::iterator find = picture_list_map_.find(iter.index());
- if (find == picture_list_map_.end())
+ PictureMap::iterator picture_it = picture_map_.find(key);
+ if (picture_it == picture_map_.end())
continue;
- PictureList& pic_list = find->second;
- // Leave empty pic_lists empty in case there are multiple invalidations.
- if (!pic_list.empty()) {
- // Inflate all recordings from invalidations with a margin so that when
- // scaled down to at least min_contents_scale, any final pixel touched
- // by an invalidation can be fully rasterized by this picture.
- tile_invalidation.Inset(-buffer_pixels(), -buffer_pixels());
-
- DCHECK_GE(tile_invalidation.width(), buffer_pixels() * 2 + 1);
- DCHECK_GE(tile_invalidation.height(), buffer_pixels() * 2 + 1);
-
- InvalidateRect(pic_list, tile_invalidation);
- modified_pile = true;
- }
- }
- }
- int repeat_count = std::max(1, slow_down_raster_scale_factor_for_debug_);
-
- // Walk through all pictures in the rect of interest and record.
- for (TilingData::Iterator iter(&tiling_, interest_rect); iter; ++iter) {
- // Create a picture in this list if it doesn't exist.
- PictureList& pic_list = picture_list_map_[iter.index()];
- if (pic_list.empty()) {
- // Inflate the base picture with a margin, similar to invalidations, so
- // that when scaled down to at least min_contents_scale, the enclosed
- // rect still includes content all the way to the edge of the layer.
- gfx::Rect tile = tiling_.TileBounds(iter.index_x(), iter.index_y());
- tile.Inset(
- -buffer_pixels(),
- -buffer_pixels(),
- -buffer_pixels(),
- -buffer_pixels());
- scoped_refptr<Picture> base_picture = Picture::Create(tile);
- pic_list.push_back(base_picture);
+ invalidated = picture_it->second.Invalidate() || invalidated;
}
+ }
- for (PictureList::iterator pic = pic_list.begin();
- pic != pic_list.end(); ++pic) {
- if (!(*pic)->HasRecording()) {
- modified_pile = true;
- base::TimeDelta best_duration = base::TimeDelta::FromInternalValue(
- std::numeric_limits<int64>::max());
- for (int i = 0; i < repeat_count; i++) {
- base::TimeTicks start_time = stats_instrumentation->StartRecording();
- (*pic)->Record(painter, tile_grid_info_);
- base::TimeDelta duration =
- stats_instrumentation->EndRecording(start_time);
- best_duration = std::min(duration, best_duration);
- }
- int recorded_pixel_count =
- (*pic)->LayerRect().width() * (*pic)->LayerRect().height();
- stats_instrumentation->AddRecord(best_duration, recorded_pixel_count);
- (*pic)->GatherPixelRefs(tile_grid_info_);
- (*pic)->CloneForDrawing(num_raster_threads_);
- }
+ gfx::Rect record_rect;
+ for (TilingData::Iterator it(&tiling_, interest_rect);
+ it; ++it) {
+ const PictureMapKey& key = it.index();
+ const PictureInfo& info = picture_map_[key];
+ if (!info.picture.get()) {
+ gfx::Rect tile = PaddedRect(key);
+ record_rect.Union(tile);
}
}
- UpdateRecordedRegion();
-
- return modified_pile;
-}
-
-class FullyContainedPredicate {
- public:
- explicit FullyContainedPredicate(gfx::Rect rect) : layer_rect_(rect) {}
- bool operator()(const scoped_refptr<Picture>& picture) {
- return picture->LayerRect().IsEmpty() ||
- layer_rect_.Contains(picture->LayerRect());
- }
- gfx::Rect layer_rect_;
-};
-
-void PicturePile::InvalidateRect(
- PictureList& picture_list,
- gfx::Rect invalidation) {
- DCHECK(!picture_list.empty());
- DCHECK(!invalidation.IsEmpty());
-
- std::vector<PictureList::iterator> overlaps;
- for (PictureList::iterator i = picture_list.begin();
- i != picture_list.end(); ++i) {
- if ((*i)->LayerRect().Contains(invalidation) && !(*i)->HasRecording())
- return;
- if ((*i)->LayerRect().Intersects(invalidation) && i != picture_list.begin())
- overlaps.push_back(i);
+ if (record_rect.IsEmpty()) {
+ if (invalidated)
+ UpdateRecordedRegion();
+ return invalidated;
}
- gfx::Rect picture_rect = invalidation;
- if (overlaps.size() >= kMaxOverlapping) {
- for (size_t j = 0; j < overlaps.size(); j++)
- picture_rect.Union((*overlaps[j])->LayerRect());
+ int repeat_count = std::max(1, slow_down_raster_scale_factor_for_debug_);
+ scoped_refptr<Picture> picture = Picture::Create(record_rect);
+
+ {
+ base::TimeDelta best_duration = base::TimeDelta::FromInternalValue(
+ std::numeric_limits<int64>::max());
+ for (int i = 0; i < repeat_count; i++) {
+ base::TimeTicks start_time = stats_instrumentation->StartRecording();
+ picture->Record(painter, tile_grid_info_);
+ base::TimeDelta duration =
+ stats_instrumentation->EndRecording(start_time);
+ best_duration = std::min(duration, best_duration);
+ }
+ int recorded_pixel_count =
+ picture->LayerRect().width() * picture->LayerRect().height();
+ stats_instrumentation->AddRecord(best_duration, recorded_pixel_count);
+ if (num_raster_threads_ > 1)
+ picture->GatherPixelRefs(tile_grid_info_);
+ picture->CloneForDrawing(num_raster_threads_);
}
- Picture* base_picture = picture_list.front().get();
- int max_pixels = kResetThreshold * base_picture->LayerRect().size().GetArea();
- if (picture_rect.size().GetArea() > max_pixels) {
- // This picture list will be entirely recreated, so clear it.
- picture_list.clear();
- return;
+ for (TilingData::Iterator it(&tiling_, record_rect);
+ it; ++it) {
+ const PictureMapKey& key = it.index();
+ gfx::Rect tile = PaddedRect(key);
+ if (record_rect.Contains(tile)) {
+ PictureInfo& info = picture_map_[key];
+ info.picture = picture;
+ }
}
- FullyContainedPredicate pred(picture_rect);
- picture_list.erase(std::remove_if(picture_list.begin(),
- picture_list.end(),
- pred),
- picture_list.end());
- picture_list.push_back(Picture::Create(picture_rect));
+ UpdateRecordedRegion();
+ return true;
}
} // namespace cc
diff --git a/cc/resources/picture_pile.h b/cc/resources/picture_pile.h
index 7830a9e62c..90fc015ca9 100644
--- a/cc/resources/picture_pile.h
+++ b/cc/resources/picture_pile.h
@@ -46,12 +46,6 @@ class CC_EXPORT PicturePile : public PicturePileBase {
private:
friend class PicturePileImpl;
- // Add an invalidation to this picture list. If the list needs to be
- // entirely recreated, leave it empty. Do not call this on an empty list.
- void InvalidateRect(
- PictureList& picture_list,
- gfx::Rect invalidation);
-
DISALLOW_COPY_AND_ASSIGN(PicturePile);
};
diff --git a/cc/resources/picture_pile_base.cc b/cc/resources/picture_pile_base.cc
index 0352d30816..8633a58165 100644
--- a/cc/resources/picture_pile_base.cc
+++ b/cc/resources/picture_pile_base.cc
@@ -5,6 +5,7 @@
#include "cc/resources/picture_pile_base.h"
#include <algorithm>
+#include <set>
#include <vector>
#include "base/logging.h"
@@ -17,7 +18,7 @@
namespace {
// Dimensions of the tiles in this picture pile as well as the dimensions of
// the base picture in each tile.
-const int kBasePictureSize = 3000;
+const int kBasePictureSize = 512;
const int kTileGridBorderPixels = 1;
}
@@ -37,7 +38,7 @@ PicturePileBase::PicturePileBase()
}
PicturePileBase::PicturePileBase(const PicturePileBase* other)
- : picture_list_map_(other->picture_list_map_),
+ : picture_map_(other->picture_map_),
tiling_(other->tiling_),
recorded_region_(other->recorded_region_),
min_contents_scale_(other->min_contents_scale_),
@@ -62,16 +63,10 @@ PicturePileBase::PicturePileBase(
other->slow_down_raster_scale_factor_for_debug_),
show_debug_picture_borders_(other->show_debug_picture_borders_),
num_raster_threads_(other->num_raster_threads_) {
- const PictureListMap& other_pic_list_map = other->picture_list_map_;
- for (PictureListMap::const_iterator map_iter = other_pic_list_map.begin();
- map_iter != other_pic_list_map.end(); ++map_iter) {
- PictureList& pic_list = picture_list_map_[map_iter->first];
- const PictureList& other_pic_list = map_iter->second;
- for (PictureList::const_iterator pic_iter = other_pic_list.begin();
- pic_iter != other_pic_list.end(); ++pic_iter) {
- pic_list.push_back(
- (*pic_iter)->GetCloneForDrawingOnThread(thread_index));
- }
+ for (PictureMap::const_iterator it = other->picture_map_.begin();
+ it != other->picture_map_.end();
+ ++it) {
+ picture_map_[it->first] = it->second.CloneForThread(thread_index);
}
}
@@ -86,20 +81,22 @@ void PicturePileBase::Resize(gfx::Size new_size) {
tiling_.SetTotalSize(new_size);
// Find all tiles that contain any pixels outside the new size.
- std::vector<PictureListMapKey> to_erase;
+ std::vector<PictureMapKey> to_erase;
int min_toss_x = tiling_.FirstBorderTileXIndexFromSrcCoord(
std::min(old_size.width(), new_size.width()));
int min_toss_y = tiling_.FirstBorderTileYIndexFromSrcCoord(
std::min(old_size.height(), new_size.height()));
- for (PictureListMap::iterator iter = picture_list_map_.begin();
- iter != picture_list_map_.end(); ++iter) {
- if (iter->first.first < min_toss_x && iter->first.second < min_toss_y)
+ for (PictureMap::const_iterator it = picture_map_.begin();
+ it != picture_map_.end();
+ ++it) {
+ const PictureMapKey& key = it->first;
+ if (key.first < min_toss_x && key.second < min_toss_y)
continue;
- to_erase.push_back(iter->first);
+ to_erase.push_back(key);
}
for (size_t i = 0; i < to_erase.size(); ++i)
- picture_list_map_.erase(to_erase[i]);
+ picture_map_.erase(to_erase[i]);
}
void PicturePileBase::SetMinContentsScale(float min_contents_scale) {
@@ -147,25 +144,26 @@ void PicturePileBase::SetBufferPixels(int new_buffer_pixels) {
}
void PicturePileBase::Clear() {
- picture_list_map_.clear();
+ picture_map_.clear();
}
void PicturePileBase::UpdateRecordedRegion() {
recorded_region_.Clear();
- for (PictureListMap::iterator it = picture_list_map_.begin();
- it != picture_list_map_.end(); ++it) {
- const PictureListMapKey& key = it->first;
- recorded_region_.Union(tile_bounds(key.first, key.second));
+ for (PictureMap::const_iterator it = picture_map_.begin();
+ it != picture_map_.end();
+ ++it) {
+ if (it->second.picture.get()) {
+ const PictureMapKey& key = it->first;
+ recorded_region_.Union(tile_bounds(key.first, key.second));
+ }
}
}
bool PicturePileBase::HasRecordingAt(int x, int y) {
- PictureListMap::iterator found =
- picture_list_map_.find(PictureListMapKey(x, y));
- if (found == picture_list_map_.end())
+ PictureMap::const_iterator found = picture_map_.find(PictureMapKey(x, y));
+ if (found == picture_map_.end())
return false;
- DCHECK(!found->second.empty());
- return true;
+ return !!found->second.picture.get();
}
bool PicturePileBase::CanRaster(float contents_scale, gfx::Rect content_rect) {
@@ -177,25 +175,49 @@ bool PicturePileBase::CanRaster(float contents_scale, gfx::Rect content_rect) {
return recorded_region_.Contains(layer_rect);
}
+gfx::Rect PicturePileBase::PaddedRect(const PictureMapKey& key) {
+ gfx::Rect tile = tiling_.TileBounds(key.first, key.second);
+ tile.Inset(
+ -buffer_pixels(), -buffer_pixels(), -buffer_pixels(), -buffer_pixels());
+ return tile;
+}
+
scoped_ptr<base::Value> PicturePileBase::AsValue() const {
scoped_ptr<base::ListValue> pictures(new base::ListValue());
gfx::Rect layer_rect(tiling_.total_size());
+ std::set<void*> appended_pictures;
for (TilingData::Iterator tile_iter(&tiling_, layer_rect);
tile_iter; ++tile_iter) {
- PictureListMap::const_iterator map_iter =
- picture_list_map_.find(tile_iter.index());
- if (map_iter == picture_list_map_.end())
- continue;
- const PictureList& pic_list= map_iter->second;
- if (pic_list.empty())
+ PictureMap::const_iterator map_iter = picture_map_.find(tile_iter.index());
+ if (map_iter == picture_map_.end())
continue;
- for (PictureList::const_reverse_iterator i = pic_list.rbegin();
- i != pic_list.rend(); ++i) {
- Picture* picture = (*i).get();
+
+ Picture* picture = map_iter->second.picture.get();
+ if (picture && (appended_pictures.count(picture) == 0)) {
+ appended_pictures.insert(picture);
pictures->Append(TracedValue::CreateIDRef(picture).release());
}
}
return pictures.PassAs<base::Value>();
}
+PicturePileBase::PictureInfo::PictureInfo() {}
+
+PicturePileBase::PictureInfo::~PictureInfo() {}
+
+bool PicturePileBase::PictureInfo::Invalidate() {
+ if (!picture.get())
+ return false;
+ picture = NULL;
+ return true;
+}
+
+PicturePileBase::PictureInfo PicturePileBase::PictureInfo::CloneForThread(
+ int thread_index) const {
+ PictureInfo info = *this;
+ if (picture.get())
+ info.picture = picture->GetCloneForDrawingOnThread(thread_index);
+ return info;
+}
+
} // namespace cc
diff --git a/cc/resources/picture_pile_base.h b/cc/resources/picture_pile_base.h
index fdb593fa81..0fa63f41f7 100644
--- a/cc/resources/picture_pile_base.h
+++ b/cc/resources/picture_pile_base.h
@@ -47,19 +47,30 @@ class CC_EXPORT PicturePileBase : public base::RefCounted<PicturePileBase> {
scoped_ptr<base::Value> AsValue() const;
protected:
+ struct CC_EXPORT PictureInfo {
+ PictureInfo();
+ ~PictureInfo();
+
+ bool Invalidate();
+ PictureInfo CloneForThread(int thread_index) const;
+
+ scoped_refptr<Picture> picture;
+ };
+
+ typedef std::pair<int, int> PictureMapKey;
+ typedef base::hash_map<PictureMapKey, PictureInfo> PictureMap;
+
virtual ~PicturePileBase();
int num_raster_threads() { return num_raster_threads_; }
int buffer_pixels() const { return tiling_.border_texels(); }
void Clear();
- typedef std::pair<int, int> PictureListMapKey;
- typedef std::list<scoped_refptr<Picture> > PictureList;
- typedef base::hash_map<PictureListMapKey, PictureList> PictureListMap;
+ gfx::Rect PaddedRect(const PictureMapKey& key);
- // A picture pile is a tiled set of picture lists. The picture list map
- // is a map of tile indices to picture lists.
- PictureListMap picture_list_map_;
+ // A picture pile is a tiled set of pictures. The picture map is a map of tile
+ // indices to picture infos.
+ PictureMap picture_map_;
TilingData tiling_;
Region recorded_region_;
float min_contents_scale_;
diff --git a/cc/resources/picture_pile_impl.cc b/cc/resources/picture_pile_impl.cc
index 95b333c3d6..3d0f5ecd77 100644
--- a/cc/resources/picture_pile_impl.cc
+++ b/cc/resources/picture_pile_impl.cc
@@ -142,6 +142,64 @@ void PicturePileImpl::RasterToBitmap(
rendering_stats_instrumentation);
}
+void PicturePileImpl::CoalesceRasters(gfx::Rect canvas_rect,
+ gfx::Rect content_rect,
+ float contents_scale,
+ PictureRegionMap* results) {
+ DCHECK(results);
+ // Rasterize the collection of relevant picture piles.
+ gfx::Rect layer_rect = gfx::ScaleToEnclosingRect(
+ content_rect, 1.f / contents_scale);
+
+ // Coalesce rasters of the same picture into different rects:
+ // - Compute the clip of each of the pile chunks,
+ // - Subtract it from the canvas rect to get difference region
+ // - Later, use the difference region to subtract each of the comprising
+ // rects from the canvas.
+ // Note that in essence, we're trying to mimic clipRegion with intersect op
+ // that also respects the current canvas transform and clip. In order to use
+ // the canvas transform, we must stick to clipRect operations (clipRegion
+ // ignores the transform). Intersect then can be written as subtracting the
+ // negation of the region we're trying to intersect. Luckily, we know that all
+ // of the rects will have to fit into |content_rect|, so we can start with
+ // that and subtract chunk rects to get the region that we need to subtract
+ // from the canvas. Then, we can use clipRect with difference op to subtract
+ // each rect in the region.
+ for (TilingData::Iterator tile_iter(&tiling_, layer_rect);
+ tile_iter; ++tile_iter) {
+ PictureMap::iterator map_iter = picture_map_.find(tile_iter.index());
+ if (map_iter == picture_map_.end())
+ continue;
+ PictureInfo& info = map_iter->second;
+ if (!info.picture.get())
+ continue;
+
+ // This is intentionally *enclosed* rect, so that the clip is aligned on
+ // integral post-scale content pixels and does not extend past the edges
+ // of the picture chunk's layer rect. The min_contents_scale enforces that
+ // enough buffer pixels have been added such that the enclosed rect
+ // encompasses all invalidated pixels at any larger scale level.
+ gfx::Rect chunk_rect = PaddedRect(tile_iter.index());
+ gfx::Rect content_clip =
+ gfx::ScaleToEnclosedRect(chunk_rect, contents_scale);
+ DCHECK(!content_clip.IsEmpty()) << "Layer rect: "
+ << info.picture->LayerRect().ToString()
+ << "Contents scale: " << contents_scale;
+ content_clip.Intersect(canvas_rect);
+
+ PictureRegionMap::iterator it = results->find(info.picture.get());
+ if (it == results->end()) {
+ Region& region = (*results)[info.picture.get()];
+ region = content_rect;
+ region.Subtract(content_clip);
+ continue;
+ }
+
+ Region& region = it->second;
+ region.Subtract(content_clip);
+ }
+}
+
void PicturePileImpl::RasterCommon(
SkCanvas* canvas,
SkDrawPictureCallback* callback,
@@ -151,111 +209,74 @@ void PicturePileImpl::RasterCommon(
DCHECK(contents_scale >= min_contents_scale_);
canvas->translate(-canvas_rect.x(), -canvas_rect.y());
-
gfx::SizeF total_content_size = gfx::ScaleSize(tiling_.total_size(),
contents_scale);
gfx::Rect total_content_rect(gfx::ToCeiledSize(total_content_size));
gfx::Rect content_rect = total_content_rect;
content_rect.Intersect(canvas_rect);
- // Rasterize the collection of relevant picture piles.
- gfx::Rect layer_rect = gfx::ScaleToEnclosingRect(
- content_rect, 1.f / contents_scale);
-
canvas->clipRect(gfx::RectToSkRect(content_rect),
SkRegion::kIntersect_Op);
- Region unclipped(content_rect);
- for (TilingData::Iterator tile_iter(&tiling_, layer_rect);
- tile_iter; ++tile_iter) {
- PictureListMap::iterator map_iter =
- picture_list_map_.find(tile_iter.index());
- if (map_iter == picture_list_map_.end())
- continue;
- PictureList& pic_list= map_iter->second;
- if (pic_list.empty())
- continue;
+ PictureRegionMap picture_region_map;
+ CoalesceRasters(
+ canvas_rect, content_rect, contents_scale, &picture_region_map);
- // Raster through the picture list top down, using clips to make sure that
- // pictures on top are not overdrawn by pictures on the bottom.
- for (PictureList::reverse_iterator i = pic_list.rbegin();
- i != pic_list.rend(); ++i) {
- // This is intentionally *enclosed* rect, so that the clip is aligned on
- // integral post-scale content pixels and does not extend past the edges
- // of the picture's layer rect. The min_contents_scale enforces that
- // enough buffer pixels have been added such that the enclosed rect
- // encompasses all invalidated pixels at any larger scale level.
- gfx::Rect content_clip = gfx::ScaleToEnclosedRect(
- (*i)->LayerRect(), contents_scale);
-
- DCHECK(!content_clip.IsEmpty()) <<
- "Layer rect: " << (*i)->LayerRect().ToString() <<
- "Contents scale: " << contents_scale;
-
- content_clip.Intersect(canvas_rect);
-
- if (!unclipped.Intersects(content_clip))
- continue;
-
- base::TimeDelta best_duration =
- base::TimeDelta::FromInternalValue(std::numeric_limits<int64>::max());
- int repeat_count = std::max(1, slow_down_raster_scale_factor_for_debug_);
- int rasterized_pixel_count = 0;
-
- for (int j = 0; j < repeat_count; ++j) {
- base::TimeTicks start_time;
- if (rendering_stats_instrumentation)
- start_time = rendering_stats_instrumentation->StartRecording();
- rasterized_pixel_count =
- (*i)->Raster(canvas, callback, content_clip, contents_scale);
- if (rendering_stats_instrumentation) {
- base::TimeDelta duration =
- rendering_stats_instrumentation->EndRecording(start_time);
- best_duration = std::min(best_duration, duration);
- }
- }
- if (rendering_stats_instrumentation) {
- rendering_stats_instrumentation->AddRaster(best_duration,
- rasterized_pixel_count);
- }
+#ifndef NDEBUG
+ Region total_clip;
+#endif // NDEBUG
+
+ // Iterate the coalesced map and use each picture's region
+ // to clip the canvas.
+ for (PictureRegionMap::iterator it = picture_region_map.begin();
+ it != picture_region_map.end();
+ ++it) {
+ Picture* picture = it->first;
+ Region negated_clip_region = it->second;
+
+#ifndef NDEBUG
+ Region positive_clip = content_rect;
+ positive_clip.Subtract(negated_clip_region);
+ total_clip.Union(positive_clip);
+#endif // NDEBUG
+
+ base::TimeDelta best_duration =
+ base::TimeDelta::FromInternalValue(std::numeric_limits<int64>::max());
+ int repeat_count = std::max(1, slow_down_raster_scale_factor_for_debug_);
+ int rasterized_pixel_count = 0;
+
+ for (int j = 0; j < repeat_count; ++j) {
+ base::TimeTicks start_time;
+ if (rendering_stats_instrumentation)
+ start_time = rendering_stats_instrumentation->StartRecording();
- if (show_debug_picture_borders_) {
- gfx::Rect border = gfx::ScaleToEnclosedRect(
- (*i)->LayerRect(), contents_scale);
- border.Inset(0, 0, 1, 1);
-
- SkPaint picture_border_paint;
- picture_border_paint.setColor(DebugColors::PictureBorderColor());
- canvas->drawLine(border.x(), border.y(), border.right(), border.y(),
- picture_border_paint);
- canvas->drawLine(border.right(), border.y(), border.right(),
- border.bottom(), picture_border_paint);
- canvas->drawLine(border.right(), border.bottom(), border.x(),
- border.bottom(), picture_border_paint);
- canvas->drawLine(border.x(), border.bottom(), border.x(), border.y(),
- picture_border_paint);
+ rasterized_pixel_count = picture->Raster(
+ canvas, callback, negated_clip_region, contents_scale);
+
+ if (rendering_stats_instrumentation) {
+ base::TimeDelta duration =
+ rendering_stats_instrumentation->EndRecording(start_time);
+ best_duration = std::min(best_duration, duration);
}
+ }
- // Don't allow pictures underneath to draw where this picture did.
- canvas->clipRect(
- gfx::RectToSkRect(content_clip),
- SkRegion::kDifference_Op);
- unclipped.Subtract(content_clip);
+ if (rendering_stats_instrumentation) {
+ rendering_stats_instrumentation->AddRaster(best_duration,
+ rasterized_pixel_count);
}
}
#ifndef NDEBUG
- // Fill the remaining clip with debug color. This allows us to
+ // Fill the clip with debug color. This allows us to
// distinguish between non painted areas and problems with missing
// pictures.
SkPaint paint;
+ for (Region::Iterator it(total_clip); it.has_rect(); it.next())
+ canvas->clipRect(gfx::RectToSkRect(it.rect()), SkRegion::kDifference_Op);
paint.setColor(DebugColors::MissingPictureFillColor());
paint.setXfermodeMode(SkXfermode::kSrc_Mode);
canvas->drawPaint(paint);
#endif // NDEBUG
-
- // We should always paint some part of |content_rect|.
- DCHECK(!unclipped.Contains(content_rect));
}
skia::RefPtr<SkPicture> PicturePileImpl::GetFlattenedPicture() {
@@ -316,14 +337,12 @@ PicturePileImpl::PixelRefIterator::PixelRefIterator(
: picture_pile_(picture_pile),
layer_rect_(gfx::ScaleToEnclosingRect(
content_rect, 1.f / contents_scale)),
- tile_iterator_(&picture_pile_->tiling_, layer_rect_),
- picture_list_(NULL) {
+ tile_iterator_(&picture_pile_->tiling_, layer_rect_) {
// Early out if there isn't a single tile.
if (!tile_iterator_)
return;
- if (AdvanceToTileWithPictures())
- AdvanceToPictureWithPixelRefs();
+ AdvanceToTilePictureWithPixelRefs();
}
PicturePileImpl::PixelRefIterator::~PixelRefIterator() {
@@ -335,50 +354,39 @@ PicturePileImpl::PixelRefIterator&
if (pixel_ref_iterator_)
return *this;
- ++picture_list_iterator_;
- AdvanceToPictureWithPixelRefs();
+ ++tile_iterator_;
+ AdvanceToTilePictureWithPixelRefs();
return *this;
}
-bool PicturePileImpl::PixelRefIterator::AdvanceToTileWithPictures() {
+void PicturePileImpl::PixelRefIterator::AdvanceToTilePictureWithPixelRefs() {
for (; tile_iterator_; ++tile_iterator_) {
- PictureListMap::const_iterator map_iterator =
- picture_pile_->picture_list_map_.find(tile_iterator_.index());
- if (map_iterator != picture_pile_->picture_list_map_.end()) {
- picture_list_ = &map_iterator->second;
- picture_list_iterator_ = picture_list_->begin();
- return true;
- }
- }
+ PictureMap::const_iterator it =
+ picture_pile_->picture_map_.find(tile_iterator_.index());
+ if (it == picture_pile_->picture_map_.end())
+ continue;
- return false;
-}
+ const Picture* picture = it->second.picture.get();
+ if (!picture || (processed_pictures_.count(picture) != 0))
+ continue;
-void PicturePileImpl::PixelRefIterator::AdvanceToPictureWithPixelRefs() {
- DCHECK(tile_iterator_);
- do {
- for (;
- picture_list_iterator_ != picture_list_->end();
- ++picture_list_iterator_) {
- pixel_ref_iterator_ =
- Picture::PixelRefIterator(layer_rect_, picture_list_iterator_->get());
- if (pixel_ref_iterator_)
- return;
- }
- ++tile_iterator_;
- } while (AdvanceToTileWithPictures());
+ processed_pictures_.insert(picture);
+ pixel_ref_iterator_ = Picture::PixelRefIterator(layer_rect_, picture);
+ if (pixel_ref_iterator_)
+ break;
+ }
}
void PicturePileImpl::DidBeginTracing() {
gfx::Rect layer_rect(tiling_.total_size());
- for (PictureListMap::iterator pli = picture_list_map_.begin();
- pli != picture_list_map_.end();
- pli++) {
- PictureList& picture_list = (*pli).second;
- for (PictureList::iterator picture = picture_list.begin();
- picture != picture_list.end();
- picture++) {
- (*picture)->EmitTraceSnapshot();
+ std::set<void*> processed_pictures;
+ for (PictureMap::iterator it = picture_map_.begin();
+ it != picture_map_.end();
+ ++it) {
+ Picture* picture = it->second.picture.get();
+ if (picture && (processed_pictures.count(picture) == 0)) {
+ picture->EmitTraceSnapshot();
+ processed_pictures.insert(picture);
}
}
}
diff --git a/cc/resources/picture_pile_impl.h b/cc/resources/picture_pile_impl.h
index ed50bec8b5..66b5f72fc3 100644
--- a/cc/resources/picture_pile_impl.h
+++ b/cc/resources/picture_pile_impl.h
@@ -7,6 +7,7 @@
#include <list>
#include <map>
+#include <set>
#include <vector>
#include "base/time/time.h"
@@ -87,15 +88,13 @@ class CC_EXPORT PicturePileImpl : public PicturePileBase {
operator bool() const { return pixel_ref_iterator_; }
private:
- bool AdvanceToTileWithPictures();
- void AdvanceToPictureWithPixelRefs();
+ void AdvanceToTilePictureWithPixelRefs();
const PicturePileImpl* picture_pile_;
gfx::Rect layer_rect_;
TilingData::Iterator tile_iterator_;
Picture::PixelRefIterator pixel_ref_iterator_;
- const PictureList* picture_list_;
- PictureList::const_iterator picture_list_iterator_;
+ std::set<const void*> processed_pictures_;
};
void DidBeginTracing();
@@ -123,6 +122,13 @@ class CC_EXPORT PicturePileImpl : public PicturePileBase {
PicturePileImpl(const PicturePileImpl* other, unsigned thread_index);
+ private:
+ typedef std::map<Picture*, Region> PictureRegionMap;
+ void CoalesceRasters(gfx::Rect canvas_rect,
+ gfx::Rect content_rect,
+ float contents_scale,
+ PictureRegionMap* result);
+
void RasterCommon(
SkCanvas* canvas,
SkDrawPictureCallback* callback,
diff --git a/cc/resources/picture_pile_impl_unittest.cc b/cc/resources/picture_pile_impl_unittest.cc
index a986c8846b..c68b185522 100644
--- a/cc/resources/picture_pile_impl_unittest.cc
+++ b/cc/resources/picture_pile_impl_unittest.cc
@@ -635,85 +635,6 @@ TEST(PicturePileImplTest, PixelRefIteratorLazyRefsBaseNonLazy) {
}
}
-TEST(PicturePileImplTest, PixelRefIteratorMultiplePictures) {
- gfx::Size tile_size(256, 256);
- gfx::Size layer_bounds(256, 256);
-
- SkTileGridPicture::TileGridInfo tile_grid_info;
- tile_grid_info.fTileInterval = SkISize::Make(256, 256);
- tile_grid_info.fMargin.setEmpty();
- tile_grid_info.fOffset.setZero();
-
- scoped_refptr<FakePicturePileImpl> pile =
- FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
-
- SkBitmap lazy_bitmap[2][2];
- CreateBitmap(gfx::Size(32, 32), "lazy", &lazy_bitmap[0][0]);
- CreateBitmap(gfx::Size(32, 32), "lazy", &lazy_bitmap[0][1]);
- CreateBitmap(gfx::Size(32, 32), "lazy", &lazy_bitmap[1][1]);
- SkBitmap non_lazy_bitmap;
- CreateBitmap(gfx::Size(256, 256), "notlazy", &non_lazy_bitmap);
-
- // Each bitmap goes into its own picture, the final layout
- // has lazy pixel refs in the following regions:
- // ||=======||
- // ||x| |x||
- // ||-- --||
- // || |x||
- // ||=======||
- pile->add_draw_bitmap(non_lazy_bitmap, gfx::Point(0, 0));
- pile->RerecordPile();
-
- FakeContentLayerClient content_layer_clients[2][2];
- scoped_refptr<Picture> pictures[2][2];
- for (int y = 0; y < 2; ++y) {
- for (int x = 0; x < 2; ++x) {
- if (x == 0 && y == 1)
- continue;
- SkPaint paint;
- content_layer_clients[y][x].add_draw_bitmap(
- lazy_bitmap[y][x],
- gfx::Point(x * 128 + 10, y * 128 + 10), paint);
- pictures[y][x] = Picture::Create(
- gfx::Rect(x * 128 + 10, y * 128 + 10, 64, 64));
- pictures[y][x]->Record(
- &content_layer_clients[y][x],
- tile_grid_info);
- pictures[y][x]->GatherPixelRefs(tile_grid_info);
- pile->AddPictureToRecording(0, 0, pictures[y][x]);
- }
- }
-
- // These should find only one pixel ref.
- {
- PicturePileImpl::PixelRefIterator iterator(
- gfx::Rect(0, 0, 128, 128), 1.0, pile.get());
- EXPECT_TRUE(iterator);
- EXPECT_TRUE(*iterator == lazy_bitmap[0][0].pixelRef());
- EXPECT_FALSE(++iterator);
- }
- {
- PicturePileImpl::PixelRefIterator iterator(
- gfx::Rect(128, 0, 128, 128), 1.0, pile.get());
- EXPECT_TRUE(iterator);
- EXPECT_TRUE(*iterator == lazy_bitmap[0][1].pixelRef());
- EXPECT_FALSE(++iterator);
- }
- {
- PicturePileImpl::PixelRefIterator iterator(
- gfx::Rect(128, 128, 128, 128), 1.0, pile.get());
- EXPECT_TRUE(iterator);
- EXPECT_TRUE(*iterator == lazy_bitmap[1][1].pixelRef());
- EXPECT_FALSE(++iterator);
- }
- // This one should not find any refs
- {
- PicturePileImpl::PixelRefIterator iterator(
- gfx::Rect(0, 128, 128, 128), 1.0, pile.get());
- EXPECT_FALSE(iterator);
- }
-}
-
TEST(PicturePileImpl, RasterContentsOpaque) {
gfx::Size tile_size(1000, 1000);
gfx::Size layer_bounds(3, 5);
diff --git a/cc/resources/picture_pile_unittest.cc b/cc/resources/picture_pile_unittest.cc
index 1eeb5ad5fe..0c9b2e1194 100644
--- a/cc/resources/picture_pile_unittest.cc
+++ b/cc/resources/picture_pile_unittest.cc
@@ -16,11 +16,11 @@ class TestPicturePile : public PicturePile {
public:
using PicturePile::buffer_pixels;
- PictureListMap& picture_list_map() { return picture_list_map_; }
+ PictureMap& picture_map() { return picture_map_; }
- typedef PicturePile::PictureList PictureList;
- typedef PicturePile::PictureListMapKey PictureListMapKey;
- typedef PicturePile::PictureListMap PictureListMap;
+ typedef PicturePile::PictureInfo PictureInfo;
+ typedef PicturePile::PictureMapKey PictureMapKey;
+ typedef PicturePile::PictureMap PictureMap;
protected:
virtual ~TestPicturePile() {}
@@ -60,22 +60,17 @@ TEST(PicturePileTest, SmallInvalidateInflated) {
EXPECT_EQ(1, pile->tiling().num_tiles_x());
EXPECT_EQ(1, pile->tiling().num_tiles_y());
- TestPicturePile::PictureList& picture_list =
- pile->picture_list_map().find(
- TestPicturePile::PictureListMapKey(0, 0))->second;
- EXPECT_EQ(2u, picture_list.size());
- for (TestPicturePile::PictureList::iterator it = picture_list.begin();
- it != picture_list.end();
- ++it) {
- scoped_refptr<Picture> picture = *it;
- gfx::Rect picture_rect =
- gfx::ScaleToEnclosedRect(picture->LayerRect(), min_scale);
-
- // The invalidation in each tile should have been made large enough
- // that scaling it never makes a rect smaller than 1 px wide or tall.
- EXPECT_FALSE(picture_rect.IsEmpty()) << "Picture rect " <<
- picture_rect.ToString();
- }
+ TestPicturePile::PictureInfo& picture_info =
+ pile->picture_map().find(TestPicturePile::PictureMapKey(0, 0))->second;
+ // We should have a picture.
+ EXPECT_TRUE(!!picture_info.picture.get());
+ gfx::Rect picture_rect =
+ gfx::ScaleToEnclosedRect(picture_info.picture->LayerRect(), min_scale);
+
+ // The the picture should be large enough that scaling it never makes a rect
+ // smaller than 1 px wide or tall.
+ EXPECT_FALSE(picture_rect.IsEmpty()) << "Picture rect " <<
+ picture_rect.ToString();
}
TEST(PicturePileTest, LargeInvalidateInflated) {
@@ -112,24 +107,17 @@ TEST(PicturePileTest, LargeInvalidateInflated) {
EXPECT_EQ(1, pile->tiling().num_tiles_x());
EXPECT_EQ(1, pile->tiling().num_tiles_y());
- TestPicturePile::PictureList& picture_list =
- pile->picture_list_map().find(
- TestPicturePile::PictureListMapKey(0, 0))->second;
- EXPECT_EQ(2u, picture_list.size());
+ TestPicturePile::PictureInfo& picture_info =
+ pile->picture_map().find(TestPicturePile::PictureMapKey(0, 0))->second;
+ EXPECT_TRUE(!!picture_info.picture.get());
int expected_inflation = pile->buffer_pixels();
- scoped_refptr<Picture> base_picture = *picture_list.begin();
+ scoped_refptr<Picture> base_picture = picture_info.picture;
gfx::Rect base_picture_rect(layer_size);
base_picture_rect.Inset(-expected_inflation, -expected_inflation);
EXPECT_EQ(base_picture_rect.ToString(),
base_picture->LayerRect().ToString());
-
- scoped_refptr<Picture> picture = *(++picture_list.begin());
- gfx::Rect picture_rect(invalidate_rect);
- picture_rect.Inset(-expected_inflation, -expected_inflation);
- EXPECT_EQ(picture_rect.ToString(),
- picture->LayerRect().ToString());
}
TEST(PicturePileTest, InvalidateOnTileBoundaryInflated) {
@@ -179,30 +167,13 @@ TEST(PicturePileTest, InvalidateOnTileBoundaryInflated) {
for (int i = 0; i < pile->tiling().num_tiles_x(); ++i) {
for (int j = 0; j < pile->tiling().num_tiles_y(); ++j) {
- // (1, 0) and (1, 1) should be invalidated partially.
- bool expect_invalidated = i == 1 && (j == 0 || j == 1);
-
- TestPicturePile::PictureList& picture_list =
- pile->picture_list_map().find(
- TestPicturePile::PictureListMapKey(i, j))->second;
- if (!expect_invalidated) {
- EXPECT_EQ(1u, picture_list.size()) << "For i,j " << i << "," << j;
- continue;
- }
-
- EXPECT_EQ(2u, picture_list.size()) << "For i,j " << i << "," << j;
- for (TestPicturePile::PictureList::iterator it = picture_list.begin();
- it != picture_list.end();
- ++it) {
- scoped_refptr<Picture> picture = *it;
- gfx::Rect picture_rect =
- gfx::ScaleToEnclosedRect(picture->LayerRect(), min_scale);
-
- // The invalidation in each tile should have been made large enough
- // that scaling it never makes a rect smaller than 1 px wide or tall.
- EXPECT_FALSE(picture_rect.IsEmpty()) << "Picture rect " <<
- picture_rect.ToString();
- }
+ TestPicturePile::PictureInfo& picture_info =
+ pile->picture_map().find(
+ TestPicturePile::PictureMapKey(i, j))->second;
+
+ // TODO(vmpstr): Fix this to check invalidation frequency instead
+ // of the picture, since we always have one picture per tile.
+ EXPECT_TRUE(!!picture_info.picture.get());
}
}
}
diff --git a/cc/resources/pixel_buffer_raster_worker_pool.cc b/cc/resources/pixel_buffer_raster_worker_pool.cc
index a555e58154..edd7d6c99d 100644
--- a/cc/resources/pixel_buffer_raster_worker_pool.cc
+++ b/cc/resources/pixel_buffer_raster_worker_pool.cc
@@ -212,7 +212,7 @@ void PixelBufferRasterWorkerPool::ScheduleTasks(RasterTask::Queue* queue) {
check_for_completed_raster_tasks_pending_ = false;
ScheduleCheckForCompletedRasterTasks();
- TRACE_EVENT_ASYNC_STEP1(
+ TRACE_EVENT_ASYNC_STEP_INTO1(
"cc", "ScheduledTasks", this, StateName(),
"state", TracedValue::FromValue(StateAsValue().release()));
}
@@ -397,7 +397,7 @@ void PixelBufferRasterWorkerPool::CheckForCompletedRasterTasks() {
if (PendingRasterTaskCount())
ScheduleMoreTasks();
- TRACE_EVENT_ASYNC_STEP1(
+ TRACE_EVENT_ASYNC_STEP_INTO1(
"cc", "ScheduledTasks", this, StateName(),
"state", TracedValue::FromValue(StateAsValue().release()));
diff --git a/cc/resources/prioritized_resource.cc b/cc/resources/prioritized_resource.cc
index 313b275a3a..8a7874d05b 100644
--- a/cc/resources/prioritized_resource.cc
+++ b/cc/resources/prioritized_resource.cc
@@ -124,6 +124,7 @@ PrioritizedResource::Backing::Backing(unsigned id,
priority_at_last_priority_update_(PriorityCalculator::LowestPriority()),
was_above_priority_cutoff_at_last_priority_update_(false),
in_drawing_impl_tree_(false),
+ in_parent_compositor_(false),
#ifdef NDEBUG
resource_has_been_deleted_(false) {}
#else
@@ -157,7 +158,7 @@ bool PrioritizedResource::Backing::ResourceHasBeenDeleted() const {
bool PrioritizedResource::Backing::CanBeRecycled() const {
DCHECK(!proxy() || proxy()->IsImplThread());
return !was_above_priority_cutoff_at_last_priority_update_ &&
- !in_drawing_impl_tree_;
+ !in_drawing_impl_tree_ && !in_parent_compositor_;
}
void PrioritizedResource::Backing::UpdatePriority() {
@@ -173,10 +174,12 @@ void PrioritizedResource::Backing::UpdatePriority() {
}
}
-void PrioritizedResource::Backing::UpdateInDrawingImplTree() {
+void PrioritizedResource::Backing::UpdateState(
+ ResourceProvider* resource_provider) {
DCHECK(!proxy() ||
(proxy()->IsImplThread() && proxy()->IsMainThreadBlocked()));
in_drawing_impl_tree_ = !!owner();
+ in_parent_compositor_ = resource_provider->InUseByConsumer(id());
if (!in_drawing_impl_tree_) {
DCHECK_EQ(priority_at_last_priority_update_,
PriorityCalculator::LowestPriority());
diff --git a/cc/resources/prioritized_resource.h b/cc/resources/prioritized_resource.h
index a3d5d89cf6..bdd906d382 100644
--- a/cc/resources/prioritized_resource.h
+++ b/cc/resources/prioritized_resource.h
@@ -111,7 +111,7 @@ class CC_EXPORT PrioritizedResource {
ResourceFormat format);
~Backing();
void UpdatePriority();
- void UpdateInDrawingImplTree();
+ void UpdateState(ResourceProvider* resource_provider);
PrioritizedResource* owner() { return owner_; }
bool CanBeRecycled() const;
@@ -122,6 +122,7 @@ class CC_EXPORT PrioritizedResource {
return was_above_priority_cutoff_at_last_priority_update_;
}
bool in_drawing_impl_tree() const { return in_drawing_impl_tree_; }
+ bool in_parent_compositor() const { return in_parent_compositor_; }
void DeleteResource(ResourceProvider* resource_provider);
bool ResourceHasBeenDeleted() const;
@@ -137,6 +138,8 @@ class CC_EXPORT PrioritizedResource {
// Set if this is currently-drawing impl tree.
bool in_drawing_impl_tree_;
+ // Set if this is in the parent compositor.
+ bool in_parent_compositor_;
bool resource_has_been_deleted_;
diff --git a/cc/resources/prioritized_resource_manager.cc b/cc/resources/prioritized_resource_manager.cc
index 4743b9aa3d..ece04b1105 100644
--- a/cc/resources/prioritized_resource_manager.cc
+++ b/cc/resources/prioritized_resource_manager.cc
@@ -160,7 +160,8 @@ void PrioritizedResourceManager::PushTexturePrioritiesToBackings() {
memory_visible_and_nearby_bytes_;
}
-void PrioritizedResourceManager::UpdateBackingsInDrawingImplTree() {
+void PrioritizedResourceManager::UpdateBackingsState(
+ ResourceProvider* resource_provider) {
TRACE_EVENT0("cc",
"PrioritizedResourceManager::UpdateBackingsInDrawingImplTree");
DCHECK(proxy_->IsImplThread() && proxy_->IsMainThreadBlocked());
@@ -169,7 +170,7 @@ void PrioritizedResourceManager::UpdateBackingsInDrawingImplTree() {
for (BackingList::iterator it = backings_.begin(); it != backings_.end();
++it) {
PrioritizedResource::Backing* backing = (*it);
- backing->UpdateInDrawingImplTree();
+ backing->UpdateState(resource_provider);
}
SortBackings();
AssertInvariants();
@@ -320,8 +321,7 @@ void PrioritizedResourceManager::ReduceWastedMemory(
++it) {
if ((*it)->owner())
break;
- if (resource_provider->InUseByConsumer((*it)->id()) &&
- !resource_provider->IsLost((*it)->id()))
+ if ((*it)->in_parent_compositor())
continue;
wasted_memory += (*it)->bytes();
}
@@ -380,18 +380,6 @@ bool PrioritizedResourceManager::ReduceMemoryOnImplThread(
resource_provider);
}
-void PrioritizedResourceManager::ReduceWastedMemoryOnImplThread(
- ResourceProvider* resource_provider) {
- DCHECK(proxy_->IsImplThread());
- DCHECK(resource_provider);
- // If we are in the process of uploading a new frame then the backings at the
- // very end of the list are not sorted by priority. Sort them before doing the
- // eviction.
- if (backings_tail_not_sorted_)
- SortBackings();
- ReduceWastedMemory(resource_provider);
-}
-
void PrioritizedResourceManager::UnlinkAndClearEvictedBackings() {
DCHECK(proxy_->IsMainThread());
base::AutoLock scoped_lock(evicted_backings_lock_);
diff --git a/cc/resources/prioritized_resource_manager.h b/cc/resources/prioritized_resource_manager.h
index 07cc7cf39a..8a7c275ee7 100644
--- a/cc/resources/prioritized_resource_manager.h
+++ b/cc/resources/prioritized_resource_manager.h
@@ -96,10 +96,6 @@ class CC_EXPORT PrioritizedResourceManager {
int priority_cutoff,
ResourceProvider* resource_provider);
- // Delete contents textures' backing resources that can be recycled. This
- // may be called on the impl thread while the main thread is running.
- void ReduceWastedMemoryOnImplThread(ResourceProvider* resource_provider);
-
// Returns true if there exist any textures that are linked to backings that
// have had their resources evicted. Only when we commit a tree that has no
// textures linked to evicted backings may we allow drawing. After an
@@ -129,7 +125,7 @@ class CC_EXPORT PrioritizedResourceManager {
void PushTexturePrioritiesToBackings();
// Mark all textures' backings as being in the drawing impl tree.
- void UpdateBackingsInDrawingImplTree();
+ void UpdateBackingsState(ResourceProvider* resource_provider);
const Proxy* ProxyForDebug() const;
@@ -159,6 +155,10 @@ class CC_EXPORT PrioritizedResourceManager {
// Make textures that can be recycled appear first
if (a->CanBeRecycled() != b->CanBeRecycled())
return (a->CanBeRecycled() > b->CanBeRecycled());
+ // Put textures in the parent compositor last since they can't be
+ // freed when they are evicted anyhow.
+ if (a->in_parent_compositor() != b->in_parent_compositor())
+ return (a->in_parent_compositor() < b->in_parent_compositor());
// Then sort by being above or below the priority cutoff.
if (a->was_above_priority_cutoff_at_last_priority_update() !=
b->was_above_priority_cutoff_at_last_priority_update())
diff --git a/cc/resources/prioritized_resource_unittest.cc b/cc/resources/prioritized_resource_unittest.cc
index fb71533101..82178c2750 100644
--- a/cc/resources/prioritized_resource_unittest.cc
+++ b/cc/resources/prioritized_resource_unittest.cc
@@ -4,6 +4,8 @@
#include "cc/resources/prioritized_resource.h"
+#include <vector>
+
#include "cc/resources/prioritized_resource_manager.h"
#include "cc/resources/resource.h"
#include "cc/test/fake_output_surface.h"
@@ -24,7 +26,7 @@ class PrioritizedResourceTest : public testing::Test {
DebugScopedSetImplThread impl_thread(&proxy_);
CHECK(output_surface_->BindToClient(&output_surface_client_));
resource_provider_ =
- cc::ResourceProvider::Create(output_surface_.get(), 0, false);
+ ResourceProvider::Create(output_surface_.get(), NULL, 0, false);
}
virtual ~PrioritizedResourceTest() {
@@ -51,7 +53,7 @@ class PrioritizedResourceTest : public testing::Test {
texture->RequestLate();
ResourceManagerAssertInvariants(texture->resource_manager());
DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
+ impl_thread_and_main_thread_blocked(&proxy_);
bool success = texture->can_acquire_backing_texture();
if (success)
texture->AcquireBackingTexture(ResourceProvider());
@@ -67,7 +69,7 @@ class PrioritizedResourceTest : public testing::Test {
void ResourceManagerUpdateBackingsPriorities(
PrioritizedResourceManager* resource_manager) {
DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
+ impl_thread_and_main_thread_blocked(&proxy_);
resource_manager->PushTexturePrioritiesToBackings();
}
@@ -77,7 +79,7 @@ class PrioritizedResourceTest : public testing::Test {
PrioritizedResourceManager* resource_manager) {
#ifndef NDEBUG
DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
+ impl_thread_and_main_thread_blocked(&proxy_);
resource_manager->AssertInvariants();
#endif
}
@@ -91,12 +93,23 @@ class PrioritizedResourceTest : public testing::Test {
return resource_manager->evicted_backings_.size();
}
+ std::vector<unsigned> BackingResources(
+ PrioritizedResourceManager* resource_manager) {
+ std::vector<unsigned> resources;
+ for (PrioritizedResourceManager::BackingList::iterator it =
+ resource_manager->backings_.begin();
+ it != resource_manager->backings_.end();
+ ++it)
+ resources.push_back((*it)->id());
+ return resources;
+ }
+
protected:
FakeProxy proxy_;
const gfx::Size texture_size_;
const ResourceFormat texture_format_;
FakeOutputSurfaceClient output_surface_client_;
- scoped_ptr<OutputSurface> output_surface_;
+ scoped_ptr<cc::OutputSurface> output_surface_;
scoped_ptr<cc::ResourceProvider> resource_provider_;
};
@@ -144,7 +157,7 @@ TEST_F(PrioritizedResourceTest, RequestTextureExceedingMaxLimit) {
resource_manager->MaxMemoryNeededBytes());
DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
+ impl_thread_and_main_thread_blocked(&proxy_);
resource_manager->ClearAllMemory(ResourceProvider());
}
@@ -168,7 +181,7 @@ TEST_F(PrioritizedResourceTest, ChangeMemoryLimits) {
ValidateTexture(textures[i].get(), false);
{
DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
+ impl_thread_and_main_thread_blocked(&proxy_);
resource_manager->ReduceMemory(ResourceProvider());
}
@@ -183,7 +196,7 @@ TEST_F(PrioritizedResourceTest, ChangeMemoryLimits) {
EXPECT_EQ(ValidateTexture(textures[i].get(), false), i < 5);
{
DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
+ impl_thread_and_main_thread_blocked(&proxy_);
resource_manager->ReduceMemory(ResourceProvider());
}
@@ -200,7 +213,7 @@ TEST_F(PrioritizedResourceTest, ChangeMemoryLimits) {
EXPECT_EQ(ValidateTexture(textures[i].get(), false), i < 4);
{
DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
+ impl_thread_and_main_thread_blocked(&proxy_);
resource_manager->ReduceMemory(ResourceProvider());
}
@@ -211,7 +224,7 @@ TEST_F(PrioritizedResourceTest, ChangeMemoryLimits) {
resource_manager->MaxMemoryNeededBytes());
DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
+ impl_thread_and_main_thread_blocked(&proxy_);
resource_manager->ClearAllMemory(ResourceProvider());
}
@@ -249,7 +262,7 @@ TEST_F(PrioritizedResourceTest, ReduceWastedMemory) {
}
{
DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
+ impl_thread_and_main_thread_blocked(&proxy_);
resource_manager->ReduceMemory(ResourceProvider());
}
@@ -261,7 +274,8 @@ TEST_F(PrioritizedResourceTest, ReduceWastedMemory) {
PrioritizeTexturesAndBackings(resource_manager.get());
{
DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
+ impl_thread_and_main_thread_blocked(&proxy_);
+ resource_manager->UpdateBackingsState(ResourceProvider());
resource_manager->ReduceWastedMemory(ResourceProvider());
}
EXPECT_EQ(TexturesMemorySize(20), resource_manager->MemoryUseBytes());
@@ -273,13 +287,14 @@ TEST_F(PrioritizedResourceTest, ReduceWastedMemory) {
PrioritizeTexturesAndBackings(resource_manager.get());
{
DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
+ impl_thread_and_main_thread_blocked(&proxy_);
+ resource_manager->UpdateBackingsState(ResourceProvider());
resource_manager->ReduceWastedMemory(ResourceProvider());
}
EXPECT_GT(TexturesMemorySize(20), resource_manager->MemoryUseBytes());
DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
+ impl_thread_and_main_thread_blocked(&proxy_);
resource_manager->ClearAllMemory(ResourceProvider());
}
@@ -339,7 +354,8 @@ TEST_F(PrioritizedResourceTest, InUseNotWastedMemory) {
PrioritizeTexturesAndBackings(resource_manager.get());
{
DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
+ impl_thread_and_main_thread_blocked(&proxy_);
+ resource_manager->UpdateBackingsState(ResourceProvider());
resource_manager->ReduceWastedMemory(ResourceProvider());
}
EXPECT_EQ(TexturesMemorySize(20), resource_manager->MemoryUseBytes());
@@ -351,13 +367,14 @@ TEST_F(PrioritizedResourceTest, InUseNotWastedMemory) {
resource_provider_->ReceiveReturnsFromParent(returns);
{
DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
+ impl_thread_and_main_thread_blocked(&proxy_);
+ resource_manager->UpdateBackingsState(ResourceProvider());
resource_manager->ReduceWastedMemory(ResourceProvider());
}
EXPECT_GT(TexturesMemorySize(20), resource_manager->MemoryUseBytes());
DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
+ impl_thread_and_main_thread_blocked(&proxy_);
resource_manager->ClearAllMemory(ResourceProvider());
}
@@ -384,7 +401,7 @@ TEST_F(PrioritizedResourceTest, ChangePriorityCutoff) {
EXPECT_EQ(ValidateTexture(textures[i].get(), true), i < 6);
{
DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
+ impl_thread_and_main_thread_blocked(&proxy_);
resource_manager->ReduceMemory(ResourceProvider());
}
EXPECT_EQ(TexturesMemorySize(6), resource_manager->MemoryAboveCutoffBytes());
@@ -398,17 +415,16 @@ TEST_F(PrioritizedResourceTest, ChangePriorityCutoff) {
EXPECT_EQ(ValidateTexture(textures[i].get(), false), i < 4);
{
DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
+ impl_thread_and_main_thread_blocked(&proxy_);
resource_manager->ReduceMemory(ResourceProvider());
}
EXPECT_EQ(TexturesMemorySize(4), resource_manager->MemoryAboveCutoffBytes());
// Do a one-time eviction for one more texture based on priority cutoff
- PrioritizedResourceManager::BackingList evicted_backings;
resource_manager->UnlinkAndClearEvictedBackings();
{
DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
+ impl_thread_and_main_thread_blocked(&proxy_);
resource_manager->ReduceMemoryOnImplThread(
TexturesMemorySize(8), 104, ResourceProvider());
EXPECT_EQ(0u, EvictedBackingCount(resource_manager.get()));
@@ -425,13 +441,149 @@ TEST_F(PrioritizedResourceTest, ChangePriorityCutoff) {
EXPECT_EQ(ValidateTexture(textures[i].get(), false), i < 4);
{
DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
+ impl_thread_and_main_thread_blocked(&proxy_);
resource_manager->ReduceMemory(ResourceProvider());
}
EXPECT_EQ(TexturesMemorySize(4), resource_manager->MemoryAboveCutoffBytes());
DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
+ impl_thread_and_main_thread_blocked(&proxy_);
+ resource_manager->ClearAllMemory(ResourceProvider());
+}
+
+TEST_F(PrioritizedResourceTest, NotEvictingTexturesInParent) {
+ const size_t kMaxTextures = 8;
+ scoped_ptr<PrioritizedResourceManager> resource_manager =
+ CreateManager(kMaxTextures);
+ scoped_ptr<PrioritizedResource> textures[kMaxTextures];
+ unsigned texture_resource_ids[kMaxTextures];
+
+ for (size_t i = 0; i < kMaxTextures; ++i) {
+ textures[i] =
+ resource_manager->CreateTexture(texture_size_, texture_format_);
+ textures[i]->set_request_priority(100 + i);
+ }
+
+ PrioritizeTexturesAndBackings(resource_manager.get());
+ for (size_t i = 0; i < kMaxTextures; ++i) {
+ EXPECT_TRUE(ValidateTexture(textures[i].get(), true));
+
+ {
+ DebugScopedSetImplThreadAndMainThreadBlocked
+ impl_thread_and_main_thread_blocked(&proxy_);
+ uint8_t image[4] = {0};
+ textures[i]->SetPixels(resource_provider_.get(),
+ image,
+ gfx::Rect(1, 1),
+ gfx::Rect(1, 1),
+ gfx::Vector2d());
+ }
+ }
+ {
+ DebugScopedSetImplThreadAndMainThreadBlocked
+ impl_thread_and_main_thread_blocked(&proxy_);
+ resource_manager->ReduceMemory(ResourceProvider());
+ }
+ EXPECT_EQ(TexturesMemorySize(8), resource_manager->MemoryAboveCutoffBytes());
+
+ for (size_t i = 0; i < 8; ++i)
+ texture_resource_ids[i] = textures[i]->resource_id();
+
+ // Evict four textures. It will be the last four.
+ {
+ DebugScopedSetImplThreadAndMainThreadBlocked
+ impl_thread_and_main_thread_blocked(&proxy_);
+ resource_manager->ReduceMemoryOnImplThread(
+ TexturesMemorySize(4), 200, ResourceProvider());
+
+ EXPECT_EQ(4u, EvictedBackingCount(resource_manager.get()));
+
+ // The last four backings are evicted.
+ std::vector<unsigned> remaining = BackingResources(resource_manager.get());
+ EXPECT_TRUE(std::find(remaining.begin(),
+ remaining.end(),
+ texture_resource_ids[0]) != remaining.end());
+ EXPECT_TRUE(std::find(remaining.begin(),
+ remaining.end(),
+ texture_resource_ids[1]) != remaining.end());
+ EXPECT_TRUE(std::find(remaining.begin(),
+ remaining.end(),
+ texture_resource_ids[2]) != remaining.end());
+ EXPECT_TRUE(std::find(remaining.begin(),
+ remaining.end(),
+ texture_resource_ids[3]) != remaining.end());
+ }
+ resource_manager->UnlinkAndClearEvictedBackings();
+ EXPECT_EQ(TexturesMemorySize(4), resource_manager->MemoryUseBytes());
+
+ // Re-allocate the the texture after the eviction.
+ PrioritizeTexturesAndBackings(resource_manager.get());
+ for (size_t i = 0; i < kMaxTextures; ++i) {
+ EXPECT_TRUE(ValidateTexture(textures[i].get(), true));
+
+ {
+ DebugScopedSetImplThreadAndMainThreadBlocked
+ impl_thread_and_main_thread_blocked(&proxy_);
+ uint8_t image[4] = {0};
+ textures[i]->SetPixels(resource_provider_.get(),
+ image,
+ gfx::Rect(1, 1),
+ gfx::Rect(1, 1),
+ gfx::Vector2d());
+ }
+ }
+ {
+ DebugScopedSetImplThreadAndMainThreadBlocked
+ impl_thread_and_main_thread_blocked(&proxy_);
+ resource_manager->ReduceMemory(ResourceProvider());
+ }
+ EXPECT_EQ(TexturesMemorySize(8), resource_manager->MemoryAboveCutoffBytes());
+
+ // Send the last two of the textures to a parent compositor.
+ ResourceProvider::ResourceIdArray to_send;
+ TransferableResourceArray transferable;
+ for (size_t i = 6; i < 8; ++i)
+ to_send.push_back(textures[i]->resource_id());
+ resource_provider_->PrepareSendToParent(to_send, &transferable);
+
+ for (size_t i = 0; i < 8; ++i)
+ texture_resource_ids[i] = textures[i]->resource_id();
+
+ // Drop all the textures. Now we have backings that can be recycled.
+ for (size_t i = 0; i < 8; ++i)
+ textures[0].reset();
+ PrioritizeTexturesAndBackings(resource_manager.get());
+
+ // The next commit finishes.
+ {
+ DebugScopedSetImplThreadAndMainThreadBlocked
+ impl_thread_and_main_thread_blocked(&proxy_);
+ resource_manager->UpdateBackingsState(ResourceProvider());
+ }
+
+ // Evict four textures. It would be the last four again, except that 2 of them
+ // are sent to the parent, so they are evicted last.
+ {
+ DebugScopedSetImplThreadAndMainThreadBlocked
+ impl_thread_and_main_thread_blocked(&proxy_);
+ resource_manager->ReduceMemoryOnImplThread(
+ TexturesMemorySize(4), 200, ResourceProvider());
+
+ EXPECT_EQ(4u, EvictedBackingCount(resource_manager.get()));
+ // The last 2 backings remain this time.
+ std::vector<unsigned> remaining = BackingResources(resource_manager.get());
+ EXPECT_TRUE(std::find(remaining.begin(),
+ remaining.end(),
+ texture_resource_ids[6]) != remaining.end());
+ EXPECT_TRUE(std::find(remaining.begin(),
+ remaining.end(),
+ texture_resource_ids[7]) != remaining.end());
+ }
+ resource_manager->UnlinkAndClearEvictedBackings();
+ EXPECT_EQ(TexturesMemorySize(4), resource_manager->MemoryUseBytes());
+
+ DebugScopedSetImplThreadAndMainThreadBlocked
+ impl_thread_and_main_thread_blocked(&proxy_);
resource_manager->ClearAllMemory(ResourceProvider());
}
@@ -494,7 +646,7 @@ TEST_F(PrioritizedResourceTest, ResourceManagerPartialUpdateTextures) {
EXPECT_FALSE(textures[3]->have_backing_texture());
DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
+ impl_thread_and_main_thread_blocked(&proxy_);
resource_manager->ClearAllMemory(ResourceProvider());
}
@@ -539,7 +691,7 @@ TEST_F(PrioritizedResourceTest, ResourceManagerPrioritiesAreEqual) {
resource_manager->MemoryAboveCutoffBytes());
DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
+ impl_thread_and_main_thread_blocked(&proxy_);
resource_manager->ClearAllMemory(ResourceProvider());
}
@@ -559,7 +711,7 @@ TEST_F(PrioritizedResourceTest, ResourceManagerDestroyedFirst) {
EXPECT_TRUE(texture->have_backing_texture());
{
DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
+ impl_thread_and_main_thread_blocked(&proxy_);
resource_manager->ClearAllMemory(ResourceProvider());
}
resource_manager.reset();
@@ -589,7 +741,7 @@ TEST_F(PrioritizedResourceTest, TextureMovedToNewManager) {
texture->SetTextureManager(NULL);
{
DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
+ impl_thread_and_main_thread_blocked(&proxy_);
resource_manager_one->ClearAllMemory(ResourceProvider());
}
resource_manager_one.reset();
@@ -606,7 +758,7 @@ TEST_F(PrioritizedResourceTest, TextureMovedToNewManager) {
EXPECT_TRUE(texture->have_backing_texture());
DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
+ impl_thread_and_main_thread_blocked(&proxy_);
resource_manager_two->ClearAllMemory(ResourceProvider());
}
@@ -663,7 +815,7 @@ TEST_F(PrioritizedResourceTest,
resource_manager->MaxMemoryNeededBytes());
DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
+ impl_thread_and_main_thread_blocked(&proxy_);
resource_manager->ClearAllMemory(ResourceProvider());
}
@@ -711,7 +863,7 @@ TEST_F(PrioritizedResourceTest,
resource_manager->MaxMemoryNeededBytes());
DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
+ impl_thread_and_main_thread_blocked(&proxy_);
resource_manager->ClearAllMemory(ResourceProvider());
}
@@ -763,7 +915,7 @@ TEST_F(PrioritizedResourceTest,
resource_manager->MemoryAboveCutoffBytes());
DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
+ impl_thread_and_main_thread_blocked(&proxy_);
resource_manager->ClearAllMemory(ResourceProvider());
}
@@ -815,7 +967,7 @@ TEST_F(PrioritizedResourceTest, RequestLateBackingsSorting) {
EXPECT_FALSE(TextureBackingIsAbovePriorityCutoff(textures[i].get()));
DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
+ impl_thread_and_main_thread_blocked(&proxy_);
resource_manager->ClearAllMemory(ResourceProvider());
}
@@ -841,7 +993,7 @@ TEST_F(PrioritizedResourceTest, ClearUploadsToEvictedResources) {
ResourceUpdateQueue queue;
DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
+ impl_thread_and_main_thread_blocked(&proxy_);
for (size_t i = 0; i < kMaxTextures; ++i) {
const ResourceUpdate upload = ResourceUpdate::Create(
textures[i].get(), NULL, gfx::Rect(), gfx::Rect(), gfx::Vector2d());
@@ -934,7 +1086,7 @@ TEST_F(PrioritizedResourceTest, UsageStatistics) {
// Push priorities to backings, and verify we see the new values.
{
DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
+ impl_thread_and_main_thread_blocked(&proxy_);
resource_manager->PushTexturePrioritiesToBackings();
EXPECT_EQ(TexturesMemorySize(2), resource_manager->MemoryUseBytes());
EXPECT_EQ(TexturesMemorySize(3), resource_manager->MemoryVisibleBytes());
@@ -943,7 +1095,7 @@ TEST_F(PrioritizedResourceTest, UsageStatistics) {
}
DebugScopedSetImplThreadAndMainThreadBlocked
- impl_thread_and_main_thread_blocked(&proxy_);
+ impl_thread_and_main_thread_blocked(&proxy_);
resource_manager->ClearAllMemory(ResourceProvider());
}
diff --git a/cc/resources/prioritized_tile_set_unittest.cc b/cc/resources/prioritized_tile_set_unittest.cc
index 37c9cc15a0..4bf27fb88c 100644
--- a/cc/resources/prioritized_tile_set_unittest.cc
+++ b/cc/resources/prioritized_tile_set_unittest.cc
@@ -57,9 +57,9 @@ class PrioritizedTileSetTest : public testing::Test {
CHECK(output_surface_->BindToClient(&output_surface_client_));
resource_provider_ =
- ResourceProvider::Create(output_surface_.get(), 0, false).Pass();
- tile_manager_.reset(new FakeTileManager(&tile_manager_client_,
- resource_provider_.get()));
+ ResourceProvider::Create(output_surface_.get(), NULL, 0, false).Pass();
+ tile_manager_.reset(
+ new FakeTileManager(&tile_manager_client_, resource_provider_.get()));
picture_pile_ = FakePicturePileImpl::CreatePile();
}
diff --git a/cc/resources/raster_worker_pool.cc b/cc/resources/raster_worker_pool.cc
index 43bc725d1e..67c548f19d 100644
--- a/cc/resources/raster_worker_pool.cc
+++ b/cc/resources/raster_worker_pool.cc
@@ -140,6 +140,7 @@ class RasterWorkerPoolTaskImpl : public internal::RasterWorkerPoolTask {
break;
case LUMINANCE_8:
case RGB_565:
+ case ETC1:
NOTREACHED();
break;
}
diff --git a/cc/resources/raster_worker_pool_unittest.cc b/cc/resources/raster_worker_pool_unittest.cc
index 61cb324f77..023be7907a 100644
--- a/cc/resources/raster_worker_pool_unittest.cc
+++ b/cc/resources/raster_worker_pool_unittest.cc
@@ -68,7 +68,7 @@ class RasterWorkerPoolTest : public testing::Test,
CHECK(output_surface_->BindToClient(&output_surface_client_));
resource_provider_ =
- ResourceProvider::Create(output_surface_.get(), 0, false).Pass();
+ ResourceProvider::Create(output_surface_.get(), NULL, 0, false).Pass();
}
virtual ~RasterWorkerPoolTest() {
resource_provider_.reset();
diff --git a/cc/resources/resource.h b/cc/resources/resource.h
index 2650a0c8b6..e9dd393a6a 100644
--- a/cc/resources/resource.h
+++ b/cc/resources/resource.h
@@ -26,7 +26,8 @@ class CC_EXPORT Resource {
size_t bytes() const;
inline static size_t MemorySizeBytes(gfx::Size size, ResourceFormat format) {
- return BytesPerPixel(format) * size.width() * size.height();
+ DCHECK_EQ(0u, (BitsPerPixel(format) * size.width() * size.height()) % 8);
+ return (BitsPerPixel(format) * size.width() * size.height()) / 8;
}
protected:
diff --git a/cc/resources/resource_format.cc b/cc/resources/resource_format.cc
index edd7b06a32..35617174cb 100644
--- a/cc/resources/resource_format.cc
+++ b/cc/resources/resource_format.cc
@@ -13,6 +13,7 @@ SkBitmap::Config SkBitmapConfig(ResourceFormat format) {
case RGBA_8888:
case BGRA_8888:
return SkBitmap::kARGB_8888_Config;
+ case ETC1:
case LUMINANCE_8:
case RGB_565:
NOTREACHED();
diff --git a/cc/resources/resource_format.h b/cc/resources/resource_format.h
index 47f9a50571..54061394ff 100644
--- a/cc/resources/resource_format.h
+++ b/cc/resources/resource_format.h
@@ -17,7 +17,8 @@ enum ResourceFormat {
BGRA_8888,
LUMINANCE_8,
RGB_565,
- RESOURCE_FORMAT_MAX = RGB_565,
+ ETC1,
+ RESOURCE_FORMAT_MAX = ETC1,
};
SkBitmap::Config SkBitmapConfig(ResourceFormat format);
diff --git a/cc/resources/resource_provider.cc b/cc/resources/resource_provider.cc
index d76fc4b45c..874fe3f641 100644
--- a/cc/resources/resource_provider.cc
+++ b/cc/resources/resource_provider.cc
@@ -8,6 +8,7 @@
#include <limits>
#include "base/containers/hash_tables.h"
+#include "base/debug/trace_event.h"
#include "base/stl_util.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
@@ -15,6 +16,7 @@
#include "cc/output/gl_renderer.h" // For the GLC() macro.
#include "cc/resources/platform_color.h"
#include "cc/resources/returned_resource.h"
+#include "cc/resources/shared_bitmap_manager.h"
#include "cc/resources/transferable_resource.h"
#include "cc/scheduler/texture_uploader.h"
#include "gpu/GLES2/gl2extchromium.h"
@@ -45,6 +47,7 @@ GLenum TextureToStorageFormat(ResourceFormat format) {
case RGBA_4444:
case LUMINANCE_8:
case RGB_565:
+ case ETC1:
NOTREACHED();
break;
}
@@ -60,6 +63,7 @@ bool IsFormatSupportedForStorage(ResourceFormat format) {
case RGBA_4444:
case LUMINANCE_8:
case RGB_565:
+ case ETC1:
return false;
}
return false;
@@ -118,7 +122,8 @@ ResourceProvider::Resource::Resource()
lost(false),
hint(TextureUsageAny),
type(static_cast<ResourceType>(0)),
- format(RGBA_8888) {}
+ format(RGBA_8888),
+ shared_bitmap(NULL) {}
ResourceProvider::Resource::~Resource() {}
@@ -159,11 +164,13 @@ ResourceProvider::Resource::Resource(unsigned texture_id,
lost(false),
hint(hint),
type(GLTexture),
- format(format) {
+ format(format),
+ shared_bitmap(NULL) {
DCHECK(wrap_mode == GL_CLAMP_TO_EDGE || wrap_mode == GL_REPEAT);
}
ResourceProvider::Resource::Resource(uint8_t* pixels,
+ SharedBitmap* bitmap,
gfx::Size size,
GLenum filter,
GLint wrap_mode)
@@ -196,7 +203,8 @@ ResourceProvider::Resource::Resource(uint8_t* pixels,
lost(false),
hint(TextureUsageAny),
type(Bitmap),
- format(RGBA_8888) {
+ format(RGBA_8888),
+ shared_bitmap(bitmap) {
DCHECK(wrap_mode == GL_CLAMP_TO_EDGE || wrap_mode == GL_REPEAT);
}
@@ -206,10 +214,12 @@ ResourceProvider::Child::~Child() {}
scoped_ptr<ResourceProvider> ResourceProvider::Create(
OutputSurface* output_surface,
+ SharedBitmapManager* shared_bitmap_manager,
int highp_threshold_min,
bool use_rgba_4444_texture_format) {
scoped_ptr<ResourceProvider> resource_provider(
new ResourceProvider(output_surface,
+ shared_bitmap_manager,
highp_threshold_min,
use_rgba_4444_texture_format));
@@ -311,10 +321,19 @@ ResourceProvider::ResourceId ResourceProvider::CreateGLTexture(
ResourceProvider::ResourceId ResourceProvider::CreateBitmap(gfx::Size size) {
DCHECK(thread_checker_.CalledOnValidThread());
- uint8_t* pixels = new uint8_t[4 * size.GetArea()];
+ scoped_ptr<SharedBitmap> bitmap;
+ if (shared_bitmap_manager_)
+ bitmap = shared_bitmap_manager_->AllocateSharedBitmap(size);
+
+ uint8_t* pixels;
+ if (bitmap)
+ pixels = bitmap->pixels();
+ else
+ pixels = new uint8_t[4 * size.GetArea()];
ResourceId id = next_id_++;
- Resource resource(pixels, size, GL_LINEAR, GL_CLAMP_TO_EDGE);
+ Resource resource(
+ pixels, bitmap.release(), size, GL_LINEAR, GL_CLAMP_TO_EDGE);
resource.allocated = true;
resources_[id] = resource;
return id;
@@ -375,8 +394,16 @@ ResourceProvider::ResourceId ResourceProvider::CreateResourceFromTextureMailbox(
base::SharedMemory* shared_memory = mailbox.shared_memory();
DCHECK(shared_memory->memory());
uint8_t* pixels = reinterpret_cast<uint8_t*>(shared_memory->memory());
- resource = Resource(
- pixels, mailbox.shared_memory_size(), GL_LINEAR, GL_CLAMP_TO_EDGE);
+ scoped_ptr<SharedBitmap> shared_bitmap;
+ if (shared_bitmap_manager_) {
+ shared_bitmap =
+ shared_bitmap_manager_->GetBitmapForSharedMemory(shared_memory);
+ }
+ resource = Resource(pixels,
+ shared_bitmap.release(),
+ mailbox.shared_memory_size(),
+ GL_LINEAR,
+ GL_CLAMP_TO_EDGE);
}
resource.external = true;
resource.allocated = true;
@@ -407,8 +434,9 @@ void ResourceProvider::DeleteResource(ResourceId id) {
void ResourceProvider::DeleteResourceInternal(ResourceMap::iterator it,
DeleteStyle style) {
+ TRACE_EVENT0("cc", "ResourceProvider::DeleteResourceInternal");
Resource* resource = &it->second;
- bool lost_resource = lost_output_surface_ || resource->lost;
+ bool lost_resource = resource->lost;
DCHECK(resource->exported_count == 0 || style != Normal);
if (style == ForShutdown && resource->exported_count > 0)
@@ -438,6 +466,7 @@ void ResourceProvider::DeleteResourceInternal(ResourceMap::iterator it,
if (resource->mailbox.IsValid() && resource->external) {
unsigned sync_point = resource->mailbox.sync_point();
if (resource->mailbox.IsTexture()) {
+ lost_resource |= lost_output_surface_;
WebGraphicsContext3D* context3d = Context3d();
DCHECK(context3d);
if (resource->gl_id)
@@ -450,10 +479,16 @@ void ResourceProvider::DeleteResourceInternal(ResourceMap::iterator it,
if (resource->pixels && shared_memory) {
DCHECK(shared_memory->memory() == resource->pixels);
resource->pixels = NULL;
+ delete resource->shared_bitmap;
+ resource->shared_bitmap = NULL;
}
}
resource->release_callback.Run(sync_point, lost_resource);
}
+ if (resource->shared_bitmap) {
+ delete resource->shared_bitmap;
+ resource->pixels = NULL;
+ }
if (resource->pixels)
delete[] resource->pixels;
if (resource->pixel_buffer)
@@ -754,9 +789,11 @@ ResourceProvider::ScopedWriteLockSoftware::~ScopedWriteLockSoftware() {
}
ResourceProvider::ResourceProvider(OutputSurface* output_surface,
+ SharedBitmapManager* shared_bitmap_manager,
int highp_threshold_min,
bool use_rgba_4444_texture_format)
: output_surface_(output_surface),
+ shared_bitmap_manager_(shared_bitmap_manager),
lost_output_surface_(false),
highp_threshold_min_(highp_threshold_min),
next_id_(1),
@@ -803,6 +840,7 @@ bool ResourceProvider::InitializeGL() {
use_texture_storage_ext_ = caps.texture_storage;
use_shallow_flush_ = caps.shallow_flush;
use_texture_usage_hint_ = caps.texture_usage;
+ use_compressed_texture_etc1_ = caps.texture_format_etc1;
texture_uploader_ =
TextureUploader::Create(context3d, use_map_sub, use_shallow_flush_);
@@ -876,17 +914,15 @@ void ResourceProvider::PrepareSendToParent(const ResourceIdArray& resources,
TransferableResourceArray* list) {
DCHECK(thread_checker_.CalledOnValidThread());
WebGraphicsContext3D* context3d = Context3d();
- if (!context3d || !context3d->makeContextCurrent()) {
- // TODO(skaslev): Implement this path for software compositing.
- return;
- }
+ if (context3d)
+ context3d->makeContextCurrent();
bool need_sync_point = false;
for (ResourceIdArray::const_iterator it = resources.begin();
it != resources.end();
++it) {
TransferableResource resource;
TransferResource(context3d, *it, &resource);
- if (!resource.sync_point)
+ if (!resource.sync_point && !resource.is_software)
need_sync_point = true;
++resources_.find(*it)->second.exported_count;
list->push_back(resource);
@@ -906,10 +942,8 @@ void ResourceProvider::ReceiveFromChild(
int child, const TransferableResourceArray& resources) {
DCHECK(thread_checker_.CalledOnValidThread());
WebGraphicsContext3D* context3d = Context3d();
- if (!context3d || !context3d->makeContextCurrent()) {
- // TODO(skaslev): Implement this path for software compositing.
- return;
- }
+ if (context3d)
+ context3d->makeContextCurrent();
Child& child_info = children_.find(child)->second;
for (TransferableResourceArray::const_iterator it = resources.begin();
it != resources.end();
@@ -920,34 +954,58 @@ void ResourceProvider::ReceiveFromChild(
resources_[resource_in_map_it->second].imported_count++;
continue;
}
- unsigned texture_id;
- // NOTE: If the parent is a browser and the child a renderer, the parent
- // is not supposed to have its context wait, because that could induce
- // deadlocks and/or security issues. The caller is responsible for
- // waiting asynchronously, and resetting sync_point before calling this.
- // However if the parent is a renderer (e.g. browser tag), it may be ok
- // (and is simpler) to wait.
- if (it->sync_point)
- GLC(context3d, context3d->waitSyncPoint(it->sync_point));
- GLC(context3d, texture_id = context3d->createTexture());
- GLC(context3d, context3d->bindTexture(it->target, texture_id));
- GLC(context3d,
- context3d->consumeTextureCHROMIUM(it->target, it->mailbox.name));
+
+ scoped_ptr<SharedBitmap> bitmap;
+ uint8_t* pixels = NULL;
+ if (it->is_software) {
+ if (shared_bitmap_manager_)
+ bitmap = shared_bitmap_manager_->GetSharedBitmapFromId(it->size,
+ it->mailbox);
+ if (bitmap)
+ pixels = bitmap->pixels();
+ }
+
+ if ((!it->is_software && !context3d) || (it->is_software && !pixels)) {
+ TRACE_EVENT0("cc", "ResourceProvider::ReceiveFromChild dropping invalid");
+ ReturnedResourceArray to_return;
+ to_return.push_back(it->ToReturnedResource());
+ child_info.return_callback.Run(to_return);
+ continue;
+ }
+
ResourceId local_id = next_id_++;
- Resource resource(texture_id,
- it->size,
- it->target,
- it->filter,
- 0,
- GL_CLAMP_TO_EDGE,
- TextureUsageAny,
- it->format);
- resource.mailbox.SetName(it->mailbox);
+ Resource& resource = resources_[local_id];
+ if (it->is_software) {
+ resource = Resource(
+ pixels, bitmap.release(), it->size, GL_LINEAR, GL_CLAMP_TO_EDGE);
+ } else {
+ unsigned texture_id;
+ // NOTE: If the parent is a browser and the child a renderer, the parent
+ // is not supposed to have its context wait, because that could induce
+ // deadlocks and/or security issues. The caller is responsible for
+ // waiting asynchronously, and resetting sync_point before calling this.
+ // However if the parent is a renderer (e.g. browser tag), it may be ok
+ // (and is simpler) to wait.
+ if (it->sync_point)
+ GLC(context3d, context3d->waitSyncPoint(it->sync_point));
+ GLC(context3d, texture_id = context3d->createTexture());
+ GLC(context3d, context3d->bindTexture(it->target, texture_id));
+ GLC(context3d,
+ context3d->consumeTextureCHROMIUM(it->target, it->mailbox.name));
+ resource = Resource(texture_id,
+ it->size,
+ it->target,
+ it->filter,
+ 0,
+ GL_CLAMP_TO_EDGE,
+ TextureUsageAny,
+ it->format);
+ resource.mailbox.SetName(it->mailbox);
+ }
resource.child_id = child;
// Don't allocate a texture for a child.
resource.allocated = true;
resource.imported_count = 1;
- resources_[local_id] = resource;
child_info.parent_to_child_map[local_id] = it->id;
child_info.child_to_parent_map[it->id] = local_id;
}
@@ -997,10 +1055,8 @@ void ResourceProvider::ReceiveReturnsFromParent(
const ReturnedResourceArray& resources) {
DCHECK(thread_checker_.CalledOnValidThread());
WebGraphicsContext3D* context3d = Context3d();
- if (!context3d || !context3d->makeContextCurrent()) {
- // TODO(skaslev): Implement this path for software compositing.
- return;
- }
+ if (context3d)
+ context3d->makeContextCurrent();
int child_id = 0;
Child* child_info = NULL;
@@ -1043,7 +1099,7 @@ void ResourceProvider::ReceiveReturnsFromParent(
if (resource->gl_id) {
if (returned.sync_point)
GLC(context3d, context3d->waitSyncPoint(returned.sync_point));
- } else {
+ } else if (!resource->shared_bitmap) {
resource->mailbox =
TextureMailbox(resource->mailbox.name(), returned.sync_point);
}
@@ -1096,10 +1152,10 @@ void ResourceProvider::TransferResource(WebGraphicsContext3D* context,
resource->filter = source->filter;
resource->size = source->size;
- // TODO(skaslev) Implement this path for shared memory resources.
- DCHECK(!source->mailbox.IsSharedMemory());
-
- if (!source->mailbox.IsTexture()) {
+ if (source->shared_bitmap) {
+ resource->mailbox = source->shared_bitmap->id();
+ resource->is_software = true;
+ } else if (!source->mailbox.IsValid()) {
// This is a resource allocated by the compositor, we need to produce it.
// Don't set a sync point, the caller will do it.
DCHECK(source->gl_id);
@@ -1110,6 +1166,7 @@ void ResourceProvider::TransferResource(WebGraphicsContext3D* context,
resource->mailbox.name));
source->mailbox.SetName(resource->mailbox);
} else {
+ DCHECK(source->mailbox.IsTexture());
// This is either an external resource, or a compositor resource that we
// already exported. Make sure to forward the sync point that we were given.
resource->mailbox = source->mailbox.name();
@@ -1129,10 +1186,8 @@ void ResourceProvider::DeleteAndReturnUnusedResourcesToChild(
return;
WebGraphicsContext3D* context3d = Context3d();
- if (!context3d || !context3d->makeContextCurrent()) {
- // TODO(skaslev): Implement this path for software compositing.
- return;
- }
+ if (context3d)
+ context3d->makeContextCurrent();
ReturnedResourceArray to_return;
@@ -1152,7 +1207,8 @@ void ResourceProvider::DeleteAndReturnUnusedResourcesToChild(
ResourceId child_id = child_info->parent_to_child_map[local_id];
DCHECK(child_info->child_to_parent_map.count(child_id));
- bool is_lost = resource.lost || lost_output_surface_;
+ bool is_lost =
+ resource.lost || (!resource.shared_bitmap && lost_output_surface_);
if (resource.exported_count > 0) {
if (style != ForShutdown) {
// Defer this until we receive the resource back from the parent.
@@ -1164,7 +1220,7 @@ void ResourceProvider::DeleteAndReturnUnusedResourcesToChild(
is_lost = true;
}
- if (resource.filter != resource.original_filter) {
+ if (context3d && resource.filter != resource.original_filter) {
DCHECK(resource.target);
DCHECK(resource.gl_id);
@@ -1182,7 +1238,7 @@ void ResourceProvider::DeleteAndReturnUnusedResourcesToChild(
ReturnedResource returned;
returned.id = child_id;
returned.sync_point = resource.mailbox.sync_point();
- if (!returned.sync_point)
+ if (!returned.sync_point && !resource.shared_bitmap)
need_sync_point = true;
returned.count = resource.imported_count;
returned.lost = is_lost;
@@ -1194,6 +1250,7 @@ void ResourceProvider::DeleteAndReturnUnusedResourcesToChild(
DeleteResourceInternal(it, style);
}
if (need_sync_point) {
+ DCHECK(context3d);
unsigned int sync_point = context3d->insertSyncPoint();
for (size_t i = 0; i < to_return.size(); ++i) {
if (!to_return[i].sync_point)
@@ -1210,6 +1267,7 @@ void ResourceProvider::AcquirePixelBuffer(ResourceId id) {
DCHECK(!resource->external);
DCHECK_EQ(resource->exported_count, 0);
DCHECK(!resource->image_id);
+ DCHECK_NE(ETC1, resource->format);
if (resource->type == GLTexture) {
WebGraphicsContext3D* context3d = Context3d();
@@ -1219,7 +1277,7 @@ void ResourceProvider::AcquirePixelBuffer(ResourceId id) {
context3d->bindBuffer(
GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM,
resource->gl_pixel_buffer_id);
- unsigned bytes_per_pixel = BytesPerPixel(resource->format);
+ unsigned bytes_per_pixel = BitsPerPixel(resource->format) / 8;
context3d->bufferData(
GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM,
resource->size.height() * RoundUp(bytes_per_pixel
@@ -1542,15 +1600,19 @@ void ResourceProvider::LazyAllocate(Resource* resource) {
size.width(),
size.height()));
} else {
- GLC(context3d, context3d->texImage2D(GL_TEXTURE_2D,
- 0,
- GLInternalFormat(format),
- size.width(),
- size.height(),
- 0,
- GLDataFormat(format),
- GLDataType(format),
- NULL));
+ // ETC1 does not support preallocation.
+ if (format != ETC1) {
+ GLC(context3d,
+ context3d->texImage2D(GL_TEXTURE_2D,
+ 0,
+ GLInternalFormat(format),
+ size.width(),
+ size.height(),
+ 0,
+ GLDataFormat(format),
+ GLDataType(format),
+ NULL));
+ }
}
}
@@ -1646,6 +1708,16 @@ int ResourceProvider::GetImageStride(ResourceId id) {
return stride;
}
+base::SharedMemory* ResourceProvider::GetSharedMemory(ResourceId id) {
+ Resource* resource = GetResource(id);
+ DCHECK(!resource->external);
+ DCHECK_EQ(resource->exported_count, 0);
+
+ if (!resource->shared_bitmap)
+ return NULL;
+ return resource->shared_bitmap->memory();
+}
+
GLint ResourceProvider::GetActiveTextureUnit(WebGraphicsContext3D* context) {
GLint active_unit = 0;
context->getIntegerv(GL_ACTIVE_TEXTURE, &active_unit);
diff --git a/cc/resources/resource_provider.h b/cc/resources/resource_provider.h
index b8cb399286..23f1414fa0 100644
--- a/cc/resources/resource_provider.h
+++ b/cc/resources/resource_provider.h
@@ -39,6 +39,8 @@ class Vector2d;
}
namespace cc {
+class SharedBitmap;
+class SharedBitmapManager;
class TextureUploader;
// This class is not thread-safe and can only be called from the thread it was
@@ -59,9 +61,11 @@ class CC_EXPORT ResourceProvider {
Bitmap,
};
- static scoped_ptr<ResourceProvider> Create(OutputSurface* output_surface,
- int highp_threshold_min,
- bool use_rgba_4444_texture_format);
+ static scoped_ptr<ResourceProvider> Create(
+ OutputSurface* output_surface,
+ SharedBitmapManager* shared_bitmap_manager,
+ int highp_threshold_min,
+ bool use_rgba_4444_texture_format);
virtual ~ResourceProvider();
void InitializeSoftware();
@@ -320,6 +324,8 @@ class CC_EXPORT ResourceProvider {
// Returns the stride for the image.
int GetImageStride(ResourceId id);
+ base::SharedMemory* GetSharedMemory(ResourceId id);
+
// For tests only! This prevents detecting uninitialized reads.
// Use SetPixels or LockForWrite to allocate implicitly.
void AllocateForTesting(ResourceId id);
@@ -359,6 +365,7 @@ class CC_EXPORT ResourceProvider {
TextureUsageHint hint,
ResourceFormat format);
Resource(uint8_t* pixels,
+ SharedBitmap* bitmap,
gfx::Size size,
GLenum filter,
GLint wrap_mode);
@@ -398,6 +405,7 @@ class CC_EXPORT ResourceProvider {
TextureUsageHint hint;
ResourceType type;
ResourceFormat format;
+ SharedBitmap* shared_bitmap;
};
typedef base::hash_map<ResourceId, Resource> ResourceMap;
@@ -422,6 +430,7 @@ class CC_EXPORT ResourceProvider {
}
ResourceProvider(OutputSurface* output_surface,
+ SharedBitmapManager* shared_bitmap_manager,
int highp_threshold_min,
bool use_rgba_4444_texture_format);
@@ -461,6 +470,7 @@ class CC_EXPORT ResourceProvider {
WebKit::WebGraphicsContext3D* Context3d() const;
OutputSurface* output_surface_;
+ SharedBitmapManager* shared_bitmap_manager_;
bool lost_output_surface_;
int highp_threshold_min_;
ResourceId next_id_;
@@ -472,6 +482,7 @@ class CC_EXPORT ResourceProvider {
bool use_texture_storage_ext_;
bool use_texture_usage_hint_;
bool use_shallow_flush_;
+ bool use_compressed_texture_etc1_;
scoped_ptr<TextureUploader> texture_uploader_;
int max_texture_size_;
ResourceFormat best_texture_format_;
@@ -487,16 +498,17 @@ class CC_EXPORT ResourceProvider {
// TODO(epenner): Move these format conversions to resource_format.h
// once that builds on mac (npapi.h currently #includes OpenGL.h).
-inline unsigned BytesPerPixel(ResourceFormat format) {
+inline unsigned BitsPerPixel(ResourceFormat format) {
DCHECK_LE(format, RESOURCE_FORMAT_MAX);
- static const unsigned format_bytes_per_pixel[RESOURCE_FORMAT_MAX + 1] = {
- 4, // RGBA_8888
- 2, // RGBA_4444
- 4, // BGRA_8888
- 1, // LUMINANCE_8
- 2 // RGB_565
+ static const unsigned format_bits_per_pixel[RESOURCE_FORMAT_MAX + 1] = {
+ 32, // RGBA_8888
+ 16, // RGBA_4444
+ 32, // BGRA_8888
+ 8, // LUMINANCE_8
+ 16, // RGB_565,
+ 4 // ETC1
};
- return format_bytes_per_pixel[format];
+ return format_bits_per_pixel[format];
}
inline GLenum GLDataType(ResourceFormat format) {
@@ -506,7 +518,8 @@ inline GLenum GLDataType(ResourceFormat format) {
GL_UNSIGNED_SHORT_4_4_4_4, // RGBA_4444
GL_UNSIGNED_BYTE, // BGRA_8888
GL_UNSIGNED_BYTE, // LUMINANCE_8
- GL_UNSIGNED_SHORT_5_6_5 // RGB_565
+ GL_UNSIGNED_SHORT_5_6_5, // RGB_565,
+ GL_UNSIGNED_BYTE // ETC1
};
return format_gl_data_type[format];
}
@@ -514,11 +527,12 @@ inline GLenum GLDataType(ResourceFormat format) {
inline GLenum GLDataFormat(ResourceFormat format) {
DCHECK_LE(format, RESOURCE_FORMAT_MAX);
static const unsigned format_gl_data_format[RESOURCE_FORMAT_MAX + 1] = {
- GL_RGBA, // RGBA_8888
- GL_RGBA, // RGBA_4444
- GL_BGRA_EXT, // BGRA_8888
- GL_LUMINANCE, // LUMINANCE_8
- GL_RGB // RGB_565
+ GL_RGBA, // RGBA_8888
+ GL_RGBA, // RGBA_4444
+ GL_BGRA_EXT, // BGRA_8888
+ GL_LUMINANCE, // LUMINANCE_8
+ GL_RGB, // RGB_565
+ GL_ETC1_RGB8_OES // ETC1
};
return format_gl_data_format[format];
}
diff --git a/cc/resources/resource_provider_unittest.cc b/cc/resources/resource_provider_unittest.cc
index 1e2318361b..a0b65234e5 100644
--- a/cc/resources/resource_provider_unittest.cc
+++ b/cc/resources/resource_provider_unittest.cc
@@ -15,6 +15,7 @@
#include "cc/debug/test_web_graphics_context_3d.h"
#include "cc/output/output_surface.h"
#include "cc/resources/returned_resource.h"
+#include "cc/resources/shared_bitmap_manager.h"
#include "cc/resources/single_release_callback.h"
#include "cc/test/fake_output_surface.h"
#include "cc/test/fake_output_surface_client.h"
@@ -44,6 +45,41 @@ namespace {
static void EmptyReleaseCallback(unsigned sync_point, bool lost_resource) {}
+static void SharedMemoryReleaseCallback(scoped_ptr<base::SharedMemory> memory,
+ unsigned sync_point,
+ bool lost_resource) {}
+
+static void ReleaseTextureMailbox(unsigned* release_sync_point,
+ bool* release_lost_resource,
+ unsigned sync_point,
+ bool lost_resource) {
+ *release_sync_point = sync_point;
+ *release_lost_resource = lost_resource;
+}
+
+static void ReleaseSharedMemoryCallback(
+ scoped_ptr<base::SharedMemory> shared_memory,
+ bool* release_called,
+ unsigned* release_sync_point,
+ bool* lost_resource_result,
+ unsigned sync_point,
+ bool lost_resource) {
+ *release_called = true;
+ *release_sync_point = sync_point;
+ *lost_resource_result = lost_resource;
+}
+
+static scoped_ptr<base::SharedMemory> CreateAndFillSharedMemory(
+ gfx::Size size,
+ uint32_t value) {
+ scoped_ptr<base::SharedMemory> shared_memory(new base::SharedMemory);
+ CHECK(shared_memory->CreateAndMapAnonymous(4 * size.GetArea()));
+ uint32_t* pixels = reinterpret_cast<uint32_t*>(shared_memory->memory());
+ CHECK(pixels);
+ std::fill_n(pixels, size.GetArea(), value);
+ return shared_memory.Pass();
+}
+
class TextureStateTrackingContext : public TestWebGraphicsContext3D {
public:
MOCK_METHOD2(bindTexture, void(WGC3Denum target, WebGLId texture));
@@ -196,8 +232,11 @@ class ResourceProviderContext : public TestWebGraphicsContext3D {
CheckTextureIsBound(target);
ASSERT_EQ(static_cast<unsigned>(GL_TEXTURE_2D), target);
ASSERT_FALSE(level);
- ASSERT_EQ(GLDataFormat(BoundTexture(target)->format), format);
ASSERT_EQ(static_cast<unsigned>(GL_UNSIGNED_BYTE), type);
+ {
+ base::AutoLock lock_for_texture_access(namespace_->lock);
+ ASSERT_EQ(GLDataFormat(BoundTexture(target)->format), format);
+ }
ASSERT_TRUE(pixels);
SetPixels(xoffset, yoffset, width, height, pixels);
}
@@ -205,6 +244,7 @@ class ResourceProviderContext : public TestWebGraphicsContext3D {
virtual void texParameteri(WGC3Denum target, WGC3Denum param, WGC3Dint value)
OVERRIDE {
CheckTextureIsBound(target);
+ base::AutoLock lock_for_texture_access(namespace_->lock);
scoped_refptr<TestTexture> texture = BoundTexture(target);
if (param != GL_TEXTURE_MIN_FILTER)
return;
@@ -224,6 +264,7 @@ class ResourceProviderContext : public TestWebGraphicsContext3D {
// haven't waited on that sync point.
scoped_ptr<PendingProduceTexture> pending(new PendingProduceTexture);
memcpy(pending->mailbox, mailbox, sizeof(pending->mailbox));
+ base::AutoLock lock_for_texture_access(namespace_->lock);
pending->texture = BoundTexture(target);
pending_produce_textures_.push_back(pending.Pass());
}
@@ -231,14 +272,15 @@ class ResourceProviderContext : public TestWebGraphicsContext3D {
virtual void consumeTextureCHROMIUM(WGC3Denum target,
const WGC3Dbyte* mailbox) OVERRIDE {
CheckTextureIsBound(target);
+ base::AutoLock lock_for_texture_access(namespace_->lock);
scoped_refptr<TestTexture> texture =
shared_data_->ConsumeTexture(mailbox, last_waited_sync_point_);
- base::AutoLock lock(namespace_->lock);
namespace_->textures.Replace(BoundTextureId(target), texture);
}
void GetPixels(gfx::Size size, ResourceFormat format, uint8_t* pixels) {
CheckTextureIsBound(GL_TEXTURE_2D);
+ base::AutoLock lock_for_texture_access(namespace_->lock);
scoped_refptr<TestTexture> texture = BoundTexture(GL_TEXTURE_2D);
ASSERT_EQ(texture->size, size);
ASSERT_EQ(texture->format, format);
@@ -247,11 +289,13 @@ class ResourceProviderContext : public TestWebGraphicsContext3D {
WGC3Denum GetTextureFilter() {
CheckTextureIsBound(GL_TEXTURE_2D);
+ base::AutoLock lock_for_texture_access(namespace_->lock);
return BoundTexture(GL_TEXTURE_2D)->filter;
}
scoped_refptr<TestTexture> BoundTexture(WGC3Denum target) {
- base::AutoLock lock(namespace_->lock);
+ // The caller is expected to lock the namespace for texture access.
+ namespace_->lock.AssertAcquired();
return namespace_->textures.TextureForId(BoundTextureId(target));
}
@@ -276,6 +320,7 @@ class ResourceProviderContext : public TestWebGraphicsContext3D {
texture_format = BGRA_8888;
break;
}
+ base::AutoLock lock_for_texture_access(namespace_->lock);
BoundTexture(GL_TEXTURE_2D)->Reallocate(size, texture_format);
}
@@ -285,6 +330,7 @@ class ResourceProviderContext : public TestWebGraphicsContext3D {
int height,
const void* pixels) {
CheckTextureIsBound(GL_TEXTURE_2D);
+ base::AutoLock lock_for_texture_access(namespace_->lock);
scoped_refptr<TestTexture> texture = BoundTexture(GL_TEXTURE_2D);
ASSERT_TRUE(texture->data.get());
ASSERT_TRUE(xoffset >= 0 && xoffset + width <= texture->size.width());
@@ -313,6 +359,55 @@ class ResourceProviderContext : public TestWebGraphicsContext3D {
PendingProduceTextureList pending_produce_textures_;
};
+void FreeSharedBitmap(SharedBitmap* shared_bitmap) {
+ delete shared_bitmap->memory();
+}
+
+void IgnoreSharedBitmap(SharedBitmap* shared_bitmap) {}
+
+class TestSharedBitmapManager : public SharedBitmapManager {
+ public:
+ TestSharedBitmapManager() : count_(0) {}
+ virtual ~TestSharedBitmapManager() {}
+
+ virtual scoped_ptr<SharedBitmap> AllocateSharedBitmap(gfx::Size size)
+ OVERRIDE {
+ scoped_ptr<base::SharedMemory> memory(new base::SharedMemory);
+ memory->CreateAndMapAnonymous(size.GetArea() * 4);
+ int8 name[64] = { 0 };
+ name[0] = count_++;
+ SharedBitmapId id;
+ id.SetName(name);
+ bitmap_map_[id] = memory.get();
+ return scoped_ptr<SharedBitmap>(
+ new SharedBitmap(memory.release(), id, base::Bind(&FreeSharedBitmap)));
+ }
+
+ virtual scoped_ptr<SharedBitmap> GetSharedBitmapFromId(
+ gfx::Size,
+ const SharedBitmapId& id) OVERRIDE {
+ if (bitmap_map_.find(id) == bitmap_map_.end())
+ return scoped_ptr<SharedBitmap>();
+ return scoped_ptr<SharedBitmap>(
+ new SharedBitmap(bitmap_map_[id], id, base::Bind(&IgnoreSharedBitmap)));
+ }
+
+ virtual scoped_ptr<SharedBitmap> GetBitmapForSharedMemory(
+ base::SharedMemory* memory) OVERRIDE {
+ int8 name[64] = { 0 };
+ name[0] = count_++;
+ SharedBitmapId id;
+ id.SetName(name);
+ bitmap_map_[id] = memory;
+ return scoped_ptr<SharedBitmap>(
+ new SharedBitmap(memory, id, base::Bind(&IgnoreSharedBitmap)));
+ }
+
+ private:
+ int count_;
+ std::map<SharedBitmapId, base::SharedMemory*> bitmap_map_;
+};
+
void GetResourcePixels(ResourceProvider* resource_provider,
ResourceProviderContext* context,
ResourceProvider::ResourceId id,
@@ -346,7 +441,8 @@ class ResourceProviderTest
public:
ResourceProviderTest()
: shared_data_(ContextSharedData::Create()),
- context3d_(NULL) {
+ context3d_(NULL),
+ child_context_(NULL) {
switch (GetParam()) {
case ResourceProvider::GLTexture: {
scoped_ptr<ResourceProviderContext> context3d(
@@ -358,19 +454,33 @@ class ResourceProviderTest
context3d.PassAs<TestWebGraphicsContext3D>());
output_surface_ = FakeOutputSurface::Create3d(context_provider);
+
+ scoped_ptr<ResourceProviderContext> child_context_owned =
+ ResourceProviderContext::Create(shared_data_.get());
+ child_context_ = child_context_owned.get();
+ child_output_surface_ = FakeOutputSurface::Create3d(
+ child_context_owned.PassAs<TestWebGraphicsContext3D>());
break;
}
case ResourceProvider::Bitmap:
output_surface_ = FakeOutputSurface::CreateSoftware(
make_scoped_ptr(new SoftwareOutputDevice));
+ child_output_surface_ = FakeOutputSurface::CreateSoftware(
+ make_scoped_ptr(new SoftwareOutputDevice));
break;
case ResourceProvider::InvalidType:
NOTREACHED();
break;
}
CHECK(output_surface_->BindToClient(&output_surface_client_));
+ CHECK(child_output_surface_->BindToClient(&child_output_surface_client_));
+
+ shared_bitmap_manager_.reset(new TestSharedBitmapManager());
+
resource_provider_ = ResourceProvider::Create(
- output_surface_.get(), 0, false);
+ output_surface_.get(), shared_bitmap_manager_.get(), 0, false);
+ child_resource_provider_ = ResourceProvider::Create(
+ child_output_surface_.get(), shared_bitmap_manager_.get(), 0, false);
}
static void CollectResources(ReturnedResourceArray* array,
@@ -391,12 +501,56 @@ class ResourceProviderTest
ResourceProviderContext* context() { return context3d_; }
+ ResourceProvider::ResourceId CreateChildMailbox(unsigned* release_sync_point,
+ bool* lost_resource,
+ bool* release_called,
+ unsigned* sync_point) {
+ if (GetParam() == ResourceProvider::GLTexture) {
+ unsigned texture = child_context_->createTexture();
+ gpu::Mailbox gpu_mailbox;
+ child_context_->bindTexture(GL_TEXTURE_2D, texture);
+ child_context_->genMailboxCHROMIUM(gpu_mailbox.name);
+ child_context_->produceTextureCHROMIUM(GL_TEXTURE_2D, gpu_mailbox.name);
+ *sync_point = child_context_->insertSyncPoint();
+ EXPECT_LT(0u, *sync_point);
+
+ scoped_ptr<base::SharedMemory> shared_memory;
+ scoped_ptr<SingleReleaseCallback> callback =
+ SingleReleaseCallback::Create(base::Bind(ReleaseSharedMemoryCallback,
+ base::Passed(&shared_memory),
+ release_called,
+ release_sync_point,
+ lost_resource));
+ return child_resource_provider_->CreateResourceFromTextureMailbox(
+ TextureMailbox(gpu_mailbox, *sync_point), callback.Pass());
+ } else {
+ gfx::Size size(64, 64);
+ scoped_ptr<base::SharedMemory> shared_memory(
+ CreateAndFillSharedMemory(size, 0));
+
+ base::SharedMemory* shared_memory_ptr = shared_memory.get();
+ scoped_ptr<SingleReleaseCallback> callback =
+ SingleReleaseCallback::Create(base::Bind(ReleaseSharedMemoryCallback,
+ base::Passed(&shared_memory),
+ release_called,
+ release_sync_point,
+ lost_resource));
+ return child_resource_provider_->CreateResourceFromTextureMailbox(
+ TextureMailbox(shared_memory_ptr, size), callback.Pass());
+ }
+ }
+
protected:
scoped_ptr<ContextSharedData> shared_data_;
ResourceProviderContext* context3d_;
+ ResourceProviderContext* child_context_;
FakeOutputSurfaceClient output_surface_client_;
+ FakeOutputSurfaceClient child_output_surface_client_;
scoped_ptr<OutputSurface> output_surface_;
+ scoped_ptr<OutputSurface> child_output_surface_;
scoped_ptr<ResourceProvider> resource_provider_;
+ scoped_ptr<ResourceProvider> child_resource_provider_;
+ scoped_ptr<TestSharedBitmapManager> shared_bitmap_manager_;
};
void CheckCreateResource(ResourceProvider::ResourceType expected_default_type,
@@ -502,50 +656,35 @@ TEST_P(ResourceProviderTest, Upload) {
resource_provider_->DeleteResource(id);
}
-TEST_P(ResourceProviderTest, TransferResources) {
- // Resource transfer is only supported with GL textures for now.
+TEST_P(ResourceProviderTest, TransferGLResources) {
if (GetParam() != ResourceProvider::GLTexture)
return;
-
- scoped_ptr<ResourceProviderContext> child_context_owned(
- ResourceProviderContext::Create(shared_data_.get()));
- ResourceProviderContext* child_context = child_context_owned.get();
-
- FakeOutputSurfaceClient child_output_surface_client;
- scoped_ptr<OutputSurface> child_output_surface(
- FakeOutputSurface::Create3d(
- child_context_owned.PassAs<TestWebGraphicsContext3D>()));
- CHECK(child_output_surface->BindToClient(&child_output_surface_client));
-
- scoped_ptr<ResourceProvider> child_resource_provider(
- ResourceProvider::Create(child_output_surface.get(), 0, false));
-
gfx::Size size(1, 1);
ResourceFormat format = RGBA_8888;
size_t pixel_size = TextureSizeBytes(size, format);
ASSERT_EQ(4U, pixel_size);
- ResourceProvider::ResourceId id1 = child_resource_provider->CreateResource(
+ ResourceProvider::ResourceId id1 = child_resource_provider_->CreateResource(
size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureUsageAny, format);
uint8_t data1[4] = { 1, 2, 3, 4 };
gfx::Rect rect(size);
- child_resource_provider->SetPixels(id1, data1, rect, rect, gfx::Vector2d());
+ child_resource_provider_->SetPixels(id1, data1, rect, rect, gfx::Vector2d());
- ResourceProvider::ResourceId id2 = child_resource_provider->CreateResource(
+ ResourceProvider::ResourceId id2 = child_resource_provider_->CreateResource(
size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureUsageAny, format);
uint8_t data2[4] = { 5, 5, 5, 5 };
- child_resource_provider->SetPixels(id2, data2, rect, rect, gfx::Vector2d());
+ child_resource_provider_->SetPixels(id2, data2, rect, rect, gfx::Vector2d());
- WebGLId external_texture_id = child_context->createExternalTexture();
- child_context->bindTexture(GL_TEXTURE_EXTERNAL_OES, external_texture_id);
+ WebGLId external_texture_id = child_context_->createExternalTexture();
+ child_context_->bindTexture(GL_TEXTURE_EXTERNAL_OES, external_texture_id);
gpu::Mailbox external_mailbox;
- child_context->genMailboxCHROMIUM(external_mailbox.name);
- child_context->produceTextureCHROMIUM(GL_TEXTURE_EXTERNAL_OES,
- external_mailbox.name);
- const unsigned external_sync_point = child_context->insertSyncPoint();
+ child_context_->genMailboxCHROMIUM(external_mailbox.name);
+ child_context_->produceTextureCHROMIUM(GL_TEXTURE_EXTERNAL_OES,
+ external_mailbox.name);
+ const unsigned external_sync_point = child_context_->insertSyncPoint();
ResourceProvider::ResourceId id3 =
- child_resource_provider->CreateResourceFromTextureMailbox(
+ child_resource_provider_->CreateResourceFromTextureMailbox(
TextureMailbox(
external_mailbox, GL_TEXTURE_EXTERNAL_OES, external_sync_point),
SingleReleaseCallback::Create(base::Bind(&EmptyReleaseCallback)));
@@ -560,8 +699,8 @@ TEST_P(ResourceProviderTest, TransferResources) {
resource_ids_to_transfer.push_back(id2);
resource_ids_to_transfer.push_back(id3);
TransferableResourceArray list;
- child_resource_provider->PrepareSendToParent(resource_ids_to_transfer,
- &list);
+ child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
+ &list);
ASSERT_EQ(3u, list.size());
EXPECT_NE(0u, list[0].sync_point);
EXPECT_NE(0u, list[1].sync_point);
@@ -569,9 +708,9 @@ TEST_P(ResourceProviderTest, TransferResources) {
EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D), list[0].target);
EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D), list[1].target);
EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_EXTERNAL_OES), list[2].target);
- EXPECT_TRUE(child_resource_provider->InUseByConsumer(id1));
- EXPECT_TRUE(child_resource_provider->InUseByConsumer(id2));
- EXPECT_TRUE(child_resource_provider->InUseByConsumer(id3));
+ EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id1));
+ EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id2));
+ EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id3));
resource_provider_->ReceiveFromChild(child_id, list);
resource_provider_->DeclareUsedResourcesFromChild(child_id,
resource_ids_to_transfer);
@@ -605,17 +744,17 @@ TEST_P(ResourceProviderTest, TransferResources) {
ResourceProvider::ResourceIdArray resource_ids_to_transfer;
resource_ids_to_transfer.push_back(id1);
TransferableResourceArray list;
- child_resource_provider->PrepareSendToParent(resource_ids_to_transfer,
- &list);
+ child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
+ &list);
EXPECT_EQ(1u, list.size());
EXPECT_EQ(id1, list[0].id);
EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D), list[0].target);
ReturnedResourceArray returned;
TransferableResource::ReturnResources(list, &returned);
- child_resource_provider->ReceiveReturnsFromParent(returned);
+ child_resource_provider_->ReceiveReturnsFromParent(returned);
// id1 was exported twice, we returned it only once, it should still be
// in-use.
- EXPECT_TRUE(child_resource_provider->InUseByConsumer(id1));
+ EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id1));
}
{
EXPECT_EQ(0u, returned_to_child.size());
@@ -632,25 +771,27 @@ TEST_P(ResourceProviderTest, TransferResources) {
EXPECT_FALSE(returned_to_child[0].lost);
EXPECT_FALSE(returned_to_child[1].lost);
EXPECT_FALSE(returned_to_child[2].lost);
- child_resource_provider->ReceiveReturnsFromParent(returned_to_child);
+ child_resource_provider_->ReceiveReturnsFromParent(returned_to_child);
returned_to_child.clear();
}
- EXPECT_FALSE(child_resource_provider->InUseByConsumer(id1));
- EXPECT_FALSE(child_resource_provider->InUseByConsumer(id2));
- EXPECT_FALSE(child_resource_provider->InUseByConsumer(id3));
+ EXPECT_FALSE(child_resource_provider_->InUseByConsumer(id1));
+ EXPECT_FALSE(child_resource_provider_->InUseByConsumer(id2));
+ EXPECT_FALSE(child_resource_provider_->InUseByConsumer(id3));
{
- ResourceProvider::ScopedReadLockGL lock(child_resource_provider.get(), id1);
+ ResourceProvider::ScopedReadLockGL lock(child_resource_provider_.get(),
+ id1);
ASSERT_NE(0U, lock.texture_id());
- child_context->bindTexture(GL_TEXTURE_2D, lock.texture_id());
- child_context->GetPixels(size, format, result);
+ child_context_->bindTexture(GL_TEXTURE_2D, lock.texture_id());
+ child_context_->GetPixels(size, format, result);
EXPECT_EQ(0, memcmp(data1, result, pixel_size));
}
{
- ResourceProvider::ScopedReadLockGL lock(child_resource_provider.get(), id2);
+ ResourceProvider::ScopedReadLockGL lock(child_resource_provider_.get(),
+ id2);
ASSERT_NE(0U, lock.texture_id());
- child_context->bindTexture(GL_TEXTURE_2D, lock.texture_id());
- child_context->GetPixels(size, format, result);
+ child_context_->bindTexture(GL_TEXTURE_2D, lock.texture_id());
+ child_context_->GetPixels(size, format, result);
EXPECT_EQ(0, memcmp(data2, result, pixel_size));
}
{
@@ -660,8 +801,8 @@ TEST_P(ResourceProviderTest, TransferResources) {
resource_ids_to_transfer.push_back(id2);
resource_ids_to_transfer.push_back(id3);
TransferableResourceArray list;
- child_resource_provider->PrepareSendToParent(resource_ids_to_transfer,
- &list);
+ child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
+ &list);
ASSERT_EQ(3u, list.size());
EXPECT_EQ(id1, list[0].id);
EXPECT_EQ(id2, list[1].id);
@@ -672,9 +813,9 @@ TEST_P(ResourceProviderTest, TransferResources) {
EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D), list[0].target);
EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D), list[1].target);
EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_EXTERNAL_OES), list[2].target);
- EXPECT_TRUE(child_resource_provider->InUseByConsumer(id1));
- EXPECT_TRUE(child_resource_provider->InUseByConsumer(id2));
- EXPECT_TRUE(child_resource_provider->InUseByConsumer(id3));
+ EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id1));
+ EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id2));
+ EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id3));
resource_provider_->ReceiveFromChild(child_id, list);
resource_provider_->DeclareUsedResourcesFromChild(child_id,
resource_ids_to_transfer);
@@ -695,9 +836,234 @@ TEST_P(ResourceProviderTest, TransferResources) {
EXPECT_FALSE(returned_to_child[2].lost);
}
-TEST_P(ResourceProviderTest, DeleteExportedResources) {
- // Resource transfer is only supported with GL textures for now.
- if (GetParam() != ResourceProvider::GLTexture)
+TEST_P(ResourceProviderTest, TransferSoftwareResources) {
+ if (GetParam() != ResourceProvider::Bitmap)
+ return;
+
+ gfx::Size size(1, 1);
+ ResourceFormat format = RGBA_8888;
+ size_t pixel_size = TextureSizeBytes(size, format);
+ ASSERT_EQ(4U, pixel_size);
+
+ ResourceProvider::ResourceId id1 = child_resource_provider_->CreateResource(
+ size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureUsageAny, format);
+ uint8_t data1[4] = { 1, 2, 3, 4 };
+ gfx::Rect rect(size);
+ child_resource_provider_->SetPixels(id1, data1, rect, rect, gfx::Vector2d());
+
+ ResourceProvider::ResourceId id2 = child_resource_provider_->CreateResource(
+ size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureUsageAny, format);
+ uint8_t data2[4] = { 5, 5, 5, 5 };
+ child_resource_provider_->SetPixels(id2, data2, rect, rect, gfx::Vector2d());
+
+ scoped_ptr<base::SharedMemory> shared_memory(new base::SharedMemory());
+ shared_memory->CreateAndMapAnonymous(1);
+ base::SharedMemory* shared_memory_ptr = shared_memory.get();
+ ResourceProvider::ResourceId id3 =
+ child_resource_provider_->CreateResourceFromTextureMailbox(
+ TextureMailbox(shared_memory_ptr, gfx::Size(1, 1)),
+ SingleReleaseCallback::Create(base::Bind(
+ &SharedMemoryReleaseCallback, base::Passed(&shared_memory))));
+
+ ReturnedResourceArray returned_to_child;
+ int child_id =
+ resource_provider_->CreateChild(GetReturnCallback(&returned_to_child));
+ {
+ // Transfer some resources to the parent.
+ ResourceProvider::ResourceIdArray resource_ids_to_transfer;
+ resource_ids_to_transfer.push_back(id1);
+ resource_ids_to_transfer.push_back(id2);
+ resource_ids_to_transfer.push_back(id3);
+ TransferableResourceArray list;
+ child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
+ &list);
+ ASSERT_EQ(3u, list.size());
+ EXPECT_EQ(0u, list[0].sync_point);
+ EXPECT_EQ(0u, list[1].sync_point);
+ EXPECT_EQ(0u, list[2].sync_point);
+ EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id1));
+ EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id2));
+ EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id3));
+ resource_provider_->ReceiveFromChild(child_id, list);
+ resource_provider_->DeclareUsedResourcesFromChild(child_id,
+ resource_ids_to_transfer);
+ }
+
+ EXPECT_EQ(3u, resource_provider_->num_resources());
+ ResourceProvider::ResourceIdMap resource_map =
+ resource_provider_->GetChildToParentMap(child_id);
+ ResourceProvider::ResourceId mapped_id1 = resource_map[id1];
+ ResourceProvider::ResourceId mapped_id2 = resource_map[id2];
+ ResourceProvider::ResourceId mapped_id3 = resource_map[id3];
+ EXPECT_NE(0u, mapped_id1);
+ EXPECT_NE(0u, mapped_id2);
+ EXPECT_NE(0u, mapped_id3);
+ EXPECT_FALSE(resource_provider_->InUseByConsumer(id1));
+ EXPECT_FALSE(resource_provider_->InUseByConsumer(id2));
+ EXPECT_FALSE(resource_provider_->InUseByConsumer(id3));
+
+ uint8_t result[4] = { 0 };
+ GetResourcePixels(
+ resource_provider_.get(), context(), mapped_id1, size, format, result);
+ EXPECT_EQ(0, memcmp(data1, result, pixel_size));
+
+ GetResourcePixels(
+ resource_provider_.get(), context(), mapped_id2, size, format, result);
+ EXPECT_EQ(0, memcmp(data2, result, pixel_size));
+
+ {
+ // Check that transfering again the same resource from the child to the
+ // parent works.
+ ResourceProvider::ResourceIdArray resource_ids_to_transfer;
+ resource_ids_to_transfer.push_back(id1);
+ TransferableResourceArray list;
+ child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
+ &list);
+ EXPECT_EQ(1u, list.size());
+ EXPECT_EQ(id1, list[0].id);
+ ReturnedResourceArray returned;
+ TransferableResource::ReturnResources(list, &returned);
+ child_resource_provider_->ReceiveReturnsFromParent(returned);
+ // id1 was exported twice, we returned it only once, it should still be
+ // in-use.
+ EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id1));
+ }
+ {
+ EXPECT_EQ(0u, returned_to_child.size());
+
+ // Transfer resources back from the parent to the child. Set no resources as
+ // being in use.
+ ResourceProvider::ResourceIdArray no_resources;
+ resource_provider_->DeclareUsedResourcesFromChild(child_id, no_resources);
+
+ ASSERT_EQ(3u, returned_to_child.size());
+ EXPECT_EQ(0u, returned_to_child[0].sync_point);
+ EXPECT_EQ(0u, returned_to_child[1].sync_point);
+ EXPECT_EQ(0u, returned_to_child[2].sync_point);
+ EXPECT_EQ(id1, returned_to_child[0].id);
+ EXPECT_EQ(id2, returned_to_child[1].id);
+ EXPECT_EQ(id3, returned_to_child[2].id);
+ EXPECT_FALSE(returned_to_child[0].lost);
+ EXPECT_FALSE(returned_to_child[1].lost);
+ EXPECT_FALSE(returned_to_child[2].lost);
+ child_resource_provider_->ReceiveReturnsFromParent(returned_to_child);
+ returned_to_child.clear();
+ }
+ EXPECT_FALSE(child_resource_provider_->InUseByConsumer(id1));
+ EXPECT_FALSE(child_resource_provider_->InUseByConsumer(id2));
+ EXPECT_FALSE(child_resource_provider_->InUseByConsumer(id3));
+
+ {
+ ResourceProvider::ScopedReadLockSoftware lock(
+ child_resource_provider_.get(), id1);
+ const SkBitmap* sk_bitmap = lock.sk_bitmap();
+ EXPECT_EQ(sk_bitmap->width(), size.width());
+ EXPECT_EQ(sk_bitmap->height(), size.height());
+ EXPECT_EQ(0, memcmp(data1, sk_bitmap->getPixels(), pixel_size));
+ }
+ {
+ ResourceProvider::ScopedReadLockSoftware lock(
+ child_resource_provider_.get(), id2);
+ const SkBitmap* sk_bitmap = lock.sk_bitmap();
+ EXPECT_EQ(sk_bitmap->width(), size.width());
+ EXPECT_EQ(sk_bitmap->height(), size.height());
+ EXPECT_EQ(0, memcmp(data2, sk_bitmap->getPixels(), pixel_size));
+ }
+ {
+ // Transfer resources to the parent again.
+ ResourceProvider::ResourceIdArray resource_ids_to_transfer;
+ resource_ids_to_transfer.push_back(id1);
+ resource_ids_to_transfer.push_back(id2);
+ resource_ids_to_transfer.push_back(id3);
+ TransferableResourceArray list;
+ child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
+ &list);
+ ASSERT_EQ(3u, list.size());
+ EXPECT_EQ(id1, list[0].id);
+ EXPECT_EQ(id2, list[1].id);
+ EXPECT_EQ(id3, list[2].id);
+ EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id1));
+ EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id2));
+ EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id3));
+ resource_provider_->ReceiveFromChild(child_id, list);
+ resource_provider_->DeclareUsedResourcesFromChild(child_id,
+ resource_ids_to_transfer);
+ }
+
+ EXPECT_EQ(0u, returned_to_child.size());
+
+ EXPECT_EQ(3u, resource_provider_->num_resources());
+ resource_provider_->DestroyChild(child_id);
+ EXPECT_EQ(0u, resource_provider_->num_resources());
+
+ ASSERT_EQ(3u, returned_to_child.size());
+ EXPECT_EQ(0u, returned_to_child[0].sync_point);
+ EXPECT_EQ(0u, returned_to_child[1].sync_point);
+ EXPECT_EQ(0u, returned_to_child[2].sync_point);
+ EXPECT_EQ(id1, returned_to_child[0].id);
+ EXPECT_EQ(id2, returned_to_child[1].id);
+ EXPECT_EQ(id3, returned_to_child[2].id);
+ EXPECT_FALSE(returned_to_child[0].lost);
+ EXPECT_FALSE(returned_to_child[1].lost);
+ EXPECT_FALSE(returned_to_child[2].lost);
+}
+
+TEST_P(ResourceProviderTest, TransferSoftwareToNonUber) {
+ // TODO(jbauman): Remove test when shared bitmap manager available
+ // everywhere.
+ if (GetParam() != ResourceProvider::Bitmap)
+ return;
+
+ scoped_ptr<FakeOutputSurface> parent_output_surface =
+ FakeOutputSurface::CreateSoftware(
+ make_scoped_ptr(new SoftwareOutputDevice));
+ FakeOutputSurfaceClient parent_output_surface_client;
+ CHECK(parent_output_surface->BindToClient(&parent_output_surface_client));
+
+ scoped_ptr<ResourceProvider> parent_resource_provider(
+ ResourceProvider::Create(parent_output_surface.get(), NULL, 0, false));
+
+ gfx::Size size(1, 1);
+ ResourceFormat format = RGBA_8888;
+ size_t pixel_size = TextureSizeBytes(size, format);
+ ASSERT_EQ(4U, pixel_size);
+
+ ResourceProvider::ResourceId id1 = resource_provider_->CreateResource(
+ size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureUsageAny, format);
+ uint8_t data1[4] = { 1, 2, 3, 4 };
+ gfx::Rect rect(size);
+ resource_provider_->SetPixels(id1, data1, rect, rect, gfx::Vector2d());
+
+ ReturnedResourceArray returned_to_child;
+ int child_id = parent_resource_provider->CreateChild(
+ GetReturnCallback(&returned_to_child));
+ {
+ ResourceProvider::ResourceIdArray resource_ids_to_transfer;
+ resource_ids_to_transfer.push_back(id1);
+ TransferableResourceArray list;
+ resource_provider_->PrepareSendToParent(resource_ids_to_transfer, &list);
+ ASSERT_EQ(1u, list.size());
+ EXPECT_TRUE(resource_provider_->InUseByConsumer(id1));
+ parent_resource_provider->ReceiveFromChild(child_id, list);
+ }
+
+ EXPECT_EQ(0u, parent_resource_provider->num_resources());
+ ASSERT_EQ(1u, returned_to_child.size());
+ EXPECT_EQ(returned_to_child[0].id, id1);
+ ResourceProvider::ResourceIdMap resource_map =
+ parent_resource_provider->GetChildToParentMap(child_id);
+ ResourceProvider::ResourceId mapped_id1 = resource_map[id1];
+ EXPECT_EQ(0u, mapped_id1);
+
+ parent_resource_provider->DestroyChild(child_id);
+ EXPECT_EQ(0u, parent_resource_provider->num_resources());
+
+ ASSERT_EQ(1u, returned_to_child.size());
+ EXPECT_FALSE(returned_to_child[0].lost);
+}
+
+TEST_P(ResourceProviderTest, TransferGLToSoftware) {
+ if (GetParam() != ResourceProvider::Bitmap)
return;
scoped_ptr<ResourceProviderContext> child_context_owned(
@@ -709,7 +1075,7 @@ TEST_P(ResourceProviderTest, DeleteExportedResources) {
CHECK(child_output_surface->BindToClient(&child_output_surface_client));
scoped_ptr<ResourceProvider> child_resource_provider(
- ResourceProvider::Create(child_output_surface.get(), 0, false));
+ ResourceProvider::Create(child_output_surface.get(), NULL, 0, false));
gfx::Size size(1, 1);
ResourceFormat format = RGBA_8888;
@@ -718,14 +1084,103 @@ TEST_P(ResourceProviderTest, DeleteExportedResources) {
ResourceProvider::ResourceId id1 = child_resource_provider->CreateResource(
size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureUsageAny, format);
- uint8_t data1[4] = {1, 2, 3, 4};
+ uint8_t data1[4] = { 1, 2, 3, 4 };
gfx::Rect rect(size);
child_resource_provider->SetPixels(id1, data1, rect, rect, gfx::Vector2d());
- ResourceProvider::ResourceId id2 = child_resource_provider->CreateResource(
+ ReturnedResourceArray returned_to_child;
+ int child_id =
+ resource_provider_->CreateChild(GetReturnCallback(&returned_to_child));
+ {
+ ResourceProvider::ResourceIdArray resource_ids_to_transfer;
+ resource_ids_to_transfer.push_back(id1);
+ TransferableResourceArray list;
+ child_resource_provider->PrepareSendToParent(resource_ids_to_transfer,
+ &list);
+ ASSERT_EQ(1u, list.size());
+ EXPECT_NE(0u, list[0].sync_point);
+ EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D), list[0].target);
+ EXPECT_TRUE(child_resource_provider->InUseByConsumer(id1));
+ resource_provider_->ReceiveFromChild(child_id, list);
+ }
+
+ EXPECT_EQ(0u, resource_provider_->num_resources());
+ ASSERT_EQ(1u, returned_to_child.size());
+ EXPECT_EQ(returned_to_child[0].id, id1);
+ ResourceProvider::ResourceIdMap resource_map =
+ resource_provider_->GetChildToParentMap(child_id);
+ ResourceProvider::ResourceId mapped_id1 = resource_map[id1];
+ EXPECT_EQ(0u, mapped_id1);
+
+ resource_provider_->DestroyChild(child_id);
+ EXPECT_EQ(0u, resource_provider_->num_resources());
+
+ ASSERT_EQ(1u, returned_to_child.size());
+ EXPECT_FALSE(returned_to_child[0].lost);
+}
+
+TEST_P(ResourceProviderTest, TransferInvalidSoftware) {
+ if (GetParam() != ResourceProvider::Bitmap)
+ return;
+
+ gfx::Size size(1, 1);
+ ResourceFormat format = RGBA_8888;
+ size_t pixel_size = TextureSizeBytes(size, format);
+ ASSERT_EQ(4U, pixel_size);
+
+ ResourceProvider::ResourceId id1 = child_resource_provider_->CreateResource(
+ size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureUsageAny, format);
+ uint8_t data1[4] = { 1, 2, 3, 4 };
+ gfx::Rect rect(size);
+ child_resource_provider_->SetPixels(id1, data1, rect, rect, gfx::Vector2d());
+
+ ReturnedResourceArray returned_to_child;
+ int child_id =
+ resource_provider_->CreateChild(GetReturnCallback(&returned_to_child));
+ {
+ ResourceProvider::ResourceIdArray resource_ids_to_transfer;
+ resource_ids_to_transfer.push_back(id1);
+ TransferableResourceArray list;
+ child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
+ &list);
+ ASSERT_EQ(1u, list.size());
+ // Make invalid.
+ list[0].mailbox.name[1] = 5;
+ EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id1));
+ resource_provider_->ReceiveFromChild(child_id, list);
+ }
+
+ EXPECT_EQ(0u, resource_provider_->num_resources());
+ ASSERT_EQ(1u, returned_to_child.size());
+ EXPECT_EQ(returned_to_child[0].id, id1);
+ ResourceProvider::ResourceIdMap resource_map =
+ resource_provider_->GetChildToParentMap(child_id);
+ ResourceProvider::ResourceId mapped_id1 = resource_map[id1];
+ EXPECT_EQ(0u, mapped_id1);
+
+ resource_provider_->DestroyChild(child_id);
+ EXPECT_EQ(0u, resource_provider_->num_resources());
+
+ ASSERT_EQ(1u, returned_to_child.size());
+ EXPECT_FALSE(returned_to_child[0].lost);
+}
+
+TEST_P(ResourceProviderTest, DeleteExportedResources) {
+ gfx::Size size(1, 1);
+ ResourceFormat format = RGBA_8888;
+ size_t pixel_size = TextureSizeBytes(size, format);
+ ASSERT_EQ(4U, pixel_size);
+
+ ResourceProvider::ResourceId id1 = child_resource_provider_->CreateResource(
+ size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureUsageAny, format);
+ uint8_t data1[4] = { 1, 2, 3, 4 };
+ gfx::Rect rect(size);
+ child_resource_provider_->SetPixels(id1, data1, rect, rect, gfx::Vector2d());
+
+ ResourceProvider::ResourceId id2 = child_resource_provider_->CreateResource(
size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureUsageAny, format);
uint8_t data2[4] = {5, 5, 5, 5};
- child_resource_provider->SetPixels(id2, data2, rect, rect, gfx::Vector2d());
+ child_resource_provider_->SetPixels(id2, data2, rect, rect, gfx::Vector2d());
ReturnedResourceArray returned_to_child;
int child_id =
@@ -736,13 +1191,15 @@ TEST_P(ResourceProviderTest, DeleteExportedResources) {
resource_ids_to_transfer.push_back(id1);
resource_ids_to_transfer.push_back(id2);
TransferableResourceArray list;
- child_resource_provider->PrepareSendToParent(resource_ids_to_transfer,
- &list);
+ child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
+ &list);
ASSERT_EQ(2u, list.size());
- EXPECT_NE(0u, list[0].sync_point);
- EXPECT_NE(0u, list[1].sync_point);
- EXPECT_TRUE(child_resource_provider->InUseByConsumer(id1));
- EXPECT_TRUE(child_resource_provider->InUseByConsumer(id2));
+ if (GetParam() == ResourceProvider::GLTexture) {
+ EXPECT_NE(0u, list[0].sync_point);
+ EXPECT_NE(0u, list[1].sync_point);
+ }
+ EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id1));
+ EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id2));
resource_provider_->ReceiveFromChild(child_id, list);
resource_provider_->DeclareUsedResourcesFromChild(child_id,
resource_ids_to_transfer);
@@ -767,8 +1224,10 @@ TEST_P(ResourceProviderTest, DeleteExportedResources) {
resource_provider_->PrepareSendToParent(resource_ids_to_transfer, &list);
ASSERT_EQ(2u, list.size());
- EXPECT_NE(0u, list[0].sync_point);
- EXPECT_NE(0u, list[1].sync_point);
+ if (GetParam() == ResourceProvider::GLTexture) {
+ EXPECT_NE(0u, list[0].sync_point);
+ EXPECT_NE(0u, list[1].sync_point);
+ }
EXPECT_TRUE(resource_provider_->InUseByConsumer(id1));
EXPECT_TRUE(resource_provider_->InUseByConsumer(id2));
@@ -791,44 +1250,31 @@ TEST_P(ResourceProviderTest, DeleteExportedResources) {
EXPECT_EQ(0u, resource_provider_->num_resources());
ASSERT_EQ(2u, returned_to_child.size());
- EXPECT_NE(0u, returned_to_child[0].sync_point);
- EXPECT_NE(0u, returned_to_child[1].sync_point);
+ if (GetParam() == ResourceProvider::GLTexture) {
+ EXPECT_NE(0u, returned_to_child[0].sync_point);
+ EXPECT_NE(0u, returned_to_child[1].sync_point);
+ }
EXPECT_FALSE(returned_to_child[0].lost);
EXPECT_FALSE(returned_to_child[1].lost);
}
}
TEST_P(ResourceProviderTest, DestroyChildWithExportedResources) {
- // Resource transfer is only supported with GL textures for now.
- if (GetParam() != ResourceProvider::GLTexture)
- return;
-
- scoped_ptr<ResourceProviderContext> child_context_owned(
- ResourceProviderContext::Create(shared_data_.get()));
-
- FakeOutputSurfaceClient child_output_surface_client;
- scoped_ptr<OutputSurface> child_output_surface(FakeOutputSurface::Create3d(
- child_context_owned.PassAs<TestWebGraphicsContext3D>()));
- CHECK(child_output_surface->BindToClient(&child_output_surface_client));
-
- scoped_ptr<ResourceProvider> child_resource_provider(
- ResourceProvider::Create(child_output_surface.get(), 0, false));
-
gfx::Size size(1, 1);
ResourceFormat format = RGBA_8888;
size_t pixel_size = TextureSizeBytes(size, format);
ASSERT_EQ(4U, pixel_size);
- ResourceProvider::ResourceId id1 = child_resource_provider->CreateResource(
+ ResourceProvider::ResourceId id1 = child_resource_provider_->CreateResource(
size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureUsageAny, format);
uint8_t data1[4] = {1, 2, 3, 4};
gfx::Rect rect(size);
- child_resource_provider->SetPixels(id1, data1, rect, rect, gfx::Vector2d());
+ child_resource_provider_->SetPixels(id1, data1, rect, rect, gfx::Vector2d());
- ResourceProvider::ResourceId id2 = child_resource_provider->CreateResource(
+ ResourceProvider::ResourceId id2 = child_resource_provider_->CreateResource(
size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureUsageAny, format);
uint8_t data2[4] = {5, 5, 5, 5};
- child_resource_provider->SetPixels(id2, data2, rect, rect, gfx::Vector2d());
+ child_resource_provider_->SetPixels(id2, data2, rect, rect, gfx::Vector2d());
ReturnedResourceArray returned_to_child;
int child_id =
@@ -839,13 +1285,15 @@ TEST_P(ResourceProviderTest, DestroyChildWithExportedResources) {
resource_ids_to_transfer.push_back(id1);
resource_ids_to_transfer.push_back(id2);
TransferableResourceArray list;
- child_resource_provider->PrepareSendToParent(resource_ids_to_transfer,
- &list);
+ child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
+ &list);
ASSERT_EQ(2u, list.size());
- EXPECT_NE(0u, list[0].sync_point);
- EXPECT_NE(0u, list[1].sync_point);
- EXPECT_TRUE(child_resource_provider->InUseByConsumer(id1));
- EXPECT_TRUE(child_resource_provider->InUseByConsumer(id2));
+ if (GetParam() == ResourceProvider::GLTexture) {
+ EXPECT_NE(0u, list[0].sync_point);
+ EXPECT_NE(0u, list[1].sync_point);
+ }
+ EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id1));
+ EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id2));
resource_provider_->ReceiveFromChild(child_id, list);
resource_provider_->DeclareUsedResourcesFromChild(child_id,
resource_ids_to_transfer);
@@ -870,8 +1318,10 @@ TEST_P(ResourceProviderTest, DestroyChildWithExportedResources) {
resource_provider_->PrepareSendToParent(resource_ids_to_transfer, &list);
ASSERT_EQ(2u, list.size());
- EXPECT_NE(0u, list[0].sync_point);
- EXPECT_NE(0u, list[1].sync_point);
+ if (GetParam() == ResourceProvider::GLTexture) {
+ EXPECT_NE(0u, list[0].sync_point);
+ EXPECT_NE(0u, list[1].sync_point);
+ }
EXPECT_TRUE(resource_provider_->InUseByConsumer(id1));
EXPECT_TRUE(resource_provider_->InUseByConsumer(id2));
@@ -889,8 +1339,10 @@ TEST_P(ResourceProviderTest, DestroyChildWithExportedResources) {
EXPECT_EQ(0u, resource_provider_->num_resources());
ASSERT_EQ(2u, returned_to_child.size());
- EXPECT_NE(0u, returned_to_child[0].sync_point);
- EXPECT_NE(0u, returned_to_child[1].sync_point);
+ if (GetParam() == ResourceProvider::GLTexture) {
+ EXPECT_NE(0u, returned_to_child[0].sync_point);
+ EXPECT_NE(0u, returned_to_child[1].sync_point);
+ }
EXPECT_TRUE(returned_to_child[0].lost);
EXPECT_TRUE(returned_to_child[1].lost);
returned_to_child.clear();
@@ -909,32 +1361,16 @@ TEST_P(ResourceProviderTest, DestroyChildWithExportedResources) {
}
TEST_P(ResourceProviderTest, DeleteTransferredResources) {
- // Resource transfer is only supported with GL textures for now.
- if (GetParam() != ResourceProvider::GLTexture)
- return;
-
- scoped_ptr<ResourceProviderContext> child_context_owned(
- ResourceProviderContext::Create(shared_data_.get()));
-
- FakeOutputSurfaceClient child_output_surface_client;
- scoped_ptr<OutputSurface> child_output_surface(
- FakeOutputSurface::Create3d(
- child_context_owned.PassAs<TestWebGraphicsContext3D>()));
- CHECK(child_output_surface->BindToClient(&child_output_surface_client));
-
- scoped_ptr<ResourceProvider> child_resource_provider(
- ResourceProvider::Create(child_output_surface.get(), 0, false));
-
gfx::Size size(1, 1);
ResourceFormat format = RGBA_8888;
size_t pixel_size = TextureSizeBytes(size, format);
ASSERT_EQ(4U, pixel_size);
- ResourceProvider::ResourceId id = child_resource_provider->CreateResource(
+ ResourceProvider::ResourceId id = child_resource_provider_->CreateResource(
size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureUsageAny, format);
uint8_t data[4] = { 1, 2, 3, 4 };
gfx::Rect rect(size);
- child_resource_provider->SetPixels(id, data, rect, rect, gfx::Vector2d());
+ child_resource_provider_->SetPixels(id, data, rect, rect, gfx::Vector2d());
ReturnedResourceArray returned_to_child;
int child_id =
@@ -944,19 +1380,20 @@ TEST_P(ResourceProviderTest, DeleteTransferredResources) {
ResourceProvider::ResourceIdArray resource_ids_to_transfer;
resource_ids_to_transfer.push_back(id);
TransferableResourceArray list;
- child_resource_provider->PrepareSendToParent(resource_ids_to_transfer,
- &list);
+ child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
+ &list);
ASSERT_EQ(1u, list.size());
- EXPECT_NE(0u, list[0].sync_point);
- EXPECT_TRUE(child_resource_provider->InUseByConsumer(id));
+ if (GetParam() == ResourceProvider::GLTexture)
+ EXPECT_NE(0u, list[0].sync_point);
+ EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id));
resource_provider_->ReceiveFromChild(child_id, list);
resource_provider_->DeclareUsedResourcesFromChild(child_id,
resource_ids_to_transfer);
}
// Delete textures in the child, while they are transfered.
- child_resource_provider->DeleteResource(id);
- EXPECT_EQ(1u, child_resource_provider->num_resources());
+ child_resource_provider_->DeleteResource(id);
+ EXPECT_EQ(1u, child_resource_provider_->num_resources());
{
EXPECT_EQ(0u, returned_to_child.size());
@@ -966,10 +1403,11 @@ TEST_P(ResourceProviderTest, DeleteTransferredResources) {
resource_provider_->DeclareUsedResourcesFromChild(child_id, no_resources);
ASSERT_EQ(1u, returned_to_child.size());
- EXPECT_NE(0u, returned_to_child[0].sync_point);
- child_resource_provider->ReceiveReturnsFromParent(returned_to_child);
+ if (GetParam() == ResourceProvider::GLTexture)
+ EXPECT_NE(0u, returned_to_child[0].sync_point);
+ child_resource_provider_->ReceiveReturnsFromParent(returned_to_child);
}
- EXPECT_EQ(0u, child_resource_provider->num_resources());
+ EXPECT_EQ(0u, child_resource_provider_->num_resources());
}
class ResourceProviderTestTextureFilters : public ResourceProviderTest {
@@ -985,7 +1423,7 @@ class ResourceProviderTestTextureFilters : public ResourceProviderTest {
CHECK(child_output_surface->BindToClient(&child_output_surface_client));
scoped_ptr<ResourceProvider> child_resource_provider(
- ResourceProvider::Create(child_output_surface.get(), 0, false));
+ ResourceProvider::Create(child_output_surface.get(), NULL, 0, false));
scoped_ptr<TextureStateTrackingContext> parent_context_owned(
new TextureStateTrackingContext);
@@ -997,7 +1435,7 @@ class ResourceProviderTestTextureFilters : public ResourceProviderTest {
CHECK(parent_output_surface->BindToClient(&parent_output_surface_client));
scoped_ptr<ResourceProvider> parent_resource_provider(
- ResourceProvider::Create(parent_output_surface.get(), 0, false));
+ ResourceProvider::Create(parent_output_surface.get(), NULL, 0, false));
gfx::Size size(1, 1);
ResourceFormat format = RGBA_8888;
@@ -1140,16 +1578,8 @@ TEST_P(ResourceProviderTest, TextureFilters_ChildLinearParentNearest) {
ResourceProviderTestTextureFilters::RunTest(GL_LINEAR, GL_NEAREST);
}
-void ReleaseTextureMailbox(unsigned* release_sync_point,
- bool* release_lost_resource,
- unsigned sync_point,
- bool lost_resource) {
- *release_sync_point = sync_point;
- *release_lost_resource = lost_resource;
-}
-
TEST_P(ResourceProviderTest, TransferMailboxResources) {
- // Resource transfer is only supported with GL textures for now.
+ // Other mailbox transfers tested elsewhere.
if (GetParam() != ResourceProvider::GLTexture)
return;
unsigned texture = context()->createTexture();
@@ -1269,27 +1699,14 @@ TEST_P(ResourceProviderTest, TransferMailboxResources) {
}
TEST_P(ResourceProviderTest, LostResourceInParent) {
- // Resource transfer is only supported with GL textures for now.
- if (GetParam() != ResourceProvider::GLTexture)
- return;
-
- scoped_ptr<ResourceProviderContext> child_context_owned(
- ResourceProviderContext::Create(shared_data_.get()));
-
- FakeOutputSurfaceClient child_output_surface_client;
- scoped_ptr<OutputSurface> child_output_surface(FakeOutputSurface::Create3d(
- child_context_owned.PassAs<TestWebGraphicsContext3D>()));
- CHECK(child_output_surface->BindToClient(&child_output_surface_client));
-
- scoped_ptr<ResourceProvider> child_resource_provider(
- ResourceProvider::Create(child_output_surface.get(), 0, false));
-
gfx::Size size(1, 1);
ResourceFormat format = RGBA_8888;
ResourceProvider::ResourceId resource =
- child_resource_provider->CreateResource(
+ child_resource_provider_->CreateResource(
size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureUsageAny, format);
- child_resource_provider->AllocateForTesting(resource);
+ child_resource_provider_->AllocateForTesting(resource);
+ // Expect a GL resource to be lost.
+ bool should_lose_resource = GetParam() == ResourceProvider::GLTexture;
ReturnedResourceArray returned_to_child;
int child_id =
@@ -1299,8 +1716,8 @@ TEST_P(ResourceProviderTest, LostResourceInParent) {
ResourceProvider::ResourceIdArray resource_ids_to_transfer;
resource_ids_to_transfer.push_back(resource);
TransferableResourceArray list;
- child_resource_provider->PrepareSendToParent(resource_ids_to_transfer,
- &list);
+ child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
+ &list);
EXPECT_EQ(1u, list.size());
resource_provider_->ReceiveFromChild(child_id, list);
@@ -1319,42 +1736,28 @@ TEST_P(ResourceProviderTest, LostResourceInParent) {
ResourceProvider::ResourceIdArray no_resources;
resource_provider_->DeclareUsedResourcesFromChild(child_id, no_resources);
- // Expect the resource to be lost.
+ // Expect a GL resource to be lost.
ASSERT_EQ(1u, returned_to_child.size());
- EXPECT_TRUE(returned_to_child[0].lost);
- child_resource_provider->ReceiveReturnsFromParent(returned_to_child);
+ EXPECT_EQ(should_lose_resource, returned_to_child[0].lost);
+ child_resource_provider_->ReceiveReturnsFromParent(returned_to_child);
returned_to_child.clear();
}
- // The resource should be lost.
- EXPECT_TRUE(child_resource_provider->IsLost(resource));
+ // A GL resource should be lost.
+ EXPECT_EQ(should_lose_resource, child_resource_provider_->IsLost(resource));
// Lost resources stay in use in the parent forever.
- EXPECT_TRUE(child_resource_provider->InUseByConsumer(resource));
+ EXPECT_EQ(should_lose_resource,
+ child_resource_provider_->InUseByConsumer(resource));
}
TEST_P(ResourceProviderTest, LostResourceInGrandParent) {
- // Resource transfer is only supported with GL textures for now.
- if (GetParam() != ResourceProvider::GLTexture)
- return;
-
- scoped_ptr<ResourceProviderContext> child_context_owned(
- ResourceProviderContext::Create(shared_data_.get()));
-
- FakeOutputSurfaceClient child_output_surface_client;
- scoped_ptr<OutputSurface> child_output_surface(FakeOutputSurface::Create3d(
- child_context_owned.PassAs<TestWebGraphicsContext3D>()));
- CHECK(child_output_surface->BindToClient(&child_output_surface_client));
-
- scoped_ptr<ResourceProvider> child_resource_provider(
- ResourceProvider::Create(child_output_surface.get(), 0, false));
-
gfx::Size size(1, 1);
ResourceFormat format = RGBA_8888;
ResourceProvider::ResourceId resource =
- child_resource_provider->CreateResource(
+ child_resource_provider_->CreateResource(
size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureUsageAny, format);
- child_resource_provider->AllocateForTesting(resource);
+ child_resource_provider_->AllocateForTesting(resource);
ReturnedResourceArray returned_to_child;
int child_id =
@@ -1364,8 +1767,8 @@ TEST_P(ResourceProviderTest, LostResourceInGrandParent) {
ResourceProvider::ResourceIdArray resource_ids_to_transfer;
resource_ids_to_transfer.push_back(resource);
TransferableResourceArray list;
- child_resource_provider->PrepareSendToParent(resource_ids_to_transfer,
- &list);
+ child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
+ &list);
EXPECT_EQ(1u, list.size());
resource_provider_->ReceiveFromChild(child_id, list);
@@ -1413,47 +1816,24 @@ TEST_P(ResourceProviderTest, LostResourceInGrandParent) {
// Expect the resource to be lost.
ASSERT_EQ(1u, returned_to_child.size());
EXPECT_TRUE(returned_to_child[0].lost);
- child_resource_provider->ReceiveReturnsFromParent(returned_to_child);
+ child_resource_provider_->ReceiveReturnsFromParent(returned_to_child);
returned_to_child.clear();
}
// The resource should be lost.
- EXPECT_TRUE(child_resource_provider->IsLost(resource));
+ EXPECT_TRUE(child_resource_provider_->IsLost(resource));
// Lost resources stay in use in the parent forever.
- EXPECT_TRUE(child_resource_provider->InUseByConsumer(resource));
+ EXPECT_TRUE(child_resource_provider_->InUseByConsumer(resource));
}
TEST_P(ResourceProviderTest, LostMailboxInParent) {
- // Resource transfer is only supported with GL textures for now.
- if (GetParam() != ResourceProvider::GLTexture)
- return;
-
- scoped_ptr<ResourceProviderContext> child_context_owned(
- ResourceProviderContext::Create(shared_data_.get()));
- ResourceProviderContext* child_context = child_context_owned.get();
-
- FakeOutputSurfaceClient child_output_surface_client;
- scoped_ptr<OutputSurface> child_output_surface(FakeOutputSurface::Create3d(
- child_context_owned.PassAs<TestWebGraphicsContext3D>()));
- CHECK(child_output_surface->BindToClient(&child_output_surface_client));
-
- scoped_ptr<ResourceProvider> child_resource_provider(
- ResourceProvider::Create(child_output_surface.get(), 0, false));
-
- unsigned texture = child_context->createTexture();
- gpu::Mailbox gpu_mailbox;
- child_context->bindTexture(GL_TEXTURE_2D, texture);
- child_context->genMailboxCHROMIUM(gpu_mailbox.name);
- child_context->produceTextureCHROMIUM(GL_TEXTURE_2D, gpu_mailbox.name);
-
unsigned release_sync_point = 0;
bool lost_resource = false;
- ReleaseCallback callback =
- base::Bind(ReleaseTextureMailbox, &release_sync_point, &lost_resource);
- ResourceProvider::ResourceId resource =
- child_resource_provider->CreateResourceFromTextureMailbox(
- TextureMailbox(gpu_mailbox), SingleReleaseCallback::Create(callback));
+ bool release_called = false;
+ unsigned sync_point = 0;
+ ResourceProvider::ResourceId resource = CreateChildMailbox(
+ &release_sync_point, &lost_resource, &release_called, &sync_point);
ReturnedResourceArray returned_to_child;
int child_id =
@@ -1463,8 +1843,8 @@ TEST_P(ResourceProviderTest, LostMailboxInParent) {
ResourceProvider::ResourceIdArray resource_ids_to_transfer;
resource_ids_to_transfer.push_back(resource);
TransferableResourceArray list;
- child_resource_provider->PrepareSendToParent(resource_ids_to_transfer,
- &list);
+ child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
+ &list);
EXPECT_EQ(1u, list.size());
resource_provider_->ReceiveFromChild(child_id, list);
@@ -1483,51 +1863,27 @@ TEST_P(ResourceProviderTest, LostMailboxInParent) {
ResourceProvider::ResourceIdArray no_resources;
resource_provider_->DeclareUsedResourcesFromChild(child_id, no_resources);
- // Expect the resource to be lost.
ASSERT_EQ(1u, returned_to_child.size());
- EXPECT_TRUE(returned_to_child[0].lost);
- child_resource_provider->ReceiveReturnsFromParent(returned_to_child);
+ // Losing an output surface only loses hardware resources.
+ EXPECT_EQ(returned_to_child[0].lost,
+ GetParam() == ResourceProvider::GLTexture);
+ child_resource_provider_->ReceiveReturnsFromParent(returned_to_child);
returned_to_child.clear();
}
- // Delete the resource in the child. Expect the resource to be lost.
- child_resource_provider->DeleteResource(resource);
- EXPECT_TRUE(lost_resource);
-
- child_context->waitSyncPoint(release_sync_point);
- child_context->deleteTexture(texture);
+ // Delete the resource in the child. Expect the resource to be lost if it's
+ // a GL texture.
+ child_resource_provider_->DeleteResource(resource);
+ EXPECT_EQ(lost_resource, GetParam() == ResourceProvider::GLTexture);
}
TEST_P(ResourceProviderTest, LostMailboxInGrandParent) {
- // Resource transfer is only supported with GL textures for now.
- if (GetParam() != ResourceProvider::GLTexture)
- return;
-
- scoped_ptr<ResourceProviderContext> child_context_owned(
- ResourceProviderContext::Create(shared_data_.get()));
- ResourceProviderContext* child_context = child_context_owned.get();
-
- FakeOutputSurfaceClient child_output_surface_client;
- scoped_ptr<OutputSurface> child_output_surface(FakeOutputSurface::Create3d(
- child_context_owned.PassAs<TestWebGraphicsContext3D>()));
- CHECK(child_output_surface->BindToClient(&child_output_surface_client));
-
- scoped_ptr<ResourceProvider> child_resource_provider(
- ResourceProvider::Create(child_output_surface.get(), 0, false));
-
- unsigned texture = child_context->createTexture();
- gpu::Mailbox gpu_mailbox;
- child_context->bindTexture(GL_TEXTURE_2D, texture);
- child_context->genMailboxCHROMIUM(gpu_mailbox.name);
- child_context->produceTextureCHROMIUM(GL_TEXTURE_2D, gpu_mailbox.name);
-
unsigned release_sync_point = 0;
bool lost_resource = false;
- ReleaseCallback callback =
- base::Bind(ReleaseTextureMailbox, &release_sync_point, &lost_resource);
- ResourceProvider::ResourceId resource =
- child_resource_provider->CreateResourceFromTextureMailbox(
- TextureMailbox(gpu_mailbox), SingleReleaseCallback::Create(callback));
+ bool release_called = false;
+ unsigned sync_point = 0;
+ ResourceProvider::ResourceId resource = CreateChildMailbox(
+ &release_sync_point, &lost_resource, &release_called, &sync_point);
ReturnedResourceArray returned_to_child;
int child_id =
@@ -1537,8 +1893,8 @@ TEST_P(ResourceProviderTest, LostMailboxInGrandParent) {
ResourceProvider::ResourceIdArray resource_ids_to_transfer;
resource_ids_to_transfer.push_back(resource);
TransferableResourceArray list;
- child_resource_provider->PrepareSendToParent(resource_ids_to_transfer,
- &list);
+ child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
+ &list);
EXPECT_EQ(1u, list.size());
resource_provider_->ReceiveFromChild(child_id, list);
@@ -1580,116 +1936,54 @@ TEST_P(ResourceProviderTest, LostMailboxInGrandParent) {
// Expect the resource to be lost.
ASSERT_EQ(1u, returned_to_child.size());
EXPECT_TRUE(returned_to_child[0].lost);
- child_resource_provider->ReceiveReturnsFromParent(returned_to_child);
+ child_resource_provider_->ReceiveReturnsFromParent(returned_to_child);
returned_to_child.clear();
}
// Delete the resource in the child. Expect the resource to be lost.
- child_resource_provider->DeleteResource(resource);
+ child_resource_provider_->DeleteResource(resource);
EXPECT_TRUE(lost_resource);
-
- child_context->waitSyncPoint(release_sync_point);
- child_context->deleteTexture(texture);
}
TEST_P(ResourceProviderTest, Shutdown) {
- // TextureMailbox callbacks only exist for GL textures for now.
- if (GetParam() != ResourceProvider::GLTexture)
- return;
- unsigned texture = context()->createTexture();
- context()->bindTexture(GL_TEXTURE_2D, texture);
- gpu::Mailbox mailbox;
- context()->genMailboxCHROMIUM(mailbox.name);
- context()->produceTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name);
- unsigned sync_point = context()->insertSyncPoint();
-
- EXPECT_LT(0u, sync_point);
-
unsigned release_sync_point = 0;
bool lost_resource = false;
- scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create(
- base::Bind(ReleaseTextureMailbox, &release_sync_point, &lost_resource));
- resource_provider_->CreateResourceFromTextureMailbox(
- TextureMailbox(mailbox, sync_point),
- callback.Pass());
+ bool release_called = false;
+ unsigned sync_point = 0;
+ CreateChildMailbox(
+ &release_sync_point, &lost_resource, &release_called, &sync_point);
EXPECT_EQ(0u, release_sync_point);
EXPECT_FALSE(lost_resource);
- resource_provider_.reset();
-
- EXPECT_LE(sync_point, release_sync_point);
- EXPECT_FALSE(lost_resource);
-}
-
-static scoped_ptr<base::SharedMemory> CreateAndFillSharedMemory(
- gfx::Size size, uint32_t value) {
- scoped_ptr<base::SharedMemory> shared_memory(new base::SharedMemory);
- CHECK(shared_memory->CreateAndMapAnonymous(4 * size.GetArea()));
- uint32_t* pixels = reinterpret_cast<uint32_t*>(shared_memory->memory());
- CHECK(pixels);
- std::fill_n(pixels, size.GetArea(), value);
- return shared_memory.Pass();
-}
-
-static void ReleaseSharedMemoryCallback(
- bool* release_called,
- unsigned sync_point, bool lost_resource) {
- *release_called = true;
-}
-
-TEST_P(ResourceProviderTest, ShutdownSharedMemory) {
- if (GetParam() != ResourceProvider::Bitmap)
- return;
-
- gfx::Size size(64, 64);
- scoped_ptr<base::SharedMemory> shared_memory(
- CreateAndFillSharedMemory(size, 0));
-
- bool release_called = false;
- scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create(
- base::Bind(ReleaseSharedMemoryCallback, &release_called));
- resource_provider_->CreateResourceFromTextureMailbox(
- TextureMailbox(shared_memory.get(), size),
- callback.Pass());
-
- resource_provider_.reset();
+ child_resource_provider_.reset();
+ if (GetParam() == ResourceProvider::GLTexture) {
+ EXPECT_LE(sync_point, release_sync_point);
+ }
EXPECT_TRUE(release_called);
+ EXPECT_FALSE(lost_resource);
}
TEST_P(ResourceProviderTest, ShutdownWithExportedResource) {
- // TextureMailbox callbacks only exist for GL textures for now.
- if (GetParam() != ResourceProvider::GLTexture)
- return;
- unsigned texture = context()->createTexture();
- context()->bindTexture(GL_TEXTURE_2D, texture);
- gpu::Mailbox mailbox;
- context()->genMailboxCHROMIUM(mailbox.name);
- context()->produceTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name);
- unsigned sync_point = context()->insertSyncPoint();
-
- EXPECT_LT(0u, sync_point);
-
unsigned release_sync_point = 0;
bool lost_resource = false;
- scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create(
- base::Bind(ReleaseTextureMailbox, &release_sync_point, &lost_resource));
- ResourceProvider::ResourceId resource =
- resource_provider_->CreateResourceFromTextureMailbox(
- TextureMailbox(mailbox, sync_point),
- callback.Pass());
+ bool release_called = false;
+ unsigned sync_point = 0;
+ ResourceProvider::ResourceId resource = CreateChildMailbox(
+ &release_sync_point, &lost_resource, &release_called, &sync_point);
// Transfer the resource, so we can't release it properly on shutdown.
ResourceProvider::ResourceIdArray resource_ids_to_transfer;
resource_ids_to_transfer.push_back(resource);
TransferableResourceArray list;
- resource_provider_->PrepareSendToParent(resource_ids_to_transfer, &list);
+ child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
+ &list);
EXPECT_EQ(0u, release_sync_point);
EXPECT_FALSE(lost_resource);
- resource_provider_.reset();
+ child_resource_provider_.reset();
// Since the resource is in the parent, the child considers it lost.
EXPECT_EQ(0u, release_sync_point);
@@ -1742,7 +2036,7 @@ TEST_P(ResourceProviderTest, ScopedSampler) {
CHECK(output_surface->BindToClient(&output_surface_client));
scoped_ptr<ResourceProvider> resource_provider(
- ResourceProvider::Create(output_surface.get(), 0, false));
+ ResourceProvider::Create(output_surface.get(), NULL, 0, false));
gfx::Size size(1, 1);
ResourceFormat format = RGBA_8888;
@@ -1823,7 +2117,7 @@ TEST_P(ResourceProviderTest, ManagedResource) {
CHECK(output_surface->BindToClient(&output_surface_client));
scoped_ptr<ResourceProvider> resource_provider(
- ResourceProvider::Create(output_surface.get(), 0, false));
+ ResourceProvider::Create(output_surface.get(), NULL, 0, false));
gfx::Size size(1, 1);
ResourceFormat format = RGBA_8888;
@@ -1868,7 +2162,7 @@ TEST_P(ResourceProviderTest, TextureWrapMode) {
CHECK(output_surface->BindToClient(&output_surface_client));
scoped_ptr<ResourceProvider> resource_provider(
- ResourceProvider::Create(output_surface.get(), 0, false));
+ ResourceProvider::Create(output_surface.get(), NULL, 0, false));
gfx::Size size(1, 1);
ResourceFormat format = RGBA_8888;
@@ -1921,7 +2215,7 @@ TEST_P(ResourceProviderTest, TextureMailbox_SharedMemory) {
CHECK(output_surface->BindToClient(&output_surface_client));
scoped_ptr<ResourceProvider> resource_provider(
- ResourceProvider::Create(output_surface.get(), 0, false));
+ ResourceProvider::Create(output_surface.get(), NULL, 0, false));
scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create(
base::Bind(&EmptyReleaseCallback));
@@ -1956,7 +2250,7 @@ TEST_P(ResourceProviderTest, TextureMailbox_GLTexture2D) {
CHECK(output_surface->BindToClient(&output_surface_client));
scoped_ptr<ResourceProvider> resource_provider(
- ResourceProvider::Create(output_surface.get(), 0, false));
+ ResourceProvider::Create(output_surface.get(), NULL, 0, false));
unsigned texture_id = 1;
unsigned sync_point = 30;
@@ -2020,7 +2314,7 @@ TEST_P(ResourceProviderTest, TextureMailbox_GLTextureExternalOES) {
CHECK(output_surface->BindToClient(&output_surface_client));
scoped_ptr<ResourceProvider> resource_provider(
- ResourceProvider::Create(output_surface.get(), 0, false));
+ ResourceProvider::Create(output_surface.get(), NULL, 0, false));
unsigned texture_id = 1;
unsigned sync_point = 30;
@@ -2114,6 +2408,15 @@ class AllocationTrackingContext3D : public TestWebGraphicsContext3D {
WGC3Denum format,
WGC3Denum type,
const void* pixels));
+ MOCK_METHOD8(compressedTexImage2D,
+ void(WGC3Denum target,
+ WGC3Dint level,
+ WGC3Denum internalformat,
+ WGC3Dsizei width,
+ WGC3Dsizei height,
+ WGC3Dint border,
+ WGC3Dsizei image_size,
+ const void* data));
MOCK_METHOD1(waitAsyncTexImage2DCHROMIUM, void(WGC3Denum));
MOCK_METHOD3(createImageCHROMIUM, WGC3Duint(WGC3Dsizei, WGC3Dsizei,
WGC3Denum));
@@ -2140,7 +2443,7 @@ TEST_P(ResourceProviderTest, TextureAllocation) {
CHECK(output_surface->BindToClient(&output_surface_client));
scoped_ptr<ResourceProvider> resource_provider(
- ResourceProvider::Create(output_surface.get(), 0, false));
+ ResourceProvider::Create(output_surface.get(), NULL, 0, false));
gfx::Size size(2, 2);
gfx::Vector2d offset(0, 0);
@@ -2216,7 +2519,7 @@ TEST_P(ResourceProviderTest, PixelBuffer_GLTexture) {
int texture_id = 123;
scoped_ptr<ResourceProvider> resource_provider(
- ResourceProvider::Create(output_surface.get(), 0, false));
+ ResourceProvider::Create(output_surface.get(), NULL, 0, false));
id = resource_provider->CreateResource(
size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureUsageAny, format);
@@ -2253,7 +2556,7 @@ TEST_P(ResourceProviderTest, PixelBuffer_Bitmap) {
const uint32_t kBadBeef = 0xbadbeef;
scoped_ptr<ResourceProvider> resource_provider(
- ResourceProvider::Create(output_surface.get(), 0, false));
+ ResourceProvider::Create(output_surface.get(), NULL, 0, false));
id = resource_provider->CreateResource(
size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureUsageAny, format);
@@ -2299,7 +2602,7 @@ TEST_P(ResourceProviderTest, ForcingAsyncUploadToComplete) {
int texture_id = 123;
scoped_ptr<ResourceProvider> resource_provider(
- ResourceProvider::Create(output_surface.get(), 0, false));
+ ResourceProvider::Create(output_surface.get(), NULL, 0, false));
id = resource_provider->CreateResource(
size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureUsageAny, format);
@@ -2340,7 +2643,7 @@ TEST_P(ResourceProviderTest, PixelBufferLostContext) {
int texture_id = 123;
scoped_ptr<ResourceProvider> resource_provider(
- ResourceProvider::Create(output_surface.get(), 0, false));
+ ResourceProvider::Create(output_surface.get(), NULL, 0, false));
EXPECT_CALL(*context, createTexture()).WillRepeatedly(Return(texture_id));
@@ -2378,7 +2681,7 @@ TEST_P(ResourceProviderTest, Image_GLTexture) {
const unsigned kImageId = 234u;
scoped_ptr<ResourceProvider> resource_provider(
- ResourceProvider::Create(output_surface.get(), 0, false));
+ ResourceProvider::Create(output_surface.get(), NULL, 0, false));
id = resource_provider->CreateResource(
size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureUsageAny, format);
@@ -2470,7 +2773,7 @@ TEST_P(ResourceProviderTest, Image_Bitmap) {
const uint32_t kBadBeef = 0xbadbeef;
scoped_ptr<ResourceProvider> resource_provider(
- ResourceProvider::Create(output_surface.get(), 0, false));
+ ResourceProvider::Create(output_surface.get(), NULL, 0, false));
id = resource_provider->CreateResource(
size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureUsageAny, format);
@@ -2521,7 +2824,7 @@ TEST(ResourceProviderTest, BasicInitializeGLSoftware) {
scoped_ptr<SoftwareOutputDevice>(new SoftwareOutputDevice)));
EXPECT_TRUE(output_surface->BindToClient(&client));
scoped_ptr<ResourceProvider> resource_provider(
- ResourceProvider::Create(output_surface.get(), 0, false));
+ ResourceProvider::Create(output_surface.get(), NULL, 0, false));
CheckCreateResource(ResourceProvider::Bitmap, resource_provider.get(), NULL);
@@ -2538,6 +2841,71 @@ TEST(ResourceProviderTest, BasicInitializeGLSoftware) {
output_surface.get());
}
+TEST_P(ResourceProviderTest, CompressedTextureETC1Allocate) {
+ if (GetParam() != ResourceProvider::GLTexture)
+ return;
+
+ scoped_ptr<AllocationTrackingContext3D> context_owned(
+ new AllocationTrackingContext3D);
+ AllocationTrackingContext3D* context = context_owned.get();
+ context_owned->set_support_compressed_texture_etc1(true);
+
+ FakeOutputSurfaceClient output_surface_client;
+ scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
+ context_owned.PassAs<TestWebGraphicsContext3D>()));
+ CHECK(output_surface->BindToClient(&output_surface_client));
+
+ gfx::Size size(4, 4);
+ scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
+ output_surface.get(), shared_bitmap_manager_.get(), 0, false));
+ int texture_id = 123;
+
+ ResourceProvider::ResourceId id = resource_provider->CreateResource(
+ size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureUsageAny, ETC1);
+ EXPECT_NE(0u, id);
+ EXPECT_CALL(*context, createTexture()).WillOnce(Return(texture_id));
+ EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id)).Times(2);
+ resource_provider->AllocateForTesting(id);
+
+ EXPECT_CALL(*context, deleteTexture(texture_id)).Times(1);
+ resource_provider->DeleteResource(id);
+}
+
+TEST_P(ResourceProviderTest, CompressedTextureETC1SetPixels) {
+ if (GetParam() != ResourceProvider::GLTexture)
+ return;
+
+ scoped_ptr<AllocationTrackingContext3D> context_owned(
+ new AllocationTrackingContext3D);
+ AllocationTrackingContext3D* context = context_owned.get();
+ context_owned->set_support_compressed_texture_etc1(true);
+
+ FakeOutputSurfaceClient output_surface_client;
+ scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
+ context_owned.PassAs<TestWebGraphicsContext3D>()));
+ CHECK(output_surface->BindToClient(&output_surface_client));
+
+ gfx::Size size(4, 4);
+ scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
+ output_surface.get(), shared_bitmap_manager_.get(), 0, false));
+ int texture_id = 123;
+ uint8_t pixels[8];
+
+ ResourceProvider::ResourceId id = resource_provider->CreateResource(
+ size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureUsageAny, ETC1);
+ EXPECT_NE(0u, id);
+ EXPECT_CALL(*context, createTexture()).WillOnce(Return(texture_id));
+ EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id)).Times(3);
+ EXPECT_CALL(*context,
+ compressedTexImage2D(
+ _, 0, _, size.width(), size.height(), _, _, _)).Times(1);
+ resource_provider->SetPixels(
+ id, pixels, gfx::Rect(size), gfx::Rect(size), gfx::Vector2d(0, 0));
+
+ EXPECT_CALL(*context, deleteTexture(texture_id)).Times(1);
+ resource_provider->DeleteResource(id);
+}
+
INSTANTIATE_TEST_CASE_P(
ResourceProviderTests,
ResourceProviderTest,
diff --git a/cc/resources/resource_update_controller.cc b/cc/resources/resource_update_controller.cc
index 3114d1eead..59c536b084 100644
--- a/cc/resources/resource_update_controller.cc
+++ b/cc/resources/resource_update_controller.cc
@@ -9,6 +9,7 @@
#include "base/single_thread_task_runner.h"
#include "cc/resources/prioritized_resource.h"
#include "cc/resources/resource_provider.h"
+#include "ui/gfx/frame_time.h"
namespace {
@@ -113,7 +114,7 @@ void ResourceUpdateController::OnTimerFired() {
}
base::TimeTicks ResourceUpdateController::Now() const {
- return base::TimeTicks::Now();
+ return gfx::FrameTime::Now();
}
base::TimeDelta ResourceUpdateController::UpdateMoreTexturesTime() const {
diff --git a/cc/resources/resource_update_controller_unittest.cc b/cc/resources/resource_update_controller_unittest.cc
index 498d68202c..9f43f80d7c 100644
--- a/cc/resources/resource_update_controller_unittest.cc
+++ b/cc/resources/resource_update_controller_unittest.cc
@@ -137,7 +137,7 @@ class ResourceUpdateControllerTest : public Test {
CHECK(output_surface_->BindToClient(&output_surface_client_));
resource_provider_ =
- ResourceProvider::Create(output_surface_.get(), 0, false);
+ ResourceProvider::Create(output_surface_.get(), NULL, 0, false);
}
void AppendFullUploadsOfIndexedTextureToUpdateQueue(int count,
diff --git a/cc/resources/scoped_resource_unittest.cc b/cc/resources/scoped_resource_unittest.cc
index 8b59995f28..dc0df8bf3b 100644
--- a/cc/resources/scoped_resource_unittest.cc
+++ b/cc/resources/scoped_resource_unittest.cc
@@ -19,7 +19,7 @@ TEST(ScopedResourceTest, NewScopedResource) {
CHECK(output_surface->BindToClient(&output_surface_client));
scoped_ptr<ResourceProvider> resource_provider(
- ResourceProvider::Create(output_surface.get(), 0, false));
+ ResourceProvider::Create(output_surface.get(), NULL, 0, false));
scoped_ptr<ScopedResource> texture =
ScopedResource::create(resource_provider.get());
@@ -37,7 +37,7 @@ TEST(ScopedResourceTest, CreateScopedResource) {
CHECK(output_surface->BindToClient(&output_surface_client));
scoped_ptr<ResourceProvider> resource_provider(
- ResourceProvider::Create(output_surface.get(), 0, false));
+ ResourceProvider::Create(output_surface.get(), NULL, 0, false));
scoped_ptr<ScopedResource> texture =
ScopedResource::create(resource_provider.get());
texture->Allocate(gfx::Size(30, 30),
@@ -59,7 +59,7 @@ TEST(ScopedResourceTest, ScopedResourceIsDeleted) {
CHECK(output_surface->BindToClient(&output_surface_client));
scoped_ptr<ResourceProvider> resource_provider(
- ResourceProvider::Create(output_surface.get(), 0, false));
+ ResourceProvider::Create(output_surface.get(), NULL, 0, false));
{
scoped_ptr<ScopedResource> texture =
ScopedResource::create(resource_provider.get());
@@ -93,7 +93,7 @@ TEST(ScopedResourceTest, LeakScopedResource) {
CHECK(output_surface->BindToClient(&output_surface_client));
scoped_ptr<ResourceProvider> resource_provider(
- ResourceProvider::Create(output_surface.get(), 0, false));
+ ResourceProvider::Create(output_surface.get(), NULL, 0, false));
{
scoped_ptr<ScopedResource> texture =
ScopedResource::create(resource_provider.get());
diff --git a/cc/resources/shared_bitmap.cc b/cc/resources/shared_bitmap.cc
new file mode 100644
index 0000000000..3a6fc3589e
--- /dev/null
+++ b/cc/resources/shared_bitmap.cc
@@ -0,0 +1,17 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cc/resources/shared_bitmap.h"
+
+namespace cc {
+
+SharedBitmap::SharedBitmap(
+ base::SharedMemory* memory,
+ const SharedBitmapId& id,
+ const base::Callback<void(SharedBitmap*)>& free_callback)
+ : memory_(memory), id_(id), free_callback_(free_callback) {}
+
+SharedBitmap::~SharedBitmap() { free_callback_.Run(this); }
+
+} // namespace cc
diff --git a/cc/resources/shared_bitmap.h b/cc/resources/shared_bitmap.h
new file mode 100644
index 0000000000..9575068411
--- /dev/null
+++ b/cc/resources/shared_bitmap.h
@@ -0,0 +1,51 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CC_RESOURCES_SHARED_BITMAP_H_
+#define CC_RESOURCES_SHARED_BITMAP_H_
+
+#include "base/basictypes.h"
+#include "base/callback.h"
+#include "base/memory/shared_memory.h"
+#include "cc/base/cc_export.h"
+#include "gpu/command_buffer/common/mailbox.h"
+
+namespace base { class SharedMemory; }
+
+namespace cc {
+typedef gpu::Mailbox SharedBitmapId;
+
+class CC_EXPORT SharedBitmap {
+ public:
+ SharedBitmap(base::SharedMemory* memory,
+ const SharedBitmapId& id,
+ const base::Callback<void(SharedBitmap*)>& free_callback);
+
+ ~SharedBitmap();
+
+ bool operator<(const SharedBitmap& right) const {
+ if (memory_ < right.memory_)
+ return true;
+ if (memory_ > right.memory_)
+ return false;
+ return id_ < right.id_;
+ }
+
+ uint8* pixels() { return static_cast<uint8*>(memory_->memory()); }
+
+ base::SharedMemory* memory() { return memory_; }
+
+ SharedBitmapId id() { return id_; }
+
+ private:
+ base::SharedMemory* memory_;
+ SharedBitmapId id_;
+ base::Callback<void(SharedBitmap*)> free_callback_;
+
+ DISALLOW_COPY_AND_ASSIGN(SharedBitmap);
+};
+
+} // namespace cc
+
+#endif // CC_RESOURCES_SHARED_BITMAP_H_
diff --git a/cc/resources/shared_bitmap_manager.h b/cc/resources/shared_bitmap_manager.h
new file mode 100644
index 0000000000..53dd156470
--- /dev/null
+++ b/cc/resources/shared_bitmap_manager.h
@@ -0,0 +1,32 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CC_RESOURCES_SHARED_BITMAP_MANAGER_H_
+#define CC_RESOURCES_SHARED_BITMAP_MANAGER_H_
+
+#include "base/basictypes.h"
+#include "cc/base/cc_export.h"
+#include "cc/resources/shared_bitmap.h"
+#include "ui/gfx/size.h"
+
+namespace cc {
+
+class CC_EXPORT SharedBitmapManager {
+ public:
+ SharedBitmapManager() {}
+
+ virtual scoped_ptr<SharedBitmap> AllocateSharedBitmap(gfx::Size) = 0;
+ virtual scoped_ptr<SharedBitmap> GetSharedBitmapFromId(
+ gfx::Size,
+ const SharedBitmapId&) = 0;
+ virtual scoped_ptr<SharedBitmap> GetBitmapForSharedMemory(
+ base::SharedMemory*) = 0;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(SharedBitmapManager);
+};
+
+} // namespace cc
+
+#endif // CC_RESOURCES_SHARED_BITMAP_MANAGER_H_
diff --git a/cc/resources/tile_manager.cc b/cc/resources/tile_manager.cc
index b2e536fa8a..df69f700be 100644
--- a/cc/resources/tile_manager.cc
+++ b/cc/resources/tile_manager.cc
@@ -471,13 +471,13 @@ void TileManager::ManageTiles(const GlobalStateThatImpactsTilePriority& state) {
// Update internal state.
if (state != global_state_) {
+ global_state_ = state;
prioritized_tiles_dirty_ = true;
resource_pool_->SetResourceUsageLimits(
global_state_.memory_limit_in_bytes,
global_state_.unused_memory_limit_in_bytes,
global_state_.num_resources_limit);
}
- global_state_ = state;
// We need to call CheckForCompletedTasks() once in-between each call
// to ScheduleTasks() to prevent canceled tasks from being scheduled.
diff --git a/cc/resources/tile_manager_perftest.cc b/cc/resources/tile_manager_perftest.cc
index 7292f1debd..f533e6524b 100644
--- a/cc/resources/tile_manager_perftest.cc
+++ b/cc/resources/tile_manager_perftest.cc
@@ -40,7 +40,7 @@ class TileManagerPerfTest : public testing::Test {
CHECK(output_surface_->BindToClient(&output_surface_client_));
resource_provider_ =
- ResourceProvider::Create(output_surface_.get(), 0, false);
+ ResourceProvider::Create(output_surface_.get(), NULL, 0, false);
tile_manager_ = make_scoped_ptr(
new FakeTileManager(&tile_manager_client_, resource_provider_.get()));
picture_pile_ = FakePicturePileImpl::CreatePile();
diff --git a/cc/resources/tile_manager_unittest.cc b/cc/resources/tile_manager_unittest.cc
index 2f9db48d24..c5bc6da4de 100644
--- a/cc/resources/tile_manager_unittest.cc
+++ b/cc/resources/tile_manager_unittest.cc
@@ -26,7 +26,7 @@ class TileManagerTest : public testing::TestWithParam<bool> {
CHECK(output_surface_->BindToClient(&output_surface_client_));
resource_provider_ =
- ResourceProvider::Create(output_surface_.get(), 0, false);
+ ResourceProvider::Create(output_surface_.get(), NULL, 0, false);
tile_manager_ = make_scoped_ptr(
new FakeTileManager(&tile_manager_client_, resource_provider_.get()));
diff --git a/cc/resources/transferable_resource.cc b/cc/resources/transferable_resource.cc
index 88ad8fd055..62f1bdb164 100644
--- a/cc/resources/transferable_resource.cc
+++ b/cc/resources/transferable_resource.cc
@@ -9,7 +9,12 @@
namespace cc {
TransferableResource::TransferableResource()
- : id(0), sync_point(0), format(RGBA_8888), target(0), filter(0) {}
+ : id(0),
+ sync_point(0),
+ format(RGBA_8888),
+ target(0),
+ filter(0),
+ is_software(false) {}
TransferableResource::~TransferableResource() {
}
diff --git a/cc/resources/transferable_resource.h b/cc/resources/transferable_resource.h
index cb650a78ea..5c93d1c042 100644
--- a/cc/resources/transferable_resource.h
+++ b/cc/resources/transferable_resource.h
@@ -35,6 +35,7 @@ struct CC_EXPORT TransferableResource {
uint32 filter;
gfx::Size size;
gpu::Mailbox mailbox;
+ bool is_software;
};
} // namespace cc
diff --git a/cc/resources/ui_resource_bitmap.cc b/cc/resources/ui_resource_bitmap.cc
index 86acfa5185..62a85fc8e3 100644
--- a/cc/resources/ui_resource_bitmap.cc
+++ b/cc/resources/ui_resource_bitmap.cc
@@ -12,20 +12,21 @@ namespace cc {
void UIResourceBitmap::Create(const skia::RefPtr<SkPixelRef>& pixel_ref,
UIResourceFormat format,
- UIResourceWrapMode wrap_mode,
gfx::Size size) {
DCHECK(size.width());
DCHECK(size.height());
DCHECK(pixel_ref);
DCHECK(pixel_ref->isImmutable());
format_ = format;
- wrap_mode_ = wrap_mode;
size_ = size;
pixel_ref_ = pixel_ref;
+
+ // Default values for secondary parameters.
+ wrap_mode_ = CLAMP_TO_EDGE;
+ opaque_ = (format == ETC1);
}
-UIResourceBitmap::UIResourceBitmap(const SkBitmap& skbitmap,
- UIResourceWrapMode wrap_mode) {
+UIResourceBitmap::UIResourceBitmap(const SkBitmap& skbitmap) {
DCHECK_EQ(skbitmap.config(), SkBitmap::kARGB_8888_Config);
DCHECK_EQ(skbitmap.width(), skbitmap.rowBytesAsPixels());
DCHECK(skbitmap.isImmutable());
@@ -33,8 +34,15 @@ UIResourceBitmap::UIResourceBitmap(const SkBitmap& skbitmap,
skia::RefPtr<SkPixelRef> pixel_ref = skia::SharePtr(skbitmap.pixelRef());
Create(pixel_ref,
UIResourceBitmap::RGBA8,
- wrap_mode,
gfx::Size(skbitmap.width(), skbitmap.height()));
+
+ SetOpaque(skbitmap.isOpaque());
+}
+
+UIResourceBitmap::UIResourceBitmap(const skia::RefPtr<SkPixelRef>& pixel_ref,
+ UIResourceFormat format,
+ gfx::Size size) {
+ Create(pixel_ref, format, size);
}
UIResourceBitmap::~UIResourceBitmap() {}
diff --git a/cc/resources/ui_resource_bitmap.h b/cc/resources/ui_resource_bitmap.h
index 78cb465812..d0f717a7b2 100644
--- a/cc/resources/ui_resource_bitmap.h
+++ b/cc/resources/ui_resource_bitmap.h
@@ -24,7 +24,8 @@ namespace cc {
class CC_EXPORT UIResourceBitmap {
public:
enum UIResourceFormat {
- RGBA8
+ RGBA8,
+ ETC1
};
enum UIResourceWrapMode {
CLAMP_TO_EDGE,
@@ -34,12 +35,18 @@ class CC_EXPORT UIResourceBitmap {
gfx::Size GetSize() const { return size_; }
UIResourceFormat GetFormat() const { return format_; }
UIResourceWrapMode GetWrapMode() const { return wrap_mode_; }
+ void SetWrapMode(UIResourceWrapMode wrap_mode) { wrap_mode_ = wrap_mode; }
+ bool GetOpaque() const { return opaque_; }
+ void SetOpaque(bool opaque) { opaque_ = opaque; }
// The constructor for the UIResourceBitmap. User must ensure that |skbitmap|
// is immutable. The SkBitmap format should be in 32-bit RGBA. Wrap mode is
// unnecessary for most UI resources and is defaulted to CLAMP_TO_EDGE.
- UIResourceBitmap(const SkBitmap& skbitmap,
- UIResourceWrapMode wrap_mode = CLAMP_TO_EDGE);
+ explicit UIResourceBitmap(const SkBitmap& skbitmap);
+
+ UIResourceBitmap(const skia::RefPtr<SkPixelRef>& pixel_ref,
+ UIResourceFormat format,
+ gfx::Size size);
~UIResourceBitmap();
@@ -47,13 +54,13 @@ class CC_EXPORT UIResourceBitmap {
friend class AutoLockUIResourceBitmap;
void Create(const skia::RefPtr<SkPixelRef>& pixel_ref,
UIResourceFormat format,
- UIResourceWrapMode wrap_mode,
gfx::Size size);
skia::RefPtr<SkPixelRef> pixel_ref_;
UIResourceFormat format_;
UIResourceWrapMode wrap_mode_;
gfx::Size size_;
+ bool opaque_;
};
class CC_EXPORT AutoLockUIResourceBitmap {
diff --git a/cc/resources/video_resource_updater.cc b/cc/resources/video_resource_updater.cc
index 34c7ab65c3..b819b38fbd 100644
--- a/cc/resources/video_resource_updater.cc
+++ b/cc/resources/video_resource_updater.cc
@@ -261,24 +261,30 @@ VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes(
0xff);
}
- // In software mode, the resource provider won't be lost. Soon this callback
- // will be called directly from the resource provider, same as 3d
- // compositing mode, so this raw unretained resource_provider will always
- // be valid when the callback is fired.
RecycleResourceData recycle_data = {
plane_resources[0].resource_id,
plane_resources[0].resource_size,
plane_resources[0].resource_format,
gpu::Mailbox()
};
+ base::SharedMemory* shared_memory =
+ resource_provider_->GetSharedMemory(plane_resources[0].resource_id);
+ if (shared_memory) {
+ external_resources.mailboxes.push_back(
+ TextureMailbox(shared_memory, plane_resources[0].resource_size));
+ external_resources.release_callbacks
+ .push_back(base::Bind(&RecycleResource, AsWeakPtr(), recycle_data));
+ external_resources.type = VideoFrameExternalResources::RGB_RESOURCE;
+ } else {
+ // TODO(jbauman): Remove this path once shared memory is available
+ // everywhere.
+ external_resources.software_resources
+ .push_back(plane_resources[0].resource_id);
+ external_resources.software_release_callback =
+ base::Bind(&RecycleResource, AsWeakPtr(), recycle_data);
+ external_resources.type = VideoFrameExternalResources::SOFTWARE_RESOURCE;
+ }
- external_resources.software_resources.push_back(
- plane_resources[0].resource_id);
- external_resources.software_release_callback =
- base::Bind(&RecycleResource, AsWeakPtr(), recycle_data);
-
-
- external_resources.type = VideoFrameExternalResources::SOFTWARE_RESOURCE;
return external_resources;
}
diff --git a/cc/resources/video_resource_updater_unittest.cc b/cc/resources/video_resource_updater_unittest.cc
index c36689e16c..028e0a673e 100644
--- a/cc/resources/video_resource_updater_unittest.cc
+++ b/cc/resources/video_resource_updater_unittest.cc
@@ -26,7 +26,7 @@ class VideoResourceUpdaterTest : public testing::Test {
FakeOutputSurface::Create3d(context3d.Pass());
CHECK(output_surface3d_->BindToClient(&client_));
resource_provider3d_ =
- ResourceProvider::Create(output_surface3d_.get(), 0, false);
+ ResourceProvider::Create(output_surface3d_.get(), NULL, 0, false);
}
scoped_refptr<media::VideoFrame> CreateTestYUVVideoFrame() {
diff --git a/cc/scheduler/delay_based_time_source.cc b/cc/scheduler/delay_based_time_source.cc
index d150c717a1..00515b72f7 100644
--- a/cc/scheduler/delay_based_time_source.cc
+++ b/cc/scheduler/delay_based_time_source.cc
@@ -33,6 +33,27 @@ static const double kPhaseChangeThreshold = 0.25;
} // namespace
+// The following methods correspond to the DelayBasedTimeSource that uses
+// the base::TimeTicks::HighResNow as the timebase.
+scoped_refptr<DelayBasedTimeSourceHighRes> DelayBasedTimeSourceHighRes::Create(
+ base::TimeDelta interval,
+ base::SingleThreadTaskRunner* task_runner) {
+ return make_scoped_refptr(
+ new DelayBasedTimeSourceHighRes(interval, task_runner));
+}
+
+DelayBasedTimeSourceHighRes::DelayBasedTimeSourceHighRes(
+ base::TimeDelta interval, base::SingleThreadTaskRunner* task_runner)
+ : DelayBasedTimeSource(interval, task_runner) {}
+
+DelayBasedTimeSourceHighRes::~DelayBasedTimeSourceHighRes() {}
+
+base::TimeTicks DelayBasedTimeSourceHighRes::Now() const {
+ return base::TimeTicks::HighResNow();
+}
+
+// The following methods correspond to the DelayBasedTimeSource that uses
+// the base::TimeTicks::Now as the timebase.
scoped_refptr<DelayBasedTimeSource> DelayBasedTimeSource::Create(
base::TimeDelta interval,
base::SingleThreadTaskRunner* task_runner) {
diff --git a/cc/scheduler/delay_based_time_source.h b/cc/scheduler/delay_based_time_source.h
index 55aac5a97f..ddb89da356 100644
--- a/cc/scheduler/delay_based_time_source.h
+++ b/cc/scheduler/delay_based_time_source.h
@@ -15,7 +15,7 @@ namespace cc {
// This timer implements a time source that achieves the specified interval
// in face of millisecond-precision delayed callbacks and random queueing
-// delays.
+// delays. DelayBasedTimeSource uses base::TimeTicks::Now as its timebase.
class CC_EXPORT DelayBasedTimeSource : public TimeSource {
public:
static scoped_refptr<DelayBasedTimeSource> Create(
@@ -73,6 +73,23 @@ class CC_EXPORT DelayBasedTimeSource : public TimeSource {
DISALLOW_COPY_AND_ASSIGN(DelayBasedTimeSource);
};
+// DelayBasedTimeSource uses base::TimeTicks::HighResNow as its timebase.
+class DelayBasedTimeSourceHighRes : public DelayBasedTimeSource {
+ public:
+ static scoped_refptr<DelayBasedTimeSourceHighRes> Create(
+ base::TimeDelta interval, base::SingleThreadTaskRunner* task_runner);
+
+ virtual base::TimeTicks Now() const OVERRIDE;
+
+ protected:
+ DelayBasedTimeSourceHighRes(base::TimeDelta interval,
+ base::SingleThreadTaskRunner* task_runner);
+ virtual ~DelayBasedTimeSourceHighRes();
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(DelayBasedTimeSourceHighRes);
+};
+
} // namespace cc
#endif // CC_SCHEDULER_DELAY_BASED_TIME_SOURCE_H_
diff --git a/cc/scheduler/frame_rate_controller.cc b/cc/scheduler/frame_rate_controller.cc
index 47c27ed3f8..2729748859 100644
--- a/cc/scheduler/frame_rate_controller.cc
+++ b/cc/scheduler/frame_rate_controller.cc
@@ -11,6 +11,7 @@
#include "base/single_thread_task_runner.h"
#include "cc/scheduler/delay_based_time_source.h"
#include "cc/scheduler/time_source.h"
+#include "ui/gfx/frame_time.h"
namespace cc {
@@ -165,7 +166,7 @@ base::TimeTicks FrameRateController::LastTickTime() {
if (is_time_source_throttling_)
return time_source_->LastTickTime();
- return base::TimeTicks::Now();
+ return gfx::FrameTime::Now();
}
} // namespace cc
diff --git a/cc/scheduler/scheduler.cc b/cc/scheduler/scheduler.cc
index 382bd96348..93b91311e6 100644
--- a/cc/scheduler/scheduler.cc
+++ b/cc/scheduler/scheduler.cc
@@ -9,6 +9,7 @@
#include "base/debug/trace_event.h"
#include "base/logging.h"
#include "cc/debug/traced_value.h"
+#include "ui/gfx/frame_time.h"
namespace cc {
@@ -78,6 +79,11 @@ void Scheduler::SetSwapUsedIncompleteTile(bool used_incomplete_tile) {
ProcessScheduledActions();
}
+void Scheduler::SetSmoothnessTakesPriority(bool smoothness_takes_priority) {
+ state_machine_.SetSmoothnessTakesPriority(smoothness_takes_priority);
+ ProcessScheduledActions();
+}
+
void Scheduler::SetMainThreadNeedsLayerTextures() {
state_machine_.SetMainThreadNeedsLayerTextures();
ProcessScheduledActions();
@@ -118,7 +124,7 @@ base::TimeTicks Scheduler::AnticipatedDrawTime() {
last_begin_impl_frame_args_.interval <= base::TimeDelta())
return base::TimeTicks();
- base::TimeTicks now = base::TimeTicks::Now();
+ base::TimeTicks now = gfx::FrameTime::Now();
base::TimeTicks timebase = std::max(last_begin_impl_frame_args_.frame_time,
last_begin_impl_frame_args_.deadline);
int64 intervals =
diff --git a/cc/scheduler/scheduler.h b/cc/scheduler/scheduler.h
index 00b8377e9c..1a284f187d 100644
--- a/cc/scheduler/scheduler.h
+++ b/cc/scheduler/scheduler.h
@@ -86,6 +86,8 @@ class CC_EXPORT Scheduler {
void SetSwapUsedIncompleteTile(bool used_incomplete_tile);
+ void SetSmoothnessTakesPriority(bool smoothness_takes_priority);
+
void FinishCommit();
void BeginMainFrameAborted(bool did_handle);
diff --git a/cc/scheduler/scheduler_settings.cc b/cc/scheduler/scheduler_settings.cc
index 6c1db6bf10..9b8032c43a 100644
--- a/cc/scheduler/scheduler_settings.cc
+++ b/cc/scheduler/scheduler_settings.cc
@@ -7,7 +7,7 @@
namespace cc {
SchedulerSettings::SchedulerSettings()
- : deadline_scheduling_enabled(false),
+ : deadline_scheduling_enabled(true),
impl_side_painting(false),
timeout_and_draw_when_animation_checkerboards(true),
maximum_number_of_failed_draws_before_draw_is_forced_(3),
diff --git a/cc/scheduler/scheduler_state_machine.cc b/cc/scheduler/scheduler_state_machine.cc
index c14186a74d..0fd0f57b3b 100644
--- a/cc/scheduler/scheduler_state_machine.cc
+++ b/cc/scheduler/scheduler_state_machine.cc
@@ -9,6 +9,7 @@
#include "base/logging.h"
#include "base/strings/stringprintf.h"
#include "base/values.h"
+#include "ui/gfx/frame_time.h"
namespace cc {
@@ -39,7 +40,8 @@ SchedulerStateMachine::SchedulerStateMachine(const SchedulerSettings& settings)
pending_tree_is_ready_for_activation_(false),
active_tree_needs_first_draw_(false),
draw_if_possible_failed_(false),
- did_create_and_initialize_first_output_surface_(false) {}
+ did_create_and_initialize_first_output_surface_(false),
+ smoothness_takes_priority_(false) {}
const char* SchedulerStateMachine::OutputSurfaceStateToString(
OutputSurfaceState state) {
@@ -192,7 +194,7 @@ scoped_ptr<base::Value> SchedulerStateMachine::AsValue() const {
state->Set("major_state", major_state.release());
scoped_ptr<base::DictionaryValue> timestamps_state(new base::DictionaryValue);
- base::TimeTicks now = base::TimeTicks::Now();
+ base::TimeTicks now = gfx::FrameTime::Now();
timestamps_state->SetDouble(
"0_interval",
last_begin_impl_frame_args_.interval.InMicroseconds() / 1000.0L);
@@ -255,6 +257,8 @@ scoped_ptr<base::Value> SchedulerStateMachine::AsValue() const {
minor_state->SetBoolean("draw_if_possible_failed", draw_if_possible_failed_);
minor_state->SetBoolean("did_create_and_initialize_first_output_surface",
did_create_and_initialize_first_output_surface_);
+ minor_state->SetBoolean("smoothness_takes_priority",
+ smoothness_takes_priority_);
state->Set("minor_state", minor_state.release());
return state.PassAs<base::Value>();
@@ -820,7 +824,7 @@ bool SchedulerStateMachine::BeginImplFrameNeededToDraw() const {
// These are cases where we are very likely to draw soon, but might not
// actually have a new frame to draw when we receive the next BeginImplFrame.
// Proactively requesting the BeginImplFrame helps hide the round trip latency
-// of the SetNeedsBeginFrame request that has to go to the Browser.
+// of the SetNeedsBeginImplFrame request that has to go to the Browser.
bool SchedulerStateMachine::ProactiveBeginImplFrameWanted() const {
// The output surface is the provider of BeginImplFrames,
// so we are not going to get them even if we ask for them.
@@ -847,9 +851,10 @@ bool SchedulerStateMachine::ProactiveBeginImplFrameWanted() const {
return true;
// If we just swapped, it's likely that we are going to produce another
- // frame soon. This helps avoid negative glitches in our SetNeedsBeginFrame
- // requests, which may propagate to the BeginImplFrame provider and get
- // sampled at an inopportune time, delaying the next BeginImplFrame.
+ // frame soon. This helps avoid negative glitches in our
+ // SetNeedsBeginImplFrame requests, which may propagate to the BeginImplFrame
+ // provider and get sampled at an inopportune time, delaying the next
+ // BeginImplFrame.
if (last_frame_number_swap_performed_ == current_frame_number_)
return true;
@@ -896,12 +901,19 @@ bool SchedulerStateMachine::ShouldTriggerBeginImplFrameDeadlineEarly() const {
if (active_tree_needs_first_draw_)
return true;
+ if (!needs_redraw_)
+ return false;
+
// This is used to prioritize impl-thread draws when the main thread isn't
// producing anything, e.g., after an aborted commit. We also check that we
// don't have a pending tree -- otherwise we should give it a chance to
// activate.
// TODO(skyostil): Revisit this when we have more accurate deadline estimates.
- if (commit_state_ == COMMIT_STATE_IDLE && needs_redraw_ && !has_pending_tree_)
+ if (commit_state_ == COMMIT_STATE_IDLE && !has_pending_tree_)
+ return true;
+
+ // Prioritize impl-thread draws in smoothness mode.
+ if (smoothness_takes_priority_)
return true;
return false;
@@ -935,6 +947,11 @@ void SchedulerStateMachine::SetSwapUsedIncompleteTile(
swap_used_incomplete_tile_ = used_incomplete_tile;
}
+void SchedulerStateMachine::SetSmoothnessTakesPriority(
+ bool smoothness_takes_priority) {
+ smoothness_takes_priority_ = smoothness_takes_priority;
+}
+
void SchedulerStateMachine::DidDrawIfPossibleCompleted(bool success) {
draw_if_possible_failed_ = !success;
if (draw_if_possible_failed_) {
diff --git a/cc/scheduler/scheduler_state_machine.h b/cc/scheduler/scheduler_state_machine.h
index 01eeca60e8..9b6d4fb41e 100644
--- a/cc/scheduler/scheduler_state_machine.h
+++ b/cc/scheduler/scheduler_state_machine.h
@@ -171,6 +171,10 @@ class CC_EXPORT SchedulerStateMachine {
// with a low resolution or checkerboarded tile.
void SetSwapUsedIncompleteTile(bool used_incomplete_tile);
+ // Indicates whether to prioritize animation smoothness over new content
+ // activation.
+ void SetSmoothnessTakesPriority(bool smoothness_takes_priority);
+
// Indicates whether ACTION_DRAW_AND_SWAP_IF_POSSIBLE drew to the screen.
void DidDrawIfPossibleCompleted(bool success);
@@ -283,6 +287,7 @@ class CC_EXPORT SchedulerStateMachine {
bool active_tree_needs_first_draw_;
bool draw_if_possible_failed_;
bool did_create_and_initialize_first_output_surface_;
+ bool smoothness_takes_priority_;
private:
DISALLOW_COPY_AND_ASSIGN(SchedulerStateMachine);
diff --git a/cc/scheduler/scheduler_state_machine_unittest.cc b/cc/scheduler/scheduler_state_machine_unittest.cc
index e58015dd26..67925a059b 100644
--- a/cc/scheduler/scheduler_state_machine_unittest.cc
+++ b/cc/scheduler/scheduler_state_machine_unittest.cc
@@ -1735,5 +1735,31 @@ TEST(SchedulerStateMachineTest,
EXPECT_TRUE(state.ShouldTriggerBeginImplFrameDeadlineEarly());
}
+TEST(SchedulerStateMachineTest, TestTriggerDeadlineEarlyForSmoothness) {
+ SchedulerSettings settings;
+ settings.deadline_scheduling_enabled = true;
+ settings.impl_side_painting = true;
+ StateMachine state(settings);
+ state.SetCanStart();
+ state.UpdateState(state.NextAction());
+ state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
+ state.SetVisible(true);
+ state.SetCanDraw(true);
+
+ // This test ensures that impl-draws are prioritized over main thread updates
+ // in prefer smoothness mode.
+ state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
+ state.SetNeedsRedraw(true);
+ state.SetNeedsCommit();
+ EXPECT_ACTION_UPDATE_STATE(
+ SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
+
+ // The deadline is not triggered early until we enter prefer smoothness mode.
+ EXPECT_FALSE(state.ShouldTriggerBeginImplFrameDeadlineEarly());
+ state.SetSmoothnessTakesPriority(true);
+ EXPECT_TRUE(state.ShouldTriggerBeginImplFrameDeadlineEarly());
+}
+
} // namespace
} // namespace cc
diff --git a/cc/scheduler/texture_uploader.cc b/cc/scheduler/texture_uploader.cc
index cebc986891..ba4e372175 100644
--- a/cc/scheduler/texture_uploader.cc
+++ b/cc/scheduler/texture_uploader.cc
@@ -143,6 +143,13 @@ void TextureUploader::Upload(const uint8* image,
if (is_full_upload)
BeginQuery();
+ if (format == ETC1) {
+ // ETC1 does not support subimage uploads.
+ DCHECK(is_full_upload);
+ UploadWithTexImageETC1(image, size);
+ return;
+ }
+
if (use_map_tex_sub_image_) {
UploadWithMapTexSubImage(
image, image_rect, source_rect, dest_offset, format);
@@ -190,7 +197,7 @@ void TextureUploader::UploadWithTexSubImage(const uint8* image,
gfx::Vector2d offset(source_rect.origin() - image_rect.origin());
const uint8* pixel_source;
- unsigned bytes_per_pixel = BytesPerPixel(format);
+ unsigned bytes_per_pixel = BitsPerPixel(format) / 8;
// Use 4-byte row alignment (OpenGL default) for upload performance.
// Assuming that GL_UNPACK_ALIGNMENT has not changed from default.
unsigned upload_image_stride =
@@ -239,11 +246,13 @@ void TextureUploader::UploadWithMapTexSubImage(const uint8* image,
if (source_rect.IsEmpty())
return;
DCHECK(image);
+ // Compressed textures have no implementation of mapTexSubImage.
+ DCHECK_NE(ETC1, format);
// Offset from image-rect to source-rect.
gfx::Vector2d offset(source_rect.origin() - image_rect.origin());
- unsigned bytes_per_pixel = BytesPerPixel(format);
+ unsigned bytes_per_pixel = BitsPerPixel(format) / 8;
// Use 4-byte row alignment (OpenGL default) for upload performance.
// Assuming that GL_UNPACK_ALIGNMENT has not changed from default.
unsigned upload_image_stride =
@@ -285,6 +294,22 @@ void TextureUploader::UploadWithMapTexSubImage(const uint8* image,
context_->unmapTexSubImage2DCHROMIUM(pixel_dest);
}
+void TextureUploader::UploadWithTexImageETC1(const uint8* image,
+ gfx::Size size) {
+ TRACE_EVENT0("cc", "TextureUploader::UploadWithTexImageETC1");
+ DCHECK_EQ(0, size.width() % 4);
+ DCHECK_EQ(0, size.height() % 4);
+
+ context_->compressedTexImage2D(GL_TEXTURE_2D,
+ 0,
+ GLInternalFormat(ETC1),
+ size.width(),
+ size.height(),
+ 0,
+ Resource::MemorySizeBytes(size, ETC1),
+ image);
+}
+
void TextureUploader::ProcessQueries() {
while (!pending_queries_.empty()) {
if (pending_queries_.front()->IsPending())
diff --git a/cc/scheduler/texture_uploader.h b/cc/scheduler/texture_uploader.h
index a131ba04f9..5b1b1d8332 100644
--- a/cc/scheduler/texture_uploader.h
+++ b/cc/scheduler/texture_uploader.h
@@ -103,6 +103,7 @@ class CC_EXPORT TextureUploader {
gfx::Rect source_rect,
gfx::Vector2d dest_offset,
ResourceFormat format);
+ void UploadWithTexImageETC1(const uint8* image, gfx::Size size);
WebKit::WebGraphicsContext3D* context_;
ScopedPtrDeque<Query> pending_queries_;
diff --git a/cc/test/data/background_filter_blur_off_axis.png b/cc/test/data/background_filter_blur_off_axis.png
index 59488a6201..b5777f42e0 100644
--- a/cc/test/data/background_filter_blur_off_axis.png
+++ b/cc/test/data/background_filter_blur_off_axis.png
Binary files differ
diff --git a/cc/test/data/touch_region_heavy.json b/cc/test/data/touch_region_heavy.json
new file mode 100644
index 0000000000..26d618e508
--- /dev/null
+++ b/cc/test/data/touch_region_heavy.json
@@ -0,0 +1,515 @@
+{
+ "Bounds": [ 0, 0 ],
+ "Children": [ {
+ "Bounds": [ 384, 640 ],
+ "Children": [ {
+ "Bounds": [ 384, 1681 ],
+ "Children": [ {
+ "Bounds": [ 384, 1681 ],
+ "Children": [ {
+ "Bounds": [ 384, 1681 ],
+ "Children": [ {
+ "Bounds": [ 298, 114 ],
+ "Children": [ {
+ "Bounds": [ 12979, 130 ],
+ "Children": [ ],
+ "ContentsOpaque": false,
+ "DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -10288.0, 118.0, 0.0, 1.0 ],
+ "DrawsContent": true,
+ "LayerType": "cc::TiledLayerImpl",
+ "Opacity": 1.0,
+ "Position": [ -9999.0, -1.0 ],
+ "TouchRegion": [ -9999, -1, 11499, 1, -9999, 0, 12979, 126, -9999, 126, 11499, 3 ]
+ } ],
+ "ContentsOpaque": false,
+ "DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 11.0, 119.0, 0.0, 1.0 ],
+ "DrawsContent": false,
+ "LayerType": "cc::TiledLayerImpl",
+ "Opacity": 1.0,
+ "Position": [ 11.0, 120.0 ]
+ }, {
+ "Bounds": [ 320, 320 ],
+ "Children": [ {
+ "Bounds": [ 152, 152 ],
+ "Children": [ ],
+ "ContentsOpaque": false,
+ "DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ],
+ "DrawsContent": true,
+ "LayerType": "cc::TiledLayerImpl",
+ "Opacity": 0.0,
+ "Position": [ 4.0, 5.0 ]
+ } ],
+ "ContentsOpaque": false,
+ "DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 287.0, 0.0, 1.0 ],
+ "DrawsContent": false,
+ "LayerType": "cc::TiledLayerImpl",
+ "Opacity": 1.0,
+ "Position": [ 0.0, 288.0 ]
+ }, {
+ "Bounds": [ 320, 320 ],
+ "Children": [ {
+ "Bounds": [ 152, 152 ],
+ "Children": [ ],
+ "ContentsOpaque": false,
+ "DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ],
+ "DrawsContent": true,
+ "LayerType": "cc::TiledLayerImpl",
+ "Opacity": 0.0,
+ "Position": [ 4.0, 5.0 ]
+ } ],
+ "ContentsOpaque": false,
+ "DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 287.0, 0.0, 1.0 ],
+ "DrawsContent": false,
+ "LayerType": "cc::TiledLayerImpl",
+ "Opacity": 1.0,
+ "Position": [ 0.0, 288.0 ]
+ }, {
+ "Bounds": [ 320, 320 ],
+ "Children": [ {
+ "Bounds": [ 152, 152 ],
+ "Children": [ ],
+ "ContentsOpaque": false,
+ "DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ],
+ "DrawsContent": true,
+ "LayerType": "cc::TiledLayerImpl",
+ "Opacity": 0.0,
+ "Position": [ 4.0, 5.0 ]
+ } ],
+ "ContentsOpaque": false,
+ "DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 287.0, 0.0, 1.0 ],
+ "DrawsContent": false,
+ "LayerType": "cc::TiledLayerImpl",
+ "Opacity": 1.0,
+ "Position": [ 0.0, 288.0 ]
+ }, {
+ "Bounds": [ 320, 320 ],
+ "Children": [ {
+ "Bounds": [ 152, 152 ],
+ "Children": [ ],
+ "ContentsOpaque": false,
+ "DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ],
+ "DrawsContent": true,
+ "LayerType": "cc::TiledLayerImpl",
+ "Opacity": 0.0,
+ "Position": [ 4.0, 5.0 ]
+ } ],
+ "ContentsOpaque": false,
+ "DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 287.0, 0.0, 1.0 ],
+ "DrawsContent": false,
+ "LayerType": "cc::TiledLayerImpl",
+ "Opacity": 1.0,
+ "Position": [ 0.0, 288.0 ]
+ }, {
+ "Bounds": [ 300, 114 ],
+ "Children": [ {
+ "Bounds": [ 300, 114 ],
+ "Children": [ ],
+ "ContentsOpaque": false,
+ "DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 10.0, 119.0, 0.0, 1.0 ],
+ "DrawsContent": true,
+ "LayerType": "cc::TiledLayerImpl",
+ "Opacity": 1.0,
+ "Position": [ 0.0, 0.0 ],
+ "TouchRegion": [ 0, -1, 300, 115, 1, 114, 298, 1 ]
+ } ],
+ "ContentsOpaque": false,
+ "DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 10.0, 119.0, 0.0, 1.0 ],
+ "DrawsContent": false,
+ "LayerType": "cc::TiledLayerImpl",
+ "Opacity": 1.0,
+ "Position": [ 10.0, 120.0 ]
+ }, {
+ "Bounds": [ 300, 114 ],
+ "Children": [ {
+ "Bounds": [ 18, 36 ],
+ "Children": [ ],
+ "ContentsOpaque": false,
+ "DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 10.0, 154.0, 0.0, 1.0 ],
+ "DrawsContent": true,
+ "LayerType": "cc::TiledLayerImpl",
+ "Opacity": 1.0,
+ "Position": [ 0.0, 35.0 ],
+ "TouchRegion": [ -9999, -1, 10017, 36 ]
+ } ],
+ "ContentsOpaque": false,
+ "DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 10.0, 119.0, 0.0, 1.0 ],
+ "DrawsContent": false,
+ "LayerType": "cc::TiledLayerImpl",
+ "Opacity": 1.0,
+ "Position": [ 10.0, 120.0 ]
+ }, {
+ "Bounds": [ 300, 114 ],
+ "Children": [ {
+ "Bounds": [ 300, 36 ],
+ "Children": [ ],
+ "ContentsOpaque": false,
+ "DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 10.0, 154.0, 0.0, 1.0 ],
+ "DrawsContent": true,
+ "LayerType": "cc::TiledLayerImpl",
+ "Opacity": 1.0,
+ "Position": [ 0.0, 35.0 ],
+ "TouchRegion": [ -9999, -1, 10017, 36 ]
+ } ],
+ "ContentsOpaque": false,
+ "DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 10.0, 119.0, 0.0, 1.0 ],
+ "DrawsContent": false,
+ "LayerType": "cc::TiledLayerImpl",
+ "Opacity": 1.0,
+ "Position": [ 10.0, 120.0 ]
+ }, {
+ "Bounds": [ 320, 320 ],
+ "Children": [ {
+ "Bounds": [ 152, 152 ],
+ "Children": [ ],
+ "ContentsOpaque": false,
+ "DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 4.0, 292.0, 0.0, 1.0 ],
+ "DrawsContent": true,
+ "LayerType": "cc::TiledLayerImpl",
+ "Opacity": 1.0,
+ "Position": [ 4.0, 5.0 ]
+ } ],
+ "ContentsOpaque": false,
+ "DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 287.0, 0.0, 1.0 ],
+ "DrawsContent": false,
+ "LayerType": "cc::TiledLayerImpl",
+ "Opacity": 1.0,
+ "Position": [ 0.0, 288.0 ]
+ }, {
+ "Bounds": [ 320, 320 ],
+ "Children": [ {
+ "Bounds": [ 152, 152 ],
+ "Children": [ ],
+ "ContentsOpaque": false,
+ "DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 164.0, 292.0, 0.0, 1.0 ],
+ "DrawsContent": true,
+ "LayerType": "cc::TiledLayerImpl",
+ "Opacity": 1.0,
+ "Position": [ 4.0, 5.0 ]
+ } ],
+ "ContentsOpaque": false,
+ "DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 287.0, 0.0, 1.0 ],
+ "DrawsContent": false,
+ "LayerType": "cc::TiledLayerImpl",
+ "Opacity": 1.0,
+ "Position": [ 0.0, 288.0 ]
+ }, {
+ "Bounds": [ 320, 320 ],
+ "Children": [ {
+ "Bounds": [ 152, 152 ],
+ "Children": [ ],
+ "ContentsOpaque": false,
+ "DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 4.0, 452.0, 0.0, 1.0 ],
+ "DrawsContent": true,
+ "LayerType": "cc::TiledLayerImpl",
+ "Opacity": 1.0,
+ "Position": [ 4.0, 5.0 ],
+ "TouchRegion": [ -1, 0, 152, 117, -9895, 117, 10046, 5, -9994, 122, 10145, 24, -9895, 146, 10046, 1, -1, 147, 152, 5, 5, 152, 140, 1 ]
+ } ],
+ "ContentsOpaque": false,
+ "DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 287.0, 0.0, 1.0 ],
+ "DrawsContent": false,
+ "LayerType": "cc::TiledLayerImpl",
+ "Opacity": 1.0,
+ "Position": [ 0.0, 288.0 ]
+ }, {
+ "Bounds": [ 320, 320 ],
+ "Children": [ {
+ "Bounds": [ 152, 152 ],
+ "Children": [ ],
+ "ContentsOpaque": false,
+ "DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 164.0, 452.0, 0.0, 1.0 ],
+ "DrawsContent": true,
+ "LayerType": "cc::TiledLayerImpl",
+ "Opacity": 1.0,
+ "Position": [ 4.0, 5.0 ],
+ "TouchRegion": [ -1, 0, 152, 117, -9895, 117, 10046, 5, -9994, 122, 10145, 24, -9895, 146, 10046, 1, -1, 147, 152, 5, 5, 152, 140, 1 ]
+ } ],
+ "ContentsOpaque": false,
+ "DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 287.0, 0.0, 1.0 ],
+ "DrawsContent": false,
+ "LayerType": "cc::TiledLayerImpl",
+ "Opacity": 1.0,
+ "Position": [ 0.0, 288.0 ]
+ }, {
+ "Bounds": [ 320, 800 ],
+ "Children": [ {
+ "Bounds": [ 152, 152 ],
+ "Children": [ ],
+ "ContentsOpaque": false,
+ "DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 4.0, 658.0, 0.0, 1.0 ],
+ "DrawsContent": true,
+ "LayerType": "cc::TiledLayerImpl",
+ "Opacity": 1.0,
+ "Position": [ 4.0, 5.0 ],
+ "TouchRegion": [ -1, 0, 152, 117, -9895, 117, 10046, 5, -9994, 122, 10145, 24, -9895, 146, 10046, 1, -1, 147, 152, 5, 5, 152, 140, 1 ]
+ } ],
+ "ContentsOpaque": false,
+ "DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 653.0, 0.0, 1.0 ],
+ "DrawsContent": false,
+ "LayerType": "cc::TiledLayerImpl",
+ "Opacity": 1.0,
+ "Position": [ 0.0, 654.0 ]
+ }, {
+ "Bounds": [ 320, 800 ],
+ "Children": [ {
+ "Bounds": [ 152, 152 ],
+ "Children": [ ],
+ "ContentsOpaque": false,
+ "DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 164.0, 658.0, 0.0, 1.0 ],
+ "DrawsContent": true,
+ "LayerType": "cc::TiledLayerImpl",
+ "Opacity": 1.0,
+ "Position": [ 4.0, 5.0 ],
+ "TouchRegion": [ -1, 0, 152, 117, -9895, 117, 10046, 5, -9994, 122, 10145, 24, -9895, 146, 10046, 1, -1, 147, 152, 5, 5, 152, 140, 1 ]
+ } ],
+ "ContentsOpaque": false,
+ "DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 653.0, 0.0, 1.0 ],
+ "DrawsContent": false,
+ "LayerType": "cc::TiledLayerImpl",
+ "Opacity": 1.0,
+ "Position": [ 0.0, 654.0 ]
+ }, {
+ "Bounds": [ 320, 800 ],
+ "Children": [ {
+ "Bounds": [ 152, 152 ],
+ "Children": [ ],
+ "ContentsOpaque": false,
+ "DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 4.0, 818.0, 0.0, 1.0 ],
+ "DrawsContent": true,
+ "LayerType": "cc::TiledLayerImpl",
+ "Opacity": 1.0,
+ "Position": [ 4.0, 5.0 ],
+ "TouchRegion": [ -1, 0, 152, 117, -9895, 117, 10046, 5, -9994, 122, 10145, 24, -9895, 146, 10046, 1, -1, 147, 152, 5, 5, 152, 140, 1 ]
+ } ],
+ "ContentsOpaque": false,
+ "DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 653.0, 0.0, 1.0 ],
+ "DrawsContent": false,
+ "LayerType": "cc::TiledLayerImpl",
+ "Opacity": 1.0,
+ "Position": [ 0.0, 654.0 ]
+ }, {
+ "Bounds": [ 320, 800 ],
+ "Children": [ {
+ "Bounds": [ 152, 152 ],
+ "Children": [ ],
+ "ContentsOpaque": false,
+ "DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 164.0, 818.0, 0.0, 1.0 ],
+ "DrawsContent": true,
+ "LayerType": "cc::TiledLayerImpl",
+ "Opacity": 1.0,
+ "Position": [ 4.0, 5.0 ],
+ "TouchRegion": [ -1, 0, 152, 117, -9895, 117, 10046, 5, -9994, 122, 10145, 24, -9895, 146, 10046, 1, -1, 147, 152, 5, 5, 152, 140, 1 ]
+ } ],
+ "ContentsOpaque": false,
+ "DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 653.0, 0.0, 1.0 ],
+ "DrawsContent": false,
+ "LayerType": "cc::TiledLayerImpl",
+ "Opacity": 1.0,
+ "Position": [ 0.0, 654.0 ]
+ }, {
+ "Bounds": [ 320, 800 ],
+ "Children": [ {
+ "Bounds": [ 152, 152 ],
+ "Children": [ ],
+ "ContentsOpaque": false,
+ "DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 4.0, 978.0, 0.0, 1.0 ],
+ "DrawsContent": true,
+ "LayerType": "cc::TiledLayerImpl",
+ "Opacity": 1.0,
+ "Position": [ 4.0, 5.0 ],
+ "TouchRegion": [ -1, 0, 152, 117, -9895, 117, 10046, 5, -9994, 122, 10145, 24, -9895, 146, 10046, 1, -1, 147, 152, 5, 5, 152, 140, 1 ]
+ } ],
+ "ContentsOpaque": false,
+ "DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 653.0, 0.0, 1.0 ],
+ "DrawsContent": false,
+ "LayerType": "cc::TiledLayerImpl",
+ "Opacity": 1.0,
+ "Position": [ 0.0, 654.0 ]
+ }, {
+ "Bounds": [ 320, 800 ],
+ "Children": [ {
+ "Bounds": [ 152, 152 ],
+ "Children": [ ],
+ "ContentsOpaque": false,
+ "DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 164.0, 978.0, 0.0, 1.0 ],
+ "DrawsContent": true,
+ "LayerType": "cc::TiledLayerImpl",
+ "Opacity": 1.0,
+ "Position": [ 4.0, 5.0 ],
+ "TouchRegion": [ -1, 0, 152, 117, -9895, 117, 10046, 5, -9994, 122, 10145, 24, -9895, 146, 10046, 1, -1, 147, 152, 5, 5, 152, 140, 1 ]
+ } ],
+ "ContentsOpaque": false,
+ "DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 653.0, 0.0, 1.0 ],
+ "DrawsContent": false,
+ "LayerType": "cc::TiledLayerImpl",
+ "Opacity": 1.0,
+ "Position": [ 0.0, 654.0 ]
+ }, {
+ "Bounds": [ 320, 800 ],
+ "Children": [ {
+ "Bounds": [ 152, 152 ],
+ "Children": [ ],
+ "ContentsOpaque": false,
+ "DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 4.0, 1138.0, 0.0, 1.0 ],
+ "DrawsContent": true,
+ "LayerType": "cc::TiledLayerImpl",
+ "Opacity": 1.0,
+ "Position": [ 4.0, 5.0 ],
+ "TouchRegion": [ -1, 0, 152, 117, -9895, 117, 10046, 5, -9994, 122, 10145, 24, -9895, 146, 10046, 1, -1, 147, 152, 5, 5, 152, 140, 1 ]
+ } ],
+ "ContentsOpaque": false,
+ "DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 653.0, 0.0, 1.0 ],
+ "DrawsContent": false,
+ "LayerType": "cc::TiledLayerImpl",
+ "Opacity": 1.0,
+ "Position": [ 0.0, 654.0 ]
+ }, {
+ "Bounds": [ 320, 800 ],
+ "Children": [ {
+ "Bounds": [ 152, 152 ],
+ "Children": [ ],
+ "ContentsOpaque": false,
+ "DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 164.0, 1138.0, 0.0, 1.0 ],
+ "DrawsContent": true,
+ "LayerType": "cc::TiledLayerImpl",
+ "Opacity": 1.0,
+ "Position": [ 4.0, 5.0 ],
+ "TouchRegion": [ -1, 0, 152, 117, -9895, 117, 10046, 5, -9994, 122, 10145, 24, -9895, 146, 10046, 1, -1, 147, 152, 5, 5, 152, 140, 1 ]
+ } ],
+ "ContentsOpaque": false,
+ "DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 653.0, 0.0, 1.0 ],
+ "DrawsContent": false,
+ "LayerType": "cc::TiledLayerImpl",
+ "Opacity": 1.0,
+ "Position": [ 0.0, 654.0 ]
+ }, {
+ "Bounds": [ 320, 800 ],
+ "Children": [ {
+ "Bounds": [ 152, 152 ],
+ "Children": [ ],
+ "ContentsOpaque": false,
+ "DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 4.0, 1298.0, 0.0, 1.0 ],
+ "DrawsContent": true,
+ "LayerType": "cc::TiledLayerImpl",
+ "Opacity": 1.0,
+ "Position": [ 4.0, 5.0 ],
+ "TouchRegion": [ -1, 0, 152, 117, -9895, 117, 10046, 5, -9994, 122, 10145, 24, -9895, 146, 10046, 1, -1, 147, 152, 5, 5, 152, 140, 1 ]
+ } ],
+ "ContentsOpaque": false,
+ "DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 653.0, 0.0, 1.0 ],
+ "DrawsContent": false,
+ "LayerType": "cc::TiledLayerImpl",
+ "Opacity": 1.0,
+ "Position": [ 0.0, 654.0 ]
+ }, {
+ "Bounds": [ 320, 800 ],
+ "Children": [ {
+ "Bounds": [ 152, 152 ],
+ "Children": [ ],
+ "ContentsOpaque": false,
+ "DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 164.0, 1298.0, 0.0, 1.0 ],
+ "DrawsContent": true,
+ "LayerType": "cc::TiledLayerImpl",
+ "Opacity": 1.0,
+ "Position": [ 4.0, 5.0 ],
+ "TouchRegion": [ -1, 0, 152, 117, -9895, 117, 10046, 5, -9994, 122, 10145, 24, -9895, 146, 10046, 1, -1, 147, 152, 5, 5, 152, 140, 1 ]
+ } ],
+ "ContentsOpaque": false,
+ "DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 653.0, 0.0, 1.0 ],
+ "DrawsContent": false,
+ "LayerType": "cc::TiledLayerImpl",
+ "Opacity": 1.0,
+ "Position": [ 0.0, 654.0 ]
+ }, {
+ "Bounds": [ 320, 1498 ],
+ "Children": [ {
+ "Bounds": [ 104, 37 ],
+ "Children": [ ],
+ "ContentsOpaque": false,
+ "DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 5.0, 256.0, 0.0, 1.0 ],
+ "DrawsContent": true,
+ "LayerType": "cc::TiledLayerImpl",
+ "Opacity": 1.0,
+ "Position": [ 5.0, 147.0 ]
+ } ],
+ "ContentsOpaque": false,
+ "DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 109.0, 0.0, 1.0 ],
+ "DrawsContent": false,
+ "LayerType": "cc::TiledLayerImpl",
+ "Opacity": 1.0,
+ "Position": [ 0.0, 110.0 ]
+ }, {
+ "Bounds": [ 320, 1498 ],
+ "Children": [ {
+ "Bounds": [ 1, 13 ],
+ "Children": [ ],
+ "ContentsOpaque": true,
+ "DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 108.0, 266.0, 0.0, 1.0 ],
+ "DrawsContent": true,
+ "LayerType": "cc::TiledLayerImpl",
+ "Opacity": 1.0,
+ "Position": [ 108.0, 157.0 ]
+ } ],
+ "ContentsOpaque": false,
+ "DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 109.0, 0.0, 1.0 ],
+ "DrawsContent": false,
+ "LayerType": "cc::TiledLayerImpl",
+ "Opacity": 1.0,
+ "Position": [ 0.0, 110.0 ]
+ } ],
+ "ContentsOpaque": true,
+ "DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -0.0, -1.0, 0.0, 1.0 ],
+ "DrawsContent": true,
+ "LayerType": "cc::TiledLayerImpl",
+ "Opacity": 1.0,
+ "Position": [ 0.0, 0.0 ],
+ "TouchRegion": [ -9993, 0, 326, 50, 0, 0, 320, 50, -9993, 50, 326, 6, -9990, 56, 320, 3, -9990, 59, 320, 1, 8, 59, 44, 1, -9990, 60, 320, 32, 8, 60, 44, 32, 247, 60, 65, 32, -9990, 92, 320, 1, 8, 92, 44, 1, -9990, 93, 320, 27, -9990, 120, 320, 48, 10, 120, 300, 48, -9990, 168, 320, 42, -262, 168, 262, 42, 10, 168, 300, 42, -9990, 210, 320, 2, 10, 210, 300, 2, -9990, 212, 320, 22, -262, 212, 262, 22, 10, 212, 300, 22, -9990, 234, 320, 20, -262, 234, 262, 20, -9990, 254, 320, 2, -9990, 256, 320, 42, -262, 256, 262, 42, -9990, 298, 320, 2, -9990, 300, 320, 42, -262, 300, 262, 42, -9990, 342, 320, 180 ]
+ } ],
+ "ContentsOpaque": false,
+ "DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -0.0, -1.0, 0.0, 1.0 ],
+ "DrawsContent": false,
+ "LayerType": "cc::TiledLayerImpl",
+ "Opacity": 1.0,
+ "Position": [ 0.0, 0.0 ]
+ } ],
+ "ContentsOpaque": false,
+ "DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -0.0, -1.0, 0.0, 1.0 ],
+ "DrawsContent": false,
+ "LayerType": "cc::TiledLayerImpl",
+ "Opacity": 1.0,
+ "Position": [ 0.0, 0.0 ],
+ "Scrollable": true
+ } ],
+ "ContentsOpaque": false,
+ "DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ],
+ "DrawsContent": false,
+ "LayerType": "cc::TiledLayerImpl",
+ "Opacity": 1.0,
+ "Position": [ 0.0, 0.0 ]
+ }, {
+ "Bounds": [ 10, 640 ],
+ "Children": [ {
+ "Bounds": [ 10, 640 ],
+ "Children": [ ],
+ "ContentsOpaque": false,
+ "DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 374.0, 0.0, 0.0, 1.0 ],
+ "DrawsContent": true,
+ "LayerType": "cc::PaintedScrollbarLayerImpl",
+ "Opacity": 1.0,
+ "Position": [ 0.0, 0.0 ]
+ } ],
+ "ContentsOpaque": false,
+ "DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 374.0, 0.0, 0.0, 1.0 ],
+ "DrawsContent": false,
+ "LayerType": "cc::TiledLayerImpl",
+ "Opacity": 1.0,
+ "Position": [ 374.0, 0.0 ]
+ } ],
+ "ContentsOpaque": false,
+ "DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ],
+ "DrawsContent": false,
+ "LayerType": "cc::TiledLayerImpl",
+ "Opacity": 1.0,
+ "Position": [ 0.0, 0.0 ]
+}
+
diff --git a/cc/test/data/touch_region_light.json b/cc/test/data/touch_region_light.json
new file mode 100644
index 0000000000..8b737b56e1
--- /dev/null
+++ b/cc/test/data/touch_region_light.json
@@ -0,0 +1,67 @@
+{
+ "Bounds": [ 0, 0 ],
+ "Children": [ {
+ "Bounds": [ 384, 640 ],
+ "Children": [ {
+ "Bounds": [ 384, 732 ],
+ "Children": [ {
+ "Bounds": [ 384, 732 ],
+ "Children": [ {
+ "Bounds": [ 384, 732 ],
+ "Children": [ ],
+ "ContentsOpaque": true,
+ "DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -0.0, -1.0, 0.0, 1.0 ],
+ "DrawsContent": true,
+ "LayerType": "cc::TiledLayerImpl",
+ "Opacity": 1.0,
+ "Position": [ 0.0, 0.0 ],
+ "TouchRegion": [ 0, 0, 384, 732 ]
+ } ],
+ "ContentsOpaque": false,
+ "DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -0.0, -1.0, 0.0, 1.0 ],
+ "DrawsContent": false,
+ "LayerType": "cc::TiledLayerImpl",
+ "Opacity": 1.0,
+ "Position": [ 0.0, 0.0 ]
+ } ],
+ "ContentsOpaque": false,
+ "DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -0.0, -1.0, 0.0, 1.0 ],
+ "DrawsContent": false,
+ "LayerType": "cc::TiledLayerImpl",
+ "Opacity": 1.0,
+ "Position": [ 0.0, 0.0 ],
+ "Scrollable": true
+ } ],
+ "ContentsOpaque": false,
+ "DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ],
+ "DrawsContent": false,
+ "LayerType": "cc::TiledLayerImpl",
+ "Opacity": 1.0,
+ "Position": [ 0.0, 0.0 ]
+ }, {
+ "Bounds": [ 10, 640 ],
+ "Children": [ {
+ "Bounds": [ 10, 640 ],
+ "Children": [ ],
+ "ContentsOpaque": false,
+ "DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 374.0, 0.0, 0.0, 1.0 ],
+ "DrawsContent": true,
+ "LayerType": "cc::PaintedScrollbarLayerImpl",
+ "Opacity": 1.0,
+ "Position": [ 0.0, 0.0 ]
+ } ],
+ "ContentsOpaque": false,
+ "DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 374.0, 0.0, 0.0, 1.0 ],
+ "DrawsContent": false,
+ "LayerType": "cc::TiledLayerImpl",
+ "Opacity": 1.0,
+ "Position": [ 374.0, 0.0 ]
+ } ],
+ "ContentsOpaque": false,
+ "DrawTransform": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ],
+ "DrawsContent": false,
+ "LayerType": "cc::TiledLayerImpl",
+ "Opacity": 1.0,
+ "Position": [ 0.0, 0.0 ]
+}
+
diff --git a/cc/test/fake_layer_tree_host.h b/cc/test/fake_layer_tree_host.h
index 074355ddb8..3acfdd291e 100644
--- a/cc/test/fake_layer_tree_host.h
+++ b/cc/test/fake_layer_tree_host.h
@@ -46,7 +46,7 @@ class FakeLayerTreeHost : protected LayerTreeHost {
private:
FakeLayerTreeHost(LayerTreeHostClient* client,
const LayerTreeSettings& settings)
- : LayerTreeHost(client, settings),
+ : LayerTreeHost(client, NULL, settings),
host_impl_(settings, &proxy_),
needs_commit_(false) {}
diff --git a/cc/test/fake_layer_tree_host_client.h b/cc/test/fake_layer_tree_host_client.h
index 0a8470adac..a1e170819a 100644
--- a/cc/test/fake_layer_tree_host_client.h
+++ b/cc/test/fake_layer_tree_host_client.h
@@ -24,8 +24,8 @@ class FakeLayerTreeHostClient : public LayerTreeHostClient {
explicit FakeLayerTreeHostClient(RendererOptions options);
virtual ~FakeLayerTreeHostClient();
- virtual void WillBeginFrame() OVERRIDE {}
- virtual void DidBeginFrame() OVERRIDE {}
+ virtual void WillBeginMainFrame() OVERRIDE {}
+ virtual void DidBeginMainFrame() OVERRIDE {}
virtual void Animate(double frame_begin_time) OVERRIDE {}
virtual void Layout() OVERRIDE {}
virtual void ApplyScrollAndScale(gfx::Vector2d scroll_delta,
diff --git a/cc/test/fake_layer_tree_host_impl.cc b/cc/test/fake_layer_tree_host_impl.cc
index c1a7326f63..258617bc0f 100644
--- a/cc/test/fake_layer_tree_host_impl.cc
+++ b/cc/test/fake_layer_tree_host_impl.cc
@@ -11,18 +11,19 @@ FakeLayerTreeHostImpl::FakeLayerTreeHostImpl(Proxy* proxy)
: LayerTreeHostImpl(LayerTreeSettings(),
&client_,
proxy,
- &stats_instrumentation_) {
+ &stats_instrumentation_,
+ NULL) {
// Explicitly clear all debug settings.
SetDebugState(LayerTreeDebugState());
}
-FakeLayerTreeHostImpl::FakeLayerTreeHostImpl(
- const LayerTreeSettings& settings,
- Proxy* proxy)
+FakeLayerTreeHostImpl::FakeLayerTreeHostImpl(const LayerTreeSettings& settings,
+ Proxy* proxy)
: LayerTreeHostImpl(settings,
&client_,
proxy,
- &stats_instrumentation_) {
+ &stats_instrumentation_,
+ NULL) {
// Explicitly clear all debug settings.
SetDebugState(LayerTreeDebugState());
}
diff --git a/cc/test/fake_layer_tree_host_impl_client.h b/cc/test/fake_layer_tree_host_impl_client.h
index b0e3a15807..708bbcf94e 100644
--- a/cc/test/fake_layer_tree_host_impl_client.h
+++ b/cc/test/fake_layer_tree_host_impl_client.h
@@ -15,7 +15,7 @@ class FakeLayerTreeHostImplClient : public LayerTreeHostImplClient {
// LayerTreeHostImplClient implementation.
virtual void DidLoseOutputSurfaceOnImplThread() OVERRIDE {}
virtual void OnSwapBuffersCompleteOnImplThread() OVERRIDE {}
- virtual void BeginFrameOnImplThread(const BeginFrameArgs& args)
+ virtual void BeginImplFrame(const BeginFrameArgs& args)
OVERRIDE {}
virtual void OnCanDrawStateChanged(bool can_draw) OVERRIDE {}
virtual void NotifyReadyToActivate() OVERRIDE {}
@@ -30,7 +30,6 @@ class FakeLayerTreeHostImplClient : public LayerTreeHostImplClient {
virtual bool ReduceContentsTextureMemoryOnImplThread(
size_t limit_bytes,
int priority_cutoff) OVERRIDE;
- virtual void ReduceWastedContentsTextureMemoryOnImplThread() OVERRIDE {}
virtual void SendManagedMemoryStats() OVERRIDE {}
virtual bool IsInsideDraw() OVERRIDE;
virtual void RenewTreePriority() OVERRIDE {}
diff --git a/cc/test/fake_output_surface.cc b/cc/test/fake_output_surface.cc
index ae5bd22707..a2d67f7f61 100644
--- a/cc/test/fake_output_surface.cc
+++ b/cc/test/fake_output_surface.cc
@@ -19,7 +19,7 @@ FakeOutputSurface::FakeOutputSurface(
: OutputSurface(context_provider),
client_(NULL),
num_sent_frames_(0),
- needs_begin_frame_(false),
+ needs_begin_impl_frame_(false),
forced_draw_to_software_device_(false),
has_external_stencil_test_(false),
fake_weak_ptr_factory_(this) {
@@ -84,22 +84,22 @@ void FakeOutputSurface::SwapBuffers(CompositorFrame* frame) {
}
}
-void FakeOutputSurface::SetNeedsBeginFrame(bool enable) {
- needs_begin_frame_ = enable;
- OutputSurface::SetNeedsBeginFrame(enable);
+void FakeOutputSurface::SetNeedsBeginImplFrame(bool enable) {
+ needs_begin_impl_frame_ = enable;
+ OutputSurface::SetNeedsBeginImplFrame(enable);
- // If there is not BeginFrame emulation from the FrameRateController,
- // then we just post a BeginFrame to emulate it as part of the test.
+ // If there is not BeginImplFrame emulation from the FrameRateController,
+ // then we just post a BeginImplFrame to emulate it as part of the test.
if (enable && !frame_rate_controller_) {
base::MessageLoop::current()->PostDelayedTask(
- FROM_HERE, base::Bind(&FakeOutputSurface::OnBeginFrame,
+ FROM_HERE, base::Bind(&FakeOutputSurface::OnBeginImplFrame,
fake_weak_ptr_factory_.GetWeakPtr()),
base::TimeDelta::FromMilliseconds(16));
}
}
-void FakeOutputSurface::OnBeginFrame() {
- OutputSurface::BeginFrame(BeginFrameArgs::CreateForTesting());
+void FakeOutputSurface::OnBeginImplFrame() {
+ OutputSurface::BeginImplFrame(BeginFrameArgs::CreateForTesting());
}
diff --git a/cc/test/fake_output_surface.h b/cc/test/fake_output_surface.h
index a93b4f3497..0540f13228 100644
--- a/cc/test/fake_output_surface.h
+++ b/cc/test/fake_output_surface.h
@@ -94,9 +94,9 @@ class FakeOutputSurface : public OutputSurface {
virtual void SwapBuffers(CompositorFrame* frame) OVERRIDE;
- virtual void SetNeedsBeginFrame(bool enable) OVERRIDE;
- bool needs_begin_frame() const {
- return needs_begin_frame_;
+ virtual void SetNeedsBeginImplFrame(bool enable) OVERRIDE;
+ bool needs_begin_impl_frame() const {
+ return needs_begin_impl_frame_;
}
void set_forced_draw_to_software_device(bool forced) {
@@ -140,12 +140,12 @@ class FakeOutputSurface : public OutputSurface {
scoped_ptr<SoftwareOutputDevice> software_device,
bool delegated_rendering);
- void OnBeginFrame();
+ void OnBeginImplFrame();
OutputSurfaceClient* client_;
CompositorFrame last_sent_frame_;
size_t num_sent_frames_;
- bool needs_begin_frame_;
+ bool needs_begin_impl_frame_;
bool forced_draw_to_software_device_;
bool has_external_stencil_test_;
TransferableResourceArray resources_held_by_parent_;
diff --git a/cc/test/fake_output_surface_client.cc b/cc/test/fake_output_surface_client.cc
index 2ce6cf077f..841797403c 100644
--- a/cc/test/fake_output_surface_client.cc
+++ b/cc/test/fake_output_surface_client.cc
@@ -12,8 +12,8 @@ bool FakeOutputSurfaceClient::DeferredInitialize(
return deferred_initialize_result_;
}
-void FakeOutputSurfaceClient::BeginFrame(const BeginFrameArgs& args) {
- begin_frame_count_++;
+void FakeOutputSurfaceClient::BeginImplFrame(const BeginFrameArgs& args) {
+ begin_impl_frame_count_++;
}
void FakeOutputSurfaceClient::DidLoseOutputSurface() {
diff --git a/cc/test/fake_output_surface_client.h b/cc/test/fake_output_surface_client.h
index 08511ad326..bf127d1d4f 100644
--- a/cc/test/fake_output_surface_client.h
+++ b/cc/test/fake_output_surface_client.h
@@ -13,7 +13,7 @@ namespace cc {
class FakeOutputSurfaceClient : public OutputSurfaceClient {
public:
FakeOutputSurfaceClient()
- : begin_frame_count_(0),
+ : begin_impl_frame_count_(0),
deferred_initialize_result_(true),
deferred_initialize_called_(false),
did_lose_output_surface_called_(false),
@@ -24,7 +24,7 @@ class FakeOutputSurfaceClient : public OutputSurfaceClient {
scoped_refptr<ContextProvider> offscreen_context_provider) OVERRIDE;
virtual void ReleaseGL() OVERRIDE {}
virtual void SetNeedsRedrawRect(gfx::Rect damage_rect) OVERRIDE {}
- virtual void BeginFrame(const BeginFrameArgs& args) OVERRIDE;
+ virtual void BeginImplFrame(const BeginFrameArgs& args) OVERRIDE;
virtual void OnSwapBuffersComplete() OVERRIDE {}
virtual void ReclaimResources(const CompositorFrameAck* ack) OVERRIDE {}
virtual void DidLoseOutputSurface() OVERRIDE;
@@ -37,8 +37,8 @@ class FakeOutputSurfaceClient : public OutputSurfaceClient {
virtual void SetDiscardBackBufferWhenNotVisible(bool discard) OVERRIDE;
virtual void SetTreeActivationCallback(const base::Closure&) OVERRIDE {}
- int begin_frame_count() {
- return begin_frame_count_;
+ int begin_impl_frame_count() {
+ return begin_impl_frame_count_;
}
void set_deferred_initialize_result(bool result) {
@@ -60,7 +60,7 @@ class FakeOutputSurfaceClient : public OutputSurfaceClient {
}
private:
- int begin_frame_count_;
+ int begin_impl_frame_count_;
bool deferred_initialize_result_;
bool deferred_initialize_called_;
bool did_lose_output_surface_called_;
diff --git a/cc/test/fake_picture_layer_impl.h b/cc/test/fake_picture_layer_impl.h
index 2eeaeef959..759ceeb938 100644
--- a/cc/test/fake_picture_layer_impl.h
+++ b/cc/test/fake_picture_layer_impl.h
@@ -47,6 +47,7 @@ class FakePictureLayerImpl : public PictureLayerImpl {
PictureLayerImpl* twin_layer() { return twin_layer_; }
PictureLayerTilingSet* tilings() { return tilings_.get(); }
+ PicturePileImpl* pile() { return pile_.get(); }
size_t append_quads_count() { return append_quads_count_; }
const Region& invalidation() const { return invalidation_; }
diff --git a/cc/test/fake_picture_pile_impl.cc b/cc/test/fake_picture_pile_impl.cc
index 03084ed7be..989c4f9f7a 100644
--- a/cc/test/fake_picture_pile_impl.cc
+++ b/cc/test/fake_picture_pile_impl.cc
@@ -65,19 +65,12 @@ void FakePicturePileImpl::AddRecordingAt(int x, int y) {
scoped_refptr<Picture> picture(Picture::Create(bounds));
picture->Record(&client_, tile_grid_info_);
picture->GatherPixelRefs(tile_grid_info_);
- picture_list_map_[std::pair<int, int>(x, y)].push_back(picture);
+ picture_map_[std::pair<int, int>(x, y)].picture = picture;
EXPECT_TRUE(HasRecordingAt(x, y));
UpdateRecordedRegion();
}
-void FakePicturePileImpl::AddPictureToRecording(
- int x,
- int y,
- scoped_refptr<Picture> picture) {
- picture_list_map_[std::pair<int, int>(x, y)].push_back(picture);
-}
-
void FakePicturePileImpl::RemoveRecordingAt(int x, int y) {
EXPECT_GE(x, 0);
EXPECT_GE(y, 0);
@@ -86,7 +79,7 @@ void FakePicturePileImpl::RemoveRecordingAt(int x, int y) {
if (!HasRecordingAt(x, y))
return;
- picture_list_map_.erase(std::pair<int, int>(x, y));
+ picture_map_.erase(std::pair<int, int>(x, y));
EXPECT_FALSE(HasRecordingAt(x, y));
UpdateRecordedRegion();
diff --git a/cc/test/fake_picture_pile_impl.h b/cc/test/fake_picture_pile_impl.h
index 770dffe4e3..935e4a254e 100644
--- a/cc/test/fake_picture_pile_impl.h
+++ b/cc/test/fake_picture_pile_impl.h
@@ -29,11 +29,6 @@ class FakePicturePileImpl : public PicturePileImpl {
void RemoveRecordingAt(int x, int y);
void RerecordPile();
- void AddPictureToRecording(
- int x,
- int y,
- scoped_refptr<Picture> picture);
-
void add_draw_rect(const gfx::RectF& rect) {
client_.add_draw_rect(rect, default_paint_);
}
diff --git a/cc/test/fake_proxy.cc b/cc/test/fake_proxy.cc
index 3fe12c85c9..90c5b1c1cd 100644
--- a/cc/test/fake_proxy.cc
+++ b/cc/test/fake_proxy.cc
@@ -29,6 +29,8 @@ RendererCapabilities& FakeProxy::GetRendererCapabilities() {
return capabilities_;
}
+bool FakeProxy::BeginMainFrameRequested() const { return false; }
+
bool FakeProxy::CommitRequested() const { return false; }
size_t FakeProxy::MaxPartialTextureUpdates() const {
diff --git a/cc/test/fake_proxy.h b/cc/test/fake_proxy.h
index 3127cb430e..bcde11ecb7 100644
--- a/cc/test/fake_proxy.h
+++ b/cc/test/fake_proxy.h
@@ -36,6 +36,7 @@ class FakeProxy : public Proxy {
virtual void NotifyInputThrottledUntilCommit() OVERRIDE {}
virtual void SetDeferCommits(bool defer_commits) OVERRIDE {}
virtual void MainThreadHasStoppedFlinging() OVERRIDE {}
+ virtual bool BeginMainFrameRequested() const OVERRIDE;
virtual bool CommitRequested() const OVERRIDE;
virtual void Start(scoped_ptr<OutputSurface> first_output_surface) OVERRIDE {}
virtual void Stop() OVERRIDE {}
diff --git a/cc/test/fake_ui_resource_layer_tree_host_impl.cc b/cc/test/fake_ui_resource_layer_tree_host_impl.cc
index ec087f25a8..c1d3e75181 100644
--- a/cc/test/fake_ui_resource_layer_tree_host_impl.cc
+++ b/cc/test/fake_ui_resource_layer_tree_host_impl.cc
@@ -18,7 +18,12 @@ void FakeUIResourceLayerTreeHostImpl::CreateUIResource(
const UIResourceBitmap& bitmap) {
if (ResourceIdForUIResource(uid))
DeleteUIResource(uid);
- fake_ui_resource_map_[uid] = fake_next_resource_id_;
+
+ UIResourceData data;
+ data.resource_id = fake_next_resource_id_++;
+ data.size = bitmap.GetSize();
+ data.opaque = bitmap.GetOpaque();
+ fake_ui_resource_map_[uid] = data;
}
void FakeUIResourceLayerTreeHostImpl::DeleteUIResource(UIResourceId uid) {
@@ -32,8 +37,15 @@ ResourceProvider::ResourceId
UIResourceId uid) const {
UIResourceMap::const_iterator iter = fake_ui_resource_map_.find(uid);
if (iter != fake_ui_resource_map_.end())
- return iter->second;
+ return iter->second.resource_id;
return 0;
}
+bool FakeUIResourceLayerTreeHostImpl::IsUIResourceOpaque(UIResourceId uid)
+ const {
+ UIResourceMap::const_iterator iter = fake_ui_resource_map_.find(uid);
+ DCHECK(iter != fake_ui_resource_map_.end());
+ return iter->second.opaque;
+}
+
} // namespace cc
diff --git a/cc/test/fake_ui_resource_layer_tree_host_impl.h b/cc/test/fake_ui_resource_layer_tree_host_impl.h
index eceece96df..7e461dfe28 100644
--- a/cc/test/fake_ui_resource_layer_tree_host_impl.h
+++ b/cc/test/fake_ui_resource_layer_tree_host_impl.h
@@ -23,9 +23,11 @@ class FakeUIResourceLayerTreeHostImpl : public FakeLayerTreeHostImpl {
virtual ResourceProvider::ResourceId ResourceIdForUIResource(
UIResourceId uid) const OVERRIDE;
+ virtual bool IsUIResourceOpaque(UIResourceId uid) const OVERRIDE;
+
private:
ResourceProvider::ResourceId fake_next_resource_id_;
- typedef base::hash_map<UIResourceId, ResourceProvider::ResourceId>
+ typedef base::hash_map<UIResourceId, LayerTreeHostImpl::UIResourceData>
UIResourceMap;
UIResourceMap fake_ui_resource_map_;
};
diff --git a/cc/test/layer_tree_json_parser.cc b/cc/test/layer_tree_json_parser.cc
index af24571be9..9a1b198a7b 100644
--- a/cc/test/layer_tree_json_parser.cc
+++ b/cc/test/layer_tree_json_parser.cc
@@ -53,8 +53,8 @@ scoped_refptr<Layer> ParseTreeFromValue(base::Value* val,
ListValue* bounds;
success &= dict->GetList("ImageBounds", &bounds);
double image_width, image_height;
- success &= bounds->GetDouble(0, &image_height);
- success &= bounds->GetDouble(1, &image_width);
+ success &= bounds->GetDouble(0, &image_width);
+ success &= bounds->GetDouble(1, &image_height);
success &= dict->GetList("Border", &list);
int border_x, border_y, border_width, border_height;
@@ -81,7 +81,7 @@ scoped_refptr<Layer> ParseTreeFromValue(base::Value* val,
new_layer = nine_patch_layer;
} else if (layer_type == "TextureLayer") {
- new_layer = TextureLayer::Create(NULL);
+ new_layer = TextureLayer::CreateForMailbox(NULL);
} else if (layer_type == "PictureLayer") {
new_layer = PictureLayer::Create(content_client);
} else { // Type "Layer" or "unknown"
@@ -104,6 +104,24 @@ scoped_refptr<Layer> ParseTreeFromValue(base::Value* val,
if (dict->GetBoolean("Scrollable", &scrollable))
new_layer->SetScrollable(scrollable);
+ bool wheel_handler;
+ if (dict->GetBoolean("WheelHandler", &wheel_handler))
+ new_layer->SetHaveWheelEventHandlers(wheel_handler);
+
+ if (dict->HasKey("TouchRegion")) {
+ success &= dict->GetList("TouchRegion", &list);
+ cc::Region touch_region;
+ for (size_t i = 0; i < list->GetSize(); ) {
+ int rect_x, rect_y, rect_width, rect_height;
+ success &= list->GetInteger(i++, &rect_x);
+ success &= list->GetInteger(i++, &rect_y);
+ success &= list->GetInteger(i++, &rect_width);
+ success &= list->GetInteger(i++, &rect_height);
+ touch_region.Union(gfx::Rect(rect_x, rect_y, rect_width, rect_height));
+ }
+ new_layer->SetTouchEventHandlerRegion(touch_region);
+ }
+
success &= dict->GetList("DrawTransform", &list);
double transform[16];
for (int i = 0; i < 16; ++i)
diff --git a/cc/test/layer_tree_json_parser_unittest.cc b/cc/test/layer_tree_json_parser_unittest.cc
new file mode 100644
index 0000000000..4261a71109
--- /dev/null
+++ b/cc/test/layer_tree_json_parser_unittest.cc
@@ -0,0 +1,116 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cc/test/layer_tree_json_parser.h"
+
+#include "cc/layers/layer.h"
+#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/geometry_test_utils.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace cc {
+
+namespace {
+
+bool LayerTreesMatch(LayerImpl* const layer_impl,
+ Layer* const layer) {
+#define RETURN_IF_EXPECTATION_FAILS(exp) \
+ do { \
+ exp; \
+ if (testing::UnitTest::GetInstance()->current_test_info()-> \
+ result()->Failed()) \
+ return false; \
+ } while (0)
+
+ RETURN_IF_EXPECTATION_FAILS(EXPECT_EQ(layer_impl->children().size(),
+ layer->children().size()));
+ RETURN_IF_EXPECTATION_FAILS(EXPECT_SIZE_EQ(layer_impl->bounds(),
+ layer->bounds()));
+ RETURN_IF_EXPECTATION_FAILS(EXPECT_POINT_EQ(layer_impl->position(),
+ layer->position()));
+ RETURN_IF_EXPECTATION_FAILS(
+ EXPECT_TRANSFORMATION_MATRIX_EQ(layer_impl->draw_transform(),
+ layer->draw_transform()));
+ RETURN_IF_EXPECTATION_FAILS(EXPECT_EQ(layer_impl->contents_opaque(),
+ layer->contents_opaque()));
+ RETURN_IF_EXPECTATION_FAILS(EXPECT_EQ(layer_impl->scrollable(),
+ layer->scrollable()));
+ RETURN_IF_EXPECTATION_FAILS(EXPECT_FLOAT_EQ(layer_impl->opacity(),
+ layer->opacity()));
+ RETURN_IF_EXPECTATION_FAILS(EXPECT_EQ(layer_impl->have_wheel_event_handlers(),
+ layer->have_wheel_event_handlers()));
+ RETURN_IF_EXPECTATION_FAILS(
+ EXPECT_EQ(layer_impl->touch_event_handler_region(),
+ layer->touch_event_handler_region()));
+
+ for (size_t i = 0; i < layer_impl->children().size(); ++i) {
+ RETURN_IF_EXPECTATION_FAILS(
+ EXPECT_TRUE(LayerTreesMatch(layer_impl->children()[i],
+ layer->children()[i])));
+ }
+
+ return true;
+#undef RETURN_IF_EXPECTATION_FAILS
+}
+
+} // namespace
+
+class LayerTreeJsonParserSanityCheck : public testing::Test {
+};
+
+TEST_F(LayerTreeJsonParserSanityCheck, Basic) {
+ FakeImplProxy proxy;
+ FakeLayerTreeHostImpl host_impl(&proxy);
+ LayerTreeImpl* tree = host_impl.active_tree();
+
+ scoped_ptr<LayerImpl> root_impl(LayerImpl::Create(tree, 1));
+ scoped_ptr<LayerImpl> parent(LayerImpl::Create(tree, 2));
+ scoped_ptr<LayerImpl> child(LayerImpl::Create(tree, 3));
+
+ root_impl->SetBounds(gfx::Size(100, 100));
+ parent->SetBounds(gfx::Size(50, 50));
+ child->SetBounds(gfx::Size(40, 40));
+
+ parent->SetPosition(gfx::Point(25, 25));
+
+ child->SetHaveWheelEventHandlers(true);
+
+ parent->AddChild(child.Pass());
+ root_impl->AddChild(parent.Pass());
+ tree->SetRootLayer(root_impl.Pass());
+
+ std::string json = host_impl.LayerTreeAsJson();
+ scoped_refptr<Layer> root = ParseTreeFromJson(json, NULL);
+ ASSERT_TRUE(root);
+ EXPECT_TRUE(LayerTreesMatch(host_impl.RootLayer(), root.get()));
+}
+
+TEST_F(LayerTreeJsonParserSanityCheck, EventHandlerRegions) {
+ FakeImplProxy proxy;
+ FakeLayerTreeHostImpl host_impl(&proxy);
+ LayerTreeImpl* tree = host_impl.active_tree();
+
+ scoped_ptr<LayerImpl> root_impl(LayerImpl::Create(tree, 1));
+ scoped_ptr<LayerImpl> touch_layer(LayerImpl::Create(tree, 2));
+
+ root_impl->SetBounds(gfx::Size(100, 100));
+ touch_layer->SetBounds(gfx::Size(50, 50));
+
+ cc::Region touch_region;
+ touch_region.Union(gfx::Rect(10, 10, 20, 30));
+ touch_region.Union(gfx::Rect(40, 10, 20, 20));
+ touch_layer->SetTouchEventHandlerRegion(touch_region);
+
+ root_impl->AddChild(touch_layer.Pass());
+ tree->SetRootLayer(root_impl.Pass());
+
+ std::string json = host_impl.LayerTreeAsJson();
+ scoped_refptr<Layer> root = ParseTreeFromJson(json, NULL);
+ ASSERT_TRUE(root);
+ EXPECT_TRUE(LayerTreesMatch(host_impl.RootLayer(), root.get()));
+}
+
+} // namespace cc
diff --git a/cc/test/layer_tree_pixel_test.cc b/cc/test/layer_tree_pixel_test.cc
index 70e6223f30..d0a5c59d4e 100644
--- a/cc/test/layer_tree_pixel_test.cc
+++ b/cc/test/layer_tree_pixel_test.cc
@@ -4,7 +4,9 @@
#include "cc/test/layer_tree_pixel_test.h"
+#include "base/command_line.h"
#include "base/path_service.h"
+#include "cc/base/switches.h"
#include "cc/layers/solid_color_layer.h"
#include "cc/layers/texture_layer.h"
#include "cc/output/copy_output_request.h"
@@ -96,8 +98,9 @@ void LayerTreePixelTest::AfterTest() {
EXPECT_TRUE(PathService::Get(cc::DIR_TEST_DATA, &test_data_dir));
base::FilePath ref_file_path = test_data_dir.Append(ref_file_);
- // To rebaseline:
- // EXPECT_TRUE(WritePNGFile(*result_bitmap_, ref_file_path, true));
+ CommandLine* cmd = CommandLine::ForCurrentProcess();
+ if (cmd->HasSwitch(switches::kCCRebaselinePixeltests))
+ EXPECT_TRUE(WritePNGFile(*result_bitmap_, ref_file_path, true));
EXPECT_TRUE(MatchesPNGFile(*result_bitmap_,
ref_file_path,
diff --git a/cc/test/layer_tree_test.cc b/cc/test/layer_tree_test.cc
index da0ed55872..9ca0bbde14 100644
--- a/cc/test/layer_tree_test.cc
+++ b/cc/test/layer_tree_test.cc
@@ -23,6 +23,7 @@
#include "cc/trees/layer_tree_host_impl.h"
#include "cc/trees/single_thread_proxy.h"
#include "testing/gmock/include/gmock/gmock.h"
+#include "ui/gfx/frame_time.h"
#include "ui/gfx/size_conversions.h"
namespace cc {
@@ -68,14 +69,15 @@ class LayerTreeHostImplForTesting : public LayerTreeHostImpl {
: LayerTreeHostImpl(settings,
host_impl_client,
proxy,
- stats_instrumentation),
+ stats_instrumentation,
+ NULL),
test_hooks_(test_hooks),
block_notify_ready_to_activate_for_testing_(false),
notify_ready_to_activate_was_blocked_(false) {}
- virtual void BeginFrame(const BeginFrameArgs& args) OVERRIDE {
+ virtual void BeginImplFrame(const BeginFrameArgs& args) OVERRIDE {
test_hooks_->WillBeginImplFrameOnThread(this, args);
- LayerTreeHostImpl::BeginFrame(args);
+ LayerTreeHostImpl::BeginImplFrame(args);
test_hooks_->DidBeginImplFrameOnThread(this, args);
}
@@ -233,7 +235,7 @@ class LayerTreeHostForTesting : public LayerTreeHost {
LayerTreeHostForTesting(TestHooks* test_hooks,
LayerTreeHostClient* client,
const LayerTreeSettings& settings)
- : LayerTreeHost(client, settings),
+ : LayerTreeHost(client, NULL, settings),
test_hooks_(test_hooks),
test_started_(false) {}
@@ -250,9 +252,13 @@ class LayerTreeHostClientForTesting : public LayerTreeHostClient {
}
virtual ~LayerTreeHostClientForTesting() {}
- virtual void WillBeginFrame() OVERRIDE { test_hooks_->WillBeginFrame(); }
+ virtual void WillBeginMainFrame() OVERRIDE {
+ test_hooks_->WillBeginMainFrame();
+ }
- virtual void DidBeginFrame() OVERRIDE { test_hooks_->DidBeginFrame(); }
+ virtual void DidBeginMainFrame() OVERRIDE {
+ test_hooks_->DidBeginMainFrame();
+ }
virtual void Animate(double monotonic_time) OVERRIDE {
test_hooks_->Animate(base::TimeTicks::FromInternalValue(
@@ -586,7 +592,7 @@ void LayerTreeTest::DispatchComposite() {
}
schedule_when_set_visible_true_ = false;
- base::TimeTicks now = base::TimeTicks::Now();
+ base::TimeTicks now = gfx::FrameTime::Now();
layer_tree_host_->Composite(now);
}
@@ -602,7 +608,7 @@ void LayerTreeTest::RunTest(bool threaded,
delegating_renderer_ = delegating_renderer;
- // Spend less time waiting for BeginFrame because the output is
+ // Spend less time waiting for BeginImplFrame because the output is
// mocked out.
settings_.refresh_rate = 200.0;
if (impl_side_painting) {
diff --git a/cc/test/layer_tree_test.h b/cc/test/layer_tree_test.h
index 4fb5525e7e..aa5583745e 100644
--- a/cc/test/layer_tree_test.h
+++ b/cc/test/layer_tree_test.h
@@ -57,8 +57,8 @@ class TestHooks : public AnimationDelegate {
virtual void ApplyScrollAndScale(gfx::Vector2d scroll_delta,
float scale) {}
virtual void Animate(base::TimeTicks monotonic_time) {}
- virtual void WillBeginFrame() {}
- virtual void DidBeginFrame() {}
+ virtual void WillBeginMainFrame() {}
+ virtual void DidBeginMainFrame() {}
virtual void Layout() {}
virtual void DidInitializeOutputSurface(bool succeeded) {}
virtual void DidFailToInitializeOutputSurface() {}
diff --git a/cc/test/pixel_test.cc b/cc/test/pixel_test.cc
index 05688b1de5..12b729b31d 100644
--- a/cc/test/pixel_test.cc
+++ b/cc/test/pixel_test.cc
@@ -4,8 +4,10 @@
#include "cc/test/pixel_test.h"
+#include "base/command_line.h"
#include "base/path_service.h"
#include "base/run_loop.h"
+#include "cc/base/switches.h"
#include "cc/output/compositor_frame_metadata.h"
#include "cc/output/copy_output_request.h"
#include "cc/output/copy_output_result.h"
@@ -49,7 +51,7 @@ class PixelTest::PixelTestRendererClient
}
virtual void ReleaseGL() OVERRIDE {}
virtual void SetNeedsRedrawRect(gfx::Rect damage_rect) OVERRIDE {}
- virtual void BeginFrame(const BeginFrameArgs& args) OVERRIDE {}
+ virtual void BeginImplFrame(const BeginFrameArgs& args) OVERRIDE {}
virtual void OnSwapBuffersComplete() OVERRIDE {}
virtual void ReclaimResources(const CompositorFrameAck* ack) OVERRIDE {}
virtual void DidLoseOutputSurface() OVERRIDE {}
@@ -147,8 +149,9 @@ bool PixelTest::PixelsMatchReference(const base::FilePath& ref_file,
if (!result_bitmap_)
return false;
- // To rebaseline:
- // return WritePNGFile(*result_bitmap_, test_data_dir.Append(ref_file), true);
+ CommandLine* cmd = CommandLine::ForCurrentProcess();
+ if (cmd->HasSwitch(switches::kCCRebaselinePixeltests))
+ return WritePNGFile(*result_bitmap_, test_data_dir.Append(ref_file), true);
return MatchesPNGFile(*result_bitmap_,
test_data_dir.Append(ref_file),
@@ -165,7 +168,7 @@ void PixelTest::SetUpGLRenderer(bool use_skia_gpu_backend) {
output_surface_->BindToClient(fake_client_.get());
resource_provider_ =
- ResourceProvider::Create(output_surface_.get(), 0, false);
+ ResourceProvider::Create(output_surface_.get(), NULL, 0, false);
texture_mailbox_deleter_ = make_scoped_ptr(new TextureMailboxDeleter);
@@ -208,12 +211,12 @@ void PixelTest::SetUpSoftwareRenderer() {
output_surface_.reset(new PixelTestOutputSurface(device.Pass()));
output_surface_->BindToClient(fake_client_.get());
resource_provider_ =
- ResourceProvider::Create(output_surface_.get(), 0, false);
+ ResourceProvider::Create(output_surface_.get(), NULL, 0, false);
renderer_ = SoftwareRenderer::Create(fake_client_.get(),
&settings_,
output_surface_.get(),
resource_provider_.get())
- .PassAs<DirectRenderer>();
+ .PassAs<DirectRenderer>();
}
} // namespace cc
diff --git a/cc/test/run_all_perftests.cc b/cc/test/run_all_perftests.cc
new file mode 100644
index 0000000000..abe854986d
--- /dev/null
+++ b/cc/test/run_all_perftests.cc
@@ -0,0 +1,16 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cc/test/cc_test_suite.h"
+#include "testing/gmock/include/gmock/gmock.h"
+
+int main(int argc, char** argv) {
+ ::testing::InitGoogleMock(&argc, argv);
+ cc::CCTestSuite test_suite(argc, argv);
+
+ // Always run the perf tests serially, to avoid distorting
+ // perf measurements with randomness resulting from running
+ // in parallel.
+ return test_suite.Run();
+}
diff --git a/cc/trees/layer_tree_host.cc b/cc/trees/layer_tree_host.cc
index 2d3c6083c5..d93e3d5e03 100644
--- a/cc/trees/layer_tree_host.cc
+++ b/cc/trees/layer_tree_host.cc
@@ -95,10 +95,11 @@ bool LayerTreeHost::AnyLayerTreeHostInstanceExists() {
scoped_ptr<LayerTreeHost> LayerTreeHost::Create(
LayerTreeHostClient* client,
+ SharedBitmapManager* manager,
const LayerTreeSettings& settings,
scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner) {
- scoped_ptr<LayerTreeHost> layer_tree_host(new LayerTreeHost(client,
- settings));
+ scoped_ptr<LayerTreeHost> layer_tree_host(
+ new LayerTreeHost(client, manager, settings));
if (!layer_tree_host->Initialize(impl_task_runner))
return scoped_ptr<LayerTreeHost>();
return layer_tree_host.Pass();
@@ -107,6 +108,7 @@ scoped_ptr<LayerTreeHost> LayerTreeHost::Create(
static int s_next_tree_id = 1;
LayerTreeHost::LayerTreeHost(LayerTreeHostClient* client,
+ SharedBitmapManager* manager,
const LayerTreeSettings& settings)
: next_ui_resource_id_(1),
animating_(false),
@@ -134,7 +136,8 @@ LayerTreeHost::LayerTreeHost(LayerTreeHostClient* client,
in_paint_layer_contents_(false),
total_frames_used_for_lcd_text_metrics_(0),
tree_id_(s_next_tree_id++),
- next_commit_forces_redraw_(false) {
+ next_commit_forces_redraw_(false),
+ shared_bitmap_manager_(manager) {
if (settings_.accelerated_animation_enabled)
animation_registrar_ = AnimationRegistrar::Create();
s_num_layer_tree_instances++;
@@ -258,8 +261,8 @@ void LayerTreeHost::AcquireLayerTextures() {
proxy_->AcquireLayerTextures();
}
-void LayerTreeHost::DidBeginFrame() {
- client_->DidBeginFrame();
+void LayerTreeHost::DidBeginMainFrame() {
+ client_->DidBeginMainFrame();
}
void LayerTreeHost::UpdateClientAnimations(base::TimeTicks frame_begin_time) {
@@ -310,7 +313,8 @@ void LayerTreeHost::FinishCommitOnImplThread(LayerTreeHostImpl* host_impl) {
host_impl->set_max_memory_needed_bytes(
contents_texture_manager_->MaxMemoryNeededBytes());
- contents_texture_manager_->UpdateBackingsInDrawingImplTree();
+ contents_texture_manager_->UpdateBackingsState(
+ host_impl->resource_provider());
}
// In impl-side painting, synchronize to the pending tree so that it has
@@ -469,7 +473,9 @@ scoped_ptr<LayerTreeHostImpl> LayerTreeHost::CreateLayerTreeHostImpl(
LayerTreeHostImpl::Create(settings_,
client,
proxy_.get(),
- rendering_stats_instrumentation_.get());
+ rendering_stats_instrumentation_.get(),
+ shared_bitmap_manager_);
+ shared_bitmap_manager_ = NULL;
if (settings_.calculate_top_controls_position &&
host_impl->top_controls_manager()) {
top_controls_manager_weak_ptr_ =
@@ -567,6 +573,11 @@ bool LayerTreeHost::CommitRequested() const {
return proxy_->CommitRequested();
}
+bool LayerTreeHost::BeginMainFrameRequested() const {
+ return proxy_->BeginMainFrameRequested();
+}
+
+
void LayerTreeHost::SetNextCommitWaitsForActivation() {
proxy_->SetNextCommitWaitsForActivation();
}
@@ -688,8 +699,9 @@ void LayerTreeHost::SetOverhangBitmap(const SkBitmap& bitmap) {
bitmap_copy.setImmutable();
}
- overhang_ui_resource_ = ScopedUIResource::Create(
- this, UIResourceBitmap(bitmap_copy, UIResourceBitmap::REPEAT));
+ UIResourceBitmap overhang_bitmap(bitmap_copy);
+ overhang_bitmap.SetWrapMode(UIResourceBitmap::REPEAT);
+ overhang_ui_resource_ = ScopedUIResource::Create(this, overhang_bitmap);
}
void LayerTreeHost::SetVisible(bool visible) {
diff --git a/cc/trees/layer_tree_host.h b/cc/trees/layer_tree_host.h
index fa025b67f2..c79f3e515f 100644
--- a/cc/trees/layer_tree_host.h
+++ b/cc/trees/layer_tree_host.h
@@ -67,6 +67,7 @@ class Region;
class RenderingStatsInstrumentation;
class ResourceProvider;
class ResourceUpdateQueue;
+class SharedBitmapManager;
class TopControlsManager;
struct RenderingStats;
struct ScrollAndScaleSet;
@@ -123,8 +124,10 @@ class CC_EXPORT UIResourceRequest {
class CC_EXPORT LayerTreeHost : NON_EXPORTED_BASE(public RateLimiterClient) {
public:
+ // The SharedBitmapManager will be used on the compositor thread.
static scoped_ptr<LayerTreeHost> Create(
LayerTreeHostClient* client,
+ SharedBitmapManager* manager,
const LayerTreeSettings& settings,
scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner);
virtual ~LayerTreeHost();
@@ -140,8 +143,8 @@ class CC_EXPORT LayerTreeHost : NON_EXPORTED_BASE(public RateLimiterClient) {
}
// LayerTreeHost interface to Proxy.
- void WillBeginFrame() { client_->WillBeginFrame(); }
- void DidBeginFrame();
+ void WillBeginMainFrame() { client_->WillBeginMainFrame(); }
+ void DidBeginMainFrame();
void UpdateClientAnimations(base::TimeTicks monotonic_frame_begin_time);
void AnimateLayers(base::TimeTicks monotonic_frame_begin_time);
void DidStopFlinging();
@@ -212,6 +215,7 @@ class CC_EXPORT LayerTreeHost : NON_EXPORTED_BASE(public RateLimiterClient) {
void SetNeedsRedraw();
void SetNeedsRedrawRect(gfx::Rect damage_rect);
bool CommitRequested() const;
+ bool BeginMainFrameRequested() const;
void SetNextCommitWaitsForActivation();
@@ -223,6 +227,7 @@ class CC_EXPORT LayerTreeHost : NON_EXPORTED_BASE(public RateLimiterClient) {
void SetRootLayer(scoped_refptr<Layer> root_layer);
Layer* root_layer() { return root_layer_.get(); }
const Layer* root_layer() const { return root_layer_.get(); }
+ const Layer* page_scale_layer() const { return page_scale_layer_.get(); }
void RegisterViewportLayers(
scoped_refptr<Layer> page_scale_layer,
scoped_refptr<Layer> inner_viewport_scroll_layer,
@@ -324,7 +329,9 @@ class CC_EXPORT LayerTreeHost : NON_EXPORTED_BASE(public RateLimiterClient) {
const MicroBenchmark::DoneCallback& callback);
protected:
- LayerTreeHost(LayerTreeHostClient* client, const LayerTreeSettings& settings);
+ LayerTreeHost(LayerTreeHostClient* client,
+ SharedBitmapManager* manager,
+ const LayerTreeSettings& settings);
bool Initialize(scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner);
bool InitializeForTesting(scoped_ptr<Proxy> proxy_for_testing);
void SetOutputSurfaceLostForTesting(bool is_lost) {
@@ -465,6 +472,8 @@ class CC_EXPORT LayerTreeHost : NON_EXPORTED_BASE(public RateLimiterClient) {
scoped_refptr<Layer> inner_viewport_scroll_layer_;
scoped_refptr<Layer> outer_viewport_scroll_layer_;
+ SharedBitmapManager* shared_bitmap_manager_;
+
DISALLOW_COPY_AND_ASSIGN(LayerTreeHost);
};
diff --git a/cc/trees/layer_tree_host_client.h b/cc/trees/layer_tree_host_client.h
index 648ee85b4b..bde12dadc7 100644
--- a/cc/trees/layer_tree_host_client.h
+++ b/cc/trees/layer_tree_host_client.h
@@ -19,10 +19,10 @@ class OutputSurface;
class LayerTreeHostClient {
public:
- virtual void WillBeginFrame() = 0;
+ virtual void WillBeginMainFrame() = 0;
// Marks finishing compositing-related tasks on the main thread. In threaded
// mode, this corresponds to DidCommit().
- virtual void DidBeginFrame() = 0;
+ virtual void DidBeginMainFrame() = 0;
virtual void Animate(double frame_begin_time) = 0;
virtual void Layout() = 0;
virtual void ApplyScrollAndScale(gfx::Vector2d scroll_delta,
diff --git a/cc/trees/layer_tree_host_common.cc b/cc/trees/layer_tree_host_common.cc
index 3ccedb14fe..4095900fae 100644
--- a/cc/trees/layer_tree_host_common.cc
+++ b/cc/trees/layer_tree_host_common.cc
@@ -135,8 +135,13 @@ static gfx::Vector2dF ComputeChangeOfBasisTranslation(
gfx::Vector2dF translation;
for (const LayerType* target = descendant_target; target != ancestor_target;
- target = NextTargetSurface(target))
- translation += target->render_surface()->draw_transform().To2dTranslation();
+ target = NextTargetSurface(target)) {
+ const gfx::Transform& trans = target->render_surface()->draw_transform();
+ // Ensure that this translation is truly 2d.
+ DCHECK(trans.IsIdentityOrTranslation());
+ DCHECK_EQ(0.f, trans.matrix().get(2, 3));
+ translation += trans.To2dTranslation();
+ }
return translation;
}
@@ -743,7 +748,8 @@ void ApplyPositionAdjustment(
gfx::Transform ComputeScrollCompensationForThisLayer(
LayerImpl* scrolling_layer,
- const gfx::Transform& parent_matrix) {
+ const gfx::Transform& parent_matrix,
+ gfx::Vector2dF scroll_delta) {
// For every layer that has non-zero scroll_delta, we have to compute a
// transform that can undo the scroll_delta translation. In particular, we
// want this matrix to premultiply a fixed-position layer's parent_matrix, so
@@ -765,7 +771,6 @@ gfx::Transform ComputeScrollCompensationForThisLayer(
//
gfx::Transform scroll_compensation_for_this_layer = parent_matrix; // Step 3
- gfx::Vector2dF scroll_delta = GetEffectiveScrollDelta(scrolling_layer);
scroll_compensation_for_this_layer.Translate(
scroll_delta.x(),
scroll_delta.y()); // Step 2
@@ -783,7 +788,8 @@ gfx::Transform ComputeScrollCompensationForThisLayer(
gfx::Transform ComputeScrollCompensationMatrixForChildren(
Layer* current_layer,
const gfx::Transform& current_parent_matrix,
- const gfx::Transform& current_scroll_compensation) {
+ const gfx::Transform& current_scroll_compensation,
+ gfx::Vector2dF scroll_delta) {
// The main thread (i.e. Layer) does not need to worry about scroll
// compensation. So we can just return an identity matrix here.
return gfx::Transform();
@@ -792,7 +798,8 @@ gfx::Transform ComputeScrollCompensationMatrixForChildren(
gfx::Transform ComputeScrollCompensationMatrixForChildren(
LayerImpl* layer,
const gfx::Transform& parent_matrix,
- const gfx::Transform& current_scroll_compensation_matrix) {
+ const gfx::Transform& current_scroll_compensation_matrix,
+ gfx::Vector2dF scroll_delta) {
// "Total scroll compensation" is the transform needed to cancel out all
// scroll_delta translations that occurred since the nearest container layer,
// even if there are render_surfaces in-between.
@@ -827,7 +834,6 @@ gfx::Transform ComputeScrollCompensationMatrixForChildren(
// Avoid the overheads (including stack allocation and matrix
// initialization/copy) if we know that the scroll compensation doesn't need
// to be reset or adjusted.
- gfx::Vector2dF scroll_delta = GetEffectiveScrollDelta(layer);
if (!current_layer_resets_scroll_compensation_for_descendants &&
scroll_delta.IsZero() && !layer->render_surface())
return current_scroll_compensation_matrix;
@@ -846,7 +852,7 @@ gfx::Transform ComputeScrollCompensationMatrixForChildren(
if (!scroll_delta.IsZero()) {
gfx::Transform scroll_compensation_for_this_layer =
ComputeScrollCompensationForThisLayer(
- layer, parent_matrix);
+ layer, parent_matrix, scroll_delta);
next_scroll_compensation_matrix.PreconcatTransform(
scroll_compensation_for_this_layer);
}
@@ -1093,7 +1099,7 @@ struct SubtreeGlobals {
int max_texture_size;
float device_scale_factor;
float page_scale_factor;
- LayerType* page_scale_application_layer;
+ const LayerType* page_scale_application_layer;
bool can_adjust_raster_scales;
bool can_render_to_separate_surface;
};
@@ -1490,12 +1496,19 @@ static void CalculateDrawPropertiesInternal(
combined_transform.Translate(position.x(), position.y());
}
+ gfx::Vector2dF effective_scroll_delta = GetEffectiveScrollDelta(layer);
if (!animating_transform_to_target && layer->scrollable() &&
combined_transform.IsScaleOrTranslation()) {
// Align the scrollable layer's position to screen space pixels to avoid
// blurriness. To avoid side-effects, do this only if the transform is
// simple.
+ gfx::Vector2dF previous_translation = combined_transform.To2dTranslation();
RoundTranslationComponents(&combined_transform);
+ gfx::Vector2dF current_translation = combined_transform.To2dTranslation();
+
+ // This rounding changes the scroll delta, and so must be included
+ // in the scroll compensation matrix.
+ effective_scroll_delta -= current_translation - previous_translation;
}
// Apply adjustment from position constraints.
@@ -1871,7 +1884,8 @@ static void CalculateDrawPropertiesInternal(
ComputeScrollCompensationMatrixForChildren(
layer,
data_from_ancestor.parent_matrix,
- data_from_ancestor.scroll_compensation_matrix);
+ data_from_ancestor.scroll_compensation_matrix,
+ effective_scroll_delta);
data_for_children.fixed_container =
layer->IsContainerForFixedPositionLayers() ?
layer : data_from_ancestor.fixed_container;
@@ -2344,34 +2358,21 @@ LayerImpl* LayerTreeHostCommon::FindLayerThatIsHitByPoint(
LayerImpl* LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
gfx::PointF screen_space_point,
const LayerImplList& render_surface_layer_list) {
- LayerImpl* found_layer = NULL;
-
- typedef LayerIterator<LayerImpl,
- LayerImplList,
- RenderSurfaceImpl,
- LayerIteratorActions::FrontToBack> LayerIteratorType;
- LayerIteratorType end = LayerIteratorType::End(&render_surface_layer_list);
-
- for (LayerIteratorType
- it = LayerIteratorType::Begin(&render_surface_layer_list);
- it != end;
- ++it) {
- // We don't want to consider render_surfaces for hit testing.
- if (!it.represents_itself())
- continue;
-
- LayerImpl* current_layer = (*it);
-
- if (!LayerHasTouchEventHandlersAt(screen_space_point, current_layer))
- continue;
-
- found_layer = current_layer;
- break;
+ // First find out which layer was hit from the saved list of visible layers
+ // in the most recent frame.
+ LayerImpl* layer_impl = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
+ screen_space_point,
+ render_surface_layer_list);
+
+ // Walk up the hierarchy and look for a layer with a touch event handler
+ // region that the given point hits.
+ // This walk may not be necessary anymore: http://crbug.com/310817
+ for (; layer_impl; layer_impl = layer_impl->parent()) {
+ if (LayerTreeHostCommon::LayerHasTouchEventHandlersAt(screen_space_point,
+ layer_impl))
+ break;
}
-
- // This can potentially return NULL, which means the screen_space_point did
- // not successfully hit test any layers, not even the root layer.
- return found_layer;
+ return layer_impl;
}
bool LayerTreeHostCommon::LayerHasTouchEventHandlersAt(
diff --git a/cc/trees/layer_tree_host_common.h b/cc/trees/layer_tree_host_common.h
index adabd13516..727244864e 100644
--- a/cc/trees/layer_tree_host_common.h
+++ b/cc/trees/layer_tree_host_common.h
@@ -36,7 +36,7 @@ class CC_EXPORT LayerTreeHostCommon {
const gfx::Transform& device_transform,
float device_scale_factor,
float page_scale_factor,
- LayerType* page_scale_application_layer,
+ const LayerType* page_scale_application_layer,
int max_texture_size,
bool can_use_lcd_text,
bool can_render_to_separate_surface,
@@ -59,7 +59,7 @@ class CC_EXPORT LayerTreeHostCommon {
const gfx::Transform& device_transform;
float device_scale_factor;
float page_scale_factor;
- LayerType* page_scale_application_layer;
+ const LayerType* page_scale_application_layer;
int max_texture_size;
bool can_use_lcd_text;
bool can_render_to_separate_surface;
diff --git a/cc/trees/layer_tree_host_common_perftest.cc b/cc/trees/layer_tree_host_common_perftest.cc
new file mode 100644
index 0000000000..d9407092ee
--- /dev/null
+++ b/cc/trees/layer_tree_host_common_perftest.cc
@@ -0,0 +1,204 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cc/trees/layer_tree_host_common.h"
+
+#include <sstream>
+
+#include "base/file_util.h"
+#include "base/files/file_path.h"
+#include "base/path_service.h"
+#include "base/strings/string_piece.h"
+#include "base/threading/thread.h"
+#include "base/time/time.h"
+#include "cc/layers/layer.h"
+#include "cc/test/fake_content_layer_client.h"
+#include "cc/test/fake_layer_tree_host_client.h"
+#include "cc/test/lap_timer.h"
+#include "cc/test/layer_tree_json_parser.h"
+#include "cc/test/layer_tree_test.h"
+#include "cc/test/paths.h"
+#include "cc/trees/layer_tree_impl.h"
+#include "testing/perf/perf_test.h"
+
+namespace cc {
+namespace {
+
+static const int kTimeLimitMillis = 2000;
+static const int kWarmupRuns = 5;
+static const int kTimeCheckInterval = 10;
+
+class LayerTreeHostCommonPerfTest : public LayerTreeTest {
+ public:
+ LayerTreeHostCommonPerfTest()
+ : timer_(kWarmupRuns,
+ base::TimeDelta::FromMilliseconds(kTimeLimitMillis),
+ kTimeCheckInterval) {}
+
+ void ReadTestFile(const std::string& name) {
+ base::FilePath test_data_dir;
+ ASSERT_TRUE(PathService::Get(cc::DIR_TEST_DATA, &test_data_dir));
+ base::FilePath json_file = test_data_dir.AppendASCII(name + ".json");
+ ASSERT_TRUE(base::ReadFileToString(json_file, &json_));
+ }
+
+ virtual void SetupTree() OVERRIDE {
+ gfx::Size viewport = gfx::Size(720, 1038);
+ layer_tree_host()->SetViewportSize(viewport);
+ scoped_refptr<Layer> root =
+ ParseTreeFromJson(json_, &content_layer_client_);
+ ASSERT_TRUE(root.get());
+ layer_tree_host()->SetRootLayer(root);
+ }
+
+ void SetTestName(const std::string& name) { test_name_ = name; }
+
+ virtual void AfterTest() OVERRIDE {
+ CHECK(!test_name_.empty()) << "Must SetTestName() before TearDown().";
+ perf_test::PrintResult("calc_draw_props_count",
+ "",
+ test_name_,
+ timer_.NumLaps(),
+ "count",
+ true);
+ perf_test::PrintResult("calc_draw_props_time",
+ "",
+ test_name_,
+ 1000 * timer_.MsPerLap(),
+ "us",
+ true);
+ }
+
+ protected:
+ FakeContentLayerClient content_layer_client_;
+ LapTimer timer_;
+ std::string test_name_;
+ std::string json_;
+};
+
+class CalcDrawPropsMainTest : public LayerTreeHostCommonPerfTest {
+ public:
+ void RunCalcDrawProps() {
+ RunTest(false, false, false);
+ }
+
+ virtual void BeginTest() OVERRIDE {
+ timer_.Reset();
+
+ do {
+ bool can_render_to_separate_surface = true;
+ int max_texture_size = 8096;
+ RenderSurfaceLayerList update_list;
+ LayerTreeHostCommon::CalcDrawPropsMainInputs inputs(
+ layer_tree_host()->root_layer(),
+ layer_tree_host()->device_viewport_size(),
+ gfx::Transform(),
+ layer_tree_host()->device_scale_factor(),
+ layer_tree_host()->page_scale_factor(),
+ layer_tree_host()->page_scale_layer(),
+ max_texture_size,
+ layer_tree_host()->settings().can_use_lcd_text,
+ can_render_to_separate_surface,
+ layer_tree_host()
+ ->settings()
+ .layer_transforms_should_scale_layer_contents,
+ &update_list);
+ LayerTreeHostCommon::CalculateDrawProperties(&inputs);
+
+ timer_.NextLap();
+ } while (!timer_.HasTimeLimitExpired());
+
+ EndTest();
+ }
+};
+
+class CalcDrawPropsImplTest : public LayerTreeHostCommonPerfTest {
+ public:
+ void RunCalcDrawProps() {
+ RunTestWithImplSidePainting();
+ }
+
+ virtual void BeginTest() OVERRIDE {
+ PostSetNeedsCommitToMainThread();
+ }
+
+ virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
+ timer_.Reset();
+ LayerTreeImpl* active_tree = host_impl->active_tree();
+
+ do {
+ bool can_render_to_separate_surface = true;
+ int max_texture_size = 8096;
+ LayerImplList update_list;
+ LayerTreeHostCommon::CalcDrawPropsImplInputs inputs(
+ active_tree->root_layer(),
+ active_tree->DrawViewportSize(),
+ host_impl->DrawTransform(),
+ active_tree->device_scale_factor(),
+ active_tree->total_page_scale_factor(),
+ active_tree->RootContainerLayer(),
+ max_texture_size,
+ host_impl->settings().can_use_lcd_text,
+ can_render_to_separate_surface,
+ host_impl->settings().layer_transforms_should_scale_layer_contents,
+ &update_list);
+ LayerTreeHostCommon::CalculateDrawProperties(&inputs);
+
+ timer_.NextLap();
+ } while (!timer_.HasTimeLimitExpired());
+
+ EndTest();
+ }
+};
+
+TEST_F(CalcDrawPropsMainTest, TenTen) {
+ SetTestName("10_10");
+ ReadTestFile("10_10_layer_tree");
+ RunCalcDrawProps();
+}
+
+TEST_F(CalcDrawPropsMainTest, HeavyPage) {
+ SetTestName("heavy_page");
+ ReadTestFile("heavy_layer_tree");
+ RunCalcDrawProps();
+}
+
+TEST_F(CalcDrawPropsMainTest, TouchRegionLight) {
+ SetTestName("touch_region_light");
+ ReadTestFile("touch_region_light");
+ RunCalcDrawProps();
+}
+
+TEST_F(CalcDrawPropsMainTest, TouchRegionHeavy) {
+ SetTestName("touch_region_heavy");
+ ReadTestFile("touch_region_heavy");
+ RunCalcDrawProps();
+}
+
+TEST_F(CalcDrawPropsImplTest, TenTen) {
+ SetTestName("10_10");
+ ReadTestFile("10_10_layer_tree");
+ RunCalcDrawProps();
+}
+
+TEST_F(CalcDrawPropsImplTest, HeavyPage) {
+ SetTestName("heavy_page");
+ ReadTestFile("heavy_layer_tree");
+ RunCalcDrawProps();
+}
+
+TEST_F(CalcDrawPropsImplTest, TouchRegionLight) {
+ SetTestName("touch_region_light");
+ ReadTestFile("touch_region_light");
+ RunCalcDrawProps();
+}
+
+TEST_F(CalcDrawPropsImplTest, TouchRegionHeavy) {
+ SetTestName("touch_region_heavy");
+ ReadTestFile("touch_region_heavy");
+ RunCalcDrawProps();
+}
+
+} // namespace
+} // namespace cc
diff --git a/cc/trees/layer_tree_host_common_unittest.cc b/cc/trees/layer_tree_host_common_unittest.cc
index 700bca43ea..58d82ceda4 100644
--- a/cc/trees/layer_tree_host_common_unittest.cc
+++ b/cc/trees/layer_tree_host_common_unittest.cc
@@ -6025,6 +6025,90 @@ TEST_F(LayerTreeHostCommonTest,
EXPECT_EQ(456, result_layer->id());
}
+TEST_F(LayerTreeHostCommonTest,
+ HitCheckingTouchHandlerOverlappingRegions) {
+ gfx::Transform identity_matrix;
+ gfx::PointF anchor;
+
+ FakeImplProxy proxy;
+ FakeLayerTreeHostImpl host_impl(&proxy);
+ scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl.active_tree(), 1);
+ SetLayerPropertiesForTesting(root.get(),
+ identity_matrix,
+ identity_matrix,
+ anchor,
+ gfx::PointF(),
+ gfx::Size(100, 100),
+ false);
+ {
+ scoped_ptr<LayerImpl> touch_layer =
+ LayerImpl::Create(host_impl.active_tree(), 123);
+ // this layer is positioned, and hit testing should correctly know where the
+ // layer is located.
+ gfx::PointF position;
+ gfx::Size bounds(50, 50);
+ SetLayerPropertiesForTesting(touch_layer.get(),
+ identity_matrix,
+ identity_matrix,
+ anchor,
+ position,
+ bounds,
+ false);
+ touch_layer->SetDrawsContent(true);
+ touch_layer->SetTouchEventHandlerRegion(gfx::Rect(0, 0, 50, 50));
+ root->AddChild(touch_layer.Pass());
+ }
+
+ {
+ scoped_ptr<LayerImpl> notouch_layer =
+ LayerImpl::Create(host_impl.active_tree(), 1234);
+ // this layer is positioned, and hit testing should correctly know where the
+ // layer is located.
+ gfx::PointF position(0, 25);
+ gfx::Size bounds(50, 50);
+ SetLayerPropertiesForTesting(notouch_layer.get(),
+ identity_matrix,
+ identity_matrix,
+ anchor,
+ position,
+ bounds,
+ false);
+ notouch_layer->SetDrawsContent(true);
+ root->AddChild(notouch_layer.Pass());
+ }
+
+ LayerImplList render_surface_layer_list;
+ LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
+ root.get(), root->bounds(), &render_surface_layer_list);
+ inputs.can_adjust_raster_scales = true;
+ LayerTreeHostCommon::CalculateDrawProperties(&inputs);
+
+ // Sanity check the scenario we just created.
+ ASSERT_EQ(1u, render_surface_layer_list.size());
+ ASSERT_EQ(2u, root->render_surface()->layer_list().size());
+ ASSERT_EQ(123, root->render_surface()->layer_list().at(0)->id());
+ ASSERT_EQ(1234, root->render_surface()->layer_list().at(1)->id());
+
+ gfx::Point test_point(35, 35);
+ LayerImpl* result_layer =
+ LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
+ test_point, render_surface_layer_list);
+ EXPECT_FALSE(result_layer);
+
+ test_point = gfx::Point(35, 15);
+ result_layer =
+ LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
+ test_point, render_surface_layer_list);
+ ASSERT_TRUE(result_layer);
+ EXPECT_EQ(123, result_layer->id());
+
+ test_point = gfx::Point(35, 65);
+ result_layer =
+ LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
+ test_point, render_surface_layer_list);
+ EXPECT_FALSE(result_layer);
+}
+
class NoScaleContentLayer : public ContentLayer {
public:
static scoped_refptr<NoScaleContentLayer> Create(ContentLayerClient* client) {
@@ -9548,5 +9632,118 @@ TEST_F(LayerTreeHostCommonTest, DoNotClobberSorting) {
EXPECT_EQ(4, root->render_surface()->layer_list().at(3)->id());
}
+TEST_F(LayerTreeHostCommonTest, ScrollCompensationWithRounding) {
+ // This test verifies that a scrolling layer that gets snapped to
+ // integer coordinates doesn't move a fixed position child.
+ //
+ // + root
+ // + container
+ // + scroller
+ // + fixed
+ //
+ FakeImplProxy proxy;
+ FakeLayerTreeHostImpl host_impl(&proxy);
+ host_impl.CreatePendingTree();
+ scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl.active_tree(), 1);
+ scoped_ptr<LayerImpl> container =
+ LayerImpl::Create(host_impl.active_tree(), 2);
+ LayerImpl* container_layer = container.get();
+ scoped_ptr<LayerImpl> scroller =
+ LayerImpl::Create(host_impl.active_tree(), 3);
+ LayerImpl* scroll_layer = scroller.get();
+ scoped_ptr<LayerImpl> fixed = LayerImpl::Create(host_impl.active_tree(), 4);
+ LayerImpl* fixed_layer = fixed.get();
+
+ container->SetIsContainerForFixedPositionLayers(true);
+
+ LayerPositionConstraint constraint;
+ constraint.set_is_fixed_position(true);
+ fixed->SetPositionConstraint(constraint);
+
+ scroller->SetScrollable(true);
+
+ gfx::Transform identity_transform;
+ gfx::Transform container_transform;
+ container_transform.Translate3d(10.0, 20.0, 0.0);
+ gfx::Vector2dF container_offset = container_transform.To2dTranslation();
+
+ SetLayerPropertiesForTesting(root.get(),
+ identity_transform,
+ identity_transform,
+ gfx::PointF(),
+ gfx::PointF(),
+ gfx::Size(50, 50),
+ false);
+ SetLayerPropertiesForTesting(container.get(),
+ container_transform,
+ identity_transform,
+ gfx::PointF(),
+ gfx::PointF(),
+ gfx::Size(40, 40),
+ false);
+ SetLayerPropertiesForTesting(scroller.get(),
+ identity_transform,
+ identity_transform,
+ gfx::PointF(),
+ gfx::PointF(),
+ gfx::Size(30, 30),
+ false);
+ SetLayerPropertiesForTesting(fixed.get(),
+ identity_transform,
+ identity_transform,
+ gfx::PointF(),
+ gfx::PointF(),
+ gfx::Size(50, 50),
+ false);
+
+ scroller->AddChild(fixed.Pass());
+ container->AddChild(scroller.Pass());
+ root->AddChild(container.Pass());
+
+ // Rounded to integers already.
+ {
+ gfx::Vector2dF scroll_delta(3.0, 5.0);
+ scroll_layer->SetScrollDelta(scroll_delta);
+
+ LayerImplList render_surface_layer_list;
+ LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
+ root.get(), root->bounds(), &render_surface_layer_list);
+ LayerTreeHostCommon::CalculateDrawProperties(&inputs);
+
+ EXPECT_TRANSFORMATION_MATRIX_EQ(
+ container_layer->draw_properties().screen_space_transform,
+ fixed_layer->draw_properties().screen_space_transform);
+ EXPECT_VECTOR_EQ(
+ fixed_layer->draw_properties().screen_space_transform.To2dTranslation(),
+ container_offset);
+ EXPECT_VECTOR_EQ(scroll_layer->draw_properties()
+ .screen_space_transform.To2dTranslation(),
+ container_offset - scroll_delta);
+ }
+
+ // Scroll delta requiring rounding.
+ {
+ gfx::Vector2dF scroll_delta(4.1f, 8.1f);
+ scroll_layer->SetScrollDelta(scroll_delta);
+
+ gfx::Vector2dF rounded_scroll_delta(4.f, 8.f);
+
+ LayerImplList render_surface_layer_list;
+ LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
+ root.get(), root->bounds(), &render_surface_layer_list);
+ LayerTreeHostCommon::CalculateDrawProperties(&inputs);
+
+ EXPECT_TRANSFORMATION_MATRIX_EQ(
+ container_layer->draw_properties().screen_space_transform,
+ fixed_layer->draw_properties().screen_space_transform);
+ EXPECT_VECTOR_EQ(
+ fixed_layer->draw_properties().screen_space_transform.To2dTranslation(),
+ container_offset);
+ EXPECT_VECTOR_EQ(scroll_layer->draw_properties()
+ .screen_space_transform.To2dTranslation(),
+ container_offset - rounded_scroll_delta);
+ }
+}
+
} // namespace
} // namespace cc
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc
index ebc1d83dfc..7171580b86 100644
--- a/cc/trees/layer_tree_host_impl.cc
+++ b/cc/trees/layer_tree_host_impl.cc
@@ -56,6 +56,7 @@
#include "cc/trees/quad_culler.h"
#include "cc/trees/single_thread_proxy.h"
#include "cc/trees/tree_synchronizer.h"
+#include "ui/gfx/frame_time.h"
#include "ui/gfx/size_conversions.h"
#include "ui/gfx/vector2d_conversions.h"
@@ -180,19 +181,18 @@ scoped_ptr<LayerTreeHostImpl> LayerTreeHostImpl::Create(
const LayerTreeSettings& settings,
LayerTreeHostImplClient* client,
Proxy* proxy,
- RenderingStatsInstrumentation* rendering_stats_instrumentation) {
- return make_scoped_ptr(
- new LayerTreeHostImpl(settings,
- client,
- proxy,
- rendering_stats_instrumentation));
+ RenderingStatsInstrumentation* rendering_stats_instrumentation,
+ SharedBitmapManager* manager) {
+ return make_scoped_ptr(new LayerTreeHostImpl(
+ settings, client, proxy, rendering_stats_instrumentation, manager));
}
LayerTreeHostImpl::LayerTreeHostImpl(
const LayerTreeSettings& settings,
LayerTreeHostImplClient* client,
Proxy* proxy,
- RenderingStatsInstrumentation* rendering_stats_instrumentation)
+ RenderingStatsInstrumentation* rendering_stats_instrumentation,
+ SharedBitmapManager* manager)
: client_(client),
proxy_(proxy),
input_handler_client_(NULL),
@@ -207,9 +207,9 @@ LayerTreeHostImpl::LayerTreeHostImpl(
visible_(true),
cached_managed_memory_policy_(
PrioritizedResourceManager::DefaultMemoryAllocationLimit(),
- ManagedMemoryPolicy::CUTOFF_ALLOW_EVERYTHING,
+ gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING,
0,
- ManagedMemoryPolicy::CUTOFF_ALLOW_NOTHING,
+ gpu::MemoryAllocation::CUTOFF_ALLOW_NOTHING,
ManagedMemoryPolicy::kDefaultNumResourcesLimit),
pinch_gesture_active_(false),
pinch_gesture_end_should_clear_scrolling_layer_(false),
@@ -230,7 +230,8 @@ LayerTreeHostImpl::LayerTreeHostImpl(
external_stencil_test_enabled_(false),
animation_registrar_(AnimationRegistrar::Create()),
rendering_stats_instrumentation_(rendering_stats_instrumentation),
- need_to_update_visible_tiles_before_draw_(false) {
+ need_to_update_visible_tiles_before_draw_(false),
+ shared_bitmap_manager_(manager) {
DCHECK(proxy_->IsImplThread());
DidVisibilityChange(this, visible_);
@@ -280,7 +281,7 @@ void LayerTreeHostImpl::CommitComplete() {
// 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()->ApplyScrollDeltasSinceBeginFrame();
+ pending_tree()->ApplyScrollDeltasSinceBeginMainFrame();
pending_tree_->set_needs_update_draw_properties();
pending_tree_->UpdateDrawProperties();
// Start working on newly created tiles immediately if needed.
@@ -436,21 +437,11 @@ bool LayerTreeHostImpl::HaveTouchEventHandlersAt(gfx::Point viewport_point) {
gfx::PointF device_viewport_point =
gfx::ScalePoint(viewport_point, device_scale_factor_);
- // First find out which layer was hit from the saved list of visible layers
- // in the most recent frame.
- LayerImpl* layer_impl = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
- device_viewport_point,
- active_tree_->RenderSurfaceLayerList());
-
- // Walk up the hierarchy and look for a layer with a touch event handler
- // region that the given point hits.
- for (; layer_impl; layer_impl = layer_impl->parent()) {
- if (LayerTreeHostCommon::LayerHasTouchEventHandlersAt(device_viewport_point,
- layer_impl))
- return true;
- }
-
- return false;
+ LayerImpl* layer_impl =
+ LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
+ device_viewport_point,
+ active_tree_->RenderSurfaceLayerList());
+ return layer_impl != NULL;
}
void LayerTreeHostImpl::SetLatencyInfoForInputEvent(
@@ -513,7 +504,8 @@ static DrawMode GetDrawMode(OutputSurface* output_surface) {
} else if (output_surface->context_provider()) {
return DRAW_MODE_HARDWARE;
} else {
- DCHECK(output_surface->software_device());
+ DCHECK_EQ(!output_surface->software_device(),
+ output_surface->capabilities().delegated_rendering);
return DRAW_MODE_SOFTWARE;
}
}
@@ -1207,8 +1199,8 @@ void LayerTreeHostImpl::SetNeedsRedrawRect(gfx::Rect damage_rect) {
client_->SetNeedsRedrawRectOnImplThread(damage_rect);
}
-void LayerTreeHostImpl::BeginFrame(const BeginFrameArgs& args) {
- client_->BeginFrameOnImplThread(args);
+void LayerTreeHostImpl::BeginImplFrame(const BeginFrameArgs& args) {
+ client_->BeginImplFrame(args);
}
void LayerTreeHostImpl::OnSwapBuffersComplete() {
@@ -1395,9 +1387,9 @@ bool LayerTreeHostImpl::SwapBuffers(const LayerTreeHostImpl::FrameData& frame) {
return true;
}
-void LayerTreeHostImpl::SetNeedsBeginFrame(bool enable) {
+void LayerTreeHostImpl::SetNeedsBeginImplFrame(bool enable) {
if (output_surface_)
- output_surface_->SetNeedsBeginFrame(enable);
+ output_surface_->SetNeedsBeginImplFrame(enable);
}
gfx::SizeF LayerTreeHostImpl::UnscaledScrollableViewportSize() const {
@@ -1479,9 +1471,7 @@ void LayerTreeHostImpl::CreatePendingTree() {
else
pending_tree_ = LayerTreeImpl::create(this);
client_->OnCanDrawStateChanged(CanDraw());
- TRACE_EVENT_ASYNC_BEGIN0("cc", "PendingTree", pending_tree_.get());
- TRACE_EVENT_ASYNC_STEP0("cc",
- "PendingTree", pending_tree_.get(), "waiting");
+ TRACE_EVENT_ASYNC_BEGIN0("cc", "PendingTree:waiting", pending_tree_.get());
}
void LayerTreeHostImpl::UpdateVisibleTiles() {
@@ -1492,7 +1482,7 @@ void LayerTreeHostImpl::UpdateVisibleTiles() {
void LayerTreeHostImpl::ActivatePendingTree() {
CHECK(pending_tree_);
- TRACE_EVENT_ASYNC_END0("cc", "PendingTree", pending_tree_.get());
+ TRACE_EVENT_ASYNC_END0("cc", "PendingTree:waiting", pending_tree_.get());
need_to_update_visible_tiles_before_draw_ = true;
@@ -1524,10 +1514,6 @@ void LayerTreeHostImpl::ActivatePendingTree() {
active_tree_->SetRootLayerScrollOffsetDelegate(
root_layer_scroll_offset_delegate_);
- // Reduce wasted memory now that unlinked resources are guaranteed not
- // to be used.
- client_->ReduceWastedContentsTextureMemoryOnImplThread();
-
client_->OnCanDrawStateChanged(CanDraw());
client_->SetNeedsRedrawOnImplThread();
client_->RenewTreePriority();
@@ -1575,9 +1561,9 @@ ManagedMemoryPolicy LayerTreeHostImpl::ActualManagedMemoryPolicy() const {
ManagedMemoryPolicy actual = cached_managed_memory_policy_;
if (debug_state_.rasterize_only_visible_content) {
actual.priority_cutoff_when_not_visible =
- ManagedMemoryPolicy::CUTOFF_ALLOW_NOTHING;
+ gpu::MemoryAllocation::CUTOFF_ALLOW_NOTHING;
actual.priority_cutoff_when_visible =
- ManagedMemoryPolicy::CUTOFF_ALLOW_REQUIRED_ONLY;
+ gpu::MemoryAllocation::CUTOFF_ALLOW_REQUIRED_ONLY;
}
if (zero_budget_) {
@@ -1682,10 +1668,11 @@ bool LayerTreeHostImpl::InitializeRenderer(
if (!output_surface->BindToClient(this))
return false;
- scoped_ptr<ResourceProvider> resource_provider = ResourceProvider::Create(
- output_surface.get(),
- settings_.highp_threshold_min,
- settings_.use_rgba_4444_textures);
+ scoped_ptr<ResourceProvider> resource_provider =
+ ResourceProvider::Create(output_surface.get(),
+ shared_bitmap_manager_,
+ settings_.highp_threshold_min,
+ settings_.use_rgba_4444_textures);
if (!resource_provider)
return false;
@@ -1705,14 +1692,14 @@ bool LayerTreeHostImpl::InitializeRenderer(
GetRendererCapabilities().using_map_image);
}
- // Setup BeginFrameEmulation if it's not supported natively
- if (!settings_.begin_frame_scheduling_enabled) {
+ // Setup BeginImplFrameEmulation if it's not supported natively
+ if (!settings_.begin_impl_frame_scheduling_enabled) {
const base::TimeDelta display_refresh_interval =
base::TimeDelta::FromMicroseconds(
base::Time::kMicrosecondsPerSecond /
settings_.refresh_rate);
- output_surface->InitializeBeginFrameEmulation(
+ output_surface->InitializeBeginImplFrameEmulation(
proxy_->ImplThreadTaskRunner(),
settings_.throttle_frame_production,
display_refresh_interval);
@@ -2350,10 +2337,8 @@ void LayerTreeHostImpl::MouseMoveAt(gfx::Point viewport_point) {
bool should_animate = animation_controller->DidMouseMoveNear(
CurrentPhysicalTimeTicks(), distance_to_scrollbar / device_scale_factor_);
- if (should_animate) {
- client_->SetNeedsRedrawOnImplThread();
+ if (should_animate)
StartScrollbarAnimation();
- }
}
bool LayerTreeHostImpl::HandleMouseOverScrollbar(LayerImpl* layer_impl,
@@ -2363,8 +2348,11 @@ bool LayerTreeHostImpl::HandleMouseOverScrollbar(LayerImpl* layer_impl,
layer_impl = active_tree_->LayerById(scroll_layer_id);
if (layer_impl && layer_impl->scrollbar_animation_controller()) {
scroll_layer_id_when_mouse_over_scrollbar_ = scroll_layer_id;
- layer_impl->scrollbar_animation_controller()->DidMouseMoveNear(
- CurrentPhysicalTimeTicks(), 0);
+ bool should_animate =
+ layer_impl->scrollbar_animation_controller()->DidMouseMoveNear(
+ CurrentPhysicalTimeTicks(), 0);
+ if (should_animate)
+ StartScrollbarAnimation();
} else {
scroll_layer_id_when_mouse_over_scrollbar_ = 0;
}
@@ -2381,6 +2369,8 @@ void LayerTreeHostImpl::PinchGestureBegin() {
client_->RenewTreePriority();
pinch_gesture_end_should_clear_scrolling_layer_ = !CurrentlyScrollingLayer();
active_tree_->SetCurrentlyScrollingLayer(RootScrollLayer());
+ if (top_controls_manager_)
+ top_controls_manager_->PinchBegin();
}
void LayerTreeHostImpl::PinchGestureUpdate(float magnify_delta,
@@ -2418,6 +2408,8 @@ void LayerTreeHostImpl::PinchGestureEnd() {
pinch_gesture_end_should_clear_scrolling_layer_ = false;
ClearCurrentlyScrollingLayer();
}
+ if (top_controls_manager_)
+ top_controls_manager_->PinchEnd();
client_->SetNeedsCommitOnImplThread();
}
@@ -2691,7 +2683,7 @@ base::Time LayerTreeHostImpl::CurrentFrameTime() {
}
base::TimeTicks LayerTreeHostImpl::CurrentPhysicalTimeTicks() const {
- return base::TimeTicks::Now();
+ return gfx::FrameTime::Now();
}
scoped_ptr<base::Value> LayerTreeHostImpl::AsValueWithFrame(
@@ -2760,6 +2752,7 @@ void LayerTreeHostImpl::CreateUIResource(UIResourceId uid,
UIResourceData data;
data.resource_id = id;
data.size = bitmap.GetSize();
+ data.opaque = bitmap.GetOpaque();
ui_resource_map_[uid] = data;
@@ -2806,6 +2799,12 @@ ResourceProvider::ResourceId LayerTreeHostImpl::ResourceIdForUIResource(
return 0;
}
+bool LayerTreeHostImpl::IsUIResourceOpaque(UIResourceId uid) const {
+ UIResourceMap::const_iterator iter = ui_resource_map_.find(uid);
+ DCHECK(iter != ui_resource_map_.end());
+ return iter->second.opaque;
+}
+
bool LayerTreeHostImpl::EvictedUIResourcesExist() const {
return !evicted_ui_resources_.empty();
}
diff --git a/cc/trees/layer_tree_host_impl.h b/cc/trees/layer_tree_host_impl.h
index 555cb24c71..dec0e6c7f7 100644
--- a/cc/trees/layer_tree_host_impl.h
+++ b/cc/trees/layer_tree_host_impl.h
@@ -59,7 +59,7 @@ class LayerTreeHostImplClient {
public:
virtual void DidLoseOutputSurfaceOnImplThread() = 0;
virtual void OnSwapBuffersCompleteOnImplThread() = 0;
- virtual void BeginFrameOnImplThread(const BeginFrameArgs& args) = 0;
+ virtual void BeginImplFrame(const BeginFrameArgs& args) = 0;
virtual void OnCanDrawStateChanged(bool can_draw) = 0;
virtual void NotifyReadyToActivate() = 0;
virtual void SetNeedsRedrawOnImplThread() = 0;
@@ -74,7 +74,6 @@ class LayerTreeHostImplClient {
virtual bool ReduceContentsTextureMemoryOnImplThread(
size_t limit_bytes,
int priority_cutoff) = 0;
- virtual void ReduceWastedContentsTextureMemoryOnImplThread() = 0;
virtual void SendManagedMemoryStats() = 0;
virtual bool IsInsideDraw() = 0;
virtual void RenewTreePriority() = 0;
@@ -99,7 +98,8 @@ class CC_EXPORT LayerTreeHostImpl
const LayerTreeSettings& settings,
LayerTreeHostImplClient* client,
Proxy* proxy,
- RenderingStatsInstrumentation* rendering_stats_instrumentation);
+ RenderingStatsInstrumentation* rendering_stats_instrumentation,
+ SharedBitmapManager* manager);
virtual ~LayerTreeHostImpl();
// InputHandler implementation
@@ -220,7 +220,7 @@ class CC_EXPORT LayerTreeHostImpl
scoped_refptr<ContextProvider> offscreen_context_provider) OVERRIDE;
virtual void ReleaseGL() OVERRIDE;
virtual void SetNeedsRedrawRect(gfx::Rect rect) OVERRIDE;
- virtual void BeginFrame(const BeginFrameArgs& args) OVERRIDE;
+ virtual void BeginImplFrame(const BeginFrameArgs& args) OVERRIDE;
virtual void SetExternalDrawConstraints(
const gfx::Transform& transform,
gfx::Rect viewport,
@@ -259,7 +259,7 @@ class CC_EXPORT LayerTreeHostImpl
const RendererCapabilities& GetRendererCapabilities() const;
virtual bool SwapBuffers(const FrameData& frame);
- void SetNeedsBeginFrame(bool enable);
+ void SetNeedsBeginImplFrame(bool enable);
void DidModifyTilePriorities();
void Readback(void* pixels, gfx::Rect rect_in_device_viewport);
@@ -401,9 +401,12 @@ class CC_EXPORT LayerTreeHostImpl
virtual ResourceProvider::ResourceId ResourceIdForUIResource(
UIResourceId uid) const;
+ virtual bool IsUIResourceOpaque(UIResourceId uid) const;
+
struct UIResourceData {
ResourceProvider::ResourceId resource_id;
gfx::Size size;
+ bool opaque;
};
protected:
@@ -411,7 +414,8 @@ class CC_EXPORT LayerTreeHostImpl
const LayerTreeSettings& settings,
LayerTreeHostImplClient* client,
Proxy* proxy,
- RenderingStatsInstrumentation* rendering_stats_instrumentation);
+ RenderingStatsInstrumentation* rendering_stats_instrumentation,
+ SharedBitmapManager* manager);
// Virtual for testing.
virtual void AnimateLayers(base::TimeTicks monotonic_time,
@@ -620,6 +624,8 @@ class CC_EXPORT LayerTreeHostImpl
// Optional callback to notify of new tree activations.
base::Closure tree_activation_callback_;
+ SharedBitmapManager* shared_bitmap_manager_;
+
DISALLOW_COPY_AND_ASSIGN(LayerTreeHostImpl);
};
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc
index f6350255b1..18b273ef13 100644
--- a/cc/trees/layer_tree_host_impl_unittest.cc
+++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -53,6 +53,7 @@
#include "media/base/media.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.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"
@@ -92,10 +93,8 @@ class LayerTreeHostImplTest : public testing::Test,
settings.minimum_occlusion_tracking_size = gfx::Size();
settings.impl_side_painting = true;
- host_impl_ = LayerTreeHostImpl::Create(settings,
- this,
- &proxy_,
- &stats_instrumentation_);
+ host_impl_ = LayerTreeHostImpl::Create(
+ settings, this, &proxy_, &stats_instrumentation_, NULL);
host_impl_->InitializeRenderer(CreateOutputSurface());
host_impl_->SetViewportSize(gfx::Size(10, 10));
}
@@ -106,8 +105,7 @@ class LayerTreeHostImplTest : public testing::Test,
did_lose_output_surface_ = true;
}
virtual void OnSwapBuffersCompleteOnImplThread() OVERRIDE {}
- virtual void BeginFrameOnImplThread(const BeginFrameArgs& args)
- OVERRIDE {}
+ virtual void BeginImplFrame(const BeginFrameArgs& args) OVERRIDE {}
virtual void OnCanDrawStateChanged(bool can_draw) OVERRIDE {
on_can_draw_state_changed_called_ = true;
}
@@ -139,7 +137,6 @@ class LayerTreeHostImplTest : public testing::Test,
current_priority_cutoff_value_ = priority_cutoff;
return reduce_memory_result_;
}
- virtual void ReduceWastedContentsTextureMemoryOnImplThread() OVERRIDE {}
virtual void SendManagedMemoryStats() OVERRIDE {}
virtual bool IsInsideDraw() OVERRIDE { return false; }
virtual void RenewTreePriority() OVERRIDE {}
@@ -157,10 +154,8 @@ class LayerTreeHostImplTest : public testing::Test,
settings.minimum_occlusion_tracking_size = gfx::Size();
settings.partial_swap_enabled = partial_swap;
- host_impl_ = LayerTreeHostImpl::Create(settings,
- this,
- &proxy_,
- &stats_instrumentation_);
+ host_impl_ = LayerTreeHostImpl::Create(
+ settings, this, &proxy_, &stats_instrumentation_, NULL);
host_impl_->InitializeRenderer(output_surface.Pass());
host_impl_->SetViewportSize(gfx::Size(10, 10));
@@ -272,7 +267,7 @@ class LayerTreeHostImplTest : public testing::Test,
void DrawFrame() {
LayerTreeHostImpl::FrameData frame;
EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
host_impl_->DidDrawAllLayers(frame);
}
@@ -391,7 +386,7 @@ TEST_F(LayerTreeHostImplTest, CanDrawIncompleteFrames) {
LayerTreeSettings settings;
settings.impl_side_painting = true;
host_impl_ = LayerTreeHostImpl::Create(
- settings, this, &proxy_, &stats_instrumentation_);
+ settings, this, &proxy_, &stats_instrumentation_, NULL);
scoped_ptr<FakeOutputSurface> output_surface(
FakeOutputSurface::CreateAlwaysDrawAndSwap3d());
@@ -494,10 +489,8 @@ TEST_F(LayerTreeHostImplTest, ScrollWithoutRootLayer) {
TEST_F(LayerTreeHostImplTest, ScrollWithoutRenderer) {
LayerTreeSettings settings;
- host_impl_ = LayerTreeHostImpl::Create(settings,
- this,
- &proxy_,
- &stats_instrumentation_);
+ host_impl_ = LayerTreeHostImpl::Create(
+ settings, this, &proxy_, &stats_instrumentation_, NULL);
scoped_ptr<TestWebGraphicsContext3D> context_owned =
TestWebGraphicsContext3D::Create();
context_owned->set_times_make_current_succeeds(0);
@@ -1152,8 +1145,8 @@ class LayerTreeHostImplOverridePhysicalTime : public LayerTreeHostImpl {
: LayerTreeHostImpl(settings,
client,
proxy,
- rendering_stats_instrumentation) {}
-
+ rendering_stats_instrumentation,
+ NULL) {}
virtual base::TimeTicks CurrentPhysicalTimeTicks() const OVERRIDE {
return fake_current_physical_time_;
@@ -1214,7 +1207,7 @@ TEST_F(LayerTreeHostImplTest, ScrollbarLinearFadeScheduling) {
host_impl_->active_tree()->DidBecomeActive();
InitializeRendererAndDrawFrame();
- base::TimeTicks fake_now = base::TimeTicks::Now();
+ base::TimeTicks fake_now = gfx::FrameTime::Now();
host_impl_override_time->SetCurrentPhysicalTimeTicksForTest(fake_now);
// If no scroll happened recently, StartScrollbarAnimation should have no
@@ -1286,7 +1279,7 @@ void LayerTreeHostImplTest::SetupMouseMoveAtWithDeviceScale(
gfx::Size content_size(1000, 1000);
host_impl_ = LayerTreeHostImpl::Create(
- settings, this, &proxy_, &stats_instrumentation_);
+ settings, this, &proxy_, &stats_instrumentation_, NULL);
host_impl_->InitializeRenderer(CreateOutputSurface());
host_impl_->SetDeviceScaleFactor(device_scale_factor);
host_impl_->SetViewportSize(device_viewport_size);
@@ -1335,20 +1328,17 @@ void LayerTreeHostImplTest::SetupMouseMoveAtWithDeviceScale(
scrollbar_animation_controller->set_mouse_move_distance_for_test(100.f);
host_impl_->MouseMoveAt(gfx::Point(1, 1));
- EXPECT_FALSE(did_request_redraw_);
+ EXPECT_FALSE(scrollbar_animation_controller->mouse_is_near_scrollbar());
- did_request_redraw_ = false;
host_impl_->MouseMoveAt(gfx::Point(200, 50));
- EXPECT_TRUE(did_request_redraw_);
+ EXPECT_TRUE(scrollbar_animation_controller->mouse_is_near_scrollbar());
- did_request_redraw_ = false;
host_impl_->MouseMoveAt(gfx::Point(184, 100));
- EXPECT_FALSE(did_request_redraw_);
+ EXPECT_FALSE(scrollbar_animation_controller->mouse_is_near_scrollbar());
scrollbar_animation_controller->set_mouse_move_distance_for_test(102.f);
- did_request_redraw_ = false;
host_impl_->MouseMoveAt(gfx::Point(184, 100));
- EXPECT_TRUE(did_request_redraw_);
+ EXPECT_TRUE(scrollbar_animation_controller->mouse_is_near_scrollbar());
did_request_redraw_ = false;
EXPECT_EQ(0, host_impl_->scroll_layer_id_when_mouse_over_scrollbar());
@@ -1513,7 +1503,7 @@ TEST_F(LayerTreeHostImplTest, WillDrawReturningFalseDoesNotCall) {
{
LayerTreeHostImpl::FrameData frame;
EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect(10, 10)));
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
host_impl_->DidDrawAllLayers(frame);
EXPECT_TRUE(layer->will_draw_called());
@@ -1528,7 +1518,7 @@ TEST_F(LayerTreeHostImplTest, WillDrawReturningFalseDoesNotCall) {
layer->ClearDidDrawCheck();
EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect(10, 10)));
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
host_impl_->DidDrawAllLayers(frame);
EXPECT_TRUE(layer->will_draw_called());
@@ -1560,7 +1550,7 @@ TEST_F(LayerTreeHostImplTest, DidDrawNotCalledOnHiddenLayer) {
EXPECT_FALSE(layer->did_draw_called());
EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
host_impl_->DidDrawAllLayers(frame);
EXPECT_FALSE(layer->will_draw_called());
@@ -1575,7 +1565,7 @@ TEST_F(LayerTreeHostImplTest, DidDrawNotCalledOnHiddenLayer) {
EXPECT_FALSE(layer->did_draw_called());
EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
host_impl_->DidDrawAllLayers(frame);
EXPECT_TRUE(layer->will_draw_called());
@@ -1614,7 +1604,7 @@ TEST_F(LayerTreeHostImplTest, WillDrawNotCalledOnOccludedLayer) {
EXPECT_FALSE(top_layer->did_draw_called());
EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
host_impl_->DidDrawAllLayers(frame);
EXPECT_FALSE(occluded_layer->will_draw_called());
@@ -1646,7 +1636,7 @@ TEST_F(LayerTreeHostImplTest, DidDrawCalledOnAllLayers) {
LayerTreeHostImpl::FrameData frame;
EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
host_impl_->DidDrawAllLayers(frame);
EXPECT_TRUE(root->did_draw_called());
@@ -1719,7 +1709,7 @@ TEST_F(LayerTreeHostImplTest, PrepareToDrawFailsWhenAnimationUsesCheckerboard) {
LayerTreeHostImpl::FrameData frame;
EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
host_impl_->DidDrawAllLayers(frame);
// When a texture is missing and we're not animating, we draw as usual with
@@ -1737,7 +1727,7 @@ TEST_F(LayerTreeHostImplTest, PrepareToDrawFailsWhenAnimationUsesCheckerboard) {
host_impl_->resource_provider()));
EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
host_impl_->DidDrawAllLayers(frame);
// When a texture is missing and we're animating, we don't want to draw
@@ -1755,7 +1745,7 @@ TEST_F(LayerTreeHostImplTest, PrepareToDrawFailsWhenAnimationUsesCheckerboard) {
host_impl_->resource_provider()));
EXPECT_FALSE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
host_impl_->DidDrawAllLayers(frame);
// When the layer skips draw and we're animating, we still draw the frame.
@@ -1772,7 +1762,7 @@ TEST_F(LayerTreeHostImplTest, PrepareToDrawFailsWhenAnimationUsesCheckerboard) {
host_impl_->resource_provider()));
EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
host_impl_->DidDrawAllLayers(frame);
}
@@ -1794,10 +1784,8 @@ TEST_F(LayerTreeHostImplTest, ScrollNonScrollableRootWithTopControls) {
settings.calculate_top_controls_position = true;
settings.top_controls_height = 50;
- host_impl_ = LayerTreeHostImpl::Create(settings,
- this,
- &proxy_,
- &stats_instrumentation_);
+ host_impl_ = LayerTreeHostImpl::Create(
+ settings, this, &proxy_, &stats_instrumentation_, NULL);
host_impl_->InitializeRenderer(CreateOutputSurface());
host_impl_->SetViewportSize(gfx::Size(10, 10));
@@ -2068,7 +2056,7 @@ TEST_F(LayerTreeHostImplTest, PageScaleDeltaAppliedToRootScrollLayerOnly) {
// the page scale delta on the root layer is applied hierarchically.
LayerTreeHostImpl::FrameData frame;
EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
host_impl_->DidDrawAllLayers(frame);
EXPECT_EQ(1.f, root->draw_transform().matrix().getDouble(0, 0));
@@ -2759,7 +2747,7 @@ TEST_F(LayerTreeHostImplTest, OverscrollAlways) {
LayerTreeSettings settings;
settings.always_overscroll = true;
host_impl_ = LayerTreeHostImpl::Create(
- settings, this, &proxy_, &stats_instrumentation_);
+ settings, this, &proxy_, &stats_instrumentation_, NULL);
SetupScrollAndContentsLayers(gfx::Size(50, 50));
host_impl_->SetViewportSize(gfx::Size(50, 50));
@@ -2903,7 +2891,7 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) {
layer1->SetExpectation(false, false);
layer1->set_update_rect(gfx::RectF(layer1->content_bounds()));
EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
EXPECT_TRUE(layer1->quads_appended());
host_impl_->DidDrawAllLayers(frame);
@@ -2912,7 +2900,7 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) {
layer1->SetExpectation(true, false);
layer1->set_update_rect(gfx::RectF(layer1->content_bounds()));
EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
EXPECT_TRUE(layer1->quads_appended());
host_impl_->DidDrawAllLayers(frame);
@@ -2922,7 +2910,7 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) {
layer1->SetExpectation(true, false);
layer1->set_update_rect(gfx::RectF(layer1->content_bounds()));
EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
EXPECT_TRUE(layer1->quads_appended());
host_impl_->DidDrawAllLayers(frame);
@@ -2932,7 +2920,7 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) {
layer1->SetExpectation(true, false);
layer1->set_update_rect(gfx::RectF(layer1->content_bounds()));
EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
EXPECT_TRUE(layer1->quads_appended());
host_impl_->DidDrawAllLayers(frame);
@@ -2954,7 +2942,7 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) {
layer2->SetExpectation(false, false);
layer2->set_update_rect(gfx::RectF(layer1->content_bounds()));
EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
EXPECT_TRUE(layer1->quads_appended());
EXPECT_TRUE(layer2->quads_appended());
host_impl_->DidDrawAllLayers(frame);
@@ -2967,7 +2955,7 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) {
layer2->SetExpectation(false, false);
layer2->set_update_rect(gfx::RectF(layer1->content_bounds()));
EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
EXPECT_TRUE(layer1->quads_appended());
EXPECT_TRUE(layer2->quads_appended());
host_impl_->DidDrawAllLayers(frame);
@@ -2981,7 +2969,7 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) {
layer2->SetExpectation(false, false);
layer2->set_update_rect(gfx::RectF(layer1->content_bounds()));
EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
EXPECT_TRUE(layer1->quads_appended());
EXPECT_TRUE(layer2->quads_appended());
host_impl_->DidDrawAllLayers(frame);
@@ -2998,7 +2986,7 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) {
layer2->SetExpectation(false, false);
layer2->set_update_rect(gfx::RectF(layer1->content_bounds()));
EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
EXPECT_TRUE(layer1->quads_appended());
EXPECT_TRUE(layer2->quads_appended());
host_impl_->DidDrawAllLayers(frame);
@@ -3014,7 +3002,7 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) {
layer2->SetExpectation(true, false);
layer2->set_update_rect(gfx::RectF(layer1->content_bounds()));
EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
EXPECT_TRUE(layer1->quads_appended());
EXPECT_TRUE(layer2->quads_appended());
host_impl_->DidDrawAllLayers(frame);
@@ -3029,7 +3017,7 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) {
layer2->SetExpectation(true, false);
layer2->set_update_rect(gfx::RectF(layer1->content_bounds()));
EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
EXPECT_TRUE(layer1->quads_appended());
EXPECT_TRUE(layer2->quads_appended());
host_impl_->DidDrawAllLayers(frame);
@@ -3045,7 +3033,7 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) {
layer2->SetExpectation(false, false);
layer2->set_update_rect(gfx::RectF(layer1->content_bounds()));
EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
EXPECT_TRUE(layer1->quads_appended());
EXPECT_TRUE(layer2->quads_appended());
host_impl_->DidDrawAllLayers(frame);
@@ -3058,7 +3046,7 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) {
layer1->SetExpectation(true, false);
layer1->set_update_rect(gfx::RectF(layer1->content_bounds()));
EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
EXPECT_TRUE(layer1->quads_appended());
host_impl_->DidDrawAllLayers(frame);
@@ -3070,7 +3058,7 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) {
layer1->SetExpectation(true, false);
layer1->set_update_rect(gfx::RectF(layer1->content_bounds()));
EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
EXPECT_TRUE(layer1->quads_appended());
host_impl_->DidDrawAllLayers(frame);
@@ -3082,7 +3070,7 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) {
layer1->SetExpectation(true, false);
layer1->set_update_rect(gfx::RectF(layer1->content_bounds()));
EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
EXPECT_TRUE(layer1->quads_appended());
host_impl_->DidDrawAllLayers(frame);
@@ -3095,7 +3083,7 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) {
layer1->SetExpectation(false, false);
layer1->set_update_rect(gfx::RectF(layer1->content_bounds()));
EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
EXPECT_TRUE(layer1->quads_appended());
host_impl_->DidDrawAllLayers(frame);
}
@@ -3112,7 +3100,7 @@ class LayerTreeHostImplViewportCoveredTest : public LayerTreeHostImplTest {
settings.minimum_occlusion_tracking_size = gfx::Size();
settings.impl_side_painting = true;
host_impl_ = LayerTreeHostImpl::Create(
- settings, this, &proxy_, &stats_instrumentation_);
+ settings, this, &proxy_, &stats_instrumentation_, NULL);
scoped_ptr<FakeOutputSurface> output_surface;
if (always_draw)
@@ -3317,7 +3305,8 @@ TEST_F(LayerTreeHostImplViewportCoveredTest, ViewportCoveredOverhangBitmap) {
skbitmap.setImmutable();
// Specify an overhang bitmap to use.
- UIResourceBitmap ui_resource_bitmap(skbitmap, UIResourceBitmap::REPEAT);
+ UIResourceBitmap ui_resource_bitmap(skbitmap);
+ ui_resource_bitmap.SetWrapMode(UIResourceBitmap::REPEAT);
UIResourceId ui_resource_id = 12345;
host_impl_->CreateUIResource(ui_resource_id, ui_resource_bitmap);
host_impl_->SetOverhangUIResource(ui_resource_id, gfx::Size(32, 32));
@@ -3453,7 +3442,7 @@ TEST_F(LayerTreeHostImplTest, ReshapeNotCalledUntilDraw) {
host_impl_->SetViewportSize(gfx::Size(10, 10));
host_impl_->SetDeviceScaleFactor(1.f);
EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
EXPECT_TRUE(reshape_tracker->reshape_called());
EXPECT_EQ(reshape_tracker->last_reshape_width(), 10);
EXPECT_EQ(reshape_tracker->last_reshape_height(), 10);
@@ -3463,7 +3452,7 @@ TEST_F(LayerTreeHostImplTest, ReshapeNotCalledUntilDraw) {
host_impl_->SetViewportSize(gfx::Size(20, 30));
EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
EXPECT_TRUE(reshape_tracker->reshape_called());
EXPECT_EQ(reshape_tracker->last_reshape_width(), 20);
EXPECT_EQ(reshape_tracker->last_reshape_height(), 30);
@@ -3473,7 +3462,7 @@ TEST_F(LayerTreeHostImplTest, ReshapeNotCalledUntilDraw) {
host_impl_->SetDeviceScaleFactor(2.f);
EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
EXPECT_TRUE(reshape_tracker->reshape_called());
EXPECT_EQ(reshape_tracker->last_reshape_width(), 20);
EXPECT_EQ(reshape_tracker->last_reshape_height(), 30);
@@ -3532,10 +3521,8 @@ TEST_F(LayerTreeHostImplTest, PartialSwapReceivesDamageRect) {
LayerTreeSettings settings;
settings.partial_swap_enabled = true;
scoped_ptr<LayerTreeHostImpl> layer_tree_host_impl =
- LayerTreeHostImpl::Create(settings,
- this,
- &proxy_,
- &stats_instrumentation_);
+ LayerTreeHostImpl::Create(
+ settings, this, &proxy_, &stats_instrumentation_, NULL);
layer_tree_host_impl->InitializeRenderer(output_surface.Pass());
layer_tree_host_impl->SetViewportSize(gfx::Size(500, 500));
@@ -3559,7 +3546,7 @@ TEST_F(LayerTreeHostImplTest, PartialSwapReceivesDamageRect) {
// First frame, the entire screen should get swapped.
EXPECT_TRUE(layer_tree_host_impl->PrepareToDraw(&frame, gfx::Rect()));
- layer_tree_host_impl->DrawLayers(&frame, base::TimeTicks::Now());
+ layer_tree_host_impl->DrawLayers(&frame, gfx::FrameTime::Now());
layer_tree_host_impl->DidDrawAllLayers(frame);
layer_tree_host_impl->SwapBuffers(frame);
gfx::Rect actual_swap_rect = swap_tracker->update_rect();
@@ -3577,7 +3564,7 @@ TEST_F(LayerTreeHostImplTest, PartialSwapReceivesDamageRect) {
layer_tree_host_impl->active_tree()->root_layer()->children()[0]->SetPosition(
gfx::PointF());
EXPECT_TRUE(layer_tree_host_impl->PrepareToDraw(&frame, gfx::Rect()));
- layer_tree_host_impl->DrawLayers(&frame, base::TimeTicks::Now());
+ layer_tree_host_impl->DrawLayers(&frame, gfx::FrameTime::Now());
host_impl_->DidDrawAllLayers(frame);
layer_tree_host_impl->SwapBuffers(frame);
actual_swap_rect = swap_tracker->update_rect();
@@ -3597,7 +3584,7 @@ TEST_F(LayerTreeHostImplTest, PartialSwapReceivesDamageRect) {
layer_tree_host_impl->active_tree()->root_layer()->SetBackgroundColor(
SK_ColorBLACK);
EXPECT_TRUE(layer_tree_host_impl->PrepareToDraw(&frame, gfx::Rect()));
- layer_tree_host_impl->DrawLayers(&frame, base::TimeTicks::Now());
+ layer_tree_host_impl->DrawLayers(&frame, gfx::FrameTime::Now());
host_impl_->DidDrawAllLayers(frame);
layer_tree_host_impl->SwapBuffers(frame);
actual_swap_rect = swap_tracker->update_rect();
@@ -3765,7 +3752,7 @@ TEST_F(LayerTreeHostImplTest, NoPartialSwap) {
{
LayerTreeHostImpl::FrameData frame;
EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
host_impl_->DidDrawAllLayers(frame);
}
Mock::VerifyAndClearExpectations(&mock_context);
@@ -3778,7 +3765,7 @@ TEST_F(LayerTreeHostImplTest, NoPartialSwap) {
{
LayerTreeHostImpl::FrameData frame;
EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
host_impl_->DidDrawAllLayers(frame);
}
Mock::VerifyAndClearExpectations(&mock_context);
@@ -3800,7 +3787,7 @@ TEST_F(LayerTreeHostImplTest, PartialSwap) {
{
LayerTreeHostImpl::FrameData frame;
EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
host_impl_->DidDrawAllLayers(frame);
}
Mock::VerifyAndClearExpectations(&mock_context);
@@ -3815,7 +3802,7 @@ TEST_F(LayerTreeHostImplTest, PartialSwap) {
{
LayerTreeHostImpl::FrameData frame;
EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
host_impl_->DidDrawAllLayers(frame);
}
Mock::VerifyAndClearExpectations(&mock_context);
@@ -3847,8 +3834,8 @@ 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);
+ scoped_ptr<LayerTreeHostImpl> my_host_impl = LayerTreeHostImpl::Create(
+ settings, client, proxy, stats_instrumentation, NULL);
my_host_impl->InitializeRenderer(output_surface.Pass());
my_host_impl->SetViewportSize(gfx::Size(100, 100));
@@ -3929,7 +3916,7 @@ TEST_F(LayerTreeHostImplTest, ContributingLayerEmptyScissorPartialSwap) {
EXPECT_EQ(DrawQuad::RENDER_PASS,
frame.render_passes[1]->quad_list[0]->material);
- my_host_impl->DrawLayers(&frame, base::TimeTicks::Now());
+ my_host_impl->DrawLayers(&frame, gfx::FrameTime::Now());
my_host_impl->DidDrawAllLayers(frame);
}
}
@@ -3950,7 +3937,7 @@ TEST_F(LayerTreeHostImplTest, ContributingLayerEmptyScissorNoPartialSwap) {
EXPECT_EQ(DrawQuad::RENDER_PASS,
frame.render_passes[1]->quad_list[0]->material);
- my_host_impl->DrawLayers(&frame, base::TimeTicks::Now());
+ my_host_impl->DrawLayers(&frame, gfx::FrameTime::Now());
my_host_impl->DidDrawAllLayers(frame);
}
}
@@ -4029,7 +4016,7 @@ TEST_F(LayerTreeHostImplTest, LayersFreeTextures) {
LayerTreeHostImpl::FrameData frame;
EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
host_impl_->DidDrawAllLayers(frame);
host_impl_->SwapBuffers(frame);
@@ -4072,7 +4059,7 @@ TEST_F(LayerTreeHostImplTest, HasTransparentBackground) {
.Times(1);
LayerTreeHostImpl::FrameData frame;
EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
host_impl_->DidDrawAllLayers(frame);
Mock::VerifyAndClearExpectations(&mock_context);
@@ -4080,7 +4067,7 @@ TEST_F(LayerTreeHostImplTest, HasTransparentBackground) {
host_impl_->active_tree()->set_has_transparent_background(true);
host_impl_->SetFullRootLayerDamage();
EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
host_impl_->DidDrawAllLayers(frame);
Mock::VerifyAndClearExpectations(&mock_context);
}
@@ -4167,7 +4154,7 @@ class LayerTreeHostImplTestWithDelegatingRenderer
root_render_pass->quad_list[1]->visible_rect);
}
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
host_impl_->DidDrawAllLayers(frame);
EXPECT_EQ(expect_to_draw, host_impl_->SwapBuffers(frame));
}
@@ -4228,10 +4215,8 @@ class FakeMaskLayerImpl : public LayerImpl {
TEST_F(LayerTreeHostImplTest, MaskLayerWithScaling) {
LayerTreeSettings settings;
settings.layer_transforms_should_scale_layer_contents = true;
- host_impl_ = LayerTreeHostImpl::Create(settings,
- this,
- &proxy_,
- &stats_instrumentation_);
+ host_impl_ = LayerTreeHostImpl::Create(
+ settings, this, &proxy_, &stats_instrumentation_, NULL);
host_impl_->InitializeRenderer(CreateOutputSurface());
host_impl_->SetViewportSize(gfx::Size(10, 10));
@@ -4309,7 +4294,7 @@ TEST_F(LayerTreeHostImplTest, MaskLayerWithScaling) {
EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
render_pass_quad->mask_uv_rect.ToString());
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
host_impl_->DidDrawAllLayers(frame);
}
@@ -4337,7 +4322,7 @@ TEST_F(LayerTreeHostImplTest, MaskLayerWithScaling) {
EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
render_pass_quad->mask_uv_rect.ToString());
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
host_impl_->DidDrawAllLayers(frame);
}
@@ -4367,7 +4352,7 @@ TEST_F(LayerTreeHostImplTest, MaskLayerWithScaling) {
EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
render_pass_quad->mask_uv_rect.ToString());
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
host_impl_->DidDrawAllLayers(frame);
}
}
@@ -4430,7 +4415,7 @@ TEST_F(LayerTreeHostImplTest, MaskLayerWithDifferentBounds) {
EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
render_pass_quad->mask_uv_rect.ToString());
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
host_impl_->DidDrawAllLayers(frame);
}
@@ -4457,7 +4442,7 @@ TEST_F(LayerTreeHostImplTest, MaskLayerWithDifferentBounds) {
EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
render_pass_quad->mask_uv_rect.ToString());
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
host_impl_->DidDrawAllLayers(frame);
}
@@ -4487,7 +4472,7 @@ TEST_F(LayerTreeHostImplTest, MaskLayerWithDifferentBounds) {
EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
render_pass_quad->mask_uv_rect.ToString());
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
host_impl_->DidDrawAllLayers(frame);
}
@@ -4512,7 +4497,7 @@ TEST_F(LayerTreeHostImplTest, MaskLayerWithDifferentBounds) {
EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
render_pass_quad->mask_uv_rect.ToString());
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
host_impl_->DidDrawAllLayers(frame);
}
}
@@ -4581,7 +4566,7 @@ TEST_F(LayerTreeHostImplTest, ReflectionMaskLayerWithDifferentBounds) {
EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
replica_quad->mask_uv_rect.ToString());
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
host_impl_->DidDrawAllLayers(frame);
}
@@ -4609,7 +4594,7 @@ TEST_F(LayerTreeHostImplTest, ReflectionMaskLayerWithDifferentBounds) {
EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
replica_quad->mask_uv_rect.ToString());
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
host_impl_->DidDrawAllLayers(frame);
}
@@ -4640,7 +4625,7 @@ TEST_F(LayerTreeHostImplTest, ReflectionMaskLayerWithDifferentBounds) {
EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
replica_quad->mask_uv_rect.ToString());
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
host_impl_->DidDrawAllLayers(frame);
}
@@ -4666,7 +4651,7 @@ TEST_F(LayerTreeHostImplTest, ReflectionMaskLayerWithDifferentBounds) {
EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
replica_quad->mask_uv_rect.ToString());
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
host_impl_->DidDrawAllLayers(frame);
}
}
@@ -4757,7 +4742,7 @@ TEST_F(LayerTreeHostImplTest, ReflectionMaskLayerForSurfaceWithUnclippedChild) {
EXPECT_EQ(gfx::RectF(0.f, 0.f, 2.f, 1.f).ToString(),
replica_quad->mask_uv_rect.ToString());
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
host_impl_->DidDrawAllLayers(frame);
}
@@ -4791,7 +4776,7 @@ TEST_F(LayerTreeHostImplTest, ReflectionMaskLayerForSurfaceWithUnclippedChild) {
EXPECT_EQ(gfx::RectF(-1.f, 0.f, 2.f, 1.f).ToString(),
replica_quad->mask_uv_rect.ToString());
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
host_impl_->DidDrawAllLayers(frame);
}
}
@@ -4887,7 +4872,7 @@ TEST_F(LayerTreeHostImplTest, MaskLayerForSurfaceWithClippedLayer) {
1.f / 50.f).ToString(),
render_pass_quad->mask_uv_rect.ToString());
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
host_impl_->DidDrawAllLayers(frame);
}
}
@@ -4960,7 +4945,7 @@ TEST_F(LayerTreeHostImplTest, FarAwayQuadsDontNeedAA) {
quad->quadTransform(), quad, &device_layer_quad, edge);
EXPECT_FALSE(antialiased);
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
host_impl_->DidDrawAllLayers(frame);
}
@@ -5061,7 +5046,7 @@ TEST_F(LayerTreeHostImplTest,
LayerTreeHostImpl::FrameData frame;
EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
host_impl_->DidDrawAllLayers(frame);
EXPECT_EQ(1u, frame.will_draw_layers.size());
@@ -5219,10 +5204,8 @@ TEST_F(LayerTreeHostImplTestDeferredInitialize, Fails_OffscreenContext) {
// doesn't support memory management extensions.
TEST_F(LayerTreeHostImplTest, DefaultMemoryAllocation) {
LayerTreeSettings settings;
- host_impl_ = LayerTreeHostImpl::Create(settings,
- this,
- &proxy_,
- &stats_instrumentation_);
+ host_impl_ = LayerTreeHostImpl::Create(
+ settings, this, &proxy_, &stats_instrumentation_, NULL);
scoped_ptr<OutputSurface> output_surface(
FakeOutputSurface::Create3d(TestWebGraphicsContext3D::Create()));
@@ -5232,8 +5215,8 @@ TEST_F(LayerTreeHostImplTest, DefaultMemoryAllocation) {
TEST_F(LayerTreeHostImplTest, MemoryPolicy) {
ManagedMemoryPolicy policy1(
- 456, ManagedMemoryPolicy::CUTOFF_ALLOW_EVERYTHING,
- 123, ManagedMemoryPolicy::CUTOFF_ALLOW_NICE_TO_HAVE, 1000);
+ 456, gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING,
+ 123, gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE, 1000);
int visible_cutoff_value = ManagedMemoryPolicy::PriorityCutoffToValue(
policy1.priority_cutoff_when_visible);
int not_visible_cutoff_value = ManagedMemoryPolicy::PriorityCutoffToValue(
@@ -5331,12 +5314,10 @@ TEST_F(LayerTreeHostImplTest, ShutdownReleasesContext) {
scoped_refptr<TestContextProvider> context_provider =
TestContextProvider::Create();
- host_impl_ = LayerTreeHostImpl::Create(LayerTreeSettings(),
- this,
- &proxy_,
- &stats_instrumentation_);
- host_impl_->InitializeRenderer(
- FakeOutputSurface::Create3d(context_provider).PassAs<OutputSurface>());
+ host_impl_ = LayerTreeHostImpl::Create(
+ LayerTreeSettings(), this, &proxy_, &stats_instrumentation_, NULL);
+ host_impl_->InitializeRenderer(FakeOutputSurface::Create3d(context_provider)
+ .PassAs<OutputSurface>());
host_impl_->SetViewportSize(gfx::Size(10, 10));
SetupRootLayerImpl(LayerImpl::Create(host_impl_->active_tree(), 1));
@@ -5349,7 +5330,7 @@ TEST_F(LayerTreeHostImplTest, ShutdownReleasesContext) {
LayerTreeHostImpl::FrameData frame;
EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
- host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
+ host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
host_impl_->DidDrawAllLayers(frame);
// The CopyOutputResult's callback has a ref on the ContextProvider and a
diff --git a/cc/trees/layer_tree_host_perftest.cc b/cc/trees/layer_tree_host_perftest.cc
index 1eebe41d9c..79ee46be81 100644
--- a/cc/trees/layer_tree_host_perftest.cc
+++ b/cc/trees/layer_tree_host_perftest.cc
@@ -44,6 +44,10 @@ class LayerTreeHostPerfTest : public LayerTreeTest {
fake_content_layer_client_.set_paint_all_opaque(true);
}
+ virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
+ settings->throttle_frame_production = false;
+ }
+
virtual void BeginTest() OVERRIDE {
BuildTree();
PostSetNeedsCommitToMainThread();
diff --git a/cc/trees/layer_tree_host_pixeltest_on_demand_raster.cc b/cc/trees/layer_tree_host_pixeltest_on_demand_raster.cc
index a1990b01d5..c432a5ed0e 100644
--- a/cc/trees/layer_tree_host_pixeltest_on_demand_raster.cc
+++ b/cc/trees/layer_tree_host_pixeltest_on_demand_raster.cc
@@ -29,8 +29,8 @@ class LayerTreeHostOnDemandRasterPixelTest : public LayerTreePixelTest {
virtual void BeginCommitOnThread(LayerTreeHostImpl* impl) OVERRIDE {
// Not enough memory available. Enforce on-demand rasterization.
impl->SetMemoryPolicy(
- ManagedMemoryPolicy(1, ManagedMemoryPolicy::CUTOFF_ALLOW_EVERYTHING,
- 1, ManagedMemoryPolicy::CUTOFF_ALLOW_NOTHING,
+ ManagedMemoryPolicy(1, gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING,
+ 1, gpu::MemoryAllocation::CUTOFF_ALLOW_NOTHING,
1000));
impl->SetDiscardBackBufferWhenNotVisible(true);
}
diff --git a/cc/trees/layer_tree_host_unittest.cc b/cc/trees/layer_tree_host_unittest.cc
index c5127b181b..950fd79466 100644
--- a/cc/trees/layer_tree_host_unittest.cc
+++ b/cc/trees/layer_tree_host_unittest.cc
@@ -51,6 +51,7 @@
#include "third_party/khronos/GLES2/gl2.h"
#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"
@@ -730,6 +731,101 @@ class LayerTreeHostTestSetNextCommitForcesRedraw : public LayerTreeHostTest {
SINGLE_AND_MULTI_THREAD_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.
+class LayerTreeHostTestUndrawnLayersDamageLater : public LayerTreeHostTest {
+ public:
+ LayerTreeHostTestUndrawnLayersDamageLater()
+ : root_layer_(ContentLayer::Create(&client_)) {
+ }
+
+ virtual void SetupTree() OVERRIDE {
+ root_layer_->SetIsDrawable(true);
+ root_layer_->SetBounds(gfx::Size(50, 50));
+ layer_tree_host()->SetRootLayer(root_layer_);
+
+ // The initially transparent layer has a larger child layer, which is
+ // not initially drawn because of the this (parent) layer.
+ parent_layer_ = FakeContentLayer::Create(&client_);
+ parent_layer_->SetBounds(gfx::Size(15, 15));
+ parent_layer_->SetOpacity(0.0f);
+ root_layer_->AddChild(parent_layer_);
+
+ child_layer_ = FakeContentLayer::Create(&client_);
+ child_layer_->SetBounds(gfx::Size(25, 25));
+ parent_layer_->AddChild(child_layer_);
+
+ LayerTreeHostTest::SetupTree();
+ }
+
+ virtual void BeginTest() OVERRIDE {
+ PostSetNeedsCommitToMainThread();
+ }
+
+ virtual bool PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
+ LayerTreeHostImpl::FrameData* frame_data,
+ bool result) OVERRIDE {
+ EXPECT_TRUE(result);
+
+ gfx::RectF root_damage_rect;
+ if (!frame_data->render_passes.empty())
+ root_damage_rect = frame_data->render_passes.back()->damage_rect;
+
+ // The first time, the whole view needs be drawn.
+ // Afterwards, just the opacity of surface_layer1 is changed a few times,
+ // and each damage should be the bounding box of it and its child. If this
+ // was working improperly, the damage might not include its childs bounding
+ // box.
+ switch (layer_tree_host()->source_frame_number()) {
+ case 1:
+ EXPECT_RECT_EQ(gfx::Rect(root_layer_->bounds()), root_damage_rect);
+ break;
+ case 2:
+ case 3:
+ case 4:
+ EXPECT_RECT_EQ(gfx::Rect(child_layer_->bounds()), root_damage_rect);
+ break;
+ default:
+ NOTREACHED();
+ }
+
+ return result;
+ }
+
+ virtual void DidCommitAndDrawFrame() OVERRIDE {
+ switch (layer_tree_host()->source_frame_number()) {
+ case 1:
+ // Test not owning the surface.
+ parent_layer_->SetOpacity(1.0f);
+ break;
+ case 2:
+ parent_layer_->SetOpacity(0.0f);
+ break;
+ case 3:
+ // Test owning the surface.
+ parent_layer_->SetOpacity(0.5f);
+ parent_layer_->SetForceRenderSurface(true);
+ break;
+ case 4:
+ EndTest();
+ break;
+ default:
+ NOTREACHED();
+ }
+ }
+
+
+ virtual void AfterTest() OVERRIDE {}
+
+ private:
+ FakeContentLayerClient client_;
+ scoped_refptr<ContentLayer> root_layer_;
+ scoped_refptr<FakeContentLayer> parent_layer_;
+ scoped_refptr<FakeContentLayer> child_layer_;
+};
+
+SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestUndrawnLayersDamageLater);
+
// If the layerTreeHost says it can't draw, Then we should not try to draw.
class LayerTreeHostTestCanDrawBlocksDrawing : public LayerTreeHostTest {
public:
@@ -1004,10 +1100,9 @@ class LayerTreeHostTestFrameTimeUpdatesAfterDraw : public LayerTreeHostTest {
first_frame_time_ = impl->CurrentFrameTimeTicks();
impl->SetNeedsRedraw();
- // Since base::TimeTicks::Now() uses a low-resolution clock on
- // Windows, we need to make sure that the clock has incremented past
- // first_frame_time_.
- while (first_frame_time_ == base::TimeTicks::Now()) {}
+ // Since we might use a low-resolution clock on Windows, we need to
+ // make sure that the clock has incremented past first_frame_time_.
+ while (first_frame_time_ == gfx::FrameTime::Now()) {}
return;
}
@@ -2204,7 +2299,7 @@ class LayerTreeHostWithProxy : public LayerTreeHost {
LayerTreeHostWithProxy(FakeLayerTreeHostClient* client,
const LayerTreeSettings& settings,
scoped_ptr<FakeProxy> proxy)
- : LayerTreeHost(client, settings) {
+ : LayerTreeHost(client, NULL, settings) {
proxy->SetLayerTreeHost(this);
EXPECT_TRUE(InitializeForTesting(proxy.PassAs<Proxy>()));
}
@@ -2272,7 +2367,7 @@ TEST(LayerTreeHostTest, PartialUpdatesWithGLRenderer) {
settings.max_partial_texture_updates = 4;
scoped_ptr<LayerTreeHost> host =
- LayerTreeHost::Create(&client, settings, NULL);
+ LayerTreeHost::Create(&client, NULL, settings, NULL);
EXPECT_TRUE(host->InitializeOutputSurfaceIfNeeded());
EXPECT_EQ(4u, host->settings().max_partial_texture_updates);
}
@@ -2284,7 +2379,7 @@ TEST(LayerTreeHostTest, PartialUpdatesWithSoftwareRenderer) {
settings.max_partial_texture_updates = 4;
scoped_ptr<LayerTreeHost> host =
- LayerTreeHost::Create(&client, settings, NULL);
+ LayerTreeHost::Create(&client, NULL, settings, NULL);
EXPECT_TRUE(host->InitializeOutputSurfaceIfNeeded());
EXPECT_EQ(4u, host->settings().max_partial_texture_updates);
}
@@ -2296,7 +2391,7 @@ TEST(LayerTreeHostTest, PartialUpdatesWithDelegatingRendererAndGLContent) {
settings.max_partial_texture_updates = 4;
scoped_ptr<LayerTreeHost> host =
- LayerTreeHost::Create(&client, settings, NULL);
+ LayerTreeHost::Create(&client, NULL, settings, NULL);
EXPECT_TRUE(host->InitializeOutputSurfaceIfNeeded());
EXPECT_EQ(0u, host->MaxPartialTextureUpdates());
}
@@ -2309,7 +2404,7 @@ TEST(LayerTreeHostTest,
settings.max_partial_texture_updates = 4;
scoped_ptr<LayerTreeHost> host =
- LayerTreeHost::Create(&client, settings, NULL);
+ LayerTreeHost::Create(&client, NULL, settings, NULL);
EXPECT_TRUE(host->InitializeOutputSurfaceIfNeeded());
EXPECT_EQ(0u, host->MaxPartialTextureUpdates());
}
@@ -2358,9 +2453,9 @@ class LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted
// Because a resource was evicted, a commit will be kicked off.
host_impl->SetMemoryPolicy(
ManagedMemoryPolicy(100 * 100 * 4 * 2,
- ManagedMemoryPolicy::CUTOFF_ALLOW_EVERYTHING,
+ gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING,
100 * 100 * 4 * 1,
- ManagedMemoryPolicy::CUTOFF_ALLOW_EVERYTHING,
+ gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING,
1000));
host_impl->SetDiscardBackBufferWhenNotVisible(true);
break;
@@ -2482,15 +2577,16 @@ class LayerTreeHostTestLCDNotification : public LayerTreeHostTest {
SINGLE_THREAD_TEST_F(LayerTreeHostTestLCDNotification);
-// Verify that the BeginFrame notification is used to initiate rendering.
-class LayerTreeHostTestBeginFrameNotification : public LayerTreeHostTest {
+// Verify that the BeginImplFrame notification is used to initiate rendering.
+class LayerTreeHostTestBeginImplFrameNotification : public LayerTreeHostTest {
public:
virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
- settings->begin_frame_scheduling_enabled = true;
+ settings->begin_impl_frame_scheduling_enabled = true;
}
virtual void BeginTest() OVERRIDE {
- // This will trigger a SetNeedsBeginFrame which will trigger a BeginFrame.
+ // This will trigger a SetNeedsBeginImplFrame which will trigger a
+ // BeginImplFrame.
PostSetNeedsCommitToMainThread();
}
@@ -2508,24 +2604,24 @@ class LayerTreeHostTestBeginFrameNotification : public LayerTreeHostTest {
base::TimeTicks frame_time_;
};
-MULTI_THREAD_TEST_F(LayerTreeHostTestBeginFrameNotification);
+MULTI_THREAD_TEST_F(LayerTreeHostTestBeginImplFrameNotification);
-class LayerTreeHostTestBeginFrameNotificationShutdownWhileEnabled
+class LayerTreeHostTestBeginImplFrameNotificationShutdownWhileEnabled
: public LayerTreeHostTest {
public:
virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
- settings->begin_frame_scheduling_enabled = true;
+ settings->begin_impl_frame_scheduling_enabled = true;
settings->using_synchronous_renderer_compositor = true;
}
virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
- // The BeginFrame notification is turned off now but will get enabled
+ // The BeginImplFrame notification is turned off now but will get enabled
// once we return. End test while it's enabled.
ImplThreadTaskRunner()->PostTask(
FROM_HERE,
- base::Bind(&LayerTreeHostTestBeginFrameNotification::EndTest,
+ base::Bind(&LayerTreeHostTestBeginImplFrameNotification::EndTest,
base::Unretained(this)));
}
@@ -2533,7 +2629,7 @@ class LayerTreeHostTestBeginFrameNotificationShutdownWhileEnabled
};
MULTI_THREAD_TEST_F(
- LayerTreeHostTestBeginFrameNotificationShutdownWhileEnabled);
+ LayerTreeHostTestBeginImplFrameNotificationShutdownWhileEnabled);
class LayerTreeHostTestAbortedCommitDoesntStall : public LayerTreeHostTest {
protected:
@@ -2541,7 +2637,7 @@ class LayerTreeHostTestAbortedCommitDoesntStall : public LayerTreeHostTest {
: commit_count_(0), commit_complete_count_(0) {}
virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
- settings->begin_frame_scheduling_enabled = true;
+ settings->begin_impl_frame_scheduling_enabled = true;
}
virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
@@ -4709,7 +4805,7 @@ MULTI_THREAD_TEST_F(LayerTreeHostTestUpdateLayerInEmptyViewport);
class LayerTreeHostTestAbortEvictedTextures : public LayerTreeHostTest {
public:
LayerTreeHostTestAbortEvictedTextures()
- : num_will_begin_frames_(0), num_impl_commits_(0) {}
+ : num_will_begin_main_frames_(0), num_impl_commits_(0) {}
protected:
virtual void SetupTree() OVERRIDE {
@@ -4723,9 +4819,9 @@ class LayerTreeHostTestAbortEvictedTextures : public LayerTreeHostTest {
virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
- virtual void WillBeginFrame() OVERRIDE {
- num_will_begin_frames_++;
- switch (num_will_begin_frames_) {
+ virtual void WillBeginMainFrame() OVERRIDE {
+ num_will_begin_main_frames_++;
+ switch (num_will_begin_main_frames_) {
case 2:
// Send a redraw to the compositor thread. This will (wrongly) be
// ignored unless aborting resets the texture state.
@@ -4755,12 +4851,12 @@ class LayerTreeHostTestAbortEvictedTextures : public LayerTreeHostTest {
virtual void AfterTest() OVERRIDE {
// Ensure that the commit was truly aborted.
- EXPECT_EQ(2, num_will_begin_frames_);
+ EXPECT_EQ(2, num_will_begin_main_frames_);
EXPECT_EQ(1, num_impl_commits_);
}
private:
- int num_will_begin_frames_;
+ int num_will_begin_main_frames_;
int num_impl_commits_;
};
@@ -4881,9 +4977,9 @@ class LayerTreeHostTestMemoryLimits : public LayerTreeHostTest {
// This will trigger a commit because the priority cutoff has changed.
impl->SetMemoryPolicy(ManagedMemoryPolicy(
16u*1024u*1024u,
- ManagedMemoryPolicy::CUTOFF_ALLOW_NICE_TO_HAVE,
+ gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE,
0,
- ManagedMemoryPolicy::CUTOFF_ALLOW_NOTHING,
+ gpu::MemoryAllocation::CUTOFF_ALLOW_NOTHING,
1000));
break;
case 2:
@@ -4891,9 +4987,9 @@ class LayerTreeHostTestMemoryLimits : public LayerTreeHostTest {
// changed, and there is already enough memory for all allocations.
impl->SetMemoryPolicy(ManagedMemoryPolicy(
32u*1024u*1024u,
- ManagedMemoryPolicy::CUTOFF_ALLOW_NICE_TO_HAVE,
+ gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE,
0,
- ManagedMemoryPolicy::CUTOFF_ALLOW_NOTHING,
+ gpu::MemoryAllocation::CUTOFF_ALLOW_NOTHING,
1000));
break;
case 3:
@@ -5041,14 +5137,14 @@ class LayerTreeHostTestSetMemoryPolicyOnLostOutputSurface
second_context_provider_ :
first_context_provider_));
output_surface->SetMemoryPolicyToSetAtBind(make_scoped_ptr(
- new cc::ManagedMemoryPolicy(
+ new ManagedMemoryPolicy(
second_context_provider_ ?
second_output_surface_memory_limit_ :
first_output_surface_memory_limit_,
- cc::ManagedMemoryPolicy::CUTOFF_ALLOW_NICE_TO_HAVE,
+ gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE,
0,
- cc::ManagedMemoryPolicy::CUTOFF_ALLOW_NOTHING,
- cc::ManagedMemoryPolicy::kDefaultNumResourcesLimit)));
+ gpu::MemoryAllocation::CUTOFF_ALLOW_NOTHING,
+ ManagedMemoryPolicy::kDefaultNumResourcesLimit)));
return output_surface.PassAs<OutputSurface>();
}
diff --git a/cc/trees/layer_tree_host_unittest_animation.cc b/cc/trees/layer_tree_host_unittest_animation.cc
index 70e2a9ec6d..90fc936519 100644
--- a/cc/trees/layer_tree_host_unittest_animation.cc
+++ b/cc/trees/layer_tree_host_unittest_animation.cc
@@ -375,14 +375,17 @@ class LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree
// Verify that commits are actually alternating with empty / non-empty
// trees.
- switch (host_impl->active_tree()->source_frame_number()) {
+ int frame_number = host_impl->active_tree()->source_frame_number();
+ switch (frame_number) {
case 0:
case 2:
- EXPECT_TRUE(host_impl->active_tree()->root_layer());
+ EXPECT_TRUE(host_impl->active_tree()->root_layer())
+ << "frame: " << frame_number;
break;
case 1:
case 3:
- EXPECT_FALSE(host_impl->active_tree()->root_layer());
+ EXPECT_FALSE(host_impl->active_tree()->root_layer())
+ << "frame: " << frame_number;
break;
}
diff --git a/cc/trees/layer_tree_host_unittest_context.cc b/cc/trees/layer_tree_host_unittest_context.cc
index e4a0ca7ecc..03b8d7f629 100644
--- a/cc/trees/layer_tree_host_unittest_context.cc
+++ b/cc/trees/layer_tree_host_unittest_context.cc
@@ -894,8 +894,9 @@ TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures,
RunTest(true, true, false);
}
+// Flaky on all platforms, http://crbug.com/310979
TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures,
- LoseAfterEvict_MultiThread_DelegatingRenderer_ImplSidePaint) {
+ DISABLED_LoseAfterEvict_MultiThread_DelegatingRenderer_ImplSidePaint) {
lose_after_evict_ = true;
RunTest(true, true, true);
}
@@ -1089,7 +1090,7 @@ class LayerTreeHostContextTestDontUseLostResources
child_output_surface_ = FakeOutputSurface::Create3d();
child_output_surface_->BindToClient(&output_surface_client_);
child_resource_provider_ =
- ResourceProvider::Create(child_output_surface_.get(), 0, false);
+ ResourceProvider::Create(child_output_surface_.get(), NULL, 0, false);
}
static void EmptyReleaseCallback(unsigned sync_point, bool lost) {}
@@ -1402,13 +1403,16 @@ class LayerTreeHostContextTestCompositeAndReadbackBeforeOutputSurfaceInit
times_output_surface_created_ = 0;
+ // Post the SetNeedsCommit before the readback to make sure it is run
+ // on the main thread before the readback's replacement commit when
+ // we have a threaded compositor.
+ PostSetNeedsCommitToMainThread();
+
char pixels[4];
bool result = layer_tree_host()->CompositeAndReadback(
&pixels, gfx::Rect(1, 1));
EXPECT_EQ(!delegating_renderer(), result);
EXPECT_EQ(1, times_output_surface_created_);
-
- PostSetNeedsCommitToMainThread();
}
virtual void DidInitializeOutputSurface(bool succeeded) OVERRIDE {
@@ -1781,6 +1785,7 @@ class LayerTreeHostTestCannotCreateIfCannotCreateOutputSurface
settings.impl_side_painting = impl_side_painting;
scoped_ptr<LayerTreeHost> layer_tree_host = LayerTreeHost::Create(
this,
+ NULL,
settings,
impl_thread ? impl_thread->message_loop_proxy() : NULL);
EXPECT_FALSE(layer_tree_host);
diff --git a/cc/trees/layer_tree_host_unittest_damage.cc b/cc/trees/layer_tree_host_unittest_damage.cc
index 83831f6349..402a56a898 100644
--- a/cc/trees/layer_tree_host_unittest_damage.cc
+++ b/cc/trees/layer_tree_host_unittest_damage.cc
@@ -58,9 +58,9 @@ class LayerTreeHostDamageTestSetVisibleDoesNotDraw
// No evictions when we become not-visible.
impl->SetMemoryPolicy(ManagedMemoryPolicy(
1000 * 1000 * 1000,
- ManagedMemoryPolicy::CUTOFF_ALLOW_EVERYTHING,
+ gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING,
1000 * 1000 * 1000,
- ManagedMemoryPolicy::CUTOFF_ALLOW_EVERYTHING,
+ gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING,
ManagedMemoryPolicy::kDefaultNumResourcesLimit));
PostSetVisibleToMainThread(false);
diff --git a/cc/trees/layer_tree_host_unittest_scroll.cc b/cc/trees/layer_tree_host_unittest_scroll.cc
index ab87be1b5c..1142622529 100644
--- a/cc/trees/layer_tree_host_unittest_scroll.cc
+++ b/cc/trees/layer_tree_host_unittest_scroll.cc
@@ -172,8 +172,8 @@ class LayerTreeHostScrollTestScrollAbortedCommit
impl_scroll_(-3, 2),
second_main_scroll_(14, -3),
impl_scale_(2.f),
- num_will_begin_frames_(0),
- num_did_begin_frames_(0),
+ num_will_begin_main_frames_(0),
+ num_did_begin_main_frames_(0),
num_will_commits_(0),
num_did_commits_(0),
num_impl_commits_(0),
@@ -194,10 +194,10 @@ class LayerTreeHostScrollTestScrollAbortedCommit
layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.01f, 100.f);
}
- virtual void WillBeginFrame() OVERRIDE {
- num_will_begin_frames_++;
+ virtual void WillBeginMainFrame() OVERRIDE {
+ num_will_begin_main_frames_++;
Layer* root_scroll_layer = layer_tree_host()->root_layer()->children()[0];
- switch (num_will_begin_frames_) {
+ switch (num_will_begin_main_frames_) {
case 1:
// This will not be aborted because of the initial prop changes.
EXPECT_EQ(0, num_impl_scrolls_);
@@ -239,7 +239,7 @@ class LayerTreeHostScrollTestScrollAbortedCommit
}
}
- virtual void DidBeginFrame() OVERRIDE { num_did_begin_frames_++; }
+ virtual void DidBeginMainFrame() OVERRIDE { num_did_begin_main_frames_++; }
virtual void WillCommit() OVERRIDE { num_will_commits_++; }
@@ -317,8 +317,8 @@ class LayerTreeHostScrollTestScrollAbortedCommit
virtual 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_frames_);
- EXPECT_EQ(4, num_did_begin_frames_);
+ EXPECT_EQ(4, num_will_begin_main_frames_);
+ EXPECT_EQ(4, num_did_begin_main_frames_);
EXPECT_EQ(4, num_will_commits_);
EXPECT_EQ(4, num_did_commits_);
// ...but the compositor thread only sees two real ones.
@@ -330,8 +330,8 @@ class LayerTreeHostScrollTestScrollAbortedCommit
gfx::Vector2d impl_scroll_;
gfx::Vector2d second_main_scroll_;
float impl_scale_;
- int num_will_begin_frames_;
- int num_did_begin_frames_;
+ int num_will_begin_main_frames_;
+ int num_did_begin_main_frames_;
int num_will_commits_;
int num_did_commits_;
int num_impl_commits_;
@@ -1013,7 +1013,7 @@ TEST(LayerTreeHostFlingTest, DidStopFlingingThread) {
ASSERT_TRUE(impl_thread.message_loop_proxy().get());
scoped_ptr<LayerTreeHost> layer_tree_host = LayerTreeHost::Create(
- &client, settings, impl_thread.message_loop_proxy());
+ &client, NULL, settings, impl_thread.message_loop_proxy());
impl_thread.message_loop_proxy()
->PostTask(FROM_HERE,
diff --git a/cc/trees/layer_tree_impl.cc b/cc/trees/layer_tree_impl.cc
index 3e3d64c6d7..4604043663 100644
--- a/cc/trees/layer_tree_impl.cc
+++ b/cc/trees/layer_tree_impl.cc
@@ -271,17 +271,17 @@ void LayerTreeImpl::ApplySentScrollAndScaleDeltasFromAbortedCommit() {
root_layer(), base::Bind(&ApplySentScrollDeltasFromAbortedCommitTo));
}
-static void ApplyScrollDeltasSinceBeginFrameTo(LayerImpl* layer) {
- layer->ApplyScrollDeltasSinceBeginFrame();
+static void ApplyScrollDeltasSinceBeginMainFrameTo(LayerImpl* layer) {
+ layer->ApplyScrollDeltasSinceBeginMainFrame();
}
-void LayerTreeImpl::ApplyScrollDeltasSinceBeginFrame() {
+void LayerTreeImpl::ApplyScrollDeltasSinceBeginMainFrame() {
DCHECK(IsPendingTree());
if (!root_layer())
return;
LayerTreeHostCommon::CallFunctionForSubtree(
- root_layer(), base::Bind(&ApplyScrollDeltasSinceBeginFrameTo));
+ root_layer(), base::Bind(&ApplyScrollDeltasSinceBeginMainFrameTo));
}
void LayerTreeImpl::SetViewportLayersFromIds(
@@ -710,6 +710,10 @@ ResourceProvider::ResourceId LayerTreeImpl::ResourceIdForUIResource(
return layer_tree_host_impl_->ResourceIdForUIResource(uid);
}
+bool LayerTreeImpl::IsUIResourceOpaque(UIResourceId uid) const {
+ return layer_tree_host_impl_->IsUIResourceOpaque(uid);
+}
+
void LayerTreeImpl::ProcessUIResourceRequestQueue() {
while (ui_resource_request_queue_.size() > 0) {
UIResourceRequest req = ui_resource_request_queue_.front();
diff --git a/cc/trees/layer_tree_impl.h b/cc/trees/layer_tree_impl.h
index faf360f6fc..1b40b926fa 100644
--- a/cc/trees/layer_tree_impl.h
+++ b/cc/trees/layer_tree_impl.h
@@ -123,7 +123,7 @@ class CC_EXPORT LayerTreeImpl {
int outer_viewport_scroll_layer_id);
void ClearViewportLayers();
void ApplySentScrollAndScaleDeltasFromAbortedCommit();
- void ApplyScrollDeltasSinceBeginFrame();
+ void ApplyScrollDeltasSinceBeginMainFrame();
SkColor background_color() const { return background_color_; }
void set_background_color(SkColor color) { background_color_ = color; }
@@ -212,6 +212,8 @@ class CC_EXPORT LayerTreeImpl {
ResourceProvider::ResourceId ResourceIdForUIResource(UIResourceId uid) const;
void ProcessUIResourceRequestQueue();
+ bool IsUIResourceOpaque(UIResourceId uid) const;
+
void AddLayerWithCopyOutputRequest(LayerImpl* layer);
void RemoveLayerWithCopyOutputRequest(LayerImpl* layer);
const std::vector<LayerImpl*> LayersWithCopyOutputRequest() const;
diff --git a/cc/trees/layer_tree_settings.cc b/cc/trees/layer_tree_settings.cc
index b7aafbb2d7..eb0f2f3493 100644
--- a/cc/trees/layer_tree_settings.cc
+++ b/cc/trees/layer_tree_settings.cc
@@ -16,8 +16,8 @@ LayerTreeSettings::LayerTreeSettings()
: impl_side_painting(false),
allow_antialiasing(true),
throttle_frame_production(true),
- begin_frame_scheduling_enabled(false),
- deadline_scheduling_enabled(false),
+ begin_impl_frame_scheduling_enabled(false),
+ deadline_scheduling_enabled(true),
using_synchronous_renderer_compositor(false),
per_tile_painting_enabled(false),
partial_swap_enabled(false),
diff --git a/cc/trees/layer_tree_settings.h b/cc/trees/layer_tree_settings.h
index ca063b82d5..fafeb4db87 100644
--- a/cc/trees/layer_tree_settings.h
+++ b/cc/trees/layer_tree_settings.h
@@ -21,7 +21,7 @@ class CC_EXPORT LayerTreeSettings {
bool impl_side_painting;
bool allow_antialiasing;
bool throttle_frame_production;
- bool begin_frame_scheduling_enabled;
+ bool begin_impl_frame_scheduling_enabled;
bool deadline_scheduling_enabled;
bool using_synchronous_renderer_compositor;
bool per_tile_painting_enabled;
diff --git a/cc/trees/occlusion_tracker.cc b/cc/trees/occlusion_tracker.cc
index 2bd9b552e8..8f98c279a4 100644
--- a/cc/trees/occlusion_tracker.cc
+++ b/cc/trees/occlusion_tracker.cc
@@ -272,12 +272,6 @@ static void ReduceOcclusionBelowSurface(LayerType* contributing_layer,
// to expand outside the clip.
affected_area_in_target.Inset(
-outset_left, -outset_top, -outset_right, -outset_bottom);
-
- gfx::Rect FilterOutsetsInTarget(-outset_left,
- -outset_top,
- outset_left + outset_right,
- outset_top + outset_bottom);
-
Region affected_occlusion = IntersectRegions(*occlusion_from_inside_target,
affected_area_in_target);
Region::Iterator affected_occlusion_rects(affected_occlusion);
diff --git a/cc/trees/proxy.h b/cc/trees/proxy.h
index 84844c8949..69975a6dd7 100644
--- a/cc/trees/proxy.h
+++ b/cc/trees/proxy.h
@@ -81,6 +81,7 @@ class CC_EXPORT Proxy {
virtual void MainThreadHasStoppedFlinging() = 0;
virtual bool CommitRequested() const = 0;
+ virtual bool BeginMainFrameRequested() const = 0;
// Must be called before using the proxy.
virtual void Start(scoped_ptr<OutputSurface> first_output_surface) = 0;
diff --git a/cc/trees/single_thread_proxy.cc b/cc/trees/single_thread_proxy.cc
index 634c3bc8b3..9de0fdd8d8 100644
--- a/cc/trees/single_thread_proxy.cc
+++ b/cc/trees/single_thread_proxy.cc
@@ -15,6 +15,7 @@
#include "cc/trees/blocking_task_runner.h"
#include "cc/trees/layer_tree_host.h"
#include "cc/trees/layer_tree_impl.h"
+#include "ui/gfx/frame_time.h"
namespace cc {
@@ -59,7 +60,7 @@ bool SingleThreadProxy::CompositeAndReadback(void* pixels, gfx::Rect rect) {
gfx::Rect device_viewport_damage_rect = rect;
LayerTreeHostImpl::FrameData frame;
- if (!CommitAndComposite(base::TimeTicks::Now(),
+ if (!CommitAndComposite(gfx::FrameTime::Now(),
device_viewport_damage_rect,
true, // for_readback
&frame))
@@ -254,6 +255,8 @@ void SingleThreadProxy::SetDeferCommits(bool defer_commits) {
bool SingleThreadProxy::CommitRequested() const { return false; }
+bool SingleThreadProxy::BeginMainFrameRequested() const { return false; }
+
size_t SingleThreadProxy::MaxPartialTextureUpdates() const {
return std::numeric_limits<size_t>::max();
}
@@ -329,11 +332,6 @@ bool SingleThreadProxy::ReduceContentsTextureMemoryOnImplThread(
limit_bytes, priority_cutoff, layer_tree_host_impl_->resource_provider());
}
-void SingleThreadProxy::ReduceWastedContentsTextureMemoryOnImplThread() {
- // Impl-side painting only.
- NOTREACHED();
-}
-
void SingleThreadProxy::SendManagedMemoryStats() {
DCHECK(Proxy::IsImplThread());
if (!layer_tree_host_impl_)
@@ -455,7 +453,7 @@ bool SingleThreadProxy::CommitAndComposite(
device_viewport_damage_rect,
for_readback,
frame);
- layer_tree_host_->DidBeginFrame();
+ layer_tree_host_->DidBeginMainFrame();
return result;
}
diff --git a/cc/trees/single_thread_proxy.h b/cc/trees/single_thread_proxy.h
index 474fb1f110..843be729c4 100644
--- a/cc/trees/single_thread_proxy.h
+++ b/cc/trees/single_thread_proxy.h
@@ -39,6 +39,7 @@ class SingleThreadProxy : public Proxy, LayerTreeHostImplClient {
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(scoped_ptr<OutputSurface> first_output_surface) OVERRIDE;
virtual void Stop() OVERRIDE;
@@ -51,7 +52,7 @@ class SingleThreadProxy : public Proxy, LayerTreeHostImplClient {
// LayerTreeHostImplClient implementation
virtual void DidLoseOutputSurfaceOnImplThread() OVERRIDE;
virtual void OnSwapBuffersCompleteOnImplThread() OVERRIDE {}
- virtual void BeginFrameOnImplThread(const BeginFrameArgs& args)
+ virtual void BeginImplFrame(const BeginFrameArgs& args)
OVERRIDE {}
virtual void OnCanDrawStateChanged(bool can_draw) OVERRIDE;
virtual void NotifyReadyToActivate() OVERRIDE;
@@ -66,7 +67,6 @@ class SingleThreadProxy : public Proxy, LayerTreeHostImplClient {
virtual bool ReduceContentsTextureMemoryOnImplThread(
size_t limit_bytes,
int priority_cutoff) OVERRIDE;
- virtual void ReduceWastedContentsTextureMemoryOnImplThread() OVERRIDE;
virtual void SendManagedMemoryStats() OVERRIDE;
virtual bool IsInsideDraw() OVERRIDE;
virtual void RenewTreePriority() OVERRIDE {}
diff --git a/cc/trees/thread_proxy.cc b/cc/trees/thread_proxy.cc
index e57def2c13..4f2f488eae 100644
--- a/cc/trees/thread_proxy.cc
+++ b/cc/trees/thread_proxy.cc
@@ -22,6 +22,7 @@
#include "cc/trees/blocking_task_runner.h"
#include "cc/trees/layer_tree_host.h"
#include "cc/trees/layer_tree_impl.h"
+#include "ui/gfx/frame_time.h"
// Measured in seconds.
const double kSmoothnessTakesPriorityExpirationDelay = 0.25;
@@ -72,7 +73,7 @@ ThreadProxy::ThreadProxy(
manage_tiles_pending_(false),
commit_waits_for_activation_(false),
inside_commit_(false),
- begin_frame_sent_to_main_thread_completion_event_on_impl_thread_(NULL),
+ begin_main_frame_sent_completion_event_on_impl_thread_(NULL),
readback_request_on_impl_thread_(NULL),
commit_completion_event_on_impl_thread_(NULL),
completion_event_for_commit_held_on_tree_activation_(NULL),
@@ -80,8 +81,8 @@ ThreadProxy::ThreadProxy(
next_frame_is_newly_committed_frame_on_impl_thread_(false),
throttle_frame_production_(
layer_tree_host->settings().throttle_frame_production),
- begin_frame_scheduling_enabled_(
- layer_tree_host->settings().begin_frame_scheduling_enabled),
+ begin_impl_frame_scheduling_enabled_(
+ layer_tree_host->settings().begin_impl_frame_scheduling_enabled),
using_synchronous_renderer_compositor_(
layer_tree_host->settings().using_synchronous_renderer_compositor),
inside_draw_(false),
@@ -90,7 +91,7 @@ ThreadProxy::ThreadProxy(
input_throttled_until_commit_(false),
renew_tree_priority_on_impl_thread_pending_(false),
draw_duration_history_(kDurationHistorySize),
- begin_frame_to_commit_duration_history_(kDurationHistorySize),
+ begin_main_frame_to_commit_duration_history_(kDurationHistorySize),
commit_to_activate_duration_history_(kDurationHistorySize),
weak_factory_on_impl_thread_(this),
weak_factory_(this) {
@@ -126,22 +127,22 @@ bool ThreadProxy::CompositeAndReadback(void* pixels, gfx::Rect rect) {
request.pixels = pixels;
{
DebugScopedSetMainThreadBlocked main_thread_blocked(this);
- CompletionEvent begin_frame_sent_to_main_thread_completion;
+ CompletionEvent begin_main_frame_sent_completion;
Proxy::ImplThreadTaskRunner()
->PostTask(FROM_HERE,
base::Bind(&ThreadProxy::ForceCommitForReadbackOnImplThread,
impl_thread_weak_ptr_,
- &begin_frame_sent_to_main_thread_completion,
+ &begin_main_frame_sent_completion,
&request));
- begin_frame_sent_to_main_thread_completion.Wait();
+ begin_main_frame_sent_completion.Wait();
}
in_composite_and_readback_ = true;
// This is the forced commit.
- // Note: The Impl thread also queues a separate BeginFrameOnMainThread on the
+ // Note: The Impl thread also queues a separate BeginMainFrame on the
// main thread, which will be called after this CompositeAndReadback
// completes, to replace the forced commit.
- BeginFrameOnMainThread(scoped_ptr<BeginFrameAndCommitState>());
+ BeginMainFrame(scoped_ptr<BeginMainFrameAndCommitState>());
in_composite_and_readback_ = false;
// Composite and readback requires a second commit to undo any changes
@@ -153,15 +154,15 @@ bool ThreadProxy::CompositeAndReadback(void* pixels, gfx::Rect rect) {
}
void ThreadProxy::ForceCommitForReadbackOnImplThread(
- CompletionEvent* begin_frame_sent_completion,
+ CompletionEvent* begin_main_frame_sent_completion,
ReadbackRequest* request) {
TRACE_EVENT0("cc", "ThreadProxy::ForceCommitForReadbackOnImplThread");
DCHECK(IsImplThread());
- DCHECK(!begin_frame_sent_to_main_thread_completion_event_on_impl_thread_);
+ DCHECK(!begin_main_frame_sent_completion_event_on_impl_thread_);
DCHECK(!readback_request_on_impl_thread_);
if (!layer_tree_host_impl_) {
- begin_frame_sent_completion->Signal();
+ begin_main_frame_sent_completion->Signal();
request->success = false;
request->completion.Signal();
return;
@@ -171,12 +172,12 @@ void ThreadProxy::ForceCommitForReadbackOnImplThread(
scheduler_on_impl_thread_->SetNeedsForcedCommitForReadback();
if (scheduler_on_impl_thread_->CommitPending()) {
- begin_frame_sent_completion->Signal();
+ begin_main_frame_sent_completion->Signal();
return;
}
- begin_frame_sent_to_main_thread_completion_event_on_impl_thread_ =
- begin_frame_sent_completion;
+ begin_main_frame_sent_completion_event_on_impl_thread_ =
+ begin_main_frame_sent_completion;
}
void ThreadProxy::FinishAllRendering() {
@@ -342,6 +343,11 @@ void ThreadProxy::SetNeedsAnimate() {
void ThreadProxy::SetNeedsUpdateLayers() {
DCHECK(IsMainThread());
+
+ if (commit_request_sent_to_impl_thread_)
+ return;
+ TRACE_EVENT0("cc", "ThreadProxy::SetNeedsUpdateLayers");
+
SendCommitRequestToImplThreadIfNeeded();
}
@@ -387,13 +393,13 @@ void ThreadProxy::SetNeedsBeginImplFrame(bool enable) {
DCHECK(IsImplThread());
TRACE_EVENT1("cc", "ThreadProxy::SetNeedsBeginImplFrame",
"enable", enable);
- layer_tree_host_impl_->SetNeedsBeginFrame(enable);
+ layer_tree_host_impl_->SetNeedsBeginImplFrame(enable);
UpdateBackgroundAnimateTicking();
}
-void ThreadProxy::BeginFrameOnImplThread(const BeginFrameArgs& args) {
+void ThreadProxy::BeginImplFrame(const BeginFrameArgs& args) {
DCHECK(IsImplThread());
- TRACE_EVENT0("cc", "ThreadProxy::BeginFrameOnImplThread");
+ TRACE_EVENT0("cc", "ThreadProxy::BeginImplFrame");
// Sample the frame time now. This time will be used for updating animations
// when we draw.
@@ -460,16 +466,6 @@ bool ThreadProxy::ReduceContentsTextureMemoryOnImplThread(size_t limit_bytes,
return true;
}
-void ThreadProxy::ReduceWastedContentsTextureMemoryOnImplThread() {
- DCHECK(IsImplThread());
-
- if (!layer_tree_host_->contents_texture_manager())
- return;
-
- layer_tree_host_->contents_texture_manager()->ReduceWastedMemoryOnImplThread(
- layer_tree_host_impl_->resource_provider());
-}
-
void ThreadProxy::SendManagedMemoryStats() {
DCHECK(IsImplThread());
if (!layer_tree_host_impl_)
@@ -521,7 +517,7 @@ void ThreadProxy::SetDeferCommits(bool defer_commits) {
if (!defer_commits_ && pending_deferred_commit_)
Proxy::MainThreadTaskRunner()->PostTask(
FROM_HERE,
- base::Bind(&ThreadProxy::BeginFrameOnMainThread,
+ base::Bind(&ThreadProxy::BeginMainFrame,
main_thread_weak_ptr_,
base::Passed(&pending_deferred_commit_)));
}
@@ -531,6 +527,11 @@ bool ThreadProxy::CommitRequested() const {
return commit_requested_;
}
+bool ThreadProxy::BeginMainFrameRequested() const {
+ DCHECK(IsMainThread());
+ return commit_request_sent_to_impl_thread_;
+}
+
void ThreadProxy::SetNeedsRedrawOnImplThread() {
DCHECK(IsImplThread());
TRACE_EVENT0("cc", "ThreadProxy::SetNeedsRedrawOnImplThread");
@@ -685,52 +686,52 @@ void ThreadProxy::FinishAllRenderingOnImplThread(CompletionEvent* completion) {
void ThreadProxy::ScheduledActionSendBeginMainFrame() {
TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionSendBeginMainFrame");
- scoped_ptr<BeginFrameAndCommitState> begin_frame_state(
- new BeginFrameAndCommitState);
- begin_frame_state->monotonic_frame_begin_time =
+ scoped_ptr<BeginMainFrameAndCommitState> begin_main_frame_state(
+ new BeginMainFrameAndCommitState);
+ begin_main_frame_state->monotonic_frame_begin_time =
layer_tree_host_impl_->CurrentPhysicalTimeTicks();
- begin_frame_state->scroll_info =
+ begin_main_frame_state->scroll_info =
layer_tree_host_impl_->ProcessScrollDeltas();
if (!layer_tree_host_impl_->settings().impl_side_painting) {
DCHECK_GT(layer_tree_host_impl_->memory_allocation_limit_bytes(), 0u);
}
- begin_frame_state->memory_allocation_limit_bytes =
+ begin_main_frame_state->memory_allocation_limit_bytes =
layer_tree_host_impl_->memory_allocation_limit_bytes();
- begin_frame_state->memory_allocation_priority_cutoff =
+ begin_main_frame_state->memory_allocation_priority_cutoff =
layer_tree_host_impl_->memory_allocation_priority_cutoff();
- begin_frame_state->evicted_ui_resources =
+ begin_main_frame_state->evicted_ui_resources =
layer_tree_host_impl_->EvictedUIResourcesExist();
Proxy::MainThreadTaskRunner()->PostTask(
FROM_HERE,
- base::Bind(&ThreadProxy::BeginFrameOnMainThread,
+ base::Bind(&ThreadProxy::BeginMainFrame,
main_thread_weak_ptr_,
- base::Passed(&begin_frame_state)));
+ base::Passed(&begin_main_frame_state)));
- if (begin_frame_sent_to_main_thread_completion_event_on_impl_thread_) {
- begin_frame_sent_to_main_thread_completion_event_on_impl_thread_->Signal();
- begin_frame_sent_to_main_thread_completion_event_on_impl_thread_ = NULL;
+ if (begin_main_frame_sent_completion_event_on_impl_thread_) {
+ begin_main_frame_sent_completion_event_on_impl_thread_->Signal();
+ begin_main_frame_sent_completion_event_on_impl_thread_ = NULL;
}
- begin_frame_sent_to_main_thread_time_ = base::TimeTicks::HighResNow();
+ begin_main_frame_sent_time_ = base::TimeTicks::HighResNow();
}
-void ThreadProxy::BeginFrameOnMainThread(
- scoped_ptr<BeginFrameAndCommitState> begin_frame_state) {
- TRACE_EVENT0("cc", "ThreadProxy::BeginFrameOnMainThread");
+void ThreadProxy::BeginMainFrame(
+ scoped_ptr<BeginMainFrameAndCommitState> begin_main_frame_state) {
+ TRACE_EVENT0("cc", "ThreadProxy::BeginMainFrame");
DCHECK(IsMainThread());
if (!layer_tree_host_)
return;
if (defer_commits_) {
- pending_deferred_commit_ = begin_frame_state.Pass();
+ pending_deferred_commit_ = begin_main_frame_state.Pass();
layer_tree_host_->DidDeferCommit();
TRACE_EVENT0("cc", "EarlyOut_DeferCommits");
return;
}
// Do not notify the impl thread of commit requests that occur during
- // the apply/animate/layout part of the BeginFrameAndCommit process since
+ // the apply/animate/layout part of the BeginMainFrameAndCommit process since
// those commit requests will get painted immediately. Once we have done
// the paint, commit_requested_ will be set to false to allow new commit
// requests to be scheduled.
@@ -750,22 +751,22 @@ void ThreadProxy::BeginFrameOnMainThread(
bool did_handle = false;
Proxy::ImplThreadTaskRunner()->PostTask(
FROM_HERE,
- base::Bind(&ThreadProxy::BeginFrameAbortedByMainThreadOnImplThread,
+ base::Bind(&ThreadProxy::BeginMainFrameAbortedOnImplThread,
impl_thread_weak_ptr_,
did_handle));
return;
}
- if (begin_frame_state)
- layer_tree_host_->ApplyScrollAndScale(*begin_frame_state->scroll_info);
+ if (begin_main_frame_state)
+ layer_tree_host_->ApplyScrollAndScale(*begin_main_frame_state->scroll_info);
- layer_tree_host_->WillBeginFrame();
+ layer_tree_host_->WillBeginMainFrame();
- if (begin_frame_state) {
+ if (begin_main_frame_state) {
layer_tree_host_->UpdateClientAnimations(
- begin_frame_state->monotonic_frame_begin_time);
+ begin_main_frame_state->monotonic_frame_begin_time);
layer_tree_host_->AnimateLayers(
- begin_frame_state->monotonic_frame_begin_time);
+ begin_main_frame_state->monotonic_frame_begin_time);
}
// Unlink any backings that the impl thread has evicted, so that we know to
@@ -774,18 +775,19 @@ void ThreadProxy::BeginFrameOnMainThread(
layer_tree_host_->contents_texture_manager()->
UnlinkAndClearEvictedBackings();
- if (begin_frame_state) {
+ if (begin_main_frame_state) {
layer_tree_host_->contents_texture_manager()->SetMaxMemoryLimitBytes(
- begin_frame_state->memory_allocation_limit_bytes);
+ begin_main_frame_state->memory_allocation_limit_bytes);
layer_tree_host_->contents_texture_manager()->SetExternalPriorityCutoff(
- begin_frame_state->memory_allocation_priority_cutoff);
+ begin_main_frame_state->memory_allocation_priority_cutoff);
}
}
// Recreate all UI resources if there were evicted UI resources when the impl
// thread initiated the commit.
- bool evicted_ui_resources =
- begin_frame_state ? begin_frame_state->evicted_ui_resources : false;
+ bool evicted_ui_resources = begin_main_frame_state
+ ? begin_main_frame_state->evicted_ui_resources
+ : false;
if (evicted_ui_resources)
layer_tree_host_->RecreateUIResources();
@@ -818,7 +820,7 @@ void ThreadProxy::BeginFrameOnMainThread(
bool did_handle = true;
Proxy::ImplThreadTaskRunner()->PostTask(
FROM_HERE,
- base::Bind(&ThreadProxy::BeginFrameAbortedByMainThreadOnImplThread,
+ base::Bind(&ThreadProxy::BeginMainFrameAbortedOnImplThread,
impl_thread_weak_ptr_,
did_handle));
@@ -826,7 +828,7 @@ void ThreadProxy::BeginFrameOnMainThread(
// detected to be a no-op. From the perspective of an embedder, this commit
// went through, and input should no longer be throttled, etc.
layer_tree_host_->CommitComplete();
- layer_tree_host_->DidBeginFrame();
+ layer_tree_host_->DidBeginMainFrame();
return;
}
@@ -854,7 +856,7 @@ void ThreadProxy::BeginFrameOnMainThread(
// point of view, but asynchronously performed on the impl thread,
// coordinated by the Scheduler.
{
- TRACE_EVENT0("cc", "ThreadProxy::BeginFrameOnMainThread::commit");
+ TRACE_EVENT0("cc", "ThreadProxy::BeginMainFrame::commit");
DebugScopedSetMainThreadBlocked main_thread_blocked(this);
@@ -881,7 +883,7 @@ void ThreadProxy::BeginFrameOnMainThread(
}
layer_tree_host_->CommitComplete();
- layer_tree_host_->DidBeginFrame();
+ layer_tree_host_->DidBeginMainFrame();
}
void ThreadProxy::StartCommitOnImplThread(
@@ -933,8 +935,8 @@ void ThreadProxy::StartCommitOnImplThread(
scheduler_on_impl_thread_->AnticipatedDrawTime());
}
-void ThreadProxy::BeginFrameAbortedByMainThreadOnImplThread(bool did_handle) {
- TRACE_EVENT0("cc", "ThreadProxy::BeginFrameAbortedByMainThreadOnImplThread");
+void ThreadProxy::BeginMainFrameAbortedOnImplThread(bool did_handle) {
+ TRACE_EVENT0("cc", "ThreadProxy::BeginMainFrameAbortedOnImplThread");
DCHECK(IsImplThread());
DCHECK(scheduler_on_impl_thread_);
DCHECK(scheduler_on_impl_thread_->CommitPending());
@@ -992,8 +994,8 @@ void ThreadProxy::ScheduledActionCommit() {
commit_waits_for_activation_ = false;
commit_complete_time_ = base::TimeTicks::HighResNow();
- begin_frame_to_commit_duration_history_.InsertSample(
- commit_complete_time_ - begin_frame_sent_to_main_thread_time_);
+ begin_main_frame_to_commit_duration_history_.InsertSample(
+ commit_complete_time_ - begin_main_frame_sent_time_);
// SetVisible kicks off the next scheduler action, so this must be last.
scheduler_on_impl_thread_->SetVisible(layer_tree_host_impl_->visible());
@@ -1243,7 +1245,7 @@ base::TimeDelta ThreadProxy::DrawDurationEstimate() {
}
base::TimeDelta ThreadProxy::BeginMainFrameToCommitDurationEstimate() {
- return begin_frame_to_commit_duration_history_.Percentile(
+ return begin_main_frame_to_commit_duration_history_.Percentile(
kCommitAndActivationDurationEstimationPercentile);
}
@@ -1254,7 +1256,7 @@ base::TimeDelta ThreadProxy::CommitToActivateDurationEstimate() {
void ThreadProxy::PostBeginImplFrameDeadline(const base::Closure& closure,
base::TimeTicks deadline) {
- base::TimeDelta delta = deadline - base::TimeTicks::Now();
+ base::TimeDelta delta = deadline - gfx::FrameTime::Now();
if (delta <= base::TimeDelta())
delta = base::TimeDelta();
Proxy::ImplThreadTaskRunner()->PostDelayedTask(FROM_HERE, closure, delta);
@@ -1398,7 +1400,7 @@ void ThreadProxy::LayerTreeHostClosedOnImplThread(CompletionEvent* completion) {
layer_tree_host_->DeleteContentsTexturesOnImplThread(
layer_tree_host_impl_->resource_provider());
current_resource_update_controller_on_impl_thread_.reset();
- layer_tree_host_impl_->SetNeedsBeginFrame(false);
+ layer_tree_host_impl_->SetNeedsBeginImplFrame(false);
scheduler_on_impl_thread_.reset();
layer_tree_host_impl_.reset();
weak_factory_on_impl_thread_.InvalidateWeakPtrs();
@@ -1409,12 +1411,12 @@ size_t ThreadProxy::MaxPartialTextureUpdates() const {
return ResourceUpdateController::MaxPartialTextureUpdates();
}
-ThreadProxy::BeginFrameAndCommitState::BeginFrameAndCommitState()
+ThreadProxy::BeginMainFrameAndCommitState::BeginMainFrameAndCommitState()
: memory_allocation_limit_bytes(0),
memory_allocation_priority_cutoff(0),
evicted_ui_resources(false) {}
-ThreadProxy::BeginFrameAndCommitState::~BeginFrameAndCommitState() {}
+ThreadProxy::BeginMainFrameAndCommitState::~BeginMainFrameAndCommitState() {}
scoped_ptr<base::Value> ThreadProxy::AsValue() const {
scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue());
@@ -1522,6 +1524,8 @@ void ThreadProxy::RenewTreePriority() {
priority = NEW_CONTENT_TAKES_PRIORITY;
layer_tree_host_impl_->SetTreePriority(priority);
+ scheduler_on_impl_thread_->SetSmoothnessTakesPriority(
+ priority == SMOOTHNESS_TAKES_PRIORITY);
// Notify the the client of this compositor via the output surface.
// TODO(epenner): Route this to compositor-thread instead of output-surface
diff --git a/cc/trees/thread_proxy.h b/cc/trees/thread_proxy.h
index 6badb03d00..3a213b90cd 100644
--- a/cc/trees/thread_proxy.h
+++ b/cc/trees/thread_proxy.h
@@ -56,6 +56,7 @@ class ThreadProxy : public Proxy,
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(scoped_ptr<OutputSurface> first_output_surface) OVERRIDE;
virtual void Stop() OVERRIDE;
@@ -69,7 +70,7 @@ class ThreadProxy : public Proxy,
// LayerTreeHostImplClient implementation
virtual void DidLoseOutputSurfaceOnImplThread() OVERRIDE;
virtual void OnSwapBuffersCompleteOnImplThread() OVERRIDE;
- virtual void BeginFrameOnImplThread(const BeginFrameArgs& args) OVERRIDE;
+ virtual void BeginImplFrame(const BeginFrameArgs& args) OVERRIDE;
virtual void OnCanDrawStateChanged(bool can_draw) OVERRIDE;
virtual void NotifyReadyToActivate() OVERRIDE;
virtual void SetNeedsRedrawOnImplThread() OVERRIDE;
@@ -83,7 +84,6 @@ class ThreadProxy : public Proxy,
virtual bool ReduceContentsTextureMemoryOnImplThread(size_t limit_bytes,
int priority_cutoff)
OVERRIDE;
- virtual void ReduceWastedContentsTextureMemoryOnImplThread() OVERRIDE;
virtual void SendManagedMemoryStats() OVERRIDE;
virtual bool IsInsideDraw() OVERRIDE;
virtual void RenewTreePriority() OVERRIDE;
@@ -119,9 +119,9 @@ class ThreadProxy : public Proxy,
ThreadProxy(LayerTreeHost* layer_tree_host,
scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner);
- struct BeginFrameAndCommitState {
- BeginFrameAndCommitState();
- ~BeginFrameAndCommitState();
+ struct BeginMainFrameAndCommitState {
+ BeginMainFrameAndCommitState();
+ ~BeginMainFrameAndCommitState();
base::TimeTicks monotonic_frame_begin_time;
scoped_ptr<ScrollAndScaleSet> scroll_info;
@@ -131,8 +131,8 @@ class ThreadProxy : public Proxy,
};
// Called on main thread.
- void BeginFrameOnMainThread(
- scoped_ptr<BeginFrameAndCommitState> begin_frame_state);
+ void BeginMainFrame(
+ scoped_ptr<BeginMainFrameAndCommitState> begin_main_frame_state);
void DidCommitAndDrawFrame();
void DidCompleteSwapBuffers();
void SetAnimationEvents(scoped_ptr<AnimationEventsVector> queue,
@@ -150,13 +150,13 @@ class ThreadProxy : public Proxy,
struct SchedulerStateRequest;
void ForceCommitForReadbackOnImplThread(
- CompletionEvent* begin_frame_sent_completion,
+ CompletionEvent* begin_main_frame_sent_completion,
ReadbackRequest* request);
void StartCommitOnImplThread(
CompletionEvent* completion,
ResourceUpdateQueue* queue,
scoped_refptr<cc::ContextProvider> offscreen_context_provider);
- void BeginFrameAbortedByMainThreadOnImplThread(bool did_handle);
+ void BeginMainFrameAbortedOnImplThread(bool did_handle);
void RequestReadbackOnImplThread(ReadbackRequest* request);
void FinishAllRenderingOnImplThread(CompletionEvent* completion);
void InitializeImplOnImplThread(CompletionEvent* completion);
@@ -198,9 +198,9 @@ class ThreadProxy : public Proxy,
bool animate_requested_;
// Set only when SetNeedsCommit is called.
bool commit_requested_;
- // Set by SetNeedsCommit and SetNeedsAnimate.
+ // Set by SetNeedsAnimate, SetNeedsUpdateLayers, and SetNeedsCommit.
bool commit_request_sent_to_impl_thread_;
- // Set by BeginFrameOnMainThread
+ // Set by BeginMainFrame
bool created_offscreen_context_provider_;
base::CancelableClosure output_surface_creation_callback_;
LayerTreeHost* layer_tree_host_;
@@ -226,7 +226,7 @@ class ThreadProxy : public Proxy,
// Set when the main thread is waiting on a
// ScheduledActionSendBeginMainFrame to be issued.
CompletionEvent*
- begin_frame_sent_to_main_thread_completion_event_on_impl_thread_;
+ begin_main_frame_sent_completion_event_on_impl_thread_;
// Set when the main thread is waiting on a readback.
ReadbackRequest* readback_request_on_impl_thread_;
@@ -248,7 +248,7 @@ class ThreadProxy : public Proxy,
bool next_frame_is_newly_committed_frame_on_impl_thread_;
bool throttle_frame_production_;
- bool begin_frame_scheduling_enabled_;
+ bool begin_impl_frame_scheduling_enabled_;
bool using_synchronous_renderer_compositor_;
bool inside_draw_;
@@ -257,19 +257,19 @@ class ThreadProxy : public Proxy,
bool defer_commits_;
bool input_throttled_until_commit_;
- scoped_ptr<BeginFrameAndCommitState> pending_deferred_commit_;
+ scoped_ptr<BeginMainFrameAndCommitState> pending_deferred_commit_;
base::TimeTicks smoothness_takes_priority_expiration_time_;
bool renew_tree_priority_on_impl_thread_pending_;
RollingTimeDeltaHistory draw_duration_history_;
- RollingTimeDeltaHistory begin_frame_to_commit_duration_history_;
+ RollingTimeDeltaHistory begin_main_frame_to_commit_duration_history_;
RollingTimeDeltaHistory commit_to_activate_duration_history_;
// Used for computing samples added to
- // begin_frame_to_commit_draw_duration_history_ and
+ // begin_main_frame_to_commit_duration_history_ and
// activation_duration_history_.
- base::TimeTicks begin_frame_sent_to_main_thread_time_;
+ base::TimeTicks begin_main_frame_sent_time_;
base::TimeTicks commit_complete_time_;
base::WeakPtr<ThreadProxy> main_thread_weak_ptr_;
diff --git a/cc/trees/tree_synchronizer_unittest.cc b/cc/trees/tree_synchronizer_unittest.cc
index 4e0c89fca5..3910bc051c 100644
--- a/cc/trees/tree_synchronizer_unittest.cc
+++ b/cc/trees/tree_synchronizer_unittest.cc
@@ -552,11 +552,8 @@ TEST_F(TreeSynchronizerTest, SynchronizeAnimations) {
FakeProxy proxy;
DebugScopedSetImplThread impl(&proxy);
FakeRenderingStatsInstrumentation stats_instrumentation;
- scoped_ptr<LayerTreeHostImpl> host_impl =
- LayerTreeHostImpl::Create(settings,
- NULL,
- &proxy,
- &stats_instrumentation);
+ scoped_ptr<LayerTreeHostImpl> host_impl = LayerTreeHostImpl::Create(
+ settings, NULL, &proxy, &stats_instrumentation, NULL);
scoped_refptr<Layer> layer_tree_root = Layer::Create();
host_->SetRootLayer(layer_tree_root);
@@ -587,11 +584,8 @@ TEST_F(TreeSynchronizerTest, SynchronizeScrollParent) {
FakeProxy proxy;
DebugScopedSetImplThread impl(&proxy);
FakeRenderingStatsInstrumentation stats_instrumentation;
- scoped_ptr<LayerTreeHostImpl> host_impl =
- LayerTreeHostImpl::Create(settings,
- NULL,
- &proxy,
- &stats_instrumentation);
+ scoped_ptr<LayerTreeHostImpl> host_impl = LayerTreeHostImpl::Create(
+ settings, NULL, &proxy, &stats_instrumentation, NULL);
scoped_refptr<Layer> layer_tree_root = Layer::Create();
scoped_refptr<Layer> scroll_parent = Layer::Create();
@@ -665,11 +659,8 @@ TEST_F(TreeSynchronizerTest, SynchronizeClipParent) {
FakeProxy proxy;
DebugScopedSetImplThread impl(&proxy);
FakeRenderingStatsInstrumentation stats_instrumentation;
- scoped_ptr<LayerTreeHostImpl> host_impl =
- LayerTreeHostImpl::Create(settings,
- NULL,
- &proxy,
- &stats_instrumentation);
+ scoped_ptr<LayerTreeHostImpl> host_impl = LayerTreeHostImpl::Create(
+ settings, NULL, &proxy, &stats_instrumentation, NULL);
scoped_refptr<Layer> layer_tree_root = Layer::Create();
scoped_refptr<Layer> clip_parent = Layer::Create();