mirror of
https://github.com/libretro/RetroArch
synced 2025-02-20 06:40:18 +00:00
Add special point scaler for optimal speed.
This commit is contained in:
parent
3f613882a3
commit
41359681c3
@ -15,6 +15,7 @@
|
||||
|
||||
|
||||
#include "filter.h"
|
||||
#include "scaler_int.h"
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
@ -57,6 +58,8 @@ static bool gen_filter_point(struct scaler_ctx *ctx)
|
||||
gen_filter_point_sub(&ctx->horiz, ctx->out_width, x_pos, x_step);
|
||||
gen_filter_point_sub(&ctx->vert, ctx->out_height, y_pos, y_step);
|
||||
|
||||
ctx->scaler_special = scaler_argb8888_point_special;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -139,6 +139,8 @@ bool scaler_ctx_gen_filter(struct scaler_ctx *ctx)
|
||||
ctx->unscaled = false;
|
||||
}
|
||||
|
||||
ctx->scaler_special = NULL;
|
||||
|
||||
if (!allocate_frames(ctx))
|
||||
return false;
|
||||
|
||||
@ -192,13 +194,50 @@ void scaler_ctx_scale(struct scaler_ctx *ctx,
|
||||
clock_gettime(CLOCK_MONOTONIC, &start_tv);
|
||||
#endif
|
||||
|
||||
if (ctx->unscaled)
|
||||
if (ctx->unscaled) // Just perform straight pixel conversion.
|
||||
{
|
||||
ctx->direct_pixconv(output, input,
|
||||
ctx->out_width, ctx->out_height,
|
||||
ctx->out_stride, ctx->in_stride);
|
||||
}
|
||||
else
|
||||
else if (ctx->scaler_special) // Take some special, and (hopefully) more optimized path.
|
||||
{
|
||||
const void *inp = input;
|
||||
int in_stride = ctx->in_stride;
|
||||
|
||||
if (ctx->in_fmt != SCALER_FMT_ARGB8888)
|
||||
{
|
||||
ctx->in_pixconv(ctx->input.frame, input,
|
||||
ctx->in_width, ctx->in_height,
|
||||
ctx->input.stride, ctx->in_stride);
|
||||
|
||||
inp = ctx->input.frame;
|
||||
in_stride = ctx->input.stride;
|
||||
}
|
||||
|
||||
bool conv_out = ctx->out_fmt != SCALER_FMT_ARGB8888;
|
||||
void *outp = output;
|
||||
int out_stride = ctx->out_stride;
|
||||
|
||||
if (conv_out)
|
||||
{
|
||||
outp = ctx->output.frame;
|
||||
out_stride = ctx->output.stride;
|
||||
}
|
||||
|
||||
ctx->scaler_special(ctx, outp, inp,
|
||||
ctx->out_width, ctx->out_height,
|
||||
ctx->in_width, ctx->in_height,
|
||||
out_stride, in_stride);
|
||||
|
||||
if (conv_out)
|
||||
{
|
||||
ctx->out_pixconv(output, ctx->output.frame,
|
||||
ctx->out_width, ctx->out_height,
|
||||
ctx->out_stride, ctx->output.stride);
|
||||
}
|
||||
}
|
||||
else // Take generic filter path.
|
||||
{
|
||||
if (ctx->in_fmt != SCALER_FMT_ARGB8888)
|
||||
{
|
||||
@ -230,4 +269,3 @@ void scaler_ctx_scale(struct scaler_ctx *ctx,
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -63,6 +63,8 @@ struct scaler_ctx
|
||||
const void*, int);
|
||||
void (*scaler_vert)(const struct scaler_ctx*,
|
||||
void*, int);
|
||||
void (*scaler_special)(const struct scaler_ctx*,
|
||||
void*, const void*, int, int, int, int, int, int);
|
||||
|
||||
void (*in_pixconv)(void*, const void*, int, int, int, int);
|
||||
void (*out_pixconv)(void*, const void*, int, int, int, int);
|
||||
|
@ -231,3 +231,33 @@ void scaler_argb8888_horiz(const struct scaler_ctx *ctx, const void *input_, int
|
||||
}
|
||||
#endif
|
||||
|
||||
void scaler_argb8888_point_special(const struct scaler_ctx *ctx,
|
||||
void *output_, const void *input_,
|
||||
int out_width, int out_height,
|
||||
int in_width, int in_height,
|
||||
int out_stride, int in_stride)
|
||||
{
|
||||
(void)ctx;
|
||||
int x_pos = (1 << 15) * in_width / out_width - (1 << 15);
|
||||
int x_step = (1 << 16) * in_width / out_width;
|
||||
int y_pos = (1 << 15) * in_height / out_height - (1 << 15);
|
||||
int y_step = (1 << 16) * in_height / out_height;
|
||||
|
||||
if (x_pos < 0)
|
||||
x_pos = 0;
|
||||
if (y_pos < 0)
|
||||
y_pos = 0;
|
||||
|
||||
const uint32_t *input = (const uint32_t*)input_;
|
||||
uint32_t *output = (uint32_t*)output_;
|
||||
|
||||
for (int h = 0; h < out_height; h++, y_pos += y_step, output += out_stride >> 2)
|
||||
{
|
||||
int x = x_pos;
|
||||
const uint32_t *inp = input + (y_pos >> 16) * (in_stride >> 2);
|
||||
|
||||
for (int w = 0; w < out_width; w++, x += x_step)
|
||||
output[w] = inp[x >> 16];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -21,5 +21,11 @@
|
||||
void scaler_argb8888_vert(const struct scaler_ctx *ctx, void *output, int stride);
|
||||
void scaler_argb8888_horiz(const struct scaler_ctx *ctx, const void *input, int stride);
|
||||
|
||||
void scaler_argb8888_point_special(const struct scaler_ctx *ctx,
|
||||
void *output, const void *input,
|
||||
int out_width, int out_height,
|
||||
int in_width, int in_height,
|
||||
int out_stride, int in_stride);
|
||||
|
||||
#endif
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user