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

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

Issue 2863673002: cc: Fix data race in PaintOpBuffer by not mutating PaintOps. (Closed)
Patch Set: 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/paint_op_buffer.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2017 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "cc/paint/paint_op_buffer.h" 5 #include "cc/paint/paint_op_buffer.h"
6 6
7 #include "cc/paint/display_item_list.h" 7 #include "cc/paint/display_item_list.h"
8 #include "cc/paint/paint_record.h" 8 #include "cc/paint/paint_record.h"
9 #include "third_party/skia/include/core/SkAnnotation.h" 9 #include "third_party/skia/include/core/SkAnnotation.h"
10 10
(...skipping 28 matching lines...) Expand all
39 M(SaveOp) \ 39 M(SaveOp) \
40 M(SaveLayerOp) \ 40 M(SaveLayerOp) \
41 M(SaveLayerAlphaOp) \ 41 M(SaveLayerAlphaOp) \
42 M(ScaleOp) \ 42 M(ScaleOp) \
43 M(SetMatrixOp) \ 43 M(SetMatrixOp) \
44 M(TranslateOp) 44 M(TranslateOp)
45 45
46 using RasterFunction = void (*)(const PaintOp* op, 46 using RasterFunction = void (*)(const PaintOp* op,
47 SkCanvas* canvas, 47 SkCanvas* canvas,
48 const SkMatrix& original_ctm); 48 const SkMatrix& original_ctm);
49 using RasterWithFlagsFunction = void (*)(const PaintOpWithFlags* op,
50 const PaintFlags* flags,
51 SkCanvas* canvas,
52 const SkMatrix& original_ctm);
49 53
50 NOINLINE static void RasterWithAlphaInternal(RasterFunction raster_fn, 54 NOINLINE static void RasterWithAlphaInternal(RasterFunction raster_fn,
51 const PaintOp* op, 55 const PaintOp* op,
52 SkCanvas* canvas, 56 SkCanvas* canvas,
53 uint8_t alpha) { 57 uint8_t alpha) {
54 // TODO(enne): is it ok to just drop the bounds here? 58 // TODO(enne): is it ok to just drop the bounds here?
55 canvas->saveLayerAlpha(nullptr, alpha); 59 canvas->saveLayerAlpha(nullptr, alpha);
56 SkMatrix unused_matrix; 60 SkMatrix unused_matrix;
57 raster_fn(op, canvas, unused_matrix); 61 raster_fn(op, canvas, unused_matrix);
58 canvas->restore(); 62 canvas->restore();
59 } 63 }
60 64
61 // Helper template to share common code for RasterWithAlpha when paint ops 65 // Helper template to share common code for RasterWithAlpha when paint ops
62 // have or don't have PaintFlags. 66 // have or don't have PaintFlags.
63 template <typename T, bool HasFlags> 67 template <typename T, bool HasFlags>
64 struct Rasterizer { 68 struct Rasterizer {
65 static void RasterWithAlpha(const T* op, SkCanvas* canvas, uint8_t alpha) { 69 static void RasterWithAlpha(const T* op, SkCanvas* canvas, uint8_t alpha) {
66 static_assert( 70 static_assert(
67 !T::kHasPaintFlags, 71 !T::kHasPaintFlags,
68 "This function should not be used for a PaintOp that has PaintFlags"); 72 "This function should not be used for a PaintOp that has PaintFlags");
69 DCHECK(T::kIsDrawOp); 73 DCHECK(T::kIsDrawOp);
70 RasterWithAlphaInternal(&T::Raster, op, canvas, alpha); 74 RasterWithAlphaInternal(&T::Raster, op, canvas, alpha);
71 } 75 }
72 }; 76 };
73 77
74 NOINLINE static void RasterWithAlphaInternalForFlags(RasterFunction raster_fn, 78 NOINLINE static void RasterWithAlphaInternalForFlags(
75 const PaintOpWithFlags* op, 79 RasterWithFlagsFunction raster_fn,
76 SkCanvas* canvas, 80 const PaintOpWithFlags* op,
77 uint8_t alpha) { 81 SkCanvas* canvas,
82 uint8_t alpha) {
78 SkMatrix unused_matrix; 83 SkMatrix unused_matrix;
79 if (alpha == 255) { 84 if (alpha == 255) {
80 raster_fn(op, canvas, unused_matrix); 85 raster_fn(op, &op->flags, canvas, unused_matrix);
81 } else if (op->flags.SupportsFoldingAlpha()) { 86 } else if (op->flags.SupportsFoldingAlpha()) {
82 PaintOpWithFlags* mutable_op = const_cast<PaintOpWithFlags*>(op); 87 PaintFlags flags = op->flags;
83 uint8_t flags_alpha = op->flags.getAlpha(); 88 flags.setAlpha(SkMulDiv255Round(flags.getAlpha(), alpha));
84 mutable_op->flags.setAlpha(SkMulDiv255Round(flags_alpha, alpha)); 89 raster_fn(op, &flags, canvas, unused_matrix);
85 raster_fn(op, canvas, unused_matrix);
86 mutable_op->flags.setAlpha(flags_alpha);
87 } else { 90 } else {
88 canvas->saveLayerAlpha(nullptr, alpha); 91 canvas->saveLayerAlpha(nullptr, alpha);
89 raster_fn(op, canvas, unused_matrix); 92 raster_fn(op, &op->flags, canvas, unused_matrix);
90 canvas->restore(); 93 canvas->restore();
91 } 94 }
92 } 95 }
93 96
94 template <typename T> 97 template <typename T>
95 struct Rasterizer<T, true> { 98 struct Rasterizer<T, true> {
96 static void RasterWithAlpha(const T* op, SkCanvas* canvas, uint8_t alpha) { 99 static void RasterWithAlpha(const T* op, SkCanvas* canvas, uint8_t alpha) {
97 static_assert(T::kHasPaintFlags, 100 static_assert(T::kHasPaintFlags,
98 "This function expects the PaintOp to have PaintFlags"); 101 "This function expects the PaintOp to have PaintFlags");
99 DCHECK(T::kIsDrawOp); 102 DCHECK(T::kIsDrawOp);
100 RasterWithAlphaInternalForFlags(&T::Raster, op, canvas, alpha); 103 RasterWithAlphaInternalForFlags(&T::RasterWithFlags, op, canvas, alpha);
101 } 104 }
102 }; 105 };
103 106
104 template <> 107 template <>
105 struct Rasterizer<DrawRecordOp, false> { 108 struct Rasterizer<DrawRecordOp, false> {
106 static void RasterWithAlpha(const DrawRecordOp* op, 109 static void RasterWithAlpha(const DrawRecordOp* op,
107 SkCanvas* canvas, 110 SkCanvas* canvas,
108 uint8_t alpha) { 111 uint8_t alpha) {
109 // This "looking into records" optimization is done here instead of 112 // This "looking into records" optimization is done here instead of
110 // in the PaintOpBuffer::Raster function as DisplayItemList calls 113 // in the PaintOpBuffer::Raster function as DisplayItemList calls
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
226 canvas->clipRRect(op->rrect, op->op, op->antialias); 229 canvas->clipRRect(op->rrect, op->op, op->antialias);
227 } 230 }
228 231
229 void ConcatOp::Raster(const PaintOp* base_op, 232 void ConcatOp::Raster(const PaintOp* base_op,
230 SkCanvas* canvas, 233 SkCanvas* canvas,
231 const SkMatrix& original_ctm) { 234 const SkMatrix& original_ctm) {
232 auto* op = static_cast<const ConcatOp*>(base_op); 235 auto* op = static_cast<const ConcatOp*>(base_op);
233 canvas->concat(op->matrix); 236 canvas->concat(op->matrix);
234 } 237 }
235 238
236 void DrawArcOp::Raster(const PaintOp* base_op, 239 void DrawArcOp::RasterWithFlags(const PaintOpWithFlags* base_op,
237 SkCanvas* canvas, 240 const PaintFlags* flags,
238 const SkMatrix& original_ctm) { 241 SkCanvas* canvas,
242 const SkMatrix& original_ctm) {
239 auto* op = static_cast<const DrawArcOp*>(base_op); 243 auto* op = static_cast<const DrawArcOp*>(base_op);
240 canvas->drawArc(op->oval, op->start_angle, op->sweep_angle, op->use_center, 244 canvas->drawArc(op->oval, op->start_angle, op->sweep_angle, op->use_center,
241 ToSkPaint(op->flags)); 245 ToSkPaint(*flags));
242 } 246 }
243 247
244 void DrawCircleOp::Raster(const PaintOp* base_op, 248 void DrawCircleOp::RasterWithFlags(const PaintOpWithFlags* base_op,
245 SkCanvas* canvas, 249 const PaintFlags* flags,
246 const SkMatrix& original_ctm) { 250 SkCanvas* canvas,
251 const SkMatrix& original_ctm) {
247 auto* op = static_cast<const DrawCircleOp*>(base_op); 252 auto* op = static_cast<const DrawCircleOp*>(base_op);
248 canvas->drawCircle(op->cx, op->cy, op->radius, ToSkPaint(op->flags)); 253 canvas->drawCircle(op->cx, op->cy, op->radius, ToSkPaint(*flags));
249 } 254 }
250 255
251 void DrawColorOp::Raster(const PaintOp* base_op, 256 void DrawColorOp::Raster(const PaintOp* base_op,
252 SkCanvas* canvas, 257 SkCanvas* canvas,
253 const SkMatrix& original_ctm) { 258 const SkMatrix& original_ctm) {
254 auto* op = static_cast<const DrawColorOp*>(base_op); 259 auto* op = static_cast<const DrawColorOp*>(base_op);
255 canvas->drawColor(op->color, op->mode); 260 canvas->drawColor(op->color, op->mode);
256 } 261 }
257 262
258 void DrawDisplayItemListOp::Raster(const PaintOp* base_op, 263 void DrawDisplayItemListOp::Raster(const PaintOp* base_op,
259 SkCanvas* canvas, 264 SkCanvas* canvas,
260 const SkMatrix& original_ctm) { 265 const SkMatrix& original_ctm) {
261 auto* op = static_cast<const DrawDisplayItemListOp*>(base_op); 266 auto* op = static_cast<const DrawDisplayItemListOp*>(base_op);
262 op->list->Raster(canvas, nullptr); 267 op->list->Raster(canvas, nullptr);
263 } 268 }
264 269
265 void DrawDRRectOp::Raster(const PaintOp* base_op, 270 void DrawDRRectOp::RasterWithFlags(const PaintOpWithFlags* base_op,
266 SkCanvas* canvas, 271 const PaintFlags* flags,
267 const SkMatrix& original_ctm) { 272 SkCanvas* canvas,
273 const SkMatrix& original_ctm) {
268 auto* op = static_cast<const DrawDRRectOp*>(base_op); 274 auto* op = static_cast<const DrawDRRectOp*>(base_op);
269 canvas->drawDRRect(op->outer, op->inner, ToSkPaint(op->flags)); 275 canvas->drawDRRect(op->outer, op->inner, ToSkPaint(*flags));
270 } 276 }
271 277
272 void DrawImageOp::Raster(const PaintOp* base_op, 278 void DrawImageOp::RasterWithFlags(const PaintOpWithFlags* base_op,
273 SkCanvas* canvas, 279 const PaintFlags* flags,
274 const SkMatrix& original_ctm) { 280 SkCanvas* canvas,
281 const SkMatrix& original_ctm) {
275 auto* op = static_cast<const DrawImageOp*>(base_op); 282 auto* op = static_cast<const DrawImageOp*>(base_op);
276 canvas->drawImage(op->image.sk_image().get(), op->left, op->top, 283 canvas->drawImage(op->image.sk_image().get(), op->left, op->top,
277 ToSkPaint(&op->flags)); 284 ToSkPaint(flags));
278 } 285 }
279 286
280 void DrawImageRectOp::Raster(const PaintOp* base_op, 287 void DrawImageRectOp::RasterWithFlags(const PaintOpWithFlags* base_op,
281 SkCanvas* canvas, 288 const PaintFlags* flags,
282 const SkMatrix& original_ctm) { 289 SkCanvas* canvas,
290 const SkMatrix& original_ctm) {
283 auto* op = static_cast<const DrawImageRectOp*>(base_op); 291 auto* op = static_cast<const DrawImageRectOp*>(base_op);
284 // TODO(enne): Probably PaintCanvas should just use the skia enum directly. 292 // TODO(enne): Probably PaintCanvas should just use the skia enum directly.
285 SkCanvas::SrcRectConstraint skconstraint = 293 SkCanvas::SrcRectConstraint skconstraint =
286 static_cast<SkCanvas::SrcRectConstraint>(op->constraint); 294 static_cast<SkCanvas::SrcRectConstraint>(op->constraint);
287 canvas->drawImageRect(op->image.sk_image().get(), op->src, op->dst, 295 canvas->drawImageRect(op->image.sk_image().get(), op->src, op->dst,
288 ToSkPaint(&op->flags), skconstraint); 296 ToSkPaint(flags), skconstraint);
289 } 297 }
290 298
291 void DrawIRectOp::Raster(const PaintOp* base_op, 299 void DrawIRectOp::RasterWithFlags(const PaintOpWithFlags* base_op,
292 SkCanvas* canvas, 300 const PaintFlags* flags,
293 const SkMatrix& original_ctm) { 301 SkCanvas* canvas,
302 const SkMatrix& original_ctm) {
294 auto* op = static_cast<const DrawIRectOp*>(base_op); 303 auto* op = static_cast<const DrawIRectOp*>(base_op);
295 canvas->drawIRect(op->rect, ToSkPaint(op->flags)); 304 canvas->drawIRect(op->rect, ToSkPaint(*flags));
296 } 305 }
297 306
298 void DrawLineOp::Raster(const PaintOp* base_op, 307 void DrawLineOp::RasterWithFlags(const PaintOpWithFlags* base_op,
299 SkCanvas* canvas, 308 const PaintFlags* flags,
300 const SkMatrix& original_ctm) { 309 SkCanvas* canvas,
310 const SkMatrix& original_ctm) {
301 auto* op = static_cast<const DrawLineOp*>(base_op); 311 auto* op = static_cast<const DrawLineOp*>(base_op);
302 canvas->drawLine(op->x0, op->y0, op->x1, op->y1, ToSkPaint(op->flags)); 312 canvas->drawLine(op->x0, op->y0, op->x1, op->y1, ToSkPaint(*flags));
303 } 313 }
304 314
305 void DrawOvalOp::Raster(const PaintOp* base_op, 315 void DrawOvalOp::RasterWithFlags(const PaintOpWithFlags* base_op,
306 SkCanvas* canvas, 316 const PaintFlags* flags,
307 const SkMatrix& original_ctm) { 317 SkCanvas* canvas,
318 const SkMatrix& original_ctm) {
308 auto* op = static_cast<const DrawOvalOp*>(base_op); 319 auto* op = static_cast<const DrawOvalOp*>(base_op);
309 canvas->drawOval(op->oval, ToSkPaint(op->flags)); 320 canvas->drawOval(op->oval, ToSkPaint(*flags));
310 } 321 }
311 322
312 void DrawPathOp::Raster(const PaintOp* base_op, 323 void DrawPathOp::RasterWithFlags(const PaintOpWithFlags* base_op,
313 SkCanvas* canvas, 324 const PaintFlags* flags,
314 const SkMatrix& original_ctm) { 325 SkCanvas* canvas,
326 const SkMatrix& original_ctm) {
315 auto* op = static_cast<const DrawPathOp*>(base_op); 327 auto* op = static_cast<const DrawPathOp*>(base_op);
316 canvas->drawPath(op->path, ToSkPaint(op->flags)); 328 canvas->drawPath(op->path, ToSkPaint(*flags));
317 } 329 }
318 330
319 void DrawPosTextOp::Raster(const PaintOp* base_op, 331 void DrawPosTextOp::RasterWithFlags(const PaintOpWithFlags* base_op,
320 SkCanvas* canvas, 332 const PaintFlags* flags,
321 const SkMatrix& original_ctm) { 333 SkCanvas* canvas,
334 const SkMatrix& original_ctm) {
322 auto* op = static_cast<const DrawPosTextOp*>(base_op); 335 auto* op = static_cast<const DrawPosTextOp*>(base_op);
323 canvas->drawPosText(op->GetData(), op->bytes, op->GetArray(), 336 canvas->drawPosText(op->GetData(), op->bytes, op->GetArray(),
324 ToSkPaint(op->flags)); 337 ToSkPaint(*flags));
325 } 338 }
326 339
327 void DrawRecordOp::Raster(const PaintOp* base_op, 340 void DrawRecordOp::Raster(const PaintOp* base_op,
328 SkCanvas* canvas, 341 SkCanvas* canvas,
329 const SkMatrix& original_ctm) { 342 const SkMatrix& original_ctm) {
330 auto* op = static_cast<const DrawRecordOp*>(base_op); 343 auto* op = static_cast<const DrawRecordOp*>(base_op);
331 op->record->playback(canvas); 344 op->record->playback(canvas);
332 } 345 }
333 346
334 void DrawRectOp::Raster(const PaintOp* base_op, 347 void DrawRectOp::RasterWithFlags(const PaintOpWithFlags* base_op,
335 SkCanvas* canvas, 348 const PaintFlags* flags,
336 const SkMatrix& original_ctm) { 349 SkCanvas* canvas,
350 const SkMatrix& original_ctm) {
337 auto* op = static_cast<const DrawRectOp*>(base_op); 351 auto* op = static_cast<const DrawRectOp*>(base_op);
338 canvas->drawRect(op->rect, ToSkPaint(op->flags)); 352 canvas->drawRect(op->rect, ToSkPaint(*flags));
339 } 353 }
340 354
341 void DrawRRectOp::Raster(const PaintOp* base_op, 355 void DrawRRectOp::RasterWithFlags(const PaintOpWithFlags* base_op,
342 SkCanvas* canvas, 356 const PaintFlags* flags,
343 const SkMatrix& original_ctm) { 357 SkCanvas* canvas,
358 const SkMatrix& original_ctm) {
344 auto* op = static_cast<const DrawRRectOp*>(base_op); 359 auto* op = static_cast<const DrawRRectOp*>(base_op);
345 canvas->drawRRect(op->rrect, ToSkPaint(op->flags)); 360 canvas->drawRRect(op->rrect, ToSkPaint(*flags));
346 } 361 }
347 362
348 void DrawTextOp::Raster(const PaintOp* base_op, 363 void DrawTextOp::RasterWithFlags(const PaintOpWithFlags* base_op,
349 SkCanvas* canvas, 364 const PaintFlags* flags,
350 const SkMatrix& original_ctm) { 365 SkCanvas* canvas,
366 const SkMatrix& original_ctm) {
351 auto* op = static_cast<const DrawTextOp*>(base_op); 367 auto* op = static_cast<const DrawTextOp*>(base_op);
352 canvas->drawText(op->GetData(), op->bytes, op->x, op->y, 368 canvas->drawText(op->GetData(), op->bytes, op->x, op->y, ToSkPaint(*flags));
353 ToSkPaint(op->flags));
354 } 369 }
355 370
356 void DrawTextBlobOp::Raster(const PaintOp* base_op, 371 void DrawTextBlobOp::RasterWithFlags(const PaintOpWithFlags* base_op,
357 SkCanvas* canvas, 372 const PaintFlags* flags,
358 const SkMatrix& original_ctm) { 373 SkCanvas* canvas,
374 const SkMatrix& original_ctm) {
359 auto* op = static_cast<const DrawTextBlobOp*>(base_op); 375 auto* op = static_cast<const DrawTextBlobOp*>(base_op);
360 canvas->drawTextBlob(op->blob.get(), op->x, op->y, ToSkPaint(op->flags)); 376 canvas->drawTextBlob(op->blob.get(), op->x, op->y, ToSkPaint(*flags));
361 } 377 }
362 378
363 void RestoreOp::Raster(const PaintOp* base_op, 379 void RestoreOp::Raster(const PaintOp* base_op,
364 SkCanvas* canvas, 380 SkCanvas* canvas,
365 const SkMatrix& original_ctm) { 381 const SkMatrix& original_ctm) {
366 canvas->restore(); 382 canvas->restore();
367 } 383 }
368 384
369 void RotateOp::Raster(const PaintOp* base_op, 385 void RotateOp::Raster(const PaintOp* base_op,
370 SkCanvas* canvas, 386 SkCanvas* canvas,
371 const SkMatrix& original_ctm) { 387 const SkMatrix& original_ctm) {
372 auto* op = static_cast<const RotateOp*>(base_op); 388 auto* op = static_cast<const RotateOp*>(base_op);
373 canvas->rotate(op->degrees); 389 canvas->rotate(op->degrees);
374 } 390 }
375 391
376 void SaveOp::Raster(const PaintOp* base_op, 392 void SaveOp::Raster(const PaintOp* base_op,
377 SkCanvas* canvas, 393 SkCanvas* canvas,
378 const SkMatrix& original_ctm) { 394 const SkMatrix& original_ctm) {
379 canvas->save(); 395 canvas->save();
380 } 396 }
381 397
382 void SaveLayerOp::Raster(const PaintOp* base_op, 398 void SaveLayerOp::RasterWithFlags(const PaintOpWithFlags* base_op,
383 SkCanvas* canvas, 399 const PaintFlags* flags,
384 const SkMatrix& original_ctm) { 400 SkCanvas* canvas,
401 const SkMatrix& original_ctm) {
385 auto* op = static_cast<const SaveLayerOp*>(base_op); 402 auto* op = static_cast<const SaveLayerOp*>(base_op);
386 // See PaintOp::kUnsetRect 403 // See PaintOp::kUnsetRect
387 bool unset = op->bounds.left() == SK_ScalarInfinity; 404 bool unset = op->bounds.left() == SK_ScalarInfinity;
388 405
389 canvas->saveLayer(unset ? nullptr : &op->bounds, ToSkPaint(&op->flags)); 406 canvas->saveLayer(unset ? nullptr : &op->bounds, ToSkPaint(flags));
390 } 407 }
391 408
392 void SaveLayerAlphaOp::Raster(const PaintOp* base_op, 409 void SaveLayerAlphaOp::Raster(const PaintOp* base_op,
393 SkCanvas* canvas, 410 SkCanvas* canvas,
394 const SkMatrix& original_ctm) { 411 const SkMatrix& original_ctm) {
395 auto* op = static_cast<const SaveLayerAlphaOp*>(base_op); 412 auto* op = static_cast<const SaveLayerAlphaOp*>(base_op);
396 // See PaintOp::kUnsetRect 413 // See PaintOp::kUnsetRect
397 bool unset = op->bounds.left() == SK_ScalarInfinity; 414 bool unset = op->bounds.left() == SK_ScalarInfinity;
398 canvas->saveLayerAlpha(unset ? nullptr : &op->bounds, op->alpha); 415 canvas->saveLayerAlpha(unset ? nullptr : &op->bounds, op->alpha);
399 } 416 }
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after
672 return std::make_pair(op, skip); 689 return std::make_pair(op, skip);
673 } 690 }
674 691
675 void PaintOpBuffer::ShrinkToFit() { 692 void PaintOpBuffer::ShrinkToFit() {
676 if (!used_ || used_ == reserved_) 693 if (!used_ || used_ == reserved_)
677 return; 694 return;
678 ReallocBuffer(used_); 695 ReallocBuffer(used_);
679 } 696 }
680 697
681 } // namespace cc 698 } // namespace cc
OLDNEW
« no previous file with comments | « cc/paint/paint_op_buffer.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698