| Index: services/gfx/compositor/graph/node_def.cc
|
| diff --git a/services/gfx/compositor/graph/node_def.cc b/services/gfx/compositor/graph/node_def.cc
|
| index 6a1dfc9a974083244d8bf59ee8bcbe6a2a86f066..ce55a9bd01b0ad7746393a6838604ed885666049 100644
|
| --- a/services/gfx/compositor/graph/node_def.cc
|
| +++ b/services/gfx/compositor/graph/node_def.cc
|
| @@ -15,7 +15,9 @@
|
| #include "services/gfx/compositor/render/render_image.h"
|
| #include "third_party/skia/include/core/SkCanvas.h"
|
| #include "third_party/skia/include/core/SkColor.h"
|
| +#include "third_party/skia/include/core/SkMatrix.h"
|
| #include "third_party/skia/include/core/SkPaint.h"
|
| +#include "third_party/skia/include/core/SkPoint.h"
|
| #include "third_party/skia/include/core/SkRect.h"
|
|
|
| namespace compositor {
|
| @@ -29,16 +31,23 @@ void SetPaintForBlend(SkPaint* paint, mojo::gfx::composition::Blend* blend) {
|
| if (blend)
|
| paint->setAlpha(blend->alpha);
|
| }
|
| +
|
| +bool Contains(const SkRect& bounds, const SkPoint& point) {
|
| + return point.x() >= bounds.left() && point.x() < bounds.right() &&
|
| + point.y() >= bounds.top() && point.y() < bounds.bottom();
|
| +}
|
| } // namespace
|
|
|
| NodeDef::NodeDef(uint32_t node_id,
|
| mojo::TransformPtr content_transform,
|
| mojo::RectPtr content_clip,
|
| + mojo::gfx::composition::HitTestBehaviorPtr hit_test_behavior,
|
| Combinator combinator,
|
| const std::vector<uint32_t>& child_node_ids)
|
| : node_id_(node_id),
|
| content_transform_(content_transform.Pass()),
|
| content_clip_(content_clip.Pass()),
|
| + hit_test_behavior_(hit_test_behavior.Pass()),
|
| combinator_(combinator),
|
| child_node_ids_(child_node_ids) {}
|
|
|
| @@ -222,16 +231,116 @@ void NodeDef::RecordPictureInner(const SceneContent* content,
|
| });
|
| }
|
|
|
| -RectNodeDef::RectNodeDef(uint32_t node_id,
|
| - mojo::TransformPtr content_transform,
|
| - mojo::RectPtr content_clip,
|
| - Combinator combinator,
|
| - const std::vector<uint32_t>& child_node_ids,
|
| - const mojo::Rect& content_rect,
|
| - const mojo::gfx::composition::Color& color)
|
| +bool NodeDef::HitTest(const SceneContent* content,
|
| + const Snapshot* snapshot,
|
| + const SkPoint& parent_point,
|
| + const SkMatrix& global_to_parent_transform,
|
| + mojo::Array<mojo::gfx::composition::HitPtr>* hits) const {
|
| + DCHECK(content);
|
| + DCHECK(snapshot);
|
| + DCHECK(hits);
|
| +
|
| + // TODO(jeffbrown): These calculations should probably be happening using
|
| + // a 4x4 matrix instead.
|
| + SkPoint local_point = parent_point;
|
| + SkMatrix global_to_local_transform = global_to_parent_transform;
|
| + if (content_transform_) {
|
| + // TODO(jeffbrown): Cache the inverse transform.
|
| + // Defer matrix multiplications using a matrix stack.
|
| + SkMatrix inverse_transform;
|
| + if (!content_transform_.To<SkMatrix>().invert(&inverse_transform)) {
|
| + // Matrix is singular!
|
| + // Return [0,0,0][0,0,0][0,0,1] (all zeroes except last component).
|
| + // This causes all points to be mapped to (0,0) when transformed.
|
| + inverse_transform.setScale(0.f, 0.f);
|
| + }
|
| + inverse_transform.mapXY(parent_point.x(), parent_point.y(), &local_point);
|
| + global_to_local_transform.preConcat(inverse_transform);
|
| + }
|
| +
|
| + if (content_clip_ && !Contains(content_clip_->To<SkRect>(), local_point))
|
| + return false;
|
| +
|
| + bool opaque_children = false;
|
| + if (!hit_test_behavior_ || !hit_test_behavior_->prune) {
|
| + opaque_children = HitTestInner(content, snapshot, local_point,
|
| + global_to_local_transform, hits);
|
| + }
|
| +
|
| + return HitTestSelf(content, snapshot, local_point, global_to_local_transform,
|
| + hits) ||
|
| + opaque_children;
|
| +}
|
| +
|
| +bool NodeDef::HitTestInner(
|
| + const SceneContent* content,
|
| + const Snapshot* snapshot,
|
| + const SkPoint& local_point,
|
| + const SkMatrix& global_to_local_transform,
|
| + mojo::Array<mojo::gfx::composition::HitPtr>* hits) const {
|
| + DCHECK(content);
|
| + DCHECK(snapshot);
|
| + DCHECK(hits);
|
| +
|
| + // TODO(jeffbrown): Implement a more efficient way to traverse children in
|
| + // reverse order.
|
| + std::vector<const NodeDef*> children;
|
| + TraverseSnapshottedChildren(
|
| + content, snapshot, [this, &children](const NodeDef* child_node) -> bool {
|
| + children.push_back(child_node);
|
| + return true;
|
| + });
|
| +
|
| + for (auto it = children.crbegin(); it != children.crend(); ++it) {
|
| + if ((*it)->HitTest(content, snapshot, local_point,
|
| + global_to_local_transform, hits))
|
| + return true; // opaque child covering siblings
|
| + }
|
| + return false;
|
| +}
|
| +
|
| +bool NodeDef::HitTestSelf(
|
| + const SceneContent* content,
|
| + const Snapshot* snapshot,
|
| + const SkPoint& local_point,
|
| + const SkMatrix& global_to_local_transform,
|
| + mojo::Array<mojo::gfx::composition::HitPtr>* hits) const {
|
| + DCHECK(content);
|
| + DCHECK(snapshot);
|
| + DCHECK(hits);
|
| +
|
| + if (!hit_test_behavior_ ||
|
| + hit_test_behavior_->visibility ==
|
| + mojo::gfx::composition::HitTestBehavior::Visibility::INVISIBLE)
|
| + return false;
|
| +
|
| + if (hit_test_behavior_->hit_rect &&
|
| + !Contains(hit_test_behavior_->hit_rect->To<SkRect>(), local_point))
|
| + return false;
|
| +
|
| + auto hit = mojo::gfx::composition::Hit::New();
|
| + hit->set_node(mojo::gfx::composition::NodeHit::New());
|
| + hit->get_node()->node_id = node_id_;
|
| + hit->get_node()->transform =
|
| + mojo::ConvertTo<mojo::TransformPtr>(global_to_local_transform);
|
| + hits->push_back(hit.Pass());
|
| + return hit_test_behavior_->visibility ==
|
| + mojo::gfx::composition::HitTestBehavior::Visibility::OPAQUE;
|
| +}
|
| +
|
| +RectNodeDef::RectNodeDef(
|
| + uint32_t node_id,
|
| + mojo::TransformPtr content_transform,
|
| + mojo::RectPtr content_clip,
|
| + mojo::gfx::composition::HitTestBehaviorPtr hit_test_behavior,
|
| + Combinator combinator,
|
| + const std::vector<uint32_t>& child_node_ids,
|
| + const mojo::Rect& content_rect,
|
| + const mojo::gfx::composition::Color& color)
|
| : NodeDef(node_id,
|
| content_transform.Pass(),
|
| content_clip.Pass(),
|
| + hit_test_behavior.Pass(),
|
| combinator,
|
| child_node_ids),
|
| content_rect_(content_rect),
|
| @@ -253,18 +362,21 @@ void RectNodeDef::RecordPictureInner(const SceneContent* content,
|
| NodeDef::RecordPictureInner(content, snapshot, canvas);
|
| }
|
|
|
| -ImageNodeDef::ImageNodeDef(uint32_t node_id,
|
| - mojo::TransformPtr content_transform,
|
| - mojo::RectPtr content_clip,
|
| - Combinator combinator,
|
| - const std::vector<uint32_t>& child_node_ids,
|
| - const mojo::Rect& content_rect,
|
| - mojo::RectPtr image_rect,
|
| - uint32 image_resource_id,
|
| - mojo::gfx::composition::BlendPtr blend)
|
| +ImageNodeDef::ImageNodeDef(
|
| + uint32_t node_id,
|
| + mojo::TransformPtr content_transform,
|
| + mojo::RectPtr content_clip,
|
| + mojo::gfx::composition::HitTestBehaviorPtr hit_test_behavior,
|
| + Combinator combinator,
|
| + const std::vector<uint32_t>& child_node_ids,
|
| + const mojo::Rect& content_rect,
|
| + mojo::RectPtr image_rect,
|
| + uint32 image_resource_id,
|
| + mojo::gfx::composition::BlendPtr blend)
|
| : NodeDef(node_id,
|
| content_transform.Pass(),
|
| content_clip.Pass(),
|
| + hit_test_behavior.Pass(),
|
| combinator,
|
| child_node_ids),
|
| content_rect_(content_rect),
|
| @@ -306,16 +418,19 @@ void ImageNodeDef::RecordPictureInner(const SceneContent* content,
|
| NodeDef::RecordPictureInner(content, snapshot, canvas);
|
| }
|
|
|
| -SceneNodeDef::SceneNodeDef(uint32_t node_id,
|
| - mojo::TransformPtr content_transform,
|
| - mojo::RectPtr content_clip,
|
| - Combinator combinator,
|
| - const std::vector<uint32_t>& child_node_ids,
|
| - uint32_t scene_resource_id,
|
| - uint32_t scene_version)
|
| +SceneNodeDef::SceneNodeDef(
|
| + uint32_t node_id,
|
| + mojo::TransformPtr content_transform,
|
| + mojo::RectPtr content_clip,
|
| + mojo::gfx::composition::HitTestBehaviorPtr hit_test_behavior,
|
| + Combinator combinator,
|
| + const std::vector<uint32_t>& child_node_ids,
|
| + uint32_t scene_resource_id,
|
| + uint32_t scene_version)
|
| : NodeDef(node_id,
|
| content_transform.Pass(),
|
| content_clip.Pass(),
|
| + hit_test_behavior.Pass(),
|
| combinator,
|
| child_node_ids),
|
| scene_resource_id_(scene_resource_id),
|
| @@ -368,24 +483,53 @@ void SceneNodeDef::RecordPictureInner(const SceneContent* content,
|
| const SceneContent* resolved_content =
|
| snapshot->GetResolvedSceneContent(this);
|
| DCHECK(resolved_content);
|
| -
|
| - const NodeDef* root_node = resolved_content->GetRootNodeIfExists();
|
| - DCHECK(root_node); // must have a root otherwise would have been blocked
|
| - root_node->RecordPicture(resolved_content, snapshot, canvas);
|
| + resolved_content->RecordPicture(snapshot, canvas);
|
|
|
| NodeDef::RecordPictureInner(content, snapshot, canvas);
|
| }
|
|
|
| -LayerNodeDef::LayerNodeDef(uint32_t node_id,
|
| - mojo::TransformPtr content_transform,
|
| - mojo::RectPtr content_clip,
|
| - Combinator combinator,
|
| - const std::vector<uint32_t>& child_node_ids,
|
| - const mojo::Size& size,
|
| - mojo::gfx::composition::BlendPtr blend)
|
| +bool SceneNodeDef::HitTestInner(
|
| + const SceneContent* content,
|
| + const Snapshot* snapshot,
|
| + const SkPoint& local_point,
|
| + const SkMatrix& global_to_local_transform,
|
| + mojo::Array<mojo::gfx::composition::HitPtr>* hits) const {
|
| + DCHECK(content);
|
| + DCHECK(snapshot);
|
| + DCHECK(hits);
|
| +
|
| + if (NodeDef::HitTestInner(content, snapshot, local_point,
|
| + global_to_local_transform, hits))
|
| + return true; // opaque child covering referenced scene
|
| +
|
| + const SceneContent* resolved_content =
|
| + snapshot->GetResolvedSceneContent(this);
|
| + DCHECK(resolved_content);
|
| +
|
| + mojo::gfx::composition::SceneHitPtr scene_hit;
|
| + bool opaque = resolved_content->HitTest(
|
| + snapshot, local_point, global_to_local_transform, &scene_hit);
|
| + if (scene_hit) {
|
| + auto hit = mojo::gfx::composition::Hit::New();
|
| + hit->set_scene(scene_hit.Pass());
|
| + hits->push_back(hit.Pass());
|
| + }
|
| + return opaque;
|
| +}
|
| +
|
| +LayerNodeDef::LayerNodeDef(
|
| + uint32_t node_id,
|
| + mojo::TransformPtr content_transform,
|
| + mojo::RectPtr content_clip,
|
| + mojo::gfx::composition::HitTestBehaviorPtr hit_test_behavior,
|
| + Combinator combinator,
|
| + const std::vector<uint32_t>& child_node_ids,
|
| + const mojo::Size& size,
|
| + mojo::gfx::composition::BlendPtr blend)
|
| : NodeDef(node_id,
|
| content_transform.Pass(),
|
| content_clip.Pass(),
|
| + hit_test_behavior.Pass(),
|
| combinator,
|
| child_node_ids),
|
| size_(size),
|
|
|