SDL: Desktop OpenGL 1.X/2.X PSVita Support

From 8c542a35918bc7f0418b68d2b4a23fa5d99c8fa2 Mon Sep 17 00:00:00 2001
From: Jaylon Gowie <[EMAIL REDACTED]>
Date: Tue, 29 Mar 2022 19:08:56 -0500
Subject: [PATCH] Desktop OpenGL 1.X/2.X PSVita Support

---
 CMakeLists.txt                                |  11 ++
 include/SDL_config.h.cmake                    |   1 +
 src/render/opengl/SDL_render_gl.c             |   7 ++
 src/video/SDL_egl.c                           |   4 +-
 src/video/vita/SDL_vitagl_pvr.c               |  65 ++++++++---
 src/video/vita/SDL_vitagl_pvr_c.h             |   9 +-
 .../vita/{SDL_vitagl.c => SDL_vitagles.c}     |  24 ++--
 .../vita/{SDL_vitagl_c.h => SDL_vitagles_c.h} |  24 ++--
 src/video/vita/SDL_vitagles_pvr.c             | 103 ++++++++++++++++++
 src/video/vita/SDL_vitagles_pvr_c.h           |  35 ++++++
 src/video/vita/SDL_vitavideo.c                |  57 +++++++---
 src/video/vita/SDL_vitavideo.h                |  21 ++--
 12 files changed, 290 insertions(+), 71 deletions(-)
 rename src/video/vita/{SDL_vitagl.c => SDL_vitagles.c} (91%)
 rename src/video/vita/{SDL_vitagl_c.h => SDL_vitagles_c.h} (67%)
 create mode 100644 src/video/vita/SDL_vitagles_pvr.c
 create mode 100644 src/video/vita/SDL_vitagles_pvr_c.h

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 88a2d29d281..6ca97b7c7cd 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -2321,6 +2321,7 @@ elseif(VITA)
       check_include_file(gpu_es4/psp2_pvr_hint.h HAVE_PVR_H)
       if(HAVE_PVR_H)
         target_compile_definitions(sdl-build-options INTERFACE "-D__psp2__")
+        check_include_file(gl4esinit.h HAVE_GL4ES_H)
         set(SDL_VIDEO_OPENGL_EGL 1)
         set(HAVE_OPENGLES TRUE)
         set(SDL_VIDEO_OPENGL_ES 1)
@@ -2332,8 +2333,18 @@ elseif(VITA)
           libgpu_es4_ext_stub_weak
           libIMGEGL_stub_weak
         )
+
         set(HAVE_VITA_PVR ON)
         set(SDL_VIDEO_VITA_PVR 1)
+
+        if(HAVE_GL4ES_H)
+          set(HAVE_OPENGL TRUE)
+          set(SDL_VIDEO_OPENGL 1)
+          set(SDL_VIDEO_RENDER_OGL 1)
+          list(APPEND EXTRA_LIBS libGL_stub)
+          set(SDL_VIDEO_VITA_PVR_OGL 1)
+        endif()
+
       else()
         set(HAVE_VITA_PVR OFF)
       endif()
diff --git a/include/SDL_config.h.cmake b/include/SDL_config.h.cmake
index 9a1bf675808..f82b0a205db 100644
--- a/include/SDL_config.h.cmake
+++ b/include/SDL_config.h.cmake
@@ -520,6 +520,7 @@
 
 #cmakedefine SDL_VIDEO_VITA_PIB @SDL_VIDEO_VITA_PIB@
 #cmakedefine SDL_VIDEO_VITA_PVR @SDL_VIDEO_VITA_PVR@
+#cmakedefine SDL_VIDEO_VITA_PVR_OGL @SDL_VIDEO_VITA_PVR_OGL@
 
 #if !defined(__WIN32__) && !defined(__WINRT__)
 #  if !defined(_STDINT_H_) && !defined(_STDINT_H) && !defined(HAVE_STDINT_H) && !defined(_HAVE_STDINT_H)
