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 |