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. |
|
jonathan.backer
2011/10/18 15:28:26
Just a high level comment (feel free to ignore). T
Ben Goodger (Google)
2011/10/18 15:40:40
Seems like we'd need to extract some of this code
piman
2011/10/19 17:53:23
If we were to support 2 compositors in the long ru
| |
| 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" |
| 11 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFloatPoint.h" | |
| 12 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFloatRect.h" | |
| 13 #include "third_party/WebKit/Source/WebKit/chromium/public/WebSize.h" | |
| 11 #include "ui/base/animation/animation.h" | 14 #include "ui/base/animation/animation.h" |
| 12 #include "ui/gfx/compositor/layer_animator.h" | 15 #include "ui/gfx/compositor/layer_animator.h" |
| 13 #include "ui/gfx/canvas_skia.h" | 16 #include "ui/gfx/canvas_skia.h" |
| 14 #include "ui/gfx/interpolated_transform.h" | 17 #include "ui/gfx/interpolated_transform.h" |
| 15 #include "ui/gfx/point3.h" | 18 #include "ui/gfx/point3.h" |
| 16 | 19 |
| 17 namespace { | 20 namespace { |
| 18 | 21 |
| 19 const float EPSILON = 1e-3f; | 22 const float EPSILON = 1e-3f; |
| 20 | 23 |
| 21 bool IsApproximateMultilpleOf(float value, float base) { | 24 bool IsApproximateMultilpleOf(float value, float base) { |
| 22 float remainder = fmod(fabs(value), base); | 25 float remainder = fmod(fabs(value), base); |
| 23 return remainder < EPSILON || base - remainder < EPSILON; | 26 return remainder < EPSILON || base - remainder < EPSILON; |
| 24 } | 27 } |
| 25 | 28 |
| 26 } // namespace | 29 } // namespace |
| 27 | 30 |
| 28 namespace ui { | 31 namespace ui { |
| 29 | 32 |
| 30 Layer::Layer(Compositor* compositor) | 33 Layer::Layer(Compositor* compositor) |
| 31 : type_(LAYER_HAS_TEXTURE), | 34 : type_(LAYER_HAS_TEXTURE), |
| 32 compositor_(compositor), | 35 compositor_(compositor), |
| 33 parent_(NULL), | 36 parent_(NULL), |
| 34 visible_(true), | 37 visible_(true), |
| 35 fills_bounds_opaquely_(true), | 38 fills_bounds_opaquely_(true), |
| 36 layer_updated_externally_(false), | 39 layer_updated_externally_(false), |
| 37 opacity_(1.0f), | 40 opacity_(1.0f), |
| 38 delegate_(NULL) { | 41 delegate_(NULL) { |
| 42 #if defined(USE_WEBKIT_COMPOSITOR) | |
| 43 CreateWebLayer(); | |
| 44 #endif | |
| 39 } | 45 } |
| 40 | 46 |
| 41 Layer::Layer(Compositor* compositor, LayerType type) | 47 Layer::Layer(Compositor* compositor, LayerType type) |
| 42 : type_(type), | 48 : type_(type), |
| 43 compositor_(compositor), | 49 compositor_(compositor), |
| 44 parent_(NULL), | 50 parent_(NULL), |
| 45 visible_(true), | 51 visible_(true), |
| 46 fills_bounds_opaquely_(true), | 52 fills_bounds_opaquely_(true), |
| 47 layer_updated_externally_(false), | 53 layer_updated_externally_(false), |
| 48 opacity_(1.0f), | 54 opacity_(1.0f), |
| 49 delegate_(NULL) { | 55 delegate_(NULL) { |
| 56 #if defined(USE_WEBKIT_COMPOSITOR) | |
| 57 CreateWebLayer(); | |
| 58 #endif | |
| 50 } | 59 } |
| 51 | 60 |
| 52 Layer::~Layer() { | 61 Layer::~Layer() { |
| 53 if (parent_) | 62 if (parent_) |
| 54 parent_->Remove(this); | 63 parent_->Remove(this); |
| 55 for (size_t i = 0; i < children_.size(); ++i) | 64 for (size_t i = 0; i < children_.size(); ++i) |
| 56 children_[i]->parent_ = NULL; | 65 children_[i]->parent_ = NULL; |
| 66 if (!web_layer_.isNull()) | |
|
Ben Goodger (Google)
2011/10/16 22:39:51
I'd actually rather see #ifdefs in this file... gi
piman
2011/10/19 17:53:23
Done. My initial thought was that we could support
| |
| 67 web_layer_.removeFromParent(); | |
| 57 } | 68 } |
| 58 | 69 |
| 59 Compositor* Layer::GetCompositor() { | 70 Compositor* Layer::GetCompositor() { |
| 60 return compositor_ ? compositor_ : parent_ ? parent_->GetCompositor() : NULL; | 71 return compositor_ ? compositor_ : parent_ ? parent_->GetCompositor() : NULL; |
| 61 } | 72 } |
| 62 | 73 |
| 63 void Layer::SetCompositor(Compositor* compositor) { | 74 void Layer::SetCompositor(Compositor* compositor) { |
| 64 // This function must only be called once, with a valid compositor, and only | 75 // This function must only be called once, with a valid compositor, and only |
| 65 // for the compositor's root layer. | 76 // for the compositor's root layer. |
| 66 DCHECK(!compositor_); | 77 DCHECK(!compositor_); |
| 67 DCHECK(compositor); | 78 DCHECK(compositor); |
| 68 DCHECK_EQ(compositor->root_layer(), this); | 79 DCHECK_EQ(compositor->root_layer(), this); |
| 69 compositor_ = compositor; | 80 compositor_ = compositor; |
| 70 } | 81 } |
| 71 | 82 |
| 72 void Layer::Add(Layer* child) { | 83 void Layer::Add(Layer* child) { |
| 73 if (child->parent_) | 84 if (child->parent_) |
| 74 child->parent_->Remove(child); | 85 child->parent_->Remove(child); |
| 75 child->parent_ = this; | 86 child->parent_ = this; |
| 76 children_.push_back(child); | 87 children_.push_back(child); |
| 88 if (!web_layer_.isNull()) { | |
| 89 DCHECK(!child->web_layer_.isNull()); | |
| 90 web_layer_.addChild(child->web_layer_); | |
| 91 } | |
| 77 | 92 |
| 78 RecomputeHole(); | 93 RecomputeHole(); |
| 79 } | 94 } |
| 80 | 95 |
| 81 void Layer::Remove(Layer* child) { | 96 void Layer::Remove(Layer* child) { |
| 82 std::vector<Layer*>::iterator i = | 97 std::vector<Layer*>::iterator i = |
| 83 std::find(children_.begin(), children_.end(), child); | 98 std::find(children_.begin(), children_.end(), child); |
| 84 DCHECK(i != children_.end()); | 99 DCHECK(i != children_.end()); |
| 85 children_.erase(i); | 100 children_.erase(i); |
| 86 child->parent_ = NULL; | 101 child->parent_ = NULL; |
| 102 if (!child->web_layer_.isNull()) | |
| 103 child->web_layer_.removeFromParent(); | |
| 87 | 104 |
| 88 RecomputeHole(); | 105 RecomputeHole(); |
| 89 | 106 |
| 90 child->DropTextures(); | 107 child->DropTextures(); |
| 91 } | 108 } |
| 92 | 109 |
| 93 void Layer::MoveToFront(Layer* child) { | 110 void Layer::MoveToFront(Layer* child) { |
| 94 std::vector<Layer*>::iterator i = | 111 std::vector<Layer*>::iterator i = |
| 95 std::find(children_.begin(), children_.end(), child); | 112 std::find(children_.begin(), children_.end(), child); |
| 96 DCHECK(i != children_.end()); | 113 DCHECK(i != children_.end()); |
| 97 children_.erase(i); | 114 children_.erase(i); |
| 98 children_.push_back(child); | 115 children_.push_back(child); |
| 116 if (!web_layer_.isNull()) { | |
| 117 DCHECK(!child->web_layer_.isNull()); | |
| 118 child->web_layer_.removeFromParent(); | |
| 119 web_layer_.addChild(child->web_layer_); | |
| 120 } | |
| 99 } | 121 } |
| 100 | 122 |
| 101 bool Layer::Contains(const Layer* other) const { | 123 bool Layer::Contains(const Layer* other) const { |
| 102 for (const Layer* parent = other; parent; parent = parent->parent()) { | 124 for (const Layer* parent = other; parent; parent = parent->parent()) { |
| 103 if (parent == this) | 125 if (parent == this) |
| 104 return true; | 126 return true; |
| 105 } | 127 } |
| 106 return false; | 128 return false; |
| 107 } | 129 } |
| 108 | 130 |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 152 bool was_drawn = IsDrawn(); | 174 bool was_drawn = IsDrawn(); |
| 153 visible_ = visible; | 175 visible_ = visible; |
| 154 bool is_drawn = IsDrawn(); | 176 bool is_drawn = IsDrawn(); |
| 155 if (was_drawn == is_drawn) | 177 if (was_drawn == is_drawn) |
| 156 return; | 178 return; |
| 157 | 179 |
| 158 if (!is_drawn) | 180 if (!is_drawn) |
| 159 DropTextures(); | 181 DropTextures(); |
| 160 if (parent_) | 182 if (parent_) |
| 161 parent_->RecomputeHole(); | 183 parent_->RecomputeHole(); |
| 184 if (!web_layer_.isNull()) { | |
| 185 // TODO(piman): Expose a visibility flag on WebLayer. | |
| 186 web_layer_.setOpacity(visible_ ? opacity_ : 0.f); | |
| 187 } | |
| 162 } | 188 } |
| 163 | 189 |
| 164 bool Layer::IsDrawn() const { | 190 bool Layer::IsDrawn() const { |
| 165 const Layer* layer = this; | 191 const Layer* layer = this; |
| 166 while (layer && layer->visible_) | 192 while (layer && layer->visible_) |
| 167 layer = layer->parent_; | 193 layer = layer->parent_; |
| 168 return layer == NULL; | 194 return layer == NULL; |
| 169 } | 195 } |
| 170 | 196 |
| 171 bool Layer::ShouldDraw() { | 197 bool Layer::ShouldDraw() const { |
| 172 return type_ == LAYER_HAS_TEXTURE && GetCombinedOpacity() > 0.0f && | 198 return type_ == LAYER_HAS_TEXTURE && GetCombinedOpacity() > 0.0f && |
| 173 !hole_rect_.Contains(gfx::Rect(gfx::Point(0, 0), bounds_.size())); | 199 !hole_rect_.Contains(gfx::Rect(gfx::Point(0, 0), bounds_.size())); |
| 174 } | 200 } |
| 175 | 201 |
| 176 // static | 202 // static |
| 177 void Layer::ConvertPointToLayer(const Layer* source, | 203 void Layer::ConvertPointToLayer(const Layer* source, |
| 178 const Layer* target, | 204 const Layer* target, |
| 179 gfx::Point* point) { | 205 gfx::Point* point) { |
| 180 const Layer* inner = NULL; | 206 const Layer* inner = NULL; |
| 181 const Layer* outer = NULL; | 207 const Layer* outer = NULL; |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 193 } | 219 } |
| 194 | 220 |
| 195 void Layer::SetFillsBoundsOpaquely(bool fills_bounds_opaquely) { | 221 void Layer::SetFillsBoundsOpaquely(bool fills_bounds_opaquely) { |
| 196 if (fills_bounds_opaquely_ == fills_bounds_opaquely) | 222 if (fills_bounds_opaquely_ == fills_bounds_opaquely) |
| 197 return; | 223 return; |
| 198 | 224 |
| 199 fills_bounds_opaquely_ = fills_bounds_opaquely; | 225 fills_bounds_opaquely_ = fills_bounds_opaquely; |
| 200 | 226 |
| 201 if (parent()) | 227 if (parent()) |
| 202 parent()->RecomputeHole(); | 228 parent()->RecomputeHole(); |
| 229 if (!web_layer_.isNull()) | |
| 230 web_layer_.setOpaque(fills_bounds_opaquely); | |
| 203 } | 231 } |
| 204 | 232 |
| 205 void Layer::SetExternalTexture(ui::Texture* texture) { | 233 void Layer::SetExternalTexture(ui::Texture* texture) { |
| 206 DCHECK(texture); | 234 DCHECK(texture); |
| 207 layer_updated_externally_ = true; | 235 layer_updated_externally_ = true; |
| 208 texture_ = texture; | 236 texture_ = texture; |
| 209 } | 237 } |
| 210 | 238 |
| 211 void Layer::SetCanvas(const SkCanvas& canvas, const gfx::Point& origin) { | 239 void Layer::SetCanvas(const SkCanvas& canvas, const gfx::Point& origin) { |
| 240 DCHECK(web_layer_.isNull()); | |
| 212 DCHECK_EQ(type_, LAYER_HAS_TEXTURE); | 241 DCHECK_EQ(type_, LAYER_HAS_TEXTURE); |
| 213 | 242 |
| 214 if (!texture_.get()) | 243 if (!texture_.get()) |
| 215 texture_ = GetCompositor()->CreateTexture(); | 244 texture_ = GetCompositor()->CreateTexture(); |
| 216 | 245 |
| 217 texture_->SetCanvas(canvas, origin, bounds_.size()); | 246 texture_->SetCanvas(canvas, origin, bounds_.size()); |
| 218 invalid_rect_ = gfx::Rect(); | 247 invalid_rect_ = gfx::Rect(); |
| 219 } | 248 } |
| 220 | 249 |
| 221 void Layer::SchedulePaint(const gfx::Rect& invalid_rect) { | 250 void Layer::SchedulePaint(const gfx::Rect& invalid_rect) { |
| 222 invalid_rect_ = invalid_rect_.Union(invalid_rect); | 251 if (web_layer_.isNull()) { |
| 223 ScheduleDraw(); | 252 invalid_rect_ = invalid_rect_.Union(invalid_rect); |
| 253 ScheduleDraw(); | |
| 254 } else { | |
| 255 WebKit::WebFloatRect web_rect(invalid_rect.x(), | |
| 256 invalid_rect.y(), | |
| 257 invalid_rect.width(), | |
| 258 invalid_rect.height()); | |
| 259 web_layer_.invalidateRect(web_rect); | |
| 260 } | |
| 224 } | 261 } |
| 225 | 262 |
| 226 void Layer::ScheduleDraw() { | 263 void Layer::ScheduleDraw() { |
| 227 if (GetCompositor()) | 264 Compositor* compositor = GetCompositor(); |
| 228 GetCompositor()->ScheduleDraw(); | 265 if (compositor) |
| 266 compositor->ScheduleDraw(); | |
| 229 } | 267 } |
| 230 | 268 |
| 231 void Layer::Draw() { | 269 void Layer::Draw() { |
| 270 DCHECK(web_layer_.isNull()); | |
| 232 DCHECK(GetCompositor()); | 271 DCHECK(GetCompositor()); |
| 233 if (!ShouldDraw()) | 272 if (!ShouldDraw()) |
| 234 return; | 273 return; |
| 235 | 274 |
| 236 UpdateLayerCanvas(); | 275 UpdateLayerCanvas(); |
| 237 | 276 |
| 238 // Layer drew nothing, no texture was created. | 277 // Layer drew nothing, no texture was created. |
| 239 if (!texture_.get()) | 278 if (!texture_.get()) |
| 240 return; | 279 return; |
| 241 | 280 |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 264 PunchHole(gfx::Rect(gfx::Point(), bounds().size()), hole_rect_, | 303 PunchHole(gfx::Rect(gfx::Point(), bounds().size()), hole_rect_, |
| 265 ®ions_to_draw); | 304 ®ions_to_draw); |
| 266 | 305 |
| 267 for (size_t i = 0; i < regions_to_draw.size(); ++i) { | 306 for (size_t i = 0; i < regions_to_draw.size(); ++i) { |
| 268 if (!regions_to_draw[i].IsEmpty()) | 307 if (!regions_to_draw[i].IsEmpty()) |
| 269 texture_->Draw(texture_draw_params, regions_to_draw[i]); | 308 texture_->Draw(texture_draw_params, regions_to_draw[i]); |
| 270 } | 309 } |
| 271 } | 310 } |
| 272 | 311 |
| 273 void Layer::DrawTree() { | 312 void Layer::DrawTree() { |
| 313 DCHECK(web_layer_.isNull()); | |
| 274 if (!visible_) | 314 if (!visible_) |
| 275 return; | 315 return; |
| 276 | 316 |
| 277 Draw(); | 317 Draw(); |
| 278 for (size_t i = 0; i < children_.size(); ++i) | 318 for (size_t i = 0; i < children_.size(); ++i) |
| 279 children_.at(i)->DrawTree(); | 319 children_.at(i)->DrawTree(); |
| 280 } | 320 } |
| 281 | 321 |
| 322 void Layer::notifyNeedsComposite() { | |
| 323 DCHECK(!web_layer_.isNull()); | |
| 324 ScheduleDraw(); | |
| 325 } | |
| 326 | |
| 327 void Layer::RecomputeDrawsContent() { | |
|
Ben Goodger (Google)
2011/10/16 22:39:51
order in .cc should match .h
piman
2011/10/19 17:53:23
Done.
| |
| 328 DCHECK(!web_layer_.isNull()); | |
| 329 web_layer_.setDrawsContent(ShouldDraw()); | |
| 330 } | |
| 331 | |
| 332 void Layer::paintContents(WebKit::WebCanvas* web_canvas, | |
| 333 const WebKit::WebRect& clip) { | |
| 334 DCHECK(!web_layer_.isNull()); | |
| 335 gfx::CanvasSkia canvas(web_canvas); | |
| 336 delegate_->OnPaintLayer(&canvas); | |
| 337 } | |
| 338 | |
| 282 float Layer::GetCombinedOpacity() const { | 339 float Layer::GetCombinedOpacity() const { |
| 283 float opacity = opacity_; | 340 float opacity = opacity_; |
| 284 Layer* current = this->parent_; | 341 Layer* current = this->parent_; |
| 285 while (current) { | 342 while (current) { |
| 286 opacity *= current->opacity_; | 343 opacity *= current->opacity_; |
| 287 current = current->parent_; | 344 current = current->parent_; |
| 288 } | 345 } |
| 289 return opacity; | 346 return opacity; |
| 290 } | 347 } |
| 291 | 348 |
| 292 void Layer::UpdateLayerCanvas() { | 349 void Layer::UpdateLayerCanvas() { |
| 350 DCHECK(web_layer_.isNull()); | |
| 293 // If we have no delegate, that means that whoever constructed the Layer is | 351 // If we have no delegate, that means that whoever constructed the Layer is |
| 294 // setting its canvas directly with SetCanvas(). | 352 // setting its canvas directly with SetCanvas(). |
| 295 if (!delegate_ || layer_updated_externally_) | 353 if (!delegate_ || layer_updated_externally_) |
| 296 return; | 354 return; |
| 297 gfx::Rect local_bounds = gfx::Rect(gfx::Point(), bounds_.size()); | 355 gfx::Rect local_bounds = gfx::Rect(gfx::Point(), bounds_.size()); |
| 298 gfx::Rect draw_rect = texture_.get() ? invalid_rect_.Intersect(local_bounds) : | 356 gfx::Rect draw_rect = texture_.get() ? invalid_rect_.Intersect(local_bounds) : |
| 299 local_bounds; | 357 local_bounds; |
| 300 if (draw_rect.IsEmpty()) { | 358 if (draw_rect.IsEmpty()) { |
| 301 invalid_rect_ = gfx::Rect(); | 359 invalid_rect_ = gfx::Rect(); |
| 302 return; | 360 return; |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 344 candidate_hole = bounds().Intersect(candidate_hole); | 402 candidate_hole = bounds().Intersect(candidate_hole); |
| 345 | 403 |
| 346 // Ensure we have the largest hole. | 404 // Ensure we have the largest hole. |
| 347 if (candidate_hole.size().GetArea() > hole_rect_.size().GetArea()) | 405 if (candidate_hole.size().GetArea() > hole_rect_.size().GetArea()) |
| 348 hole_rect_ = candidate_hole; | 406 hole_rect_ = candidate_hole; |
| 349 } | 407 } |
| 350 | 408 |
| 351 // Free up texture memory if the hole fills bounds of layer. | 409 // Free up texture memory if the hole fills bounds of layer. |
| 352 if (!ShouldDraw() && !layer_updated_externally_) | 410 if (!ShouldDraw() && !layer_updated_externally_) |
| 353 texture_ = NULL; | 411 texture_ = NULL; |
| 412 | |
| 413 if (!web_layer_.isNull()) | |
| 414 RecomputeDrawsContent(); | |
| 354 } | 415 } |
| 355 | 416 |
| 356 bool Layer::IsCompletelyOpaque() const { | 417 bool Layer::IsCompletelyOpaque() const { |
| 357 return fills_bounds_opaquely() && GetCombinedOpacity() == 1.0f; | 418 return fills_bounds_opaquely() && GetCombinedOpacity() == 1.0f; |
| 358 } | 419 } |
| 359 | 420 |
| 360 // static | 421 // static |
| 361 void Layer::PunchHole(const gfx::Rect& rect, | 422 void Layer::PunchHole(const gfx::Rect& rect, |
| 362 const gfx::Rect& region_to_punch_out, | 423 const gfx::Rect& region_to_punch_out, |
| 363 std::vector<gfx::Rect>* sides) { | 424 std::vector<gfx::Rect>* sides) { |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 387 trimmed_rect.height())); | 448 trimmed_rect.height())); |
| 388 | 449 |
| 389 // Bottom (below the hole). | 450 // Bottom (below the hole). |
| 390 sides->push_back(gfx::Rect(rect.x(), | 451 sides->push_back(gfx::Rect(rect.x(), |
| 391 trimmed_rect.bottom(), | 452 trimmed_rect.bottom(), |
| 392 rect.width(), | 453 rect.width(), |
| 393 rect.bottom() - trimmed_rect.bottom())); | 454 rect.bottom() - trimmed_rect.bottom())); |
| 394 } | 455 } |
| 395 | 456 |
| 396 void Layer::DropTextures() { | 457 void Layer::DropTextures() { |
| 458 if (!web_layer_.isNull()) | |
| 459 return; | |
| 397 if (!layer_updated_externally_) | 460 if (!layer_updated_externally_) |
| 398 texture_ = NULL; | 461 texture_ = NULL; |
| 399 for (size_t i = 0; i < children_.size(); ++i) | 462 for (size_t i = 0; i < children_.size(); ++i) |
| 400 children_[i]->DropTextures(); | 463 children_[i]->DropTextures(); |
| 401 } | 464 } |
| 402 | 465 |
| 403 bool Layer::ConvertPointForAncestor(const Layer* ancestor, | 466 bool Layer::ConvertPointForAncestor(const Layer* ancestor, |
| 404 gfx::Point* point) const { | 467 gfx::Point* point) const { |
| 405 ui::Transform transform; | 468 ui::Transform transform; |
| 406 bool result = GetTransformRelativeTo(ancestor, &transform); | 469 bool result = GetTransformRelativeTo(ancestor, &transform); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 453 SetTransformImmediately(animator_->GetTargetTransform()); | 516 SetTransformImmediately(animator_->GetTargetTransform()); |
| 454 } | 517 } |
| 455 animator_.reset(); | 518 animator_.reset(); |
| 456 } | 519 } |
| 457 | 520 |
| 458 void Layer::SetBoundsImmediately(const gfx::Rect& bounds) { | 521 void Layer::SetBoundsImmediately(const gfx::Rect& bounds) { |
| 459 bounds_ = bounds; | 522 bounds_ = bounds; |
| 460 | 523 |
| 461 if (parent()) | 524 if (parent()) |
| 462 parent()->RecomputeHole(); | 525 parent()->RecomputeHole(); |
| 526 if (!web_layer_.isNull()) { | |
| 527 web_layer_.setBounds(bounds.size()); | |
| 528 RecomputeTransform(); | |
| 529 RecomputeDrawsContent(); | |
| 530 } | |
| 463 } | 531 } |
| 464 | 532 |
| 465 void Layer::SetTransformImmediately(const ui::Transform& transform) { | 533 void Layer::SetTransformImmediately(const ui::Transform& transform) { |
| 466 transform_ = transform; | 534 transform_ = transform; |
| 467 | 535 |
| 468 if (parent()) | 536 if (parent()) |
| 469 parent()->RecomputeHole(); | 537 parent()->RecomputeHole(); |
| 538 if (!web_layer_.isNull()) | |
| 539 RecomputeTransform(); | |
| 540 } | |
| 541 | |
| 542 void Layer::RecomputeTransform() { | |
| 543 DCHECK(!web_layer_.isNull()); | |
| 544 ui::Transform transform = transform_; | |
| 545 transform.ConcatTranslate(bounds_.x(), bounds_.y()); | |
| 546 web_layer_.setTransform(transform.matrix()); | |
| 470 } | 547 } |
| 471 | 548 |
| 472 void Layer::SetOpacityImmediately(float opacity) { | 549 void Layer::SetOpacityImmediately(float opacity) { |
| 473 bool was_opaque = GetCombinedOpacity() == 1.0f; | 550 bool was_opaque = GetCombinedOpacity() == 1.0f; |
| 474 opacity_ = opacity; | 551 opacity_ = opacity; |
| 475 bool is_opaque = GetCombinedOpacity() == 1.0f; | 552 bool is_opaque = GetCombinedOpacity() == 1.0f; |
| 476 | 553 |
| 477 // If our opacity has changed we need to recompute our hole, our parent's hole | 554 // If our opacity has changed we need to recompute our hole, our parent's hole |
| 478 // and the holes of all our descendants. | 555 // and the holes of all our descendants. |
| 479 if (was_opaque != is_opaque) { | 556 if (was_opaque != is_opaque) { |
| 480 if (parent_) | 557 if (parent_) |
| 481 parent_->RecomputeHole(); | 558 parent_->RecomputeHole(); |
| 482 std::queue<Layer*> to_process; | 559 std::queue<Layer*> to_process; |
| 483 to_process.push(this); | 560 to_process.push(this); |
| 484 while (!to_process.empty()) { | 561 while (!to_process.empty()) { |
| 485 Layer* current = to_process.front(); | 562 Layer* current = to_process.front(); |
| 486 to_process.pop(); | 563 to_process.pop(); |
| 487 current->RecomputeHole(); | 564 current->RecomputeHole(); |
| 488 for (size_t i = 0; i < current->children_.size(); ++i) | 565 for (size_t i = 0; i < current->children_.size(); ++i) |
| 489 to_process.push(current->children_.at(i)); | 566 to_process.push(current->children_.at(i)); |
| 490 } | 567 } |
| 491 } | 568 } |
| 569 if (!web_layer_.isNull()) { | |
| 570 if (visible_) | |
| 571 web_layer_.setOpacity(opacity); | |
| 572 RecomputeDrawsContent(); | |
| 573 } | |
| 492 } | 574 } |
| 493 | 575 |
| 494 void Layer::SetBoundsFromAnimator(const gfx::Rect& bounds) { | 576 void Layer::SetBoundsFromAnimator(const gfx::Rect& bounds) { |
| 495 SetBoundsImmediately(bounds); | 577 SetBoundsImmediately(bounds); |
| 496 } | 578 } |
| 497 | 579 |
| 498 void Layer::SetTransformFromAnimator(const Transform& transform) { | 580 void Layer::SetTransformFromAnimator(const Transform& transform) { |
| 499 SetTransformImmediately(transform); | 581 SetTransformImmediately(transform); |
| 500 } | 582 } |
| 501 | 583 |
| 502 void Layer::SetOpacityFromAnimator(float opacity) { | 584 void Layer::SetOpacityFromAnimator(float opacity) { |
| 503 SetOpacityImmediately(opacity); | 585 SetOpacityImmediately(opacity); |
| 504 } | 586 } |
| 505 | 587 |
| 588 void Layer::CreateWebLayer() { | |
| 589 web_layer_ = WebKit::WebContentLayer::create(this, this); | |
| 590 web_layer_.setAnchorPoint(WebKit::WebFloatPoint(0.f, 0.f)); | |
| 591 web_layer_.setOpaque(true); | |
| 592 RecomputeDrawsContent(); | |
| 593 } | |
| 594 | |
| 506 } // namespace ui | 595 } // namespace ui |
| OLD | NEW |