diff --git a/src/render/opengl/SDL_render_gl.c b/src/render/opengl/SDL_render_gl.c
index b5df73ace0d..89d21241ac4 100644
--- a/src/render/opengl/SDL_render_gl.c
+++ b/src/render/opengl/SDL_render_gl.c
@@ -30,6 +30,11 @@
 #include <OpenGL/OpenGL.h>
 #endif
 
+#ifdef __psp2__
+#include <GL/gl.h>
+#include <GL/glext.h>
+#endif
+
 /* To prevent unnecessary window recreation, 
  * these should match the defaults selected in SDL_GL_ResetAttributes 
  */
@@ -1733,6 +1738,7 @@ GL_CreateRenderer(SDL_Window * window, Uint32 flags)
     SDL_GL_GetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, &major);
     SDL_GL_GetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, &minor);
 
+#ifndef __psp2__
     window_flags = SDL_GetWindowFlags(window);
     if (!(window_flags & SDL_WINDOW_OPENGL) ||
         profile_mask == SDL_GL_CONTEXT_PROFILE_ES || major != RENDERER_CONTEXT_MAJOR || minor != RENDERER_CONTEXT_MINOR) {
@@ -1746,6 +1752,7 @@ GL_CreateRenderer(SDL_Window * window, Uint32 flags)
             goto error;
         }
     }
