Chromium Code Reviews| 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 |