Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "services/gfx/compositor/graph/node_def.h" | 5 #include "services/gfx/compositor/graph/node_def.h" |
| 6 | 6 |
| 7 #include <ostream> | 7 #include <ostream> |
| 8 | 8 |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "mojo/services/gfx/composition/cpp/formatting.h" | 10 #include "mojo/services/gfx/composition/cpp/formatting.h" |
| 11 #include "mojo/skia/type_converters.h" | 11 #include "mojo/skia/type_converters.h" |
| 12 #include "services/gfx/compositor/graph/scene_content.h" | 12 #include "services/gfx/compositor/graph/scene_content.h" |
| 13 #include "services/gfx/compositor/graph/scene_def.h" | 13 #include "services/gfx/compositor/graph/scene_def.h" |
| 14 #include "services/gfx/compositor/graph/snapshot.h" | 14 #include "services/gfx/compositor/graph/snapshot.h" |
| 15 #include "services/gfx/compositor/render/render_image.h" | 15 #include "services/gfx/compositor/render/render_image.h" |
| 16 #include "third_party/skia/include/core/SkCanvas.h" | 16 #include "third_party/skia/include/core/SkCanvas.h" |
| 17 #include "third_party/skia/include/core/SkColor.h" | 17 #include "third_party/skia/include/core/SkColor.h" |
| 18 #include "third_party/skia/include/core/SkMatrix.h" | |
| 18 #include "third_party/skia/include/core/SkPaint.h" | 19 #include "third_party/skia/include/core/SkPaint.h" |
| 20 #include "third_party/skia/include/core/SkPoint.h" | |
| 19 #include "third_party/skia/include/core/SkRect.h" | 21 #include "third_party/skia/include/core/SkRect.h" |
| 20 | 22 |
| 21 namespace compositor { | 23 namespace compositor { |
| 22 namespace { | 24 namespace { |
| 23 SkColor MakeSkColor(const mojo::gfx::composition::Color& color) { | 25 SkColor MakeSkColor(const mojo::gfx::composition::Color& color) { |
| 24 return SkColorSetARGBInline(color.alpha, color.red, color.green, color.blue); | 26 return SkColorSetARGBInline(color.alpha, color.red, color.green, color.blue); |
| 25 } | 27 } |
| 26 | 28 |
| 27 void SetPaintForBlend(SkPaint* paint, mojo::gfx::composition::Blend* blend) { | 29 void SetPaintForBlend(SkPaint* paint, mojo::gfx::composition::Blend* blend) { |
| 28 DCHECK(paint); | 30 DCHECK(paint); |
| 29 if (blend) | 31 if (blend) |
| 30 paint->setAlpha(blend->alpha); | 32 paint->setAlpha(blend->alpha); |
| 31 } | 33 } |
| 34 | |
| 35 bool Contains(const SkRect& bounds, const SkPoint& point) { | |
| 36 return point.x() >= bounds.left() && point.x() < bounds.right() && | |
| 37 point.y() >= bounds.top() && point.y() < bounds.bottom(); | |
| 38 } | |
| 32 } // namespace | 39 } // namespace |
| 33 | 40 |
| 34 NodeDef::NodeDef(uint32_t node_id, | 41 NodeDef::NodeDef(uint32_t node_id, |
| 35 mojo::TransformPtr content_transform, | 42 mojo::TransformPtr content_transform, |
| 36 mojo::RectPtr content_clip, | 43 mojo::RectPtr content_clip, |
| 44 mojo::gfx::composition::HitTestBehaviorPtr hit_test_behavior, | |
| 37 Combinator combinator, | 45 Combinator combinator, |
| 38 const std::vector<uint32_t>& child_node_ids) | 46 const std::vector<uint32_t>& child_node_ids) |
| 39 : node_id_(node_id), | 47 : node_id_(node_id), |
| 40 content_transform_(content_transform.Pass()), | 48 content_transform_(content_transform.Pass()), |
| 41 content_clip_(content_clip.Pass()), | 49 content_clip_(content_clip.Pass()), |
| 50 hit_test_behavior_(hit_test_behavior.Pass()), | |
| 42 combinator_(combinator), | 51 combinator_(combinator), |
| 43 child_node_ids_(child_node_ids) {} | 52 child_node_ids_(child_node_ids) {} |
| 44 | 53 |
| 45 NodeDef::~NodeDef() {} | 54 NodeDef::~NodeDef() {} |
| 46 | 55 |
| 47 std::string NodeDef::FormattedLabel(const SceneContent* content) const { | 56 std::string NodeDef::FormattedLabel(const SceneContent* content) const { |
| 48 return content->FormattedLabelForNode(node_id_); | 57 return content->FormattedLabelForNode(node_id_); |
| 49 } | 58 } |
| 50 | 59 |
| 51 bool NodeDef::RecordContent(SceneContentBuilder* builder) const { | 60 bool NodeDef::RecordContent(SceneContentBuilder* builder) const { |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 215 DCHECK(canvas); | 224 DCHECK(canvas); |
| 216 | 225 |
| 217 TraverseSnapshottedChildren( | 226 TraverseSnapshottedChildren( |
| 218 content, snapshot, | 227 content, snapshot, |
| 219 [this, content, snapshot, canvas](const NodeDef* child_node) -> bool { | 228 [this, content, snapshot, canvas](const NodeDef* child_node) -> bool { |
| 220 child_node->RecordPicture(content, snapshot, canvas); | 229 child_node->RecordPicture(content, snapshot, canvas); |
| 221 return true; | 230 return true; |
| 222 }); | 231 }); |
| 223 } | 232 } |
| 224 | 233 |
| 225 RectNodeDef::RectNodeDef(uint32_t node_id, | 234 void NodeDef::HitTest(const SceneContent* content, |
| 226 mojo::TransformPtr content_transform, | 235 const Snapshot* snapshot, |
| 227 mojo::RectPtr content_clip, | 236 const SkPoint& global_point, |
| 228 Combinator combinator, | 237 const SkMatrix& parent_transform, |
| 229 const std::vector<uint32_t>& child_node_ids, | 238 bool* opaque, |
| 230 const mojo::Rect& content_rect, | 239 mojo::Array<mojo::gfx::composition::HitPtr>* hits) const { |
| 231 const mojo::gfx::composition::Color& color) | 240 DCHECK(content); |
| 241 DCHECK(snapshot); | |
| 242 DCHECK(opaque); | |
| 243 DCHECK(hits); | |
| 244 | |
| 245 SkMatrix node_transform = parent_transform; | |
| 246 if (content_transform_) | |
| 247 node_transform.postConcat(content_transform_.To<SkMatrix>()); | |
|
abarth
2016/03/09 04:02:48
I think you want to do this work in 4x4 matrices.
jeffbrown
2016/03/09 20:32:11
You're probably right. Noted for later since this
| |
| 248 if (content_clip_) { | |
| 249 SkRect global_clip_rect; | |
| 250 node_transform.mapRect(&global_clip_rect, content_clip_->To<SkRect>()); | |
|
abarth
2016/03/09 04:02:48
This isn't very efficient because you're doing a m
jeffbrown
2016/03/09 20:32:11
I previously wrote the code that way. The trade-o
| |
| 251 if (!Contains(global_clip_rect, global_point)) | |
| 252 return; | |
| 253 } | |
| 254 | |
| 255 if (!hit_test_behavior_ || !hit_test_behavior_->prune) | |
| 256 HitTestInner(content, snapshot, global_point, node_transform, opaque, hits); | |
| 257 | |
| 258 if (!hit_test_behavior_ || | |
| 259 hit_test_behavior_->visibility == | |
| 260 mojo::gfx::composition::HitTestBehavior::Visibility::INVISIBLE) | |
| 261 return; | |
| 262 | |
| 263 if (hit_test_behavior_->hit_rect) { | |
| 264 SkRect global_hit_rect; | |
| 265 node_transform.mapRect(&global_hit_rect, | |
| 266 hit_test_behavior_->hit_rect->To<SkRect>()); | |
| 267 if (!Contains(global_hit_rect, global_point)) | |
| 268 return; | |
| 269 } | |
| 270 | |
| 271 if (hit_test_behavior_->visibility == | |
| 272 mojo::gfx::composition::HitTestBehavior::Visibility::OPAQUE) | |
| 273 *opaque = true; | |
| 274 | |
| 275 SkMatrix inverse_node_transform; | |
| 276 if (!node_transform.invert(&inverse_node_transform)) { | |
| 277 // Matrix is singular! | |
| 278 // Return [0,0,0][0,0,0][0,0,1] (all zeroes except last component). | |
| 279 // This causes all points to be mapped to (0,0) when transformed. | |
| 280 inverse_node_transform.setScale(0.f, 0.f); | |
| 281 } | |
| 282 | |
| 283 auto hit = mojo::gfx::composition::Hit::New(); | |
| 284 hit->set_node(mojo::gfx::composition::NodeHit::New()); | |
| 285 hit->get_node()->node_id = node_id_; | |
| 286 hit->get_node()->transform = | |
| 287 mojo::ConvertTo<mojo::TransformPtr>(inverse_node_transform); | |
| 288 hits->push_back(hit.Pass()); | |
| 289 } | |
| 290 | |
| 291 void NodeDef::HitTestInner( | |
|
abarth
2016/03/09 04:02:48
s/HitTestInner/HitTestChildren/ ?
jeffbrown
2016/03/09 20:32:11
Strictly speaking it's not just children since ref
| |
| 292 const SceneContent* content, | |
| 293 const Snapshot* snapshot, | |
| 294 const SkPoint& global_point, | |
| 295 const SkMatrix& node_transform, | |
| 296 bool* opaque, | |
| 297 mojo::Array<mojo::gfx::composition::HitPtr>* hits) const { | |
| 298 DCHECK(content); | |
| 299 DCHECK(snapshot); | |
| 300 DCHECK(opaque); | |
| 301 DCHECK(hits); | |
| 302 | |
| 303 // TODO(jeffbrown): Implement a more efficient way to traverse children in | |
| 304 // reverse order. | |
| 305 std::vector<const NodeDef*> children; | |
| 306 TraverseSnapshottedChildren( | |
| 307 content, snapshot, [this, &children](const NodeDef* child_node) -> bool { | |
| 308 children.push_back(child_node); | |
| 309 return true; | |
| 310 }); | |
| 311 | |
| 312 for (auto it = children.crbegin(); it != children.crend(); ++it) { | |
| 313 (*it)->HitTest(content, snapshot, global_point, node_transform, opaque, | |
| 314 hits); | |
| 315 if (*opaque) | |
|
abarth
2016/03/09 04:02:48
In other systems, we've passed this value through
jeffbrown
2016/03/09 20:32:11
SceneContent::HitTest returns a SceneHitPtr as its
| |
| 316 break; | |
| 317 } | |
| 318 } | |
| 319 | |
| 320 RectNodeDef::RectNodeDef( | |
| 321 uint32_t node_id, | |
| 322 mojo::TransformPtr content_transform, | |
| 323 mojo::RectPtr content_clip, | |
| 324 mojo::gfx::composition::HitTestBehaviorPtr hit_test_behavior, | |
| 325 Combinator combinator, | |
| 326 const std::vector<uint32_t>& child_node_ids, | |
| 327 const mojo::Rect& content_rect, | |
| 328 const mojo::gfx::composition::Color& color) | |
| 232 : NodeDef(node_id, | 329 : NodeDef(node_id, |
| 233 content_transform.Pass(), | 330 content_transform.Pass(), |
| 234 content_clip.Pass(), | 331 content_clip.Pass(), |
| 332 hit_test_behavior.Pass(), | |
| 235 combinator, | 333 combinator, |
| 236 child_node_ids), | 334 child_node_ids), |
| 237 content_rect_(content_rect), | 335 content_rect_(content_rect), |
| 238 color_(color) {} | 336 color_(color) {} |
| 239 | 337 |
| 240 RectNodeDef::~RectNodeDef() {} | 338 RectNodeDef::~RectNodeDef() {} |
| 241 | 339 |
| 242 void RectNodeDef::RecordPictureInner(const SceneContent* content, | 340 void RectNodeDef::RecordPictureInner(const SceneContent* content, |
| 243 const Snapshot* snapshot, | 341 const Snapshot* snapshot, |
| 244 SkCanvas* canvas) const { | 342 SkCanvas* canvas) const { |
| 245 DCHECK(content); | 343 DCHECK(content); |
| 246 DCHECK(snapshot); | 344 DCHECK(snapshot); |
| 247 DCHECK(canvas); | 345 DCHECK(canvas); |
| 248 | 346 |
| 249 SkPaint paint; | 347 SkPaint paint; |
| 250 paint.setColor(MakeSkColor(color_)); | 348 paint.setColor(MakeSkColor(color_)); |
| 251 canvas->drawRect(content_rect_.To<SkRect>(), paint); | 349 canvas->drawRect(content_rect_.To<SkRect>(), paint); |
| 252 | 350 |
| 253 NodeDef::RecordPictureInner(content, snapshot, canvas); | 351 NodeDef::RecordPictureInner(content, snapshot, canvas); |
| 254 } | 352 } |
| 255 | 353 |
| 256 ImageNodeDef::ImageNodeDef(uint32_t node_id, | 354 ImageNodeDef::ImageNodeDef( |
| 257 mojo::TransformPtr content_transform, | 355 uint32_t node_id, |
| 258 mojo::RectPtr content_clip, | 356 mojo::TransformPtr content_transform, |
| 259 Combinator combinator, | 357 mojo::RectPtr content_clip, |
| 260 const std::vector<uint32_t>& child_node_ids, | 358 mojo::gfx::composition::HitTestBehaviorPtr hit_test_behavior, |
| 261 const mojo::Rect& content_rect, | 359 Combinator combinator, |
| 262 mojo::RectPtr image_rect, | 360 const std::vector<uint32_t>& child_node_ids, |
| 263 uint32 image_resource_id, | 361 const mojo::Rect& content_rect, |
| 264 mojo::gfx::composition::BlendPtr blend) | 362 mojo::RectPtr image_rect, |
| 363 uint32 image_resource_id, | |
| 364 mojo::gfx::composition::BlendPtr blend) | |
| 265 : NodeDef(node_id, | 365 : NodeDef(node_id, |
| 266 content_transform.Pass(), | 366 content_transform.Pass(), |
| 267 content_clip.Pass(), | 367 content_clip.Pass(), |
| 368 hit_test_behavior.Pass(), | |
| 268 combinator, | 369 combinator, |
| 269 child_node_ids), | 370 child_node_ids), |
| 270 content_rect_(content_rect), | 371 content_rect_(content_rect), |
| 271 image_rect_(image_rect.Pass()), | 372 image_rect_(image_rect.Pass()), |
| 272 image_resource_id_(image_resource_id), | 373 image_resource_id_(image_resource_id), |
| 273 blend_(blend.Pass()) {} | 374 blend_(blend.Pass()) {} |
| 274 | 375 |
| 275 ImageNodeDef::~ImageNodeDef() {} | 376 ImageNodeDef::~ImageNodeDef() {} |
| 276 | 377 |
| 277 bool ImageNodeDef::RecordContent(SceneContentBuilder* builder) const { | 378 bool ImageNodeDef::RecordContent(SceneContentBuilder* builder) const { |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 299 canvas->drawImageRect(image_resource->image()->image().get(), | 400 canvas->drawImageRect(image_resource->image()->image().get(), |
| 300 image_rect_ | 401 image_rect_ |
| 301 ? image_rect_->To<SkRect>() | 402 ? image_rect_->To<SkRect>() |
| 302 : SkRect::MakeWH(image_resource->image()->width(), | 403 : SkRect::MakeWH(image_resource->image()->width(), |
| 303 image_resource->image()->height()), | 404 image_resource->image()->height()), |
| 304 content_rect_.To<SkRect>(), &paint); | 405 content_rect_.To<SkRect>(), &paint); |
| 305 | 406 |
| 306 NodeDef::RecordPictureInner(content, snapshot, canvas); | 407 NodeDef::RecordPictureInner(content, snapshot, canvas); |
| 307 } | 408 } |
| 308 | 409 |
| 309 SceneNodeDef::SceneNodeDef(uint32_t node_id, | 410 SceneNodeDef::SceneNodeDef( |
| 310 mojo::TransformPtr content_transform, | 411 uint32_t node_id, |
| 311 mojo::RectPtr content_clip, | 412 mojo::TransformPtr content_transform, |
| 312 Combinator combinator, | 413 mojo::RectPtr content_clip, |
| 313 const std::vector<uint32_t>& child_node_ids, | 414 mojo::gfx::composition::HitTestBehaviorPtr hit_test_behavior, |
| 314 uint32_t scene_resource_id, | 415 Combinator combinator, |
| 315 uint32_t scene_version) | 416 const std::vector<uint32_t>& child_node_ids, |
| 417 uint32_t scene_resource_id, | |
| 418 uint32_t scene_version) | |
| 316 : NodeDef(node_id, | 419 : NodeDef(node_id, |
| 317 content_transform.Pass(), | 420 content_transform.Pass(), |
| 318 content_clip.Pass(), | 421 content_clip.Pass(), |
| 422 hit_test_behavior.Pass(), | |
| 319 combinator, | 423 combinator, |
| 320 child_node_ids), | 424 child_node_ids), |
| 321 scene_resource_id_(scene_resource_id), | 425 scene_resource_id_(scene_resource_id), |
| 322 scene_version_(scene_version) {} | 426 scene_version_(scene_version) {} |
| 323 | 427 |
| 324 SceneNodeDef::~SceneNodeDef() {} | 428 SceneNodeDef::~SceneNodeDef() {} |
| 325 | 429 |
| 326 bool SceneNodeDef::RecordContent(SceneContentBuilder* builder) const { | 430 bool SceneNodeDef::RecordContent(SceneContentBuilder* builder) const { |
| 327 DCHECK(builder); | 431 DCHECK(builder); |
| 328 | 432 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 361 void SceneNodeDef::RecordPictureInner(const SceneContent* content, | 465 void SceneNodeDef::RecordPictureInner(const SceneContent* content, |
| 362 const Snapshot* snapshot, | 466 const Snapshot* snapshot, |
| 363 SkCanvas* canvas) const { | 467 SkCanvas* canvas) const { |
| 364 DCHECK(content); | 468 DCHECK(content); |
| 365 DCHECK(snapshot); | 469 DCHECK(snapshot); |
| 366 DCHECK(canvas); | 470 DCHECK(canvas); |
| 367 | 471 |
| 368 const SceneContent* resolved_content = | 472 const SceneContent* resolved_content = |
| 369 snapshot->GetResolvedSceneContent(this); | 473 snapshot->GetResolvedSceneContent(this); |
| 370 DCHECK(resolved_content); | 474 DCHECK(resolved_content); |
| 371 | 475 resolved_content->RecordPicture(snapshot, canvas); |
| 372 const NodeDef* root_node = resolved_content->GetRootNodeIfExists(); | |
| 373 DCHECK(root_node); // must have a root otherwise would have been blocked | |
| 374 root_node->RecordPicture(resolved_content, snapshot, canvas); | |
| 375 | 476 |
| 376 NodeDef::RecordPictureInner(content, snapshot, canvas); | 477 NodeDef::RecordPictureInner(content, snapshot, canvas); |
| 377 } | 478 } |
| 378 | 479 |
| 379 LayerNodeDef::LayerNodeDef(uint32_t node_id, | 480 void SceneNodeDef::HitTestInner( |
| 380 mojo::TransformPtr content_transform, | 481 const SceneContent* content, |
| 381 mojo::RectPtr content_clip, | 482 const Snapshot* snapshot, |
| 382 Combinator combinator, | 483 const SkPoint& global_point, |
| 383 const std::vector<uint32_t>& child_node_ids, | 484 const SkMatrix& node_transform, |
| 384 const mojo::Size& size, | 485 bool* opaque, |
| 385 mojo::gfx::composition::BlendPtr blend) | 486 mojo::Array<mojo::gfx::composition::HitPtr>* hits) const { |
| 487 DCHECK(content); | |
| 488 DCHECK(snapshot); | |
| 489 DCHECK(opaque); | |
| 490 DCHECK(hits); | |
| 491 | |
| 492 NodeDef::HitTestInner(content, snapshot, global_point, node_transform, opaque, | |
| 493 hits); | |
|
abarth
2016/03/09 04:02:48
Do we need to test opaque after calling this funct
jeffbrown
2016/03/09 20:32:11
Initially I didn't think so since I was imagining
| |
| 494 | |
| 495 const SceneContent* resolved_content = | |
| 496 snapshot->GetResolvedSceneContent(this); | |
| 497 DCHECK(resolved_content); | |
| 498 mojo::gfx::composition::SceneHitPtr scene_hit = | |
| 499 resolved_content->HitTest(snapshot, global_point, node_transform, opaque); | |
| 500 if (scene_hit) { | |
| 501 auto hit = mojo::gfx::composition::Hit::New(); | |
| 502 hit->set_scene(scene_hit.Pass()); | |
| 503 hits->push_back(hit.Pass()); | |
| 504 } | |
| 505 } | |
| 506 | |
| 507 LayerNodeDef::LayerNodeDef( | |
| 508 uint32_t node_id, | |
| 509 mojo::TransformPtr content_transform, | |
| 510 mojo::RectPtr content_clip, | |
| 511 mojo::gfx::composition::HitTestBehaviorPtr hit_test_behavior, | |
| 512 Combinator combinator, | |
| 513 const std::vector<uint32_t>& child_node_ids, | |
| 514 const mojo::Size& size, | |
| 515 mojo::gfx::composition::BlendPtr blend) | |
| 386 : NodeDef(node_id, | 516 : NodeDef(node_id, |
| 387 content_transform.Pass(), | 517 content_transform.Pass(), |
| 388 content_clip.Pass(), | 518 content_clip.Pass(), |
| 519 hit_test_behavior.Pass(), | |
| 389 combinator, | 520 combinator, |
| 390 child_node_ids), | 521 child_node_ids), |
| 391 size_(size), | 522 size_(size), |
| 392 blend_(blend.Pass()) {} | 523 blend_(blend.Pass()) {} |
| 393 | 524 |
| 394 LayerNodeDef::~LayerNodeDef() {} | 525 LayerNodeDef::~LayerNodeDef() {} |
| 395 | 526 |
| 396 void LayerNodeDef::RecordPictureInner(const SceneContent* content, | 527 void LayerNodeDef::RecordPictureInner(const SceneContent* content, |
| 397 const Snapshot* snapshot, | 528 const Snapshot* snapshot, |
| 398 SkCanvas* canvas) const { | 529 SkCanvas* canvas) const { |
| 399 DCHECK(content); | 530 DCHECK(content); |
| 400 DCHECK(snapshot); | 531 DCHECK(snapshot); |
| 401 DCHECK(canvas); | 532 DCHECK(canvas); |
| 402 | 533 |
| 403 SkPaint paint; | 534 SkPaint paint; |
| 404 SetPaintForBlend(&paint, blend_.get()); | 535 SetPaintForBlend(&paint, blend_.get()); |
| 405 | 536 |
| 406 canvas->saveLayer(SkRect::MakeWH(size_.width, size_.height), &paint); | 537 canvas->saveLayer(SkRect::MakeWH(size_.width, size_.height), &paint); |
| 407 NodeDef::RecordPictureInner(content, snapshot, canvas); | 538 NodeDef::RecordPictureInner(content, snapshot, canvas); |
| 408 canvas->restore(); | 539 canvas->restore(); |
| 409 } | 540 } |
| 410 | 541 |
| 411 } // namespace compositor | 542 } // namespace compositor |
| OLD | NEW |