+#endif
 
     renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer));
     if (!renderer) {
diff --git a/src/video/SDL_egl.c b/src/video/SDL_egl.c
index 924b3fd440d..b8993a34a38 100644
--- a/src/video/SDL_egl.c
+++ b/src/video/SDL_egl.c
@@ -99,7 +99,7 @@
 #define DEFAULT_OGL_ES "libGLESv1_CM.so.1"
 #endif /* SDL_VIDEO_DRIVER_RPI */
 
-#if SDL_VIDEO_OPENGL
+#if SDL_VIDEO_OPENGL && !SDL_VIDEO_VITA_PVR_OGL
 #include "SDL_opengl.h"
 #endif
 
@@ -1062,7 +1062,7 @@ SDL_EGL_CreateContext(_THIS, EGLSurface egl_surface)
             if (SDL_GL_ExtensionSupported("GL_OES_surfaceless_context")) {
                 _this->gl_allow_no_surface = SDL_TRUE;
             }
-#if SDL_VIDEO_OPENGL
+#if SDL_VIDEO_OPENGL && !defined(SDL_VIDEO_DRIVER_VITA)
         } else {
             /* Desktop OpenGL supports it by default from version 3.0 on. */
             void (APIENTRY * glGetIntegervFunc) (GLenum pname, GLint * params);
diff --git a/src/video/vita/SDL_vitagl_pvr.c b/src/video/vita/SDL_vitagl_pvr.c
index 3b7fb74772b..5415d137173 100644
--- a/src/video/vita/SDL_vitagl_pvr.c
+++ b/src/video/vita/SDL_vitagl_pvr.c
@@ -20,11 +20,12 @@
 */
 #include "../../SDL_internal.h"
 
-#if SDL_VIDEO_DRIVER_VITA && SDL_VIDEO_VITA_PVR
+#if SDL_VIDEO_DRIVER_VITA && SDL_VIDEO_VITA_PVR && SDL_VIDEO_VITA_PVR_OGL
 #include <stdlib.h>
 #include <string.h>
 #include <psp2/kernel/modulemgr.h>
 #include <gpu_es4/psp2_pvr_hint.h>
+#include <gl4esinit.h>
 
 #include "SDL_error.h"
 #include "SDL_log.h"
@@ -34,6 +35,16 @@
 
 #define MAX_PATH 256 // vita limits are somehow wrong
 
+/* Defaults */
+int FB_WIDTH = 960;
+int FB_HEIGHT = 544;
+
+void getFBSize(int *width, int *height)
+{
+    *width = FB_WIDTH;
+    *height = FB_HEIGHT;
+}
+
 int
 VITA_GL_LoadLibrary(_THIS, const char *path)
 {
@@ -53,6 +64,9 @@ VITA_GL_LoadLibrary(_THIS, const char *path)
         sceKernelLoadStartModule("vs0:sys/external/libfios2.suprx", 0, NULL, 0, NULL, NULL);
         sceKernelLoadStartModule("vs0:sys/external/libc.suprx", 0, NULL, 0, NULL, NULL);
 
+        SDL_snprintf(target_path, MAX_PATH, "%s/%s", default_path, "libGL.suprx");
+        sceKernelLoadStartModule(target_path, 0, NULL, 0, NULL, NULL);
+
         SDL_snprintf(target_path, MAX_PATH, "%s/%s", default_path, "libgpu_es4_ext.suprx");
         sceKernelLoadStartModule(target_path, 0, NULL, 0, NULL, NULL);
 
@@ -74,30 +88,45 @@ VITA_GL_LoadLibrary(_THIS, const char *path)
 SDL_GLContext
 VITA_GL_CreateContext(_THIS, SDL_Window * window)
 {
-    return SDL_EGL_CreateContext(_this, ((SDL_WindowData *) window->driverdata)->egl_surface);
-}
+    char gl_version[3];
+    SDL_GLContext context = NULL;
+    int temp_major = _this->gl_config.major_version;
+    int temp_minor = _this->gl_config.minor_version;
+    int temp_profile = _this->gl_config.profile_mask;
 
-int
-VITA_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context)
-{
-    if (window && context) {
-        return SDL_EGL_MakeCurrent(_this, ((SDL_WindowData *) window->driverdata)->egl_surface, context);
-    } else {
-        return SDL_EGL_MakeCurrent(_this, NULL, NULL);
+    /* Set version to 2.1 and PROFILE to ES */
+    _this->gl_config.major_version = 2;
+    _this->gl_config.minor_version = 1;
+    _this->gl_config.profile_mask = SDL_GL_CONTEXT_PROFILE_ES;
+
+    context = SDL_EGL_CreateContext(_this, ((SDL_WindowData *) window->driverdata)->egl_surface);
+
+    if (context != NULL)
+    {
+        FB_WIDTH = window->w;
+        FB_HEIGHT = window->h;
+        set_getprocaddress((void *(*)(const char *))eglGetProcAddress);
+	    set_getmainfbsize(getFBSize);
+        SDL_snprintf(gl_version, 3, "%d%d", temp_major, temp_minor);
+        gl4es_setenv("LIBGL_NOTEXRECT", "1", 1); /* Currently broken in driver */
+	    gl4es_setenv("LIBGL_GL", gl_version, 1);
+	    initialize_gl4es();
     }
+
+    /* Restore gl_config */
+    _this->gl_config.major_version = temp_major;
+    _this->gl_config.minor_version = temp_minor;
+    _this->gl_config.profile_mask = temp_profile;
+
+    return context;
 }
 
-int
-VITA_GL_SwapWindow(_THIS, SDL_Window * window)
+void *
+VITA_GL_GetProcAddress(_THIS, const char *proc)
 {
-    SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata;
-    if (videodata->ime_active) {
-        sceImeUpdate();
-    }
-    return SDL_EGL_SwapBuffers(_this, ((SDL_WindowData *) window->driverdata)->egl_surface);
+    return gl4es_GetProcAddress(proc);
 }
 
-
 #endif /* SDL_VIDEO_DRIVER_VITA && SDL_VIDEO_VITA_PVR */
 
 /* vi: set ts=4 sw=4 expandtab: */
diff --git a/src/video/vita/SDL_vitagl_pvr_c.h b/src/video/vita/SDL_vitagl_pvr_c.h
index 670eaebb02d..2329d472b6d 100644
--- a/src/video/vita/SDL_vitagl_pvr_c.h
+++ b/src/video/vita/SDL_vitagl_pvr_c.h
@@ -19,17 +19,16 @@
   3. This notice may not be removed or altered from any source distribution.
 */
 
-#ifndef SDL_vitagl_c_h_
-#define SDL_vitagl_c_h_
+#ifndef SDL_vitagl_pvr_c_h_
+#define SDL_vitagl_pvr_c_h_
 
 #include "SDL_vitavideo.h"
 
-extern int VITA_GL_MakeCurrent(_THIS,SDL_Window * window, SDL_GLContext context);
-extern int VITA_GL_SwapWindow(_THIS, SDL_Window * window);
 extern SDL_GLContext VITA_GL_CreateContext(_THIS, SDL_Window * window);
 extern int VITA_GL_LoadLibrary(_THIS, const char *path);
+extern void *VITA_GL_GetProcAddress(_THIS, const char *proc);
 
 
-#endif /* SDL_vitagl_c_h_ */
+#endif /* SDL_vitagl_pvr_c_h_ */
 
 /* vi: set ts=4 sw=4 expandtab: */
diff --git a/src/video/vita/SDL_vitagl.c b/src/video/vita/SDL_vitagles.c
similarity index 91%
rename from src/video/vita/SDL_vitagl.c
rename to src/video/vita/SDL_vitagles.c
index f6502286569..18ca7d57bfd 100644
--- a/src/video/vita/SDL_vitagl.c
+++ b/src/video/vita/SDL_vitagles.c
@@ -27,7 +27,7 @@
 #include "SDL_error.h"
 #include "SDL_log.h"
 #include "SDL_vitavideo.h"
-#include "SDL_vitagl_c.h"
+#include "SDL_vitagles_c.h"
 
 /*****************************************************************************/
 /* SDL OpenGL/OpenGL ES functions                                            */
@@ -45,7 +45,7 @@
     } while (0)
 
 void 
-VITA_GL_KeyboardCallback(ScePigletPreSwapData *data)
+VITA_GLES_KeyboardCallback(ScePigletPreSwapData *data)
 {
     SceCommonDialogUpdateParam commonDialogParam;
     SDL_zero(commonDialogParam);
@@ -62,20 +62,20 @@ VITA_GL_KeyboardCallback(ScePigletPreSwapData *data)
 }
 
 int
-VITA_GL_LoadLibrary(_THIS, const char *path)
+VITA_GLES_LoadLibrary(_THIS, const char *path)
 {
   pibInit(PIB_SHACCCG | PIB_GET_PROC_ADDR_CORE);
   return 0;
 }
 
 void *
-VITA_GL_GetProcAddress(_THIS, const char *proc)
+VITA_GLES_GetProcAddress(_THIS, const char *proc)
 {
     return eglGetProcAddress(proc);
 }
 
 void
-VITA_GL_UnloadLibrary(_THIS)
+VITA_GLES_UnloadLibrary(_THIS)
 {
     eglTerminate(_this->gl_data->display);
 }
@@ -84,7 +84,7 @@ static EGLint width = 960;
 static EGLint height = 544;
 
 SDL_GLContext
-VITA_GL_CreateContext(_THIS, SDL_Window * window)
+VITA_GLES_CreateContext(_THIS, SDL_Window * window)
 {
 
     SDL_WindowData *wdata = (SDL_WindowData *) window->driverdata;
@@ -159,13 +159,13 @@ VITA_GL_CreateContext(_THIS, SDL_Window * window)
     _this->gl_data->surface = surface;
 
     preSwapCallback = (PFNEGLPIGLETVITASETPRESWAPCALLBACKSCEPROC) eglGetProcAddress("eglPigletVitaSetPreSwapCallbackSCE");
-    preSwapCallback(VITA_GL_KeyboardCallback);
+    preSwapCallback(VITA_GLES_KeyboardCallback);
 
     return context;
 }
 
 int
-VITA_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context)
+VITA_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context)
 {
         if (!eglMakeCurrent(_this->gl_data->display, _this->gl_data->surface,
                           _this->gl_data->surface, _this->gl_data->context))
@@ -176,7 +176,7 @@ VITA_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context)
 }
 
 int
