| /* | |
| * Copyright 2025 Rive | |
| */ | |
| #pragma once | |
| #include <stdint.h> | |
| #include <algorithm> | |
| #include <cassert> | |
| namespace rive::gpu | |
| { | |
| // Some Mali and PowerVR devices crash when issuing draw commands with a large | |
| // instance count. This class breaks large instance ranges up into chunks that | |
| // can be safely issued on affected GPUs. | |
| class InstanceChunker | |
| { | |
| public: | |
| struct Chunk | |
| { | |
| uint32_t instanceCount; | |
| uint32_t baseInstance; | |
| }; | |
| struct Iterator | |
| { | |
| public: | |
| uint32_t currentChunkInstanceCount() const | |
| { | |
| return std::min(endInstance - currentInstance, | |
| maxSupportedInstancesPerDrawCommand); | |
| } | |
| Chunk operator*() const | |
| { | |
| return {currentChunkInstanceCount(), currentInstance}; | |
| } | |
| Iterator& operator++() | |
| { | |
| currentInstance += currentChunkInstanceCount(); | |
| return *this; | |
| } | |
| bool operator==(const Iterator& other) const | |
| { | |
| assert(endInstance == other.endInstance); | |
| assert(maxSupportedInstancesPerDrawCommand == | |
| other.maxSupportedInstancesPerDrawCommand); | |
| return currentInstance == other.currentInstance; | |
| } | |
| bool operator!=(const Iterator& other) const | |
| { | |
| return !(*this == other); | |
| } | |
| uint32_t currentInstance; | |
| uint32_t endInstance; | |
| uint32_t maxSupportedInstancesPerDrawCommand; | |
| }; | |
| InstanceChunker(uint32_t instanceCount, | |
| uint32_t baseInstance, | |
| uint32_t maxSupportedInstancesPerDrawCommand) : | |
| m_startInstance(baseInstance), | |
| m_endInstance(baseInstance + instanceCount), | |
| m_maxSupportedInstancesPerDrawCommand( | |
| maxSupportedInstancesPerDrawCommand) | |
| {} | |
| Iterator begin() const | |
| { | |
| return {m_startInstance, | |
| m_endInstance, | |
| m_maxSupportedInstancesPerDrawCommand}; | |
| } | |
| Iterator end() const | |
| { | |
| return {m_endInstance, | |
| m_endInstance, | |
| m_maxSupportedInstancesPerDrawCommand}; | |
| } | |
| private: | |
| uint32_t m_startInstance; | |
| uint32_t m_endInstance; | |
| uint32_t m_maxSupportedInstancesPerDrawCommand; | |
| }; | |
| } // namespace rive::gpu |