OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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/command_line.h" | 9 #include "base/command_line.h" |
10 #include "base/debug/trace_event.h" | 10 #include "base/debug/trace_event.h" |
11 #include "base/logging.h" | 11 #include "base/logging.h" |
12 #include "base/memory/scoped_ptr.h" | 12 #include "base/memory/scoped_ptr.h" |
13 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebContentLa yer.h" | 13 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebContentLa yer.h" |
14 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebExternalT extureLayer.h" | 14 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebExternalT extureLayer.h" |
15 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebFloatPoin t.h" | 15 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebFloatPoin t.h" |
16 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebFloatRect .h" | 16 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebFloatRect .h" |
17 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebSize.h" | 17 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebSize.h" |
18 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebSolidColo rLayer.h" | |
18 #include "ui/base/animation/animation.h" | 19 #include "ui/base/animation/animation.h" |
19 #include "ui/gfx/canvas_skia.h" | 20 #include "ui/gfx/canvas_skia.h" |
20 #include "ui/gfx/compositor/compositor_switches.h" | 21 #include "ui/gfx/compositor/compositor_switches.h" |
21 #include "ui/gfx/compositor/layer_animator.h" | 22 #include "ui/gfx/compositor/layer_animator.h" |
22 #include "ui/gfx/interpolated_transform.h" | 23 #include "ui/gfx/interpolated_transform.h" |
23 #include "ui/gfx/point3.h" | 24 #include "ui/gfx/point3.h" |
24 | 25 |
25 #if defined(USE_WEBKIT_COMPOSITOR) | 26 #if defined(USE_WEBKIT_COMPOSITOR) |
26 #include "ui/gfx/compositor/compositor_cc.h" | 27 #include "ui/gfx/compositor/compositor_cc.h" |
27 #endif | 28 #endif |
28 | 29 |
29 namespace { | 30 namespace { |
30 | 31 |
31 const float EPSILON = 1e-3f; | 32 const float EPSILON = 1e-3f; |
32 | 33 |
33 bool IsApproximateMultilpleOf(float value, float base) { | 34 bool IsApproximateMultipleOf(float value, float base) { |
34 float remainder = fmod(fabs(value), base); | 35 float remainder = fmod(fabs(value), base); |
35 return remainder < EPSILON || base - remainder < EPSILON; | 36 return remainder < EPSILON || base - remainder < EPSILON; |
36 } | 37 } |
37 | 38 |
38 const ui::Layer* GetRoot(const ui::Layer* layer) { | 39 const ui::Layer* GetRoot(const ui::Layer* layer) { |
39 return layer->parent() ? GetRoot(layer->parent()) : layer; | 40 return layer->parent() ? GetRoot(layer->parent()) : layer; |
40 } | 41 } |
41 | 42 |
42 } // namespace | 43 } // namespace |
43 | 44 |
44 namespace ui { | 45 namespace ui { |
45 | 46 |
46 Layer::Layer() | 47 Layer::Layer() |
47 : type_(LAYER_HAS_TEXTURE), | 48 : type_(LAYER_TEXTURED), |
48 compositor_(NULL), | 49 compositor_(NULL), |
49 parent_(NULL), | 50 parent_(NULL), |
50 visible_(true), | 51 visible_(true), |
51 fills_bounds_opaquely_(true), | 52 fills_bounds_opaquely_(true), |
52 recompute_hole_(false), | 53 recompute_hole_(false), |
53 layer_updated_externally_(false), | 54 layer_updated_externally_(false), |
54 opacity_(1.0f), | 55 opacity_(1.0f), |
55 delegate_(NULL) { | 56 delegate_(NULL) { |
56 #if defined(USE_WEBKIT_COMPOSITOR) | 57 #if defined(USE_WEBKIT_COMPOSITOR) |
57 CreateWebLayer(); | 58 CreateWebLayer(); |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
216 } | 217 } |
217 | 218 |
218 bool Layer::IsDrawn() const { | 219 bool Layer::IsDrawn() const { |
219 const Layer* layer = this; | 220 const Layer* layer = this; |
220 while (layer && layer->visible_) | 221 while (layer && layer->visible_) |
221 layer = layer->parent_; | 222 layer = layer->parent_; |
222 return layer == NULL; | 223 return layer == NULL; |
223 } | 224 } |
224 | 225 |
225 bool Layer::ShouldDraw() const { | 226 bool Layer::ShouldDraw() const { |
226 return type_ == LAYER_HAS_TEXTURE && GetCombinedOpacity() > 0.0f && | 227 return type_ != LAYER_NOT_DRAWN && GetCombinedOpacity() > 0.0f && |
227 !hole_rect_.Contains(gfx::Rect(gfx::Point(0, 0), bounds_.size())); | 228 !hole_rect_.Contains(gfx::Rect(gfx::Point(0, 0), bounds_.size())); |
228 } | 229 } |
229 | 230 |
230 // static | 231 // static |
231 void Layer::ConvertPointToLayer(const Layer* source, | 232 void Layer::ConvertPointToLayer(const Layer* source, |
232 const Layer* target, | 233 const Layer* target, |
233 gfx::Point* point) { | 234 gfx::Point* point) { |
234 if (source == target) | 235 if (source == target) |
235 return; | 236 return; |
236 | 237 |
237 const Layer* root_layer = GetRoot(source); | 238 const Layer* root_layer = GetRoot(source); |
238 CHECK_EQ(root_layer, GetRoot(target)); | 239 CHECK_EQ(root_layer, GetRoot(target)); |
239 | 240 |
240 if (source != root_layer) | 241 if (source != root_layer) |
241 source->ConvertPointForAncestor(root_layer, point); | 242 source->ConvertPointForAncestor(root_layer, point); |
242 if (target != root_layer) | 243 if (target != root_layer) |
243 target->ConvertPointFromAncestor(root_layer, point); | 244 target->ConvertPointFromAncestor(root_layer, point); |
244 } | 245 } |
245 | 246 |
246 void Layer::SetFillsBoundsOpaquely(bool fills_bounds_opaquely) { | 247 void Layer::SetFillsBoundsOpaquely(bool fills_bounds_opaquely) { |
248 if (type_ == LAYER_SOLID_COLOR) | |
249 return; | |
piman
2012/01/26 02:16:07
Mmh, I feel like we should setOpaque somewhere. I'
Daniel Erat
2012/01/26 18:10:26
Thanks, makes sense. I've added a call to setOpaq
| |
250 | |
247 if (fills_bounds_opaquely_ == fills_bounds_opaquely) | 251 if (fills_bounds_opaquely_ == fills_bounds_opaquely) |
248 return; | 252 return; |
249 | 253 |
250 fills_bounds_opaquely_ = fills_bounds_opaquely; | 254 fills_bounds_opaquely_ = fills_bounds_opaquely; |
251 | 255 |
252 SetNeedsToRecomputeHole(); | 256 SetNeedsToRecomputeHole(); |
253 #if defined(USE_WEBKIT_COMPOSITOR) | 257 #if defined(USE_WEBKIT_COMPOSITOR) |
254 web_layer_.setOpaque(fills_bounds_opaquely); | 258 web_layer_.setOpaque(fills_bounds_opaquely); |
255 RecomputeDebugBorderColor(); | 259 RecomputeDebugBorderColor(); |
256 #endif | 260 #endif |
257 } | 261 } |
258 | 262 |
259 void Layer::SetExternalTexture(ui::Texture* texture) { | 263 void Layer::SetExternalTexture(ui::Texture* texture) { |
264 DCHECK_EQ(type_, LAYER_TEXTURED); | |
260 layer_updated_externally_ = !!texture; | 265 layer_updated_externally_ = !!texture; |
261 texture_ = texture; | 266 texture_ = texture; |
262 #if defined(USE_WEBKIT_COMPOSITOR) | 267 #if defined(USE_WEBKIT_COMPOSITOR) |
263 if (web_layer_is_accelerated_ != layer_updated_externally_) { | 268 if (web_layer_is_accelerated_ != layer_updated_externally_) { |
264 // Switch to a different type of layer. | 269 // Switch to a different type of layer. |
265 web_layer_.removeAllChildren(); | 270 web_layer_.removeAllChildren(); |
266 WebKit::WebLayer new_layer; | 271 WebKit::WebLayer new_layer; |
267 if (layer_updated_externally_) | 272 if (layer_updated_externally_) |
268 new_layer = WebKit::WebExternalTextureLayer::create(); | 273 new_layer = WebKit::WebExternalTextureLayer::create(); |
269 else | 274 else |
(...skipping 23 matching lines...) Expand all Loading... | |
293 texture_layer.setFlipped(texture_cc->flipped()); | 298 texture_layer.setFlipped(texture_cc->flipped()); |
294 } | 299 } |
295 RecomputeDrawsContentAndUVRect(); | 300 RecomputeDrawsContentAndUVRect(); |
296 #endif | 301 #endif |
297 } | 302 } |
298 | 303 |
299 void Layer::SetCanvas(const SkCanvas& canvas, const gfx::Point& origin) { | 304 void Layer::SetCanvas(const SkCanvas& canvas, const gfx::Point& origin) { |
300 #if defined(USE_WEBKIT_COMPOSITOR) | 305 #if defined(USE_WEBKIT_COMPOSITOR) |
301 NOTREACHED(); | 306 NOTREACHED(); |
302 #else | 307 #else |
303 DCHECK_EQ(type_, LAYER_HAS_TEXTURE); | 308 DCHECK_EQ(type_, LAYER_TEXTURED); |
304 | 309 |
305 if (!texture_.get()) | 310 if (!texture_.get()) |
306 texture_ = GetCompositor()->CreateTexture(); | 311 texture_ = GetCompositor()->CreateTexture(); |
307 | 312 |
308 texture_->SetCanvas(canvas, origin, bounds_.size()); | 313 texture_->SetCanvas(canvas, origin, bounds_.size()); |
309 invalid_rect_ = gfx::Rect(); | 314 invalid_rect_ = gfx::Rect(); |
310 #endif | 315 #endif |
311 } | 316 } |
312 | 317 |
318 void Layer::SetColor(SkColor color) { | |
319 DCHECK_EQ(type_, LAYER_SOLID_COLOR); | |
320 #if defined(USE_WEBKIT_COMPOSITOR) | |
321 // WebColor is equivalent to SkColor, per WebColor.h. | |
322 web_layer_.to<WebKit::WebSolidColorLayer>().setBackgroundColor( | |
323 static_cast<WebKit::WebColor>(color)); | |
324 #endif | |
325 } | |
326 | |
313 void Layer::SchedulePaint(const gfx::Rect& invalid_rect) { | 327 void Layer::SchedulePaint(const gfx::Rect& invalid_rect) { |
314 #if defined(USE_WEBKIT_COMPOSITOR) | 328 #if defined(USE_WEBKIT_COMPOSITOR) |
329 if (type_ == LAYER_SOLID_COLOR) | |
330 return; | |
331 | |
315 WebKit::WebFloatRect web_rect( | 332 WebKit::WebFloatRect web_rect( |
316 invalid_rect.x(), | 333 invalid_rect.x(), |
317 invalid_rect.y(), | 334 invalid_rect.y(), |
318 invalid_rect.width(), | 335 invalid_rect.width(), |
319 invalid_rect.height()); | 336 invalid_rect.height()); |
320 if (!web_layer_is_accelerated_) | 337 if (!web_layer_is_accelerated_) |
321 web_layer_.to<WebKit::WebContentLayer>().invalidateRect(web_rect); | 338 web_layer_.to<WebKit::WebContentLayer>().invalidateRect(web_rect); |
322 else | 339 else |
323 web_layer_.to<WebKit::WebExternalTextureLayer>().invalidateRect(web_rect); | 340 web_layer_.to<WebKit::WebExternalTextureLayer>().invalidateRect(web_rect); |
324 #else | 341 #else |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
499 return; | 516 return; |
500 | 517 |
501 ui::Transform current_transform; | 518 ui::Transform current_transform; |
502 if (transform().HasChange()) | 519 if (transform().HasChange()) |
503 current_transform.ConcatTransform(transform()); | 520 current_transform.ConcatTransform(transform()); |
504 current_transform.ConcatTranslate( | 521 current_transform.ConcatTranslate( |
505 static_cast<float>(bounds().x()), | 522 static_cast<float>(bounds().x()), |
506 static_cast<float>(bounds().y())); | 523 static_cast<float>(bounds().y())); |
507 current_transform.ConcatTransform(parent_transform); | 524 current_transform.ConcatTransform(parent_transform); |
508 | 525 |
509 if (fills_bounds_opaquely_ && type_ == LAYER_HAS_TEXTURE) { | 526 if (fills_bounds_opaquely_ && type_ != LAYER_NOT_DRAWN) { |
510 LayerProperties properties; | 527 LayerProperties properties; |
511 properties.layer = this; | 528 properties.layer = this; |
512 properties.transform_relative_to_root = current_transform; | 529 properties.transform_relative_to_root = current_transform; |
513 traversal->push_back(properties); | 530 traversal->push_back(properties); |
514 } | 531 } |
515 | 532 |
516 for (size_t i = 0; i < children_.size(); i++) | 533 for (size_t i = 0; i < children_.size(); i++) |
517 children_[i]->GetLayerProperties(current_transform, traversal); | 534 children_[i]->GetLayerProperties(current_transform, traversal); |
518 } | 535 } |
519 | 536 |
(...skipping 24 matching lines...) Expand all Loading... | |
544 if (!traversal[i].transform_relative_to_root.GetInverse(&inverted)) | 561 if (!traversal[i].transform_relative_to_root.GetInverse(&inverted)) |
545 continue; | 562 continue; |
546 | 563 |
547 candidate_hole_transform.ConcatTransform(inverted); | 564 candidate_hole_transform.ConcatTransform(inverted); |
548 | 565 |
549 // cannot punch a hole if the relative transform between the two layers | 566 // cannot punch a hole if the relative transform between the two layers |
550 // is not multiple of 90. | 567 // is not multiple of 90. |
551 float degrees; | 568 float degrees; |
552 gfx::Point p; | 569 gfx::Point p; |
553 if (!InterpolatedTransform::FactorTRS(candidate_hole_transform, &p, | 570 if (!InterpolatedTransform::FactorTRS(candidate_hole_transform, &p, |
554 °rees, NULL) || !IsApproximateMultilpleOf(degrees, 90.0f)) | 571 °rees, NULL) || !IsApproximateMultipleOf(degrees, 90.0f)) |
555 continue; | 572 continue; |
556 | 573 |
557 candidate_hole_transform.TransformRect(&candidate_hole); | 574 candidate_hole_transform.TransformRect(&candidate_hole); |
558 candidate_hole = candidate_hole.Intersect(bounds); | 575 candidate_hole = candidate_hole.Intersect(bounds); |
559 | 576 |
560 if (candidate_hole.size().GetArea() > | 577 if (candidate_hole.size().GetArea() > |
561 layer->hole_rect().size().GetArea()) { | 578 layer->hole_rect().size().GetArea()) { |
562 layer->set_hole_rect(candidate_hole); | 579 layer->set_hole_rect(candidate_hole); |
563 } | 580 } |
564 } | 581 } |
565 // Free up texture memory if the hole fills bounds of layer. | 582 // Free up texture memory if the hole fills bounds of layer. |
566 if (!layer->ShouldDraw() && !layer_updated_externally()) | 583 if (!layer->ShouldDraw() && !layer_updated_externally()) |
567 layer->DropTexture(); | 584 layer->DropTexture(); |
568 | 585 |
569 #if defined(USE_WEBKIT_COMPOSITOR) | 586 #if defined(USE_WEBKIT_COMPOSITOR) |
570 RecomputeDrawsContentAndUVRect(); | 587 RecomputeDrawsContentAndUVRect(); |
571 #endif | 588 #endif |
572 } | 589 } |
573 | 590 |
574 recompute_hole_ = false; | 591 recompute_hole_ = false; |
575 } | 592 } |
576 | 593 |
577 // static | 594 // static |
578 void Layer::PunchHole(const gfx::Rect& rect, | 595 void Layer::PunchHole(const gfx::Rect& rect, |
579 const gfx::Rect& region_to_punch_out, | 596 const gfx::Rect& region_to_punch_out, |
580 std::vector<gfx::Rect>* sides) { | 597 std::vector<gfx::Rect>* sides) { |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
724 const Transform& Layer::GetTransformForAnimation() const { | 741 const Transform& Layer::GetTransformForAnimation() const { |
725 return transform(); | 742 return transform(); |
726 } | 743 } |
727 | 744 |
728 float Layer::GetOpacityForAnimation() const { | 745 float Layer::GetOpacityForAnimation() const { |
729 return opacity(); | 746 return opacity(); |
730 } | 747 } |
731 | 748 |
732 #if defined(USE_WEBKIT_COMPOSITOR) | 749 #if defined(USE_WEBKIT_COMPOSITOR) |
733 void Layer::CreateWebLayer() { | 750 void Layer::CreateWebLayer() { |
734 web_layer_ = WebKit::WebContentLayer::create(this); | 751 if (type_ == LAYER_SOLID_COLOR) |
752 web_layer_ = WebKit::WebSolidColorLayer::create(); | |
753 else | |
754 web_layer_ = WebKit::WebContentLayer::create(this); | |
735 web_layer_.setAnchorPoint(WebKit::WebFloatPoint(0.f, 0.f)); | 755 web_layer_.setAnchorPoint(WebKit::WebFloatPoint(0.f, 0.f)); |
736 web_layer_.setOpaque(true); | 756 web_layer_.setOpaque(true); |
737 web_layer_is_accelerated_ = false; | 757 web_layer_is_accelerated_ = false; |
738 show_debug_borders_ = CommandLine::ForCurrentProcess()->HasSwitch( | 758 show_debug_borders_ = CommandLine::ForCurrentProcess()->HasSwitch( |
739 switches::kUIShowLayerBorders); | 759 switches::kUIShowLayerBorders); |
740 web_layer_.setDebugBorderWidth(show_debug_borders_ ? 2 : 0); | 760 web_layer_.setDebugBorderWidth(show_debug_borders_ ? 2 : 0); |
741 RecomputeDrawsContentAndUVRect(); | 761 RecomputeDrawsContentAndUVRect(); |
742 RecomputeDebugBorderColor(); | 762 RecomputeDebugBorderColor(); |
743 } | 763 } |
744 | 764 |
745 void Layer::RecomputeTransform() { | 765 void Layer::RecomputeTransform() { |
746 ui::Transform transform = transform_; | 766 ui::Transform transform = transform_; |
747 transform.ConcatTranslate(bounds_.x(), bounds_.y()); | 767 transform.ConcatTranslate(bounds_.x(), bounds_.y()); |
748 web_layer_.setTransform(transform.matrix()); | 768 web_layer_.setTransform(transform.matrix()); |
749 } | 769 } |
750 | 770 |
751 void Layer::RecomputeDrawsContentAndUVRect() { | 771 void Layer::RecomputeDrawsContentAndUVRect() { |
752 DCHECK(!web_layer_.isNull()); | 772 DCHECK(!web_layer_.isNull()); |
753 bool should_draw = type_ == LAYER_HAS_TEXTURE && | 773 bool should_draw = type_ != LAYER_NOT_DRAWN && |
754 !hole_rect_.Contains(gfx::Rect(gfx::Point(0, 0), bounds_.size())); | 774 !hole_rect_.Contains(gfx::Rect(gfx::Point(0, 0), bounds_.size())); |
775 | |
755 if (!web_layer_is_accelerated_) { | 776 if (!web_layer_is_accelerated_) { |
756 web_layer_.to<WebKit::WebContentLayer>().setDrawsContent(should_draw); | 777 if (type_ != LAYER_SOLID_COLOR) |
778 web_layer_.to<WebKit::WebContentLayer>().setDrawsContent(should_draw); | |
757 web_layer_.setBounds(bounds_.size()); | 779 web_layer_.setBounds(bounds_.size()); |
758 } else { | 780 } else { |
759 DCHECK(texture_); | 781 DCHECK(texture_); |
760 TextureCC* texture_cc = static_cast<TextureCC*>(texture_.get()); | 782 TextureCC* texture_cc = static_cast<TextureCC*>(texture_.get()); |
761 unsigned int texture_id = texture_cc->texture_id(); | 783 unsigned int texture_id = texture_cc->texture_id(); |
762 WebKit::WebExternalTextureLayer texture_layer = | 784 WebKit::WebExternalTextureLayer texture_layer = |
763 web_layer_.to<WebKit::WebExternalTextureLayer>(); | 785 web_layer_.to<WebKit::WebExternalTextureLayer>(); |
764 texture_layer.setTextureId(should_draw ? texture_id : 0); | 786 texture_layer.setTextureId(should_draw ? texture_id : 0); |
765 gfx::Size size(std::min(bounds_.width(), texture_cc->size().width()), | 787 gfx::Size size(std::min(bounds_.width(), texture_cc->size().width()), |
766 std::min(bounds_.height(), texture_cc->size().height())); | 788 std::min(bounds_.height(), texture_cc->size().height())); |
(...skipping 13 matching lines...) Expand all Loading... | |
780 unsigned int color = 0xFF000000; | 802 unsigned int color = 0xFF000000; |
781 color |= web_layer_is_accelerated_ ? 0x0000FF00 : 0x00FF0000; | 803 color |= web_layer_is_accelerated_ ? 0x0000FF00 : 0x00FF0000; |
782 bool opaque = fills_bounds_opaquely_ && (GetCombinedOpacity() == 1.f); | 804 bool opaque = fills_bounds_opaquely_ && (GetCombinedOpacity() == 1.f); |
783 if (!opaque) | 805 if (!opaque) |
784 color |= 0xFF; | 806 color |= 0xFF; |
785 web_layer_.setDebugBorderColor(color); | 807 web_layer_.setDebugBorderColor(color); |
786 } | 808 } |
787 #endif | 809 #endif |
788 | 810 |
789 } // namespace ui | 811 } // namespace ui |
OLD | NEW |