| #pragma once | |
| #include "rive/math/simd.hpp" | |
| #include <vector> | |
| #include "../src/intersection_board.hpp" | |
| namespace rive | |
| { | |
| class IntersectionBoardReferenceImpl | |
| { | |
| public: | |
| using FindResult = gpu::IntersectionTile::FindResult; | |
| // For testing IntersectionTile. | |
| void reset(int left, int top, int16_t baselineGroupIndex) | |
| { | |
| m_baselineGroupIndex = baselineGroupIndex; | |
| m_rects.clear(); | |
| m_groupIndices.clear(); | |
| m_overlapBits.clear(); | |
| } | |
| // For testing IntersectionBoard. | |
| void resizeAndReset(uint32_t viewportWidth, uint32_t viewportHeight) | |
| { | |
| reset(0, 0, 0); | |
| } | |
| // For testing IntersectionTile. | |
| void addRectangle(int4 ltrb, int16_t groupIndex, uint16_t overlapBits = 0) | |
| { | |
| m_rects.push_back(ltrb); | |
| m_groupIndices.push_back(groupIndex); | |
| m_overlapBits.push_back(overlapBits); | |
| } | |
| // For testing IntersectionTile. | |
| FindResult findMaxIntersectingGroupIndex(int4 ltrb, | |
| FindResult running) const | |
| { | |
| int16_t index = std::max(m_baselineGroupIndex, | |
| simd::reduce_max(running.maxGroupIndices)); | |
| uint16_t overlap = simd::reduce_or(running.overlapBits); | |
| for (size_t i = 0; i < m_rects.size(); ++i) | |
| { | |
| if (simd::all(ltrb.xy < m_rects[i].zw) && | |
| simd::all(ltrb.zw > m_rects[i].xy)) | |
| { | |
| if (m_groupIndices[i] > index) | |
| { | |
| index = m_groupIndices[i]; | |
| overlap = m_overlapBits[i]; | |
| } | |
| else if (m_groupIndices[i] == index) | |
| { | |
| overlap |= m_overlapBits[i]; | |
| } | |
| } | |
| } | |
| return {index, overlap}; | |
| } | |
| template <gpu::GroupingType> | |
| FindResult findMaxIntersectingGroupIndex(int4 ltrb, | |
| FindResult running) const | |
| { | |
| return findMaxIntersectingGroupIndex(ltrb, running); | |
| } | |
| // For testing IntersectionBoard. | |
| int16_t addRectangle(int4 ltrb) | |
| { | |
| auto r = | |
| findMaxIntersectingGroupIndex<gpu::GroupingType::disjoint>(ltrb, | |
| {}); | |
| auto groupIndex = r.maxGroupIndices[0] + 1; | |
| addRectangle(ltrb, groupIndex); | |
| return groupIndex; | |
| } | |
| int16_t addRectangle(int4 ltrb, | |
| rive::gpu::GroupingType groupingType, | |
| uint16_t overlapBits, | |
| uint16_t disallowOverlapMask) | |
| { | |
| auto r = findMaxIntersectingGroupIndex(ltrb, {}); | |
| int16_t groupIndex = r.maxGroupIndices[0] + 1; | |
| if (groupingType == rive::gpu::GroupingType::overlapAllowed && | |
| (r.overlapBits[0] & disallowOverlapMask) == 0) | |
| { | |
| // Back up into the layer that we can overlap. | |
| groupIndex = std::max(1, groupIndex - 1); | |
| } | |
| addRectangle(ltrb, groupIndex, overlapBits); | |
| return groupIndex; | |
| } | |
| private: | |
| int16_t m_baselineGroupIndex; | |
| std::vector<int4> m_rects; | |
| std::vector<int16_t> m_groupIndices; | |
| std::vector<int16_t> m_overlapBits; | |
| }; | |
| } // namespace rive |