mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-26 09:30:24 +00:00
LibGPU+LibSoftGPU: Move size and pixel format information to GPU::Image
Size and format information are the same for every implementation and do not need to be virtual. This removes the need to reimplement them for each driver.
This commit is contained in:
parent
dc8be499e6
commit
3b2ded1d44
Notes:
sideshowbarker
2024-07-18 03:20:18 +09:00
Author: https://github.com/sunverwerth Commit: https://github.com/SerenityOS/serenity/commit/3b2ded1d44 Pull-request: https://github.com/SerenityOS/serenity/pull/16590 Reviewed-by: https://github.com/ADKaster Reviewed-by: https://github.com/ccapitalK Reviewed-by: https://github.com/gmta ✅ Reviewed-by: https://github.com/supercomputer7 ✅
6 changed files with 51 additions and 37 deletions
|
@ -1,5 +1,6 @@
|
|||
set(SOURCES
|
||||
Driver.cpp
|
||||
Image.cpp
|
||||
)
|
||||
|
||||
serenity_lib(LibGPU gpu)
|
||||
|
|
32
Userland/Libraries/LibGPU/Image.cpp
Normal file
32
Userland/Libraries/LibGPU/Image.cpp
Normal file
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Copyright (c) 2022, Stephan Unverwerth <s.unverwerth@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <AK/Math.h>
|
||||
#include <LibGPU/Image.h>
|
||||
|
||||
namespace GPU {
|
||||
|
||||
Image::Image(void const* ownership_token, GPU::PixelFormat const& pixel_format, u32 width, u32 height, u32 depth, u32 max_levels)
|
||||
: m_ownership_token { ownership_token }
|
||||
, m_pixel_format { pixel_format }
|
||||
{
|
||||
VERIFY(width > 0);
|
||||
VERIFY(height > 0);
|
||||
VERIFY(depth > 0);
|
||||
VERIFY(max_levels > 0);
|
||||
|
||||
u32 number_of_levels_in_full_chain = max(max(AK::log2(width), AK::log2(height)), AK::log2(depth)) + 1;
|
||||
m_mipmap_sizes.resize(min(max_levels, number_of_levels_in_full_chain));
|
||||
|
||||
for (u32 level = 0; level < m_mipmap_sizes.size(); ++level) {
|
||||
m_mipmap_sizes[level] = { width, height, depth };
|
||||
width = max(width / 2, 1);
|
||||
height = max(height / 2, 1);
|
||||
depth = max(depth / 2, 1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -8,24 +8,24 @@
|
|||
#pragma once
|
||||
|
||||
#include <AK/RefCounted.h>
|
||||
#include <AK/Vector.h>
|
||||
#include <LibGPU/ImageDataLayout.h>
|
||||
#include <LibGPU/ImageFormat.h>
|
||||
#include <LibGfx/Vector3.h>
|
||||
|
||||
namespace GPU {
|
||||
|
||||
class Image : public RefCounted<Image> {
|
||||
public:
|
||||
Image(void const* ownership_token)
|
||||
: m_ownership_token { ownership_token }
|
||||
{
|
||||
}
|
||||
|
||||
Image(void const* ownership_token, PixelFormat const&, u32 width, u32 height, u32 depth, u32 max_levels);
|
||||
virtual ~Image() { }
|
||||
|
||||
virtual u32 width_at_level(u32 level) const = 0;
|
||||
virtual u32 height_at_level(u32 level) const = 0;
|
||||
virtual u32 depth_at_level(u32 level) const = 0;
|
||||
virtual u32 number_of_levels() const = 0;
|
||||
u32 width_at_level(u32 level) const { return m_mipmap_sizes[level].x(); }
|
||||
u32 height_at_level(u32 level) const { return m_mipmap_sizes[level].y(); }
|
||||
u32 depth_at_level(u32 level) const { return m_mipmap_sizes[level].z(); }
|
||||
u32 number_of_levels() const { return m_mipmap_sizes.size(); }
|
||||
|
||||
PixelFormat pixel_format() const { return m_pixel_format; }
|
||||
|
||||
virtual void regenerate_mipmaps() = 0;
|
||||
|
||||
|
@ -38,6 +38,8 @@ public:
|
|||
|
||||
private:
|
||||
void const* const m_ownership_token { nullptr };
|
||||
Vector<Vector3<u32>> m_mipmap_sizes;
|
||||
PixelFormat m_pixel_format;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -12,3 +12,4 @@ set(SOURCES
|
|||
add_compile_options(-Wno-psabi)
|
||||
serenity_lib(LibSoftGPU softgpu)
|
||||
target_link_libraries(LibSoftGPU PRIVATE LibCore LibGfx)
|
||||
target_sources(LibSoftGPU PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../LibGPU/Image.cpp")
|
||||
|
|
|
@ -14,9 +14,8 @@
|
|||
namespace SoftGPU {
|
||||
|
||||
Image::Image(void const* ownership_token, GPU::PixelFormat const& pixel_format, u32 width, u32 height, u32 depth, u32 max_levels)
|
||||
: GPU::Image(ownership_token)
|
||||
, m_pixel_format(pixel_format)
|
||||
, m_mipmap_buffers(FixedArray<RefPtr<Typed3DBuffer<FloatVector4>>>::must_create_but_fixme_should_propagate_errors(max_levels))
|
||||
: GPU::Image(ownership_token, pixel_format, width, height, depth, max_levels)
|
||||
, m_mipmap_buffers(FixedArray<RefPtr<Typed3DBuffer<FloatVector4>>>::must_create_but_fixme_should_propagate_errors(number_of_levels()))
|
||||
{
|
||||
VERIFY(pixel_format == GPU::PixelFormat::Alpha
|
||||
|| pixel_format == GPU::PixelFormat::Intensity
|
||||
|
@ -24,28 +23,14 @@ Image::Image(void const* ownership_token, GPU::PixelFormat const& pixel_format,
|
|||
|| pixel_format == GPU::PixelFormat::LuminanceAlpha
|
||||
|| pixel_format == GPU::PixelFormat::RGB
|
||||
|| pixel_format == GPU::PixelFormat::RGBA);
|
||||
VERIFY(width > 0);
|
||||
VERIFY(height > 0);
|
||||
VERIFY(depth > 0);
|
||||
VERIFY(max_levels > 0);
|
||||
|
||||
m_width_is_power_of_two = is_power_of_two(width);
|
||||
m_height_is_power_of_two = is_power_of_two(height);
|
||||
m_depth_is_power_of_two = is_power_of_two(depth);
|
||||
|
||||
u32 level;
|
||||
for (level = 0; level < max_levels; ++level) {
|
||||
m_mipmap_buffers[level] = MUST(Typed3DBuffer<FloatVector4>::try_create(width, height, depth));
|
||||
|
||||
if (width <= 1 && height <= 1 && depth <= 1)
|
||||
break;
|
||||
|
||||
width = max(width / 2, 1);
|
||||
height = max(height / 2, 1);
|
||||
depth = max(depth / 2, 1);
|
||||
for (u32 level = 0; level < number_of_levels(); ++level) {
|
||||
m_mipmap_buffers[level] = MUST(Typed3DBuffer<FloatVector4>::try_create(width_at_level(level), height_at_level(level), depth_at_level(level)));
|
||||
}
|
||||
|
||||
m_number_of_levels = level + 1;
|
||||
}
|
||||
|
||||
GPU::ImageDataLayout Image::image_data_layout(u32 level, Vector3<i32> offset) const
|
||||
|
@ -86,7 +71,7 @@ void Image::write_texels(u32 level, Vector3<i32> const& output_offset, void cons
|
|||
|
||||
PixelConverter converter { input_layout, output_layout };
|
||||
ErrorOr<void> conversion_result;
|
||||
switch (m_pixel_format) {
|
||||
switch (pixel_format()) {
|
||||
case GPU::PixelFormat::Luminance:
|
||||
case GPU::PixelFormat::RGB:
|
||||
// Both Luminance and RGB set the alpha to 1, regardless of the source texel
|
||||
|
@ -195,7 +180,7 @@ void Image::regenerate_mipmaps()
|
|||
};
|
||||
|
||||
// For levels 1..number_of_levels-1, we generate downscaled versions of the level above
|
||||
for (u32 level = 1; level < m_number_of_levels; ++level) {
|
||||
for (u32 level = 1; level < number_of_levels(); ++level) {
|
||||
auto higher_level_bitmap = copy_image_into_bitmap(level - 1);
|
||||
auto current_level_bitmap = empty_bitmap_for_level(level);
|
||||
|
||||
|
|
|
@ -22,10 +22,6 @@ class Image final : public GPU::Image {
|
|||
public:
|
||||
Image(void const* ownership_token, GPU::PixelFormat const&, u32 width, u32 height, u32 depth, u32 max_levels);
|
||||
|
||||
virtual u32 width_at_level(u32 level) const override { return m_mipmap_buffers[level]->width(); }
|
||||
virtual u32 height_at_level(u32 level) const override { return m_mipmap_buffers[level]->height(); }
|
||||
virtual u32 depth_at_level(u32 level) const override { return m_mipmap_buffers[level]->depth(); }
|
||||
virtual u32 number_of_levels() const override { return m_number_of_levels; }
|
||||
bool width_is_power_of_two() const { return m_width_is_power_of_two; }
|
||||
bool height_is_power_of_two() const { return m_height_is_power_of_two; }
|
||||
bool depth_is_power_of_two() const { return m_depth_is_power_of_two; }
|
||||
|
@ -58,9 +54,6 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
u32 m_number_of_levels { 0 };
|
||||
|
||||
GPU::PixelFormat m_pixel_format;
|
||||
FixedArray<RefPtr<Typed3DBuffer<FloatVector4>>> m_mipmap_buffers;
|
||||
|
||||
bool m_width_is_power_of_two { false };
|
||||
|
|
Loading…
Reference in a new issue