refactor(renderer): pulled out decodeImage from context helper and made it platform decode

# Description
made decode Image implantation in `RenderContextHelperImpl` now defined in `RenderContext`

# Details
We were copy pasting the code for decoding into several places. Moving it to `RenderContext` allows us to have it in one spot and just be used by default.

Diffs=
e7b0480e4e refactor(renderer): pulled out decodeImage from context helper and made it platform decode (#9448)

Co-authored-by: Jonathon Copeland <jcopela4@gmail.com>
This commit is contained in:
blakdragan7
2025-04-15 17:37:06 +00:00
parent 21ae889c2f
commit 009f7da659
9 changed files with 59 additions and 71 deletions

View File

@@ -1 +1 @@
53131428a668ea7907d47de9fb36501dc7990dda
e7b0480e4e4b46a349584504b2ae690345167969

View File

@@ -24,11 +24,6 @@ public:
PixelFormat pixelFormat,
std::unique_ptr<const uint8_t[]> bytes);
Bitmap(uint32_t width,
uint32_t height,
PixelFormat pixelFormat,
const uint8_t* bytes);
private:
uint32_t m_Width;
uint32_t m_Height;

View File

@@ -18,13 +18,6 @@ Bitmap::Bitmap(uint32_t width,
m_Bytes(std::move(bytes))
{}
Bitmap::Bitmap(uint32_t width,
uint32_t height,
PixelFormat pixelFormat,
const uint8_t* bytes) :
Bitmap(width, height, pixelFormat, std::unique_ptr<const uint8_t[]>(bytes))
{}
static size_t bytes_per_pixel(Bitmap::PixelFormat format)
{
switch (format)

View File

@@ -14,8 +14,6 @@ namespace rive::gpu
class RenderContextHelperImpl : public RenderContextImpl
{
public:
rcp<Texture> decodeImageTexture(Span<const uint8_t> encodedBytes) override;
void resizeFlushUniformBuffer(size_t sizeInBytes) override;
void resizeImageDrawUniformBuffer(size_t sizeInBytes) override;
void resizePathBuffer(size_t sizeInBytes,
@@ -70,12 +68,6 @@ protected:
BufferRing* tessSpanBufferRing() { return m_tessSpanBuffer.get(); }
BufferRing* triangleBufferRing() { return m_triangleBuffer.get(); }
virtual rcp<Texture> makeImageTexture(
uint32_t width,
uint32_t height,
uint32_t mipLevelCount,
const uint8_t imageDataRGBAPremul[]) = 0;
virtual std::unique_ptr<BufferRing> makeUniformBufferRing(
size_t capacityInBytes) = 0;
virtual std::unique_ptr<BufferRing> makeStorageBufferRing(

View File

@@ -5,6 +5,7 @@
#pragma once
#include "rive/renderer/render_context.hpp"
#include "rive/renderer/texture.hpp"
namespace rive::gpu
{
@@ -26,10 +27,22 @@ public:
RenderBufferFlags,
size_t) = 0;
// Decodes the image bytes and creates a texture that can be bound to the
// draw shader for an image paint.
virtual rcp<Texture> decodeImageTexture(
Span<const uint8_t> encodedBytes) = 0;
// Use platform apis to decode the image bytes and creates a texture if
// available. If not available leaving its default implementation will cause
// rive decoders to be used instead
virtual rcp<Texture> platformDecodeImageTexture(
Span<const uint8_t> encodedBytes)
{
return nullptr;
};
// this is called in the case of the default Bitmap class being used to
// decode images so that it can be converted into a backend specific image.
virtual rcp<Texture> makeImageTexture(
uint32_t width,
uint32_t height,
uint32_t mipLevelCount,
const uint8_t imageDataRGBAPremul[]) = 0;
// Resize GPU buffers. These methods cannot fail, and must allocate the
// exact size requested.

View File

@@ -142,7 +142,10 @@ public:
RenderBufferFlags,
size_t) override;
rcp<Texture> decodeImageTexture(Span<const uint8_t> encodedBytes) override;
rcp<Texture> makeImageTexture(uint32_t width,
uint32_t height,
uint32_t mipLevelCount,
const uint8_t imageDataRGBAPremul[]) override;
void hotloadShaders(rive::Span<const uint32_t> spirvData);

View File

@@ -15,6 +15,10 @@
#include <string_view>
#ifdef RIVE_DECODERS
#include "rive/decoders/bitmap_decoder.hpp"
#endif
namespace rive::gpu
{
constexpr size_t kDefaultSimpleGradientCapacity = 512;
@@ -132,7 +136,28 @@ rcp<RenderBuffer> RenderContext::makeRenderBuffer(RenderBufferType type,
rcp<RenderImage> RenderContext::decodeImage(Span<const uint8_t> encodedBytes)
{
rcp<Texture> texture = m_impl->decodeImageTexture(encodedBytes);
rcp<Texture> texture = m_impl->platformDecodeImageTexture(encodedBytes);
#ifdef RIVE_DECODERS
if (texture == nullptr)
{
auto bitmap = Bitmap::decode(encodedBytes.data(), encodedBytes.size());
if (bitmap)
{
// For now, RenderContextImpl::makeImageTexture() only accepts RGBA.
if (bitmap->pixelFormat() != Bitmap::PixelFormat::RGBAPremul)
{
bitmap->pixelFormat(Bitmap::PixelFormat::RGBAPremul);
}
uint32_t width = bitmap->width();
uint32_t height = bitmap->height();
uint32_t mipLevelCount = math::msb(height | width);
texture = m_impl->makeImageTexture(width,
height,
mipLevelCount,
bitmap->bytes());
}
}
#endif
return texture != nullptr ? make_rcp<RiveRenderImage>(std::move(texture))
: nullptr;
}

View File

@@ -13,26 +13,6 @@
namespace rive::gpu
{
rcp<Texture> RenderContextHelperImpl::decodeImageTexture(
Span<const uint8_t> encodedBytes)
{
#ifdef RIVE_DECODERS
auto bitmap = Bitmap::decode(encodedBytes.data(), encodedBytes.size());
if (bitmap)
{
// For now, RenderContextImpl::makeImageTexture() only accepts RGBA.
if (bitmap->pixelFormat() != Bitmap::PixelFormat::RGBAPremul)
{
bitmap->pixelFormat(Bitmap::PixelFormat::RGBAPremul);
}
uint32_t width = bitmap->width();
uint32_t height = bitmap->height();
uint32_t mipLevelCount = math::msb(height | width);
return makeImageTexture(width, height, mipLevelCount, bitmap->bytes());
}
#endif
return nullptr;
}
void RenderContextHelperImpl::resizeFlushUniformBuffer(size_t sizeInBytes)
{

View File

@@ -627,31 +627,18 @@ private:
std::numeric_limits<size_t>::max();
};
rcp<Texture> RenderContextVulkanImpl::decodeImageTexture(
Span<const uint8_t> encodedBytes)
rcp<Texture> RenderContextVulkanImpl::makeImageTexture(
uint32_t width,
uint32_t height,
uint32_t mipLevelCount,
const uint8_t imageDataRGBAPremul[])
{
#ifdef RIVE_DECODERS
auto bitmap = Bitmap::decode(encodedBytes.data(), encodedBytes.size());
if (bitmap)
{
// For now, RenderContextImpl::makeImageTexture() only accepts
// RGBAPremul.
if (bitmap->pixelFormat() != Bitmap::PixelFormat::RGBAPremul)
{
bitmap->pixelFormat(Bitmap::PixelFormat::RGBAPremul);
}
uint32_t width = bitmap->width();
uint32_t height = bitmap->height();
uint32_t mipLevelCount = math::msb(height | width);
return make_rcp<TextureVulkanImpl>(m_vk,
width,
height,
mipLevelCount,
TextureFormat::rgba8,
bitmap->bytes());
}
#endif
return nullptr;
return make_rcp<TextureVulkanImpl>(m_vk,
width,
height,
mipLevelCount,
TextureFormat::rgba8,
imageDataRGBAPremul);
}
// Renders color ramps to the gradient texture.