Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(372)

Side by Side Diff: ui/compositor/layer.cc

Issue 851853002: It is time. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Trying to reup because the last upload failed. Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « ui/compositor/layer.h ('k') | ui/compositor/layer_animation_delegate.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2012 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 "ui/compositor/layer.h"
6
7 #include <algorithm>
8
9 #include "base/command_line.h"
10 #include "base/debug/trace_event.h"
11 #include "base/json/json_writer.h"
12 #include "base/lazy_instance.h"
13 #include "base/logging.h"
14 #include "base/memory/scoped_ptr.h"
15 #include "cc/base/scoped_ptr_algorithm.h"
16 #include "cc/layers/content_layer.h"
17 #include "cc/layers/delegated_renderer_layer.h"
18 #include "cc/layers/nine_patch_layer.h"
19 #include "cc/layers/picture_layer.h"
20 #include "cc/layers/solid_color_layer.h"
21 #include "cc/layers/surface_layer.h"
22 #include "cc/layers/texture_layer.h"
23 #include "cc/output/copy_output_request.h"
24 #include "cc/output/delegated_frame_data.h"
25 #include "cc/output/filter_operation.h"
26 #include "cc/output/filter_operations.h"
27 #include "cc/resources/transferable_resource.h"
28 #include "ui/compositor/compositor_switches.h"
29 #include "ui/compositor/dip_util.h"
30 #include "ui/compositor/layer_animator.h"
31 #include "ui/gfx/animation/animation.h"
32 #include "ui/gfx/canvas.h"
33 #include "ui/gfx/display.h"
34 #include "ui/gfx/interpolated_transform.h"
35 #include "ui/gfx/point3_f.h"
36 #include "ui/gfx/point_conversions.h"
37 #include "ui/gfx/size_conversions.h"
38
39 namespace {
40
41 const ui::Layer* GetRoot(const ui::Layer* layer) {
42 while (layer->parent())
43 layer = layer->parent();
44 return layer;
45 }
46
47 struct UIImplSidePaintingStatus {
48 UIImplSidePaintingStatus()
49 : enabled(ui::IsUIImplSidePaintingEnabled()) {
50 }
51 bool enabled;
52 };
53 base::LazyInstance<UIImplSidePaintingStatus> g_ui_impl_side_painting_status =
54 LAZY_INSTANCE_INITIALIZER;
55
56 } // namespace
57
58 namespace ui {
59
60 Layer::Layer()
61 : type_(LAYER_TEXTURED),
62 compositor_(NULL),
63 parent_(NULL),
64 visible_(true),
65 force_render_surface_(false),
66 fills_bounds_opaquely_(true),
67 fills_bounds_completely_(false),
68 background_blur_radius_(0),
69 layer_saturation_(0.0f),
70 layer_brightness_(0.0f),
71 layer_grayscale_(0.0f),
72 layer_inverted_(false),
73 layer_mask_(NULL),
74 layer_mask_back_link_(NULL),
75 zoom_(1),
76 zoom_inset_(0),
77 delegate_(NULL),
78 owner_(NULL),
79 cc_layer_(NULL),
80 device_scale_factor_(1.0f) {
81 CreateCcLayer();
82 }
83
84 Layer::Layer(LayerType type)
85 : type_(type),
86 compositor_(NULL),
87 parent_(NULL),
88 visible_(true),
89 force_render_surface_(false),
90 fills_bounds_opaquely_(true),
91 fills_bounds_completely_(false),
92 background_blur_radius_(0),
93 layer_saturation_(0.0f),
94 layer_brightness_(0.0f),
95 layer_grayscale_(0.0f),
96 layer_inverted_(false),
97 layer_mask_(NULL),
98 layer_mask_back_link_(NULL),
99 zoom_(1),
100 zoom_inset_(0),
101 delegate_(NULL),
102 owner_(NULL),
103 cc_layer_(NULL),
104 device_scale_factor_(1.0f) {
105 CreateCcLayer();
106 }
107
108 Layer::~Layer() {
109 // Destroying the animator may cause observers to use the layer (and
110 // indirectly the WebLayer). Destroy the animator first so that the WebLayer
111 // is still around.
112 if (animator_.get())
113 animator_->SetDelegate(NULL);
114 animator_ = NULL;
115 if (compositor_)
116 compositor_->SetRootLayer(NULL);
117 if (parent_)
118 parent_->Remove(this);
119 if (layer_mask_)
120 SetMaskLayer(NULL);
121 if (layer_mask_back_link_)
122 layer_mask_back_link_->SetMaskLayer(NULL);
123 for (size_t i = 0; i < children_.size(); ++i)
124 children_[i]->parent_ = NULL;
125 cc_layer_->RemoveLayerAnimationEventObserver(this);
126 cc_layer_->RemoveFromParent();
127 }
128
129 // static
130 bool Layer::UsingPictureLayer() {
131 return g_ui_impl_side_painting_status.Get().enabled;
132 }
133
134 Compositor* Layer::GetCompositor() {
135 return GetRoot(this)->compositor_;
136 }
137
138 float Layer::opacity() const {
139 return cc_layer_->opacity();
140 }
141
142 void Layer::SetCompositor(Compositor* compositor) {
143 // This function must only be called to set the compositor on the root layer,
144 // or to reset it.
145 DCHECK(!compositor || !compositor_);
146 DCHECK(!compositor || compositor->root_layer() == this);
147 DCHECK(!parent_);
148 if (compositor_) {
149 RemoveAnimatorsInTreeFromCollection(
150 compositor_->layer_animator_collection());
151 }
152 compositor_ = compositor;
153 if (compositor) {
154 OnDeviceScaleFactorChanged(compositor->device_scale_factor());
155 SendPendingThreadedAnimations();
156 AddAnimatorsInTreeToCollection(compositor_->layer_animator_collection());
157 }
158 }
159
160 void Layer::Add(Layer* child) {
161 DCHECK(!child->compositor_);
162 if (child->parent_)
163 child->parent_->Remove(child);
164 child->parent_ = this;
165 children_.push_back(child);
166 cc_layer_->AddChild(child->cc_layer_);
167 child->OnDeviceScaleFactorChanged(device_scale_factor_);
168 if (GetCompositor())
169 child->SendPendingThreadedAnimations();
170 LayerAnimatorCollection* collection = GetLayerAnimatorCollection();
171 if (collection)
172 child->AddAnimatorsInTreeToCollection(collection);
173 }
174
175 void Layer::Remove(Layer* child) {
176 // Current bounds are used to calculate offsets when layers are reparented.
177 // Stop (and complete) an ongoing animation to update the bounds immediately.
178 LayerAnimator* child_animator = child->animator_.get();
179 if (child_animator)
180 child_animator->StopAnimatingProperty(ui::LayerAnimationElement::BOUNDS);
181 LayerAnimatorCollection* collection = GetLayerAnimatorCollection();
182 if (collection)
183 child->RemoveAnimatorsInTreeFromCollection(collection);
184
185 std::vector<Layer*>::iterator i =
186 std::find(children_.begin(), children_.end(), child);
187 DCHECK(i != children_.end());
188 children_.erase(i);
189 child->parent_ = NULL;
190 child->cc_layer_->RemoveFromParent();
191 }
192
193 void Layer::StackAtTop(Layer* child) {
194 if (children_.size() <= 1 || child == children_.back())
195 return; // Already in front.
196 StackAbove(child, children_.back());
197 }
198
199 void Layer::StackAbove(Layer* child, Layer* other) {
200 StackRelativeTo(child, other, true);
201 }
202
203 void Layer::StackAtBottom(Layer* child) {
204 if (children_.size() <= 1 || child == children_.front())
205 return; // Already on bottom.
206 StackBelow(child, children_.front());
207 }
208
209 void Layer::StackBelow(Layer* child, Layer* other) {
210 StackRelativeTo(child, other, false);
211 }
212
213 bool Layer::Contains(const Layer* other) const {
214 for (const Layer* parent = other; parent; parent = parent->parent()) {
215 if (parent == this)
216 return true;
217 }
218 return false;
219 }
220
221 void Layer::SetAnimator(LayerAnimator* animator) {
222 if (animator)
223 animator->SetDelegate(this);
224 animator_ = animator;
225 }
226
227 LayerAnimator* Layer::GetAnimator() {
228 if (!animator_.get())
229 SetAnimator(LayerAnimator::CreateDefaultAnimator());
230 return animator_.get();
231 }
232
233 void Layer::SetTransform(const gfx::Transform& transform) {
234 GetAnimator()->SetTransform(transform);
235 }
236
237 gfx::Transform Layer::GetTargetTransform() const {
238 if (animator_.get() && animator_->IsAnimatingProperty(
239 LayerAnimationElement::TRANSFORM)) {
240 return animator_->GetTargetTransform();
241 }
242 return transform();
243 }
244
245 void Layer::SetBounds(const gfx::Rect& bounds) {
246 GetAnimator()->SetBounds(bounds);
247 }
248
249 void Layer::SetSubpixelPositionOffset(const gfx::Vector2dF offset) {
250 subpixel_position_offset_ = offset;
251 RecomputePosition();
252 }
253
254 gfx::Rect Layer::GetTargetBounds() const {
255 if (animator_.get() && animator_->IsAnimatingProperty(
256 LayerAnimationElement::BOUNDS)) {
257 return animator_->GetTargetBounds();
258 }
259 return bounds_;
260 }
261
262 void Layer::SetMasksToBounds(bool masks_to_bounds) {
263 cc_layer_->SetMasksToBounds(masks_to_bounds);
264 }
265
266 bool Layer::GetMasksToBounds() const {
267 return cc_layer_->masks_to_bounds();
268 }
269
270 void Layer::SetOpacity(float opacity) {
271 GetAnimator()->SetOpacity(opacity);
272 }
273
274 float Layer::GetCombinedOpacity() const {
275 float opacity = this->opacity();
276 Layer* current = this->parent_;
277 while (current) {
278 opacity *= current->opacity();
279 current = current->parent_;
280 }
281 return opacity;
282 }
283
284 void Layer::SetBackgroundBlur(int blur_radius) {
285 background_blur_radius_ = blur_radius;
286
287 SetLayerBackgroundFilters();
288 }
289
290 void Layer::SetLayerSaturation(float saturation) {
291 layer_saturation_ = saturation;
292 SetLayerFilters();
293 }
294
295 void Layer::SetLayerBrightness(float brightness) {
296 GetAnimator()->SetBrightness(brightness);
297 }
298
299 float Layer::GetTargetBrightness() const {
300 if (animator_.get() && animator_->IsAnimatingProperty(
301 LayerAnimationElement::BRIGHTNESS)) {
302 return animator_->GetTargetBrightness();
303 }
304 return layer_brightness();
305 }
306
307 void Layer::SetLayerGrayscale(float grayscale) {
308 GetAnimator()->SetGrayscale(grayscale);
309 }
310
311 float Layer::GetTargetGrayscale() const {
312 if (animator_.get() && animator_->IsAnimatingProperty(
313 LayerAnimationElement::GRAYSCALE)) {
314 return animator_->GetTargetGrayscale();
315 }
316 return layer_grayscale();
317 }
318
319 void Layer::SetLayerInverted(bool inverted) {
320 layer_inverted_ = inverted;
321 SetLayerFilters();
322 }
323
324 void Layer::SetMaskLayer(Layer* layer_mask) {
325 // The provided mask should not have a layer mask itself.
326 DCHECK(!layer_mask ||
327 (!layer_mask->layer_mask_layer() &&
328 layer_mask->children().empty() &&
329 !layer_mask->layer_mask_back_link_));
330 DCHECK(!layer_mask_back_link_);
331 if (layer_mask_ == layer_mask)
332 return;
333 // We need to de-reference the currently linked object so that no problem
334 // arises if the mask layer gets deleted before this object.
335 if (layer_mask_)
336 layer_mask_->layer_mask_back_link_ = NULL;
337 layer_mask_ = layer_mask;
338 cc_layer_->SetMaskLayer(
339 layer_mask ? layer_mask->cc_layer() : NULL);
340 // We need to reference the linked object so that it can properly break the
341 // link to us when it gets deleted.
342 if (layer_mask) {
343 layer_mask->layer_mask_back_link_ = this;
344 layer_mask->OnDeviceScaleFactorChanged(device_scale_factor_);
345 }
346 }
347
348 void Layer::SetBackgroundZoom(float zoom, int inset) {
349 zoom_ = zoom;
350 zoom_inset_ = inset;
351
352 SetLayerBackgroundFilters();
353 }
354
355 void Layer::SetAlphaShape(scoped_ptr<SkRegion> region) {
356 alpha_shape_ = region.Pass();
357
358 SetLayerFilters();
359 }
360
361 void Layer::SetLayerFilters() {
362 cc::FilterOperations filters;
363 if (layer_saturation_) {
364 filters.Append(cc::FilterOperation::CreateSaturateFilter(
365 layer_saturation_));
366 }
367 if (layer_grayscale_) {
368 filters.Append(cc::FilterOperation::CreateGrayscaleFilter(
369 layer_grayscale_));
370 }
371 if (layer_inverted_)
372 filters.Append(cc::FilterOperation::CreateInvertFilter(1.0));
373 // Brightness goes last, because the resulting colors neeed clamping, which
374 // cause further color matrix filters to be applied separately. In this order,
375 // they all can be combined in a single pass.
376 if (layer_brightness_) {
377 filters.Append(cc::FilterOperation::CreateSaturatingBrightnessFilter(
378 layer_brightness_));
379 }
380 if (alpha_shape_) {
381 filters.Append(cc::FilterOperation::CreateAlphaThresholdFilter(
382 *alpha_shape_, 0.f, 0.f));
383 }
384
385 cc_layer_->SetFilters(filters);
386 }
387
388 void Layer::SetLayerBackgroundFilters() {
389 cc::FilterOperations filters;
390 if (zoom_ != 1)
391 filters.Append(cc::FilterOperation::CreateZoomFilter(zoom_, zoom_inset_));
392
393 if (background_blur_radius_) {
394 filters.Append(cc::FilterOperation::CreateBlurFilter(
395 background_blur_radius_));
396 }
397
398 cc_layer_->SetBackgroundFilters(filters);
399 }
400
401 float Layer::GetTargetOpacity() const {
402 if (animator_.get() && animator_->IsAnimatingProperty(
403 LayerAnimationElement::OPACITY))
404 return animator_->GetTargetOpacity();
405 return opacity();
406 }
407
408 void Layer::SetVisible(bool visible) {
409 GetAnimator()->SetVisibility(visible);
410 }
411
412 bool Layer::GetTargetVisibility() const {
413 if (animator_.get() && animator_->IsAnimatingProperty(
414 LayerAnimationElement::VISIBILITY))
415 return animator_->GetTargetVisibility();
416 return visible_;
417 }
418
419 bool Layer::IsDrawn() const {
420 const Layer* layer = this;
421 while (layer && layer->visible_)
422 layer = layer->parent_;
423 return layer == NULL;
424 }
425
426 bool Layer::ShouldDraw() const {
427 return type_ != LAYER_NOT_DRAWN && GetCombinedOpacity() > 0.0f;
428 }
429
430 // static
431 void Layer::ConvertPointToLayer(const Layer* source,
432 const Layer* target,
433 gfx::Point* point) {
434 if (source == target)
435 return;
436
437 const Layer* root_layer = GetRoot(source);
438 CHECK_EQ(root_layer, GetRoot(target));
439
440 if (source != root_layer)
441 source->ConvertPointForAncestor(root_layer, point);
442 if (target != root_layer)
443 target->ConvertPointFromAncestor(root_layer, point);
444 }
445
446 bool Layer::GetTargetTransformRelativeTo(const Layer* ancestor,
447 gfx::Transform* transform) const {
448 const Layer* p = this;
449 for (; p && p != ancestor; p = p->parent()) {
450 gfx::Transform translation;
451 translation.Translate(static_cast<float>(p->bounds().x()),
452 static_cast<float>(p->bounds().y()));
453 // Use target transform so that result will be correct once animation is
454 // finished.
455 if (!p->GetTargetTransform().IsIdentity())
456 transform->ConcatTransform(p->GetTargetTransform());
457 transform->ConcatTransform(translation);
458 }
459 return p == ancestor;
460 }
461
462 void Layer::SetFillsBoundsOpaquely(bool fills_bounds_opaquely) {
463 if (fills_bounds_opaquely_ == fills_bounds_opaquely)
464 return;
465
466 fills_bounds_opaquely_ = fills_bounds_opaquely;
467
468 cc_layer_->SetContentsOpaque(fills_bounds_opaquely);
469 }
470
471 void Layer::SetFillsBoundsCompletely(bool fills_bounds_completely) {
472 fills_bounds_completely_ = fills_bounds_completely;
473 }
474
475 void Layer::SwitchToLayer(scoped_refptr<cc::Layer> new_layer) {
476 // Finish animations being handled by cc_layer_.
477 if (animator_.get()) {
478 animator_->StopAnimatingProperty(LayerAnimationElement::TRANSFORM);
479 animator_->StopAnimatingProperty(LayerAnimationElement::OPACITY);
480 }
481
482 if (texture_layer_.get())
483 texture_layer_->ClearClient();
484 // TODO(piman): delegated_renderer_layer_ cleanup.
485
486 cc_layer_->RemoveAllChildren();
487 if (cc_layer_->parent()) {
488 cc_layer_->parent()->ReplaceChild(cc_layer_, new_layer);
489 }
490 cc_layer_->SetLayerClient(NULL);
491 cc_layer_->RemoveLayerAnimationEventObserver(this);
492 new_layer->SetOpacity(cc_layer_->opacity());
493 new_layer->SetTransform(cc_layer_->transform());
494 new_layer->SetPosition(cc_layer_->position());
495 new_layer->SetBackgroundColor(cc_layer_->background_color());
496
497 cc_layer_ = new_layer.get();
498 content_layer_ = NULL;
499 solid_color_layer_ = NULL;
500 texture_layer_ = NULL;
501 delegated_renderer_layer_ = NULL;
502 surface_layer_ = NULL;
503
504 cc_layer_->AddLayerAnimationEventObserver(this);
505 for (size_t i = 0; i < children_.size(); ++i) {
506 DCHECK(children_[i]->cc_layer_);
507 cc_layer_->AddChild(children_[i]->cc_layer_);
508 }
509 cc_layer_->SetLayerClient(this);
510 cc_layer_->SetTransformOrigin(gfx::Point3F());
511 cc_layer_->SetContentsOpaque(fills_bounds_opaquely_);
512 cc_layer_->SetForceRenderSurface(force_render_surface_);
513 cc_layer_->SetIsDrawable(type_ != LAYER_NOT_DRAWN);
514 cc_layer_->SetHideLayerAndSubtree(!visible_);
515
516 SetLayerFilters();
517 SetLayerBackgroundFilters();
518 }
519
520 void Layer::SwitchCCLayerForTest() {
521 scoped_refptr<cc::Layer> new_layer;
522 if (Layer::UsingPictureLayer())
523 new_layer = cc::PictureLayer::Create(this);
524 else
525 new_layer = cc::ContentLayer::Create(this);
526 SwitchToLayer(new_layer);
527 content_layer_ = new_layer;
528 }
529
530 void Layer::SetTextureMailbox(
531 const cc::TextureMailbox& mailbox,
532 scoped_ptr<cc::SingleReleaseCallback> release_callback,
533 gfx::Size texture_size_in_dip) {
534 DCHECK(type_ == LAYER_TEXTURED || type_ == LAYER_SOLID_COLOR);
535 DCHECK(mailbox.IsValid());
536 DCHECK(release_callback);
537 if (!texture_layer_.get()) {
538 scoped_refptr<cc::TextureLayer> new_layer =
539 cc::TextureLayer::CreateForMailbox(this);
540 new_layer->SetFlipped(true);
541 SwitchToLayer(new_layer);
542 texture_layer_ = new_layer;
543 }
544 if (mailbox_release_callback_)
545 mailbox_release_callback_->Run(0, false);
546 mailbox_release_callback_ = release_callback.Pass();
547 mailbox_ = mailbox;
548 SetTextureSize(texture_size_in_dip);
549 }
550
551 void Layer::SetTextureSize(gfx::Size texture_size_in_dip) {
552 DCHECK(texture_layer_.get());
553 if (frame_size_in_dip_ == texture_size_in_dip)
554 return;
555 frame_size_in_dip_ = texture_size_in_dip;
556 RecomputeDrawsContentAndUVRect();
557 texture_layer_->SetNeedsDisplay();
558 }
559
560 void Layer::SetShowDelegatedContent(cc::DelegatedFrameProvider* frame_provider,
561 gfx::Size frame_size_in_dip) {
562 DCHECK(type_ == LAYER_TEXTURED || type_ == LAYER_SOLID_COLOR);
563
564 scoped_refptr<cc::DelegatedRendererLayer> new_layer =
565 cc::DelegatedRendererLayer::Create(frame_provider);
566 SwitchToLayer(new_layer);
567 delegated_renderer_layer_ = new_layer;
568
569 frame_size_in_dip_ = frame_size_in_dip;
570 RecomputeDrawsContentAndUVRect();
571 }
572
573 void Layer::SetShowSurface(
574 cc::SurfaceId id,
575 const cc::SurfaceLayer::SatisfyCallback& satisfy_callback,
576 const cc::SurfaceLayer::RequireCallback& require_callback,
577 gfx::Size frame_size_in_dip) {
578 DCHECK(type_ == LAYER_TEXTURED || type_ == LAYER_SOLID_COLOR);
579
580 scoped_refptr<cc::SurfaceLayer> new_layer =
581 cc::SurfaceLayer::Create(satisfy_callback, require_callback);
582 new_layer->SetSurfaceId(id, 1.f, frame_size_in_dip);
583 SwitchToLayer(new_layer);
584 surface_layer_ = new_layer;
585
586 frame_size_in_dip_ = frame_size_in_dip;
587 RecomputeDrawsContentAndUVRect();
588 }
589
590 void Layer::SetShowSolidColorContent() {
591 DCHECK_EQ(type_, LAYER_SOLID_COLOR);
592
593 if (solid_color_layer_.get())
594 return;
595
596 scoped_refptr<cc::SolidColorLayer> new_layer = cc::SolidColorLayer::Create();
597 SwitchToLayer(new_layer);
598 solid_color_layer_ = new_layer;
599
600 mailbox_ = cc::TextureMailbox();
601 if (mailbox_release_callback_) {
602 mailbox_release_callback_->Run(0, false);
603 mailbox_release_callback_.reset();
604 }
605 RecomputeDrawsContentAndUVRect();
606 }
607
608 void Layer::UpdateNinePatchLayerBitmap(const SkBitmap& bitmap) {
609 DCHECK(type_ == LAYER_NINE_PATCH && nine_patch_layer_.get());
610 SkBitmap bitmap_copy;
611 if (bitmap.isImmutable()) {
612 bitmap_copy = bitmap;
613 } else {
614 // UIResourceBitmap requires an immutable copy of the input |bitmap|.
615 bitmap.copyTo(&bitmap_copy);
616 bitmap_copy.setImmutable();
617 }
618 nine_patch_layer_->SetBitmap(bitmap_copy);
619 }
620
621 void Layer::UpdateNinePatchLayerAperture(const gfx::Rect& aperture) {
622 DCHECK(type_ == LAYER_NINE_PATCH && nine_patch_layer_.get());
623 nine_patch_layer_->SetAperture(aperture);
624 }
625
626 void Layer::UpdateNinePatchLayerBorder(const gfx::Rect& border) {
627 DCHECK(type_ == LAYER_NINE_PATCH && nine_patch_layer_.get());
628 nine_patch_layer_->SetBorder(border);
629 }
630
631 void Layer::SetColor(SkColor color) { GetAnimator()->SetColor(color); }
632
633 bool Layer::SchedulePaint(const gfx::Rect& invalid_rect) {
634 if ((type_ == LAYER_SOLID_COLOR && !texture_layer_.get()) ||
635 type_ == LAYER_NINE_PATCH || (!delegate_ && !mailbox_.IsValid()))
636 return false;
637
638 damaged_region_.op(invalid_rect.x(),
639 invalid_rect.y(),
640 invalid_rect.right(),
641 invalid_rect.bottom(),
642 SkRegion::kUnion_Op);
643 ScheduleDraw();
644 return true;
645 }
646
647 void Layer::ScheduleDraw() {
648 Compositor* compositor = GetCompositor();
649 if (compositor)
650 compositor->ScheduleDraw();
651 }
652
653 void Layer::SendDamagedRects() {
654 if ((delegate_ || mailbox_.IsValid()) && !damaged_region_.isEmpty()) {
655 for (SkRegion::Iterator iter(damaged_region_); !iter.done(); iter.next()) {
656 const SkIRect& sk_damaged = iter.rect();
657 gfx::Rect damaged(
658 sk_damaged.x(),
659 sk_damaged.y(),
660 sk_damaged.width(),
661 sk_damaged.height());
662 cc_layer_->SetNeedsDisplayRect(damaged);
663 }
664 damaged_region_.setEmpty();
665 }
666 for (size_t i = 0; i < children_.size(); ++i)
667 children_[i]->SendDamagedRects();
668 }
669
670 void Layer::CompleteAllAnimations() {
671 typedef std::vector<scoped_refptr<LayerAnimator> > LayerAnimatorVector;
672 LayerAnimatorVector animators;
673 CollectAnimators(&animators);
674 for (LayerAnimatorVector::const_iterator it = animators.begin();
675 it != animators.end();
676 ++it) {
677 (*it)->StopAnimating();
678 }
679 }
680
681 void Layer::SuppressPaint() {
682 if (!delegate_)
683 return;
684 delegate_ = NULL;
685 for (size_t i = 0; i < children_.size(); ++i)
686 children_[i]->SuppressPaint();
687 }
688
689 void Layer::OnDeviceScaleFactorChanged(float device_scale_factor) {
690 if (device_scale_factor_ == device_scale_factor)
691 return;
692 if (animator_.get())
693 animator_->StopAnimatingProperty(LayerAnimationElement::TRANSFORM);
694 device_scale_factor_ = device_scale_factor;
695 RecomputeDrawsContentAndUVRect();
696 RecomputePosition();
697 SchedulePaint(gfx::Rect(bounds_.size()));
698 if (delegate_)
699 delegate_->OnDeviceScaleFactorChanged(device_scale_factor);
700 for (size_t i = 0; i < children_.size(); ++i)
701 children_[i]->OnDeviceScaleFactorChanged(device_scale_factor);
702 if (layer_mask_)
703 layer_mask_->OnDeviceScaleFactorChanged(device_scale_factor);
704 }
705
706 void Layer::OnDelegatedFrameDamage(const gfx::Rect& damage_rect_in_dip) {
707 DCHECK(delegated_renderer_layer_.get() || surface_layer_.get());
708 if (!delegate_)
709 return;
710 delegate_->OnDelegatedFrameDamage(damage_rect_in_dip);
711 }
712
713 void Layer::RequestCopyOfOutput(scoped_ptr<cc::CopyOutputRequest> request) {
714 cc_layer_->RequestCopyOfOutput(request.Pass());
715 }
716
717 void Layer::PaintContents(SkCanvas* sk_canvas,
718 const gfx::Rect& clip,
719 ContentLayerClient::GraphicsContextStatus gc_status) {
720 TRACE_EVENT0("ui", "Layer::PaintContents");
721 scoped_ptr<gfx::Canvas> canvas(gfx::Canvas::CreateCanvasWithoutScaling(
722 sk_canvas, device_scale_factor_));
723 if (delegate_)
724 delegate_->OnPaintLayer(canvas.get());
725 }
726
727 scoped_refptr<cc::DisplayItemList> Layer::PaintContentsToDisplayList(
728 const gfx::Rect& clip,
729 ContentLayerClient::GraphicsContextStatus gc_status) {
730 NOTIMPLEMENTED();
731 return cc::DisplayItemList::Create();
732 }
733
734 bool Layer::FillsBoundsCompletely() const { return fills_bounds_completely_; }
735
736 bool Layer::PrepareTextureMailbox(
737 cc::TextureMailbox* mailbox,
738 scoped_ptr<cc::SingleReleaseCallback>* release_callback,
739 bool use_shared_memory) {
740 if (!mailbox_release_callback_)
741 return false;
742 *mailbox = mailbox_;
743 *release_callback = mailbox_release_callback_.Pass();
744 return true;
745 }
746
747 void Layer::SetForceRenderSurface(bool force) {
748 if (force_render_surface_ == force)
749 return;
750
751 force_render_surface_ = force;
752 cc_layer_->SetForceRenderSurface(force_render_surface_);
753 }
754
755 class LayerDebugInfo : public base::debug::ConvertableToTraceFormat {
756 public:
757 explicit LayerDebugInfo(std::string name) : name_(name) { }
758 void AppendAsTraceFormat(std::string* out) const override {
759 base::DictionaryValue dictionary;
760 dictionary.SetString("layer_name", name_);
761 base::JSONWriter::Write(&dictionary, out);
762 }
763
764 private:
765 ~LayerDebugInfo() override {}
766 std::string name_;
767 };
768
769 scoped_refptr<base::debug::ConvertableToTraceFormat> Layer::TakeDebugInfo() {
770 return new LayerDebugInfo(name_);
771 }
772
773 void Layer::OnAnimationStarted(const cc::AnimationEvent& event) {
774 if (animator_.get())
775 animator_->OnThreadedAnimationStarted(event);
776 }
777
778 void Layer::CollectAnimators(
779 std::vector<scoped_refptr<LayerAnimator> >* animators) {
780 if (IsAnimating())
781 animators->push_back(animator_);
782 std::for_each(children_.begin(), children_.end(),
783 std::bind2nd(std::mem_fun(&Layer::CollectAnimators),
784 animators));
785 }
786
787 void Layer::StackRelativeTo(Layer* child, Layer* other, bool above) {
788 DCHECK_NE(child, other);
789 DCHECK_EQ(this, child->parent());
790 DCHECK_EQ(this, other->parent());
791
792 const size_t child_i =
793 std::find(children_.begin(), children_.end(), child) - children_.begin();
794 const size_t other_i =
795 std::find(children_.begin(), children_.end(), other) - children_.begin();
796 if ((above && child_i == other_i + 1) || (!above && child_i + 1 == other_i))
797 return;
798
799 const size_t dest_i =
800 above ?
801 (child_i < other_i ? other_i : other_i + 1) :
802 (child_i < other_i ? other_i - 1 : other_i);
803 children_.erase(children_.begin() + child_i);
804 children_.insert(children_.begin() + dest_i, child);
805
806 child->cc_layer_->RemoveFromParent();
807 cc_layer_->InsertChild(child->cc_layer_, dest_i);
808 }
809
810 bool Layer::ConvertPointForAncestor(const Layer* ancestor,
811 gfx::Point* point) const {
812 gfx::Transform transform;
813 bool result = GetTargetTransformRelativeTo(ancestor, &transform);
814 gfx::Point3F p(*point);
815 transform.TransformPoint(&p);
816 *point = gfx::ToFlooredPoint(p.AsPointF());
817 return result;
818 }
819
820 bool Layer::ConvertPointFromAncestor(const Layer* ancestor,
821 gfx::Point* point) const {
822 gfx::Transform transform;
823 bool result = GetTargetTransformRelativeTo(ancestor, &transform);
824 gfx::Point3F p(*point);
825 transform.TransformPointReverse(&p);
826 *point = gfx::ToFlooredPoint(p.AsPointF());
827 return result;
828 }
829
830 void Layer::SetBoundsFromAnimation(const gfx::Rect& bounds) {
831 if (bounds == bounds_)
832 return;
833
834 base::Closure closure;
835 if (delegate_)
836 closure = delegate_->PrepareForLayerBoundsChange();
837 bool was_move = bounds_.size() == bounds.size();
838 bounds_ = bounds;
839
840 RecomputeDrawsContentAndUVRect();
841 RecomputePosition();
842
843 if (!closure.is_null())
844 closure.Run();
845
846 if (was_move) {
847 // Don't schedule a draw if we're invisible. We'll schedule one
848 // automatically when we get visible.
849 if (IsDrawn())
850 ScheduleDraw();
851 } else {
852 // Always schedule a paint, even if we're invisible.
853 SchedulePaint(gfx::Rect(bounds.size()));
854 }
855 }
856
857 void Layer::SetTransformFromAnimation(const gfx::Transform& transform) {
858 cc_layer_->SetTransform(transform);
859 }
860
861 void Layer::SetOpacityFromAnimation(float opacity) {
862 cc_layer_->SetOpacity(opacity);
863 ScheduleDraw();
864 }
865
866 void Layer::SetVisibilityFromAnimation(bool visible) {
867 if (visible_ == visible)
868 return;
869
870 visible_ = visible;
871 cc_layer_->SetHideLayerAndSubtree(!visible_);
872 }
873
874 void Layer::SetBrightnessFromAnimation(float brightness) {
875 layer_brightness_ = brightness;
876 SetLayerFilters();
877 }
878
879 void Layer::SetGrayscaleFromAnimation(float grayscale) {
880 layer_grayscale_ = grayscale;
881 SetLayerFilters();
882 }
883
884 void Layer::SetColorFromAnimation(SkColor color) {
885 DCHECK_EQ(type_, LAYER_SOLID_COLOR);
886 cc_layer_->SetBackgroundColor(color);
887 SetFillsBoundsOpaquely(SkColorGetA(color) == 0xFF);
888 }
889
890 void Layer::ScheduleDrawForAnimation() {
891 ScheduleDraw();
892 }
893
894 const gfx::Rect& Layer::GetBoundsForAnimation() const {
895 return bounds();
896 }
897
898 gfx::Transform Layer::GetTransformForAnimation() const {
899 return transform();
900 }
901
902 float Layer::GetOpacityForAnimation() const {
903 return opacity();
904 }
905
906 bool Layer::GetVisibilityForAnimation() const {
907 return visible();
908 }
909
910 float Layer::GetBrightnessForAnimation() const {
911 return layer_brightness();
912 }
913
914 float Layer::GetGrayscaleForAnimation() const {
915 return layer_grayscale();
916 }
917
918 SkColor Layer::GetColorForAnimation() const {
919 // WebColor is equivalent to SkColor, per WebColor.h.
920 // The NULL check is here since this is invoked regardless of whether we have
921 // been configured as LAYER_SOLID_COLOR.
922 return solid_color_layer_.get() ?
923 solid_color_layer_->background_color() : SK_ColorBLACK;
924 }
925
926 float Layer::GetDeviceScaleFactor() const {
927 return device_scale_factor_;
928 }
929
930 void Layer::AddThreadedAnimation(scoped_ptr<cc::Animation> animation) {
931 DCHECK(cc_layer_);
932 // Until this layer has a compositor (and hence cc_layer_ has a
933 // LayerTreeHost), addAnimation will fail.
934 if (GetCompositor())
935 cc_layer_->AddAnimation(animation.Pass());
936 else
937 pending_threaded_animations_.push_back(animation.Pass());
938 }
939
940 namespace{
941
942 struct HasAnimationId {
943 HasAnimationId(int id): id_(id) {
944 }
945
946 bool operator()(cc::Animation* animation) const {
947 return animation->id() == id_;
948 }
949
950 private:
951 int id_;
952 };
953
954 }
955
956 void Layer::RemoveThreadedAnimation(int animation_id) {
957 DCHECK(cc_layer_);
958 if (pending_threaded_animations_.size() == 0) {
959 cc_layer_->RemoveAnimation(animation_id);
960 return;
961 }
962
963 pending_threaded_animations_.erase(
964 cc::remove_if(&pending_threaded_animations_,
965 pending_threaded_animations_.begin(),
966 pending_threaded_animations_.end(),
967 HasAnimationId(animation_id)),
968 pending_threaded_animations_.end());
969 }
970
971 LayerAnimatorCollection* Layer::GetLayerAnimatorCollection() {
972 Compositor* compositor = GetCompositor();
973 return compositor ? compositor->layer_animator_collection() : NULL;
974 }
975
976 void Layer::SendPendingThreadedAnimations() {
977 for (cc::ScopedPtrVector<cc::Animation>::iterator it =
978 pending_threaded_animations_.begin();
979 it != pending_threaded_animations_.end();
980 ++it)
981 cc_layer_->AddAnimation(pending_threaded_animations_.take(it));
982
983 pending_threaded_animations_.clear();
984
985 for (size_t i = 0; i < children_.size(); ++i)
986 children_[i]->SendPendingThreadedAnimations();
987 }
988
989 void Layer::CreateCcLayer() {
990 if (type_ == LAYER_SOLID_COLOR) {
991 solid_color_layer_ = cc::SolidColorLayer::Create();
992 cc_layer_ = solid_color_layer_.get();
993 } else if (type_ == LAYER_NINE_PATCH) {
994 nine_patch_layer_ = cc::NinePatchLayer::Create();
995 cc_layer_ = nine_patch_layer_.get();
996 } else {
997 if (Layer::UsingPictureLayer())
998 content_layer_ = cc::PictureLayer::Create(this);
999 else
1000 content_layer_ = cc::ContentLayer::Create(this);
1001 cc_layer_ = content_layer_.get();
1002 }
1003 cc_layer_->SetTransformOrigin(gfx::Point3F());
1004 cc_layer_->SetContentsOpaque(true);
1005 cc_layer_->SetIsDrawable(type_ != LAYER_NOT_DRAWN);
1006 cc_layer_->AddLayerAnimationEventObserver(this);
1007 cc_layer_->SetLayerClient(this);
1008 RecomputePosition();
1009 }
1010
1011 gfx::Transform Layer::transform() const {
1012 return cc_layer_->transform();
1013 }
1014
1015 void Layer::RecomputeDrawsContentAndUVRect() {
1016 DCHECK(cc_layer_);
1017 gfx::Size size(bounds_.size());
1018 if (texture_layer_.get()) {
1019 size.SetToMin(frame_size_in_dip_);
1020 gfx::PointF uv_top_left(0.f, 0.f);
1021 gfx::PointF uv_bottom_right(
1022 static_cast<float>(size.width()) / frame_size_in_dip_.width(),
1023 static_cast<float>(size.height()) / frame_size_in_dip_.height());
1024 texture_layer_->SetUV(uv_top_left, uv_bottom_right);
1025 } else if (delegated_renderer_layer_.get() || surface_layer_.get()) {
1026 size.SetToMin(frame_size_in_dip_);
1027 }
1028 cc_layer_->SetBounds(size);
1029 }
1030
1031 void Layer::RecomputePosition() {
1032 cc_layer_->SetPosition(bounds_.origin() + subpixel_position_offset_);
1033 }
1034
1035 void Layer::AddAnimatorsInTreeToCollection(
1036 LayerAnimatorCollection* collection) {
1037 DCHECK(collection);
1038 if (IsAnimating())
1039 animator_->AddToCollection(collection);
1040 std::for_each(
1041 children_.begin(),
1042 children_.end(),
1043 std::bind2nd(std::mem_fun(&Layer::AddAnimatorsInTreeToCollection),
1044 collection));
1045 }
1046
1047 void Layer::RemoveAnimatorsInTreeFromCollection(
1048 LayerAnimatorCollection* collection) {
1049 DCHECK(collection);
1050 if (IsAnimating())
1051 animator_->RemoveFromCollection(collection);
1052 std::for_each(
1053 children_.begin(),
1054 children_.end(),
1055 std::bind2nd(std::mem_fun(&Layer::RemoveAnimatorsInTreeFromCollection),
1056 collection));
1057 }
1058
1059 bool Layer::IsAnimating() const {
1060 return animator_.get() && animator_->is_animating();
1061 }
1062
1063 } // namespace ui
OLDNEW
« no previous file with comments | « ui/compositor/layer.h ('k') | ui/compositor/layer_animation_delegate.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698