| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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/scene_content.h" | 5 #include "services/gfx/compositor/graph/scene_content.h" |
| 6 | 6 |
| 7 #include <ostream> | 7 #include <ostream> |
| 8 | 8 |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "services/gfx/compositor/graph/scene_def.h" | 10 #include "services/gfx/compositor/graph/scene_def.h" |
| 11 | 11 |
| 12 namespace compositor { | 12 namespace compositor { |
| 13 | 13 |
| 14 SceneContent::SceneContent(const SceneLabel& label, | 14 SceneContent::SceneContent(const SceneLabel& label, |
| 15 uint32_t version, | 15 uint32_t version, |
| 16 size_t max_resources, | 16 size_t max_resources, |
| 17 size_t max_nodes) | 17 size_t max_nodes) |
| 18 : label_(label), | 18 : label_(label), |
| 19 version_(version), | 19 version_(version), |
| 20 resources_(max_resources), | 20 resources_(max_resources), |
| 21 nodes_(max_nodes) {} | 21 nodes_(max_nodes) {} |
| 22 | 22 |
| 23 SceneContent::~SceneContent() {} | 23 SceneContent::~SceneContent() {} |
| 24 | 24 |
| 25 void SceneContent::RecordPicture(const Snapshot* snapshot, | 25 void SceneContent::RecordPicture(const Snapshot* snapshot, |
| 26 SkCanvas* canvas) const { | 26 SkCanvas* canvas) const { |
| 27 const NodeDef* root = GetRootNodeIfExists(); | 27 const Node* root = GetRootNodeIfExists(); |
| 28 if (root) | 28 if (root) |
| 29 root->RecordPicture(this, snapshot, canvas); | 29 root->RecordPicture(this, snapshot, canvas); |
| 30 } | 30 } |
| 31 | 31 |
| 32 bool SceneContent::HitTest( | 32 bool SceneContent::HitTest( |
| 33 const Snapshot* snapshot, | 33 const Snapshot* snapshot, |
| 34 const SkPoint& scene_point, | 34 const SkPoint& scene_point, |
| 35 const SkMatrix44& global_to_scene_transform, | 35 const SkMatrix44& global_to_scene_transform, |
| 36 mojo::gfx::composition::SceneHitPtr* out_scene_hit) const { | 36 mojo::gfx::composition::SceneHitPtr* out_scene_hit) const { |
| 37 DCHECK(snapshot); | 37 DCHECK(snapshot); |
| 38 DCHECK(out_scene_hit); | 38 DCHECK(out_scene_hit); |
| 39 | 39 |
| 40 const NodeDef* root = GetRootNodeIfExists(); | 40 const Node* root = GetRootNodeIfExists(); |
| 41 if (!root) | 41 if (!root) |
| 42 return false; | 42 return false; |
| 43 | 43 |
| 44 mojo::Array<mojo::gfx::composition::HitPtr> hits; | 44 mojo::Array<mojo::gfx::composition::HitPtr> hits; |
| 45 bool opaque = root->HitTest(this, snapshot, scene_point, | 45 bool opaque = root->HitTest(this, snapshot, scene_point, |
| 46 global_to_scene_transform, &hits); | 46 global_to_scene_transform, &hits); |
| 47 if (hits.size()) { | 47 if (hits.size()) { |
| 48 auto scene_hit = mojo::gfx::composition::SceneHit::New(); | 48 auto scene_hit = mojo::gfx::composition::SceneHit::New(); |
| 49 scene_hit->scene_token = mojo::gfx::composition::SceneToken::New(); | 49 scene_hit->scene_token = mojo::gfx::composition::SceneToken::New(); |
| 50 scene_hit->scene_token->value = label_.token(); | 50 scene_hit->scene_token->value = label_.token(); |
| 51 scene_hit->scene_version = version_; | 51 scene_hit->scene_version = version_; |
| 52 scene_hit->hits = hits.Pass(); | 52 scene_hit->hits = hits.Pass(); |
| 53 *out_scene_hit = scene_hit.Pass(); | 53 *out_scene_hit = scene_hit.Pass(); |
| 54 } | 54 } |
| 55 return opaque; | 55 return opaque; |
| 56 } | 56 } |
| 57 | 57 |
| 58 const ResourceDef* SceneContent::GetResource( | 58 const Resource* SceneContent::GetResource(uint32_t resource_id, |
| 59 uint32_t resource_id, | 59 Resource::Type resource_type) const { |
| 60 ResourceDef::Type resource_type) const { | |
| 61 auto it = resources_.find(resource_id); | 60 auto it = resources_.find(resource_id); |
| 62 DCHECK(it != resources_.end()); | 61 DCHECK(it != resources_.end()); |
| 63 DCHECK(it->second->type() == resource_type); | 62 DCHECK(it->second->type() == resource_type); |
| 64 return it->second.get(); | 63 return it->second.get(); |
| 65 } | 64 } |
| 66 | 65 |
| 67 const NodeDef* SceneContent::GetNode(uint32_t node_id) const { | 66 const Node* SceneContent::GetNode(uint32_t node_id) const { |
| 68 auto it = nodes_.find(node_id); | 67 auto it = nodes_.find(node_id); |
| 69 DCHECK(it != nodes_.end()); | 68 DCHECK(it != nodes_.end()); |
| 70 return it->second.get(); | 69 return it->second.get(); |
| 71 } | 70 } |
| 72 | 71 |
| 73 const NodeDef* SceneContent::GetRootNodeIfExists() const { | 72 const Node* SceneContent::GetRootNodeIfExists() const { |
| 74 auto it = nodes_.find(mojo::gfx::composition::kSceneRootNodeId); | 73 auto it = nodes_.find(mojo::gfx::composition::kSceneRootNodeId); |
| 75 return it != nodes_.end() ? it->second.get() : nullptr; | 74 return it != nodes_.end() ? it->second.get() : nullptr; |
| 76 } | 75 } |
| 77 | 76 |
| 78 SceneContentBuilder::SceneContentBuilder(const SceneDef* scene, | 77 SceneContentBuilder::SceneContentBuilder(const SceneDef* scene, |
| 79 uint32_t version, | 78 uint32_t version, |
| 80 std::ostream& err, | 79 std::ostream& err, |
| 81 size_t max_resources, | 80 size_t max_resources, |
| 82 size_t max_nodes) | 81 size_t max_nodes) |
| 83 : content_( | 82 : content_( |
| 84 new SceneContent(scene->label(), version, max_resources, max_nodes)), | 83 new SceneContent(scene->label(), version, max_resources, max_nodes)), |
| 85 scene_(scene), | 84 scene_(scene), |
| 86 err_(err) { | 85 err_(err) { |
| 87 DCHECK(scene); | 86 DCHECK(scene); |
| 88 } | 87 } |
| 89 | 88 |
| 90 SceneContentBuilder::~SceneContentBuilder() {} | 89 SceneContentBuilder::~SceneContentBuilder() {} |
| 91 | 90 |
| 92 const ResourceDef* SceneContentBuilder::RequireResource( | 91 const Resource* SceneContentBuilder::RequireResource( |
| 93 uint32_t resource_id, | 92 uint32_t resource_id, |
| 94 ResourceDef::Type resource_type, | 93 Resource::Type resource_type, |
| 95 uint32_t referrer_node_id) { | 94 uint32_t referrer_node_id) { |
| 96 DCHECK(content_); | 95 DCHECK(content_); |
| 97 | 96 |
| 98 auto it = content_->resources_.find(resource_id); | 97 auto it = content_->resources_.find(resource_id); |
| 99 if (it != content_->resources_.end()) | 98 if (it != content_->resources_.end()) |
| 100 return it->second.get(); | 99 return it->second.get(); |
| 101 | 100 |
| 102 const ResourceDef* resource = scene_->FindResource(resource_id); | 101 const Resource* resource = scene_->FindResource(resource_id); |
| 103 if (!resource) { | 102 if (!resource) { |
| 104 err_ << "Missing resource " << resource_id << " referenced from node " | 103 err_ << "Missing resource " << resource_id << " referenced from node " |
| 105 << content_->FormattedLabelForNode(referrer_node_id); | 104 << content_->FormattedLabelForNode(referrer_node_id); |
| 106 return nullptr; | 105 return nullptr; |
| 107 } | 106 } |
| 108 | 107 |
| 109 if (resource->type() != resource_type) { | 108 if (resource->type() != resource_type) { |
| 110 err_ << "Resource " << resource_id << " referenced from node " | 109 err_ << "Resource " << resource_id << " referenced from node " |
| 111 << content_->FormattedLabelForNode(referrer_node_id) | 110 << content_->FormattedLabelForNode(referrer_node_id) |
| 112 << " has incorrect type for its intended usage"; | 111 << " has incorrect type for its intended usage"; |
| 113 return nullptr; | 112 return nullptr; |
| 114 } | 113 } |
| 115 | 114 |
| 116 content_->resources_.emplace(std::make_pair(resource_id, resource)); | 115 content_->resources_.emplace(std::make_pair(resource_id, resource)); |
| 117 return resource; | 116 return resource; |
| 118 } | 117 } |
| 119 | 118 |
| 120 const NodeDef* SceneContentBuilder::RequireNode(uint32_t node_id, | 119 const Node* SceneContentBuilder::RequireNode(uint32_t node_id, |
| 121 uint32_t referrer_node_id) { | 120 uint32_t referrer_node_id) { |
| 122 DCHECK(content_); | 121 DCHECK(content_); |
| 123 | 122 |
| 124 auto it = content_->nodes_.find(node_id); | 123 auto it = content_->nodes_.find(node_id); |
| 125 if (it != content_->nodes_.end()) { | 124 if (it != content_->nodes_.end()) { |
| 126 if (it->second) | 125 if (it->second) |
| 127 return it->second.get(); | 126 return it->second.get(); |
| 128 err_ << "Cycle detected at node " << node_id << " referenced from node " | 127 err_ << "Cycle detected at node " << node_id << " referenced from node " |
| 129 << content_->FormattedLabelForNode(referrer_node_id); | 128 << content_->FormattedLabelForNode(referrer_node_id); |
| 130 return nullptr; | 129 return nullptr; |
| 131 } | 130 } |
| 132 | 131 |
| 133 const NodeDef* node = scene_->FindNode(node_id); | 132 const Node* node = scene_->FindNode(node_id); |
| 134 if (!node) { | 133 if (!node) { |
| 135 err_ << "Missing node " << node_id << " referenced from node " | 134 err_ << "Missing node " << node_id << " referenced from node " |
| 136 << content_->FormattedLabelForNode(referrer_node_id); | 135 << content_->FormattedLabelForNode(referrer_node_id); |
| 137 return nullptr; | 136 return nullptr; |
| 138 } | 137 } |
| 139 | 138 |
| 140 return AddNode(node) ? node : nullptr; | 139 return AddNode(node) ? node : nullptr; |
| 141 } | 140 } |
| 142 | 141 |
| 143 bool SceneContentBuilder::AddNode(const NodeDef* node) { | 142 bool SceneContentBuilder::AddNode(const Node* node) { |
| 144 DCHECK(content_); | 143 DCHECK(content_); |
| 145 DCHECK(node); | 144 DCHECK(node); |
| 146 | 145 |
| 147 // Reserve a spot in the table to mark the node recording in progress. | 146 // Reserve a spot in the table to mark the node recording in progress. |
| 148 DCHECK(content_->nodes_.size() < content_->nodes_.bucket_count()); | 147 DCHECK(content_->nodes_.size() < content_->nodes_.bucket_count()); |
| 149 auto storage = content_->nodes_.emplace(node->node_id(), nullptr); | 148 auto storage = content_->nodes_.emplace(node->node_id(), nullptr); |
| 150 DCHECK(storage.second); | 149 DCHECK(storage.second); |
| 151 | 150 |
| 152 // Record the node's content. | 151 // Record the node's content. |
| 153 // This performs a depth first search of the node. If it succeeds, we | 152 // This performs a depth first search of the node. If it succeeds, we |
| 154 // will know that this part of the graph has no cycles. Note that this | 153 // will know that this part of the graph has no cycles. Note that this |
| 155 // function may recurse back into |AddNode| to add additional nodes. | 154 // function may recurse back into |AddNode| to add additional nodes. |
| 156 if (!node->RecordContent(this)) | 155 if (!node->RecordContent(this)) |
| 157 return false; | 156 return false; |
| 158 | 157 |
| 159 // Store the node in the table. | 158 // Store the node in the table. |
| 160 // It is safe to use the interator returned by emplace even though additional | 159 // It is safe to use the interator returned by emplace even though additional |
| 161 // nodes may have been added since the map's bucket count was initialized | 160 // nodes may have been added since the map's bucket count was initialized |
| 162 // at creation time to the total number of nodes so it should never be | 161 // at creation time to the total number of nodes so it should never be |
| 163 // rehashed during this traversal. | 162 // rehashed during this traversal. |
| 164 storage.first->second = node; | 163 storage.first->second = node; |
| 165 return true; | 164 return true; |
| 166 } | 165 } |
| 167 | 166 |
| 168 scoped_refptr<const SceneContent> SceneContentBuilder::Build() { | 167 scoped_refptr<const SceneContent> SceneContentBuilder::Build() { |
| 169 DCHECK(content_); | 168 DCHECK(content_); |
| 170 | 169 |
| 171 const NodeDef* root = scene_->FindRootNode(); | 170 const Node* root = scene_->FindRootNode(); |
| 172 return !root || AddNode(root) ? std::move(content_) : nullptr; | 171 return !root || AddNode(root) ? std::move(content_) : nullptr; |
| 173 } | 172 } |
| 174 | 173 |
| 175 } // namespace compositor | 174 } // namespace compositor |
| OLD | NEW |