Skip to content

Commit

Permalink
Use the Scaler object
Browse files Browse the repository at this point in the history
  • Loading branch information
JesseTG committed Sep 23, 2023
1 parent adb690e commit afa9d60
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 36 deletions.
33 changes: 10 additions & 23 deletions src/libretro/platform/platform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

#include <array>
#include <cstdarg>
#include <cstdio>
#include <memory>

#include <gfx/scaler/scaler.h>
#include <libretro.h>
Expand All @@ -28,12 +30,13 @@
#include "../memory.hpp"
#include "../environment.hpp"
#include "../config.hpp"
#include "retro/scaler.hpp"
#include "sram.hpp"

constexpr unsigned DSI_CAMERA_WIDTH = 640;
constexpr unsigned DSI_CAMERA_HEIGHT = 480;
static struct retro_camera_callback _camera{};
static struct scaler_ctx _scaler{};
static std::unique_ptr<retro::Scaler> scaler{};

// YUV422 framebuffer, two pixels per 32-bit int (see DSi_Camera.h)
static std::array<uint32_t, DSI_CAMERA_WIDTH * DSI_CAMERA_HEIGHT / 2> _camera_buffer{};
Expand Down Expand Up @@ -100,25 +103,13 @@ static void conv_argb8888_yuyv(void *output_, const void *input_,

static void CaptureImage(const uint32_t *buffer, unsigned width, unsigned height, size_t pitch) noexcept {

if (_scaler.in_width != static_cast<int>(width) || _scaler.in_height != static_cast<int>(height) ||
_scaler.in_stride != static_cast<int>(pitch)) {
// If the camera's dimensions changed behind our back (or haven't been initialized)...
_scaler.in_width = width;
_scaler.in_height = height;
_scaler.in_stride = pitch;
_scaler.out_width = DSI_CAMERA_WIDTH;
_scaler.out_height = DSI_CAMERA_HEIGHT;
_scaler.out_stride = DSI_CAMERA_WIDTH * sizeof(uint32_t) / 2;
_scaler.direct_pixconv = conv_argb8888_yuyv;
_scaler.in_pixconv = nullptr;
_scaler.out_pixconv = conv_argb8888_yuyv;

if (!scaler_ctx_gen_filter(&_scaler)) {
retro::warn("Failed to initialize camera scaler.");
}
if (!scaler || scaler->InWidth() != width || scaler->InHeight() != height || scaler->InStride() != pitch) {
// If the scaler hasn't been initialized, or if the camera's dimensions changed behind our back...

scaler = std::make_unique<retro::Scaler>(SCALER_FMT_ARGB8888, SCALER_FMT_RGBA4444, SCALER_TYPE_BILINEAR, width, height, DSI_CAMERA_WIDTH, DSI_CAMERA_HEIGHT);
}

scaler_ctx_scale(&_scaler, _camera_buffer.data(), buffer);
scaler->Scale(_camera_buffer.data(), buffer);
}

void Platform::Init(int, char **) {
Expand All @@ -136,10 +127,6 @@ void Platform::Init(int, char **) {
_camera.width = DSI_CAMERA_WIDTH;
_camera.height = DSI_CAMERA_HEIGHT;

_scaler.in_fmt = SCALER_FMT_ARGB8888;
_scaler.out_fmt = SCALER_FMT_YUYV;
_scaler.scaler_type = SCALER_TYPE_BILINEAR; // TODO: Make configurable

if (!retro::environment(RETRO_ENVIRONMENT_GET_CAMERA_INTERFACE, &_camera)) {
retro::warn("Camera interface not available.");
} else {
Expand All @@ -157,7 +144,7 @@ void Platform::DeInit() {

_camera.start = nullptr;
_camera.stop = nullptr;
scaler_ctx_gen_reset(&_scaler);
scaler.reset();
}

void Platform::SignalStop(Platform::StopReason reason) {
Expand Down
16 changes: 16 additions & 0 deletions src/libretro/retro/scaler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "scaler.hpp"

#include <stdexcept>
#include <retro_assert.h>

constexpr unsigned PixelSize(scaler_pix_fmt fmt) noexcept {
switch (fmt) {
Expand Down Expand Up @@ -56,6 +57,10 @@ const char* PixelFormatName(scaler_pix_fmt fmt) noexcept {
}
}

retro::Scaler::Scaler() noexcept {

}

retro::Scaler::Scaler(
scaler_pix_fmt in_fmt,
scaler_pix_fmt out_fmt,
Expand Down Expand Up @@ -94,6 +99,17 @@ retro::Scaler::Scaler(
}
}

retro::Scaler::Scaler(scaler_ctx&& ctx) noexcept {
scaler = ctx;
ctx = {};

retro_assert(ctx.input.frame == nullptr);
retro_assert(ctx.scaled.frame == nullptr);
retro_assert(ctx.output.frame == nullptr);
retro_assert(ctx.in_pixconv == nullptr);
retro_assert(ctx.out_pixconv == nullptr);
}

retro::Scaler::~Scaler() noexcept {
scaler_ctx_gen_reset(&scaler);
}
Expand Down
2 changes: 2 additions & 0 deletions src/libretro/retro/scaler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@
namespace retro {
class Scaler {
public:
Scaler() noexcept;
Scaler(scaler_pix_fmt in_fmt, scaler_pix_fmt out_fmt, scaler_type type, unsigned in_width, unsigned in_height, unsigned out_width, unsigned out_height);
Scaler(scaler_ctx&& ctx) noexcept;
~Scaler() noexcept;
Scaler(const Scaler&) = delete;
Scaler(Scaler&&) noexcept;
Expand Down
22 changes: 10 additions & 12 deletions src/libretro/screenlayout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ melonds::ScreenLayoutData::ScreenLayoutData() :
}

melonds::ScreenLayoutData::~ScreenLayoutData() noexcept {
scaler_ctx_gen_reset(&hybridScaler);
}

void melonds::ScreenLayoutData::CopyScreen(const uint32_t* src, glm::uvec2 destTranslation) noexcept {
Expand Down Expand Up @@ -120,7 +119,7 @@ void melonds::ScreenLayoutData::CombineScreens(const uint32_t* topBuffer, const
retro_assert(hybridBuffer);
const uint32_t* primaryBuffer = layout == ScreenLayout::HybridTop ? topBuffer : bottomBuffer;

scaler_ctx_scale(&hybridScaler, hybridBuffer.Buffer(), primaryBuffer);
hybridScaler.Scale(hybridBuffer.Buffer(), primaryBuffer);
buffer.CopyRows(hybridBuffer.Buffer(), hybridScreenTranslation, NDS_SCREEN_SIZE<unsigned> * hybridRatio);

HybridSideScreenDisplay smallScreenLayout = HybridSmallScreenLayout();
Expand Down Expand Up @@ -323,16 +322,15 @@ void melonds::ScreenLayoutData::Update(melonds::Renderer renderer) noexcept {
// TODO: Don't recreate this buffer if the hybrid ratio didn't change
// TODO: Maintain a separate _hybridDirty flag
hybridBuffer = PixelBuffer(NDS_SCREEN_SIZE<unsigned> * hybridRatio);
hybridScaler.in_width = NDS_SCREEN_WIDTH;
hybridScaler.in_height = NDS_SCREEN_HEIGHT;
hybridScaler.in_stride = NDS_SCREEN_WIDTH * sizeof(uint32_t);
hybridScaler.out_width = NDS_SCREEN_WIDTH * hybridRatio;
hybridScaler.out_height = NDS_SCREEN_HEIGHT * hybridRatio;
hybridScaler.out_stride = NDS_SCREEN_WIDTH * hybridRatio * sizeof(uint32_t);
hybridScaler.in_fmt = SCALER_FMT_ARGB8888;
hybridScaler.out_fmt = SCALER_FMT_ARGB8888;
hybridScaler.scaler_type = config::video::ScreenFilter() == ScreenFilter::Nearest ? SCALER_TYPE_POINT : SCALER_TYPE_BILINEAR;
scaler_ctx_gen_filter(&hybridScaler);
hybridScaler = retro::Scaler(
SCALER_FMT_ARGB8888,
SCALER_FMT_ARGB8888,
config::video::ScreenFilter() == ScreenFilter::Nearest ? SCALER_TYPE_POINT : SCALER_TYPE_BILINEAR,
NDS_SCREEN_WIDTH,
NDS_SCREEN_HEIGHT,
NDS_SCREEN_WIDTH * hybridRatio,
NDS_SCREEN_HEIGHT * hybridRatio
);
} else {
hybridBuffer = nullptr;
}
Expand Down
3 changes: 2 additions & 1 deletion src/libretro/screenlayout.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include "environment.hpp"
#include "input.hpp"
#include "buffer.hpp"
#include "retro/scaler.hpp"

namespace melonds {
/// The native width of a single Nintendo DS screen, in pixels
Expand Down Expand Up @@ -228,7 +229,7 @@ namespace melonds {

// Used as a staging area for the hybrid screen to be scaled
PixelBuffer hybridBuffer;
struct scaler_ctx hybridScaler;
retro::Scaler hybridScaler;
};

constexpr bool LayoutSupportsScreenGap(ScreenLayout layout) noexcept {
Expand Down

0 comments on commit afa9d60

Please sign in to comment.