mirror of
https://github.com/libretro/RetroArch
synced 2025-01-30 03:32:46 +00:00
Indenting/C-style comments
This commit is contained in:
parent
fb284a37e1
commit
fe510bca6f
@ -29,7 +29,8 @@ typedef struct android_camera
|
||||
GLuint tex;
|
||||
} androidcamera_t;
|
||||
|
||||
static void *android_camera_init(const char *device, uint64_t caps, unsigned width, unsigned height)
|
||||
static void *android_camera_init(const char *device, uint64_t caps,
|
||||
unsigned width, unsigned height)
|
||||
{
|
||||
JNIEnv *env;
|
||||
jclass class;
|
||||
@ -44,7 +45,8 @@ static void *android_camera_init(const char *device, uint64_t caps, unsigned wid
|
||||
}
|
||||
|
||||
struct android_app *android_app = (struct android_app*)g_android;
|
||||
androidcamera_t *androidcamera = (androidcamera_t*)calloc(1, sizeof(androidcamera_t));
|
||||
androidcamera_t *androidcamera = (androidcamera_t*)
|
||||
calloc(1, sizeof(androidcamera_t));
|
||||
if (!androidcamera)
|
||||
return NULL;
|
||||
|
||||
@ -56,31 +58,38 @@ static void *android_camera_init(const char *device, uint64_t caps, unsigned wid
|
||||
if (class == NULL)
|
||||
goto dealloc;
|
||||
|
||||
GET_METHOD_ID(env, androidcamera->onCameraInit, class, "onCameraInit", "()V");
|
||||
GET_METHOD_ID(env, androidcamera->onCameraInit, class,
|
||||
"onCameraInit", "()V");
|
||||
if (!androidcamera->onCameraInit)
|
||||
goto dealloc;
|
||||
|
||||
GET_METHOD_ID(env, androidcamera->onCameraFree, class, "onCameraFree", "()V");
|
||||
GET_METHOD_ID(env, androidcamera->onCameraFree, class,
|
||||
"onCameraFree", "()V");
|
||||
if (!androidcamera->onCameraFree)
|
||||
goto dealloc;
|
||||
|
||||
GET_METHOD_ID(env, androidcamera->onCameraSetTexture, class, "onCameraSetTexture", "(I)V");
|
||||
GET_METHOD_ID(env, androidcamera->onCameraSetTexture, class,
|
||||
"onCameraSetTexture", "(I)V");
|
||||
if (!androidcamera->onCameraSetTexture)
|
||||
goto dealloc;
|
||||
|
||||
GET_METHOD_ID(env, androidcamera->onCameraStart, class, "onCameraStart", "()V");
|
||||
GET_METHOD_ID(env, androidcamera->onCameraStart, class,
|
||||
"onCameraStart", "()V");
|
||||
if (!androidcamera->onCameraStart)
|
||||
goto dealloc;
|
||||
|
||||
GET_METHOD_ID(env, androidcamera->onCameraStop, class, "onCameraStop", "()V");
|
||||
GET_METHOD_ID(env, androidcamera->onCameraStop, class,
|
||||
"onCameraStop", "()V");
|
||||
if (!androidcamera->onCameraStop)
|
||||
goto dealloc;
|
||||
|
||||
GET_METHOD_ID(env, androidcamera->onCameraPoll, class, "onCameraPoll", "()Z");
|
||||
GET_METHOD_ID(env, androidcamera->onCameraPoll, class,
|
||||
"onCameraPoll", "()Z");
|
||||
if (!androidcamera->onCameraPoll)
|
||||
goto dealloc;
|
||||
|
||||
CALL_VOID_METHOD(env, android_app->activity->clazz, androidcamera->onCameraInit);
|
||||
CALL_VOID_METHOD(env, android_app->activity->clazz,
|
||||
androidcamera->onCameraInit);
|
||||
|
||||
return androidcamera;
|
||||
dealloc:
|
||||
@ -96,7 +105,8 @@ static void android_camera_free(void *data)
|
||||
if (!env)
|
||||
return;
|
||||
|
||||
CALL_VOID_METHOD(env, android_app->activity->clazz, androidcamera->onCameraFree);
|
||||
CALL_VOID_METHOD(env, android_app->activity->clazz,
|
||||
androidcamera->onCameraFree);
|
||||
|
||||
free(androidcamera);
|
||||
}
|
||||
@ -111,13 +121,17 @@ static bool android_camera_start(void *data)
|
||||
|
||||
glGenTextures(1, &androidcamera->tex);
|
||||
glBindTexture(GL_TEXTURE_EXTERNAL_OES, androidcamera->tex);
|
||||
glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S,
|
||||
GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T,
|
||||
GL_CLAMP_TO_EDGE);
|
||||
|
||||
CALL_VOID_METHOD_PARAM(env, android_app->activity->clazz, androidcamera->onCameraSetTexture, (int) androidcamera->tex);
|
||||
CALL_VOID_METHOD(env, android_app->activity->clazz, androidcamera->onCameraStart);
|
||||
CALL_VOID_METHOD_PARAM(env, android_app->activity->clazz,
|
||||
androidcamera->onCameraSetTexture, (int) androidcamera->tex);
|
||||
CALL_VOID_METHOD(env, android_app->activity->clazz,
|
||||
androidcamera->onCameraStart);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -130,13 +144,15 @@ static void android_camera_stop(void *data)
|
||||
if (!env)
|
||||
return;
|
||||
|
||||
CALL_VOID_METHOD(env, android_app->activity->clazz, androidcamera->onCameraStop);
|
||||
CALL_VOID_METHOD(env, android_app->activity->clazz,
|
||||
androidcamera->onCameraStop);
|
||||
|
||||
if (androidcamera->tex)
|
||||
glDeleteTextures(1, &androidcamera->tex);
|
||||
}
|
||||
|
||||
static bool android_camera_poll(void *data, retro_camera_frame_raw_framebuffer_t frame_raw_cb,
|
||||
static bool android_camera_poll(void *data,
|
||||
retro_camera_frame_raw_framebuffer_t frame_raw_cb,
|
||||
retro_camera_frame_opengl_texture_t frame_gl_cb)
|
||||
{
|
||||
struct android_app *android_app = (struct android_app*)g_android;
|
||||
@ -148,11 +164,13 @@ static bool android_camera_poll(void *data, retro_camera_frame_raw_framebuffer_t
|
||||
(void)frame_raw_cb;
|
||||
|
||||
jboolean newFrame;
|
||||
CALL_BOOLEAN_METHOD(env, newFrame, android_app->activity->clazz, androidcamera->onCameraPoll);
|
||||
CALL_BOOLEAN_METHOD(env, newFrame, android_app->activity->clazz,
|
||||
androidcamera->onCameraPoll);
|
||||
|
||||
if (newFrame)
|
||||
{
|
||||
// FIXME: Identity for now. Use proper texture matrix as returned by Android Camera.
|
||||
/* FIXME: Identity for now. Use proper texture matrix as
|
||||
* returned by Android Camera. */
|
||||
static const float affine[] = {
|
||||
1.0f, 0.0f, 0.0f,
|
||||
0.0f, 1.0f, 0.0f,
|
||||
|
@ -61,7 +61,8 @@ typedef struct video4linux
|
||||
char dev_name[PATH_MAX];
|
||||
} video4linux_t;
|
||||
|
||||
static void process_image(video4linux_t *v4l, const uint8_t *buffer_yuv)
|
||||
static void process_image(video4linux_t *v4l,
|
||||
const uint8_t *buffer_yuv)
|
||||
{
|
||||
RARCH_PERFORMANCE_INIT(yuv_convert_direct);
|
||||
RARCH_PERFORMANCE_START(yuv_convert_direct);
|
||||
@ -182,7 +183,8 @@ static bool init_device(void *data)
|
||||
|
||||
if (!(cap.capabilities & V4L2_CAP_STREAMING))
|
||||
{
|
||||
RARCH_ERR("%s does not support streaming I/O (V4L2_CAP_STREAMING).\n", v4l->dev_name);
|
||||
RARCH_ERR("%s does not support streaming I/O (V4L2_CAP_STREAMING).\n",
|
||||
v4l->dev_name);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -193,7 +195,7 @@ static bool init_device(void *data)
|
||||
{
|
||||
crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
crop.c = cropcap.defrect;
|
||||
// Ignore errors here.
|
||||
/* Ignore errors here. */
|
||||
xioctl(v4l->fd, VIDIOC_S_CROP, &crop);
|
||||
}
|
||||
|
||||
@ -211,21 +213,23 @@ static bool init_device(void *data)
|
||||
return false;
|
||||
}
|
||||
|
||||
// VIDIOC_S_FMT may change width, height and pitch.
|
||||
/* VIDIOC_S_FMT may change width, height and pitch. */
|
||||
v4l->width = fmt.fmt.pix.width;
|
||||
v4l->height = fmt.fmt.pix.height;
|
||||
v4l->pitch = max(fmt.fmt.pix.bytesperline, v4l->width * 2);
|
||||
|
||||
// Sanity check to see if our assumptions are met.
|
||||
// It is possible to support whatever the device gives us,
|
||||
// but this dramatically increases complexity.
|
||||
/* Sanity check to see if our assumptions are met.
|
||||
* It is possible to support whatever the device gives us,
|
||||
* but this dramatically increases complexity.
|
||||
*/
|
||||
if (fmt.fmt.pix.pixelformat != V4L2_PIX_FMT_YUYV)
|
||||
{
|
||||
RARCH_ERR("The V4L2 device doesn't support YUYV.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fmt.fmt.pix.field != V4L2_FIELD_NONE && fmt.fmt.pix.field != V4L2_FIELD_INTERLACED)
|
||||
if (fmt.fmt.pix.field != V4L2_FIELD_NONE
|
||||
&& fmt.fmt.pix.field != V4L2_FIELD_INTERLACED)
|
||||
{
|
||||
RARCH_ERR("The V4L2 device doesn't support progressive nor interlaced video.\n");
|
||||
return false;
|
||||
@ -300,7 +304,8 @@ static void v4l_free(void *data)
|
||||
free(v4l);
|
||||
}
|
||||
|
||||
static void *v4l_init(const char *device, uint64_t caps, unsigned width, unsigned height)
|
||||
static void *v4l_init(const char *device, uint64_t caps,
|
||||
unsigned width, unsigned height)
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
@ -314,7 +319,8 @@ static void *v4l_init(const char *device, uint64_t caps, unsigned width, unsigne
|
||||
if (!v4l)
|
||||
return NULL;
|
||||
|
||||
strlcpy(v4l->dev_name, device ? device : "/dev/video0", sizeof(v4l->dev_name));
|
||||
strlcpy(v4l->dev_name, device ? device : "/dev/video0",
|
||||
sizeof(v4l->dev_name));
|
||||
|
||||
v4l->width = width;
|
||||
v4l->height = height;
|
||||
@ -322,7 +328,8 @@ static void *v4l_init(const char *device, uint64_t caps, unsigned width, unsigne
|
||||
|
||||
if (stat(v4l->dev_name, &st) == -1)
|
||||
{
|
||||
RARCH_ERR("Cannot identify '%s' : %d, %s\n", v4l->dev_name, errno, strerror(errno));
|
||||
RARCH_ERR("Cannot identify '%s' : %d, %s\n", v4l->dev_name,
|
||||
errno, strerror(errno));
|
||||
goto error;
|
||||
}
|
||||
|
||||
@ -336,14 +343,17 @@ static void *v4l_init(const char *device, uint64_t caps, unsigned width, unsigne
|
||||
|
||||
if (v4l->fd == -1)
|
||||
{
|
||||
RARCH_ERR("Cannot open '%s': %d, %s\n", v4l->dev_name, errno, strerror(errno));
|
||||
RARCH_ERR("Cannot open '%s': %d, %s\n", v4l->dev_name,
|
||||
errno, strerror(errno));
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!init_device(v4l))
|
||||
goto error;
|
||||
|
||||
v4l->buffer_output = (uint32_t*)malloc(v4l->width * v4l->height * sizeof(uint32_t));
|
||||
v4l->buffer_output = (uint32_t*)
|
||||
malloc(v4l->width * v4l->height * sizeof(uint32_t));
|
||||
|
||||
if (!v4l->buffer_output)
|
||||
{
|
||||
RARCH_ERR("Failed to allocate output buffer.\n");
|
||||
@ -403,7 +413,8 @@ static bool preprocess_image(void *data)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool v4l_poll(void *data, retro_camera_frame_raw_framebuffer_t frame_raw_cb,
|
||||
static bool v4l_poll(void *data,
|
||||
retro_camera_frame_raw_framebuffer_t frame_raw_cb,
|
||||
retro_camera_frame_opengl_texture_t frame_gl_cb)
|
||||
{
|
||||
video4linux_t *v4l = (video4linux_t*)data;
|
||||
@ -415,7 +426,8 @@ static bool v4l_poll(void *data, retro_camera_frame_raw_framebuffer_t frame_raw_
|
||||
if (preprocess_image(data))
|
||||
{
|
||||
if (frame_raw_cb != NULL)
|
||||
frame_raw_cb(v4l->buffer_output, v4l->width, v4l->height, v4l->width * 4);
|
||||
frame_raw_cb(v4l->buffer_output, v4l->width,
|
||||
v4l->height, v4l->width * 4);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
|
@ -18,7 +18,8 @@
|
||||
#include "../general.h"
|
||||
#include "../performance.h"
|
||||
|
||||
static inline float time_to_fps(retro_time_t last_time, retro_time_t new_time, int frames)
|
||||
static inline float time_to_fps(retro_time_t last_time,
|
||||
retro_time_t new_time, int frames)
|
||||
{
|
||||
return (1000000.0f * frames) / (new_time - last_time);
|
||||
}
|
||||
@ -35,9 +36,11 @@ bool gfx_get_fps(char *buf, size_t size, char *buf_fps, size_t size_fps)
|
||||
retro_time_t new_time = rarch_get_time_usec();
|
||||
if (g_extern.frame_count)
|
||||
{
|
||||
unsigned write_index = g_extern.measure_data.frame_time_samples_count++ &
|
||||
unsigned write_index =
|
||||
g_extern.measure_data.frame_time_samples_count++ &
|
||||
(MEASURE_FRAME_TIME_SAMPLES_COUNT - 1);
|
||||
g_extern.measure_data.frame_time_samples[write_index] = new_time - fps_time;
|
||||
g_extern.measure_data.frame_time_samples[write_index] =
|
||||
new_time - fps_time;
|
||||
fps_time = new_time;
|
||||
|
||||
if ((g_extern.frame_count % FPS_UPDATE_INTERVAL) == 0)
|
||||
@ -45,12 +48,14 @@ bool gfx_get_fps(char *buf, size_t size, char *buf_fps, size_t size_fps)
|
||||
last_fps = time_to_fps(time, new_time, FPS_UPDATE_INTERVAL);
|
||||
time = new_time;
|
||||
|
||||
snprintf(buf, size, "%s || FPS: %6.1f || Frames: %u", g_extern.title_buf, last_fps, g_extern.frame_count);
|
||||
snprintf(buf, size, "%s || FPS: %6.1f || Frames: %u",
|
||||
g_extern.title_buf, last_fps, g_extern.frame_count);
|
||||
ret = true;
|
||||
}
|
||||
|
||||
if (buf_fps)
|
||||
snprintf(buf_fps, size_fps, "FPS: %6.1f || Frames: %u", last_fps, g_extern.frame_count);
|
||||
snprintf(buf_fps, size_fps, "FPS: %6.1f || Frames: %u",
|
||||
last_fps, g_extern.frame_count);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -67,8 +72,11 @@ bool gfx_get_fps(char *buf, size_t size, char *buf_fps, size_t size_fps)
|
||||
#if defined(_WIN32) && !defined(_XBOX)
|
||||
#include <windows.h>
|
||||
#include "../dynamic.h"
|
||||
// We only load this library once, so we let it be unloaded at application shutdown,
|
||||
// since unloading it early seems to cause issues on some systems.
|
||||
|
||||
/* We only load this library once, so we let it be
|
||||
* unloaded at application shutdown, since unloading
|
||||
* it early seems to cause issues on some systems.
|
||||
*/
|
||||
|
||||
static dylib_t dwmlib;
|
||||
static bool dwm_composition_disabled;
|
||||
@ -96,7 +104,8 @@ static void gfx_init_dwm(void)
|
||||
}
|
||||
atexit(gfx_dwm_shutdown);
|
||||
|
||||
HRESULT (WINAPI *mmcss)(BOOL) = (HRESULT (WINAPI*)(BOOL))dylib_proc(dwmlib, "DwmEnableMMCSS");
|
||||
HRESULT (WINAPI *mmcss)(BOOL) =
|
||||
(HRESULT (WINAPI*)(BOOL))dylib_proc(dwmlib, "DwmEnableMMCSS");
|
||||
if (mmcss)
|
||||
{
|
||||
RARCH_LOG("Setting multimedia scheduling for DWM.\n");
|
||||
@ -113,7 +122,8 @@ void gfx_set_dwm(void)
|
||||
if (g_settings.video.disable_composition == dwm_composition_disabled)
|
||||
return;
|
||||
|
||||
HRESULT (WINAPI *composition_enable)(UINT) = (HRESULT (WINAPI*)(UINT))dylib_proc(dwmlib, "DwmEnableComposition");
|
||||
HRESULT (WINAPI *composition_enable)(UINT) =
|
||||
(HRESULT (WINAPI*)(UINT))dylib_proc(dwmlib, "DwmEnableComposition");
|
||||
if (!composition_enable)
|
||||
{
|
||||
RARCH_ERR("Did not find DwmEnableComposition ...\n");
|
||||
@ -127,7 +137,8 @@ void gfx_set_dwm(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
void gfx_scale_integer(struct rarch_viewport *vp, unsigned width, unsigned height, float aspect_ratio, bool keep_aspect)
|
||||
void gfx_scale_integer(struct rarch_viewport *vp, unsigned width,
|
||||
unsigned height, float aspect_ratio, bool keep_aspect)
|
||||
{
|
||||
int padding_x = 0;
|
||||
int padding_y = 0;
|
||||
@ -135,7 +146,8 @@ void gfx_scale_integer(struct rarch_viewport *vp, unsigned width, unsigned heigh
|
||||
if (g_settings.video.aspect_ratio_idx == ASPECT_RATIO_CUSTOM)
|
||||
{
|
||||
const struct rarch_viewport *custom =
|
||||
(const struct rarch_viewport*)&g_extern.console.screen.viewports.custom_vp;
|
||||
(const struct rarch_viewport*)
|
||||
&g_extern.console.screen.viewports.custom_vp;
|
||||
|
||||
padding_x = width - custom->width;
|
||||
padding_y = height - custom->height;
|
||||
@ -144,27 +156,34 @@ void gfx_scale_integer(struct rarch_viewport *vp, unsigned width, unsigned heigh
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use system reported sizes as these define the geometry for the "normal" case.
|
||||
/* Use system reported sizes as these define the
|
||||
* geometry for the "normal" case. */
|
||||
unsigned base_height = g_extern.system.av_info.geometry.base_height;
|
||||
|
||||
if (base_height == 0)
|
||||
base_height = 1;
|
||||
// Account for non-square pixels.
|
||||
// This is sort of contradictory with the goal of integer scale,
|
||||
// but it is desirable in some cases.
|
||||
// If square pixels are used, base_height will be equal to g_extern.system.av_info.base_height.
|
||||
|
||||
/* Account for non-square pixels.
|
||||
* This is sort of contradictory with the goal of integer scale,
|
||||
* but it is desirable in some cases.
|
||||
*
|
||||
* If square pixels are used, base_height will be equal to
|
||||
* g_extern.system.av_info.base_height. */
|
||||
unsigned base_width = (unsigned)roundf(base_height * aspect_ratio);
|
||||
|
||||
// Make sure that we don't get 0x scale ...
|
||||
/* Make sure that we don't get 0x scale ... */
|
||||
if (width >= base_width && height >= base_height)
|
||||
{
|
||||
if (keep_aspect) // X/Y scale must be same.
|
||||
if (keep_aspect)
|
||||
{
|
||||
/* X/Y scale must be same. */
|
||||
unsigned max_scale = min(width / base_width, height / base_height);
|
||||
padding_x = width - base_width * max_scale;
|
||||
padding_y = height - base_height * max_scale;
|
||||
}
|
||||
else // X/Y can be independent, each scaled as much as possible.
|
||||
else
|
||||
{
|
||||
/* X/Y can be independent, each scaled as much as possible. */
|
||||
padding_x = width % base_width;
|
||||
padding_y = height % base_height;
|
||||
}
|
||||
@ -240,23 +259,27 @@ void gfx_set_square_pixel_viewport(unsigned width, unsigned height)
|
||||
|
||||
void gfx_set_core_viewport(void)
|
||||
{
|
||||
const struct retro_game_geometry *geom = &g_extern.system.av_info.geometry;
|
||||
const struct retro_game_geometry *geom =
|
||||
(const struct retro_game_geometry*)&g_extern.system.av_info.geometry;
|
||||
|
||||
if (geom->base_width <= 0.0f || geom->base_height <= 0.0f)
|
||||
return;
|
||||
|
||||
// Fallback to 1:1 pixel ratio if none provided
|
||||
/* Fallback to 1:1 pixel ratio if none provided */
|
||||
if (geom->aspect_ratio > 0.0f)
|
||||
aspectratio_lut[ASPECT_RATIO_CORE].value = geom->aspect_ratio;
|
||||
else
|
||||
aspectratio_lut[ASPECT_RATIO_CORE].value = (float)geom->base_width / geom->base_height;
|
||||
aspectratio_lut[ASPECT_RATIO_CORE].value =
|
||||
(float)geom->base_width / geom->base_height;
|
||||
}
|
||||
|
||||
void gfx_set_config_viewport(void)
|
||||
{
|
||||
if (g_settings.video.aspect_ratio < 0.0f)
|
||||
{
|
||||
const struct retro_game_geometry *geom = &g_extern.system.av_info.geometry;
|
||||
const struct retro_game_geometry *geom =
|
||||
(const struct retro_game_geometry*)
|
||||
&g_extern.system.av_info.geometry;
|
||||
|
||||
if (geom->aspect_ratio > 0.0f && g_settings.video.aspect_ratio_auto)
|
||||
aspectratio_lut[ASPECT_RATIO_CONFIG].value = geom->aspect_ratio;
|
||||
@ -265,15 +288,17 @@ void gfx_set_config_viewport(void)
|
||||
unsigned base_width = geom->base_width;
|
||||
unsigned base_height = geom->base_height;
|
||||
|
||||
// Get around division by zero errors
|
||||
/* Get around division by zero errors */
|
||||
if (base_width == 0)
|
||||
base_width = 1;
|
||||
if (base_height == 0)
|
||||
base_height = 1;
|
||||
aspectratio_lut[ASPECT_RATIO_CONFIG].value = (float)base_width / base_height; // 1:1 PAR.
|
||||
aspectratio_lut[ASPECT_RATIO_CONFIG].value =
|
||||
(float)base_width / base_height; /* 1:1 PAR. */
|
||||
}
|
||||
}
|
||||
else
|
||||
aspectratio_lut[ASPECT_RATIO_CONFIG].value = g_settings.video.aspect_ratio;
|
||||
aspectratio_lut[ASPECT_RATIO_CONFIG].value =
|
||||
g_settings.video.aspect_ratio;
|
||||
}
|
||||
|
||||
|
@ -30,15 +30,19 @@ extern "C" {
|
||||
#include "../config.h"
|
||||
#endif
|
||||
|
||||
// bufs gets a string suitable for Window title, buf_fps for raw FPS only.
|
||||
// buf_fps is optional.
|
||||
bool gfx_get_fps(char *buf, size_t size, char *buf_fps, size_t size_fps);
|
||||
/* bufs gets a string suitable for Window title,
|
||||
* buf_fps for raw FPS only.
|
||||
* buf_fps is optional.
|
||||
*/
|
||||
bool gfx_get_fps(char *buf, size_t size,
|
||||
char *buf_fps, size_t size_fps);
|
||||
|
||||
#ifdef _WIN32
|
||||
void gfx_set_dwm(void);
|
||||
#endif
|
||||
|
||||
void gfx_scale_integer(struct rarch_viewport *vp, unsigned win_width, unsigned win_height,
|
||||
void gfx_scale_integer(struct rarch_viewport *vp,
|
||||
unsigned win_width, unsigned win_height,
|
||||
float aspect_ratio, bool keep_aspect);
|
||||
|
||||
enum aspect_ratio
|
||||
|
@ -59,7 +59,8 @@ static const gfx_ctx_driver_t *gfx_ctx_drivers[] = {
|
||||
#if defined(__QNX__)
|
||||
&gfx_ctx_bbqnx,
|
||||
#endif
|
||||
#if defined(IOS) || defined(OSX) //< Don't use __APPLE__ as it breaks basic SDL builds
|
||||
#if defined(IOS) || defined(OSX)
|
||||
/* < Don't use __APPLE__ as it breaks basic SDL builds */
|
||||
&gfx_ctx_apple,
|
||||
#endif
|
||||
#if (defined(HAVE_SDL) || defined(HAVE_SDL2)) && defined(HAVE_OPENGL)
|
||||
@ -83,7 +84,9 @@ const gfx_ctx_driver_t *gfx_ctx_find_driver(const char *ident)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const gfx_ctx_driver_t *gfx_ctx_init_first(void *data, enum gfx_ctx_api api, unsigned major, unsigned minor, bool hw_render_ctx)
|
||||
const gfx_ctx_driver_t *gfx_ctx_init_first(void *data,
|
||||
enum gfx_ctx_api api, unsigned major,
|
||||
unsigned minor, bool hw_render_ctx)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; gfx_ctx_drivers[i]; i++)
|
||||
|
@ -40,71 +40,89 @@ enum gfx_ctx_api
|
||||
|
||||
typedef void (*gfx_ctx_proc_t)(void);
|
||||
|
||||
// The opaque void* argument should be the overlying driver data (e.g. gl_t for OpenGL contexts).
|
||||
// This will allow us in the future to have separate contexts to separate gl_t structs (if needed).
|
||||
// For now, this is only relevant for D3D.
|
||||
/* The opaque void* argument should be the overlying driver data
|
||||
* (e.g. gl_t for OpenGL contexts).
|
||||
*
|
||||
* This will allow us in the future to have separate contexts
|
||||
* to separate gl_t structs (if needed).
|
||||
*
|
||||
* For now, this is only relevant for D3D. */
|
||||
|
||||
typedef struct gfx_ctx_driver
|
||||
{
|
||||
bool (*init)(void *data);
|
||||
void (*destroy)(void *data);
|
||||
|
||||
bool (*bind_api)(void *data, enum gfx_ctx_api, unsigned major, unsigned minor); // Which API to bind to.
|
||||
/* Which API to bind to. */
|
||||
bool (*bind_api)(void *data, enum gfx_ctx_api,
|
||||
unsigned major, unsigned minor);
|
||||
|
||||
// Sets the swap interval.
|
||||
/* Sets the swap interval. */
|
||||
void (*swap_interval)(void *data, unsigned);
|
||||
|
||||
// Sets video mode. Creates a window, etc.
|
||||
/* Sets video mode. Creates a window, etc. */
|
||||
bool (*set_video_mode)(void*, unsigned, unsigned, bool);
|
||||
|
||||
// Gets current window size.
|
||||
// If not initialized yet, it returns current screen size.
|
||||
/* Gets current window size.
|
||||
* If not initialized yet, it returns current screen size. */
|
||||
void (*get_video_size)(void*, unsigned*, unsigned*);
|
||||
|
||||
// Translates a window size to an aspect ratio.
|
||||
// In most cases this will be just width / height, but
|
||||
// some contexts will better know which actual aspect ratio is used.
|
||||
// This can be NULL to assume the default behavior.
|
||||
/* Translates a window size to an aspect ratio.
|
||||
* In most cases this will be just width / height, but
|
||||
* some contexts will better know which actual aspect ratio is used.
|
||||
* This can be NULL to assume the default behavior.
|
||||
*/
|
||||
float (*translate_aspect)(void*, unsigned, unsigned);
|
||||
|
||||
// Asks driver to update window title (FPS, etc).
|
||||
/* Asks driver to update window title (FPS, etc). */
|
||||
void (*update_window_title)(void*);
|
||||
|
||||
// Queries for resize and quit events.
|
||||
// Also processes events.
|
||||
void (*check_window)(void*, bool*, bool*, unsigned*, unsigned*, unsigned);
|
||||
/* Queries for resize and quit events.
|
||||
* Also processes events. */
|
||||
void (*check_window)(void*, bool*, bool*,
|
||||
unsigned*, unsigned*, unsigned);
|
||||
|
||||
// Acknowledge a resize event. This is needed for some APIs. Most backends will ignore this.
|
||||
/* Acknowledge a resize event. This is needed for some APIs.
|
||||
* Most backends will ignore this. */
|
||||
void (*set_resize)(void*, unsigned, unsigned);
|
||||
|
||||
// Checks if window has input focus.
|
||||
/* Checks if window has input focus. */
|
||||
bool (*has_focus)(void*);
|
||||
|
||||
// Swaps buffers. VBlank sync depends on earlier calls to swap_interval.
|
||||
/* Swaps buffers. VBlank sync depends on
|
||||
* earlier calls to swap_interval. */
|
||||
void (*swap_buffers)(void*);
|
||||
|
||||
// Most video backends will want to use a certain input driver.
|
||||
// Checks for it here.
|
||||
/* Most video backends will want to use a certain input driver.
|
||||
* Checks for it here. */
|
||||
void (*input_driver)(void*, const input_driver_t**, void**);
|
||||
|
||||
// Wraps whatever gl_proc_address() there is.
|
||||
// Does not take opaque, to avoid lots of ugly wrapper code.
|
||||
/* Wraps whatever gl_proc_address() there is.
|
||||
* Does not take opaque, to avoid lots of ugly wrapper code. */
|
||||
gfx_ctx_proc_t (*get_proc_address)(const char*);
|
||||
|
||||
#ifdef HAVE_EGL
|
||||
// Returns true if this context supports EGLImage buffers for screen drawing and was initalized correctly.
|
||||
/* Returns true if this context supports EGLImage buffers for
|
||||
* screen drawing and was initalized correctly. */
|
||||
bool (*init_egl_image_buffer)(void*, const video_info_t*);
|
||||
// Writes the frame to the EGLImage and sets image_handle to it. Returns true if a new image handle is created.
|
||||
// Always returns true the first time it's called for a new index. The graphics core must handle a change in the handle correctly.
|
||||
bool (*write_egl_image)(void*, const void *frame, unsigned width, unsigned height, unsigned pitch, bool rgb32, unsigned index, void **image_handle);
|
||||
|
||||
/* Writes the frame to the EGLImage and sets image_handle to it.
|
||||
* Returns true if a new image handle is created.
|
||||
* Always returns true the first time it's called for a new index.
|
||||
* The graphics core must handle a change in the handle correctly. */
|
||||
bool (*write_egl_image)(void*, const void *frame, unsigned width,
|
||||
unsigned height, unsigned pitch, bool rgb32,
|
||||
unsigned index, void **image_handle);
|
||||
#endif
|
||||
|
||||
// Shows or hides mouse. Can be NULL if context doesn't have a concept of mouse pointer.
|
||||
/* Shows or hides mouse. Can be NULL if context doesn't
|
||||
* have a concept of mouse pointer. */
|
||||
void (*show_mouse)(void*, bool state);
|
||||
|
||||
// Human readable string.
|
||||
/* Human readable string. */
|
||||
const char *ident;
|
||||
|
||||
// Optional. Binds HW-render offscreen context.
|
||||
/* Optional. Binds HW-render offscreen context. */
|
||||
void (*bind_hw_render)(void *data, bool enable);
|
||||
} gfx_ctx_driver_t;
|
||||
|
||||
@ -125,8 +143,12 @@ extern const gfx_ctx_driver_t gfx_ctx_apple;
|
||||
extern const gfx_ctx_driver_t gfx_ctx_emscripten;
|
||||
extern const gfx_ctx_driver_t gfx_ctx_null;
|
||||
|
||||
const gfx_ctx_driver_t *gfx_ctx_find_driver(const char *ident); // Finds driver with ident. Does not initialize.
|
||||
const gfx_ctx_driver_t *gfx_ctx_init_first(void *data, enum gfx_ctx_api api, unsigned major, unsigned minor, bool hw_render_ctx); // Finds first suitable driver and initializes.
|
||||
/* Finds driver with ident. Does not initialize. */
|
||||
const gfx_ctx_driver_t *gfx_ctx_find_driver(const char *ident);
|
||||
|
||||
/* Finds first suitable driver and initializes. */
|
||||
const gfx_ctx_driver_t *gfx_ctx_init_first(void *data, enum gfx_ctx_api api,
|
||||
unsigned major, unsigned minor, bool hw_render_ctx);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
181
gfx/shader_cg.c
181
gfx/shader_cg.c
@ -32,9 +32,12 @@
|
||||
|
||||
#include "state_tracker.h"
|
||||
|
||||
//#define RARCH_CG_DEBUG
|
||||
#if 0
|
||||
#define RARCH_CG_DEBUG
|
||||
#endif
|
||||
|
||||
// Used when we call deactivate() since just unbinding the program didn't seem to work... :(
|
||||
/* Used when we call deactivate() since just unbinding
|
||||
* the program didn't seem to work... */
|
||||
static const char *stock_cg_program =
|
||||
"struct input"
|
||||
"{"
|
||||
@ -149,7 +152,7 @@ static char cg_alias_define[GFX_MAX_SHADERS][128];
|
||||
static void gl_cg_reset_attrib(void)
|
||||
{
|
||||
unsigned i;
|
||||
// Add sanity check that we did not overflow.
|
||||
/* Add sanity check that we did not overflow. */
|
||||
rarch_assert(cg_attrib_index <= ARRAY_SIZE(cg_attribs));
|
||||
|
||||
for (i = 0; i < cg_attrib_index; i++)
|
||||
@ -207,19 +210,22 @@ static void gl_cg_set_params(void *data, unsigned width, unsigned height,
|
||||
{
|
||||
(void)data;
|
||||
unsigned i;
|
||||
if (!cg_active || (active_index == 0) || (active_index == GL_SHADER_STOCK_BLEND))
|
||||
if (!cg_active || (active_index == 0) ||
|
||||
(active_index == GL_SHADER_STOCK_BLEND))
|
||||
return;
|
||||
|
||||
// Set frame.
|
||||
/* Set frame. */
|
||||
set_param_2f(prg[active_index].vid_size_f, width, height);
|
||||
set_param_2f(prg[active_index].tex_size_f, tex_width, tex_height);
|
||||
set_param_2f(prg[active_index].out_size_f, out_width, out_height);
|
||||
set_param_1f(prg[active_index].frame_dir_f, g_extern.frame_is_reverse ? -1.0 : 1.0);
|
||||
set_param_1f(prg[active_index].frame_dir_f,
|
||||
g_extern.frame_is_reverse ? -1.0 : 1.0);
|
||||
|
||||
set_param_2f(prg[active_index].vid_size_v, width, height);
|
||||
set_param_2f(prg[active_index].tex_size_v, tex_width, tex_height);
|
||||
set_param_2f(prg[active_index].out_size_v, out_width, out_height);
|
||||
set_param_1f(prg[active_index].frame_dir_v, g_extern.frame_is_reverse ? -1.0 : 1.0);
|
||||
set_param_1f(prg[active_index].frame_dir_v,
|
||||
g_extern.frame_is_reverse ? -1.0 : 1.0);
|
||||
|
||||
if (prg[active_index].frame_cnt_f || prg[active_index].frame_cnt_v)
|
||||
{
|
||||
@ -231,7 +237,7 @@ static void gl_cg_set_params(void *data, unsigned width, unsigned height,
|
||||
set_param_1f(prg[active_index].frame_cnt_v, (float)frame_count);
|
||||
}
|
||||
|
||||
// Set orig texture.
|
||||
/* Set orig texture. */
|
||||
CGparameter param = prg[active_index].orig.tex;
|
||||
if (param)
|
||||
{
|
||||
@ -239,18 +245,23 @@ static void gl_cg_set_params(void *data, unsigned width, unsigned height,
|
||||
cgGLEnableTextureParameter(param);
|
||||
}
|
||||
|
||||
set_param_2f(prg[active_index].orig.vid_size_v, info->input_size[0], info->input_size[1]);
|
||||
set_param_2f(prg[active_index].orig.vid_size_f, info->input_size[0], info->input_size[1]);
|
||||
set_param_2f(prg[active_index].orig.tex_size_v, info->tex_size[0], info->tex_size[1]);
|
||||
set_param_2f(prg[active_index].orig.tex_size_f, info->tex_size[0], info->tex_size[1]);
|
||||
set_param_2f(prg[active_index].orig.vid_size_v,
|
||||
info->input_size[0], info->input_size[1]);
|
||||
set_param_2f(prg[active_index].orig.vid_size_f,
|
||||
info->input_size[0], info->input_size[1]);
|
||||
set_param_2f(prg[active_index].orig.tex_size_v,
|
||||
info->tex_size[0], info->tex_size[1]);
|
||||
set_param_2f(prg[active_index].orig.tex_size_f,
|
||||
info->tex_size[0], info->tex_size[1]);
|
||||
if (prg[active_index].orig.coord)
|
||||
{
|
||||
cgGLSetParameterPointer(prg[active_index].orig.coord, 2, GL_FLOAT, 0, info->coord);
|
||||
cgGLSetParameterPointer(prg[active_index].orig.coord, 2,
|
||||
GL_FLOAT, 0, info->coord);
|
||||
cgGLEnableClientState(prg[active_index].orig.coord);
|
||||
cg_attribs[cg_attrib_index++] = prg[active_index].orig.coord;
|
||||
}
|
||||
|
||||
// Set prev textures.
|
||||
/* Set prev textures. */
|
||||
for (i = 0; i < PREV_TEXTURES; i++)
|
||||
{
|
||||
param = prg[active_index].prev[i].tex;
|
||||
@ -260,30 +271,38 @@ static void gl_cg_set_params(void *data, unsigned width, unsigned height,
|
||||
cgGLEnableTextureParameter(param);
|
||||
}
|
||||
|
||||
set_param_2f(prg[active_index].prev[i].vid_size_v, prev_info[i].input_size[0], prev_info[i].input_size[1]);
|
||||
set_param_2f(prg[active_index].prev[i].vid_size_f, prev_info[i].input_size[0], prev_info[i].input_size[1]);
|
||||
set_param_2f(prg[active_index].prev[i].tex_size_v, prev_info[i].tex_size[0], prev_info[i].tex_size[1]);
|
||||
set_param_2f(prg[active_index].prev[i].tex_size_f, prev_info[i].tex_size[0], prev_info[i].tex_size[1]);
|
||||
set_param_2f(prg[active_index].prev[i].vid_size_v,
|
||||
prev_info[i].input_size[0], prev_info[i].input_size[1]);
|
||||
set_param_2f(prg[active_index].prev[i].vid_size_f,
|
||||
prev_info[i].input_size[0], prev_info[i].input_size[1]);
|
||||
set_param_2f(prg[active_index].prev[i].tex_size_v,
|
||||
prev_info[i].tex_size[0], prev_info[i].tex_size[1]);
|
||||
set_param_2f(prg[active_index].prev[i].tex_size_f,
|
||||
prev_info[i].tex_size[0], prev_info[i].tex_size[1]);
|
||||
|
||||
if (prg[active_index].prev[i].coord)
|
||||
{
|
||||
cgGLSetParameterPointer(prg[active_index].prev[i].coord, 2, GL_FLOAT, 0, prev_info[i].coord);
|
||||
cgGLSetParameterPointer(prg[active_index].prev[i].coord,
|
||||
2, GL_FLOAT, 0, prev_info[i].coord);
|
||||
cgGLEnableClientState(prg[active_index].prev[i].coord);
|
||||
cg_attribs[cg_attrib_index++] = prg[active_index].prev[i].coord;
|
||||
}
|
||||
}
|
||||
|
||||
// Set lookup textures.
|
||||
/* Set lookup textures. */
|
||||
for (i = 0; i < cg_shader->luts; i++)
|
||||
{
|
||||
CGparameter fparam = cgGetNamedParameter(prg[active_index].fprg, cg_shader->lut[i].id);
|
||||
CGparameter fparam = cgGetNamedParameter(
|
||||
prg[active_index].fprg, cg_shader->lut[i].id);
|
||||
|
||||
if (fparam)
|
||||
{
|
||||
cgGLSetTextureParameter(fparam, lut_textures[i]);
|
||||
cgGLEnableTextureParameter(fparam);
|
||||
}
|
||||
|
||||
CGparameter vparam = cgGetNamedParameter(prg[active_index].vprg, cg_shader->lut[i].id);
|
||||
CGparameter vparam = cgGetNamedParameter(
|
||||
prg[active_index].vprg, cg_shader->lut[i].id);
|
||||
if (vparam)
|
||||
{
|
||||
cgGLSetTextureParameter(vparam, lut_textures[i]);
|
||||
@ -291,55 +310,66 @@ static void gl_cg_set_params(void *data, unsigned width, unsigned height,
|
||||
}
|
||||
}
|
||||
|
||||
// Set FBO textures.
|
||||
/* Set FBO textures. */
|
||||
if (active_index)
|
||||
{
|
||||
for (i = 0; i < fbo_info_cnt; i++)
|
||||
{
|
||||
if (prg[active_index].fbo[i].tex)
|
||||
{
|
||||
cgGLSetTextureParameter(prg[active_index].fbo[i].tex, fbo_info[i].tex);
|
||||
cgGLSetTextureParameter(
|
||||
prg[active_index].fbo[i].tex, fbo_info[i].tex);
|
||||
cgGLEnableTextureParameter(prg[active_index].fbo[i].tex);
|
||||
}
|
||||
|
||||
set_param_2f(prg[active_index].fbo[i].vid_size_v, fbo_info[i].input_size[0], fbo_info[i].input_size[1]);
|
||||
set_param_2f(prg[active_index].fbo[i].vid_size_f, fbo_info[i].input_size[0], fbo_info[i].input_size[1]);
|
||||
set_param_2f(prg[active_index].fbo[i].vid_size_v,
|
||||
fbo_info[i].input_size[0], fbo_info[i].input_size[1]);
|
||||
set_param_2f(prg[active_index].fbo[i].vid_size_f,
|
||||
fbo_info[i].input_size[0], fbo_info[i].input_size[1]);
|
||||
|
||||
set_param_2f(prg[active_index].fbo[i].tex_size_v, fbo_info[i].tex_size[0], fbo_info[i].tex_size[1]);
|
||||
set_param_2f(prg[active_index].fbo[i].tex_size_f, fbo_info[i].tex_size[0], fbo_info[i].tex_size[1]);
|
||||
set_param_2f(prg[active_index].fbo[i].tex_size_v,
|
||||
fbo_info[i].tex_size[0], fbo_info[i].tex_size[1]);
|
||||
set_param_2f(prg[active_index].fbo[i].tex_size_f,
|
||||
fbo_info[i].tex_size[0], fbo_info[i].tex_size[1]);
|
||||
|
||||
if (prg[active_index].fbo[i].coord)
|
||||
{
|
||||
cgGLSetParameterPointer(prg[active_index].fbo[i].coord, 2, GL_FLOAT, 0, fbo_info[i].coord);
|
||||
cgGLSetParameterPointer(prg[active_index].fbo[i].coord,
|
||||
2, GL_FLOAT, 0, fbo_info[i].coord);
|
||||
cgGLEnableClientState(prg[active_index].fbo[i].coord);
|
||||
cg_attribs[cg_attrib_index++] = prg[active_index].fbo[i].coord;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// #pragma parameters
|
||||
/* #pragma parameters. */
|
||||
for (i = 0; i < cg_shader->num_parameters; i++)
|
||||
{
|
||||
CGparameter param_v = cgGetNamedParameter(prg[active_index].vprg, cg_shader->parameters[i].id);
|
||||
CGparameter param_f = cgGetNamedParameter(prg[active_index].fprg, cg_shader->parameters[i].id);
|
||||
CGparameter param_v = cgGetNamedParameter(
|
||||
prg[active_index].vprg, cg_shader->parameters[i].id);
|
||||
CGparameter param_f = cgGetNamedParameter(
|
||||
prg[active_index].fprg, cg_shader->parameters[i].id);
|
||||
set_param_1f(param_v, cg_shader->parameters[i].current);
|
||||
set_param_1f(param_f, cg_shader->parameters[i].current);
|
||||
}
|
||||
|
||||
// Set state parameters
|
||||
/* Set state parameters. */
|
||||
if (state_tracker)
|
||||
{
|
||||
// Only query uniforms in first pass.
|
||||
/* Only query uniforms in first pass. */
|
||||
static struct state_tracker_uniform info[MAX_VARIABLES];
|
||||
static unsigned cnt = 0;
|
||||
|
||||
if (active_index == 1)
|
||||
cnt = state_get_uniform(state_tracker, info, MAX_VARIABLES, frame_count);
|
||||
cnt = state_get_uniform(state_tracker, info,
|
||||
MAX_VARIABLES, frame_count);
|
||||
|
||||
for (i = 0; i < cnt; i++)
|
||||
{
|
||||
CGparameter param_v = cgGetNamedParameter(prg[active_index].vprg, info[i].id);
|
||||
CGparameter param_f = cgGetNamedParameter(prg[active_index].fprg, info[i].id);
|
||||
CGparameter param_v = cgGetNamedParameter(
|
||||
prg[active_index].vprg, info[i].id);
|
||||
CGparameter param_f = cgGetNamedParameter(
|
||||
prg[active_index].fprg, info[i].id);
|
||||
set_param_1f(param_v, info[i].value);
|
||||
set_param_1f(param_f, info[i].value);
|
||||
}
|
||||
@ -353,7 +383,7 @@ static void gl_cg_deinit_progs(void)
|
||||
cgGLUnbindProgram(cgFProf);
|
||||
cgGLUnbindProgram(cgVProf);
|
||||
|
||||
// Programs may alias [0].
|
||||
/* Programs may alias [0]. */
|
||||
for (i = 1; i < GFX_MAX_SHADERS; i++)
|
||||
{
|
||||
if (prg[i].fprg && prg[i].fprg != prg[0].fprg)
|
||||
@ -393,7 +423,7 @@ static void gl_cg_deinit_state(void)
|
||||
cg_shader = NULL;
|
||||
}
|
||||
|
||||
// Final deinit.
|
||||
/* Final deinit. */
|
||||
static void gl_cg_deinit_context_state(void)
|
||||
{
|
||||
if (cgCtx)
|
||||
@ -404,7 +434,7 @@ static void gl_cg_deinit_context_state(void)
|
||||
}
|
||||
}
|
||||
|
||||
// Full deinit.
|
||||
/* Full deinit. */
|
||||
static void gl_cg_deinit(void)
|
||||
{
|
||||
gl_cg_deinit_state();
|
||||
@ -418,7 +448,8 @@ static void gl_cg_deinit(void)
|
||||
listing_##type = strdup(list); \
|
||||
}
|
||||
|
||||
static bool load_program(unsigned index, const char *prog, bool path_is_file)
|
||||
static bool load_program(unsigned index,
|
||||
const char *prog, bool path_is_file)
|
||||
{
|
||||
bool ret = true;
|
||||
char *listing_f = NULL;
|
||||
@ -438,16 +469,20 @@ static bool load_program(unsigned index, const char *prog, bool path_is_file)
|
||||
|
||||
if (path_is_file)
|
||||
{
|
||||
prg[index].fprg = cgCreateProgramFromFile(cgCtx, CG_SOURCE, prog, cgFProf, "main_fragment", argv);
|
||||
prg[index].fprg = cgCreateProgramFromFile(cgCtx, CG_SOURCE,
|
||||
prog, cgFProf, "main_fragment", argv);
|
||||
SET_LISTING(f);
|
||||
prg[index].vprg = cgCreateProgramFromFile(cgCtx, CG_SOURCE, prog, cgVProf, "main_vertex", argv);
|
||||
prg[index].vprg = cgCreateProgramFromFile(cgCtx, CG_SOURCE,
|
||||
prog, cgVProf, "main_vertex", argv);
|
||||
SET_LISTING(v);
|
||||
}
|
||||
else
|
||||
{
|
||||
prg[index].fprg = cgCreateProgram(cgCtx, CG_SOURCE, prog, cgFProf, "main_fragment", argv);
|
||||
prg[index].fprg = cgCreateProgram(cgCtx, CG_SOURCE,
|
||||
prog, cgFProf, "main_fragment", argv);
|
||||
SET_LISTING(f);
|
||||
prg[index].vprg = cgCreateProgram(cgCtx, CG_SOURCE, prog, cgVProf, "main_vertex", argv);
|
||||
prg[index].vprg = cgCreateProgram(cgCtx, CG_SOURCE,
|
||||
prog, cgVProf, "main_vertex", argv);
|
||||
SET_LISTING(v);
|
||||
}
|
||||
|
||||
@ -501,7 +536,8 @@ static bool load_plain(const char *path)
|
||||
if (path)
|
||||
{
|
||||
RARCH_LOG("Loading Cg file: %s\n", path);
|
||||
strlcpy(cg_shader->pass[0].source.path, path, sizeof(cg_shader->pass[0].source.path));
|
||||
strlcpy(cg_shader->pass[0].source.path, path,
|
||||
sizeof(cg_shader->pass[0].source.path));
|
||||
if (!load_program(1, path, true))
|
||||
return false;
|
||||
}
|
||||
@ -538,14 +574,16 @@ static bool load_imports(void)
|
||||
memtype = -1u;
|
||||
}
|
||||
|
||||
if ((memtype != -1u) && (cg_shader->variable[i].addr >= pretro_get_memory_size(memtype)))
|
||||
if ((memtype != -1u) &&
|
||||
(cg_shader->variable[i].addr >= pretro_get_memory_size(memtype)))
|
||||
{
|
||||
RARCH_ERR("Address out of bounds.\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
tracker_info.wram = (uint8_t*)pretro_get_memory_data(RETRO_MEMORY_SYSTEM_RAM);
|
||||
tracker_info.wram = (uint8_t*)
|
||||
pretro_get_memory_data(RETRO_MEMORY_SYSTEM_RAM);
|
||||
tracker_info.info = cg_shader->variable;
|
||||
tracker_info.info_elem = cg_shader->variables;
|
||||
|
||||
@ -556,7 +594,8 @@ static bool load_imports(void)
|
||||
tracker_info.script_is_file = true;
|
||||
}
|
||||
|
||||
tracker_info.script_class = *cg_shader->script_class ? cg_shader->script_class : NULL;
|
||||
tracker_info.script_class =
|
||||
*cg_shader->script_class ? cg_shader->script_class : NULL;
|
||||
#endif
|
||||
|
||||
state_tracker = state_tracker_init(&tracker_info);
|
||||
@ -609,13 +648,15 @@ static bool load_preset(const char *path)
|
||||
|
||||
if (cg_shader->passes > GFX_MAX_SHADERS - 3)
|
||||
{
|
||||
RARCH_WARN("Too many shaders ... Capping shader amount to %d.\n", GFX_MAX_SHADERS - 3);
|
||||
RARCH_WARN("Too many shaders ... Capping shader amount to %d.\n",
|
||||
GFX_MAX_SHADERS - 3);
|
||||
cg_shader->passes = GFX_MAX_SHADERS - 3;
|
||||
}
|
||||
|
||||
for (i = 0; i < cg_shader->passes; i++)
|
||||
if (*cg_shader->pass[i].alias)
|
||||
snprintf(cg_alias_define[i], sizeof(cg_alias_define[i]), "-D%s_ALIAS", cg_shader->pass[i].alias);
|
||||
snprintf(cg_alias_define[i], sizeof(cg_alias_define[i]),
|
||||
"-D%s_ALIAS", cg_shader->pass[i].alias);
|
||||
|
||||
for (i = 0; i < cg_shader->passes; i++)
|
||||
{
|
||||
@ -646,7 +687,8 @@ static void set_program_base_attrib(unsigned i)
|
||||
CGparameter param = cgGetFirstParameter(prg[i].vprg, CG_PROGRAM);
|
||||
for (; param; param = cgGetNextParameter(param))
|
||||
{
|
||||
if (cgGetParameterDirection(param) != CG_IN || cgGetParameterVariability(param) != CG_VARYING)
|
||||
if (cgGetParameterDirection(param) != CG_IN
|
||||
|| cgGetParameterVariability(param) != CG_VARYING)
|
||||
continue;
|
||||
|
||||
const char *semantic = cgGetParameterSemantic(param);
|
||||
@ -754,18 +796,26 @@ static void set_program_attributes(unsigned i)
|
||||
"PREV6",
|
||||
};
|
||||
|
||||
snprintf(attr_buf_tex, sizeof(attr_buf_tex), "%s.texture", prev_names[j]);
|
||||
snprintf(attr_buf_vid_size, sizeof(attr_buf_vid_size), "%s.video_size", prev_names[j]);
|
||||
snprintf(attr_buf_tex_size, sizeof(attr_buf_tex_size), "%s.texture_size", prev_names[j]);
|
||||
snprintf(attr_buf_coord, sizeof(attr_buf_coord), "%s.tex_coord", prev_names[j]);
|
||||
snprintf(attr_buf_tex, sizeof(attr_buf_tex),
|
||||
"%s.texture", prev_names[j]);
|
||||
snprintf(attr_buf_vid_size, sizeof(attr_buf_vid_size),
|
||||
"%s.video_size", prev_names[j]);
|
||||
snprintf(attr_buf_tex_size, sizeof(attr_buf_tex_size),
|
||||
"%s.texture_size", prev_names[j]);
|
||||
snprintf(attr_buf_coord, sizeof(attr_buf_coord),
|
||||
"%s.tex_coord", prev_names[j]);
|
||||
|
||||
prg[i].prev[j].tex = cgGetNamedParameter(prg[i].fprg, attr_buf_tex);
|
||||
|
||||
prg[i].prev[j].vid_size_v = cgGetNamedParameter(prg[i].vprg, attr_buf_vid_size);
|
||||
prg[i].prev[j].vid_size_f = cgGetNamedParameter(prg[i].fprg, attr_buf_vid_size);
|
||||
prg[i].prev[j].vid_size_v =
|
||||
cgGetNamedParameter(prg[i].vprg, attr_buf_vid_size);
|
||||
prg[i].prev[j].vid_size_f =
|
||||
cgGetNamedParameter(prg[i].fprg, attr_buf_vid_size);
|
||||
|
||||
prg[i].prev[j].tex_size_v = cgGetNamedParameter(prg[i].vprg, attr_buf_tex_size);
|
||||
prg[i].prev[j].tex_size_f = cgGetNamedParameter(prg[i].fprg, attr_buf_tex_size);
|
||||
prg[i].prev[j].tex_size_v =
|
||||
cgGetNamedParameter(prg[i].vprg, attr_buf_tex_size);
|
||||
prg[i].prev[j].tex_size_f =
|
||||
cgGetNamedParameter(prg[i].fprg, attr_buf_tex_size);
|
||||
|
||||
prg[i].prev[j].coord = cgGetNamedParameter(prg[i].vprg, attr_buf_coord);
|
||||
}
|
||||
@ -838,13 +888,14 @@ static bool gl_cg_init(void *data, const char *path)
|
||||
for (i = 1; i <= cg_shader->passes; i++)
|
||||
set_program_attributes(i);
|
||||
|
||||
// If we aren't using last pass non-FBO shader,
|
||||
// this shader will be assumed to be "fixed-function".
|
||||
// Just use prg[0] for that pass, which will be
|
||||
// pass-through.
|
||||
/* If we aren't using last pass non-FBO shader,
|
||||
* this shader will be assumed to be "fixed-function".
|
||||
*
|
||||
* Just use prg[0] for that pass, which will be
|
||||
* pass-through. */
|
||||
prg[cg_shader->passes + 1] = prg[0];
|
||||
|
||||
// No need to apply Android hack in Cg.
|
||||
/* No need to apply Android hack in Cg. */
|
||||
prg[GL_SHADER_STOCK_BLEND] = prg[0];
|
||||
|
||||
cgGLBindProgram(prg[1].fprg);
|
||||
|
@ -81,7 +81,8 @@ struct gl_shader_backend
|
||||
#ifdef HAVE_OPENGL
|
||||
void gl_load_texture_data(GLuint obj, const struct texture_image *img,
|
||||
GLenum wrap, bool linear, bool mipmap);
|
||||
bool gl_load_luts(const struct gfx_shader *generic_shader, GLuint *lut_textures);
|
||||
bool gl_load_luts(const struct gfx_shader *generic_shader,
|
||||
GLuint *lut_textures);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -60,7 +60,7 @@ static unsigned gl_attrib_index;
|
||||
|
||||
static char glsl_alias_define[1024];
|
||||
|
||||
// Cache the VBO.
|
||||
/* Cache the VBO. */
|
||||
struct cache_vbo
|
||||
{
|
||||
GLuint vbo_primary;
|
||||
@ -120,8 +120,8 @@ static const char *glsl_prefixes[] = {
|
||||
"ruby",
|
||||
};
|
||||
|
||||
// Need to duplicate these to work around broken stuff on Android.
|
||||
// Must enforce alpha = 1.0 or 32-bit games can potentially go black.
|
||||
/* Need to duplicate these to work around broken stuff on Android.
|
||||
* Must enforce alpha = 1.0 or 32-bit games can potentially go black. */
|
||||
static const char *stock_vertex_modern =
|
||||
"attribute vec2 TexCoord;\n"
|
||||
"attribute vec2 VertexCoord;\n"
|
||||
@ -308,7 +308,8 @@ static void print_linker_log(GLuint obj)
|
||||
free(info_log);
|
||||
}
|
||||
|
||||
static bool compile_shader(GLuint shader, const char *define, const char *program)
|
||||
static bool compile_shader(GLuint shader,
|
||||
const char *define, const char *program)
|
||||
{
|
||||
char version[32] = {0};
|
||||
if (glsl_core && !strstr(program, "#version"))
|
||||
@ -354,7 +355,8 @@ static bool link_program(GLuint prog)
|
||||
return false;
|
||||
}
|
||||
|
||||
static GLuint compile_program(const char *vertex, const char *fragment, unsigned i)
|
||||
static GLuint compile_program(const char *vertex,
|
||||
const char *fragment, unsigned i)
|
||||
{
|
||||
GLuint prog = glCreateProgram();
|
||||
if (!prog)
|
||||
@ -367,7 +369,8 @@ static GLuint compile_program(const char *vertex, const char *fragment, unsigned
|
||||
{
|
||||
RARCH_LOG("Found GLSL vertex shader.\n");
|
||||
vert = glCreateShader(GL_VERTEX_SHADER);
|
||||
if (!compile_shader(vert, "#define VERTEX\n#define PARAMETER_UNIFORM\n", vertex))
|
||||
if (!compile_shader(
|
||||
vert, "#define VERTEX\n#define PARAMETER_UNIFORM\n", vertex))
|
||||
{
|
||||
RARCH_ERR("Failed to compile vertex shader #%u\n", i);
|
||||
return 0;
|
||||
@ -380,7 +383,8 @@ static GLuint compile_program(const char *vertex, const char *fragment, unsigned
|
||||
{
|
||||
RARCH_LOG("Found GLSL fragment shader.\n");
|
||||
frag = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
if (!compile_shader(frag, "#define FRAGMENT\n#define PARAMETER_UNIFORM\n", fragment))
|
||||
if (!compile_shader(frag,
|
||||
"#define FRAGMENT\n#define PARAMETER_UNIFORM\n", fragment))
|
||||
{
|
||||
RARCH_ERR("Failed to compile fragment shader #%u\n", i);
|
||||
return 0;
|
||||
@ -398,8 +402,9 @@ static GLuint compile_program(const char *vertex, const char *fragment, unsigned
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Clean up dead memory. We're not going to relink the program.
|
||||
// Detaching first seems to kill some mobile drivers (according to the intertubes anyways).
|
||||
/* Clean up dead memory. We're not going to relink the program.
|
||||
* Detaching first seems to kill some mobile drivers
|
||||
* (according to the intertubes anyways). */
|
||||
if (vert)
|
||||
glDeleteShader(vert);
|
||||
if (frag)
|
||||
@ -414,7 +419,8 @@ static GLuint compile_program(const char *vertex, const char *fragment, unsigned
|
||||
return prog;
|
||||
}
|
||||
|
||||
static bool load_source_path(struct gfx_shader_pass *pass, const char *path)
|
||||
static bool load_source_path(struct gfx_shader_pass *pass,
|
||||
const char *path)
|
||||
{
|
||||
if (read_file(path, (void**)&pass->source.string.vertex) <= 0)
|
||||
return false;
|
||||
@ -430,9 +436,10 @@ static bool compile_programs(GLuint *gl_prog)
|
||||
{
|
||||
struct gfx_shader_pass *pass = &glsl_shader->pass[i];
|
||||
|
||||
// If we load from GLSLP (CGP),
|
||||
// load the file here, and pretend
|
||||
// we were really using XML all along.
|
||||
/* If we load from GLSLP (CGP),
|
||||
* load the file here, and pretend
|
||||
* we were really using XML all along.
|
||||
*/
|
||||
if (*pass->source.path && !load_source_path(pass, pass->source.path))
|
||||
{
|
||||
RARCH_ERR("Failed to load GLSL shader: %s.\n", pass->source.path);
|
||||
@ -458,7 +465,7 @@ static bool compile_programs(GLuint *gl_prog)
|
||||
static void gl_glsl_reset_attrib(void)
|
||||
{
|
||||
unsigned i;
|
||||
// Add sanity check that we did not overflow.
|
||||
/* Add sanity check that we did not overflow. */
|
||||
rarch_assert(gl_attrib_index <= ARRAY_SIZE(gl_attribs));
|
||||
|
||||
for (i = 0; i < gl_attrib_index; i++)
|
||||
@ -466,25 +473,31 @@ static void gl_glsl_reset_attrib(void)
|
||||
gl_attrib_index = 0;
|
||||
}
|
||||
|
||||
static void gl_glsl_set_vbo(GLfloat **buffer, size_t *buffer_elems, const GLfloat *data, size_t elems)
|
||||
static void gl_glsl_set_vbo(GLfloat **buffer, size_t *buffer_elems,
|
||||
const GLfloat *data, size_t elems)
|
||||
{
|
||||
if (elems != *buffer_elems || memcmp(data, *buffer, elems * sizeof(GLfloat)))
|
||||
if (elems != *buffer_elems ||
|
||||
memcmp(data, *buffer, elems * sizeof(GLfloat)))
|
||||
{
|
||||
if (elems > *buffer_elems)
|
||||
{
|
||||
GLfloat *new_buffer = (GLfloat*)realloc(*buffer, elems * sizeof(GLfloat));
|
||||
GLfloat *new_buffer = (GLfloat*)
|
||||
realloc(*buffer, elems * sizeof(GLfloat));
|
||||
rarch_assert(new_buffer);
|
||||
*buffer = new_buffer;
|
||||
}
|
||||
|
||||
memcpy(*buffer, data, elems * sizeof(GLfloat));
|
||||
glBufferData(GL_ARRAY_BUFFER, elems * sizeof(GLfloat), data, GL_STATIC_DRAW);
|
||||
glBufferData(GL_ARRAY_BUFFER, elems * sizeof(GLfloat),
|
||||
data, GL_STATIC_DRAW);
|
||||
*buffer_elems = elems;
|
||||
}
|
||||
}
|
||||
|
||||
static void gl_glsl_set_attribs(GLuint vbo, GLfloat **buffer, size_t *buffer_elems,
|
||||
const GLfloat *data, size_t elems, const struct glsl_attrib *attrs, size_t num_attrs)
|
||||
static void gl_glsl_set_attribs(GLuint vbo,
|
||||
GLfloat **buffer, size_t *buffer_elems,
|
||||
const GLfloat *data, size_t elems,
|
||||
const struct glsl_attrib *attrs, size_t num_attrs)
|
||||
{
|
||||
size_t i;
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
||||
@ -517,7 +530,8 @@ static void clear_uniforms_frame(struct shader_uniforms_frame *frame)
|
||||
frame->tex_coord = -1;
|
||||
}
|
||||
|
||||
static void find_uniforms_frame(GLuint prog, struct shader_uniforms_frame *frame, const char *base)
|
||||
static void find_uniforms_frame(GLuint prog,
|
||||
struct shader_uniforms_frame *frame, const char *base)
|
||||
{
|
||||
char texture[64];
|
||||
char texture_size[64];
|
||||
@ -539,7 +553,8 @@ static void find_uniforms_frame(GLuint prog, struct shader_uniforms_frame *frame
|
||||
frame->tex_coord = get_attrib(prog, tex_coord);
|
||||
}
|
||||
|
||||
static void find_uniforms(unsigned pass, GLuint prog, struct shader_uniforms *uni)
|
||||
static void find_uniforms(unsigned pass, GLuint prog,
|
||||
struct shader_uniforms *uni)
|
||||
{
|
||||
unsigned i;
|
||||
glUseProgram(prog);
|
||||
@ -660,10 +675,13 @@ static bool gl_glsl_init(void *data, const char *path)
|
||||
bool shader_support = glCreateProgram && glUseProgram && glCreateShader
|
||||
&& glDeleteShader && glShaderSource && glCompileShader && glAttachShader
|
||||
&& glDetachShader && glLinkProgram && glGetUniformLocation
|
||||
&& glUniform1i && glUniform1f && glUniform2fv && glUniform4fv && glUniformMatrix4fv
|
||||
&& glGetShaderiv && glGetShaderInfoLog && glGetProgramiv && glGetProgramInfoLog
|
||||
&& glUniform1i && glUniform1f && glUniform2fv && glUniform4fv
|
||||
&& glUniformMatrix4fv
|
||||
&& glGetShaderiv && glGetShaderInfoLog && glGetProgramiv
|
||||
&& glGetProgramInfoLog
|
||||
&& glDeleteProgram && glGetAttachedShaders
|
||||
&& glGetAttribLocation && glEnableVertexAttribArray && glDisableVertexAttribArray
|
||||
&& glGetAttribLocation && glEnableVertexAttribArray
|
||||
&& glDisableVertexAttribArray
|
||||
&& glVertexAttribPointer
|
||||
&& glGenBuffers && glBufferData && glDeleteBuffers && glBindBuffer;
|
||||
|
||||
@ -685,7 +703,8 @@ static bool gl_glsl_init(void *data, const char *path)
|
||||
bool ret;
|
||||
if (strcmp(path_get_extension(path), "glsl") == 0)
|
||||
{
|
||||
strlcpy(glsl_shader->pass[0].source.path, path, sizeof(glsl_shader->pass[0].source.path));
|
||||
strlcpy(glsl_shader->pass[0].source.path, path,
|
||||
sizeof(glsl_shader->pass[0].source.path));
|
||||
glsl_shader->passes = 1;
|
||||
glsl_shader->modern = true;
|
||||
ret = true;
|
||||
@ -714,8 +733,10 @@ static bool gl_glsl_init(void *data, const char *path)
|
||||
{
|
||||
RARCH_WARN("[GL]: Stock GLSL shaders will be used.\n");
|
||||
glsl_shader->passes = 1;
|
||||
glsl_shader->pass[0].source.string.vertex = strdup(glsl_core ? stock_vertex_core : stock_vertex_modern);
|
||||
glsl_shader->pass[0].source.string.fragment = strdup(glsl_core ? stock_fragment_core : stock_fragment_modern);
|
||||
glsl_shader->pass[0].source.string.vertex =
|
||||
strdup(glsl_core ? stock_vertex_core : stock_vertex_modern);
|
||||
glsl_shader->pass[0].source.string.fragment =
|
||||
strdup(glsl_core ? stock_fragment_core : stock_fragment_modern);
|
||||
glsl_shader->modern = true;
|
||||
}
|
||||
|
||||
@ -753,15 +774,16 @@ static bool gl_glsl_init(void *data, const char *path)
|
||||
}
|
||||
#endif
|
||||
|
||||
// Find all aliases we use in our GLSLP and add #defines for them so
|
||||
// that a shader can choose a fallback if we are not using a preset.
|
||||
/* Find all aliases we use in our GLSLP and add #defines for them so
|
||||
* that a shader can choose a fallback if we are not using a preset. */
|
||||
*glsl_alias_define = '\0';
|
||||
for (i = 0; i < glsl_shader->passes; i++)
|
||||
{
|
||||
if (*glsl_shader->pass[i].alias)
|
||||
{
|
||||
char define[128];
|
||||
snprintf(define, sizeof(define), "#define %s_ALIAS\n", glsl_shader->pass[i].alias);
|
||||
snprintf(define, sizeof(define), "#define %s_ALIAS\n",
|
||||
glsl_shader->pass[i].alias);
|
||||
strlcat(glsl_alias_define, define, sizeof(glsl_alias_define));
|
||||
}
|
||||
}
|
||||
@ -813,9 +835,13 @@ static bool gl_glsl_init(void *data, const char *path)
|
||||
|
||||
if (glsl_shader->modern)
|
||||
{
|
||||
gl_program[GL_SHADER_STOCK_BLEND] = compile_program(glsl_core ? stock_vertex_core_blend : stock_vertex_modern_blend,
|
||||
glsl_core ? stock_fragment_core_blend : stock_fragment_modern_blend, GL_SHADER_STOCK_BLEND);
|
||||
find_uniforms(0, gl_program[GL_SHADER_STOCK_BLEND], &gl_uniforms[GL_SHADER_STOCK_BLEND]);
|
||||
gl_program[GL_SHADER_STOCK_BLEND] = compile_program(glsl_core ?
|
||||
stock_vertex_core_blend : stock_vertex_modern_blend,
|
||||
glsl_core ?
|
||||
stock_fragment_core_blend : stock_fragment_modern_blend,
|
||||
GL_SHADER_STOCK_BLEND);
|
||||
find_uniforms(0, gl_program[GL_SHADER_STOCK_BLEND],
|
||||
&gl_uniforms[GL_SHADER_STOCK_BLEND]);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -890,7 +916,7 @@ static void gl_glsl_set_params(void *data, unsigned width, unsigned height,
|
||||
{
|
||||
if (uni->lut_texture[i] >= 0)
|
||||
{
|
||||
// Have to rebind as HW render could override this.
|
||||
/* Have to rebind as HW render could override this. */
|
||||
glActiveTexture(GL_TEXTURE0 + texunit);
|
||||
glBindTexture(GL_TEXTURE_2D, gl_teximage[i]);
|
||||
glUniform1i(uni->lut_texture[i], texunit);
|
||||
@ -898,12 +924,12 @@ static void gl_glsl_set_params(void *data, unsigned width, unsigned height,
|
||||
}
|
||||
}
|
||||
|
||||
// Set original texture.
|
||||
/* Set original texture. */
|
||||
if (active_index)
|
||||
{
|
||||
if (uni->orig.texture >= 0)
|
||||
{
|
||||
// Bind original texture.
|
||||
/* Bind original texture. */
|
||||
glActiveTexture(GL_TEXTURE0 + texunit);
|
||||
glUniform1i(uni->orig.texture, texunit);
|
||||
glBindTexture(GL_TEXTURE_2D, info->tex);
|
||||
@ -916,7 +942,7 @@ static void gl_glsl_set_params(void *data, unsigned width, unsigned height,
|
||||
if (uni->orig.input_size >= 0)
|
||||
glUniform2fv(uni->orig.input_size, 1, info->input_size);
|
||||
|
||||
// Pass texture coordinates.
|
||||
/* Pass texture coordinates. */
|
||||
if (uni->orig.tex_coord >= 0)
|
||||
{
|
||||
attr->loc = uni->orig.tex_coord;
|
||||
@ -929,7 +955,7 @@ static void gl_glsl_set_params(void *data, unsigned width, unsigned height,
|
||||
size += 8;
|
||||
}
|
||||
|
||||
// Bind FBO textures.
|
||||
/* Bind FBO textures. */
|
||||
for (i = 0; i < fbo_info_cnt; i++)
|
||||
{
|
||||
if (uni->pass[i].texture)
|
||||
@ -960,7 +986,7 @@ static void gl_glsl_set_params(void *data, unsigned width, unsigned height,
|
||||
}
|
||||
}
|
||||
|
||||
// Set previous textures. Only bind if they're actually used.
|
||||
/* Set previous textures. Only bind if they're actually used. */
|
||||
for (i = 0; i < PREV_TEXTURES; i++)
|
||||
{
|
||||
if (uni->prev[i].texture >= 0)
|
||||
@ -977,7 +1003,7 @@ static void gl_glsl_set_params(void *data, unsigned width, unsigned height,
|
||||
if (uni->prev[i].input_size >= 0)
|
||||
glUniform2fv(uni->prev[i].input_size, 1, prev_info[i].input_size);
|
||||
|
||||
// Pass texture coordinates.
|
||||
/* Pass texture coordinates. */
|
||||
if (uni->prev[i].tex_coord >= 0)
|
||||
{
|
||||
attr->loc = uni->prev[i].tex_coord;
|
||||
@ -1001,25 +1027,28 @@ static void gl_glsl_set_params(void *data, unsigned width, unsigned height,
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
// #pragma parameters
|
||||
/* #pragma parameters. */
|
||||
for (i = 0; i < glsl_shader->num_parameters; i++)
|
||||
{
|
||||
int location = glGetUniformLocation(gl_program[active_index], glsl_shader->parameters[i].id);
|
||||
int location = glGetUniformLocation(gl_program[active_index],
|
||||
glsl_shader->parameters[i].id);
|
||||
glUniform1f(location, glsl_shader->parameters[i].current);
|
||||
}
|
||||
|
||||
// Set state parameters
|
||||
/* Set state parameters. */
|
||||
if (gl_state_tracker)
|
||||
{
|
||||
static struct state_tracker_uniform info[GFX_MAX_VARIABLES];
|
||||
static unsigned cnt = 0;
|
||||
|
||||
if (active_index == 1)
|
||||
cnt = state_get_uniform(gl_state_tracker, info, GFX_MAX_VARIABLES, frame_count);
|
||||
cnt = state_get_uniform(gl_state_tracker, info,
|
||||
GFX_MAX_VARIABLES, frame_count);
|
||||
|
||||
for (i = 0; i < cnt; i++)
|
||||
{
|
||||
int location = glGetUniformLocation(gl_program[active_index], info[i].id);
|
||||
int location = glGetUniformLocation(gl_program[active_index],
|
||||
info[i].id);
|
||||
glUniform1f(location, info[i].value);
|
||||
}
|
||||
}
|
||||
@ -1043,11 +1072,12 @@ static bool gl_glsl_set_coords(const struct gl_coords *coords)
|
||||
if (!glsl_enable || !glsl_shader->modern)
|
||||
return false;
|
||||
|
||||
// Avoid hitting malloc on every single regular quad draw.
|
||||
/* Avoid hitting malloc on every single regular quad draw. */
|
||||
GLfloat short_buffer[4 * (2 + 2 + 4 + 2)];
|
||||
GLfloat *buffer = short_buffer;
|
||||
if (coords->vertices > 4)
|
||||
buffer = (GLfloat*)calloc(coords->vertices * (2 + 2 + 4 + 2), sizeof(*buffer));
|
||||
buffer = (GLfloat*)calloc(coords->vertices *
|
||||
(2 + 2 + 4 + 2), sizeof(*buffer));
|
||||
|
||||
if (!buffer)
|
||||
return false;
|
||||
@ -1067,7 +1097,8 @@ static bool gl_glsl_set_coords(const struct gl_coords *coords)
|
||||
attribs_size++;
|
||||
attr++;
|
||||
|
||||
memcpy(buffer + size, coords->tex_coord, 2 * coords->vertices * sizeof(GLfloat));
|
||||
memcpy(buffer + size, coords->tex_coord,
|
||||
2 * coords->vertices * sizeof(GLfloat));
|
||||
size += 2 * coords->vertices;
|
||||
}
|
||||
|
||||
@ -1079,7 +1110,8 @@ static bool gl_glsl_set_coords(const struct gl_coords *coords)
|
||||
attribs_size++;
|
||||
attr++;
|
||||
|
||||
memcpy(buffer + size, coords->vertex, 2 * coords->vertices * sizeof(GLfloat));
|
||||
memcpy(buffer + size, coords->vertex,
|
||||
2 * coords->vertices * sizeof(GLfloat));
|
||||
size += 2 * coords->vertices;
|
||||
}
|
||||
|
||||
@ -1091,7 +1123,8 @@ static bool gl_glsl_set_coords(const struct gl_coords *coords)
|
||||
attribs_size++;
|
||||
attr++;
|
||||
|
||||
memcpy(buffer + size, coords->color, 4 * coords->vertices * sizeof(GLfloat));
|
||||
memcpy(buffer + size, coords->color,
|
||||
4 * coords->vertices * sizeof(GLfloat));
|
||||
size += 4 * coords->vertices;
|
||||
}
|
||||
|
||||
@ -1103,7 +1136,8 @@ static bool gl_glsl_set_coords(const struct gl_coords *coords)
|
||||
attribs_size++;
|
||||
attr++;
|
||||
|
||||
memcpy(buffer + size, coords->lut_tex_coord, 2 * coords->vertices * sizeof(GLfloat));
|
||||
memcpy(buffer + size, coords->lut_tex_coord,
|
||||
2 * coords->vertices * sizeof(GLfloat));
|
||||
size += 2 * coords->vertices;
|
||||
}
|
||||
|
||||
@ -1197,7 +1231,8 @@ void gl_glsl_set_get_proc_address(gfx_ctx_proc_t (*proc)(const char*))
|
||||
glsl_get_proc_address = proc;
|
||||
}
|
||||
|
||||
void gl_glsl_set_context_type(bool core_profile, unsigned major, unsigned minor)
|
||||
void gl_glsl_set_context_type(bool core_profile,
|
||||
unsigned major, unsigned minor)
|
||||
{
|
||||
glsl_core = core_profile;
|
||||
glsl_major = major;
|
||||
|
@ -89,7 +89,8 @@ static bool shader_parse_pass(config_file_t *conf, struct gfx_shader_pass *pass,
|
||||
char frame_count_mod[64] = {0};
|
||||
char frame_count_mod_buf[64];
|
||||
print_buf(frame_count_mod_buf, "frame_count_mod%u", i);
|
||||
if (config_get_array(conf, frame_count_mod_buf, frame_count_mod, sizeof(frame_count_mod)))
|
||||
if (config_get_array(conf, frame_count_mod_buf,
|
||||
frame_count_mod, sizeof(frame_count_mod)))
|
||||
pass->frame_count_mod = strtoul(frame_count_mod, NULL, 0);
|
||||
|
||||
// FBO types and mipmapping
|
||||
@ -225,7 +226,8 @@ static bool shader_parse_pass(config_file_t *conf, struct gfx_shader_pass *pass,
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool shader_parse_textures(config_file_t *conf, struct gfx_shader *shader)
|
||||
static bool shader_parse_textures(config_file_t *conf,
|
||||
struct gfx_shader *shader)
|
||||
{
|
||||
const char *id;
|
||||
char *save;
|
||||
@ -238,19 +240,22 @@ static bool shader_parse_textures(config_file_t *conf, struct gfx_shader *shader
|
||||
id && shader->luts < GFX_MAX_TEXTURES;
|
||||
shader->luts++, id = strtok_r(NULL, ";", &save))
|
||||
{
|
||||
if (!config_get_array(conf, id, shader->lut[shader->luts].path, sizeof(shader->lut[shader->luts].path)))
|
||||
if (!config_get_array(conf, id, shader->lut[shader->luts].path,
|
||||
sizeof(shader->lut[shader->luts].path)))
|
||||
{
|
||||
RARCH_ERR("Cannot find path to texture \"%s\" ...\n", id);
|
||||
return false;
|
||||
}
|
||||
|
||||
strlcpy(shader->lut[shader->luts].id, id, sizeof(shader->lut[shader->luts].id));
|
||||
strlcpy(shader->lut[shader->luts].id, id,
|
||||
sizeof(shader->lut[shader->luts].id));
|
||||
|
||||
char id_filter[64];
|
||||
print_buf(id_filter, "%s_linear", id);
|
||||
bool smooth = false;
|
||||
if (config_get_bool(conf, id_filter, &smooth))
|
||||
shader->lut[shader->luts].filter = smooth ? RARCH_FILTER_LINEAR : RARCH_FILTER_NEAREST;
|
||||
shader->lut[shader->luts].filter = smooth ?
|
||||
RARCH_FILTER_LINEAR : RARCH_FILTER_NEAREST;
|
||||
else
|
||||
shader->lut[shader->luts].filter = RARCH_FILTER_UNSPEC;
|
||||
|
||||
@ -272,7 +277,8 @@ static bool shader_parse_textures(config_file_t *conf, struct gfx_shader *shader
|
||||
return true;
|
||||
}
|
||||
|
||||
static struct gfx_shader_parameter *find_parameter(struct gfx_shader_parameter *params, unsigned num_params, const char *id)
|
||||
static struct gfx_shader_parameter *find_parameter(
|
||||
struct gfx_shader_parameter *params, unsigned num_params, const char *id)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < num_params; i++)
|
||||
@ -283,14 +289,16 @@ static struct gfx_shader_parameter *find_parameter(struct gfx_shader_parameter *
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool gfx_shader_resolve_parameters(config_file_t *conf, struct gfx_shader *shader)
|
||||
bool gfx_shader_resolve_parameters(config_file_t *conf,
|
||||
struct gfx_shader *shader)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
shader->num_parameters = 0;
|
||||
struct gfx_shader_parameter *param = &shader->parameters[shader->num_parameters];
|
||||
struct gfx_shader_parameter *param = (struct gfx_shader_parameter*)
|
||||
&shader->parameters[shader->num_parameters];
|
||||
|
||||
// Find all parameters in our shaders.
|
||||
/* Find all parameters in our shaders. */
|
||||
for (i = 0; i < shader->passes; i++)
|
||||
{
|
||||
char line[2048];
|
||||
@ -298,10 +306,13 @@ bool gfx_shader_resolve_parameters(config_file_t *conf, struct gfx_shader *shade
|
||||
if (!file)
|
||||
continue;
|
||||
|
||||
while (shader->num_parameters < ARRAY_SIZE(shader->parameters) && fgets(line, sizeof(line), file))
|
||||
while (shader->num_parameters < ARRAY_SIZE(shader->parameters)
|
||||
&& fgets(line, sizeof(line), file))
|
||||
{
|
||||
int ret = sscanf(line, "#pragma parameter %63s \"%63[^\"]\" %f %f %f %f",
|
||||
param->id, param->desc, ¶m->initial, ¶m->minimum, ¶m->maximum, ¶m->step);
|
||||
int ret = sscanf(line,
|
||||
"#pragma parameter %63s \"%63[^\"]\" %f %f %f %f",
|
||||
param->id, param->desc, ¶m->initial,
|
||||
¶m->minimum, ¶m->maximum, ¶m->step);
|
||||
|
||||
if (ret >= 5)
|
||||
{
|
||||
@ -312,7 +323,8 @@ bool gfx_shader_resolve_parameters(config_file_t *conf, struct gfx_shader *shade
|
||||
param->step = 0.1f * (param->maximum - param->minimum);
|
||||
|
||||
RARCH_LOG("Found #pragma parameter %s (%s) %f %f %f %f\n",
|
||||
param->desc, param->id, param->initial, param->minimum, param->maximum, param->step);
|
||||
param->desc, param->id, param->initial,
|
||||
param->minimum, param->maximum, param->step);
|
||||
param->current = param->initial;
|
||||
|
||||
shader->num_parameters++;
|
||||
@ -323,19 +335,23 @@ bool gfx_shader_resolve_parameters(config_file_t *conf, struct gfx_shader *shade
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
// Read in parameters which override the defaults.
|
||||
/* Read in parameters which override the defaults. */
|
||||
if (conf)
|
||||
{
|
||||
char parameters[1024];
|
||||
char *save = NULL;
|
||||
const char *id;
|
||||
|
||||
if (!config_get_array(conf, "parameters", parameters, sizeof(parameters)))
|
||||
if (!config_get_array(conf, "parameters",
|
||||
parameters, sizeof(parameters)))
|
||||
return true;
|
||||
|
||||
for (id = strtok_r(parameters, ";", &save); id; id = strtok_r(NULL, ";", &save))
|
||||
for (id = strtok_r(parameters, ";", &save); id;
|
||||
id = strtok_r(NULL, ";", &save))
|
||||
{
|
||||
struct gfx_shader_parameter *param = find_parameter(shader->parameters, shader->num_parameters, id);
|
||||
struct gfx_shader_parameter *param = (struct gfx_shader_parameter*)
|
||||
find_parameter(shader->parameters, shader->num_parameters, id);
|
||||
|
||||
if (!param)
|
||||
{
|
||||
RARCH_WARN("[CGP/GLSLP]: Parameter %s is set in the preset, but no shader uses this parameter, ignoring.\n", id);
|
||||
@ -350,7 +366,8 @@ bool gfx_shader_resolve_parameters(config_file_t *conf, struct gfx_shader *shade
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool shader_parse_imports(config_file_t *conf, struct gfx_shader *shader)
|
||||
static bool shader_parse_imports(config_file_t *conf,
|
||||
struct gfx_shader *shader)
|
||||
{
|
||||
char imports[1024];
|
||||
char *save = NULL;
|
||||
@ -362,7 +379,9 @@ static bool shader_parse_imports(config_file_t *conf, struct gfx_shader *shader)
|
||||
id && shader->variables < GFX_MAX_VARIABLES;
|
||||
shader->variables++, id = strtok_r(NULL, ";", &save))
|
||||
{
|
||||
struct state_tracker_uniform_info *var = &shader->variable[shader->variables];
|
||||
struct state_tracker_uniform_info *var =
|
||||
(struct state_tracker_uniform_info*)
|
||||
&shader->variable[shader->variables];
|
||||
|
||||
strlcpy(var->id, id, sizeof(var->id));
|
||||
|
||||
@ -442,8 +461,10 @@ static bool shader_parse_imports(config_file_t *conf, struct gfx_shader *shader)
|
||||
var->equal = equal;
|
||||
}
|
||||
|
||||
config_get_path(conf, "import_script", shader->script_path, sizeof(shader->script_path));
|
||||
config_get_array(conf, "import_script_class", shader->script_class, sizeof(shader->script_class));
|
||||
config_get_path(conf, "import_script",
|
||||
shader->script_path, sizeof(shader->script_path));
|
||||
config_get_array(conf, "import_script_class",
|
||||
shader->script_class, sizeof(shader->script_class));
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -483,7 +504,7 @@ bool gfx_shader_read_conf_cgp(config_file_t *conf, struct gfx_shader *shader)
|
||||
return true;
|
||||
}
|
||||
|
||||
// CGP store
|
||||
/* CGP store */
|
||||
static const char *scale_type_to_str(enum gfx_scale_type type)
|
||||
{
|
||||
switch (type)
|
||||
@ -513,7 +534,8 @@ static void shader_write_scale_dim(config_file_t *conf, const char *dim,
|
||||
config_set_float(conf, key, scale);
|
||||
}
|
||||
|
||||
static void shader_write_fbo(config_file_t *conf, const struct gfx_fbo_scale *fbo, unsigned i)
|
||||
static void shader_write_fbo(config_file_t *conf,
|
||||
const struct gfx_fbo_scale *fbo, unsigned i)
|
||||
{
|
||||
char key[64];
|
||||
print_buf(key, "float_framebuffer%u", i);
|
||||
@ -550,7 +572,8 @@ static const char *import_semantic_to_string(enum state_tracker_type type)
|
||||
}
|
||||
}
|
||||
|
||||
static void shader_write_variable(config_file_t *conf, const struct state_tracker_uniform_info *info)
|
||||
static void shader_write_variable(config_file_t *conf,
|
||||
const struct state_tracker_uniform_info *info)
|
||||
{
|
||||
const char *id = info->id;
|
||||
|
||||
@ -566,7 +589,8 @@ static void shader_write_variable(config_file_t *conf, const struct state_tracke
|
||||
print_buf(mask_buf, "%s_mask", id);
|
||||
print_buf(equal_buf, "%s_equal", id);
|
||||
|
||||
config_set_string(conf, semantic_buf, import_semantic_to_string(info->type));
|
||||
config_set_string(conf, semantic_buf,
|
||||
import_semantic_to_string(info->type));
|
||||
config_set_hex(conf, mask_buf, info->mask);
|
||||
config_set_hex(conf, equal_buf, info->equal);
|
||||
|
||||
@ -589,7 +613,8 @@ static void shader_write_variable(config_file_t *conf, const struct state_tracke
|
||||
}
|
||||
}
|
||||
|
||||
void gfx_shader_write_conf_cgp(config_file_t *conf, struct gfx_shader *shader)
|
||||
void gfx_shader_write_conf_cgp(config_file_t *conf,
|
||||
struct gfx_shader *shader)
|
||||
{
|
||||
unsigned i;
|
||||
config_set_int(conf, "shaders", shader->passes);
|
||||
@ -631,7 +656,7 @@ void gfx_shader_write_conf_cgp(config_file_t *conf, struct gfx_shader *shader)
|
||||
strlcpy(parameters, shader->parameters[0].id, sizeof(parameters));
|
||||
for (i = 1; i < shader->num_parameters; i++)
|
||||
{
|
||||
// O(n^2), but number of parameters is very limited.
|
||||
/* O(n^2), but number of parameters is very limited. */
|
||||
strlcat(parameters, ";", sizeof(parameters));
|
||||
strlcat(parameters, shader->parameters[i].id, sizeof(parameters));
|
||||
}
|
||||
@ -639,7 +664,8 @@ void gfx_shader_write_conf_cgp(config_file_t *conf, struct gfx_shader *shader)
|
||||
config_set_string(conf, "parameters", parameters);
|
||||
|
||||
for (i = 0; i < shader->num_parameters; i++)
|
||||
config_set_float(conf, shader->parameters[i].id, shader->parameters[i].current);
|
||||
config_set_float(conf, shader->parameters[i].id,
|
||||
shader->parameters[i].current);
|
||||
}
|
||||
|
||||
if (shader->luts)
|
||||
@ -648,7 +674,7 @@ void gfx_shader_write_conf_cgp(config_file_t *conf, struct gfx_shader *shader)
|
||||
strlcpy(textures, shader->lut[0].id, sizeof(textures));
|
||||
for (i = 1; i < shader->luts; i++)
|
||||
{
|
||||
// O(n^2), but number of textures is very limited.
|
||||
/* O(n^2), but number of textures is very limited. */
|
||||
strlcat(textures, ";", sizeof(textures));
|
||||
strlcat(textures, shader->lut[i].id, sizeof(textures));
|
||||
}
|
||||
@ -664,7 +690,8 @@ void gfx_shader_write_conf_cgp(config_file_t *conf, struct gfx_shader *shader)
|
||||
if (shader->lut[i].filter != RARCH_FILTER_UNSPEC)
|
||||
{
|
||||
print_buf(key, "%s_linear", shader->lut[i].id);
|
||||
config_set_bool(conf, key, shader->lut[i].filter == RARCH_FILTER_LINEAR);
|
||||
config_set_bool(conf, key,
|
||||
shader->lut[i].filter == RARCH_FILTER_LINEAR);
|
||||
}
|
||||
|
||||
print_buf(key, "%s_wrap_mode", shader->lut[i].id);
|
||||
@ -697,7 +724,8 @@ void gfx_shader_write_conf_cgp(config_file_t *conf, struct gfx_shader *shader)
|
||||
}
|
||||
}
|
||||
|
||||
enum rarch_shader_type gfx_shader_parse_type(const char *path, enum rarch_shader_type fallback)
|
||||
enum rarch_shader_type gfx_shader_parse_type(const char *path,
|
||||
enum rarch_shader_type fallback)
|
||||
{
|
||||
if (!path)
|
||||
return fallback;
|
||||
@ -712,7 +740,8 @@ enum rarch_shader_type gfx_shader_parse_type(const char *path, enum rarch_shader
|
||||
return fallback;
|
||||
}
|
||||
|
||||
void gfx_shader_resolve_relative(struct gfx_shader *shader, const char *ref_path)
|
||||
void gfx_shader_resolve_relative(struct gfx_shader *shader,
|
||||
const char *ref_path)
|
||||
{
|
||||
unsigned i;
|
||||
char tmp_path[PATH_MAX];
|
||||
|
@ -65,7 +65,8 @@ enum
|
||||
|
||||
enum gfx_wrap_type
|
||||
{
|
||||
RARCH_WRAP_BORDER = 0, // Kinda deprecated, but keep as default. Will be translated to EDGE in GLES.
|
||||
RARCH_WRAP_BORDER = 0, /* Kinda deprecated, but keep as default.
|
||||
Will be translated to EDGE in GLES. */
|
||||
RARCH_WRAP_DEFAULT = RARCH_WRAP_BORDER,
|
||||
RARCH_WRAP_EDGE,
|
||||
RARCH_WRAP_REPEAT,
|
||||
@ -125,13 +126,13 @@ struct gfx_shader_lut
|
||||
bool mipmap;
|
||||
};
|
||||
|
||||
// This is pretty big, shouldn't be put on the stack.
|
||||
// Avoid lots of allocation for convenience.
|
||||
/* This is pretty big, shouldn't be put on the stack.
|
||||
* Avoid lots of allocation for convenience. */
|
||||
struct gfx_shader
|
||||
{
|
||||
enum rarch_shader_type type;
|
||||
|
||||
bool modern; // Only used for XML shaders.
|
||||
bool modern; /* Only used for XML shaders. */
|
||||
char prefix[64];
|
||||
|
||||
unsigned passes;
|
||||
@ -146,17 +147,24 @@ struct gfx_shader
|
||||
unsigned variables;
|
||||
struct state_tracker_uniform_info variable[GFX_MAX_VARIABLES];
|
||||
char script_path[PATH_MAX];
|
||||
char *script; // Dynamically allocated. Must be free'd. Only used by XML.
|
||||
char *script; /* Dynamically allocated. Must be free'd. Only used by XML. */
|
||||
char script_class[512];
|
||||
};
|
||||
|
||||
bool gfx_shader_read_conf_cgp(config_file_t *conf, struct gfx_shader *shader);
|
||||
void gfx_shader_write_conf_cgp(config_file_t *conf, struct gfx_shader *shader);
|
||||
bool gfx_shader_read_conf_cgp(config_file_t *conf,
|
||||
struct gfx_shader *shader);
|
||||
|
||||
void gfx_shader_resolve_relative(struct gfx_shader *shader, const char *ref_path);
|
||||
bool gfx_shader_resolve_parameters(config_file_t *conf, struct gfx_shader *shader);
|
||||
void gfx_shader_write_conf_cgp(config_file_t *conf,
|
||||
struct gfx_shader *shader);
|
||||
|
||||
enum rarch_shader_type gfx_shader_parse_type(const char *path, enum rarch_shader_type fallback);
|
||||
void gfx_shader_resolve_relative(struct gfx_shader *shader,
|
||||
const char *ref_path);
|
||||
|
||||
bool gfx_shader_resolve_parameters(config_file_t *conf,
|
||||
struct gfx_shader *shader);
|
||||
|
||||
enum rarch_shader_type gfx_shader_parse_type(const char *path,
|
||||
enum rarch_shader_type fallback);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -71,7 +71,9 @@ state_tracker_t* state_tracker_init(const struct state_tracker_info *info)
|
||||
#ifdef HAVE_PYTHON
|
||||
if (info->script)
|
||||
{
|
||||
tracker->py = py_state_new(info->script, info->script_is_file, info->script_class ? info->script_class : "GameAware");
|
||||
tracker->py = py_state_new(info->script, info->script_is_file,
|
||||
info->script_class ? info->script_class : "GameAware");
|
||||
|
||||
if (!tracker->py)
|
||||
{
|
||||
free(tracker);
|
||||
@ -81,15 +83,18 @@ state_tracker_t* state_tracker_init(const struct state_tracker_info *info)
|
||||
}
|
||||
#endif
|
||||
|
||||
tracker->info = (struct state_tracker_internal*)calloc(info->info_elem, sizeof(struct state_tracker_internal));
|
||||
tracker->info = (struct state_tracker_internal*)
|
||||
calloc(info->info_elem, sizeof(struct state_tracker_internal));
|
||||
tracker->info_elem = info->info_elem;
|
||||
|
||||
for (i = 0; i < info->info_elem; i++)
|
||||
{
|
||||
strlcpy(tracker->info[i].id, info->info[i].id, sizeof(tracker->info[i].id));
|
||||
strlcpy(tracker->info[i].id, info->info[i].id,
|
||||
sizeof(tracker->info[i].id));
|
||||
tracker->info[i].addr = info->info[i].addr;
|
||||
tracker->info[i].type = info->info[i].type;
|
||||
tracker->info[i].mask = (info->info[i].mask == 0) ? 0xffff : info->info[i].mask;
|
||||
tracker->info[i].mask = (info->info[i].mask == 0)
|
||||
? 0xffff : info->info[i].mask;
|
||||
tracker->info[i].equal = info->info[i].equal;
|
||||
|
||||
#ifdef HAVE_PYTHON
|
||||
@ -106,7 +111,7 @@ state_tracker_t* state_tracker_init(const struct state_tracker_info *info)
|
||||
}
|
||||
#endif
|
||||
|
||||
// If we don't have a valid pointer.
|
||||
/* If we don't have a valid pointer. */
|
||||
static const uint8_t empty = 0;
|
||||
|
||||
switch (info->info[i].ram_type)
|
||||
@ -217,7 +222,7 @@ static void update_element(
|
||||
}
|
||||
}
|
||||
|
||||
// Updates 16-bit input in same format as SNES itself.
|
||||
/* Updates 16-bit input in same format as SNES itself. */
|
||||
static void update_input(state_tracker_t *tracker)
|
||||
{
|
||||
unsigned i;
|
||||
@ -239,24 +244,30 @@ static void update_input(state_tracker_t *tracker)
|
||||
RETRO_DEVICE_ID_JOYPAD_B,
|
||||
};
|
||||
|
||||
// Only bind for up to two players for now.
|
||||
/* Only bind for up to two players for now. */
|
||||
static const struct retro_keybind *binds[2] = {
|
||||
g_settings.input.binds[0],
|
||||
g_settings.input.binds[1],
|
||||
};
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
input_push_analog_dpad(g_settings.input.binds[i], g_settings.input.analog_dpad_mode[i]);
|
||||
input_push_analog_dpad(g_settings.input.binds[i],
|
||||
g_settings.input.analog_dpad_mode[i]);
|
||||
for (i = 0; i < MAX_PLAYERS; i++)
|
||||
input_push_analog_dpad(g_settings.input.autoconf_binds[i], g_settings.input.analog_dpad_mode[i]);
|
||||
input_push_analog_dpad(g_settings.input.autoconf_binds[i],
|
||||
g_settings.input.analog_dpad_mode[i]);
|
||||
|
||||
uint16_t state[2] = {0};
|
||||
if (!driver.block_libretro_input)
|
||||
{
|
||||
for (i = 4; i < 16; i++)
|
||||
{
|
||||
state[0] |= (driver.input->input_state(driver.input_data, binds, 0, RETRO_DEVICE_JOYPAD, 0, buttons[i - 4]) ? 1 : 0) << i;
|
||||
state[1] |= (driver.input->input_state(driver.input_data, binds, 1, RETRO_DEVICE_JOYPAD, 0, buttons[i - 4]) ? 1 : 0) << i;
|
||||
state[0] |= (driver.input->input_state(
|
||||
driver.input_data, binds, 0,
|
||||
RETRO_DEVICE_JOYPAD, 0, buttons[i - 4]) ? 1 : 0) << i;
|
||||
state[1] |= (driver.input->input_state(
|
||||
driver.input_data, binds, 1,
|
||||
RETRO_DEVICE_JOYPAD, 0, buttons[i - 4]) ? 1 : 0) << i;
|
||||
}
|
||||
}
|
||||
|
||||
@ -269,7 +280,9 @@ static void update_input(state_tracker_t *tracker)
|
||||
tracker->input_state[i] = state[i];
|
||||
}
|
||||
|
||||
unsigned state_get_uniform(state_tracker_t *tracker, struct state_tracker_uniform *uniforms, unsigned elem, unsigned frame_count)
|
||||
unsigned state_get_uniform(state_tracker_t *tracker,
|
||||
struct state_tracker_uniform *uniforms,
|
||||
unsigned elem, unsigned frame_count)
|
||||
{
|
||||
unsigned i, elems;
|
||||
elems = tracker->info_elem < elem ? tracker->info_elem : elem;
|
||||
|
@ -78,9 +78,12 @@ struct state_tracker_uniform
|
||||
typedef struct state_tracker state_tracker_t;
|
||||
|
||||
state_tracker_t* state_tracker_init(const struct state_tracker_info *info);
|
||||
|
||||
void state_tracker_free(state_tracker_t *tracker);
|
||||
|
||||
unsigned state_get_uniform(state_tracker_t *tracker, struct state_tracker_uniform *uniforms, unsigned elem, unsigned frame_count);
|
||||
unsigned state_get_uniform(state_tracker_t *tracker,
|
||||
struct state_tracker_uniform *uniforms,
|
||||
unsigned elem, unsigned frame_count);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ enum thread_cmd
|
||||
CMD_INIT,
|
||||
CMD_SET_SHADER,
|
||||
CMD_FREE,
|
||||
CMD_ALIVE, // Blocking alive check. Used when paused.
|
||||
CMD_ALIVE, /* Blocking alive check. Used when paused. */
|
||||
CMD_SET_ROTATION,
|
||||
CMD_READ_VIEWPORT,
|
||||
|
||||
@ -133,7 +133,7 @@ typedef struct thread_video
|
||||
} cmd_data;
|
||||
|
||||
struct rarch_viewport vp;
|
||||
struct rarch_viewport read_vp; // Last viewport reported to caller.
|
||||
struct rarch_viewport read_vp; /* Last viewport reported to caller. */
|
||||
|
||||
struct
|
||||
{
|
||||
@ -151,7 +151,8 @@ typedef struct thread_video
|
||||
|
||||
} thread_video_t;
|
||||
|
||||
static void *thread_init_never_call(const video_info_t *video, const input_driver_t **input, void **input_data)
|
||||
static void *thread_init_never_call(const video_info_t *video,
|
||||
const input_driver_t **input, void **input_data)
|
||||
{
|
||||
(void)video;
|
||||
(void)input;
|
||||
@ -184,7 +185,8 @@ static void thread_update_driver_state(thread_video_t *thr)
|
||||
}
|
||||
|
||||
if (thr->poke && thr->poke->set_texture_enable)
|
||||
thr->poke->set_texture_enable(thr->driver_data, thr->texture.enable, thr->texture.full_screen);
|
||||
thr->poke->set_texture_enable(thr->driver_data,
|
||||
thr->texture.enable, thr->texture.full_screen);
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_OVERLAY)
|
||||
@ -225,13 +227,18 @@ static void thread_loop(void *data)
|
||||
scond_wait(thr->cond_thread, thr->lock);
|
||||
if (thr->frame.updated)
|
||||
updated = true;
|
||||
enum thread_cmd send_cmd = thr->send_cmd; // To avoid race condition where send_cmd is updated right after the switch is checked.
|
||||
|
||||
/* To avoid race condition where send_cmd is updated
|
||||
* right after the switch is checked. */
|
||||
|
||||
enum thread_cmd send_cmd = thr->send_cmd;
|
||||
slock_unlock(thr->lock);
|
||||
|
||||
switch (send_cmd)
|
||||
{
|
||||
case CMD_INIT:
|
||||
thr->driver_data = thr->driver->init(&thr->info, thr->input, thr->input_data);
|
||||
thr->driver_data = thr->driver->init(&thr->info,
|
||||
thr->input, thr->input_data);
|
||||
thr->cmd_data.b = thr->driver_data;
|
||||
thr->driver->viewport_info(thr->driver_data, &thr->vp);
|
||||
thread_reply(thr, CMD_INIT);
|
||||
@ -257,22 +264,34 @@ static void thread_loop(void *data)
|
||||
{
|
||||
struct rarch_viewport vp = {0};
|
||||
thr->driver->viewport_info(thr->driver_data, &vp);
|
||||
if (memcmp(&vp, &thr->read_vp, sizeof(vp)) == 0) // We can read safely
|
||||
if (memcmp(&vp, &thr->read_vp, sizeof(vp)) == 0)
|
||||
{
|
||||
// read_viewport() in GL driver calls rarch_render_cached_frame() to be able to read from back buffer.
|
||||
// This means frame() callback in threaded wrapper will be called from this thread, causing a timeout, and no frame to be rendered.
|
||||
// To avoid this, set a flag so wrapper can see if it's called in this "special" way.
|
||||
/* We can read safely
|
||||
*
|
||||
* read_viewport() in GL driver calls
|
||||
* rarch_render_cached_frame() to be able to read from
|
||||
* back buffer.
|
||||
*
|
||||
* This means frame() callback in threaded wrapper will
|
||||
* be called from this thread, causing a timeout, and
|
||||
* no frame to be rendered.
|
||||
*
|
||||
* To avoid this, set a flag so wrapper can see if
|
||||
* it's called in this "special" way. */
|
||||
thr->frame.within_thread = true;
|
||||
|
||||
if (thr->driver && thr->driver->read_viewport)
|
||||
ret = thr->driver->read_viewport(thr->driver_data, (uint8_t*)thr->cmd_data.v);
|
||||
ret = thr->driver->read_viewport(thr->driver_data,
|
||||
(uint8_t*)thr->cmd_data.v);
|
||||
|
||||
thr->cmd_data.b = ret;
|
||||
thr->frame.within_thread = false;
|
||||
thread_reply(thr, CMD_READ_VIEWPORT);
|
||||
}
|
||||
else // Viewport dimensions changed right after main thread read the async value. Cannot read safely.
|
||||
else
|
||||
{
|
||||
/* Viewport dimensions changed right after main
|
||||
* thread read the async value. Cannot read safely. */
|
||||
thr->cmd_data.b = false;
|
||||
thread_reply(thr, CMD_READ_VIEWPORT);
|
||||
}
|
||||
@ -313,9 +332,14 @@ static void thread_loop(void *data)
|
||||
|
||||
thr->cmd_data.b = ret;
|
||||
thr->alpha_mods = thr->cmd_data.image.num;
|
||||
thr->alpha_mod = (float*)realloc(thr->alpha_mod, thr->alpha_mods * sizeof(float));
|
||||
for (i = 0; i < thr->alpha_mods; i++) // Avoid temporary garbage data.
|
||||
thr->alpha_mod = (float*)realloc(thr->alpha_mod,
|
||||
thr->alpha_mods * sizeof(float));
|
||||
|
||||
for (i = 0; i < thr->alpha_mods; i++)
|
||||
{
|
||||
/* Avoid temporary garbage data. */
|
||||
thr->alpha_mod[i] = 1.0f;
|
||||
}
|
||||
thread_reply(thr, CMD_OVERLAY_LOAD);
|
||||
|
||||
break;
|
||||
@ -344,7 +368,8 @@ static void thread_loop(void *data)
|
||||
|
||||
case CMD_OVERLAY_FULL_SCREEN:
|
||||
if (thr->overlay && thr->overlay->full_screen)
|
||||
thr->overlay->full_screen(thr->driver_data, thr->cmd_data.b);
|
||||
thr->overlay->full_screen(thr->driver_data,
|
||||
thr->cmd_data.b);
|
||||
thread_reply(thr, CMD_OVERLAY_FULL_SCREEN);
|
||||
break;
|
||||
#endif
|
||||
@ -364,7 +389,8 @@ static void thread_loop(void *data)
|
||||
break;
|
||||
|
||||
case CMD_NONE:
|
||||
// Never reply on no command. Possible deadlock if thread sends command right after frame update.
|
||||
/* Never reply on no command. Possible deadlock if
|
||||
* thread sends command right after frame update. */
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -458,20 +484,23 @@ static bool thread_frame(void *data, const void *frame_,
|
||||
{
|
||||
thread_video_t *thr = (thread_video_t*)data;
|
||||
|
||||
// If called from within read_viewport, we're actually in the driver thread, so just render directly.
|
||||
/* If called from within read_viewport, we're actually in the
|
||||
* driver thread, so just render directly. */
|
||||
if (thr->frame.within_thread)
|
||||
{
|
||||
thread_update_driver_state(thr);
|
||||
|
||||
if (thr->driver && thr->driver->frame)
|
||||
return thr->driver->frame(thr->driver_data, frame_, width, height, pitch, msg);
|
||||
return thr->driver->frame(thr->driver_data, frame_,
|
||||
width, height, pitch, msg);
|
||||
return false;
|
||||
}
|
||||
|
||||
RARCH_PERFORMANCE_INIT(thread_frame);
|
||||
RARCH_PERFORMANCE_START(thread_frame);
|
||||
|
||||
unsigned copy_stride = width * (thr->info.rgb32 ? sizeof(uint32_t) : sizeof(uint16_t));
|
||||
unsigned copy_stride = width * (thr->info.rgb32 ?
|
||||
sizeof(uint32_t) : sizeof(uint16_t));
|
||||
|
||||
const uint8_t *src = (const uint8_t*)frame_;
|
||||
uint8_t *dst = thr->frame.buffer;
|
||||
@ -480,9 +509,11 @@ static bool thread_frame(void *data, const void *frame_,
|
||||
|
||||
if (!thr->nonblock)
|
||||
{
|
||||
retro_time_t target_frame_time = (retro_time_t)roundf(1000000LL / g_settings.video.refresh_rate);
|
||||
retro_time_t target_frame_time = (retro_time_t)
|
||||
roundf(1000000LL / g_settings.video.refresh_rate);
|
||||
retro_time_t target = thr->last_time + target_frame_time;
|
||||
// Ideally, use absolute time, but that is only a good idea on POSIX.
|
||||
|
||||
/* Ideally, use absolute time, but that is only a good idea on POSIX. */
|
||||
while (thr->frame.updated)
|
||||
{
|
||||
retro_time_t current = rarch_get_time_usec();
|
||||
@ -496,7 +527,8 @@ static bool thread_frame(void *data, const void *frame_,
|
||||
}
|
||||
}
|
||||
|
||||
// Drop frame if updated flag is still set, as thread is still working on last frame.
|
||||
/* Drop frame if updated flag is still set, as thread is
|
||||
* still working on last frame. */
|
||||
if (!thr->frame.updated)
|
||||
{
|
||||
if (src)
|
||||
@ -544,8 +576,8 @@ static void thread_set_nonblock_state(void *data, bool state)
|
||||
thr->nonblock = state;
|
||||
}
|
||||
|
||||
static bool thread_init(thread_video_t *thr, const video_info_t *info, const input_driver_t **input,
|
||||
void **input_data)
|
||||
static bool thread_init(thread_video_t *thr, const video_info_t *info,
|
||||
const input_driver_t **input, void **input_data)
|
||||
{
|
||||
thr->lock = slock_new();
|
||||
thr->alpha_lock = slock_new();
|
||||
@ -578,7 +610,8 @@ static bool thread_init(thread_video_t *thr, const video_info_t *info, const inp
|
||||
return thr->cmd_data.b;
|
||||
}
|
||||
|
||||
static bool thread_set_shader(void *data, enum rarch_shader_type type, const char *path)
|
||||
static bool thread_set_shader(void *data,
|
||||
enum rarch_shader_type type, const char *path)
|
||||
{
|
||||
thread_video_t *thr = (thread_video_t*)data;
|
||||
thr->cmd_data.set_shader.type = type;
|
||||
@ -596,15 +629,18 @@ static void thread_set_rotation(void *data, unsigned rotation)
|
||||
thread_wait_reply(thr, CMD_SET_ROTATION);
|
||||
}
|
||||
|
||||
// This value is set async as stalling on the video driver for every query is too slow.
|
||||
// This means this value might not be correct, so viewport reads are not supported for now.
|
||||
/* This value is set async as stalling on the video driver for
|
||||
* every query is too slow.
|
||||
*
|
||||
* This means this value might not be correct, so viewport
|
||||
* reads are not supported for now. */
|
||||
static void thread_viewport_info(void *data, struct rarch_viewport *vp)
|
||||
{
|
||||
thread_video_t *thr = (thread_video_t*)data;
|
||||
slock_lock(thr->lock);
|
||||
*vp = thr->vp;
|
||||
|
||||
// Explicitly mem-copied so we can use memcmp correctly later.
|
||||
/* Explicitly mem-copied so we can use memcmp correctly later. */
|
||||
memcpy(&thr->read_vp, &thr->vp, sizeof(thr->vp));
|
||||
slock_unlock(thr->lock);
|
||||
}
|
||||
@ -655,7 +691,8 @@ static void thread_overlay_enable(void *data, bool state)
|
||||
thread_wait_reply(thr, CMD_OVERLAY_ENABLE);
|
||||
}
|
||||
|
||||
static bool thread_overlay_load(void *data, const struct texture_image *images, unsigned num_images)
|
||||
static bool thread_overlay_load(void *data,
|
||||
const struct texture_image *images, unsigned num_images)
|
||||
{
|
||||
thread_video_t *thr = (thread_video_t*)data;
|
||||
thr->cmd_data.image.data = images;
|
||||
@ -665,7 +702,8 @@ static bool thread_overlay_load(void *data, const struct texture_image *images,
|
||||
return thr->cmd_data.b;
|
||||
}
|
||||
|
||||
static void thread_overlay_tex_geom(void *data, unsigned index, float x, float y, float w, float h)
|
||||
static void thread_overlay_tex_geom(void *data,
|
||||
unsigned index, float x, float y, float w, float h)
|
||||
{
|
||||
thread_video_t *thr = (thread_video_t*)data;
|
||||
thr->cmd_data.rect.index = index;
|
||||
@ -677,7 +715,8 @@ static void thread_overlay_tex_geom(void *data, unsigned index, float x, float y
|
||||
thread_wait_reply(thr, CMD_OVERLAY_TEX_GEOM);
|
||||
}
|
||||
|
||||
static void thread_overlay_vertex_geom(void *data, unsigned index, float x, float y, float w, float h)
|
||||
static void thread_overlay_vertex_geom(void *data,
|
||||
unsigned index, float x, float y, float w, float h)
|
||||
{
|
||||
thread_video_t *thr = (thread_video_t*)data;
|
||||
thr->cmd_data.rect.index = index;
|
||||
@ -697,7 +736,7 @@ static void thread_overlay_full_screen(void *data, bool enable)
|
||||
thread_wait_reply(thr, CMD_OVERLAY_FULL_SCREEN);
|
||||
}
|
||||
|
||||
// We cannot wait for this to complete. Totally blocks the main thread.
|
||||
/* We cannot wait for this to complete. Totally blocks the main thread. */
|
||||
static void thread_overlay_set_alpha(void *data, unsigned index, float mod)
|
||||
{
|
||||
thread_video_t *thr = (thread_video_t*)data;
|
||||
@ -716,7 +755,8 @@ static const video_overlay_interface_t thread_overlay = {
|
||||
thread_overlay_set_alpha,
|
||||
};
|
||||
|
||||
static void thread_get_overlay_interface(void *data, const video_overlay_interface_t **iface)
|
||||
static void thread_get_overlay_interface(void *data,
|
||||
const video_overlay_interface_t **iface)
|
||||
{
|
||||
thread_video_t *thr = (thread_video_t*)data;
|
||||
*iface = &thread_overlay;
|
||||
@ -748,7 +788,9 @@ static void thread_set_texture_frame(void *data, const void *frame,
|
||||
thread_video_t *thr = (thread_video_t*)data;
|
||||
|
||||
slock_lock(thr->frame.lock);
|
||||
size_t required = width * height * (rgb32 ? sizeof(uint32_t) : sizeof(uint16_t));
|
||||
size_t required = width * height *
|
||||
(rgb32 ? sizeof(uint32_t) : sizeof(uint16_t));
|
||||
|
||||
if (required > thr->texture.frame_cap)
|
||||
{
|
||||
thr->texture.frame = realloc(thr->texture.frame, required);
|
||||
@ -786,7 +828,8 @@ static void thread_apply_state_changes(void *data)
|
||||
slock_unlock(thr->frame.lock);
|
||||
}
|
||||
|
||||
// This is read-only state which should not have any kind of race condition.
|
||||
/* This is read-only state which should not
|
||||
* have any kind of race condition. */
|
||||
static struct gfx_shader *thread_get_current_shader(void *data)
|
||||
{
|
||||
thread_video_t *thr = (thread_video_t*)data;
|
||||
@ -813,7 +856,8 @@ static const video_poke_interface_t thread_poke = {
|
||||
thread_get_current_shader,
|
||||
};
|
||||
|
||||
static void thread_get_poke_interface(void *data, const video_poke_interface_t **iface)
|
||||
static void thread_get_poke_interface(void *data,
|
||||
const video_poke_interface_t **iface)
|
||||
{
|
||||
thread_video_t *thr = (thread_video_t*)data;
|
||||
|
||||
@ -827,7 +871,7 @@ static void thread_get_poke_interface(void *data, const video_poke_interface_t *
|
||||
}
|
||||
|
||||
static const video_driver_t video_thread = {
|
||||
thread_init_never_call, // Should never be called directly.
|
||||
thread_init_never_call, /* Should never be called directly. */
|
||||
thread_frame,
|
||||
thread_set_nonblock_state,
|
||||
thread_alive,
|
||||
@ -839,15 +883,17 @@ static const video_driver_t video_thread = {
|
||||
thread_viewport_info,
|
||||
thread_read_viewport,
|
||||
#ifdef HAVE_OVERLAY
|
||||
thread_get_overlay_interface, // get_overlay_interface
|
||||
thread_get_overlay_interface, /* get_overlay_interface */
|
||||
#endif
|
||||
thread_get_poke_interface,
|
||||
};
|
||||
|
||||
static void thread_set_callbacks(thread_video_t *thr, const video_driver_t *driver)
|
||||
static void thread_set_callbacks(thread_video_t *thr,
|
||||
const video_driver_t *driver)
|
||||
{
|
||||
thr->video_thread = video_thread;
|
||||
// Disable optional features if not present.
|
||||
|
||||
/* Disable optional features if not present. */
|
||||
if (!driver->read_viewport)
|
||||
thr->video_thread.read_viewport = NULL;
|
||||
if (!driver->set_rotation)
|
||||
@ -859,13 +905,13 @@ static void thread_set_callbacks(thread_video_t *thr, const video_driver_t *driv
|
||||
thr->video_thread.overlay_interface = NULL;
|
||||
#endif
|
||||
|
||||
// Might have to optionally disable poke_interface features as well.
|
||||
/* Might have to optionally disable poke_interface features as well. */
|
||||
if (!thr->video_thread.poke_interface)
|
||||
thr->video_thread.poke_interface = NULL;
|
||||
}
|
||||
|
||||
bool rarch_threaded_video_init(const video_driver_t **out_driver, void **out_data,
|
||||
const input_driver_t **input, void **input_data,
|
||||
bool rarch_threaded_video_init(const video_driver_t **out_driver,
|
||||
void **out_data, const input_driver_t **input, void **input_data,
|
||||
const video_driver_t *driver, const video_info_t *info)
|
||||
{
|
||||
thread_video_t *thr = (thread_video_t*)calloc(1, sizeof(*thr));
|
||||
|
@ -35,7 +35,8 @@ static void *android_location_init(void)
|
||||
jclass class;
|
||||
|
||||
struct android_app *android_app = (struct android_app*)g_android;
|
||||
androidlocation_t *androidlocation = (androidlocation_t*)calloc(1, sizeof(androidlocation_t));
|
||||
androidlocation_t *androidlocation = (androidlocation_t*)
|
||||
calloc(1, sizeof(androidlocation_t));
|
||||
if (!androidlocation)
|
||||
return NULL;
|
||||
|
||||
@ -47,43 +48,53 @@ static void *android_location_init(void)
|
||||
if (class == NULL)
|
||||
goto dealloc;
|
||||
|
||||
GET_METHOD_ID(env, androidlocation->onLocationInit, class, "onLocationInit", "()V");
|
||||
GET_METHOD_ID(env, androidlocation->onLocationInit, class,
|
||||
"onLocationInit", "()V");
|
||||
if (!androidlocation->onLocationInit)
|
||||
goto dealloc;
|
||||
|
||||
GET_METHOD_ID(env, androidlocation->onLocationFree, class, "onLocationFree", "()V");
|
||||
GET_METHOD_ID(env, androidlocation->onLocationFree, class,
|
||||
"onLocationFree", "()V");
|
||||
if (!androidlocation->onLocationFree)
|
||||
goto dealloc;
|
||||
|
||||
GET_METHOD_ID(env, androidlocation->onLocationStart, class, "onLocationStart", "()V");
|
||||
GET_METHOD_ID(env, androidlocation->onLocationStart, class,
|
||||
"onLocationStart", "()V");
|
||||
if (!androidlocation->onLocationStart)
|
||||
goto dealloc;
|
||||
|
||||
GET_METHOD_ID(env, androidlocation->onLocationStop, class, "onLocationStop", "()V");
|
||||
GET_METHOD_ID(env, androidlocation->onLocationStop, class,
|
||||
"onLocationStop", "()V");
|
||||
if (!androidlocation->onLocationStop)
|
||||
goto dealloc;
|
||||
|
||||
GET_METHOD_ID(env, androidlocation->onLocationGetLatitude, class, "onLocationGetLatitude", "()D");
|
||||
GET_METHOD_ID(env, androidlocation->onLocationGetLatitude, class,
|
||||
"onLocationGetLatitude", "()D");
|
||||
if (!androidlocation->onLocationGetLatitude)
|
||||
goto dealloc;
|
||||
|
||||
GET_METHOD_ID(env, androidlocation->onLocationGetLongitude, class, "onLocationGetLongitude", "()D");
|
||||
GET_METHOD_ID(env, androidlocation->onLocationGetLongitude, class,
|
||||
"onLocationGetLongitude", "()D");
|
||||
if (!androidlocation->onLocationGetLongitude)
|
||||
goto dealloc;
|
||||
|
||||
GET_METHOD_ID(env, androidlocation->onLocationGetHorizontalAccuracy, class, "onLocationGetHorizontalAccuracy", "()D");
|
||||
GET_METHOD_ID(env, androidlocation->onLocationGetHorizontalAccuracy,
|
||||
class, "onLocationGetHorizontalAccuracy", "()D");
|
||||
if (!androidlocation->onLocationGetHorizontalAccuracy)
|
||||
goto dealloc;
|
||||
|
||||
GET_METHOD_ID(env, androidlocation->onLocationSetInterval, class, "onLocationSetInterval", "(II)V");
|
||||
GET_METHOD_ID(env, androidlocation->onLocationSetInterval,
|
||||
class, "onLocationSetInterval", "(II)V");
|
||||
if (!androidlocation->onLocationSetInterval)
|
||||
goto dealloc;
|
||||
|
||||
GET_METHOD_ID(env, androidlocation->onLocationHasChanged, class, "onLocationHasChanged", "()Z");
|
||||
GET_METHOD_ID(env, androidlocation->onLocationHasChanged,
|
||||
class, "onLocationHasChanged", "()Z");
|
||||
if (!androidlocation->onLocationHasChanged)
|
||||
goto dealloc;
|
||||
|
||||
CALL_VOID_METHOD(env, android_app->activity->clazz, androidlocation->onLocationInit);
|
||||
CALL_VOID_METHOD(env, android_app->activity->clazz,
|
||||
androidlocation->onLocationInit);
|
||||
|
||||
return androidlocation;
|
||||
dealloc:
|
||||
@ -99,7 +110,8 @@ static void android_location_free(void *data)
|
||||
if (!env)
|
||||
return;
|
||||
|
||||
CALL_VOID_METHOD(env, android_app->activity->clazz, androidlocation->onLocationFree);
|
||||
CALL_VOID_METHOD(env, android_app->activity->clazz,
|
||||
androidlocation->onLocationFree);
|
||||
|
||||
free(androidlocation);
|
||||
}
|
||||
@ -112,7 +124,8 @@ static bool android_location_start(void *data)
|
||||
if (!env)
|
||||
return false;
|
||||
|
||||
CALL_VOID_METHOD(env, android_app->activity->clazz, androidlocation->onLocationStart);
|
||||
CALL_VOID_METHOD(env, android_app->activity->clazz,
|
||||
androidlocation->onLocationStart);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -125,10 +138,12 @@ static void android_location_stop(void *data)
|
||||
if (!env)
|
||||
return;
|
||||
|
||||
CALL_VOID_METHOD(env, android_app->activity->clazz, androidlocation->onLocationStop);
|
||||
CALL_VOID_METHOD(env, android_app->activity->clazz,
|
||||
androidlocation->onLocationStop);
|
||||
}
|
||||
|
||||
static bool android_location_get_position(void *data, double *latitude, double *longitude, double *horiz_accuracy,
|
||||
static bool android_location_get_position(void *data, double *latitude,
|
||||
double *longitude, double *horiz_accuracy,
|
||||
double *vert_accuracy)
|
||||
{
|
||||
struct android_app *android_app = (struct android_app*)g_android;
|
||||
@ -140,14 +155,18 @@ static bool android_location_get_position(void *data, double *latitude, double *
|
||||
jdouble lat, lon, horiz_accu;
|
||||
jboolean newLocation;
|
||||
|
||||
CALL_BOOLEAN_METHOD(env, newLocation, android_app->activity->clazz, androidlocation->onLocationHasChanged);
|
||||
CALL_BOOLEAN_METHOD(env, newLocation, android_app->activity->clazz,
|
||||
androidlocation->onLocationHasChanged);
|
||||
|
||||
if (!newLocation)
|
||||
goto fail;
|
||||
|
||||
CALL_DOUBLE_METHOD(env, lat, android_app->activity->clazz, androidlocation->onLocationGetLatitude);
|
||||
CALL_DOUBLE_METHOD(env, lon, android_app->activity->clazz, androidlocation->onLocationGetLongitude);
|
||||
CALL_DOUBLE_METHOD(env, horiz_accu, android_app->activity->clazz, androidlocation->onLocationGetHorizontalAccuracy);
|
||||
CALL_DOUBLE_METHOD(env, lat, android_app->activity->clazz,
|
||||
androidlocation->onLocationGetLatitude);
|
||||
CALL_DOUBLE_METHOD(env, lon, android_app->activity->clazz,
|
||||
androidlocation->onLocationGetLongitude);
|
||||
CALL_DOUBLE_METHOD(env, horiz_accu, android_app->activity->clazz,
|
||||
androidlocation->onLocationGetHorizontalAccuracy);
|
||||
|
||||
if (lat != 0.0)
|
||||
*latitude = lat;
|
||||
@ -156,7 +175,8 @@ static bool android_location_get_position(void *data, double *latitude, double *
|
||||
if (horiz_accu != 0.0)
|
||||
*horiz_accuracy = horiz_accu;
|
||||
|
||||
/* TODO/FIXME - custom implement vertical accuracy since Android location API does not have it? */
|
||||
/* TODO/FIXME - custom implement vertical accuracy since
|
||||
* Android location API does not have it? */
|
||||
*vert_accuracy = 0.0;
|
||||
|
||||
return true;
|
||||
@ -169,7 +189,8 @@ fail:
|
||||
return false;
|
||||
}
|
||||
|
||||
static void android_location_set_interval(void *data, unsigned interval_ms, unsigned interval_distance)
|
||||
static void android_location_set_interval(void *data, unsigned interval_ms,
|
||||
unsigned interval_distance)
|
||||
{
|
||||
struct android_app *android_app = (struct android_app*)g_android;
|
||||
androidlocation_t *androidlocation = (androidlocation_t*)data;
|
||||
@ -177,7 +198,9 @@ static void android_location_set_interval(void *data, unsigned interval_ms, unsi
|
||||
if (!env)
|
||||
return;
|
||||
|
||||
CALL_VOID_METHOD_PARAM(env, android_app->activity->clazz, androidlocation->onLocationSetInterval, (int)interval_ms, (int)interval_distance);
|
||||
CALL_VOID_METHOD_PARAM(env, android_app->activity->clazz,
|
||||
androidlocation->onLocationSetInterval, (int)interval_ms,
|
||||
(int)interval_distance);
|
||||
}
|
||||
|
||||
const location_driver_t location_android = {
|
||||
|
@ -37,7 +37,8 @@ static void null_location_stop(void *data)
|
||||
(void)data;
|
||||
}
|
||||
|
||||
static bool null_location_get_position(void *data, double *latitude, double *longitude, double *horiz_accuracy,
|
||||
static bool null_location_get_position(void *data, double *latitude,
|
||||
double *longitude, double *horiz_accuracy,
|
||||
double *vert_accuracy)
|
||||
{
|
||||
*latitude = 0.0;
|
||||
@ -47,7 +48,8 @@ static bool null_location_get_position(void *data, double *latitude, double *lon
|
||||
return true;
|
||||
}
|
||||
|
||||
static void null_location_set_interval(void *data, unsigned interval_ms, unsigned interval_distance)
|
||||
static void null_location_set_interval(void *data,
|
||||
unsigned interval_ms, unsigned interval_distance)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -74,15 +74,15 @@ struct ff_video_info
|
||||
uint8_t *outbuf;
|
||||
size_t outbuf_size;
|
||||
|
||||
// Output pixel format.
|
||||
/* Output pixel format. */
|
||||
enum PixelFormat pix_fmt;
|
||||
// Input pixel format. Only used by sws.
|
||||
/* Input pixel format. Only used by sws. */
|
||||
enum PixelFormat in_pix_fmt;
|
||||
|
||||
unsigned frame_drop_ratio;
|
||||
unsigned frame_drop_count;
|
||||
|
||||
// Input pixel size.
|
||||
/* Input pixel size. */
|
||||
size_t pix_size;
|
||||
|
||||
AVFormatContext *format;
|
||||
@ -380,9 +380,11 @@ static bool ffmpeg_init_video(ffmpeg_t *handle)
|
||||
|
||||
video->encoder = codec;
|
||||
|
||||
/* Don't use swscaler unless format is not something "in-house" scaler supports.
|
||||
* libswscale doesn't scale RGB -> RGB correctly (goes via YUV first), and it's non-trivial to fix
|
||||
* upstream as it's heavily geared towards YUV.
|
||||
/* Don't use swscaler unless format is not something "in-house" scaler
|
||||
* supports.
|
||||
*
|
||||
* libswscale doesn't scale RGB -> RGB correctly (goes via YUV first),
|
||||
* and it's non-trivial to fix upstream as it's heavily geared towards YUV.
|
||||
* If we're dealing with strange formats or YUV, just use libswscale.
|
||||
*/
|
||||
if (params->out_pix_fmt != PIX_FMT_NONE)
|
||||
@ -446,8 +448,10 @@ static bool ffmpeg_init_video(ffmpeg_t *handle)
|
||||
video->codec->codec_type = AVMEDIA_TYPE_VIDEO;
|
||||
video->codec->width = param->out_width;
|
||||
video->codec->height = param->out_height;
|
||||
video->codec->time_base = av_d2q((double)params->frame_drop_ratio /param->fps, 1000000); /* Arbitrary big number. */
|
||||
video->codec->sample_aspect_ratio = av_d2q(param->aspect_ratio * param->out_height / param->out_width, 255);
|
||||
video->codec->time_base = av_d2q((double)
|
||||
params->frame_drop_ratio /param->fps, 1000000); /* Arbitrary big number. */
|
||||
video->codec->sample_aspect_ratio = av_d2q(
|
||||
param->aspect_ratio * param->out_height / param->out_width, 255);
|
||||
video->codec->pix_fmt = video->pix_fmt;
|
||||
|
||||
video->codec->thread_count = params->threads;
|
||||
@ -468,8 +472,7 @@ static bool ffmpeg_init_video(ffmpeg_t *handle)
|
||||
return false;
|
||||
|
||||
/* Allocate a big buffer. ffmpeg API doesn't seem to give us some
|
||||
* clues how big this buffer should be.
|
||||
*/
|
||||
* clues how big this buffer should be. */
|
||||
video->outbuf_size = 1 << 23;
|
||||
video->outbuf = (uint8_t*)av_malloc(video->outbuf_size);
|
||||
|
||||
@ -769,7 +772,8 @@ static bool ffmpeg_push_video(void *data,
|
||||
if (!handle || !video_data)
|
||||
return false;
|
||||
|
||||
drop_frame = handle->video.frame_drop_count++ % handle->video.frame_drop_ratio;
|
||||
drop_frame = handle->video.frame_drop_count++ %
|
||||
handle->video.frame_drop_ratio;
|
||||
|
||||
handle->video.frame_drop_count %= handle->video.frame_drop_ratio;
|
||||
|
||||
@ -940,7 +944,8 @@ static void ffmpeg_scale_input(ffmpeg_t *handle,
|
||||
|
||||
handle->video.scaler.out_width = handle->params.out_width;
|
||||
handle->video.scaler.out_height = handle->params.out_height;
|
||||
handle->video.scaler.out_stride = handle->video.conv_frame->linesize[0];
|
||||
handle->video.scaler.out_stride =
|
||||
handle->video.conv_frame->linesize[0];
|
||||
|
||||
scaler_ctx_gen_filter(&handle->video.scaler);
|
||||
}
|
||||
@ -1010,10 +1015,12 @@ static void planarize_audio(ffmpeg_t *handle)
|
||||
|
||||
if (handle->audio.use_float)
|
||||
planarize_float((float*)handle->audio.planar_buf,
|
||||
(const float*)handle->audio.buffer, handle->audio.frames_in_buffer);
|
||||
(const float*)handle->audio.buffer,
|
||||
handle->audio.frames_in_buffer);
|
||||
else
|
||||
planarize_s16((int16_t*)handle->audio.planar_buf,
|
||||
(const int16_t*)handle->audio.buffer, handle->audio.frames_in_buffer);
|
||||
(const int16_t*)handle->audio.buffer,
|
||||
handle->audio.frames_in_buffer);
|
||||
}
|
||||
|
||||
static bool encode_audio(ffmpeg_t *handle, AVPacket *pkt, bool dry)
|
||||
@ -1152,13 +1159,17 @@ static bool ffmpeg_push_audio_thread(ffmpeg_t *handle,
|
||||
size_t written_frames = 0;
|
||||
while (written_frames < data->frames)
|
||||
{
|
||||
size_t can_write = handle->audio.codec->frame_size - handle->audio.frames_in_buffer;
|
||||
size_t can_write = handle->audio.codec->frame_size -
|
||||
handle->audio.frames_in_buffer;
|
||||
size_t write_left = data->frames - written_frames;
|
||||
size_t write_frames = write_left > can_write ? can_write : write_left;
|
||||
size_t write_size = write_frames * handle->params.channels * handle->audio.sample_size;
|
||||
size_t write_size = write_frames *
|
||||
handle->params.channels * handle->audio.sample_size;
|
||||
|
||||
size_t bytes_in_buffer = handle->audio.frames_in_buffer * handle->params.channels * handle->audio.sample_size;
|
||||
size_t written_bytes = written_frames * handle->params.channels * handle->audio.sample_size;
|
||||
size_t bytes_in_buffer = handle->audio.frames_in_buffer *
|
||||
handle->params.channels * handle->audio.sample_size;
|
||||
size_t written_bytes = written_frames *
|
||||
handle->params.channels * handle->audio.sample_size;
|
||||
|
||||
memcpy(handle->audio.buffer + bytes_in_buffer,
|
||||
(const uint8_t*)data->data + written_bytes,
|
||||
@ -1167,7 +1178,8 @@ static bool ffmpeg_push_audio_thread(ffmpeg_t *handle,
|
||||
written_frames += write_frames;
|
||||
handle->audio.frames_in_buffer += write_frames;
|
||||
|
||||
if ((handle->audio.frames_in_buffer < (size_t)handle->audio.codec->frame_size) && require_block)
|
||||
if ((handle->audio.frames_in_buffer
|
||||
< (size_t)handle->audio.codec->frame_size) && require_block)
|
||||
break;
|
||||
|
||||
AVPacket pkt;
|
||||
@ -1224,12 +1236,17 @@ static void ffmpeg_flush_video(ffmpeg_t *handle)
|
||||
|
||||
static void ffmpeg_flush_buffers(ffmpeg_t *handle)
|
||||
{
|
||||
void *video_buf = av_malloc(2 * handle->params.fb_width * handle->params.fb_height * handle->video.pix_size);
|
||||
size_t audio_buf_size = handle->config.audio_enable ? (handle->audio.codec->frame_size * handle->params.channels * sizeof(int16_t)) : 0;
|
||||
void *video_buf = av_malloc(2 * handle->params.fb_width *
|
||||
handle->params.fb_height * handle->video.pix_size);
|
||||
size_t audio_buf_size = handle->config.audio_enable ?
|
||||
(handle->audio.codec->frame_size *
|
||||
handle->params.channels * sizeof(int16_t)) : 0;
|
||||
void *audio_buf = audio_buf_size ? av_malloc(audio_buf_size) : NULL;
|
||||
|
||||
/* Try pushing data in an interleaving pattern to ease the work of the muxer a bit. */
|
||||
/* Try pushing data in an interleaving pattern to
|
||||
* ease the work of the muxer a bit. */
|
||||
bool did_work;
|
||||
|
||||
do
|
||||
{
|
||||
did_work = false;
|
||||
@ -1253,7 +1270,8 @@ static void ffmpeg_flush_buffers(ffmpeg_t *handle)
|
||||
if (fifo_read_avail(handle->attr_fifo) >= sizeof(attr_buf))
|
||||
{
|
||||
fifo_read(handle->attr_fifo, &attr_buf, sizeof(attr_buf));
|
||||
fifo_read(handle->video_fifo, video_buf, attr_buf.height * attr_buf.pitch);
|
||||
fifo_read(handle->video_fifo, video_buf,
|
||||
attr_buf.height * attr_buf.pitch);
|
||||
attr_buf.data = video_buf;
|
||||
ffmpeg_push_video_thread(handle, &attr_buf);
|
||||
|
||||
@ -1296,11 +1314,14 @@ static void ffmpeg_thread(void *data)
|
||||
{
|
||||
ffmpeg_t *ff = (ffmpeg_t*)data;
|
||||
|
||||
/* For some reason, FFmpeg has a tendency to crash if we don't overallocate a bit. */
|
||||
void *video_buf = av_malloc(2 * ff->params.fb_width * ff->params.fb_height * ff->video.pix_size);
|
||||
/* For some reason, FFmpeg has a tendency to crash
|
||||
* if we don't overallocate a bit. */
|
||||
void *video_buf = av_malloc(2 * ff->params.fb_width *
|
||||
ff->params.fb_height * ff->video.pix_size);
|
||||
assert(video_buf);
|
||||
|
||||
size_t audio_buf_size = ff->config.audio_enable ? (ff->audio.codec->frame_size * ff->params.channels * sizeof(int16_t)) : 0;
|
||||
size_t audio_buf_size = ff->config.audio_enable ?
|
||||
(ff->audio.codec->frame_size * ff->params.channels * sizeof(int16_t)) : 0;
|
||||
void *audio_buf = audio_buf_size ? av_malloc(audio_buf_size) : NULL;
|
||||
|
||||
while (ff->alive)
|
||||
@ -1338,7 +1359,8 @@ static void ffmpeg_thread(void *data)
|
||||
{
|
||||
slock_lock(ff->lock);
|
||||
fifo_read(ff->attr_fifo, &attr_buf, sizeof(attr_buf));
|
||||
fifo_read(ff->video_fifo, video_buf, attr_buf.height * attr_buf.pitch);
|
||||
fifo_read(ff->video_fifo, video_buf,
|
||||
attr_buf.height * attr_buf.pitch);
|
||||
slock_unlock(ff->lock);
|
||||
scond_signal(ff->cond);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user