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

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

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

Powered by Google App Engine
This is Rietveld 408576698