diff options
author | Ben Murdoch <benm@google.com> | 2013-08-12 14:20:17 +0100 |
---|---|---|
committer | Ben Murdoch <benm@google.com> | 2013-08-12 14:20:17 +0100 |
commit | ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16 (patch) | |
tree | aa3b1013e823cb7bdee9ece936928292f57b31f4 /cc | |
parent | f7fa989080f1e63c6a8aa24d5434922d52d9f51e (diff) | |
download | chromium_org-ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16.tar.gz |
Merge from Chromium at DEPS revision r216972
This commit was generated by merge_to_master.py.
Change-Id: I01cb28d94e3fcf99e3624d75cafa50d929787ddd
Diffstat (limited to 'cc')
58 files changed, 800 insertions, 148 deletions
diff --git a/cc/base/math_util.cc b/cc/base/math_util.cc index 39a183e27d..fa7b21a8c2 100644 --- a/cc/base/math_util.cc +++ b/cc/base/math_util.cc @@ -487,6 +487,13 @@ scoped_ptr<base::Value> MathUtil::AsValue(gfx::Size s) { return res.PassAs<base::Value>(); } +scoped_ptr<base::Value> MathUtil::AsValue(gfx::SizeF s) { + scoped_ptr<base::DictionaryValue> res(new base::DictionaryValue()); + res->SetDouble("width", s.width()); + res->SetDouble("height", s.height()); + return res.PassAs<base::Value>(); +} + scoped_ptr<base::Value> MathUtil::AsValue(gfx::Rect r) { scoped_ptr<base::ListValue> res(new base::ListValue()); res->AppendInteger(r.x()); @@ -546,6 +553,16 @@ scoped_ptr<base::Value> MathUtil::AsValue(const gfx::RectF& rect) { return res.PassAs<base::Value>(); } +scoped_ptr<base::Value> MathUtil::AsValue(const gfx::Transform& transform) { + scoped_ptr<base::ListValue> res(new base::ListValue()); + const SkMatrix44& m = transform.matrix(); + for (int row = 0; row < 4; ++row) { + for (int col = 0; col < 4; ++col) + res->AppendDouble(m.getDouble(row, col)); + } + return res.PassAs<base::Value>(); +} + scoped_ptr<base::Value> MathUtil::AsValueSafely(double value) { return scoped_ptr<base::Value>(base::Value::CreateDoubleValue( std::min(value, std::numeric_limits<double>::max()))); diff --git a/cc/base/math_util.h b/cc/base/math_util.h index 23eb20fa38..37f0c07602 100644 --- a/cc/base/math_util.h +++ b/cc/base/math_util.h @@ -156,11 +156,13 @@ class CC_EXPORT MathUtil { // Conversion to value. static scoped_ptr<base::Value> AsValue(gfx::Size s); + static scoped_ptr<base::Value> AsValue(gfx::SizeF s); static scoped_ptr<base::Value> AsValue(gfx::Rect r); static bool FromValue(const base::Value*, gfx::Rect* out_rect); static scoped_ptr<base::Value> AsValue(gfx::PointF q); static scoped_ptr<base::Value> AsValue(const gfx::QuadF& q); static scoped_ptr<base::Value> AsValue(const gfx::RectF& rect); + static scoped_ptr<base::Value> AsValue(const gfx::Transform& transform); // Returns a base::Value representation of the floating point value. // If the value is inf, returns max double/float representation. diff --git a/cc/cc.target.darwin-arm.mk b/cc/cc.target.darwin-arm.mk index 7029dcc329..68deea038c 100644 --- a/cc/cc.target.darwin-arm.mk +++ b/cc/cc.target.darwin-arm.mk @@ -249,6 +249,7 @@ MY_DEFS_Debug := \ '-DSK_BUILD_FOR_ANDROID' \ '-DUSE_CHROMIUM_SKIA' \ '-DSK_USE_POSIX_THREADS' \ + '-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \ '-DMEDIA_DISABLE_LIBVPX' \ '-DMESA_EGL_NO_X11_HEADERS' \ '-DPOSIX_AVOID_MMAP' \ @@ -364,6 +365,7 @@ MY_DEFS_Release := \ '-DSK_BUILD_FOR_ANDROID' \ '-DUSE_CHROMIUM_SKIA' \ '-DSK_USE_POSIX_THREADS' \ + '-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \ '-DMEDIA_DISABLE_LIBVPX' \ '-DMESA_EGL_NO_X11_HEADERS' \ '-DPOSIX_AVOID_MMAP' \ diff --git a/cc/cc.target.darwin-mips.mk b/cc/cc.target.darwin-mips.mk index d0f7ee7ad6..d6330589ef 100644 --- a/cc/cc.target.darwin-mips.mk +++ b/cc/cc.target.darwin-mips.mk @@ -248,6 +248,7 @@ MY_DEFS_Debug := \ '-DSK_BUILD_FOR_ANDROID' \ '-DUSE_CHROMIUM_SKIA' \ '-DSK_USE_POSIX_THREADS' \ + '-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \ '-DMEDIA_DISABLE_LIBVPX' \ '-DMESA_EGL_NO_X11_HEADERS' \ '-DPOSIX_AVOID_MMAP' \ @@ -362,6 +363,7 @@ MY_DEFS_Release := \ '-DSK_BUILD_FOR_ANDROID' \ '-DUSE_CHROMIUM_SKIA' \ '-DSK_USE_POSIX_THREADS' \ + '-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \ '-DMEDIA_DISABLE_LIBVPX' \ '-DMESA_EGL_NO_X11_HEADERS' \ '-DPOSIX_AVOID_MMAP' \ diff --git a/cc/cc.target.darwin-x86.mk b/cc/cc.target.darwin-x86.mk index 3f83839a71..84112c87ef 100644 --- a/cc/cc.target.darwin-x86.mk +++ b/cc/cc.target.darwin-x86.mk @@ -251,6 +251,7 @@ MY_DEFS_Debug := \ '-DSK_BUILD_FOR_ANDROID' \ '-DUSE_CHROMIUM_SKIA' \ '-DSK_USE_POSIX_THREADS' \ + '-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \ '-DMEDIA_DISABLE_LIBVPX' \ '-DMESA_EGL_NO_X11_HEADERS' \ '-DU_USING_ICU_NAMESPACE=0' \ @@ -368,6 +369,7 @@ MY_DEFS_Release := \ '-DSK_BUILD_FOR_ANDROID' \ '-DUSE_CHROMIUM_SKIA' \ '-DSK_USE_POSIX_THREADS' \ + '-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \ '-DMEDIA_DISABLE_LIBVPX' \ '-DMESA_EGL_NO_X11_HEADERS' \ '-DU_USING_ICU_NAMESPACE=0' \ diff --git a/cc/cc.target.linux-arm.mk b/cc/cc.target.linux-arm.mk index 7029dcc329..68deea038c 100644 --- a/cc/cc.target.linux-arm.mk +++ b/cc/cc.target.linux-arm.mk @@ -249,6 +249,7 @@ MY_DEFS_Debug := \ '-DSK_BUILD_FOR_ANDROID' \ '-DUSE_CHROMIUM_SKIA' \ '-DSK_USE_POSIX_THREADS' \ + '-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \ '-DMEDIA_DISABLE_LIBVPX' \ '-DMESA_EGL_NO_X11_HEADERS' \ '-DPOSIX_AVOID_MMAP' \ @@ -364,6 +365,7 @@ MY_DEFS_Release := \ '-DSK_BUILD_FOR_ANDROID' \ '-DUSE_CHROMIUM_SKIA' \ '-DSK_USE_POSIX_THREADS' \ + '-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \ '-DMEDIA_DISABLE_LIBVPX' \ '-DMESA_EGL_NO_X11_HEADERS' \ '-DPOSIX_AVOID_MMAP' \ diff --git a/cc/cc.target.linux-mips.mk b/cc/cc.target.linux-mips.mk index d0f7ee7ad6..d6330589ef 100644 --- a/cc/cc.target.linux-mips.mk +++ b/cc/cc.target.linux-mips.mk @@ -248,6 +248,7 @@ MY_DEFS_Debug := \ '-DSK_BUILD_FOR_ANDROID' \ '-DUSE_CHROMIUM_SKIA' \ '-DSK_USE_POSIX_THREADS' \ + '-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \ '-DMEDIA_DISABLE_LIBVPX' \ '-DMESA_EGL_NO_X11_HEADERS' \ '-DPOSIX_AVOID_MMAP' \ @@ -362,6 +363,7 @@ MY_DEFS_Release := \ '-DSK_BUILD_FOR_ANDROID' \ '-DUSE_CHROMIUM_SKIA' \ '-DSK_USE_POSIX_THREADS' \ + '-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \ '-DMEDIA_DISABLE_LIBVPX' \ '-DMESA_EGL_NO_X11_HEADERS' \ '-DPOSIX_AVOID_MMAP' \ diff --git a/cc/cc.target.linux-x86.mk b/cc/cc.target.linux-x86.mk index 3f83839a71..84112c87ef 100644 --- a/cc/cc.target.linux-x86.mk +++ b/cc/cc.target.linux-x86.mk @@ -251,6 +251,7 @@ MY_DEFS_Debug := \ '-DSK_BUILD_FOR_ANDROID' \ '-DUSE_CHROMIUM_SKIA' \ '-DSK_USE_POSIX_THREADS' \ + '-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \ '-DMEDIA_DISABLE_LIBVPX' \ '-DMESA_EGL_NO_X11_HEADERS' \ '-DU_USING_ICU_NAMESPACE=0' \ @@ -368,6 +369,7 @@ MY_DEFS_Release := \ '-DSK_BUILD_FOR_ANDROID' \ '-DUSE_CHROMIUM_SKIA' \ '-DSK_USE_POSIX_THREADS' \ + '-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \ '-DMEDIA_DISABLE_LIBVPX' \ '-DMESA_EGL_NO_X11_HEADERS' \ '-DU_USING_ICU_NAMESPACE=0' \ diff --git a/cc/debug/traced_value.cc b/cc/debug/traced_value.cc index 637c700552..fbca5c60c8 100644 --- a/cc/debug/traced_value.cc +++ b/cc/debug/traced_value.cc @@ -21,6 +21,15 @@ void TracedValue::MakeDictIntoImplicitSnapshot( dict->SetString("id", base::StringPrintf("%s/%p", object_name, id)); } +void TracedValue::MakeDictIntoImplicitSnapshotWithCategory( + const char* category, + base::DictionaryValue* dict, + const char* object_name, + const void* id) { + dict->SetString("cat", category); + MakeDictIntoImplicitSnapshot(dict, object_name, id); +} + scoped_ptr<base::debug::ConvertableToTraceFormat> TracedValue::FromValue( base::Value* value) { TracedValue* ptr = new TracedValue(value); diff --git a/cc/debug/traced_value.h b/cc/debug/traced_value.h index e5d63a1c10..148aca8ebb 100644 --- a/cc/debug/traced_value.h +++ b/cc/debug/traced_value.h @@ -21,6 +21,11 @@ class TracedValue : public base::debug::ConvertableToTraceFormat { static scoped_ptr<base::Value> CreateIDRef(const void* id); static void MakeDictIntoImplicitSnapshot( base::DictionaryValue* dict, const char* object_name, const void* id); + static void MakeDictIntoImplicitSnapshotWithCategory( + const char* category, + base::DictionaryValue* dict, + const char* object_name, + const void* id); static scoped_ptr<ConvertableToTraceFormat> FromValue( base::Value* value); diff --git a/cc/layers/delegated_renderer_layer.cc b/cc/layers/delegated_renderer_layer.cc index cbff44e03d..66064d9e84 100644 --- a/cc/layers/delegated_renderer_layer.cc +++ b/cc/layers/delegated_renderer_layer.cc @@ -41,28 +41,19 @@ void DelegatedRendererLayer::PushPropertiesTo(LayerImpl* impl) { delegated_impl->SetDisplaySize(display_size_); - if (!frame_data_) { - delegated_impl->SetFrameData(scoped_ptr<DelegatedFrameData>(), - gfx::Rect(), - &unused_resources_for_child_compositor_); - } else if (frame_size_.IsEmpty()) { - scoped_ptr<DelegatedFrameData> empty_frame(new DelegatedFrameData); - delegated_impl->SetFrameData(empty_frame.Pass(), - gfx::Rect(), - &unused_resources_for_child_compositor_); - } else { - delegated_impl->SetFrameData(frame_data_.Pass(), - damage_in_frame_, - &unused_resources_for_child_compositor_); - } + if (frame_data_) + delegated_impl->SetFrameData(frame_data_.Pass(), damage_in_frame_); frame_data_.reset(); damage_in_frame_ = gfx::RectF(); + delegated_impl->CollectUnusedResources( + &unused_resources_for_child_compositor_); + if (client_) client_->DidCommitFrameData(); // TODO(danakj): TakeUnusedResourcesForChildCompositor requires a push - // properties to happen in order to push up newly unused resources returned + // properties to happen in order to collect unused resources returned // from the parent compositor. crbug.com/259090 needs_push_properties_ = true; } diff --git a/cc/layers/delegated_renderer_layer_impl.cc b/cc/layers/delegated_renderer_layer_impl.cc index 31b0a8d042..2dfdac6eb2 100644 --- a/cc/layers/delegated_renderer_layer_impl.cc +++ b/cc/layers/delegated_renderer_layer_impl.cc @@ -92,8 +92,13 @@ void DelegatedRendererLayerImpl::PushPropertiesTo(LayerImpl* layer) { void DelegatedRendererLayerImpl::SetFrameData( scoped_ptr<DelegatedFrameData> frame_data, - gfx::RectF damage_in_frame, - TransferableResourceArray* resources_for_ack) { + gfx::RectF damage_in_frame) { + DCHECK(frame_data); + + // A frame with an empty root render pass is invalid. + DCHECK(frame_data->render_pass_list.empty() || + !frame_data->render_pass_list.back()->output_rect.IsEmpty()); + CreateChildIdIfNeeded(); DCHECK(child_id_); @@ -101,48 +106,53 @@ void DelegatedRendererLayerImpl::SetFrameData( const ResourceProvider::ResourceIdMap& resource_map = resource_provider->GetChildToParentMap(child_id_); - if (frame_data) { - // A frame with an empty root render pass is invalid. - DCHECK(frame_data->render_pass_list.empty() || - !frame_data->render_pass_list.back()->output_rect.IsEmpty()); - - // Display size is already set so we can compute what the damage rect - // will be in layer space. - if (!frame_data->render_pass_list.empty()) { - RenderPass* new_root_pass = frame_data->render_pass_list.back(); - gfx::RectF damage_in_layer = MathUtil::MapClippedRect( - DelegatedFrameToLayerSpaceTransform( - new_root_pass->output_rect.size()), - damage_in_frame); - set_update_rect(gfx::UnionRects(update_rect(), damage_in_layer)); + resource_provider->ReceiveFromChild(child_id_, frame_data->resource_list); + + bool invalid_frame = false; + ResourceProvider::ResourceIdSet used_resources; + DrawQuad::ResourceIteratorCallback remap_resources_to_parent_callback = + base::Bind(&ResourceRemapHelper, + &invalid_frame, + resource_map, + &used_resources); + for (size_t i = 0; i < frame_data->render_pass_list.size(); ++i) { + RenderPass* pass = frame_data->render_pass_list[i]; + for (size_t j = 0; j < pass->quad_list.size(); ++j) { + DrawQuad* quad = pass->quad_list[j]; + quad->IterateResources(remap_resources_to_parent_callback); } + } - resource_provider->ReceiveFromChild(child_id_, frame_data->resource_list); - - bool invalid_frame = false; - ResourceProvider::ResourceIdSet used_resources; - DrawQuad::ResourceIteratorCallback remap_resources_to_parent_callback = - base::Bind(&ResourceRemapHelper, - &invalid_frame, - resource_map, - &used_resources); - for (size_t i = 0; i < frame_data->render_pass_list.size(); ++i) { - RenderPass* pass = frame_data->render_pass_list[i]; - for (size_t j = 0; j < pass->quad_list.size(); ++j) { - DrawQuad* quad = pass->quad_list[j]; - quad->IterateResources(remap_resources_to_parent_callback); - } - } + if (invalid_frame) + return; - if (!invalid_frame) { - // Save the remapped quads on the layer. This steals the quads and render - // passes from the frame_data. - SetRenderPasses(&frame_data->render_pass_list); - resources_.swap(used_resources); - have_render_passes_to_push_ = true; - } + // Display size is already set so we can compute what the damage rect + // will be in layer space. + if (!frame_data->render_pass_list.empty()) { + RenderPass* new_root_pass = frame_data->render_pass_list.back(); + gfx::RectF damage_in_layer = MathUtil::MapClippedRect( + DelegatedFrameToLayerSpaceTransform( + new_root_pass->output_rect.size()), + damage_in_frame); + set_update_rect(gfx::UnionRects(update_rect(), damage_in_layer)); } + // Save the remapped quads on the layer. This steals the quads and render + // passes from the frame_data. + SetRenderPasses(&frame_data->render_pass_list); + resources_.swap(used_resources); + have_render_passes_to_push_ = true; +} + +void DelegatedRendererLayerImpl::CollectUnusedResources( + TransferableResourceArray* resources_for_ack) { + CreateChildIdIfNeeded(); + DCHECK(child_id_); + + ResourceProvider* resource_provider = layer_tree_impl()->resource_provider(); + const ResourceProvider::ResourceIdMap& resource_map = + resource_provider->GetChildToParentMap(child_id_); + ResourceProvider::ResourceIdArray unused_resources; for (ResourceProvider::ResourceIdMap::const_iterator it = resource_map.begin(); diff --git a/cc/layers/delegated_renderer_layer_impl.h b/cc/layers/delegated_renderer_layer_impl.h index 5725454bf5..9cfdcb6a35 100644 --- a/cc/layers/delegated_renderer_layer_impl.h +++ b/cc/layers/delegated_renderer_layer_impl.h @@ -41,8 +41,9 @@ class CC_EXPORT DelegatedRendererLayerImpl : public LayerImpl { void AppendContributingRenderPasses(RenderPassSink* render_pass_sink); void SetFrameData(scoped_ptr<DelegatedFrameData> frame_data, - gfx::RectF damage_in_frame, - TransferableResourceArray* resources_for_ack); + gfx::RectF damage_in_frame); + + void CollectUnusedResources(TransferableResourceArray* resources_for_ack); void SetDisplaySize(gfx::Size size); diff --git a/cc/output/filter_operation.cc b/cc/output/filter_operation.cc index de59cfc1c0..6a778388ae 100644 --- a/cc/output/filter_operation.cc +++ b/cc/output/filter_operation.cc @@ -4,6 +4,7 @@ #include <algorithm> +#include "base/values.h" #include "cc/base/math_util.h" #include "cc/output/filter_operation.h" #include "third_party/skia/include/core/SkMath.h" @@ -217,4 +218,40 @@ FilterOperation FilterOperation::Blend(const FilterOperation* from, return blended_filter; } +scoped_ptr<base::Value> FilterOperation::AsValue() const { + scoped_ptr<base::DictionaryValue> value(new DictionaryValue); + value->SetInteger("type", type_); + switch (type_) { + case FilterOperation::GRAYSCALE: + case FilterOperation::SEPIA: + case FilterOperation::SATURATE: + case FilterOperation::HUE_ROTATE: + case FilterOperation::INVERT: + case FilterOperation::BRIGHTNESS: + case FilterOperation::CONTRAST: + case FilterOperation::OPACITY: + case FilterOperation::BLUR: + case FilterOperation::SATURATING_BRIGHTNESS: + value->SetDouble("amount", amount_); + break; + case FilterOperation::DROP_SHADOW: + value->SetDouble("std_deviation", amount_); + value->Set("offset", MathUtil::AsValue(drop_shadow_offset_).release()); + value->SetInteger("color", drop_shadow_color_); + break; + case FilterOperation::COLOR_MATRIX: { + scoped_ptr<ListValue> matrix(new ListValue); + for (size_t i = 0; i < arraysize(matrix_); ++i) + matrix->AppendDouble(matrix_[i]); + value->Set("matrix", matrix.release()); + break; + } + case FilterOperation::ZOOM: + value->SetDouble("amount", amount_); + value->SetDouble("inset", zoom_inset_); + break; + } + return value.PassAs<base::Value>(); +} + } // namespace cc diff --git a/cc/output/filter_operation.h b/cc/output/filter_operation.h index ad25cf48f6..f56176213b 100644 --- a/cc/output/filter_operation.h +++ b/cc/output/filter_operation.h @@ -6,11 +6,16 @@ #define CC_OUTPUT_FILTER_OPERATION_H_ #include "base/logging.h" +#include "base/memory/scoped_ptr.h" #include "cc/base/cc_export.h" #include "third_party/skia/include/core/SkColor.h" #include "third_party/skia/include/core/SkScalar.h" #include "ui/gfx/point.h" +namespace base { +class Value; +} + namespace cc { class CC_EXPORT FilterOperation { @@ -161,6 +166,8 @@ class CC_EXPORT FilterOperation { const FilterOperation* to, double progress); + scoped_ptr<base::Value> AsValue() const; + private: FilterOperation(FilterType type, float amount); diff --git a/cc/output/filter_operations.cc b/cc/output/filter_operations.cc index 4331527909..2420841802 100644 --- a/cc/output/filter_operations.cc +++ b/cc/output/filter_operations.cc @@ -4,9 +4,11 @@ #include <cmath> -#include "cc/output/filter_operation.h" #include "cc/output/filter_operations.h" +#include "base/values.h" +#include "cc/output/filter_operation.h" + namespace cc { FilterOperations::FilterOperations() {} @@ -145,4 +147,11 @@ FilterOperations FilterOperations::Blend(const FilterOperations& from, return blended_filters; } +scoped_ptr<base::Value> FilterOperations::AsValue() const { + scoped_ptr<base::ListValue> value(new ListValue); + for (size_t i = 0; i < operations_.size(); ++i) + value->Append(operations_[i].AsValue().release()); + return value.PassAs<base::Value>(); +} + } // namespace cc diff --git a/cc/output/filter_operations.h b/cc/output/filter_operations.h index d7198d15ca..aa8d58dd8d 100644 --- a/cc/output/filter_operations.h +++ b/cc/output/filter_operations.h @@ -8,8 +8,13 @@ #include <vector> #include "base/logging.h" +#include "base/memory/scoped_ptr.h" #include "cc/output/filter_operation.h" +namespace base { +class Value; +} + namespace cc { // An ordered list of filter operations. @@ -62,6 +67,8 @@ class CC_EXPORT FilterOperations { // of this. FilterOperations Blend(const FilterOperations& from, double progress) const; + scoped_ptr<base::Value> AsValue() const; + private: std::vector<FilterOperation> operations_; }; diff --git a/cc/quads/checkerboard_draw_quad.cc b/cc/quads/checkerboard_draw_quad.cc index fcc6dc597b..5e17d885f4 100644 --- a/cc/quads/checkerboard_draw_quad.cc +++ b/cc/quads/checkerboard_draw_quad.cc @@ -5,6 +5,7 @@ #include "cc/quads/checkerboard_draw_quad.h" #include "base/logging.h" +#include "base/values.h" namespace cc { @@ -45,4 +46,8 @@ const CheckerboardDrawQuad* CheckerboardDrawQuad::MaterialCast( return static_cast<const CheckerboardDrawQuad*>(quad); } +void CheckerboardDrawQuad::ExtendValue(base::DictionaryValue* value) const { + value->SetInteger("color", color); +} + } // namespace cc diff --git a/cc/quads/checkerboard_draw_quad.h b/cc/quads/checkerboard_draw_quad.h index b2ed876b8c..4f7452eb0a 100644 --- a/cc/quads/checkerboard_draw_quad.h +++ b/cc/quads/checkerboard_draw_quad.h @@ -35,6 +35,7 @@ class CC_EXPORT CheckerboardDrawQuad : public DrawQuad { static const CheckerboardDrawQuad* MaterialCast(const DrawQuad*); private: + virtual void ExtendValue(base::DictionaryValue* value) const OVERRIDE; CheckerboardDrawQuad(); }; diff --git a/cc/quads/content_draw_quad_base.cc b/cc/quads/content_draw_quad_base.cc index 2c2b4aec9a..947af0b2d9 100644 --- a/cc/quads/content_draw_quad_base.cc +++ b/cc/quads/content_draw_quad_base.cc @@ -5,6 +5,8 @@ #include "cc/quads/content_draw_quad_base.h" #include "base/logging.h" +#include "base/values.h" +#include "cc/base/math_util.h" namespace cc { @@ -47,4 +49,10 @@ void ContentDrawQuadBase::SetAll(const SharedQuadState* shared_quad_state, this->swizzle_contents = swizzle_contents; } +void ContentDrawQuadBase::ExtendValue(base::DictionaryValue* value) const { + value->Set("tex_coord_rect", MathUtil::AsValue(tex_coord_rect).release()); + value->Set("texture_size", MathUtil::AsValue(texture_size).release()); + value->SetBoolean("swizzle_contents", swizzle_contents); +} + } // namespace cc diff --git a/cc/quads/content_draw_quad_base.h b/cc/quads/content_draw_quad_base.h index b2c936fdda..cbf18ca2b1 100644 --- a/cc/quads/content_draw_quad_base.h +++ b/cc/quads/content_draw_quad_base.h @@ -41,6 +41,7 @@ class CC_EXPORT ContentDrawQuadBase : public DrawQuad { protected: ContentDrawQuadBase(); virtual ~ContentDrawQuadBase(); + virtual void ExtendValue(base::DictionaryValue* value) const OVERRIDE; }; } // namespace cc diff --git a/cc/quads/debug_border_draw_quad.cc b/cc/quads/debug_border_draw_quad.cc index 1ebc0a6bdc..89ee8e0128 100644 --- a/cc/quads/debug_border_draw_quad.cc +++ b/cc/quads/debug_border_draw_quad.cc @@ -5,6 +5,7 @@ #include "cc/quads/debug_border_draw_quad.h" #include "base/logging.h" +#include "base/values.h" namespace cc { @@ -52,4 +53,9 @@ const DebugBorderDrawQuad* DebugBorderDrawQuad::MaterialCast( return static_cast<const DebugBorderDrawQuad*>(quad); } +void DebugBorderDrawQuad::ExtendValue(base::DictionaryValue* value) const { + value->SetInteger("color", color); + value->SetInteger("width", width); +} + } // namespace cc diff --git a/cc/quads/debug_border_draw_quad.h b/cc/quads/debug_border_draw_quad.h index 2f4b3cab28..5b369514b5 100644 --- a/cc/quads/debug_border_draw_quad.h +++ b/cc/quads/debug_border_draw_quad.h @@ -39,6 +39,7 @@ class CC_EXPORT DebugBorderDrawQuad : public DrawQuad { private: DebugBorderDrawQuad(); + virtual void ExtendValue(base::DictionaryValue* value) const OVERRIDE; }; } // namespace cc diff --git a/cc/quads/draw_quad.cc b/cc/quads/draw_quad.cc index 6c8d9b6654..0d021d9208 100644 --- a/cc/quads/draw_quad.cc +++ b/cc/quads/draw_quad.cc @@ -5,6 +5,9 @@ #include "cc/quads/draw_quad.h" #include "base/logging.h" +#include "base/values.h" +#include "cc/base/math_util.h" +#include "cc/debug/traced_value.h" #include "cc/quads/checkerboard_draw_quad.h" #include "cc/quads/debug_border_draw_quad.h" #include "cc/quads/io_surface_draw_quad.h" @@ -15,6 +18,7 @@ #include "cc/quads/texture_draw_quad.h" #include "cc/quads/tile_draw_quad.h" #include "cc/quads/yuv_video_draw_quad.h" +#include "ui/gfx/quad_f.h" namespace { template<typename T> T* TypedCopy(const cc::DrawQuad* other) { @@ -90,4 +94,48 @@ scoped_ptr<DrawQuad> DrawQuad::Copy( return copy_quad.Pass(); } +scoped_ptr<base::Value> DrawQuad::AsValue() const { + scoped_ptr<base::DictionaryValue> value(new base::DictionaryValue()); + value->SetInteger("material", material); + value->Set("shared_state", + TracedValue::CreateIDRef(shared_quad_state).release()); + + value->Set("content_space_rect", MathUtil::AsValue(rect).release()); + bool rect_is_clipped; + gfx::QuadF rect_as_target_space_quad = MathUtil::MapQuad( + shared_quad_state->content_to_target_transform, + gfx::QuadF(rect), + &rect_is_clipped); + value->Set("rect_as_target_space_quad", + MathUtil::AsValue(rect_as_target_space_quad).release()); + value->SetBoolean("rect_is_clipped", rect_is_clipped); + + value->Set("content_space_opaque_rect", + MathUtil::AsValue(opaque_rect).release()); + bool opaque_rect_is_clipped; + gfx::QuadF opaque_rect_as_target_space_quad = MathUtil::MapQuad( + shared_quad_state->content_to_target_transform, + gfx::QuadF(opaque_rect), + &opaque_rect_is_clipped); + value->Set("opaque_rect_as_target_space_quad", + MathUtil::AsValue(opaque_rect_as_target_space_quad).release()); + value->SetBoolean("opaque_rect_is_clipped", opaque_rect_is_clipped); + + value->Set("content_space_visible_rect", + MathUtil::AsValue(visible_rect).release()); + bool visible_rect_is_clipped; + gfx::QuadF visible_rect_as_target_space_quad = MathUtil::MapQuad( + shared_quad_state->content_to_target_transform, + gfx::QuadF(visible_rect), + &visible_rect_is_clipped); + value->Set("visible_rect_as_target_space_quad", + MathUtil::AsValue(visible_rect_as_target_space_quad).release()); + value->SetBoolean("visible_rect_is_clipped", visible_rect_is_clipped); + + value->SetBoolean("needs_blending", needs_blending); + value->SetBoolean("should_draw_with_blending", ShouldDrawWithBlending()); + ExtendValue(value.get()); + return value.PassAs<base::Value>(); +} + } // namespace cc diff --git a/cc/quads/draw_quad.h b/cc/quads/draw_quad.h index a92cddf887..c3696d6f30 100644 --- a/cc/quads/draw_quad.h +++ b/cc/quads/draw_quad.h @@ -10,12 +10,24 @@ #include "cc/quads/shared_quad_state.h" #include "cc/resources/resource_provider.h" +namespace base { +class Value; +class DictionaryValue; +} + namespace cc { // DrawQuad is a bag of data used for drawing a quad. Because different // materials need different bits of per-quad data to render, classes that derive // from DrawQuad store additional data in their derived instance. The Material // enum is used to "safely" downcast to the derived class. +// Note: quads contain rects and sizes, which live in different spaces. There is +// the "content space", which is the arbitrary space in which the quad's +// geometry is defined (generally related to the layer that produced the quad, +// e.g. the content space for TiledLayerImpls, or the geometry space for +// PictureLayerImpls). There is also the "target space", which is the space, in +// "physical" pixels, of the render target where the quads is drawn. The quad's +// transform maps the content space to the target space. class CC_EXPORT DrawQuad { public: enum Material { @@ -51,14 +63,15 @@ class CC_EXPORT DrawQuad { Material material; // This rect, after applying the quad_transform(), gives the geometry that - // this quad should draw to. + // this quad should draw to. This rect lives in content space. gfx::Rect rect; - // This specifies the region of the quad that is opaque. + // This specifies the region of the quad that is opaque. This rect lives in + // content space. gfx::Rect opaque_rect; // Allows changing the rect that gets drawn to make it smaller. This value - // should be clipped to |rect|. + // should be clipped to |rect|. This rect lives in content space. gfx::Rect visible_rect; // By default blending is used when some part of the quad is not opaque. @@ -111,6 +124,8 @@ class CC_EXPORT DrawQuad { return IsLeftEdge() || IsTopEdge() || IsRightEdge() || IsBottomEdge(); } + scoped_ptr<base::Value> AsValue() const; + protected: DrawQuad(); @@ -120,6 +135,7 @@ class CC_EXPORT DrawQuad { gfx::Rect opaque_rect, gfx::Rect visible_rect, bool needs_blending); + virtual void ExtendValue(base::DictionaryValue* value) const = 0; }; } // namespace cc diff --git a/cc/quads/io_surface_draw_quad.cc b/cc/quads/io_surface_draw_quad.cc index 1bbf8a4e3d..2c986dd3a2 100644 --- a/cc/quads/io_surface_draw_quad.cc +++ b/cc/quads/io_surface_draw_quad.cc @@ -5,6 +5,8 @@ #include "cc/quads/io_surface_draw_quad.h" #include "base/logging.h" +#include "base/values.h" +#include "cc/base/math_util.h" namespace cc { @@ -58,4 +60,20 @@ const IOSurfaceDrawQuad* IOSurfaceDrawQuad::MaterialCast( return static_cast<const IOSurfaceDrawQuad*>(quad); } +void IOSurfaceDrawQuad::ExtendValue(base::DictionaryValue* value) const { + value->Set("io_surface_size", MathUtil::AsValue(io_surface_size).release()); + value->SetInteger("io_surface_resource_id", io_surface_resource_id); + const char* orientation_string = NULL; + switch (orientation) { + case FLIPPED: + orientation_string = "flipped"; + break; + case UNFLIPPED: + orientation_string = "unflipped"; + break; + } + + value->SetString("orientation", orientation_string); +} + } // namespace cc diff --git a/cc/quads/io_surface_draw_quad.h b/cc/quads/io_surface_draw_quad.h index 1a30c90341..fc8b501940 100644 --- a/cc/quads/io_surface_draw_quad.h +++ b/cc/quads/io_surface_draw_quad.h @@ -48,6 +48,7 @@ class CC_EXPORT IOSurfaceDrawQuad : public DrawQuad { private: IOSurfaceDrawQuad(); + virtual void ExtendValue(base::DictionaryValue* value) const OVERRIDE; }; } // namespace cc diff --git a/cc/quads/picture_draw_quad.cc b/cc/quads/picture_draw_quad.cc index 81f79138bb..0494764d8a 100644 --- a/cc/quads/picture_draw_quad.cc +++ b/cc/quads/picture_draw_quad.cc @@ -4,6 +4,9 @@ #include "cc/quads/picture_draw_quad.h" +#include "base/values.h" +#include "cc/base/math_util.h" + namespace cc { PictureDrawQuad::PictureDrawQuad() { @@ -68,4 +71,13 @@ const PictureDrawQuad* PictureDrawQuad::MaterialCast(const DrawQuad* quad) { return static_cast<const PictureDrawQuad*>(quad); } +void PictureDrawQuad::ExtendValue(base::DictionaryValue* value) const { + ContentDrawQuadBase::ExtendValue(value); + value->Set("content_rect", MathUtil::AsValue(content_rect).release()); + value->SetDouble("contents_scale", contents_scale); + value->SetBoolean("can_draw_direct_to_backbuffer", + can_draw_direct_to_backbuffer); + // TODO(piman): picture_pile? +} + } // namespace cc diff --git a/cc/quads/picture_draw_quad.h b/cc/quads/picture_draw_quad.h index 29af6d5c6d..beec88ce3f 100644 --- a/cc/quads/picture_draw_quad.h +++ b/cc/quads/picture_draw_quad.h @@ -58,6 +58,7 @@ class CC_EXPORT PictureDrawQuad : public ContentDrawQuadBase { private: PictureDrawQuad(); + virtual void ExtendValue(base::DictionaryValue* value) const OVERRIDE; }; } // namespace cc diff --git a/cc/quads/render_pass.cc b/cc/quads/render_pass.cc index ef6308cff2..50d502884b 100644 --- a/cc/quads/render_pass.cc +++ b/cc/quads/render_pass.cc @@ -4,12 +4,20 @@ #include "cc/quads/render_pass.h" +#include "base/values.h" +#include "cc/base/math_util.h" +#include "cc/debug/traced_value.h" #include "cc/output/copy_output_request.h" #include "cc/quads/draw_quad.h" #include "cc/quads/shared_quad_state.h" namespace cc { +void* RenderPass::Id::AsTracingId() const { + COMPILE_ASSERT(sizeof(size_t) <= sizeof(void*), size_t_bigger_than_pointer); + return reinterpret_cast<void*>(base::HashPair(layer_id, index)); +} + scoped_ptr<RenderPass> RenderPass::Create() { return make_scoped_ptr(new RenderPass); } @@ -19,7 +27,11 @@ RenderPass::RenderPass() has_transparent_background(true), has_occlusion_from_outside_target_surface(false) {} -RenderPass::~RenderPass() {} +RenderPass::~RenderPass() { + TRACE_EVENT_OBJECT_DELETED_WITH_ID( + TRACE_DISABLED_BY_DEFAULT("cc.debug.quads"), + "cc::RenderPass", id.AsTracingId()); +} scoped_ptr<RenderPass> RenderPass::Copy(Id new_id) const { scoped_ptr<RenderPass> copy_pass(Create()); @@ -69,4 +81,29 @@ void RenderPass::SetAll(Id id, DCHECK(shared_quad_state_list.empty()); } +scoped_ptr<base::Value> RenderPass::AsValue() const { + scoped_ptr<base::DictionaryValue> value(new base::DictionaryValue()); + value->Set("output_rect", MathUtil::AsValue(output_rect).release()); + value->Set("damage_rect", MathUtil::AsValue(damage_rect).release()); + value->SetBoolean("has_transparent_background", has_transparent_background); + value->SetBoolean("has_occlusion_from_outside_target_surface", + has_occlusion_from_outside_target_surface); + value->SetInteger("copy_requests", copy_requests.size()); + scoped_ptr<base::ListValue> shared_states_value(new base::ListValue()); + for (size_t i = 0; i < shared_quad_state_list.size(); ++i) { + shared_states_value->Append(shared_quad_state_list[i]->AsValue().release()); + } + value->Set("shared_quad_state_list", shared_states_value.release()); + scoped_ptr<base::ListValue> quad_list_value(new base::ListValue()); + for (size_t i = 0; i < quad_list.size(); ++i) { + quad_list_value->Append(quad_list[i]->AsValue().release()); + } + value->Set("quad_list", quad_list_value.release()); + + TracedValue::MakeDictIntoImplicitSnapshotWithCategory( + TRACE_DISABLED_BY_DEFAULT("cc.debug.quads"), + value.get(), "cc::RenderPass", id.AsTracingId()); + return value.PassAs<base::Value>(); +} + } // namespace cc diff --git a/cc/quads/render_pass.h b/cc/quads/render_pass.h index 3d5a37cb78..224a0506f0 100644 --- a/cc/quads/render_pass.h +++ b/cc/quads/render_pass.h @@ -20,6 +20,10 @@ #include "ui/gfx/rect_f.h" #include "ui/gfx/transform.h" +namespace base { +class Value; +}; + namespace cc { class DrawQuad; @@ -47,6 +51,7 @@ class CC_EXPORT RenderPass { int index; Id(int layer_id, int index) : layer_id(layer_id), index(index) {} + void* AsTracingId() const; bool operator==(const Id& other) const { return layer_id == other.layer_id && index == other.index; @@ -79,6 +84,8 @@ class CC_EXPORT RenderPass { bool has_transparent_background, bool has_occlusion_from_outside_target_surface); + scoped_ptr<base::Value> AsValue() const; + // Uniquely identifies the render pass in the compositor's current frame. Id id; diff --git a/cc/quads/render_pass_draw_quad.cc b/cc/quads/render_pass_draw_quad.cc index ead3d792a3..0528cd5e34 100644 --- a/cc/quads/render_pass_draw_quad.cc +++ b/cc/quads/render_pass_draw_quad.cc @@ -4,6 +4,10 @@ #include "cc/quads/render_pass_draw_quad.h" +#include "base/values.h" +#include "cc/base/math_util.h" +#include "cc/debug/traced_value.h" + namespace cc { RenderPassDrawQuad::RenderPassDrawQuad() @@ -93,4 +97,19 @@ const RenderPassDrawQuad* RenderPassDrawQuad::MaterialCast( return static_cast<const RenderPassDrawQuad*>(quad); } +void RenderPassDrawQuad::ExtendValue(base::DictionaryValue* value) const { + value->Set("render_pass_id", + TracedValue::CreateIDRef(render_pass_id.AsTracingId()).release()); + value->SetBoolean("is_replica", is_replica); + value->SetInteger("mask_resource_id", mask_resource_id); + value->Set("contents_changed_since_last_frame", + MathUtil::AsValue(contents_changed_since_last_frame).release()); + value->Set("mask_uv_rect", MathUtil::AsValue(mask_uv_rect).release()); + value->Set("filters", filters.AsValue().release()); + // TODO(piman): dump SkImageFilters rather than just indicating if there are + // any or not. + value->SetBoolean("has_filter", !!filter); + value->Set("background_filters", background_filters.AsValue().release()); +} + } // namespace cc diff --git a/cc/quads/render_pass_draw_quad.h b/cc/quads/render_pass_draw_quad.h index f0c76a9557..e253dec430 100644 --- a/cc/quads/render_pass_draw_quad.h +++ b/cc/quads/render_pass_draw_quad.h @@ -72,6 +72,7 @@ class CC_EXPORT RenderPassDrawQuad : public DrawQuad { private: RenderPassDrawQuad(); + virtual void ExtendValue(base::DictionaryValue* value) const OVERRIDE; }; } // namespace cc diff --git a/cc/quads/shared_quad_state.cc b/cc/quads/shared_quad_state.cc index 7bfb2b440f..6a53d9f6a9 100644 --- a/cc/quads/shared_quad_state.cc +++ b/cc/quads/shared_quad_state.cc @@ -4,11 +4,19 @@ #include "cc/quads/shared_quad_state.h" +#include "base/values.h" +#include "cc/base/math_util.h" +#include "cc/debug/traced_value.h" + namespace cc { SharedQuadState::SharedQuadState() : is_clipped(false), opacity(0.f) {} -SharedQuadState::~SharedQuadState() {} +SharedQuadState::~SharedQuadState() { + TRACE_EVENT_OBJECT_DELETED_WITH_ID( + TRACE_DISABLED_BY_DEFAULT("cc.debug.quads"), + "cc::SharedQuadState", this); +} scoped_ptr<SharedQuadState> SharedQuadState::Create() { return make_scoped_ptr(new SharedQuadState); @@ -33,4 +41,21 @@ void SharedQuadState::SetAll( this->opacity = opacity; } +scoped_ptr<base::Value> SharedQuadState::AsValue() const { + scoped_ptr<base::DictionaryValue> value(new base::DictionaryValue()); + value->Set("transform", + MathUtil::AsValue(content_to_target_transform).release()); + value->Set("layer_content_bounds", + MathUtil::AsValue(content_bounds).release()); + value->Set("layer_visible_content_rect", + MathUtil::AsValue(visible_content_rect).release()); + value->SetBoolean("is_clipped", is_clipped); + value->Set("clip_rect", MathUtil::AsValue(clip_rect).release()); + value->SetDouble("opacity", opacity); + TracedValue::MakeDictIntoImplicitSnapshotWithCategory( + TRACE_DISABLED_BY_DEFAULT("cc.debug.quads"), + value.get(), "cc::SharedQuadState", this); + return value.PassAs<base::Value>(); +} + } // namespace cc diff --git a/cc/quads/shared_quad_state.h b/cc/quads/shared_quad_state.h index eb3e91eaed..79bd09b60f 100644 --- a/cc/quads/shared_quad_state.h +++ b/cc/quads/shared_quad_state.h @@ -10,6 +10,10 @@ #include "ui/gfx/rect.h" #include "ui/gfx/transform.h" +namespace base { +class Value; +} + namespace cc { class CC_EXPORT SharedQuadState { @@ -25,12 +29,15 @@ class CC_EXPORT SharedQuadState { gfx::Rect clip_rect, bool is_clipped, float opacity); + scoped_ptr<base::Value> AsValue() const; // Transforms from quad's original content space to its target content space. gfx::Transform content_to_target_transform; - // This rect lives in the content space for the quad's originating layer. + // This size lives in the content space for the quad's originating layer. gfx::Size content_bounds; + // This rect lives in the content space for the quad's originating layer. gfx::Rect visible_content_rect; + // This rect lives in the target content space. gfx::Rect clip_rect; bool is_clipped; float opacity; diff --git a/cc/quads/solid_color_draw_quad.cc b/cc/quads/solid_color_draw_quad.cc index 5575aaf127..ae3b914220 100644 --- a/cc/quads/solid_color_draw_quad.cc +++ b/cc/quads/solid_color_draw_quad.cc @@ -5,6 +5,7 @@ #include "cc/quads/solid_color_draw_quad.h" #include "base/logging.h" +#include "base/values.h" namespace cc { @@ -50,4 +51,9 @@ const SolidColorDrawQuad* SolidColorDrawQuad::MaterialCast( return static_cast<const SolidColorDrawQuad*>(quad); } -} // namespacec cc +void SolidColorDrawQuad::ExtendValue(base::DictionaryValue* value) const { + value->SetInteger("color", color); + value->SetBoolean("force_anti_aliasing_off", force_anti_aliasing_off); +} + +} // namespace cc diff --git a/cc/quads/solid_color_draw_quad.h b/cc/quads/solid_color_draw_quad.h index 4d7ab9fbd8..2c41243409 100644 --- a/cc/quads/solid_color_draw_quad.h +++ b/cc/quads/solid_color_draw_quad.h @@ -39,6 +39,7 @@ class CC_EXPORT SolidColorDrawQuad : public DrawQuad { private: SolidColorDrawQuad(); + virtual void ExtendValue(base::DictionaryValue* value) const OVERRIDE; }; } // namespace cc diff --git a/cc/quads/stream_video_draw_quad.cc b/cc/quads/stream_video_draw_quad.cc index 831304f1a0..c239256ac5 100644 --- a/cc/quads/stream_video_draw_quad.cc +++ b/cc/quads/stream_video_draw_quad.cc @@ -5,6 +5,8 @@ #include "cc/quads/stream_video_draw_quad.h" #include "base/logging.h" +#include "base/values.h" +#include "cc/base/math_util.h" namespace cc { @@ -51,4 +53,9 @@ const StreamVideoDrawQuad* StreamVideoDrawQuad::MaterialCast( return static_cast<const StreamVideoDrawQuad*>(quad); } +void StreamVideoDrawQuad::ExtendValue(base::DictionaryValue* value) const { + value->SetInteger("resource_id", resource_id); + value->Set("matrix", MathUtil::AsValue(matrix).release()); +} + } // namespace cc diff --git a/cc/quads/stream_video_draw_quad.h b/cc/quads/stream_video_draw_quad.h index 0ce31af568..e610f4333c 100644 --- a/cc/quads/stream_video_draw_quad.h +++ b/cc/quads/stream_video_draw_quad.h @@ -40,6 +40,7 @@ class CC_EXPORT StreamVideoDrawQuad : public DrawQuad { private: StreamVideoDrawQuad(); + virtual void ExtendValue(base::DictionaryValue* value) const OVERRIDE; }; } // namespace cc diff --git a/cc/quads/texture_draw_quad.cc b/cc/quads/texture_draw_quad.cc index c894985717..ae7cfd6e23 100644 --- a/cc/quads/texture_draw_quad.cc +++ b/cc/quads/texture_draw_quad.cc @@ -5,6 +5,8 @@ #include "cc/quads/texture_draw_quad.h" #include "base/logging.h" +#include "base/values.h" +#include "cc/base/math_util.h" #include "ui/gfx/vector2d_f.h" namespace cc { @@ -156,4 +158,17 @@ bool TextureDrawQuad::PerformClipping() { return true; } +void TextureDrawQuad::ExtendValue(base::DictionaryValue* value) const { + value->SetInteger("resource_id", resource_id); + value->SetBoolean("premultiplied_alpha", premultiplied_alpha); + value->Set("uv_top_left", MathUtil::AsValue(uv_top_left).release()); + value->Set("uv_bottom_right", MathUtil::AsValue(uv_bottom_right).release()); + value->SetInteger("background_color", background_color); + scoped_ptr<ListValue> vertex_opacity_value(new ListValue); + for (size_t i = 0; i < 4; ++i) + vertex_opacity_value->AppendDouble(vertex_opacity[i]); + value->Set("vertex_opacity", vertex_opacity_value.release()); + value->SetBoolean("flipped", flipped); +} + } // namespace cc diff --git a/cc/quads/texture_draw_quad.h b/cc/quads/texture_draw_quad.h index 3db10c64a9..7f06618848 100644 --- a/cc/quads/texture_draw_quad.h +++ b/cc/quads/texture_draw_quad.h @@ -57,6 +57,7 @@ class CC_EXPORT TextureDrawQuad : public DrawQuad { private: TextureDrawQuad(); + virtual void ExtendValue(base::DictionaryValue* value) const OVERRIDE; }; } // namespace cc diff --git a/cc/quads/tile_draw_quad.cc b/cc/quads/tile_draw_quad.cc index 414b320cb3..3ff98095e9 100644 --- a/cc/quads/tile_draw_quad.cc +++ b/cc/quads/tile_draw_quad.cc @@ -5,6 +5,7 @@ #include "cc/quads/tile_draw_quad.h" #include "base/logging.h" +#include "base/values.h" #include "third_party/khronos/GLES2/gl2.h" namespace cc { @@ -58,4 +59,9 @@ const TileDrawQuad* TileDrawQuad::MaterialCast(const DrawQuad* quad) { return static_cast<const TileDrawQuad*>(quad); } +void TileDrawQuad::ExtendValue(base::DictionaryValue* value) const { + ContentDrawQuadBase::ExtendValue(value); + value->SetInteger("resource_id", resource_id); +} + } // namespace cc diff --git a/cc/quads/tile_draw_quad.h b/cc/quads/tile_draw_quad.h index 25957f6827..6da1e54a95 100644 --- a/cc/quads/tile_draw_quad.h +++ b/cc/quads/tile_draw_quad.h @@ -41,6 +41,7 @@ class CC_EXPORT TileDrawQuad : public ContentDrawQuadBase { private: TileDrawQuad(); + virtual void ExtendValue(base::DictionaryValue* value) const OVERRIDE; }; } // namespace cc diff --git a/cc/quads/yuv_video_draw_quad.cc b/cc/quads/yuv_video_draw_quad.cc index 2ac75dcd53..ecdc78fdcb 100644 --- a/cc/quads/yuv_video_draw_quad.cc +++ b/cc/quads/yuv_video_draw_quad.cc @@ -5,6 +5,8 @@ #include "cc/quads/yuv_video_draw_quad.h" #include "base/logging.h" +#include "base/values.h" +#include "cc/base/math_util.h" namespace cc { @@ -72,4 +74,12 @@ const YUVVideoDrawQuad* YUVVideoDrawQuad::MaterialCast( return static_cast<const YUVVideoDrawQuad*>(quad); } +void YUVVideoDrawQuad::ExtendValue(base::DictionaryValue* value) const { + value->Set("tex_scale", MathUtil::AsValue(tex_scale).release()); + value->SetInteger("y_plane_resource_id", y_plane_resource_id); + value->SetInteger("u_plane_resource_id", u_plane_resource_id); + value->SetInteger("v_plane_resource_id", v_plane_resource_id); + value->SetInteger("a_plane_resource_id", a_plane_resource_id); +} + } // namespace cc diff --git a/cc/quads/yuv_video_draw_quad.h b/cc/quads/yuv_video_draw_quad.h index 34a0612451..aa750fa8ba 100644 --- a/cc/quads/yuv_video_draw_quad.h +++ b/cc/quads/yuv_video_draw_quad.h @@ -52,6 +52,7 @@ class CC_EXPORT YUVVideoDrawQuad : public DrawQuad { private: YUVVideoDrawQuad(); + virtual void ExtendValue(base::DictionaryValue* value) const OVERRIDE; }; } // namespace cc diff --git a/cc/resources/pixel_buffer_raster_worker_pool.cc b/cc/resources/pixel_buffer_raster_worker_pool.cc index 112de14378..a03ed81f4e 100644 --- a/cc/resources/pixel_buffer_raster_worker_pool.cc +++ b/cc/resources/pixel_buffer_raster_worker_pool.cc @@ -590,10 +590,6 @@ void PixelBufferRasterWorkerPool::OnRasterTaskCompleted( scoped_refptr<internal::RasterWorkerPoolTask> task, bool was_canceled, bool needs_upload) { - TRACE_EVENT2("cc", "PixelBufferRasterWorkerPool::OnRasterTaskCompleted", - "was_canceled", was_canceled, - "needs_upload", needs_upload); - DCHECK(pixel_buffer_tasks_.find(task.get()) != pixel_buffer_tasks_.end()); // Balanced with MapPixelBuffer() call in ScheduleMoreTasks(). diff --git a/cc/resources/resource_provider.cc b/cc/resources/resource_provider.cc index 6d6ac9d839..11eaab07a2 100644 --- a/cc/resources/resource_provider.cc +++ b/cc/resources/resource_provider.cc @@ -785,7 +785,6 @@ const ResourceProvider::ResourceIdMap& ResourceProvider::GetChildToParentMap( void ResourceProvider::PrepareSendToParent(const ResourceIdArray& resources, TransferableResourceArray* list) { DCHECK(thread_checker_.CalledOnValidThread()); - list->clear(); WebGraphicsContext3D* context3d = output_surface_->context3d(); if (!context3d || !context3d->makeContextCurrent()) { // TODO(skaslev): Implement this path for software compositing. @@ -818,7 +817,6 @@ void ResourceProvider::PrepareSendToChild(int child, const ResourceIdArray& resources, TransferableResourceArray* list) { DCHECK(thread_checker_.CalledOnValidThread()); - list->clear(); WebGraphicsContext3D* context3d = output_surface_->context3d(); if (!context3d || !context3d->makeContextCurrent()) { // TODO(skaslev): Implement this path for software compositing. diff --git a/cc/resources/video_resource_updater_unittest.cc b/cc/resources/video_resource_updater_unittest.cc index 95b3124369..ff574fff7f 100644 --- a/cc/resources/video_resource_updater_unittest.cc +++ b/cc/resources/video_resource_updater_unittest.cc @@ -36,18 +36,17 @@ class VideoResourceUpdaterTest : public testing::Test { return media::VideoFrame::WrapExternalYuvData( media::VideoFrame::YV16, // format - size, // coded_size - gfx::Rect(size), // visible_rect - size, // natural_size - size.width(), // y_stride - size.width() / 2, // u_stride - size.width() / 2, // v_stride - y_data, // y_data - u_data, // u_data - v_data, // v_data - base::TimeDelta(), // timestamp, - base::SharedMemory::NULLHandle(), // shm_handle - base::Closure()); // no_longer_needed_cb + size, // coded_size + gfx::Rect(size), // visible_rect + size, // natural_size + size.width(), // y_stride + size.width() / 2, // u_stride + size.width() / 2, // v_stride + y_data, // y_data + u_data, // u_data + v_data, // v_data + base::TimeDelta(), // timestamp, + base::Closure()); // no_longer_needed_cb } TestWebGraphicsContext3D* context3d_; diff --git a/cc/resources/worker_pool.cc b/cc/resources/worker_pool.cc index 812bbebc94..dca0c704f0 100644 --- a/cc/resources/worker_pool.cc +++ b/cc/resources/worker_pool.cc @@ -402,7 +402,8 @@ void WorkerPool::CheckForCompletedTasks() { void WorkerPool::ProcessCompletedTasks( const TaskVector& completed_tasks) { - TRACE_EVENT0("cc", "WorkerPool::ProcessCompletedTasks"); + TRACE_EVENT1("cc", "WorkerPool::ProcessCompletedTasks", + "completed_task_count", completed_tasks.size()); // Worker pool instance is not reentrant while processing completed tasks. in_dispatch_completion_callbacks_ = true; diff --git a/cc/test/fake_delegated_renderer_layer_impl.cc b/cc/test/fake_delegated_renderer_layer_impl.cc index 8ae1fa5a4a..c6a639e65e 100644 --- a/cc/test/fake_delegated_renderer_layer_impl.cc +++ b/cc/test/fake_delegated_renderer_layer_impl.cc @@ -16,6 +16,12 @@ FakeDelegatedRendererLayerImpl::FakeDelegatedRendererLayerImpl( FakeDelegatedRendererLayerImpl::~FakeDelegatedRendererLayerImpl() {} +scoped_ptr<LayerImpl> FakeDelegatedRendererLayerImpl::CreateLayerImpl( + LayerTreeImpl* tree_impl) { + return FakeDelegatedRendererLayerImpl::Create( + tree_impl, id()).PassAs<LayerImpl>(); +} + static ResourceProvider::ResourceId AddResourceToFrame( DelegatedFrameData* frame, ResourceProvider::ResourceId resource_id) { @@ -40,7 +46,8 @@ void FakeDelegatedRendererLayerImpl::SetFrameDataForRenderPasses( } TransferableResourceArray resources_for_ack; - SetFrameData(delegated_frame.Pass(), gfx::RectF(), &resources_for_ack); + SetFrameData(delegated_frame.Pass(), gfx::RectF()); + CollectUnusedResources(&resources_for_ack); } } // namespace cc diff --git a/cc/test/fake_delegated_renderer_layer_impl.h b/cc/test/fake_delegated_renderer_layer_impl.h index b9789f5fdc..a9ca0f9f79 100644 --- a/cc/test/fake_delegated_renderer_layer_impl.h +++ b/cc/test/fake_delegated_renderer_layer_impl.h @@ -17,6 +17,9 @@ class FakeDelegatedRendererLayerImpl : public DelegatedRendererLayerImpl { } virtual ~FakeDelegatedRendererLayerImpl(); + virtual scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) + OVERRIDE; + int ChildId() const { return ChildIdForTesting(); } const ScopedPtrVector<RenderPass>& RenderPassesInDrawOrder() const { return RenderPassesInDrawOrderForTesting(); diff --git a/cc/test/fake_output_surface.cc b/cc/test/fake_output_surface.cc index 09af44c4a4..9ae75529af 100644 --- a/cc/test/fake_output_surface.cc +++ b/cc/test/fake_output_surface.cc @@ -61,6 +61,14 @@ void FakeOutputSurface::SwapBuffers(CompositorFrame* frame) { if (frame->software_frame_data || frame->delegated_frame_data || !context3d()) { frame->AssignTo(&last_sent_frame_); + + if (last_sent_frame_.delegated_frame_data) { + resources_held_by_parent_.insert( + resources_held_by_parent_.end(), + last_sent_frame_.delegated_frame_data->resource_list.begin(), + last_sent_frame_.delegated_frame_data->resource_list.end()); + } + ++num_sent_frames_; PostSwapBuffersComplete(); DidSwapBuffers(); @@ -116,4 +124,17 @@ void FakeOutputSurface::SetTreeActivationCallback( client_->SetTreeActivationCallback(callback); } +void FakeOutputSurface::ReturnResource(unsigned id, CompositorFrameAck* ack) { + TransferableResourceArray::iterator it; + for (it = resources_held_by_parent_.begin(); + it != resources_held_by_parent_.end(); + ++it) { + if (it->id == id) + break; + } + DCHECK(it != resources_held_by_parent_.end()); + ack->resources.push_back(*it); + resources_held_by_parent_.erase(it); +} + } // namespace cc diff --git a/cc/test/fake_output_surface.h b/cc/test/fake_output_surface.h index dfd4db5344..5091dff02c 100644 --- a/cc/test/fake_output_surface.h +++ b/cc/test/fake_output_surface.h @@ -95,6 +95,12 @@ class FakeOutputSurface : public OutputSurface { void SetTreeActivationCallback(const base::Closure& callback); + const TransferableResourceArray& resources_held_by_parent() { + return resources_held_by_parent_; + } + + void ReturnResource(unsigned id, CompositorFrameAck* ack); + protected: FakeOutputSurface( scoped_ptr<WebKit::WebGraphicsContext3D> context3d, @@ -117,6 +123,7 @@ class FakeOutputSurface : public OutputSurface { bool needs_begin_frame_; bool forced_draw_to_software_device_; base::WeakPtrFactory<FakeOutputSurface> fake_weak_ptr_factory_; + TransferableResourceArray resources_held_by_parent_; }; static inline scoped_ptr<cc::OutputSurface> CreateFakeOutputSurface() { diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc index c61e6bec0d..d4a9498150 100644 --- a/cc/trees/layer_tree_host_impl.cc +++ b/cc/trees/layer_tree_host_impl.cc @@ -7,6 +7,7 @@ #include <algorithm> #include "base/basictypes.h" +#include "base/containers/hash_tables.h" #include "base/json/json_writer.h" #include "base/metrics/histogram.h" #include "base/stl_util.h" @@ -437,6 +438,25 @@ void LayerTreeHostImpl::TrackDamageForAllSurfaces( } } +scoped_ptr<base::Value> LayerTreeHostImpl::FrameData::AsValue() const { + scoped_ptr<base::DictionaryValue> value(new base::DictionaryValue()); + value->SetBoolean("contains_incomplete_tile", contains_incomplete_tile); + value->SetBoolean("has_no_damage", has_no_damage); + + // Quad data can be quite large, so only dump render passes if we select + // cc.debug.quads. + bool quads_enabled; + TRACE_EVENT_CATEGORY_GROUP_ENABLED( + TRACE_DISABLED_BY_DEFAULT("cc.debug.quads"), &quads_enabled); + if (quads_enabled) { + scoped_ptr<base::ListValue> render_pass_list(new base::ListValue()); + for (size_t i = 0; i < render_passes.size(); ++i) + render_pass_list->Append(render_passes[i]->AsValue().release()); + value->Set("render_passes", render_pass_list.release()); + } + return value.PassAs<base::Value>(); +} + void LayerTreeHostImpl::FrameData::AppendRenderPass( scoped_ptr<RenderPass> render_pass) { render_passes_by_id[render_pass->id] = render_pass.get(); @@ -1257,8 +1277,9 @@ void LayerTreeHostImpl::DrawLayers(FrameData* frame, } TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID( - TRACE_DISABLED_BY_DEFAULT("cc.debug"), "cc::LayerTreeHostImpl", this, - TracedValue::FromValue(AsValue().release())); + TRACE_DISABLED_BY_DEFAULT("cc.debug") "," + TRACE_DISABLED_BY_DEFAULT("cc.debug.quads"), "cc::LayerTreeHostImpl", + this, TracedValue::FromValue(AsValueWithFrame(frame).release())); // Because the contents of the HUD depend on everything else in the frame, the // contents of its texture are updated as the last thing before the frame is @@ -2136,6 +2157,7 @@ void LayerTreeHostImpl::PinchGestureBegin() { pinch_gesture_active_ = true; previous_pinch_anchor_ = gfx::Point(); client_->RenewTreePriority(); + active_tree_->SetCurrentlyScrollingLayer(RootScrollLayer()); } void LayerTreeHostImpl::PinchGestureUpdate(float magnify_delta, @@ -2430,7 +2452,8 @@ base::TimeTicks LayerTreeHostImpl::CurrentPhysicalTimeTicks() const { return base::TimeTicks::Now(); } -scoped_ptr<base::Value> LayerTreeHostImpl::AsValue() const { +scoped_ptr<base::Value> LayerTreeHostImpl::AsValueWithFrame( + FrameData* frame) const { scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); if (this->pending_tree_) state->Set("activation_state", ActivationStateAsValue().release()); @@ -2441,6 +2464,8 @@ scoped_ptr<base::Value> LayerTreeHostImpl::AsValue() const { state->Set("active_tree", active_tree_->AsValue().release()); if (pending_tree_) state->Set("pending_tree", pending_tree_->AsValue().release()); + if (frame) + state->Set("frame", frame->AsValue().release()); return state.PassAs<base::Value>(); } diff --git a/cc/trees/layer_tree_host_impl.h b/cc/trees/layer_tree_host_impl.h index ae6f3c1cad..31870ac48b 100644 --- a/cc/trees/layer_tree_host_impl.h +++ b/cc/trees/layer_tree_host_impl.h @@ -139,6 +139,7 @@ class CC_EXPORT LayerTreeHostImpl struct CC_EXPORT FrameData : public RenderPassSink { FrameData(); virtual ~FrameData(); + scoped_ptr<base::Value> AsValue() const; std::vector<gfx::Rect> occluding_screen_space_rects; std::vector<gfx::Rect> non_occluding_screen_space_rects; @@ -371,7 +372,8 @@ class CC_EXPORT LayerTreeHostImpl virtual base::TimeTicks CurrentPhysicalTimeTicks() const; - scoped_ptr<base::Value> AsValue() const; + scoped_ptr<base::Value> AsValue() const { return AsValueWithFrame(NULL); } + scoped_ptr<base::Value> AsValueWithFrame(FrameData* frame) const; scoped_ptr<base::Value> ActivationStateAsValue() const; bool page_scale_animation_active() const { return !!page_scale_animation_; } diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc index 72a72b4552..ab81c672b8 100644 --- a/cc/trees/layer_tree_host_impl_unittest.cc +++ b/cc/trees/layer_tree_host_impl_unittest.cc @@ -770,9 +770,10 @@ TEST_F(LayerTreeHostImplTest, ImplPinchZoom) { scroll_layer->SetScrollDelta(gfx::Vector2d()); float page_scale_delta = 2.f; - host_impl_->PinchGestureBegin(); + host_impl_->ScrollBegin(gfx::Point(50, 50), InputHandler::Gesture); host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point(50, 50)); host_impl_->PinchGestureEnd(); + host_impl_->ScrollEnd(); EXPECT_TRUE(did_request_redraw_); EXPECT_TRUE(did_request_commit_); @@ -794,9 +795,11 @@ TEST_F(LayerTreeHostImplTest, ImplPinchZoom) { scroll_layer->SetScrollDelta(gfx::Vector2d()); float page_scale_delta = 2.f; + host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture); host_impl_->PinchGestureBegin(); host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point()); host_impl_->PinchGestureEnd(); + host_impl_->ScrollEnd(); gfx::Vector2d scroll_delta(0, 10); EXPECT_EQ(InputHandler::ScrollStarted, @@ -832,9 +835,11 @@ TEST_F(LayerTreeHostImplTest, PinchGesture) { scroll_layer->SetScrollDelta(gfx::Vector2d()); float page_scale_delta = 2.f; + host_impl_->ScrollBegin(gfx::Point(50, 50), InputHandler::Gesture); host_impl_->PinchGestureBegin(); host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point(50, 50)); host_impl_->PinchGestureEnd(); + host_impl_->ScrollEnd(); EXPECT_TRUE(did_request_redraw_); EXPECT_TRUE(did_request_commit_); @@ -851,9 +856,11 @@ TEST_F(LayerTreeHostImplTest, PinchGesture) { scroll_layer->SetScrollDelta(gfx::Vector2d()); float page_scale_delta = 10.f; + host_impl_->ScrollBegin(gfx::Point(50, 50), InputHandler::Gesture); host_impl_->PinchGestureBegin(); host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point(50, 50)); host_impl_->PinchGestureEnd(); + host_impl_->ScrollEnd(); scoped_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); @@ -869,9 +876,11 @@ TEST_F(LayerTreeHostImplTest, PinchGesture) { scroll_layer->SetScrollOffset(gfx::Vector2d(50, 50)); float page_scale_delta = 0.1f; + host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture); host_impl_->PinchGestureBegin(); host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point()); host_impl_->PinchGestureEnd(); + host_impl_->ScrollEnd(); scoped_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); @@ -889,10 +898,12 @@ TEST_F(LayerTreeHostImplTest, PinchGesture) { scroll_layer->SetScrollOffset(gfx::Vector2d(20, 20)); float page_scale_delta = 1.f; + host_impl_->ScrollBegin(gfx::Point(10, 10), InputHandler::Gesture); host_impl_->PinchGestureBegin(); host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point(10, 10)); host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point(20, 20)); host_impl_->PinchGestureEnd(); + host_impl_->ScrollEnd(); scoped_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); @@ -909,7 +920,7 @@ TEST_F(LayerTreeHostImplTest, PinchGesture) { scroll_layer->SetScrollOffset(gfx::Vector2d(20, 20)); float page_scale_delta = 1.f; - host_impl_->ScrollBegin(gfx::Point(10, 10), InputHandler::Wheel); + host_impl_->ScrollBegin(gfx::Point(10, 10), InputHandler::Gesture); host_impl_->PinchGestureBegin(); host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point(10, 10)); host_impl_->ScrollBy(gfx::Point(10, 10), gfx::Vector2d(-10, -10)); @@ -922,6 +933,30 @@ TEST_F(LayerTreeHostImplTest, PinchGesture) { EXPECT_EQ(scroll_info->page_scale_delta, page_scale_delta); ExpectContains(*scroll_info, scroll_layer->id(), gfx::Vector2d(-10, -10)); } + + // Two-finger panning should work when starting fully zoomed out. + { + host_impl_->active_tree()->SetPageScaleFactorAndLimits(0.5f, + 0.5f, + 4.f); + scroll_layer->SetScrollDelta(gfx::Vector2d()); + scroll_layer->SetScrollOffset(gfx::Vector2d(0, 0)); + host_impl_->active_tree()->UpdateMaxScrollOffset(); + + host_impl_->ScrollBegin(gfx::Point(0, 0), InputHandler::Gesture); + host_impl_->PinchGestureBegin(); + host_impl_->PinchGestureUpdate(2.f, gfx::Point(0, 0)); + host_impl_->PinchGestureUpdate(1.f, gfx::Point(0, 0)); + host_impl_->ScrollBy(gfx::Point(0, 0), gfx::Vector2d(10, 10)); + host_impl_->PinchGestureUpdate(1.f, gfx::Point(10, 10)); + host_impl_->PinchGestureEnd(); + host_impl_->ScrollEnd(); + + scoped_ptr<ScrollAndScaleSet> scroll_info = + host_impl_->ProcessScrollDeltas(); + EXPECT_EQ(scroll_info->page_scale_delta, 2.f); + ExpectContains(*scroll_info, scroll_layer->id(), gfx::Vector2d(20, 20)); + } } TEST_F(LayerTreeHostImplTest, PageScaleAnimation) { @@ -1184,9 +1219,11 @@ TEST_F(LayerTreeHostImplTest, CompositorFrameMetadata) { } // Page scale should update metadata correctly (shrinking only the viewport). + host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture); host_impl_->PinchGestureBegin(); host_impl_->PinchGestureUpdate(2.f, gfx::Point()); host_impl_->PinchGestureEnd(); + host_impl_->ScrollEnd(); { CompositorFrameMetadata metadata = host_impl_->MakeCompositorFrameMetadata(); @@ -1789,9 +1826,11 @@ TEST_F(LayerTreeHostImplTest, ScrollRootAndChangePageScaleOnImplThread) { host_impl_->ScrollEnd(); // Set new page scale on impl thread by pinching. + host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture); host_impl_->PinchGestureBegin(); host_impl_->PinchGestureUpdate(page_scale, gfx::Point()); host_impl_->PinchGestureEnd(); + host_impl_->ScrollEnd(); DrawOneFrame(); // The scroll delta is not scaled because the main thread did not scale. @@ -1826,9 +1865,11 @@ TEST_F(LayerTreeHostImplTest, PageScaleDeltaAppliedToRootScrollLayerOnly) { LayerImpl* grand_child = child->children()[0]; // Set new page scale on impl thread by pinching. + host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture); host_impl_->PinchGestureBegin(); host_impl_->PinchGestureUpdate(new_page_scale, gfx::Point()); host_impl_->PinchGestureEnd(); + host_impl_->ScrollEnd(); DrawOneFrame(); EXPECT_EQ(1.f, root->contents_scale_x()); diff --git a/cc/trees/layer_tree_host_unittest_delegated.cc b/cc/trees/layer_tree_host_unittest_delegated.cc index 08ba3e0610..d48931328a 100644 --- a/cc/trees/layer_tree_host_unittest_delegated.cc +++ b/cc/trees/layer_tree_host_unittest_delegated.cc @@ -4,14 +4,18 @@ #include "cc/trees/layer_tree_host.h" +#include "base/bind.h" #include "cc/layers/delegated_renderer_layer.h" #include "cc/layers/delegated_renderer_layer_client.h" #include "cc/layers/delegated_renderer_layer_impl.h" +#include "cc/output/compositor_frame.h" +#include "cc/output/compositor_frame_ack.h" #include "cc/output/delegated_frame_data.h" #include "cc/quads/shared_quad_state.h" #include "cc/quads/texture_draw_quad.h" #include "cc/test/fake_delegated_renderer_layer.h" #include "cc/test/fake_delegated_renderer_layer_impl.h" +#include "cc/test/fake_output_surface.h" #include "cc/test/layer_tree_test.h" #include "cc/trees/layer_tree_impl.h" #include "gpu/GLES2/gl2extchromium.h" @@ -35,6 +39,49 @@ class LayerTreeHostDelegatedTest : public LayerTreeTest { return frame.Pass(); } + scoped_ptr<DelegatedFrameData> CreateInvalidFrameData( + gfx::Rect root_output_rect, + gfx::Rect root_damage_rect) { + scoped_ptr<DelegatedFrameData> frame(new DelegatedFrameData); + + scoped_ptr<RenderPass> root_pass(RenderPass::Create()); + root_pass->SetNew(RenderPass::Id(1, 1), + root_output_rect, + root_damage_rect, + gfx::Transform()); + + scoped_ptr<SharedQuadState> shared_quad_state = SharedQuadState::Create(); + + gfx::Rect rect = root_output_rect; + gfx::Rect opaque_rect = root_output_rect; + // An invalid resource id! The resource isn't part of the frame. + unsigned resource_id = 5; + bool premultiplied_alpha = false; + gfx::PointF uv_top_left = gfx::PointF(0.f, 0.f); + gfx::PointF uv_bottom_right = gfx::PointF(1.f, 1.f); + SkColor background_color = 0; + float vertex_opacity[4] = {1.f, 1.f, 1.f, 1.f}; + bool flipped = false; + + scoped_ptr<TextureDrawQuad> invalid_draw_quad = TextureDrawQuad::Create(); + invalid_draw_quad->SetNew(shared_quad_state.get(), + rect, + opaque_rect, + resource_id, + premultiplied_alpha, + uv_top_left, + uv_bottom_right, + background_color, + vertex_opacity, + flipped); + root_pass->quad_list.push_back(invalid_draw_quad.PassAs<DrawQuad>()); + + root_pass->shared_quad_state_list.push_back(shared_quad_state.Pass()); + + frame->render_pass_list.push_back(root_pass.Pass()); + return frame.Pass(); + } + void AddTransferableResource(DelegatedFrameData* frame, ResourceProvider::ResourceId resource_id) { TransferableResource resource; @@ -65,6 +112,54 @@ class LayerTreeHostDelegatedTest : public LayerTreeTest { scoped_ptr<DelegatedFrameData> frame(new DelegatedFrameData); return frame.Pass(); } + + + static ResourceProvider::ResourceId AppendResourceId( + std::vector<ResourceProvider::ResourceId>* resources_in_last_sent_frame, + ResourceProvider::ResourceId resource_id) { + resources_in_last_sent_frame->push_back(resource_id); + return resource_id; + } + + void ReturnUnusedResourcesFromParent(LayerTreeHostImpl* host_impl) { + DelegatedFrameData* delegated_frame_data = + output_surface()->last_sent_frame().delegated_frame_data.get(); + if (!delegated_frame_data) + return; + + std::vector<ResourceProvider::ResourceId> resources_in_last_sent_frame; + for (size_t i = 0; i < delegated_frame_data->render_pass_list.size(); ++i) { + RenderPass* pass = delegated_frame_data->render_pass_list.at(i); + for (size_t j = 0; j < pass->quad_list.size(); ++j) { + DrawQuad* quad = pass->quad_list[j]; + quad->IterateResources(base::Bind(&AppendResourceId, + &resources_in_last_sent_frame)); + } + } + + std::vector<ResourceProvider::ResourceId> resources_to_return; + + const TransferableResourceArray& resources_held_by_parent = + output_surface()->resources_held_by_parent(); + for (size_t i = 0; i < resources_held_by_parent.size(); ++i) { + ResourceProvider::ResourceId resource_in_parent = + resources_held_by_parent[i].id; + bool resource_in_parent_is_not_part_of_frame = + std::find(resources_in_last_sent_frame.begin(), + resources_in_last_sent_frame.end(), + resource_in_parent) == resources_in_last_sent_frame.end(); + if (resource_in_parent_is_not_part_of_frame) + resources_to_return.push_back(resource_in_parent); + } + + if (resources_to_return.empty()) + return; + + CompositorFrameAck ack; + for (size_t i = 0; i < resources_to_return.size(); ++i) + output_surface()->ReturnResource(resources_to_return[i], &ack); + host_impl->OnSwapBuffersComplete(&ack); + } }; class LayerTreeHostDelegatedTestCaseSingleDelegatedLayer @@ -267,13 +362,18 @@ class LayerTreeHostDelegatedTestLayerUsesFrameDamage gfx::Rect(5, 5, 1, 1))); break; case 13: + // An invalid frame isn't used, so it should not cause damage. + delegated_->SetFrameData(CreateInvalidFrameData(gfx::Rect(0, 0, 10, 10), + gfx::Rect(5, 5, 1, 1))); + break; + case 14: // Should create gfx::Rect(1, 1, 2, 2) of damage. The frame size is // 5x5 and the display size is now set to 10x10, so this should result // in a gfx::Rect(2, 2, 4, 4) damage rect. delegated_->SetFrameData(CreateFrameData(gfx::Rect(0, 0, 5, 5), gfx::Rect(1, 1, 2, 2))); break; - case 14: + case 15: // Should create zero damage. layer_tree_host()->SetNeedsCommit(); break; @@ -352,10 +452,14 @@ class LayerTreeHostDelegatedTestLayerUsesFrameDamage damage_rect.ToString()); break; case 13: - EXPECT_EQ(gfx::RectF(2.f, 2.f, 4.f, 4.f).ToString(), + EXPECT_EQ(gfx::RectF(0.f, 0.f, 0.f, 0.f).ToString(), damage_rect.ToString()); break; case 14: + EXPECT_EQ(gfx::RectF(2.f, 2.f, 4.f, 4.f).ToString(), + damage_rect.ToString()); + break; + case 15: EXPECT_EQ(gfx::RectF(0.f, 0.f, 0.f, 0.f).ToString(), damage_rect.ToString()); EndTest(); @@ -479,7 +583,7 @@ class LayerTreeHostDelegatedTestReturnUnusedResources PostSetNeedsCommitToMainThread(); } - virtual void DidCommit() OVERRIDE { + virtual void DidCommitAndDrawFrame() OVERRIDE { scoped_ptr<DelegatedFrameData> frame; TransferableResourceArray resources; @@ -495,6 +599,11 @@ class LayerTreeHostDelegatedTestReturnUnusedResources delegated_->SetFrameData(frame.Pass()); break; case 2: + // Retrieve unused resources to the main thread. + // TODO(danakj): Shouldn't need to commit to get resources. + layer_tree_host()->SetNeedsCommit(); + return; + case 3: // All of the resources are in use. delegated_->TakeUnusedResourcesForChildCompositor(&resources); EXPECT_EQ(0u, resources.size()); @@ -506,7 +615,12 @@ class LayerTreeHostDelegatedTestReturnUnusedResources AddTransferableResource(frame.get(), 444); delegated_->SetFrameData(frame.Pass()); break; - case 3: + case 4: + // Retrieve unused resources to the main thread. + // TODO(danakj): Shouldn't need to commit to get resources. + layer_tree_host()->SetNeedsCommit(); + return; + case 5: // 555 is no longer in use. delegated_->TakeUnusedResourcesForChildCompositor(&resources); EXPECT_EQ(1u, resources.size()); @@ -516,7 +630,12 @@ class LayerTreeHostDelegatedTestReturnUnusedResources frame = CreateFrameData(gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1)); delegated_->SetFrameData(frame.Pass()); break; - case 4: + case 6: + // Postpone collecting resources for a frame. They should still be there + // the next frame. + layer_tree_host()->SetNeedsCommit(); + return; + case 7: // 444 and 999 are no longer in use. delegated_->TakeUnusedResourcesForChildCompositor(&resources); EXPECT_EQ(2u, resources.size()); @@ -537,11 +656,15 @@ class LayerTreeHostDelegatedTestReturnUnusedResources EXPECT_TRUE(empty_resources.empty()); } + virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, + bool result) OVERRIDE { + ReturnUnusedResourcesFromParent(host_impl); + } + virtual void AfterTest() OVERRIDE {} }; -// Enable this for delegating renderer. crbug.com/239290 -SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F( +SINGLE_AND_MULTI_THREAD_TEST_F( LayerTreeHostDelegatedTestReturnUnusedResources); class LayerTreeHostDelegatedTestReusedResources @@ -551,7 +674,7 @@ class LayerTreeHostDelegatedTestReusedResources PostSetNeedsCommitToMainThread(); } - virtual void DidCommit() OVERRIDE { + virtual void DidCommitAndDrawFrame() OVERRIDE { scoped_ptr<DelegatedFrameData> frame; TransferableResourceArray resources; @@ -569,6 +692,11 @@ class LayerTreeHostDelegatedTestReusedResources delegated_->SetFrameData(frame.Pass()); break; case 2: + // Retrieve unused resources to the main thread. + // TODO(danakj): Shouldn't need to commit to get resources. + layer_tree_host()->SetNeedsCommit(); + return; + case 3: // All of the resources are in use. delegated_->TakeUnusedResourcesForChildCompositor(&resources); EXPECT_EQ(0u, resources.size()); @@ -588,7 +716,12 @@ class LayerTreeHostDelegatedTestReusedResources AddTextureQuad(frame.get(), 444); delegated_->SetFrameData(frame.Pass()); break; - case 3: + case 4: + // Retrieve unused resources to the main thread. + // TODO(danakj): Shouldn't need to commit to get resources. + layer_tree_host()->SetNeedsCommit(); + return; + case 5: // The 999 resource is the only unused one. delegated_->TakeUnusedResourcesForChildCompositor(&resources); EXPECT_EQ(1u, resources.size()); @@ -598,12 +731,15 @@ class LayerTreeHostDelegatedTestReusedResources } } + virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, + bool result) OVERRIDE { + ReturnUnusedResourcesFromParent(host_impl); + } + virtual void AfterTest() OVERRIDE {} }; -// Enable this for delegating renderer. crbug.com/239290 -SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F( - LayerTreeHostDelegatedTestReusedResources); +SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestReusedResources); class LayerTreeHostDelegatedTestFrameBeforeAck : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer { @@ -612,7 +748,7 @@ class LayerTreeHostDelegatedTestFrameBeforeAck PostSetNeedsCommitToMainThread(); } - virtual void DidCommit() OVERRIDE { + virtual void DidCommitAndDrawFrame() OVERRIDE { scoped_ptr<DelegatedFrameData> frame; TransferableResourceArray resources; @@ -630,6 +766,11 @@ class LayerTreeHostDelegatedTestFrameBeforeAck delegated_->SetFrameData(frame.Pass()); break; case 2: + // Retrieve unused resources to the main thread. + // TODO(danakj): Shouldn't need to commit to get resources. + layer_tree_host()->SetNeedsCommit(); + return; + case 3: // All of the resources are in use. delegated_->TakeUnusedResourcesForChildCompositor(&resources); EXPECT_EQ(0u, resources.size()); @@ -645,7 +786,12 @@ class LayerTreeHostDelegatedTestFrameBeforeAck // The parent compositor (this one) does a commit. break; - case 3: + case 4: + // Retrieve unused resources to the main thread. + // TODO(danakj): Shouldn't need to commit to get resources. + layer_tree_host()->SetNeedsCommit(); + return; + case 5: delegated_->TakeUnusedResourcesForChildCompositor(&resources); EXPECT_EQ(2u, resources.size()); if (resources[0].id == 555) { @@ -668,7 +814,7 @@ class LayerTreeHostDelegatedTestFrameBeforeAck } virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { - if (host_impl->active_tree()->source_frame_number() != 3) + if (host_impl->active_tree()->source_frame_number() != 5) return; LayerImpl* root_impl = host_impl->active_tree()->root_layer(); @@ -697,12 +843,15 @@ class LayerTreeHostDelegatedTestFrameBeforeAck EndTest(); } + virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, + bool result) OVERRIDE { + ReturnUnusedResourcesFromParent(host_impl); + } + virtual void AfterTest() OVERRIDE {} }; -// Enable this for delegating renderer. crbug.com/239290 -SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F( - LayerTreeHostDelegatedTestFrameBeforeAck); +SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestFrameBeforeAck); class LayerTreeHostDelegatedTestFrameBeforeTakeResources : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer { @@ -711,7 +860,7 @@ class LayerTreeHostDelegatedTestFrameBeforeTakeResources PostSetNeedsCommitToMainThread(); } - virtual void DidCommit() OVERRIDE { + virtual void DidCommitAndDrawFrame() OVERRIDE { scoped_ptr<DelegatedFrameData> frame; TransferableResourceArray resources; @@ -729,6 +878,11 @@ class LayerTreeHostDelegatedTestFrameBeforeTakeResources delegated_->SetFrameData(frame.Pass()); break; case 2: + // Retrieve unused resources to the main thread. + // TODO(danakj): Shouldn't need to commit to get resources. + layer_tree_host()->SetNeedsCommit(); + return; + case 3: // All of the resources are in use. delegated_->TakeUnusedResourcesForChildCompositor(&resources); EXPECT_EQ(0u, resources.size()); @@ -744,7 +898,12 @@ class LayerTreeHostDelegatedTestFrameBeforeTakeResources // The parent compositor (this one) does a commit. break; - case 3: + case 4: + // Retrieve unused resources to the main thread. + // TODO(danakj): Shouldn't need to commit to get resources. + layer_tree_host()->SetNeedsCommit(); + return; + case 5: // The child compositor sends a frame before taking resources back // from the previous commit. This frame makes use of the resources 555 // and 444, which were just released during commit. @@ -758,7 +917,12 @@ class LayerTreeHostDelegatedTestFrameBeforeTakeResources delegated_->TakeUnusedResourcesForChildCompositor(&resources); EXPECT_EQ(0u, resources.size()); break; - case 4: + case 6: + // Retrieve unused resources to the main thread. + // TODO(danakj): Shouldn't need to commit to get resources. + layer_tree_host()->SetNeedsCommit(); + return; + case 7: delegated_->TakeUnusedResourcesForChildCompositor(&resources); EXPECT_EQ(0u, resources.size()); EndTest(); @@ -767,7 +931,7 @@ class LayerTreeHostDelegatedTestFrameBeforeTakeResources } virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { - if (host_impl->active_tree()->source_frame_number() != 3) + if (host_impl->active_tree()->source_frame_number() != 5) return; LayerImpl* root_impl = host_impl->active_tree()->root_layer(); @@ -803,11 +967,15 @@ class LayerTreeHostDelegatedTestFrameBeforeTakeResources EXPECT_EQ(map.find(444)->second, quad3->resource_id); } + virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, + bool result) OVERRIDE { + ReturnUnusedResourcesFromParent(host_impl); + } + virtual void AfterTest() OVERRIDE {} }; -// Enable this for delegating renderer. crbug.com/239290 -SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F( +SINGLE_AND_MULTI_THREAD_TEST_F( LayerTreeHostDelegatedTestFrameBeforeTakeResources); class LayerTreeHostDelegatedTestBadFrame @@ -817,7 +985,7 @@ class LayerTreeHostDelegatedTestBadFrame PostSetNeedsCommitToMainThread(); } - virtual void DidCommit() OVERRIDE { + virtual void DidCommitAndDrawFrame() OVERRIDE { scoped_ptr<DelegatedFrameData> frame; TransferableResourceArray resources; @@ -833,6 +1001,11 @@ class LayerTreeHostDelegatedTestBadFrame delegated_->SetFrameData(frame.Pass()); break; case 2: + // Retrieve unused resources to the main thread. + // TODO(danakj): Shouldn't need to commit to get resources. + layer_tree_host()->SetNeedsCommit(); + return; + case 3: // All of the resources are in use. delegated_->TakeUnusedResourcesForChildCompositor(&resources); EXPECT_EQ(0u, resources.size()); @@ -851,7 +1024,12 @@ class LayerTreeHostDelegatedTestBadFrame // The parent compositor (this one) does a commit. break; - case 3: + case 4: + // Retrieve unused resources to the main thread. + // TODO(danakj): Shouldn't need to commit to get resources. + layer_tree_host()->SetNeedsCommit(); + return; + case 5: // The bad frame's resource is given back to the child compositor. delegated_->TakeUnusedResourcesForChildCompositor(&resources); EXPECT_EQ(1u, resources.size()); @@ -862,7 +1040,12 @@ class LayerTreeHostDelegatedTestBadFrame AddTextureQuad(frame.get(), 999); delegated_->SetFrameData(frame.Pass()); break; - case 4: + case 6: + // Retrieve unused resources to the main thread. + // TODO(danakj): Shouldn't need to commit to get resources. + layer_tree_host()->SetNeedsCommit(); + return; + case 7: // The unused 555 from the last good frame is now released. delegated_->TakeUnusedResourcesForChildCompositor(&resources); EXPECT_EQ(1u, resources.size()); @@ -873,10 +1056,13 @@ class LayerTreeHostDelegatedTestBadFrame } } - virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { + virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, + bool result) OVERRIDE { if (host_impl->active_tree()->source_frame_number() < 1) return; + ReturnUnusedResourcesFromParent(host_impl); + LayerImpl* root_impl = host_impl->active_tree()->root_layer(); FakeDelegatedRendererLayerImpl* delegated_impl = static_cast<FakeDelegatedRendererLayerImpl*>(root_impl->children()[0]); @@ -907,7 +1093,7 @@ class LayerTreeHostDelegatedTestBadFrame EXPECT_EQ(map.find(555)->second, quad2->resource_id); break; } - case 2: { + case 3: { // We only keep resources from the last valid frame. EXPECT_EQ(2u, map.size()); EXPECT_EQ(1u, map.count(999)); @@ -929,7 +1115,14 @@ class LayerTreeHostDelegatedTestBadFrame EXPECT_EQ(map.find(555)->second, quad2->resource_id); break; } - case 3: { + case 5: + // Resources given to our parent compositor will be returned now, but + // the DelegatedRendererLayerImpl doesn't know about it until the next + // commit. + // TODO(danakj): Shouldn't need a commit to return resources to the + // DelegatedRendererLayerImpl or to the main thread. + break; + case 6: { // We have the new good frame with just 999 in it. EXPECT_EQ(1u, map.size()); EXPECT_EQ(1u, map.count(999)); @@ -950,9 +1143,7 @@ class LayerTreeHostDelegatedTestBadFrame virtual void AfterTest() OVERRIDE {} }; -// Enable this for delegating renderer. crbug.com/239290 -SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F( - LayerTreeHostDelegatedTestBadFrame); +SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestBadFrame); class LayerTreeHostDelegatedTestUnnamedResource : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer { @@ -1077,13 +1268,7 @@ SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestDontLeakResource); class LayerTreeHostDelegatedTestResourceSentToParent : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer { public: - virtual void BeginTest() OVERRIDE { - // Prevent drawing with resources that are sent to the grandparent. - layer_tree_host()->SetViewportSize(gfx::Size()); - PostSetNeedsCommitToMainThread(); - } - - virtual void DidCommit() OVERRIDE { + virtual void DidCommitAndDrawFrame() OVERRIDE { scoped_ptr<DelegatedFrameData> frame; TransferableResourceArray resources; @@ -1113,6 +1298,8 @@ class LayerTreeHostDelegatedTestResourceSentToParent delegated_->TakeUnusedResourcesForChildCompositor(&resources); EXPECT_EQ(0u, resources.size()); + // The impl side will get back the resource at some point. + // TODO(danakj): The test should work without this. layer_tree_host()->SetNeedsCommit(); break; case 4: @@ -1148,15 +1335,7 @@ class LayerTreeHostDelegatedTestResourceSentToParent EXPECT_EQ(1u, delegated_impl->Resources().count(map.find(999)->second)); EXPECT_EQ(1u, delegated_impl->Resources().count(map.find(555)->second)); - // The 999 resource is sent to a grandparent compositor. - ResourceProvider::ResourceIdArray resources_for_parent; - resources_for_parent.push_back(map.find(999)->second); - TransferableResourceArray transferable_resources; - host_impl->resource_provider()->PrepareSendToParent( - resources_for_parent, &transferable_resources); - - resource_in_grandparent = transferable_resources[0]; - EXPECT_EQ(map.find(999)->second, resource_in_grandparent.id); + // The 999 resource will be sent to a grandparent compositor. break; } case 2: { @@ -1164,17 +1343,14 @@ class LayerTreeHostDelegatedTestResourceSentToParent EXPECT_EQ(1u, map.count(999)); EXPECT_EQ(1u, map.count(555)); - /// 999 is in the parent, so not held by delegated renderer layer. + // 999 is in the parent, so not held by delegated renderer layer. EXPECT_EQ(1u, delegated_impl->Resources().size()); EXPECT_EQ(1u, delegated_impl->Resources().count(map.find(555)->second)); // Receive 999 back from the grandparent. - EXPECT_EQ(map.find(999)->second, resource_in_grandparent.id); - TransferableResourceArray transferable_resources; - transferable_resources.push_back(resource_in_grandparent); - - host_impl->resource_provider()->ReceiveFromParent( - transferable_resources); + CompositorFrameAck ack; + output_surface()->ReturnResource(map.find(999)->second, &ack); + host_impl->OnSwapBuffersComplete(&ack); break; } case 3: @@ -1184,6 +1360,7 @@ class LayerTreeHostDelegatedTestResourceSentToParent EXPECT_EQ(1u, delegated_impl->Resources().size()); EXPECT_EQ(1u, delegated_impl->Resources().count(map.find(555)->second)); + break; } } @@ -1192,7 +1369,8 @@ class LayerTreeHostDelegatedTestResourceSentToParent TransferableResource resource_in_grandparent; }; -SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestResourceSentToParent); +SINGLE_AND_MULTI_THREAD_DELEGATING_RENDERER_TEST_F( + LayerTreeHostDelegatedTestResourceSentToParent); class LayerTreeHostDelegatedTestCommitWithoutTake : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer { diff --git a/cc/trees/thread_proxy.cc b/cc/trees/thread_proxy.cc index 57057884d9..a0bd4bf5a7 100644 --- a/cc/trees/thread_proxy.cc +++ b/cc/trees/thread_proxy.cc @@ -112,7 +112,11 @@ bool ThreadProxy::CompositeAndReadback(void* pixels, gfx::Rect rect) { TRACE_EVENT0("cc", "ThreadProxy::CompositeAndReadback"); DCHECK(IsMainThread()); DCHECK(layer_tree_host_); - DCHECK(!defer_commits_); + + if (defer_commits_) { + TRACE_EVENT0("cc", "CompositeAndReadback_DeferCommit"); + return false; + } if (!layer_tree_host_->InitializeOutputSurfaceIfNeeded()) { TRACE_EVENT0("cc", "CompositeAndReadback_EarlyOut_LR_Uninitialized"); |