Files
klubhaus-doorbell/libraries/FastLED/src/fl/rectangular_draw_buffer.h
2026-02-12 00:45:31 -08:00

91 lines
2.9 KiB
C++

#pragma once
// Takes multiple CRGB arrays[] of different sizes and generates one CRGB
// array of size MAX(WIDTH) * NUM_OF_STRIPS that contains them all.
// This allows the flexible LED array usage in FastLED for block renderers.
// Needed by controllers that require a compact, rectangular buffer of pixel
// data. Namely, ObjectFLED and the I2S controllers. This class handles using
// multiple independent strips of LEDs, each with their own buffer of pixel
// data. The strips are not necessarily contiguous in memory. One or more
// DrawItems containing the pin number and number are queued up. When the
// queue-ing is done, the buffers are compacted into the rectangular buffer.
// Data access is achieved through a span<u8> representing the pixel data
// for that pin.
#include "fl/stdint.h"
#include "fl/int.h"
#include "fl/map.h"
#include "fl/namespace.h"
#include "fl/scoped_array.h"
#include "fl/span.h"
#include "fl/vector.h"
namespace fl {
struct DrawItem {
DrawItem() = default;
DrawItem(u8 pin, u16 numLeds, bool is_rgbw);
// Rule of 5 for POD data
DrawItem(const DrawItem &other) = default;
DrawItem &operator=(const DrawItem &other) = default;
DrawItem(DrawItem &&other) noexcept = default;
DrawItem &operator=(DrawItem &&other) noexcept = default;
u8 mPin = 0;
u32 mNumBytes = 0;
bool mIsRgbw = false;
bool operator!=(const DrawItem &other) const {
return mPin != other.mPin || mNumBytes != other.mNumBytes ||
mIsRgbw != other.mIsRgbw;
}
};
class RectangularDrawBuffer {
public:
RectangularDrawBuffer() = default;
~RectangularDrawBuffer() = default;
fl::span<u8> getLedsBufferBytesForPin(u8 pin,
bool clear_first = true);
// Safe to call multiple times before calling queue() once. Returns true on
// the first call, false after.
bool onQueuingStart();
void queue(const DrawItem &item);
// Compiles the RectangularBuffer if necessary.
// Safe to call multiple times before calling onQueueingStart() again.
// Returns true on the first call, false after.
bool onQueuingDone();
// Valid after onQueueDone:
u32 getMaxBytesInStrip() const;
u32 getTotalBytes() const;
void getBlockInfo(u32 *num_strips, u32 *bytes_per_strip,
u32 *total_bytes) const;
// protected:
typedef fl::HeapVector<DrawItem> DrawList;
// We manually manage the memory for the buffer of all LEDs so that it can
// go into psram on ESP32S3, which is managed by fl::PSRamAllocator.
scoped_array<u8> mAllLedsBufferUint8;
u32 mAllLedsBufferUint8Size = 0;
fl::FixedMap<u8, fl::span<u8>, 50> mPinToLedSegment;
DrawList mDrawList;
DrawList mPrevDrawList;
bool mDrawListChangedThisFrame = false;
enum QueueState { IDLE, QUEUEING, QUEUE_DONE };
QueueState mQueueState = IDLE;
};
} // namespace fl