| 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 |