2011-02-06 00:00:13 -08:00
|
|
|
/*
|
2011-04-08 13:03:26 -07:00
|
|
|
Simple DirectMedia Layer
|
2017-01-01 18:33:28 -08:00
|
|
|
Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
|
2011-02-06 00:00:13 -08:00
|
|
|
|
2011-04-08 13:03:26 -07:00
|
|
|
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.
|
2011-02-11 19:11:27 -08:00
|
|
|
|
2011-04-08 13:03:26 -07:00
|
|
|
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:
|
2011-02-06 00:00:13 -08:00
|
|
|
|
2011-04-08 13:03:26 -07:00
|
|
|
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.
|
2011-02-11 19:11:27 -08:00
|
|
|
*/
|
2013-11-24 23:56:17 -05:00
|
|
|
#include "../../SDL_internal.h"
|
2011-02-06 00:00:13 -08:00
|
|
|
|
2011-02-08 10:04:09 -08:00
|
|
|
#if SDL_VIDEO_RENDER_OGL_ES2 && !SDL_RENDER_DISABLED
|
2011-02-06 00:00:13 -08:00
|
|
|
|
2011-03-13 11:18:35 -07:00
|
|
|
#include "SDL_hints.h"
|
2011-02-06 02:35:14 -08:00
|
|
|
#include "SDL_opengles2.h"
|
2011-02-06 00:00:13 -08:00
|
|
|
#include "../SDL_sysrender.h"
|
2013-10-05 12:29:05 -07:00
|
|
|
#include "../../video/SDL_blit.h"
|
2011-02-06 00:00:13 -08:00
|
|
|
#include "SDL_shaders_gles2.h"
|
|
|
|
|
2014-12-26 22:30:19 -05:00
|
|
|
/* !!! FIXME: Emscripten makes these into WebGL calls, and WebGL doesn't offer
|
|
|
|
!!! FIXME: client-side arrays (without an Emscripten compatibility hack,
|
|
|
|
!!! FIXME: at least), but the current VBO code here is dramatically
|
|
|
|
!!! FIXME: slower on actual iOS devices, even though the iOS Simulator
|
|
|
|
!!! FIXME: is okay. Some time after 2.0.4 ships, we should revisit this,
|
|
|
|
!!! FIXME: fix the performance bottleneck, and make everything use VBOs.
|
|
|
|
*/
|
|
|
|
#ifdef __EMSCRIPTEN__
|
|
|
|
#define SDL_GLES2_USE_VBOS 1
|
|
|
|
#else
|
|
|
|
#define SDL_GLES2_USE_VBOS 0
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* To prevent unnecessary window recreation,
|
2014-02-27 20:21:46 -03:00
|
|
|
* these should match the defaults selected in SDL_GL_ResetAttributes
|
|
|
|
*/
|
2014-02-25 17:42:34 -03:00
|
|
|
#define RENDERER_CONTEXT_MAJOR 2
|
|
|
|
#define RENDERER_CONTEXT_MINOR 0
|
|
|
|
|
2012-01-08 13:31:22 -05:00
|
|
|
/* Used to re-create the window with OpenGL ES capability */
|
Fixed bug 1242 - PATCH: Improve support for OpenGL ES under X11
Scott Percival 2011-07-03 06:41:51 PDT
This submission is aimed at making life easier for OpenGL ES capable devices
running a X11 stack (e.g. Maemo, Meego, TrimSlice, other ARM SoC boards not
running Android). SDL's Pandora support already has the neccesary GLES-to-X11
glue code, however it's all ghetto'd off in Makefile.pandora and not very
flexible.
The patch:
- adds an awesome --enable-video-opengles option to configure
- re-modifies the opengles and opengles2 SDL_renderers to use function pointers
- no idea why this was removed?
- for SDL_Renderers, links in libGLESv1_CM, libGLES_CM (for PowerVR fans) or
libGLESv2 at runtime
- links in libEGL.so at runtime - the old code made an assumption that
eglFunctions could be pulled from the active GLES library, PowerVR for one
doesn't let you do that with their libGLESv2
- allows you to pick which of GLES v1 or v2 to load via
SDL_GL_CONTEXT_MAJOR_VERSION
So far I've tested this on a Nokia N900 (OMAP 3430/SGX 530 running Maemo 5) and
a Toshiba AC100 (Tegra 2 running Ubuntu 10.10). I haven't tested it on... well,
everything that isn't those two, such as a Pandora, iOS or Android device. The
Pandora specific code should be kept intact (fingers crossed), and nothing
painfully drastic has been added to the SDL_renderers. The library loading
sequence in SDL_x11opengles has been updated to accomodate both NVIDIA's
propensity to let developers get away with murder and PowerVR's alternative of
punishing every missed step.
The test apps work okay with GLES or GLES2 as the renderer. For some reason
alpha blending doesn't seem to work on the Tegra 2; last week NVIDIA pushed out
a new set of X11 GLES drivers, so I'll try and investigate once I upgrade
those. Also, this patch adds things to configure.in, include/SDL_config.h.in
and test/configure.in. I didn't know what the policy was re. committing
generated spaghetti from autotools, so ./autogen.sh has to be run again. Sorry.
I think that's about everything, let me know if there's anything I've
overlooked.
2012-01-08 02:23:37 -05:00
|
|
|
extern int SDL_RecreateWindow(SDL_Window * window, Uint32 flags);
|
|
|
|
|
2011-02-06 00:00:13 -08:00
|
|
|
/*************************************************************************************************
|
|
|
|
* Bootstrap data *
|
|
|
|
*************************************************************************************************/
|
|
|
|
|
|
|
|
static SDL_Renderer *GLES2_CreateRenderer(SDL_Window *window, Uint32 flags);
|
|
|
|
|
|
|
|
SDL_RenderDriver GLES2_RenderDriver = {
|
|
|
|
GLES2_CreateRenderer,
|
|
|
|
{
|
|
|
|
"opengles2",
|
2012-01-19 21:06:47 -05:00
|
|
|
(SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_TARGETTEXTURE),
|
2011-12-29 05:11:33 -05:00
|
|
|
4,
|
2014-06-21 21:46:42 -07:00
|
|
|
{
|
2011-12-29 05:11:33 -05:00
|
|
|
SDL_PIXELFORMAT_ARGB8888,
|
2014-06-21 21:46:42 -07:00
|
|
|
SDL_PIXELFORMAT_ABGR8888,
|
2011-12-29 05:11:33 -05:00
|
|
|
SDL_PIXELFORMAT_RGB888,
|
2014-06-21 21:46:42 -07:00
|
|
|
SDL_PIXELFORMAT_BGR888
|
|
|
|
},
|
2011-02-06 00:00:13 -08:00
|
|
|
0,
|
|
|
|
0
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
/*************************************************************************************************
|
|
|
|
* Context structures *
|
|
|
|
*************************************************************************************************/
|
|
|
|
|
2012-01-18 22:45:49 -05:00
|
|
|
typedef struct GLES2_FBOList GLES2_FBOList;
|
|
|
|
|
|
|
|
struct GLES2_FBOList
|
|
|
|
{
|
|
|
|
Uint32 w, h;
|
|
|
|
GLuint FBO;
|
|
|
|
GLES2_FBOList *next;
|
|
|
|
};
|
|
|
|
|
2011-02-06 00:00:13 -08:00
|
|
|
typedef struct GLES2_TextureData
|
|
|
|
{
|
|
|
|
GLenum texture;
|
|
|
|
GLenum texture_type;
|
|
|
|
GLenum pixel_format;
|
|
|
|
GLenum pixel_type;
|
|
|
|
void *pixel_data;
|
2014-07-07 11:00:25 -07:00
|
|
|
int pitch;
|
2014-08-06 11:34:54 -07:00
|
|
|
/* YUV texture support */
|
2014-06-07 11:36:08 -07:00
|
|
|
SDL_bool yuv;
|
2014-08-06 11:34:54 -07:00
|
|
|
SDL_bool nv12;
|
2014-06-07 11:36:08 -07:00
|
|
|
GLenum texture_v;
|
|
|
|
GLenum texture_u;
|
2012-01-18 22:45:49 -05:00
|
|
|
GLES2_FBOList *fbo;
|
2011-02-06 00:00:13 -08:00
|
|
|
} GLES2_TextureData;
|
|
|
|
|
|
|
|
typedef struct GLES2_ShaderCacheEntry
|
|
|
|
{
|
|
|
|
GLuint id;
|
|
|
|
GLES2_ShaderType type;
|
|
|
|
const GLES2_ShaderInstance *instance;
|
|
|
|
int references;
|
2013-10-05 00:29:57 -04:00
|
|
|
Uint8 modulation_r, modulation_g, modulation_b, modulation_a;
|
2011-02-06 00:00:13 -08:00
|
|
|
struct GLES2_ShaderCacheEntry *prev;
|
|
|
|
struct GLES2_ShaderCacheEntry *next;
|
|
|
|
} GLES2_ShaderCacheEntry;
|
|
|
|
|
|
|
|
typedef struct GLES2_ShaderCache
|
|
|
|
{
|
|
|
|
int count;
|
|
|
|
GLES2_ShaderCacheEntry *head;
|
|
|
|
} GLES2_ShaderCache;
|
|
|
|
|
|
|
|
typedef struct GLES2_ProgramCacheEntry
|
|
|
|
{
|
|
|
|
GLuint id;
|
|
|
|
GLES2_ShaderCacheEntry *vertex_shader;
|
|
|
|
GLES2_ShaderCacheEntry *fragment_shader;
|
|
|
|
GLuint uniform_locations[16];
|
2013-10-05 00:29:57 -04:00
|
|
|
Uint8 color_r, color_g, color_b, color_a;
|
|
|
|
Uint8 modulation_r, modulation_g, modulation_b, modulation_a;
|
|
|
|
GLfloat projection[4][4];
|
2011-02-06 00:00:13 -08:00
|
|
|
struct GLES2_ProgramCacheEntry *prev;
|
|
|
|
struct GLES2_ProgramCacheEntry *next;
|
|
|
|
} GLES2_ProgramCacheEntry;
|
|
|
|
|
|
|
|
typedef struct GLES2_ProgramCache
|
|
|
|
{
|
|
|
|
int count;
|
|
|
|
GLES2_ProgramCacheEntry *head;
|
|
|
|
GLES2_ProgramCacheEntry *tail;
|
|
|
|
} GLES2_ProgramCache;
|
|
|
|
|
|
|
|
typedef enum
|
|
|
|
{
|
|
|
|
GLES2_ATTRIBUTE_POSITION = 0,
|
2012-06-01 19:51:08 -03:00
|
|
|
GLES2_ATTRIBUTE_TEXCOORD = 1,
|
|
|
|
GLES2_ATTRIBUTE_ANGLE = 2,
|
|
|
|
GLES2_ATTRIBUTE_CENTER = 3,
|
2011-02-06 00:00:13 -08:00
|
|
|
} GLES2_Attribute;
|
|
|
|
|
|
|
|
typedef enum
|
|
|
|
{
|
|
|
|
GLES2_UNIFORM_PROJECTION,
|
|
|
|
GLES2_UNIFORM_TEXTURE,
|
|
|
|
GLES2_UNIFORM_MODULATION,
|
2014-06-07 11:36:08 -07:00
|
|
|
GLES2_UNIFORM_COLOR,
|
|
|
|
GLES2_UNIFORM_TEXTURE_U,
|
|
|
|
GLES2_UNIFORM_TEXTURE_V
|
2011-02-06 00:00:13 -08:00
|
|
|
} GLES2_Uniform;
|
|
|
|
|
|
|
|
typedef enum
|
|
|
|
{
|
|
|
|
GLES2_IMAGESOURCE_SOLID,
|
2011-12-29 05:11:33 -05:00
|
|
|
GLES2_IMAGESOURCE_TEXTURE_ABGR,
|
|
|
|
GLES2_IMAGESOURCE_TEXTURE_ARGB,
|
|
|
|
GLES2_IMAGESOURCE_TEXTURE_RGB,
|
2014-06-07 11:36:08 -07:00
|
|
|
GLES2_IMAGESOURCE_TEXTURE_BGR,
|
2014-08-06 11:34:54 -07:00
|
|
|
GLES2_IMAGESOURCE_TEXTURE_YUV,
|
|
|
|
GLES2_IMAGESOURCE_TEXTURE_NV12,
|
|
|
|
GLES2_IMAGESOURCE_TEXTURE_NV21
|
2011-02-06 00:00:13 -08:00
|
|
|
} GLES2_ImageSource;
|
|
|
|
|
|
|
|
typedef struct GLES2_DriverContext
|
|
|
|
{
|
|
|
|
SDL_GLContext *context;
|
2013-10-03 20:48:52 -07:00
|
|
|
|
|
|
|
SDL_bool debug_enabled;
|
|
|
|
|
2011-02-19 21:51:21 -08:00
|
|
|
struct {
|
Implemented more flexible blending modes for accelerated renderers
This fixes bug 2594 - Propose new blend mode, SDL_BLENDMODE_BLEND_DSTA
blendMode = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_SRC_ALPHA,
SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
SDL_BLENDOPERATION_ADD,
SDL_BLENDFACTOR_ZERO,
SDL_BLENDFACTOR_ONE,
SDL_BLENDOPERATION_ADD);
This fixes bug 2828 - Subtractive Blending
blendMode = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_SRC_ALPHA,
SDL_BLENDFACTOR_ONE,
SDL_BLENDOPERATION_SUBTRACT,
SDL_BLENDFACTOR_ZERO,
SDL_BLENDFACTOR_ONE,
SDL_BLENDOPERATION_SUBTRACT);
This goes partway to fixing bug 3684 - Add support for a pre-multiplied alpha blending mode
blendMode = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_ONE,
SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
SDL_BLENDOPERATION_ADD,
SDL_BLENDFACTOR_ONE,
SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
SDL_BLENDOPERATION_ADD);
2017-08-14 05:51:44 -07:00
|
|
|
SDL_BlendMode blendMode;
|
2011-02-19 21:51:21 -08:00
|
|
|
SDL_bool tex_coords;
|
|
|
|
} current;
|
|
|
|
|
Fixed bug 1242 - PATCH: Improve support for OpenGL ES under X11
Scott Percival 2011-07-03 06:41:51 PDT
This submission is aimed at making life easier for OpenGL ES capable devices
running a X11 stack (e.g. Maemo, Meego, TrimSlice, other ARM SoC boards not
running Android). SDL's Pandora support already has the neccesary GLES-to-X11
glue code, however it's all ghetto'd off in Makefile.pandora and not very
flexible.
The patch:
- adds an awesome --enable-video-opengles option to configure
- re-modifies the opengles and opengles2 SDL_renderers to use function pointers
- no idea why this was removed?
- for SDL_Renderers, links in libGLESv1_CM, libGLES_CM (for PowerVR fans) or
libGLESv2 at runtime
- links in libEGL.so at runtime - the old code made an assumption that
eglFunctions could be pulled from the active GLES library, PowerVR for one
doesn't let you do that with their libGLESv2
- allows you to pick which of GLES v1 or v2 to load via
SDL_GL_CONTEXT_MAJOR_VERSION
So far I've tested this on a Nokia N900 (OMAP 3430/SGX 530 running Maemo 5) and
a Toshiba AC100 (Tegra 2 running Ubuntu 10.10). I haven't tested it on... well,
everything that isn't those two, such as a Pandora, iOS or Android device. The
Pandora specific code should be kept intact (fingers crossed), and nothing
painfully drastic has been added to the SDL_renderers. The library loading
sequence in SDL_x11opengles has been updated to accomodate both NVIDIA's
propensity to let developers get away with murder and PowerVR's alternative of
punishing every missed step.
The test apps work okay with GLES or GLES2 as the renderer. For some reason
alpha blending doesn't seem to work on the Tegra 2; last week NVIDIA pushed out
a new set of X11 GLES drivers, so I'll try and investigate once I upgrade
those. Also, this patch adds things to configure.in, include/SDL_config.h.in
and test/configure.in. I didn't know what the policy was re. committing
generated spaghetti from autotools, so ./autogen.sh has to be run again. Sorry.
I think that's about everything, let me know if there's anything I've
overlooked.
2012-01-08 02:23:37 -05:00
|
|
|
#define SDL_PROC(ret,func,params) ret (APIENTRY *func) params;
|
|
|
|
#include "SDL_gles2funcs.h"
|
|
|
|
#undef SDL_PROC
|
2012-01-18 22:45:49 -05:00
|
|
|
GLES2_FBOList *framebuffers;
|
2012-01-30 20:56:25 -05:00
|
|
|
GLuint window_framebuffer;
|
Fixed bug 1242 - PATCH: Improve support for OpenGL ES under X11
Scott Percival 2011-07-03 06:41:51 PDT
This submission is aimed at making life easier for OpenGL ES capable devices
running a X11 stack (e.g. Maemo, Meego, TrimSlice, other ARM SoC boards not
running Android). SDL's Pandora support already has the neccesary GLES-to-X11
glue code, however it's all ghetto'd off in Makefile.pandora and not very
flexible.
The patch:
- adds an awesome --enable-video-opengles option to configure
- re-modifies the opengles and opengles2 SDL_renderers to use function pointers
- no idea why this was removed?
- for SDL_Renderers, links in libGLESv1_CM, libGLES_CM (for PowerVR fans) or
libGLESv2 at runtime
- links in libEGL.so at runtime - the old code made an assumption that
eglFunctions could be pulled from the active GLES library, PowerVR for one
doesn't let you do that with their libGLESv2
- allows you to pick which of GLES v1 or v2 to load via
SDL_GL_CONTEXT_MAJOR_VERSION
So far I've tested this on a Nokia N900 (OMAP 3430/SGX 530 running Maemo 5) and
a Toshiba AC100 (Tegra 2 running Ubuntu 10.10). I haven't tested it on... well,
everything that isn't those two, such as a Pandora, iOS or Android device. The
Pandora specific code should be kept intact (fingers crossed), and nothing
painfully drastic has been added to the SDL_renderers. The library loading
sequence in SDL_x11opengles has been updated to accomodate both NVIDIA's
propensity to let developers get away with murder and PowerVR's alternative of
punishing every missed step.
The test apps work okay with GLES or GLES2 as the renderer. For some reason
alpha blending doesn't seem to work on the Tegra 2; last week NVIDIA pushed out
a new set of X11 GLES drivers, so I'll try and investigate once I upgrade
those. Also, this patch adds things to configure.in, include/SDL_config.h.in
and test/configure.in. I didn't know what the policy was re. committing
generated spaghetti from autotools, so ./autogen.sh has to be run again. Sorry.
I think that's about everything, let me know if there's anything I've
overlooked.
2012-01-08 02:23:37 -05:00
|
|
|
|
2011-02-06 00:00:13 -08:00
|
|
|
int shader_format_count;
|
|
|
|
GLenum *shader_formats;
|
|
|
|
GLES2_ShaderCache shader_cache;
|
|
|
|
GLES2_ProgramCache program_cache;
|
|
|
|
GLES2_ProgramCacheEntry *current_program;
|
2013-10-05 00:29:57 -04:00
|
|
|
Uint8 clear_r, clear_g, clear_b, clear_a;
|
Initial merge of Emscripten port!
With this commit, you can compile SDL2 with Emscripten
( http://emscripten.org/ ), and make your SDL-based C/C++ program
into a web app.
This port was due to the efforts of several people, including: Charlie Birks,
Sathyanarayanan Gunasekaran, Jukka Jylänki, Alon Zakai, Edward Rudd,
Bruce Mitchener, and Martin Gerhardy. (Thanks, everyone!)
--HG--
extra : rebase_source : 97af74c8a5121e926ebe89f123536b5dd6681695
2014-12-18 00:19:52 -05:00
|
|
|
|
2014-12-26 22:30:19 -05:00
|
|
|
#if SDL_GLES2_USE_VBOS
|
Initial merge of Emscripten port!
With this commit, you can compile SDL2 with Emscripten
( http://emscripten.org/ ), and make your SDL-based C/C++ program
into a web app.
This port was due to the efforts of several people, including: Charlie Birks,
Sathyanarayanan Gunasekaran, Jukka Jylänki, Alon Zakai, Edward Rudd,
Bruce Mitchener, and Martin Gerhardy. (Thanks, everyone!)
--HG--
extra : rebase_source : 97af74c8a5121e926ebe89f123536b5dd6681695
2014-12-18 00:19:52 -05:00
|
|
|
GLuint vertex_buffers[4];
|
|
|
|
GLsizeiptr vertex_buffer_size[4];
|
2014-12-26 22:30:19 -05:00
|
|
|
#endif
|
2011-02-06 00:00:13 -08:00
|
|
|
} GLES2_DriverContext;
|
|
|
|
|
|
|
|
#define GLES2_MAX_CACHED_PROGRAMS 8
|
|
|
|
|
2013-10-03 20:48:52 -07:00
|
|
|
|
|
|
|
SDL_FORCE_INLINE const char*
|
|
|
|
GL_TranslateError (GLenum error)
|
|
|
|
{
|
|
|
|
#define GL_ERROR_TRANSLATE(e) case e: return #e;
|
|
|
|
switch (error) {
|
|
|
|
GL_ERROR_TRANSLATE(GL_INVALID_ENUM)
|
|
|
|
GL_ERROR_TRANSLATE(GL_INVALID_VALUE)
|
|
|
|
GL_ERROR_TRANSLATE(GL_INVALID_OPERATION)
|
|
|
|
GL_ERROR_TRANSLATE(GL_OUT_OF_MEMORY)
|
|
|
|
GL_ERROR_TRANSLATE(GL_NO_ERROR)
|
|
|
|
default:
|
|
|
|
return "UNKNOWN";
|
|
|
|
}
|
|
|
|
#undef GL_ERROR_TRANSLATE
|
|
|
|
}
|
|
|
|
|
|
|
|
SDL_FORCE_INLINE void
|
|
|
|
GL_ClearErrors(SDL_Renderer *renderer)
|
|
|
|
{
|
|
|
|
GLES2_DriverContext *data = (GLES2_DriverContext *) renderer->driverdata;
|
|
|
|
|
2015-05-16 17:35:36 -03:00
|
|
|
if (!data->debug_enabled) {
|
2013-10-03 20:48:52 -07:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
while (data->glGetError() != GL_NO_ERROR) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
SDL_FORCE_INLINE int
|
|
|
|
GL_CheckAllErrors (const char *prefix, SDL_Renderer *renderer, const char *file, int line, const char *function)
|
|
|
|
{
|
|
|
|
GLES2_DriverContext *data = (GLES2_DriverContext *) renderer->driverdata;
|
|
|
|
int ret = 0;
|
|
|
|
|
2015-05-16 17:35:36 -03:00
|
|
|
if (!data->debug_enabled) {
|
2013-10-03 20:48:52 -07:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
/* check gl errors (can return multiple errors) */
|
|
|
|
for (;;) {
|
|
|
|
GLenum error = data->glGetError();
|
|
|
|
if (error != GL_NO_ERROR) {
|
|
|
|
if (prefix == NULL || prefix[0] == '\0') {
|
|
|
|
prefix = "generic";
|
|
|
|
}
|
|
|
|
SDL_SetError("%s: %s (%d): %s %s (0x%X)", prefix, file, line, function, GL_TranslateError(error), error);
|
|
|
|
ret = -1;
|
|
|
|
} else {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
#define GL_CheckError(prefix, renderer)
|
2017-08-17 21:35:46 -04:00
|
|
|
#elif defined(_MSC_VER) || defined(__WATCOMC__)
|
2013-10-03 20:48:52 -07:00
|
|
|
#define GL_CheckError(prefix, renderer) GL_CheckAllErrors(prefix, renderer, __FILE__, __LINE__, __FUNCTION__)
|
|
|
|
#else
|
|
|
|
#define GL_CheckError(prefix, renderer) GL_CheckAllErrors(prefix, renderer, __FILE__, __LINE__, __PRETTY_FUNCTION__)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
2011-02-06 00:00:13 -08:00
|
|
|
/*************************************************************************************************
|
|
|
|
* Renderer state APIs *
|
|
|
|
*************************************************************************************************/
|
|
|
|
|
2011-02-07 20:06:26 -08:00
|
|
|
static int GLES2_ActivateRenderer(SDL_Renderer *renderer);
|
2011-02-06 00:00:13 -08:00
|
|
|
static void GLES2_WindowEvent(SDL_Renderer * renderer,
|
|
|
|
const SDL_WindowEvent *event);
|
2011-02-15 13:59:59 -08:00
|
|
|
static int GLES2_UpdateViewport(SDL_Renderer * renderer);
|
2011-02-06 00:00:13 -08:00
|
|
|
static void GLES2_DestroyRenderer(SDL_Renderer *renderer);
|
2012-01-21 22:22:30 -05:00
|
|
|
static int GLES2_SetOrthographicProjection(SDL_Renderer *renderer);
|
2011-02-06 00:00:13 -08:00
|
|
|
|
2012-01-18 22:45:49 -05:00
|
|
|
|
2011-02-06 00:00:13 -08:00
|
|
|
static SDL_GLContext SDL_CurrentContext = NULL;
|
|
|
|
|
Fixed bug 1242 - PATCH: Improve support for OpenGL ES under X11
Scott Percival 2011-07-03 06:41:51 PDT
This submission is aimed at making life easier for OpenGL ES capable devices
running a X11 stack (e.g. Maemo, Meego, TrimSlice, other ARM SoC boards not
running Android). SDL's Pandora support already has the neccesary GLES-to-X11
glue code, however it's all ghetto'd off in Makefile.pandora and not very
flexible.
The patch:
- adds an awesome --enable-video-opengles option to configure
- re-modifies the opengles and opengles2 SDL_renderers to use function pointers
- no idea why this was removed?
- for SDL_Renderers, links in libGLESv1_CM, libGLES_CM (for PowerVR fans) or
libGLESv2 at runtime
- links in libEGL.so at runtime - the old code made an assumption that
eglFunctions could be pulled from the active GLES library, PowerVR for one
doesn't let you do that with their libGLESv2
- allows you to pick which of GLES v1 or v2 to load via
SDL_GL_CONTEXT_MAJOR_VERSION
So far I've tested this on a Nokia N900 (OMAP 3430/SGX 530 running Maemo 5) and
a Toshiba AC100 (Tegra 2 running Ubuntu 10.10). I haven't tested it on... well,
everything that isn't those two, such as a Pandora, iOS or Android device. The
Pandora specific code should be kept intact (fingers crossed), and nothing
painfully drastic has been added to the SDL_renderers. The library loading
sequence in SDL_x11opengles has been updated to accomodate both NVIDIA's
propensity to let developers get away with murder and PowerVR's alternative of
punishing every missed step.
The test apps work okay with GLES or GLES2 as the renderer. For some reason
alpha blending doesn't seem to work on the Tegra 2; last week NVIDIA pushed out
a new set of X11 GLES drivers, so I'll try and investigate once I upgrade
those. Also, this patch adds things to configure.in, include/SDL_config.h.in
and test/configure.in. I didn't know what the policy was re. committing
generated spaghetti from autotools, so ./autogen.sh has to be run again. Sorry.
I think that's about everything, let me know if there's anything I've
overlooked.
2012-01-08 02:23:37 -05:00
|
|
|
static int GLES2_LoadFunctions(GLES2_DriverContext * data)
|
|
|
|
{
|
2012-01-08 13:31:22 -05:00
|
|
|
#if SDL_VIDEO_DRIVER_UIKIT
|
|
|
|
#define __SDL_NOGETPROCADDR__
|
|
|
|
#elif SDL_VIDEO_DRIVER_ANDROID
|
|
|
|
#define __SDL_NOGETPROCADDR__
|
|
|
|
#elif SDL_VIDEO_DRIVER_PANDORA
|
|
|
|
#define __SDL_NOGETPROCADDR__
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if defined __SDL_NOGETPROCADDR__
|
Fixed bug 1242 - PATCH: Improve support for OpenGL ES under X11
Scott Percival 2011-07-03 06:41:51 PDT
This submission is aimed at making life easier for OpenGL ES capable devices
running a X11 stack (e.g. Maemo, Meego, TrimSlice, other ARM SoC boards not
running Android). SDL's Pandora support already has the neccesary GLES-to-X11
glue code, however it's all ghetto'd off in Makefile.pandora and not very
flexible.
The patch:
- adds an awesome --enable-video-opengles option to configure
- re-modifies the opengles and opengles2 SDL_renderers to use function pointers
- no idea why this was removed?
- for SDL_Renderers, links in libGLESv1_CM, libGLES_CM (for PowerVR fans) or
libGLESv2 at runtime
- links in libEGL.so at runtime - the old code made an assumption that
eglFunctions could be pulled from the active GLES library, PowerVR for one
doesn't let you do that with their libGLESv2
- allows you to pick which of GLES v1 or v2 to load via
SDL_GL_CONTEXT_MAJOR_VERSION
So far I've tested this on a Nokia N900 (OMAP 3430/SGX 530 running Maemo 5) and
a Toshiba AC100 (Tegra 2 running Ubuntu 10.10). I haven't tested it on... well,
everything that isn't those two, such as a Pandora, iOS or Android device. The
Pandora specific code should be kept intact (fingers crossed), and nothing
painfully drastic has been added to the SDL_renderers. The library loading
sequence in SDL_x11opengles has been updated to accomodate both NVIDIA's
propensity to let developers get away with murder and PowerVR's alternative of
punishing every missed step.
The test apps work okay with GLES or GLES2 as the renderer. For some reason
alpha blending doesn't seem to work on the Tegra 2; last week NVIDIA pushed out
a new set of X11 GLES drivers, so I'll try and investigate once I upgrade
those. Also, this patch adds things to configure.in, include/SDL_config.h.in
and test/configure.in. I didn't know what the policy was re. committing
generated spaghetti from autotools, so ./autogen.sh has to be run again. Sorry.
I think that's about everything, let me know if there's anything I've
overlooked.
2012-01-08 02:23:37 -05:00
|
|
|
#define SDL_PROC(ret,func,params) data->func=func;
|
|
|
|
#else
|
|
|
|
#define SDL_PROC(ret,func,params) \
|
|
|
|
do { \
|
|
|
|
data->func = SDL_GL_GetProcAddress(#func); \
|
|
|
|
if ( ! data->func ) { \
|
2017-03-26 21:00:19 +02:00
|
|
|
return SDL_SetError("Couldn't load GLES2 function %s: %s", #func, SDL_GetError()); \
|
Fixed bug 1242 - PATCH: Improve support for OpenGL ES under X11
Scott Percival 2011-07-03 06:41:51 PDT
This submission is aimed at making life easier for OpenGL ES capable devices
running a X11 stack (e.g. Maemo, Meego, TrimSlice, other ARM SoC boards not
running Android). SDL's Pandora support already has the neccesary GLES-to-X11
glue code, however it's all ghetto'd off in Makefile.pandora and not very
flexible.
The patch:
- adds an awesome --enable-video-opengles option to configure
- re-modifies the opengles and opengles2 SDL_renderers to use function pointers
- no idea why this was removed?
- for SDL_Renderers, links in libGLESv1_CM, libGLES_CM (for PowerVR fans) or
libGLESv2 at runtime
- links in libEGL.so at runtime - the old code made an assumption that
eglFunctions could be pulled from the active GLES library, PowerVR for one
doesn't let you do that with their libGLESv2
- allows you to pick which of GLES v1 or v2 to load via
SDL_GL_CONTEXT_MAJOR_VERSION
So far I've tested this on a Nokia N900 (OMAP 3430/SGX 530 running Maemo 5) and
a Toshiba AC100 (Tegra 2 running Ubuntu 10.10). I haven't tested it on... well,
everything that isn't those two, such as a Pandora, iOS or Android device. The
Pandora specific code should be kept intact (fingers crossed), and nothing
painfully drastic has been added to the SDL_renderers. The library loading
sequence in SDL_x11opengles has been updated to accomodate both NVIDIA's
propensity to let developers get away with murder and PowerVR's alternative of
punishing every missed step.
The test apps work okay with GLES or GLES2 as the renderer. For some reason
alpha blending doesn't seem to work on the Tegra 2; last week NVIDIA pushed out
a new set of X11 GLES drivers, so I'll try and investigate once I upgrade
those. Also, this patch adds things to configure.in, include/SDL_config.h.in
and test/configure.in. I didn't know what the policy was re. committing
generated spaghetti from autotools, so ./autogen.sh has to be run again. Sorry.
I think that's about everything, let me know if there's anything I've
overlooked.
2012-01-08 02:23:37 -05:00
|
|
|
} \
|
2012-01-18 22:45:49 -05:00
|
|
|
} while ( 0 );
|
2015-06-05 19:41:18 +02:00
|
|
|
#endif /* __SDL_NOGETPROCADDR__ */
|
Fixed bug 1242 - PATCH: Improve support for OpenGL ES under X11
Scott Percival 2011-07-03 06:41:51 PDT
This submission is aimed at making life easier for OpenGL ES capable devices
running a X11 stack (e.g. Maemo, Meego, TrimSlice, other ARM SoC boards not
running Android). SDL's Pandora support already has the neccesary GLES-to-X11
glue code, however it's all ghetto'd off in Makefile.pandora and not very
flexible.
The patch:
- adds an awesome --enable-video-opengles option to configure
- re-modifies the opengles and opengles2 SDL_renderers to use function pointers
- no idea why this was removed?
- for SDL_Renderers, links in libGLESv1_CM, libGLES_CM (for PowerVR fans) or
libGLESv2 at runtime
- links in libEGL.so at runtime - the old code made an assumption that
eglFunctions could be pulled from the active GLES library, PowerVR for one
doesn't let you do that with their libGLESv2
- allows you to pick which of GLES v1 or v2 to load via
SDL_GL_CONTEXT_MAJOR_VERSION
So far I've tested this on a Nokia N900 (OMAP 3430/SGX 530 running Maemo 5) and
a Toshiba AC100 (Tegra 2 running Ubuntu 10.10). I haven't tested it on... well,
everything that isn't those two, such as a Pandora, iOS or Android device. The
Pandora specific code should be kept intact (fingers crossed), and nothing
painfully drastic has been added to the SDL_renderers. The library loading
sequence in SDL_x11opengles has been updated to accomodate both NVIDIA's
propensity to let developers get away with murder and PowerVR's alternative of
punishing every missed step.
The test apps work okay with GLES or GLES2 as the renderer. For some reason
alpha blending doesn't seem to work on the Tegra 2; last week NVIDIA pushed out
a new set of X11 GLES drivers, so I'll try and investigate once I upgrade
those. Also, this patch adds things to configure.in, include/SDL_config.h.in
and test/configure.in. I didn't know what the policy was re. committing
generated spaghetti from autotools, so ./autogen.sh has to be run again. Sorry.
I think that's about everything, let me know if there's anything I've
overlooked.
2012-01-08 02:23:37 -05:00
|
|
|
|
|
|
|
#include "SDL_gles2funcs.h"
|
|
|
|
#undef SDL_PROC
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-11-13 22:57:41 -08:00
|
|
|
static GLES2_FBOList *
|
2012-01-18 22:45:49 -05:00
|
|
|
GLES2_GetFBO(GLES2_DriverContext *data, Uint32 w, Uint32 h)
|
|
|
|
{
|
|
|
|
GLES2_FBOList *result = data->framebuffers;
|
2015-05-16 17:35:36 -03:00
|
|
|
while ((result) && ((result->w != w) || (result->h != h)) ) {
|
2012-01-18 22:45:49 -05:00
|
|
|
result = result->next;
|
|
|
|
}
|
2015-05-16 17:35:36 -03:00
|
|
|
if (result == NULL) {
|
2012-01-18 22:45:49 -05:00
|
|
|
result = SDL_malloc(sizeof(GLES2_FBOList));
|
|
|
|
result->w = w;
|
|
|
|
result->h = h;
|
2012-01-28 14:53:23 -05:00
|
|
|
data->glGenFramebuffers(1, &result->FBO);
|
2012-01-18 22:45:49 -05:00
|
|
|
result->next = data->framebuffers;
|
|
|
|
data->framebuffers = result;
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2011-02-06 00:00:13 -08:00
|
|
|
static int
|
|
|
|
GLES2_ActivateRenderer(SDL_Renderer * renderer)
|
|
|
|
{
|
2013-10-03 20:48:52 -07:00
|
|
|
GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->driverdata;
|
2011-02-06 00:00:13 -08:00
|
|
|
|
2013-10-03 20:48:52 -07:00
|
|
|
if (SDL_CurrentContext != data->context) {
|
2011-02-06 00:00:13 -08:00
|
|
|
/* Null out the current program to ensure we set it again */
|
2013-10-03 20:48:52 -07:00
|
|
|
data->current_program = NULL;
|
2011-02-06 00:00:13 -08:00
|
|
|
|
2013-10-03 20:48:52 -07:00
|
|
|
if (SDL_GL_MakeCurrent(renderer->window, data->context) < 0) {
|
2011-02-06 00:00:13 -08:00
|
|
|
return -1;
|
|
|
|
}
|
2013-10-03 20:48:52 -07:00
|
|
|
SDL_CurrentContext = data->context;
|
2011-02-06 00:00:13 -08:00
|
|
|
|
2011-02-15 13:59:59 -08:00
|
|
|
GLES2_UpdateViewport(renderer);
|
2011-02-06 00:00:13 -08:00
|
|
|
}
|
2013-10-03 20:48:52 -07:00
|
|
|
|
|
|
|
GL_ClearErrors(renderer);
|
|
|
|
|
2011-02-06 00:00:13 -08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
GLES2_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event)
|
|
|
|
{
|
2013-10-03 20:48:52 -07:00
|
|
|
GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->driverdata;
|
2012-01-18 22:45:49 -05:00
|
|
|
|
2012-01-22 21:46:06 -05:00
|
|
|
if (event->event == SDL_WINDOWEVENT_SIZE_CHANGED ||
|
|
|
|
event->event == SDL_WINDOWEVENT_SHOWN ||
|
|
|
|
event->event == SDL_WINDOWEVENT_HIDDEN) {
|
2011-02-06 00:00:13 -08:00
|
|
|
/* Rebind the context to the window area */
|
|
|
|
SDL_CurrentContext = NULL;
|
|
|
|
}
|
2011-11-07 23:07:00 -05:00
|
|
|
|
|
|
|
if (event->event == SDL_WINDOWEVENT_MINIMIZED) {
|
|
|
|
/* According to Apple documentation, we need to finish drawing NOW! */
|
2013-10-03 20:48:52 -07:00
|
|
|
data->glFinish();
|
2011-11-07 23:07:00 -05:00
|
|
|
}
|
2011-02-06 00:00:13 -08:00
|
|
|
}
|
|
|
|
|
2014-12-01 07:31:22 -04:00
|
|
|
static int
|
|
|
|
GLES2_GetOutputSize(SDL_Renderer * renderer, int *w, int *h)
|
|
|
|
{
|
|
|
|
SDL_GL_GetDrawableSize(renderer->window, w, h);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
Implemented more flexible blending modes for accelerated renderers
This fixes bug 2594 - Propose new blend mode, SDL_BLENDMODE_BLEND_DSTA
blendMode = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_SRC_ALPHA,
SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
SDL_BLENDOPERATION_ADD,
SDL_BLENDFACTOR_ZERO,
SDL_BLENDFACTOR_ONE,
SDL_BLENDOPERATION_ADD);
This fixes bug 2828 - Subtractive Blending
blendMode = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_SRC_ALPHA,
SDL_BLENDFACTOR_ONE,
SDL_BLENDOPERATION_SUBTRACT,
SDL_BLENDFACTOR_ZERO,
SDL_BLENDFACTOR_ONE,
SDL_BLENDOPERATION_SUBTRACT);
This goes partway to fixing bug 3684 - Add support for a pre-multiplied alpha blending mode
blendMode = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_ONE,
SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
SDL_BLENDOPERATION_ADD,
SDL_BLENDFACTOR_ONE,
SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
SDL_BLENDOPERATION_ADD);
2017-08-14 05:51:44 -07:00
|
|
|
static GLenum GetBlendFunc(SDL_BlendFactor factor)
|
|
|
|
{
|
|
|
|
switch (factor) {
|
|
|
|
case SDL_BLENDFACTOR_ZERO:
|
|
|
|
return GL_ZERO;
|
|
|
|
case SDL_BLENDFACTOR_ONE:
|
|
|
|
return GL_ONE;
|
|
|
|
case SDL_BLENDFACTOR_SRC_COLOR:
|
|
|
|
return GL_SRC_COLOR;
|
|
|
|
case SDL_BLENDFACTOR_ONE_MINUS_SRC_COLOR:
|
|
|
|
return GL_ONE_MINUS_SRC_COLOR;
|
|
|
|
case SDL_BLENDFACTOR_SRC_ALPHA:
|
|
|
|
return GL_SRC_ALPHA;
|
|
|
|
case SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA:
|
|
|
|
return GL_ONE_MINUS_SRC_ALPHA;
|
|
|
|
case SDL_BLENDFACTOR_DST_COLOR:
|
|
|
|
return GL_DST_COLOR;
|
|
|
|
case SDL_BLENDFACTOR_ONE_MINUS_DST_COLOR:
|
|
|
|
return GL_ONE_MINUS_DST_COLOR;
|
|
|
|
case SDL_BLENDFACTOR_DST_ALPHA:
|
|
|
|
return GL_DST_ALPHA;
|
|
|
|
case SDL_BLENDFACTOR_ONE_MINUS_DST_ALPHA:
|
|
|
|
return GL_ONE_MINUS_DST_ALPHA;
|
|
|
|
default:
|
|
|
|
return GL_INVALID_ENUM;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static GLenum GetBlendEquation(SDL_BlendOperation operation)
|
|
|
|
{
|
|
|
|
switch (operation) {
|
|
|
|
case SDL_BLENDOPERATION_ADD:
|
|
|
|
return GL_FUNC_ADD;
|
|
|
|
case SDL_BLENDOPERATION_SUBTRACT:
|
|
|
|
return GL_FUNC_SUBTRACT;
|
|
|
|
case SDL_BLENDOPERATION_REV_SUBTRACT:
|
|
|
|
return GL_FUNC_REVERSE_SUBTRACT;
|
|
|
|
default:
|
|
|
|
return GL_INVALID_ENUM;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static SDL_bool
|
|
|
|
GLES2_SupportsBlendMode(SDL_Renderer * renderer, SDL_BlendMode blendMode)
|
|
|
|
{
|
|
|
|
SDL_BlendFactor srcColorFactor = SDL_GetBlendModeSrcColorFactor(blendMode);
|
|
|
|
SDL_BlendFactor srcAlphaFactor = SDL_GetBlendModeSrcAlphaFactor(blendMode);
|
|
|
|
SDL_BlendOperation colorOperation = SDL_GetBlendModeColorOperation(blendMode);
|
|
|
|
SDL_BlendFactor dstColorFactor = SDL_GetBlendModeDstColorFactor(blendMode);
|
|
|
|
SDL_BlendFactor dstAlphaFactor = SDL_GetBlendModeDstAlphaFactor(blendMode);
|
|
|
|
SDL_BlendOperation alphaOperation = SDL_GetBlendModeAlphaOperation(blendMode);
|
|
|
|
|
|
|
|
if (GetBlendFunc(srcColorFactor) == GL_INVALID_ENUM ||
|
|
|
|
GetBlendFunc(srcAlphaFactor) == GL_INVALID_ENUM ||
|
|
|
|
GetBlendEquation(colorOperation) == GL_INVALID_ENUM ||
|
|
|
|
GetBlendFunc(dstColorFactor) == GL_INVALID_ENUM ||
|
|
|
|
GetBlendFunc(dstAlphaFactor) == GL_INVALID_ENUM ||
|
|
|
|
GetBlendEquation(alphaOperation) == GL_INVALID_ENUM) {
|
|
|
|
return SDL_FALSE;
|
|
|
|
}
|
|
|
|
return SDL_TRUE;
|
|
|
|
}
|
|
|
|
|
2011-02-15 13:59:59 -08:00
|
|
|
static int
|
|
|
|
GLES2_UpdateViewport(SDL_Renderer * renderer)
|
2011-02-07 20:06:26 -08:00
|
|
|
{
|
2013-10-03 20:48:52 -07:00
|
|
|
GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->driverdata;
|
2011-02-07 20:06:26 -08:00
|
|
|
|
2013-10-03 20:48:52 -07:00
|
|
|
if (SDL_CurrentContext != data->context) {
|
2011-02-15 13:59:59 -08:00
|
|
|
/* We'll update the viewport after we rebind the context */
|
|
|
|
return 0;
|
2011-02-07 20:06:26 -08:00
|
|
|
}
|
2011-02-15 13:59:59 -08:00
|
|
|
|
2015-05-28 18:57:10 -07:00
|
|
|
if (renderer->target) {
|
|
|
|
data->glViewport(renderer->viewport.x, renderer->viewport.y,
|
|
|
|
renderer->viewport.w, renderer->viewport.h);
|
|
|
|
} else {
|
|
|
|
int w, h;
|
|
|
|
|
2016-10-13 08:46:34 -07:00
|
|
|
SDL_GL_GetDrawableSize(renderer->window, &w, &h);
|
2015-05-28 18:57:10 -07:00
|
|
|
data->glViewport(renderer->viewport.x, (h - renderer->viewport.y - renderer->viewport.h),
|
|
|
|
renderer->viewport.w, renderer->viewport.h);
|
|
|
|
}
|
2012-01-28 14:05:48 -05:00
|
|
|
|
2013-10-03 20:48:52 -07:00
|
|
|
if (data->current_program) {
|
2012-01-28 14:05:48 -05:00
|
|
|
GLES2_SetOrthographicProjection(renderer);
|
|
|
|
}
|
2013-10-03 20:48:52 -07:00
|
|
|
return GL_CheckError("", renderer);
|
2011-02-07 20:06:26 -08:00
|
|
|
}
|
|
|
|
|
2013-05-04 04:46:00 -07:00
|
|
|
static int
|
|
|
|
GLES2_UpdateClipRect(SDL_Renderer * renderer)
|
|
|
|
{
|
2013-10-03 20:48:52 -07:00
|
|
|
GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->driverdata;
|
2013-05-04 04:46:00 -07:00
|
|
|
|
2013-10-03 20:48:52 -07:00
|
|
|
if (SDL_CurrentContext != data->context) {
|
2013-05-10 10:31:01 -03:00
|
|
|
/* We'll update the clip rect after we rebind the context */
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2014-04-19 13:15:41 -07:00
|
|
|
if (renderer->clipping_enabled) {
|
|
|
|
const SDL_Rect *rect = &renderer->clip_rect;
|
2013-10-03 20:48:52 -07:00
|
|
|
data->glEnable(GL_SCISSOR_TEST);
|
2015-05-28 18:57:10 -07:00
|
|
|
if (renderer->target) {
|
|
|
|
data->glScissor(renderer->viewport.x + rect->x, renderer->viewport.y + rect->y, rect->w, rect->h);
|
|
|
|
} else {
|
|
|
|
int w, h;
|
|
|
|
|
2016-10-13 08:46:34 -07:00
|
|
|
SDL_GL_GetDrawableSize(renderer->window, &w, &h);
|
2015-12-28 15:15:58 -05:00
|
|
|
data->glScissor(renderer->viewport.x + rect->x, h - renderer->viewport.y - rect->y - rect->h, rect->w, rect->h);
|
2015-05-28 18:57:10 -07:00
|
|
|
}
|
2013-05-04 04:46:00 -07:00
|
|
|
} else {
|
2013-10-03 20:48:52 -07:00
|
|
|
data->glDisable(GL_SCISSOR_TEST);
|
2013-05-04 04:46:00 -07:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2011-02-06 00:00:13 -08:00
|
|
|
static void
|
|
|
|
GLES2_DestroyRenderer(SDL_Renderer *renderer)
|
|
|
|
{
|
2013-10-03 20:48:52 -07:00
|
|
|
GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->driverdata;
|
2011-02-06 00:00:13 -08:00
|
|
|
|
|
|
|
/* Deallocate everything */
|
2013-10-03 20:48:52 -07:00
|
|
|
if (data) {
|
2011-02-06 10:22:25 -08:00
|
|
|
GLES2_ActivateRenderer(renderer);
|
|
|
|
|
2012-01-07 22:33:58 -05:00
|
|
|
{
|
|
|
|
GLES2_ShaderCacheEntry *entry;
|
|
|
|
GLES2_ShaderCacheEntry *next;
|
2013-10-03 20:48:52 -07:00
|
|
|
entry = data->shader_cache.head;
|
2015-05-16 17:35:36 -03:00
|
|
|
while (entry) {
|
2013-10-03 20:48:52 -07:00
|
|
|
data->glDeleteShader(entry->id);
|
2011-11-07 00:45:13 -05:00
|
|
|
next = entry->next;
|
|
|
|
SDL_free(entry);
|
|
|
|
entry = next;
|
2012-01-07 22:33:58 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
{
|
|
|
|
GLES2_ProgramCacheEntry *entry;
|
|
|
|
GLES2_ProgramCacheEntry *next;
|
2013-10-03 20:48:52 -07:00
|
|
|
entry = data->program_cache.head;
|
2011-11-07 00:45:13 -05:00
|
|
|
while (entry) {
|
2013-10-03 20:48:52 -07:00
|
|
|
data->glDeleteProgram(entry->id);
|
2011-11-07 00:45:13 -05:00
|
|
|
next = entry->next;
|
|
|
|
SDL_free(entry);
|
|
|
|
entry = next;
|
|
|
|
}
|
2012-01-07 22:33:58 -05:00
|
|
|
}
|
2013-10-03 20:48:52 -07:00
|
|
|
if (data->context) {
|
|
|
|
while (data->framebuffers) {
|
|
|
|
GLES2_FBOList *nextnode = data->framebuffers->next;
|
|
|
|
data->glDeleteFramebuffers(1, &data->framebuffers->FBO);
|
|
|
|
GL_CheckError("", renderer);
|
|
|
|
SDL_free(data->framebuffers);
|
|
|
|
data->framebuffers = nextnode;
|
2012-01-18 22:45:49 -05:00
|
|
|
}
|
2013-10-03 20:48:52 -07:00
|
|
|
SDL_GL_DeleteContext(data->context);
|
2011-02-06 10:22:25 -08:00
|
|
|
}
|
2013-10-03 20:48:52 -07:00
|
|
|
SDL_free(data->shader_formats);
|
|
|
|
SDL_free(data);
|
2011-02-06 00:00:13 -08:00
|
|
|
}
|
|
|
|
SDL_free(renderer);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************************************
|
|
|
|
* Texture APIs *
|
|
|
|
*************************************************************************************************/
|
|
|
|
|
|
|
|
static int GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture);
|
2013-10-03 20:48:52 -07:00
|
|
|
static int GLES2_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect,
|
|
|
|
const void *pixels, int pitch);
|
2014-06-07 11:36:08 -07:00
|
|
|
static int GLES2_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * texture,
|
|
|
|
const SDL_Rect * rect,
|
|
|
|
const Uint8 *Yplane, int Ypitch,
|
|
|
|
const Uint8 *Uplane, int Upitch,
|
|
|
|
const Uint8 *Vplane, int Vpitch);
|
2011-02-06 00:00:13 -08:00
|
|
|
static int GLES2_LockTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect,
|
|
|
|
void **pixels, int *pitch);
|
|
|
|
static void GLES2_UnlockTexture(SDL_Renderer *renderer, SDL_Texture *texture);
|
2012-01-22 01:26:28 -05:00
|
|
|
static int GLES2_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture);
|
2013-10-03 20:48:52 -07:00
|
|
|
static void GLES2_DestroyTexture(SDL_Renderer *renderer, SDL_Texture *texture);
|
2011-02-06 00:00:13 -08:00
|
|
|
|
2011-03-13 11:18:35 -07:00
|
|
|
static GLenum
|
|
|
|
GetScaleQuality(void)
|
|
|
|
{
|
|
|
|
const char *hint = SDL_GetHint(SDL_HINT_RENDER_SCALE_QUALITY);
|
|
|
|
|
|
|
|
if (!hint || *hint == '0' || SDL_strcasecmp(hint, "nearest") == 0) {
|
|
|
|
return GL_NEAREST;
|
|
|
|
} else {
|
|
|
|
return GL_LINEAR;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-02-06 00:00:13 -08:00
|
|
|
static int
|
|
|
|
GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture)
|
|
|
|
{
|
2013-10-03 20:48:52 -07:00
|
|
|
GLES2_DriverContext *renderdata = (GLES2_DriverContext *)renderer->driverdata;
|
|
|
|
GLES2_TextureData *data;
|
2011-02-06 00:00:13 -08:00
|
|
|
GLenum format;
|
|
|
|
GLenum type;
|
2011-03-21 17:15:49 -07:00
|
|
|
GLenum scaleMode;
|
2011-02-06 00:00:13 -08:00
|
|
|
|
|
|
|
GLES2_ActivateRenderer(renderer);
|
|
|
|
|
|
|
|
/* Determine the corresponding GLES texture format params */
|
|
|
|
switch (texture->format)
|
|
|
|
{
|
2011-12-29 05:11:33 -05:00
|
|
|
case SDL_PIXELFORMAT_ARGB8888:
|
2014-06-21 21:46:42 -07:00
|
|
|
case SDL_PIXELFORMAT_ABGR8888:
|
2011-12-29 05:11:33 -05:00
|
|
|
case SDL_PIXELFORMAT_RGB888:
|
2014-06-21 21:46:42 -07:00
|
|
|
case SDL_PIXELFORMAT_BGR888:
|
2011-02-06 00:00:13 -08:00
|
|
|
format = GL_RGBA;
|
|
|
|
type = GL_UNSIGNED_BYTE;
|
|
|
|
break;
|
2014-06-07 11:36:08 -07:00
|
|
|
case SDL_PIXELFORMAT_IYUV:
|
|
|
|
case SDL_PIXELFORMAT_YV12:
|
2014-08-06 11:34:54 -07:00
|
|
|
case SDL_PIXELFORMAT_NV12:
|
|
|
|
case SDL_PIXELFORMAT_NV21:
|
2014-06-07 11:36:08 -07:00
|
|
|
format = GL_LUMINANCE;
|
|
|
|
type = GL_UNSIGNED_BYTE;
|
|
|
|
break;
|
2011-02-06 00:00:13 -08:00
|
|
|
default:
|
2013-03-31 12:48:50 -04:00
|
|
|
return SDL_SetError("Texture format not supported");
|
2011-02-06 00:00:13 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Allocate a texture struct */
|
2013-10-03 20:48:52 -07:00
|
|
|
data = (GLES2_TextureData *)SDL_calloc(1, sizeof(GLES2_TextureData));
|
|
|
|
if (!data) {
|
2013-03-31 12:48:50 -04:00
|
|
|
return SDL_OutOfMemory();
|
2011-02-06 00:00:13 -08:00
|
|
|
}
|
2013-10-03 20:48:52 -07:00
|
|
|
data->texture = 0;
|
|
|
|
data->texture_type = GL_TEXTURE_2D;
|
|
|
|
data->pixel_format = format;
|
|
|
|
data->pixel_type = type;
|
2014-06-07 11:36:08 -07:00
|
|
|
data->yuv = ((texture->format == SDL_PIXELFORMAT_IYUV) || (texture->format == SDL_PIXELFORMAT_YV12));
|
2014-08-06 11:34:54 -07:00
|
|
|
data->nv12 = ((texture->format == SDL_PIXELFORMAT_NV12) || (texture->format == SDL_PIXELFORMAT_NV21));
|
2014-06-07 11:36:08 -07:00
|
|
|
data->texture_u = 0;
|
|
|
|
data->texture_v = 0;
|
2011-03-21 17:15:49 -07:00
|
|
|
scaleMode = GetScaleQuality();
|
2011-02-06 00:00:13 -08:00
|
|
|
|
2013-10-03 20:48:52 -07:00
|
|
|
/* Allocate a blob for image renderdata */
|
2013-03-31 12:48:50 -04:00
|
|
|
if (texture->access == SDL_TEXTUREACCESS_STREAMING) {
|
2014-06-07 11:36:08 -07:00
|
|
|
size_t size;
|
2013-10-03 20:48:52 -07:00
|
|
|
data->pitch = texture->w * SDL_BYTESPERPIXEL(texture->format);
|
2014-06-07 11:36:08 -07:00
|
|
|
size = texture->h * data->pitch;
|
|
|
|
if (data->yuv) {
|
|
|
|
/* Need to add size for the U and V planes */
|
Fixed bug 3857 - SDL_ConvertPixels misses YUV conversions
Sylvain
Few issues with YUV on SDL2 when using odd dimensions, and missing conversions from/back to YUV formats.
1) The big part is that SDL_ConvertPixels() does not convert to/from YUV in most cases. This now works with any format and also with odd dimensions,
by adding two internal functions SDL_ConvertPixels_YUV_to_ARGB8888 and SDL_ConvertPixels_ARGB8888_to_YUV (could it be XRGB888 ?).
The target format is hard coded to ARGB888 (which is the default in the internal of the software renderer).
In case of different YUV conversion, it will do an intermediate conversion to a ARGB8888 buffer.
SDL_ConvertPixels_YUV_to_ARGB8888 is somehow redundant with all the "Color*Dither*Mod*".
But it allows some completeness of SDL_ConvertPixels to handle all YUV format.
It also works with odd dimensions.
Moreover, I did some benchmark(SDL_ConvertPixel vs Color32DitherYV12Mod1X and Color32DitherYUY2Mod1X).
gcc-6.3 and clang-4.0. gcc performs better than clang. And, with gcc, SDL_ConvertPixels() performs better (20%) than the two C function Color32Dither*().
For instance, to convert 10 times a 3888x2592 image, it takes ~195 ms with SDL_ConvertPixels and ~235 ms with Color32Dither*().
Especially because of gcc vectorize feature that optimises all conversion loops (-ftree-loop-vectorize).
Nb: I put no image pitch for the YUV buffers. because it complexify a little bit the code and the API :
There would be some ambiguity when setting the pitch exactly to image width:
would it a be pitch of image width (for luma and chroma). or just contiguous data ? (could set pitch=0 for the later).
2) Small issues with odd dimensions:
If width "w" is odd, luma plane width is still "w" whereas chroma planes will be "(w + 1)/2". Almost the same for odd h.
Solution is to strategically substitute "w" by "(w+1)/2" at the good places ...
- In the repository, SDL_ConvertPixels() handles YUV only if yuv source format is exactly the same as YUV destination format.
It basically does a memcpy of pixels, but it's done incorrectly when width or height is odd (wrong size of chroma planes). This is fixed.
- SDL Renderers don't support odd width/height for YUV textures.
This is fixed for software, opengl, opengles2. (opengles 1 does not support it and fallback to software rendering).
This is *not* fixed for D3D and D3D11 ... (and others, psp ?)
Only *two* Dither function are fixed ... not sure if others are really used.
- This is not possible to create a NV12/NV12 texture with the software renderer, whereas other renderers allow it.
This is fixed, by using SDL_ConvertPixels underneath.
- It was not possible to SDL_UpdateTexture() of format NV12/NV21 with the software renderer. this is fixed.
Here's also two testcases:
- that do all combination of conversion.
- to test partial UpdateTexture
2017-10-06 16:50:24 -07:00
|
|
|
size += 2 * ((texture->h + 1) / 2) * ((data->pitch + 1) / 2);
|
2014-06-07 11:36:08 -07:00
|
|
|
}
|
2014-08-06 11:34:54 -07:00
|
|
|
if (data->nv12) {
|
|
|
|
/* Need to add size for the U/V plane */
|
Fixed bug 3857 - SDL_ConvertPixels misses YUV conversions
Sylvain
Few issues with YUV on SDL2 when using odd dimensions, and missing conversions from/back to YUV formats.
1) The big part is that SDL_ConvertPixels() does not convert to/from YUV in most cases. This now works with any format and also with odd dimensions,
by adding two internal functions SDL_ConvertPixels_YUV_to_ARGB8888 and SDL_ConvertPixels_ARGB8888_to_YUV (could it be XRGB888 ?).
The target format is hard coded to ARGB888 (which is the default in the internal of the software renderer).
In case of different YUV conversion, it will do an intermediate conversion to a ARGB8888 buffer.
SDL_ConvertPixels_YUV_to_ARGB8888 is somehow redundant with all the "Color*Dither*Mod*".
But it allows some completeness of SDL_ConvertPixels to handle all YUV format.
It also works with odd dimensions.
Moreover, I did some benchmark(SDL_ConvertPixel vs Color32DitherYV12Mod1X and Color32DitherYUY2Mod1X).
gcc-6.3 and clang-4.0. gcc performs better than clang. And, with gcc, SDL_ConvertPixels() performs better (20%) than the two C function Color32Dither*().
For instance, to convert 10 times a 3888x2592 image, it takes ~195 ms with SDL_ConvertPixels and ~235 ms with Color32Dither*().
Especially because of gcc vectorize feature that optimises all conversion loops (-ftree-loop-vectorize).
Nb: I put no image pitch for the YUV buffers. because it complexify a little bit the code and the API :
There would be some ambiguity when setting the pitch exactly to image width:
would it a be pitch of image width (for luma and chroma). or just contiguous data ? (could set pitch=0 for the later).
2) Small issues with odd dimensions:
If width "w" is odd, luma plane width is still "w" whereas chroma planes will be "(w + 1)/2". Almost the same for odd h.
Solution is to strategically substitute "w" by "(w+1)/2" at the good places ...
- In the repository, SDL_ConvertPixels() handles YUV only if yuv source format is exactly the same as YUV destination format.
It basically does a memcpy of pixels, but it's done incorrectly when width or height is odd (wrong size of chroma planes). This is fixed.
- SDL Renderers don't support odd width/height for YUV textures.
This is fixed for software, opengl, opengles2. (opengles 1 does not support it and fallback to software rendering).
This is *not* fixed for D3D and D3D11 ... (and others, psp ?)
Only *two* Dither function are fixed ... not sure if others are really used.
- This is not possible to create a NV12/NV12 texture with the software renderer, whereas other renderers allow it.
This is fixed, by using SDL_ConvertPixels underneath.
- It was not possible to SDL_UpdateTexture() of format NV12/NV21 with the software renderer. this is fixed.
Here's also two testcases:
- that do all combination of conversion.
- to test partial UpdateTexture
2017-10-06 16:50:24 -07:00
|
|
|
size += 2 * ((texture->h + 1) / 2) * ((data->pitch + 1) / 2);
|
2014-08-06 11:34:54 -07:00
|
|
|
}
|
2014-06-07 11:36:08 -07:00
|
|
|
data->pixel_data = SDL_calloc(1, size);
|
2013-10-03 20:48:52 -07:00
|
|
|
if (!data->pixel_data) {
|
|
|
|
SDL_free(data);
|
2013-03-31 12:48:50 -04:00
|
|
|
return SDL_OutOfMemory();
|
2011-02-06 00:00:13 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Allocate the texture */
|
2013-10-03 20:48:52 -07:00
|
|
|
GL_CheckError("", renderer);
|
2014-06-07 11:36:08 -07:00
|
|
|
|
|
|
|
if (data->yuv) {
|
|
|
|
renderdata->glGenTextures(1, &data->texture_v);
|
|
|
|
if (GL_CheckError("glGenTexures()", renderer) < 0) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
renderdata->glActiveTexture(GL_TEXTURE2);
|
|
|
|
renderdata->glBindTexture(data->texture_type, data->texture_v);
|
|
|
|
renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_MIN_FILTER, scaleMode);
|
|
|
|
renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_MAG_FILTER, scaleMode);
|
|
|
|
renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
|
|
|
renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
Fixed bug 3857 - SDL_ConvertPixels misses YUV conversions
Sylvain
Few issues with YUV on SDL2 when using odd dimensions, and missing conversions from/back to YUV formats.
1) The big part is that SDL_ConvertPixels() does not convert to/from YUV in most cases. This now works with any format and also with odd dimensions,
by adding two internal functions SDL_ConvertPixels_YUV_to_ARGB8888 and SDL_ConvertPixels_ARGB8888_to_YUV (could it be XRGB888 ?).
The target format is hard coded to ARGB888 (which is the default in the internal of the software renderer).
In case of different YUV conversion, it will do an intermediate conversion to a ARGB8888 buffer.
SDL_ConvertPixels_YUV_to_ARGB8888 is somehow redundant with all the "Color*Dither*Mod*".
But it allows some completeness of SDL_ConvertPixels to handle all YUV format.
It also works with odd dimensions.
Moreover, I did some benchmark(SDL_ConvertPixel vs Color32DitherYV12Mod1X and Color32DitherYUY2Mod1X).
gcc-6.3 and clang-4.0. gcc performs better than clang. And, with gcc, SDL_ConvertPixels() performs better (20%) than the two C function Color32Dither*().
For instance, to convert 10 times a 3888x2592 image, it takes ~195 ms with SDL_ConvertPixels and ~235 ms with Color32Dither*().
Especially because of gcc vectorize feature that optimises all conversion loops (-ftree-loop-vectorize).
Nb: I put no image pitch for the YUV buffers. because it complexify a little bit the code and the API :
There would be some ambiguity when setting the pitch exactly to image width:
would it a be pitch of image width (for luma and chroma). or just contiguous data ? (could set pitch=0 for the later).
2) Small issues with odd dimensions:
If width "w" is odd, luma plane width is still "w" whereas chroma planes will be "(w + 1)/2". Almost the same for odd h.
Solution is to strategically substitute "w" by "(w+1)/2" at the good places ...
- In the repository, SDL_ConvertPixels() handles YUV only if yuv source format is exactly the same as YUV destination format.
It basically does a memcpy of pixels, but it's done incorrectly when width or height is odd (wrong size of chroma planes). This is fixed.
- SDL Renderers don't support odd width/height for YUV textures.
This is fixed for software, opengl, opengles2. (opengles 1 does not support it and fallback to software rendering).
This is *not* fixed for D3D and D3D11 ... (and others, psp ?)
Only *two* Dither function are fixed ... not sure if others are really used.
- This is not possible to create a NV12/NV12 texture with the software renderer, whereas other renderers allow it.
This is fixed, by using SDL_ConvertPixels underneath.
- It was not possible to SDL_UpdateTexture() of format NV12/NV21 with the software renderer. this is fixed.
Here's also two testcases:
- that do all combination of conversion.
- to test partial UpdateTexture
2017-10-06 16:50:24 -07:00
|
|
|
renderdata->glTexImage2D(data->texture_type, 0, format, (texture->w + 1) / 2, (texture->h + 1) / 2, 0, format, type, NULL);
|
2014-06-07 11:36:08 -07:00
|
|
|
|
|
|
|
renderdata->glGenTextures(1, &data->texture_u);
|
|
|
|
if (GL_CheckError("glGenTexures()", renderer) < 0) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
renderdata->glActiveTexture(GL_TEXTURE1);
|
|
|
|
renderdata->glBindTexture(data->texture_type, data->texture_u);
|
|
|
|
renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_MIN_FILTER, scaleMode);
|
|
|
|
renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_MAG_FILTER, scaleMode);
|
|
|
|
renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
|
|
|
renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
Fixed bug 3857 - SDL_ConvertPixels misses YUV conversions
Sylvain
Few issues with YUV on SDL2 when using odd dimensions, and missing conversions from/back to YUV formats.
1) The big part is that SDL_ConvertPixels() does not convert to/from YUV in most cases. This now works with any format and also with odd dimensions,
by adding two internal functions SDL_ConvertPixels_YUV_to_ARGB8888 and SDL_ConvertPixels_ARGB8888_to_YUV (could it be XRGB888 ?).
The target format is hard coded to ARGB888 (which is the default in the internal of the software renderer).
In case of different YUV conversion, it will do an intermediate conversion to a ARGB8888 buffer.
SDL_ConvertPixels_YUV_to_ARGB8888 is somehow redundant with all the "Color*Dither*Mod*".
But it allows some completeness of SDL_ConvertPixels to handle all YUV format.
It also works with odd dimensions.
Moreover, I did some benchmark(SDL_ConvertPixel vs Color32DitherYV12Mod1X and Color32DitherYUY2Mod1X).
gcc-6.3 and clang-4.0. gcc performs better than clang. And, with gcc, SDL_ConvertPixels() performs better (20%) than the two C function Color32Dither*().
For instance, to convert 10 times a 3888x2592 image, it takes ~195 ms with SDL_ConvertPixels and ~235 ms with Color32Dither*().
Especially because of gcc vectorize feature that optimises all conversion loops (-ftree-loop-vectorize).
Nb: I put no image pitch for the YUV buffers. because it complexify a little bit the code and the API :
There would be some ambiguity when setting the pitch exactly to image width:
would it a be pitch of image width (for luma and chroma). or just contiguous data ? (could set pitch=0 for the later).
2) Small issues with odd dimensions:
If width "w" is odd, luma plane width is still "w" whereas chroma planes will be "(w + 1)/2". Almost the same for odd h.
Solution is to strategically substitute "w" by "(w+1)/2" at the good places ...
- In the repository, SDL_ConvertPixels() handles YUV only if yuv source format is exactly the same as YUV destination format.
It basically does a memcpy of pixels, but it's done incorrectly when width or height is odd (wrong size of chroma planes). This is fixed.
- SDL Renderers don't support odd width/height for YUV textures.
This is fixed for software, opengl, opengles2. (opengles 1 does not support it and fallback to software rendering).
This is *not* fixed for D3D and D3D11 ... (and others, psp ?)
Only *two* Dither function are fixed ... not sure if others are really used.
- This is not possible to create a NV12/NV12 texture with the software renderer, whereas other renderers allow it.
This is fixed, by using SDL_ConvertPixels underneath.
- It was not possible to SDL_UpdateTexture() of format NV12/NV21 with the software renderer. this is fixed.
Here's also two testcases:
- that do all combination of conversion.
- to test partial UpdateTexture
2017-10-06 16:50:24 -07:00
|
|
|
renderdata->glTexImage2D(data->texture_type, 0, format, (texture->w + 1) / 2, (texture->h + 1) / 2, 0, format, type, NULL);
|
2014-06-07 11:36:08 -07:00
|
|
|
if (GL_CheckError("glTexImage2D()", renderer) < 0) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-08-06 11:34:54 -07:00
|
|
|
if (data->nv12) {
|
|
|
|
renderdata->glGenTextures(1, &data->texture_u);
|
|
|
|
if (GL_CheckError("glGenTexures()", renderer) < 0) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
renderdata->glActiveTexture(GL_TEXTURE1);
|
|
|
|
renderdata->glBindTexture(data->texture_type, data->texture_u);
|
|
|
|
renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_MIN_FILTER, scaleMode);
|
|
|
|
renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_MAG_FILTER, scaleMode);
|
|
|
|
renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
|
|
|
renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
Fixed bug 3857 - SDL_ConvertPixels misses YUV conversions
Sylvain
Few issues with YUV on SDL2 when using odd dimensions, and missing conversions from/back to YUV formats.
1) The big part is that SDL_ConvertPixels() does not convert to/from YUV in most cases. This now works with any format and also with odd dimensions,
by adding two internal functions SDL_ConvertPixels_YUV_to_ARGB8888 and SDL_ConvertPixels_ARGB8888_to_YUV (could it be XRGB888 ?).
The target format is hard coded to ARGB888 (which is the default in the internal of the software renderer).
In case of different YUV conversion, it will do an intermediate conversion to a ARGB8888 buffer.
SDL_ConvertPixels_YUV_to_ARGB8888 is somehow redundant with all the "Color*Dither*Mod*".
But it allows some completeness of SDL_ConvertPixels to handle all YUV format.
It also works with odd dimensions.
Moreover, I did some benchmark(SDL_ConvertPixel vs Color32DitherYV12Mod1X and Color32DitherYUY2Mod1X).
gcc-6.3 and clang-4.0. gcc performs better than clang. And, with gcc, SDL_ConvertPixels() performs better (20%) than the two C function Color32Dither*().
For instance, to convert 10 times a 3888x2592 image, it takes ~195 ms with SDL_ConvertPixels and ~235 ms with Color32Dither*().
Especially because of gcc vectorize feature that optimises all conversion loops (-ftree-loop-vectorize).
Nb: I put no image pitch for the YUV buffers. because it complexify a little bit the code and the API :
There would be some ambiguity when setting the pitch exactly to image width:
would it a be pitch of image width (for luma and chroma). or just contiguous data ? (could set pitch=0 for the later).
2) Small issues with odd dimensions:
If width "w" is odd, luma plane width is still "w" whereas chroma planes will be "(w + 1)/2". Almost the same for odd h.
Solution is to strategically substitute "w" by "(w+1)/2" at the good places ...
- In the repository, SDL_ConvertPixels() handles YUV only if yuv source format is exactly the same as YUV destination format.
It basically does a memcpy of pixels, but it's done incorrectly when width or height is odd (wrong size of chroma planes). This is fixed.
- SDL Renderers don't support odd width/height for YUV textures.
This is fixed for software, opengl, opengles2. (opengles 1 does not support it and fallback to software rendering).
This is *not* fixed for D3D and D3D11 ... (and others, psp ?)
Only *two* Dither function are fixed ... not sure if others are really used.
- This is not possible to create a NV12/NV12 texture with the software renderer, whereas other renderers allow it.
This is fixed, by using SDL_ConvertPixels underneath.
- It was not possible to SDL_UpdateTexture() of format NV12/NV21 with the software renderer. this is fixed.
Here's also two testcases:
- that do all combination of conversion.
- to test partial UpdateTexture
2017-10-06 16:50:24 -07:00
|
|
|
renderdata->glTexImage2D(data->texture_type, 0, GL_LUMINANCE_ALPHA, (texture->w + 1) / 2, (texture->h + 1) / 2, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, NULL);
|
2014-08-06 11:34:54 -07:00
|
|
|
if (GL_CheckError("glTexImage2D()", renderer) < 0) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-10-03 20:48:52 -07:00
|
|
|
renderdata->glGenTextures(1, &data->texture);
|
|
|
|
if (GL_CheckError("glGenTexures()", renderer) < 0) {
|
|
|
|
return -1;
|
2012-01-18 22:45:49 -05:00
|
|
|
}
|
2013-10-03 20:48:52 -07:00
|
|
|
texture->driverdata = data;
|
2014-06-07 11:36:08 -07:00
|
|
|
renderdata->glActiveTexture(GL_TEXTURE0);
|
2013-10-03 20:48:52 -07:00
|
|
|
renderdata->glBindTexture(data->texture_type, data->texture);
|
|
|
|
renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_MIN_FILTER, scaleMode);
|
|
|
|
renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_MAG_FILTER, scaleMode);
|
|
|
|
renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
|
|
|
renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
|
|
|
renderdata->glTexImage2D(data->texture_type, 0, format, texture->w, texture->h, 0, format, type, NULL);
|
|
|
|
if (GL_CheckError("glTexImage2D()", renderer) < 0) {
|
|
|
|
return -1;
|
2011-02-06 00:00:13 -08:00
|
|
|
}
|
|
|
|
|
2013-10-03 20:48:52 -07:00
|
|
|
if (texture->access == SDL_TEXTUREACCESS_TARGET) {
|
|
|
|
data->fbo = GLES2_GetFBO(renderer->driverdata, texture->w, texture->h);
|
|
|
|
} else {
|
|
|
|
data->fbo = NULL;
|
|
|
|
}
|
2011-02-08 10:38:12 -08:00
|
|
|
|
2013-10-03 20:48:52 -07:00
|
|
|
return GL_CheckError("", renderer);
|
2011-02-06 00:00:13 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
Fixed bug 2595 - Padded, non-contiguous YUV does not display correctly using OpenGL ES 2.0 renderer
Alvin
The new OpenGL ES 2.0 YUV Texture support does not correctly display padded, non-contiguous YUV data.
I am using SDL2 60edb019f0fe (as provided by 'hg id --id') from Mercurial.
The YUV data I am using is provided by the FFMPEG family of libraries. According to FFMPEG's documentation, "The linesize [pitch] may be larger than the size of usable data -- there may be extra padding present for performance reasons."
The dimensions of the video file that I am using are 480x360. What I get from FFMPEG is a Ypitch of 512, and Upitch and Vpitch are both 256.
When I pack new Y, U and V buffers with only the "usable" data (Ypitch is 480 and Upitch and Vpitch are both 240), and use those new buffers, the image is display correctly.
It appears that the Ypitch, Upitch and Vpitch parameters are not being used by SDL_UpdateYUVTexture().
I use SDL_PIXELFORMAT_YV12 for my YUV texture, however, the same results are seen when I use SDL_PIXELFORMAT_IYUV.
Not sure if this is related or not, but when I render the YUV texture (padded and unpadded) to a RGB24 texture, the resulting image is greyscale (or could by just the Y channel).
The URL field for this bug entry is set to my email (SDL mailing list archive) which includes an example image of what I see when rendering padded, non-contiguous YUV data.
2014-06-21 12:38:46 -07:00
|
|
|
GLES2_TexSubImage2D(GLES2_DriverContext *data, GLenum target, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels, GLint pitch, GLint bpp)
|
2011-02-06 00:00:13 -08:00
|
|
|
{
|
|
|
|
Uint8 *blob = NULL;
|
|
|
|
Uint8 *src;
|
Fixed bug 2595 - Padded, non-contiguous YUV does not display correctly using OpenGL ES 2.0 renderer
Alvin
The new OpenGL ES 2.0 YUV Texture support does not correctly display padded, non-contiguous YUV data.
I am using SDL2 60edb019f0fe (as provided by 'hg id --id') from Mercurial.
The YUV data I am using is provided by the FFMPEG family of libraries. According to FFMPEG's documentation, "The linesize [pitch] may be larger than the size of usable data -- there may be extra padding present for performance reasons."
The dimensions of the video file that I am using are 480x360. What I get from FFMPEG is a Ypitch of 512, and Upitch and Vpitch are both 256.
When I pack new Y, U and V buffers with only the "usable" data (Ypitch is 480 and Upitch and Vpitch are both 240), and use those new buffers, the image is display correctly.
It appears that the Ypitch, Upitch and Vpitch parameters are not being used by SDL_UpdateYUVTexture().
I use SDL_PIXELFORMAT_YV12 for my YUV texture, however, the same results are seen when I use SDL_PIXELFORMAT_IYUV.
Not sure if this is related or not, but when I render the YUV texture (padded and unpadded) to a RGB24 texture, the resulting image is greyscale (or could by just the Y channel).
The URL field for this bug entry is set to my email (SDL mailing list archive) which includes an example image of what I see when rendering padded, non-contiguous YUV data.
2014-06-21 12:38:46 -07:00
|
|
|
int src_pitch;
|
2011-02-06 00:00:13 -08:00
|
|
|
int y;
|
|
|
|
|
|
|
|
/* Reformat the texture data into a tightly packed array */
|
Fixed bug 2595 - Padded, non-contiguous YUV does not display correctly using OpenGL ES 2.0 renderer
Alvin
The new OpenGL ES 2.0 YUV Texture support does not correctly display padded, non-contiguous YUV data.
I am using SDL2 60edb019f0fe (as provided by 'hg id --id') from Mercurial.
The YUV data I am using is provided by the FFMPEG family of libraries. According to FFMPEG's documentation, "The linesize [pitch] may be larger than the size of usable data -- there may be extra padding present for performance reasons."
The dimensions of the video file that I am using are 480x360. What I get from FFMPEG is a Ypitch of 512, and Upitch and Vpitch are both 256.
When I pack new Y, U and V buffers with only the "usable" data (Ypitch is 480 and Upitch and Vpitch are both 240), and use those new buffers, the image is display correctly.
It appears that the Ypitch, Upitch and Vpitch parameters are not being used by SDL_UpdateYUVTexture().
I use SDL_PIXELFORMAT_YV12 for my YUV texture, however, the same results are seen when I use SDL_PIXELFORMAT_IYUV.
Not sure if this is related or not, but when I render the YUV texture (padded and unpadded) to a RGB24 texture, the resulting image is greyscale (or could by just the Y channel).
The URL field for this bug entry is set to my email (SDL mailing list archive) which includes an example image of what I see when rendering padded, non-contiguous YUV data.
2014-06-21 12:38:46 -07:00
|
|
|
src_pitch = width * bpp;
|
2014-06-25 00:58:40 -07:00
|
|
|
src = (Uint8 *)pixels;
|
Fixed bug 2595 - Padded, non-contiguous YUV does not display correctly using OpenGL ES 2.0 renderer
Alvin
The new OpenGL ES 2.0 YUV Texture support does not correctly display padded, non-contiguous YUV data.
I am using SDL2 60edb019f0fe (as provided by 'hg id --id') from Mercurial.
The YUV data I am using is provided by the FFMPEG family of libraries. According to FFMPEG's documentation, "The linesize [pitch] may be larger than the size of usable data -- there may be extra padding present for performance reasons."
The dimensions of the video file that I am using are 480x360. What I get from FFMPEG is a Ypitch of 512, and Upitch and Vpitch are both 256.
When I pack new Y, U and V buffers with only the "usable" data (Ypitch is 480 and Upitch and Vpitch are both 240), and use those new buffers, the image is display correctly.
It appears that the Ypitch, Upitch and Vpitch parameters are not being used by SDL_UpdateYUVTexture().
I use SDL_PIXELFORMAT_YV12 for my YUV texture, however, the same results are seen when I use SDL_PIXELFORMAT_IYUV.
Not sure if this is related or not, but when I render the YUV texture (padded and unpadded) to a RGB24 texture, the resulting image is greyscale (or could by just the Y channel).
The URL field for this bug entry is set to my email (SDL mailing list archive) which includes an example image of what I see when rendering padded, non-contiguous YUV data.
2014-06-21 12:38:46 -07:00
|
|
|
if (pitch != src_pitch) {
|
|
|
|
blob = (Uint8 *)SDL_malloc(src_pitch * height);
|
2013-03-31 12:48:50 -04:00
|
|
|
if (!blob) {
|
|
|
|
return SDL_OutOfMemory();
|
2011-02-06 00:00:13 -08:00
|
|
|
}
|
|
|
|
src = blob;
|
Fixed bug 2595 - Padded, non-contiguous YUV does not display correctly using OpenGL ES 2.0 renderer
Alvin
The new OpenGL ES 2.0 YUV Texture support does not correctly display padded, non-contiguous YUV data.
I am using SDL2 60edb019f0fe (as provided by 'hg id --id') from Mercurial.
The YUV data I am using is provided by the FFMPEG family of libraries. According to FFMPEG's documentation, "The linesize [pitch] may be larger than the size of usable data -- there may be extra padding present for performance reasons."
The dimensions of the video file that I am using are 480x360. What I get from FFMPEG is a Ypitch of 512, and Upitch and Vpitch are both 256.
When I pack new Y, U and V buffers with only the "usable" data (Ypitch is 480 and Upitch and Vpitch are both 240), and use those new buffers, the image is display correctly.
It appears that the Ypitch, Upitch and Vpitch parameters are not being used by SDL_UpdateYUVTexture().
I use SDL_PIXELFORMAT_YV12 for my YUV texture, however, the same results are seen when I use SDL_PIXELFORMAT_IYUV.
Not sure if this is related or not, but when I render the YUV texture (padded and unpadded) to a RGB24 texture, the resulting image is greyscale (or could by just the Y channel).
The URL field for this bug entry is set to my email (SDL mailing list archive) which includes an example image of what I see when rendering padded, non-contiguous YUV data.
2014-06-21 12:38:46 -07:00
|
|
|
for (y = 0; y < height; ++y)
|
2011-02-06 00:00:13 -08:00
|
|
|
{
|
Fixed bug 2595 - Padded, non-contiguous YUV does not display correctly using OpenGL ES 2.0 renderer
Alvin
The new OpenGL ES 2.0 YUV Texture support does not correctly display padded, non-contiguous YUV data.
I am using SDL2 60edb019f0fe (as provided by 'hg id --id') from Mercurial.
The YUV data I am using is provided by the FFMPEG family of libraries. According to FFMPEG's documentation, "The linesize [pitch] may be larger than the size of usable data -- there may be extra padding present for performance reasons."
The dimensions of the video file that I am using are 480x360. What I get from FFMPEG is a Ypitch of 512, and Upitch and Vpitch are both 256.
When I pack new Y, U and V buffers with only the "usable" data (Ypitch is 480 and Upitch and Vpitch are both 240), and use those new buffers, the image is display correctly.
It appears that the Ypitch, Upitch and Vpitch parameters are not being used by SDL_UpdateYUVTexture().
I use SDL_PIXELFORMAT_YV12 for my YUV texture, however, the same results are seen when I use SDL_PIXELFORMAT_IYUV.
Not sure if this is related or not, but when I render the YUV texture (padded and unpadded) to a RGB24 texture, the resulting image is greyscale (or could by just the Y channel).
The URL field for this bug entry is set to my email (SDL mailing list archive) which includes an example image of what I see when rendering padded, non-contiguous YUV data.
2014-06-21 12:38:46 -07:00
|
|
|
SDL_memcpy(src, pixels, src_pitch);
|
|
|
|
src += src_pitch;
|
2011-02-06 00:00:13 -08:00
|
|
|
pixels = (Uint8 *)pixels + pitch;
|
|
|
|
}
|
|
|
|
src = blob;
|
|
|
|
}
|
|
|
|
|
Fixed bug 2595 - Padded, non-contiguous YUV does not display correctly using OpenGL ES 2.0 renderer
Alvin
The new OpenGL ES 2.0 YUV Texture support does not correctly display padded, non-contiguous YUV data.
I am using SDL2 60edb019f0fe (as provided by 'hg id --id') from Mercurial.
The YUV data I am using is provided by the FFMPEG family of libraries. According to FFMPEG's documentation, "The linesize [pitch] may be larger than the size of usable data -- there may be extra padding present for performance reasons."
The dimensions of the video file that I am using are 480x360. What I get from FFMPEG is a Ypitch of 512, and Upitch and Vpitch are both 256.
When I pack new Y, U and V buffers with only the "usable" data (Ypitch is 480 and Upitch and Vpitch are both 240), and use those new buffers, the image is display correctly.
It appears that the Ypitch, Upitch and Vpitch parameters are not being used by SDL_UpdateYUVTexture().
I use SDL_PIXELFORMAT_YV12 for my YUV texture, however, the same results are seen when I use SDL_PIXELFORMAT_IYUV.
Not sure if this is related or not, but when I render the YUV texture (padded and unpadded) to a RGB24 texture, the resulting image is greyscale (or could by just the Y channel).
The URL field for this bug entry is set to my email (SDL mailing list archive) which includes an example image of what I see when rendering padded, non-contiguous YUV data.
2014-06-21 12:38:46 -07:00
|
|
|
data->glTexSubImage2D(target, 0, xoffset, yoffset, width, height, format, type, src);
|
|
|
|
if (blob) {
|
|
|
|
SDL_free(blob);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
GLES2_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect,
|
|
|
|
const void *pixels, int pitch)
|
|
|
|
{
|
|
|
|
GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->driverdata;
|
|
|
|
GLES2_TextureData *tdata = (GLES2_TextureData *)texture->driverdata;
|
|
|
|
|
|
|
|
GLES2_ActivateRenderer(renderer);
|
|
|
|
|
|
|
|
/* Bail out if we're supposed to update an empty rectangle */
|
2015-05-16 17:35:36 -03:00
|
|
|
if (rect->w <= 0 || rect->h <= 0) {
|
Fixed bug 2595 - Padded, non-contiguous YUV does not display correctly using OpenGL ES 2.0 renderer
Alvin
The new OpenGL ES 2.0 YUV Texture support does not correctly display padded, non-contiguous YUV data.
I am using SDL2 60edb019f0fe (as provided by 'hg id --id') from Mercurial.
The YUV data I am using is provided by the FFMPEG family of libraries. According to FFMPEG's documentation, "The linesize [pitch] may be larger than the size of usable data -- there may be extra padding present for performance reasons."
The dimensions of the video file that I am using are 480x360. What I get from FFMPEG is a Ypitch of 512, and Upitch and Vpitch are both 256.
When I pack new Y, U and V buffers with only the "usable" data (Ypitch is 480 and Upitch and Vpitch are both 240), and use those new buffers, the image is display correctly.
It appears that the Ypitch, Upitch and Vpitch parameters are not being used by SDL_UpdateYUVTexture().
I use SDL_PIXELFORMAT_YV12 for my YUV texture, however, the same results are seen when I use SDL_PIXELFORMAT_IYUV.
Not sure if this is related or not, but when I render the YUV texture (padded and unpadded) to a RGB24 texture, the resulting image is greyscale (or could by just the Y channel).
The URL field for this bug entry is set to my email (SDL mailing list archive) which includes an example image of what I see when rendering padded, non-contiguous YUV data.
2014-06-21 12:38:46 -07:00
|
|
|
return 0;
|
2015-05-16 17:35:36 -03:00
|
|
|
}
|
Fixed bug 2595 - Padded, non-contiguous YUV does not display correctly using OpenGL ES 2.0 renderer
Alvin
The new OpenGL ES 2.0 YUV Texture support does not correctly display padded, non-contiguous YUV data.
I am using SDL2 60edb019f0fe (as provided by 'hg id --id') from Mercurial.
The YUV data I am using is provided by the FFMPEG family of libraries. According to FFMPEG's documentation, "The linesize [pitch] may be larger than the size of usable data -- there may be extra padding present for performance reasons."
The dimensions of the video file that I am using are 480x360. What I get from FFMPEG is a Ypitch of 512, and Upitch and Vpitch are both 256.
When I pack new Y, U and V buffers with only the "usable" data (Ypitch is 480 and Upitch and Vpitch are both 240), and use those new buffers, the image is display correctly.
It appears that the Ypitch, Upitch and Vpitch parameters are not being used by SDL_UpdateYUVTexture().
I use SDL_PIXELFORMAT_YV12 for my YUV texture, however, the same results are seen when I use SDL_PIXELFORMAT_IYUV.
Not sure if this is related or not, but when I render the YUV texture (padded and unpadded) to a RGB24 texture, the resulting image is greyscale (or could by just the Y channel).
The URL field for this bug entry is set to my email (SDL mailing list archive) which includes an example image of what I see when rendering padded, non-contiguous YUV data.
2014-06-21 12:38:46 -07:00
|
|
|
|
2011-02-06 00:00:13 -08:00
|
|
|
/* Create a texture subimage with the supplied data */
|
2013-10-03 20:48:52 -07:00
|
|
|
data->glBindTexture(tdata->texture_type, tdata->texture);
|
Fixed bug 2595 - Padded, non-contiguous YUV does not display correctly using OpenGL ES 2.0 renderer
Alvin
The new OpenGL ES 2.0 YUV Texture support does not correctly display padded, non-contiguous YUV data.
I am using SDL2 60edb019f0fe (as provided by 'hg id --id') from Mercurial.
The YUV data I am using is provided by the FFMPEG family of libraries. According to FFMPEG's documentation, "The linesize [pitch] may be larger than the size of usable data -- there may be extra padding present for performance reasons."
The dimensions of the video file that I am using are 480x360. What I get from FFMPEG is a Ypitch of 512, and Upitch and Vpitch are both 256.
When I pack new Y, U and V buffers with only the "usable" data (Ypitch is 480 and Upitch and Vpitch are both 240), and use those new buffers, the image is display correctly.
It appears that the Ypitch, Upitch and Vpitch parameters are not being used by SDL_UpdateYUVTexture().
I use SDL_PIXELFORMAT_YV12 for my YUV texture, however, the same results are seen when I use SDL_PIXELFORMAT_IYUV.
Not sure if this is related or not, but when I render the YUV texture (padded and unpadded) to a RGB24 texture, the resulting image is greyscale (or could by just the Y channel).
The URL field for this bug entry is set to my email (SDL mailing list archive) which includes an example image of what I see when rendering padded, non-contiguous YUV data.
2014-06-21 12:38:46 -07:00
|
|
|
GLES2_TexSubImage2D(data, tdata->texture_type,
|
2011-02-06 00:00:13 -08:00
|
|
|
rect->x,
|
|
|
|
rect->y,
|
|
|
|
rect->w,
|
|
|
|
rect->h,
|
|
|
|
tdata->pixel_format,
|
|
|
|
tdata->pixel_type,
|
Fixed bug 2595 - Padded, non-contiguous YUV does not display correctly using OpenGL ES 2.0 renderer
Alvin
The new OpenGL ES 2.0 YUV Texture support does not correctly display padded, non-contiguous YUV data.
I am using SDL2 60edb019f0fe (as provided by 'hg id --id') from Mercurial.
The YUV data I am using is provided by the FFMPEG family of libraries. According to FFMPEG's documentation, "The linesize [pitch] may be larger than the size of usable data -- there may be extra padding present for performance reasons."
The dimensions of the video file that I am using are 480x360. What I get from FFMPEG is a Ypitch of 512, and Upitch and Vpitch are both 256.
When I pack new Y, U and V buffers with only the "usable" data (Ypitch is 480 and Upitch and Vpitch are both 240), and use those new buffers, the image is display correctly.
It appears that the Ypitch, Upitch and Vpitch parameters are not being used by SDL_UpdateYUVTexture().
I use SDL_PIXELFORMAT_YV12 for my YUV texture, however, the same results are seen when I use SDL_PIXELFORMAT_IYUV.
Not sure if this is related or not, but when I render the YUV texture (padded and unpadded) to a RGB24 texture, the resulting image is greyscale (or could by just the Y channel).
The URL field for this bug entry is set to my email (SDL mailing list archive) which includes an example image of what I see when rendering padded, non-contiguous YUV data.
2014-06-21 12:38:46 -07:00
|
|
|
pixels, pitch, SDL_BYTESPERPIXEL(texture->format));
|
2011-02-06 20:56:21 -08:00
|
|
|
|
2014-06-25 00:58:40 -07:00
|
|
|
if (tdata->yuv) {
|
|
|
|
/* Skip to the correct offset into the next texture */
|
|
|
|
pixels = (const void*)((const Uint8*)pixels + rect->h * pitch);
|
|
|
|
if (texture->format == SDL_PIXELFORMAT_YV12) {
|
|
|
|
data->glBindTexture(tdata->texture_type, tdata->texture_v);
|
|
|
|
} else {
|
|
|
|
data->glBindTexture(tdata->texture_type, tdata->texture_u);
|
|
|
|
}
|
|
|
|
GLES2_TexSubImage2D(data, tdata->texture_type,
|
|
|
|
rect->x / 2,
|
|
|
|
rect->y / 2,
|
Fixed bug 3857 - SDL_ConvertPixels misses YUV conversions
Sylvain
Few issues with YUV on SDL2 when using odd dimensions, and missing conversions from/back to YUV formats.
1) The big part is that SDL_ConvertPixels() does not convert to/from YUV in most cases. This now works with any format and also with odd dimensions,
by adding two internal functions SDL_ConvertPixels_YUV_to_ARGB8888 and SDL_ConvertPixels_ARGB8888_to_YUV (could it be XRGB888 ?).
The target format is hard coded to ARGB888 (which is the default in the internal of the software renderer).
In case of different YUV conversion, it will do an intermediate conversion to a ARGB8888 buffer.
SDL_ConvertPixels_YUV_to_ARGB8888 is somehow redundant with all the "Color*Dither*Mod*".
But it allows some completeness of SDL_ConvertPixels to handle all YUV format.
It also works with odd dimensions.
Moreover, I did some benchmark(SDL_ConvertPixel vs Color32DitherYV12Mod1X and Color32DitherYUY2Mod1X).
gcc-6.3 and clang-4.0. gcc performs better than clang. And, with gcc, SDL_ConvertPixels() performs better (20%) than the two C function Color32Dither*().
For instance, to convert 10 times a 3888x2592 image, it takes ~195 ms with SDL_ConvertPixels and ~235 ms with Color32Dither*().
Especially because of gcc vectorize feature that optimises all conversion loops (-ftree-loop-vectorize).
Nb: I put no image pitch for the YUV buffers. because it complexify a little bit the code and the API :
There would be some ambiguity when setting the pitch exactly to image width:
would it a be pitch of image width (for luma and chroma). or just contiguous data ? (could set pitch=0 for the later).
2) Small issues with odd dimensions:
If width "w" is odd, luma plane width is still "w" whereas chroma planes will be "(w + 1)/2". Almost the same for odd h.
Solution is to strategically substitute "w" by "(w+1)/2" at the good places ...
- In the repository, SDL_ConvertPixels() handles YUV only if yuv source format is exactly the same as YUV destination format.
It basically does a memcpy of pixels, but it's done incorrectly when width or height is odd (wrong size of chroma planes). This is fixed.
- SDL Renderers don't support odd width/height for YUV textures.
This is fixed for software, opengl, opengles2. (opengles 1 does not support it and fallback to software rendering).
This is *not* fixed for D3D and D3D11 ... (and others, psp ?)
Only *two* Dither function are fixed ... not sure if others are really used.
- This is not possible to create a NV12/NV12 texture with the software renderer, whereas other renderers allow it.
This is fixed, by using SDL_ConvertPixels underneath.
- It was not possible to SDL_UpdateTexture() of format NV12/NV21 with the software renderer. this is fixed.
Here's also two testcases:
- that do all combination of conversion.
- to test partial UpdateTexture
2017-10-06 16:50:24 -07:00
|
|
|
(rect->w + 1) / 2,
|
|
|
|
(rect->h + 1) / 2,
|
2014-06-25 00:58:40 -07:00
|
|
|
tdata->pixel_format,
|
|
|
|
tdata->pixel_type,
|
Fixed bug 3857 - SDL_ConvertPixels misses YUV conversions
Sylvain
Few issues with YUV on SDL2 when using odd dimensions, and missing conversions from/back to YUV formats.
1) The big part is that SDL_ConvertPixels() does not convert to/from YUV in most cases. This now works with any format and also with odd dimensions,
by adding two internal functions SDL_ConvertPixels_YUV_to_ARGB8888 and SDL_ConvertPixels_ARGB8888_to_YUV (could it be XRGB888 ?).
The target format is hard coded to ARGB888 (which is the default in the internal of the software renderer).
In case of different YUV conversion, it will do an intermediate conversion to a ARGB8888 buffer.
SDL_ConvertPixels_YUV_to_ARGB8888 is somehow redundant with all the "Color*Dither*Mod*".
But it allows some completeness of SDL_ConvertPixels to handle all YUV format.
It also works with odd dimensions.
Moreover, I did some benchmark(SDL_ConvertPixel vs Color32DitherYV12Mod1X and Color32DitherYUY2Mod1X).
gcc-6.3 and clang-4.0. gcc performs better than clang. And, with gcc, SDL_ConvertPixels() performs better (20%) than the two C function Color32Dither*().
For instance, to convert 10 times a 3888x2592 image, it takes ~195 ms with SDL_ConvertPixels and ~235 ms with Color32Dither*().
Especially because of gcc vectorize feature that optimises all conversion loops (-ftree-loop-vectorize).
Nb: I put no image pitch for the YUV buffers. because it complexify a little bit the code and the API :
There would be some ambiguity when setting the pitch exactly to image width:
would it a be pitch of image width (for luma and chroma). or just contiguous data ? (could set pitch=0 for the later).
2) Small issues with odd dimensions:
If width "w" is odd, luma plane width is still "w" whereas chroma planes will be "(w + 1)/2". Almost the same for odd h.
Solution is to strategically substitute "w" by "(w+1)/2" at the good places ...
- In the repository, SDL_ConvertPixels() handles YUV only if yuv source format is exactly the same as YUV destination format.
It basically does a memcpy of pixels, but it's done incorrectly when width or height is odd (wrong size of chroma planes). This is fixed.
- SDL Renderers don't support odd width/height for YUV textures.
This is fixed for software, opengl, opengles2. (opengles 1 does not support it and fallback to software rendering).
This is *not* fixed for D3D and D3D11 ... (and others, psp ?)
Only *two* Dither function are fixed ... not sure if others are really used.
- This is not possible to create a NV12/NV12 texture with the software renderer, whereas other renderers allow it.
This is fixed, by using SDL_ConvertPixels underneath.
- It was not possible to SDL_UpdateTexture() of format NV12/NV21 with the software renderer. this is fixed.
Here's also two testcases:
- that do all combination of conversion.
- to test partial UpdateTexture
2017-10-06 16:50:24 -07:00
|
|
|
pixels, (pitch + 1) / 2, 1);
|
|
|
|
|
2014-06-25 00:58:40 -07:00
|
|
|
|
|
|
|
/* Skip to the correct offset into the next texture */
|
Fixed bug 3857 - SDL_ConvertPixels misses YUV conversions
Sylvain
Few issues with YUV on SDL2 when using odd dimensions, and missing conversions from/back to YUV formats.
1) The big part is that SDL_ConvertPixels() does not convert to/from YUV in most cases. This now works with any format and also with odd dimensions,
by adding two internal functions SDL_ConvertPixels_YUV_to_ARGB8888 and SDL_ConvertPixels_ARGB8888_to_YUV (could it be XRGB888 ?).
The target format is hard coded to ARGB888 (which is the default in the internal of the software renderer).
In case of different YUV conversion, it will do an intermediate conversion to a ARGB8888 buffer.
SDL_ConvertPixels_YUV_to_ARGB8888 is somehow redundant with all the "Color*Dither*Mod*".
But it allows some completeness of SDL_ConvertPixels to handle all YUV format.
It also works with odd dimensions.
Moreover, I did some benchmark(SDL_ConvertPixel vs Color32DitherYV12Mod1X and Color32DitherYUY2Mod1X).
gcc-6.3 and clang-4.0. gcc performs better than clang. And, with gcc, SDL_ConvertPixels() performs better (20%) than the two C function Color32Dither*().
For instance, to convert 10 times a 3888x2592 image, it takes ~195 ms with SDL_ConvertPixels and ~235 ms with Color32Dither*().
Especially because of gcc vectorize feature that optimises all conversion loops (-ftree-loop-vectorize).
Nb: I put no image pitch for the YUV buffers. because it complexify a little bit the code and the API :
There would be some ambiguity when setting the pitch exactly to image width:
would it a be pitch of image width (for luma and chroma). or just contiguous data ? (could set pitch=0 for the later).
2) Small issues with odd dimensions:
If width "w" is odd, luma plane width is still "w" whereas chroma planes will be "(w + 1)/2". Almost the same for odd h.
Solution is to strategically substitute "w" by "(w+1)/2" at the good places ...
- In the repository, SDL_ConvertPixels() handles YUV only if yuv source format is exactly the same as YUV destination format.
It basically does a memcpy of pixels, but it's done incorrectly when width or height is odd (wrong size of chroma planes). This is fixed.
- SDL Renderers don't support odd width/height for YUV textures.
This is fixed for software, opengl, opengles2. (opengles 1 does not support it and fallback to software rendering).
This is *not* fixed for D3D and D3D11 ... (and others, psp ?)
Only *two* Dither function are fixed ... not sure if others are really used.
- This is not possible to create a NV12/NV12 texture with the software renderer, whereas other renderers allow it.
This is fixed, by using SDL_ConvertPixels underneath.
- It was not possible to SDL_UpdateTexture() of format NV12/NV21 with the software renderer. this is fixed.
Here's also two testcases:
- that do all combination of conversion.
- to test partial UpdateTexture
2017-10-06 16:50:24 -07:00
|
|
|
pixels = (const void*)((const Uint8*)pixels + ((rect->h + 1) / 2) * ((pitch + 1)/2));
|
2014-06-25 00:58:40 -07:00
|
|
|
if (texture->format == SDL_PIXELFORMAT_YV12) {
|
|
|
|
data->glBindTexture(tdata->texture_type, tdata->texture_u);
|
|
|
|
} else {
|
|
|
|
data->glBindTexture(tdata->texture_type, tdata->texture_v);
|
|
|
|
}
|
|
|
|
GLES2_TexSubImage2D(data, tdata->texture_type,
|
|
|
|
rect->x / 2,
|
|
|
|
rect->y / 2,
|
Fixed bug 3857 - SDL_ConvertPixels misses YUV conversions
Sylvain
Few issues with YUV on SDL2 when using odd dimensions, and missing conversions from/back to YUV formats.
1) The big part is that SDL_ConvertPixels() does not convert to/from YUV in most cases. This now works with any format and also with odd dimensions,
by adding two internal functions SDL_ConvertPixels_YUV_to_ARGB8888 and SDL_ConvertPixels_ARGB8888_to_YUV (could it be XRGB888 ?).
The target format is hard coded to ARGB888 (which is the default in the internal of the software renderer).
In case of different YUV conversion, it will do an intermediate conversion to a ARGB8888 buffer.
SDL_ConvertPixels_YUV_to_ARGB8888 is somehow redundant with all the "Color*Dither*Mod*".
But it allows some completeness of SDL_ConvertPixels to handle all YUV format.
It also works with odd dimensions.
Moreover, I did some benchmark(SDL_ConvertPixel vs Color32DitherYV12Mod1X and Color32DitherYUY2Mod1X).
gcc-6.3 and clang-4.0. gcc performs better than clang. And, with gcc, SDL_ConvertPixels() performs better (20%) than the two C function Color32Dither*().
For instance, to convert 10 times a 3888x2592 image, it takes ~195 ms with SDL_ConvertPixels and ~235 ms with Color32Dither*().
Especially because of gcc vectorize feature that optimises all conversion loops (-ftree-loop-vectorize).
Nb: I put no image pitch for the YUV buffers. because it complexify a little bit the code and the API :
There would be some ambiguity when setting the pitch exactly to image width:
would it a be pitch of image width (for luma and chroma). or just contiguous data ? (could set pitch=0 for the later).
2) Small issues with odd dimensions:
If width "w" is odd, luma plane width is still "w" whereas chroma planes will be "(w + 1)/2". Almost the same for odd h.
Solution is to strategically substitute "w" by "(w+1)/2" at the good places ...
- In the repository, SDL_ConvertPixels() handles YUV only if yuv source format is exactly the same as YUV destination format.
It basically does a memcpy of pixels, but it's done incorrectly when width or height is odd (wrong size of chroma planes). This is fixed.
- SDL Renderers don't support odd width/height for YUV textures.
This is fixed for software, opengl, opengles2. (opengles 1 does not support it and fallback to software rendering).
This is *not* fixed for D3D and D3D11 ... (and others, psp ?)
Only *two* Dither function are fixed ... not sure if others are really used.
- This is not possible to create a NV12/NV12 texture with the software renderer, whereas other renderers allow it.
This is fixed, by using SDL_ConvertPixels underneath.
- It was not possible to SDL_UpdateTexture() of format NV12/NV21 with the software renderer. this is fixed.
Here's also two testcases:
- that do all combination of conversion.
- to test partial UpdateTexture
2017-10-06 16:50:24 -07:00
|
|
|
(rect->w + 1) / 2,
|
|
|
|
(rect->h + 1) / 2,
|
2014-06-25 00:58:40 -07:00
|
|
|
tdata->pixel_format,
|
|
|
|
tdata->pixel_type,
|
Fixed bug 3857 - SDL_ConvertPixels misses YUV conversions
Sylvain
Few issues with YUV on SDL2 when using odd dimensions, and missing conversions from/back to YUV formats.
1) The big part is that SDL_ConvertPixels() does not convert to/from YUV in most cases. This now works with any format and also with odd dimensions,
by adding two internal functions SDL_ConvertPixels_YUV_to_ARGB8888 and SDL_ConvertPixels_ARGB8888_to_YUV (could it be XRGB888 ?).
The target format is hard coded to ARGB888 (which is the default in the internal of the software renderer).
In case of different YUV conversion, it will do an intermediate conversion to a ARGB8888 buffer.
SDL_ConvertPixels_YUV_to_ARGB8888 is somehow redundant with all the "Color*Dither*Mod*".
But it allows some completeness of SDL_ConvertPixels to handle all YUV format.
It also works with odd dimensions.
Moreover, I did some benchmark(SDL_ConvertPixel vs Color32DitherYV12Mod1X and Color32DitherYUY2Mod1X).
gcc-6.3 and clang-4.0. gcc performs better than clang. And, with gcc, SDL_ConvertPixels() performs better (20%) than the two C function Color32Dither*().
For instance, to convert 10 times a 3888x2592 image, it takes ~195 ms with SDL_ConvertPixels and ~235 ms with Color32Dither*().
Especially because of gcc vectorize feature that optimises all conversion loops (-ftree-loop-vectorize).
Nb: I put no image pitch for the YUV buffers. because it complexify a little bit the code and the API :
There would be some ambiguity when setting the pitch exactly to image width:
would it a be pitch of image width (for luma and chroma). or just contiguous data ? (could set pitch=0 for the later).
2) Small issues with odd dimensions:
If width "w" is odd, luma plane width is still "w" whereas chroma planes will be "(w + 1)/2". Almost the same for odd h.
Solution is to strategically substitute "w" by "(w+1)/2" at the good places ...
- In the repository, SDL_ConvertPixels() handles YUV only if yuv source format is exactly the same as YUV destination format.
It basically does a memcpy of pixels, but it's done incorrectly when width or height is odd (wrong size of chroma planes). This is fixed.
- SDL Renderers don't support odd width/height for YUV textures.
This is fixed for software, opengl, opengles2. (opengles 1 does not support it and fallback to software rendering).
This is *not* fixed for D3D and D3D11 ... (and others, psp ?)
Only *two* Dither function are fixed ... not sure if others are really used.
- This is not possible to create a NV12/NV12 texture with the software renderer, whereas other renderers allow it.
This is fixed, by using SDL_ConvertPixels underneath.
- It was not possible to SDL_UpdateTexture() of format NV12/NV21 with the software renderer. this is fixed.
Here's also two testcases:
- that do all combination of conversion.
- to test partial UpdateTexture
2017-10-06 16:50:24 -07:00
|
|
|
pixels, (pitch + 1) / 2, 1);
|
2014-06-25 00:58:40 -07:00
|
|
|
}
|
|
|
|
|
2014-08-06 11:34:54 -07:00
|
|
|
if (tdata->nv12) {
|
|
|
|
/* Skip to the correct offset into the next texture */
|
|
|
|
pixels = (const void*)((const Uint8*)pixels + rect->h * pitch);
|
|
|
|
data->glBindTexture(tdata->texture_type, tdata->texture_u);
|
|
|
|
GLES2_TexSubImage2D(data, tdata->texture_type,
|
|
|
|
rect->x / 2,
|
|
|
|
rect->y / 2,
|
Fixed bug 3857 - SDL_ConvertPixels misses YUV conversions
Sylvain
Few issues with YUV on SDL2 when using odd dimensions, and missing conversions from/back to YUV formats.
1) The big part is that SDL_ConvertPixels() does not convert to/from YUV in most cases. This now works with any format and also with odd dimensions,
by adding two internal functions SDL_ConvertPixels_YUV_to_ARGB8888 and SDL_ConvertPixels_ARGB8888_to_YUV (could it be XRGB888 ?).
The target format is hard coded to ARGB888 (which is the default in the internal of the software renderer).
In case of different YUV conversion, it will do an intermediate conversion to a ARGB8888 buffer.
SDL_ConvertPixels_YUV_to_ARGB8888 is somehow redundant with all the "Color*Dither*Mod*".
But it allows some completeness of SDL_ConvertPixels to handle all YUV format.
It also works with odd dimensions.
Moreover, I did some benchmark(SDL_ConvertPixel vs Color32DitherYV12Mod1X and Color32DitherYUY2Mod1X).
gcc-6.3 and clang-4.0. gcc performs better than clang. And, with gcc, SDL_ConvertPixels() performs better (20%) than the two C function Color32Dither*().
For instance, to convert 10 times a 3888x2592 image, it takes ~195 ms with SDL_ConvertPixels and ~235 ms with Color32Dither*().
Especially because of gcc vectorize feature that optimises all conversion loops (-ftree-loop-vectorize).
Nb: I put no image pitch for the YUV buffers. because it complexify a little bit the code and the API :
There would be some ambiguity when setting the pitch exactly to image width:
would it a be pitch of image width (for luma and chroma). or just contiguous data ? (could set pitch=0 for the later).
2) Small issues with odd dimensions:
If width "w" is odd, luma plane width is still "w" whereas chroma planes will be "(w + 1)/2". Almost the same for odd h.
Solution is to strategically substitute "w" by "(w+1)/2" at the good places ...
- In the repository, SDL_ConvertPixels() handles YUV only if yuv source format is exactly the same as YUV destination format.
It basically does a memcpy of pixels, but it's done incorrectly when width or height is odd (wrong size of chroma planes). This is fixed.
- SDL Renderers don't support odd width/height for YUV textures.
This is fixed for software, opengl, opengles2. (opengles 1 does not support it and fallback to software rendering).
This is *not* fixed for D3D and D3D11 ... (and others, psp ?)
Only *two* Dither function are fixed ... not sure if others are really used.
- This is not possible to create a NV12/NV12 texture with the software renderer, whereas other renderers allow it.
This is fixed, by using SDL_ConvertPixels underneath.
- It was not possible to SDL_UpdateTexture() of format NV12/NV21 with the software renderer. this is fixed.
Here's also two testcases:
- that do all combination of conversion.
- to test partial UpdateTexture
2017-10-06 16:50:24 -07:00
|
|
|
(rect->w + 1) / 2,
|
|
|
|
(rect->h + 1) / 2,
|
2014-08-06 11:34:54 -07:00
|
|
|
GL_LUMINANCE_ALPHA,
|
|
|
|
GL_UNSIGNED_BYTE,
|
Fixed bug 3857 - SDL_ConvertPixels misses YUV conversions
Sylvain
Few issues with YUV on SDL2 when using odd dimensions, and missing conversions from/back to YUV formats.
1) The big part is that SDL_ConvertPixels() does not convert to/from YUV in most cases. This now works with any format and also with odd dimensions,
by adding two internal functions SDL_ConvertPixels_YUV_to_ARGB8888 and SDL_ConvertPixels_ARGB8888_to_YUV (could it be XRGB888 ?).
The target format is hard coded to ARGB888 (which is the default in the internal of the software renderer).
In case of different YUV conversion, it will do an intermediate conversion to a ARGB8888 buffer.
SDL_ConvertPixels_YUV_to_ARGB8888 is somehow redundant with all the "Color*Dither*Mod*".
But it allows some completeness of SDL_ConvertPixels to handle all YUV format.
It also works with odd dimensions.
Moreover, I did some benchmark(SDL_ConvertPixel vs Color32DitherYV12Mod1X and Color32DitherYUY2Mod1X).
gcc-6.3 and clang-4.0. gcc performs better than clang. And, with gcc, SDL_ConvertPixels() performs better (20%) than the two C function Color32Dither*().
For instance, to convert 10 times a 3888x2592 image, it takes ~195 ms with SDL_ConvertPixels and ~235 ms with Color32Dither*().
Especially because of gcc vectorize feature that optimises all conversion loops (-ftree-loop-vectorize).
Nb: I put no image pitch for the YUV buffers. because it complexify a little bit the code and the API :
There would be some ambiguity when setting the pitch exactly to image width:
would it a be pitch of image width (for luma and chroma). or just contiguous data ? (could set pitch=0 for the later).
2) Small issues with odd dimensions:
If width "w" is odd, luma plane width is still "w" whereas chroma planes will be "(w + 1)/2". Almost the same for odd h.
Solution is to strategically substitute "w" by "(w+1)/2" at the good places ...
- In the repository, SDL_ConvertPixels() handles YUV only if yuv source format is exactly the same as YUV destination format.
It basically does a memcpy of pixels, but it's done incorrectly when width or height is odd (wrong size of chroma planes). This is fixed.
- SDL Renderers don't support odd width/height for YUV textures.
This is fixed for software, opengl, opengles2. (opengles 1 does not support it and fallback to software rendering).
This is *not* fixed for D3D and D3D11 ... (and others, psp ?)
Only *two* Dither function are fixed ... not sure if others are really used.
- This is not possible to create a NV12/NV12 texture with the software renderer, whereas other renderers allow it.
This is fixed, by using SDL_ConvertPixels underneath.
- It was not possible to SDL_UpdateTexture() of format NV12/NV21 with the software renderer. this is fixed.
Here's also two testcases:
- that do all combination of conversion.
- to test partial UpdateTexture
2017-10-06 16:50:24 -07:00
|
|
|
pixels, 2 * ((pitch + 1) / 2), 2);
|
2014-08-06 11:34:54 -07:00
|
|
|
}
|
|
|
|
|
2013-10-03 20:48:52 -07:00
|
|
|
return GL_CheckError("glTexSubImage2D()", renderer);
|
|
|
|
}
|
|
|
|
|
2014-06-07 11:36:08 -07:00
|
|
|
static int
|
|
|
|
GLES2_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * texture,
|
|
|
|
const SDL_Rect * rect,
|
|
|
|
const Uint8 *Yplane, int Ypitch,
|
|
|
|
const Uint8 *Uplane, int Upitch,
|
|
|
|
const Uint8 *Vplane, int Vpitch)
|
|
|
|
{
|
|
|
|
GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->driverdata;
|
|
|
|
GLES2_TextureData *tdata = (GLES2_TextureData *)texture->driverdata;
|
|
|
|
|
Fixed bug 2595 - Padded, non-contiguous YUV does not display correctly using OpenGL ES 2.0 renderer
Alvin
The new OpenGL ES 2.0 YUV Texture support does not correctly display padded, non-contiguous YUV data.
I am using SDL2 60edb019f0fe (as provided by 'hg id --id') from Mercurial.
The YUV data I am using is provided by the FFMPEG family of libraries. According to FFMPEG's documentation, "The linesize [pitch] may be larger than the size of usable data -- there may be extra padding present for performance reasons."
The dimensions of the video file that I am using are 480x360. What I get from FFMPEG is a Ypitch of 512, and Upitch and Vpitch are both 256.
When I pack new Y, U and V buffers with only the "usable" data (Ypitch is 480 and Upitch and Vpitch are both 240), and use those new buffers, the image is display correctly.
It appears that the Ypitch, Upitch and Vpitch parameters are not being used by SDL_UpdateYUVTexture().
I use SDL_PIXELFORMAT_YV12 for my YUV texture, however, the same results are seen when I use SDL_PIXELFORMAT_IYUV.
Not sure if this is related or not, but when I render the YUV texture (padded and unpadded) to a RGB24 texture, the resulting image is greyscale (or could by just the Y channel).
The URL field for this bug entry is set to my email (SDL mailing list archive) which includes an example image of what I see when rendering padded, non-contiguous YUV data.
2014-06-21 12:38:46 -07:00
|
|
|
GLES2_ActivateRenderer(renderer);
|
|
|
|
|
|
|
|
/* Bail out if we're supposed to update an empty rectangle */
|
2015-05-16 17:35:36 -03:00
|
|
|
if (rect->w <= 0 || rect->h <= 0) {
|
Fixed bug 2595 - Padded, non-contiguous YUV does not display correctly using OpenGL ES 2.0 renderer
Alvin
The new OpenGL ES 2.0 YUV Texture support does not correctly display padded, non-contiguous YUV data.
I am using SDL2 60edb019f0fe (as provided by 'hg id --id') from Mercurial.
The YUV data I am using is provided by the FFMPEG family of libraries. According to FFMPEG's documentation, "The linesize [pitch] may be larger than the size of usable data -- there may be extra padding present for performance reasons."
The dimensions of the video file that I am using are 480x360. What I get from FFMPEG is a Ypitch of 512, and Upitch and Vpitch are both 256.
When I pack new Y, U and V buffers with only the "usable" data (Ypitch is 480 and Upitch and Vpitch are both 240), and use those new buffers, the image is display correctly.
It appears that the Ypitch, Upitch and Vpitch parameters are not being used by SDL_UpdateYUVTexture().
I use SDL_PIXELFORMAT_YV12 for my YUV texture, however, the same results are seen when I use SDL_PIXELFORMAT_IYUV.
Not sure if this is related or not, but when I render the YUV texture (padded and unpadded) to a RGB24 texture, the resulting image is greyscale (or could by just the Y channel).
The URL field for this bug entry is set to my email (SDL mailing list archive) which includes an example image of what I see when rendering padded, non-contiguous YUV data.
2014-06-21 12:38:46 -07:00
|
|
|
return 0;
|
2015-05-16 17:35:36 -03:00
|
|
|
}
|
Fixed bug 2595 - Padded, non-contiguous YUV does not display correctly using OpenGL ES 2.0 renderer
Alvin
The new OpenGL ES 2.0 YUV Texture support does not correctly display padded, non-contiguous YUV data.
I am using SDL2 60edb019f0fe (as provided by 'hg id --id') from Mercurial.
The YUV data I am using is provided by the FFMPEG family of libraries. According to FFMPEG's documentation, "The linesize [pitch] may be larger than the size of usable data -- there may be extra padding present for performance reasons."
The dimensions of the video file that I am using are 480x360. What I get from FFMPEG is a Ypitch of 512, and Upitch and Vpitch are both 256.
When I pack new Y, U and V buffers with only the "usable" data (Ypitch is 480 and Upitch and Vpitch are both 240), and use those new buffers, the image is display correctly.
It appears that the Ypitch, Upitch and Vpitch parameters are not being used by SDL_UpdateYUVTexture().
I use SDL_PIXELFORMAT_YV12 for my YUV texture, however, the same results are seen when I use SDL_PIXELFORMAT_IYUV.
Not sure if this is related or not, but when I render the YUV texture (padded and unpadded) to a RGB24 texture, the resulting image is greyscale (or could by just the Y channel).
The URL field for this bug entry is set to my email (SDL mailing list archive) which includes an example image of what I see when rendering padded, non-contiguous YUV data.
2014-06-21 12:38:46 -07:00
|
|
|
|
2014-06-07 11:36:08 -07:00
|
|
|
data->glBindTexture(tdata->texture_type, tdata->texture_v);
|
Fixed bug 2595 - Padded, non-contiguous YUV does not display correctly using OpenGL ES 2.0 renderer
Alvin
The new OpenGL ES 2.0 YUV Texture support does not correctly display padded, non-contiguous YUV data.
I am using SDL2 60edb019f0fe (as provided by 'hg id --id') from Mercurial.
The YUV data I am using is provided by the FFMPEG family of libraries. According to FFMPEG's documentation, "The linesize [pitch] may be larger than the size of usable data -- there may be extra padding present for performance reasons."
The dimensions of the video file that I am using are 480x360. What I get from FFMPEG is a Ypitch of 512, and Upitch and Vpitch are both 256.
When I pack new Y, U and V buffers with only the "usable" data (Ypitch is 480 and Upitch and Vpitch are both 240), and use those new buffers, the image is display correctly.
It appears that the Ypitch, Upitch and Vpitch parameters are not being used by SDL_UpdateYUVTexture().
I use SDL_PIXELFORMAT_YV12 for my YUV texture, however, the same results are seen when I use SDL_PIXELFORMAT_IYUV.
Not sure if this is related or not, but when I render the YUV texture (padded and unpadded) to a RGB24 texture, the resulting image is greyscale (or could by just the Y channel).
The URL field for this bug entry is set to my email (SDL mailing list archive) which includes an example image of what I see when rendering padded, non-contiguous YUV data.
2014-06-21 12:38:46 -07:00
|
|
|
GLES2_TexSubImage2D(data, tdata->texture_type,
|
2014-06-25 21:06:47 -07:00
|
|
|
rect->x / 2,
|
|
|
|
rect->y / 2,
|
Fixed bug 3857 - SDL_ConvertPixels misses YUV conversions
Sylvain
Few issues with YUV on SDL2 when using odd dimensions, and missing conversions from/back to YUV formats.
1) The big part is that SDL_ConvertPixels() does not convert to/from YUV in most cases. This now works with any format and also with odd dimensions,
by adding two internal functions SDL_ConvertPixels_YUV_to_ARGB8888 and SDL_ConvertPixels_ARGB8888_to_YUV (could it be XRGB888 ?).
The target format is hard coded to ARGB888 (which is the default in the internal of the software renderer).
In case of different YUV conversion, it will do an intermediate conversion to a ARGB8888 buffer.
SDL_ConvertPixels_YUV_to_ARGB8888 is somehow redundant with all the "Color*Dither*Mod*".
But it allows some completeness of SDL_ConvertPixels to handle all YUV format.
It also works with odd dimensions.
Moreover, I did some benchmark(SDL_ConvertPixel vs Color32DitherYV12Mod1X and Color32DitherYUY2Mod1X).
gcc-6.3 and clang-4.0. gcc performs better than clang. And, with gcc, SDL_ConvertPixels() performs better (20%) than the two C function Color32Dither*().
For instance, to convert 10 times a 3888x2592 image, it takes ~195 ms with SDL_ConvertPixels and ~235 ms with Color32Dither*().
Especially because of gcc vectorize feature that optimises all conversion loops (-ftree-loop-vectorize).
Nb: I put no image pitch for the YUV buffers. because it complexify a little bit the code and the API :
There would be some ambiguity when setting the pitch exactly to image width:
would it a be pitch of image width (for luma and chroma). or just contiguous data ? (could set pitch=0 for the later).
2) Small issues with odd dimensions:
If width "w" is odd, luma plane width is still "w" whereas chroma planes will be "(w + 1)/2". Almost the same for odd h.
Solution is to strategically substitute "w" by "(w+1)/2" at the good places ...
- In the repository, SDL_ConvertPixels() handles YUV only if yuv source format is exactly the same as YUV destination format.
It basically does a memcpy of pixels, but it's done incorrectly when width or height is odd (wrong size of chroma planes). This is fixed.
- SDL Renderers don't support odd width/height for YUV textures.
This is fixed for software, opengl, opengles2. (opengles 1 does not support it and fallback to software rendering).
This is *not* fixed for D3D and D3D11 ... (and others, psp ?)
Only *two* Dither function are fixed ... not sure if others are really used.
- This is not possible to create a NV12/NV12 texture with the software renderer, whereas other renderers allow it.
This is fixed, by using SDL_ConvertPixels underneath.
- It was not possible to SDL_UpdateTexture() of format NV12/NV21 with the software renderer. this is fixed.
Here's also two testcases:
- that do all combination of conversion.
- to test partial UpdateTexture
2017-10-06 16:50:24 -07:00
|
|
|
(rect->w + 1) / 2,
|
|
|
|
(rect->h + 1) / 2,
|
2014-06-07 11:36:08 -07:00
|
|
|
tdata->pixel_format,
|
|
|
|
tdata->pixel_type,
|
Fixed bug 2595 - Padded, non-contiguous YUV does not display correctly using OpenGL ES 2.0 renderer
Alvin
The new OpenGL ES 2.0 YUV Texture support does not correctly display padded, non-contiguous YUV data.
I am using SDL2 60edb019f0fe (as provided by 'hg id --id') from Mercurial.
The YUV data I am using is provided by the FFMPEG family of libraries. According to FFMPEG's documentation, "The linesize [pitch] may be larger than the size of usable data -- there may be extra padding present for performance reasons."
The dimensions of the video file that I am using are 480x360. What I get from FFMPEG is a Ypitch of 512, and Upitch and Vpitch are both 256.
When I pack new Y, U and V buffers with only the "usable" data (Ypitch is 480 and Upitch and Vpitch are both 240), and use those new buffers, the image is display correctly.
It appears that the Ypitch, Upitch and Vpitch parameters are not being used by SDL_UpdateYUVTexture().
I use SDL_PIXELFORMAT_YV12 for my YUV texture, however, the same results are seen when I use SDL_PIXELFORMAT_IYUV.
Not sure if this is related or not, but when I render the YUV texture (padded and unpadded) to a RGB24 texture, the resulting image is greyscale (or could by just the Y channel).
The URL field for this bug entry is set to my email (SDL mailing list archive) which includes an example image of what I see when rendering padded, non-contiguous YUV data.
2014-06-21 12:38:46 -07:00
|
|
|
Vplane, Vpitch, 1);
|
2014-06-07 11:36:08 -07:00
|
|
|
|
|
|
|
data->glBindTexture(tdata->texture_type, tdata->texture_u);
|
Fixed bug 2595 - Padded, non-contiguous YUV does not display correctly using OpenGL ES 2.0 renderer
Alvin
The new OpenGL ES 2.0 YUV Texture support does not correctly display padded, non-contiguous YUV data.
I am using SDL2 60edb019f0fe (as provided by 'hg id --id') from Mercurial.
The YUV data I am using is provided by the FFMPEG family of libraries. According to FFMPEG's documentation, "The linesize [pitch] may be larger than the size of usable data -- there may be extra padding present for performance reasons."
The dimensions of the video file that I am using are 480x360. What I get from FFMPEG is a Ypitch of 512, and Upitch and Vpitch are both 256.
When I pack new Y, U and V buffers with only the "usable" data (Ypitch is 480 and Upitch and Vpitch are both 240), and use those new buffers, the image is display correctly.
It appears that the Ypitch, Upitch and Vpitch parameters are not being used by SDL_UpdateYUVTexture().
I use SDL_PIXELFORMAT_YV12 for my YUV texture, however, the same results are seen when I use SDL_PIXELFORMAT_IYUV.
Not sure if this is related or not, but when I render the YUV texture (padded and unpadded) to a RGB24 texture, the resulting image is greyscale (or could by just the Y channel).
The URL field for this bug entry is set to my email (SDL mailing list archive) which includes an example image of what I see when rendering padded, non-contiguous YUV data.
2014-06-21 12:38:46 -07:00
|
|
|
GLES2_TexSubImage2D(data, tdata->texture_type,
|
2014-06-25 21:06:47 -07:00
|
|
|
rect->x / 2,
|
|
|
|
rect->y / 2,
|
Fixed bug 3857 - SDL_ConvertPixels misses YUV conversions
Sylvain
Few issues with YUV on SDL2 when using odd dimensions, and missing conversions from/back to YUV formats.
1) The big part is that SDL_ConvertPixels() does not convert to/from YUV in most cases. This now works with any format and also with odd dimensions,
by adding two internal functions SDL_ConvertPixels_YUV_to_ARGB8888 and SDL_ConvertPixels_ARGB8888_to_YUV (could it be XRGB888 ?).
The target format is hard coded to ARGB888 (which is the default in the internal of the software renderer).
In case of different YUV conversion, it will do an intermediate conversion to a ARGB8888 buffer.
SDL_ConvertPixels_YUV_to_ARGB8888 is somehow redundant with all the "Color*Dither*Mod*".
But it allows some completeness of SDL_ConvertPixels to handle all YUV format.
It also works with odd dimensions.
Moreover, I did some benchmark(SDL_ConvertPixel vs Color32DitherYV12Mod1X and Color32DitherYUY2Mod1X).
gcc-6.3 and clang-4.0. gcc performs better than clang. And, with gcc, SDL_ConvertPixels() performs better (20%) than the two C function Color32Dither*().
For instance, to convert 10 times a 3888x2592 image, it takes ~195 ms with SDL_ConvertPixels and ~235 ms with Color32Dither*().
Especially because of gcc vectorize feature that optimises all conversion loops (-ftree-loop-vectorize).
Nb: I put no image pitch for the YUV buffers. because it complexify a little bit the code and the API :
There would be some ambiguity when setting the pitch exactly to image width:
would it a be pitch of image width (for luma and chroma). or just contiguous data ? (could set pitch=0 for the later).
2) Small issues with odd dimensions:
If width "w" is odd, luma plane width is still "w" whereas chroma planes will be "(w + 1)/2". Almost the same for odd h.
Solution is to strategically substitute "w" by "(w+1)/2" at the good places ...
- In the repository, SDL_ConvertPixels() handles YUV only if yuv source format is exactly the same as YUV destination format.
It basically does a memcpy of pixels, but it's done incorrectly when width or height is odd (wrong size of chroma planes). This is fixed.
- SDL Renderers don't support odd width/height for YUV textures.
This is fixed for software, opengl, opengles2. (opengles 1 does not support it and fallback to software rendering).
This is *not* fixed for D3D and D3D11 ... (and others, psp ?)
Only *two* Dither function are fixed ... not sure if others are really used.
- This is not possible to create a NV12/NV12 texture with the software renderer, whereas other renderers allow it.
This is fixed, by using SDL_ConvertPixels underneath.
- It was not possible to SDL_UpdateTexture() of format NV12/NV21 with the software renderer. this is fixed.
Here's also two testcases:
- that do all combination of conversion.
- to test partial UpdateTexture
2017-10-06 16:50:24 -07:00
|
|
|
(rect->w + 1) / 2,
|
|
|
|
(rect->h + 1) / 2,
|
2014-06-07 11:36:08 -07:00
|
|
|
tdata->pixel_format,
|
|
|
|
tdata->pixel_type,
|
Fixed bug 2595 - Padded, non-contiguous YUV does not display correctly using OpenGL ES 2.0 renderer
Alvin
The new OpenGL ES 2.0 YUV Texture support does not correctly display padded, non-contiguous YUV data.
I am using SDL2 60edb019f0fe (as provided by 'hg id --id') from Mercurial.
The YUV data I am using is provided by the FFMPEG family of libraries. According to FFMPEG's documentation, "The linesize [pitch] may be larger than the size of usable data -- there may be extra padding present for performance reasons."
The dimensions of the video file that I am using are 480x360. What I get from FFMPEG is a Ypitch of 512, and Upitch and Vpitch are both 256.
When I pack new Y, U and V buffers with only the "usable" data (Ypitch is 480 and Upitch and Vpitch are both 240), and use those new buffers, the image is display correctly.
It appears that the Ypitch, Upitch and Vpitch parameters are not being used by SDL_UpdateYUVTexture().
I use SDL_PIXELFORMAT_YV12 for my YUV texture, however, the same results are seen when I use SDL_PIXELFORMAT_IYUV.
Not sure if this is related or not, but when I render the YUV texture (padded and unpadded) to a RGB24 texture, the resulting image is greyscale (or could by just the Y channel).
The URL field for this bug entry is set to my email (SDL mailing list archive) which includes an example image of what I see when rendering padded, non-contiguous YUV data.
2014-06-21 12:38:46 -07:00
|
|
|
Uplane, Upitch, 1);
|
2014-06-07 11:36:08 -07:00
|
|
|
|
|
|
|
data->glBindTexture(tdata->texture_type, tdata->texture);
|
Fixed bug 2595 - Padded, non-contiguous YUV does not display correctly using OpenGL ES 2.0 renderer
Alvin
The new OpenGL ES 2.0 YUV Texture support does not correctly display padded, non-contiguous YUV data.
I am using SDL2 60edb019f0fe (as provided by 'hg id --id') from Mercurial.
The YUV data I am using is provided by the FFMPEG family of libraries. According to FFMPEG's documentation, "The linesize [pitch] may be larger than the size of usable data -- there may be extra padding present for performance reasons."
The dimensions of the video file that I am using are 480x360. What I get from FFMPEG is a Ypitch of 512, and Upitch and Vpitch are both 256.
When I pack new Y, U and V buffers with only the "usable" data (Ypitch is 480 and Upitch and Vpitch are both 240), and use those new buffers, the image is display correctly.
It appears that the Ypitch, Upitch and Vpitch parameters are not being used by SDL_UpdateYUVTexture().
I use SDL_PIXELFORMAT_YV12 for my YUV texture, however, the same results are seen when I use SDL_PIXELFORMAT_IYUV.
Not sure if this is related or not, but when I render the YUV texture (padded and unpadded) to a RGB24 texture, the resulting image is greyscale (or could by just the Y channel).
The URL field for this bug entry is set to my email (SDL mailing list archive) which includes an example image of what I see when rendering padded, non-contiguous YUV data.
2014-06-21 12:38:46 -07:00
|
|
|
GLES2_TexSubImage2D(data, tdata->texture_type,
|
2014-06-07 11:36:08 -07:00
|
|
|
rect->x,
|
|
|
|
rect->y,
|
|
|
|
rect->w,
|
|
|
|
rect->h,
|
|
|
|
tdata->pixel_format,
|
|
|
|
tdata->pixel_type,
|
2014-06-25 00:58:40 -07:00
|
|
|
Yplane, Ypitch, 1);
|
2014-06-07 11:36:08 -07:00
|
|
|
|
|
|
|
return GL_CheckError("glTexSubImage2D()", renderer);
|
|
|
|
}
|
|
|
|
|
2013-10-03 20:48:52 -07:00
|
|
|
static int
|
|
|
|
GLES2_LockTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect,
|
|
|
|
void **pixels, int *pitch)
|
|
|
|
{
|
|
|
|
GLES2_TextureData *tdata = (GLES2_TextureData *)texture->driverdata;
|
|
|
|
|
|
|
|
/* Retrieve the buffer/pitch for the specified region */
|
|
|
|
*pixels = (Uint8 *)tdata->pixel_data +
|
|
|
|
(tdata->pitch * rect->y) +
|
|
|
|
(rect->x * SDL_BYTESPERPIXEL(texture->format));
|
|
|
|
*pitch = tdata->pitch;
|
|
|
|
|
2011-02-06 00:00:13 -08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2013-10-03 20:48:52 -07:00
|
|
|
static void
|
|
|
|
GLES2_UnlockTexture(SDL_Renderer *renderer, SDL_Texture *texture)
|
|
|
|
{
|
|
|
|
GLES2_TextureData *tdata = (GLES2_TextureData *)texture->driverdata;
|
|
|
|
SDL_Rect rect;
|
|
|
|
|
|
|
|
/* We do whole texture updates, at least for now */
|
|
|
|
rect.x = 0;
|
|
|
|
rect.y = 0;
|
|
|
|
rect.w = texture->w;
|
|
|
|
rect.h = texture->h;
|
|
|
|
GLES2_UpdateTexture(renderer, texture, &rect, tdata->pixel_data, tdata->pitch);
|
|
|
|
}
|
|
|
|
|
2012-01-21 22:22:30 -05:00
|
|
|
static int
|
2012-01-22 01:26:28 -05:00
|
|
|
GLES2_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture)
|
2012-01-21 22:22:30 -05:00
|
|
|
{
|
|
|
|
GLES2_DriverContext *data = (GLES2_DriverContext *) renderer->driverdata;
|
|
|
|
GLES2_TextureData *texturedata = NULL;
|
|
|
|
GLenum status;
|
|
|
|
|
|
|
|
if (texture == NULL) {
|
2012-01-30 20:56:25 -05:00
|
|
|
data->glBindFramebuffer(GL_FRAMEBUFFER, data->window_framebuffer);
|
2012-01-21 22:22:30 -05:00
|
|
|
} else {
|
|
|
|
texturedata = (GLES2_TextureData *) texture->driverdata;
|
|
|
|
data->glBindFramebuffer(GL_FRAMEBUFFER, texturedata->fbo->FBO);
|
|
|
|
/* TODO: check if texture pixel format allows this operation */
|
|
|
|
data->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texturedata->texture_type, texturedata->texture, 0);
|
|
|
|
/* Check FBO status */
|
|
|
|
status = data->glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
|
|
|
if (status != GL_FRAMEBUFFER_COMPLETE) {
|
2013-03-31 12:48:50 -04:00
|
|
|
return SDL_SetError("glFramebufferTexture2D() failed");
|
2012-01-21 22:22:30 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2013-10-03 20:48:52 -07:00
|
|
|
static void
|
|
|
|
GLES2_DestroyTexture(SDL_Renderer *renderer, SDL_Texture *texture)
|
|
|
|
{
|
|
|
|
GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->driverdata;
|
|
|
|
GLES2_TextureData *tdata = (GLES2_TextureData *)texture->driverdata;
|
|
|
|
|
|
|
|
GLES2_ActivateRenderer(renderer);
|
|
|
|
|
|
|
|
/* Destroy the texture */
|
2015-05-16 17:35:36 -03:00
|
|
|
if (tdata) {
|
2013-10-03 20:48:52 -07:00
|
|
|
data->glDeleteTextures(1, &tdata->texture);
|
2014-06-07 11:36:08 -07:00
|
|
|
if (tdata->texture_v) {
|
|
|
|
data->glDeleteTextures(1, &tdata->texture_v);
|
|
|
|
}
|
|
|
|
if (tdata->texture_u) {
|
|
|
|
data->glDeleteTextures(1, &tdata->texture_u);
|
|
|
|
}
|
2013-10-03 20:48:52 -07:00
|
|
|
SDL_free(tdata->pixel_data);
|
|
|
|
SDL_free(tdata);
|
|
|
|
texture->driverdata = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-02-06 00:00:13 -08:00
|
|
|
/*************************************************************************************************
|
|
|
|
* Shader management functions *
|
|
|
|
*************************************************************************************************/
|
|
|
|
|
Implemented more flexible blending modes for accelerated renderers
This fixes bug 2594 - Propose new blend mode, SDL_BLENDMODE_BLEND_DSTA
blendMode = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_SRC_ALPHA,
SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
SDL_BLENDOPERATION_ADD,
SDL_BLENDFACTOR_ZERO,
SDL_BLENDFACTOR_ONE,
SDL_BLENDOPERATION_ADD);
This fixes bug 2828 - Subtractive Blending
blendMode = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_SRC_ALPHA,
SDL_BLENDFACTOR_ONE,
SDL_BLENDOPERATION_SUBTRACT,
SDL_BLENDFACTOR_ZERO,
SDL_BLENDFACTOR_ONE,
SDL_BLENDOPERATION_SUBTRACT);
This goes partway to fixing bug 3684 - Add support for a pre-multiplied alpha blending mode
blendMode = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_ONE,
SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
SDL_BLENDOPERATION_ADD,
SDL_BLENDFACTOR_ONE,
SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
SDL_BLENDOPERATION_ADD);
2017-08-14 05:51:44 -07:00
|
|
|
static GLES2_ShaderCacheEntry *GLES2_CacheShader(SDL_Renderer *renderer, GLES2_ShaderType type);
|
2011-02-06 00:00:13 -08:00
|
|
|
static void GLES2_EvictShader(SDL_Renderer *renderer, GLES2_ShaderCacheEntry *entry);
|
|
|
|
static GLES2_ProgramCacheEntry *GLES2_CacheProgram(SDL_Renderer *renderer,
|
|
|
|
GLES2_ShaderCacheEntry *vertex,
|
Implemented more flexible blending modes for accelerated renderers
This fixes bug 2594 - Propose new blend mode, SDL_BLENDMODE_BLEND_DSTA
blendMode = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_SRC_ALPHA,
SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
SDL_BLENDOPERATION_ADD,
SDL_BLENDFACTOR_ZERO,
SDL_BLENDFACTOR_ONE,
SDL_BLENDOPERATION_ADD);
This fixes bug 2828 - Subtractive Blending
blendMode = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_SRC_ALPHA,
SDL_BLENDFACTOR_ONE,
SDL_BLENDOPERATION_SUBTRACT,
SDL_BLENDFACTOR_ZERO,
SDL_BLENDFACTOR_ONE,
SDL_BLENDOPERATION_SUBTRACT);
This goes partway to fixing bug 3684 - Add support for a pre-multiplied alpha blending mode
blendMode = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_ONE,
SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
SDL_BLENDOPERATION_ADD,
SDL_BLENDFACTOR_ONE,
SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
SDL_BLENDOPERATION_ADD);
2017-08-14 05:51:44 -07:00
|
|
|
GLES2_ShaderCacheEntry *fragment);
|
|
|
|
static int GLES2_SelectProgram(SDL_Renderer *renderer, GLES2_ImageSource source);
|
2011-02-06 00:00:13 -08:00
|
|
|
|
|
|
|
static GLES2_ProgramCacheEntry *
|
|
|
|
GLES2_CacheProgram(SDL_Renderer *renderer, GLES2_ShaderCacheEntry *vertex,
|
Implemented more flexible blending modes for accelerated renderers
This fixes bug 2594 - Propose new blend mode, SDL_BLENDMODE_BLEND_DSTA
blendMode = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_SRC_ALPHA,
SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
SDL_BLENDOPERATION_ADD,
SDL_BLENDFACTOR_ZERO,
SDL_BLENDFACTOR_ONE,
SDL_BLENDOPERATION_ADD);
This fixes bug 2828 - Subtractive Blending
blendMode = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_SRC_ALPHA,
SDL_BLENDFACTOR_ONE,
SDL_BLENDOPERATION_SUBTRACT,
SDL_BLENDFACTOR_ZERO,
SDL_BLENDFACTOR_ONE,
SDL_BLENDOPERATION_SUBTRACT);
This goes partway to fixing bug 3684 - Add support for a pre-multiplied alpha blending mode
blendMode = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_ONE,
SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
SDL_BLENDOPERATION_ADD,
SDL_BLENDFACTOR_ONE,
SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
SDL_BLENDOPERATION_ADD);
2017-08-14 05:51:44 -07:00
|
|
|
GLES2_ShaderCacheEntry *fragment)
|
2011-02-06 00:00:13 -08:00
|
|
|
{
|
2013-10-03 20:48:52 -07:00
|
|
|
GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->driverdata;
|
2011-02-06 00:00:13 -08:00
|
|
|
GLES2_ProgramCacheEntry *entry;
|
|
|
|
GLES2_ShaderCacheEntry *shaderEntry;
|
|
|
|
GLint linkSuccessful;
|
|
|
|
|
|
|
|
/* Check if we've already cached this program */
|
2013-10-03 20:48:52 -07:00
|
|
|
entry = data->program_cache.head;
|
2015-05-16 17:35:36 -03:00
|
|
|
while (entry) {
|
|
|
|
if (entry->vertex_shader == vertex && entry->fragment_shader == fragment) {
|
2011-02-06 00:00:13 -08:00
|
|
|
break;
|
2015-05-16 17:35:36 -03:00
|
|
|
}
|
2011-02-06 00:00:13 -08:00
|
|
|
entry = entry->next;
|
|
|
|
}
|
2015-05-16 17:35:36 -03:00
|
|
|
if (entry) {
|
|
|
|
if (data->program_cache.head != entry) {
|
|
|
|
if (entry->next) {
|
2011-02-06 00:00:13 -08:00
|
|
|
entry->next->prev = entry->prev;
|
2015-05-16 17:35:36 -03:00
|
|
|
}
|
|
|
|
if (entry->prev) {
|
2011-02-06 00:00:13 -08:00
|
|
|
entry->prev->next = entry->next;
|
2015-05-16 17:35:36 -03:00
|
|
|
}
|
2011-02-06 00:00:13 -08:00
|
|
|
entry->prev = NULL;
|
2013-10-03 20:48:52 -07:00
|
|
|
entry->next = data->program_cache.head;
|
|
|
|
data->program_cache.head->prev = entry;
|
|
|
|
data->program_cache.head = entry;
|
2011-02-06 00:00:13 -08:00
|
|
|
}
|
|
|
|
return entry;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Create a program cache entry */
|
|
|
|
entry = (GLES2_ProgramCacheEntry *)SDL_calloc(1, sizeof(GLES2_ProgramCacheEntry));
|
2015-05-16 17:35:36 -03:00
|
|
|
if (!entry) {
|
2011-02-06 00:00:13 -08:00
|
|
|
SDL_OutOfMemory();
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
entry->vertex_shader = vertex;
|
|
|
|
entry->fragment_shader = fragment;
|
2012-01-18 22:45:49 -05:00
|
|
|
|
2011-02-06 00:00:13 -08:00
|
|
|
/* Create the program and link it */
|
2013-10-03 20:48:52 -07:00
|
|
|
entry->id = data->glCreateProgram();
|
|
|
|
data->glAttachShader(entry->id, vertex->id);
|
|
|
|
data->glAttachShader(entry->id, fragment->id);
|
|
|
|
data->glBindAttribLocation(entry->id, GLES2_ATTRIBUTE_POSITION, "a_position");
|
|
|
|
data->glBindAttribLocation(entry->id, GLES2_ATTRIBUTE_TEXCOORD, "a_texCoord");
|
|
|
|
data->glBindAttribLocation(entry->id, GLES2_ATTRIBUTE_ANGLE, "a_angle");
|
|
|
|
data->glBindAttribLocation(entry->id, GLES2_ATTRIBUTE_CENTER, "a_center");
|
|
|
|
data->glLinkProgram(entry->id);
|
|
|
|
data->glGetProgramiv(entry->id, GL_LINK_STATUS, &linkSuccessful);
|
2015-05-16 17:35:36 -03:00
|
|
|
if (!linkSuccessful) {
|
2013-10-03 20:48:52 -07:00
|
|
|
data->glDeleteProgram(entry->id);
|
2011-02-06 00:00:13 -08:00
|
|
|
SDL_free(entry);
|
2013-03-31 12:48:50 -04:00
|
|
|
SDL_SetError("Failed to link shader program");
|
2011-02-06 00:00:13 -08:00
|
|
|
return NULL;
|
|
|
|
}
|
2012-01-18 22:45:49 -05:00
|
|
|
|
2011-02-06 00:00:13 -08:00
|
|
|
/* Predetermine locations of uniform variables */
|
|
|
|
entry->uniform_locations[GLES2_UNIFORM_PROJECTION] =
|
2013-10-03 20:48:52 -07:00
|
|
|
data->glGetUniformLocation(entry->id, "u_projection");
|
2014-06-07 11:36:08 -07:00
|
|
|
entry->uniform_locations[GLES2_UNIFORM_TEXTURE_V] =
|
|
|
|
data->glGetUniformLocation(entry->id, "u_texture_v");
|
|
|
|
entry->uniform_locations[GLES2_UNIFORM_TEXTURE_U] =
|
|
|
|
data->glGetUniformLocation(entry->id, "u_texture_u");
|
2011-02-06 00:00:13 -08:00
|
|
|
entry->uniform_locations[GLES2_UNIFORM_TEXTURE] =
|
2013-10-03 20:48:52 -07:00
|
|
|
data->glGetUniformLocation(entry->id, "u_texture");
|
2011-02-06 00:00:13 -08:00
|
|
|
entry->uniform_locations[GLES2_UNIFORM_MODULATION] =
|
2013-10-03 20:48:52 -07:00
|
|
|
data->glGetUniformLocation(entry->id, "u_modulation");
|
2011-02-06 00:00:13 -08:00
|
|
|
entry->uniform_locations[GLES2_UNIFORM_COLOR] =
|
2013-10-05 00:29:57 -04:00
|
|
|
data->glGetUniformLocation(entry->id, "u_color");
|
|
|
|
|
2013-12-23 17:15:32 -08:00
|
|
|
entry->modulation_r = entry->modulation_g = entry->modulation_b = entry->modulation_a = 255;
|
|
|
|
entry->color_r = entry->color_g = entry->color_b = entry->color_a = 255;
|
2013-10-05 00:29:57 -04:00
|
|
|
|
|
|
|
data->glUseProgram(entry->id);
|
2014-06-07 11:36:08 -07:00
|
|
|
data->glUniform1i(entry->uniform_locations[GLES2_UNIFORM_TEXTURE_V], 2); /* always texture unit 2. */
|
|
|
|
data->glUniform1i(entry->uniform_locations[GLES2_UNIFORM_TEXTURE_U], 1); /* always texture unit 1. */
|
2013-10-05 00:29:57 -04:00
|
|
|
data->glUniform1i(entry->uniform_locations[GLES2_UNIFORM_TEXTURE], 0); /* always texture unit 0. */
|
2014-06-07 11:36:08 -07:00
|
|
|
data->glUniformMatrix4fv(entry->uniform_locations[GLES2_UNIFORM_PROJECTION], 1, GL_FALSE, (GLfloat *)entry->projection);
|
2013-10-05 00:29:57 -04:00
|
|
|
data->glUniform4f(entry->uniform_locations[GLES2_UNIFORM_MODULATION], 1.0f, 1.0f, 1.0f, 1.0f);
|
|
|
|
data->glUniform4f(entry->uniform_locations[GLES2_UNIFORM_COLOR], 1.0f, 1.0f, 1.0f, 1.0f);
|
2011-02-06 00:00:13 -08:00
|
|
|
|
|
|
|
/* Cache the linked program */
|
2015-05-16 17:35:36 -03:00
|
|
|
if (data->program_cache.head) {
|
2013-10-03 20:48:52 -07:00
|
|
|
entry->next = data->program_cache.head;
|
|
|
|
data->program_cache.head->prev = entry;
|
2015-05-16 17:35:36 -03:00
|
|
|
} else {
|
2013-10-03 20:48:52 -07:00
|
|
|
data->program_cache.tail = entry;
|
2011-02-06 00:00:13 -08:00
|
|
|
}
|
2013-10-03 20:48:52 -07:00
|
|
|
data->program_cache.head = entry;
|
|
|
|
++data->program_cache.count;
|
2011-02-06 00:00:13 -08:00
|
|
|
|
|
|
|
/* Increment the refcount of the shaders we're using */
|
|
|
|
++vertex->references;
|
|
|
|
++fragment->references;
|
|
|
|
|
|
|
|
/* Evict the last entry from the cache if we exceed the limit */
|
2015-05-16 17:35:36 -03:00
|
|
|
if (data->program_cache.count > GLES2_MAX_CACHED_PROGRAMS) {
|
2013-10-03 20:48:52 -07:00
|
|
|
shaderEntry = data->program_cache.tail->vertex_shader;
|
2015-05-16 17:35:36 -03:00
|
|
|
if (--shaderEntry->references <= 0) {
|
2011-02-06 00:00:13 -08:00
|
|
|
GLES2_EvictShader(renderer, shaderEntry);
|
2015-05-16 17:35:36 -03:00
|
|
|
}
|
2013-10-03 20:48:52 -07:00
|
|
|
shaderEntry = data->program_cache.tail->fragment_shader;
|
2015-05-16 17:35:36 -03:00
|
|
|
if (--shaderEntry->references <= 0) {
|
2011-02-06 00:00:13 -08:00
|
|
|
GLES2_EvictShader(renderer, shaderEntry);
|
2015-05-16 17:35:36 -03:00
|
|
|
}
|
2013-10-03 20:48:52 -07:00
|
|
|
data->glDeleteProgram(data->program_cache.tail->id);
|
|
|
|
data->program_cache.tail = data->program_cache.tail->prev;
|
|
|
|
SDL_free(data->program_cache.tail->next);
|
|
|
|
data->program_cache.tail->next = NULL;
|
|
|
|
--data->program_cache.count;
|
2011-02-06 00:00:13 -08:00
|
|
|
}
|
|
|
|
return entry;
|
|
|
|
}
|
|
|
|
|
|
|
|
static GLES2_ShaderCacheEntry *
|
Implemented more flexible blending modes for accelerated renderers
This fixes bug 2594 - Propose new blend mode, SDL_BLENDMODE_BLEND_DSTA
blendMode = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_SRC_ALPHA,
SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
SDL_BLENDOPERATION_ADD,
SDL_BLENDFACTOR_ZERO,
SDL_BLENDFACTOR_ONE,
SDL_BLENDOPERATION_ADD);
This fixes bug 2828 - Subtractive Blending
blendMode = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_SRC_ALPHA,
SDL_BLENDFACTOR_ONE,
SDL_BLENDOPERATION_SUBTRACT,
SDL_BLENDFACTOR_ZERO,
SDL_BLENDFACTOR_ONE,
SDL_BLENDOPERATION_SUBTRACT);
This goes partway to fixing bug 3684 - Add support for a pre-multiplied alpha blending mode
blendMode = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_ONE,
SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
SDL_BLENDOPERATION_ADD,
SDL_BLENDFACTOR_ONE,
SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
SDL_BLENDOPERATION_ADD);
2017-08-14 05:51:44 -07:00
|
|
|
GLES2_CacheShader(SDL_Renderer *renderer, GLES2_ShaderType type)
|
2011-02-06 00:00:13 -08:00
|
|
|
{
|
2013-10-03 20:48:52 -07:00
|
|
|
GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->driverdata;
|
2011-02-06 00:00:13 -08:00
|
|
|
const GLES2_Shader *shader;
|
|
|
|
const GLES2_ShaderInstance *instance = NULL;
|
|
|
|
GLES2_ShaderCacheEntry *entry = NULL;
|
|
|
|
GLint compileSuccessful = GL_FALSE;
|
|
|
|
int i, j;
|
|
|
|
|
|
|
|
/* Find the corresponding shader */
|
Implemented more flexible blending modes for accelerated renderers
This fixes bug 2594 - Propose new blend mode, SDL_BLENDMODE_BLEND_DSTA
blendMode = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_SRC_ALPHA,
SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
SDL_BLENDOPERATION_ADD,
SDL_BLENDFACTOR_ZERO,
SDL_BLENDFACTOR_ONE,
SDL_BLENDOPERATION_ADD);
This fixes bug 2828 - Subtractive Blending
blendMode = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_SRC_ALPHA,
SDL_BLENDFACTOR_ONE,
SDL_BLENDOPERATION_SUBTRACT,
SDL_BLENDFACTOR_ZERO,
SDL_BLENDFACTOR_ONE,
SDL_BLENDOPERATION_SUBTRACT);
This goes partway to fixing bug 3684 - Add support for a pre-multiplied alpha blending mode
blendMode = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_ONE,
SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
SDL_BLENDOPERATION_ADD,
SDL_BLENDFACTOR_ONE,
SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
SDL_BLENDOPERATION_ADD);
2017-08-14 05:51:44 -07:00
|
|
|
shader = GLES2_GetShader(type);
|
2015-05-16 17:35:36 -03:00
|
|
|
if (!shader) {
|
2011-02-06 00:00:13 -08:00
|
|
|
SDL_SetError("No shader matching the requested characteristics was found");
|
|
|
|
return NULL;
|
|
|
|
}
|
2012-01-18 22:45:49 -05:00
|
|
|
|
2011-02-06 00:00:13 -08:00
|
|
|
/* Find a matching shader instance that's supported on this hardware */
|
2015-05-16 17:35:36 -03:00
|
|
|
for (i = 0; i < shader->instance_count && !instance; ++i) {
|
|
|
|
for (j = 0; j < data->shader_format_count && !instance; ++j) {
|
|
|
|
if (!shader->instances[i]) {
|
2011-02-06 08:46:48 -08:00
|
|
|
continue;
|
2015-05-16 17:35:36 -03:00
|
|
|
}
|
|
|
|
if (shader->instances[i]->format != data->shader_formats[j]) {
|
2011-02-06 00:00:13 -08:00
|
|
|
continue;
|
2015-05-16 17:35:36 -03:00
|
|
|
}
|
2011-02-06 00:00:13 -08:00
|
|
|
instance = shader->instances[i];
|
|
|
|
}
|
|
|
|
}
|
2015-05-16 17:35:36 -03:00
|
|
|
if (!instance) {
|
2011-02-06 00:00:13 -08:00
|
|
|
SDL_SetError("The specified shader cannot be loaded on the current platform");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check if we've already cached this shader */
|
2013-10-03 20:48:52 -07:00
|
|
|
entry = data->shader_cache.head;
|
2015-05-16 17:35:36 -03:00
|
|
|
while (entry) {
|
|
|
|
if (entry->instance == instance) {
|
2011-02-06 00:00:13 -08:00
|
|
|
break;
|
2015-05-16 17:35:36 -03:00
|
|
|
}
|
2011-02-06 00:00:13 -08:00
|
|
|
entry = entry->next;
|
|
|
|
}
|
2015-05-16 17:35:36 -03:00
|
|
|
if (entry) {
|
2011-02-06 00:00:13 -08:00
|
|
|
return entry;
|
2015-05-16 17:35:36 -03:00
|
|
|
}
|
2011-02-06 00:00:13 -08:00
|
|
|
|
|
|
|
/* Create a shader cache entry */
|
|
|
|
entry = (GLES2_ShaderCacheEntry *)SDL_calloc(1, sizeof(GLES2_ShaderCacheEntry));
|
2015-05-16 17:35:36 -03:00
|
|
|
if (!entry) {
|
2011-02-06 00:00:13 -08:00
|
|
|
SDL_OutOfMemory();
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
entry->type = type;
|
|
|
|
entry->instance = instance;
|
|
|
|
|
|
|
|
/* Compile or load the selected shader instance */
|
2013-10-03 20:48:52 -07:00
|
|
|
entry->id = data->glCreateShader(instance->type);
|
2015-05-16 17:35:36 -03:00
|
|
|
if (instance->format == (GLenum)-1) {
|
2016-11-23 21:52:48 -05:00
|
|
|
data->glShaderSource(entry->id, 1, (const char **)(char *)&instance->data, NULL);
|
2013-10-03 20:48:52 -07:00
|
|
|
data->glCompileShader(entry->id);
|
|
|
|
data->glGetShaderiv(entry->id, GL_COMPILE_STATUS, &compileSuccessful);
|
2015-05-16 17:35:36 -03:00
|
|
|
} else {
|
2013-10-03 20:48:52 -07:00
|
|
|
data->glShaderBinary(1, &entry->id, instance->format, instance->data, instance->length);
|
2011-02-06 00:00:13 -08:00
|
|
|
compileSuccessful = GL_TRUE;
|
|
|
|
}
|
2015-05-16 17:35:36 -03:00
|
|
|
if (!compileSuccessful) {
|
2011-02-06 10:59:37 -08:00
|
|
|
char *info = NULL;
|
2011-12-29 05:11:33 -05:00
|
|
|
int length = 0;
|
2011-02-06 10:59:37 -08:00
|
|
|
|
2013-10-03 20:48:52 -07:00
|
|
|
data->glGetShaderiv(entry->id, GL_INFO_LOG_LENGTH, &length);
|
2011-02-06 10:59:37 -08:00
|
|
|
if (length > 0) {
|
|
|
|
info = SDL_stack_alloc(char, length);
|
|
|
|
if (info) {
|
2013-10-03 20:48:52 -07:00
|
|
|
data->glGetShaderInfoLog(entry->id, length, &length, info);
|
2011-02-06 10:59:37 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (info) {
|
|
|
|
SDL_SetError("Failed to load the shader: %s", info);
|
|
|
|
SDL_stack_free(info);
|
|
|
|
} else {
|
|
|
|
SDL_SetError("Failed to load the shader");
|
|
|
|
}
|
2013-10-03 20:48:52 -07:00
|
|
|
data->glDeleteShader(entry->id);
|
2011-02-06 00:00:13 -08:00
|
|
|
SDL_free(entry);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Link the shader entry in at the front of the cache */
|
2015-05-16 17:35:36 -03:00
|
|
|
if (data->shader_cache.head) {
|
2013-10-03 20:48:52 -07:00
|
|
|
entry->next = data->shader_cache.head;
|
|
|
|
data->shader_cache.head->prev = entry;
|
2011-02-06 00:00:13 -08:00
|
|
|
}
|
2013-10-03 20:48:52 -07:00
|
|
|
data->shader_cache.head = entry;
|
|
|
|
++data->shader_cache.count;
|
2011-02-06 00:00:13 -08:00
|
|
|
return entry;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
GLES2_EvictShader(SDL_Renderer *renderer, GLES2_ShaderCacheEntry *entry)
|
|
|
|
{
|
2013-10-03 20:48:52 -07:00
|
|
|
GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->driverdata;
|
2011-02-06 00:00:13 -08:00
|
|
|
|
|
|
|
/* Unlink the shader from the cache */
|
2015-05-16 17:35:36 -03:00
|
|
|
if (entry->next) {
|
2011-02-06 00:00:13 -08:00
|
|
|
entry->next->prev = entry->prev;
|
2015-05-16 17:35:36 -03:00
|
|
|
}
|
|
|
|
if (entry->prev) {
|
2011-02-06 00:00:13 -08:00
|
|
|
entry->prev->next = entry->next;
|
2015-05-16 17:35:36 -03:00
|
|
|
}
|
|
|
|
if (data->shader_cache.head == entry) {
|
2013-10-03 20:48:52 -07:00
|
|
|
data->shader_cache.head = entry->next;
|
2015-05-16 17:35:36 -03:00
|
|
|
}
|
2013-10-03 20:48:52 -07:00
|
|
|
--data->shader_cache.count;
|
2011-02-06 00:00:13 -08:00
|
|
|
|
|
|
|
/* Deallocate the shader */
|
2013-10-03 20:48:52 -07:00
|
|
|
data->glDeleteShader(entry->id);
|
2011-02-06 00:00:13 -08:00
|
|
|
SDL_free(entry);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
Implemented more flexible blending modes for accelerated renderers
This fixes bug 2594 - Propose new blend mode, SDL_BLENDMODE_BLEND_DSTA
blendMode = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_SRC_ALPHA,
SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
SDL_BLENDOPERATION_ADD,
SDL_BLENDFACTOR_ZERO,
SDL_BLENDFACTOR_ONE,
SDL_BLENDOPERATION_ADD);
This fixes bug 2828 - Subtractive Blending
blendMode = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_SRC_ALPHA,
SDL_BLENDFACTOR_ONE,
SDL_BLENDOPERATION_SUBTRACT,
SDL_BLENDFACTOR_ZERO,
SDL_BLENDFACTOR_ONE,
SDL_BLENDOPERATION_SUBTRACT);
This goes partway to fixing bug 3684 - Add support for a pre-multiplied alpha blending mode
blendMode = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_ONE,
SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
SDL_BLENDOPERATION_ADD,
SDL_BLENDFACTOR_ONE,
SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
SDL_BLENDOPERATION_ADD);
2017-08-14 05:51:44 -07:00
|
|
|
GLES2_SelectProgram(SDL_Renderer *renderer, GLES2_ImageSource source)
|
2011-02-06 00:00:13 -08:00
|
|
|
{
|
2013-10-03 20:48:52 -07:00
|
|
|
GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->driverdata;
|
2011-02-06 00:00:13 -08:00
|
|
|
GLES2_ShaderCacheEntry *vertex = NULL;
|
|
|
|
GLES2_ShaderCacheEntry *fragment = NULL;
|
|
|
|
GLES2_ShaderType vtype, ftype;
|
|
|
|
GLES2_ProgramCacheEntry *program;
|
|
|
|
|
|
|
|
/* Select an appropriate shader pair for the specified modes */
|
|
|
|
vtype = GLES2_SHADER_VERTEX_DEFAULT;
|
2015-05-16 17:35:36 -03:00
|
|
|
switch (source) {
|
2011-02-06 00:00:13 -08:00
|
|
|
case GLES2_IMAGESOURCE_SOLID:
|
|
|
|
ftype = GLES2_SHADER_FRAGMENT_SOLID_SRC;
|
|
|
|
break;
|
2011-12-29 05:11:33 -05:00
|
|
|
case GLES2_IMAGESOURCE_TEXTURE_ABGR:
|
|
|
|
ftype = GLES2_SHADER_FRAGMENT_TEXTURE_ABGR_SRC;
|
2012-06-22 11:38:49 -04:00
|
|
|
break;
|
2011-12-29 05:11:33 -05:00
|
|
|
case GLES2_IMAGESOURCE_TEXTURE_ARGB:
|
|
|
|
ftype = GLES2_SHADER_FRAGMENT_TEXTURE_ARGB_SRC;
|
|
|
|
break;
|
|
|
|
case GLES2_IMAGESOURCE_TEXTURE_RGB:
|
|
|
|
ftype = GLES2_SHADER_FRAGMENT_TEXTURE_RGB_SRC;
|
|
|
|
break;
|
|
|
|
case GLES2_IMAGESOURCE_TEXTURE_BGR:
|
|
|
|
ftype = GLES2_SHADER_FRAGMENT_TEXTURE_BGR_SRC;
|
2011-02-06 00:00:13 -08:00
|
|
|
break;
|
2014-06-07 11:36:08 -07:00
|
|
|
case GLES2_IMAGESOURCE_TEXTURE_YUV:
|
|
|
|
ftype = GLES2_SHADER_FRAGMENT_TEXTURE_YUV_SRC;
|
|
|
|
break;
|
2014-08-06 11:34:54 -07:00
|
|
|
case GLES2_IMAGESOURCE_TEXTURE_NV12:
|
|
|
|
ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV12_SRC;
|
|
|
|
break;
|
|
|
|
case GLES2_IMAGESOURCE_TEXTURE_NV21:
|
|
|
|
ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV21_SRC;
|
|
|
|
break;
|
2011-12-29 05:11:33 -05:00
|
|
|
default:
|
|
|
|
goto fault;
|
2011-02-06 00:00:13 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Load the requested shaders */
|
Implemented more flexible blending modes for accelerated renderers
This fixes bug 2594 - Propose new blend mode, SDL_BLENDMODE_BLEND_DSTA
blendMode = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_SRC_ALPHA,
SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
SDL_BLENDOPERATION_ADD,
SDL_BLENDFACTOR_ZERO,
SDL_BLENDFACTOR_ONE,
SDL_BLENDOPERATION_ADD);
This fixes bug 2828 - Subtractive Blending
blendMode = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_SRC_ALPHA,
SDL_BLENDFACTOR_ONE,
SDL_BLENDOPERATION_SUBTRACT,
SDL_BLENDFACTOR_ZERO,
SDL_BLENDFACTOR_ONE,
SDL_BLENDOPERATION_SUBTRACT);
This goes partway to fixing bug 3684 - Add support for a pre-multiplied alpha blending mode
blendMode = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_ONE,
SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
SDL_BLENDOPERATION_ADD,
SDL_BLENDFACTOR_ONE,
SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
SDL_BLENDOPERATION_ADD);
2017-08-14 05:51:44 -07:00
|
|
|
vertex = GLES2_CacheShader(renderer, vtype);
|
2015-05-16 17:35:36 -03:00
|
|
|
if (!vertex) {
|
2011-02-06 00:00:13 -08:00
|
|
|
goto fault;
|
2015-05-16 17:35:36 -03:00
|
|
|
}
|
Implemented more flexible blending modes for accelerated renderers
This fixes bug 2594 - Propose new blend mode, SDL_BLENDMODE_BLEND_DSTA
blendMode = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_SRC_ALPHA,
SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
SDL_BLENDOPERATION_ADD,
SDL_BLENDFACTOR_ZERO,
SDL_BLENDFACTOR_ONE,
SDL_BLENDOPERATION_ADD);
This fixes bug 2828 - Subtractive Blending
blendMode = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_SRC_ALPHA,
SDL_BLENDFACTOR_ONE,
SDL_BLENDOPERATION_SUBTRACT,
SDL_BLENDFACTOR_ZERO,
SDL_BLENDFACTOR_ONE,
SDL_BLENDOPERATION_SUBTRACT);
This goes partway to fixing bug 3684 - Add support for a pre-multiplied alpha blending mode
blendMode = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_ONE,
SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
SDL_BLENDOPERATION_ADD,
SDL_BLENDFACTOR_ONE,
SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
SDL_BLENDOPERATION_ADD);
2017-08-14 05:51:44 -07:00
|
|
|
fragment = GLES2_CacheShader(renderer, ftype);
|
2015-05-16 17:35:36 -03:00
|
|
|
if (!fragment) {
|
2011-02-06 00:00:13 -08:00
|
|
|
goto fault;
|
2015-05-16 17:35:36 -03:00
|
|
|
}
|
2011-02-06 00:00:13 -08:00
|
|
|
|
|
|
|
/* Check if we need to change programs at all */
|
2013-10-03 20:48:52 -07:00
|
|
|
if (data->current_program &&
|
|
|
|
data->current_program->vertex_shader == vertex &&
|
2015-05-16 17:35:36 -03:00
|
|
|
data->current_program->fragment_shader == fragment) {
|
2011-02-06 00:00:13 -08:00
|
|
|
return 0;
|
2015-05-16 17:35:36 -03:00
|
|
|
}
|
2011-02-06 00:00:13 -08:00
|
|
|
|
|
|
|
/* Generate a matching program */
|
Implemented more flexible blending modes for accelerated renderers
This fixes bug 2594 - Propose new blend mode, SDL_BLENDMODE_BLEND_DSTA
blendMode = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_SRC_ALPHA,
SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
SDL_BLENDOPERATION_ADD,
SDL_BLENDFACTOR_ZERO,
SDL_BLENDFACTOR_ONE,
SDL_BLENDOPERATION_ADD);
This fixes bug 2828 - Subtractive Blending
blendMode = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_SRC_ALPHA,
SDL_BLENDFACTOR_ONE,
SDL_BLENDOPERATION_SUBTRACT,
SDL_BLENDFACTOR_ZERO,
SDL_BLENDFACTOR_ONE,
SDL_BLENDOPERATION_SUBTRACT);
This goes partway to fixing bug 3684 - Add support for a pre-multiplied alpha blending mode
blendMode = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_ONE,
SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
SDL_BLENDOPERATION_ADD,
SDL_BLENDFACTOR_ONE,
SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
SDL_BLENDOPERATION_ADD);
2017-08-14 05:51:44 -07:00
|
|
|
program = GLES2_CacheProgram(renderer, vertex, fragment);
|
2015-05-16 17:35:36 -03:00
|
|
|
if (!program) {
|
2011-02-06 00:00:13 -08:00
|
|
|
goto fault;
|
2015-05-16 17:35:36 -03:00
|
|
|
}
|
2011-02-06 00:00:13 -08:00
|
|
|
|
|
|
|
/* Select that program in OpenGL */
|
2013-10-03 20:48:52 -07:00
|
|
|
data->glUseProgram(program->id);
|
2011-02-06 00:00:13 -08:00
|
|
|
|
|
|
|
/* Set the current program */
|
2013-10-03 20:48:52 -07:00
|
|
|
data->current_program = program;
|
2011-02-06 00:00:13 -08:00
|
|
|
|
|
|
|
/* Activate an orthographic projection */
|
2015-05-16 17:35:36 -03:00
|
|
|
if (GLES2_SetOrthographicProjection(renderer) < 0) {
|
2011-02-06 00:00:13 -08:00
|
|
|
goto fault;
|
2015-05-16 17:35:36 -03:00
|
|
|
}
|
2011-02-06 00:00:13 -08:00
|
|
|
|
|
|
|
/* Clean up and return */
|
|
|
|
return 0;
|
|
|
|
fault:
|
2015-05-16 17:35:36 -03:00
|
|
|
if (vertex && vertex->references <= 0) {
|
2011-02-06 00:00:13 -08:00
|
|
|
GLES2_EvictShader(renderer, vertex);
|
2015-05-16 17:35:36 -03:00
|
|
|
}
|
|
|
|
if (fragment && fragment->references <= 0) {
|
2011-02-06 00:00:13 -08:00
|
|
|
GLES2_EvictShader(renderer, fragment);
|
2015-05-16 17:35:36 -03:00
|
|
|
}
|
2013-10-03 20:48:52 -07:00
|
|
|
data->current_program = NULL;
|
2011-02-06 00:00:13 -08:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
GLES2_SetOrthographicProjection(SDL_Renderer *renderer)
|
|
|
|
{
|
2013-10-03 20:48:52 -07:00
|
|
|
GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->driverdata;
|
2011-02-06 00:00:13 -08:00
|
|
|
GLfloat projection[4][4];
|
|
|
|
|
2013-05-29 03:07:55 -07:00
|
|
|
if (!renderer->viewport.w || !renderer->viewport.h) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2011-02-06 00:00:13 -08:00
|
|
|
/* Prepare an orthographic projection */
|
2011-02-15 13:59:59 -08:00
|
|
|
projection[0][0] = 2.0f / renderer->viewport.w;
|
2011-02-06 00:00:13 -08:00
|
|
|
projection[0][1] = 0.0f;
|
|
|
|
projection[0][2] = 0.0f;
|
|
|
|
projection[0][3] = 0.0f;
|
|
|
|
projection[1][0] = 0.0f;
|
2012-06-22 11:38:49 -04:00
|
|
|
if (renderer->target) {
|
|
|
|
projection[1][1] = 2.0f / renderer->viewport.h;
|
|
|
|
} else {
|
|
|
|
projection[1][1] = -2.0f / renderer->viewport.h;
|
|
|
|
}
|
2011-02-06 00:00:13 -08:00
|
|
|
projection[1][2] = 0.0f;
|
|
|
|
projection[1][3] = 0.0f;
|
|
|
|
projection[2][0] = 0.0f;
|
|
|
|
projection[2][1] = 0.0f;
|
2012-06-22 11:38:49 -04:00
|
|
|
projection[2][2] = 0.0f;
|
2011-02-06 00:00:13 -08:00
|
|
|
projection[2][3] = 0.0f;
|
|
|
|
projection[3][0] = -1.0f;
|
2012-06-22 11:38:49 -04:00
|
|
|
if (renderer->target) {
|
|
|
|
projection[3][1] = -1.0f;
|
|
|
|
} else {
|
|
|
|
projection[3][1] = 1.0f;
|
|
|
|
}
|
2011-02-06 00:00:13 -08:00
|
|
|
projection[3][2] = 0.0f;
|
|
|
|
projection[3][3] = 1.0f;
|
|
|
|
|
|
|
|
/* Set the projection matrix */
|
2013-10-05 00:29:57 -04:00
|
|
|
if (SDL_memcmp(data->current_program->projection, projection, sizeof (projection)) != 0) {
|
|
|
|
const GLuint locProjection = data->current_program->uniform_locations[GLES2_UNIFORM_PROJECTION];
|
|
|
|
data->glUniformMatrix4fv(locProjection, 1, GL_FALSE, (GLfloat *)projection);
|
|
|
|
SDL_memcpy(data->current_program->projection, projection, sizeof (projection));
|
|
|
|
}
|
|
|
|
|
2011-02-06 00:00:13 -08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************************************
|
|
|
|
* Rendering functions *
|
|
|
|
*************************************************************************************************/
|
|
|
|
|
2011-02-07 20:06:26 -08:00
|
|
|
static const float inv255f = 1.0f / 255.0f;
|
|
|
|
|
2011-02-06 00:00:13 -08:00
|
|
|
static int GLES2_RenderClear(SDL_Renderer *renderer);
|
2012-10-01 20:59:33 -07:00
|
|
|
static int GLES2_RenderDrawPoints(SDL_Renderer *renderer, const SDL_FPoint *points, int count);
|
|
|
|
static int GLES2_RenderDrawLines(SDL_Renderer *renderer, const SDL_FPoint *points, int count);
|
|
|
|
static int GLES2_RenderFillRects(SDL_Renderer *renderer, const SDL_FRect *rects, int count);
|
2011-02-06 00:00:13 -08:00
|
|
|
static int GLES2_RenderCopy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *srcrect,
|
2012-10-01 20:59:33 -07:00
|
|
|
const SDL_FRect *dstrect);
|
2012-06-01 19:51:08 -03:00
|
|
|
static int GLES2_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture,
|
2012-10-01 20:59:33 -07:00
|
|
|
const SDL_Rect * srcrect, const SDL_FRect * dstrect,
|
|
|
|
const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip);
|
2013-05-04 04:46:00 -07:00
|
|
|
static int GLES2_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
|
|
|
|
Uint32 pixel_format, void * pixels, int pitch);
|
2011-02-06 00:00:13 -08:00
|
|
|
static void GLES2_RenderPresent(SDL_Renderer *renderer);
|
|
|
|
|
2013-10-05 12:29:05 -07:00
|
|
|
static SDL_bool
|
|
|
|
CompareColors(Uint8 r1, Uint8 g1, Uint8 b1, Uint8 a1,
|
|
|
|
Uint8 r2, Uint8 g2, Uint8 b2, Uint8 a2)
|
|
|
|
{
|
|
|
|
Uint32 Pixel1, Pixel2;
|
|
|
|
RGBA8888_FROM_RGBA(Pixel1, r1, g1, b1, a1);
|
|
|
|
RGBA8888_FROM_RGBA(Pixel2, r2, g2, b2, a2);
|
|
|
|
return (Pixel1 == Pixel2);
|
|
|
|
}
|
2011-02-17 02:23:48 -08:00
|
|
|
|
2011-02-06 00:00:13 -08:00
|
|
|
static int
|
2011-02-17 02:23:48 -08:00
|
|
|
GLES2_RenderClear(SDL_Renderer * renderer)
|
2011-02-06 00:00:13 -08:00
|
|
|
{
|
2014-02-09 01:49:01 -08:00
|
|
|
Uint8 r, g, b, a;
|
|
|
|
|
2013-10-03 20:48:52 -07:00
|
|
|
GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->driverdata;
|
2011-02-06 00:00:13 -08:00
|
|
|
|
Fixed bug 1242 - PATCH: Improve support for OpenGL ES under X11
Scott Percival 2011-07-03 06:41:51 PDT
This submission is aimed at making life easier for OpenGL ES capable devices
running a X11 stack (e.g. Maemo, Meego, TrimSlice, other ARM SoC boards not
running Android). SDL's Pandora support already has the neccesary GLES-to-X11
glue code, however it's all ghetto'd off in Makefile.pandora and not very
flexible.
The patch:
- adds an awesome --enable-video-opengles option to configure
- re-modifies the opengles and opengles2 SDL_renderers to use function pointers
- no idea why this was removed?
- for SDL_Renderers, links in libGLESv1_CM, libGLES_CM (for PowerVR fans) or
libGLESv2 at runtime
- links in libEGL.so at runtime - the old code made an assumption that
eglFunctions could be pulled from the active GLES library, PowerVR for one
doesn't let you do that with their libGLESv2
- allows you to pick which of GLES v1 or v2 to load via
SDL_GL_CONTEXT_MAJOR_VERSION
So far I've tested this on a Nokia N900 (OMAP 3430/SGX 530 running Maemo 5) and
a Toshiba AC100 (Tegra 2 running Ubuntu 10.10). I haven't tested it on... well,
everything that isn't those two, such as a Pandora, iOS or Android device. The
Pandora specific code should be kept intact (fingers crossed), and nothing
painfully drastic has been added to the SDL_renderers. The library loading
sequence in SDL_x11opengles has been updated to accomodate both NVIDIA's
propensity to let developers get away with murder and PowerVR's alternative of
punishing every missed step.
The test apps work okay with GLES or GLES2 as the renderer. For some reason
alpha blending doesn't seem to work on the Tegra 2; last week NVIDIA pushed out
a new set of X11 GLES drivers, so I'll try and investigate once I upgrade
those. Also, this patch adds things to configure.in, include/SDL_config.h.in
and test/configure.in. I didn't know what the policy was re. committing
generated spaghetti from autotools, so ./autogen.sh has to be run again. Sorry.
I think that's about everything, let me know if there's anything I've
overlooked.
2012-01-08 02:23:37 -05:00
|
|
|
GLES2_ActivateRenderer(renderer);
|
2012-01-18 22:45:49 -05:00
|
|
|
|
2013-10-05 12:29:05 -07:00
|
|
|
if (!CompareColors(data->clear_r, data->clear_g, data->clear_b, data->clear_a,
|
|
|
|
renderer->r, renderer->g, renderer->b, renderer->a)) {
|
2014-02-09 01:49:01 -08:00
|
|
|
|
|
|
|
/* Select the color to clear with */
|
|
|
|
g = renderer->g;
|
|
|
|
a = renderer->a;
|
|
|
|
|
|
|
|
if (renderer->target &&
|
|
|
|
(renderer->target->format == SDL_PIXELFORMAT_ARGB8888 ||
|
|
|
|
renderer->target->format == SDL_PIXELFORMAT_RGB888)) {
|
|
|
|
r = renderer->b;
|
|
|
|
b = renderer->r;
|
|
|
|
} else {
|
|
|
|
r = renderer->r;
|
|
|
|
b = renderer->b;
|
|
|
|
}
|
|
|
|
|
|
|
|
data->glClearColor((GLfloat) r * inv255f,
|
|
|
|
(GLfloat) g * inv255f,
|
|
|
|
(GLfloat) b * inv255f,
|
|
|
|
(GLfloat) a * inv255f);
|
2013-10-05 00:29:57 -04:00
|
|
|
data->clear_r = renderer->r;
|
|
|
|
data->clear_g = renderer->g;
|
|
|
|
data->clear_b = renderer->b;
|
|
|
|
data->clear_a = renderer->a;
|
|
|
|
}
|
2011-02-17 02:23:48 -08:00
|
|
|
|
2016-10-01 11:46:32 -07:00
|
|
|
if (renderer->clipping_enabled) {
|
|
|
|
data->glDisable(GL_SCISSOR_TEST);
|
|
|
|
}
|
|
|
|
|
2013-10-03 20:48:52 -07:00
|
|
|
data->glClear(GL_COLOR_BUFFER_BIT);
|
2011-02-17 02:23:48 -08:00
|
|
|
|
2016-10-01 11:46:32 -07:00
|
|
|
if (renderer->clipping_enabled) {
|
|
|
|
data->glEnable(GL_SCISSOR_TEST);
|
|
|
|
}
|
|
|
|
|
2011-02-06 00:00:13 -08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
Implemented more flexible blending modes for accelerated renderers
This fixes bug 2594 - Propose new blend mode, SDL_BLENDMODE_BLEND_DSTA
blendMode = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_SRC_ALPHA,
SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
SDL_BLENDOPERATION_ADD,
SDL_BLENDFACTOR_ZERO,
SDL_BLENDFACTOR_ONE,
SDL_BLENDOPERATION_ADD);
This fixes bug 2828 - Subtractive Blending
blendMode = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_SRC_ALPHA,
SDL_BLENDFACTOR_ONE,
SDL_BLENDOPERATION_SUBTRACT,
SDL_BLENDFACTOR_ZERO,
SDL_BLENDFACTOR_ONE,
SDL_BLENDOPERATION_SUBTRACT);
This goes partway to fixing bug 3684 - Add support for a pre-multiplied alpha blending mode
blendMode = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_ONE,
SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
SDL_BLENDOPERATION_ADD,
SDL_BLENDFACTOR_ONE,
SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
SDL_BLENDOPERATION_ADD);
2017-08-14 05:51:44 -07:00
|
|
|
GLES2_SetBlendMode(GLES2_DriverContext *data, SDL_BlendMode blendMode)
|
2011-02-06 00:00:13 -08:00
|
|
|
{
|
2013-10-03 20:48:52 -07:00
|
|
|
if (blendMode != data->current.blendMode) {
|
Implemented more flexible blending modes for accelerated renderers
This fixes bug 2594 - Propose new blend mode, SDL_BLENDMODE_BLEND_DSTA
blendMode = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_SRC_ALPHA,
SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
SDL_BLENDOPERATION_ADD,
SDL_BLENDFACTOR_ZERO,
SDL_BLENDFACTOR_ONE,
SDL_BLENDOPERATION_ADD);
This fixes bug 2828 - Subtractive Blending
blendMode = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_SRC_ALPHA,
SDL_BLENDFACTOR_ONE,
SDL_BLENDOPERATION_SUBTRACT,
SDL_BLENDFACTOR_ZERO,
SDL_BLENDFACTOR_ONE,
SDL_BLENDOPERATION_SUBTRACT);
This goes partway to fixing bug 3684 - Add support for a pre-multiplied alpha blending mode
blendMode = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_ONE,
SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
SDL_BLENDOPERATION_ADD,
SDL_BLENDFACTOR_ONE,
SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
SDL_BLENDOPERATION_ADD);
2017-08-14 05:51:44 -07:00
|
|
|
if (blendMode == SDL_BLENDMODE_NONE) {
|
2013-10-03 20:48:52 -07:00
|
|
|
data->glDisable(GL_BLEND);
|
Implemented more flexible blending modes for accelerated renderers
This fixes bug 2594 - Propose new blend mode, SDL_BLENDMODE_BLEND_DSTA
blendMode = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_SRC_ALPHA,
SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
SDL_BLENDOPERATION_ADD,
SDL_BLENDFACTOR_ZERO,
SDL_BLENDFACTOR_ONE,
SDL_BLENDOPERATION_ADD);
This fixes bug 2828 - Subtractive Blending
blendMode = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_SRC_ALPHA,
SDL_BLENDFACTOR_ONE,
SDL_BLENDOPERATION_SUBTRACT,
SDL_BLENDFACTOR_ZERO,
SDL_BLENDFACTOR_ONE,
SDL_BLENDOPERATION_SUBTRACT);
This goes partway to fixing bug 3684 - Add support for a pre-multiplied alpha blending mode
blendMode = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_ONE,
SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
SDL_BLENDOPERATION_ADD,
SDL_BLENDFACTOR_ONE,
SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
SDL_BLENDOPERATION_ADD);
2017-08-14 05:51:44 -07:00
|
|
|
} else {
|
2013-10-03 20:48:52 -07:00
|
|
|
data->glEnable(GL_BLEND);
|
Implemented more flexible blending modes for accelerated renderers
This fixes bug 2594 - Propose new blend mode, SDL_BLENDMODE_BLEND_DSTA
blendMode = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_SRC_ALPHA,
SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
SDL_BLENDOPERATION_ADD,
SDL_BLENDFACTOR_ZERO,
SDL_BLENDFACTOR_ONE,
SDL_BLENDOPERATION_ADD);
This fixes bug 2828 - Subtractive Blending
blendMode = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_SRC_ALPHA,
SDL_BLENDFACTOR_ONE,
SDL_BLENDOPERATION_SUBTRACT,
SDL_BLENDFACTOR_ZERO,
SDL_BLENDFACTOR_ONE,
SDL_BLENDOPERATION_SUBTRACT);
This goes partway to fixing bug 3684 - Add support for a pre-multiplied alpha blending mode
blendMode = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_ONE,
SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
SDL_BLENDOPERATION_ADD,
SDL_BLENDFACTOR_ONE,
SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
SDL_BLENDOPERATION_ADD);
2017-08-14 05:51:44 -07:00
|
|
|
data->glBlendFuncSeparate(GetBlendFunc(SDL_GetBlendModeSrcColorFactor(blendMode)),
|
|
|
|
GetBlendFunc(SDL_GetBlendModeDstColorFactor(blendMode)),
|
|
|
|
GetBlendFunc(SDL_GetBlendModeSrcAlphaFactor(blendMode)),
|
|
|
|
GetBlendFunc(SDL_GetBlendModeDstAlphaFactor(blendMode)));
|
|
|
|
data->glBlendEquationSeparate(GetBlendEquation(SDL_GetBlendModeColorOperation(blendMode)),
|
|
|
|
GetBlendEquation(SDL_GetBlendModeAlphaOperation(blendMode)));
|
2011-02-19 21:51:21 -08:00
|
|
|
}
|
2013-10-03 20:48:52 -07:00
|
|
|
data->current.blendMode = blendMode;
|
2011-02-19 21:51:21 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2013-10-03 20:48:52 -07:00
|
|
|
GLES2_SetTexCoords(GLES2_DriverContext * data, SDL_bool enabled)
|
2011-02-19 21:51:21 -08:00
|
|
|
{
|
2013-10-03 20:48:52 -07:00
|
|
|
if (enabled != data->current.tex_coords) {
|
2011-02-19 21:51:21 -08:00
|
|
|
if (enabled) {
|
2013-10-03 20:48:52 -07:00
|
|
|
data->glEnableVertexAttribArray(GLES2_ATTRIBUTE_TEXCOORD);
|
2011-02-19 21:51:21 -08:00
|
|
|
} else {
|
2013-10-03 20:48:52 -07:00
|
|
|
data->glDisableVertexAttribArray(GLES2_ATTRIBUTE_TEXCOORD);
|
2011-02-19 21:51:21 -08:00
|
|
|
}
|
2013-10-03 20:48:52 -07:00
|
|
|
data->current.tex_coords = enabled;
|
2011-02-06 00:00:13 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2011-02-19 21:51:21 -08:00
|
|
|
GLES2_SetDrawingState(SDL_Renderer * renderer)
|
2011-02-06 00:00:13 -08:00
|
|
|
{
|
2013-10-03 20:48:52 -07:00
|
|
|
GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->driverdata;
|
2013-10-05 00:29:57 -04:00
|
|
|
GLES2_ProgramCacheEntry *program;
|
|
|
|
Uint8 r, g, b, a;
|
2011-02-19 21:51:21 -08:00
|
|
|
|
2011-02-06 00:00:13 -08:00
|
|
|
GLES2_ActivateRenderer(renderer);
|
|
|
|
|
Implemented more flexible blending modes for accelerated renderers
This fixes bug 2594 - Propose new blend mode, SDL_BLENDMODE_BLEND_DSTA
blendMode = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_SRC_ALPHA,
SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
SDL_BLENDOPERATION_ADD,
SDL_BLENDFACTOR_ZERO,
SDL_BLENDFACTOR_ONE,
SDL_BLENDOPERATION_ADD);
This fixes bug 2828 - Subtractive Blending
blendMode = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_SRC_ALPHA,
SDL_BLENDFACTOR_ONE,
SDL_BLENDOPERATION_SUBTRACT,
SDL_BLENDFACTOR_ZERO,
SDL_BLENDFACTOR_ONE,
SDL_BLENDOPERATION_SUBTRACT);
This goes partway to fixing bug 3684 - Add support for a pre-multiplied alpha blending mode
blendMode = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_ONE,
SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
SDL_BLENDOPERATION_ADD,
SDL_BLENDFACTOR_ONE,
SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
SDL_BLENDOPERATION_ADD);
2017-08-14 05:51:44 -07:00
|
|
|
GLES2_SetBlendMode(data, renderer->blendMode);
|
2011-02-19 21:51:21 -08:00
|
|
|
|
2013-10-03 20:48:52 -07:00
|
|
|
GLES2_SetTexCoords(data, SDL_FALSE);
|
2011-02-06 00:00:13 -08:00
|
|
|
|
|
|
|
/* Activate an appropriate shader and set the projection matrix */
|
Implemented more flexible blending modes for accelerated renderers
This fixes bug 2594 - Propose new blend mode, SDL_BLENDMODE_BLEND_DSTA
blendMode = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_SRC_ALPHA,
SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
SDL_BLENDOPERATION_ADD,
SDL_BLENDFACTOR_ZERO,
SDL_BLENDFACTOR_ONE,
SDL_BLENDOPERATION_ADD);
This fixes bug 2828 - Subtractive Blending
blendMode = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_SRC_ALPHA,
SDL_BLENDFACTOR_ONE,
SDL_BLENDOPERATION_SUBTRACT,
SDL_BLENDFACTOR_ZERO,
SDL_BLENDFACTOR_ONE,
SDL_BLENDOPERATION_SUBTRACT);
This goes partway to fixing bug 3684 - Add support for a pre-multiplied alpha blending mode
blendMode = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_ONE,
SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
SDL_BLENDOPERATION_ADD,
SDL_BLENDFACTOR_ONE,
SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
SDL_BLENDOPERATION_ADD);
2017-08-14 05:51:44 -07:00
|
|
|
if (GLES2_SelectProgram(renderer, GLES2_IMAGESOURCE_SOLID) < 0) {
|
2011-02-06 00:00:13 -08:00
|
|
|
return -1;
|
2013-10-05 00:29:57 -04:00
|
|
|
}
|
2011-02-06 00:00:13 -08:00
|
|
|
|
|
|
|
/* Select the color to draw with */
|
2013-10-05 00:29:57 -04:00
|
|
|
g = renderer->g;
|
|
|
|
a = renderer->a;
|
|
|
|
|
2012-06-22 11:38:49 -04:00
|
|
|
if (renderer->target &&
|
2013-10-05 00:29:57 -04:00
|
|
|
(renderer->target->format == SDL_PIXELFORMAT_ARGB8888 ||
|
2012-06-22 11:38:49 -04:00
|
|
|
renderer->target->format == SDL_PIXELFORMAT_RGB888)) {
|
2013-10-05 00:29:57 -04:00
|
|
|
r = renderer->b;
|
|
|
|
b = renderer->r;
|
|
|
|
} else {
|
|
|
|
r = renderer->r;
|
|
|
|
b = renderer->b;
|
|
|
|
}
|
|
|
|
|
|
|
|
program = data->current_program;
|
2013-10-05 12:29:05 -07:00
|
|
|
if (!CompareColors(program->color_r, program->color_g, program->color_b, program->color_a, r, g, b, a)) {
|
2013-10-05 00:29:57 -04:00
|
|
|
/* Select the color to draw with */
|
|
|
|
data->glUniform4f(program->uniform_locations[GLES2_UNIFORM_COLOR], r * inv255f, g * inv255f, b * inv255f, a * inv255f);
|
|
|
|
program->color_r = r;
|
|
|
|
program->color_g = g;
|
|
|
|
program->color_b = b;
|
|
|
|
program->color_a = a;
|
2012-06-22 11:38:49 -04:00
|
|
|
}
|
2013-10-05 00:29:57 -04:00
|
|
|
|
2011-02-19 21:51:21 -08:00
|
|
|
return 0;
|
|
|
|
}
|
2011-02-06 00:00:13 -08:00
|
|
|
|
Initial merge of Emscripten port!
With this commit, you can compile SDL2 with Emscripten
( http://emscripten.org/ ), and make your SDL-based C/C++ program
into a web app.
This port was due to the efforts of several people, including: Charlie Birks,
Sathyanarayanan Gunasekaran, Jukka Jylänki, Alon Zakai, Edward Rudd,
Bruce Mitchener, and Martin Gerhardy. (Thanks, everyone!)
--HG--
extra : rebase_source : 97af74c8a5121e926ebe89f123536b5dd6681695
2014-12-18 00:19:52 -05:00
|
|
|
static int
|
|
|
|
GLES2_UpdateVertexBuffer(SDL_Renderer *renderer, GLES2_Attribute attr,
|
|
|
|
const void *vertexData, size_t dataSizeInBytes)
|
|
|
|
{
|
|
|
|
GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->driverdata;
|
2014-12-26 22:30:19 -05:00
|
|
|
|
|
|
|
#if !SDL_GLES2_USE_VBOS
|
Initial merge of Emscripten port!
With this commit, you can compile SDL2 with Emscripten
( http://emscripten.org/ ), and make your SDL-based C/C++ program
into a web app.
This port was due to the efforts of several people, including: Charlie Birks,
Sathyanarayanan Gunasekaran, Jukka Jylänki, Alon Zakai, Edward Rudd,
Bruce Mitchener, and Martin Gerhardy. (Thanks, everyone!)
--HG--
extra : rebase_source : 97af74c8a5121e926ebe89f123536b5dd6681695
2014-12-18 00:19:52 -05:00
|
|
|
data->glVertexAttribPointer(attr, attr == GLES2_ATTRIBUTE_ANGLE ? 1 : 2, GL_FLOAT, GL_FALSE, 0, vertexData);
|
|
|
|
#else
|
2015-05-16 17:35:36 -03:00
|
|
|
if (!data->vertex_buffers[attr]) {
|
Initial merge of Emscripten port!
With this commit, you can compile SDL2 with Emscripten
( http://emscripten.org/ ), and make your SDL-based C/C++ program
into a web app.
This port was due to the efforts of several people, including: Charlie Birks,
Sathyanarayanan Gunasekaran, Jukka Jylänki, Alon Zakai, Edward Rudd,
Bruce Mitchener, and Martin Gerhardy. (Thanks, everyone!)
--HG--
extra : rebase_source : 97af74c8a5121e926ebe89f123536b5dd6681695
2014-12-18 00:19:52 -05:00
|
|
|
data->glGenBuffers(1, &data->vertex_buffers[attr]);
|
2015-05-16 17:35:36 -03:00
|
|
|
}
|
Initial merge of Emscripten port!
With this commit, you can compile SDL2 with Emscripten
( http://emscripten.org/ ), and make your SDL-based C/C++ program
into a web app.
This port was due to the efforts of several people, including: Charlie Birks,
Sathyanarayanan Gunasekaran, Jukka Jylänki, Alon Zakai, Edward Rudd,
Bruce Mitchener, and Martin Gerhardy. (Thanks, everyone!)
--HG--
extra : rebase_source : 97af74c8a5121e926ebe89f123536b5dd6681695
2014-12-18 00:19:52 -05:00
|
|
|
|
|
|
|
data->glBindBuffer(GL_ARRAY_BUFFER, data->vertex_buffers[attr]);
|
|
|
|
|
|
|
|
if (data->vertex_buffer_size[attr] < dataSizeInBytes) {
|
|
|
|
data->glBufferData(GL_ARRAY_BUFFER, dataSizeInBytes, vertexData, GL_STREAM_DRAW);
|
|
|
|
data->vertex_buffer_size[attr] = dataSizeInBytes;
|
|
|
|
} else {
|
|
|
|
data->glBufferSubData(GL_ARRAY_BUFFER, 0, dataSizeInBytes, vertexData);
|
|
|
|
}
|
|
|
|
|
|
|
|
data->glVertexAttribPointer(attr, attr == GLES2_ATTRIBUTE_ANGLE ? 1 : 2, GL_FLOAT, GL_FALSE, 0, 0);
|
|
|
|
#endif
|
2014-12-26 22:30:19 -05:00
|
|
|
|
Initial merge of Emscripten port!
With this commit, you can compile SDL2 with Emscripten
( http://emscripten.org/ ), and make your SDL-based C/C++ program
into a web app.
This port was due to the efforts of several people, including: Charlie Birks,
Sathyanarayanan Gunasekaran, Jukka Jylänki, Alon Zakai, Edward Rudd,
Bruce Mitchener, and Martin Gerhardy. (Thanks, everyone!)
--HG--
extra : rebase_source : 97af74c8a5121e926ebe89f123536b5dd6681695
2014-12-18 00:19:52 -05:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2011-02-19 21:51:21 -08:00
|
|
|
static int
|
2012-10-01 20:59:33 -07:00
|
|
|
GLES2_RenderDrawPoints(SDL_Renderer *renderer, const SDL_FPoint *points, int count)
|
2011-02-19 21:51:21 -08:00
|
|
|
{
|
2013-10-03 20:48:52 -07:00
|
|
|
GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->driverdata;
|
2011-02-19 21:51:21 -08:00
|
|
|
GLfloat *vertices;
|
|
|
|
int idx;
|
|
|
|
|
|
|
|
if (GLES2_SetDrawingState(renderer) < 0) {
|
|
|
|
return -1;
|
|
|
|
}
|
2011-02-06 00:00:13 -08:00
|
|
|
|
|
|
|
/* Emit the specified vertices as points */
|
|
|
|
vertices = SDL_stack_alloc(GLfloat, count * 2);
|
2013-03-31 12:48:50 -04:00
|
|
|
for (idx = 0; idx < count; ++idx) {
|
2012-10-01 20:59:33 -07:00
|
|
|
GLfloat x = points[idx].x + 0.5f;
|
|
|
|
GLfloat y = points[idx].y + 0.5f;
|
2011-02-06 00:00:13 -08:00
|
|
|
|
|
|
|
vertices[idx * 2] = x;
|
|
|
|
vertices[(idx * 2) + 1] = y;
|
|
|
|
}
|
Initial merge of Emscripten port!
With this commit, you can compile SDL2 with Emscripten
( http://emscripten.org/ ), and make your SDL-based C/C++ program
into a web app.
This port was due to the efforts of several people, including: Charlie Birks,
Sathyanarayanan Gunasekaran, Jukka Jylänki, Alon Zakai, Edward Rudd,
Bruce Mitchener, and Martin Gerhardy. (Thanks, everyone!)
--HG--
extra : rebase_source : 97af74c8a5121e926ebe89f123536b5dd6681695
2014-12-18 00:19:52 -05:00
|
|
|
/*data->glVertexAttribPointer(GLES2_ATTRIBUTE_POSITION, 2, GL_FLOAT, GL_FALSE, 0, vertices);*/
|
|
|
|
GLES2_UpdateVertexBuffer(renderer, GLES2_ATTRIBUTE_POSITION, vertices, count * 2 * sizeof(GLfloat));
|
2013-10-03 20:48:52 -07:00
|
|
|
data->glDrawArrays(GL_POINTS, 0, count);
|
2011-02-06 00:00:13 -08:00
|
|
|
SDL_stack_free(vertices);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2012-10-01 20:59:33 -07:00
|
|
|
GLES2_RenderDrawLines(SDL_Renderer *renderer, const SDL_FPoint *points, int count)
|
2011-02-06 00:00:13 -08:00
|
|
|
{
|
2013-10-03 20:48:52 -07:00
|
|
|
GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->driverdata;
|
2011-02-06 00:00:13 -08:00
|
|
|
GLfloat *vertices;
|
|
|
|
int idx;
|
|
|
|
|
2011-02-19 21:51:21 -08:00
|
|
|
if (GLES2_SetDrawingState(renderer) < 0) {
|
2011-02-06 00:00:13 -08:00
|
|
|
return -1;
|
2011-02-19 21:51:21 -08:00
|
|
|
}
|
2011-02-06 00:00:13 -08:00
|
|
|
|
|
|
|
/* Emit a line strip including the specified vertices */
|
|
|
|
vertices = SDL_stack_alloc(GLfloat, count * 2);
|
2013-03-31 12:48:50 -04:00
|
|
|
for (idx = 0; idx < count; ++idx) {
|
2012-10-01 20:59:33 -07:00
|
|
|
GLfloat x = points[idx].x + 0.5f;
|
|
|
|
GLfloat y = points[idx].y + 0.5f;
|
2011-02-06 00:00:13 -08:00
|
|
|
|
|
|
|
vertices[idx * 2] = x;
|
|
|
|
vertices[(idx * 2) + 1] = y;
|
|
|
|
}
|
Initial merge of Emscripten port!
With this commit, you can compile SDL2 with Emscripten
( http://emscripten.org/ ), and make your SDL-based C/C++ program
into a web app.
This port was due to the efforts of several people, including: Charlie Birks,
Sathyanarayanan Gunasekaran, Jukka Jylänki, Alon Zakai, Edward Rudd,
Bruce Mitchener, and Martin Gerhardy. (Thanks, everyone!)
--HG--
extra : rebase_source : 97af74c8a5121e926ebe89f123536b5dd6681695
2014-12-18 00:19:52 -05:00
|
|
|
/*data->glVertexAttribPointer(GLES2_ATTRIBUTE_POSITION, 2, GL_FLOAT, GL_FALSE, 0, vertices);*/
|
|
|
|
GLES2_UpdateVertexBuffer(renderer, GLES2_ATTRIBUTE_POSITION, vertices, count * 2 * sizeof(GLfloat));
|
2013-10-03 20:48:52 -07:00
|
|
|
data->glDrawArrays(GL_LINE_STRIP, 0, count);
|
2011-11-10 00:22:44 -05:00
|
|
|
|
|
|
|
/* We need to close the endpoint of the line */
|
|
|
|
if (count == 2 ||
|
|
|
|
points[0].x != points[count-1].x || points[0].y != points[count-1].y) {
|
2013-10-03 20:48:52 -07:00
|
|
|
data->glDrawArrays(GL_POINTS, count-1, 1);
|
2011-11-10 00:22:44 -05:00
|
|
|
}
|
2011-02-06 00:00:13 -08:00
|
|
|
SDL_stack_free(vertices);
|
2013-10-03 20:48:52 -07:00
|
|
|
|
|
|
|
return GL_CheckError("", renderer);
|
2011-02-06 00:00:13 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2012-10-01 20:59:33 -07:00
|
|
|
GLES2_RenderFillRects(SDL_Renderer *renderer, const SDL_FRect *rects, int count)
|
2011-02-06 00:00:13 -08:00
|
|
|
{
|
2013-10-03 20:48:52 -07:00
|
|
|
GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->driverdata;
|
2011-02-06 00:00:13 -08:00
|
|
|
GLfloat vertices[8];
|
|
|
|
int idx;
|
|
|
|
|
2011-02-19 21:51:21 -08:00
|
|
|
if (GLES2_SetDrawingState(renderer) < 0) {
|
2011-02-06 00:00:13 -08:00
|
|
|
return -1;
|
2011-02-19 21:51:21 -08:00
|
|
|
}
|
2011-02-06 00:00:13 -08:00
|
|
|
|
|
|
|
/* Emit a line loop for each rectangle */
|
2011-02-15 13:59:59 -08:00
|
|
|
for (idx = 0; idx < count; ++idx) {
|
2012-10-01 20:59:33 -07:00
|
|
|
const SDL_FRect *rect = &rects[idx];
|
2011-02-15 13:59:59 -08:00
|
|
|
|
2012-10-01 20:59:33 -07:00
|
|
|
GLfloat xMin = rect->x;
|
|
|
|
GLfloat xMax = (rect->x + rect->w);
|
|
|
|
GLfloat yMin = rect->y;
|
|
|
|
GLfloat yMax = (rect->y + rect->h);
|
2011-02-06 00:00:13 -08:00
|
|
|
|
|
|
|
vertices[0] = xMin;
|
|
|
|
vertices[1] = yMin;
|
|
|
|
vertices[2] = xMax;
|
|
|
|
vertices[3] = yMin;
|
|
|
|
vertices[4] = xMin;
|
|
|
|
vertices[5] = yMax;
|
|
|
|
vertices[6] = xMax;
|
|
|
|
vertices[7] = yMax;
|
Initial merge of Emscripten port!
With this commit, you can compile SDL2 with Emscripten
( http://emscripten.org/ ), and make your SDL-based C/C++ program
into a web app.
This port was due to the efforts of several people, including: Charlie Birks,
Sathyanarayanan Gunasekaran, Jukka Jylänki, Alon Zakai, Edward Rudd,
Bruce Mitchener, and Martin Gerhardy. (Thanks, everyone!)
--HG--
extra : rebase_source : 97af74c8a5121e926ebe89f123536b5dd6681695
2014-12-18 00:19:52 -05:00
|
|
|
/*data->glVertexAttribPointer(GLES2_ATTRIBUTE_POSITION, 2, GL_FLOAT, GL_FALSE, 0, vertices);*/
|
|
|
|
GLES2_UpdateVertexBuffer(renderer, GLES2_ATTRIBUTE_POSITION, vertices, 8 * sizeof(GLfloat));
|
2013-10-03 20:48:52 -07:00
|
|
|
data->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
2011-02-06 00:00:13 -08:00
|
|
|
}
|
2013-10-03 20:48:52 -07:00
|
|
|
return GL_CheckError("", renderer);
|
2011-02-06 00:00:13 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2014-08-06 11:34:54 -07:00
|
|
|
GLES2_SetupCopy(SDL_Renderer *renderer, SDL_Texture *texture)
|
2011-02-06 00:00:13 -08:00
|
|
|
{
|
2013-10-03 20:48:52 -07:00
|
|
|
GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->driverdata;
|
2011-02-06 00:00:13 -08:00
|
|
|
GLES2_TextureData *tdata = (GLES2_TextureData *)texture->driverdata;
|
2013-08-22 17:26:22 -03:00
|
|
|
GLES2_ImageSource sourceType = GLES2_IMAGESOURCE_TEXTURE_ABGR;
|
2013-10-05 00:29:57 -04:00
|
|
|
GLES2_ProgramCacheEntry *program;
|
|
|
|
Uint8 r, g, b, a;
|
2011-02-06 00:00:13 -08:00
|
|
|
|
2012-06-01 19:51:08 -03:00
|
|
|
/* Activate an appropriate shader and set the projection matrix */
|
|
|
|
if (renderer->target) {
|
|
|
|
/* Check if we need to do color mapping between the source and render target textures */
|
|
|
|
if (renderer->target->format != texture->format) {
|
2015-05-16 17:35:36 -03:00
|
|
|
switch (texture->format) {
|
2014-06-21 21:46:42 -07:00
|
|
|
case SDL_PIXELFORMAT_ARGB8888:
|
2015-05-16 17:35:36 -03:00
|
|
|
switch (renderer->target->format) {
|
|
|
|
case SDL_PIXELFORMAT_ABGR8888:
|
|
|
|
case SDL_PIXELFORMAT_BGR888:
|
|
|
|
sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB;
|
|
|
|
break;
|
|
|
|
case SDL_PIXELFORMAT_RGB888:
|
|
|
|
sourceType = GLES2_IMAGESOURCE_TEXTURE_ABGR;
|
|
|
|
break;
|
2012-06-01 19:51:08 -03:00
|
|
|
}
|
|
|
|
break;
|
2014-06-21 21:46:42 -07:00
|
|
|
case SDL_PIXELFORMAT_ABGR8888:
|
2015-05-16 17:35:36 -03:00
|
|
|
switch (renderer->target->format) {
|
|
|
|
case SDL_PIXELFORMAT_ARGB8888:
|
|
|
|
case SDL_PIXELFORMAT_RGB888:
|
|
|
|
sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB;
|
|
|
|
break;
|
|
|
|
case SDL_PIXELFORMAT_BGR888:
|
|
|
|
sourceType = GLES2_IMAGESOURCE_TEXTURE_ABGR;
|
|
|
|
break;
|
2012-06-01 19:51:08 -03:00
|
|
|
}
|
|
|
|
break;
|
2014-06-21 21:46:42 -07:00
|
|
|
case SDL_PIXELFORMAT_RGB888:
|
2015-05-16 17:35:36 -03:00
|
|
|
switch (renderer->target->format) {
|
|
|
|
case SDL_PIXELFORMAT_ABGR8888:
|
|
|
|
sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB;
|
|
|
|
break;
|
|
|
|
case SDL_PIXELFORMAT_ARGB8888:
|
|
|
|
sourceType = GLES2_IMAGESOURCE_TEXTURE_BGR;
|
|
|
|
break;
|
|
|
|
case SDL_PIXELFORMAT_BGR888:
|
|
|
|
sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB;
|
|
|
|
break;
|
2012-06-01 19:51:08 -03:00
|
|
|
}
|
|
|
|
break;
|
2014-06-21 21:46:42 -07:00
|
|
|
case SDL_PIXELFORMAT_BGR888:
|
2015-05-16 17:35:36 -03:00
|
|
|
switch (renderer->target->format) {
|
|
|
|
case SDL_PIXELFORMAT_ABGR8888:
|
|
|
|
sourceType = GLES2_IMAGESOURCE_TEXTURE_BGR;
|
|
|
|
break;
|
|
|
|
case SDL_PIXELFORMAT_ARGB8888:
|
|
|
|
sourceType = GLES2_IMAGESOURCE_TEXTURE_RGB;
|
|
|
|
break;
|
|
|
|
case SDL_PIXELFORMAT_RGB888:
|
|
|
|
sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB;
|
|
|
|
break;
|
2012-06-01 19:51:08 -03:00
|
|
|
}
|
|
|
|
break;
|
2014-08-06 11:34:54 -07:00
|
|
|
case SDL_PIXELFORMAT_IYUV:
|
|
|
|
case SDL_PIXELFORMAT_YV12:
|
|
|
|
sourceType = GLES2_IMAGESOURCE_TEXTURE_YUV;
|
|
|
|
break;
|
|
|
|
case SDL_PIXELFORMAT_NV12:
|
|
|
|
sourceType = GLES2_IMAGESOURCE_TEXTURE_NV12;
|
|
|
|
break;
|
|
|
|
case SDL_PIXELFORMAT_NV21:
|
|
|
|
sourceType = GLES2_IMAGESOURCE_TEXTURE_NV21;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return SDL_SetError("Unsupported texture format");
|
2012-06-01 19:51:08 -03:00
|
|
|
}
|
2015-05-16 17:35:36 -03:00
|
|
|
} else {
|
|
|
|
sourceType = GLES2_IMAGESOURCE_TEXTURE_ABGR; /* Texture formats match, use the non color mapping shader (even if the formats are not ABGR) */
|
2012-06-01 19:51:08 -03:00
|
|
|
}
|
2014-08-06 11:34:54 -07:00
|
|
|
} else {
|
2015-05-16 17:35:36 -03:00
|
|
|
switch (texture->format) {
|
2012-06-01 19:51:08 -03:00
|
|
|
case SDL_PIXELFORMAT_ARGB8888:
|
|
|
|
sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB;
|
|
|
|
break;
|
2014-06-21 21:46:42 -07:00
|
|
|
case SDL_PIXELFORMAT_ABGR8888:
|
|
|
|
sourceType = GLES2_IMAGESOURCE_TEXTURE_ABGR;
|
2012-06-01 19:51:08 -03:00
|
|
|
break;
|
|
|
|
case SDL_PIXELFORMAT_RGB888:
|
|
|
|
sourceType = GLES2_IMAGESOURCE_TEXTURE_RGB;
|
|
|
|
break;
|
2014-06-21 21:46:42 -07:00
|
|
|
case SDL_PIXELFORMAT_BGR888:
|
|
|
|
sourceType = GLES2_IMAGESOURCE_TEXTURE_BGR;
|
|
|
|
break;
|
2014-06-07 11:36:08 -07:00
|
|
|
case SDL_PIXELFORMAT_IYUV:
|
|
|
|
case SDL_PIXELFORMAT_YV12:
|
|
|
|
sourceType = GLES2_IMAGESOURCE_TEXTURE_YUV;
|
|
|
|
break;
|
2014-08-06 11:34:54 -07:00
|
|
|
case SDL_PIXELFORMAT_NV12:
|
|
|
|
sourceType = GLES2_IMAGESOURCE_TEXTURE_NV12;
|
|
|
|
break;
|
|
|
|
case SDL_PIXELFORMAT_NV21:
|
|
|
|
sourceType = GLES2_IMAGESOURCE_TEXTURE_NV21;
|
|
|
|
break;
|
2013-02-26 03:34:34 -08:00
|
|
|
default:
|
2014-08-06 11:34:54 -07:00
|
|
|
return SDL_SetError("Unsupported texture format");
|
2012-06-01 19:51:08 -03:00
|
|
|
}
|
|
|
|
}
|
2013-10-05 00:29:57 -04:00
|
|
|
|
Implemented more flexible blending modes for accelerated renderers
This fixes bug 2594 - Propose new blend mode, SDL_BLENDMODE_BLEND_DSTA
blendMode = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_SRC_ALPHA,
SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
SDL_BLENDOPERATION_ADD,
SDL_BLENDFACTOR_ZERO,
SDL_BLENDFACTOR_ONE,
SDL_BLENDOPERATION_ADD);
This fixes bug 2828 - Subtractive Blending
blendMode = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_SRC_ALPHA,
SDL_BLENDFACTOR_ONE,
SDL_BLENDOPERATION_SUBTRACT,
SDL_BLENDFACTOR_ZERO,
SDL_BLENDFACTOR_ONE,
SDL_BLENDOPERATION_SUBTRACT);
This goes partway to fixing bug 3684 - Add support for a pre-multiplied alpha blending mode
blendMode = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_ONE,
SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
SDL_BLENDOPERATION_ADD,
SDL_BLENDFACTOR_ONE,
SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
SDL_BLENDOPERATION_ADD);
2017-08-14 05:51:44 -07:00
|
|
|
if (GLES2_SelectProgram(renderer, sourceType) < 0) {
|
2012-06-01 19:51:08 -03:00
|
|
|
return -1;
|
2013-10-05 00:29:57 -04:00
|
|
|
}
|
2012-06-01 19:51:08 -03:00
|
|
|
|
|
|
|
/* Select the target texture */
|
2014-06-07 11:36:08 -07:00
|
|
|
if (tdata->yuv) {
|
|
|
|
data->glActiveTexture(GL_TEXTURE2);
|
|
|
|
data->glBindTexture(tdata->texture_type, tdata->texture_v);
|
|
|
|
|
|
|
|
data->glActiveTexture(GL_TEXTURE1);
|
|
|
|
data->glBindTexture(tdata->texture_type, tdata->texture_u);
|
|
|
|
|
|
|
|
data->glActiveTexture(GL_TEXTURE0);
|
|
|
|
}
|
2014-08-06 11:34:54 -07:00
|
|
|
if (tdata->nv12) {
|
|
|
|
data->glActiveTexture(GL_TEXTURE1);
|
|
|
|
data->glBindTexture(tdata->texture_type, tdata->texture_u);
|
|
|
|
|
|
|
|
data->glActiveTexture(GL_TEXTURE0);
|
|
|
|
}
|
2013-10-03 20:48:52 -07:00
|
|
|
data->glBindTexture(tdata->texture_type, tdata->texture);
|
2012-06-01 19:51:08 -03:00
|
|
|
|
|
|
|
/* Configure color modulation */
|
2013-10-05 00:29:57 -04:00
|
|
|
g = texture->g;
|
|
|
|
a = texture->a;
|
|
|
|
|
2012-06-22 11:38:49 -04:00
|
|
|
if (renderer->target &&
|
|
|
|
(renderer->target->format == SDL_PIXELFORMAT_ARGB8888 ||
|
|
|
|
renderer->target->format == SDL_PIXELFORMAT_RGB888)) {
|
2013-10-05 00:29:57 -04:00
|
|
|
r = texture->b;
|
|
|
|
b = texture->r;
|
2012-06-22 11:38:49 -04:00
|
|
|
} else {
|
2013-10-05 00:29:57 -04:00
|
|
|
r = texture->r;
|
|
|
|
b = texture->b;
|
|
|
|
}
|
|
|
|
|
|
|
|
program = data->current_program;
|
|
|
|
|
2013-10-05 12:29:05 -07:00
|
|
|
if (!CompareColors(program->modulation_r, program->modulation_g, program->modulation_b, program->modulation_a, r, g, b, a)) {
|
2013-10-05 00:29:57 -04:00
|
|
|
data->glUniform4f(program->uniform_locations[GLES2_UNIFORM_MODULATION], r * inv255f, g * inv255f, b * inv255f, a * inv255f);
|
|
|
|
program->modulation_r = r;
|
|
|
|
program->modulation_g = g;
|
|
|
|
program->modulation_b = b;
|
|
|
|
program->modulation_a = a;
|
2012-06-22 11:38:49 -04:00
|
|
|
}
|
2012-06-01 19:51:08 -03:00
|
|
|
|
|
|
|
/* Configure texture blending */
|
2017-08-14 10:04:59 -07:00
|
|
|
GLES2_SetBlendMode(data, texture->blendMode);
|
2012-06-01 19:51:08 -03:00
|
|
|
|
2013-10-03 20:48:52 -07:00
|
|
|
GLES2_SetTexCoords(data, SDL_TRUE);
|
2014-08-06 11:34:54 -07:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
GLES2_RenderCopy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *srcrect,
|
|
|
|
const SDL_FRect *dstrect)
|
|
|
|
{
|
|
|
|
GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->driverdata;
|
|
|
|
GLfloat vertices[8];
|
|
|
|
GLfloat texCoords[8];
|
|
|
|
|
|
|
|
GLES2_ActivateRenderer(renderer);
|
|
|
|
|
|
|
|
if (GLES2_SetupCopy(renderer, texture) < 0) {
|
|
|
|
return -1;
|
|
|
|
}
|
2012-06-01 19:51:08 -03:00
|
|
|
|
|
|
|
/* Emit the textured quad */
|
2012-10-01 20:59:33 -07:00
|
|
|
vertices[0] = dstrect->x;
|
|
|
|
vertices[1] = dstrect->y;
|
|
|
|
vertices[2] = (dstrect->x + dstrect->w);
|
|
|
|
vertices[3] = dstrect->y;
|
|
|
|
vertices[4] = dstrect->x;
|
|
|
|
vertices[5] = (dstrect->y + dstrect->h);
|
|
|
|
vertices[6] = (dstrect->x + dstrect->w);
|
|
|
|
vertices[7] = (dstrect->y + dstrect->h);
|
Initial merge of Emscripten port!
With this commit, you can compile SDL2 with Emscripten
( http://emscripten.org/ ), and make your SDL-based C/C++ program
into a web app.
This port was due to the efforts of several people, including: Charlie Birks,
Sathyanarayanan Gunasekaran, Jukka Jylänki, Alon Zakai, Edward Rudd,
Bruce Mitchener, and Martin Gerhardy. (Thanks, everyone!)
--HG--
extra : rebase_source : 97af74c8a5121e926ebe89f123536b5dd6681695
2014-12-18 00:19:52 -05:00
|
|
|
/*data->glVertexAttribPointer(GLES2_ATTRIBUTE_POSITION, 2, GL_FLOAT, GL_FALSE, 0, vertices);*/
|
|
|
|
GLES2_UpdateVertexBuffer(renderer, GLES2_ATTRIBUTE_POSITION, vertices, 8 * sizeof(GLfloat));
|
2012-06-01 19:51:08 -03:00
|
|
|
texCoords[0] = srcrect->x / (GLfloat)texture->w;
|
|
|
|
texCoords[1] = srcrect->y / (GLfloat)texture->h;
|
|
|
|
texCoords[2] = (srcrect->x + srcrect->w) / (GLfloat)texture->w;
|
|
|
|
texCoords[3] = srcrect->y / (GLfloat)texture->h;
|
|
|
|
texCoords[4] = srcrect->x / (GLfloat)texture->w;
|
|
|
|
texCoords[5] = (srcrect->y + srcrect->h) / (GLfloat)texture->h;
|
|
|
|
texCoords[6] = (srcrect->x + srcrect->w) / (GLfloat)texture->w;
|
|
|
|
texCoords[7] = (srcrect->y + srcrect->h) / (GLfloat)texture->h;
|
Initial merge of Emscripten port!
With this commit, you can compile SDL2 with Emscripten
( http://emscripten.org/ ), and make your SDL-based C/C++ program
into a web app.
This port was due to the efforts of several people, including: Charlie Birks,
Sathyanarayanan Gunasekaran, Jukka Jylänki, Alon Zakai, Edward Rudd,
Bruce Mitchener, and Martin Gerhardy. (Thanks, everyone!)
--HG--
extra : rebase_source : 97af74c8a5121e926ebe89f123536b5dd6681695
2014-12-18 00:19:52 -05:00
|
|
|
/*data->glVertexAttribPointer(GLES2_ATTRIBUTE_TEXCOORD, 2, GL_FLOAT, GL_FALSE, 0, texCoords);*/
|
|
|
|
GLES2_UpdateVertexBuffer(renderer, GLES2_ATTRIBUTE_TEXCOORD, texCoords, 8 * sizeof(GLfloat));
|
2013-10-03 20:48:52 -07:00
|
|
|
data->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
|
|
|
|
|
|
|
return GL_CheckError("", renderer);
|
2012-06-01 19:51:08 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
GLES2_RenderCopyEx(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *srcrect,
|
2012-10-01 20:59:33 -07:00
|
|
|
const SDL_FRect *dstrect, const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip)
|
2012-06-01 19:51:08 -03:00
|
|
|
{
|
2013-10-03 20:48:52 -07:00
|
|
|
GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->driverdata;
|
2012-06-01 19:51:08 -03:00
|
|
|
GLfloat vertices[8];
|
|
|
|
GLfloat texCoords[8];
|
|
|
|
GLfloat translate[8];
|
|
|
|
GLfloat fAngle[4];
|
|
|
|
GLfloat tmp;
|
|
|
|
|
|
|
|
GLES2_ActivateRenderer(renderer);
|
2013-05-18 14:17:52 -07:00
|
|
|
|
2014-08-06 11:34:54 -07:00
|
|
|
if (GLES2_SetupCopy(renderer, texture) < 0) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2013-10-03 20:48:52 -07:00
|
|
|
data->glEnableVertexAttribArray(GLES2_ATTRIBUTE_CENTER);
|
|
|
|
data->glEnableVertexAttribArray(GLES2_ATTRIBUTE_ANGLE);
|
2013-01-27 15:52:56 -08:00
|
|
|
fAngle[0] = fAngle[1] = fAngle[2] = fAngle[3] = (GLfloat)(360.0f - angle);
|
2012-06-01 19:51:08 -03:00
|
|
|
/* Calculate the center of rotation */
|
2012-10-01 20:59:33 -07:00
|
|
|
translate[0] = translate[2] = translate[4] = translate[6] = (center->x + dstrect->x);
|
|
|
|
translate[1] = translate[3] = translate[5] = translate[7] = (center->y + dstrect->y);
|
2012-06-01 19:51:08 -03:00
|
|
|
|
2011-02-06 00:00:13 -08:00
|
|
|
/* Emit the textured quad */
|
2012-10-01 20:59:33 -07:00
|
|
|
vertices[0] = dstrect->x;
|
|
|
|
vertices[1] = dstrect->y;
|
|
|
|
vertices[2] = (dstrect->x + dstrect->w);
|
|
|
|
vertices[3] = dstrect->y;
|
|
|
|
vertices[4] = dstrect->x;
|
|
|
|
vertices[5] = (dstrect->y + dstrect->h);
|
|
|
|
vertices[6] = (dstrect->x + dstrect->w);
|
|
|
|
vertices[7] = (dstrect->y + dstrect->h);
|
2012-06-01 19:51:08 -03:00
|
|
|
if (flip & SDL_FLIP_HORIZONTAL) {
|
|
|
|
tmp = vertices[0];
|
|
|
|
vertices[0] = vertices[4] = vertices[2];
|
|
|
|
vertices[2] = vertices[6] = tmp;
|
|
|
|
}
|
|
|
|
if (flip & SDL_FLIP_VERTICAL) {
|
|
|
|
tmp = vertices[1];
|
|
|
|
vertices[1] = vertices[3] = vertices[5];
|
|
|
|
vertices[5] = vertices[7] = tmp;
|
|
|
|
}
|
2013-05-18 14:17:52 -07:00
|
|
|
|
Initial merge of Emscripten port!
With this commit, you can compile SDL2 with Emscripten
( http://emscripten.org/ ), and make your SDL-based C/C++ program
into a web app.
This port was due to the efforts of several people, including: Charlie Birks,
Sathyanarayanan Gunasekaran, Jukka Jylänki, Alon Zakai, Edward Rudd,
Bruce Mitchener, and Martin Gerhardy. (Thanks, everyone!)
--HG--
extra : rebase_source : 97af74c8a5121e926ebe89f123536b5dd6681695
2014-12-18 00:19:52 -05:00
|
|
|
/*data->glVertexAttribPointer(GLES2_ATTRIBUTE_ANGLE, 1, GL_FLOAT, GL_FALSE, 0, &fAngle);
|
2013-10-03 20:48:52 -07:00
|
|
|
data->glVertexAttribPointer(GLES2_ATTRIBUTE_CENTER, 2, GL_FLOAT, GL_FALSE, 0, translate);
|
Initial merge of Emscripten port!
With this commit, you can compile SDL2 with Emscripten
( http://emscripten.org/ ), and make your SDL-based C/C++ program
into a web app.
This port was due to the efforts of several people, including: Charlie Birks,
Sathyanarayanan Gunasekaran, Jukka Jylänki, Alon Zakai, Edward Rudd,
Bruce Mitchener, and Martin Gerhardy. (Thanks, everyone!)
--HG--
extra : rebase_source : 97af74c8a5121e926ebe89f123536b5dd6681695
2014-12-18 00:19:52 -05:00
|
|
|
data->glVertexAttribPointer(GLES2_ATTRIBUTE_POSITION, 2, GL_FLOAT, GL_FALSE, 0, vertices);*/
|
|
|
|
|
|
|
|
GLES2_UpdateVertexBuffer(renderer, GLES2_ATTRIBUTE_ANGLE, fAngle, 4 * sizeof(GLfloat));
|
|
|
|
GLES2_UpdateVertexBuffer(renderer, GLES2_ATTRIBUTE_CENTER, translate, 8 * sizeof(GLfloat));
|
|
|
|
GLES2_UpdateVertexBuffer(renderer, GLES2_ATTRIBUTE_POSITION, vertices, 8 * sizeof(GLfloat));
|
2012-01-18 22:45:49 -05:00
|
|
|
|
2011-02-06 00:00:13 -08:00
|
|
|
texCoords[0] = srcrect->x / (GLfloat)texture->w;
|
|
|
|
texCoords[1] = srcrect->y / (GLfloat)texture->h;
|
|
|
|
texCoords[2] = (srcrect->x + srcrect->w) / (GLfloat)texture->w;
|
|
|
|
texCoords[3] = srcrect->y / (GLfloat)texture->h;
|
|
|
|
texCoords[4] = srcrect->x / (GLfloat)texture->w;
|
|
|
|
texCoords[5] = (srcrect->y + srcrect->h) / (GLfloat)texture->h;
|
|
|
|
texCoords[6] = (srcrect->x + srcrect->w) / (GLfloat)texture->w;
|
|
|
|
texCoords[7] = (srcrect->y + srcrect->h) / (GLfloat)texture->h;
|
Initial merge of Emscripten port!
With this commit, you can compile SDL2 with Emscripten
( http://emscripten.org/ ), and make your SDL-based C/C++ program
into a web app.
This port was due to the efforts of several people, including: Charlie Birks,
Sathyanarayanan Gunasekaran, Jukka Jylänki, Alon Zakai, Edward Rudd,
Bruce Mitchener, and Martin Gerhardy. (Thanks, everyone!)
--HG--
extra : rebase_source : 97af74c8a5121e926ebe89f123536b5dd6681695
2014-12-18 00:19:52 -05:00
|
|
|
/*data->glVertexAttribPointer(GLES2_ATTRIBUTE_TEXCOORD, 2, GL_FLOAT, GL_FALSE, 0, texCoords);*/
|
|
|
|
GLES2_UpdateVertexBuffer(renderer, GLES2_ATTRIBUTE_TEXCOORD, texCoords, 8 * sizeof(GLfloat));
|
2013-10-03 20:48:52 -07:00
|
|
|
data->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
|
|
|
data->glDisableVertexAttribArray(GLES2_ATTRIBUTE_CENTER);
|
|
|
|
data->glDisableVertexAttribArray(GLES2_ATTRIBUTE_ANGLE);
|
|
|
|
|
|
|
|
return GL_CheckError("", renderer);
|
2011-02-06 00:00:13 -08:00
|
|
|
}
|
|
|
|
|
2011-10-31 02:55:21 -04:00
|
|
|
static int
|
|
|
|
GLES2_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
|
|
|
|
Uint32 pixel_format, void * pixels, int pitch)
|
|
|
|
{
|
2013-10-03 20:48:52 -07:00
|
|
|
GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->driverdata;
|
2016-10-01 11:38:53 -07:00
|
|
|
Uint32 temp_format = renderer->target ? renderer->target->format : SDL_PIXELFORMAT_ABGR8888;
|
2011-10-31 02:55:21 -04:00
|
|
|
void *temp_pixels;
|
|
|
|
int temp_pitch;
|
|
|
|
Uint8 *src, *dst, *tmp;
|
|
|
|
int w, h, length, rows;
|
|
|
|
int status;
|
|
|
|
|
|
|
|
GLES2_ActivateRenderer(renderer);
|
|
|
|
|
|
|
|
temp_pitch = rect->w * SDL_BYTESPERPIXEL(temp_format);
|
|
|
|
temp_pixels = SDL_malloc(rect->h * temp_pitch);
|
|
|
|
if (!temp_pixels) {
|
2013-03-31 12:48:50 -04:00
|
|
|
return SDL_OutOfMemory();
|
2011-10-31 02:55:21 -04:00
|
|
|
}
|
|
|
|
|
2013-07-12 00:55:04 -07:00
|
|
|
SDL_GetRendererOutputSize(renderer, &w, &h);
|
2011-10-31 02:55:21 -04:00
|
|
|
|
2016-10-01 11:34:04 -07:00
|
|
|
data->glReadPixels(rect->x, renderer->target ? rect->y : (h-rect->y)-rect->h,
|
|
|
|
rect->w, rect->h, GL_RGBA, GL_UNSIGNED_BYTE, temp_pixels);
|
2013-10-03 20:48:52 -07:00
|
|
|
if (GL_CheckError("glReadPixels()", renderer) < 0) {
|
|
|
|
return -1;
|
|
|
|
}
|
2011-10-31 02:55:21 -04:00
|
|
|
|
2016-10-01 11:34:04 -07:00
|
|
|
/* Flip the rows to be top-down if necessary */
|
|
|
|
if (!renderer->target) {
|
|
|
|
length = rect->w * SDL_BYTESPERPIXEL(temp_format);
|
|
|
|
src = (Uint8*)temp_pixels + (rect->h-1)*temp_pitch;
|
|
|
|
dst = (Uint8*)temp_pixels;
|
|
|
|
tmp = SDL_stack_alloc(Uint8, length);
|
|
|
|
rows = rect->h / 2;
|
|
|
|
while (rows--) {
|
|
|
|
SDL_memcpy(tmp, dst, length);
|
|
|
|
SDL_memcpy(dst, src, length);
|
|
|
|
SDL_memcpy(src, tmp, length);
|
|
|
|
dst += temp_pitch;
|
|
|
|
src -= temp_pitch;
|
|
|
|
}
|
|
|
|
SDL_stack_free(tmp);
|
|
|
|
}
|
2011-10-31 02:55:21 -04:00
|
|
|
|
|
|
|
status = SDL_ConvertPixels(rect->w, rect->h,
|
|
|
|
temp_format, temp_pixels, temp_pitch,
|
|
|
|
pixel_format, pixels, pitch);
|
|
|
|
SDL_free(temp_pixels);
|
|
|
|
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
2011-02-06 00:00:13 -08:00
|
|
|
static void
|
|
|
|
GLES2_RenderPresent(SDL_Renderer *renderer)
|
|
|
|
{
|
|
|
|
GLES2_ActivateRenderer(renderer);
|
|
|
|
|
|
|
|
/* Tell the video driver to swap buffers */
|
|
|
|
SDL_GL_SwapWindow(renderer->window);
|
|
|
|
}
|
|
|
|
|
2012-09-03 11:16:12 -03:00
|
|
|
|
|
|
|
/*************************************************************************************************
|
|
|
|
* Bind/unbinding of textures
|
|
|
|
*************************************************************************************************/
|
|
|
|
static int GLES2_BindTexture (SDL_Renderer * renderer, SDL_Texture *texture, float *texw, float *texh);
|
|
|
|
static int GLES2_UnbindTexture (SDL_Renderer * renderer, SDL_Texture *texture);
|
|
|
|
|
2013-10-03 20:48:52 -07:00
|
|
|
static int GLES2_BindTexture (SDL_Renderer * renderer, SDL_Texture *texture, float *texw, float *texh)
|
|
|
|
{
|
2012-09-03 11:16:12 -03:00
|
|
|
GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->driverdata;
|
|
|
|
GLES2_TextureData *texturedata = (GLES2_TextureData *)texture->driverdata;
|
|
|
|
GLES2_ActivateRenderer(renderer);
|
|
|
|
|
|
|
|
data->glBindTexture(texturedata->texture_type, texturedata->texture);
|
|
|
|
|
2015-05-16 17:35:36 -03:00
|
|
|
if (texw) {
|
|
|
|
*texw = 1.0;
|
|
|
|
}
|
|
|
|
if (texh) {
|
|
|
|
*texh = 1.0;
|
|
|
|
}
|
2012-09-03 11:16:12 -03:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2013-10-03 20:48:52 -07:00
|
|
|
static int GLES2_UnbindTexture (SDL_Renderer * renderer, SDL_Texture *texture)
|
|
|
|
{
|
2012-09-03 11:16:12 -03:00
|
|
|
GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->driverdata;
|
|
|
|
GLES2_TextureData *texturedata = (GLES2_TextureData *)texture->driverdata;
|
|
|
|
GLES2_ActivateRenderer(renderer);
|
|
|
|
|
2013-04-17 11:45:50 -04:00
|
|
|
data->glBindTexture(texturedata->texture_type, 0);
|
2012-09-03 11:16:12 -03:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-02-06 00:00:13 -08:00
|
|
|
/*************************************************************************************************
|
|
|
|
* Renderer instantiation *
|
|
|
|
*************************************************************************************************/
|
|
|
|
|
2016-11-13 22:57:41 -08:00
|
|
|
#ifdef ZUNE_HD
|
2011-02-06 00:00:13 -08:00
|
|
|
#define GL_NVIDIA_PLATFORM_BINARY_NV 0x890B
|
2016-11-13 22:57:41 -08:00
|
|
|
#endif
|
2011-02-06 00:00:13 -08:00
|
|
|
|
2011-02-19 21:51:21 -08:00
|
|
|
static void
|
|
|
|
GLES2_ResetState(SDL_Renderer *renderer)
|
|
|
|
{
|
2013-10-03 20:48:52 -07:00
|
|
|
GLES2_DriverContext *data = (GLES2_DriverContext *) renderer->driverdata;
|
2011-02-19 21:51:21 -08:00
|
|
|
|
2013-10-03 20:48:52 -07:00
|
|
|
if (SDL_CurrentContext == data->context) {
|
2011-02-19 21:51:21 -08:00
|
|
|
GLES2_UpdateViewport(renderer);
|
|
|
|
} else {
|
|
|
|
GLES2_ActivateRenderer(renderer);
|
|
|
|
}
|
|
|
|
|
Implemented more flexible blending modes for accelerated renderers
This fixes bug 2594 - Propose new blend mode, SDL_BLENDMODE_BLEND_DSTA
blendMode = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_SRC_ALPHA,
SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
SDL_BLENDOPERATION_ADD,
SDL_BLENDFACTOR_ZERO,
SDL_BLENDFACTOR_ONE,
SDL_BLENDOPERATION_ADD);
This fixes bug 2828 - Subtractive Blending
blendMode = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_SRC_ALPHA,
SDL_BLENDFACTOR_ONE,
SDL_BLENDOPERATION_SUBTRACT,
SDL_BLENDFACTOR_ZERO,
SDL_BLENDFACTOR_ONE,
SDL_BLENDOPERATION_SUBTRACT);
This goes partway to fixing bug 3684 - Add support for a pre-multiplied alpha blending mode
blendMode = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_ONE,
SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
SDL_BLENDOPERATION_ADD,
SDL_BLENDFACTOR_ONE,
SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
SDL_BLENDOPERATION_ADD);
2017-08-14 05:51:44 -07:00
|
|
|
data->current.blendMode = SDL_BLENDMODE_INVALID;
|
2013-10-03 20:48:52 -07:00
|
|
|
data->current.tex_coords = SDL_FALSE;
|
|
|
|
|
2013-10-05 00:29:57 -04:00
|
|
|
data->glActiveTexture(GL_TEXTURE0);
|
|
|
|
data->glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
|
|
|
data->glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
|
|
|
|
|
|
|
data->glClearColor((GLfloat) data->clear_r * inv255f,
|
|
|
|
(GLfloat) data->clear_g * inv255f,
|
|
|
|
(GLfloat) data->clear_b * inv255f,
|
|
|
|
(GLfloat) data->clear_a * inv255f);
|
|
|
|
|
2013-10-03 20:48:52 -07:00
|
|
|
data->glEnableVertexAttribArray(GLES2_ATTRIBUTE_POSITION);
|
|
|
|
data->glDisableVertexAttribArray(GLES2_ATTRIBUTE_TEXCOORD);
|
2011-02-19 21:51:21 -08:00
|
|
|
|
2013-10-03 20:48:52 -07:00
|
|
|
GL_CheckError("", renderer);
|
2011-02-19 21:51:21 -08:00
|
|
|
}
|
|
|
|
|
2011-02-06 00:00:13 -08:00
|
|
|
static SDL_Renderer *
|
|
|
|
GLES2_CreateRenderer(SDL_Window *window, Uint32 flags)
|
|
|
|
{
|
|
|
|
SDL_Renderer *renderer;
|
2013-10-03 20:48:52 -07:00
|
|
|
GLES2_DriverContext *data;
|
2011-02-06 00:00:13 -08:00
|
|
|
GLint nFormats;
|
|
|
|
#ifndef ZUNE_HD
|
|
|
|
GLboolean hasCompiler;
|
|
|
|
#endif
|
2016-11-13 22:57:41 -08:00
|
|
|
Uint32 window_flags = 0; /* -Wconditional-uninitialized */
|
2012-01-30 20:56:25 -05:00
|
|
|
GLint window_framebuffer;
|
2013-09-30 22:16:14 -07:00
|
|
|
GLint value;
|
2015-12-10 20:25:34 -04:00
|
|
|
int profile_mask = 0, major = 0, minor = 0;
|
2014-06-22 02:48:43 -07:00
|
|
|
SDL_bool changed_window = SDL_FALSE;
|
2013-12-19 06:01:18 +09:00
|
|
|
|
Fixed bug 3169 - GLES2_CreateRenderer does not check SDL_GL_GetAttribute result, causing use of uninitialized data
Yann Dirson
When attempting to force use of opengles2 renderer with:
int wanted_renderer = -1;
for (int i = 0; i < numrenderers; i++) {
SDL_RendererInfo renderer_info;
if (SDL_GetRenderDriverInfo(i, &renderer_info) != 0) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't get renderer driver info: %s\n",
SDL_GetError());
quit(2);
}
std::cerr << "Renderer " << i << " '" << renderer_info.name << "': flags=0x"
<< std::hex << renderer_info.flags << std::dec
<< ", " << renderer_info.num_texture_formats << " texture formats, max="
<< renderer_info.max_texture_width << "x"
<< renderer_info.max_texture_height << "\n";
if (!strcmp(renderer_info.name, "opengles2")) {
std::cerr << " selecting!\n";
wanted_renderer = i;
}
}
renderer = SDL_CreateRenderer(window, wanted_renderer, 0);
... on banana pi or raspberry pi I get an error like the following (the actual
context profile value varies, being used uninitialized)
ERROR: Couldn't create renderer: Unknown OpenGL context profile 900
With this patch I get the following, which should help more pointing to a real problem:
ERROR: Couldn't create renderer: Failed getting OpenGL glGetString entry point
I pushed a patch (based on master branch of unofficial git mirror):
https://github.com/O-Computers/SDL/commit/550389c89f4e73a0a5294f95b9f6e6c18ba48509
I'll be opening a different bug for the underlying issue.
2016-10-01 13:33:32 -07:00
|
|
|
if (SDL_GL_GetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, &profile_mask) < 0) {
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
if (SDL_GL_GetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, &major) < 0) {
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
if (SDL_GL_GetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, &minor) < 0) {
|
|
|
|
goto error;
|
|
|
|
}
|
2012-01-18 22:45:49 -05:00
|
|
|
|
2014-06-22 02:48:43 -07:00
|
|
|
window_flags = SDL_GetWindowFlags(window);
|
2017-10-18 08:52:04 -07:00
|
|
|
/* OpenGL ES 3.0 is a superset of OpenGL ES 2.0 */
|
2014-06-22 02:48:43 -07:00
|
|
|
if (!(window_flags & SDL_WINDOW_OPENGL) ||
|
2017-10-18 08:52:04 -07:00
|
|
|
profile_mask != SDL_GL_CONTEXT_PROFILE_ES || major < RENDERER_CONTEXT_MAJOR) {
|
2014-06-22 02:48:43 -07:00
|
|
|
|
|
|
|
changed_window = SDL_TRUE;
|
2014-02-27 20:21:46 -03:00
|
|
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
|
|
|
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, RENDERER_CONTEXT_MAJOR);
|
|
|
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, RENDERER_CONTEXT_MINOR);
|
|
|
|
|
2014-06-22 02:48:43 -07:00
|
|
|
if (SDL_RecreateWindow(window, window_flags | SDL_WINDOW_OPENGL) < 0) {
|
|
|
|
goto error;
|
Fixed bug 1242 - PATCH: Improve support for OpenGL ES under X11
Scott Percival 2011-07-03 06:41:51 PDT
This submission is aimed at making life easier for OpenGL ES capable devices
running a X11 stack (e.g. Maemo, Meego, TrimSlice, other ARM SoC boards not
running Android). SDL's Pandora support already has the neccesary GLES-to-X11
glue code, however it's all ghetto'd off in Makefile.pandora and not very
flexible.
The patch:
- adds an awesome --enable-video-opengles option to configure
- re-modifies the opengles and opengles2 SDL_renderers to use function pointers
- no idea why this was removed?
- for SDL_Renderers, links in libGLESv1_CM, libGLES_CM (for PowerVR fans) or
libGLESv2 at runtime
- links in libEGL.so at runtime - the old code made an assumption that
eglFunctions could be pulled from the active GLES library, PowerVR for one
doesn't let you do that with their libGLESv2
- allows you to pick which of GLES v1 or v2 to load via
SDL_GL_CONTEXT_MAJOR_VERSION
So far I've tested this on a Nokia N900 (OMAP 3430/SGX 530 running Maemo 5) and
a Toshiba AC100 (Tegra 2 running Ubuntu 10.10). I haven't tested it on... well,
everything that isn't those two, such as a Pandora, iOS or Android device. The
Pandora specific code should be kept intact (fingers crossed), and nothing
painfully drastic has been added to the SDL_renderers. The library loading
sequence in SDL_x11opengles has been updated to accomodate both NVIDIA's
propensity to let developers get away with murder and PowerVR's alternative of
punishing every missed step.
The test apps work okay with GLES or GLES2 as the renderer. For some reason
alpha blending doesn't seem to work on the Tegra 2; last week NVIDIA pushed out
a new set of X11 GLES drivers, so I'll try and investigate once I upgrade
those. Also, this patch adds things to configure.in, include/SDL_config.h.in
and test/configure.in. I didn't know what the policy was re. committing
generated spaghetti from autotools, so ./autogen.sh has to be run again. Sorry.
I think that's about everything, let me know if there's anything I've
overlooked.
2012-01-08 02:23:37 -05:00
|
|
|
}
|
|
|
|
}
|
2011-02-06 00:00:13 -08:00
|
|
|
|
|
|
|
/* Create the renderer struct */
|
|
|
|
renderer = (SDL_Renderer *)SDL_calloc(1, sizeof(SDL_Renderer));
|
2011-02-06 10:22:25 -08:00
|
|
|
if (!renderer) {
|
|
|
|
SDL_OutOfMemory();
|
2014-06-22 02:48:43 -07:00
|
|
|
goto error;
|
2011-02-06 10:22:25 -08:00
|
|
|
}
|
|
|
|
|
2013-10-03 20:48:52 -07:00
|
|
|
data = (GLES2_DriverContext *)SDL_calloc(1, sizeof(GLES2_DriverContext));
|
|
|
|
if (!data) {
|
2011-02-06 10:22:25 -08:00
|
|
|
GLES2_DestroyRenderer(renderer);
|
2011-02-06 00:00:13 -08:00
|
|
|
SDL_OutOfMemory();
|
2014-06-22 02:48:43 -07:00
|
|
|
goto error;
|
2011-02-06 00:00:13 -08:00
|
|
|
}
|
|
|
|
renderer->info = GLES2_RenderDriver.info;
|
2014-03-09 22:48:38 -07:00
|
|
|
renderer->info.flags = (SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE);
|
2013-10-03 20:48:52 -07:00
|
|
|
renderer->driverdata = data;
|
Fixed bug 1256 - Invalid window warning in GL_CreateRenderer
Martin Gerhardy 2011-07-27 02:26:06 PDT
the window reference is lost in the GL_CreateRenderer function. The attached
patch should fix this error.
#0 SDLSystem_LogOutputFunction (userdata=0x63b010, category=1,
priority=SDL_LOG_PRIORITY_ERROR, message=0x7fffffffcd00 "Invalid window") at
src/system/sdl/SDLSystem.cpp:8
#1 0x00007ffff7b1ddb3 in SDL_LogMessageV (category=1,
priority=SDL_LOG_PRIORITY_ERROR, fmt=<value optimized out>, ap=<value optimized
out>) at src/SDL_log.c:275
#2 0x00007ffff7b1df7c in SDL_LogError (category=<value optimized out>,
fmt=<value optimized out>) at src/SDL_log.c:212
#3 0x00007ffff7b1d582 in SDL_SetError (fmt=0x7ffff7baaff0 "") at
src/SDL_error.c:111
#4 0x00007ffff7b96f9e in SDL_GL_MakeCurrent (window=0x0, ctx=0xa62ce0) at
src/video/SDL_video.c:2484
#5 0x00007ffff7b4ba0c in GL_ActivateRenderer (renderer=0xa8f680) at
src/render/opengl/SDL_render_gl.c:195
#6 0x00007ffff7b4c59a in GL_ResetState (window=0x918010, flags=<value
optimized out>) at src/render/opengl/SDL_render_gl.c:214
#7 GL_CreateRenderer (window=0x918010, flags=<value optimized out>) at
src/render/opengl/SDL_render_gl.c:343
#8 0x00007ffff7b48053 in SDL_CreateRenderer (window=0x918010, index=<value
optimized out>, flags=2) at src/render/SDL_render.c:166
2012-01-07 02:32:08 -05:00
|
|
|
renderer->window = window;
|
2011-02-06 02:35:14 -08:00
|
|
|
|
2011-02-06 10:22:25 -08:00
|
|
|
/* Create an OpenGL ES 2.0 context */
|
2013-10-03 20:48:52 -07:00
|
|
|
data->context = SDL_GL_CreateContext(window);
|
2014-06-22 02:48:43 -07:00
|
|
|
if (!data->context) {
|
2011-02-06 10:22:25 -08:00
|
|
|
GLES2_DestroyRenderer(renderer);
|
2014-06-22 02:48:43 -07:00
|
|
|
goto error;
|
2011-02-06 00:00:13 -08:00
|
|
|
}
|
2013-10-03 20:48:52 -07:00
|
|
|
if (SDL_GL_MakeCurrent(window, data->context) < 0) {
|
2011-02-06 10:22:25 -08:00
|
|
|
GLES2_DestroyRenderer(renderer);
|
2014-06-22 02:48:43 -07:00
|
|
|
goto error;
|
2011-02-06 00:48:16 -08:00
|
|
|
}
|
|
|
|
|
2013-10-03 20:48:52 -07:00
|
|
|
if (GLES2_LoadFunctions(data) < 0) {
|
Fixed bug 1242 - PATCH: Improve support for OpenGL ES under X11
Scott Percival 2011-07-03 06:41:51 PDT
This submission is aimed at making life easier for OpenGL ES capable devices
running a X11 stack (e.g. Maemo, Meego, TrimSlice, other ARM SoC boards not
running Android). SDL's Pandora support already has the neccesary GLES-to-X11
glue code, however it's all ghetto'd off in Makefile.pandora and not very
flexible.
The patch:
- adds an awesome --enable-video-opengles option to configure
- re-modifies the opengles and opengles2 SDL_renderers to use function pointers
- no idea why this was removed?
- for SDL_Renderers, links in libGLESv1_CM, libGLES_CM (for PowerVR fans) or
libGLESv2 at runtime
- links in libEGL.so at runtime - the old code made an assumption that
eglFunctions could be pulled from the active GLES library, PowerVR for one
doesn't let you do that with their libGLESv2
- allows you to pick which of GLES v1 or v2 to load via
SDL_GL_CONTEXT_MAJOR_VERSION
So far I've tested this on a Nokia N900 (OMAP 3430/SGX 530 running Maemo 5) and
a Toshiba AC100 (Tegra 2 running Ubuntu 10.10). I haven't tested it on... well,
everything that isn't those two, such as a Pandora, iOS or Android device. The
Pandora specific code should be kept intact (fingers crossed), and nothing
painfully drastic has been added to the SDL_renderers. The library loading
sequence in SDL_x11opengles has been updated to accomodate both NVIDIA's
propensity to let developers get away with murder and PowerVR's alternative of
punishing every missed step.
The test apps work okay with GLES or GLES2 as the renderer. For some reason
alpha blending doesn't seem to work on the Tegra 2; last week NVIDIA pushed out
a new set of X11 GLES drivers, so I'll try and investigate once I upgrade
those. Also, this patch adds things to configure.in, include/SDL_config.h.in
and test/configure.in. I didn't know what the policy was re. committing
generated spaghetti from autotools, so ./autogen.sh has to be run again. Sorry.
I think that's about everything, let me know if there's anything I've
overlooked.
2012-01-08 02:23:37 -05:00
|
|
|
GLES2_DestroyRenderer(renderer);
|
2014-06-22 02:48:43 -07:00
|
|
|
goto error;
|
Fixed bug 1242 - PATCH: Improve support for OpenGL ES under X11
Scott Percival 2011-07-03 06:41:51 PDT
This submission is aimed at making life easier for OpenGL ES capable devices
running a X11 stack (e.g. Maemo, Meego, TrimSlice, other ARM SoC boards not
running Android). SDL's Pandora support already has the neccesary GLES-to-X11
glue code, however it's all ghetto'd off in Makefile.pandora and not very
flexible.
The patch:
- adds an awesome --enable-video-opengles option to configure
- re-modifies the opengles and opengles2 SDL_renderers to use function pointers
- no idea why this was removed?
- for SDL_Renderers, links in libGLESv1_CM, libGLES_CM (for PowerVR fans) or
libGLESv2 at runtime
- links in libEGL.so at runtime - the old code made an assumption that
eglFunctions could be pulled from the active GLES library, PowerVR for one
doesn't let you do that with their libGLESv2
- allows you to pick which of GLES v1 or v2 to load via
SDL_GL_CONTEXT_MAJOR_VERSION
So far I've tested this on a Nokia N900 (OMAP 3430/SGX 530 running Maemo 5) and
a Toshiba AC100 (Tegra 2 running Ubuntu 10.10). I haven't tested it on... well,
everything that isn't those two, such as a Pandora, iOS or Android device. The
Pandora specific code should be kept intact (fingers crossed), and nothing
painfully drastic has been added to the SDL_renderers. The library loading
sequence in SDL_x11opengles has been updated to accomodate both NVIDIA's
propensity to let developers get away with murder and PowerVR's alternative of
punishing every missed step.
The test apps work okay with GLES or GLES2 as the renderer. For some reason
alpha blending doesn't seem to work on the Tegra 2; last week NVIDIA pushed out
a new set of X11 GLES drivers, so I'll try and investigate once I upgrade
those. Also, this patch adds things to configure.in, include/SDL_config.h.in
and test/configure.in. I didn't know what the policy was re. committing
generated spaghetti from autotools, so ./autogen.sh has to be run again. Sorry.
I think that's about everything, let me know if there's anything I've
overlooked.
2012-01-08 02:23:37 -05:00
|
|
|
}
|
|
|
|
|
2013-11-29 00:19:46 -05:00
|
|
|
#if __WINRT__
|
|
|
|
/* DLudwig, 2013-11-29: ANGLE for WinRT doesn't seem to work unless VSync
|
|
|
|
* is turned on. Not doing so will freeze the screen's contents to that
|
|
|
|
* of the first drawn frame.
|
|
|
|
*/
|
|
|
|
flags |= SDL_RENDERER_PRESENTVSYNC;
|
|
|
|
#endif
|
|
|
|
|
2011-02-06 00:48:16 -08:00
|
|
|
if (flags & SDL_RENDERER_PRESENTVSYNC) {
|
|
|
|
SDL_GL_SetSwapInterval(1);
|
|
|
|
} else {
|
|
|
|
SDL_GL_SetSwapInterval(0);
|
|
|
|
}
|
|
|
|
if (SDL_GL_GetSwapInterval() > 0) {
|
|
|
|
renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC;
|
|
|
|
}
|
2011-02-06 00:00:13 -08:00
|
|
|
|
2013-10-03 20:48:52 -07:00
|
|
|
/* Check for debug output support */
|
|
|
|
if (SDL_GL_GetAttribute(SDL_GL_CONTEXT_FLAGS, &value) == 0 &&
|
|
|
|
(value & SDL_GL_CONTEXT_DEBUG_FLAG)) {
|
|
|
|
data->debug_enabled = SDL_TRUE;
|
|
|
|
}
|
|
|
|
|
2013-09-30 22:16:14 -07:00
|
|
|
value = 0;
|
2013-10-03 20:48:52 -07:00
|
|
|
data->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &value);
|
2013-09-30 22:16:14 -07:00
|
|
|
renderer->info.max_texture_width = value;
|
|
|
|
value = 0;
|
2013-10-03 20:48:52 -07:00
|
|
|
data->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &value);
|
2013-09-30 22:16:14 -07:00
|
|
|
renderer->info.max_texture_height = value;
|
|
|
|
|
2011-02-06 00:00:13 -08:00
|
|
|
/* Determine supported shader formats */
|
|
|
|
/* HACK: glGetInteger is broken on the Zune HD's compositor, so we just hardcode this */
|
|
|
|
#ifdef ZUNE_HD
|
|
|
|
nFormats = 1;
|
|
|
|
#else /* !ZUNE_HD */
|
2013-10-03 20:48:52 -07:00
|
|
|
data->glGetIntegerv(GL_NUM_SHADER_BINARY_FORMATS, &nFormats);
|
|
|
|
data->glGetBooleanv(GL_SHADER_COMPILER, &hasCompiler);
|
2015-05-16 17:35:36 -03:00
|
|
|
if (hasCompiler) {
|
2011-02-06 00:00:13 -08:00
|
|
|
++nFormats;
|
2015-05-16 17:35:36 -03:00
|
|
|
}
|
2011-02-06 00:00:13 -08:00
|
|
|
#endif /* ZUNE_HD */
|
2013-10-03 20:48:52 -07:00
|
|
|
data->shader_formats = (GLenum *)SDL_calloc(nFormats, sizeof(GLenum));
|
2015-05-16 17:35:36 -03:00
|
|
|
if (!data->shader_formats) {
|
2011-02-06 10:22:25 -08:00
|
|
|
GLES2_DestroyRenderer(renderer);
|
2011-02-06 00:00:13 -08:00
|
|
|
SDL_OutOfMemory();
|
2014-06-22 02:48:43 -07:00
|
|
|
goto error;
|
2011-02-06 00:00:13 -08:00
|
|
|
}
|
2013-10-03 20:48:52 -07:00
|
|
|
data->shader_format_count = nFormats;
|
2011-02-06 00:00:13 -08:00
|
|
|
#ifdef ZUNE_HD
|
2013-10-03 20:48:52 -07:00
|
|
|
data->shader_formats[0] = GL_NVIDIA_PLATFORM_BINARY_NV;
|
2011-02-06 00:00:13 -08:00
|
|
|
#else /* !ZUNE_HD */
|
2013-10-03 20:48:52 -07:00
|
|
|
data->glGetIntegerv(GL_SHADER_BINARY_FORMATS, (GLint *)data->shader_formats);
|
2015-05-16 17:35:36 -03:00
|
|
|
if (hasCompiler) {
|
2013-10-03 20:48:52 -07:00
|
|
|
data->shader_formats[nFormats - 1] = (GLenum)-1;
|
2015-05-16 17:35:36 -03:00
|
|
|
}
|
2011-02-06 00:00:13 -08:00
|
|
|
#endif /* ZUNE_HD */
|
|
|
|
|
2013-10-03 20:48:52 -07:00
|
|
|
data->framebuffers = NULL;
|
|
|
|
data->glGetIntegerv(GL_FRAMEBUFFER_BINDING, &window_framebuffer);
|
|
|
|
data->window_framebuffer = (GLuint)window_framebuffer;
|
2012-01-18 22:45:49 -05:00
|
|
|
|
2011-02-06 00:00:13 -08:00
|
|
|
/* Populate the function pointers for the module */
|
Implemented more flexible blending modes for accelerated renderers
This fixes bug 2594 - Propose new blend mode, SDL_BLENDMODE_BLEND_DSTA
blendMode = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_SRC_ALPHA,
SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
SDL_BLENDOPERATION_ADD,
SDL_BLENDFACTOR_ZERO,
SDL_BLENDFACTOR_ONE,
SDL_BLENDOPERATION_ADD);
This fixes bug 2828 - Subtractive Blending
blendMode = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_SRC_ALPHA,
SDL_BLENDFACTOR_ONE,
SDL_BLENDOPERATION_SUBTRACT,
SDL_BLENDFACTOR_ZERO,
SDL_BLENDFACTOR_ONE,
SDL_BLENDOPERATION_SUBTRACT);
This goes partway to fixing bug 3684 - Add support for a pre-multiplied alpha blending mode
blendMode = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_ONE,
SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
SDL_BLENDOPERATION_ADD,
SDL_BLENDFACTOR_ONE,
SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
SDL_BLENDOPERATION_ADD);
2017-08-14 05:51:44 -07:00
|
|
|
renderer->WindowEvent = GLES2_WindowEvent;
|
|
|
|
renderer->GetOutputSize = GLES2_GetOutputSize;
|
|
|
|
renderer->SupportsBlendMode = GLES2_SupportsBlendMode;
|
|
|
|
renderer->CreateTexture = GLES2_CreateTexture;
|
|
|
|
renderer->UpdateTexture = GLES2_UpdateTexture;
|
|
|
|
renderer->UpdateTextureYUV = GLES2_UpdateTextureYUV;
|
|
|
|
renderer->LockTexture = GLES2_LockTexture;
|
|
|
|
renderer->UnlockTexture = GLES2_UnlockTexture;
|
|
|
|
renderer->SetRenderTarget = GLES2_SetRenderTarget;
|
|
|
|
renderer->UpdateViewport = GLES2_UpdateViewport;
|
|
|
|
renderer->UpdateClipRect = GLES2_UpdateClipRect;
|
|
|
|
renderer->RenderClear = GLES2_RenderClear;
|
|
|
|
renderer->RenderDrawPoints = GLES2_RenderDrawPoints;
|
|
|
|
renderer->RenderDrawLines = GLES2_RenderDrawLines;
|
|
|
|
renderer->RenderFillRects = GLES2_RenderFillRects;
|
|
|
|
renderer->RenderCopy = GLES2_RenderCopy;
|
|
|
|
renderer->RenderCopyEx = GLES2_RenderCopyEx;
|
|
|
|
renderer->RenderReadPixels = GLES2_RenderReadPixels;
|
|
|
|
renderer->RenderPresent = GLES2_RenderPresent;
|
|
|
|
renderer->DestroyTexture = GLES2_DestroyTexture;
|
|
|
|
renderer->DestroyRenderer = GLES2_DestroyRenderer;
|
|
|
|
renderer->GL_BindTexture = GLES2_BindTexture;
|
|
|
|
renderer->GL_UnbindTexture = GLES2_UnbindTexture;
|
2011-02-19 21:51:21 -08:00
|
|
|
|
2014-06-07 11:36:08 -07:00
|
|
|
renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_YV12;
|
|
|
|
renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_IYUV;
|
2014-08-06 11:34:54 -07:00
|
|
|
renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_NV12;
|
|
|
|
renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_NV21;
|
2014-06-07 11:36:08 -07:00
|
|
|
|
2011-02-19 21:51:21 -08:00
|
|
|
GLES2_ResetState(renderer);
|
|
|
|
|
2011-02-06 00:00:13 -08:00
|
|
|
return renderer;
|
2014-06-22 02:48:43 -07:00
|
|
|
|
|
|
|
error:
|
|
|
|
if (changed_window) {
|
|
|
|
/* Uh oh, better try to put it back... */
|
|
|
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, profile_mask);
|
|
|
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, major);
|
|
|
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, minor);
|
|
|
|
SDL_RecreateWindow(window, window_flags);
|
|
|
|
}
|
|
|
|
return NULL;
|
2011-02-06 00:00:13 -08:00
|
|
|
}
|
|
|
|
|
2011-02-08 10:04:09 -08:00
|
|
|
#endif /* SDL_VIDEO_RENDER_OGL_ES2 && !SDL_RENDER_DISABLED */
|
2011-02-06 00:00:13 -08:00
|
|
|
|
|
|
|
/* vi: set ts=4 sw=4 expandtab: */
|