Home | History | Annotate | Download | only in blink
      1 // Copyright 2014 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/blink/web_layer_impl.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/debug/trace_event_impl.h"
      9 #include "base/lazy_instance.h"
     10 #include "base/strings/string_util.h"
     11 #include "base/threading/thread_checker.h"
     12 #include "cc/animation/animation.h"
     13 #include "cc/base/region.h"
     14 #include "cc/base/switches.h"
     15 #include "cc/blink/web_animation_impl.h"
     16 #include "cc/blink/web_blend_mode.h"
     17 #include "cc/blink/web_filter_operations_impl.h"
     18 #include "cc/blink/web_to_cc_animation_delegate_adapter.h"
     19 #include "cc/layers/layer.h"
     20 #include "cc/layers/layer_position_constraint.h"
     21 #include "cc/trees/layer_tree_host.h"
     22 #include "third_party/WebKit/public/platform/WebFloatPoint.h"
     23 #include "third_party/WebKit/public/platform/WebFloatRect.h"
     24 #include "third_party/WebKit/public/platform/WebGraphicsLayerDebugInfo.h"
     25 #include "third_party/WebKit/public/platform/WebLayerClient.h"
     26 #include "third_party/WebKit/public/platform/WebLayerPositionConstraint.h"
     27 #include "third_party/WebKit/public/platform/WebLayerScrollClient.h"
     28 #include "third_party/WebKit/public/platform/WebSize.h"
     29 #include "third_party/skia/include/utils/SkMatrix44.h"
     30 
     31 using cc::Animation;
     32 using cc::Layer;
     33 using blink::WebLayer;
     34 using blink::WebFloatPoint;
     35 using blink::WebVector;
     36 using blink::WebRect;
     37 using blink::WebSize;
     38 using blink::WebColor;
     39 using blink::WebFilterOperations;
     40 
     41 namespace cc_blink {
     42 namespace {
     43 
     44 bool g_impl_side_painting_enabled = false;
     45 
     46 }  // namespace
     47 
     48 WebLayerImpl::WebLayerImpl() : layer_(Layer::Create()) {
     49   web_layer_client_ = NULL;
     50   layer_->SetLayerClient(this);
     51 }
     52 
     53 WebLayerImpl::WebLayerImpl(scoped_refptr<Layer> layer) : layer_(layer) {
     54   web_layer_client_ = NULL;
     55   layer_->SetLayerClient(this);
     56 }
     57 
     58 WebLayerImpl::~WebLayerImpl() {
     59   layer_->ClearRenderSurface();
     60   layer_->set_layer_animation_delegate(NULL);
     61   web_layer_client_ = NULL;
     62 }
     63 
     64 // static
     65 bool WebLayerImpl::UsingPictureLayer() {
     66   return g_impl_side_painting_enabled;
     67 }
     68 
     69 // static
     70 void WebLayerImpl::SetImplSidePaintingEnabled(bool enabled) {
     71   g_impl_side_painting_enabled = enabled;
     72 }
     73 
     74 int WebLayerImpl::id() const {
     75   return layer_->id();
     76 }
     77 
     78 void WebLayerImpl::invalidateRect(const blink::WebFloatRect& rect) {
     79   layer_->SetNeedsDisplayRect(rect);
     80 }
     81 
     82 void WebLayerImpl::invalidate() {
     83   layer_->SetNeedsDisplay();
     84 }
     85 
     86 void WebLayerImpl::addChild(WebLayer* child) {
     87   layer_->AddChild(static_cast<WebLayerImpl*>(child)->layer());
     88 }
     89 
     90 void WebLayerImpl::insertChild(WebLayer* child, size_t index) {
     91   layer_->InsertChild(static_cast<WebLayerImpl*>(child)->layer(), index);
     92 }
     93 
     94 void WebLayerImpl::replaceChild(WebLayer* reference, WebLayer* new_layer) {
     95   layer_->ReplaceChild(static_cast<WebLayerImpl*>(reference)->layer(),
     96                        static_cast<WebLayerImpl*>(new_layer)->layer());
     97 }
     98 
     99 void WebLayerImpl::removeFromParent() {
    100   layer_->RemoveFromParent();
    101 }
    102 
    103 void WebLayerImpl::removeAllChildren() {
    104   layer_->RemoveAllChildren();
    105 }
    106 
    107 void WebLayerImpl::setBounds(const WebSize& size) {
    108   layer_->SetBounds(size);
    109 }
    110 
    111 WebSize WebLayerImpl::bounds() const {
    112   return layer_->bounds();
    113 }
    114 
    115 void WebLayerImpl::setMasksToBounds(bool masks_to_bounds) {
    116   layer_->SetMasksToBounds(masks_to_bounds);
    117 }
    118 
    119 bool WebLayerImpl::masksToBounds() const {
    120   return layer_->masks_to_bounds();
    121 }
    122 
    123 void WebLayerImpl::setMaskLayer(WebLayer* maskLayer) {
    124   layer_->SetMaskLayer(
    125       maskLayer ? static_cast<WebLayerImpl*>(maskLayer)->layer() : 0);
    126 }
    127 
    128 void WebLayerImpl::setReplicaLayer(WebLayer* replica_layer) {
    129   layer_->SetReplicaLayer(
    130       replica_layer ? static_cast<WebLayerImpl*>(replica_layer)->layer() : 0);
    131 }
    132 
    133 void WebLayerImpl::setOpacity(float opacity) {
    134   layer_->SetOpacity(opacity);
    135 }
    136 
    137 float WebLayerImpl::opacity() const {
    138   return layer_->opacity();
    139 }
    140 
    141 void WebLayerImpl::setBlendMode(blink::WebBlendMode blend_mode) {
    142   layer_->SetBlendMode(BlendModeToSkia(blend_mode));
    143 }
    144 
    145 blink::WebBlendMode WebLayerImpl::blendMode() const {
    146   return BlendModeFromSkia(layer_->blend_mode());
    147 }
    148 
    149 void WebLayerImpl::setIsRootForIsolatedGroup(bool isolate) {
    150   layer_->SetIsRootForIsolatedGroup(isolate);
    151 }
    152 
    153 bool WebLayerImpl::isRootForIsolatedGroup() {
    154   return layer_->is_root_for_isolated_group();
    155 }
    156 
    157 void WebLayerImpl::setOpaque(bool opaque) {
    158   layer_->SetContentsOpaque(opaque);
    159 }
    160 
    161 bool WebLayerImpl::opaque() const {
    162   return layer_->contents_opaque();
    163 }
    164 
    165 void WebLayerImpl::setPosition(const WebFloatPoint& position) {
    166   layer_->SetPosition(position);
    167 }
    168 
    169 WebFloatPoint WebLayerImpl::position() const {
    170   return layer_->position();
    171 }
    172 
    173 void WebLayerImpl::setTransform(const SkMatrix44& matrix) {
    174   gfx::Transform transform;
    175   transform.matrix() = matrix;
    176   layer_->SetTransform(transform);
    177 }
    178 
    179 void WebLayerImpl::setTransformOrigin(const blink::WebFloatPoint3D& point) {
    180   gfx::Point3F gfx_point = point;
    181   layer_->SetTransformOrigin(gfx_point);
    182 }
    183 
    184 blink::WebFloatPoint3D WebLayerImpl::transformOrigin() const {
    185   return layer_->transform_origin();
    186 }
    187 
    188 SkMatrix44 WebLayerImpl::transform() const {
    189   return layer_->transform().matrix();
    190 }
    191 
    192 void WebLayerImpl::setDrawsContent(bool draws_content) {
    193   layer_->SetIsDrawable(draws_content);
    194 }
    195 
    196 bool WebLayerImpl::drawsContent() const {
    197   return layer_->DrawsContent();
    198 }
    199 
    200 void WebLayerImpl::setShouldFlattenTransform(bool flatten) {
    201   layer_->SetShouldFlattenTransform(flatten);
    202 }
    203 
    204 void WebLayerImpl::setRenderingContext(int context) {
    205   layer_->Set3dSortingContextId(context);
    206 }
    207 
    208 void WebLayerImpl::setUseParentBackfaceVisibility(
    209     bool use_parent_backface_visibility) {
    210   layer_->set_use_parent_backface_visibility(use_parent_backface_visibility);
    211 }
    212 
    213 void WebLayerImpl::setBackgroundColor(WebColor color) {
    214   layer_->SetBackgroundColor(color);
    215 }
    216 
    217 WebColor WebLayerImpl::backgroundColor() const {
    218   return layer_->background_color();
    219 }
    220 
    221 void WebLayerImpl::setFilters(const WebFilterOperations& filters) {
    222   const WebFilterOperationsImpl& filters_impl =
    223       static_cast<const WebFilterOperationsImpl&>(filters);
    224   layer_->SetFilters(filters_impl.AsFilterOperations());
    225 }
    226 
    227 void WebLayerImpl::setBackgroundFilters(const WebFilterOperations& filters) {
    228   const WebFilterOperationsImpl& filters_impl =
    229       static_cast<const WebFilterOperationsImpl&>(filters);
    230   layer_->SetBackgroundFilters(filters_impl.AsFilterOperations());
    231 }
    232 
    233 void WebLayerImpl::setAnimationDelegate(
    234     blink::WebCompositorAnimationDelegate* delegate) {
    235   animation_delegate_adapter_.reset(
    236       new WebToCCAnimationDelegateAdapter(delegate));
    237   layer_->set_layer_animation_delegate(animation_delegate_adapter_.get());
    238 }
    239 
    240 bool WebLayerImpl::addAnimation(blink::WebCompositorAnimation* animation) {
    241   bool result = layer_->AddAnimation(
    242       static_cast<WebCompositorAnimationImpl*>(animation)->PassAnimation());
    243   delete animation;
    244   return result;
    245 }
    246 
    247 void WebLayerImpl::removeAnimation(int animation_id) {
    248   layer_->RemoveAnimation(animation_id);
    249 }
    250 
    251 void WebLayerImpl::removeAnimation(
    252     int animation_id,
    253     blink::WebCompositorAnimation::TargetProperty target_property) {
    254   layer_->layer_animation_controller()->RemoveAnimation(
    255       animation_id, static_cast<Animation::TargetProperty>(target_property));
    256 }
    257 
    258 void WebLayerImpl::pauseAnimation(int animation_id, double time_offset) {
    259   layer_->PauseAnimation(animation_id, time_offset);
    260 }
    261 
    262 bool WebLayerImpl::hasActiveAnimation() {
    263   return layer_->HasActiveAnimation();
    264 }
    265 
    266 void WebLayerImpl::setForceRenderSurface(bool force_render_surface) {
    267   layer_->SetForceRenderSurface(force_render_surface);
    268 }
    269 
    270 void WebLayerImpl::setScrollPosition(blink::WebPoint position) {
    271   layer_->SetScrollOffset(gfx::Point(position).OffsetFromOrigin());
    272 }
    273 
    274 blink::WebPoint WebLayerImpl::scrollPosition() const {
    275   return gfx::PointAtOffsetFromOrigin(layer_->scroll_offset());
    276 }
    277 
    278 void WebLayerImpl::setScrollClipLayer(WebLayer* clip_layer) {
    279   if (!clip_layer) {
    280     layer_->SetScrollClipLayerId(Layer::INVALID_ID);
    281     return;
    282   }
    283   layer_->SetScrollClipLayerId(clip_layer->id());
    284 }
    285 
    286 bool WebLayerImpl::scrollable() const {
    287   return layer_->scrollable();
    288 }
    289 
    290 void WebLayerImpl::setUserScrollable(bool horizontal, bool vertical) {
    291   layer_->SetUserScrollable(horizontal, vertical);
    292 }
    293 
    294 bool WebLayerImpl::userScrollableHorizontal() const {
    295   return layer_->user_scrollable_horizontal();
    296 }
    297 
    298 bool WebLayerImpl::userScrollableVertical() const {
    299   return layer_->user_scrollable_vertical();
    300 }
    301 
    302 void WebLayerImpl::setHaveWheelEventHandlers(bool have_wheel_event_handlers) {
    303   layer_->SetHaveWheelEventHandlers(have_wheel_event_handlers);
    304 }
    305 
    306 bool WebLayerImpl::haveWheelEventHandlers() const {
    307   return layer_->have_wheel_event_handlers();
    308 }
    309 
    310 void WebLayerImpl::setHaveScrollEventHandlers(bool have_scroll_event_handlers) {
    311   layer_->SetHaveScrollEventHandlers(have_scroll_event_handlers);
    312 }
    313 
    314 bool WebLayerImpl::haveScrollEventHandlers() const {
    315   return layer_->have_scroll_event_handlers();
    316 }
    317 
    318 void WebLayerImpl::setShouldScrollOnMainThread(
    319     bool should_scroll_on_main_thread) {
    320   layer_->SetShouldScrollOnMainThread(should_scroll_on_main_thread);
    321 }
    322 
    323 bool WebLayerImpl::shouldScrollOnMainThread() const {
    324   return layer_->should_scroll_on_main_thread();
    325 }
    326 
    327 void WebLayerImpl::setNonFastScrollableRegion(const WebVector<WebRect>& rects) {
    328   cc::Region region;
    329   for (size_t i = 0; i < rects.size(); ++i)
    330     region.Union(rects[i]);
    331   layer_->SetNonFastScrollableRegion(region);
    332 }
    333 
    334 WebVector<WebRect> WebLayerImpl::nonFastScrollableRegion() const {
    335   size_t num_rects = 0;
    336   for (cc::Region::Iterator region_rects(layer_->non_fast_scrollable_region());
    337        region_rects.has_rect();
    338        region_rects.next())
    339     ++num_rects;
    340 
    341   WebVector<WebRect> result(num_rects);
    342   size_t i = 0;
    343   for (cc::Region::Iterator region_rects(layer_->non_fast_scrollable_region());
    344        region_rects.has_rect();
    345        region_rects.next()) {
    346     result[i] = region_rects.rect();
    347     ++i;
    348   }
    349   return result;
    350 }
    351 
    352 void WebLayerImpl::setTouchEventHandlerRegion(const WebVector<WebRect>& rects) {
    353   cc::Region region;
    354   for (size_t i = 0; i < rects.size(); ++i)
    355     region.Union(rects[i]);
    356   layer_->SetTouchEventHandlerRegion(region);
    357 }
    358 
    359 WebVector<WebRect> WebLayerImpl::touchEventHandlerRegion() const {
    360   size_t num_rects = 0;
    361   for (cc::Region::Iterator region_rects(layer_->touch_event_handler_region());
    362        region_rects.has_rect();
    363        region_rects.next())
    364     ++num_rects;
    365 
    366   WebVector<WebRect> result(num_rects);
    367   size_t i = 0;
    368   for (cc::Region::Iterator region_rects(layer_->touch_event_handler_region());
    369        region_rects.has_rect();
    370        region_rects.next()) {
    371     result[i] = region_rects.rect();
    372     ++i;
    373   }
    374   return result;
    375 }
    376 
    377 void WebLayerImpl::setIsContainerForFixedPositionLayers(bool enable) {
    378   layer_->SetIsContainerForFixedPositionLayers(enable);
    379 }
    380 
    381 bool WebLayerImpl::isContainerForFixedPositionLayers() const {
    382   return layer_->IsContainerForFixedPositionLayers();
    383 }
    384 
    385 static blink::WebLayerPositionConstraint ToWebLayerPositionConstraint(
    386     const cc::LayerPositionConstraint& constraint) {
    387   blink::WebLayerPositionConstraint web_constraint;
    388   web_constraint.isFixedPosition = constraint.is_fixed_position();
    389   web_constraint.isFixedToRightEdge = constraint.is_fixed_to_right_edge();
    390   web_constraint.isFixedToBottomEdge = constraint.is_fixed_to_bottom_edge();
    391   return web_constraint;
    392 }
    393 
    394 static cc::LayerPositionConstraint ToLayerPositionConstraint(
    395     const blink::WebLayerPositionConstraint& web_constraint) {
    396   cc::LayerPositionConstraint constraint;
    397   constraint.set_is_fixed_position(web_constraint.isFixedPosition);
    398   constraint.set_is_fixed_to_right_edge(web_constraint.isFixedToRightEdge);
    399   constraint.set_is_fixed_to_bottom_edge(web_constraint.isFixedToBottomEdge);
    400   return constraint;
    401 }
    402 
    403 void WebLayerImpl::setPositionConstraint(
    404     const blink::WebLayerPositionConstraint& constraint) {
    405   layer_->SetPositionConstraint(ToLayerPositionConstraint(constraint));
    406 }
    407 
    408 blink::WebLayerPositionConstraint WebLayerImpl::positionConstraint() const {
    409   return ToWebLayerPositionConstraint(layer_->position_constraint());
    410 }
    411 
    412 void WebLayerImpl::setScrollClient(blink::WebLayerScrollClient* scroll_client) {
    413   if (scroll_client) {
    414     layer_->set_did_scroll_callback(
    415         base::Bind(&blink::WebLayerScrollClient::didScroll,
    416                    base::Unretained(scroll_client)));
    417   } else {
    418     layer_->set_did_scroll_callback(base::Closure());
    419   }
    420 }
    421 
    422 bool WebLayerImpl::isOrphan() const {
    423   return !layer_->layer_tree_host();
    424 }
    425 
    426 void WebLayerImpl::setWebLayerClient(blink::WebLayerClient* client) {
    427   web_layer_client_ = client;
    428 }
    429 
    430 class TracedDebugInfo : public base::debug::ConvertableToTraceFormat {
    431  public:
    432   // This object takes ownership of the debug_info object.
    433   explicit TracedDebugInfo(blink::WebGraphicsLayerDebugInfo* debug_info)
    434       : debug_info_(debug_info) {}
    435   virtual void AppendAsTraceFormat(std::string* out) const OVERRIDE {
    436     DCHECK(thread_checker_.CalledOnValidThread());
    437     blink::WebString web_string;
    438     debug_info_->appendAsTraceFormat(&web_string);
    439     out->append(web_string.utf8());
    440   }
    441 
    442  private:
    443   virtual ~TracedDebugInfo() {}
    444   scoped_ptr<blink::WebGraphicsLayerDebugInfo> debug_info_;
    445   base::ThreadChecker thread_checker_;
    446 };
    447 
    448 scoped_refptr<base::debug::ConvertableToTraceFormat>
    449 WebLayerImpl::TakeDebugInfo() {
    450   if (!web_layer_client_)
    451     return NULL;
    452   blink::WebGraphicsLayerDebugInfo* debug_info =
    453       web_layer_client_->takeDebugInfoFor(this);
    454 
    455   if (debug_info)
    456     return new TracedDebugInfo(debug_info);
    457   else
    458     return NULL;
    459 }
    460 
    461 void WebLayerImpl::setScrollParent(blink::WebLayer* parent) {
    462   cc::Layer* scroll_parent = NULL;
    463   if (parent)
    464     scroll_parent = static_cast<WebLayerImpl*>(parent)->layer();
    465   layer_->SetScrollParent(scroll_parent);
    466 }
    467 
    468 void WebLayerImpl::setClipParent(blink::WebLayer* parent) {
    469   cc::Layer* clip_parent = NULL;
    470   if (parent)
    471     clip_parent = static_cast<WebLayerImpl*>(parent)->layer();
    472   layer_->SetClipParent(clip_parent);
    473 }
    474 
    475 Layer* WebLayerImpl::layer() const {
    476   return layer_.get();
    477 }
    478 
    479 }  // namespace cc_blink
    480