|
| 1 | +#include "config.h" |
| 2 | +#include "lv_alpha_blend.h" |
| 3 | +#include "lv_common.h" |
| 4 | +#include "lv_cpu.h" |
| 5 | +#include "lv_alpha_blend_orc.h" |
| 6 | +#include <cassert> |
| 7 | + |
| 8 | +namespace { |
| 9 | + |
| 10 | + #pragma pack(1) |
| 11 | + |
| 12 | + struct rgb16_t { |
| 13 | + #if VISUAL_LITTLE_ENDIAN == 1 |
| 14 | + std::uint16_t b:5, g:6, r:5; |
| 15 | + #else |
| 16 | + std::uint16_t r:5, g:6, b:5; |
| 17 | + #endif |
| 18 | + }; |
| 19 | + |
| 20 | + #pragma pack() |
| 21 | + |
| 22 | + static_assert (sizeof (rgb16_t) == 2); |
| 23 | + |
| 24 | +} // anonymous namespace |
| 25 | + |
| 26 | +namespace LV { |
| 27 | + |
| 28 | + void alpha_blend_8 (std::span<std::uint8_t> dst, std::span<std::uint8_t const> src1, std::span<std::uint8_t const> src2, std::uint8_t alpha) |
| 29 | + { |
| 30 | + assert (dst.data () != src1.data ()); |
| 31 | + assert (dst.data () != src2.data ()); |
| 32 | + assert (src1.size () == src2.size ()); |
| 33 | + |
| 34 | + auto size {static_cast<int> (std::min (dst.size (), src1.size ()))}; |
| 35 | + ::simd_interpolate_8 (dst.data (), src1.data (), src2.data (), alpha, size); |
| 36 | + } |
| 37 | + |
| 38 | + void alpha_blend_16 (std::span<std::uint8_t> dst, std::span<std::uint8_t const> src1, std::span<std::uint8_t const> src2, std::uint8_t alpha) |
| 39 | + { |
| 40 | + assert (dst.data () != src1.data ()); |
| 41 | + assert (dst.data () != src2.data ()); |
| 42 | + assert (src1.size () == src2.size ()); |
| 43 | + |
| 44 | + auto dst_ptr = reinterpret_cast<rgb16_t*> (dst.data ()); |
| 45 | + auto src1_ptr = reinterpret_cast<rgb16_t const*> (src1.data ()); |
| 46 | + auto src2_ptr = reinterpret_cast<rgb16_t const*> (src2.data ()); |
| 47 | + |
| 48 | + auto size {static_cast<int> (std::min (dst.size (), src1.size ()))}; |
| 49 | + |
| 50 | + for (auto i = 0; i < size / sizeof (rgb16_t); i++) { |
| 51 | + dst_ptr[i].r = (alpha * (src2_ptr[i].r - src1_ptr[i].r)) / 255 + src1_ptr[i].r; |
| 52 | + dst_ptr[i].g = (alpha * (src2_ptr[i].g - src1_ptr[i].g)) / 255 + src1_ptr[i].g; |
| 53 | + dst_ptr[i].b = (alpha * (src2_ptr[i].b - src1_ptr[i].b)) / 255 + src1_ptr[i].b; |
| 54 | + } |
| 55 | + } |
| 56 | + |
| 57 | + void alpha_blend_24 (std::span<std::uint8_t> dst, std::span<std::uint8_t const> src1, std::span<std::uint8_t const> src2, std::uint8_t alpha) |
| 58 | + { |
| 59 | + assert (dst.data () != src1.data ()); |
| 60 | + assert (dst.data () != src2.data ()); |
| 61 | + assert (src1.size () == src2.size ()); |
| 62 | + |
| 63 | + auto size {static_cast<int> (std::min (dst.size (), src1.size ()))}; |
| 64 | + ::simd_interpolate_8 (dst.data (), src1.data (), src2.data (), alpha, size * 3); |
| 65 | + } |
| 66 | + |
| 67 | + void alpha_blend_32 (std::span<std::uint8_t> dst, std::span<std::uint8_t const> src1, std::span<std::uint8_t const> src2, std::uint8_t alpha) |
| 68 | + { |
| 69 | + assert (dst.data () != src1.data ()); |
| 70 | + assert (dst.data () != src2.data ()); |
| 71 | + assert (src1.size () == src2.size ()); |
| 72 | + |
| 73 | + auto size {static_cast<int> (std::min (dst.size (), src1.size ()))}; |
| 74 | + ::simd_interpolate_8 (dst.data (), src1.data (), src2.data (), alpha, size * 4); |
| 75 | + } |
| 76 | + |
| 77 | +} // LV namespace |
| 78 | + |
| 79 | + |
| 80 | +void visual_alpha_blend_8 (uint8_t *LV_RESTRICT dest, const uint8_t *LV_RESTRICT src1, const uint8_t *LV_RESTRICT src2, visual_size_t size, uint8_t alpha) |
| 81 | +{ |
| 82 | + simd_interpolate_8 (dest, src1, src2, alpha, (int) size); |
| 83 | +} |
| 84 | + |
| 85 | +void visual_alpha_blend_16 (uint8_t *LV_RESTRICT dest, const uint8_t *LV_RESTRICT src1, const uint8_t *LV_RESTRICT src2, visual_size_t size, uint8_t alpha) |
| 86 | +{ |
| 87 | + LV::alpha_blend_16 ({dest, size}, {src1, size}, {src2, size}, alpha); |
| 88 | +} |
| 89 | + |
| 90 | +void visual_alpha_blend_24 (uint8_t *LV_RESTRICT dest, const uint8_t *LV_RESTRICT src1, const uint8_t *LV_RESTRICT src2, visual_size_t size, uint8_t alpha) |
| 91 | +{ |
| 92 | + simd_interpolate_8 (dest, src1, src2, alpha, (int) size * 3); |
| 93 | +} |
| 94 | + |
| 95 | +void visual_alpha_blend_32 (uint8_t *LV_RESTRICT dest, const uint8_t *LV_RESTRICT src1, const uint8_t *LV_RESTRICT src2, visual_size_t size, uint8_t alpha) |
| 96 | +{ |
| 97 | + simd_interpolate_8 (dest, src1, src2, alpha, (int) size * 4); |
| 98 | +} |
0 commit comments