31 return static_cast<std::uint8_t
>(std::min(
46 return std::unexpected(
"invalid straight RGBA8 blit image");
64 static_cast<std::size_t
>(
sourceX)) * 4U;
67 static_cast<std::size_t
>(
x)) * 4U;
94 void RuntimeBitmapStore::publish(
DataId id, Surface& surface)
96 auto image = surface.baseImage;
102 if (!surface.colourKeyTransparent)
118 alpha =
static_cast<std::uint8_t
>(
119 static_cast<std::uint32_t
>(
alpha) * surface.globalAlpha / 255U);
122 surface.published = std::make_shared<const BitmapRuntimeAsset>(
124 surface.preferLinearFiltering, surface.presentationRect});
129 std::uint8_t globalAlpha)
133 count > std::numeric_limits<std::size_t>::max() / 4U)
134 return std::unexpected(
"runtime bitmap dimensions exceed allocation budget");
135 if (nextTag_ > std::numeric_limits<DataTag>::max())
136 return std::unexpected(
"runtime bitmap DataID namespace exhausted");
139 static_cast<DataTag>(nextTag_++));
152 publish(
id, surface);
153 surfaces_.emplace(
id, std::move(surface));
159 std::optional<std::array<float, 4>> presentationRect,
160 bool preferLinearFiltering)
162 const auto found = surfaces_.find(
id);
163 if (
found == surfaces_.end())
164 return std::unexpected(
"runtime bitmap DataID is not allocated");
167 return std::unexpected(
"runtime bitmap replacement extent mismatch");
168 if (presentationRect)
172 const auto&
rect = *presentationRect;
174 if (!std::ranges::all_of(
rect, [](
float v) {
return std::isfinite(v); }) ||
178 return std::unexpected(
"invalid runtime bitmap presentation extent");
181 return std::unexpected(
"runtime bitmap replacement extent mismatch");
183 found->second.presentationRect = presentationRect;
184 found->second.preferLinearFiltering = preferLinearFiltering;
186 publish(
id,
found->second);
191 DataId id, std::int32_t
x, std::int32_t
y,
195 const auto found = surfaces_.find(
id);
196 if (
found == surfaces_.end())
197 return std::unexpected(
"runtime bitmap DataID is not allocated");
202 const auto left = std::max<std::int64_t>(0,
x);
203 const auto top = std::max<std::int64_t>(0,
y);
204 const auto right = std::min<std::int64_t>(
205 image.width,
static_cast<std::int64_t
>(
x) +
width);
206 const auto bottom = std::min<std::int64_t>(
211 const auto red =
static_cast<std::uint8_t
>(
colorRef & 0xFFU);
212 const auto green =
static_cast<std::uint8_t
>((
colorRef >> 8U) & 0xFFU);
213 const auto blue =
static_cast<std::uint8_t
>((
colorRef >> 16U) & 0xFFU);
214 const bool keyed =
found->second.colourKeyTransparent &&
216 const auto alpha =
static_cast<std::uint8_t
>(
keyed ? 0
U : 255U);
223 (
static_cast<std::size_t
>(
row) *
image.width +
224 static_cast<std::size_t
>(
column)) * 4U;
233 publish(
id,
found->second);
241 const auto found = surfaces_.find(
id);
242 if (
found == surfaces_.end())
243 return std::unexpected(
"runtime bitmap DataID is not allocated");
251 publish(
id,
found->second);
258 const auto found = surfaces_.find(
id);
259 if (
found == surfaces_.end())
260 return std::unexpected(
"runtime bitmap DataID is not allocated");
263 publish(
id,
found->second);
270 const auto found = surfaces_.find(
id);
271 if (
found == surfaces_.end())
273 return found->second.logicalExtent;
279 const auto found = surfaces_.find(
id);
280 if (
found == surfaces_.end())
282 return found->second.globalAlpha;
288 const auto found = surfaces_.find(
id);
294 return surfaces_.erase(
id) != 0;
std::atomic< float > left
std::atomic< float > right
std::shared_ptr< const data::HmdTextureImage > source
std::expected< void, std::string > blit(DataId id, const LegacyBitmapRGBA8 &source, std::int32_t x, std::int32_t y, BitmapBlitMode mode=BitmapBlitMode::SourceOver)
std::optional< RuntimeBitmapExtent > extent(DataId id) const noexcept
std::optional< std::uint8_t > globalAlpha(DataId id) const noexcept
std::expected< void, std::string > update(DataId id, LegacyBitmapRGBA8 image, std::optional< std::array< float, 4 > > presentationRect={}, bool preferLinearFiltering=false)
std::expected< void, std::string > setGlobalAlpha(DataId id, std::uint8_t alpha)
std::shared_ptr< const BitmapRuntimeAsset > asset(DataId id) const noexcept
bool remove(DataId id) noexcept
std::expected< DataId, std::string > create(std::uint32_t width, std::uint32_t height, bool transparent, std::uint8_t globalAlpha=255)
std::expected< void, std::string > fill(DataId id, std::int32_t x, std::int32_t y, std::int32_t width, std::int32_t height, std::uint32_t colorRef)
constexpr DataTag dataTag(DataId id) noexcept
std::expected< void, std::string > blitStraightRGBA8(LegacyBitmapRGBA8 &destination, const LegacyBitmapRGBA8 &source, std::int32_t destinationX, std::int32_t destinationY, BitmapBlitMode mode)
bool isRuntimeBitmapDataId(DataId id) noexcept
constexpr DataId packDataId(std::uint16_t group, DataTag tag) noexcept
constexpr std::uint16_t RuntimeBitmapGroup
constexpr std::uint16_t dataGroup(DataId id) noexcept
std::vector< std::uint8_t > pixels