Home | History | Annotate | Download | only in layers
      1 // Copyright 2010 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "cc/layers/layer.h"
      6 
      7 #include <algorithm>
      8 
      9 #include "base/atomic_sequence_num.h"
     10 #include "base/debug/trace_event.h"
     11 #include "base/location.h"
     12 #include "base/metrics/histogram.h"
     13 #include "base/single_thread_task_runner.h"
     14 #include "base/time/time.h"
     15 #include "cc/animation/animation.h"
     16 #include "cc/animation/animation_events.h"
     17 #include "cc/animation/animation_registrar.h"
     18 #include "cc/animation/keyframed_animation_curve.h"
     19 #include "cc/animation/layer_animation_controller.h"
     20 #include "cc/base/simple_enclosed_region.h"
     21 #include "cc/layers/layer_client.h"
     22 #include "cc/layers/layer_impl.h"
     23 #include "cc/layers/scrollbar_layer_interface.h"
     24 #include "cc/output/copy_output_request.h"
     25 #include "cc/output/copy_output_result.h"
     26 #include "cc/trees/layer_tree_host.h"
     27 #include "cc/trees/layer_tree_impl.h"
     28 #include "third_party/skia/include/core/SkImageFilter.h"
     29 #include "ui/gfx/geometry/vector2d_conversions.h"
     30 #include "ui/gfx/rect_conversions.h"
     31 
     32 namespace cc {
     33 
     34 base::StaticAtomicSequenceNumber g_next_layer_id;
     35 
     36 scoped_refptr<Layer> Layer::Create() {
     37   return make_scoped_refptr(new Layer());
     38 }
     39 
     40 Layer::Layer()
     41     : needs_push_properties_(false),
     42       num_dependents_need_push_properties_(false),
     43       stacking_order_changed_(false),
     44       // Layer IDs start from 1.
     45       layer_id_(g_next_layer_id.GetNext() + 1),
     46       ignore_set_needs_commit_(false),
     47       sorting_context_id_(0),
     48       parent_(NULL),
     49       layer_tree_host_(NULL),
     50       scroll_clip_layer_id_(INVALID_ID),
     51       num_descendants_that_draw_content_(0),
     52       should_scroll_on_main_thread_(false),
     53       have_wheel_event_handlers_(false),
     54       have_scroll_event_handlers_(false),
     55       user_scrollable_horizontal_(true),
     56       user_scrollable_vertical_(true),
     57       is_root_for_isolated_group_(false),
     58       is_container_for_fixed_position_layers_(false),
     59       is_drawable_(false),
     60       draws_content_(false),
     61       hide_layer_and_subtree_(false),
     62       masks_to_bounds_(false),
     63       contents_opaque_(false),
     64       double_sided_(true),
     65       should_flatten_transform_(true),
     66       use_parent_backface_visibility_(false),
     67       draw_checkerboard_for_missing_tiles_(false),
     68       force_render_surface_(false),
     69       transform_is_invertible_(true),
     70       background_color_(0),
     71       opacity_(1.f),
     72       blend_mode_(SkXfermode::kSrcOver_Mode),
     73       scroll_parent_(NULL),
     74       clip_parent_(NULL),
     75       replica_layer_(NULL),
     76       raster_scale_(0.f),
     77       client_(NULL) {
     78   layer_animation_controller_ = LayerAnimationController::Create(layer_id_);
     79   layer_animation_controller_->AddValueObserver(this);
     80   layer_animation_controller_->set_value_provider(this);
     81 }
     82 
     83 Layer::~Layer() {
     84   // Our parent should be holding a reference to us so there should be no
     85   // way for us to be destroyed while we still have a parent.
     86   DCHECK(!parent());
     87   // Similarly we shouldn't have a layer tree host since it also keeps a
     88   // reference to us.
     89   DCHECK(!layer_tree_host());
     90 
     91   layer_animation_controller_->RemoveValueObserver(this);
     92   layer_animation_controller_->remove_value_provider(this);
     93 
     94   RemoveFromScrollTree();
     95   RemoveFromClipTree();
     96 
     97   // Remove the parent reference from all children and dependents.
     98   RemoveAllChildren();
     99   if (mask_layer_.get()) {
    100     DCHECK_EQ(this, mask_layer_->parent());
    101     mask_layer_->RemoveFromParent();
    102   }
    103   if (replica_layer_.get()) {
    104     DCHECK_EQ(this, replica_layer_->parent());
    105     replica_layer_->RemoveFromParent();
    106   }
    107 }
    108 
    109 void Layer::SetLayerTreeHost(LayerTreeHost* host) {
    110   if (layer_tree_host_ == host)
    111     return;
    112 
    113   layer_tree_host_ = host;
    114 
    115   // When changing hosts, the layer needs to commit its properties to the impl
    116   // side for the new host.
    117   SetNeedsPushProperties();
    118 
    119   for (size_t i = 0; i < children_.size(); ++i)
    120     children_[i]->SetLayerTreeHost(host);
    121 
    122   if (mask_layer_.get())
    123     mask_layer_->SetLayerTreeHost(host);
    124   if (replica_layer_.get())
    125     replica_layer_->SetLayerTreeHost(host);
    126 
    127   if (host) {
    128     layer_animation_controller_->SetAnimationRegistrar(
    129         host->animation_registrar());
    130 
    131     if (host->settings().layer_transforms_should_scale_layer_contents)
    132       reset_raster_scale_to_unknown();
    133   }
    134 
    135   if (host && layer_animation_controller_->has_any_animation())
    136     host->SetNeedsCommit();
    137 }
    138 
    139 void Layer::SetNeedsUpdate() {
    140   if (layer_tree_host_ && !ignore_set_needs_commit_)
    141     layer_tree_host_->SetNeedsUpdateLayers();
    142 }
    143 
    144 void Layer::SetNeedsCommit() {
    145   if (!layer_tree_host_)
    146     return;
    147 
    148   SetNeedsPushProperties();
    149 
    150   if (ignore_set_needs_commit_)
    151     return;
    152 
    153   layer_tree_host_->SetNeedsCommit();
    154 }
    155 
    156 void Layer::SetNeedsFullTreeSync() {
    157   if (!layer_tree_host_)
    158     return;
    159 
    160   layer_tree_host_->SetNeedsFullTreeSync();
    161 }
    162 
    163 void Layer::SetNextCommitWaitsForActivation() {
    164   if (!layer_tree_host_)
    165     return;
    166 
    167   layer_tree_host_->SetNextCommitWaitsForActivation();
    168 }
    169 
    170 void Layer::SetNeedsPushProperties() {
    171   if (needs_push_properties_)
    172     return;
    173   if (!parent_should_know_need_push_properties() && parent_)
    174     parent_->AddDependentNeedsPushProperties();
    175   needs_push_properties_ = true;
    176 }
    177 
    178 void Layer::AddDependentNeedsPushProperties() {
    179   DCHECK_GE(num_dependents_need_push_properties_, 0);
    180 
    181   if (!parent_should_know_need_push_properties() && parent_)
    182     parent_->AddDependentNeedsPushProperties();
    183 
    184   num_dependents_need_push_properties_++;
    185 }
    186 
    187 void Layer::RemoveDependentNeedsPushProperties() {
    188   num_dependents_need_push_properties_--;
    189   DCHECK_GE(num_dependents_need_push_properties_, 0);
    190 
    191   if (!parent_should_know_need_push_properties() && parent_)
    192       parent_->RemoveDependentNeedsPushProperties();
    193 }
    194 
    195 bool Layer::IsPropertyChangeAllowed() const {
    196   if (!layer_tree_host_)
    197     return true;
    198 
    199   if (!layer_tree_host_->settings().strict_layer_property_change_checking)
    200     return true;
    201 
    202   return !layer_tree_host_->in_paint_layer_contents();
    203 }
    204 
    205 gfx::Rect Layer::LayerRectToContentRect(const gfx::RectF& layer_rect) const {
    206   gfx::RectF content_rect =
    207       gfx::ScaleRect(layer_rect, contents_scale_x(), contents_scale_y());
    208   // Intersect with content rect to avoid the extra pixel because for some
    209   // values x and y, ceil((x / y) * y) may be x + 1.
    210   content_rect.Intersect(gfx::Rect(content_bounds()));
    211   return gfx::ToEnclosingRect(content_rect);
    212 }
    213 
    214 skia::RefPtr<SkPicture> Layer::GetPicture() const {
    215   return skia::RefPtr<SkPicture>();
    216 }
    217 
    218 void Layer::SetParent(Layer* layer) {
    219   DCHECK(!layer || !layer->HasAncestor(this));
    220 
    221   if (parent_should_know_need_push_properties()) {
    222     if (parent_)
    223       parent_->RemoveDependentNeedsPushProperties();
    224     if (layer)
    225       layer->AddDependentNeedsPushProperties();
    226   }
    227 
    228   parent_ = layer;
    229   SetLayerTreeHost(parent_ ? parent_->layer_tree_host() : NULL);
    230 
    231   if (!layer_tree_host_)
    232     return;
    233   const LayerTreeSettings& settings = layer_tree_host_->settings();
    234   if (!settings.layer_transforms_should_scale_layer_contents)
    235     return;
    236 
    237   reset_raster_scale_to_unknown();
    238   if (mask_layer_.get())
    239     mask_layer_->reset_raster_scale_to_unknown();
    240   if (replica_layer_.get() && replica_layer_->mask_layer_.get())
    241     replica_layer_->mask_layer_->reset_raster_scale_to_unknown();
    242 }
    243 
    244 void Layer::AddChild(scoped_refptr<Layer> child) {
    245   InsertChild(child, children_.size());
    246 }
    247 
    248 void Layer::InsertChild(scoped_refptr<Layer> child, size_t index) {
    249   DCHECK(IsPropertyChangeAllowed());
    250   child->RemoveFromParent();
    251   AddDrawableDescendants(child->NumDescendantsThatDrawContent() +
    252                          (child->DrawsContent() ? 1 : 0));
    253   child->SetParent(this);
    254   child->stacking_order_changed_ = true;
    255 
    256   index = std::min(index, children_.size());
    257   children_.insert(children_.begin() + index, child);
    258   SetNeedsFullTreeSync();
    259 }
    260 
    261 void Layer::RemoveFromParent() {
    262   DCHECK(IsPropertyChangeAllowed());
    263   if (parent_)
    264     parent_->RemoveChildOrDependent(this);
    265 }
    266 
    267 void Layer::RemoveChildOrDependent(Layer* child) {
    268   if (mask_layer_.get() == child) {
    269     mask_layer_->SetParent(NULL);
    270     mask_layer_ = NULL;
    271     SetNeedsFullTreeSync();
    272     return;
    273   }
    274   if (replica_layer_.get() == child) {
    275     replica_layer_->SetParent(NULL);
    276     replica_layer_ = NULL;
    277     SetNeedsFullTreeSync();
    278     return;
    279   }
    280 
    281   for (LayerList::iterator iter = children_.begin();
    282        iter != children_.end();
    283        ++iter) {
    284     if (iter->get() != child)
    285       continue;
    286 
    287     child->SetParent(NULL);
    288     AddDrawableDescendants(-child->NumDescendantsThatDrawContent() -
    289                            (child->DrawsContent() ? 1 : 0));
    290     children_.erase(iter);
    291     SetNeedsFullTreeSync();
    292     return;
    293   }
    294 }
    295 
    296 void Layer::ReplaceChild(Layer* reference, scoped_refptr<Layer> new_layer) {
    297   DCHECK(reference);
    298   DCHECK_EQ(reference->parent(), this);
    299   DCHECK(IsPropertyChangeAllowed());
    300 
    301   if (reference == new_layer.get())
    302     return;
    303 
    304   int reference_index = IndexOfChild(reference);
    305   if (reference_index == -1) {
    306     NOTREACHED();
    307     return;
    308   }
    309 
    310   reference->RemoveFromParent();
    311 
    312   if (new_layer.get()) {
    313     new_layer->RemoveFromParent();
    314     InsertChild(new_layer, reference_index);
    315   }
    316 }
    317 
    318 int Layer::IndexOfChild(const Layer* reference) {
    319   for (size_t i = 0; i < children_.size(); ++i) {
    320     if (children_[i].get() == reference)
    321       return i;
    322   }
    323   return -1;
    324 }
    325 
    326 void Layer::SetBounds(const gfx::Size& size) {
    327   DCHECK(IsPropertyChangeAllowed());
    328   if (bounds() == size)
    329     return;
    330 
    331   bounds_ = size;
    332   SetNeedsCommit();
    333 }
    334 
    335 Layer* Layer::RootLayer() {
    336   Layer* layer = this;
    337   while (layer->parent())
    338     layer = layer->parent();
    339   return layer;
    340 }
    341 
    342 void Layer::RemoveAllChildren() {
    343   DCHECK(IsPropertyChangeAllowed());
    344   while (children_.size()) {
    345     Layer* layer = children_[0].get();
    346     DCHECK_EQ(this, layer->parent());
    347     layer->RemoveFromParent();
    348   }
    349 }
    350 
    351 void Layer::SetChildren(const LayerList& children) {
    352   DCHECK(IsPropertyChangeAllowed());
    353   if (children == children_)
    354     return;
    355 
    356   RemoveAllChildren();
    357   for (size_t i = 0; i < children.size(); ++i)
    358     AddChild(children[i]);
    359 }
    360 
    361 bool Layer::HasAncestor(const Layer* ancestor) const {
    362   for (const Layer* layer = parent(); layer; layer = layer->parent()) {
    363     if (layer == ancestor)
    364       return true;
    365   }
    366   return false;
    367 }
    368 
    369 void Layer::RequestCopyOfOutput(
    370     scoped_ptr<CopyOutputRequest> request) {
    371   DCHECK(IsPropertyChangeAllowed());
    372   if (request->IsEmpty())
    373     return;
    374   copy_requests_.push_back(request.Pass());
    375   SetNeedsCommit();
    376 }
    377 
    378 void Layer::SetBackgroundColor(SkColor background_color) {
    379   DCHECK(IsPropertyChangeAllowed());
    380   if (background_color_ == background_color)
    381     return;
    382   background_color_ = background_color;
    383   SetNeedsCommit();
    384 }
    385 
    386 SkColor Layer::SafeOpaqueBackgroundColor() const {
    387   SkColor color = background_color();
    388   if (SkColorGetA(color) == 255 && !contents_opaque()) {
    389     color = SK_ColorTRANSPARENT;
    390   } else if (SkColorGetA(color) != 255 && contents_opaque()) {
    391     for (const Layer* layer = parent(); layer;
    392          layer = layer->parent()) {
    393       color = layer->background_color();
    394       if (SkColorGetA(color) == 255)
    395         break;
    396     }
    397     if (SkColorGetA(color) != 255)
    398       color = layer_tree_host_->background_color();
    399     if (SkColorGetA(color) != 255)
    400       color = SkColorSetA(color, 255);
    401   }
    402   return color;
    403 }
    404 
    405 void Layer::CalculateContentsScale(float ideal_contents_scale,
    406                                    float* contents_scale_x,
    407                                    float* contents_scale_y,
    408                                    gfx::Size* content_bounds) {
    409   DCHECK(layer_tree_host_);
    410 
    411   *contents_scale_x = 1;
    412   *contents_scale_y = 1;
    413   *content_bounds = bounds();
    414 }
    415 
    416 void Layer::SetMasksToBounds(bool masks_to_bounds) {
    417   DCHECK(IsPropertyChangeAllowed());
    418   if (masks_to_bounds_ == masks_to_bounds)
    419     return;
    420   masks_to_bounds_ = masks_to_bounds;
    421   SetNeedsCommit();
    422 }
    423 
    424 void Layer::SetMaskLayer(Layer* mask_layer) {
    425   DCHECK(IsPropertyChangeAllowed());
    426   if (mask_layer_.get() == mask_layer)
    427     return;
    428   if (mask_layer_.get()) {
    429     DCHECK_EQ(this, mask_layer_->parent());
    430     mask_layer_->RemoveFromParent();
    431   }
    432   mask_layer_ = mask_layer;
    433   if (mask_layer_.get()) {
    434     DCHECK(!mask_layer_->parent());
    435     mask_layer_->RemoveFromParent();
    436     mask_layer_->SetParent(this);
    437     mask_layer_->SetIsMask(true);
    438   }
    439   SetNeedsFullTreeSync();
    440 }
    441 
    442 void Layer::SetReplicaLayer(Layer* layer) {
    443   DCHECK(IsPropertyChangeAllowed());
    444   if (replica_layer_.get() == layer)
    445     return;
    446   if (replica_layer_.get()) {
    447     DCHECK_EQ(this, replica_layer_->parent());
    448     replica_layer_->RemoveFromParent();
    449   }
    450   replica_layer_ = layer;
    451   if (replica_layer_.get()) {
    452     DCHECK(!replica_layer_->parent());
    453     replica_layer_->RemoveFromParent();
    454     replica_layer_->SetParent(this);
    455   }
    456   SetNeedsFullTreeSync();
    457 }
    458 
    459 void Layer::SetFilters(const FilterOperations& filters) {
    460   DCHECK(IsPropertyChangeAllowed());
    461   if (filters_ == filters)
    462     return;
    463   filters_ = filters;
    464   SetNeedsCommit();
    465 }
    466 
    467 bool Layer::FilterIsAnimating() const {
    468   return layer_animation_controller_->IsAnimatingProperty(Animation::Filter);
    469 }
    470 
    471 void Layer::SetBackgroundFilters(const FilterOperations& filters) {
    472   DCHECK(IsPropertyChangeAllowed());
    473   if (background_filters_ == filters)
    474     return;
    475   background_filters_ = filters;
    476   SetNeedsCommit();
    477 }
    478 
    479 void Layer::SetOpacity(float opacity) {
    480   DCHECK(IsPropertyChangeAllowed());
    481   if (opacity_ == opacity)
    482     return;
    483   opacity_ = opacity;
    484   SetNeedsCommit();
    485 }
    486 
    487 bool Layer::OpacityIsAnimating() const {
    488   return layer_animation_controller_->IsAnimatingProperty(Animation::Opacity);
    489 }
    490 
    491 bool Layer::OpacityCanAnimateOnImplThread() const {
    492   return false;
    493 }
    494 
    495 void Layer::SetBlendMode(SkXfermode::Mode blend_mode) {
    496   DCHECK(IsPropertyChangeAllowed());
    497   if (blend_mode_ == blend_mode)
    498     return;
    499 
    500   // Allowing only blend modes that are defined in the CSS Compositing standard:
    501   // http://dev.w3.org/fxtf/compositing-1/#blending
    502   switch (blend_mode) {
    503     case SkXfermode::kSrcOver_Mode:
    504     case SkXfermode::kScreen_Mode:
    505     case SkXfermode::kOverlay_Mode:
    506     case SkXfermode::kDarken_Mode:
    507     case SkXfermode::kLighten_Mode:
    508     case SkXfermode::kColorDodge_Mode:
    509     case SkXfermode::kColorBurn_Mode:
    510     case SkXfermode::kHardLight_Mode:
    511     case SkXfermode::kSoftLight_Mode:
    512     case SkXfermode::kDifference_Mode:
    513     case SkXfermode::kExclusion_Mode:
    514     case SkXfermode::kMultiply_Mode:
    515     case SkXfermode::kHue_Mode:
    516     case SkXfermode::kSaturation_Mode:
    517     case SkXfermode::kColor_Mode:
    518     case SkXfermode::kLuminosity_Mode:
    519       // supported blend modes
    520       break;
    521     case SkXfermode::kClear_Mode:
    522     case SkXfermode::kSrc_Mode:
    523     case SkXfermode::kDst_Mode:
    524     case SkXfermode::kDstOver_Mode:
    525     case SkXfermode::kSrcIn_Mode:
    526     case SkXfermode::kDstIn_Mode:
    527     case SkXfermode::kSrcOut_Mode:
    528     case SkXfermode::kDstOut_Mode:
    529     case SkXfermode::kSrcATop_Mode:
    530     case SkXfermode::kDstATop_Mode:
    531     case SkXfermode::kXor_Mode:
    532     case SkXfermode::kPlus_Mode:
    533     case SkXfermode::kModulate_Mode:
    534       // Porter Duff Compositing Operators are not yet supported
    535       // http://dev.w3.org/fxtf/compositing-1/#porterduffcompositingoperators
    536       NOTREACHED();
    537       return;
    538   }
    539 
    540   blend_mode_ = blend_mode;
    541   SetNeedsCommit();
    542 }
    543 
    544 void Layer::SetIsRootForIsolatedGroup(bool root) {
    545   DCHECK(IsPropertyChangeAllowed());
    546   if (is_root_for_isolated_group_ == root)
    547     return;
    548   is_root_for_isolated_group_ = root;
    549   SetNeedsCommit();
    550 }
    551 
    552 void Layer::SetContentsOpaque(bool opaque) {
    553   DCHECK(IsPropertyChangeAllowed());
    554   if (contents_opaque_ == opaque)
    555     return;
    556   contents_opaque_ = opaque;
    557   SetNeedsCommit();
    558 }
    559 
    560 void Layer::SetPosition(const gfx::PointF& position) {
    561   DCHECK(IsPropertyChangeAllowed());
    562   if (position_ == position)
    563     return;
    564   position_ = position;
    565   SetNeedsCommit();
    566 }
    567 
    568 bool Layer::IsContainerForFixedPositionLayers() const {
    569   if (!transform_.IsIdentityOrTranslation())
    570     return true;
    571   if (parent_ && !parent_->transform_.IsIdentityOrTranslation())
    572     return true;
    573   return is_container_for_fixed_position_layers_;
    574 }
    575 
    576 void Layer::SetTransform(const gfx::Transform& transform) {
    577   DCHECK(IsPropertyChangeAllowed());
    578   if (transform_ == transform)
    579     return;
    580   transform_ = transform;
    581   transform_is_invertible_ = transform.IsInvertible();
    582   SetNeedsCommit();
    583 }
    584 
    585 void Layer::SetTransformOrigin(const gfx::Point3F& transform_origin) {
    586   DCHECK(IsPropertyChangeAllowed());
    587   if (transform_origin_ == transform_origin)
    588     return;
    589   transform_origin_ = transform_origin;
    590   SetNeedsCommit();
    591 }
    592 
    593 bool Layer::TransformIsAnimating() const {
    594   return layer_animation_controller_->IsAnimatingProperty(Animation::Transform);
    595 }
    596 
    597 void Layer::SetScrollParent(Layer* parent) {
    598   DCHECK(IsPropertyChangeAllowed());
    599   if (scroll_parent_ == parent)
    600     return;
    601 
    602   if (scroll_parent_)
    603     scroll_parent_->RemoveScrollChild(this);
    604 
    605   scroll_parent_ = parent;
    606 
    607   if (scroll_parent_)
    608     scroll_parent_->AddScrollChild(this);
    609 
    610   SetNeedsCommit();
    611 }
    612 
    613 void Layer::AddScrollChild(Layer* child) {
    614   if (!scroll_children_)
    615     scroll_children_.reset(new std::set<Layer*>);
    616   scroll_children_->insert(child);
    617   SetNeedsCommit();
    618 }
    619 
    620 void Layer::RemoveScrollChild(Layer* child) {
    621   scroll_children_->erase(child);
    622   if (scroll_children_->empty())
    623     scroll_children_.reset();
    624   SetNeedsCommit();
    625 }
    626 
    627 void Layer::SetClipParent(Layer* ancestor) {
    628   DCHECK(IsPropertyChangeAllowed());
    629   if (clip_parent_ == ancestor)
    630     return;
    631 
    632   if (clip_parent_)
    633     clip_parent_->RemoveClipChild(this);
    634 
    635   clip_parent_ = ancestor;
    636 
    637   if (clip_parent_)
    638     clip_parent_->AddClipChild(this);
    639 
    640   SetNeedsCommit();
    641 }
    642 
    643 void Layer::AddClipChild(Layer* child) {
    644   if (!clip_children_)
    645     clip_children_.reset(new std::set<Layer*>);
    646   clip_children_->insert(child);
    647   SetNeedsCommit();
    648 }
    649 
    650 void Layer::RemoveClipChild(Layer* child) {
    651   clip_children_->erase(child);
    652   if (clip_children_->empty())
    653     clip_children_.reset();
    654   SetNeedsCommit();
    655 }
    656 
    657 void Layer::SetScrollOffset(gfx::Vector2d scroll_offset) {
    658   DCHECK(IsPropertyChangeAllowed());
    659 
    660   if (scroll_offset_ == scroll_offset)
    661     return;
    662   scroll_offset_ = scroll_offset;
    663   SetNeedsCommit();
    664 }
    665 
    666 void Layer::SetScrollOffsetFromImplSide(const gfx::Vector2d& scroll_offset) {
    667   DCHECK(IsPropertyChangeAllowed());
    668   // This function only gets called during a BeginMainFrame, so there
    669   // is no need to call SetNeedsUpdate here.
    670   DCHECK(layer_tree_host_ && layer_tree_host_->CommitRequested());
    671   if (scroll_offset_ == scroll_offset)
    672     return;
    673   scroll_offset_ = scroll_offset;
    674   SetNeedsPushProperties();
    675   if (!did_scroll_callback_.is_null())
    676     did_scroll_callback_.Run();
    677   // The callback could potentially change the layer structure:
    678   // "this" may have been destroyed during the process.
    679 }
    680 
    681 void Layer::SetScrollClipLayerId(int clip_layer_id) {
    682   DCHECK(IsPropertyChangeAllowed());
    683   if (scroll_clip_layer_id_ == clip_layer_id)
    684     return;
    685   scroll_clip_layer_id_ = clip_layer_id;
    686   SetNeedsCommit();
    687 }
    688 
    689 void Layer::SetUserScrollable(bool horizontal, bool vertical) {
    690   DCHECK(IsPropertyChangeAllowed());
    691   if (user_scrollable_horizontal_ == horizontal &&
    692       user_scrollable_vertical_ == vertical)
    693     return;
    694   user_scrollable_horizontal_ = horizontal;
    695   user_scrollable_vertical_ = vertical;
    696   SetNeedsCommit();
    697 }
    698 
    699 void Layer::SetShouldScrollOnMainThread(bool should_scroll_on_main_thread) {
    700   DCHECK(IsPropertyChangeAllowed());
    701   if (should_scroll_on_main_thread_ == should_scroll_on_main_thread)
    702     return;
    703   should_scroll_on_main_thread_ = should_scroll_on_main_thread;
    704   SetNeedsCommit();
    705 }
    706 
    707 void Layer::SetHaveWheelEventHandlers(bool have_wheel_event_handlers) {
    708   DCHECK(IsPropertyChangeAllowed());
    709   if (have_wheel_event_handlers_ == have_wheel_event_handlers)
    710     return;
    711   have_wheel_event_handlers_ = have_wheel_event_handlers;
    712   SetNeedsCommit();
    713 }
    714 
    715 void Layer::SetHaveScrollEventHandlers(bool have_scroll_event_handlers) {
    716   DCHECK(IsPropertyChangeAllowed());
    717   if (have_scroll_event_handlers_ == have_scroll_event_handlers)
    718     return;
    719   have_scroll_event_handlers_ = have_scroll_event_handlers;
    720   SetNeedsCommit();
    721 }
    722 
    723 void Layer::SetNonFastScrollableRegion(const Region& region) {
    724   DCHECK(IsPropertyChangeAllowed());
    725   if (non_fast_scrollable_region_ == region)
    726     return;
    727   non_fast_scrollable_region_ = region;
    728   SetNeedsCommit();
    729 }
    730 
    731 void Layer::SetTouchEventHandlerRegion(const Region& region) {
    732   DCHECK(IsPropertyChangeAllowed());
    733   if (touch_event_handler_region_ == region)
    734     return;
    735   touch_event_handler_region_ = region;
    736   SetNeedsCommit();
    737 }
    738 
    739 void Layer::SetDrawCheckerboardForMissingTiles(bool checkerboard) {
    740   DCHECK(IsPropertyChangeAllowed());
    741   if (draw_checkerboard_for_missing_tiles_ == checkerboard)
    742     return;
    743   draw_checkerboard_for_missing_tiles_ = checkerboard;
    744   SetNeedsCommit();
    745 }
    746 
    747 void Layer::SetForceRenderSurface(bool force) {
    748   DCHECK(IsPropertyChangeAllowed());
    749   if (force_render_surface_ == force)
    750     return;
    751   force_render_surface_ = force;
    752   SetNeedsCommit();
    753 }
    754 
    755 void Layer::SetDoubleSided(bool double_sided) {
    756   DCHECK(IsPropertyChangeAllowed());
    757   if (double_sided_ == double_sided)
    758     return;
    759   double_sided_ = double_sided;
    760   SetNeedsCommit();
    761 }
    762 
    763 void Layer::Set3dSortingContextId(int id) {
    764   DCHECK(IsPropertyChangeAllowed());
    765   if (id == sorting_context_id_)
    766     return;
    767   sorting_context_id_ = id;
    768   SetNeedsCommit();
    769 }
    770 
    771 void Layer::SetShouldFlattenTransform(bool should_flatten) {
    772   DCHECK(IsPropertyChangeAllowed());
    773   if (should_flatten_transform_ == should_flatten)
    774     return;
    775   should_flatten_transform_ = should_flatten;
    776   SetNeedsCommit();
    777 }
    778 
    779 void Layer::SetIsDrawable(bool is_drawable) {
    780   DCHECK(IsPropertyChangeAllowed());
    781   if (is_drawable_ == is_drawable)
    782     return;
    783 
    784   is_drawable_ = is_drawable;
    785   UpdateDrawsContent(HasDrawableContent());
    786 }
    787 
    788 void Layer::SetHideLayerAndSubtree(bool hide) {
    789   DCHECK(IsPropertyChangeAllowed());
    790   if (hide_layer_and_subtree_ == hide)
    791     return;
    792 
    793   hide_layer_and_subtree_ = hide;
    794   SetNeedsCommit();
    795 }
    796 
    797 void Layer::SetNeedsDisplayRect(const gfx::RectF& dirty_rect) {
    798   if (dirty_rect.IsEmpty())
    799     return;
    800 
    801   SetNeedsPushProperties();
    802   update_rect_.Union(dirty_rect);
    803 
    804   if (DrawsContent())
    805     SetNeedsUpdate();
    806 }
    807 
    808 bool Layer::DescendantIsFixedToContainerLayer() const {
    809   for (size_t i = 0; i < children_.size(); ++i) {
    810     if (children_[i]->position_constraint_.is_fixed_position() ||
    811         children_[i]->DescendantIsFixedToContainerLayer())
    812       return true;
    813   }
    814   return false;
    815 }
    816 
    817 void Layer::SetIsContainerForFixedPositionLayers(bool container) {
    818   if (is_container_for_fixed_position_layers_ == container)
    819     return;
    820   is_container_for_fixed_position_layers_ = container;
    821 
    822   if (layer_tree_host_ && layer_tree_host_->CommitRequested())
    823     return;
    824 
    825   // Only request a commit if we have a fixed positioned descendant.
    826   if (DescendantIsFixedToContainerLayer())
    827     SetNeedsCommit();
    828 }
    829 
    830 void Layer::SetPositionConstraint(const LayerPositionConstraint& constraint) {
    831   DCHECK(IsPropertyChangeAllowed());
    832   if (position_constraint_ == constraint)
    833     return;
    834   position_constraint_ = constraint;
    835   SetNeedsCommit();
    836 }
    837 
    838 static void RunCopyCallbackOnMainThread(scoped_ptr<CopyOutputRequest> request,
    839                                         scoped_ptr<CopyOutputResult> result) {
    840   request->SendResult(result.Pass());
    841 }
    842 
    843 static void PostCopyCallbackToMainThread(
    844     scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner,
    845     scoped_ptr<CopyOutputRequest> request,
    846     scoped_ptr<CopyOutputResult> result) {
    847   main_thread_task_runner->PostTask(FROM_HERE,
    848                                     base::Bind(&RunCopyCallbackOnMainThread,
    849                                                base::Passed(&request),
    850                                                base::Passed(&result)));
    851 }
    852 
    853 void Layer::PushPropertiesTo(LayerImpl* layer) {
    854   DCHECK(layer_tree_host_);
    855 
    856   // If we did not SavePaintProperties() for the layer this frame, then push the
    857   // real property values, not the paint property values.
    858   bool use_paint_properties = paint_properties_.source_frame_number ==
    859                               layer_tree_host_->source_frame_number();
    860 
    861   layer->SetTransformOrigin(transform_origin_);
    862   layer->SetBackgroundColor(background_color_);
    863   layer->SetBounds(use_paint_properties ? paint_properties_.bounds
    864                                         : bounds_);
    865   layer->SetContentBounds(content_bounds());
    866   layer->SetContentsScale(contents_scale_x(), contents_scale_y());
    867 
    868   bool is_tracing;
    869   TRACE_EVENT_CATEGORY_GROUP_ENABLED(
    870       TRACE_DISABLED_BY_DEFAULT("cc.debug") "," TRACE_DISABLED_BY_DEFAULT(
    871           "devtools.timeline.layers"),
    872       &is_tracing);
    873   if (is_tracing)
    874     layer->SetDebugInfo(TakeDebugInfo());
    875 
    876   layer->SetDoubleSided(double_sided_);
    877   layer->SetDrawCheckerboardForMissingTiles(
    878       draw_checkerboard_for_missing_tiles_);
    879   layer->SetForceRenderSurface(force_render_surface_);
    880   layer->SetDrawsContent(DrawsContent());
    881   layer->SetHideLayerAndSubtree(hide_layer_and_subtree_);
    882   if (!layer->FilterIsAnimatingOnImplOnly() && !FilterIsAnimating())
    883     layer->SetFilters(filters_);
    884   DCHECK(!(FilterIsAnimating() && layer->FilterIsAnimatingOnImplOnly()));
    885   layer->SetBackgroundFilters(background_filters());
    886   layer->SetMasksToBounds(masks_to_bounds_);
    887   layer->SetShouldScrollOnMainThread(should_scroll_on_main_thread_);
    888   layer->SetHaveWheelEventHandlers(have_wheel_event_handlers_);
    889   layer->SetHaveScrollEventHandlers(have_scroll_event_handlers_);
    890   layer->SetNonFastScrollableRegion(non_fast_scrollable_region_);
    891   layer->SetTouchEventHandlerRegion(touch_event_handler_region_);
    892   layer->SetContentsOpaque(contents_opaque_);
    893   if (!layer->OpacityIsAnimatingOnImplOnly() && !OpacityIsAnimating())
    894     layer->SetOpacity(opacity_);
    895   DCHECK(!(OpacityIsAnimating() && layer->OpacityIsAnimatingOnImplOnly()));
    896   layer->SetBlendMode(blend_mode_);
    897   layer->SetIsRootForIsolatedGroup(is_root_for_isolated_group_);
    898   layer->SetPosition(position_);
    899   layer->SetIsContainerForFixedPositionLayers(
    900       IsContainerForFixedPositionLayers());
    901   layer->SetPositionConstraint(position_constraint_);
    902   layer->SetShouldFlattenTransform(should_flatten_transform_);
    903   layer->SetUseParentBackfaceVisibility(use_parent_backface_visibility_);
    904   if (!layer->TransformIsAnimatingOnImplOnly() && !TransformIsAnimating())
    905     layer->SetTransformAndInvertibility(transform_, transform_is_invertible_);
    906   DCHECK(!(TransformIsAnimating() && layer->TransformIsAnimatingOnImplOnly()));
    907   layer->Set3dSortingContextId(sorting_context_id_);
    908   layer->SetNumDescendantsThatDrawContent(num_descendants_that_draw_content_);
    909 
    910   layer->SetScrollClipLayer(scroll_clip_layer_id_);
    911   layer->set_user_scrollable_horizontal(user_scrollable_horizontal_);
    912   layer->set_user_scrollable_vertical(user_scrollable_vertical_);
    913 
    914   LayerImpl* scroll_parent = NULL;
    915   if (scroll_parent_) {
    916     scroll_parent = layer->layer_tree_impl()->LayerById(scroll_parent_->id());
    917     DCHECK(scroll_parent);
    918   }
    919 
    920   layer->SetScrollParent(scroll_parent);
    921   if (scroll_children_) {
    922     std::set<LayerImpl*>* scroll_children = new std::set<LayerImpl*>;
    923     for (std::set<Layer*>::iterator it = scroll_children_->begin();
    924          it != scroll_children_->end();
    925          ++it) {
    926       DCHECK_EQ((*it)->scroll_parent(), this);
    927       LayerImpl* scroll_child =
    928           layer->layer_tree_impl()->LayerById((*it)->id());
    929       DCHECK(scroll_child);
    930       scroll_children->insert(scroll_child);
    931     }
    932     layer->SetScrollChildren(scroll_children);
    933   } else {
    934     layer->SetScrollChildren(NULL);
    935   }
    936 
    937   LayerImpl* clip_parent = NULL;
    938   if (clip_parent_) {
    939     clip_parent =
    940         layer->layer_tree_impl()->LayerById(clip_parent_->id());
    941     DCHECK(clip_parent);
    942   }
    943 
    944   layer->SetClipParent(clip_parent);
    945   if (clip_children_) {
    946     std::set<LayerImpl*>* clip_children = new std::set<LayerImpl*>;
    947     for (std::set<Layer*>::iterator it = clip_children_->begin();
    948         it != clip_children_->end(); ++it) {
    949       DCHECK_EQ((*it)->clip_parent(), this);
    950       LayerImpl* clip_child = layer->layer_tree_impl()->LayerById((*it)->id());
    951       DCHECK(clip_child);
    952       clip_children->insert(clip_child);
    953     }
    954     layer->SetClipChildren(clip_children);
    955   } else {
    956     layer->SetClipChildren(NULL);
    957   }
    958 
    959   // Adjust the scroll delta to be just the scrolls that have happened since
    960   // the BeginMainFrame was sent.  This happens for impl-side painting
    961   // in LayerImpl::ApplyScrollDeltasSinceBeginMainFrame in a separate tree walk.
    962   if (layer->layer_tree_impl()->settings().impl_side_painting) {
    963     layer->SetScrollOffset(scroll_offset_);
    964   } else {
    965     layer->SetScrollOffsetAndDelta(
    966         scroll_offset_, layer->ScrollDelta() - layer->sent_scroll_delta());
    967     layer->SetSentScrollDelta(gfx::Vector2d());
    968   }
    969 
    970   // Wrap the copy_requests_ in a PostTask to the main thread.
    971   ScopedPtrVector<CopyOutputRequest> main_thread_copy_requests;
    972   for (ScopedPtrVector<CopyOutputRequest>::iterator it = copy_requests_.begin();
    973        it != copy_requests_.end();
    974        ++it) {
    975     scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner =
    976         layer_tree_host()->proxy()->MainThreadTaskRunner();
    977     scoped_ptr<CopyOutputRequest> original_request = copy_requests_.take(it);
    978     const CopyOutputRequest& original_request_ref = *original_request;
    979     scoped_ptr<CopyOutputRequest> main_thread_request =
    980         CopyOutputRequest::CreateRelayRequest(
    981             original_request_ref,
    982             base::Bind(&PostCopyCallbackToMainThread,
    983                        main_thread_task_runner,
    984                        base::Passed(&original_request)));
    985     main_thread_copy_requests.push_back(main_thread_request.Pass());
    986   }
    987   copy_requests_.clear();
    988   layer->PassCopyRequests(&main_thread_copy_requests);
    989 
    990   // If the main thread commits multiple times before the impl thread actually
    991   // draws, then damage tracking will become incorrect if we simply clobber the
    992   // update_rect here. The LayerImpl's update_rect needs to accumulate (i.e.
    993   // union) any update changes that have occurred on the main thread.
    994   update_rect_.Union(layer->update_rect());
    995   layer->SetUpdateRect(update_rect_);
    996 
    997   layer->SetStackingOrderChanged(stacking_order_changed_);
    998 
    999   layer_animation_controller_->PushAnimationUpdatesTo(
   1000       layer->layer_animation_controller());
   1001 
   1002   // Reset any state that should be cleared for the next update.
   1003   stacking_order_changed_ = false;
   1004   update_rect_ = gfx::RectF();
   1005 
   1006   needs_push_properties_ = false;
   1007   num_dependents_need_push_properties_ = 0;
   1008 }
   1009 
   1010 scoped_ptr<LayerImpl> Layer::CreateLayerImpl(LayerTreeImpl* tree_impl) {
   1011   return LayerImpl::Create(tree_impl, layer_id_);
   1012 }
   1013 
   1014 bool Layer::DrawsContent() const {
   1015   return draws_content_;
   1016 }
   1017 
   1018 bool Layer::HasDrawableContent() const {
   1019   return is_drawable_;
   1020 }
   1021 
   1022 void Layer::UpdateDrawsContent(bool has_drawable_content) {
   1023   bool draws_content = has_drawable_content;
   1024   DCHECK(is_drawable_ || !has_drawable_content);
   1025   if (draws_content == draws_content_)
   1026     return;
   1027 
   1028   if (HasDelegatedContent()) {
   1029     // Layers with delegated content need to be treated as if they have as
   1030     // many children as the number of layers they own delegated quads for.
   1031     // Since we don't know this number right now, we choose one that acts like
   1032     // infinity for our purposes.
   1033     AddDrawableDescendants(draws_content ? 1000 : -1000);
   1034   }
   1035 
   1036   if (parent())
   1037     parent()->AddDrawableDescendants(draws_content ? 1 : -1);
   1038 
   1039   draws_content_ = draws_content;
   1040   SetNeedsCommit();
   1041 }
   1042 
   1043 int Layer::NumDescendantsThatDrawContent() const {
   1044   return num_descendants_that_draw_content_;
   1045 }
   1046 
   1047 void Layer::SavePaintProperties() {
   1048   DCHECK(layer_tree_host_);
   1049 
   1050   // TODO(reveman): Save all layer properties that we depend on not
   1051   // changing until PushProperties() has been called. crbug.com/231016
   1052   paint_properties_.bounds = bounds_;
   1053   paint_properties_.source_frame_number =
   1054       layer_tree_host_->source_frame_number();
   1055 }
   1056 
   1057 bool Layer::Update(ResourceUpdateQueue* queue,
   1058                    const OcclusionTracker<Layer>* occlusion) {
   1059   DCHECK(layer_tree_host_);
   1060   DCHECK_EQ(layer_tree_host_->source_frame_number(),
   1061             paint_properties_.source_frame_number) <<
   1062       "SavePaintProperties must be called for any layer that is painted.";
   1063   return false;
   1064 }
   1065 
   1066 bool Layer::NeedMoreUpdates() {
   1067   return false;
   1068 }
   1069 
   1070 bool Layer::IsSuitableForGpuRasterization() const {
   1071   return true;
   1072 }
   1073 
   1074 scoped_refptr<base::debug::ConvertableToTraceFormat> Layer::TakeDebugInfo() {
   1075   if (client_)
   1076     return client_->TakeDebugInfo();
   1077   else
   1078     return NULL;
   1079 }
   1080 
   1081 void Layer::CreateRenderSurface() {
   1082   DCHECK(!draw_properties_.render_surface);
   1083   draw_properties_.render_surface = make_scoped_ptr(new RenderSurface(this));
   1084   draw_properties_.render_target = this;
   1085 }
   1086 
   1087 void Layer::ClearRenderSurface() {
   1088   draw_properties_.render_surface.reset();
   1089 }
   1090 
   1091 void Layer::ClearRenderSurfaceLayerList() {
   1092   if (draw_properties_.render_surface)
   1093     draw_properties_.render_surface->layer_list().clear();
   1094 }
   1095 
   1096 gfx::Vector2dF Layer::ScrollOffsetForAnimation() const {
   1097   return TotalScrollOffset();
   1098 }
   1099 
   1100 // On<Property>Animated is called due to an ongoing accelerated animation.
   1101 // Since this animation is also being run on the compositor thread, there
   1102 // is no need to request a commit to push this value over, so the value is
   1103 // set directly rather than by calling Set<Property>.
   1104 void Layer::OnFilterAnimated(const FilterOperations& filters) {
   1105   filters_ = filters;
   1106 }
   1107 
   1108 void Layer::OnOpacityAnimated(float opacity) {
   1109   opacity_ = opacity;
   1110 }
   1111 
   1112 void Layer::OnTransformAnimated(const gfx::Transform& transform) {
   1113   if (transform_ == transform)
   1114     return;
   1115   transform_ = transform;
   1116   transform_is_invertible_ = transform.IsInvertible();
   1117 }
   1118 
   1119 void Layer::OnScrollOffsetAnimated(const gfx::Vector2dF& scroll_offset) {
   1120   // Do nothing. Scroll deltas will be sent from the compositor thread back
   1121   // to the main thread in the same manner as during non-animated
   1122   // compositor-driven scrolling.
   1123 }
   1124 
   1125 void Layer::OnAnimationWaitingForDeletion() {
   1126   // Animations are only deleted during PushProperties.
   1127   SetNeedsPushProperties();
   1128 }
   1129 
   1130 bool Layer::IsActive() const {
   1131   return true;
   1132 }
   1133 
   1134 bool Layer::AddAnimation(scoped_ptr <Animation> animation) {
   1135   if (!layer_animation_controller_->animation_registrar())
   1136     return false;
   1137 
   1138   if (animation->target_property() == Animation::ScrollOffset &&
   1139       !layer_animation_controller_->animation_registrar()
   1140            ->supports_scroll_animations())
   1141     return false;
   1142 
   1143   UMA_HISTOGRAM_BOOLEAN("Renderer.AnimationAddedToOrphanLayer",
   1144                         !layer_tree_host_);
   1145   layer_animation_controller_->AddAnimation(animation.Pass());
   1146   SetNeedsCommit();
   1147   return true;
   1148 }
   1149 
   1150 void Layer::PauseAnimation(int animation_id, double time_offset) {
   1151   layer_animation_controller_->PauseAnimation(
   1152       animation_id, base::TimeDelta::FromSecondsD(time_offset));
   1153   SetNeedsCommit();
   1154 }
   1155 
   1156 void Layer::RemoveAnimation(int animation_id) {
   1157   layer_animation_controller_->RemoveAnimation(animation_id);
   1158   SetNeedsCommit();
   1159 }
   1160 
   1161 void Layer::SetLayerAnimationControllerForTest(
   1162     scoped_refptr<LayerAnimationController> controller) {
   1163   layer_animation_controller_->RemoveValueObserver(this);
   1164   layer_animation_controller_ = controller;
   1165   layer_animation_controller_->AddValueObserver(this);
   1166   SetNeedsCommit();
   1167 }
   1168 
   1169 bool Layer::HasActiveAnimation() const {
   1170   return layer_animation_controller_->HasActiveAnimation();
   1171 }
   1172 
   1173 void Layer::AddLayerAnimationEventObserver(
   1174     LayerAnimationEventObserver* animation_observer) {
   1175   layer_animation_controller_->AddEventObserver(animation_observer);
   1176 }
   1177 
   1178 void Layer::RemoveLayerAnimationEventObserver(
   1179     LayerAnimationEventObserver* animation_observer) {
   1180   layer_animation_controller_->RemoveEventObserver(animation_observer);
   1181 }
   1182 
   1183 SimpleEnclosedRegion Layer::VisibleContentOpaqueRegion() const {
   1184   if (contents_opaque())
   1185     return SimpleEnclosedRegion(visible_content_rect());
   1186   return SimpleEnclosedRegion();
   1187 }
   1188 
   1189 ScrollbarLayerInterface* Layer::ToScrollbarLayer() {
   1190   return NULL;
   1191 }
   1192 
   1193 RenderingStatsInstrumentation* Layer::rendering_stats_instrumentation() const {
   1194   return layer_tree_host_->rendering_stats_instrumentation();
   1195 }
   1196 
   1197 bool Layer::SupportsLCDText() const {
   1198   return false;
   1199 }
   1200 
   1201 void Layer::RemoveFromScrollTree() {
   1202   if (scroll_children_.get()) {
   1203     std::set<Layer*> copy = *scroll_children_;
   1204     for (std::set<Layer*>::iterator it = copy.begin(); it != copy.end(); ++it)
   1205       (*it)->SetScrollParent(NULL);
   1206   }
   1207 
   1208   DCHECK(!scroll_children_);
   1209   SetScrollParent(NULL);
   1210 }
   1211 
   1212 void Layer::RemoveFromClipTree() {
   1213   if (clip_children_.get()) {
   1214     std::set<Layer*> copy = *clip_children_;
   1215     for (std::set<Layer*>::iterator it = copy.begin(); it != copy.end(); ++it)
   1216       (*it)->SetClipParent(NULL);
   1217   }
   1218 
   1219   DCHECK(!clip_children_);
   1220   SetClipParent(NULL);
   1221 }
   1222 
   1223 void Layer::AddDrawableDescendants(int num) {
   1224   DCHECK_GE(num_descendants_that_draw_content_, 0);
   1225   DCHECK_GE(num_descendants_that_draw_content_ + num, 0);
   1226   if (num == 0)
   1227     return;
   1228   num_descendants_that_draw_content_ += num;
   1229   SetNeedsCommit();
   1230   if (parent())
   1231     parent()->AddDrawableDescendants(num);
   1232 }
   1233 
   1234 void Layer::RunMicroBenchmark(MicroBenchmark* benchmark) {
   1235   benchmark->RunOnLayer(this);
   1236 }
   1237 
   1238 bool Layer::HasDelegatedContent() const {
   1239   return false;
   1240 }
   1241 
   1242 }  // namespace cc
   1243