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

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

Issue 2830243002: cc: Don't perform image analysis if the DisplayItemList has no images. (Closed)
Patch Set: for-draw-ops-only 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
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 #ifndef CC_PAINT_PAINT_OP_BUFFER_H_ 5 #ifndef CC_PAINT_PAINT_OP_BUFFER_H_
6 #define CC_PAINT_PAINT_OP_BUFFER_H_ 6 #define CC_PAINT_PAINT_OP_BUFFER_H_
7 7
8 #include <stdint.h> 8 #include <stdint.h>
9 9
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
78 78
79 PaintOpType GetType() const { return static_cast<PaintOpType>(type); } 79 PaintOpType GetType() const { return static_cast<PaintOpType>(type); }
80 80
81 void Raster(SkCanvas* canvas, const SkMatrix& original_ctm) const; 81 void Raster(SkCanvas* canvas, const SkMatrix& original_ctm) const;
82 bool IsDrawOp() const; 82 bool IsDrawOp() const;
83 83
84 // Only valid for draw ops. 84 // Only valid for draw ops.
85 void RasterWithAlpha(SkCanvas* canvas, uint8_t alpha) const; 85 void RasterWithAlpha(SkCanvas* canvas, uint8_t alpha) const;
86 86
87 int CountSlowPaths() const { return 0; } 87 int CountSlowPaths() const { return 0; }
88 bool HasDiscardableImages() const { return false; }
88 89
89 // Returns the number of bytes used by this op in referenced sub records 90 // Returns the number of bytes used by this op in referenced sub records
90 // and display lists. This doesn't count other objects like paths or blobs. 91 // and display lists. This doesn't count other objects like paths or blobs.
91 size_t AdditionalBytesUsed() const { return 0; } 92 size_t AdditionalBytesUsed() const { return 0; }
92 93
93 static constexpr bool kIsDrawOp = false; 94 static constexpr bool kIsDrawOp = false;
94 // If an op has |kHasPaintFlags| set to true, it must: 95 // If an op has |kHasPaintFlags| set to true, it must:
95 // (1) Provide a PaintFlags member called |flags| 96 // (1) Provide a PaintFlags member called |flags|
96 // (2) Provide a RasterWithFlags function instead of a Raster function. 97 // (2) Provide a RasterWithFlags function instead of a Raster function.
97 static constexpr bool kHasPaintFlags = false; 98 static constexpr bool kHasPaintFlags = false;
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
274 static constexpr bool kIsDrawOp = true; 275 static constexpr bool kIsDrawOp = true;
275 explicit DrawDisplayItemListOp(scoped_refptr<DisplayItemList> list); 276 explicit DrawDisplayItemListOp(scoped_refptr<DisplayItemList> list);
276 // Windows wants to generate these when types are exported, so 277 // Windows wants to generate these when types are exported, so
277 // provide them here explicitly so that DisplayItemList doesn't have 278 // provide them here explicitly so that DisplayItemList doesn't have
278 // to be defined in this header. 279 // to be defined in this header.
279 DrawDisplayItemListOp(const DrawDisplayItemListOp& op); 280 DrawDisplayItemListOp(const DrawDisplayItemListOp& op);
280 DrawDisplayItemListOp& operator=(const DrawDisplayItemListOp& op); 281 DrawDisplayItemListOp& operator=(const DrawDisplayItemListOp& op);
281 ~DrawDisplayItemListOp(); 282 ~DrawDisplayItemListOp();
282 void Raster(SkCanvas* canvas) const; 283 void Raster(SkCanvas* canvas) const;
283 size_t AdditionalBytesUsed() const; 284 size_t AdditionalBytesUsed() const;
285 bool HasDiscardableImages() const;
284 // TODO(enne): DisplayItemList should know number of slow paths. 286 // TODO(enne): DisplayItemList should know number of slow paths.
285 287
286 scoped_refptr<DisplayItemList> list; 288 scoped_refptr<DisplayItemList> list;
287 }; 289 };
288 290
289 struct CC_PAINT_EXPORT DrawDRRectOp final : PaintOp { 291 struct CC_PAINT_EXPORT DrawDRRectOp final : PaintOp {
290 static constexpr PaintOpType kType = PaintOpType::DrawDRRect; 292 static constexpr PaintOpType kType = PaintOpType::DrawDRRect;
291 static constexpr bool kIsDrawOp = true; 293 static constexpr bool kIsDrawOp = true;
292 static constexpr bool kHasPaintFlags = true; 294 static constexpr bool kHasPaintFlags = true;
293 DrawDRRectOp(const SkRRect& outer, 295 DrawDRRectOp(const SkRRect& outer,
(...skipping 10 matching lines...) Expand all
304 struct CC_PAINT_EXPORT DrawImageOp final : PaintOp { 306 struct CC_PAINT_EXPORT DrawImageOp final : PaintOp {
305 static constexpr PaintOpType kType = PaintOpType::DrawImage; 307 static constexpr PaintOpType kType = PaintOpType::DrawImage;
306 static constexpr bool kIsDrawOp = true; 308 static constexpr bool kIsDrawOp = true;
307 static constexpr bool kHasPaintFlags = true; 309 static constexpr bool kHasPaintFlags = true;
308 DrawImageOp(const PaintImage& image, 310 DrawImageOp(const PaintImage& image,
309 SkScalar left, 311 SkScalar left,
310 SkScalar top, 312 SkScalar top,
311 const PaintFlags* flags); 313 const PaintFlags* flags);
312 ~DrawImageOp(); 314 ~DrawImageOp();
313 void RasterWithFlags(SkCanvas* canvas, const PaintFlags& flags) const; 315 void RasterWithFlags(SkCanvas* canvas, const PaintFlags& flags) const;
316 bool HasDiscardableImages() const;
314 317
315 PaintImage image; 318 PaintImage image;
316 SkScalar left; 319 SkScalar left;
317 SkScalar top; 320 SkScalar top;
318 PaintFlags flags; 321 PaintFlags flags;
319 }; 322 };
320 323
321 struct CC_PAINT_EXPORT DrawImageRectOp final : PaintOp { 324 struct CC_PAINT_EXPORT DrawImageRectOp final : PaintOp {
322 static constexpr PaintOpType kType = PaintOpType::DrawImageRect; 325 static constexpr PaintOpType kType = PaintOpType::DrawImageRect;
323 static constexpr bool kIsDrawOp = true; 326 static constexpr bool kIsDrawOp = true;
324 static constexpr bool kHasPaintFlags = true; 327 static constexpr bool kHasPaintFlags = true;
325 DrawImageRectOp(const PaintImage& image, 328 DrawImageRectOp(const PaintImage& image,
326 const SkRect& src, 329 const SkRect& src,
327 const SkRect& dst, 330 const SkRect& dst,
328 const PaintFlags* flags, 331 const PaintFlags* flags,
329 PaintCanvas::SrcRectConstraint constraint); 332 PaintCanvas::SrcRectConstraint constraint);
330 ~DrawImageRectOp(); 333 ~DrawImageRectOp();
331 void RasterWithFlags(SkCanvas* canvas, const PaintFlags& flags) const; 334 void RasterWithFlags(SkCanvas* canvas, const PaintFlags& flags) const;
335 bool HasDiscardableImages() const;
332 336
333 PaintImage image; 337 PaintImage image;
334 PaintFlags flags; 338 PaintFlags flags;
335 SkRect src; 339 SkRect src;
336 SkRect dst; 340 SkRect dst;
337 PaintCanvas::SrcRectConstraint constraint; 341 PaintCanvas::SrcRectConstraint constraint;
338 }; 342 };
339 343
340 struct CC_PAINT_EXPORT DrawIRectOp final : PaintOp { 344 struct CC_PAINT_EXPORT DrawIRectOp final : PaintOp {
341 static constexpr PaintOpType kType = PaintOpType::DrawIRect; 345 static constexpr PaintOpType kType = PaintOpType::DrawIRect;
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
405 PaintFlags flags; 409 PaintFlags flags;
406 }; 410 };
407 411
408 struct CC_PAINT_EXPORT DrawRecordOp final : PaintOp { 412 struct CC_PAINT_EXPORT DrawRecordOp final : PaintOp {
409 static constexpr PaintOpType kType = PaintOpType::DrawRecord; 413 static constexpr PaintOpType kType = PaintOpType::DrawRecord;
410 static constexpr bool kIsDrawOp = true; 414 static constexpr bool kIsDrawOp = true;
411 explicit DrawRecordOp(sk_sp<const PaintRecord> record); 415 explicit DrawRecordOp(sk_sp<const PaintRecord> record);
412 ~DrawRecordOp(); 416 ~DrawRecordOp();
413 void Raster(SkCanvas* canvas) const; 417 void Raster(SkCanvas* canvas) const;
414 size_t AdditionalBytesUsed() const; 418 size_t AdditionalBytesUsed() const;
419 bool HasDiscardableImages() const;
415 420
416 sk_sp<const PaintRecord> record; 421 sk_sp<const PaintRecord> record;
417 }; 422 };
418 423
419 struct CC_PAINT_EXPORT DrawRectOp final : PaintOp { 424 struct CC_PAINT_EXPORT DrawRectOp final : PaintOp {
420 static constexpr PaintOpType kType = PaintOpType::DrawRect; 425 static constexpr PaintOpType kType = PaintOpType::DrawRect;
421 static constexpr bool kIsDrawOp = true; 426 static constexpr bool kIsDrawOp = true;
422 static constexpr bool kHasPaintFlags = true; 427 static constexpr bool kHasPaintFlags = true;
423 DrawRectOp(const SkRect& rect, const PaintFlags& flags) 428 DrawRectOp(const SkRect& rect, const PaintFlags& flags)
424 : rect(rect), flags(flags) {} 429 : rect(rect), flags(flags) {}
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
563 568
564 void playback(SkCanvas* canvas) const; 569 void playback(SkCanvas* canvas) const;
565 void playback(SkCanvas* canvas, SkPicture::AbortCallback* callback) const; 570 void playback(SkCanvas* canvas, SkPicture::AbortCallback* callback) const;
566 571
567 // TODO(enne): These are no longer approximate. Rename these. 572 // TODO(enne): These are no longer approximate. Rename these.
568 int approximateOpCount() const { return op_count_; } 573 int approximateOpCount() const { return op_count_; }
569 size_t approximateBytesUsed() const { 574 size_t approximateBytesUsed() const {
570 return sizeof(*this) + reserved_ + subrecord_bytes_used_; 575 return sizeof(*this) + reserved_ + subrecord_bytes_used_;
571 } 576 }
572 int numSlowPaths() const { return num_slow_paths_; } 577 int numSlowPaths() const { return num_slow_paths_; }
578 bool HasDiscardableImages() const { return has_discardable_images_; }
573 579
574 // Resize the PaintOpBuffer to exactly fit the current amount of used space. 580 // Resize the PaintOpBuffer to exactly fit the current amount of used space.
575 void ShrinkToFit(); 581 void ShrinkToFit();
576 582
577 const SkRect& cullRect() const { return cull_rect_; } 583 const SkRect& cullRect() const { return cull_rect_; }
578 584
579 PaintOp* GetFirstOp() const { 585 PaintOp* GetFirstOp() const {
580 return const_cast<PaintOp*>(first_op_.data_as<PaintOp>()); 586 return const_cast<PaintOp*>(first_op_.data_as<PaintOp>());
581 } 587 }
582 588
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
714 template <typename T, bool HasFlags> 720 template <typename T, bool HasFlags>
715 struct CountSlowPathsFromFlags { 721 struct CountSlowPathsFromFlags {
716 static int Count(const T* op) { return 0; } 722 static int Count(const T* op) { return 0; }
717 }; 723 };
718 724
719 template <typename T> 725 template <typename T>
720 struct CountSlowPathsFromFlags<T, true> { 726 struct CountSlowPathsFromFlags<T, true> {
721 static int Count(const T* op) { return op->flags.getPathEffect() ? 1 : 0; } 727 static int Count(const T* op) { return op->flags.getPathEffect() ? 1 : 0; }
722 }; 728 };
723 729
730 template <typename T, bool HasFlags>
731 struct HasDiscardableImagesFromFlags {
732 static bool HasDiscardableImages(const T* op) { return false; }
733 };
734
735 template <typename T>
736 struct HasDiscardableImagesFromFlags<T, true> {
737 static bool HasDiscardableImages(const T* op) {
738 if (!op->kIsDrawOp)
739 return false;
740
741 SkShader* shader = op->flags.getShader();
742 SkImage* image = shader ? shader->isAImage(nullptr, nullptr) : nullptr;
743 return image ? image->isLazyGenerated() : false;
vmpstr 2017/04/25 17:43:40 return image && image->isLazyGenerated();
744 }
745 };
746
724 template <typename T, typename... Args> 747 template <typename T, typename... Args>
725 T* push_internal(size_t bytes, Args&&... args) { 748 T* push_internal(size_t bytes, Args&&... args) {
726 size_t skip = SkAlignPtr(sizeof(T) + bytes); 749 size_t skip = SkAlignPtr(sizeof(T) + bytes);
727 DCHECK_LT(skip, static_cast<size_t>(1) << 24); 750 DCHECK_LT(skip, static_cast<size_t>(1) << 24);
728 if (used_ + skip > reserved_ || !op_count_) { 751 if (used_ + skip > reserved_ || !op_count_) {
729 if (!op_count_) { 752 if (!op_count_) {
730 if (bytes) { 753 if (bytes) {
731 // Internal first_op buffer doesn't have room for extra data. 754 // Internal first_op buffer doesn't have room for extra data.
732 // If the op wants extra bytes, then we'll just store a Noop 755 // If the op wants extra bytes, then we'll just store a Noop
733 // in the first_op and proceed from there. This seems unlikely 756 // in the first_op and proceed from there. This seems unlikely
734 // to be a common case. 757 // to be a common case.
735 push<NoopOp>(); 758 push<NoopOp>();
736 } else { 759 } else {
737 // |first_op_| is aligned to LargestPaintOp. If T needs a smaller 760 // |first_op_| is aligned to LargestPaintOp. If T needs a smaller
738 // alignment, this is okay because it will be a factor of the actual 761 // alignment, this is okay because it will be a factor of the actual
739 // alignment being used (as they are always a power of 2). If T needs 762 // alignment being used (as they are always a power of 2). If T needs
740 // a larger alignment, that is bad and we should use T to choose the 763 // a larger alignment, that is bad and we should use T to choose the
741 // alignment of |first_op_| instead. 764 // alignment of |first_op_| instead.
742 static_assert(ALIGNOF(T) <= ALIGNOF(LargestPaintOp), ""); 765 static_assert(ALIGNOF(T) <= ALIGNOF(LargestPaintOp), "");
743 auto* op = reinterpret_cast<T*>(first_op_.data_as<T>()); 766 auto* op = reinterpret_cast<T*>(first_op_.data_as<T>());
744 new (op) T{std::forward<Args>(args)...}; 767 new (op) T{std::forward<Args>(args)...};
745 op->type = static_cast<uint32_t>(T::kType); 768 op->type = static_cast<uint32_t>(T::kType);
746 op->skip = 0; 769 op->skip = 0;
747 op_count_++; 770 op_count_++;
771 AnalyzeAddedOp(op);
748 return op; 772 return op;
749 } 773 }
750 } 774 }
751 775
752 // Start reserved_ at kInitialBufferSize and then double. 776 // Start reserved_ at kInitialBufferSize and then double.
753 // ShrinkToFit can make this smaller afterwards. 777 // ShrinkToFit can make this smaller afterwards.
754 while (used_ + skip > reserved_) 778 while (used_ + skip > reserved_)
755 reserved_ = reserved_ ? reserved_ * 2 : kInitialBufferSize; 779 reserved_ = reserved_ ? reserved_ * 2 : kInitialBufferSize;
756 data_.realloc(reserved_); 780 data_.realloc(reserved_);
757 } 781 }
758 DCHECK_LE(used_ + skip, reserved_); 782 DCHECK_LE(used_ + skip, reserved_);
759 783
760 T* op = reinterpret_cast<T*>(data_.get() + used_); 784 T* op = reinterpret_cast<T*>(data_.get() + used_);
761 used_ += skip; 785 used_ += skip;
762 new (op) T(std::forward<Args>(args)...); 786 new (op) T(std::forward<Args>(args)...);
763 op->type = static_cast<uint32_t>(T::kType); 787 op->type = static_cast<uint32_t>(T::kType);
764 op->skip = skip; 788 op->skip = skip;
765 op_count_++; 789 op_count_++;
790 AnalyzeAddedOp(op);
791 return op;
792 }
766 793
794 template <typename T>
795 void AnalyzeAddedOp(const T* op) {
767 num_slow_paths_ += CountSlowPathsFromFlags<T, T::kHasPaintFlags>::Count(op); 796 num_slow_paths_ += CountSlowPathsFromFlags<T, T::kHasPaintFlags>::Count(op);
768 num_slow_paths_ += op->CountSlowPaths(); 797 num_slow_paths_ += op->CountSlowPaths();
769 798
799 has_discardable_images_ |= op->HasDiscardableImages();
800 has_discardable_images_ |= HasDiscardableImagesFromFlags<
801 T, T::kHasPaintFlags>::HasDiscardableImages(op);
802
770 subrecord_bytes_used_ += op->AdditionalBytesUsed(); 803 subrecord_bytes_used_ += op->AdditionalBytesUsed();
771
772 return op;
773 } 804 }
774 805
775 // As a performance optimization because n=1 is an extremely common case just 806 // As a performance optimization because n=1 is an extremely common case just
776 // store the first op in the PaintOpBuffer itself to avoid an extra alloc. 807 // store the first op in the PaintOpBuffer itself to avoid an extra alloc.
777 base::AlignedMemory<sizeof(LargestPaintOp), ALIGNOF(LargestPaintOp)> 808 base::AlignedMemory<sizeof(LargestPaintOp), ALIGNOF(LargestPaintOp)>
778 first_op_; 809 first_op_;
779 SkAutoTMalloc<char> data_; 810 SkAutoTMalloc<char> data_;
780 size_t used_ = 0; 811 size_t used_ = 0;
781 size_t reserved_ = 0; 812 size_t reserved_ = 0;
782 int op_count_ = 0; 813 int op_count_ = 0;
783 814
784 // Record paths for veto-to-msaa for gpu raster. 815 // Record paths for veto-to-msaa for gpu raster.
785 int num_slow_paths_ = 0; 816 int num_slow_paths_ = 0;
786 // Record additional bytes used by referenced sub-records and display lists. 817 // Record additional bytes used by referenced sub-records and display lists.
787 size_t subrecord_bytes_used_ = 0; 818 size_t subrecord_bytes_used_ = 0;
819 bool has_discardable_images_ = false;
788 SkRect cull_rect_; 820 SkRect cull_rect_;
789 821
790 DISALLOW_COPY_AND_ASSIGN(PaintOpBuffer); 822 DISALLOW_COPY_AND_ASSIGN(PaintOpBuffer);
791 }; 823 };
792 824
793 } // namespace cc 825 } // namespace cc
794 826
795 #endif // CC_PAINT_PAINT_OP_BUFFER_H_ 827 #endif // CC_PAINT_PAINT_OP_BUFFER_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698