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

Side by Side Diff: services/gfx/compositor/graph/node_def.cc

Issue 1774373002: Mozart: Implement hit testing. (Closed) Base URL: git@github.com:domokit/mojo.git@moz-4
Patch Set: Created 4 years, 9 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
« no previous file with comments | « services/gfx/compositor/graph/node_def.h ('k') | services/gfx/compositor/graph/scene_content.h » ('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 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
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 bool NodeDef::HitTest(const SceneContent* content,
226 mojo::TransformPtr content_transform, 235 const Snapshot* snapshot,
227 mojo::RectPtr content_clip, 236 const SkPoint& parent_point,
228 Combinator combinator, 237 const SkMatrix& global_to_parent_transform,
229 const std::vector<uint32_t>& child_node_ids, 238 mojo::Array<mojo::gfx::composition::HitPtr>* hits) const {
230 const mojo::Rect& content_rect, 239 DCHECK(content);
231 const mojo::gfx::composition::Color& color) 240 DCHECK(snapshot);
241 DCHECK(hits);
242
243 // TODO(jeffbrown): These calculations should probably be happening using
244 // a 4x4 matrix instead.
245 SkPoint local_point = parent_point;
246 SkMatrix global_to_local_transform = global_to_parent_transform;
247 if (content_transform_) {
248 // TODO(jeffbrown): Cache the inverse transform.
249 // Defer matrix multiplications using a matrix stack.
250 SkMatrix inverse_transform;
251 if (!content_transform_.To<SkMatrix>().invert(&inverse_transform)) {
252 // Matrix is singular!
253 // Return [0,0,0][0,0,0][0,0,1] (all zeroes except last component).
254 // This causes all points to be mapped to (0,0) when transformed.
255 inverse_transform.setScale(0.f, 0.f);
256 }
257 inverse_transform.mapXY(parent_point.x(), parent_point.y(), &local_point);
258 global_to_local_transform.preConcat(inverse_transform);
259 }
260
261 if (content_clip_ && !Contains(content_clip_->To<SkRect>(), local_point))
262 return false;
263
264 bool opaque_children = false;
265 if (!hit_test_behavior_ || !hit_test_behavior_->prune) {
266 opaque_children = HitTestInner(content, snapshot, local_point,
267 global_to_local_transform, hits);
268 }
269
270 return HitTestSelf(content, snapshot, local_point, global_to_local_transform,
271 hits) ||
272 opaque_children;
273 }
274
275 bool NodeDef::HitTestInner(
276 const SceneContent* content,
277 const Snapshot* snapshot,
278 const SkPoint& local_point,
279 const SkMatrix& global_to_local_transform,
280 mojo::Array<mojo::gfx::composition::HitPtr>* hits) const {
281 DCHECK(content);
282 DCHECK(snapshot);
283 DCHECK(hits);
284
285 // TODO(jeffbrown): Implement a more efficient way to traverse children in
286 // reverse order.
287 std::vector<const NodeDef*> children;
288 TraverseSnapshottedChildren(
289 content, snapshot, [this, &children](const NodeDef* child_node) -> bool {
290 children.push_back(child_node);
291 return true;
292 });
293
294 for (auto it = children.crbegin(); it != children.crend(); ++it) {
295 if ((*it)->HitTest(content, snapshot, local_point,
296 global_to_local_transform, hits))
297 return true; // opaque child covering siblings
298 }
299 return false;
300 }
301
302 bool NodeDef::HitTestSelf(
303 const SceneContent* content,
304 const Snapshot* snapshot,
305 const SkPoint& local_point,
306 const SkMatrix& global_to_local_transform,
307 mojo::Array<mojo::gfx::composition::HitPtr>* hits) const {
308 DCHECK(content);
309 DCHECK(snapshot);
310 DCHECK(hits);
311
312 if (!hit_test_behavior_ ||
313 hit_test_behavior_->visibility ==
314 mojo::gfx::composition::HitTestBehavior::Visibility::INVISIBLE)
315 return false;
316
317 if (hit_test_behavior_->hit_rect &&
318 !Contains(hit_test_behavior_->hit_rect->To<SkRect>(), local_point))
319 return false;
320
321 auto hit = mojo::gfx::composition::Hit::New();
322 hit->set_node(mojo::gfx::composition::NodeHit::New());
323 hit->get_node()->node_id = node_id_;
324 hit->get_node()->transform =
325 mojo::ConvertTo<mojo::TransformPtr>(global_to_local_transform);
326 hits->push_back(hit.Pass());
327 return hit_test_behavior_->visibility ==
328 mojo::gfx::composition::HitTestBehavior::Visibility::OPAQUE;
329 }
330
331 RectNodeDef::RectNodeDef(
332 uint32_t node_id,
333 mojo::TransformPtr content_transform,
334 mojo::RectPtr content_clip,
335 mojo::gfx::composition::HitTestBehaviorPtr hit_test_behavior,
336 Combinator combinator,
337 const std::vector<uint32_t>& child_node_ids,
338 const mojo::Rect& content_rect,
339 const mojo::gfx::composition::Color& color)
232 : NodeDef(node_id, 340 : NodeDef(node_id,
233 content_transform.Pass(), 341 content_transform.Pass(),
234 content_clip.Pass(), 342 content_clip.Pass(),
343 hit_test_behavior.Pass(),
235 combinator, 344 combinator,
236 child_node_ids), 345 child_node_ids),
237 content_rect_(content_rect), 346 content_rect_(content_rect),
238 color_(color) {} 347 color_(color) {}
239 348
240 RectNodeDef::~RectNodeDef() {} 349 RectNodeDef::~RectNodeDef() {}
241 350
242 void RectNodeDef::RecordPictureInner(const SceneContent* content, 351 void RectNodeDef::RecordPictureInner(const SceneContent* content,
243 const Snapshot* snapshot, 352 const Snapshot* snapshot,
244 SkCanvas* canvas) const { 353 SkCanvas* canvas) const {
245 DCHECK(content); 354 DCHECK(content);
246 DCHECK(snapshot); 355 DCHECK(snapshot);
247 DCHECK(canvas); 356 DCHECK(canvas);
248 357
249 SkPaint paint; 358 SkPaint paint;
250 paint.setColor(MakeSkColor(color_)); 359 paint.setColor(MakeSkColor(color_));
251 canvas->drawRect(content_rect_.To<SkRect>(), paint); 360 canvas->drawRect(content_rect_.To<SkRect>(), paint);
252 361
253 NodeDef::RecordPictureInner(content, snapshot, canvas); 362 NodeDef::RecordPictureInner(content, snapshot, canvas);
254 } 363 }
255 364
256 ImageNodeDef::ImageNodeDef(uint32_t node_id, 365 ImageNodeDef::ImageNodeDef(
257 mojo::TransformPtr content_transform, 366 uint32_t node_id,
258 mojo::RectPtr content_clip, 367 mojo::TransformPtr content_transform,
259 Combinator combinator, 368 mojo::RectPtr content_clip,
260 const std::vector<uint32_t>& child_node_ids, 369 mojo::gfx::composition::HitTestBehaviorPtr hit_test_behavior,
261 const mojo::Rect& content_rect, 370 Combinator combinator,
262 mojo::RectPtr image_rect, 371 const std::vector<uint32_t>& child_node_ids,
263 uint32 image_resource_id, 372 const mojo::Rect& content_rect,
264 mojo::gfx::composition::BlendPtr blend) 373 mojo::RectPtr image_rect,
374 uint32 image_resource_id,
375 mojo::gfx::composition::BlendPtr blend)
265 : NodeDef(node_id, 376 : NodeDef(node_id,
266 content_transform.Pass(), 377 content_transform.Pass(),
267 content_clip.Pass(), 378 content_clip.Pass(),
379 hit_test_behavior.Pass(),
268 combinator, 380 combinator,
269 child_node_ids), 381 child_node_ids),
270 content_rect_(content_rect), 382 content_rect_(content_rect),
271 image_rect_(image_rect.Pass()), 383 image_rect_(image_rect.Pass()),
272 image_resource_id_(image_resource_id), 384 image_resource_id_(image_resource_id),
273 blend_(blend.Pass()) {} 385 blend_(blend.Pass()) {}
274 386
275 ImageNodeDef::~ImageNodeDef() {} 387 ImageNodeDef::~ImageNodeDef() {}
276 388
277 bool ImageNodeDef::RecordContent(SceneContentBuilder* builder) const { 389 bool ImageNodeDef::RecordContent(SceneContentBuilder* builder) const {
(...skipping 21 matching lines...) Expand all
299 canvas->drawImageRect(image_resource->image()->image().get(), 411 canvas->drawImageRect(image_resource->image()->image().get(),
300 image_rect_ 412 image_rect_
301 ? image_rect_->To<SkRect>() 413 ? image_rect_->To<SkRect>()
302 : SkRect::MakeWH(image_resource->image()->width(), 414 : SkRect::MakeWH(image_resource->image()->width(),
303 image_resource->image()->height()), 415 image_resource->image()->height()),
304 content_rect_.To<SkRect>(), &paint); 416 content_rect_.To<SkRect>(), &paint);
305 417
306 NodeDef::RecordPictureInner(content, snapshot, canvas); 418 NodeDef::RecordPictureInner(content, snapshot, canvas);
307 } 419 }
308 420
309 SceneNodeDef::SceneNodeDef(uint32_t node_id, 421 SceneNodeDef::SceneNodeDef(
310 mojo::TransformPtr content_transform, 422 uint32_t node_id,
311 mojo::RectPtr content_clip, 423 mojo::TransformPtr content_transform,
312 Combinator combinator, 424 mojo::RectPtr content_clip,
313 const std::vector<uint32_t>& child_node_ids, 425 mojo::gfx::composition::HitTestBehaviorPtr hit_test_behavior,
314 uint32_t scene_resource_id, 426 Combinator combinator,
315 uint32_t scene_version) 427 const std::vector<uint32_t>& child_node_ids,
428 uint32_t scene_resource_id,
429 uint32_t scene_version)
316 : NodeDef(node_id, 430 : NodeDef(node_id,
317 content_transform.Pass(), 431 content_transform.Pass(),
318 content_clip.Pass(), 432 content_clip.Pass(),
433 hit_test_behavior.Pass(),
319 combinator, 434 combinator,
320 child_node_ids), 435 child_node_ids),
321 scene_resource_id_(scene_resource_id), 436 scene_resource_id_(scene_resource_id),
322 scene_version_(scene_version) {} 437 scene_version_(scene_version) {}
323 438
324 SceneNodeDef::~SceneNodeDef() {} 439 SceneNodeDef::~SceneNodeDef() {}
325 440
326 bool SceneNodeDef::RecordContent(SceneContentBuilder* builder) const { 441 bool SceneNodeDef::RecordContent(SceneContentBuilder* builder) const {
327 DCHECK(builder); 442 DCHECK(builder);
328 443
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
361 void SceneNodeDef::RecordPictureInner(const SceneContent* content, 476 void SceneNodeDef::RecordPictureInner(const SceneContent* content,
362 const Snapshot* snapshot, 477 const Snapshot* snapshot,
363 SkCanvas* canvas) const { 478 SkCanvas* canvas) const {
364 DCHECK(content); 479 DCHECK(content);
365 DCHECK(snapshot); 480 DCHECK(snapshot);
366 DCHECK(canvas); 481 DCHECK(canvas);
367 482
368 const SceneContent* resolved_content = 483 const SceneContent* resolved_content =
369 snapshot->GetResolvedSceneContent(this); 484 snapshot->GetResolvedSceneContent(this);
370 DCHECK(resolved_content); 485 DCHECK(resolved_content);
486 resolved_content->RecordPicture(snapshot, canvas);
487
488 NodeDef::RecordPictureInner(content, snapshot, canvas);
489 }
490
491 bool SceneNodeDef::HitTestInner(
492 const SceneContent* content,
493 const Snapshot* snapshot,
494 const SkPoint& local_point,
495 const SkMatrix& global_to_local_transform,
496 mojo::Array<mojo::gfx::composition::HitPtr>* hits) const {
497 DCHECK(content);
498 DCHECK(snapshot);
499 DCHECK(hits);
500
501 if (NodeDef::HitTestInner(content, snapshot, local_point,
502 global_to_local_transform, hits))
503 return true; // opaque child covering referenced scene
504
505 const SceneContent* resolved_content =
506 snapshot->GetResolvedSceneContent(this);
507 DCHECK(resolved_content);
371 508
372 const NodeDef* root_node = resolved_content->GetRootNodeIfExists(); 509 mojo::gfx::composition::SceneHitPtr scene_hit;
373 DCHECK(root_node); // must have a root otherwise would have been blocked 510 bool opaque = resolved_content->HitTest(
374 root_node->RecordPicture(resolved_content, snapshot, canvas); 511 snapshot, local_point, global_to_local_transform, &scene_hit);
375 512 if (scene_hit) {
376 NodeDef::RecordPictureInner(content, snapshot, canvas); 513 auto hit = mojo::gfx::composition::Hit::New();
514 hit->set_scene(scene_hit.Pass());
515 hits->push_back(hit.Pass());
516 }
517 return opaque;
377 } 518 }
378 519
379 LayerNodeDef::LayerNodeDef(uint32_t node_id, 520 LayerNodeDef::LayerNodeDef(
380 mojo::TransformPtr content_transform, 521 uint32_t node_id,
381 mojo::RectPtr content_clip, 522 mojo::TransformPtr content_transform,
382 Combinator combinator, 523 mojo::RectPtr content_clip,
383 const std::vector<uint32_t>& child_node_ids, 524 mojo::gfx::composition::HitTestBehaviorPtr hit_test_behavior,
384 const mojo::Size& size, 525 Combinator combinator,
385 mojo::gfx::composition::BlendPtr blend) 526 const std::vector<uint32_t>& child_node_ids,
527 const mojo::Size& size,
528 mojo::gfx::composition::BlendPtr blend)
386 : NodeDef(node_id, 529 : NodeDef(node_id,
387 content_transform.Pass(), 530 content_transform.Pass(),
388 content_clip.Pass(), 531 content_clip.Pass(),
532 hit_test_behavior.Pass(),
389 combinator, 533 combinator,
390 child_node_ids), 534 child_node_ids),
391 size_(size), 535 size_(size),
392 blend_(blend.Pass()) {} 536 blend_(blend.Pass()) {}
393 537
394 LayerNodeDef::~LayerNodeDef() {} 538 LayerNodeDef::~LayerNodeDef() {}
395 539
396 void LayerNodeDef::RecordPictureInner(const SceneContent* content, 540 void LayerNodeDef::RecordPictureInner(const SceneContent* content,
397 const Snapshot* snapshot, 541 const Snapshot* snapshot,
398 SkCanvas* canvas) const { 542 SkCanvas* canvas) const {
399 DCHECK(content); 543 DCHECK(content);
400 DCHECK(snapshot); 544 DCHECK(snapshot);
401 DCHECK(canvas); 545 DCHECK(canvas);
402 546
403 SkPaint paint; 547 SkPaint paint;
404 SetPaintForBlend(&paint, blend_.get()); 548 SetPaintForBlend(&paint, blend_.get());
405 549
406 canvas->saveLayer(SkRect::MakeWH(size_.width, size_.height), &paint); 550 canvas->saveLayer(SkRect::MakeWH(size_.width, size_.height), &paint);
407 NodeDef::RecordPictureInner(content, snapshot, canvas); 551 NodeDef::RecordPictureInner(content, snapshot, canvas);
408 canvas->restore(); 552 canvas->restore();
409 } 553 }
410 554
411 } // namespace compositor 555 } // namespace compositor
OLDNEW
« no previous file with comments | « services/gfx/compositor/graph/node_def.h ('k') | services/gfx/compositor/graph/scene_content.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698