Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / cc / layers / layer.cc
index 44c71e5..1a22d92 100644 (file)
@@ -6,14 +6,18 @@
 
 #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/base/simple_enclosed_region.h"
 #include "cc/layers/layer_client.h"
 #include "cc/layers/layer_impl.h"
 #include "cc/layers/scrollbar_layer_interface.h"
@@ -27,7 +31,7 @@
 
 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());
@@ -37,18 +41,23 @@ Layer::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),
       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),
       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),
@@ -57,21 +66,15 @@ Layer::Layer()
       use_parent_backface_visibility_(false),
       draw_checkerboard_for_missing_tiles_(false),
       force_render_surface_(false),
-      is_3d_sorted_(false),
-      anchor_point_(0.5f, 0.5f),
+      transform_is_invertible_(true),
       background_color_(0),
       opacity_(1.f),
       blend_mode_(SkXfermode::kSrcOver_Mode),
-      anchor_point_z_(0.f),
       scroll_parent_(NULL),
       clip_parent_(NULL),
       replica_layer_(NULL),
       raster_scale_(0.f),
       client_(NULL) {
-  if (layer_id_ == INT_MAX) {
-    s_next_layer_id = 1;
-  }
-
   layer_animation_controller_ = LayerAnimationController::Create(layer_id_);
   layer_animation_controller_->AddValueObserver(this);
   layer_animation_controller_->set_value_provider(this);
@@ -88,6 +91,9 @@ Layer::~Layer() {
   layer_animation_controller_->RemoveValueObserver(this);
   layer_animation_controller_->remove_value_provider(this);
 
+  RemoveFromScrollTree();
+  RemoveFromClipTree();
+
   // Remove the parent reference from all children and dependents.
   RemoveAllChildren();
   if (mask_layer_.get()) {
@@ -98,9 +104,6 @@ Layer::~Layer() {
     DCHECK_EQ(this, replica_layer_->parent());
     replica_layer_->RemoveFromParent();
   }
-
-  RemoveFromScrollTree();
-  RemoveFromClipTree();
 }
 
 void Layer::SetLayerTreeHost(LayerTreeHost* host) {
@@ -131,7 +134,6 @@ void Layer::SetLayerTreeHost(LayerTreeHost* host) {
 
   if (host && layer_animation_controller_->has_any_animation())
     host->SetNeedsCommit();
-  SetNeedsFilterContextIfNeeded();
 }
 
 void Layer::SetNeedsUpdate() {
@@ -165,15 +167,6 @@ void Layer::SetNextCommitWaitsForActivation() {
   layer_tree_host_->SetNextCommitWaitsForActivation();
 }
 
-void Layer::SetNeedsFilterContextIfNeeded() {
-  if (!layer_tree_host_)
-    return;
-
-  if (!filters_.IsEmpty() || !background_filters_.IsEmpty() ||
-      !uses_default_blend_mode())
-    layer_tree_host_->set_needs_filter_context();
-}
-
 void Layer::SetNeedsPushProperties() {
   if (needs_push_properties_)
     return;
@@ -255,6 +248,8 @@ void Layer::AddChild(scoped_refptr<Layer> child) {
 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;
 
@@ -290,6 +285,8 @@ void Layer::RemoveChildOrDependent(Layer* child) {
       continue;
 
     child->SetParent(NULL);
+    AddDrawableDescendants(-child->NumDescendantsThatDrawContent() -
+                           (child->DrawsContent() ? 1 : 0));
     children_.erase(iter);
     SetNeedsFullTreeSync();
     return;
@@ -378,22 +375,6 @@ void Layer::RequestCopyOfOutput(
   SetNeedsCommit();
 }
 
-void Layer::SetAnchorPoint(const 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)
@@ -421,14 +402,10 @@ SkColor Layer::SafeOpaqueBackgroundColor() const {
   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;
@@ -485,7 +462,6 @@ void Layer::SetFilters(const FilterOperations& filters) {
     return;
   filters_ = filters;
   SetNeedsCommit();
-  SetNeedsFilterContextIfNeeded();
 }
 
 bool Layer::FilterIsAnimating() const {
@@ -498,7 +474,6 @@ void Layer::SetBackgroundFilters(const FilterOperations& filters) {
     return;
   background_filters_ = filters;
   SetNeedsCommit();
-  SetNeedsFilterContextIfNeeded();
 }
 
 void Layer::SetOpacity(float opacity) {
@@ -564,7 +539,6 @@ void Layer::SetBlendMode(SkXfermode::Mode blend_mode) {
 
   blend_mode_ = blend_mode;
   SetNeedsCommit();
-  SetNeedsFilterContextIfNeeded();
 }
 
 void Layer::SetIsRootForIsolatedGroup(bool root) {
@@ -604,6 +578,15 @@ void Layer::SetTransform(const gfx::Transform& transform) {
   if (transform_ == transform)
     return;
   transform_ = transform;
+  transform_is_invertible_ = transform.IsInvertible();
+  SetNeedsCommit();
+}
+
+void Layer::SetTransformOrigin(const gfx::Point3F& transform_origin) {
+  DCHECK(IsPropertyChangeAllowed());
+  if (transform_origin_ == transform_origin)
+    return;
+  transform_origin_ = transform_origin;
   SetNeedsCommit();
 }
 
@@ -695,40 +678,6 @@ void Layer::SetScrollOffsetFromImplSide(const gfx::Vector2d& scroll_offset) {
   // "this" may have been destroyed during the process.
 }
 
-// TODO(wjmaclean) We should template this and put it into LayerTreeHostCommon
-// so that both Layer and LayerImpl are using the same code. In order
-// to template it we should avoid calling layer_tree_host() by giving
-// Layer/LayerImpl local accessors for page_scale_layer() and
-// page_scale_factor().
-gfx::Vector2d Layer::MaxScrollOffset() const {
-  if (scroll_clip_layer_id_ == INVALID_ID)
-    return gfx::Vector2d();
-
-  gfx::Size scaled_scroll_bounds(bounds());
-  Layer const* current_layer = this;
-  Layer const* page_scale_layer = layer_tree_host()->page_scale_layer();
-  float scale_factor = 1.f;
-  do {
-    if (current_layer == page_scale_layer) {
-      scale_factor = layer_tree_host()->page_scale_factor();
-      scaled_scroll_bounds.SetSize(
-          scale_factor * scaled_scroll_bounds.width(),
-          scale_factor * scaled_scroll_bounds.height());
-    }
-    current_layer = current_layer->parent();
-  } while (current_layer && current_layer->id() != scroll_clip_layer_id_);
-  DCHECK(current_layer);
-  DCHECK(current_layer->id() == scroll_clip_layer_id_);
-
-  gfx::Vector2dF max_offset(
-      scaled_scroll_bounds.width() - current_layer->bounds().width(),
-      scaled_scroll_bounds.height() - current_layer->bounds().height());
-  // We need the final scroll offset to be in CSS coords.
-  max_offset.Scale(1.f / scale_factor);
-  max_offset.SetToMax(gfx::Vector2dF());
-  return gfx::ToFlooredVector2d(max_offset);
-}
-
 void Layer::SetScrollClipLayerId(int clip_layer_id) {
   DCHECK(IsPropertyChangeAllowed());
   if (scroll_clip_layer_id_ == clip_layer_id)
@@ -763,6 +712,14 @@ void Layer::SetHaveWheelEventHandlers(bool have_wheel_event_handlers) {
   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)
@@ -803,11 +760,11 @@ void Layer::SetDoubleSided(bool double_sided) {
   SetNeedsCommit();
 }
 
-void Layer::SetIs3dSorted(bool sorted) {
+void Layer::Set3dSortingContextId(int id) {
   DCHECK(IsPropertyChangeAllowed());
-  if (is_3d_sorted_ == sorted)
+  if (id == sorting_context_id_)
     return;
-  is_3d_sorted_ = sorted;
+  sorting_context_id_ = id;
   SetNeedsCommit();
 }
 
@@ -825,7 +782,7 @@ void Layer::SetIsDrawable(bool is_drawable) {
     return;
 
   is_drawable_ = is_drawable;
-  SetNeedsCommit();
+  UpdateDrawsContent(HasDrawableContent());
 }
 
 void Layer::SetHideLayerAndSubtree(bool hide) {
@@ -901,8 +858,7 @@ void Layer::PushPropertiesTo(LayerImpl* layer) {
   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_);
@@ -910,8 +866,10 @@ void Layer::PushPropertiesTo(LayerImpl* layer) {
   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->SetDebugInfo(TakeDebugInfo());
 
@@ -928,6 +886,7 @@ void Layer::PushPropertiesTo(LayerImpl* layer) {
   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_);
@@ -941,11 +900,12 @@ void Layer::PushPropertiesTo(LayerImpl* layer) {
       IsContainerForFixedPositionLayers());
   layer->SetPositionConstraint(position_constraint_);
   layer->SetShouldFlattenTransform(should_flatten_transform_);
-  layer->SetIs3dSorted(is_3d_sorted_);
   layer->SetUseParentBackfaceVisibility(use_parent_backface_visibility_);
   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->SetScrollClipLayer(scroll_clip_layer_id_);
   layer->set_user_scrollable_horizontal(user_scrollable_horizontal_);
@@ -1052,9 +1012,38 @@ scoped_ptr<LayerImpl> Layer::CreateLayerImpl(LayerTreeImpl* tree_impl) {
 }
 
 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_);
 
@@ -1078,6 +1067,10 @@ bool Layer::NeedMoreUpdates() {
   return false;
 }
 
+bool Layer::IsSuitableForGpuRasterization() const {
+  return true;
+}
+
 scoped_refptr<base::debug::ConvertableToTraceFormat> Layer::TakeDebugInfo() {
   if (client_)
     return client_->TakeDebugInfo();
@@ -1095,6 +1088,11 @@ void Layer::ClearRenderSurface() {
   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();
 }
@@ -1112,7 +1110,10 @@ void Layer::OnOpacityAnimated(float opacity) {
 }
 
 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) {
@@ -1134,6 +1135,11 @@ bool Layer::AddAnimation(scoped_ptr <Animation> animation) {
   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());
@@ -1142,7 +1148,8 @@ bool Layer::AddAnimation(scoped_ptr <Animation> animation) {
 }
 
 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();
 }
 
@@ -1173,10 +1180,10 @@ void Layer::RemoveLayerAnimationEventObserver(
   layer_animation_controller_->RemoveEventObserver(animation_observer);
 }
 
-Region Layer::VisibleContentOpaqueRegion() const {
+SimpleEnclosedRegion Layer::VisibleContentOpaqueRegion() const {
   if (contents_opaque())
-    return visible_content_rect();
-  return Region();
+    return SimpleEnclosedRegion(visible_content_rect());
+  return SimpleEnclosedRegion();
 }
 
 ScrollbarLayerInterface* Layer::ToScrollbarLayer() {
@@ -1193,31 +1200,43 @@ bool Layer::SupportsLCDText() const {
 
 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