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

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

Issue 2768143002: Back PaintRecord with PaintOpBuffer instead of SkPicture (Closed)
Patch Set: Fix win build 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 uint8_t alpha = SkColorGetA(flags->getColor());
84 return saveLayerAlpha(bounds, alpha);
85 }
86
87 // TODO(enne): it appears that image filters affect matrices and color
88 // matrices affect transparent flags on SkCanvas layers, but it's not clear
89 // whether those are actually needed and we could just skip ToSkPaint here.
90 buffer_->push<SaveLayerOp>(bounds, flags);
91 const SkPaint& paint = ToSkPaint(*flags);
92 return canvas_.saveLayer(bounds, &paint);
93 }
94 buffer_->push<SaveLayerOp>(bounds, flags);
95 return canvas_.saveLayer(bounds, nullptr);
96 }
97
98 int RecordPaintCanvas::saveLayerAlpha(const SkRect* bounds, uint8_t alpha) {
99 buffer_->push<SaveLayerAlphaOp>(bounds, alpha);
100 return canvas_.saveLayerAlpha(bounds, alpha);
101 }
102
103 void RecordPaintCanvas::restore() {
104 buffer_->push<RestoreOp>();
105 canvas_.restore();
106 }
107
108 int RecordPaintCanvas::getSaveCount() const {
109 return canvas_.getSaveCount();
110 }
111
112 void RecordPaintCanvas::restoreToCount(int save_count) {
113 DCHECK_GE(save_count, 1);
114 int diff = canvas_.getSaveCount() - save_count;
115 DCHECK_GE(diff, 0);
116 for (int i = 0; i < diff; ++i)
117 restore();
118 }
119
120 void RecordPaintCanvas::translate(SkScalar dx, SkScalar dy) {
121 buffer_->push<TranslateOp>(dx, dy);
122 canvas_.translate(dx, dy);
123 }
124
125 void RecordPaintCanvas::scale(SkScalar sx, SkScalar sy) {
126 buffer_->push<ScaleOp>(sx, sy);
127 canvas_.scale(sx, sy);
128 }
129
130 void RecordPaintCanvas::rotate(SkScalar degrees) {
131 buffer_->push<RotateOp>(degrees);
132 canvas_.rotate(degrees);
133 }
134
135 void RecordPaintCanvas::concat(const SkMatrix& matrix) {
136 buffer_->push<ConcatOp>(matrix);
137 canvas_.concat(matrix);
138 }
139
140 void RecordPaintCanvas::setMatrix(const SkMatrix& matrix) {
141 buffer_->push<SetMatrixOp>(matrix);
142 canvas_.setMatrix(matrix);
143 }
144
145 void RecordPaintCanvas::clipRect(const SkRect& rect,
146 SkClipOp op,
147 bool antialias) {
148 buffer_->push<ClipRectOp>(rect, op, antialias);
149 canvas_.clipRect(rect, op, antialias);
150 }
151
152 void RecordPaintCanvas::clipRRect(const SkRRect& rrect,
153 SkClipOp op,
154 bool antialias) {
155 // TODO(enne): does this happen? Should the caller know this?
156 if (rrect.isRect()) {
157 clipRect(rrect.getBounds(), op, antialias);
158 return;
159 }
160 buffer_->push<ClipRRectOp>(rrect, op, antialias);
161 canvas_.clipRRect(rrect, op, antialias);
162 }
163
164 void RecordPaintCanvas::clipPath(const SkPath& path,
165 SkClipOp op,
166 bool antialias) {
167 if (!path.isInverseFillType() && canvas_.getTotalMatrix().rectStaysRect()) {
168 // TODO(enne): do these cases happen? should the caller know that this isn't
169 // a path?
170 SkRect rect;
171 if (path.isRect(&rect)) {
172 clipRect(rect, op, antialias);
173 return;
174 }
175 SkRRect rrect;
176 if (path.isOval(&rect)) {
177 rrect.setOval(rect);
178 clipRRect(rrect, op, antialias);
179 return;
180 }
181 if (path.isRRect(&rrect)) {
182 clipRRect(rrect, op, antialias);
183 return;
184 }
185 }
186
187 buffer_->push<ClipPathOp>(path, op, antialias);
188 canvas_.clipPath(path, op, antialias);
189 return;
190 }
191
192 bool RecordPaintCanvas::quickReject(const SkRect& rect) const {
193 return canvas_.quickReject(rect);
194 }
195
196 bool RecordPaintCanvas::quickReject(const SkPath& path) const {
197 return canvas_.quickReject(path);
198 }
199
200 SkRect RecordPaintCanvas::getLocalClipBounds() const {
201 return canvas_.getLocalClipBounds();
202 }
203
204 bool RecordPaintCanvas::getLocalClipBounds(SkRect* bounds) const {
205 return canvas_.getLocalClipBounds(bounds);
206 }
207
208 SkIRect RecordPaintCanvas::getDeviceClipBounds() const {
209 return canvas_.getDeviceClipBounds();
210 }
211
212 bool RecordPaintCanvas::getDeviceClipBounds(SkIRect* bounds) const {
213 return canvas_.getDeviceClipBounds(bounds);
214 }
215
216 void RecordPaintCanvas::drawColor(SkColor color, SkBlendMode mode) {
217 buffer_->push<DrawColorOp>(color, mode);
218 }
219
220 void RecordPaintCanvas::clear(SkColor color) {
221 buffer_->push<DrawColorOp>(color, SkBlendMode::kSrc);
222 }
223
224 void RecordPaintCanvas::drawLine(SkScalar x0,
225 SkScalar y0,
226 SkScalar x1,
227 SkScalar y1,
228 const PaintFlags& flags) {
229 buffer_->push<DrawLineOp>(x0, y0, x1, y1, flags);
230 }
231
232 void RecordPaintCanvas::drawRect(const SkRect& rect, const PaintFlags& flags) {
233 buffer_->push<DrawRectOp>(rect, flags);
234 }
235
236 void RecordPaintCanvas::drawIRect(const SkIRect& rect,
237 const PaintFlags& flags) {
238 buffer_->push<DrawIRectOp>(rect, flags);
239 }
240
241 void RecordPaintCanvas::drawOval(const SkRect& oval, const PaintFlags& flags) {
242 buffer_->push<DrawOvalOp>(oval, flags);
243 }
244
245 void RecordPaintCanvas::drawRRect(const SkRRect& rrect,
246 const PaintFlags& flags) {
247 buffer_->push<DrawRRectOp>(rrect, flags);
248 }
249
250 void RecordPaintCanvas::drawDRRect(const SkRRect& outer,
251 const SkRRect& inner,
252 const PaintFlags& flags) {
253 if (outer.isEmpty())
254 return;
255 if (inner.isEmpty()) {
256 drawRRect(outer, flags);
257 return;
258 }
259 buffer_->push<DrawDRRectOp>(outer, inner, flags);
260 }
261
262 void RecordPaintCanvas::drawCircle(SkScalar cx,
263 SkScalar cy,
264 SkScalar radius,
265 const PaintFlags& flags) {
266 buffer_->push<DrawCircleOp>(cx, cy, radius, flags);
267 }
268
269 void RecordPaintCanvas::drawArc(const SkRect& oval,
270 SkScalar start_angle,
271 SkScalar sweep_angle,
272 bool use_center,
273 const PaintFlags& flags) {
274 buffer_->push<DrawArcOp>(oval, start_angle, sweep_angle, use_center, flags);
275 }
276
277 void RecordPaintCanvas::drawRoundRect(const SkRect& rect,
278 SkScalar rx,
279 SkScalar ry,
280 const PaintFlags& flags) {
281 // TODO(enne): move this into base class?
282 if (rx > 0 && ry > 0) {
283 SkRRect rrect;
284 rrect.setRectXY(rect, rx, ry);
285 drawRRect(rrect, flags);
286 } else {
287 drawRect(rect, flags);
288 }
289 }
290
291 void RecordPaintCanvas::drawPath(const SkPath& path, const PaintFlags& flags) {
292 buffer_->push<DrawPathOp>(path, flags);
293 }
294
295 void RecordPaintCanvas::drawImage(sk_sp<const SkImage> image,
296 SkScalar left,
297 SkScalar top,
298 const PaintFlags* flags) {
299 buffer_->push<DrawImageOp>(image, left, top, flags);
300 }
301
302 void RecordPaintCanvas::drawImageRect(sk_sp<const SkImage> image,
303 const SkRect& src,
304 const SkRect& dst,
305 const PaintFlags* flags,
306 SrcRectConstraint constraint) {
307 buffer_->push<DrawImageRectOp>(image, src, dst, flags, constraint);
308 }
309
310 void RecordPaintCanvas::drawBitmap(const SkBitmap& bitmap,
311 SkScalar left,
312 SkScalar top,
313 const PaintFlags* flags) {
314 // TODO(enne): Move into base class?
315 if (bitmap.drawsNothing())
316 return;
317 drawImage(SkImage::MakeFromBitmap(bitmap), left, top, flags);
318 }
319
320 void RecordPaintCanvas::drawText(const void* text,
321 size_t byte_length,
322 SkScalar x,
323 SkScalar y,
324 const PaintFlags& flags) {
325 buffer_->push_with_data<DrawTextOp>(text, byte_length, x, y, flags);
326 }
327
328 void RecordPaintCanvas::drawPosText(const void* text,
329 size_t byte_length,
330 const SkPoint pos[],
331 const PaintFlags& flags) {
332 size_t count = ToSkPaint(flags).countText(text, byte_length);
333 buffer_->push_with_data_array<DrawPosTextOp>(text, byte_length, pos, count,
334 flags);
335 }
336
337 void RecordPaintCanvas::drawTextBlob(sk_sp<SkTextBlob> blob,
338 SkScalar x,
339 SkScalar y,
340 const PaintFlags& flags) {
341 buffer_->push<DrawTextBlobOp>(blob, x, y, flags);
342 }
343
344 void RecordPaintCanvas::drawDisplayItemList(
345 scoped_refptr<DisplayItemList> list) {
346 buffer_->push<DrawDisplayItemListOp>(list);
347 }
348
349 void RecordPaintCanvas::drawPicture(sk_sp<const PaintRecord> record) {
350 // TODO(enne): If this is small, maybe flatten it?
351 buffer_->push<DrawRecordOp>(record);
352 }
353
354 bool RecordPaintCanvas::isClipEmpty() const {
355 return canvas_.isClipEmpty();
356 }
357
358 bool RecordPaintCanvas::isClipRect() const {
359 return canvas_.isClipRect();
360 }
361
362 const SkMatrix& RecordPaintCanvas::getTotalMatrix() const {
363 return canvas_.getTotalMatrix();
364 }
365
366 void RecordPaintCanvas::temporary_internal_describeTopLayer(
367 SkMatrix* matrix,
368 SkIRect* clip_bounds) {
369 return canvas_.temporary_internal_describeTopLayer(matrix, clip_bounds);
370 }
371
372 bool RecordPaintCanvas::ToPixmap(SkPixmap* output) {
373 // TODO(enne): It'd be nice to make this NOTREACHED() or remove this from
374 // RecordPaintCanvas, but this is used by GraphicsContextCanvas for knowing
375 // whether or not it can raster directly into pixels with Cg.
376 return false;
377 }
378
379 void RecordPaintCanvas::Annotate(AnnotationType type,
380 const SkRect& rect,
381 sk_sp<SkData> data) {
382 buffer_->push<AnnotateOp>(type, rect, data);
383 }
384
385 void RecordPaintCanvas::PlaybackPaintRecord(sk_sp<const PaintRecord> record) {
386 drawPicture(record);
387 }
388
389 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698