#include <algorithm>
+#include "base/atomic_sequence_num.h"
#include "base/debug/trace_event.h"
#include "base/location.h"
#include "base/metrics/histogram.h"
#include "base/single_thread_task_runner.h"
+#include "base/time/time.h"
#include "cc/animation/animation.h"
#include "cc/animation/animation_events.h"
+#include "cc/animation/animation_registrar.h"
+#include "cc/animation/keyframed_animation_curve.h"
#include "cc/animation/layer_animation_controller.h"
#include "cc/layers/layer_client.h"
#include "cc/layers/layer_impl.h"
+#include "cc/layers/scrollbar_layer_interface.h"
#include "cc/output/copy_output_request.h"
#include "cc/output/copy_output_result.h"
#include "cc/trees/layer_tree_host.h"
#include "cc/trees/layer_tree_impl.h"
#include "third_party/skia/include/core/SkImageFilter.h"
+#include "ui/gfx/geometry/vector2d_conversions.h"
#include "ui/gfx/rect_conversions.h"
namespace cc {
-static int s_next_layer_id = 1;
+base::StaticAtomicSequenceNumber g_next_layer_id;
scoped_refptr<Layer> Layer::Create() {
return make_scoped_refptr(new Layer());
: needs_push_properties_(false),
num_dependents_need_push_properties_(false),
stacking_order_changed_(false),
- layer_id_(s_next_layer_id++),
+ // Layer IDs start from 1.
+ layer_id_(g_next_layer_id.GetNext() + 1),
ignore_set_needs_commit_(false),
+ sorting_context_id_(0),
parent_(NULL),
layer_tree_host_(NULL),
- scrollable_(false),
+ scroll_clip_layer_id_(INVALID_ID),
+ num_descendants_that_draw_content_(0),
should_scroll_on_main_thread_(false),
have_wheel_event_handlers_(false),
+ have_scroll_event_handlers_(false),
user_scrollable_horizontal_(true),
user_scrollable_vertical_(true),
- anchor_point_(0.5f, 0.5f),
- background_color_(0),
- compositing_reasons_(kCompositingReasonUnknown),
- opacity_(1.f),
- anchor_point_z_(0.f),
+ is_root_for_isolated_group_(false),
is_container_for_fixed_position_layers_(false),
is_drawable_(false),
+ draws_content_(false),
hide_layer_and_subtree_(false),
masks_to_bounds_(false),
contents_opaque_(false),
double_sided_(true),
- preserves_3d_(false),
+ should_flatten_transform_(true),
use_parent_backface_visibility_(false),
draw_checkerboard_for_missing_tiles_(false),
force_render_surface_(false),
+ transform_is_invertible_(true),
+ background_color_(0),
+ opacity_(1.f),
+ blend_mode_(SkXfermode::kSrcOver_Mode),
scroll_parent_(NULL),
clip_parent_(NULL),
replica_layer_(NULL),
raster_scale_(0.f),
client_(NULL) {
- if (layer_id_ < 0) {
- s_next_layer_id = 1;
- layer_id_ = s_next_layer_id++;
- }
-
layer_animation_controller_ = LayerAnimationController::Create(layer_id_);
layer_animation_controller_->AddValueObserver(this);
+ layer_animation_controller_->set_value_provider(this);
}
Layer::~Layer() {
DCHECK(!layer_tree_host());
layer_animation_controller_->RemoveValueObserver(this);
+ layer_animation_controller_->remove_value_provider(this);
+
+ RemoveFromScrollTree();
+ RemoveFromClipTree();
// Remove the parent reference from all children and dependents.
RemoveAllChildren();
DCHECK_EQ(this, replica_layer_->parent());
replica_layer_->RemoveFromParent();
}
-
- RemoveFromScrollTree();
- RemoveFromClipTree();
}
void Layer::SetLayerTreeHost(LayerTreeHost* host) {
if (host && layer_animation_controller_->has_any_animation())
host->SetNeedsCommit();
- if (host && (!filters_.IsEmpty() || !background_filters_.IsEmpty()))
- layer_tree_host_->set_needs_filter_context();
}
void Layer::SetNeedsUpdate() {
void Layer::InsertChild(scoped_refptr<Layer> child, size_t index) {
DCHECK(IsPropertyChangeAllowed());
child->RemoveFromParent();
+ AddDrawableDescendants(child->NumDescendantsThatDrawContent() +
+ (child->DrawsContent() ? 1 : 0));
child->SetParent(this);
child->stacking_order_changed_ = true;
continue;
child->SetParent(NULL);
+ AddDrawableDescendants(-child->NumDescendantsThatDrawContent() -
+ (child->DrawsContent() ? 1 : 0));
children_.erase(iter);
SetNeedsFullTreeSync();
return;
return -1;
}
-void Layer::SetBounds(gfx::Size size) {
+void Layer::SetBounds(const gfx::Size& size) {
DCHECK(IsPropertyChangeAllowed());
if (bounds() == size)
return;
SetNeedsCommit();
}
-void Layer::SetAnchorPoint(gfx::PointF anchor_point) {
- DCHECK(IsPropertyChangeAllowed());
- if (anchor_point_ == anchor_point)
- return;
- anchor_point_ = anchor_point;
- SetNeedsCommit();
-}
-
-void Layer::SetAnchorPointZ(float anchor_point_z) {
- DCHECK(IsPropertyChangeAllowed());
- if (anchor_point_z_ == anchor_point_z)
- return;
- anchor_point_z_ = anchor_point_z;
- SetNeedsCommit();
-}
-
void Layer::SetBackgroundColor(SkColor background_color) {
DCHECK(IsPropertyChangeAllowed());
if (background_color_ == background_color)
return color;
}
-void Layer::CalculateContentsScale(
- float ideal_contents_scale,
- float device_scale_factor,
- float page_scale_factor,
- bool animating_transform_to_screen,
- float* contents_scale_x,
- float* contents_scale_y,
- gfx::Size* content_bounds) {
+void Layer::CalculateContentsScale(float ideal_contents_scale,
+ float* contents_scale_x,
+ float* contents_scale_y,
+ gfx::Size* content_bounds) {
DCHECK(layer_tree_host_);
*contents_scale_x = 1;
return;
filters_ = filters;
SetNeedsCommit();
- if (!filters.IsEmpty() && layer_tree_host_)
- layer_tree_host_->set_needs_filter_context();
}
bool Layer::FilterIsAnimating() const {
return;
background_filters_ = filters;
SetNeedsCommit();
- if (!filters.IsEmpty() && layer_tree_host_)
- layer_tree_host_->set_needs_filter_context();
}
void Layer::SetOpacity(float opacity) {
return false;
}
+void Layer::SetBlendMode(SkXfermode::Mode blend_mode) {
+ DCHECK(IsPropertyChangeAllowed());
+ if (blend_mode_ == blend_mode)
+ return;
+
+ // Allowing only blend modes that are defined in the CSS Compositing standard:
+ // http://dev.w3.org/fxtf/compositing-1/#blending
+ switch (blend_mode) {
+ case SkXfermode::kSrcOver_Mode:
+ case SkXfermode::kScreen_Mode:
+ case SkXfermode::kOverlay_Mode:
+ case SkXfermode::kDarken_Mode:
+ case SkXfermode::kLighten_Mode:
+ case SkXfermode::kColorDodge_Mode:
+ case SkXfermode::kColorBurn_Mode:
+ case SkXfermode::kHardLight_Mode:
+ case SkXfermode::kSoftLight_Mode:
+ case SkXfermode::kDifference_Mode:
+ case SkXfermode::kExclusion_Mode:
+ case SkXfermode::kMultiply_Mode:
+ case SkXfermode::kHue_Mode:
+ case SkXfermode::kSaturation_Mode:
+ case SkXfermode::kColor_Mode:
+ case SkXfermode::kLuminosity_Mode:
+ // supported blend modes
+ break;
+ case SkXfermode::kClear_Mode:
+ case SkXfermode::kSrc_Mode:
+ case SkXfermode::kDst_Mode:
+ case SkXfermode::kDstOver_Mode:
+ case SkXfermode::kSrcIn_Mode:
+ case SkXfermode::kDstIn_Mode:
+ case SkXfermode::kSrcOut_Mode:
+ case SkXfermode::kDstOut_Mode:
+ case SkXfermode::kSrcATop_Mode:
+ case SkXfermode::kDstATop_Mode:
+ case SkXfermode::kXor_Mode:
+ case SkXfermode::kPlus_Mode:
+ case SkXfermode::kModulate_Mode:
+ // Porter Duff Compositing Operators are not yet supported
+ // http://dev.w3.org/fxtf/compositing-1/#porterduffcompositingoperators
+ NOTREACHED();
+ return;
+ }
+
+ blend_mode_ = blend_mode;
+ SetNeedsCommit();
+}
+
+void Layer::SetIsRootForIsolatedGroup(bool root) {
+ DCHECK(IsPropertyChangeAllowed());
+ if (is_root_for_isolated_group_ == root)
+ return;
+ is_root_for_isolated_group_ = root;
+ SetNeedsCommit();
+}
+
void Layer::SetContentsOpaque(bool opaque) {
DCHECK(IsPropertyChangeAllowed());
if (contents_opaque_ == opaque)
SetNeedsCommit();
}
-void Layer::SetPosition(gfx::PointF position) {
+void Layer::SetPosition(const gfx::PointF& position) {
DCHECK(IsPropertyChangeAllowed());
if (position_ == position)
return;
bool Layer::IsContainerForFixedPositionLayers() const {
if (!transform_.IsIdentityOrTranslation())
return true;
- if (parent_ && !parent_->sublayer_transform_.IsIdentityOrTranslation())
+ if (parent_ && !parent_->transform_.IsIdentityOrTranslation())
return true;
return is_container_for_fixed_position_layers_;
}
-void Layer::SetSublayerTransform(const gfx::Transform& sublayer_transform) {
+void Layer::SetTransform(const gfx::Transform& transform) {
DCHECK(IsPropertyChangeAllowed());
- if (sublayer_transform_ == sublayer_transform)
+ if (transform_ == transform)
return;
- sublayer_transform_ = sublayer_transform;
+ transform_ = transform;
+ transform_is_invertible_ = transform.IsInvertible();
SetNeedsCommit();
}
-void Layer::SetTransform(const gfx::Transform& transform) {
+void Layer::SetTransformOrigin(const gfx::Point3F& transform_origin) {
DCHECK(IsPropertyChangeAllowed());
- if (transform_ == transform)
+ if (transform_origin_ == transform_origin)
return;
- transform_ = transform;
+ transform_origin_ = transform_origin;
SetNeedsCommit();
}
void Layer::SetScrollOffset(gfx::Vector2d scroll_offset) {
DCHECK(IsPropertyChangeAllowed());
+
if (scroll_offset_ == scroll_offset)
return;
scroll_offset_ = scroll_offset;
SetNeedsCommit();
}
-void Layer::SetScrollOffsetFromImplSide(gfx::Vector2d scroll_offset) {
+void Layer::SetScrollOffsetFromImplSide(const gfx::Vector2d& scroll_offset) {
DCHECK(IsPropertyChangeAllowed());
// This function only gets called during a BeginMainFrame, so there
// is no need to call SetNeedsUpdate here.
// "this" may have been destroyed during the process.
}
-void Layer::SetMaxScrollOffset(gfx::Vector2d max_scroll_offset) {
+void Layer::SetScrollClipLayerId(int clip_layer_id) {
DCHECK(IsPropertyChangeAllowed());
- if (max_scroll_offset_ == max_scroll_offset)
+ if (scroll_clip_layer_id_ == clip_layer_id)
return;
- max_scroll_offset_ = max_scroll_offset;
- SetNeedsCommit();
-}
-
-void Layer::SetScrollable(bool scrollable) {
- DCHECK(IsPropertyChangeAllowed());
- if (scrollable_ == scrollable)
- return;
- scrollable_ = scrollable;
+ scroll_clip_layer_id_ = clip_layer_id;
SetNeedsCommit();
}
SetNeedsCommit();
}
+void Layer::SetHaveScrollEventHandlers(bool have_scroll_event_handlers) {
+ DCHECK(IsPropertyChangeAllowed());
+ if (have_scroll_event_handlers_ == have_scroll_event_handlers)
+ return;
+ have_scroll_event_handlers_ = have_scroll_event_handlers;
+ SetNeedsCommit();
+}
+
void Layer::SetNonFastScrollableRegion(const Region& region) {
DCHECK(IsPropertyChangeAllowed());
if (non_fast_scrollable_region_ == region)
SetNeedsCommit();
}
+void Layer::Set3dSortingContextId(int id) {
+ DCHECK(IsPropertyChangeAllowed());
+ if (id == sorting_context_id_)
+ return;
+ sorting_context_id_ = id;
+ SetNeedsCommit();
+}
+
+void Layer::SetShouldFlattenTransform(bool should_flatten) {
+ DCHECK(IsPropertyChangeAllowed());
+ if (should_flatten_transform_ == should_flatten)
+ return;
+ should_flatten_transform_ = should_flatten;
+ SetNeedsCommit();
+}
+
void Layer::SetIsDrawable(bool is_drawable) {
DCHECK(IsPropertyChangeAllowed());
if (is_drawable_ == is_drawable)
return;
is_drawable_ = is_drawable;
- SetNeedsCommit();
+ UpdateDrawsContent(HasDrawableContent());
}
void Layer::SetHideLayerAndSubtree(bool hide) {
bool use_paint_properties = paint_properties_.source_frame_number ==
layer_tree_host_->source_frame_number();
- layer->SetAnchorPoint(anchor_point_);
- layer->SetAnchorPointZ(anchor_point_z_);
+ layer->SetTransformOrigin(transform_origin_);
layer->SetBackgroundColor(background_color_);
layer->SetBounds(use_paint_properties ? paint_properties_.bounds
: bounds_);
layer->SetContentsScale(contents_scale_x(), contents_scale_y());
bool is_tracing;
- TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
- &is_tracing);
+ TRACE_EVENT_CATEGORY_GROUP_ENABLED(
+ TRACE_DISABLED_BY_DEFAULT("cc.debug") "," TRACE_DISABLED_BY_DEFAULT(
+ "devtools.timeline.layers"),
+ &is_tracing);
if (is_tracing)
- layer->SetDebugName(DebugName());
- else
- layer->SetDebugName(std::string());
+ layer->SetDebugInfo(TakeDebugInfo());
- layer->SetCompositingReasons(compositing_reasons_);
layer->SetDoubleSided(double_sided_);
layer->SetDrawCheckerboardForMissingTiles(
draw_checkerboard_for_missing_tiles_);
layer->SetMasksToBounds(masks_to_bounds_);
layer->SetShouldScrollOnMainThread(should_scroll_on_main_thread_);
layer->SetHaveWheelEventHandlers(have_wheel_event_handlers_);
+ layer->SetHaveScrollEventHandlers(have_scroll_event_handlers_);
layer->SetNonFastScrollableRegion(non_fast_scrollable_region_);
layer->SetTouchEventHandlerRegion(touch_event_handler_region_);
layer->SetContentsOpaque(contents_opaque_);
if (!layer->OpacityIsAnimatingOnImplOnly() && !OpacityIsAnimating())
layer->SetOpacity(opacity_);
DCHECK(!(OpacityIsAnimating() && layer->OpacityIsAnimatingOnImplOnly()));
+ layer->SetBlendMode(blend_mode_);
+ layer->SetIsRootForIsolatedGroup(is_root_for_isolated_group_);
layer->SetPosition(position_);
layer->SetIsContainerForFixedPositionLayers(
IsContainerForFixedPositionLayers());
- layer->SetFixedContainerSizeDelta(gfx::Vector2dF());
layer->SetPositionConstraint(position_constraint_);
- layer->SetPreserves3d(preserves_3d());
+ layer->SetShouldFlattenTransform(should_flatten_transform_);
layer->SetUseParentBackfaceVisibility(use_parent_backface_visibility_);
- layer->SetSublayerTransform(sublayer_transform_);
if (!layer->TransformIsAnimatingOnImplOnly() && !TransformIsAnimating())
- layer->SetTransform(transform_);
+ layer->SetTransformAndInvertibility(transform_, transform_is_invertible_);
DCHECK(!(TransformIsAnimating() && layer->TransformIsAnimatingOnImplOnly()));
+ layer->Set3dSortingContextId(sorting_context_id_);
+ layer->SetNumDescendantsThatDrawContent(num_descendants_that_draw_content_);
- layer->SetScrollable(scrollable_);
+ layer->SetScrollClipLayer(scroll_clip_layer_id_);
layer->set_user_scrollable_horizontal(user_scrollable_horizontal_);
layer->set_user_scrollable_vertical(user_scrollable_vertical_);
- layer->SetMaxScrollOffset(max_scroll_offset_);
LayerImpl* scroll_parent = NULL;
- if (scroll_parent_)
+ if (scroll_parent_) {
scroll_parent = layer->layer_tree_impl()->LayerById(scroll_parent_->id());
+ DCHECK(scroll_parent);
+ }
layer->SetScrollParent(scroll_parent);
if (scroll_children_) {
std::set<LayerImpl*>* scroll_children = new std::set<LayerImpl*>;
for (std::set<Layer*>::iterator it = scroll_children_->begin();
- it != scroll_children_->end(); ++it)
- scroll_children->insert(layer->layer_tree_impl()->LayerById((*it)->id()));
+ it != scroll_children_->end();
+ ++it) {
+ DCHECK_EQ((*it)->scroll_parent(), this);
+ LayerImpl* scroll_child =
+ layer->layer_tree_impl()->LayerById((*it)->id());
+ DCHECK(scroll_child);
+ scroll_children->insert(scroll_child);
+ }
layer->SetScrollChildren(scroll_children);
+ } else {
+ layer->SetScrollChildren(NULL);
}
LayerImpl* clip_parent = NULL;
if (clip_parent_) {
clip_parent =
layer->layer_tree_impl()->LayerById(clip_parent_->id());
+ DCHECK(clip_parent);
}
layer->SetClipParent(clip_parent);
std::set<LayerImpl*>* clip_children = new std::set<LayerImpl*>;
for (std::set<Layer*>::iterator it = clip_children_->begin();
it != clip_children_->end(); ++it) {
+ DCHECK_EQ((*it)->clip_parent(), this);
LayerImpl* clip_child = layer->layer_tree_impl()->LayerById((*it)->id());
DCHECK(clip_child);
clip_children->insert(clip_child);
}
layer->SetClipChildren(clip_children);
+ } else {
+ layer->SetClipChildren(NULL);
}
// Adjust the scroll delta to be just the scrolls that have happened since
// update_rect here. The LayerImpl's update_rect needs to accumulate (i.e.
// union) any update changes that have occurred on the main thread.
update_rect_.Union(layer->update_rect());
- layer->set_update_rect(update_rect_);
+ layer->SetUpdateRect(update_rect_);
layer->SetStackingOrderChanged(stacking_order_changed_);
stacking_order_changed_ = false;
update_rect_ = gfx::RectF();
- // Animating layers require further push properties to clean up the animation.
- // crbug.com/259088
- needs_push_properties_ = layer_animation_controller_->has_any_animation();
+ needs_push_properties_ = false;
num_dependents_need_push_properties_ = 0;
}
}
bool Layer::DrawsContent() const {
+ return draws_content_;
+}
+
+bool Layer::HasDrawableContent() const {
return is_drawable_;
}
+void Layer::UpdateDrawsContent(bool has_drawable_content) {
+ bool draws_content = has_drawable_content;
+ DCHECK(is_drawable_ || !has_drawable_content);
+ if (draws_content == draws_content_)
+ return;
+
+ if (HasDelegatedContent()) {
+ // Layers with delegated content need to be treated as if they have as
+ // many children as the number of layers they own delegated quads for.
+ // Since we don't know this number right now, we choose one that acts like
+ // infinity for our purposes.
+ AddDrawableDescendants(draws_content ? 1000 : -1000);
+ }
+
+ if (parent())
+ parent()->AddDrawableDescendants(draws_content ? 1 : -1);
+
+ draws_content_ = draws_content;
+ SetNeedsCommit();
+}
+
+int Layer::NumDescendantsThatDrawContent() const {
+ return num_descendants_that_draw_content_;
+}
+
void Layer::SavePaintProperties() {
DCHECK(layer_tree_host_);
}
bool Layer::Update(ResourceUpdateQueue* queue,
- const OcclusionTracker* occlusion) {
+ const OcclusionTracker<Layer>* occlusion) {
DCHECK(layer_tree_host_);
DCHECK_EQ(layer_tree_host_->source_frame_number(),
paint_properties_.source_frame_number) <<
return false;
}
-std::string Layer::DebugName() {
- return client_ ? client_->DebugName() : std::string();
+bool Layer::IsSuitableForGpuRasterization() const {
+ return true;
}
-void Layer::SetCompositingReasons(CompositingReasons reasons) {
- compositing_reasons_ = reasons;
+scoped_refptr<base::debug::ConvertableToTraceFormat> Layer::TakeDebugInfo() {
+ if (client_)
+ return client_->TakeDebugInfo();
+ else
+ return NULL;
}
void Layer::CreateRenderSurface() {
draw_properties_.render_surface.reset();
}
+void Layer::ClearRenderSurfaceLayerList() {
+ if (draw_properties_.render_surface)
+ draw_properties_.render_surface->layer_list().clear();
+}
+
+gfx::Vector2dF Layer::ScrollOffsetForAnimation() const {
+ return TotalScrollOffset();
+}
+
// On<Property>Animated is called due to an ongoing accelerated animation.
// Since this animation is also being run on the compositor thread, there
// is no need to request a commit to push this value over, so the value is
}
void Layer::OnTransformAnimated(const gfx::Transform& transform) {
+ if (transform_ == transform)
+ return;
transform_ = transform;
+ transform_is_invertible_ = transform.IsInvertible();
+}
+
+void Layer::OnScrollOffsetAnimated(const gfx::Vector2dF& scroll_offset) {
+ // Do nothing. Scroll deltas will be sent from the compositor thread back
+ // to the main thread in the same manner as during non-animated
+ // compositor-driven scrolling.
+}
+
+void Layer::OnAnimationWaitingForDeletion() {
+ // Animations are only deleted during PushProperties.
+ SetNeedsPushProperties();
}
bool Layer::IsActive() const {
if (!layer_animation_controller_->animation_registrar())
return false;
+ if (animation->target_property() == Animation::ScrollOffset &&
+ !layer_animation_controller_->animation_registrar()
+ ->supports_scroll_animations())
+ return false;
+
UMA_HISTOGRAM_BOOLEAN("Renderer.AnimationAddedToOrphanLayer",
!layer_tree_host_);
layer_animation_controller_->AddAnimation(animation.Pass());
}
void Layer::PauseAnimation(int animation_id, double time_offset) {
- layer_animation_controller_->PauseAnimation(animation_id, time_offset);
+ layer_animation_controller_->PauseAnimation(
+ animation_id, base::TimeDelta::FromSecondsD(time_offset));
SetNeedsCommit();
}
scoped_refptr<LayerAnimationController> controller) {
layer_animation_controller_->RemoveValueObserver(this);
layer_animation_controller_ = controller;
- layer_animation_controller_->set_force_sync();
layer_animation_controller_->AddValueObserver(this);
SetNeedsCommit();
}
void Layer::RemoveFromScrollTree() {
if (scroll_children_.get()) {
- for (std::set<Layer*>::iterator it = scroll_children_->begin();
- it != scroll_children_->end(); ++it)
- (*it)->scroll_parent_ = NULL;
+ std::set<Layer*> copy = *scroll_children_;
+ for (std::set<Layer*>::iterator it = copy.begin(); it != copy.end(); ++it)
+ (*it)->SetScrollParent(NULL);
}
- if (scroll_parent_)
- scroll_parent_->RemoveScrollChild(this);
-
- scroll_parent_ = NULL;
+ DCHECK(!scroll_children_);
+ SetScrollParent(NULL);
}
void Layer::RemoveFromClipTree() {
if (clip_children_.get()) {
- for (std::set<Layer*>::iterator it = clip_children_->begin();
- it != clip_children_->end(); ++it)
- (*it)->clip_parent_ = NULL;
+ std::set<Layer*> copy = *clip_children_;
+ for (std::set<Layer*>::iterator it = copy.begin(); it != copy.end(); ++it)
+ (*it)->SetClipParent(NULL);
}
- if (clip_parent_)
- clip_parent_->RemoveClipChild(this);
+ DCHECK(!clip_children_);
+ SetClipParent(NULL);
+}
- clip_parent_ = NULL;
+void Layer::AddDrawableDescendants(int num) {
+ DCHECK_GE(num_descendants_that_draw_content_, 0);
+ DCHECK_GE(num_descendants_that_draw_content_ + num, 0);
+ if (num == 0)
+ return;
+ num_descendants_that_draw_content_ += num;
+ SetNeedsCommit();
+ if (parent())
+ parent()->AddDrawableDescendants(num);
}
void Layer::RunMicroBenchmark(MicroBenchmark* benchmark) {
benchmark->RunOnLayer(this);
}
+bool Layer::HasDelegatedContent() const {
+ return false;
+}
+
} // namespace cc