gtk: implement GPU scale factor feature (#764)

* [WIP] gtk: implement GPU scale factor feature

* Replace combobox with spin button, fix taking screenshot

* Fix distorted image, add some checks for scale factor value

* Make OSD at least properly visible
This commit is contained in:
Max Fedotov 2024-01-25 17:28:46 +03:00 committed by GitHub
parent b06537cf51
commit f2cfd23ef2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 98 additions and 17 deletions

View File

@ -63,6 +63,24 @@ void value<int>::save() {
g_key_file_set_integer(this->mKeyFile, this->mSection.c_str(), this->mKey.c_str(), this->mData);
}
/*class value<float> */
template<>
void value<float>::load() {
GError* err = NULL;
float val = g_key_file_get_double(this->mKeyFile, this->mSection.c_str(), this->mKey.c_str(), &err);
if (err != NULL) {
g_error_free(err);
} else {
this->mData = val;
}
}
template<>
void value<float>::save() {
g_key_file_set_double(this->mKeyFile, this->mSection.c_str(), this->mKey.c_str(), this->mData);
}
/* class value<string> */
template<>

View File

@ -60,6 +60,7 @@ OPT(core3D, int, 1, Config, Core3D)
OPT(textureDeposterize, bool, false, Config, 3DTextureDeposterization)
OPT(textureSmoothing, bool, false, Config, 3DTextureSmoothing)
OPT(textureUpscale, int, 1, Config, 3DTextureUpscaling)
OPT(gpuScaleFactor, float, 1.0, Config, GPUScaleFactor)
OPT(highColorInterpolation, bool, true, Config, HighResolutionColorInterpolation)
OPT(multisampling, bool, false, Config, OpenGLMultisampling)
OPT(multisamplingSize, int, 0, Config, OpenGLMultisamplingSize)

View File

@ -94,6 +94,25 @@
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="label" translatable="yes">GPU scale factor:</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">2</property>
</packing>
</child>
<child>
<object class="GtkSpinButton" id="gpuscale">
<property name="numeric">true</property>
<property name="digits">0</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">2</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="posterize">
<property name="label" translatable="yes">3D Texture Deposterization</property>
@ -101,7 +120,7 @@
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">2</property>
<property name="top_attach">3</property>
</packing>
</child>
<child>
@ -111,7 +130,7 @@
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">3</property>
<property name="top_attach">4</property>
</packing>
</child>
<child>
@ -121,7 +140,7 @@
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">3</property>
<property name="top_attach">4</property>
</packing>
</child>
<child>
@ -130,7 +149,7 @@
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">4</property>
<property name="top_attach">5</property>
</packing>
</child>
<child>
@ -146,7 +165,7 @@
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">4</property>
<property name="top_attach">5</property>
</packing>
</child>
</object>

View File

@ -99,6 +99,14 @@ static int draw_count;
extern int _scanline_filter_a, _scanline_filter_b, _scanline_filter_c, _scanline_filter_d;
VideoFilter* video;
#define GPU_SCALE_FACTOR_MIN 1.0f
#define GPU_SCALE_FACTOR_MAX 10.0f
float gpu_scale_factor = 1.0f;
int real_framebuffer_width = GPU_FRAMEBUFFER_NATIVE_WIDTH;
int real_framebuffer_height = GPU_FRAMEBUFFER_NATIVE_HEIGHT;
desmume::config::Config config;
#ifdef GDB_STUB
@ -1310,7 +1318,8 @@ static int ConfigureDrawingArea(GtkWidget *widget, GdkEventConfigure *event, gpo
static inline void gpu_screen_to_rgb(u32* dst)
{
ColorspaceConvertBuffer555To8888Opaque<false, false, BESwapDst>(GPU->GetDisplayInfo().masterNativeBuffer16, dst, GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT * 2);
ColorspaceConvertBuffer555To8888Opaque<false, false, BESwapDst>(GPU->GetDisplayInfo().isCustomSizeRequested ? (u16*)(GPU->GetDisplayInfo().masterCustomBuffer) : GPU->GetDisplayInfo().masterNativeBuffer16,
dst, real_framebuffer_width * real_framebuffer_height * 2);
}
static inline void drawScreen(cairo_t* cr, u32* buf, gint w, gint h) {
@ -1384,7 +1393,7 @@ static gboolean ExposeDrawingArea (GtkWidget *widget, GdkEventExpose *event, gpo
gint dstW = video->GetDstWidth();
gint dstH = video->GetDstHeight();
gint dstScale = dstW * 2 / 256; // Actual scale * 2 to handle 1.5x filters
gint dstScale = dstW * 2 / GPU_FRAMEBUFFER_NATIVE_WIDTH; // Actual scale * 2 to handle 1.5x filters
gint gap = nds_screen.orientation == ORIENT_VERTICAL ? nds_screen.gap_size * dstScale / 2 : 0;
gint imgW, imgH;
@ -1436,9 +1445,11 @@ static gboolean ExposeDrawingArea (GtkWidget *widget, GdkEventExpose *event, gpo
}
static void RedrawScreen() {
ColorspaceConvertBuffer555To8888Opaque<true, false, BESwapDst>(GPU->GetDisplayInfo().masterNativeBuffer16, (uint32_t *)video->GetSrcBufferPtr(), GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT * 2);
ColorspaceConvertBuffer555To8888Opaque<true, false, BESwapDst>(
GPU->GetDisplayInfo().isCustomSizeRequested ? (u16*)(GPU->GetDisplayInfo().masterCustomBuffer) : GPU->GetDisplayInfo().masterNativeBuffer16,
(uint32_t *)video->GetSrcBufferPtr(), real_framebuffer_width * real_framebuffer_height * 2);
#ifdef HAVE_LIBAGG
aggDraw.hud->attach((u8*)video->GetSrcBufferPtr(), 256, 384, 1024);
aggDraw.hud->attach((u8*)video->GetSrcBufferPtr(), real_framebuffer_width, real_framebuffer_height * 2, 1024 * gpu_scale_factor);
osd->update();
DrawHUD();
osd->clear();
@ -1989,12 +2000,16 @@ static void GraphicsSettingsDialog(GSimpleAction *action, GVariant *parameter, g
GtkGrid *wGrid;
GtkComboBox *coreCombo, *wScale, *wMultisample;
GtkToggleButton *wPosterize, *wSmoothing, *wHCInterpolate;
GtkSpinButton *wGPUScale;
GtkBuilder *builder = gtk_builder_new_from_resource("/org/desmume/DeSmuME/graphics.ui");
dialog = GTK_DIALOG(gtk_builder_get_object(builder, "dialog"));
wGrid = GTK_GRID(gtk_builder_get_object(builder, "graphics_grid"));
coreCombo = GTK_COMBO_BOX(gtk_builder_get_object(builder, "core_combo"));
wScale = GTK_COMBO_BOX(gtk_builder_get_object(builder, "scale"));
wGPUScale = GTK_SPIN_BUTTON(gtk_builder_get_object(builder, "gpuscale"));
gtk_spin_button_set_range(wGPUScale, GPU_SCALE_FACTOR_MIN, GPU_SCALE_FACTOR_MAX);
gtk_spin_button_set_increments(wGPUScale, 1.0, 1.0);
wMultisample = GTK_COMBO_BOX(gtk_builder_get_object(builder, "multisample"));
wPosterize = GTK_TOGGLE_BUTTON(gtk_builder_get_object(builder, "posterize"));
wSmoothing = GTK_TOGGLE_BUTTON(gtk_builder_get_object(builder, "smoothing"));
@ -2010,6 +2025,9 @@ static void GraphicsSettingsDialog(GSimpleAction *action, GVariant *parameter, g
// The shift it work for scale up to 4. For scaling more than 4, a mapping function is required
gtk_combo_box_set_active(wScale, CommonSettings.GFX3D_Renderer_TextureScalingFactor >> 1);
//GPU scaling factor
gtk_spin_button_set_value(wGPUScale, gpu_scale_factor);
// 3D Texture Deposterization
gtk_toggle_button_set_active(wPosterize, CommonSettings.GFX3D_Renderer_TextureDeposterize);
@ -2080,6 +2098,17 @@ static void GraphicsSettingsDialog(GSimpleAction *action, GVariant *parameter, g
default:
break;
}
gpu_scale_factor = gtk_spin_button_get_value(wGPUScale);
if(gpu_scale_factor < GPU_SCALE_FACTOR_MIN)
gpu_scale_factor = GPU_SCALE_FACTOR_MIN;
if(gpu_scale_factor > GPU_SCALE_FACTOR_MAX)
gpu_scale_factor = GPU_SCALE_FACTOR_MAX;
gtk_spin_button_set_value(wGPUScale, gpu_scale_factor);
config.gpuScaleFactor = gpu_scale_factor;
real_framebuffer_width = GPU_FRAMEBUFFER_NATIVE_WIDTH * gpu_scale_factor;
real_framebuffer_height = GPU_FRAMEBUFFER_NATIVE_HEIGHT * gpu_scale_factor;
GPU->SetCustomFramebufferSize(real_framebuffer_width, real_framebuffer_height);
video->SetSourceSize(real_framebuffer_width, real_framebuffer_height * 2);
CommonSettings.GFX3D_Renderer_TextureDeposterize = config.textureDeposterize = gtk_toggle_button_get_active(wPosterize);
CommonSettings.GFX3D_Renderer_TextureSmoothing = config.textureSmoothing = gtk_toggle_button_get_active(wSmoothing);
CommonSettings.GFX3D_Renderer_TextureScalingFactor = config.textureUpscale = scale;
@ -2140,7 +2169,7 @@ static void Printscreen(GSimpleAction *action, GVariant *parameter, gpointer use
const gchar *dir;
gchar *filename = NULL, *filen = NULL;
GError *error = NULL;
u8 rgb[256 * 384 * 4];
u8 *rgb = (u8*)malloc(real_framebuffer_width * real_framebuffer_height * 2 * 4);
static int seq = 0;
gint H, W;
@ -2149,11 +2178,11 @@ static void Printscreen(GSimpleAction *action, GVariant *parameter, gpointer use
// return;
if (nds_screen.rotation_angle == 0 || nds_screen.rotation_angle == 180) {
W = screen_size[nds_screen.orientation].width;
H = screen_size[nds_screen.orientation].height;
W = real_framebuffer_width;
H = real_framebuffer_height * 2;
} else {
W = screen_size[nds_screen.orientation].height;
H = screen_size[nds_screen.orientation].width;
W = real_framebuffer_height * 2;
H = real_framebuffer_width;
}
gpu_screen_to_rgb((u32*)rgb);
@ -2190,7 +2219,7 @@ static void Printscreen(GSimpleAction *action, GVariant *parameter, gpointer use
seq--;
}
//free(rgb);
free(rgb);
g_object_unref(screenshot);
g_free(filename);
g_free(filen);
@ -3026,8 +3055,18 @@ common_gtk_main(GApplication *app, gpointer user_data)
memset(&nds_screen, 0, sizeof(nds_screen));
nds_screen.orientation = ORIENT_VERTICAL;
gpu_scale_factor = config.gpuScaleFactor;
if(gpu_scale_factor < GPU_SCALE_FACTOR_MIN)
gpu_scale_factor = GPU_SCALE_FACTOR_MIN;
if(gpu_scale_factor > GPU_SCALE_FACTOR_MAX)
gpu_scale_factor = GPU_SCALE_FACTOR_MAX;
config.gpuScaleFactor = gpu_scale_factor;
real_framebuffer_width = GPU_FRAMEBUFFER_NATIVE_WIDTH * gpu_scale_factor;
real_framebuffer_height = GPU_FRAMEBUFFER_NATIVE_HEIGHT * gpu_scale_factor;
g_printerr("Using %d threads for video filter.\n", CommonSettings.num_cores);
video = new VideoFilter(256, 384, VideoFilterTypeID_None, CommonSettings.num_cores);
GPU->SetCustomFramebufferSize(real_framebuffer_width, real_framebuffer_height);
video = new VideoFilter(real_framebuffer_width, real_framebuffer_height * 2, VideoFilterTypeID_None, CommonSettings.num_cores);
/* Fetch the main elements from the window */
GtkBuilder *builder = gtk_builder_new_from_resource("/org/desmume/DeSmuME/main.ui");

View File

@ -28,6 +28,9 @@ static bool sdl_init(void) { return is_sdl_initialized(); }
static SDL_Window *win = NULL;
static SDL_GLContext ctx = NULL;
extern int real_framebuffer_width;
extern int real_framebuffer_height;
bool deinit_sdl_3Demu(void)
{
bool ret = false;
@ -60,7 +63,8 @@ bool init_sdl_3Demu(void)
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
win = SDL_CreateWindow(NULL, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 256, 192, SDL_WINDOW_OPENGL | SDL_WINDOW_HIDDEN);
win = SDL_CreateWindow(NULL, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, real_framebuffer_width,
real_framebuffer_height, SDL_WINDOW_OPENGL | SDL_WINDOW_HIDDEN);
if (!win) {
fprintf(stderr, "SDL: Failed to create a window: %s\n", SDL_GetError());
return false;