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.
5 #include "cc/blink/web_layer_impl.h"
10 #include "base/bind.h"
11 #include "base/lazy_instance.h"
12 #include "base/strings/string_util.h"
13 #include "base/threading/thread_checker.h"
14 #include "base/trace_event/trace_event_impl.h"
15 #include "cc/animation/animation.h"
16 #include "cc/base/region.h"
17 #include "cc/base/switches.h"
18 #include "cc/blink/web_animation_impl.h"
19 #include "cc/blink/web_blend_mode.h"
20 #include "cc/blink/web_filter_operations_impl.h"
21 #include "cc/blink/web_to_cc_animation_delegate_adapter.h"
22 #include "cc/layers/layer.h"
23 #include "cc/layers/layer_position_constraint.h"
24 #include "cc/trees/layer_tree_host.h"
25 #include "third_party/WebKit/public/platform/WebFloatPoint.h"
26 #include "third_party/WebKit/public/platform/WebFloatRect.h"
27 #include "third_party/WebKit/public/platform/WebGraphicsLayerDebugInfo.h"
28 #include "third_party/WebKit/public/platform/WebLayerClient.h"
29 #include "third_party/WebKit/public/platform/WebLayerPositionConstraint.h"
30 #include "third_party/WebKit/public/platform/WebLayerScrollClient.h"
31 #include "third_party/WebKit/public/platform/WebSize.h"
32 #include "third_party/skia/include/utils/SkMatrix44.h"
33 #include "ui/gfx/geometry/rect_conversions.h"
34 #include "ui/gfx/geometry/vector2d_conversions.h"
38 using blink::WebLayer
;
39 using blink::WebFloatPoint
;
40 using blink::WebVector
;
43 using blink::WebColor
;
44 using blink::WebFilterOperations
;
49 bool g_impl_side_painting_enabled
= false;
51 base::LazyInstance
<cc::LayerSettings
> g_layer_settings
=
52 LAZY_INSTANCE_INITIALIZER
;
56 WebLayerImpl::WebLayerImpl() : layer_(Layer::Create(LayerSettings())) {
57 web_layer_client_
= nullptr;
58 layer_
->SetLayerClient(this);
61 WebLayerImpl::WebLayerImpl(scoped_refptr
<Layer
> layer
) : layer_(layer
) {
62 web_layer_client_
= nullptr;
63 layer_
->SetLayerClient(this);
66 WebLayerImpl::~WebLayerImpl() {
67 layer_
->ClearRenderSurface();
68 if (animation_delegate_adapter_
.get())
69 layer_
->set_layer_animation_delegate(nullptr);
70 web_layer_client_
= nullptr;
74 bool WebLayerImpl::UsingPictureLayer() {
75 return g_impl_side_painting_enabled
;
79 void WebLayerImpl::SetImplSidePaintingEnabled(bool enabled
) {
80 g_impl_side_painting_enabled
= enabled
;
84 void WebLayerImpl::SetLayerSettings(const cc::LayerSettings
& settings
) {
85 g_layer_settings
.Get() = settings
;
89 const cc::LayerSettings
& WebLayerImpl::LayerSettings() {
90 return g_layer_settings
.Get();
93 int WebLayerImpl::id() const {
97 void WebLayerImpl::invalidateRect(const blink::WebRect
& rect
) {
98 layer_
->SetNeedsDisplayRect(rect
);
101 void WebLayerImpl::invalidate() {
102 layer_
->SetNeedsDisplay();
105 void WebLayerImpl::addChild(WebLayer
* child
) {
106 layer_
->AddChild(static_cast<WebLayerImpl
*>(child
)->layer());
109 void WebLayerImpl::insertChild(WebLayer
* child
, size_t index
) {
110 layer_
->InsertChild(static_cast<WebLayerImpl
*>(child
)->layer(), index
);
113 void WebLayerImpl::replaceChild(WebLayer
* reference
, WebLayer
* new_layer
) {
114 layer_
->ReplaceChild(static_cast<WebLayerImpl
*>(reference
)->layer(),
115 static_cast<WebLayerImpl
*>(new_layer
)->layer());
118 void WebLayerImpl::removeFromParent() {
119 layer_
->RemoveFromParent();
122 void WebLayerImpl::removeAllChildren() {
123 layer_
->RemoveAllChildren();
126 void WebLayerImpl::setBounds(const WebSize
& size
) {
127 layer_
->SetBounds(size
);
130 WebSize
WebLayerImpl::bounds() const {
131 return layer_
->bounds();
134 void WebLayerImpl::setMasksToBounds(bool masks_to_bounds
) {
135 layer_
->SetMasksToBounds(masks_to_bounds
);
138 bool WebLayerImpl::masksToBounds() const {
139 return layer_
->masks_to_bounds();
142 void WebLayerImpl::setMaskLayer(WebLayer
* maskLayer
) {
143 layer_
->SetMaskLayer(
144 maskLayer
? static_cast<WebLayerImpl
*>(maskLayer
)->layer() : 0);
147 void WebLayerImpl::setReplicaLayer(WebLayer
* replica_layer
) {
148 layer_
->SetReplicaLayer(
149 replica_layer
? static_cast<WebLayerImpl
*>(replica_layer
)->layer() : 0);
152 void WebLayerImpl::setOpacity(float opacity
) {
153 layer_
->SetOpacity(opacity
);
156 float WebLayerImpl::opacity() const {
157 return layer_
->opacity();
160 void WebLayerImpl::setBlendMode(blink::WebBlendMode blend_mode
) {
161 layer_
->SetBlendMode(BlendModeToSkia(blend_mode
));
164 blink::WebBlendMode
WebLayerImpl::blendMode() const {
165 return BlendModeFromSkia(layer_
->blend_mode());
168 void WebLayerImpl::setIsRootForIsolatedGroup(bool isolate
) {
169 layer_
->SetIsRootForIsolatedGroup(isolate
);
172 bool WebLayerImpl::isRootForIsolatedGroup() {
173 return layer_
->is_root_for_isolated_group();
176 void WebLayerImpl::setOpaque(bool opaque
) {
177 layer_
->SetContentsOpaque(opaque
);
180 bool WebLayerImpl::opaque() const {
181 return layer_
->contents_opaque();
184 void WebLayerImpl::setPosition(const WebFloatPoint
& position
) {
185 layer_
->SetPosition(position
);
188 WebFloatPoint
WebLayerImpl::position() const {
189 return layer_
->position();
192 void WebLayerImpl::setTransform(const SkMatrix44
& matrix
) {
193 gfx::Transform transform
;
194 transform
.matrix() = matrix
;
195 layer_
->SetTransform(transform
);
198 void WebLayerImpl::setTransformOrigin(const blink::WebFloatPoint3D
& point
) {
199 gfx::Point3F gfx_point
= point
;
200 layer_
->SetTransformOrigin(gfx_point
);
203 blink::WebFloatPoint3D
WebLayerImpl::transformOrigin() const {
204 return layer_
->transform_origin();
207 SkMatrix44
WebLayerImpl::transform() const {
208 return layer_
->transform().matrix();
211 void WebLayerImpl::setDrawsContent(bool draws_content
) {
212 layer_
->SetIsDrawable(draws_content
);
215 bool WebLayerImpl::drawsContent() const {
216 return layer_
->DrawsContent();
219 void WebLayerImpl::setShouldFlattenTransform(bool flatten
) {
220 layer_
->SetShouldFlattenTransform(flatten
);
223 void WebLayerImpl::setRenderingContext(int context
) {
224 layer_
->Set3dSortingContextId(context
);
227 void WebLayerImpl::setUseParentBackfaceVisibility(
228 bool use_parent_backface_visibility
) {
229 layer_
->set_use_parent_backface_visibility(use_parent_backface_visibility
);
232 void WebLayerImpl::setBackgroundColor(WebColor color
) {
233 layer_
->SetBackgroundColor(color
);
236 WebColor
WebLayerImpl::backgroundColor() const {
237 return layer_
->background_color();
240 void WebLayerImpl::setFilters(const WebFilterOperations
& filters
) {
241 const WebFilterOperationsImpl
& filters_impl
=
242 static_cast<const WebFilterOperationsImpl
&>(filters
);
243 layer_
->SetFilters(filters_impl
.AsFilterOperations());
246 void WebLayerImpl::setBackgroundFilters(const WebFilterOperations
& filters
) {
247 const WebFilterOperationsImpl
& filters_impl
=
248 static_cast<const WebFilterOperationsImpl
&>(filters
);
249 layer_
->SetBackgroundFilters(filters_impl
.AsFilterOperations());
252 void WebLayerImpl::setAnimationDelegate(
253 blink::WebCompositorAnimationDelegate
* delegate
) {
254 animation_delegate_adapter_
.reset(
255 new WebToCCAnimationDelegateAdapter(delegate
));
256 layer_
->set_layer_animation_delegate(animation_delegate_adapter_
.get());
259 bool WebLayerImpl::addAnimation(blink::WebCompositorAnimation
* animation
) {
260 bool result
= layer_
->AddAnimation(
261 static_cast<WebCompositorAnimationImpl
*>(animation
)->PassAnimation());
266 void WebLayerImpl::removeAnimation(int animation_id
) {
267 layer_
->RemoveAnimation(animation_id
);
270 void WebLayerImpl::removeAnimation(
272 blink::WebCompositorAnimation::TargetProperty target_property
) {
273 layer_
->RemoveAnimation(
274 animation_id
, static_cast<Animation::TargetProperty
>(target_property
));
277 void WebLayerImpl::pauseAnimation(int animation_id
, double time_offset
) {
278 layer_
->PauseAnimation(animation_id
, time_offset
);
281 bool WebLayerImpl::hasActiveAnimation() {
282 return layer_
->HasActiveAnimation();
285 void WebLayerImpl::setForceRenderSurface(bool force_render_surface
) {
286 layer_
->SetForceRenderSurface(force_render_surface
);
289 void WebLayerImpl::setScrollPositionDouble(blink::WebDoublePoint position
) {
290 layer_
->SetScrollOffset(gfx::ScrollOffset(position
.x
, position
.y
));
293 void WebLayerImpl::setScrollCompensationAdjustment(
294 blink::WebDoublePoint position
) {
295 layer_
->SetScrollCompensationAdjustment(
296 gfx::Vector2dF(position
.x
, position
.y
));
299 blink::WebDoublePoint
WebLayerImpl::scrollPositionDouble() const {
300 return blink::WebDoublePoint(layer_
->scroll_offset().x(),
301 layer_
->scroll_offset().y());
304 void WebLayerImpl::setScrollClipLayer(WebLayer
* clip_layer
) {
306 layer_
->SetScrollClipLayerId(Layer::INVALID_ID
);
309 layer_
->SetScrollClipLayerId(clip_layer
->id());
312 bool WebLayerImpl::scrollable() const {
313 return layer_
->scrollable();
316 void WebLayerImpl::setUserScrollable(bool horizontal
, bool vertical
) {
317 layer_
->SetUserScrollable(horizontal
, vertical
);
320 bool WebLayerImpl::userScrollableHorizontal() const {
321 return layer_
->user_scrollable_horizontal();
324 bool WebLayerImpl::userScrollableVertical() const {
325 return layer_
->user_scrollable_vertical();
328 void WebLayerImpl::setHaveWheelEventHandlers(bool have_wheel_event_handlers
) {
329 layer_
->SetHaveWheelEventHandlers(have_wheel_event_handlers
);
332 bool WebLayerImpl::haveWheelEventHandlers() const {
333 return layer_
->have_wheel_event_handlers();
336 void WebLayerImpl::setHaveScrollEventHandlers(bool have_scroll_event_handlers
) {
337 layer_
->SetHaveScrollEventHandlers(have_scroll_event_handlers
);
340 bool WebLayerImpl::haveScrollEventHandlers() const {
341 return layer_
->have_scroll_event_handlers();
344 void WebLayerImpl::setShouldScrollOnMainThread(
345 bool should_scroll_on_main_thread
) {
346 layer_
->SetShouldScrollOnMainThread(should_scroll_on_main_thread
);
349 bool WebLayerImpl::shouldScrollOnMainThread() const {
350 return layer_
->should_scroll_on_main_thread();
353 void WebLayerImpl::setNonFastScrollableRegion(const WebVector
<WebRect
>& rects
) {
355 for (size_t i
= 0; i
< rects
.size(); ++i
)
356 region
.Union(rects
[i
]);
357 layer_
->SetNonFastScrollableRegion(region
);
360 WebVector
<WebRect
> WebLayerImpl::nonFastScrollableRegion() const {
361 size_t num_rects
= 0;
362 for (cc::Region::Iterator
region_rects(layer_
->non_fast_scrollable_region());
363 region_rects
.has_rect();
367 WebVector
<WebRect
> result(num_rects
);
369 for (cc::Region::Iterator
region_rects(layer_
->non_fast_scrollable_region());
370 region_rects
.has_rect();
371 region_rects
.next()) {
372 result
[i
] = region_rects
.rect();
378 void WebLayerImpl::setFrameTimingRequests(
379 const WebVector
<std::pair
<int64_t, WebRect
>>& requests
) {
380 std::vector
<cc::FrameTimingRequest
> frame_timing_requests(requests
.size());
381 for (size_t i
= 0; i
< requests
.size(); ++i
) {
382 frame_timing_requests
[i
] = cc::FrameTimingRequest(
383 requests
[i
].first
, gfx::Rect(requests
[i
].second
));
385 layer_
->SetFrameTimingRequests(frame_timing_requests
);
388 WebVector
<std::pair
<int64_t, WebRect
>> WebLayerImpl::frameTimingRequests()
390 const std::vector
<cc::FrameTimingRequest
>& frame_timing_requests
=
391 layer_
->FrameTimingRequests();
393 size_t num_requests
= frame_timing_requests
.size();
395 WebVector
<std::pair
<int64_t, WebRect
>> result(num_requests
);
396 for (size_t i
= 0; i
< num_requests
; ++i
) {
397 result
[i
] = std::make_pair(frame_timing_requests
[i
].id(),
398 frame_timing_requests
[i
].rect());
403 void WebLayerImpl::setTouchEventHandlerRegion(const WebVector
<WebRect
>& rects
) {
405 for (size_t i
= 0; i
< rects
.size(); ++i
)
406 region
.Union(rects
[i
]);
407 layer_
->SetTouchEventHandlerRegion(region
);
410 WebVector
<WebRect
> WebLayerImpl::touchEventHandlerRegion() const {
411 size_t num_rects
= 0;
412 for (cc::Region::Iterator
region_rects(layer_
->touch_event_handler_region());
413 region_rects
.has_rect();
417 WebVector
<WebRect
> result(num_rects
);
419 for (cc::Region::Iterator
region_rects(layer_
->touch_event_handler_region());
420 region_rects
.has_rect();
421 region_rects
.next()) {
422 result
[i
] = region_rects
.rect();
428 static_assert(static_cast<ScrollBlocksOn
>(blink::WebScrollBlocksOnNone
) ==
429 SCROLL_BLOCKS_ON_NONE
,
430 "ScrollBlocksOn and WebScrollBlocksOn enums must match");
431 static_assert(static_cast<ScrollBlocksOn
>(blink::WebScrollBlocksOnStartTouch
) ==
432 SCROLL_BLOCKS_ON_START_TOUCH
,
433 "ScrollBlocksOn and WebScrollBlocksOn enums must match");
434 static_assert(static_cast<ScrollBlocksOn
>(blink::WebScrollBlocksOnWheelEvent
) ==
435 SCROLL_BLOCKS_ON_WHEEL_EVENT
,
436 "ScrollBlocksOn and WebScrollBlocksOn enums must match");
438 static_cast<ScrollBlocksOn
>(blink::WebScrollBlocksOnScrollEvent
) ==
439 SCROLL_BLOCKS_ON_SCROLL_EVENT
,
440 "ScrollBlocksOn and WebScrollBlocksOn enums must match");
442 void WebLayerImpl::setScrollBlocksOn(blink::WebScrollBlocksOn blocks
) {
443 layer_
->SetScrollBlocksOn(static_cast<ScrollBlocksOn
>(blocks
));
446 blink::WebScrollBlocksOn
WebLayerImpl::scrollBlocksOn() const {
447 return static_cast<blink::WebScrollBlocksOn
>(layer_
->scroll_blocks_on());
450 void WebLayerImpl::setIsContainerForFixedPositionLayers(bool enable
) {
451 layer_
->SetIsContainerForFixedPositionLayers(enable
);
454 bool WebLayerImpl::isContainerForFixedPositionLayers() const {
455 return layer_
->IsContainerForFixedPositionLayers();
458 static blink::WebLayerPositionConstraint
ToWebLayerPositionConstraint(
459 const cc::LayerPositionConstraint
& constraint
) {
460 blink::WebLayerPositionConstraint web_constraint
;
461 web_constraint
.isFixedPosition
= constraint
.is_fixed_position();
462 web_constraint
.isFixedToRightEdge
= constraint
.is_fixed_to_right_edge();
463 web_constraint
.isFixedToBottomEdge
= constraint
.is_fixed_to_bottom_edge();
464 return web_constraint
;
467 static cc::LayerPositionConstraint
ToLayerPositionConstraint(
468 const blink::WebLayerPositionConstraint
& web_constraint
) {
469 cc::LayerPositionConstraint constraint
;
470 constraint
.set_is_fixed_position(web_constraint
.isFixedPosition
);
471 constraint
.set_is_fixed_to_right_edge(web_constraint
.isFixedToRightEdge
);
472 constraint
.set_is_fixed_to_bottom_edge(web_constraint
.isFixedToBottomEdge
);
476 void WebLayerImpl::setPositionConstraint(
477 const blink::WebLayerPositionConstraint
& constraint
) {
478 layer_
->SetPositionConstraint(ToLayerPositionConstraint(constraint
));
481 blink::WebLayerPositionConstraint
WebLayerImpl::positionConstraint() const {
482 return ToWebLayerPositionConstraint(layer_
->position_constraint());
485 void WebLayerImpl::setScrollClient(blink::WebLayerScrollClient
* scroll_client
) {
487 layer_
->set_did_scroll_callback(
488 base::Bind(&blink::WebLayerScrollClient::didScroll
,
489 base::Unretained(scroll_client
)));
491 layer_
->set_did_scroll_callback(base::Closure());
495 bool WebLayerImpl::isOrphan() const {
496 return !layer_
->layer_tree_host();
499 void WebLayerImpl::setWebLayerClient(blink::WebLayerClient
* client
) {
500 web_layer_client_
= client
;
503 class TracedDebugInfo
: public base::trace_event::ConvertableToTraceFormat
{
505 // This object takes ownership of the debug_info object.
506 explicit TracedDebugInfo(blink::WebGraphicsLayerDebugInfo
* debug_info
)
507 : debug_info_(debug_info
) {}
508 void AppendAsTraceFormat(std::string
* out
) const override
{
509 DCHECK(thread_checker_
.CalledOnValidThread());
510 blink::WebString web_string
;
511 debug_info_
->appendAsTraceFormat(&web_string
);
512 out
->append(web_string
.utf8());
516 ~TracedDebugInfo() override
{}
517 scoped_ptr
<blink::WebGraphicsLayerDebugInfo
> debug_info_
;
518 base::ThreadChecker thread_checker_
;
521 scoped_refptr
<base::trace_event::ConvertableToTraceFormat
>
522 WebLayerImpl::TakeDebugInfo() {
523 if (!web_layer_client_
)
525 blink::WebGraphicsLayerDebugInfo
* debug_info
=
526 web_layer_client_
->takeDebugInfoFor(this);
529 return new TracedDebugInfo(debug_info
);
534 void WebLayerImpl::setScrollParent(blink::WebLayer
* parent
) {
535 cc::Layer
* scroll_parent
= nullptr;
537 scroll_parent
= static_cast<WebLayerImpl
*>(parent
)->layer();
538 layer_
->SetScrollParent(scroll_parent
);
541 void WebLayerImpl::setClipParent(blink::WebLayer
* parent
) {
542 cc::Layer
* clip_parent
= nullptr;
544 clip_parent
= static_cast<WebLayerImpl
*>(parent
)->layer();
545 layer_
->SetClipParent(clip_parent
);
548 Layer
* WebLayerImpl::layer() const {
552 } // namespace cc_blink