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 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
202 | 202 |
203 template <typename T> | 203 template <typename T> |
204 const M* GetArrayForThis(const T* op) const { | 204 const M* GetArrayForThis(const T* op) const { |
205 static_assert(std::is_convertible<T, PaintOpWithArrayBase>::value, | 205 static_assert(std::is_convertible<T, PaintOpWithArrayBase>::value, |
206 "T is not a PaintOpWithData"); | 206 "T is not a PaintOpWithData"); |
207 // As an optimization to not have to store an additional offset, | 207 // As an optimization to not have to store an additional offset, |
208 // assert that T has the same or more alignment requirements than M. Thus, | 208 // assert that T has the same or more alignment requirements than M. Thus, |
209 // if T is aligned, and M's alignment needs are a multiple of T's size, then | 209 // if T is aligned, and M's alignment needs are a multiple of T's size, then |
210 // M will also be aligned when placed immediately after T. | 210 // M will also be aligned when placed immediately after T. |
211 static_assert( | 211 static_assert( |
212 sizeof(T) % ALIGNOF(M) == 0, | 212 sizeof(T) % alignof(M) == 0, |
213 "T must be padded such that an array of M is aligned after it"); | 213 "T must be padded such that an array of M is aligned after it"); |
214 static_assert( | 214 static_assert( |
215 ALIGNOF(T) >= ALIGNOF(M), | 215 alignof(T) >= alignof(M), |
216 "T must have not have less alignment requirements than the array data"); | 216 "T must have not have less alignment requirements than the array data"); |
217 return reinterpret_cast<const M*>(op + 1); | 217 return reinterpret_cast<const M*>(op + 1); |
218 } | 218 } |
219 | 219 |
220 template <typename T> | 220 template <typename T> |
221 M* GetArrayForThis(T* op) { | 221 M* GetArrayForThis(T* op) { |
222 return const_cast<M*>( | 222 return const_cast<M*>( |
223 const_cast<const PaintOpWithArray*>(this)->GetArrayForThis( | 223 const_cast<const PaintOpWithArray*>(this)->GetArrayForThis( |
224 const_cast<T*>(op))); | 224 const_cast<T*>(op))); |
225 } | 225 } |
(...skipping 538 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
764 SkScalar dy; | 764 SkScalar dy; |
765 }; | 765 }; |
766 | 766 |
767 using LargestPaintOp = DrawDRRectOp; | 767 using LargestPaintOp = DrawDRRectOp; |
768 | 768 |
769 class CC_PAINT_EXPORT PaintOpBuffer : public SkRefCnt { | 769 class CC_PAINT_EXPORT PaintOpBuffer : public SkRefCnt { |
770 public: | 770 public: |
771 enum { kInitialBufferSize = 4096 }; | 771 enum { kInitialBufferSize = 4096 }; |
772 // It's not necessarily the case that the op with the maximum alignment | 772 // It's not necessarily the case that the op with the maximum alignment |
773 // requirements is also the biggest op, but for now that's true. | 773 // requirements is also the biggest op, but for now that's true. |
774 static constexpr size_t PaintOpAlign = ALIGNOF(DrawDRRectOp); | 774 static constexpr size_t PaintOpAlign = alignof(DrawDRRectOp); |
775 | 775 |
776 PaintOpBuffer(); | 776 PaintOpBuffer(); |
777 ~PaintOpBuffer() override; | 777 ~PaintOpBuffer() override; |
778 | 778 |
779 void Reset(); | 779 void Reset(); |
780 | 780 |
781 void playback(SkCanvas* canvas, | 781 void playback(SkCanvas* canvas, |
782 SkPicture::AbortCallback* callback = nullptr) const; | 782 SkPicture::AbortCallback* callback = nullptr) const; |
783 // This can be used to play back a subset of the PaintOpBuffer. | 783 // This can be used to play back a subset of the PaintOpBuffer. |
784 // The |range_starts| array is an increasing set of positions in the | 784 // The |range_starts| array is an increasing set of positions in the |
(...skipping 27 matching lines...) Expand all Loading... |
812 size_t bytes_used() const { | 812 size_t bytes_used() const { |
813 return sizeof(*this) + reserved_ + subrecord_bytes_used_; | 813 return sizeof(*this) + reserved_ + subrecord_bytes_used_; |
814 } | 814 } |
815 int numSlowPaths() const { return num_slow_paths_; } | 815 int numSlowPaths() const { return num_slow_paths_; } |
816 bool HasDiscardableImages() const { return has_discardable_images_; } | 816 bool HasDiscardableImages() const { return has_discardable_images_; } |
817 | 817 |
818 // Resize the PaintOpBuffer to exactly fit the current amount of used space. | 818 // Resize the PaintOpBuffer to exactly fit the current amount of used space. |
819 void ShrinkToFit(); | 819 void ShrinkToFit(); |
820 | 820 |
821 PaintOp* GetFirstOp() const { | 821 PaintOp* GetFirstOp() const { |
822 return const_cast<PaintOp*>(first_op_.data_as<PaintOp>()); | 822 return const_cast<PaintOp*>(reinterpret_cast<const PaintOp*>(&first_op_)); |
823 } | 823 } |
824 | 824 |
825 template <typename T, typename... Args> | 825 template <typename T, typename... Args> |
826 void push(Args&&... args) { | 826 void push(Args&&... args) { |
827 static_assert(std::is_convertible<T, PaintOp>::value, "T not a PaintOp."); | 827 static_assert(std::is_convertible<T, PaintOp>::value, "T not a PaintOp."); |
828 static_assert(!std::is_convertible<T, PaintOpWithData>::value, | 828 static_assert(!std::is_convertible<T, PaintOpWithData>::value, |
829 "Type needs to use push_with_data"); | 829 "Type needs to use push_with_data"); |
830 push_internal<T>(0, std::forward<Args>(args)...); | 830 push_internal<T>(0, std::forward<Args>(args)...); |
831 } | 831 } |
832 | 832 |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
924 }; | 924 }; |
925 | 925 |
926 private: | 926 private: |
927 void ReallocBuffer(size_t new_size); | 927 void ReallocBuffer(size_t new_size); |
928 // Returns the allocated op and the number of bytes to skip in |data_| to get | 928 // Returns the allocated op and the number of bytes to skip in |data_| to get |
929 // to the next op. | 929 // to the next op. |
930 std::pair<void*, size_t> AllocatePaintOp(size_t sizeof_op, size_t bytes); | 930 std::pair<void*, size_t> AllocatePaintOp(size_t sizeof_op, size_t bytes); |
931 | 931 |
932 template <typename T, typename... Args> | 932 template <typename T, typename... Args> |
933 T* push_internal(size_t bytes, Args&&... args) { | 933 T* push_internal(size_t bytes, Args&&... args) { |
934 static_assert(ALIGNOF(T) <= PaintOpAlign, ""); | 934 static_assert(alignof(T) <= PaintOpAlign, ""); |
935 | 935 |
936 auto pair = AllocatePaintOp(sizeof(T), bytes); | 936 auto pair = AllocatePaintOp(sizeof(T), bytes); |
937 T* op = reinterpret_cast<T*>(pair.first); | 937 T* op = reinterpret_cast<T*>(pair.first); |
938 size_t skip = pair.second; | 938 size_t skip = pair.second; |
939 | 939 |
940 new (op) T{std::forward<Args>(args)...}; | 940 new (op) T{std::forward<Args>(args)...}; |
941 op->type = static_cast<uint32_t>(T::kType); | 941 op->type = static_cast<uint32_t>(T::kType); |
942 op->skip = skip; | 942 op->skip = skip; |
943 AnalyzeAddedOp(op); | 943 AnalyzeAddedOp(op); |
944 return op; | 944 return op; |
945 } | 945 } |
946 | 946 |
947 template <typename T> | 947 template <typename T> |
948 void AnalyzeAddedOp(const T* op) { | 948 void AnalyzeAddedOp(const T* op) { |
949 num_slow_paths_ += op->CountSlowPathsFromFlags(); | 949 num_slow_paths_ += op->CountSlowPathsFromFlags(); |
950 num_slow_paths_ += op->CountSlowPaths(); | 950 num_slow_paths_ += op->CountSlowPaths(); |
951 | 951 |
952 has_discardable_images_ |= op->HasDiscardableImages(); | 952 has_discardable_images_ |= op->HasDiscardableImages(); |
953 has_discardable_images_ |= op->HasDiscardableImagesFromFlags(); | 953 has_discardable_images_ |= op->HasDiscardableImagesFromFlags(); |
954 | 954 |
955 subrecord_bytes_used_ += op->AdditionalBytesUsed(); | 955 subrecord_bytes_used_ += op->AdditionalBytesUsed(); |
956 } | 956 } |
957 | 957 |
958 // As a performance optimization because n=1 is an extremely common case just | 958 // As a performance optimization because n=1 is an extremely common case just |
959 // store the first op in the PaintOpBuffer itself to avoid an extra alloc. | 959 // store the first op in the PaintOpBuffer itself to avoid an extra alloc. |
960 base::AlignedMemory<sizeof(LargestPaintOp), PaintOpAlign> first_op_; | 960 std::aligned_storage<sizeof(LargestPaintOp), PaintOpAlign>::type first_op_; |
961 std::unique_ptr<char, base::AlignedFreeDeleter> data_; | 961 std::unique_ptr<char, base::AlignedFreeDeleter> data_; |
962 size_t used_ = 0; | 962 size_t used_ = 0; |
963 size_t reserved_ = 0; | 963 size_t reserved_ = 0; |
964 size_t op_count_ = 0; | 964 size_t op_count_ = 0; |
965 | 965 |
966 // Record paths for veto-to-msaa for gpu raster. | 966 // Record paths for veto-to-msaa for gpu raster. |
967 int num_slow_paths_ = 0; | 967 int num_slow_paths_ = 0; |
968 // Record additional bytes used by referenced sub-records and display lists. | 968 // Record additional bytes used by referenced sub-records and display lists. |
969 size_t subrecord_bytes_used_ = 0; | 969 size_t subrecord_bytes_used_ = 0; |
970 bool has_discardable_images_ = false; | 970 bool has_discardable_images_ = false; |
971 | 971 |
972 DISALLOW_COPY_AND_ASSIGN(PaintOpBuffer); | 972 DISALLOW_COPY_AND_ASSIGN(PaintOpBuffer); |
973 }; | 973 }; |
974 | 974 |
975 } // namespace cc | 975 } // namespace cc |
976 | 976 |
977 #endif // CC_PAINT_PAINT_OP_BUFFER_H_ | 977 #endif // CC_PAINT_PAINT_OP_BUFFER_H_ |
OLD | NEW |