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

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

Issue 1552963002: Initial checkin of the new Mozart compositor. (Closed) Base URL: git@github.com:domokit/mojo.git@moz-11
Patch Set: Created 4 years, 11 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
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "services/gfx/compositor/graph/node_def.h"
6
7 #include <sstream>
8
9 #include "base/logging.h"
10 #include "mojo/services/gfx/composition/cpp/logging.h"
11 #include "services/gfx/compositor/graph/scene_def.h"
12 #include "services/gfx/compositor/graph/snapshot.h"
13 #include "services/gfx/compositor/render/render_image.h"
14 #include "services/gfx/compositor/render/render_layer.h"
15
16 namespace compositor {
17
18 // TODO(jeffbrown): Move these conversion functions somewhere more useful.
abarth 2016/01/10 22:55:36 There's a converters directory in mojo/common. Ma
jeffbrown 2016/01/16 03:28:32 Yeah... but maybe later. :)
19
20 static SkRect ToSkRect(const mojo::Rect& rect) {
abarth 2016/01/10 22:55:36 The mojo types have template magic to make these s
21 return SkRect::MakeXYWH(rect.x, rect.y, rect.width, rect.height);
22 }
23
24 static SkRRect ToSkRRect(const mojo::RRect& rrect) {
25 SkVector radii[4] = {
26 {rrect.top_left_radius_x, rrect.top_left_radius_y},
27 {rrect.top_right_radius_x, rrect.top_right_radius_y},
28 {rrect.bottom_left_radius_x, rrect.bottom_left_radius_y},
29 {rrect.bottom_right_radius_x, rrect.bottom_right_radius_y}};
30 SkRRect result;
31 result.setRectRadii(
32 SkRect::MakeXYWH(rrect.x, rrect.y, rrect.width, rrect.height), radii);
abarth 2016/01/10 22:55:35 Note that this routine is more expensive that setR
jeffbrown 2016/01/16 03:28:32 Yes, but we don't know whether we're in the fast c
33 return result;
34 }
35
36 static SkMatrix ToSkMatrix(const mojo::Transform& transform) {
37 // TODO(jeffbrown): What to do with the Z components?
38 // Perhaps we need a simpler 2D transform matrix mojom.
abarth 2016/01/10 22:55:36 This is the same thing we do in Flutter. We can t
jeffbrown 2016/01/16 03:28:32 Acknowledged.
39 SkMatrix result;
40 result.setAll(transform.matrix[0], transform.matrix[1], transform.matrix[3],
41 transform.matrix[4], transform.matrix[5], transform.matrix[7],
42 transform.matrix[12], transform.matrix[13],
43 transform.matrix[15]);
44 return result;
45 }
46
47 static SkColor ToSkColor(const mojo::gfx::composition::Color& color) {
48 return SkColorSetARGBInline(color.alpha, color.red, color.green, color.blue);
49 }
50
51 static SkPath ToSkPath(const mojo::gfx::composition::Clip& clip) {
52 SkPath result;
53 if (clip.is_rect()) {
54 result.addRect(ToSkRect(*clip.get_rect()));
abarth 2016/01/10 22:55:36 Woah there. I haven't seen where you're using thi
jeffbrown 2016/01/16 03:28:32 Dropping RRect clips for now.
55 } else if (clip.is_rect()) {
56 result.addRRect(ToSkRRect(*clip.get_rrect()));
57 } else {
58 DCHECK(false); // was checked during validation
59 }
60 return result;
61 }
62
63 static SkPaint ToSkPaint(const mojo::gfx::composition::Blend& blend) {
64 SkPaint result;
65 result.setAlpha(blend.alpha);
66 return result;
67 }
68
69 NodeDef::NodeDef(uint32_t node_id,
70 mojo::TransformPtr content_transform,
71 mojo::gfx::composition::ClipPtr content_clip,
72 uint32_t hit_id,
73 Combinator combinator,
74 const std::vector<uint32_t>& child_node_ids,
75 NodeOp* op)
76 : node_id_(node_id),
77 content_transform_(content_transform.Pass()),
78 content_clip_(content_clip.Pass()),
79 hit_id_(hit_id),
80 combinator_(combinator),
81 child_node_ids_(child_node_ids),
82 op_(op) {}
83
84 NodeDef::~NodeDef() {}
85
86 bool NodeDef::Validate(SceneDef* scene, std::ostream& err) {
87 if (content_clip_) {
88 if (!content_clip_->is_rect() && !content_clip_->is_rrect()) {
89 err << "Node contains unsupported content clip type: "
90 << FormattedLabel(scene);
91 return false;
92 }
93 }
94
95 child_nodes_.clear();
96 for (uint32_t child_node_id : child_node_ids_) {
97 NodeDef* child_node = scene->FindNode(child_node_id);
98 if (!child_node) {
99 err << "Node refers to unknown child: " << FormattedLabel(scene)
100 << ", child_node_id=" << child_node_id;
101 return false;
102 }
103 child_nodes_.push_back(child_node);
104 }
105
106 return !op_ || op_->Validate(scene, this, err);
107 }
108
109 bool NodeDef::Snapshot(SnapshotBuilder* snapshot_builder,
110 RenderLayerBuilder* layer_builder,
111 SceneDef* scene) {
112 DCHECK(snapshot_builder);
113 DCHECK(layer_builder);
114 DCHECK(scene);
115
116 // Detect cycles.
117 if (visited_) {
118 if (snapshot_builder->block_log()) {
119 *snapshot_builder->block_log()
120 << "Node blocked due to recursive cycle: " << FormattedLabel(scene)
121 << std::endl;
122 }
123 return false;
124 }
125
126 // Snapshot the contents of the node.
127 visited_ = true;
128 bool success = SnapshotInner(snapshot_builder, layer_builder, scene);
129 visited_ = false;
130 return success;
131 }
132
133 bool NodeDef::SnapshotInner(SnapshotBuilder* snapshot_builder,
134 RenderLayerBuilder* layer_builder,
135 SceneDef* scene) {
136 // TODO(jeffbrown): Frequently referenced and reused nodes, especially
137 // layer nodes, may benefit from caching.
138 layer_builder->PushNode(
139 node_id_, hit_id_,
140 content_transform_ ? ToSkMatrix(*content_transform_) : SkMatrix::I(),
141 content_clip_ ? ToSkPath(*content_clip_) : SkPath());
142
143 bool success =
144 op_ ? op_->Snapshot(snapshot_builder, layer_builder, scene, this)
145 : SnapshotChildren(snapshot_builder, layer_builder, scene);
146 if (!success)
147 return false;
148
149 layer_builder->PopNode();
150 return true;
151 }
152
153 bool NodeDef::SnapshotChildren(SnapshotBuilder* snapshot_builder,
154 RenderLayerBuilder* layer_builder,
155 SceneDef* scene) {
156 DCHECK(snapshot_builder);
157 DCHECK(layer_builder);
158 DCHECK(scene);
159
160 switch (combinator_) {
161 // MERGE: All or nothing.
162 case Combinator::MERGE: {
163 for (NodeDef* child_node : child_nodes_) {
164 if (!child_node->Snapshot(snapshot_builder, layer_builder, scene)) {
165 if (snapshot_builder->block_log()) {
166 *snapshot_builder->block_log()
167 << "Node with MERGE combinator blocked since "
168 "one of its children is blocked: "
169 << FormattedLabel(scene) << ", blocked child "
170 << child_node->FormattedLabel(scene) << std::endl;
171 }
172 return false; // blocked
173 }
174 }
175 return true;
176 }
177
178 // PRUNE: Silently discard blocked children.
179 case Combinator::PRUNE: {
180 for (NodeDef* child_node : child_nodes_) {
181 RenderLayerBuilder child_layer_builder;
182 if (child_node->Snapshot(snapshot_builder, &child_layer_builder,
183 scene)) {
184 layer_builder->DrawLayer(child_layer_builder.Build());
185 }
186 }
187 return true;
188 }
189
190 // FALLBACK: Keep only the first unblocked child.
191 case Combinator::FALLBACK: {
192 if (child_nodes_.empty())
193 return true;
194 for (NodeDef* child_node : child_nodes_) {
195 RenderLayerBuilder child_layer_builder;
196 if (child_node->Snapshot(snapshot_builder, &child_layer_builder,
197 scene)) {
198 layer_builder->DrawLayer(child_layer_builder.Build());
199 return true;
200 }
201 }
202 if (snapshot_builder->block_log()) {
203 *snapshot_builder->block_log()
204 << "Node with FALLBACK combinator blocked since "
205 "all of its children are blocked: "
206 << FormattedLabel(scene) << std::endl;
207 }
208 return false; // blocked
209 }
210 }
211 }
212
213 std::string NodeDef::FormattedLabel(SceneDef* scene) {
214 std::ostringstream s;
215 s << scene->FormattedLabel() << "[" << node_id_ << "]";
216 return s.str();
abarth 2016/01/10 22:55:35 base::StringPrintf
jeffbrown 2016/01/16 03:28:32 Done.
217 }
218
219 bool NodeOp::Validate(SceneDef* scene, NodeDef* node, std::ostream& err) {
220 return true;
221 }
222
223 RectNodeOp::RectNodeOp(const mojo::Rect& content_rect,
224 const mojo::gfx::composition::Color& color)
225 : content_rect_(content_rect), color_(color) {}
226
227 RectNodeOp::~RectNodeOp() {}
228
229 bool RectNodeOp::Snapshot(SnapshotBuilder* snapshot_builder,
230 RenderLayerBuilder* layer_builder,
231 SceneDef* scene,
232 NodeDef* node) {
233 if (!node->SnapshotChildren(snapshot_builder, layer_builder, scene))
234 return false;
235
236 SkPaint paint;
237 paint.setColor(ToSkColor(color_));
238 layer_builder->DrawRect(ToSkRect(content_rect_), paint);
239 return true;
240 }
241
242 ImageNodeOp::ImageNodeOp(const mojo::Rect& content_rect,
243 mojo::RectPtr image_rect,
244 uint32 image_resource_id,
245 mojo::gfx::composition::BlendPtr blend)
246 : content_rect_(content_rect),
247 image_rect_(image_rect.Pass()),
248 image_resource_id_(image_resource_id),
249 blend_(blend.Pass()) {}
250
251 ImageNodeOp::~ImageNodeOp() {}
252
253 bool ImageNodeOp::Validate(SceneDef* scene, NodeDef* node, std::ostream& err) {
254 image_resource_ = scene->FindImageResource(image_resource_id_);
255 if (!image_resource_) {
256 err << "Node refers to unknown or invalid image resource: "
257 << node->FormattedLabel(scene)
258 << ", image_resource_id=" << image_resource_id_;
259 return false;
260 }
261 return true;
262 }
263
264 bool ImageNodeOp::Snapshot(SnapshotBuilder* snapshot_builder,
265 RenderLayerBuilder* layer_builder,
266 SceneDef* scene,
267 NodeDef* node) {
268 DCHECK(image_resource_);
269
270 if (!image_resource_->image()) {
271 if (snapshot_builder->block_log()) {
272 *snapshot_builder->block_log()
273 << "Node blocked due to its referenced image "
274 "resource being unavailable: "
275 << node->FormattedLabel(scene) << std::endl;
276 }
277 return false;
278 }
279
280 if (!node->SnapshotChildren(snapshot_builder, layer_builder, scene))
281 return false;
282
283 layer_builder->DrawImage(
284 image_resource_->image(), ToSkRect(content_rect_),
285 image_rect_ ? ToSkRect(*image_rect_)
286 : SkRect::MakeWH(image_resource_->image()->width(),
287 image_resource_->image()->height()),
288 blend_ ? ToSkPaint(*blend_) : SkPaint());
289 return true;
290 }
291
292 SceneNodeOp::SceneNodeOp(uint32_t scene_resource_id, uint32_t scene_version)
293 : scene_resource_id_(scene_resource_id), scene_version_(scene_version) {}
294
295 SceneNodeOp::~SceneNodeOp() {}
296
297 bool SceneNodeOp::Validate(SceneDef* scene, NodeDef* node, std::ostream& err) {
298 scene_resource_ = scene->FindSceneResource(scene_resource_id_);
299 if (!scene_resource_) {
300 err << "Node refers to unknown or invalid scene resource: "
301 << node->FormattedLabel(scene)
302 << ", scene_resource_id=" << scene_resource_id_;
303 return false;
304 }
305 return true;
306 }
307
308 bool SceneNodeOp::Snapshot(SnapshotBuilder* snapshot_builder,
309 RenderLayerBuilder* layer_builder,
310 SceneDef* scene,
311 NodeDef* node) {
312 DCHECK(scene_resource_);
313
314 SceneDef* referenced_scene = scene_resource_->referenced_scene();
315 if (!referenced_scene) {
316 if (snapshot_builder->block_log()) {
317 *snapshot_builder->block_log()
318 << "Node blocked due to its referenced scene "
319 "resource being unavailable: "
320 << node->FormattedLabel(scene) << std::endl;
321 }
322 return false;
323 }
324
325 uint32_t actual_version = referenced_scene->version();
326 if (scene_version_ != mojo::gfx::composition::kSceneVersionNone &&
327 actual_version != mojo::gfx::composition::kSceneVersionNone &&
328 scene_version_ != actual_version) {
329 if (snapshot_builder->block_log()) {
330 *snapshot_builder->block_log()
331 << "Node blocked due to its referenced scene "
332 "resource not having the desired version: "
333 << node->FormattedLabel(scene)
334 << ", requested_version=" << scene_version_
335 << ", actual_version=" << actual_version << std::endl;
336 }
337 return false;
338 }
339
340 if (!node->SnapshotChildren(snapshot_builder, layer_builder, scene))
341 return false;
342
343 return referenced_scene->Snapshot(snapshot_builder, layer_builder);
344 }
345
346 LayerNodeOp::LayerNodeOp(const mojo::Size& size,
347 mojo::gfx::composition::BlendPtr blend)
348 : size_(size), blend_(blend.Pass()) {}
349
350 LayerNodeOp::~LayerNodeOp() {}
351
352 bool LayerNodeOp::Snapshot(SnapshotBuilder* snapshot_builder,
353 RenderLayerBuilder* layer_builder,
354 SceneDef* scene,
355 NodeDef* node) {
356 SkRect content_rect = SkRect::MakeWH(size_.width, size_.height);
357 RenderLayerBuilder children_layer_builder(&content_rect);
358 if (!node->SnapshotChildren(snapshot_builder, &children_layer_builder, scene))
359 return false;
360
361 layer_builder->DrawSavedLayer(children_layer_builder.Build(), content_rect,
362 blend_ ? ToSkPaint(*blend_) : SkPaint());
363 return true;
364 }
365
366 } // namespace compositor
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698