Clean up the 3D renderer for enhanced flexibility (#1895)

* Give `GPU2D::Unit` a virtual destructor

- Undefined behavior avoided!

* Add an `array2d` alias

* Move various parts of `GPU2D::SoftRenderer` to `constexpr`

- `SoftRenderer::MosaicTable` is now initialized at compile-time
- Most of the `SoftRenderer::Color*` functions are now `constexpr`
- The aforementioned functions are used with a constant value in at least one place, so they'll be at least partially computed at compile-time

* Generalize `GLRenderer::PrepareCaptureFrame`

- Declare it in the base `Renderer3D` class, but make it empty

* Remove unneeded `virtual` specifiers

* Store `Framebuffer`'s memory in `unique_ptr`s

- Reduce the risk of leaks this way

* Clean up how `GLCompositor` is initialized

- Return it as an `std::optional` instead of a `std::unique_ptr`
- Make `GLCompositor` movable
- Replace `GLCompositor`'s plain arrays with `std::array` to simplify moving

* Pass `GPU` to `GLCompositor`'s important functions instead of passing it to the constructor

* Move `GLCompositor` to be a field within `GLRenderer`

- Some methods were moved up and made `virtual`

* Fix some linker errors

* Set the renderer in the frontend

* Remove unneeded `virtual` specifiers

* Remove `RenderSettings` in favor of just exposing the relevant member variables

* Update the frontend to accommodate the core changes

* Add `constexpr` and `const` to places in the interpolator

* Qualify references to `size_t`

* Construct the `optional` directly instead of using `make_optional`

- It makes the Linux build choke
- I think it's because `GLCompositor`'s constructor is `private`
This commit is contained in:
Jesse Talavera-Greenberg
2023-11-29 09:23:11 -05:00
committed by GitHub
parent e973236203
commit 7caddf9615
15 changed files with 366 additions and 334 deletions

View File

@ -29,16 +29,17 @@ namespace melonDS
class SoftRenderer : public Renderer3D
{
public:
SoftRenderer(melonDS::GPU& gpu) noexcept;
virtual ~SoftRenderer() override;
virtual void Reset() override;
SoftRenderer(melonDS::GPU& gpu, bool threaded = false) noexcept;
~SoftRenderer() override;
void Reset() override;
virtual void SetRenderSettings(const RenderSettings& settings) noexcept override;
void SetThreaded(bool threaded) noexcept;
[[nodiscard]] bool IsThreaded() const noexcept { return Threaded; }
virtual void VCount144() override;
virtual void RenderFrame() override;
virtual void RestartFrame() override;
virtual u32* GetLine(int line) override;
void VCount144() override;
void RenderFrame() override;
void RestartFrame() override;
u32* GetLine(int line) override;
void SetupRenderThread();
void StopRenderThread();
@ -65,13 +66,13 @@ private:
class Interpolator
{
public:
Interpolator() {}
Interpolator(s32 x0, s32 x1, s32 w0, s32 w1)
constexpr Interpolator() {}
constexpr Interpolator(s32 x0, s32 x1, s32 w0, s32 w1)
{
Setup(x0, x1, w0, w1);
}
void Setup(s32 x0, s32 x1, s32 w0, s32 w1)
constexpr void Setup(s32 x0, s32 x1, s32 w0, s32 w1)
{
this->x0 = x0;
this->x1 = x1;
@ -123,7 +124,7 @@ private:
}
}
void SetX(s32 x)
constexpr void SetX(s32 x)
{
x -= x0;
this->x = x;
@ -139,7 +140,7 @@ private:
}
}
s32 Interpolate(s32 y0, s32 y1)
constexpr s32 Interpolate(s32 y0, s32 y1) const
{
if (xdiff == 0 || y0 == y1) return y0;
@ -161,7 +162,7 @@ private:
}
}
s32 InterpolateZ(s32 z0, s32 z1, bool wbuffer)
constexpr s32 InterpolateZ(s32 z0, s32 z1, bool wbuffer) const
{
if (xdiff == 0 || z0 == z1) return z0;
@ -228,9 +229,9 @@ private:
class Slope
{
public:
Slope() {}
constexpr Slope() {}
s32 SetupDummy(s32 x0)
constexpr s32 SetupDummy(s32 x0)
{
dx = 0;
@ -249,7 +250,7 @@ private:
return x0;
}
s32 Setup(s32 x0, s32 x1, s32 y0, s32 y1, s32 w0, s32 w1, s32 y)
constexpr s32 Setup(s32 x0, s32 x1, s32 y0, s32 y1, s32 w0, s32 w1, s32 y)
{
this->x0 = x0;
this->y = y;
@ -293,7 +294,7 @@ private:
XMajor = (Increment > 0x40000);
if (side)
if constexpr (side)
{
// right
@ -324,7 +325,7 @@ private:
return x;
}
s32 Step()
constexpr s32 Step()
{
dx += Increment;
y++;
@ -334,7 +335,7 @@ private:
return x;
}
s32 XVal()
constexpr s32 XVal() const
{
s32 ret;
if (Negative) ret = x0 - (dx >> 18);
@ -346,7 +347,7 @@ private:
}
template<bool swapped>
void EdgeParams_XMajor(s32* length, s32* coverage)
constexpr void EdgeParams_XMajor(s32* length, s32* coverage) const
{
// only do length calc for right side when swapped as it's
// only needed for aa calcs, as actual line spans are broken
@ -372,7 +373,7 @@ private:
}
template<bool swapped>
void EdgeParams_YMajor(s32* length, s32* coverage)
constexpr void EdgeParams_YMajor(s32* length, s32* coverage) const
{
*length = 1;
@ -404,7 +405,7 @@ private:
}
template<bool swapped>
void EdgeParams(s32* length, s32* coverage)
constexpr void EdgeParams(s32* length, s32* coverage) const
{
if (XMajor)
return EdgeParams_XMajor<swapped>(length, coverage);