FastLED 3.10.8
Loading...
Searching...
No Matches
scale_up.cpp.hpp
Go to the documentation of this file.
1
2#include "fl/fx/2d/scale_up.h"
3
4#include "crgb.h"
5#include "fl/stl/stdint.h"
6#include "fl/gfx/upscale.h"
7#include "fl/stl/memory.h"
8#include "fl/math/xymap.h"
9#include "fl/stl/vector.h"
10#include "fl/stl/allocator.h"
11#include "fl/fx/fx2d.h"
12#include "fl/stl/noexcept.h"
13
14// Optimized for 2^n grid sizes in terms of both memory and performance.
15// If you are somehow running this on AVR then you probably want this if
16// you can make your grid size a power of 2.
17#define FASTLED_SCALE_UP_ALWAYS_POWER_OF_2 0 // 0 for always power of 2.
18// Uses more memory than FASTLED_SCALE_UP_ALWAYS_POWER_OF_2 but can handle
19// arbitrary grid sizes.
20#define FASTLED_SCALE_UP_HIGH_PRECISION 1 // 1 for always choose high precision.
21// Uses the most executable memory because both low and high precision versions
22// are compiled in. If the grid size is a power of 2 then the faster version is
23// used. Note that the floating point version has to be directly specified
24// because in testing it offered no benefits over the integer versions.
25#define FASTLED_SCALE_UP_DECIDE_AT_RUNTIME 2 // 2 for runtime decision.
26
27#define FASTLED_SCALE_UP_FORCE_FLOATING_POINT 3 // Warning, this is slow.
28
29#ifndef FASTLED_SCALE_UP
30#define FASTLED_SCALE_UP FASTLED_SCALE_UP_DECIDE_AT_RUNTIME
31#endif
32
33namespace fl {
34
36 // Turn off re-mapping of the delegate's XYMap, since bilinearExpand needs
37 // to work in screen coordinates. The final mapping will for this class will
38 // still be performed.
39 mDelegate->getXYMap().setRectangularGrid();
40}
41
43 if (mSurface.empty()) {
44 mSurface.resize(mDelegate->getNumLeds());
45 }
46 DrawContext delegateContext = context;
47 delegateContext.leds = fl::span<CRGB>(mSurface);
48 mDelegate->draw(delegateContext);
49
50 u16 in_w = mDelegate->getWidth();
51 u16 in_h = mDelegate->getHeight();
52 u16 out_w = getWidth();
53 u16 out_h = getHeight();
54 ;
55 if (in_w == out_w && in_h == out_h) {
56 noExpand(fl::span<const CRGB>(mSurface), context.leds, in_w, in_h);
57 } else {
58 expand(fl::span<const CRGB>(mSurface), context.leds, in_w, in_h, mXyMap);
59 }
60}
61
63 u16 height, const XYMap& mXyMap) FL_NO_EXCEPT {
64#if FASTLED_SCALE_UP == FASTLED_SCALE_UP_ALWAYS_POWER_OF_2
65 fl::upscalePowerOf2(input.data(), output.data(), static_cast<u8>(width), static_cast<u8>(height), mXyMap);
66#elif FASTLED_SCALE_UP == FASTLED_SCALE_UP_HIGH_PRECISION
67 fl::upscaleArbitrary(input.data(), output.data(), width, height, mXyMap);
68#elif FASTLED_SCALE_UP == FASTLED_SCALE_UP_DECIDE_AT_RUNTIME
69 fl::upscale(input.data(), output.data(), width, height, mXyMap);
70#elif FASTLED_SCALE_UP == FASTLED_SCALE_UP_FORCE_FLOATING_POINT
71 fl::upscaleFloat(input.data(), output.data(), static_cast<u8>(width), static_cast<u8>(height), mXyMap);
72#else
73#error "Invalid FASTLED_SCALE_UP"
74#endif
75}
76
78 u16 height) FL_NO_EXCEPT {
79 u16 n = mXyMap.getTotal();
80 for (u16 w = 0; w < width; w++) {
81 for (u16 h = 0; h < height; h++) {
82 u16 idx = mXyMap.mapToIndex(w, h);
83 if (idx < n) {
84 output[idx] = input[w * height + h];
85 }
86 }
87 }
88}
89
90} // namespace fl
XYMap xymap
XYMap mXyMap
Definition fx2d.h:31
u16 getWidth() const FL_NO_EXCEPT
Definition fx2d.h:25
Fx2d(const XYMap &xyMap) FL_NO_EXCEPT
Definition fx2d.h:20
u16 getHeight() const FL_NO_EXCEPT
Definition fx2d.h:24
ScaleUp(const XYMap &xymap, Fx2dPtr fx) FL_NO_EXCEPT
Construct a ScaleUp effect wrapper.
void noExpand(fl::span< const CRGB > input, fl::span< CRGB > output, u16 width, u16 height) FL_NO_EXCEPT
Direct copy without expansion (used when resolutions match)
void draw(DrawContext context) FL_NO_EXCEPT override
Render the effect by drawing delegate at low-res and scaling up.
fl::vector_psram< CRGB > mSurface
Low-resolution render buffer.
Definition scale_up.h:116
Fx2dPtr mDelegate
The wrapped effect that renders at low resolution.
Definition scale_up.h:115
void expand(fl::span< const CRGB > input, fl::span< CRGB > output, u16 width, u16 height, const XYMap &mXyMap) FL_NO_EXCEPT
Expand a low-resolution buffer to high-resolution using bilinear interpolation.
unsigned char u8
Definition stdint.h:131
u8 u8 fract8 blur_amount FL_NO_EXCEPT
Definition blur.h:186
void upscale(const CRGB *input, CRGB *output, u16 inputWidth, u16 inputHeight, const fl::XYMap &xyMap) FL_NO_EXCEPT
Definition upscale.h:57
u8 u8 height
Definition blur.h:186
u8 upscaleFloat(u8 v00, u8 v10, u8 v01, u8 v11, float dx, float dy) FL_NO_EXCEPT
void upscaleArbitrary(const CRGB *input, CRGB *output, u16 inputWidth, u16 inputHeight, const XYMap &xyMap) FL_NO_EXCEPT
Performs bilinear interpolation for upscaling an image.
u8 width
Definition blur.h:186
void upscalePowerOf2(const CRGB *input, CRGB *output, u8 inputWidth, u8 inputHeight, const XYMap &xyMap) FL_NO_EXCEPT
Performs bilinear interpolation for upscaling an image.
Base definition for an LED controller.
Definition crgb.hpp:179
Expands a grid using bilinear interpolation for upscaling effects.
fl::span< CRGB > leds