OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2017 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 "cc/paint/record_paint_canvas.h" | |
6 | |
7 #include "base/memory/ptr_util.h" | |
8 #include "cc/paint/display_item_list.h" | |
9 #include "cc/paint/paint_op_buffer.h" | |
10 #include "cc/paint/paint_record.h" | |
11 #include "cc/paint/paint_recorder.h" | |
12 #include "third_party/skia/include/core/SkAnnotation.h" | |
13 #include "third_party/skia/include/core/SkMetaData.h" | |
14 #include "third_party/skia/include/utils/SkNWayCanvas.h" | |
15 | |
16 namespace cc { | |
17 | |
18 RecordPaintCanvas::RecordPaintCanvas(PaintOpBuffer* buffer, | |
19 const SkRect& cull_rect) | |
20 : buffer_(buffer), canvas_(cull_rect.roundOut()) { | |
21 DCHECK(buffer_); | |
22 } | |
23 | |
24 RecordPaintCanvas::~RecordPaintCanvas() = default; | |
25 | |
26 SkMetaData& RecordPaintCanvas::getMetaData() { | |
27 // This could just be SkMetaData owned by RecordPaintCanvas, but since | |
28 // SkCanvas already has one, we might as well use it directly. | |
29 return canvas_.getMetaData(); | |
30 } | |
31 | |
32 SkImageInfo RecordPaintCanvas::imageInfo() const { | |
33 return canvas_.imageInfo(); | |
34 } | |
35 | |
36 void RecordPaintCanvas::flush() { | |
37 // This is a noop when recording. | |
38 } | |
39 | |
40 SkISize RecordPaintCanvas::getBaseLayerSize() const { | |
41 return canvas_.getBaseLayerSize(); | |
42 } | |
43 | |
44 bool RecordPaintCanvas::readPixels(const SkImageInfo& dest_info, | |
45 void* dest_pixels, | |
46 size_t dest_row_bytes, | |
47 int src_x, | |
48 int src_y) { | |
49 NOTREACHED(); | |
50 return false; | |
51 } | |
52 | |
53 bool RecordPaintCanvas::readPixels(SkBitmap* bitmap, int src_x, int src_y) { | |
54 NOTREACHED(); | |
55 return false; | |
56 } | |
57 | |
58 bool RecordPaintCanvas::readPixels(const SkIRect& srcRect, SkBitmap* bitmap) { | |
59 NOTREACHED(); | |
60 return false; | |
61 } | |
62 | |
63 bool RecordPaintCanvas::writePixels(const SkImageInfo& info, | |
64 const void* pixels, | |
65 size_t row_bytes, | |
66 int x, | |
67 int y) { | |
68 NOTREACHED(); | |
69 return false; | |
70 } | |
71 | |
72 int RecordPaintCanvas::save() { | |
73 buffer_->push<SaveOp>(); | |
74 return canvas_.save(); | |
75 } | |
76 | |
77 int RecordPaintCanvas::saveLayer(const SkRect* bounds, | |
78 const PaintFlags* flags) { | |
79 if (flags) { | |
80 if (flags->IsSimpleOpacity()) { | |
81 // TODO(enne): maybe more callers should know this and call | |
82 // saveLayerAlpha instead of needing to check here. | |
83 return saveLayerAlpha(bounds, SkColorGetA(flags->getColor())); | |
84 } | |
85 | |
86 // TODO(enne): it appears that image filters affect matrices and color | |
87 // matrices affect transparent flags on SkCanvas layers, but it's not clear | |
88 // whether those are actually needed and we could just skip ToSkPaint here. | |
89 buffer_->push<SaveLayerOp>(bounds, flags); | |
90 const SkPaint& paint = ToSkPaint(*flags); | |
91 return canvas_.saveLayer(bounds, &paint); | |
92 } | |
93 buffer_->push<SaveLayerOp>(bounds, flags); | |
94 return canvas_.saveLayer(bounds, nullptr); | |
95 } | |
96 | |
97 int RecordPaintCanvas::saveLayerAlpha(const SkRect* bounds, uint8_t alpha) { | |
98 buffer_->push<SaveLayerAlphaOp>(bounds, alpha); | |
99 return canvas_.saveLayerAlpha(bounds, alpha); | |
100 } | |
101 | |
102 void RecordPaintCanvas::restore() { | |
103 buffer_->push<RestoreOp>(); | |
104 canvas_.restore(); | |
105 } | |
106 | |
107 int RecordPaintCanvas::getSaveCount() const { | |
108 return canvas_.getSaveCount(); | |
109 } | |
110 | |
111 void RecordPaintCanvas::restoreToCount(int save_count) { | |
112 DCHECK_GE(save_count, 1); | |
113 int diff = canvas_.getSaveCount() - save_count; | |
vmpstr
2017/03/28 18:27:15
Probably DCHECK_GE(diff, 0)
enne (OOO)
2017/03/28 19:28:05
Good thought!
| |
114 for (int i = 0; i < diff; ++i) | |
115 restore(); | |
116 } | |
117 | |
118 void RecordPaintCanvas::translate(SkScalar dx, SkScalar dy) { | |
119 buffer_->push<TranslateOp>(dx, dy); | |
120 canvas_.translate(dx, dy); | |
121 } | |
122 | |
123 void RecordPaintCanvas::scale(SkScalar sx, SkScalar sy) { | |
124 buffer_->push<ScaleOp>(sx, sy); | |
125 canvas_.scale(sx, sy); | |
126 } | |
127 | |
128 void RecordPaintCanvas::rotate(SkScalar degrees) { | |
129 buffer_->push<RotateOp>(degrees); | |
130 canvas_.rotate(degrees); | |
131 } | |
132 | |
133 void RecordPaintCanvas::concat(const SkMatrix& matrix) { | |
134 buffer_->push<ConcatOp>(matrix); | |
135 canvas_.concat(matrix); | |
136 } | |
137 | |
138 void RecordPaintCanvas::setMatrix(const SkMatrix& matrix) { | |
139 buffer_->push<SetMatrixOp>(matrix); | |
140 canvas_.setMatrix(matrix); | |
141 } | |
142 | |
143 void RecordPaintCanvas::clipRect(const SkRect& rect, | |
144 SkClipOp op, | |
145 bool antialias) { | |
146 buffer_->push<ClipRectOp>(rect, op, antialias); | |
147 canvas_.clipRect(rect, op, antialias); | |
148 } | |
149 | |
150 void RecordPaintCanvas::clipRRect(const SkRRect& rrect, | |
151 SkClipOp op, | |
152 bool antialias) { | |
153 // TODO(enne): does this happen? Should the caller know this? | |
154 if (rrect.isRect()) { | |
155 clipRect(rrect.getBounds(), op, antialias); | |
156 return; | |
157 } | |
158 buffer_->push<ClipRRectOp>(rrect, op, antialias); | |
159 canvas_.clipRRect(rrect, op, antialias); | |
160 } | |
161 | |
162 void RecordPaintCanvas::clipPath(const SkPath& path, | |
163 SkClipOp op, | |
164 bool antialias) { | |
165 if (!path.isInverseFillType() && canvas_.getTotalMatrix().rectStaysRect()) { | |
166 // TODO(enne): do these cases happen? should the caller know that this isn't | |
167 // a path? | |
168 SkRect rect; | |
169 if (path.isRect(&rect)) { | |
170 clipRect(rect, op, antialias); | |
171 return; | |
172 } | |
173 SkRRect rrect; | |
174 if (path.isOval(&rect)) { | |
175 rrect.setOval(rect); | |
176 clipRRect(rrect, op, antialias); | |
177 return; | |
178 } | |
179 if (path.isRRect(&rrect)) { | |
180 clipRRect(rrect, op, antialias); | |
181 return; | |
182 } | |
183 } | |
184 | |
185 buffer_->push<ClipPathOp>(path, op, antialias); | |
186 canvas_.clipPath(path, op, antialias); | |
187 return; | |
188 } | |
189 | |
190 bool RecordPaintCanvas::quickReject(const SkRect& rect) const { | |
191 return canvas_.quickReject(rect); | |
192 } | |
193 | |
194 bool RecordPaintCanvas::quickReject(const SkPath& path) const { | |
195 return canvas_.quickReject(path); | |
196 } | |
197 | |
198 SkRect RecordPaintCanvas::getLocalClipBounds() const { | |
199 return canvas_.getLocalClipBounds(); | |
200 } | |
201 | |
202 bool RecordPaintCanvas::getLocalClipBounds(SkRect* bounds) const { | |
203 return canvas_.getLocalClipBounds(bounds); | |
204 } | |
205 | |
206 SkIRect RecordPaintCanvas::getDeviceClipBounds() const { | |
207 return canvas_.getDeviceClipBounds(); | |
208 } | |
209 | |
210 bool RecordPaintCanvas::getDeviceClipBounds(SkIRect* bounds) const { | |
211 return canvas_.getDeviceClipBounds(bounds); | |
212 } | |
213 | |
214 void RecordPaintCanvas::drawColor(SkColor color, SkBlendMode mode) { | |
215 buffer_->push<DrawColorOp>(color, mode); | |
216 } | |
217 | |
218 void RecordPaintCanvas::clear(SkColor color) { | |
219 buffer_->push<DrawColorOp>(color, SkBlendMode::kSrc); | |
220 } | |
221 | |
222 void RecordPaintCanvas::drawLine(SkScalar x0, | |
223 SkScalar y0, | |
224 SkScalar x1, | |
225 SkScalar y1, | |
226 const PaintFlags& flags) { | |
227 buffer_->push<DrawLineOp>(x0, y0, x1, y1, flags); | |
228 } | |
229 | |
230 void RecordPaintCanvas::drawRect(const SkRect& rect, const PaintFlags& flags) { | |
231 buffer_->push<DrawRectOp>(rect, flags); | |
232 } | |
233 | |
234 void RecordPaintCanvas::drawIRect(const SkIRect& rect, | |
235 const PaintFlags& flags) { | |
236 buffer_->push<DrawIRectOp>(rect, flags); | |
237 } | |
238 | |
239 void RecordPaintCanvas::drawOval(const SkRect& oval, const PaintFlags& flags) { | |
240 buffer_->push<DrawOvalOp>(oval, flags); | |
241 } | |
242 | |
243 void RecordPaintCanvas::drawRRect(const SkRRect& rrect, | |
244 const PaintFlags& flags) { | |
245 buffer_->push<DrawRRectOp>(rrect, flags); | |
246 } | |
247 | |
248 void RecordPaintCanvas::drawDRRect(const SkRRect& outer, | |
249 const SkRRect& inner, | |
250 const PaintFlags& flags) { | |
251 if (outer.isEmpty()) | |
252 return; | |
253 if (inner.isEmpty()) { | |
254 drawRRect(outer, flags); | |
255 return; | |
256 } | |
257 buffer_->push<DrawDRRectOp>(outer, inner, flags); | |
258 } | |
259 | |
260 void RecordPaintCanvas::drawCircle(SkScalar cx, | |
261 SkScalar cy, | |
262 SkScalar radius, | |
263 const PaintFlags& flags) { | |
264 buffer_->push<DrawCircleOp>(cx, cy, radius, flags); | |
265 } | |
266 | |
267 void RecordPaintCanvas::drawArc(const SkRect& oval, | |
268 SkScalar start_angle, | |
269 SkScalar sweep_angle, | |
270 bool use_center, | |
271 const PaintFlags& flags) { | |
272 buffer_->push<DrawArcOp>(oval, start_angle, sweep_angle, use_center, flags); | |
273 } | |
274 | |
275 void RecordPaintCanvas::drawRoundRect(const SkRect& rect, | |
276 SkScalar rx, | |
277 SkScalar ry, | |
278 const PaintFlags& flags) { | |
279 // TODO(enne): move this into base class? | |
280 if (rx > 0 && ry > 0) { | |
281 SkRRect rrect; | |
282 rrect.setRectXY(rect, rx, ry); | |
283 drawRRect(rrect, flags); | |
284 } else { | |
285 drawRect(rect, flags); | |
286 } | |
287 } | |
288 | |
289 void RecordPaintCanvas::drawPath(const SkPath& path, const PaintFlags& flags) { | |
290 buffer_->push<DrawPathOp>(path, flags); | |
291 } | |
292 | |
293 void RecordPaintCanvas::drawImage(sk_sp<const SkImage> image, | |
294 SkScalar left, | |
295 SkScalar top, | |
296 const PaintFlags* flags) { | |
297 buffer_->push<DrawImageOp>(image, left, top, flags); | |
298 } | |
299 | |
300 void RecordPaintCanvas::drawImageRect(sk_sp<const SkImage> image, | |
301 const SkRect& src, | |
302 const SkRect& dst, | |
303 const PaintFlags* flags, | |
304 SrcRectConstraint constraint) { | |
305 buffer_->push<DrawImageRectOp>(image, src, dst, flags, constraint); | |
306 } | |
307 | |
308 void RecordPaintCanvas::drawBitmap(const SkBitmap& bitmap, | |
309 SkScalar left, | |
310 SkScalar top, | |
311 const PaintFlags* flags) { | |
312 // TODO(enne): Move into base class? | |
313 if (bitmap.drawsNothing()) | |
314 return; | |
315 drawImage(SkImage::MakeFromBitmap(bitmap), left, top, flags); | |
316 } | |
317 | |
318 void RecordPaintCanvas::drawText(const void* text, | |
319 size_t byte_length, | |
320 SkScalar x, | |
321 SkScalar y, | |
322 const PaintFlags& flags) { | |
323 buffer_->push_with_data<DrawTextOp>(text, byte_length, x, y, flags); | |
324 } | |
325 | |
326 void RecordPaintCanvas::drawPosText(const void* text, | |
327 size_t byte_length, | |
328 const SkPoint pos[], | |
329 const PaintFlags& flags) { | |
330 size_t count = ToSkPaint(flags).countText(text, byte_length); | |
331 buffer_->push_with_data_array<DrawPosTextOp>(text, byte_length, pos, count, | |
332 flags); | |
333 } | |
334 | |
335 void RecordPaintCanvas::drawTextBlob(sk_sp<SkTextBlob> blob, | |
336 SkScalar x, | |
337 SkScalar y, | |
338 const PaintFlags& flags) { | |
339 buffer_->push<DrawTextBlobOp>(blob, x, y, flags); | |
340 } | |
341 | |
342 void RecordPaintCanvas::drawDisplayItemList( | |
343 scoped_refptr<DisplayItemList> list) { | |
344 buffer_->push<DrawDisplayItemListOp>(list); | |
345 } | |
346 | |
347 void RecordPaintCanvas::drawPicture(sk_sp<const PaintRecord> record) { | |
348 // TODO(enne): If this is small, maybe flatten it? | |
349 buffer_->push<DrawRecordOp>(record); | |
350 } | |
351 | |
352 bool RecordPaintCanvas::isClipEmpty() const { | |
353 return canvas_.isClipEmpty(); | |
354 } | |
355 | |
356 bool RecordPaintCanvas::isClipRect() const { | |
357 return canvas_.isClipRect(); | |
358 } | |
359 | |
360 const SkMatrix& RecordPaintCanvas::getTotalMatrix() const { | |
361 return canvas_.getTotalMatrix(); | |
362 } | |
363 | |
364 void RecordPaintCanvas::temporary_internal_describeTopLayer( | |
365 SkMatrix* matrix, | |
366 SkIRect* clip_bounds) { | |
367 return canvas_.temporary_internal_describeTopLayer(matrix, clip_bounds); | |
368 } | |
369 | |
370 bool RecordPaintCanvas::ToPixmap(SkPixmap* output) { | |
371 NOTREACHED(); | |
372 return false; | |
373 } | |
374 | |
375 void RecordPaintCanvas::AnnotateRectWithURL(const SkRect& rect, SkData* data) { | |
376 // TODO(enne): Does these annotate functions ever get used in recording? | |
377 // Maybe these can all be noop here? | |
378 NOTREACHED(); | |
379 } | |
380 | |
381 void RecordPaintCanvas::AnnotateNamedDestination(const SkPoint& point, | |
382 SkData* data) { | |
383 NOTREACHED(); | |
384 } | |
385 | |
386 void RecordPaintCanvas::AnnotateLinkToDestination(const SkRect& rect, | |
387 SkData* data) { | |
388 NOTREACHED(); | |
389 } | |
390 | |
391 void RecordPaintCanvas::PlaybackPaintRecord(sk_sp<const PaintRecord> record) { | |
392 drawPicture(record); | |
393 } | |
394 | |
395 } // namespace cc | |
OLD | NEW |