HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
sfloat_rgba16.hpp
1// Copyright Take Vos 2020-2021.
2// Distributed under the Boost Software License, Version 1.0.
3// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
4
5#pragma once
6
7#include "../numeric_array.hpp"
8#include "color.hpp"
9#include "../float16.hpp"
10#include "../pixel_map.hpp"
11#include <immintrin.h>
12#include <emmintrin.h>
13#include <algorithm>
14
15namespace tt {
16
18 // Red, Green, Blue, Alpha in binary16 (native endian).
20
21public:
22 sfloat_rgba16() noexcept
23 {
24 std::memset(v.data(), 0, sizeof(v));
25 }
26
27 sfloat_rgba16(sfloat_rgba16 const &rhs) noexcept = default;
28 sfloat_rgba16(sfloat_rgba16 &&rhs) noexcept = default;
29 sfloat_rgba16 &operator=(sfloat_rgba16 const &rhs) noexcept = default;
30 sfloat_rgba16 &operator=(sfloat_rgba16 &&rhs) noexcept = default;
31
32 sfloat_rgba16(f32x4 const &rhs) noexcept
33 {
34 ttlet rhs_fp16 = _mm_cvtps_ph(static_cast<__m128>(rhs), _MM_FROUND_CUR_DIRECTION);
35 _mm_storeu_si64(v.data(), rhs_fp16);
36 }
37
38 sfloat_rgba16 &operator=(f32x4 const &rhs) noexcept
39 {
40 ttlet rhs_fp16 = _mm_cvtps_ph(static_cast<__m128>(rhs), _MM_FROUND_CUR_DIRECTION);
41 _mm_storeu_si64(v.data(), rhs_fp16);
42 return *this;
43 }
44
45 explicit operator f32x4() const noexcept
46 {
47 ttlet rhs_fp16 = _mm_loadu_si64(v.data());
48 return f32x4{_mm_cvtph_ps(rhs_fp16)};
49 }
50
51 sfloat_rgba16(color const &rhs) noexcept : sfloat_rgba16(static_cast<f32x4>(rhs)) {}
52
53 sfloat_rgba16 &operator=(color const &rhs) noexcept
54 {
55 return *this = static_cast<f32x4>(rhs);
56 }
57
58 explicit operator color() const noexcept
59 {
60 return color{static_cast<f32x4>(*this)};
61 }
62
63 // std::array<float16,4> const &get() const noexcept {
64 // return v;
65 //}
66 //
67 // std::array<float16,4> &get() noexcept {
68 // return v;
69 //}
70
71 [[nodiscard]] friend bool operator==(sfloat_rgba16 const &lhs, sfloat_rgba16 const &rhs) noexcept
72 {
73 return lhs.v == rhs.v;
74 }
75 [[nodiscard]] friend bool operator!=(sfloat_rgba16 const &lhs, sfloat_rgba16 const &rhs) noexcept
76 {
77 return !(lhs == rhs);
78 }
79
80 [[nodiscard]] friend sfloat_rgba16 makeTransparent(sfloat_rgba16 const &rhs) noexcept
81 {
83 r.v = rhs.v;
84 std::get<3>(r.v) = 0x0000; // 0.0f
85 return r;
86 }
87};
88
89inline void fill(pixel_map<sfloat_rgba16> &image, f32x4 color) noexcept
90{
91 for (ssize_t y = 0; y != image.height(); ++y) {
92 auto row = image[y];
93 for (ssize_t x = 0; x != image.width(); ++x) {
94 row[x] = color;
95 }
96 }
97}
98
99inline void desaturate(pixel_map<sfloat_rgba16> &image, float brightness) noexcept
100{
101 for (ssize_t y = 0; y != image.height(); ++y) {
102 auto row = image[y];
103 for (ssize_t x = 0; x != image.width(); ++x) {
104 row[x] = desaturate(static_cast<f32x4>(row[x]), brightness);
105 }
106 }
107}
108
109inline void composit(pixel_map<sfloat_rgba16> &under, pixel_map<sfloat_rgba16> const &over) noexcept
110{
111 tt_assert(over.height() >= under.height());
112 tt_assert(over.width() >= under.width());
113
114 for (ssize_t rowNr = 0; rowNr != under.height(); ++rowNr) {
115 ttlet overRow = over.at(rowNr);
116 auto underRow = under.at(rowNr);
117 for (ssize_t columnNr = 0; columnNr != under.width(); ++columnNr) {
118 ttlet &overPixel = overRow[columnNr];
119 auto &underPixel = underRow[columnNr];
120
121 underPixel = composit(static_cast<f32x4>(underPixel), static_cast<f32x4>(overPixel));
122 }
123 }
124}
125
126inline void composit(pixel_map<sfloat_rgba16> &under, color over, pixel_map<uint8_t> const &mask) noexcept
127{
128 tt_assert(mask.height() >= under.height());
129 tt_assert(mask.width() >= under.width());
130
131 auto maskPixel = color{1.0f, 1.0f, 1.0f, 1.0f};
132
133 for (ssize_t rowNr = 0; rowNr != under.height(); ++rowNr) {
134 ttlet maskRow = mask.at(rowNr);
135 auto underRow = under.at(rowNr);
136 for (ssize_t columnNr = 0; columnNr != under.width(); ++columnNr) {
137 ttlet maskValue = maskRow[columnNr] / 255.0f;
138 maskPixel.a() = maskValue;
139
140 auto &pixel = underRow[columnNr];
141 pixel = composit(static_cast<color>(pixel), over * maskPixel);
142 }
143 }
144}
145
146} // namespace tt
This is a RGBA floating point color.
Definition color.hpp:39
Definition sfloat_rgba16.hpp:17
A 2D canvas of pixels.
Definition pixel_map.hpp:99
T data(T... args)
T memset(T... args)