(Image) Put image functions through abstract interface

(Image) Add image_driver to retroarch.cfg to specify image driver to use
(Menu)  Add Image Driver to Drivers section
This commit is contained in:
twinaphex 2014-05-10 20:26:58 +02:00
parent 107efae2e2
commit b2b5c6daec
29 changed files with 433 additions and 148 deletions

View File

@ -36,7 +36,8 @@ OBJ = frontend/frontend.o \
gfx/scaler/pixconv.o \
gfx/scaler/scaler_int.o \
gfx/scaler/scaler_filter.o \
gfx/image/image.o \
gfx/image/image_rpng.o \
gfx/image_context.o \
gfx/fonts/fonts.o \
gfx/fonts/bitmapfont.o \
audio/resampler.o \
@ -318,6 +319,7 @@ ifeq ($(HAVE_FREETYPE), 1)
endif
ifeq ($(HAVE_SDL_IMAGE), 1)
OBJ += gfx/image/image_sdl.o
LIBS += $(SDL_IMAGE_LIBS)
DEFINES += $(SDL_IMAGE_CFLAGS)
endif

View File

@ -38,7 +38,8 @@ OBJ = frontend/platform/platform_emscripten.o \
gfx/shader_parse.o \
gfx/fonts/fonts.o \
gfx/fonts/bitmapfont.o \
gfx/image/image.o \
gfx/image/image_rpng.o \
gfx/image_context.o \
audio/resampler.o \
audio/sinc.o \
audio/cc_resampler.o \

View File

@ -43,7 +43,8 @@ OBJ = frontend/frontend.o \
gfx/shader_parse.o \
gfx/fonts/fonts.o \
gfx/fonts/bitmapfont.o \
gfx/image/image.o \
gfx/image/image_rpng.o \
gfx/image_context.o \
audio/resampler.o \
audio/sinc.o \
audio/cc_resampler.o \
@ -146,6 +147,7 @@ ifeq ($(HAVE_OPENGL), 1)
endif
ifeq ($(HAVE_SDL_IMAGE), 1)
OBJ += gfx/image/image_sdl.o
LIBS += -lSDL_image
DEFINES += -DHAVE_SDL_IMAGE
endif

View File

@ -87,6 +87,11 @@ enum
INPUT_RWEBINPUT,
INPUT_NULL,
IMAGE_SDL,
IMAGE_XDK,
IMAGE_PS3,
IMAGE_RPNG,
CAMERA_V4L2,
CAMERA_RWEBCAM,
CAMERA_ANDROID,
@ -200,6 +205,14 @@ enum
#define INPUT_DEFAULT_DRIVER INPUT_NULL
#endif
#if defined(__CELLOS_LV2__)
#define IMAGE_DEFAULT_DRIVER IMAGE_PS3
#elif defined(_XBOX1)
#define IMAGE_DEFAULT_DRIVER IMAGE_XDK
#else
#define IMAGE_DEFAULT_DRIVER IMAGE_RPNG
#endif
#if defined(HAVE_V4L2)
#define CAMERA_DEFAULT_DRIVER CAMERA_V4L2
#elif defined(EMSCRIPTEN)

View File