-VITA_GL_SetSwapInterval(_THIS, int interval)
+VITA_GLES_SetSwapInterval(_THIS, int interval)
 {
     EGLBoolean status;
     status = eglSwapInterval(_this->gl_data->display, interval);
@@ -190,13 +190,13 @@ VITA_GL_SetSwapInterval(_THIS, int interval)
 }
 
 int
-VITA_GL_GetSwapInterval(_THIS)
+VITA_GLES_GetSwapInterval(_THIS)
 {
     return _this->gl_data->swapinterval;
 }
 
 int
-VITA_GL_SwapWindow(_THIS, SDL_Window * window)
+VITA_GLES_SwapWindow(_THIS, SDL_Window * window)
 {
     if (!eglSwapBuffers(_this->gl_data->display, _this->gl_data->surface)) {
         return SDL_SetError("eglSwapBuffers() failed");
@@ -205,7 +205,7 @@ VITA_GL_SwapWindow(_THIS, SDL_Window * window)
 }
 
 void
-VITA_GL_DeleteContext(_THIS, SDL_GLContext context)
+VITA_GLES_DeleteContext(_THIS, SDL_GLContext context)
 {
     SDL_VideoData *phdata = (SDL_VideoData *) _this->driverdata;
     EGLBoolean status;
diff --git a/src/video/vita/SDL_vitagl_c.h b/src/video/vita/SDL_vitagles_c.h
similarity index 67%
rename from src/video/vita/SDL_vitagl_c.h
rename to src/video/vita/SDL_vitagles_c.h
index 272653d701e..10fd8533a01 100644
--- a/src/video/vita/SDL_vitagl_c.h
+++ b/src/video/vita/SDL_vitagles_c.h
@@ -19,8 +19,8 @@
   3. This notice may not be removed or altered from any source distribution.
 */
 
-#ifndef SDL_vitagl_c_h_
-#define SDL_vitagl_c_h_
+#ifndef SDL_vitagles_c_h_
+#define SDL_vitagles_c_h_
 
 
 #include <pib.h>
@@ -39,19 +39,19 @@ typedef struct SDL_GLDriverData {
     uint32_t swapinterval;
 }SDL_GLDriverData;
 
-extern void * VITA_GL_GetProcAddress(_THIS, const char *proc);
-extern int VITA_GL_MakeCurrent(_THIS,SDL_Window * window, SDL_GLContext context);
-extern void VITA_GL_SwapBuffers(_THIS);
+extern void * VITA_GLES_GetProcAddress(_THIS, const char *proc);
+extern int VITA_GLES_MakeCurrent(_THIS,SDL_Window * window, SDL_GLContext context);
+extern void VITA_GLES_SwapBuffers(_THIS);
 
-extern int VITA_GL_SwapWindow(_THIS, SDL_Window * window);
-extern SDL_GLContext VITA_GL_CreateContext(_THIS, SDL_Window * window);
+extern int VITA_GLES_SwapWindow(_THIS, SDL_Window * window);
+extern SDL_GLContext VITA_GLES_CreateContext(_THIS, SDL_Window * window);
 
-extern int VITA_GL_LoadLibrary(_THIS, const char *path);
-extern void VITA_GL_UnloadLibrary(_THIS);
-extern int VITA_GL_SetSwapInterval(_THIS, int interval);
-extern int VITA_GL_GetSwapInterval(_THIS);
+extern int VITA_GLES_LoadLibrary(_THIS, const char *path);
+extern void VITA_GLES_UnloadLibrary(_THIS);
+extern int VITA_GLES_SetSwapInterval(_THIS, int interval);
+extern int VITA_GLES_GetSwapInterval(_THIS);
 
 
-#endif /* SDL_vitagl_c_h_ */
+#endif /* SDL_vitagles_c_h_ */
 
 /* vi: set ts=4 sw=4 expandtab: */
diff --git a/src/video/vita/SDL_vitagles_pvr.c b/src/video/vita/SDL_vitagles_pvr.c
new file mode 100644
index 00000000000..bb06d2946b3
--- /dev/null
+++ b/src/video/vita/SDL_vitagles_pvr.c
@@ -0,0 +1,103 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_VITA && SDL_VIDEO_VITA_PVR
+#include <stdlib.h>
+#include <string.h>
+#include <psp2/kernel/modulemgr.h>
+#include <gpu_es4/psp2_pvr_hint.h>
+
+#include "SDL_error.h"
+#include "SDL_log.h"
+#include "SDL_vitavideo.h"
+#include "../SDL_egl_c.h"
+#include "SDL_vitagles_pvr_c.h"
+
+#define MAX_PATH 256 // vita limits are somehow wrong
+
+int
+VITA_GLES_LoadLibrary(_THIS, const char *path)
+{
+    PVRSRV_PSP2_APPHINT hint;
+    char* override = SDL_getenv("VITA_MODULE_PATH");
+    char* skip_init = SDL_getenv("VITA_PVR_SKIP_INIT");
+    char* default_path = "app0:module";
+    char target_path[MAX_PATH];
+
+    if (skip_init == NULL) // we don't care about actual value
+    {
+        if (override != NULL)
+        {
+          default_path = override;
+        }
+
+        sceKernelLoadStartModule("vs0:sys/external/libfios2.suprx", 0, NULL, 0, NULL, NULL);
+        sceKernelLoadStartModule("vs0:sys/external/libc.suprx", 0, NULL, 0, NULL, NULL);
+
+        SDL_snprintf(target_path, MAX_PATH, "%s/%s", default_path, "libgpu_es4_ext.suprx");
+        sceKernelLoadStartModule(target_path, 0, NULL, 0, NULL, NULL);
+
+        SDL_snprintf(target_path, MAX_PATH, "%s/%s", default_path, "libIMGEGL.suprx");
+        sceKernelLoadStartModule(target_path, 0, NULL, 0, NULL, NULL);
+
+        PVRSRVInitializeAppHint(&hint);
+
+        SDL_snprintf(hint.szGLES1, MAX_PATH, "%s/%s", default_path, "libGLESv1_CM.suprx");
+        SDL_snprintf(hint.szGLES2, MAX_PATH, "%s/%s", default_path, "libGLESv2.suprx");
+        SDL_snprintf(hint.szWindowSystem, MAX_PATH, "%s/%s", default_path, "libpvrPSP2_WSEGL.suprx");
+
+        PVRSRVCreateVirtualAppHint(&hint);
+    }
+
+    return SDL_EGL_LoadLibrary(_this, path, (NativeDisplayType) 0, 0);
+}
+
+SDL_GLContext
+VITA_GLES_CreateContext(_THIS, SDL_Window * window)
+{
+    return SDL_EGL_CreateContext(_this, ((SDL_WindowData *) window->driverdata)->egl_surface);
+}
+
+int
+VITA_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context)
+{
+    if (window && context) {
+        return SDL_EGL_MakeCurrent(_this, ((SDL_WindowData *) window->driverdata)->egl_surface, context);
+    } else {
+        return SDL_EGL_MakeCurrent(_this, NULL, NULL);
+    }
+}
+
+int
+VITA_GLES_SwapWindow(_THIS, SDL_Window * window)
+{
+    SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata;
+    if (videodata->ime_active) {
+        sceImeUpdate();
+    }
+    return SDL_EGL_SwapBuffers(_this, ((SDL_WindowData *) window->driverdata)->egl_surface);
+}
+
+
+#endif /* SDL_VIDEO_DRIVER_VITA && SDL_VIDEO_VITA_PVR */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/src/video/vita/SDL_vitagles_pvr_c.h b/src/video/vita/SDL_vitagles_pvr_c.h
new file mode 100644
index 00000000000..c3a13c4362a
--- /dev/null
+++ b/src/video/vita/SDL_vitagles_pvr_c.h
@@ -0,0 +1,35 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef SDL_vitagles_pvr_c_h_
+#define SDL_vitagles_pvr_c_h_
+
+#include "SDL_vitavideo.h"
+
+extern int VITA_GLES_MakeCurrent(_THIS,SDL_Window * window, SDL_GLContext context);
+extern int VITA_GLES_SwapWindow(_THIS, SDL_Window * window);
+extern SDL_GLContext VITA_GLES_CreateContext(_THIS, SDL_Window * window);
+extern int VITA_GLES_LoadLibrary(_THIS, const char *path);
+
+
+#endif /* SDL_vitagles_pvr_c_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/src/video/vita/SDL_vitavideo.c b/src/video/vita/SDL_vitavideo.c
index 778a8707353..0a7e5d4ce0b 100644
--- a/src/video/vita/SDL_vitavideo.c
+++ b/src/video/vita/SDL_vitavideo.c
@@ -41,15 +41,17 @@
 #include "SDL_vitaframebuffer.h"
 
 #if defined(SDL_VIDEO_VITA_PIB)
-  #include "SDL_vitagl_c.h"
+  #include "SDL_vitagles_c.h"
 #elif defined(SDL_VIDEO_VITA_PVR)
+  #include "SDL_vitagles_pvr_c.h"
+#if defined(SDL_VIDEO_VITA_PVR_OGL)
   #include "SDL_vitagl_pvr_c.h"
-  #include "../SDL_egl_c.h"
-  #define VITA_GL_GetProcAddress SDL_EGL_GetProcAddress
-  #define VITA_GL_UnloadLibrary SDL_EGL_UnloadLibrary
-  #define VITA_GL_SetSwapInterval SDL_EGL_SetSwapInterval
-  #define VITA_GL_GetSwapInterval SDL_EGL_GetSwapInterval
-  #define VITA_GL_DeleteContext SDL_EGL_DeleteContext
+#endif
+  #define VITA_GLES_GetProcAddress SDL_EGL_GetProcAddress
+  #define VITA_GLES_UnloadLibrary SDL_EGL_UnloadLibrary
+  #define VITA_GLES_SetSwapInterval SDL_EGL_SetSwapInterval
+  #define VITA_GLES_GetSwapInterval SDL_EGL_GetSwapInterval
+  #define VITA_GLES_DeleteContext SDL_EGL_DeleteContext
 #endif
 
 SDL_Window *Vita_Window;
@@ -140,15 +142,22 @@ VITA_Create()
 */
 
 #if defined(SDL_VIDEO_VITA_PIB) || defined(SDL_VIDEO_VITA_PVR)
+if(SDL_getenv("VITA_PVR_OGL") != NULL) {
     device->GL_LoadLibrary = VITA_GL_LoadLibrary;
-    device->GL_GetProcAddress = VITA_GL_GetProcAddress;
-    device->GL_UnloadLibrary = VITA_GL_UnloadLibrary;
     device->GL_CreateContext = VITA_GL_CreateContext;
-    device->GL_MakeCurrent = VITA_GL_MakeCurrent;
-    device->GL_SetSwapInterval = VITA_GL_SetSwapInterval;
-    device->GL_GetSwapInterval = VITA_GL_GetSwapInterval;
-    device->GL_SwapWindow = VITA_GL_SwapWindow;
-    device->GL_DeleteContext = VITA_GL_DeleteContext;
+    device->GL_GetProcAddress = VITA_GL_GetProcAddress;
+}
+else {
+    device->GL_LoadLibrary = VITA_GLES_LoadLibrary;
+    device->GL_CreateContext = VITA_GLES_CreateContext;
+    device->GL_GetProcAddress = VITA_GLES_GetProcAddress;
+}
+    device->GL_UnloadLibrary = VITA_GLES_UnloadLibrary;
+    device->GL_MakeCurrent = VITA_GLES_MakeCurrent;
+    device->GL_SetSwapInterval = VITA_GLES_SetSwapInterval;
+    device->GL_GetSwapInterval = VITA_GLES_GetSwapInterval;
+    device->GL_SwapWindow = VITA_GLES_SwapWindow;
+    device->GL_DeleteContext = VITA_GLES_DeleteContext;
 #endif
 
     device->HasScreenKeyboardSupport = VITA_HasScreenKeyboardSupport;
@@ -245,6 +254,9 @@ VITA_CreateWindow(_THIS, SDL_Window * window)
     SDL_WindowData *wdata;
 #if defined(SDL_VIDEO_VITA_PVR)
     Psp2NativeWindow win;
+    int temp_major = 2;
+    int temp_minor = 1;
+    int temp_profile = 0;
 #endif
 
     /* Allocate window internal data */
@@ -282,11 +294,26 @@ VITA_CreateWindow(_THIS, SDL_Window * window)
         win.windowSize = PSP2_WINDOW_960X544;
     }
     if ((window->flags & SDL_WINDOW_OPENGL) != 0) {
+      if(SDL_getenv("VITA_PVR_OGL") != NULL) {
+        /* Set version to 2.1 and PROFILE to ES */
+        temp_major = _this->gl_config.major_version;
+        temp_minor = _this->gl_config.minor_version;
+        temp_profile = _this->gl_config.profile_mask;
+
+        _this->gl_config.major_version = 2;
+        _this->gl_config.minor_version = 1;
+        _this->gl_config.profile_mask = SDL_GL_CONTEXT_PROFILE_ES;
+      }
       wdata->egl_surface = SDL_EGL_CreateSurface(_this, &win);
-
       if (wdata->egl_surface == EGL_NO_SURFACE) {
           return SDL_SetError("Could not create GLES window surface");
       }
+      if(SDL_getenv("VITA_PVR_OGL") != NULL) {
+        /* Revert */
+        _this->gl_config.major_version = temp_major;
+        _this->gl_config.minor_version = temp_minor;
+        _this->gl_config.profile_mask = temp_profile;
+      }
     }
 #endif
 
