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