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

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

Issue 9288053: Remove old (pre-webkit) compositor (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix test Created 8 years, 11 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
« no previous file with comments | « ui/gfx/compositor/layer.h ('k') | ui/gfx/compositor/layer_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "ui/base/animation/animation.h" 18 #include "ui/base/animation/animation.h"
19 #include "ui/gfx/canvas_skia.h" 19 #include "ui/gfx/canvas_skia.h"
20 #include "ui/gfx/compositor/compositor_switches.h" 20 #include "ui/gfx/compositor/compositor_switches.h"
21 #include "ui/gfx/compositor/layer_animator.h" 21 #include "ui/gfx/compositor/layer_animator.h"
22 #include "ui/gfx/interpolated_transform.h" 22 #include "ui/gfx/interpolated_transform.h"
23 #include "ui/gfx/point3.h" 23 #include "ui/gfx/point3.h"
24 24
25 #if defined(USE_WEBKIT_COMPOSITOR)
26 #include "ui/gfx/compositor/compositor_cc.h" 25 #include "ui/gfx/compositor/compositor_cc.h"
27 #endif
28 26
29 namespace { 27 namespace {
30 28
31 const float EPSILON = 1e-3f; 29 const float EPSILON = 1e-3f;
32 30
33 bool IsApproximateMultilpleOf(float value, float base) { 31 bool IsApproximateMultilpleOf(float value, float base) {
34 float remainder = fmod(fabs(value), base); 32 float remainder = fmod(fabs(value), base);
35 return remainder < EPSILON || base - remainder < EPSILON; 33 return remainder < EPSILON || base - remainder < EPSILON;
36 } 34 }
37 35
38 const ui::Layer* GetRoot(const ui::Layer* layer) { 36 const ui::Layer* GetRoot(const ui::Layer* layer) {
39 return layer->parent() ? GetRoot(layer->parent()) : layer; 37 return layer->parent() ? GetRoot(layer->parent()) : layer;
40 } 38 }
41 39
42 } // namespace 40 } // namespace
43 41
44 namespace ui { 42 namespace ui {
45 43
46 Layer::Layer() 44 Layer::Layer()
47 : type_(LAYER_HAS_TEXTURE), 45 : type_(LAYER_HAS_TEXTURE),
48 compositor_(NULL), 46 compositor_(NULL),
49 parent_(NULL), 47 parent_(NULL),
50 visible_(true), 48 visible_(true),
51 fills_bounds_opaquely_(true), 49 fills_bounds_opaquely_(true),
52 recompute_hole_(false),
53 layer_updated_externally_(false), 50 layer_updated_externally_(false),
54 opacity_(1.0f), 51 opacity_(1.0f),
55 delegate_(NULL) { 52 delegate_(NULL) {
56 #if defined(USE_WEBKIT_COMPOSITOR)
57 CreateWebLayer(); 53 CreateWebLayer();
58 #endif
59 } 54 }
60 55
61 Layer::Layer(LayerType type) 56 Layer::Layer(LayerType type)
62 : type_(type), 57 : type_(type),
63 compositor_(NULL), 58 compositor_(NULL),
64 parent_(NULL), 59 parent_(NULL),
65 visible_(true), 60 visible_(true),
66 fills_bounds_opaquely_(true), 61 fills_bounds_opaquely_(true),
67 recompute_hole_(false),
68 layer_updated_externally_(false), 62 layer_updated_externally_(false),
69 opacity_(1.0f), 63 opacity_(1.0f),
70 delegate_(NULL) { 64 delegate_(NULL) {
71 #if defined(USE_WEBKIT_COMPOSITOR)
72 CreateWebLayer(); 65 CreateWebLayer();
73 #endif
74 } 66 }
75 67
76 Layer::~Layer() { 68 Layer::~Layer() {
77 if (compositor_) 69 if (compositor_)
78 compositor_->SetRootLayer(NULL); 70 compositor_->SetRootLayer(NULL);
79 if (parent_) 71 if (parent_)
80 parent_->Remove(this); 72 parent_->Remove(this);
81 for (size_t i = 0; i < children_.size(); ++i) 73 for (size_t i = 0; i < children_.size(); ++i)
82 children_[i]->parent_ = NULL; 74 children_[i]->parent_ = NULL;
83 #if defined(USE_WEBKIT_COMPOSITOR)
84 web_layer_.removeFromParent(); 75 web_layer_.removeFromParent();
85 #endif
86 } 76 }
87 77
88 Compositor* Layer::GetCompositor() { 78 Compositor* Layer::GetCompositor() {
89 return GetRoot(this)->compositor_; 79 return GetRoot(this)->compositor_;
90 } 80 }
91 81
92 void Layer::SetCompositor(Compositor* compositor) { 82 void Layer::SetCompositor(Compositor* compositor) {
93 // This function must only be called to set the compositor on the root layer, 83 // This function must only be called to set the compositor on the root layer,
94 // or to reset it. 84 // or to reset it.
95 DCHECK(!compositor || !compositor_); 85 DCHECK(!compositor || !compositor_);
96 DCHECK(!compositor || compositor->root_layer() == this); 86 DCHECK(!compositor || compositor->root_layer() == this);
97 DCHECK(!parent_); 87 DCHECK(!parent_);
98 compositor_ = compositor; 88 compositor_ = compositor;
99 } 89 }
100 90
101 void Layer::Add(Layer* child) { 91 void Layer::Add(Layer* child) {
102 DCHECK(!child->compositor_); 92 DCHECK(!child->compositor_);
103 if (child->parent_) 93 if (child->parent_)
104 child->parent_->Remove(child); 94 child->parent_->Remove(child);
105 child->parent_ = this; 95 child->parent_ = this;
106 children_.push_back(child); 96 children_.push_back(child);
107 #if defined(USE_WEBKIT_COMPOSITOR)
108 web_layer_.addChild(child->web_layer_); 97 web_layer_.addChild(child->web_layer_);
109 #endif
110
111 SetNeedsToRecomputeHole();
112 } 98 }
113 99
114 void Layer::Remove(Layer* child) { 100 void Layer::Remove(Layer* child) {
115 std::vector<Layer*>::iterator i = 101 std::vector<Layer*>::iterator i =
116 std::find(children_.begin(), children_.end(), child); 102 std::find(children_.begin(), children_.end(), child);
117 DCHECK(i != children_.end()); 103 DCHECK(i != children_.end());
118 children_.erase(i); 104 children_.erase(i);
119 child->parent_ = NULL; 105 child->parent_ = NULL;
120 #if defined(USE_WEBKIT_COMPOSITOR)
121 child->web_layer_.removeFromParent(); 106 child->web_layer_.removeFromParent();
122 #endif
123
124 SetNeedsToRecomputeHole();
125
126 child->DropTextures();
127 } 107 }
128 108
129 void Layer::StackAtTop(Layer* child) { 109 void Layer::StackAtTop(Layer* child) {
130 if (children_.size() <= 1 || child == children_.back()) 110 if (children_.size() <= 1 || child == children_.back())
131 return; // Already in front. 111 return; // Already in front.
132 StackAbove(child, children_.back()); 112 StackAbove(child, children_.back());
133 } 113 }
134 114
135 void Layer::StackAbove(Layer* child, Layer* other) { 115 void Layer::StackAbove(Layer* child, Layer* other) {
136 StackRelativeTo(child, other, true); 116 StackRelativeTo(child, other, true);
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
193 float Layer::GetTargetOpacity() const { 173 float Layer::GetTargetOpacity() const {
194 if (animator_.get() && animator_->is_animating()) 174 if (animator_.get() && animator_->is_animating())
195 return animator_->GetTargetOpacity(); 175 return animator_->GetTargetOpacity();
196 return opacity_; 176 return opacity_;
197 } 177 }
198 178
199 void Layer::SetVisible(bool visible) { 179 void Layer::SetVisible(bool visible) {
200 if (visible_ == visible) 180 if (visible_ == visible)
201 return; 181 return;
202 182
203 bool was_drawn = IsDrawn();
204 visible_ = visible; 183 visible_ = visible;
205 #if defined(USE_WEBKIT_COMPOSITOR)
206 // TODO(piman): Expose a visibility flag on WebLayer. 184 // TODO(piman): Expose a visibility flag on WebLayer.
207 web_layer_.setOpacity(visible_ ? opacity_ : 0.f); 185 web_layer_.setOpacity(visible_ ? opacity_ : 0.f);
208 #endif
209 bool is_drawn = IsDrawn();
210 if (was_drawn == is_drawn)
211 return;
212
213 if (!is_drawn)
214 DropTextures();
215 SetNeedsToRecomputeHole();
216 } 186 }
217 187
218 bool Layer::IsDrawn() const { 188 bool Layer::IsDrawn() const {
219 const Layer* layer = this; 189 const Layer* layer = this;
220 while (layer && layer->visible_) 190 while (layer && layer->visible_)
221 layer = layer->parent_; 191 layer = layer->parent_;
222 return layer == NULL; 192 return layer == NULL;
223 } 193 }
224 194
225 bool Layer::ShouldDraw() const { 195 bool Layer::ShouldDraw() const {
226 return type_ == LAYER_HAS_TEXTURE && GetCombinedOpacity() > 0.0f && 196 return type_ == LAYER_HAS_TEXTURE && GetCombinedOpacity() > 0.0f;
227 !hole_rect_.Contains(gfx::Rect(gfx::Point(0, 0), bounds_.size()));
228 } 197 }
229 198
230 // static 199 // static
231 void Layer::ConvertPointToLayer(const Layer* source, 200 void Layer::ConvertPointToLayer(const Layer* source,
232 const Layer* target, 201 const Layer* target,
233 gfx::Point* point) { 202 gfx::Point* point) {
234 if (source == target) 203 if (source == target)
235 return; 204 return;
236 205
237 const Layer* root_layer = GetRoot(source); 206 const Layer* root_layer = GetRoot(source);
238 CHECK_EQ(root_layer, GetRoot(target)); 207 CHECK_EQ(root_layer, GetRoot(target));
239 208
240 if (source != root_layer) 209 if (source != root_layer)
241 source->ConvertPointForAncestor(root_layer, point); 210 source->ConvertPointForAncestor(root_layer, point);
242 if (target != root_layer) 211 if (target != root_layer)
243 target->ConvertPointFromAncestor(root_layer, point); 212 target->ConvertPointFromAncestor(root_layer, point);
244 } 213 }
245 214
246 void Layer::SetFillsBoundsOpaquely(bool fills_bounds_opaquely) { 215 void Layer::SetFillsBoundsOpaquely(bool fills_bounds_opaquely) {
247 if (fills_bounds_opaquely_ == fills_bounds_opaquely) 216 if (fills_bounds_opaquely_ == fills_bounds_opaquely)
248 return; 217 return;
249 218
250 fills_bounds_opaquely_ = fills_bounds_opaquely; 219 fills_bounds_opaquely_ = fills_bounds_opaquely;
251 220
252 SetNeedsToRecomputeHole();
253 #if defined(USE_WEBKIT_COMPOSITOR)
254 web_layer_.setOpaque(fills_bounds_opaquely); 221 web_layer_.setOpaque(fills_bounds_opaquely);
255 RecomputeDebugBorderColor(); 222 RecomputeDebugBorderColor();
256 #endif
257 } 223 }
258 224
259 void Layer::SetExternalTexture(ui::Texture* texture) { 225 void Layer::SetExternalTexture(ui::Texture* texture) {
260 layer_updated_externally_ = !!texture; 226 layer_updated_externally_ = !!texture;
261 texture_ = texture; 227 texture_ = texture;
262 #if defined(USE_WEBKIT_COMPOSITOR)
263 if (web_layer_is_accelerated_ != layer_updated_externally_) { 228 if (web_layer_is_accelerated_ != layer_updated_externally_) {
264 // Switch to a different type of layer. 229 // Switch to a different type of layer.
265 web_layer_.removeAllChildren(); 230 web_layer_.removeAllChildren();
266 WebKit::WebLayer new_layer; 231 WebKit::WebLayer new_layer;
267 if (layer_updated_externally_) 232 if (layer_updated_externally_)
268 new_layer = WebKit::WebExternalTextureLayer::create(); 233 new_layer = WebKit::WebExternalTextureLayer::create();
269 else 234 else
270 new_layer = WebKit::WebContentLayer::create(this); 235 new_layer = WebKit::WebContentLayer::create(this);
271 if (parent_) { 236 if (parent_) {
272 DCHECK(!parent_->web_layer_.isNull()); 237 DCHECK(!parent_->web_layer_.isNull());
(...skipping 13 matching lines...) Expand all
286 RecomputeDebugBorderColor(); 251 RecomputeDebugBorderColor();
287 } 252 }
288 if (texture) { 253 if (texture) {
289 TextureCC* texture_cc = static_cast<TextureCC*>(texture); 254 TextureCC* texture_cc = static_cast<TextureCC*>(texture);
290 texture_cc->Update(); 255 texture_cc->Update();
291 WebKit::WebExternalTextureLayer texture_layer = 256 WebKit::WebExternalTextureLayer texture_layer =
292 web_layer_.to<WebKit::WebExternalTextureLayer>(); 257 web_layer_.to<WebKit::WebExternalTextureLayer>();
293 texture_layer.setFlipped(texture_cc->flipped()); 258 texture_layer.setFlipped(texture_cc->flipped());
294 } 259 }
295 RecomputeDrawsContentAndUVRect(); 260 RecomputeDrawsContentAndUVRect();
296 #endif
297 } 261 }
298 262
299 void Layer::SetCanvas(const SkCanvas& canvas, const gfx::Point& origin) { 263 void Layer::SetCanvas(const SkCanvas& canvas, const gfx::Point& origin) {
300 #if defined(USE_WEBKIT_COMPOSITOR)
301 NOTREACHED(); 264 NOTREACHED();
302 #else
303 DCHECK_EQ(type_, LAYER_HAS_TEXTURE);
304
305 if (!texture_.get())
306 texture_ = GetCompositor()->CreateTexture();
307
308 texture_->SetCanvas(canvas, origin, bounds_.size());
309 invalid_rect_ = gfx::Rect();
310 #endif
311 } 265 }
312 266
313 void Layer::SchedulePaint(const gfx::Rect& invalid_rect) { 267 void Layer::SchedulePaint(const gfx::Rect& invalid_rect) {
314 #if defined(USE_WEBKIT_COMPOSITOR)
315 WebKit::WebFloatRect web_rect( 268 WebKit::WebFloatRect web_rect(
316 invalid_rect.x(), 269 invalid_rect.x(),
317 invalid_rect.y(), 270 invalid_rect.y(),
318 invalid_rect.width(), 271 invalid_rect.width(),
319 invalid_rect.height()); 272 invalid_rect.height());
320 if (!web_layer_is_accelerated_) 273 if (!web_layer_is_accelerated_)
321 web_layer_.to<WebKit::WebContentLayer>().invalidateRect(web_rect); 274 web_layer_.to<WebKit::WebContentLayer>().invalidateRect(web_rect);
322 else 275 else
323 web_layer_.to<WebKit::WebExternalTextureLayer>().invalidateRect(web_rect); 276 web_layer_.to<WebKit::WebExternalTextureLayer>().invalidateRect(web_rect);
324 #else
325 invalid_rect_ = invalid_rect_.Union(invalid_rect);
326 ScheduleDraw();
327 #endif
328 } 277 }
329 278
330 void Layer::ScheduleDraw() { 279 void Layer::ScheduleDraw() {
331 Compositor* compositor = GetCompositor(); 280 Compositor* compositor = GetCompositor();
332 if (compositor) 281 if (compositor)
333 compositor->ScheduleDraw(); 282 compositor->ScheduleDraw();
334 } 283 }
335 284
336 void Layer::Draw() {
337 TRACE_EVENT0("ui", "Layer::Draw");
338 #if defined(USE_WEBKIT_COMPOSITOR)
339 NOTREACHED();
340 #else
341 DCHECK(GetCompositor());
342
343 if (recompute_hole_ && !parent_)
344 RecomputeHole();
345
346 if (!ShouldDraw())
347 return;
348
349 UpdateLayerCanvas();
350
351 // Layer drew nothing, no texture was created.
352 if (!texture_.get())
353 return;
354
355 ui::TextureDrawParams texture_draw_params;
356 for (Layer* layer = this; layer; layer = layer->parent_) {
357 texture_draw_params.transform.ConcatTransform(layer->transform_);
358 texture_draw_params.transform.ConcatTranslate(
359 static_cast<float>(layer->bounds_.x()),
360 static_cast<float>(layer->bounds_.y()));
361 }
362
363 const float combined_opacity = GetCombinedOpacity();
364
365 // Only blend for transparent child layers (and when we're forcing
366 // transparency). The root layer will clobber the cleared bg.
367 const bool is_root = parent_ == NULL;
368 const bool forcing_transparency = combined_opacity < 1.0f;
369 const bool is_opaque = fills_bounds_opaquely_ || !has_valid_alpha_channel();
370 texture_draw_params.blend = !is_root && (forcing_transparency || !is_opaque);
371
372 texture_draw_params.compositor_size = GetCompositor()->size();
373 texture_draw_params.opacity = combined_opacity;
374 texture_draw_params.has_valid_alpha_channel = has_valid_alpha_channel();
375
376 #if defined(OS_WIN)
377 // TODO(beng): figure out why the other branch of this code renders improperly
378 // on Windows, and fix it, otherwise just remove all of this when
379 // WK compositor is default.
380 texture_->Draw(texture_draw_params, gfx::Rect(gfx::Point(), bounds().size()));
381 #else
382 std::vector<gfx::Rect> regions_to_draw;
383 PunchHole(gfx::Rect(gfx::Point(), bounds().size()), hole_rect_,
384 &regions_to_draw);
385
386 for (size_t i = 0; i < regions_to_draw.size(); ++i) {
387 if (!regions_to_draw[i].IsEmpty())
388 texture_->Draw(texture_draw_params, regions_to_draw[i]);
389 }
390 #endif
391 #endif
392 }
393
394 void Layer::DrawTree() {
395 #if defined(USE_WEBKIT_COMPOSITOR)
396 NOTREACHED();
397 #else
398 if (!visible_)
399 return;
400
401 Draw();
402 for (size_t i = 0; i < children_.size(); ++i)
403 children_.at(i)->DrawTree();
404 #endif
405 }
406
407 void Layer::paintContents(WebKit::WebCanvas* web_canvas, 285 void Layer::paintContents(WebKit::WebCanvas* web_canvas,
408 const WebKit::WebRect& clip) { 286 const WebKit::WebRect& clip) {
409 TRACE_EVENT0("ui", "Layer::paintContents"); 287 TRACE_EVENT0("ui", "Layer::paintContents");
410 #if defined(USE_WEBKIT_COMPOSITOR)
411 gfx::CanvasSkia canvas(web_canvas); 288 gfx::CanvasSkia canvas(web_canvas);
412 if (delegate_) 289 if (delegate_)
413 delegate_->OnPaintLayer(&canvas); 290 delegate_->OnPaintLayer(&canvas);
414 #else
415 NOTREACHED();
416 #endif
417 } 291 }
418 292
419 float Layer::GetCombinedOpacity() const { 293 float Layer::GetCombinedOpacity() const {
420 float opacity = opacity_; 294 float opacity = opacity_;
421 Layer* current = this->parent_; 295 Layer* current = this->parent_;
422 while (current) { 296 while (current) {
423 opacity *= current->opacity_; 297 opacity *= current->opacity_;
424 current = current->parent_; 298 current = current->parent_;
425 } 299 }
426 return opacity; 300 return opacity;
427 } 301 }
428 302
429 void Layer::UpdateLayerCanvas() {
430 TRACE_EVENT0("ui", "Layer::UpdateLayerCanvas");
431 #if defined(USE_WEBKIT_COMPOSITOR)
432 NOTREACHED();
433 #else
434 // If we have no delegate, that means that whoever constructed the Layer is
435 // setting its canvas directly with SetCanvas().
436 if (!delegate_ || layer_updated_externally_)
437 return;
438 gfx::Rect local_bounds = gfx::Rect(gfx::Point(), bounds_.size());
439 gfx::Rect draw_rect = texture_.get() ? invalid_rect_.Intersect(local_bounds) :
440 local_bounds;
441 if (draw_rect.IsEmpty()) {
442 invalid_rect_ = gfx::Rect();
443 return;
444 }
445 scoped_ptr<gfx::Canvas> canvas(gfx::Canvas::CreateCanvas(draw_rect.size(),
446 false));
447 canvas->Translate(gfx::Point().Subtract(draw_rect.origin()));
448 if (delegate_)
449 delegate_->OnPaintLayer(canvas.get());
450 SetCanvas(*canvas->GetSkCanvas(), draw_rect.origin());
451 #endif
452 }
453
454 void Layer::StackRelativeTo(Layer* child, Layer* other, bool above) { 303 void Layer::StackRelativeTo(Layer* child, Layer* other, bool above) {
455 DCHECK_NE(child, other); 304 DCHECK_NE(child, other);
456 DCHECK_EQ(this, child->parent()); 305 DCHECK_EQ(this, child->parent());
457 DCHECK_EQ(this, other->parent()); 306 DCHECK_EQ(this, other->parent());
458 307
459 const size_t child_i = 308 const size_t child_i =
460 std::find(children_.begin(), children_.end(), child) - children_.begin(); 309 std::find(children_.begin(), children_.end(), child) - children_.begin();
461 const size_t other_i = 310 const size_t other_i =
462 std::find(children_.begin(), children_.end(), other) - children_.begin(); 311 std::find(children_.begin(), children_.end(), other) - children_.begin();
463 if ((above && child_i == other_i + 1) || (!above && child_i + 1 == other_i)) 312 if ((above && child_i == other_i + 1) || (!above && child_i + 1 == other_i))
464 return; 313 return;
465 314
466 const size_t dest_i = 315 const size_t dest_i =
467 above ? 316 above ?
468 (child_i < other_i ? other_i : other_i + 1) : 317 (child_i < other_i ? other_i : other_i + 1) :
469 (child_i < other_i ? other_i - 1 : other_i); 318 (child_i < other_i ? other_i - 1 : other_i);
470 children_.erase(children_.begin() + child_i); 319 children_.erase(children_.begin() + child_i);
471 children_.insert(children_.begin() + dest_i, child); 320 children_.insert(children_.begin() + dest_i, child);
472 321
473 SetNeedsToRecomputeHole();
474
475 #if defined(USE_WEBKIT_COMPOSITOR)
476 child->web_layer_.removeFromParent(); 322 child->web_layer_.removeFromParent();
477 web_layer_.insertChild(child->web_layer_, dest_i); 323 web_layer_.insertChild(child->web_layer_, dest_i);
478 #endif
479 }
480
481 void Layer::SetNeedsToRecomputeHole() {
482 Layer* root_layer = this;
483 while (root_layer->parent_)
484 root_layer = root_layer->parent_;
485
486 root_layer->recompute_hole_ = true;
487 }
488
489 void Layer::ClearHoleRects() {
490 hole_rect_ = gfx::Rect();
491
492 for (size_t i = 0; i < children_.size(); i++)
493 children_[i]->ClearHoleRects();
494 } 324 }
495 325
496 void Layer::GetLayerProperties(const ui::Transform& parent_transform, 326 void Layer::GetLayerProperties(const ui::Transform& parent_transform,
497 std::vector<LayerProperties>* traversal) { 327 std::vector<LayerProperties>* traversal) {
498 if (!visible_ || opacity_ != 1.0f) 328 if (!visible_ || opacity_ != 1.0f)
499 return; 329 return;
500 330
501 ui::Transform current_transform; 331 ui::Transform current_transform;
502 if (transform().HasChange()) 332 if (transform().HasChange())
503 current_transform.ConcatTransform(transform()); 333 current_transform.ConcatTransform(transform());
504 current_transform.ConcatTranslate( 334 current_transform.ConcatTranslate(
505 static_cast<float>(bounds().x()), 335 static_cast<float>(bounds().x()),
506 static_cast<float>(bounds().y())); 336 static_cast<float>(bounds().y()));
507 current_transform.ConcatTransform(parent_transform); 337 current_transform.ConcatTransform(parent_transform);
508 338
509 if (fills_bounds_opaquely_ && type_ == LAYER_HAS_TEXTURE) { 339 if (fills_bounds_opaquely_ && type_ == LAYER_HAS_TEXTURE) {
510 LayerProperties properties; 340 LayerProperties properties;
511 properties.layer = this; 341 properties.layer = this;
512 properties.transform_relative_to_root = current_transform; 342 properties.transform_relative_to_root = current_transform;
513 traversal->push_back(properties); 343 traversal->push_back(properties);
514 } 344 }
515 345
516 for (size_t i = 0; i < children_.size(); i++) 346 for (size_t i = 0; i < children_.size(); i++)
517 children_[i]->GetLayerProperties(current_transform, traversal); 347 children_[i]->GetLayerProperties(current_transform, traversal);
518 } 348 }
519 349
520 void Layer::RecomputeHole() {
521 std::vector<LayerProperties> traversal;
522 ui::Transform transform;
523
524 ClearHoleRects();
525 GetLayerProperties(transform, &traversal);
526
527 for (size_t i = 0; i < traversal.size(); i++) {
528 Layer* layer = traversal[i].layer;
529 gfx::Rect bounds = gfx::Rect(layer->bounds().size());
530
531 // Iterate through layers which are after traversal[i] in draw order
532 // and find the largest candidate hole.
533 for (size_t j = i + 1; j < traversal.size(); j++) {
534 gfx::Rect candidate_hole = gfx::Rect(traversal[j].layer->bounds().size());
535
536 // Compute transform to go from bounds of layer |j| to local bounds of
537 // layer |i|.
538 ui::Transform candidate_hole_transform;
539 ui::Transform inverted;
540
541 candidate_hole_transform.ConcatTransform(
542 traversal[j].transform_relative_to_root);
543
544 if (!traversal[i].transform_relative_to_root.GetInverse(&inverted))
545 continue;
546
547 candidate_hole_transform.ConcatTransform(inverted);
548
549 // cannot punch a hole if the relative transform between the two layers
550 // is not multiple of 90.
551 float degrees;
552 gfx::Point p;
553 if (!InterpolatedTransform::FactorTRS(candidate_hole_transform, &p,
554 &degrees, NULL) || !IsApproximateMultilpleOf(degrees, 90.0f))
555 continue;
556
557 candidate_hole_transform.TransformRect(&candidate_hole);
558 candidate_hole = candidate_hole.Intersect(bounds);
559
560 if (candidate_hole.size().GetArea() >
561 layer->hole_rect().size().GetArea()) {
562 layer->set_hole_rect(candidate_hole);
563 }
564 }
565 // Free up texture memory if the hole fills bounds of layer.
566 if (!layer->ShouldDraw() && !layer_updated_externally())
567 layer->DropTexture();
568
569 #if defined(USE_WEBKIT_COMPOSITOR)
570 RecomputeDrawsContentAndUVRect();
571 #endif
572 }
573
574 recompute_hole_ = false;
575 }
576
577 // static
578 void Layer::PunchHole(const gfx::Rect& rect,
579 const gfx::Rect& region_to_punch_out,
580 std::vector<gfx::Rect>* sides) {
581 gfx::Rect trimmed_rect = rect.Intersect(region_to_punch_out);
582
583 if (trimmed_rect.IsEmpty()) {
584 sides->push_back(rect);
585 return;
586 }
587
588 // Top (above the hole).
589 sides->push_back(gfx::Rect(rect.x(),
590 rect.y(),
591 rect.width(),
592 trimmed_rect.y() - rect.y()));
593
594 // Left (of the hole).
595 sides->push_back(gfx::Rect(rect.x(),
596 trimmed_rect.y(),
597 trimmed_rect.x() - rect.x(),
598 trimmed_rect.height()));
599
600 // Right (of the hole).
601 sides->push_back(gfx::Rect(trimmed_rect.right(),
602 trimmed_rect.y(),
603 rect.right() - trimmed_rect.right(),
604 trimmed_rect.height()));
605
606 // Bottom (below the hole).
607 sides->push_back(gfx::Rect(rect.x(),
608 trimmed_rect.bottom(),
609 rect.width(),
610 rect.bottom() - trimmed_rect.bottom()));
611 }
612
613 void Layer::DropTexture() {
614 if (!layer_updated_externally_)
615 texture_ = NULL;
616 }
617
618 void Layer::DropTextures() {
619 DropTexture();
620 for (size_t i = 0; i < children_.size(); ++i)
621 children_[i]->DropTextures();
622 }
623
624 bool Layer::ConvertPointForAncestor(const Layer* ancestor, 350 bool Layer::ConvertPointForAncestor(const Layer* ancestor,
625 gfx::Point* point) const { 351 gfx::Point* point) const {
626 ui::Transform transform; 352 ui::Transform transform;
627 bool result = GetTransformRelativeTo(ancestor, &transform); 353 bool result = GetTransformRelativeTo(ancestor, &transform);
628 gfx::Point3f p(*point); 354 gfx::Point3f p(*point);
629 transform.TransformPoint(p); 355 transform.TransformPoint(p);
630 *point = p.AsPoint(); 356 *point = p.AsPoint();
631 return result; 357 return result;
632 } 358 }
633 359
(...skipping 25 matching lines...) Expand all
659 385
660 bool was_move = bounds_.size() == bounds.size(); 386 bool was_move = bounds_.size() == bounds.size();
661 bounds_ = bounds; 387 bounds_ = bounds;
662 if (IsDrawn()) { 388 if (IsDrawn()) {
663 if (was_move) 389 if (was_move)
664 ScheduleDraw(); 390 ScheduleDraw();
665 else 391 else
666 SchedulePaint(gfx::Rect(bounds.size())); 392 SchedulePaint(gfx::Rect(bounds.size()));
667 } 393 }
668 394
669 SetNeedsToRecomputeHole();
670 #if defined(USE_WEBKIT_COMPOSITOR)
671 RecomputeTransform(); 395 RecomputeTransform();
672 RecomputeDrawsContentAndUVRect(); 396 RecomputeDrawsContentAndUVRect();
673 #endif
674 } 397 }
675 398
676 void Layer::SetTransformImmediately(const ui::Transform& transform) { 399 void Layer::SetTransformImmediately(const ui::Transform& transform) {
677 transform_ = transform; 400 transform_ = transform;
678 401
679 SetNeedsToRecomputeHole();
680 #if defined(USE_WEBKIT_COMPOSITOR)
681 RecomputeTransform(); 402 RecomputeTransform();
682 #endif
683 } 403 }
684 404
685 void Layer::SetOpacityImmediately(float opacity) { 405 void Layer::SetOpacityImmediately(float opacity) {
686 bool schedule_draw = (opacity != opacity_ && IsDrawn()); 406 bool schedule_draw = (opacity != opacity_ && IsDrawn());
687 bool was_opaque = GetCombinedOpacity() == 1.0f;
688 opacity_ = opacity; 407 opacity_ = opacity;
689 bool is_opaque = GetCombinedOpacity() == 1.0f;
690 408
691 // If our opacity has changed we need to recompute our hole, our parent's hole
692 // and the holes of all our descendants.
693 if (was_opaque != is_opaque)
694 SetNeedsToRecomputeHole();
695 #if defined(USE_WEBKIT_COMPOSITOR)
696 if (visible_) 409 if (visible_)
697 web_layer_.setOpacity(opacity); 410 web_layer_.setOpacity(opacity);
698 RecomputeDebugBorderColor(); 411 RecomputeDebugBorderColor();
699 #endif
700 if (schedule_draw) 412 if (schedule_draw)
701 ScheduleDraw(); 413 ScheduleDraw();
702 } 414 }
703 415
704 void Layer::SetBoundsFromAnimation(const gfx::Rect& bounds) { 416 void Layer::SetBoundsFromAnimation(const gfx::Rect& bounds) {
705 SetBoundsImmediately(bounds); 417 SetBoundsImmediately(bounds);
706 } 418 }
707 419
708 void Layer::SetTransformFromAnimation(const Transform& transform) { 420 void Layer::SetTransformFromAnimation(const Transform& transform) {
709 SetTransformImmediately(transform); 421 SetTransformImmediately(transform);
(...skipping 12 matching lines...) Expand all
722 } 434 }
723 435
724 const Transform& Layer::GetTransformForAnimation() const { 436 const Transform& Layer::GetTransformForAnimation() const {
725 return transform(); 437 return transform();
726 } 438 }
727 439
728 float Layer::GetOpacityForAnimation() const { 440 float Layer::GetOpacityForAnimation() const {
729 return opacity(); 441 return opacity();
730 } 442 }
731 443
732 #if defined(USE_WEBKIT_COMPOSITOR)
733 void Layer::CreateWebLayer() { 444 void Layer::CreateWebLayer() {
734 web_layer_ = WebKit::WebContentLayer::create(this); 445 web_layer_ = WebKit::WebContentLayer::create(this);
735 web_layer_.setAnchorPoint(WebKit::WebFloatPoint(0.f, 0.f)); 446 web_layer_.setAnchorPoint(WebKit::WebFloatPoint(0.f, 0.f));
736 web_layer_.setOpaque(true); 447 web_layer_.setOpaque(true);
737 web_layer_is_accelerated_ = false; 448 web_layer_is_accelerated_ = false;
738 show_debug_borders_ = CommandLine::ForCurrentProcess()->HasSwitch( 449 show_debug_borders_ = CommandLine::ForCurrentProcess()->HasSwitch(
739 switches::kUIShowLayerBorders); 450 switches::kUIShowLayerBorders);
740 web_layer_.setDebugBorderWidth(show_debug_borders_ ? 2 : 0); 451 web_layer_.setDebugBorderWidth(show_debug_borders_ ? 2 : 0);
741 RecomputeDrawsContentAndUVRect(); 452 RecomputeDrawsContentAndUVRect();
742 RecomputeDebugBorderColor(); 453 RecomputeDebugBorderColor();
743 } 454 }
744 455
745 void Layer::RecomputeTransform() { 456 void Layer::RecomputeTransform() {
746 ui::Transform transform = transform_; 457 ui::Transform transform = transform_;
747 transform.ConcatTranslate(bounds_.x(), bounds_.y()); 458 transform.ConcatTranslate(bounds_.x(), bounds_.y());
748 web_layer_.setTransform(transform.matrix()); 459 web_layer_.setTransform(transform.matrix());
749 } 460 }
750 461
751 void Layer::RecomputeDrawsContentAndUVRect() { 462 void Layer::RecomputeDrawsContentAndUVRect() {
752 DCHECK(!web_layer_.isNull()); 463 DCHECK(!web_layer_.isNull());
753 bool should_draw = type_ == LAYER_HAS_TEXTURE && 464 bool should_draw = type_ == LAYER_HAS_TEXTURE;
754 !hole_rect_.Contains(gfx::Rect(gfx::Point(0, 0), bounds_.size()));
755 if (!web_layer_is_accelerated_) { 465 if (!web_layer_is_accelerated_) {
756 web_layer_.to<WebKit::WebContentLayer>().setDrawsContent(should_draw); 466 web_layer_.to<WebKit::WebContentLayer>().setDrawsContent(should_draw);
757 web_layer_.setBounds(bounds_.size()); 467 web_layer_.setBounds(bounds_.size());
758 } else { 468 } else {
759 DCHECK(texture_); 469 DCHECK(texture_);
760 TextureCC* texture_cc = static_cast<TextureCC*>(texture_.get()); 470 TextureCC* texture_cc = static_cast<TextureCC*>(texture_.get());
761 unsigned int texture_id = texture_cc->texture_id(); 471 unsigned int texture_id = texture_cc->texture_id();
762 WebKit::WebExternalTextureLayer texture_layer = 472 WebKit::WebExternalTextureLayer texture_layer =
763 web_layer_.to<WebKit::WebExternalTextureLayer>(); 473 web_layer_.to<WebKit::WebExternalTextureLayer>();
764 texture_layer.setTextureId(should_draw ? texture_id : 0); 474 texture_layer.setTextureId(should_draw ? texture_id : 0);
(...skipping 12 matching lines...) Expand all
777 void Layer::RecomputeDebugBorderColor() { 487 void Layer::RecomputeDebugBorderColor() {
778 if (!show_debug_borders_) 488 if (!show_debug_borders_)
779 return; 489 return;
780 unsigned int color = 0xFF000000; 490 unsigned int color = 0xFF000000;
781 color |= web_layer_is_accelerated_ ? 0x0000FF00 : 0x00FF0000; 491 color |= web_layer_is_accelerated_ ? 0x0000FF00 : 0x00FF0000;
782 bool opaque = fills_bounds_opaquely_ && (GetCombinedOpacity() == 1.f); 492 bool opaque = fills_bounds_opaquely_ && (GetCombinedOpacity() == 1.f);
783 if (!opaque) 493 if (!opaque)
784 color |= 0xFF; 494 color |= 0xFF;
785 web_layer_.setDebugBorderColor(color); 495 web_layer_.setDebugBorderColor(color);
786 } 496 }
787 #endif
788 497
789 } // namespace ui 498 } // namespace ui
OLDNEW
« no previous file with comments | « ui/gfx/compositor/layer.h ('k') | ui/gfx/compositor/layer_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698