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