OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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_ |
OLD | NEW |