OLD | NEW |
---|---|
(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/render/render_layer.h" | |
6 | |
7 #include "base/logging.h" | |
8 #include "third_party/skia/include/core/SkCanvas.h" | |
9 #include "third_party/skia/include/core/SkPicture.h" | |
10 #include "third_party/skia/include/core/SkPictureRecorder.h" | |
11 | |
12 namespace compositor { | |
13 | |
14 class RenderCommand { | |
15 public: | |
16 RenderCommand() {} | |
17 virtual ~RenderCommand() {} | |
18 | |
19 virtual void Paint(const PaintingScope& painting_scope, SkCanvas* canvas) = 0; | |
20 | |
21 private: | |
22 DISALLOW_COPY_AND_ASSIGN(RenderCommand); | |
23 }; | |
24 | |
25 class PushSceneCommand : public RenderCommand { | |
26 public: | |
27 PushSceneCommand(uint32_t scene_token, uint32_t version) | |
28 : scene_token_(scene_token), version_(version) {} | |
29 ~PushSceneCommand() override {} | |
30 | |
31 void Paint(const PaintingScope& painting_scope, SkCanvas* canvas) override {} | |
32 | |
33 private: | |
34 uint32_t scene_token_; | |
35 uint32_t version_; | |
36 | |
37 DISALLOW_COPY_AND_ASSIGN(PushSceneCommand); | |
38 }; | |
39 | |
40 class PushNodeCommand : public RenderCommand { | |
41 public: | |
42 PushNodeCommand(uint32_t node_id, uint32_t hit_id) | |
43 : node_id_(node_id), hit_id_(hit_id) {} | |
44 ~PushNodeCommand() override {} | |
45 | |
46 void Paint(const PaintingScope& painting_scope, SkCanvas* canvas) override { | |
47 canvas->save(); | |
48 } | |
49 | |
50 private: | |
51 uint32_t node_id_; | |
52 uint32_t hit_id_; | |
53 SkMatrix content_transform_; | |
54 SkPath content_clip_; | |
55 | |
56 DISALLOW_COPY_AND_ASSIGN(PushNodeCommand); | |
57 }; | |
58 | |
59 class PushComplexNodeCommand : public PushNodeCommand { | |
60 public: | |
61 PushComplexNodeCommand(uint32_t node_id, | |
62 uint32_t hit_id, | |
63 const SkMatrix& content_transform, | |
64 const SkPath& content_clip) | |
65 : PushNodeCommand(node_id, hit_id), | |
66 content_transform_(content_transform), | |
67 content_clip_(content_clip) {} | |
68 ~PushComplexNodeCommand() override {} | |
69 | |
70 void Paint(const PaintingScope& painting_scope, SkCanvas* canvas) override { | |
71 PushNodeCommand::Paint(painting_scope, canvas); | |
72 if (!content_transform_.isIdentity()) | |
73 canvas->concat(content_transform_); | |
abarth
2016/01/10 22:55:36
In Flutter (and in Chrome) we optimize the case wh
jeffbrown
2016/01/16 03:28:32
Yeah, this is just to get us off the ground.
| |
74 if (!content_clip_.isEmpty()) | |
75 canvas->clipPath(content_clip_); | |
abarth
2016/01/10 22:55:36
It's strange to group these two operations togethe
jeffbrown
2016/01/16 03:28:32
Eliminating rounded clips for now.
| |
76 } | |
77 | |
78 private: | |
79 SkMatrix content_transform_; | |
80 SkPath content_clip_; | |
81 | |
82 DISALLOW_COPY_AND_ASSIGN(PushComplexNodeCommand); | |
83 }; | |
84 | |
85 class PopNodeCommand : public RenderCommand { | |
86 public: | |
87 PopNodeCommand() {} | |
88 ~PopNodeCommand() override {} | |
89 | |
90 void Paint(const PaintingScope& painting_scope, SkCanvas* canvas) override { | |
91 canvas->restore(); | |
92 } | |
93 | |
94 private: | |
95 DISALLOW_COPY_AND_ASSIGN(PopNodeCommand); | |
96 }; | |
97 | |
98 class DrawRectCommand : public RenderCommand { | |
99 public: | |
100 DrawRectCommand(const SkRect& content_rect, const SkPaint& paint) | |
101 : content_rect_(content_rect), paint_(paint) {} | |
102 ~DrawRectCommand() override {} | |
103 | |
104 void Paint(const PaintingScope& painting_scope, SkCanvas* canvas) override { | |
105 canvas->drawRect(content_rect_, paint_); | |
106 } | |
107 | |
108 private: | |
109 const SkRect content_rect_; | |
110 const SkPaint paint_; | |
111 | |
112 DISALLOW_COPY_AND_ASSIGN(DrawRectCommand); | |
113 }; | |
114 | |
115 class DrawImageCommand : public RenderCommand { | |
116 public: | |
117 DrawImageCommand(const std::shared_ptr<RenderImage>& image, | |
118 const SkRect& content_rect, | |
119 const SkRect& image_rect, | |
120 const SkPaint& paint) | |
121 : image_(image), | |
122 content_rect_(content_rect), | |
123 image_rect_(image_rect), | |
124 paint_(paint) {} | |
125 ~DrawImageCommand() override {} | |
126 | |
127 void Paint(const PaintingScope& painting_scope, SkCanvas* canvas) override { | |
128 skia::RefPtr<SkImage> skia_image = | |
129 painting_scope.painting_cache()->GetSkImage(painting_scope, image_); | |
130 canvas->drawImageRect(skia_image.get(), image_rect_, content_rect_, | |
131 &paint_); | |
132 } | |
133 | |
134 private: | |
135 const std::shared_ptr<RenderImage> image_; | |
136 const SkRect content_rect_; | |
137 const SkRect image_rect_; | |
138 const SkPaint paint_; | |
139 | |
140 DISALLOW_COPY_AND_ASSIGN(DrawImageCommand); | |
141 }; | |
142 | |
143 class DrawLayerCommand : public RenderCommand { | |
144 public: | |
145 explicit DrawLayerCommand(const std::shared_ptr<RenderLayer>& layer) | |
146 : layer_(layer) {} | |
147 ~DrawLayerCommand() override {} | |
148 | |
149 void Paint(const PaintingScope& painting_scope, SkCanvas* canvas) override { | |
150 skia::RefPtr<SkPicture> skia_picture = | |
151 painting_scope.painting_cache()->GetSkPicture(painting_scope, layer_); | |
152 canvas->drawPicture(skia_picture.get()); | |
153 } | |
154 | |
155 private: | |
156 const std::shared_ptr<RenderLayer> layer_; | |
157 | |
158 DISALLOW_COPY_AND_ASSIGN(DrawLayerCommand); | |
159 }; | |
160 | |
161 class DrawSavedLayerCommand : public DrawLayerCommand { | |
162 public: | |
163 DrawSavedLayerCommand(const std::shared_ptr<RenderLayer>& layer, | |
164 const SkRect& content_rect, | |
165 const SkPaint& paint) | |
166 : DrawLayerCommand(layer), content_rect_(content_rect), paint_(paint) {} | |
167 ~DrawSavedLayerCommand() override {} | |
168 | |
169 void Paint(const PaintingScope& painting_scope, SkCanvas* canvas) override { | |
170 canvas->saveLayer(content_rect_, &paint_); | |
171 DrawLayerCommand::Paint(painting_scope, canvas); | |
172 canvas->restore(); | |
173 } | |
174 | |
175 private: | |
176 const SkRect content_rect_; | |
177 const SkPaint paint_; | |
178 | |
179 DISALLOW_COPY_AND_ASSIGN(DrawSavedLayerCommand); | |
180 }; | |
181 | |
182 RenderLayer::RenderLayer(const SkRect& cull_rect) : cull_rect_(cull_rect) {} | |
183 | |
184 RenderLayer::~RenderLayer() {} | |
185 | |
186 skia::RefPtr<SkPicture> RenderLayer::CreateSkPicture( | |
187 const PaintingScope& painting_scope) const { | |
188 SkPictureRecorder recorder; | |
189 SkCanvas* canvas = recorder.beginRecording(cull_rect()); | |
190 DCHECK(canvas); | |
191 | |
192 for (const auto& command : commands_) | |
193 command->Paint(painting_scope, canvas); | |
194 | |
195 canvas->flush(); | |
abarth
2016/01/10 22:55:36
No need for flush here. endRecordingAsPicture is
jeffbrown
2016/01/16 03:28:32
Done.
| |
196 return skia::AdoptRef(recorder.endRecordingAsPicture()); | |
197 } | |
198 | |
199 RenderLayerBuilder::RenderLayerBuilder() : RenderLayerBuilder(nullptr) {} | |
200 | |
201 RenderLayerBuilder::RenderLayerBuilder(const SkRect* cull_rect) | |
202 : layer_(std::make_shared<RenderLayer>(cull_rect ? *cull_rect | |
203 : SkRect::MakeLargest())) { | |
204 } | |
205 | |
206 RenderLayerBuilder::~RenderLayerBuilder() {} | |
207 | |
208 void RenderLayerBuilder::PushScene(uint32_t scene_token, uint32_t version) { | |
209 DCHECK(layer_); | |
210 layer_->commands_.emplace_back(new PushSceneCommand(scene_token, version)); | |
211 } | |
212 | |
213 void RenderLayerBuilder::PopScene() { | |
214 DCHECK(layer_); | |
215 } | |
216 | |
217 void RenderLayerBuilder::PushNode(uint32_t node_id, | |
218 uint32_t hit_id, | |
219 const SkMatrix& content_transform, | |
220 const SkPath& content_clip) { | |
221 DCHECK(layer_); | |
222 if (content_transform.isIdentity() && content_clip.isEmpty()) | |
223 layer_->commands_.emplace_back(new PushNodeCommand(node_id, hit_id)); | |
abarth
2016/01/10 22:55:36
This seems like it will generate a lot of extra sa
jeffbrown
2016/01/16 03:28:32
Oh yeah, it's horrible. Not to mention all of the
| |
224 else | |
225 layer_->commands_.emplace_back(new PushComplexNodeCommand( | |
226 node_id, hit_id, content_transform, content_clip)); | |
227 } | |
228 | |
229 void RenderLayerBuilder::PopNode() { | |
230 DCHECK(layer_); | |
231 layer_->commands_.emplace_back(new PopNodeCommand()); | |
abarth
2016/01/10 22:55:36
This file looks a bit like you're re-implementing
jeffbrown
2016/01/16 03:28:32
I didn't know about SkImageGenerator. So... next
| |
232 } | |
233 | |
234 void RenderLayerBuilder::DrawRect(const SkRect& content_rect, | |
235 const SkPaint& paint) { | |
236 DCHECK(layer_); | |
237 layer_->commands_.emplace_back(new DrawRectCommand(content_rect, paint)); | |
238 } | |
239 | |
240 void RenderLayerBuilder::DrawImage(const std::shared_ptr<RenderImage>& image, | |
241 const SkRect& content_rect, | |
242 const SkRect& image_rect, | |
243 const SkPaint& paint) { | |
244 DCHECK(layer_); | |
245 layer_->commands_.emplace_back( | |
246 new DrawImageCommand(image, content_rect, image_rect, paint)); | |
247 } | |
248 | |
249 void RenderLayerBuilder::DrawLayer(const std::shared_ptr<RenderLayer>& layer) { | |
250 DCHECK(layer_); | |
251 layer_->commands_.emplace_back(new DrawLayerCommand(layer)); | |
252 } | |
253 | |
254 void RenderLayerBuilder::DrawSavedLayer( | |
255 const std::shared_ptr<RenderLayer>& layer, | |
256 const SkRect& content_rect, | |
257 const SkPaint& paint) { | |
258 DCHECK(layer_); | |
259 layer_->commands_.emplace_back( | |
260 new DrawSavedLayerCommand(layer, content_rect, paint)); | |
261 } | |
262 | |
263 std::shared_ptr<RenderLayer> RenderLayerBuilder::Build() { | |
264 return std::move(layer_); | |
265 } | |
266 | |
267 } // namespace compositor | |
OLD | NEW |