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 31using cc::Animation; 32using cc::Layer; 33using blink::WebLayer; 34using blink::WebFloatPoint; 35using blink::WebVector; 36using blink::WebRect; 37using blink::WebSize; 38using blink::WebColor; 39using blink::WebFilterOperations; 40 41namespace cc_blink { 42namespace { 43 44bool g_impl_side_painting_enabled = false; 45 46} // namespace 47 48WebLayerImpl::WebLayerImpl() : layer_(Layer::Create()) { 49 web_layer_client_ = NULL; 50 layer_->SetLayerClient(this); 51} 52 53WebLayerImpl::WebLayerImpl(scoped_refptr<Layer> layer) : layer_(layer) { 54 web_layer_client_ = NULL; 55 layer_->SetLayerClient(this); 56} 57 58WebLayerImpl::~WebLayerImpl() { 59 layer_->ClearRenderSurface(); 60 layer_->set_layer_animation_delegate(NULL); 61 web_layer_client_ = NULL; 62} 63 64// static 65bool WebLayerImpl::UsingPictureLayer() { 66 return g_impl_side_painting_enabled; 67} 68 69// static 70void WebLayerImpl::SetImplSidePaintingEnabled(bool enabled) { 71 g_impl_side_painting_enabled = enabled; 72} 73 74int WebLayerImpl::id() const { 75 return layer_->id(); 76} 77 78void WebLayerImpl::invalidateRect(const blink::WebFloatRect& rect) { 79 layer_->SetNeedsDisplayRect(rect); 80} 81 82void WebLayerImpl::invalidate() { 83 layer_->SetNeedsDisplay(); 84} 85 86void WebLayerImpl::addChild(WebLayer* child) { 87 layer_->AddChild(static_cast<WebLayerImpl*>(child)->layer()); 88} 89 90void WebLayerImpl::insertChild(WebLayer* child, size_t index) { 91 layer_->InsertChild(static_cast<WebLayerImpl*>(child)->layer(), index); 92} 93 94void WebLayerImpl::replaceChild(WebLayer* reference, WebLayer* new_layer) { 95 layer_->ReplaceChild(static_cast<WebLayerImpl*>(reference)->layer(), 96 static_cast<WebLayerImpl*>(new_layer)->layer()); 97} 98 99void WebLayerImpl::removeFromParent() { 100 layer_->RemoveFromParent(); 101} 102 103void WebLayerImpl::removeAllChildren() { 104 layer_->RemoveAllChildren(); 105} 106 107void WebLayerImpl::setBounds(const WebSize& size) { 108 layer_->SetBounds(size); 109} 110 111WebSize WebLayerImpl::bounds() const { 112 return layer_->bounds(); 113} 114 115void WebLayerImpl::setMasksToBounds(bool masks_to_bounds) { 116 layer_->SetMasksToBounds(masks_to_bounds); 117} 118 119bool WebLayerImpl::masksToBounds() const { 120 return layer_->masks_to_bounds(); 121} 122 123void WebLayerImpl::setMaskLayer(WebLayer* maskLayer) { 124 layer_->SetMaskLayer( 125 maskLayer ? static_cast<WebLayerImpl*>(maskLayer)->layer() : 0); 126} 127 128void WebLayerImpl::setReplicaLayer(WebLayer* replica_layer) { 129 layer_->SetReplicaLayer( 130 replica_layer ? static_cast<WebLayerImpl*>(replica_layer)->layer() : 0); 131} 132 133void WebLayerImpl::setOpacity(float opacity) { 134 layer_->SetOpacity(opacity); 135} 136 137float WebLayerImpl::opacity() const { 138 return layer_->opacity(); 139} 140 141void WebLayerImpl::setBlendMode(blink::WebBlendMode blend_mode) { 142 layer_->SetBlendMode(BlendModeToSkia(blend_mode)); 143} 144 145blink::WebBlendMode WebLayerImpl::blendMode() const { 146 return BlendModeFromSkia(layer_->blend_mode()); 147} 148 149void WebLayerImpl::setIsRootForIsolatedGroup(bool isolate) { 150 layer_->SetIsRootForIsolatedGroup(isolate); 151} 152 153bool WebLayerImpl::isRootForIsolatedGroup() { 154 return layer_->is_root_for_isolated_group(); 155} 156 157void WebLayerImpl::setOpaque(bool opaque) { 158 layer_->SetContentsOpaque(opaque); 159} 160 161bool WebLayerImpl::opaque() const { 162 return layer_->contents_opaque(); 163} 164 165void WebLayerImpl::setPosition(const WebFloatPoint& position) { 166 layer_->SetPosition(position); 167} 168 169WebFloatPoint WebLayerImpl::position() const { 170 return layer_->position(); 171} 172 173void WebLayerImpl::setTransform(const SkMatrix44& matrix) { 174 gfx::Transform transform; 175 transform.matrix() = matrix; 176 layer_->SetTransform(transform); 177} 178 179void WebLayerImpl::setTransformOrigin(const blink::WebFloatPoint3D& point) { 180 gfx::Point3F gfx_point = point; 181 layer_->SetTransformOrigin(gfx_point); 182} 183 184blink::WebFloatPoint3D WebLayerImpl::transformOrigin() const { 185 return layer_->transform_origin(); 186} 187 188SkMatrix44 WebLayerImpl::transform() const { 189 return layer_->transform().matrix(); 190} 191 192void WebLayerImpl::setDrawsContent(bool draws_content) { 193 layer_->SetIsDrawable(draws_content); 194} 195 196bool WebLayerImpl::drawsContent() const { 197 return layer_->DrawsContent(); 198} 199 200void WebLayerImpl::setShouldFlattenTransform(bool flatten) { 201 layer_->SetShouldFlattenTransform(flatten); 202} 203 204void WebLayerImpl::setRenderingContext(int context) { 205 layer_->Set3dSortingContextId(context); 206} 207 208void WebLayerImpl::setUseParentBackfaceVisibility( 209 bool use_parent_backface_visibility) { 210 layer_->set_use_parent_backface_visibility(use_parent_backface_visibility); 211} 212 213void WebLayerImpl::setBackgroundColor(WebColor color) { 214 layer_->SetBackgroundColor(color); 215} 216 217WebColor WebLayerImpl::backgroundColor() const { 218 return layer_->background_color(); 219} 220 221void WebLayerImpl::setFilters(const WebFilterOperations& filters) { 222 const WebFilterOperationsImpl& filters_impl = 223 static_cast<const WebFilterOperationsImpl&>(filters); 224 layer_->SetFilters(filters_impl.AsFilterOperations()); 225} 226 227void WebLayerImpl::setBackgroundFilters(const WebFilterOperations& filters) { 228 const WebFilterOperationsImpl& filters_impl = 229 static_cast<const WebFilterOperationsImpl&>(filters); 230 layer_->SetBackgroundFilters(filters_impl.AsFilterOperations()); 231} 232 233void 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 240bool WebLayerImpl::addAnimation(blink::WebCompositorAnimation* animation) { 241 bool result = layer_->AddAnimation( 242 static_cast<WebCompositorAnimationImpl*>(animation)->PassAnimation()); 243 delete animation; 244 return result; 245} 246 247void WebLayerImpl::removeAnimation(int animation_id) { 248 layer_->RemoveAnimation(animation_id); 249} 250 251void 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 258void WebLayerImpl::pauseAnimation(int animation_id, double time_offset) { 259 layer_->PauseAnimation(animation_id, time_offset); 260} 261 262bool WebLayerImpl::hasActiveAnimation() { 263 return layer_->HasActiveAnimation(); 264} 265 266void WebLayerImpl::setForceRenderSurface(bool force_render_surface) { 267 layer_->SetForceRenderSurface(force_render_surface); 268} 269 270void WebLayerImpl::setScrollPosition(blink::WebPoint position) { 271 layer_->SetScrollOffset(gfx::Point(position).OffsetFromOrigin()); 272} 273 274blink::WebPoint WebLayerImpl::scrollPosition() const { 275 return gfx::PointAtOffsetFromOrigin(layer_->scroll_offset()); 276} 277 278void 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 286bool WebLayerImpl::scrollable() const { 287 return layer_->scrollable(); 288} 289 290void WebLayerImpl::setUserScrollable(bool horizontal, bool vertical) { 291 layer_->SetUserScrollable(horizontal, vertical); 292} 293 294bool WebLayerImpl::userScrollableHorizontal() const { 295 return layer_->user_scrollable_horizontal(); 296} 297 298bool WebLayerImpl::userScrollableVertical() const { 299 return layer_->user_scrollable_vertical(); 300} 301 302void WebLayerImpl::setHaveWheelEventHandlers(bool have_wheel_event_handlers) { 303 layer_->SetHaveWheelEventHandlers(have_wheel_event_handlers); 304} 305 306bool WebLayerImpl::haveWheelEventHandlers() const { 307 return layer_->have_wheel_event_handlers(); 308} 309 310void WebLayerImpl::setHaveScrollEventHandlers(bool have_scroll_event_handlers) { 311 layer_->SetHaveScrollEventHandlers(have_scroll_event_handlers); 312} 313 314bool WebLayerImpl::haveScrollEventHandlers() const { 315 return layer_->have_scroll_event_handlers(); 316} 317 318void WebLayerImpl::setShouldScrollOnMainThread( 319 bool should_scroll_on_main_thread) { 320 layer_->SetShouldScrollOnMainThread(should_scroll_on_main_thread); 321} 322 323bool WebLayerImpl::shouldScrollOnMainThread() const { 324 return layer_->should_scroll_on_main_thread(); 325} 326 327void 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 334WebVector<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 352void 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 359WebVector<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 377void WebLayerImpl::setIsContainerForFixedPositionLayers(bool enable) { 378 layer_->SetIsContainerForFixedPositionLayers(enable); 379} 380 381bool WebLayerImpl::isContainerForFixedPositionLayers() const { 382 return layer_->IsContainerForFixedPositionLayers(); 383} 384 385static 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 394static 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 403void WebLayerImpl::setPositionConstraint( 404 const blink::WebLayerPositionConstraint& constraint) { 405 layer_->SetPositionConstraint(ToLayerPositionConstraint(constraint)); 406} 407 408blink::WebLayerPositionConstraint WebLayerImpl::positionConstraint() const { 409 return ToWebLayerPositionConstraint(layer_->position_constraint()); 410} 411 412void 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 422bool WebLayerImpl::isOrphan() const { 423 return !layer_->layer_tree_host(); 424} 425 426void WebLayerImpl::setWebLayerClient(blink::WebLayerClient* client) { 427 web_layer_client_ = client; 428} 429 430class 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 448scoped_refptr<base::debug::ConvertableToTraceFormat> 449WebLayerImpl::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 461void 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 468void 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 475Layer* WebLayerImpl::layer() const { 476 return layer_.get(); 477} 478 479} // namespace cc_blink 480