OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ui/gfx/compositor/layer.h" | 5 #include "ui/gfx/compositor/layer.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/debug/trace_event.h" | 9 #include "base/debug/trace_event.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 24 matching lines...) Expand all Loading... |
35 } // namespace | 35 } // namespace |
36 | 36 |
37 namespace ui { | 37 namespace ui { |
38 | 38 |
39 Layer::Layer(Compositor* compositor) | 39 Layer::Layer(Compositor* compositor) |
40 : type_(LAYER_HAS_TEXTURE), | 40 : type_(LAYER_HAS_TEXTURE), |
41 compositor_(compositor), | 41 compositor_(compositor), |
42 parent_(NULL), | 42 parent_(NULL), |
43 visible_(true), | 43 visible_(true), |
44 fills_bounds_opaquely_(true), | 44 fills_bounds_opaquely_(true), |
| 45 recompute_hole_(false), |
45 layer_updated_externally_(false), | 46 layer_updated_externally_(false), |
46 opacity_(1.0f), | 47 opacity_(1.0f), |
47 delegate_(NULL) { | 48 delegate_(NULL) { |
48 #if defined(USE_WEBKIT_COMPOSITOR) | 49 #if defined(USE_WEBKIT_COMPOSITOR) |
49 CreateWebLayer(); | 50 CreateWebLayer(); |
50 #endif | 51 #endif |
51 } | 52 } |
52 | 53 |
53 Layer::Layer(Compositor* compositor, LayerType type) | 54 Layer::Layer(Compositor* compositor, LayerType type) |
54 : type_(type), | 55 : type_(type), |
55 compositor_(compositor), | 56 compositor_(compositor), |
56 parent_(NULL), | 57 parent_(NULL), |
57 visible_(true), | 58 visible_(true), |
58 fills_bounds_opaquely_(true), | 59 fills_bounds_opaquely_(true), |
| 60 recompute_hole_(false), |
59 layer_updated_externally_(false), | 61 layer_updated_externally_(false), |
60 opacity_(1.0f), | 62 opacity_(1.0f), |
61 delegate_(NULL) { | 63 delegate_(NULL) { |
62 #if defined(USE_WEBKIT_COMPOSITOR) | 64 #if defined(USE_WEBKIT_COMPOSITOR) |
63 CreateWebLayer(); | 65 CreateWebLayer(); |
64 #endif | 66 #endif |
65 } | 67 } |
66 | 68 |
67 Layer::~Layer() { | 69 Layer::~Layer() { |
68 if (parent_) | 70 if (parent_) |
(...skipping 20 matching lines...) Expand all Loading... |
89 | 91 |
90 void Layer::Add(Layer* child) { | 92 void Layer::Add(Layer* child) { |
91 if (child->parent_) | 93 if (child->parent_) |
92 child->parent_->Remove(child); | 94 child->parent_->Remove(child); |
93 child->parent_ = this; | 95 child->parent_ = this; |
94 children_.push_back(child); | 96 children_.push_back(child); |
95 #if defined(USE_WEBKIT_COMPOSITOR) | 97 #if defined(USE_WEBKIT_COMPOSITOR) |
96 web_layer_.addChild(child->web_layer_); | 98 web_layer_.addChild(child->web_layer_); |
97 #endif | 99 #endif |
98 | 100 |
99 RecomputeHole(); | 101 SetNeedsToRecomputeHole(); |
100 } | 102 } |
101 | 103 |
102 void Layer::Remove(Layer* child) { | 104 void Layer::Remove(Layer* child) { |
103 std::vector<Layer*>::iterator i = | 105 std::vector<Layer*>::iterator i = |
104 std::find(children_.begin(), children_.end(), child); | 106 std::find(children_.begin(), children_.end(), child); |
105 DCHECK(i != children_.end()); | 107 DCHECK(i != children_.end()); |
106 children_.erase(i); | 108 children_.erase(i); |
107 child->parent_ = NULL; | 109 child->parent_ = NULL; |
108 #if defined(USE_WEBKIT_COMPOSITOR) | 110 #if defined(USE_WEBKIT_COMPOSITOR) |
109 child->web_layer_.removeFromParent(); | 111 child->web_layer_.removeFromParent(); |
110 #endif | 112 #endif |
111 | 113 |
112 RecomputeHole(); | 114 SetNeedsToRecomputeHole(); |
113 | 115 |
114 child->DropTextures(); | 116 child->DropTextures(); |
115 } | 117 } |
116 | 118 |
117 void Layer::MoveToFront(Layer* child) { | 119 void Layer::MoveToFront(Layer* child) { |
118 if (children_.size() <= 1 || child == children_.back()) | 120 if (children_.size() <= 1 || child == children_.back()) |
119 return; // Already in front. | 121 return; // Already in front. |
120 MoveAbove(child, children_.back()); | 122 MoveAbove(child, children_.back()); |
| 123 |
| 124 SetNeedsToRecomputeHole(); |
121 } | 125 } |
122 | 126 |
123 void Layer::MoveAbove(Layer* child, Layer* other) { | 127 void Layer::MoveAbove(Layer* child, Layer* other) { |
124 DCHECK_NE(child, other); | 128 DCHECK_NE(child, other); |
125 DCHECK_EQ(this, child->parent()); | 129 DCHECK_EQ(this, child->parent()); |
126 DCHECK_EQ(this, other->parent()); | 130 DCHECK_EQ(this, other->parent()); |
127 size_t child_i = | 131 size_t child_i = |
128 std::find(children_.begin(), children_.end(), child) - children_.begin(); | 132 std::find(children_.begin(), children_.end(), child) - children_.begin(); |
129 size_t other_i = | 133 size_t other_i = |
130 std::find(children_.begin(), children_.end(), other) - children_.begin(); | 134 std::find(children_.begin(), children_.end(), other) - children_.begin(); |
131 if (child_i > other_i) | 135 if (child_i > other_i) |
132 return; // Already in front of |other|. | 136 return; // Already in front of |other|. |
133 | 137 |
134 // Reorder children. | 138 // Reorder children. |
135 children_.erase(children_.begin() + child_i); | 139 children_.erase(children_.begin() + child_i); |
136 children_.insert(children_.begin() + other_i, child); | 140 children_.insert(children_.begin() + other_i, child); |
137 | 141 |
| 142 SetNeedsToRecomputeHole(); |
| 143 |
138 #if defined(USE_WEBKIT_COMPOSITOR) | 144 #if defined(USE_WEBKIT_COMPOSITOR) |
139 child->web_layer_.removeFromParent(); | 145 child->web_layer_.removeFromParent(); |
140 web_layer_.insertChild(child->web_layer_, other_i); | 146 web_layer_.insertChild(child->web_layer_, other_i); |
141 #endif | 147 #endif |
142 } | 148 } |
143 | 149 |
144 bool Layer::Contains(const Layer* other) const { | 150 bool Layer::Contains(const Layer* other) const { |
145 for (const Layer* parent = other; parent; parent = parent->parent()) { | 151 for (const Layer* parent = other; parent; parent = parent->parent()) { |
146 if (parent == this) | 152 if (parent == this) |
147 return true; | 153 return true; |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
200 #if defined(USE_WEBKIT_COMPOSITOR) | 206 #if defined(USE_WEBKIT_COMPOSITOR) |
201 // TODO(piman): Expose a visibility flag on WebLayer. | 207 // TODO(piman): Expose a visibility flag on WebLayer. |
202 web_layer_.setOpacity(visible_ ? opacity_ : 0.f); | 208 web_layer_.setOpacity(visible_ ? opacity_ : 0.f); |
203 #endif | 209 #endif |
204 bool is_drawn = IsDrawn(); | 210 bool is_drawn = IsDrawn(); |
205 if (was_drawn == is_drawn) | 211 if (was_drawn == is_drawn) |
206 return; | 212 return; |
207 | 213 |
208 if (!is_drawn) | 214 if (!is_drawn) |
209 DropTextures(); | 215 DropTextures(); |
210 if (parent_) | 216 SetNeedsToRecomputeHole(); |
211 parent_->RecomputeHole(); | |
212 } | 217 } |
213 | 218 |
214 bool Layer::IsDrawn() const { | 219 bool Layer::IsDrawn() const { |
215 const Layer* layer = this; | 220 const Layer* layer = this; |
216 while (layer && layer->visible_) | 221 while (layer && layer->visible_) |
217 layer = layer->parent_; | 222 layer = layer->parent_; |
218 return layer == NULL; | 223 return layer == NULL; |
219 } | 224 } |
220 | 225 |
221 bool Layer::ShouldDraw() const { | 226 bool Layer::ShouldDraw() const { |
(...skipping 16 matching lines...) Expand all Loading... |
238 if (target != root_layer) | 243 if (target != root_layer) |
239 target->ConvertPointFromAncestor(root_layer, point); | 244 target->ConvertPointFromAncestor(root_layer, point); |
240 } | 245 } |
241 | 246 |
242 void Layer::SetFillsBoundsOpaquely(bool fills_bounds_opaquely) { | 247 void Layer::SetFillsBoundsOpaquely(bool fills_bounds_opaquely) { |
243 if (fills_bounds_opaquely_ == fills_bounds_opaquely) | 248 if (fills_bounds_opaquely_ == fills_bounds_opaquely) |
244 return; | 249 return; |
245 | 250 |
246 fills_bounds_opaquely_ = fills_bounds_opaquely; | 251 fills_bounds_opaquely_ = fills_bounds_opaquely; |
247 | 252 |
248 if (parent()) | 253 SetNeedsToRecomputeHole(); |
249 parent()->RecomputeHole(); | |
250 #if defined(USE_WEBKIT_COMPOSITOR) | 254 #if defined(USE_WEBKIT_COMPOSITOR) |
251 web_layer_.setOpaque(fills_bounds_opaquely); | 255 web_layer_.setOpaque(fills_bounds_opaquely); |
252 #endif | 256 #endif |
253 } | 257 } |
254 | 258 |
255 void Layer::SetExternalTexture(ui::Texture* texture) { | 259 void Layer::SetExternalTexture(ui::Texture* texture) { |
256 DCHECK(texture); | 260 DCHECK(texture); |
257 layer_updated_externally_ = true; | 261 layer_updated_externally_ = true; |
258 texture_ = texture; | 262 texture_ = texture; |
259 #if defined(USE_WEBKIT_COMPOSITOR) | 263 #if defined(USE_WEBKIT_COMPOSITOR) |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
318 if (compositor) | 322 if (compositor) |
319 compositor->ScheduleDraw(); | 323 compositor->ScheduleDraw(); |
320 } | 324 } |
321 | 325 |
322 void Layer::Draw() { | 326 void Layer::Draw() { |
323 TRACE_EVENT0("ui", "Layer::Draw"); | 327 TRACE_EVENT0("ui", "Layer::Draw"); |
324 #if defined(USE_WEBKIT_COMPOSITOR) | 328 #if defined(USE_WEBKIT_COMPOSITOR) |
325 NOTREACHED(); | 329 NOTREACHED(); |
326 #else | 330 #else |
327 DCHECK(GetCompositor()); | 331 DCHECK(GetCompositor()); |
| 332 |
| 333 if (recompute_hole_ && !parent_) |
| 334 RecomputeHole(); |
| 335 |
328 if (!ShouldDraw()) | 336 if (!ShouldDraw()) |
329 return; | 337 return; |
330 | 338 |
331 UpdateLayerCanvas(); | 339 UpdateLayerCanvas(); |
332 | 340 |
333 // Layer drew nothing, no texture was created. | 341 // Layer drew nothing, no texture was created. |
334 if (!texture_.get()) | 342 if (!texture_.get()) |
335 return; | 343 return; |
336 | 344 |
337 ui::TextureDrawParams texture_draw_params; | 345 ui::TextureDrawParams texture_draw_params; |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
425 return; | 433 return; |
426 } | 434 } |
427 scoped_ptr<gfx::Canvas> canvas(gfx::Canvas::CreateCanvas(draw_rect.size(), | 435 scoped_ptr<gfx::Canvas> canvas(gfx::Canvas::CreateCanvas(draw_rect.size(), |
428 false)); | 436 false)); |
429 canvas->Translate(gfx::Point().Subtract(draw_rect.origin())); | 437 canvas->Translate(gfx::Point().Subtract(draw_rect.origin())); |
430 delegate_->OnPaintLayer(canvas.get()); | 438 delegate_->OnPaintLayer(canvas.get()); |
431 SetCanvas(*canvas->GetSkCanvas(), draw_rect.origin()); | 439 SetCanvas(*canvas->GetSkCanvas(), draw_rect.origin()); |
432 #endif | 440 #endif |
433 } | 441 } |
434 | 442 |
435 void Layer::RecomputeHole() { | 443 void Layer::SetNeedsToRecomputeHole() { |
436 if (type_ == LAYER_HAS_NO_TEXTURE) | 444 Layer* root_layer = this; |
| 445 while (root_layer->parent_) |
| 446 root_layer = root_layer->parent_; |
| 447 |
| 448 root_layer->recompute_hole_ = true; |
| 449 } |
| 450 |
| 451 void Layer::ClearHoleRects() { |
| 452 hole_rect_ = gfx::Rect(); |
| 453 |
| 454 for (size_t i = 0; i < children_.size(); i++) |
| 455 children_[i]->ClearHoleRects(); |
| 456 } |
| 457 |
| 458 void Layer::GetLayerProperties(const ui::Transform& parent_transform, |
| 459 std::vector<LayerProperties>* traversal) { |
| 460 if (!visible_ || opacity_ != 1.0f) |
437 return; | 461 return; |
438 | 462 |
439 // Reset to default. | 463 ui::Transform current_transform; |
440 hole_rect_ = gfx::Rect(); | 464 if (transform().HasChange()) |
| 465 current_transform.ConcatTransform(transform()); |
| 466 current_transform.ConcatTranslate( |
| 467 static_cast<float>(bounds().x()), |
| 468 static_cast<float>(bounds().y())); |
| 469 current_transform.ConcatTransform(parent_transform); |
441 | 470 |
442 // Find the largest hole | 471 if (fills_bounds_opaquely_ && type_ == LAYER_HAS_TEXTURE) { |
443 for (size_t i = 0; i < children_.size(); ++i) { | 472 LayerProperties properties; |
444 // Ignore non-opaque and hidden children. | 473 properties.layer = this; |
445 if (!children_[i]->IsCompletelyOpaque() || !children_[i]->visible_) | 474 properties.transform_relative_to_root = current_transform; |
446 continue; | 475 traversal->push_back(properties); |
447 | |
448 // Ignore children that aren't rotated by multiples of 90 degrees. | |
449 float degrees; | |
450 if (!InterpolatedTransform::FactorTRS(children_[i]->transform(), | |
451 NULL, °rees, NULL) || | |
452 !IsApproximateMultilpleOf(degrees, 90.0f)) | |
453 continue; | |
454 | |
455 // The reason why we don't just take the bounds and apply the transform is | |
456 // that the bounds encodes a position, too, so the effective transformation | |
457 // matrix is actually different that the one reported. As well, the bounds | |
458 // will not necessarily be at the origin. | |
459 gfx::Rect candidate_hole(children_[i]->bounds_.size()); | |
460 ui::Transform transform = children_[i]->transform(); | |
461 transform.ConcatTranslate(static_cast<float>(children_[i]->bounds_.x()), | |
462 static_cast<float>(children_[i]->bounds_.y())); | |
463 transform.TransformRect(&candidate_hole); | |
464 | |
465 // This layer might not contain the child (e.g., a portion of the child may | |
466 // be offscreen). Only the portion of the child that overlaps this layer is | |
467 // of any importance, so take the intersection. | |
468 candidate_hole = gfx::Rect(bounds().size()).Intersect(candidate_hole); | |
469 | |
470 // Ensure we have the largest hole. | |
471 if (candidate_hole.size().GetArea() > hole_rect_.size().GetArea()) | |
472 hole_rect_ = candidate_hole; | |
473 } | 476 } |
474 | 477 |
475 // Free up texture memory if the hole fills bounds of layer. | 478 for (size_t i = 0; i < children_.size(); i++) |
476 if (!ShouldDraw() && !layer_updated_externally_) | 479 children_[i]->GetLayerProperties(current_transform, traversal); |
477 texture_ = NULL; | 480 } |
| 481 |
| 482 void Layer::RecomputeHole() { |
| 483 std::vector<LayerProperties> traversal; |
| 484 ui::Transform transform; |
| 485 |
| 486 ClearHoleRects(); |
| 487 GetLayerProperties(transform, &traversal); |
| 488 |
| 489 for (size_t i = 0; i < traversal.size(); i++) { |
| 490 Layer* layer = traversal[i].layer; |
| 491 gfx::Rect bounds = gfx::Rect(layer->bounds().size()); |
| 492 |
| 493 // Iterate through layers which are after traversal[i] in draw order |
| 494 // and find the largest candidate hole. |
| 495 for (size_t j = i + 1; j < traversal.size(); j++) { |
| 496 gfx::Rect candidate_hole = gfx::Rect(traversal[j].layer->bounds().size()); |
| 497 |
| 498 // Compute transform to go from bounds of layer |j| to local bounds of |
| 499 // layer |i|. |
| 500 ui::Transform candidate_hole_transform; |
| 501 ui::Transform inverted; |
| 502 |
| 503 candidate_hole_transform.ConcatTransform( |
| 504 traversal[j].transform_relative_to_root); |
| 505 |
| 506 if (!traversal[i].transform_relative_to_root.GetInverse(&inverted)) |
| 507 continue; |
| 508 |
| 509 candidate_hole_transform.ConcatTransform(inverted); |
| 510 |
| 511 // cannot punch a hole if the relative transform between the two layers |
| 512 // is not multiple of 90. |
| 513 float degrees; |
| 514 gfx::Point p; |
| 515 if (!InterpolatedTransform::FactorTRS(candidate_hole_transform, &p, |
| 516 °rees, NULL) || !IsApproximateMultilpleOf(degrees, 90.0f)) |
| 517 continue; |
| 518 |
| 519 candidate_hole_transform.TransformRect(&candidate_hole); |
| 520 candidate_hole = candidate_hole.Intersect(bounds); |
| 521 |
| 522 if (candidate_hole.size().GetArea() > |
| 523 layer->hole_rect().size().GetArea()) { |
| 524 layer->set_hole_rect(candidate_hole); |
| 525 } |
| 526 } |
| 527 // Free up texture memory if the hole fills bounds of layer. |
| 528 if (!layer->ShouldDraw() && !layer_updated_externally()) |
| 529 layer->DropTexture(); |
478 | 530 |
479 #if defined(USE_WEBKIT_COMPOSITOR) | 531 #if defined(USE_WEBKIT_COMPOSITOR) |
480 RecomputeDrawsContent(); | 532 layer->RecomputeDrawsContent(); |
481 #endif | 533 #endif |
482 } | 534 } |
483 | 535 |
484 bool Layer::IsCompletelyOpaque() const { | 536 recompute_hole_ = false; |
485 return fills_bounds_opaquely() && GetCombinedOpacity() == 1.0f; | |
486 } | 537 } |
487 | 538 |
488 // static | 539 // static |
489 void Layer::PunchHole(const gfx::Rect& rect, | 540 void Layer::PunchHole(const gfx::Rect& rect, |
490 const gfx::Rect& region_to_punch_out, | 541 const gfx::Rect& region_to_punch_out, |
491 std::vector<gfx::Rect>* sides) { | 542 std::vector<gfx::Rect>* sides) { |
492 gfx::Rect trimmed_rect = rect.Intersect(region_to_punch_out); | 543 gfx::Rect trimmed_rect = rect.Intersect(region_to_punch_out); |
493 | 544 |
494 if (trimmed_rect.IsEmpty()) { | 545 if (trimmed_rect.IsEmpty()) { |
495 sides->push_back(rect); | 546 sides->push_back(rect); |
(...skipping 18 matching lines...) Expand all Loading... |
514 rect.right() - trimmed_rect.right(), | 565 rect.right() - trimmed_rect.right(), |
515 trimmed_rect.height())); | 566 trimmed_rect.height())); |
516 | 567 |
517 // Bottom (below the hole). | 568 // Bottom (below the hole). |
518 sides->push_back(gfx::Rect(rect.x(), | 569 sides->push_back(gfx::Rect(rect.x(), |
519 trimmed_rect.bottom(), | 570 trimmed_rect.bottom(), |
520 rect.width(), | 571 rect.width(), |
521 rect.bottom() - trimmed_rect.bottom())); | 572 rect.bottom() - trimmed_rect.bottom())); |
522 } | 573 } |
523 | 574 |
524 void Layer::DropTextures() { | 575 void Layer::DropTexture() { |
525 if (!layer_updated_externally_) | 576 if (!layer_updated_externally_) |
526 texture_ = NULL; | 577 texture_ = NULL; |
| 578 } |
| 579 |
| 580 void Layer::DropTextures() { |
| 581 DropTexture(); |
527 for (size_t i = 0; i < children_.size(); ++i) | 582 for (size_t i = 0; i < children_.size(); ++i) |
528 children_[i]->DropTextures(); | 583 children_[i]->DropTextures(); |
529 } | 584 } |
530 | 585 |
531 bool Layer::ConvertPointForAncestor(const Layer* ancestor, | 586 bool Layer::ConvertPointForAncestor(const Layer* ancestor, |
532 gfx::Point* point) const { | 587 gfx::Point* point) const { |
533 ui::Transform transform; | 588 ui::Transform transform; |
534 bool result = GetTransformRelativeTo(ancestor, &transform); | 589 bool result = GetTransformRelativeTo(ancestor, &transform); |
535 gfx::Point3f p(*point); | 590 gfx::Point3f p(*point); |
536 transform.TransformPoint(p); | 591 transform.TransformPoint(p); |
(...skipping 29 matching lines...) Expand all Loading... |
566 | 621 |
567 bool was_move = bounds_.size() == bounds.size(); | 622 bool was_move = bounds_.size() == bounds.size(); |
568 bounds_ = bounds; | 623 bounds_ = bounds; |
569 if (IsDrawn()) { | 624 if (IsDrawn()) { |
570 if (was_move) | 625 if (was_move) |
571 ScheduleDraw(); | 626 ScheduleDraw(); |
572 else | 627 else |
573 SchedulePaint(gfx::Rect(bounds.size())); | 628 SchedulePaint(gfx::Rect(bounds.size())); |
574 } | 629 } |
575 | 630 |
576 if (parent()) | 631 SetNeedsToRecomputeHole(); |
577 parent()->RecomputeHole(); | |
578 #if defined(USE_WEBKIT_COMPOSITOR) | 632 #if defined(USE_WEBKIT_COMPOSITOR) |
579 web_layer_.setBounds(bounds.size()); | 633 web_layer_.setBounds(bounds.size()); |
580 RecomputeTransform(); | 634 RecomputeTransform(); |
581 RecomputeDrawsContent(); | 635 RecomputeDrawsContent(); |
582 #endif | 636 #endif |
583 } | 637 } |
584 | 638 |
585 void Layer::SetTransformImmediately(const ui::Transform& transform) { | 639 void Layer::SetTransformImmediately(const ui::Transform& transform) { |
586 transform_ = transform; | 640 transform_ = transform; |
587 | 641 |
588 if (parent()) | 642 SetNeedsToRecomputeHole(); |
589 parent()->RecomputeHole(); | |
590 #if defined(USE_WEBKIT_COMPOSITOR) | 643 #if defined(USE_WEBKIT_COMPOSITOR) |
591 RecomputeTransform(); | 644 RecomputeTransform(); |
592 #endif | 645 #endif |
593 } | 646 } |
594 | 647 |
595 void Layer::SetOpacityImmediately(float opacity) { | 648 void Layer::SetOpacityImmediately(float opacity) { |
596 bool schedule_draw = (opacity != opacity_ && IsDrawn()); | 649 bool schedule_draw = (opacity != opacity_ && IsDrawn()); |
597 bool was_opaque = GetCombinedOpacity() == 1.0f; | 650 bool was_opaque = GetCombinedOpacity() == 1.0f; |
598 opacity_ = opacity; | 651 opacity_ = opacity; |
599 bool is_opaque = GetCombinedOpacity() == 1.0f; | 652 bool is_opaque = GetCombinedOpacity() == 1.0f; |
600 | 653 |
601 // If our opacity has changed we need to recompute our hole, our parent's hole | 654 // If our opacity has changed we need to recompute our hole, our parent's hole |
602 // and the holes of all our descendants. | 655 // and the holes of all our descendants. |
603 if (was_opaque != is_opaque) { | 656 if (was_opaque != is_opaque) |
604 if (parent_) | 657 SetNeedsToRecomputeHole(); |
605 parent_->RecomputeHole(); | |
606 std::queue<Layer*> to_process; | |
607 to_process.push(this); | |
608 while (!to_process.empty()) { | |
609 Layer* current = to_process.front(); | |
610 to_process.pop(); | |
611 current->RecomputeHole(); | |
612 for (size_t i = 0; i < current->children_.size(); ++i) | |
613 to_process.push(current->children_.at(i)); | |
614 } | |
615 } | |
616 #if defined(USE_WEBKIT_COMPOSITOR) | 658 #if defined(USE_WEBKIT_COMPOSITOR) |
617 if (visible_) | 659 if (visible_) |
618 web_layer_.setOpacity(opacity); | 660 web_layer_.setOpacity(opacity); |
619 #endif | 661 #endif |
620 if (schedule_draw) | 662 if (schedule_draw) |
621 ScheduleDraw(); | 663 ScheduleDraw(); |
622 } | 664 } |
623 | 665 |
624 void Layer::SetBoundsFromAnimation(const gfx::Rect& bounds) { | 666 void Layer::SetBoundsFromAnimation(const gfx::Rect& bounds) { |
625 SetBoundsImmediately(bounds); | 667 SetBoundsImmediately(bounds); |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
678 #else | 720 #else |
679 unsigned int texture_id = 0; | 721 unsigned int texture_id = 0; |
680 #endif | 722 #endif |
681 web_layer_.to<WebKit::WebExternalTextureLayer>().setTextureId( | 723 web_layer_.to<WebKit::WebExternalTextureLayer>().setTextureId( |
682 should_draw ? texture_id : 0); | 724 should_draw ? texture_id : 0); |
683 } | 725 } |
684 } | 726 } |
685 #endif | 727 #endif |
686 | 728 |
687 } // namespace ui | 729 } // namespace ui |
OLD | NEW |