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

Side by Side Diff: cc/paint/record_paint_canvas.cc

Issue 2768143002: Back PaintRecord with PaintOpBuffer instead of SkPicture (Closed)
Patch Set: Rebase, move slow path counting Created 3 years, 8 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 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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698