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

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

Issue 8368013: Improve Aura overdraw by changing hole calculation (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Nicer diff Created 9 years, 2 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 | Annotate | Revision Log
OLDNEW
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 296 matching lines...) Expand 10 before | Expand all | Expand 10 after
307 invalid_rect_ = gfx::Rect(); 307 invalid_rect_ = gfx::Rect();
308 return; 308 return;
309 } 309 }
310 scoped_ptr<gfx::Canvas> canvas(gfx::Canvas::CreateCanvas( 310 scoped_ptr<gfx::Canvas> canvas(gfx::Canvas::CreateCanvas(
311 draw_rect.width(), draw_rect.height(), false)); 311 draw_rect.width(), draw_rect.height(), false));
312 canvas->TranslateInt(-draw_rect.x(), -draw_rect.y()); 312 canvas->TranslateInt(-draw_rect.x(), -draw_rect.y());
313 delegate_->OnPaintLayer(canvas.get()); 313 delegate_->OnPaintLayer(canvas.get());
314 SetCanvas(*canvas->GetSkCanvas(), draw_rect.origin()); 314 SetCanvas(*canvas->GetSkCanvas(), draw_rect.origin());
315 } 315 }
316 316
317 void Layer::RecomputeHole() { 317 void Layer::ClearHoleRects() {
318 if (type_ == LAYER_HAS_NO_TEXTURE) 318 hole_rect_ = gfx::Rect();
319
320 for (size_t i = 0; i < children_.size(); i++)
321 children_[i]->ClearHoleRects();
322 }
323
324 void Layer::GeneratePreorderTraversal(
325 std::vector<ui::Layer*>* layer_traversal) {
326 if (!visible_)
319 return; 327 return;
320 328
321 // Reset to default. 329 if (fills_bounds_opaquely_ && type_ == LAYER_HAS_TEXTURE)
322 hole_rect_ = gfx::Rect(); 330 layer_traversal->push_back(this);
323 331
324 // Find the largest hole 332 for (size_t i = 0; i < children_.size(); i++)
325 for (size_t i = 0; i < children_.size(); ++i) { 333 children_[i]->GeneratePreorderTraversal(layer_traversal);
326 // Ignore non-opaque and hidden children. 334 }
327 if (!children_[i]->IsCompletelyOpaque() || !children_[i]->visible_)
328 continue;
329 335
330 // Ignore children that aren't rotated by multiples of 90 degrees. 336 void Layer::RecomputeHole() {
sky 2011/10/24 15:44:52 I don't like all the tree walking we do on any int
331 float degrees; 337 Layer* root_layer = this;
332 if (!InterpolatedTransform::FactorTRS(children_[i]->transform(), 338 while (root_layer->parent_) {
333 NULL, &degrees, NULL) || 339 root_layer = root_layer->parent_;
334 !IsApproximateMultilpleOf(degrees, 90.0f))
335 continue;
336
337 // The reason why we don't just take the bounds and apply the transform is
338 // that the bounds encodes a position, too, so the effective transformation
339 // matrix is actually different that the one reported. As well, the bounds
340 // will not necessarily be at the origin.
341 gfx::Rect candidate_hole(children_[i]->bounds_.size());
342 ui::Transform transform = children_[i]->transform();
343 transform.ConcatTranslate(static_cast<float>(children_[i]->bounds_.x()),
344 static_cast<float>(children_[i]->bounds_.y()));
345 transform.TransformRect(&candidate_hole);
346
347 // This layer might not contain the child (e.g., a portion of the child may
348 // be offscreen). Only the portion of the child that overlaps this layer is
349 // of any importance, so take the intersection.
350 candidate_hole = gfx::Rect(bounds().size()).Intersect(candidate_hole);
351
352 // Ensure we have the largest hole.
353 if (candidate_hole.size().GetArea() > hole_rect_.size().GetArea())
354 hole_rect_ = candidate_hole;
355 } 340 }
356 341
357 // Free up texture memory if the hole fills bounds of layer. 342 std::vector<ui::Layer*> layer_traversal;
358 if (!ShouldDraw() && !layer_updated_externally_) 343 root_layer->ClearHoleRects();
359 texture_ = NULL; 344 root_layer->GeneratePreorderTraversal(&layer_traversal);
360 }
361 345
362 bool Layer::IsCompletelyOpaque() const { 346 for (size_t i = 0; i < layer_traversal.size(); i++) {
363 return fills_bounds_opaquely() && GetCombinedOpacity() == 1.0f; 347 Layer* layer = layer_traversal[i];
348 gfx::Rect bounds = gfx::Rect(layer->bounds().size());
349 ui::Transform layer_transform;
350 layer->GetTransformRelativeTo(root_layer, &layer_transform);
351
352 // Iterate through layers which are after layer_traversal[i] in draw order
353 // and find the largest candidate hole.
354 for (size_t j = i + 1; j < layer_traversal.size(); j++) {
355 gfx::Rect candidate_hole = gfx::Rect(layer_traversal[j]->bounds().size());
356
357 // Compute transform to go from bounds of layer |j| to local bounds of lay er |i|.
sky 2011/10/24 15:44:52 This line is > 80 chars
358 ui::Transform candidate_hole_transform;
359 layer_traversal[j]->GetTransformRelativeTo(root_layer,
sky 2011/10/24 15:44:52 This is a lot of transform building. Rather than h
360 &candidate_hole_transform);
361 if (!layer_transform.Invert())
362 continue;
363 candidate_hole_transform.ConcatTransform(layer_transform);
364
365 // cannot punch a hole if the relative transform between the two layers
366 // is not multiple of 90.
367 float degrees;
368 if (!InterpolatedTransform::FactorTRS(candidate_hole_transform, NULL,
369 &degrees, NULL) || !IsApproximateMultilpleOf(degrees, 90.0f))
370 continue;
371
372 // can only punch a hole if the two layers have the same opacity.
373 if (layer->GetCombinedOpacity() !=
374 layer_traversal[j]->GetCombinedOpacity())
Ian Vollick 2011/10/22 01:06:03 Shouldn't we punch a hole only if layer_traversal[
375 continue;
376
377 candidate_hole_transform.TransformRect(&candidate_hole);
378 candidate_hole = candidate_hole.Intersect(bounds);
379
380 if (candidate_hole.size().GetArea() > layer->hole_rect().size().GetArea())
381 layer->set_hole_rect(candidate_hole);
382 }
383 // Free up texture memory if the hole fills bounds of layer.
384 if (!layer->ShouldDraw() && !layer_updated_externally())
385 layer->DropTexture();
386 }
364 } 387 }
365 388
366 // static 389 // static
367 void Layer::PunchHole(const gfx::Rect& rect, 390 void Layer::PunchHole(const gfx::Rect& rect,
368 const gfx::Rect& region_to_punch_out, 391 const gfx::Rect& region_to_punch_out,
369 std::vector<gfx::Rect>* sides) { 392 std::vector<gfx::Rect>* sides) {
370 gfx::Rect trimmed_rect = rect.Intersect(region_to_punch_out); 393 gfx::Rect trimmed_rect = rect.Intersect(region_to_punch_out);
371 394
372 if (trimmed_rect.IsEmpty()) { 395 if (trimmed_rect.IsEmpty()) {
373 sides->push_back(rect); 396 sides->push_back(rect);
(...skipping 18 matching lines...) Expand all
392 rect.right() - trimmed_rect.right(), 415 rect.right() - trimmed_rect.right(),
393 trimmed_rect.height())); 416 trimmed_rect.height()));
394 417
395 // Bottom (below the hole). 418 // Bottom (below the hole).
396 sides->push_back(gfx::Rect(rect.x(), 419 sides->push_back(gfx::Rect(rect.x(),
397 trimmed_rect.bottom(), 420 trimmed_rect.bottom(),
398 rect.width(), 421 rect.width(),
399 rect.bottom() - trimmed_rect.bottom())); 422 rect.bottom() - trimmed_rect.bottom()));
400 } 423 }
401 424
425 void Layer::DropTexture() {
426 if (!layer_updated_externally_)
427 texture_ = NULL;
428 }
429
402 void Layer::DropTextures() { 430 void Layer::DropTextures() {
403 if (!layer_updated_externally_) 431 if (!layer_updated_externally_)
404 texture_ = NULL; 432 texture_ = NULL;
405 for (size_t i = 0; i < children_.size(); ++i) 433 for (size_t i = 0; i < children_.size(); ++i)
406 children_[i]->DropTextures(); 434 children_[i]->DropTextures();
407 } 435 }
408 436
409 bool Layer::ConvertPointForAncestor(const Layer* ancestor, 437 bool Layer::ConvertPointForAncestor(const Layer* ancestor,
410 gfx::Point* point) const { 438 gfx::Point* point) const {
411 ui::Transform transform; 439 ui::Transform transform;
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
469 } 497 }
470 498
471 void Layer::SetTransformImmediately(const ui::Transform& transform) { 499 void Layer::SetTransformImmediately(const ui::Transform& transform) {
472 transform_ = transform; 500 transform_ = transform;
473 501
474 if (parent()) 502 if (parent())
475 parent()->RecomputeHole(); 503 parent()->RecomputeHole();
476 } 504 }
477 505
478 void Layer::SetOpacityImmediately(float opacity) { 506 void Layer::SetOpacityImmediately(float opacity) {
479 bool was_opaque = GetCombinedOpacity() == 1.0f;
480 opacity_ = opacity; 507 opacity_ = opacity;
481 bool is_opaque = GetCombinedOpacity() == 1.0f; 508 if (parent_)
482 509 parent_->RecomputeHole();
483 // If our opacity has changed we need to recompute our hole, our parent's hole
484 // and the holes of all our descendants.
485 if (was_opaque != is_opaque) {
486 if (parent_)
487 parent_->RecomputeHole();
488 std::queue<Layer*> to_process;
489 to_process.push(this);
490 while (!to_process.empty()) {
491 Layer* current = to_process.front();
492 to_process.pop();
493 current->RecomputeHole();
494 for (size_t i = 0; i < current->children_.size(); ++i)
495 to_process.push(current->children_.at(i));
496 }
497 }
498 } 510 }
499 511
500 void Layer::SetBoundsFromAnimator(const gfx::Rect& bounds) { 512 void Layer::SetBoundsFromAnimator(const gfx::Rect& bounds) {
501 SetBoundsImmediately(bounds); 513 SetBoundsImmediately(bounds);
502 } 514 }
503 515
504 void Layer::SetTransformFromAnimator(const Transform& transform) { 516 void Layer::SetTransformFromAnimator(const Transform& transform) {
505 SetTransformImmediately(transform); 517 SetTransformImmediately(transform);
506 } 518 }
507 519
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
575 result.append(", style=filled"); 587 result.append(", style=filled");
576 588
577 return result; 589 return result;
578 } 590 }
579 591
580 #endif 592 #endif
581 593
582 //////////////////////////////////////////////////////////////////////////////// 594 ////////////////////////////////////////////////////////////////////////////////
583 595
584 } // namespace ui 596 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698