diff --git a/src/video/vita/SDL_vitavideo.h b/src/video/vita/SDL_vitavideo.h
index 04488dde317..9fdf7e69ce9 100644
--- a/src/video/vita/SDL_vitavideo.h
+++ b/src/video/vita/SDL_vitavideo.h
@@ -90,16 +90,23 @@ SDL_bool VITA_GetWindowWMInfo(_THIS, SDL_Window * window,
                              struct SDL_SysWMinfo *info);
 
 #if SDL_VIDEO_DRIVER_VITA
+#if defined(SDL_VIDEO_VITA_PVR_OGL)
 /* OpenGL functions */
 int VITA_GL_LoadLibrary(_THIS, const char *path);
-void *VITA_GL_GetProcAddress(_THIS, const char *proc);
-void VITA_GL_UnloadLibrary(_THIS);
 SDL_GLContext VITA_GL_CreateContext(_THIS, SDL_Window * window);
-int VITA_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context);
-int VITA_GL_SetSwapInterval(_THIS, int interval);
-int VITA_GL_GetSwapInterval(_THIS);
-int VITA_GL_SwapWindow(_THIS, SDL_Window * window);
-void VITA_GL_DeleteContext(_THIS, SDL_GLContext context);
+void *VITA_GL_GetProcAddress(_THIS, const char *proc);
+#endif
+
+/* OpenGLES functions */
+int VITA_GLES_LoadLibrary(_THIS, const char *path);
+void *VITA_GLES_GetProcAddress(_THIS, const char *proc);
+void VITA_GLES_UnloadLibrary(_THIS);
+SDL_GLContext VITA_GLES_CreateContext(_THIS, SDL_Window * window);
+int VITA_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context);
+int VITA_GLES_SetSwapInterval(_THIS, int interval);
+int VITA_GLES_GetSwapInterval(_THIS);
+int VITA_GLES_SwapWindow(_THIS, SDL_Window * window);
+void VITA_GLES_DeleteContext(_THIS, SDL_GLContext context);
 #endif
 
 /* VITA on screen keyboard */