@ -509,6 +509,7 @@ void init_drivers_pre(void)
#ifdef HAVE_CAMERA
find_camera_driver();
#endif
find_image_driver();
#ifdef HAVE_LOCATION
find_location_driver();
#endif
@ -926,6 +927,8 @@ void uninit_drivers(void)
uninit_video_input();
driver.image = NULL;
#ifdef HAVE_CAMERA
uninit_camera();
@ -1484,6 +1487,7 @@ static bool init_video_pixel_converter(unsigned size)
return true;
}
void init_video_input(void)
{
rarch_init_filter(g_extern.system.pix_fmt);

View File

@ -24,7 +24,7 @@
#include <stdint.h>
#include "msvc/msvc_compat.h"
#include "gfx/scaler/scaler.h"
#include "gfx/image/image.h"
#include "gfx/image_context.h"
#include "gfx/filters/softfilter.h"
#include "audio/filters/rarch_dsp.h"
#include "input/overlay.h"
@ -449,6 +449,7 @@ enum rarch_display_type
typedef struct driver
{
const audio_driver_t *audio;
const image_ctx_driver_t *image;
const video_driver_t *video;
const input_driver_t *input;
#ifdef HAVE_OSK
@ -543,6 +544,8 @@ void uninit_drivers(void);
void global_init_drivers(void);
void global_uninit_drivers(void);
void init_image_input(void);
void init_video_input(void);
void uninit_video_input(void);
void init_audio(void);

View File

@ -356,6 +356,7 @@ static void menu_common_entries_init(void *data, unsigned menu_type)
file_list_push(rgui->selection_buf, "Audio Device", RGUI_SETTINGS_DRIVER_AUDIO_DEVICE, 0);
file_list_push(rgui->selection_buf, "Audio Resampler", RGUI_SETTINGS_DRIVER_AUDIO_RESAMPLER, 0);
file_list_push(rgui->selection_buf, "Input Driver", RGUI_SETTINGS_DRIVER_INPUT, 0);
file_list_push(rgui->selection_buf, "Image Driver", RGUI_SETTINGS_DRIVER_IMAGE, 0);
#ifdef HAVE_CAMERA
file_list_push(rgui->selection_buf, "Camera Driver", RGUI_SETTINGS_DRIVER_CAMERA, 0);
#endif
@ -3095,6 +3096,12 @@ static int menu_common_setting_set(void *data, unsigned setting, unsigned action
else if (action == RGUI_ACTION_RIGHT)
find_next_input_driver();
break;
case RGUI_SETTINGS_DRIVER_IMAGE:
if (action == RGUI_ACTION_LEFT)
find_prev_image_driver();
else if (action == RGUI_ACTION_RIGHT)
find_next_image_driver();
break;
#ifdef HAVE_CAMERA
case RGUI_SETTINGS_DRIVER_CAMERA:
if (action == RGUI_ACTION_LEFT)
@ -3860,6 +3867,9 @@ static void menu_common_setting_set_label(char *type_str, size_t type_str_size,
case RGUI_SETTINGS_DRIVER_INPUT:
strlcpy(type_str, g_settings.input.driver, type_str_size);
break;
case RGUI_SETTINGS_DRIVER_IMAGE:
strlcpy(type_str, g_settings.image.driver, type_str_size);
break;
#ifdef HAVE_CAMERA
case RGUI_SETTINGS_DRIVER_CAMERA:
strlcpy(type_str, g_settings.camera.driver, type_str_size);

View File

@ -100,6 +100,7 @@ typedef enum
RGUI_SETTINGS_DRIVER_AUDIO_DEVICE,
RGUI_SETTINGS_DRIVER_AUDIO_RESAMPLER,
RGUI_SETTINGS_DRIVER_INPUT,
RGUI_SETTINGS_DRIVER_IMAGE,
RGUI_SETTINGS_DRIVER_CAMERA,
RGUI_SETTINGS_DRIVER_LOCATION,
RGUI_SETTINGS_DRIVER_MENU,

View File

@ -437,7 +437,9 @@ static void rmenu_init_assets(void *data)
return;
menu_texture = (struct texture_image*)calloc(1, sizeof(*menu_texture));
texture_image_load(g_extern.menu_texture_path, menu_texture);
if (driver.image && driver.menu->load)
driver.image->load(driver.video_data, g_extern.menu_texture_path, menu_texture);
rgui->width = menu_texture->width;
rgui->height = menu_texture->height;
@ -455,7 +457,9 @@ static void *rmenu_init(void)
static void rmenu_free_assets(void *data)
{
texture_image_free(menu_texture);
if (driver.image && driver.image->free)
driver.image->free(driver.video_data, menu_texture);
menu_texture_inited = false;
}

View File

@ -193,6 +193,11 @@ struct settings
} menu;
#endif
struct
{
char driver[32];
} image;
#ifdef HAVE_CAMERA
struct
{

View File

@ -22,7 +22,6 @@
#include <EGL/egl.h>
#include "../../frontend/platform/platform_android.h"
#include "../image/image.h"
#include "../fonts/gl_font.h"
#include <stdint.h>

View File

@ -17,7 +17,6 @@
#include "../../driver.h"
#include "../gfx_common.h"
#include "../gl_common.h"
#include "../image/image.h"
#include "../fonts/gl_font.h"
#include <stdint.h>

View File

@ -27,8 +27,6 @@
#include <sys/platform.h>
#include <GLES2/gl2.h>
#include "../image/image.h"
#include "../fonts/gl_font.h"
#include <stdint.h>

View File

@ -18,7 +18,6 @@
#include <stdlib.h>
#include <string.h>
#include <X11/Xatom.h>
#include "../image/image.h"
#include "../../general.h"
#include "../../input/input_common.h"
#include "../../input/keyboard_line.h"

View File

@ -22,7 +22,7 @@
#include "../driver.h"
#include "../performance.h"
#include "scaler/scaler.h"
#include "image/image.h"
#include "image_context.h"
#include "../file.h"
#include <stdint.h>

View File

@ -18,7 +18,7 @@
#include "../../config.h"
#endif
#include "image.h"
#include "../image_context.h"
#include <stdlib.h>
#include <string.h>
@ -77,7 +77,7 @@ static int img_free(void *ptr, void *a)
Image decompression - libJPEG
********************************************************************************/
static bool ps3graphics_load_jpeg(const char *path, struct texture_image *out_img)
static bool ps3_load_jpeg(const char *path, struct texture_image *out_img)
{
size_t img_size;
#ifndef __PSL1GHT__
@ -178,7 +178,6 @@ static bool ps3graphics_load_jpeg(const char *path, struct texture_image *out_im
return true;
error:
RARCH_ERR("ps3graphics_load_jpeg(): error.\n");
if (out_img->pixels)
free(out_img->pixels);
out_img->pixels = 0;
@ -193,7 +192,7 @@ error:
Image decompression - libPNG
********************************************************************************/
static bool ps3graphics_load_png(const char *path, struct texture_image *out_img)
static bool ps3_load_png(const char *path, struct texture_image *out_img)
{
size_t img_size;
#ifndef __PSL1GHT__
@ -294,8 +293,6 @@ static bool ps3graphics_load_png(const char *path, struct texture_image *out_img
return true;
error:
RARCH_ERR("ps3graphics_load_png(): error.\n");
if (out_img->pixels)
free(out_img->pixels);
out_img->pixels = 0;
@ -307,25 +304,39 @@ error:
return false;
}
bool texture_image_load(const char *path, struct texture_image *out_img)
static bool ps3_image_load(void *data, const char *path, void *image_data)
{
(void)data;
struct texture_image *out_img = (struct texture_image*)image_data;
if (!out_img)
return false;
if(strstr(path, ".PNG") != NULL || strstr(path, ".png") != NULL)
{
if (!ps3graphics_load_png(path, out_img))
if (!ps3_load_png(path, out_img))
return false;
}
else
{
if (!ps3graphics_load_jpeg(path, out_img))
if (!ps3_load_jpeg(path, out_img))
return false;
}
return true;
}
void texture_image_free(struct texture_image *img)
static void ps3_image_free(void *data, void *image_data)
{
struct texture_image *img = (struct texture_image*)image_data;
if (img->pixels)
free(img->pixels);
memset(img, 0, sizeof(*img));
}
const image_ctx_driver_t image_ctx_ps3 = {
ps3_image_load,
ps3_image_free,
"ps3",
};

View File

@ -17,7 +17,7 @@
#include "../../config.h"
#endif
#include "image.h"
#include "../image_context.h"
#include "../../file.h"
#include <stdlib.h>
@ -26,84 +26,7 @@
#include "../../general.h"
#include "../rpng/rpng.h"
#ifdef HAVE_SDL_IMAGE
#include "SDL_image.h"
bool texture_image_load_argb_shift(const char *path, struct texture_image *out_img,
unsigned a_shift, unsigned r_shift, unsigned g_shift, unsigned b_shift)
{
int y, x;
SDL_Surface *img = IMG_Load(path);
if (!img)
return false;
out_img->width = img->w;
out_img->height = img->h;
size_t size = out_img->width * out_img->height * sizeof(uint32_t);
out_img->pixels = (uint32_t*)malloc(size);
if (!out_img->pixels)
{
SDL_FreeSurface(img);
return false;
}
const SDL_PixelFormat *fmt = img->format;
RARCH_LOG("SDL_image: %dx%d @ %d bpp\n", img->w, img->h, img->format->BitsPerPixel);
if (img->format->BitsPerPixel == 32)
{
for (y = 0; y < img->h; y++)
{
uint32_t *dst = out_img->pixels + y * img->w;
const uint32_t *src = (const uint32_t*)img->pixels + y * img->pitch / sizeof(uint32_t);
for (x = 0; x < img->w; x++)
{
uint32_t r = (src[x] & fmt->Rmask) >> fmt->Rshift;
uint32_t g = (src[x] & fmt->Gmask) >> fmt->Gshift;
uint32_t b = (src[x] & fmt->Bmask) >> fmt->Bshift;
uint32_t a = (src[x] & fmt->Amask) >> fmt->Ashift;
dst[x] = (a << a_shift) | (r << r_shift) | (g << g_shift) | (b << b_shift);
}
}
}
else if (img->format->BitsPerPixel == 24)
{
for (y = 0; y < img->h; y++)
{
uint32_t *dst = out_img->pixels + y * img->w;
const uint8_t *src = (const uint8_t*)img->pixels + y * img->pitch;
for (x = 0; x < img->w; x++)
{
// Correct?
uint32_t color = 0;
color |= src[3 * x + 0] << 0;
color |= src[3 * x + 1] << 8;
color |= src[3 * x + 2] << 16;
uint32_t r = (color & fmt->Rmask) >> fmt->Rshift;
uint32_t g = (color & fmt->Gmask) >> fmt->Gshift;
uint32_t b = (color & fmt->Bmask) >> fmt->Bshift;
dst[x] = (0xff << a_shift) | (r << r_shift) | (g << g_shift) | (b << b_shift);
}
}
}
else
{
RARCH_ERR("8-bit and 16-bit image support are not implemented.\n");
SDL_FreeSurface(img);
return false;
}
SDL_FreeSurface(img);
return true;
}
#else
static bool texture_image_load_tga_shift(const char *path, struct texture_image *out_img,
static bool rpng_image_load_tga_shift(const char *path, struct texture_image *out_img,
unsigned a_shift, unsigned r_shift, unsigned g_shift, unsigned b_shift)
{
unsigned i;
@ -185,18 +108,21 @@ static bool texture_image_load_tga_shift(const char *path, struct texture_image
return true;
}
bool texture_image_load_argb_shift(const char *path, struct texture_image *out_img,
static bool rpng_image_load_argb_shift(const char *path, struct texture_image *out_img,
unsigned a_shift, unsigned r_shift, unsigned g_shift, unsigned b_shift)
{
unsigned i;
(void)i;
if (strstr(path, ".tga"))
return texture_image_load_tga_shift(path, out_img, a_shift, r_shift, g_shift, b_shift);
return rpng_image_load_tga_shift(path, out_img, a_shift, r_shift, g_shift, b_shift);
#ifdef HAVE_ZLIB
else if (strstr(path, ".png"))
{
RARCH_LOG("[RPNG]: Using RPNG loader.\n");
bool ret = rpng_load_image_argb(path, &out_img->pixels, &out_img->width, &out_img->height);
RARCH_LOG("[RPNG]: Using RPNG loader.\n");
if (!ret)
return false;
@ -205,6 +131,7 @@ bool texture_image_load_argb_shift(const char *path, struct texture_image *out_i
{
unsigned num_pixels = out_img->width * out_img->height;
uint32_t *pixels = out_img->pixels;
for (i = 0; i < num_pixels; i++)
{
uint32_t col = pixels[i];
@ -223,8 +150,6 @@ bool texture_image_load_argb_shift(const char *path, struct texture_image *out_i
return false;
}
#endif
#ifdef GEKKO
#define GX_BLIT_LINE_32(off) \
@ -245,7 +170,7 @@ bool texture_image_load_argb_shift(const char *path, struct texture_image *out_i
src += tmp_pitch; \
}
static bool gx_convert_texture32(struct texture_image *image)
static bool rpng_gx_convert_texture32(struct texture_image *image)
{
// memory allocation in libogc is extremely primitive so try to avoid gaps in memory when converting
// by copying over to temp buffer first then converting over into main buffer again
@ -279,21 +204,32 @@ static bool gx_convert_texture32(struct texture_image *image)
#endif
bool texture_image_load(const char *path, struct texture_image *out_img)
static void rpng_image_free(void *data, void *image_data)
{
struct texture_image *img = (struct texture_image*)image_data;
free(img->pixels);
memset(img, 0, sizeof(*img));
}
static bool rpng_image_load(void *data, const char *path, void *image_data)
{
(void)data;
bool ret;
struct texture_image *out_img = (struct texture_image*)image_data;
// This interface "leak" is very ugly. FIXME: Fix this properly ...
if (driver.gfx_use_rgba)
ret = texture_image_load_argb_shift(path, out_img, 24, 0, 8, 16);
ret = rpng_image_load_argb_shift(path, out_img, 24, 0, 8, 16);
else
ret = texture_image_load_argb_shift(path, out_img, 24, 16, 8, 0);
ret = rpng_image_load_argb_shift(path, out_img, 24, 16, 8, 0);
#ifdef GEKKO
if (ret)
{
if (!gx_convert_texture32(out_img))
if (!rpng_gx_convert_texture32(out_img))
{
texture_image_free(out_img);
rpng_image_free(data, out_img);
ret = false;
}
}
@ -302,9 +238,8 @@ bool texture_image_load(const char *path, struct texture_image *out_img)
return ret;
}
void texture_image_free(struct texture_image *img)
{
free(img->pixels);
memset(img, 0, sizeof(*img));
}
const image_ctx_driver_t image_ctx_rpng = {
rpng_image_load,
rpng_image_free,
"rpng",
};

135
gfx/image/image_sdl.c Normal file
View File

@ -0,0 +1,135 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
*
* 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/>.
*/
#ifdef HAVE_CONFIG_H
#include "../../config.h"
#endif
#include "../image_context.h"
#include "../../file.h"
#include <stdlib.h>
#include <string.h>
#include <stddef.h>
#include "../../general.h"
#include "../rpng/rpng.h"
#include "SDL_image.h"
static bool sdl_load_argb_shift(const char *path, struct texture_image *out_img,
unsigned a_shift, unsigned r_shift, unsigned g_shift, unsigned b_shift)
{
int y, x;
size_t size;
SDL_PixelFormat *fmt;
SDL_Surface *img = (SDL_Surface*)IMG_Load(path);
if (!img)
return false;
out_img->width = img->w;
out_img->height = img->h;
size = out_img->width * out_img->height * sizeof(uint32_t);
out_img->pixels = (uint32_t*)malloc(size);
if (!out_img->pixels)
{
SDL_FreeSurface(img);
return false;
}
fmt = (SDL_PixelFormat*)img->format;
RARCH_LOG("SDL_image: %dx%d @ %d bpp\n", img->w, img->h, img->format->BitsPerPixel);
if (img->format->BitsPerPixel == 32)
{
for (y = 0; y < img->h; y++)
{
uint32_t *dst = (uint32_t*)(out_img->pixels + y * img->w);
const uint32_t *src = (const uint32_t*)(img->pixels + y * img->pitch / sizeof(uint32_t));
for (x = 0; x < img->w; x++)
{
uint32_t r = (src[x] & fmt->Rmask) >> fmt->Rshift;
uint32_t g = (src[x] & fmt->Gmask) >> fmt->Gshift;
uint32_t b = (src[x] & fmt->Bmask) >> fmt->Bshift;
uint32_t a = (src[x] & fmt->Amask) >> fmt->Ashift;
dst[x] = (a << a_shift) | (r << r_shift) | (g << g_shift) | (b << b_shift);
}
}
}
else if (img->format->BitsPerPixel == 24)
{
for (y = 0; y < img->h; y++)
{
uint32_t *dst = (uint32_t*)(out_img->pixels + y * img->w);
const uint8_t *src = (const uint8_t*)(img->pixels + y * img->pitch);
for (x = 0; x < img->w; x++)
{
// Correct?
uint32_t color,r, g, b;
color = 0;
color |= src[3 * x + 0] << 0;
color |= src[3 * x + 1] << 8;
color |= src[3 * x + 2] << 16;
r = (color & fmt->Rmask) >> fmt->Rshift;
g = (color & fmt->Gmask) >> fmt->Gshift;
b = (color & fmt->Bmask) >> fmt->Bshift;
dst[x] = (0xff << a_shift) | (r << r_shift) | (g << g_shift) | (b << b_shift);
}
}
}
else
{
RARCH_ERR("8-bit and 16-bit image support are not implemented.\n");
SDL_FreeSurface(img);
return false;
}
SDL_FreeSurface(img);
return true;
}
static bool sdl_image_load(void *data, const char *path, void *image_data)
{
bool ret;
(void)data;
struct texture_image *out_img = (struct texture_image*)image_data;
// This interface "leak" is very ugly. FIXME: Fix this properly ...
if (driver.gfx_use_rgba)
ret = sdl_load_argb_shift(path, out_img, 24, 0, 8, 16);
else
ret = sdl_load_argb_shift(path, out_img, 24, 16, 8, 0);
return ret;
}
static void sdl_image_free(void *data, void *image_data)
{
struct texture_image *img = (struct texture_image*)image_data;
free(img->pixels);
memset(img, 0, sizeof(*img));
}
const image_ctx_driver_t image_ctx_sdl = {
sdl_image_load,
sdl_image_free,
"sdl",
};

View File

@ -14,12 +14,13 @@
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "image.h"
#include "../image_context.h"
#include "../../xdk/xdk_d3d.h"
bool texture_image_load(const char *path, struct texture_image *out_img)
static bool xdk_image_load(void *data, const char *path, void *image_data)
{
d3d_video_t *d3d = (d3d_video_t*)driver.video_data;
d3d_video_t *d3d = (d3d_video_t*)data;
struct texture_image *out_img = (struct texture_image*)image_data;
D3DXIMAGE_INFO m_imageInfo;
@ -54,11 +55,22 @@ bool texture_image_load(const char *path, struct texture_image *out_img)
return true;
}
void texture_image_free(struct texture_image *img)
static void xdk_image_free(void *data, void *image_data)
{
struct texture_image *img = (struct texture_image*)image_data;
if (!img)
return;
if (img->vertex_buf)
img->vertex_buf->Release();
if (img->pixels)
img->pixels->Release();
memset(img, 0, sizeof(*img));
}
const image_ctx_driver_t image_ctx_xdk = {
xdk_image_load,
xdk_image_free,
"xdk",
};

92
gfx/image_context.c Normal file
View File

@ -0,0 +1,92 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
* Copyright (C) 2011-2014 - 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 "../general.h"
#include "gfx_context.h"
#include "../general.h"
#include <string.h>
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
static const image_ctx_driver_t *image_ctx_drivers[] = {
#if defined(__CELLOS_LV2__)
&image_ctx_ps3,
#endif
#if defined(_XBOX1)
&image_ctx_xdk1,
#endif
&image_ctx_rpng,
#if defined(HAVE_SDL_IMAGE)
&image_ctx_sdl,
#endif
NULL
};
static int find_image_driver_index(const char *driver)
{
unsigned i;
for (i = 0; image_ctx_drivers[i]; i++)
if (strcasecmp(driver, image_ctx_drivers[i]->ident) == 0)
return i;
return -1;
}
void find_image_driver(void)
{
int i;
if (driver.image)
return;
i = find_image_driver_index(g_settings.image.driver);
if (i >= 0)
driver.image = image_ctx_drivers[i];
else
{
unsigned d;
RARCH_ERR("Couldn't find any image driver named \"%s\"\n", g_settings.image.driver);
RARCH_LOG_OUTPUT("Available image drivers are:\n");
for (d = 0; image_ctx_drivers[d]; d++)
RARCH_LOG_OUTPUT("\t%s\n", image_ctx_drivers[d]->ident);
rarch_fail(1, "find_image_driver()");
}
}
void find_prev_image_driver(void)
{
int i = find_image_driver_index(g_settings.image.driver);
if (i > 0)
{
strlcpy(g_settings.image.driver, image_ctx_drivers[i - 1]->ident, sizeof(g_settings.image.driver));
driver.image = (image_ctx_driver_t*)image_ctx_drivers[i - 1];
}
else
RARCH_WARN("Couldn't find any previous image driver (current one: \"%s\").\n", g_settings.image.driver);
}
void find_next_image_driver(void)
{
int i = find_image_driver_index(g_settings.image.driver);
if (i >= 0 && image_ctx_drivers[i + 1])
{
strlcpy(g_settings.image.driver, image_ctx_drivers[i + 1]->ident, sizeof(g_settings.image.driver));
driver.image = (image_ctx_driver_t*)image_ctx_drivers[i + 1];
}
else
RARCH_WARN("Couldn't find any next image driver (current one: \"%s\").\n", g_settings.image.driver);
}

View File

@ -13,15 +13,15 @@
* If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __RARCH_IMAGE_H
#define __RARCH_IMAGE_H
#ifndef __RARCH_IMAGE_CONTEXT_H
#define __RARCH_IMAGE_CONTEXT_H
#include <stdint.h>
#include "../../boolean.h"
#include "../boolean.h"
#ifdef _XBOX1
#include <xtl.h>
#include "../../xdk/xdk_defines.h"
#include "../xdk/xdk_defines.h"
#endif
struct texture_image
@ -38,8 +38,22 @@ struct texture_image
#endif
};
bool texture_image_load(const char *path, struct texture_image* img);
void texture_image_free(struct texture_image *img);
typedef struct image_ctx_driver
{
bool (*load)(void*, const char*, void *);
void (*free)(void *, void *);
// Human readable string.
const char *ident;
} image_ctx_driver_t;
extern const image_ctx_driver_t image_ctx_xdk1;
extern const image_ctx_driver_t image_ctx_ps3;
extern const image_ctx_driver_t image_ctx_sdl;
extern const image_ctx_driver_t image_ctx_rpng;
const void *image_ctx_find_driver(const char *ident);
void find_prev_image_driver(void);
void find_next_image_driver(void);
const void *image_ctx_init_first(void);
#endif

View File

@ -26,7 +26,6 @@
#include <string.h>
#include "../compat/strl.h"
#include "../conf/config_file.h"
#include "image/image.h"
#include "../dynamic.h"
#include "../compat/posix_string.h"
#include "../file.h"

View File

@ -63,10 +63,17 @@ bool gl_load_luts(const struct gfx_shader *generic_shader, GLuint *lut_textures)
glGenTextures(num_luts, lut_textures);
for (i = 0; i < num_luts; i++)
{
bool ret = false;
struct texture_image img = {0};
RARCH_LOG("Loading texture image from: \"%s\" ...\n",
generic_shader->lut[i].path);
if (!texture_image_load(generic_shader->lut[i].path, &img))
ret = driver.image && driver.image->load;
if (ret)
ret = driver.image->load(driver.video_data, generic_shader->lut[i].path, &img);
if (!ret)
{
RARCH_ERR("Failed to load texture image from: \"%s\"\n", generic_shader->lut[i].path);
return false;
@ -76,7 +83,9 @@ bool gl_load_luts(const struct gfx_shader *generic_shader, GLuint *lut_textures)
gl_wrap_type_to_enum(generic_shader->lut[i].wrap),
generic_shader->lut[i].filter != RARCH_FILTER_NEAREST,
generic_shader->lut[i].mipmap);
texture_image_free(&img);
if (driver.image && driver.image->free)
driver.image->free(driver.video_data, &img);
}
glBindTexture(GL_TEXTURE_2D, 0);

View File

@ -33,7 +33,6 @@
#include <stdlib.h>
#include "gl_common.h"
#include "image/image.h"
#ifdef HAVE_OPENGLES2
#define BORDER_FUNC GL_CLAMP_TO_EDGE

View File

@ -172,13 +172,13 @@ VIDEO IMAGE
#include "../gfx/image/image_ps3.c"
#elif defined(_XBOX1)
#include "../gfx/image/image_xdk1.c"
#else
#include "../gfx/image/image.c"
#elif defined(HAVE_SDL_IMAGE)
#include "../gfx/image/image_sdl.c"
#endif
#if defined(WANT_RPNG) || defined(RARCH_MOBILE)
#include "../gfx/image_context.c"
#include "../gfx/image/image_rpng.c"
#include "../gfx/rpng/rpng.c"
#endif
/*============================================================
VIDEO DRIVER

View File

@ -17,7 +17,7 @@
#include "../general.h"
#include "../driver.h"
#include "../libretro.h"
#include "../gfx/image/image.h"
#include "../gfx/image_context.h"
#include "../conf/config_file.h"
#include "../compat/posix_string.h"
#include "input_common.h"
@ -162,11 +162,16 @@ void input_overlay_set_scale_factor(input_overlay_t *ol, float scale)
static void input_overlay_free_overlay(struct overlay *overlay)
{
size_t i;
for (i = 0; i < overlay->size; i++)
texture_image_free(&overlay->descs[i].image);
if (driver.image && driver.image->free)
for (i = 0; i < overlay->size; i++)
driver.image->free(driver.video_data, &overlay->descs[i].image);
free(overlay->load_images);
free(overlay->descs);
texture_image_free(&overlay->image);
if (driver.image && driver.image->free)
driver.image->free(driver.video_data, &overlay->image);
}
static void input_overlay_free_overlays(input_overlay_t *ol)
@ -197,8 +202,9 @@ static bool input_overlay_load_desc(input_overlay_t *ol, config_file_t *conf, st
fill_pathname_resolve_relative(path, ol->overlay_path, image_path, sizeof(path));
struct texture_image img = {0};
if (texture_image_load(path, &img))
desc->image = img;
if (driver.image && driver.image->load)
if (driver.image->load(driver.video_data, path, &img))
desc->image = img;
}
char overlay_desc_normalized_key[64];
@ -345,13 +351,22 @@ static bool input_overlay_load_overlay(input_overlay_t *ol, config_file_t *conf,
snprintf(overlay_path_key, sizeof(overlay_path_key), "overlay%u_overlay", index);
if (config_get_path(conf, overlay_path_key, overlay_path, sizeof(overlay_path)))
{
struct texture_image img = {0};
bool ret = false;
fill_pathname_resolve_relative(overlay_resolved_path, config_path,
overlay_path, sizeof(overlay_resolved_path));
struct texture_image img = {0};
if (texture_image_load(overlay_resolved_path, &img))
overlay->image = img;
else
ret = driver.image && driver.image->load;
if (ret)
{
ret = driver.image->load(driver.video_data, overlay_resolved_path, &img);
if(ret)
overlay->image = img;
}
if (!ret)
{
RARCH_ERR("[Overlay]: Failed to load image: %s.\n", overlay_resolved_path);
return false;

View File

@ -77,6 +77,9 @@
# Load up a specific config file based on the core being used.
# core_specific_config = false
# Image driver to use. "rpng", "sdl"
# image_driver = "rpng"
#### Video
# Video driver to use. "gl", "xvideo", "sdl"

View File

@ -202,11 +202,28 @@ const char *config_get_default_location(void)
}
#endif
const char *config_get_default_image(void)
{
switch (IMAGE_DEFAULT_DRIVER)
{
case IMAGE_SDL:
return "sdl";
case IMAGE_XDK:
return "xdk";
case IMAGE_PS3:
return "ps3";
case IMAGE_RPNG:
return "rpng";
default:
return NULL;
}
}
void config_set_defaults(void)
{
unsigned i, j;
const char *def_video = config_get_default_video();
const char *def_image = config_get_default_image();
const char *def_audio = config_get_default_audio();
const char *def_input = config_get_default_input();
#ifdef HAVE_CAMERA
@ -235,6 +252,8 @@ void config_set_defaults(void)
strlcpy(g_settings.audio.driver, def_audio, sizeof(g_settings.audio.driver));
if (def_input)
strlcpy(g_settings.input.driver, def_input, sizeof(g_settings.input.driver));
if (def_image)
strlcpy(g_settings.image.driver, def_image, sizeof(g_settings.image.driver));
g_settings.load_dummy_on_core_shutdown = load_dummy_on_core_shutdown;
@ -947,6 +966,7 @@ bool config_load_file(const char *path, bool set_defaults)
CONFIG_GET_BOOL(location.allow, "location_allow");
#endif
CONFIG_GET_STRING(image.driver, "image_driver");
CONFIG_GET_STRING(video.driver, "video_driver");
CONFIG_GET_STRING(video.gl_context, "video_gl_context");
CONFIG_GET_STRING(audio.driver, "audio_driver");
@ -1331,6 +1351,7 @@ bool config_save_file(const char *path)
config_set_int(conf, "video_fullscreen_x", g_settings.video.fullscreen_x);
config_set_int(conf, "video_fullscreen_y", g_settings.video.fullscreen_y);
config_set_string(conf,"video_driver", g_settings.video.driver);
config_set_string(conf,"image_driver", g_settings.image.driver);
config_set_bool(conf, "video_vsync", g_settings.video.vsync);
config_set_bool(conf, "video_hard_sync", g_settings.video.hard_sync);
config_set_int(conf, "video_hard_sync_frames", g_settings.video.hard_sync_frames);

View File

@ -23,7 +23,7 @@
#endif
#include "../gfx/shader_common.h"
#include "../gfx/shader_parse.h"
#include "../gfx/image/image.h"
#include "../gfx/image_context.h"
#include "../gfx/fonts/d3d_font.h"
#include "../gfx/gfx_context.h"