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

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

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

Powered by Google App Engine
This is Rietveld 408576698