Chromium Code Reviews| 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/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 29 } // namespace | 29 } // namespace |
| 30 | 30 |
| 31 namespace ui { | 31 namespace ui { |
| 32 | 32 |
| 33 Layer::Layer(Compositor* compositor) | 33 Layer::Layer(Compositor* compositor) |
| 34 : type_(LAYER_HAS_TEXTURE), | 34 : type_(LAYER_HAS_TEXTURE), |
| 35 compositor_(compositor), | 35 compositor_(compositor), |
| 36 parent_(NULL), | 36 parent_(NULL), |
| 37 visible_(true), | 37 visible_(true), |
| 38 fills_bounds_opaquely_(true), | 38 fills_bounds_opaquely_(true), |
| 39 recompute_hole_(false), | |
| 39 layer_updated_externally_(false), | 40 layer_updated_externally_(false), |
| 40 opacity_(1.0f), | 41 opacity_(1.0f), |
| 41 delegate_(NULL) { | 42 delegate_(NULL) { |
| 42 #if defined(USE_WEBKIT_COMPOSITOR) | 43 #if defined(USE_WEBKIT_COMPOSITOR) |
| 43 CreateWebLayer(); | 44 CreateWebLayer(); |
| 44 #endif | 45 #endif |
| 45 } | 46 } |
| 46 | 47 |
| 47 Layer::Layer(Compositor* compositor, LayerType type) | 48 Layer::Layer(Compositor* compositor, LayerType type) |
| 48 : type_(type), | 49 : type_(type), |
| 49 compositor_(compositor), | 50 compositor_(compositor), |
| 50 parent_(NULL), | 51 parent_(NULL), |
| 51 visible_(true), | 52 visible_(true), |
| 52 fills_bounds_opaquely_(true), | 53 fills_bounds_opaquely_(true), |
| 54 recompute_hole_(false), | |
| 53 layer_updated_externally_(false), | 55 layer_updated_externally_(false), |
| 54 opacity_(1.0f), | 56 opacity_(1.0f), |
| 55 delegate_(NULL) { | 57 delegate_(NULL) { |
| 56 #if defined(USE_WEBKIT_COMPOSITOR) | 58 #if defined(USE_WEBKIT_COMPOSITOR) |
| 57 CreateWebLayer(); | 59 CreateWebLayer(); |
| 58 #endif | 60 #endif |
| 59 } | 61 } |
| 60 | 62 |
| 61 Layer::~Layer() { | 63 Layer::~Layer() { |
| 62 if (parent_) | 64 if (parent_) |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 83 | 85 |
| 84 void Layer::Add(Layer* child) { | 86 void Layer::Add(Layer* child) { |
| 85 if (child->parent_) | 87 if (child->parent_) |
| 86 child->parent_->Remove(child); | 88 child->parent_->Remove(child); |
| 87 child->parent_ = this; | 89 child->parent_ = this; |
| 88 children_.push_back(child); | 90 children_.push_back(child); |
| 89 #if defined(USE_WEBKIT_COMPOSITOR) | 91 #if defined(USE_WEBKIT_COMPOSITOR) |
| 90 web_layer_.addChild(child->web_layer_); | 92 web_layer_.addChild(child->web_layer_); |
| 91 #endif | 93 #endif |
| 92 | 94 |
| 93 RecomputeHole(); | 95 SetNeedsToRecomputeHole(); |
| 94 } | 96 } |
| 95 | 97 |
| 96 void Layer::Remove(Layer* child) { | 98 void Layer::Remove(Layer* child) { |
| 97 std::vector<Layer*>::iterator i = | 99 std::vector<Layer*>::iterator i = |
| 98 std::find(children_.begin(), children_.end(), child); | 100 std::find(children_.begin(), children_.end(), child); |
| 99 DCHECK(i != children_.end()); | 101 DCHECK(i != children_.end()); |
| 100 children_.erase(i); | 102 children_.erase(i); |
| 101 child->parent_ = NULL; | 103 child->parent_ = NULL; |
| 102 #if defined(USE_WEBKIT_COMPOSITOR) | 104 #if defined(USE_WEBKIT_COMPOSITOR) |
| 103 child->web_layer_.removeFromParent(); | 105 child->web_layer_.removeFromParent(); |
| 104 #endif | 106 #endif |
| 105 | 107 |
| 106 RecomputeHole(); | 108 SetNeedsToRecomputeHole(); |
| 107 | 109 |
| 108 child->DropTextures(); | 110 child->DropTextures(); |
| 109 } | 111 } |
| 110 | 112 |
| 111 void Layer::MoveToFront(Layer* child) { | 113 void Layer::MoveToFront(Layer* child) { |
| 112 std::vector<Layer*>::iterator i = | 114 std::vector<Layer*>::iterator i = |
| 113 std::find(children_.begin(), children_.end(), child); | 115 std::find(children_.begin(), children_.end(), child); |
| 114 DCHECK(i != children_.end()); | 116 DCHECK(i != children_.end()); |
| 115 children_.erase(i); | 117 children_.erase(i); |
| 116 children_.push_back(child); | 118 children_.push_back(child); |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 178 return; | 180 return; |
| 179 | 181 |
| 180 bool was_drawn = IsDrawn(); | 182 bool was_drawn = IsDrawn(); |
| 181 visible_ = visible; | 183 visible_ = visible; |
| 182 bool is_drawn = IsDrawn(); | 184 bool is_drawn = IsDrawn(); |
| 183 if (was_drawn == is_drawn) | 185 if (was_drawn == is_drawn) |
| 184 return; | 186 return; |
| 185 | 187 |
| 186 if (!is_drawn) | 188 if (!is_drawn) |
| 187 DropTextures(); | 189 DropTextures(); |
| 188 if (parent_) | 190 SetNeedsToRecomputeHole(); |
| 189 parent_->RecomputeHole(); | |
| 190 #if defined(USE_WEBKIT_COMPOSITOR) | 191 #if defined(USE_WEBKIT_COMPOSITOR) |
| 191 // TODO(piman): Expose a visibility flag on WebLayer. | 192 // TODO(piman): Expose a visibility flag on WebLayer. |
| 192 web_layer_.setOpacity(visible_ ? opacity_ : 0.f); | 193 web_layer_.setOpacity(visible_ ? opacity_ : 0.f); |
| 193 #endif | 194 #endif |
| 194 } | 195 } |
| 195 | 196 |
| 196 bool Layer::IsDrawn() const { | 197 bool Layer::IsDrawn() const { |
| 197 const Layer* layer = this; | 198 const Layer* layer = this; |
| 198 while (layer && layer->visible_) | 199 while (layer && layer->visible_) |
| 199 layer = layer->parent_; | 200 layer = layer->parent_; |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 223 NOTREACHED(); // |source| and |target| are in unrelated hierarchies. | 224 NOTREACHED(); // |source| and |target| are in unrelated hierarchies. |
| 224 } | 225 } |
| 225 } | 226 } |
| 226 | 227 |
| 227 void Layer::SetFillsBoundsOpaquely(bool fills_bounds_opaquely) { | 228 void Layer::SetFillsBoundsOpaquely(bool fills_bounds_opaquely) { |
| 228 if (fills_bounds_opaquely_ == fills_bounds_opaquely) | 229 if (fills_bounds_opaquely_ == fills_bounds_opaquely) |
| 229 return; | 230 return; |
| 230 | 231 |
| 231 fills_bounds_opaquely_ = fills_bounds_opaquely; | 232 fills_bounds_opaquely_ = fills_bounds_opaquely; |
| 232 | 233 |
| 233 if (parent()) | 234 SetNeedsToRecomputeHole(); |
| 234 parent()->RecomputeHole(); | |
| 235 #if defined(USE_WEBKIT_COMPOSITOR) | 235 #if defined(USE_WEBKIT_COMPOSITOR) |
| 236 web_layer_.setOpaque(fills_bounds_opaquely); | 236 web_layer_.setOpaque(fills_bounds_opaquely); |
| 237 #endif | 237 #endif |
| 238 } | 238 } |
| 239 | 239 |
| 240 void Layer::SetExternalTexture(ui::Texture* texture) { | 240 void Layer::SetExternalTexture(ui::Texture* texture) { |
| 241 DCHECK(texture); | 241 DCHECK(texture); |
| 242 layer_updated_externally_ = true; | 242 layer_updated_externally_ = true; |
| 243 texture_ = texture; | 243 texture_ = texture; |
| 244 } | 244 } |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 274 Compositor* compositor = GetCompositor(); | 274 Compositor* compositor = GetCompositor(); |
| 275 if (compositor) | 275 if (compositor) |
| 276 compositor->ScheduleDraw(); | 276 compositor->ScheduleDraw(); |
| 277 } | 277 } |
| 278 | 278 |
| 279 void Layer::Draw() { | 279 void Layer::Draw() { |
| 280 #if defined(USE_WEBKIT_COMPOSITOR) | 280 #if defined(USE_WEBKIT_COMPOSITOR) |
| 281 NOTREACHED(); | 281 NOTREACHED(); |
| 282 #else | 282 #else |
| 283 DCHECK(GetCompositor()); | 283 DCHECK(GetCompositor()); |
| 284 | |
| 285 if (recompute_hole_ && !parent_) | |
| 286 RecomputeHole(); | |
| 287 | |
| 284 if (!ShouldDraw()) | 288 if (!ShouldDraw()) |
| 285 return; | 289 return; |
| 286 | 290 |
| 287 UpdateLayerCanvas(); | 291 UpdateLayerCanvas(); |
| 288 | 292 |
| 289 // Layer drew nothing, no texture was created. | 293 // Layer drew nothing, no texture was created. |
| 290 if (!texture_.get()) | 294 if (!texture_.get()) |
| 291 return; | 295 return; |
| 292 | 296 |
| 293 ui::TextureDrawParams texture_draw_params; | 297 ui::TextureDrawParams texture_draw_params; |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 379 return; | 383 return; |
| 380 } | 384 } |
| 381 scoped_ptr<gfx::Canvas> canvas(gfx::Canvas::CreateCanvas( | 385 scoped_ptr<gfx::Canvas> canvas(gfx::Canvas::CreateCanvas( |
| 382 draw_rect.width(), draw_rect.height(), false)); | 386 draw_rect.width(), draw_rect.height(), false)); |
| 383 canvas->TranslateInt(-draw_rect.x(), -draw_rect.y()); | 387 canvas->TranslateInt(-draw_rect.x(), -draw_rect.y()); |
| 384 delegate_->OnPaintLayer(canvas.get()); | 388 delegate_->OnPaintLayer(canvas.get()); |
| 385 SetCanvas(*canvas->GetSkCanvas(), draw_rect.origin()); | 389 SetCanvas(*canvas->GetSkCanvas(), draw_rect.origin()); |
| 386 #endif | 390 #endif |
| 387 } | 391 } |
| 388 | 392 |
| 389 void Layer::RecomputeHole() { | 393 void Layer::SetNeedsToRecomputeHole() { |
| 390 if (type_ == LAYER_HAS_NO_TEXTURE) | 394 Layer* root_layer = this; |
| 395 while (root_layer->parent_) | |
| 396 root_layer = root_layer->parent_; | |
| 397 | |
| 398 root_layer->recompute_hole_ = true; | |
| 399 } | |
| 400 | |
| 401 void Layer::ClearHoleRects() { | |
| 402 hole_rect_ = gfx::Rect(); | |
| 403 | |
| 404 for (size_t i = 0; i < children_.size(); i++) | |
| 405 children_[i]->ClearHoleRects(); | |
| 406 } | |
| 407 | |
| 408 void Layer::GeneratePreorderTraversal( | |
| 409 std::vector<LayerProperties>* traversal, | |
| 410 const ui::Transform& current_transform, float current_opacity) { | |
|
sky
2011/10/25 21:44:09
each param on its own line.
sky
2011/10/25 21:44:09
All of the params should be for the parent, not th
| |
| 411 if (!visible_) | |
|
sky
2011/10/25 21:44:09
Should this return if opacity == 0 too?
| |
| 391 return; | 412 return; |
| 392 | 413 |
| 393 // Reset to default. | 414 if (fills_bounds_opaquely_ && type_ == LAYER_HAS_TEXTURE) { |
| 394 hole_rect_ = gfx::Rect(); | 415 LayerProperties properties; |
| 395 | 416 properties.layer = this; |
| 396 // Find the largest hole | 417 properties.transform_relative_to_root = current_transform; |
| 397 for (size_t i = 0; i < children_.size(); ++i) { | 418 properties.combined_opacity = current_opacity; |
| 398 // Ignore non-opaque and hidden children. | 419 traversal->push_back(properties); |
| 399 if (!children_[i]->IsCompletelyOpaque() || !children_[i]->visible_) | |
| 400 continue; | |
| 401 | |
| 402 // Ignore children that aren't rotated by multiples of 90 degrees. | |
| 403 float degrees; | |
| 404 if (!InterpolatedTransform::FactorTRS(children_[i]->transform(), | |
| 405 NULL, °rees, NULL) || | |
| 406 !IsApproximateMultilpleOf(degrees, 90.0f)) | |
| 407 continue; | |
| 408 | |
| 409 // The reason why we don't just take the bounds and apply the transform is | |
| 410 // that the bounds encodes a position, too, so the effective transformation | |
| 411 // matrix is actually different that the one reported. As well, the bounds | |
| 412 // will not necessarily be at the origin. | |
| 413 gfx::Rect candidate_hole(children_[i]->bounds_.size()); | |
| 414 ui::Transform transform = children_[i]->transform(); | |
| 415 transform.ConcatTranslate(static_cast<float>(children_[i]->bounds_.x()), | |
| 416 static_cast<float>(children_[i]->bounds_.y())); | |
| 417 transform.TransformRect(&candidate_hole); | |
| 418 | |
| 419 // This layer might not contain the child (e.g., a portion of the child may | |
| 420 // be offscreen). Only the portion of the child that overlaps this layer is | |
| 421 // of any importance, so take the intersection. | |
| 422 candidate_hole = gfx::Rect(bounds().size()).Intersect(candidate_hole); | |
| 423 | |
| 424 // Ensure we have the largest hole. | |
| 425 if (candidate_hole.size().GetArea() > hole_rect_.size().GetArea()) | |
| 426 hole_rect_ = candidate_hole; | |
| 427 } | 420 } |
| 428 | 421 |
| 429 // Free up texture memory if the hole fills bounds of layer. | 422 for (size_t i = 0; i < children_.size(); i++) { |
| 430 if (!ShouldDraw() && !layer_updated_externally_) | 423 Layer* child = children_[i]; |
| 431 texture_ = NULL; | 424 ui::Transform child_transform; |
| 425 child_transform.ConcatTransform(current_transform); | |
| 426 if (child->transform().HasChange()) | |
| 427 child_transform.ConcatTransform(child->transform()); | |
| 428 child_transform.ConcatTranslate( | |
| 429 static_cast<float>(child->bounds().x()), | |
|
sky
2011/10/25 21:44:09
Wrapped lines should be indented by 4.
| |
| 430 static_cast<float>(child->bounds().y())); | |
| 431 float child_opacity = current_opacity * child->opacity(); | |
| 432 | |
| 433 child->GeneratePreorderTraversal(traversal, child_transform, | |
| 434 child_opacity); | |
| 435 } | |
| 436 } | |
| 437 | |
| 438 void Layer::RecomputeHole() { | |
| 439 std::vector<LayerProperties> traversal; | |
| 440 ui::Transform transform; | |
| 441 float opacity = 1.0f; | |
| 442 | |
| 443 ClearHoleRects(); | |
| 444 GeneratePreorderTraversal(&traversal, transform, opacity); | |
| 445 | |
| 446 for (size_t i = 0; i < traversal.size(); i++) { | |
| 447 Layer* layer = traversal[i].layer; | |
| 448 gfx::Rect bounds = gfx::Rect(layer->bounds().size()); | |
|
sky
2011/10/25 21:44:09
These calculations are expensive. Is it worth only
| |
| 449 | |
| 450 // Iterate through layers which are after traversal[i] in draw order | |
| 451 // and find the largest candidate hole. | |
| 452 for (size_t j = i + 1; j < traversal.size(); j++) { | |
| 453 gfx::Rect candidate_hole = gfx::Rect(traversal[j].layer->bounds().size()); | |
| 454 | |
| 455 // Compute transform to go from bounds of layer |j| to local bounds of | |
| 456 // layer |i|. | |
| 457 ui::Transform candidate_hole_transform; | |
| 458 ui::Transform inverted; | |
| 459 | |
| 460 candidate_hole_transform.ConcatTransform( | |
| 461 traversal[j].transform_relative_to_root); | |
| 462 | |
| 463 if (!traversal[i].transform_relative_to_root.GetInverse(&inverted)) | |
| 464 continue; | |
| 465 | |
| 466 candidate_hole_transform.ConcatTransform(inverted); | |
| 467 | |
| 468 // can only punch a hole if the two layers have 1.0f opacity. | |
| 469 if (traversal[i].combined_opacity != 1.0f || | |
|
sky
2011/10/25 21:44:09
Shouldn't we make GeneratePreorderTraversal ignore
| |
| 470 traversal[j].combined_opacity != 1.0f) | |
| 471 continue; | |
| 472 | |
| 473 // cannot punch a hole if the relative transform between the two layers | |
| 474 // is not multiple of 90. | |
| 475 float degrees; | |
| 476 gfx::Point p; | |
| 477 if (!InterpolatedTransform::FactorTRS(candidate_hole_transform, &p, | |
| 478 °rees, NULL) || !IsApproximateMultilpleOf(degrees, 90.0f)) | |
| 479 continue; | |
| 480 | |
| 481 candidate_hole_transform.TransformRect(&candidate_hole); | |
| 482 candidate_hole = candidate_hole.Intersect(bounds); | |
| 483 | |
| 484 if (candidate_hole.size().GetArea() > layer->hole_rect().size().GetArea()) | |
| 485 layer->set_hole_rect(candidate_hole); | |
| 486 } | |
| 487 // Free up texture memory if the hole fills bounds of layer. | |
| 488 if (!layer->ShouldDraw() && !layer_updated_externally()) | |
| 489 layer->DropTexture(); | |
| 432 | 490 |
| 433 #if defined(USE_WEBKIT_COMPOSITOR) | 491 #if defined(USE_WEBKIT_COMPOSITOR) |
| 434 RecomputeDrawsContent(); | 492 layer->RecomputeDrawsContent(); |
| 435 #endif | 493 #endif |
| 436 } | 494 } |
| 437 | 495 |
| 438 bool Layer::IsCompletelyOpaque() const { | 496 recompute_hole_ = false; |
| 439 return fills_bounds_opaquely() && GetCombinedOpacity() == 1.0f; | |
| 440 } | 497 } |
| 441 | 498 |
| 442 // static | 499 // static |
| 443 void Layer::PunchHole(const gfx::Rect& rect, | 500 void Layer::PunchHole(const gfx::Rect& rect, |
| 444 const gfx::Rect& region_to_punch_out, | 501 const gfx::Rect& region_to_punch_out, |
| 445 std::vector<gfx::Rect>* sides) { | 502 std::vector<gfx::Rect>* sides) { |
| 446 gfx::Rect trimmed_rect = rect.Intersect(region_to_punch_out); | 503 gfx::Rect trimmed_rect = rect.Intersect(region_to_punch_out); |
| 447 | 504 |
| 448 if (trimmed_rect.IsEmpty()) { | 505 if (trimmed_rect.IsEmpty()) { |
| 449 sides->push_back(rect); | 506 sides->push_back(rect); |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 468 rect.right() - trimmed_rect.right(), | 525 rect.right() - trimmed_rect.right(), |
| 469 trimmed_rect.height())); | 526 trimmed_rect.height())); |
| 470 | 527 |
| 471 // Bottom (below the hole). | 528 // Bottom (below the hole). |
| 472 sides->push_back(gfx::Rect(rect.x(), | 529 sides->push_back(gfx::Rect(rect.x(), |
| 473 trimmed_rect.bottom(), | 530 trimmed_rect.bottom(), |
| 474 rect.width(), | 531 rect.width(), |
| 475 rect.bottom() - trimmed_rect.bottom())); | 532 rect.bottom() - trimmed_rect.bottom())); |
| 476 } | 533 } |
| 477 | 534 |
| 478 void Layer::DropTextures() { | 535 void Layer::DropTexture() { |
| 479 if (!layer_updated_externally_) | 536 if (!layer_updated_externally_) |
| 480 texture_ = NULL; | 537 texture_ = NULL; |
| 538 } | |
| 539 | |
| 540 void Layer::DropTextures() { | |
| 541 DropTexture(); | |
| 481 for (size_t i = 0; i < children_.size(); ++i) | 542 for (size_t i = 0; i < children_.size(); ++i) |
| 482 children_[i]->DropTextures(); | 543 children_[i]->DropTextures(); |
| 483 } | 544 } |
| 484 | 545 |
| 485 bool Layer::ConvertPointForAncestor(const Layer* ancestor, | 546 bool Layer::ConvertPointForAncestor(const Layer* ancestor, |
| 486 gfx::Point* point) const { | 547 gfx::Point* point) const { |
| 487 ui::Transform transform; | 548 ui::Transform transform; |
| 488 bool result = GetTransformRelativeTo(ancestor, &transform); | 549 bool result = GetTransformRelativeTo(ancestor, &transform); |
| 489 gfx::Point3f p(*point); | 550 gfx::Point3f p(*point); |
| 490 transform.TransformPoint(p); | 551 transform.TransformPoint(p); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 533 if (property != LayerAnimationManager::TRANSFORM && | 594 if (property != LayerAnimationManager::TRANSFORM && |
| 534 animator_->IsAnimating(LayerAnimationManager::TRANSFORM)) { | 595 animator_->IsAnimating(LayerAnimationManager::TRANSFORM)) { |
| 535 SetTransformImmediately(animator_->GetTargetTransform()); | 596 SetTransformImmediately(animator_->GetTargetTransform()); |
| 536 } | 597 } |
| 537 animator_.reset(); | 598 animator_.reset(); |
| 538 } | 599 } |
| 539 | 600 |
| 540 void Layer::SetBoundsImmediately(const gfx::Rect& bounds) { | 601 void Layer::SetBoundsImmediately(const gfx::Rect& bounds) { |
| 541 bounds_ = bounds; | 602 bounds_ = bounds; |
| 542 | 603 |
| 543 if (parent()) | 604 SetNeedsToRecomputeHole(); |
| 544 parent()->RecomputeHole(); | |
| 545 #if defined(USE_WEBKIT_COMPOSITOR) | 605 #if defined(USE_WEBKIT_COMPOSITOR) |
| 546 web_layer_.setBounds(bounds.size()); | 606 web_layer_.setBounds(bounds.size()); |
| 547 RecomputeTransform(); | 607 RecomputeTransform(); |
| 548 RecomputeDrawsContent(); | 608 RecomputeDrawsContent(); |
| 549 #endif | 609 #endif |
| 550 } | 610 } |
| 551 | 611 |
| 552 void Layer::SetTransformImmediately(const ui::Transform& transform) { | 612 void Layer::SetTransformImmediately(const ui::Transform& transform) { |
| 553 transform_ = transform; | 613 transform_ = transform; |
| 554 | 614 |
| 555 if (parent()) | 615 SetNeedsToRecomputeHole(); |
| 556 parent()->RecomputeHole(); | |
| 557 #if defined(USE_WEBKIT_COMPOSITOR) | 616 #if defined(USE_WEBKIT_COMPOSITOR) |
| 558 RecomputeTransform(); | 617 RecomputeTransform(); |
| 559 #endif | 618 #endif |
| 560 } | 619 } |
| 561 | 620 |
| 562 void Layer::SetOpacityImmediately(float opacity) { | 621 void Layer::SetOpacityImmediately(float opacity) { |
| 563 bool was_opaque = GetCombinedOpacity() == 1.0f; | |
| 564 opacity_ = opacity; | 622 opacity_ = opacity; |
| 565 bool is_opaque = GetCombinedOpacity() == 1.0f; | 623 SetNeedsToRecomputeHole(); |
| 566 | |
| 567 // If our opacity has changed we need to recompute our hole, our parent's hole | |
| 568 // and the holes of all our descendants. | |
| 569 if (was_opaque != is_opaque) { | |
| 570 if (parent_) | |
| 571 parent_->RecomputeHole(); | |
| 572 std::queue<Layer*> to_process; | |
| 573 to_process.push(this); | |
| 574 while (!to_process.empty()) { | |
| 575 Layer* current = to_process.front(); | |
| 576 to_process.pop(); | |
| 577 current->RecomputeHole(); | |
| 578 for (size_t i = 0; i < current->children_.size(); ++i) | |
| 579 to_process.push(current->children_.at(i)); | |
| 580 } | |
| 581 } | |
| 582 #if defined(USE_WEBKIT_COMPOSITOR) | 624 #if defined(USE_WEBKIT_COMPOSITOR) |
| 583 if (visible_) | 625 if (visible_) |
| 584 web_layer_.setOpacity(opacity); | 626 web_layer_.setOpacity(opacity); |
| 585 RecomputeDrawsContent(); | 627 RecomputeDrawsContent(); |
| 586 #endif | 628 #endif |
| 587 } | 629 } |
| 588 | 630 |
| 589 void Layer::SetBoundsFromAnimator(const gfx::Rect& bounds) { | 631 void Layer::SetBoundsFromAnimator(const gfx::Rect& bounds) { |
| 590 SetBoundsImmediately(bounds); | 632 SetBoundsImmediately(bounds); |
| 591 } | 633 } |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 680 result.append(", color=red"); | 722 result.append(", color=red"); |
| 681 | 723 |
| 682 if (fills_bounds_opaquely()) | 724 if (fills_bounds_opaquely()) |
| 683 result.append(", style=filled"); | 725 result.append(", style=filled"); |
| 684 | 726 |
| 685 return result; | 727 return result; |
| 686 } | 728 } |
| 687 | 729 |
| 688 #endif | 730 #endif |
| 689 | 731 |
| 690 //////////////////////////////////////////////////////////////////////////////// | |
| 691 | |
| 692 } // namespace ui | 732 } // namespace ui |
| OLD | NEW |