mirror of
https://github.com/libretro/RetroArch.git
synced 2024-11-30 11:40:32 +00:00
225 lines
6.1 KiB
C
225 lines
6.1 KiB
C
/* RetroArch - A frontend for libretro.
|
|
* Copyright (C) 2011-2016 - Daniel De Matteis
|
|
*
|
|
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
|
* of the GNU General Public License as published by the Free Software Found-
|
|
* ation, either version 3 of the License, or (at your option) any later version.
|
|
*
|
|
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
* PURPOSE. See the GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along with RetroArch.
|
|
* If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include <gfx/scaler/scaler.h>
|
|
|
|
#include <libretro.h>
|
|
|
|
#include "../performance_counters.h"
|
|
|
|
#include "video_driver.h"
|
|
#include "video_frame.h"
|
|
|
|
void video_frame_convert_rgb16_to_rgb32(
|
|
void *data,
|
|
void *output,
|
|
const void *input,
|
|
int width, int height,
|
|
int in_pitch)
|
|
{
|
|
struct scaler_ctx *scaler = (struct scaler_ctx*)data;
|
|
|
|
if (width != scaler->in_width || height != scaler->in_height)
|
|
{
|
|
scaler->in_width = width;
|
|
scaler->in_height = height;
|
|
scaler->out_width = width;
|
|
scaler->out_height = height;
|
|
scaler->in_fmt = SCALER_FMT_RGB565;
|
|
scaler->out_fmt = SCALER_FMT_ARGB8888;
|
|
scaler->scaler_type = SCALER_TYPE_POINT;
|
|
scaler_ctx_gen_filter(scaler);
|
|
}
|
|
|
|
scaler->in_stride = in_pitch;
|
|
scaler->out_stride = width * sizeof(uint32_t);
|
|
|
|
scaler_ctx_scale(scaler, output, input);
|
|
}
|
|
|
|
void video_frame_scale(
|
|
void *data,
|
|
void *output,
|
|
const void *input,
|
|
enum scaler_pix_fmt format,
|
|
unsigned scaler_width,
|
|
unsigned scaler_height,
|
|
unsigned scaler_pitch,
|
|
unsigned width,
|
|
unsigned height,
|
|
unsigned pitch)
|
|
{
|
|
struct scaler_ctx *scaler = (struct scaler_ctx*)data;
|
|
|
|
if (
|
|
width != (unsigned)scaler->in_width
|
|
|| height != (unsigned)scaler->in_height
|
|
|| format != scaler->in_fmt
|
|
|| pitch != (unsigned)scaler->in_stride
|
|
)
|
|
{
|
|
scaler->in_fmt = format;
|
|
scaler->in_width = width;
|
|
scaler->in_height = height;
|
|
scaler->in_stride = pitch;
|
|
|
|
scaler->out_width = scaler_width;
|
|
scaler->out_height = scaler_height;
|
|
scaler->out_stride = scaler_pitch;
|
|
|
|
scaler_ctx_gen_filter(scaler);
|
|
}
|
|
|
|
scaler_ctx_scale(scaler, output, input);
|
|
}
|
|
|
|
void video_frame_record_scale(
|
|
void *data,
|
|
void *output,
|
|
const void *input,
|
|
unsigned scaler_width,
|
|
unsigned scaler_height,
|
|
unsigned scaler_pitch,
|
|
unsigned width,
|
|
unsigned height,
|
|
unsigned pitch,
|
|
bool bilinear)
|
|
{
|
|
struct scaler_ctx *scaler = (struct scaler_ctx*)data;
|
|
|
|
if (
|
|
width != (unsigned)scaler->in_width
|
|
|| height != (unsigned)scaler->in_height
|
|
)
|
|
{
|
|
scaler->in_width = width;
|
|
scaler->in_height = height;
|
|
scaler->in_stride = pitch;
|
|
|
|
scaler->scaler_type = bilinear ?
|
|
SCALER_TYPE_BILINEAR : SCALER_TYPE_POINT;
|
|
|
|
scaler->out_width = scaler_width;
|
|
scaler->out_height = scaler_height;
|
|
scaler->out_stride = scaler_pitch;
|
|
|
|
scaler_ctx_gen_filter(scaler);
|
|
}
|
|
|
|
scaler_ctx_scale(scaler, output, input);
|
|
}
|
|
|
|
void video_frame_convert_argb8888_to_abgr8888(
|
|
void *data,
|
|
void *output, const void *input,
|
|
int width, int height, int in_pitch)
|
|
{
|
|
struct scaler_ctx *scaler = (struct scaler_ctx*)data;
|
|
|
|
if (width != scaler->in_width || height != scaler->in_height)
|
|
{
|
|
scaler->in_width = width;
|
|
scaler->in_height = height;
|
|
scaler->out_width = width;
|
|
scaler->out_height = height;
|
|
scaler->in_fmt = SCALER_FMT_ARGB8888;
|
|
scaler->out_fmt = SCALER_FMT_ABGR8888;
|
|
scaler->scaler_type = SCALER_TYPE_POINT;
|
|
scaler_ctx_gen_filter(scaler);
|
|
}
|
|
|
|
scaler->in_stride = in_pitch;
|
|
scaler->out_stride = width * sizeof(uint32_t);
|
|
scaler_ctx_scale(scaler, output, input);
|
|
}
|
|
|
|
void video_frame_convert_to_bgr24(
|
|
void *data,
|
|
void *output, const void *input,
|
|
int width, int height, int in_pitch,
|
|
bool bgr24)
|
|
{
|
|
struct scaler_ctx *scaler = (struct scaler_ctx*)data;
|
|
|
|
scaler->in_width = width;
|
|
scaler->in_height = height;
|
|
scaler->out_width = width;
|
|
scaler->out_height = height;
|
|
if (bgr24)
|
|
scaler->in_fmt = SCALER_FMT_BGR24;
|
|
else if (video_driver_get_pixel_format() == RETRO_PIXEL_FORMAT_XRGB8888)
|
|
scaler->in_fmt = SCALER_FMT_ARGB8888;
|
|
else
|
|
scaler->in_fmt = SCALER_FMT_RGB565;
|
|
scaler->out_fmt = SCALER_FMT_BGR24;
|
|
scaler->scaler_type = SCALER_TYPE_POINT;
|
|
scaler_ctx_gen_filter(scaler);
|
|
|
|
scaler->in_stride = in_pitch;
|
|
scaler->out_stride = width * 3;
|
|
|
|
scaler_ctx_scale(scaler, output, input);
|
|
}
|
|
|
|
void video_frame_convert_rgba_to_bgr(
|
|
const void *src_data,
|
|
void *dst_data,
|
|
unsigned width)
|
|
{
|
|
unsigned x;
|
|
uint8_t *dst = (uint8_t*)dst_data;
|
|
const uint8_t *src = (const uint8_t*)src_data;
|
|
|
|
for (x = 0; x < width; x++, dst += 3, src += 4)
|
|
{
|
|
dst[0] = src[2];
|
|
dst[1] = src[1];
|
|
dst[2] = src[0];
|
|
}
|
|
}
|
|
|
|
bool video_pixel_frame_scale(
|
|
void *scaler_data,
|
|
void *output, const void *data,
|
|
unsigned width, unsigned height,
|
|
size_t pitch)
|
|
{
|
|
struct scaler_ctx *scaler = (struct scaler_ctx*)scaler_data;
|
|
static struct retro_perf_counter video_frame_conv = {0};
|
|
|
|
performance_counter_init(&video_frame_conv, "video_frame_conv");
|
|
|
|
if ( !data
|
|
|| video_driver_get_pixel_format() != RETRO_PIXEL_FORMAT_0RGB1555)
|
|
return false;
|
|
if (data == RETRO_HW_FRAME_BUFFER_VALID)
|
|
return false;
|
|
|
|
performance_counter_start(&video_frame_conv);
|
|
|
|
scaler->in_width = width;
|
|
scaler->in_height = height;
|
|
scaler->out_width = width;
|
|
scaler->out_height = height;
|
|
scaler->in_stride = pitch;
|
|
scaler->out_stride = width * sizeof(uint16_t);
|
|
|
|
scaler_ctx_scale(scaler, output, data);
|
|
|
|
performance_counter_stop(&video_frame_conv);
|
|
|
|
return true;
|
|
}
|