2012-06-19 15:01:34 -04:00
|
|
|
/* RetroArch - A frontend for libretro.
|
2014-01-01 01:50:59 +01:00
|
|
|
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
|
2017-01-22 13:40:32 +01:00
|
|
|
* Copyright (C) 2011-2017 - Daniel De Matteis
|
2015-01-07 18:06:50 +01:00
|
|
|
* Copyright (C) 2012-2015 - Michael Lelli
|
2012-09-18 19:41:58 -04:00
|
|
|
*
|
2012-06-19 15:01:34 -04:00
|
|
|
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
|
|
|
* of the GNU General Public License as published by the Free Software Found-
|
|
|
|
* ation, either version 3 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
|
|
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
|
|
* PURPOSE. See the GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License along with RetroArch.
|
|
|
|
* If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <math.h>
|
2016-09-15 21:16:17 +02:00
|
|
|
#include <string.h>
|
2015-11-18 12:55:28 +01:00
|
|
|
|
2012-06-19 15:01:34 -04:00
|
|
|
#include <VG/openvg.h>
|
2012-10-18 18:59:56 -04:00
|
|
|
#include <VG/vgext.h>
|
2012-06-19 15:01:34 -04:00
|
|
|
#include <EGL/egl.h>
|
2012-10-18 18:59:56 -04:00
|
|
|
#include <EGL/eglext.h>
|
2015-11-18 12:55:28 +01:00
|
|
|
|
2015-03-15 04:37:54 +01:00
|
|
|
#include <retro_inline.h>
|
2016-02-12 15:27:48 +01:00
|
|
|
#include <retro_assert.h>
|
2015-11-18 12:55:28 +01:00
|
|
|
#include <gfx/math/matrix_3x3.h>
|
2016-05-10 19:03:53 +02:00
|
|
|
#include <libretro.h>
|
2015-11-18 12:55:28 +01:00
|
|
|
|
2016-09-11 14:46:53 +02:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
#include "../../config.h"
|
|
|
|
#endif
|
|
|
|
|
2017-01-18 22:20:47 +01:00
|
|
|
#ifdef HAVE_MENU
|
|
|
|
#include "../../menu/menu_driver.h"
|
|
|
|
#endif
|
|
|
|
|
2017-01-19 17:20:42 +01:00
|
|
|
#include "../font_driver.h"
|
|
|
|
|
2015-01-12 06:45:12 +01:00
|
|
|
#include "../../retroarch.h"
|
|
|
|
#include "../../driver.h"
|
|
|
|
#include "../../content.h"
|
2015-11-23 16:41:50 +01:00
|
|
|
#include "../../verbosity.h"
|
2016-09-06 21:54:53 +01:00
|
|
|
#include "../../configuration.h"
|
2012-06-19 15:01:34 -04:00
|
|
|
|
2012-06-22 19:16:53 +02:00
|
|
|
typedef struct
|
|
|
|
{
|
2012-09-29 20:18:24 +02:00
|
|
|
bool should_resize;
|
2015-11-11 03:28:40 +01:00
|
|
|
bool keep_aspect;
|
2012-10-18 18:59:56 -04:00
|
|
|
bool mEglImageBuf;
|
2020-03-07 18:05:50 +01:00
|
|
|
bool mFontsOn;
|
|
|
|
|
|
|
|
float mScreenAspect;
|
|
|
|
|
2012-06-19 15:01:34 -04:00
|
|
|
unsigned mTextureWidth;
|
|
|
|
unsigned mTextureHeight;
|
|
|
|
unsigned mRenderWidth;
|
|
|
|
unsigned mRenderHeight;
|
|
|
|
unsigned x1, y1, x2, y2;
|
2020-03-07 18:05:50 +01:00
|
|
|
uint32_t mFontHeight;
|
|
|
|
|
|
|
|
char *mLastMsg;
|
|
|
|
|
|
|
|
VGint scissor[4];
|
2012-06-19 15:01:34 -04:00
|
|
|
VGImageFormat mTexType;
|
|
|
|
VGImage mImage;
|
2012-09-24 19:30:24 -04:00
|
|
|
math_matrix_3x3 mTransformMatrix;
|
2012-10-18 18:59:56 -04:00
|
|
|
EGLImageKHR last_egl_image;
|
2012-06-19 15:01:34 -04:00
|
|
|
|
|
|
|
VGFont mFont;
|
2012-12-15 11:02:35 +01:00
|
|
|
void *mFontRenderer;
|
2012-12-14 14:41:18 -05:00
|
|
|
const font_renderer_driver_t *font_driver;
|
2012-06-19 15:01:34 -04:00
|
|
|
VGuint mMsgLength;
|
|
|
|
VGuint mGlyphIndices[1024];
|
|
|
|
VGPaint mPaintFg;
|
|
|
|
VGPaint mPaintBg;
|
2018-10-14 08:22:26 +02:00
|
|
|
void *ctx_data;
|
|
|
|
const gfx_ctx_driver_t *ctx_driver;
|
2012-09-24 15:19:07 -04:00
|
|
|
} vg_t;
|
2012-06-19 15:01:34 -04:00
|
|
|
|
2012-10-18 18:59:56 -04:00
|
|
|
static PFNVGCREATEEGLIMAGETARGETKHRPROC pvgCreateEGLImageTargetKHR;
|
|
|
|
|
2020-02-16 22:26:07 +01:00
|
|
|
static void vg_set_nonblock_state(void *data, bool state,
|
|
|
|
bool adaptive_vsync_enabled, unsigned swap_interval)
|
2012-06-19 15:01:34 -04:00
|
|
|
{
|
2019-08-28 21:12:51 +02:00
|
|
|
vg_t *vg = (vg_t*)data;
|
2018-09-12 00:07:43 +02:00
|
|
|
int interval = state ? 0 : 1;
|
2019-08-28 21:12:51 +02:00
|
|
|
|
|
|
|
if (vg->ctx_driver && vg->ctx_driver->swap_interval)
|
|
|
|
{
|
|
|
|
if (adaptive_vsync_enabled && interval == 1)
|
|
|
|
interval = -1;
|
|
|
|
vg->ctx_driver->swap_interval(vg->ctx_data, interval);
|
|
|
|
}
|
2012-06-19 15:01:34 -04:00
|
|
|
}
|
|
|
|
|
2015-03-15 04:37:54 +01:00
|
|
|
static INLINE bool vg_query_extension(const char *ext)
|
2012-10-18 18:59:56 -04:00
|
|
|
{
|
|
|
|
const char *str = (const char*)vgGetString(VG_EXTENSIONS);
|
|
|
|
bool ret = str && strstr(str, ext);
|
2017-03-24 00:28:21 +01:00
|
|
|
RARCH_LOG("[VG]: Querying VG extension: %s => %s\n",
|
2012-10-18 18:59:56 -04:00
|
|
|
ext, ret ? "exists" : "doesn't exist");
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2017-04-24 12:25:14 +02:00
|
|
|
static void *vg_init(const video_info_t *video,
|
2019-07-27 02:21:24 +02:00
|
|
|
input_driver_t **input, void **input_data)
|
2012-06-19 15:01:34 -04:00
|
|
|
{
|
2016-10-04 12:15:46 -04:00
|
|
|
unsigned win_width, win_height;
|
2018-09-12 00:07:43 +02:00
|
|
|
VGfloat clearColor[4] = {0, 0, 0, 1};
|
|
|
|
int interval = 0;
|
2020-07-27 14:33:21 +02:00
|
|
|
unsigned mode_width = 0;
|
|
|
|
unsigned mode_height = 0;
|
2018-09-12 00:07:43 +02:00
|
|
|
unsigned temp_width = 0;
|
|
|
|
unsigned temp_height = 0;
|
2018-10-14 08:13:05 +02:00
|
|
|
void *ctx_data = NULL;
|
2018-09-12 00:07:43 +02:00
|
|
|
settings_t *settings = config_get_ptr();
|
2020-02-18 14:51:40 +01:00
|
|
|
const char *path_font = settings->paths.path_font;
|
|
|
|
float video_font_size = settings->floats.video_font_size;
|
|
|
|
float video_msg_color_r = settings->floats.video_msg_color_r;
|
|
|
|
float video_msg_color_g = settings->floats.video_msg_color_g;
|
|
|
|
float video_msg_color_b = settings->floats.video_msg_color_b;
|
2018-09-12 00:07:43 +02:00
|
|
|
vg_t *vg = (vg_t*)calloc(1, sizeof(vg_t));
|
|
|
|
const gfx_ctx_driver_t *ctx = video_context_driver_init_first(
|
2017-04-28 22:59:13 +02:00
|
|
|
vg, settings->arrays.video_context_driver,
|
2018-10-14 08:13:05 +02:00
|
|
|
GFX_CTX_OPENVG_API, 0, 0, false, &ctx_data);
|
2020-03-20 09:19:06 +01:00
|
|
|
bool adaptive_vsync_enabled = video_driver_test_all_flags(
|
|
|
|
GFX_CTX_FLAGS_ADAPTIVE_VSYNC) && video->adaptive_vsync;
|
2012-06-19 15:01:34 -04:00
|
|
|
|
2016-02-13 16:33:38 +01:00
|
|
|
if (!vg || !ctx)
|
2015-04-09 18:46:24 +02:00
|
|
|
goto error;
|
|
|
|
|
2018-10-14 08:13:05 +02:00
|
|
|
if (ctx_data)
|
|
|
|
vg->ctx_data = ctx_data;
|
|
|
|
|
2018-10-14 08:22:26 +02:00
|
|
|
vg->ctx_driver = ctx;
|
2016-05-08 20:32:46 +02:00
|
|
|
video_context_driver_set((void*)ctx);
|
2012-06-19 15:01:34 -04:00
|
|
|
|
2020-07-27 14:33:21 +02:00
|
|
|
if (vg->ctx_driver->get_video_size)
|
|
|
|
vg->ctx_driver->get_video_size(vg->ctx_data,
|
|
|
|
&mode_width, &mode_height);
|
2016-02-14 02:26:20 +01:00
|
|
|
|
2020-07-27 14:33:21 +02:00
|
|
|
temp_width = mode_width;
|
|
|
|
temp_height = mode_height;
|
2016-02-14 02:26:20 +01:00
|
|
|
|
2017-03-24 00:28:21 +01:00
|
|
|
RARCH_LOG("[VG]: Detecting screen resolution %ux%u.\n", temp_width, temp_height);
|
2015-05-20 02:40:44 +02:00
|
|
|
|
|
|
|
if (temp_width != 0 && temp_height != 0)
|
2020-01-31 03:47:50 +01:00
|
|
|
video_driver_set_size(temp_width, temp_height);
|
2012-06-19 15:01:34 -04:00
|
|
|
|
2016-02-13 20:45:45 +01:00
|
|
|
interval = video->vsync ? 1 : 0;
|
2015-04-10 08:26:43 +02:00
|
|
|
|
2019-08-28 21:12:51 +02:00
|
|
|
if (ctx->swap_interval)
|
|
|
|
{
|
|
|
|
if (adaptive_vsync_enabled && interval == 1)
|
|
|
|
interval = -1;
|
|
|
|
ctx->swap_interval(vg->ctx_data, interval);
|
|
|
|
}
|
2012-06-19 15:01:34 -04:00
|
|
|
|
2015-11-11 03:28:40 +01:00
|
|
|
vg->mTexType = video->rgb32 ? VG_sXRGB_8888 : VG_sRGB_565;
|
|
|
|
vg->keep_aspect = video->force_aspect;
|
2012-06-19 15:01:34 -04:00
|
|
|
|
2016-10-04 12:15:46 -04:00
|
|
|
win_width = video->width;
|
|
|
|
win_height = video->height;
|
|
|
|
|
2012-09-24 20:47:48 -04:00
|
|
|
if (video->fullscreen && (win_width == 0) && (win_height == 0))
|
|
|
|
{
|
2015-05-20 02:40:44 +02:00
|
|
|
video_driver_get_size(&temp_width, &temp_height);
|
|
|
|
|
|
|
|
win_width = temp_width;
|
|
|
|
win_height = temp_height;
|
2012-09-24 20:47:48 -04:00
|
|
|
}
|
|
|
|
|
2020-07-27 11:08:34 +02:00
|
|
|
if ( !vg->ctx_driver->set_video_mode
|
|
|
|
|| !vg->ctx_driver->set_video_mode(vg->ctx_data,
|
|
|
|
win_width, win_height, video->fullscreen))
|
2015-04-09 18:46:24 +02:00
|
|
|
goto error;
|
2012-09-24 20:47:48 -04:00
|
|
|
|
2015-05-20 02:40:44 +02:00
|
|
|
video_driver_get_size(&temp_width, &temp_height);
|
|
|
|
|
2020-02-18 14:51:40 +01:00
|
|
|
temp_width = 0;
|
|
|
|
temp_height = 0;
|
2020-07-27 14:33:21 +02:00
|
|
|
mode_width = 0;
|
|
|
|
mode_height = 0;
|
2016-02-14 02:26:20 +01:00
|
|
|
|
2020-07-27 14:33:21 +02:00
|
|
|
if (vg->ctx_driver->get_video_size)
|
|
|
|
vg->ctx_driver->get_video_size(vg->ctx_data,
|
|
|
|
&mode_width, &mode_height);
|
2016-02-14 02:26:20 +01:00
|
|
|
|
2020-07-27 14:33:21 +02:00
|
|
|
temp_width = mode_width;
|
|
|
|
temp_height = mode_height;
|
2016-02-14 02:26:20 +01:00
|
|
|
|
2012-09-29 20:18:24 +02:00
|
|
|
vg->should_resize = true;
|
2012-09-24 20:47:48 -04:00
|
|
|
|
2015-05-20 02:40:44 +02:00
|
|
|
if (temp_width != 0 && temp_height != 0)
|
|
|
|
{
|
2020-02-18 14:51:40 +01:00
|
|
|
RARCH_LOG("[VG]: Verified window resolution %ux%u.\n",
|
|
|
|
temp_width, temp_height);
|
2020-01-31 03:47:50 +01:00
|
|
|
video_driver_set_size(temp_width, temp_height);
|
2015-05-20 02:40:44 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
video_driver_get_size(&temp_width, &temp_height);
|
|
|
|
|
|
|
|
vg->mScreenAspect = (float)temp_width / temp_height;
|
2015-04-10 06:52:51 +02:00
|
|
|
|
2020-07-27 08:15:35 +02:00
|
|
|
if (vg->ctx_driver->translate_aspect)
|
|
|
|
vg->mScreenAspect = vg->ctx_driver->translate_aspect(
|
|
|
|
vg->ctx_data, temp_width, temp_height);
|
2012-06-19 15:01:34 -04:00
|
|
|
|
|
|
|
vgSetfv(VG_CLEAR_COLOR, 4, clearColor);
|
|
|
|
|
2012-09-24 15:19:07 -04:00
|
|
|
vg->mTextureWidth = vg->mTextureHeight = video->input_scale * RARCH_SCALE_BASE;
|
2020-02-18 14:51:40 +01:00
|
|
|
vg->mImage = vgCreateImage(
|
|
|
|
vg->mTexType,
|
|
|
|
vg->mTextureWidth,
|
|
|
|
vg->mTextureHeight,
|
2020-03-20 09:19:06 +01:00
|
|
|
video->smooth
|
|
|
|
? VG_IMAGE_QUALITY_BETTER
|
2020-02-18 14:51:40 +01:00
|
|
|
: VG_IMAGE_QUALITY_NONANTIALIASED);
|
2020-03-20 09:19:06 +01:00
|
|
|
vg_set_nonblock_state(vg, !video->vsync, adaptive_vsync_enabled, interval);
|
2012-06-19 15:01:34 -04:00
|
|
|
|
2020-08-03 00:47:58 +02:00
|
|
|
if (vg->ctx_driver->input_driver)
|
|
|
|
{
|
|
|
|
const char *joypad_name = settings->arrays.input_joypad_driver;
|
|
|
|
vg->ctx_driver->input_driver(
|
|
|
|
vg->ctx_data, joypad_name,
|
|
|
|
input, input_data);
|
|
|
|
}
|
2012-06-19 15:01:34 -04:00
|
|
|
|
2017-01-10 18:16:22 +01:00
|
|
|
if ( video->font_enable
|
2018-07-14 00:54:14 +02:00
|
|
|
&& font_renderer_create_default(
|
|
|
|
&vg->font_driver, &vg->mFontRenderer,
|
2020-02-18 14:51:40 +01:00
|
|
|
*path_font ? path_font : NULL,
|
|
|
|
video_font_size))
|
2012-06-19 15:01:34 -04:00
|
|
|
{
|
2015-04-10 06:51:00 +02:00
|
|
|
vg->mFont = vgCreateFont(0);
|
2012-06-19 15:01:34 -04:00
|
|
|
|
2012-12-14 14:32:39 -05:00
|
|
|
if (vg->mFont != VG_INVALID_HANDLE)
|
2012-06-19 15:01:34 -04:00
|
|
|
{
|
2016-10-04 12:15:46 -04:00
|
|
|
VGfloat paintFg[4];
|
|
|
|
VGfloat paintBg[4];
|
|
|
|
|
2015-04-10 06:51:00 +02:00
|
|
|
vg->mFontsOn = true;
|
2020-02-18 14:51:40 +01:00
|
|
|
vg->mFontHeight = video_font_size;
|
2015-04-10 06:51:00 +02:00
|
|
|
vg->mPaintFg = vgCreatePaint();
|
|
|
|
vg->mPaintBg = vgCreatePaint();
|
2016-10-04 12:15:46 -04:00
|
|
|
|
2020-02-18 14:51:40 +01:00
|
|
|
paintFg[0] = video_msg_color_r;
|
|
|
|
paintFg[1] = video_msg_color_g;
|
|
|
|
paintFg[2] = video_msg_color_b;
|
|
|
|
paintFg[3] = 1.0f;
|
2016-10-04 12:15:46 -04:00
|
|
|
|
2020-02-18 14:51:40 +01:00
|
|
|
paintBg[0] = video_msg_color_r / 2.0f;
|
|
|
|
paintBg[1] = video_msg_color_g / 2.0f;
|
|
|
|
paintBg[2] = video_msg_color_b / 2.0f;
|
|
|
|
paintBg[3] = 0.5f;
|
2012-06-19 15:01:34 -04:00
|
|
|
|
2012-09-24 15:19:07 -04:00
|
|
|
vgSetParameteri(vg->mPaintFg, VG_PAINT_TYPE, VG_PAINT_TYPE_COLOR);
|
|
|
|
vgSetParameterfv(vg->mPaintFg, VG_PAINT_COLOR, 4, paintFg);
|
2012-06-19 15:01:34 -04:00
|
|
|
|
2012-09-24 15:19:07 -04:00
|
|
|
vgSetParameteri(vg->mPaintBg, VG_PAINT_TYPE, VG_PAINT_TYPE_COLOR);
|
|
|
|
vgSetParameterfv(vg->mPaintBg, VG_PAINT_COLOR, 4, paintBg);
|
2012-06-19 15:01:34 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-10-04 12:15:46 -04:00
|
|
|
if (vg_query_extension("KHR_EGL_image")
|
2019-08-29 11:26:28 +02:00
|
|
|
&& vg->ctx_driver->image_buffer_init
|
|
|
|
&& vg->ctx_driver->image_buffer_init(vg->ctx_data, (void*)video))
|
2012-10-18 18:59:56 -04:00
|
|
|
{
|
2019-08-28 21:26:43 +02:00
|
|
|
if (vg->ctx_driver->get_proc_address)
|
|
|
|
pvgCreateEGLImageTargetKHR = (PFNVGCREATEEGLIMAGETARGETKHRPROC)vg->ctx_driver->get_proc_address("vgCreateEGLImageTargetKHR");
|
2012-10-18 18:59:56 -04:00
|
|
|
|
|
|
|
if (pvgCreateEGLImageTargetKHR)
|
|
|
|
{
|
|
|
|
RARCH_LOG("[VG] Using EGLImage buffer\n");
|
|
|
|
vg->mEglImageBuf = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
const char *ext = (const char*)vgGetString(VG_EXTENSIONS);
|
|
|
|
if (ext)
|
|
|
|
RARCH_LOG("[VG] Supported extensions: %s\n", ext);
|
|
|
|
#endif
|
|
|
|
|
2012-09-24 15:19:07 -04:00
|
|
|
return vg;
|
2015-04-09 18:46:24 +02:00
|
|
|
|
|
|
|
error:
|
|
|
|
if (vg)
|
|
|
|
free(vg);
|
2016-05-08 20:32:46 +02:00
|
|
|
video_context_driver_destroy();
|
2015-04-09 18:46:24 +02:00
|
|
|
return NULL;
|
2012-06-19 15:01:34 -04:00
|
|
|
}
|
|
|
|
|
2012-09-24 15:19:07 -04:00
|
|
|
static void vg_free(void *data)
|
2012-06-19 15:01:34 -04:00
|
|
|
{
|
2015-04-09 18:46:24 +02:00
|
|
|
vg_t *vg = (vg_t*)data;
|
2012-06-19 15:01:34 -04:00
|
|
|
|
2014-09-15 08:17:16 -04:00
|
|
|
if (!vg)
|
|
|
|
return;
|
|
|
|
|
2012-09-24 15:19:07 -04:00
|
|
|
vgDestroyImage(vg->mImage);
|
2012-06-19 15:01:34 -04:00
|
|
|
|
2012-09-24 15:19:07 -04:00
|
|
|
if (vg->mFontsOn)
|
2012-06-19 15:01:34 -04:00
|
|
|
{
|
2012-09-24 15:19:07 -04:00
|
|
|
vgDestroyFont(vg->mFont);
|
2012-12-14 14:32:39 -05:00
|
|
|
vg->font_driver->free(vg->mFontRenderer);
|
2012-09-24 15:19:07 -04:00
|
|
|
vgDestroyPaint(vg->mPaintFg);
|
|
|
|
vgDestroyPaint(vg->mPaintBg);
|
2012-06-19 15:01:34 -04:00
|
|
|
}
|
|
|
|
|
2020-08-03 00:35:07 +02:00
|
|
|
if (vg->ctx_driver && vg->ctx_driver->destroy)
|
|
|
|
vg->ctx_driver->destroy(vg->ctx_data);
|
2016-05-08 20:32:46 +02:00
|
|
|
video_context_driver_free();
|
2015-05-02 22:37:27 +02:00
|
|
|
|
2012-09-24 15:19:07 -04:00
|
|
|
free(vg);
|
2012-06-19 15:01:34 -04:00
|
|
|
}
|
|
|
|
|
2020-03-10 19:32:21 +01:00
|
|
|
static void vg_calculate_quad(vg_t *vg,
|
|
|
|
unsigned width, unsigned height)
|
2012-06-19 15:01:34 -04:00
|
|
|
{
|
2015-04-11 08:45:55 +02:00
|
|
|
/* set viewport for aspect ratio, taken from the OpenGL driver. */
|
2015-11-11 03:28:40 +01:00
|
|
|
if (vg->keep_aspect)
|
2012-06-19 15:01:34 -04:00
|
|
|
{
|
2015-05-20 18:24:45 +02:00
|
|
|
float desired_aspect = video_driver_get_aspect_ratio();
|
2012-06-19 15:01:34 -04:00
|
|
|
|
2016-10-04 12:15:46 -04:00
|
|
|
/* If the aspect ratios of screen and desired aspect ratio
|
2015-04-11 08:45:55 +02:00
|
|
|
* are sufficiently equal (floating point stuff),
|
|
|
|
* assume they are actually equal. */
|
2012-09-24 15:19:07 -04:00
|
|
|
if (fabs(vg->mScreenAspect - desired_aspect) < 0.0001)
|
2012-06-19 15:01:34 -04:00
|
|
|
{
|
2012-09-24 15:19:07 -04:00
|
|
|
vg->x1 = 0;
|
|
|
|
vg->y1 = 0;
|
2015-05-20 00:45:42 +02:00
|
|
|
vg->x2 = width;
|
|
|
|
vg->y2 = height;
|
2012-06-19 15:01:34 -04:00
|
|
|
}
|
2012-09-24 15:19:07 -04:00
|
|
|
else if (vg->mScreenAspect > desired_aspect)
|
2012-06-19 15:01:34 -04:00
|
|
|
{
|
2012-09-24 15:19:07 -04:00
|
|
|
float delta = (desired_aspect / vg->mScreenAspect - 1.0) / 2.0 + 0.5;
|
2015-05-20 00:45:42 +02:00
|
|
|
vg->x1 = width * (0.5 - delta);
|
2012-09-24 15:19:07 -04:00
|
|
|
vg->y1 = 0;
|
2015-05-20 00:45:42 +02:00
|
|
|
vg->x2 = 2.0 * width * delta + vg->x1;
|
|
|
|
vg->y2 = height + vg->y1;
|
2012-06-19 15:01:34 -04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-09-24 15:19:07 -04:00
|
|
|
float delta = (vg->mScreenAspect / desired_aspect - 1.0) / 2.0 + 0.5;
|
|
|
|
vg->x1 = 0;
|
2015-05-20 00:45:42 +02:00
|
|
|
vg->y1 = height * (0.5 - delta);
|
|
|
|
vg->x2 = width + vg->x1;
|
|
|
|
vg->y2 = 2.0 * height * delta + vg->y1;
|
2012-06-19 15:01:34 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-09-24 15:19:07 -04:00
|
|
|
vg->x1 = 0;
|
|
|
|
vg->y1 = 0;
|
2015-05-20 00:45:42 +02:00
|
|
|
vg->x2 = width;
|
|
|
|
vg->y2 = height;
|
2012-06-19 15:01:34 -04:00
|
|
|
}
|
|
|
|
|
2012-09-24 15:19:07 -04:00
|
|
|
vg->scissor[0] = vg->x1;
|
|
|
|
vg->scissor[1] = vg->y1;
|
|
|
|
vg->scissor[2] = vg->x2 - vg->x1;
|
|
|
|
vg->scissor[3] = vg->y2 - vg->y1;
|
2012-06-19 15:01:34 -04:00
|
|
|
|
2012-09-24 15:19:07 -04:00
|
|
|
vgSetiv(VG_SCISSOR_RECTS, 4, vg->scissor);
|
2012-06-19 15:01:34 -04:00
|
|
|
}
|
|
|
|
|
2015-04-11 08:45:55 +02:00
|
|
|
static void vg_copy_frame(void *data, const void *frame,
|
|
|
|
unsigned width, unsigned height, unsigned pitch)
|
2012-10-18 18:59:56 -04:00
|
|
|
{
|
|
|
|
vg_t *vg = (vg_t*)data;
|
|
|
|
|
|
|
|
if (vg->mEglImageBuf)
|
|
|
|
{
|
|
|
|
EGLImageKHR img = 0;
|
2016-02-13 23:35:47 +01:00
|
|
|
bool new_egl = false;
|
|
|
|
|
2020-07-27 08:25:11 +02:00
|
|
|
if (vg->ctx_driver->image_buffer_write)
|
|
|
|
new_egl = vg->ctx_driver->image_buffer_write(
|
|
|
|
vg->ctx_data,
|
|
|
|
frame, width, height, pitch,
|
|
|
|
(vg->mTexType == VG_sXRGB_8888),
|
|
|
|
0,
|
|
|
|
&img);
|
2016-10-04 12:15:46 -04:00
|
|
|
|
2015-10-26 03:18:13 +01:00
|
|
|
retro_assert(img != EGL_NO_IMAGE_KHR);
|
2012-10-18 18:59:56 -04:00
|
|
|
|
|
|
|
if (new_egl)
|
|
|
|
{
|
|
|
|
vgDestroyImage(vg->mImage);
|
|
|
|
vg->mImage = pvgCreateEGLImageTargetKHR((VGeglImageKHR) img);
|
|
|
|
if (!vg->mImage)
|
|
|
|
{
|
2016-02-26 17:36:39 +01:00
|
|
|
RARCH_ERR(
|
|
|
|
"[VG:EGLImage] Error creating image: %08x\n",
|
|
|
|
vgGetError());
|
2012-10-18 18:59:56 -04:00
|
|
|
exit(2);
|
|
|
|
}
|
|
|
|
vg->last_egl_image = img;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
vgImageSubData(vg->mImage, frame, pitch, vg->mTexType, 0, 0, width, height);
|
|
|
|
}
|
|
|
|
|
2015-04-11 08:45:55 +02:00
|
|
|
static bool vg_frame(void *data, const void *frame,
|
2015-08-03 23:01:07 +02:00
|
|
|
unsigned frame_width, unsigned frame_height,
|
2017-01-09 14:25:59 +01:00
|
|
|
uint64_t frame_count, unsigned pitch, const char *msg,
|
2017-01-18 17:41:27 +01:00
|
|
|
video_frame_info_t *video_info)
|
2012-06-19 15:01:34 -04:00
|
|
|
{
|
2015-09-20 10:02:47 +02:00
|
|
|
vg_t *vg = (vg_t*)data;
|
2020-05-19 16:20:43 +02:00
|
|
|
unsigned width = video_info->width;
|
|
|
|
unsigned height = video_info->height;
|
2020-08-03 16:33:54 +02:00
|
|
|
#ifdef HAVE_MENU
|
2020-05-19 16:20:43 +02:00
|
|
|
bool menu_is_alive = video_info->menu_is_alive;
|
2020-08-03 16:33:54 +02:00
|
|
|
#endif
|
2015-04-10 09:02:24 +02:00
|
|
|
|
2016-10-04 12:15:46 -04:00
|
|
|
if ( frame_width != vg->mRenderWidth
|
|
|
|
|| frame_height != vg->mRenderHeight
|
2016-02-26 17:36:39 +01:00
|
|
|
|| vg->should_resize)
|
2012-06-19 15:01:34 -04:00
|
|
|
{
|
2015-05-20 00:45:42 +02:00
|
|
|
vg->mRenderWidth = frame_width;
|
|
|
|
vg->mRenderHeight = frame_height;
|
2020-03-10 19:32:21 +01:00
|
|
|
vg_calculate_quad(vg, width, height);
|
2012-09-24 19:30:24 -04:00
|
|
|
matrix_3x3_quad_to_quad(
|
2012-09-24 15:19:07 -04:00
|
|
|
vg->x1, vg->y1, vg->x2, vg->y1, vg->x2, vg->y2, vg->x1, vg->y2,
|
2015-04-10 06:52:51 +02:00
|
|
|
/* needs to be flipped, Khronos loves their bottom-left origin */
|
2015-05-20 00:45:42 +02:00
|
|
|
0, frame_height, frame_width, frame_height, frame_width, 0, 0, 0,
|
2012-09-24 19:30:24 -04:00
|
|
|
&vg->mTransformMatrix);
|
2012-06-19 15:01:34 -04:00
|
|
|
vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE);
|
2012-09-24 19:30:24 -04:00
|
|
|
vgLoadMatrix(vg->mTransformMatrix.data);
|
2012-09-29 20:18:24 +02:00
|
|
|
|
|
|
|
vg->should_resize = false;
|
2012-06-19 15:01:34 -04:00
|
|
|
}
|
2015-05-20 00:45:42 +02:00
|
|
|
|
2012-06-19 15:01:34 -04:00
|
|
|
vgSeti(VG_SCISSORING, VG_FALSE);
|
2015-05-20 00:45:42 +02:00
|
|
|
vgClear(0, 0, width, height);
|
2012-06-19 15:01:34 -04:00
|
|
|
vgSeti(VG_SCISSORING, VG_TRUE);
|
|
|
|
|
2015-05-20 00:45:42 +02:00
|
|
|
vg_copy_frame(vg, frame, frame_width, frame_height, pitch);
|
2012-10-18 18:59:56 -04:00
|
|
|
|
2017-01-18 22:20:47 +01:00
|
|
|
#ifdef HAVE_MENU
|
2020-05-19 16:20:43 +02:00
|
|
|
menu_driver_frame(menu_is_alive, video_info);
|
2017-01-18 22:20:47 +01:00
|
|
|
#endif
|
|
|
|
|
2012-09-24 15:19:07 -04:00
|
|
|
vgDrawImage(vg->mImage);
|
2012-06-19 15:01:34 -04:00
|
|
|
|
2014-06-08 13:23:56 +02:00
|
|
|
#if 0
|
2012-09-24 15:19:07 -04:00
|
|
|
if (msg && vg->mFontsOn)
|
|
|
|
vg_draw_message(vg, msg);
|
2014-06-08 13:23:56 +02:00
|
|
|
#endif
|
2012-06-19 15:01:34 -04:00
|
|
|
|
2020-04-29 14:38:11 +02:00
|
|
|
if (vg->ctx_driver->update_window_title)
|
2020-07-09 07:46:40 +02:00
|
|
|
vg->ctx_driver->update_window_title(vg->ctx_data);
|
2020-04-29 14:38:11 +02:00
|
|
|
|
2020-08-02 18:49:31 +02:00
|
|
|
if (vg->ctx_driver->swap_buffers)
|
|
|
|
vg->ctx_driver->swap_buffers(vg->ctx_data);
|
2012-06-19 15:01:34 -04:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2012-09-24 15:19:07 -04:00
|
|
|
static bool vg_alive(void *data)
|
2012-06-19 15:01:34 -04:00
|
|
|
{
|
2016-02-13 19:53:14 +01:00
|
|
|
bool quit = false;
|
2018-11-06 20:58:41 +01:00
|
|
|
bool resize = false;
|
2016-02-13 19:53:14 +01:00
|
|
|
unsigned temp_width = 0;
|
|
|
|
unsigned temp_height = 0;
|
|
|
|
vg_t *vg = (vg_t*)data;
|
|
|
|
|
2018-10-14 17:49:10 +02:00
|
|
|
vg->ctx_driver->check_window(vg->ctx_data,
|
2020-03-06 20:29:15 +01:00
|
|
|
&quit, &resize, &temp_width, &temp_height);
|
2015-05-20 02:40:44 +02:00
|
|
|
|
|
|
|
if (temp_width != 0 && temp_height != 0)
|
2020-01-31 03:47:50 +01:00
|
|
|
video_driver_set_size(temp_width, temp_height);
|
2015-05-20 02:40:44 +02:00
|
|
|
|
2012-09-18 19:41:58 -04:00
|
|
|
return !quit;
|
2012-06-19 15:01:34 -04:00
|
|
|
}
|
|
|
|
|
2015-01-18 22:32:14 +01:00
|
|
|
static bool vg_suppress_screensaver(void *data, bool enable)
|
|
|
|
{
|
2019-08-28 22:52:41 +02:00
|
|
|
bool enabled = enable;
|
|
|
|
vg_t *vg = (vg_t*)data;
|
|
|
|
if (vg->ctx_data && vg->ctx_driver->suppress_screensaver)
|
|
|
|
return vg->ctx_driver->suppress_screensaver(vg->ctx_data, enabled);
|
|
|
|
return false;
|
2015-01-18 22:32:14 +01:00
|
|
|
}
|
|
|
|
|
2014-09-09 20:18:06 +02:00
|
|
|
static bool vg_set_shader(void *data,
|
2020-07-27 13:16:14 +02:00
|
|
|
enum rarch_shader_type type, const char *path) { return false; }
|
2014-09-09 20:18:06 +02:00
|
|
|
static void vg_get_poke_interface(void *data,
|
2020-08-02 23:44:28 +02:00
|
|
|
const video_poke_interface_t **iface) { }
|
2014-09-09 20:18:06 +02:00
|
|
|
|
2020-07-27 13:39:02 +02:00
|
|
|
static bool vg_has_windowed(void *data)
|
|
|
|
{
|
|
|
|
vg_t *vg = (vg_t*)data;
|
|
|
|
if (vg && vg->ctx_driver)
|
|
|
|
return vg->ctx_driver->has_windowed;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2020-07-27 13:46:55 +02:00
|
|
|
static bool vg_focus(void *data)
|
|
|
|
{
|
|
|
|
vg_t *vg = (vg_t*)data;
|
|
|
|
if (vg && vg->ctx_driver && vg->ctx_driver->has_focus)
|
|
|
|
return vg->ctx_driver->has_focus(vg->ctx_data);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2014-09-11 07:06:20 +02:00
|
|
|
video_driver_t video_vg = {
|
2012-09-24 15:19:07 -04:00
|
|
|
vg_init,
|
|
|
|
vg_frame,
|
|
|
|
vg_set_nonblock_state,
|
|
|
|
vg_alive,
|
2020-07-27 13:46:55 +02:00
|
|
|
vg_focus,
|
2015-01-18 22:32:14 +01:00
|
|
|
vg_suppress_screensaver,
|
2020-07-27 13:39:02 +02:00
|
|
|
vg_has_windowed,
|
2014-09-09 20:18:06 +02:00
|
|
|
vg_set_shader,
|
2012-09-24 15:19:07 -04:00
|
|
|
vg_free,
|
2014-09-09 20:18:06 +02:00
|
|
|
"vg",
|
2017-05-13 19:19:49 +02:00
|
|
|
NULL, /* set_viewport */
|
2019-05-22 07:07:33 +02:00
|
|
|
NULL, /* set_rotation */
|
|
|
|
NULL, /* viewport_info */
|
|
|
|
NULL, /* read_viewport */
|
2017-05-13 19:19:49 +02:00
|
|
|
NULL, /* read_frame_raw */
|
2014-09-09 20:18:06 +02:00
|
|
|
#ifdef HAVE_OVERLAY
|
2017-05-13 19:19:49 +02:00
|
|
|
NULL, /* overlay_interface */
|
2019-04-01 04:00:58 +01:00
|
|
|
#endif
|
|
|
|
#ifdef HAVE_VIDEO_LAYOUT
|
|
|
|
NULL,
|
2014-09-09 20:18:06 +02:00
|
|
|
#endif
|
|
|
|
vg_get_poke_interface
|
2012-06-19 15:01:34 -04:00
|
|
|
};
|