Made it possible to create a texture of any format, even if not supported by the renderer.
This allows me to reduce the set of formats supported by the renderers to the most optimal set, for a nice speed boost. --HG-- rename : src/video/SDL_yuv_mmx.c => src/render/SDL_yuv_mmx.c rename : src/video/SDL_yuv_sw.c => src/render/SDL_yuv_sw.c rename : src/video/SDL_yuv_sw_c.h => src/render/SDL_yuv_sw_c.h rename : src/video/mmx.h => src/render/mmx.h
This commit is contained in:
parent
613d92a832
commit
d2b54f7d24
20 changed files with 585 additions and 1315 deletions
|
@ -37,27 +37,6 @@
|
|||
http://developer.apple.com/documentation/GraphicsImaging/Conceptual/OpenGL-MacProgGuide/opengl_texturedata/chapter_10_section_2.html
|
||||
*/
|
||||
|
||||
/* !!! FIXME: this should go in a higher level than the GL renderer. */
|
||||
static __inline__ int
|
||||
bytes_per_pixel(const Uint32 format)
|
||||
{
|
||||
if (!SDL_ISPIXELFORMAT_FOURCC(format)) {
|
||||
return SDL_BYTESPERPIXEL(format);
|
||||
}
|
||||
|
||||
/* FOURCC format */
|
||||
switch (format) {
|
||||
case SDL_PIXELFORMAT_YV12:
|
||||
case SDL_PIXELFORMAT_IYUV:
|
||||
case SDL_PIXELFORMAT_YUY2:
|
||||
case SDL_PIXELFORMAT_UYVY:
|
||||
case SDL_PIXELFORMAT_YVYU:
|
||||
return 2;
|
||||
default:
|
||||
return 1; /* shouldn't ever hit this. */
|
||||
}
|
||||
}
|
||||
|
||||
/* Used to re-create the window with OpenGL capability */
|
||||
extern int SDL_RecreateWindow(SDL_Window * window, Uint32 flags);
|
||||
|
||||
|
@ -67,18 +46,12 @@ static SDL_Renderer *GL_CreateRenderer(SDL_Window * window, Uint32 flags);
|
|||
static void GL_WindowEvent(SDL_Renderer * renderer,
|
||||
const SDL_WindowEvent *event);
|
||||
static int GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture);
|
||||
static int GL_QueryTexturePixels(SDL_Renderer * renderer,
|
||||
SDL_Texture * texture, void **pixels,
|
||||
int *pitch);
|
||||
static int GL_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
|
||||
const SDL_Rect * rect, const void *pixels,
|
||||
int pitch);
|
||||
static int GL_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
|
||||
const SDL_Rect * rect, int markDirty, void **pixels,
|
||||
int *pitch);
|
||||
const SDL_Rect * rect, void **pixels, int *pitch);
|
||||
static void GL_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture);
|
||||
static void GL_DirtyTexture(SDL_Renderer * renderer, SDL_Texture * texture,
|
||||
int numrects, const SDL_Rect * rects);
|
||||
static int GL_RenderClear(SDL_Renderer * renderer);
|
||||
static int GL_RenderDrawPoints(SDL_Renderer * renderer,
|
||||
const SDL_Point * points, int count);
|
||||
|
@ -102,21 +75,8 @@ SDL_RenderDriver GL_RenderDriver = {
|
|||
{
|
||||
"opengl",
|
||||
(SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED),
|
||||
13,
|
||||
{
|
||||
SDL_PIXELFORMAT_RGB332,
|
||||
SDL_PIXELFORMAT_RGB444,
|
||||
SDL_PIXELFORMAT_RGB555,
|
||||
SDL_PIXELFORMAT_ARGB4444,
|
||||
SDL_PIXELFORMAT_ARGB1555,
|
||||
SDL_PIXELFORMAT_RGB565,
|
||||
SDL_PIXELFORMAT_RGB24,
|
||||
SDL_PIXELFORMAT_BGR24,
|
||||
SDL_PIXELFORMAT_RGB888,
|
||||
SDL_PIXELFORMAT_BGR888,
|
||||
SDL_PIXELFORMAT_ARGB8888,
|
||||
SDL_PIXELFORMAT_ABGR8888,
|
||||
SDL_PIXELFORMAT_ARGB2101010},
|
||||
1,
|
||||
{SDL_PIXELFORMAT_ARGB8888},
|
||||
0,
|
||||
0}
|
||||
};
|
||||
|
@ -126,10 +86,6 @@ typedef struct
|
|||
SDL_GLContext context;
|
||||
SDL_bool updateSize;
|
||||
SDL_bool GL_ARB_texture_rectangle_supported;
|
||||
SDL_bool GL_EXT_paletted_texture_supported;
|
||||
SDL_bool GL_APPLE_ycbcr_422_supported;
|
||||
SDL_bool GL_MESA_ycbcr_texture_supported;
|
||||
SDL_bool GL_ARB_fragment_program_supported;
|
||||
int blendMode;
|
||||
|
||||
/* OpenGL functions */
|
||||
|
@ -139,33 +95,18 @@ typedef struct
|
|||
|
||||
void (*glTextureRangeAPPLE) (GLenum target, GLsizei length,
|
||||
const GLvoid * pointer);
|
||||
|
||||
PFNGLGETPROGRAMIVARBPROC glGetProgramivARB;
|
||||
PFNGLGETPROGRAMSTRINGARBPROC glGetProgramStringARB;
|
||||
PFNGLPROGRAMLOCALPARAMETER4FVARBPROC glProgramLocalParameter4fvARB;
|
||||
PFNGLDELETEPROGRAMSARBPROC glDeleteProgramsARB;
|
||||
PFNGLGENPROGRAMSARBPROC glGenProgramsARB;
|
||||
PFNGLBINDPROGRAMARBPROC glBindProgramARB;
|
||||
PFNGLPROGRAMSTRINGARBPROC glProgramStringARB;
|
||||
|
||||
/* (optional) fragment programs */
|
||||
GLuint fragment_program_UYVY;
|
||||
} GL_RenderData;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GLuint texture;
|
||||
GLuint shader;
|
||||
GLenum type;
|
||||
GLfloat texw;
|
||||
GLfloat texh;
|
||||
GLenum format;
|
||||
GLenum formattype;
|
||||
Uint8 *palette;
|
||||
void *pixels;
|
||||
int pitch;
|
||||
SDL_DirtyRectList dirty;
|
||||
int HACK_RYAN_FIXME;
|
||||
} GL_TextureData;
|
||||
|
||||
|
||||
|
@ -257,11 +198,9 @@ GL_CreateRenderer(SDL_Window * window, Uint32 flags)
|
|||
|
||||
renderer->WindowEvent = GL_WindowEvent;
|
||||
renderer->CreateTexture = GL_CreateTexture;
|
||||
renderer->QueryTexturePixels = GL_QueryTexturePixels;
|
||||
renderer->UpdateTexture = GL_UpdateTexture;
|
||||
renderer->LockTexture = GL_LockTexture;
|
||||
renderer->UnlockTexture = GL_UnlockTexture;
|
||||
renderer->DirtyTexture = GL_DirtyTexture;
|
||||
renderer->RenderClear = GL_RenderClear;
|
||||
renderer->RenderDrawPoints = GL_RenderDrawPoints;
|
||||
renderer->RenderDrawLines = GL_RenderDrawLines;
|
||||
|
@ -317,40 +256,12 @@ GL_CreateRenderer(SDL_Window * window, Uint32 flags)
|
|||
|| SDL_GL_ExtensionSupported("GL_EXT_texture_rectangle")) {
|
||||
data->GL_ARB_texture_rectangle_supported = SDL_TRUE;
|
||||
}
|
||||
if (SDL_GL_ExtensionSupported("GL_APPLE_ycbcr_422")) {
|
||||
data->GL_APPLE_ycbcr_422_supported = SDL_TRUE;
|
||||
}
|
||||
if (SDL_GL_ExtensionSupported("GL_MESA_ycbcr_texture")) {
|
||||
data->GL_MESA_ycbcr_texture_supported = SDL_TRUE;
|
||||
}
|
||||
if (SDL_GL_ExtensionSupported("GL_APPLE_texture_range")) {
|
||||
data->glTextureRangeAPPLE =
|
||||
(void (*)(GLenum, GLsizei, const GLvoid *))
|
||||
SDL_GL_GetProcAddress("glTextureRangeAPPLE");
|
||||
}
|
||||
|
||||
/* we might use fragment programs for YUV data, etc. */
|
||||
if (SDL_GL_ExtensionSupported("GL_ARB_fragment_program")) {
|
||||
/* !!! FIXME: this doesn't check for errors. */
|
||||
/* !!! FIXME: this should really reuse the glfuncs.h stuff. */
|
||||
data->glGetProgramivARB = (PFNGLGETPROGRAMIVARBPROC)
|
||||
SDL_GL_GetProcAddress("glGetProgramivARB");
|
||||
data->glGetProgramStringARB = (PFNGLGETPROGRAMSTRINGARBPROC)
|
||||
SDL_GL_GetProcAddress("glGetProgramStringARB");
|
||||
data->glProgramLocalParameter4fvARB =
|
||||
(PFNGLPROGRAMLOCALPARAMETER4FVARBPROC)
|
||||
SDL_GL_GetProcAddress("glProgramLocalParameter4fvARB");
|
||||
data->glDeleteProgramsARB = (PFNGLDELETEPROGRAMSARBPROC)
|
||||
SDL_GL_GetProcAddress("glDeleteProgramsARB");
|
||||
data->glGenProgramsARB = (PFNGLGENPROGRAMSARBPROC)
|
||||
SDL_GL_GetProcAddress("glGenProgramsARB");
|
||||
data->glBindProgramARB = (PFNGLBINDPROGRAMARBPROC)
|
||||
SDL_GL_GetProcAddress("glBindProgramARB");
|
||||
data->glProgramStringARB = (PFNGLPROGRAMSTRINGARBPROC)
|
||||
SDL_GL_GetProcAddress("glProgramStringARB");
|
||||
data->GL_ARB_fragment_program_supported = SDL_TRUE;
|
||||
}
|
||||
|
||||
/* Set up parameters for rendering */
|
||||
data->blendMode = -1;
|
||||
data->glDisable(GL_DEPTH_TEST);
|
||||
|
@ -419,240 +330,16 @@ power_of_2(int input)
|
|||
return value;
|
||||
}
|
||||
|
||||
|
||||
//#define DEBUG_PROGRAM_COMPILE 1
|
||||
|
||||
static void
|
||||
set_shader_error(GL_RenderData * data, const char *prefix)
|
||||
{
|
||||
GLint pos = 0;
|
||||
const GLubyte *errstr;
|
||||
data->glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &pos);
|
||||
errstr = data->glGetString(GL_PROGRAM_ERROR_STRING_ARB);
|
||||
SDL_SetError("%s: shader compile error at position %d: %s",
|
||||
prefix, (int) pos, (const char *) errstr);
|
||||
}
|
||||
|
||||
static GLuint
|
||||
compile_shader(GL_RenderData * data, GLenum shader_type, const char *_code)
|
||||
{
|
||||
const int have_texture_rects = data->GL_ARB_texture_rectangle_supported;
|
||||
const char *replacement = have_texture_rects ? "RECT" : "2D";
|
||||
const size_t replacementlen = SDL_strlen(replacement);
|
||||
const char *token = "%TEXTURETARGET%";
|
||||
const size_t tokenlen = SDL_strlen(token);
|
||||
char *code = NULL;
|
||||
char *ptr = NULL;
|
||||
GLuint program = 0;
|
||||
|
||||
/*
|
||||
* The TEX instruction needs a different target depending on what we use.
|
||||
* To handle this, we use "%TEXTURETARGET%" and replace the string before
|
||||
* compiling the shader.
|
||||
*/
|
||||
code = SDL_strdup(_code);
|
||||
if (code == NULL)
|
||||
return 0;
|
||||
|
||||
for (ptr = SDL_strstr(code, token); ptr; ptr = SDL_strstr(ptr + 1, token)) {
|
||||
SDL_memcpy(ptr, replacement, replacementlen);
|
||||
SDL_memmove(ptr + replacementlen, ptr + tokenlen,
|
||||
SDL_strlen(ptr + tokenlen) + 1);
|
||||
}
|
||||
|
||||
#if DEBUG_PROGRAM_COMPILE
|
||||
printf("compiling shader:\n%s\n\n", code);
|
||||
#endif
|
||||
|
||||
data->glGetError(); /* flush any existing error state. */
|
||||
data->glGenProgramsARB(1, &program);
|
||||
data->glBindProgramARB(shader_type, program);
|
||||
data->glProgramStringARB(shader_type, GL_PROGRAM_FORMAT_ASCII_ARB,
|
||||
(GLsizei)SDL_strlen(code), code);
|
||||
|
||||
SDL_free(code);
|
||||
|
||||
if (data->glGetError() == GL_INVALID_OPERATION) {
|
||||
#if DEBUG_PROGRAM_COMPILE
|
||||
GLint pos = 0;
|
||||
const GLubyte *errstr;
|
||||
data->glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &pos);
|
||||
errstr = data->glGetString(GL_PROGRAM_ERROR_STRING_ARB);
|
||||
printf("program compile error at position %d: %s\n\n",
|
||||
(int) pos, (const char *) errstr);
|
||||
#endif
|
||||
data->glBindProgramARB(shader_type, 0);
|
||||
data->glDeleteProgramsARB(1, &program);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return program;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Fragment program that renders from UYVY textures.
|
||||
* The UYVY to RGB equasion is:
|
||||
* R = 1.164(Y-16) + 1.596(Cr-128)
|
||||
* G = 1.164(Y-16) - 0.813(Cr-128) - 0.391(Cb-128)
|
||||
* B = 1.164(Y-16) + 2.018(Cb-128)
|
||||
* Byte layout is Cb, Y1, Cr, Y2, stored in the R, G, B, A channels.
|
||||
* 4 bytes == 2 pixels: Y1/Cb/Cr, Y2/Cb/Cr
|
||||
*
|
||||
* !!! FIXME: this ignores blendmodes, etc.
|
||||
* !!! FIXME: this could be more efficient...use a dot product for green, etc.
|
||||
*/
|
||||
static const char *fragment_program_UYVY_source_code = "!!ARBfp1.0\n"
|
||||
/* outputs... */
|
||||
"OUTPUT outcolor = result.color;\n"
|
||||
/* scratch registers... */
|
||||
"TEMP uyvy;\n" "TEMP luminance;\n" "TEMP work;\n"
|
||||
/* Halve the coordinates to grab the correct 32 bits for the fragment. */
|
||||
"MUL work, fragment.texcoord, { 0.5, 1.0, 1.0, 1.0 };\n"
|
||||
/* Sample the YUV texture. Cb, Y1, Cr, Y2, are stored in x, y, z, w. */
|
||||
"TEX uyvy, work, texture[0], %TEXTURETARGET%;\n"
|
||||
/* Do subtractions (128/255, 16/255, 128/255, 16/255) */
|
||||
"SUB uyvy, uyvy, { 0.501960784313726, 0.06274509803922, 0.501960784313726, 0.06274509803922 };\n"
|
||||
/* Choose the luminance component by texcoord. */
|
||||
/* !!! FIXME: laziness wins out for now... just average Y1 and Y2. */
|
||||
"ADD luminance, uyvy.yyyy, uyvy.wwww;\n"
|
||||
"MUL luminance, luminance, { 0.5, 0.5, 0.5, 0.5 };\n"
|
||||
/* Multiply luminance by its magic value. */
|
||||
"MUL luminance, luminance, { 1.164, 1.164, 1.164, 1.164 };\n"
|
||||
/* uyvy.xyzw becomes Cr/Cr/Cb/Cb, with multiplications. */
|
||||
"MUL uyvy, uyvy.zzxx, { 1.596, -0.813, 2.018, -0.391 };\n"
|
||||
/* Add luminance to Cr and Cb, store to RGB channels. */
|
||||
"ADD work.rgb, luminance, uyvy;\n"
|
||||
/* Do final addition for Green channel. (!!! FIXME: this should be a DPH?) */
|
||||
"ADD work.g, work.g, uyvy.w;\n"
|
||||
/* Make sure alpha channel is fully opaque. (!!! FIXME: blend modes!) */
|
||||
"MOV work.a, { 1.0 };\n"
|
||||
/* Store out the final fragment color... */
|
||||
"MOV outcolor, work;\n"
|
||||
/* ...and we're done! */
|
||||
"END\n";
|
||||
|
||||
static __inline__ SDL_bool
|
||||
convert_format(GL_RenderData *renderdata, Uint32 pixel_format,
|
||||
GLint* internalFormat, GLenum* format, GLenum* type)
|
||||
{
|
||||
switch (pixel_format) {
|
||||
case SDL_PIXELFORMAT_RGB332:
|
||||
*internalFormat = GL_R3_G3_B2;
|
||||
*format = GL_RGB;
|
||||
*type = GL_UNSIGNED_BYTE_3_3_2;
|
||||
break;
|
||||
case SDL_PIXELFORMAT_RGB444:
|
||||
*internalFormat = GL_RGB4;
|
||||
*format = GL_RGB;
|
||||
*type = GL_UNSIGNED_SHORT_4_4_4_4;
|
||||
break;
|
||||
case SDL_PIXELFORMAT_RGB555:
|
||||
*internalFormat = GL_RGB5;
|
||||
*format = GL_RGB;
|
||||
*type = GL_UNSIGNED_SHORT_5_5_5_1;
|
||||
break;
|
||||
case SDL_PIXELFORMAT_ARGB4444:
|
||||
*internalFormat = GL_RGBA4;
|
||||
*format = GL_BGRA;
|
||||
*type = GL_UNSIGNED_SHORT_4_4_4_4_REV;
|
||||
break;
|
||||
case SDL_PIXELFORMAT_ARGB1555:
|
||||
*internalFormat = GL_RGB5_A1;
|
||||
*format = GL_BGRA;
|
||||
*type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
|
||||
break;
|
||||
case SDL_PIXELFORMAT_RGB565:
|
||||
*internalFormat = GL_RGB8;
|
||||
*format = GL_RGB;
|
||||
*type = GL_UNSIGNED_SHORT_5_6_5;
|
||||
break;
|
||||
case SDL_PIXELFORMAT_RGB24:
|
||||
*internalFormat = GL_RGB8;
|
||||
*format = GL_RGB;
|
||||
*type = GL_UNSIGNED_BYTE;
|
||||
break;
|
||||
case SDL_PIXELFORMAT_RGB888:
|
||||
*internalFormat = GL_RGB8;
|
||||
*format = GL_BGRA;
|
||||
*type = GL_UNSIGNED_BYTE;
|
||||
break;
|
||||
case SDL_PIXELFORMAT_BGR24:
|
||||
*internalFormat = GL_RGB8;
|
||||
*format = GL_BGR;
|
||||
*type = GL_UNSIGNED_BYTE;
|
||||
break;
|
||||
case SDL_PIXELFORMAT_BGR888:
|
||||
*internalFormat = GL_RGB8;
|
||||
*format = GL_RGBA;
|
||||
*type = GL_UNSIGNED_BYTE;
|
||||
break;
|
||||
case SDL_PIXELFORMAT_ARGB8888:
|
||||
#ifdef __MACOSX__
|
||||
*internalFormat = GL_RGBA;
|
||||
*internalFormat = GL_RGBA8;
|
||||
*format = GL_BGRA;
|
||||
*type = GL_UNSIGNED_INT_8_8_8_8_REV;
|
||||
#else
|
||||
*internalFormat = GL_RGBA8;
|
||||
*format = GL_BGRA;
|
||||
*type = GL_UNSIGNED_BYTE;
|
||||
#endif
|
||||
break;
|
||||
case SDL_PIXELFORMAT_ABGR8888:
|
||||
*internalFormat = GL_RGBA8;
|
||||
*format = GL_RGBA;
|
||||
*type = GL_UNSIGNED_BYTE;
|
||||
break;
|
||||
case SDL_PIXELFORMAT_ARGB2101010:
|
||||
*internalFormat = GL_RGB10_A2;
|
||||
*format = GL_BGRA;
|
||||
*type = GL_UNSIGNED_INT_2_10_10_10_REV;
|
||||
break;
|
||||
case SDL_PIXELFORMAT_UYVY:
|
||||
if (renderdata->GL_APPLE_ycbcr_422_supported) {
|
||||
*internalFormat = GL_RGB;
|
||||
*format = GL_YCBCR_422_APPLE;
|
||||
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
|
||||
*type = GL_UNSIGNED_SHORT_8_8_APPLE;
|
||||
#else
|
||||
*type = GL_UNSIGNED_SHORT_8_8_REV_APPLE;
|
||||
#endif
|
||||
} else if (renderdata->GL_MESA_ycbcr_texture_supported) {
|
||||
*internalFormat = GL_YCBCR_MESA;
|
||||
*format = GL_YCBCR_MESA;
|
||||
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
|
||||
*type = GL_UNSIGNED_SHORT_8_8_MESA;
|
||||
#else
|
||||
*type = GL_UNSIGNED_SHORT_8_8_REV_MESA;
|
||||
#endif
|
||||
} else if (renderdata->GL_ARB_fragment_program_supported) {
|
||||
*internalFormat = GL_RGBA;
|
||||
*format = GL_RGBA;
|
||||
*type = GL_UNSIGNED_BYTE;
|
||||
} else {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
break;
|
||||
case SDL_PIXELFORMAT_YUY2:
|
||||
if (renderdata->GL_APPLE_ycbcr_422_supported) {
|
||||
*internalFormat = GL_RGB;
|
||||
*format = GL_YCBCR_422_APPLE;
|
||||
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
|
||||
*type = GL_UNSIGNED_SHORT_8_8_REV_APPLE;
|
||||
#else
|
||||
*type = GL_UNSIGNED_SHORT_8_8_APPLE;
|
||||
#endif
|
||||
} else if (renderdata->GL_MESA_ycbcr_texture_supported) {
|
||||
*internalFormat = GL_YCBCR_MESA;
|
||||
*format = GL_YCBCR_MESA;
|
||||
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
|
||||
*type = GL_UNSIGNED_SHORT_8_8_REV_MESA;
|
||||
#else
|
||||
*type = GL_UNSIGNED_SHORT_8_8_MESA;
|
||||
#endif
|
||||
} else {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return SDL_FALSE;
|
||||
|
@ -668,7 +355,6 @@ GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
|||
GLint internalFormat;
|
||||
GLenum format, type;
|
||||
int texture_w, texture_h;
|
||||
GLuint shader = 0;
|
||||
GLenum result;
|
||||
|
||||
GL_ActivateRenderer(renderer);
|
||||
|
@ -679,21 +365,6 @@ GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
|||
SDL_GetPixelFormatName(texture->format));
|
||||
return -1;
|
||||
}
|
||||
if (texture->format == SDL_PIXELFORMAT_UYVY &&
|
||||
!renderdata->GL_APPLE_ycbcr_422_supported &&
|
||||
!renderdata->GL_MESA_ycbcr_texture_supported &&
|
||||
renderdata->GL_ARB_fragment_program_supported) {
|
||||
if (renderdata->fragment_program_UYVY == 0) {
|
||||
renderdata->fragment_program_UYVY =
|
||||
compile_shader(renderdata, GL_FRAGMENT_PROGRAM_ARB,
|
||||
fragment_program_UYVY_source_code);
|
||||
if (renderdata->fragment_program_UYVY == 0) {
|
||||
set_shader_error(renderdata, "UYVY");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
shader = renderdata->fragment_program_UYVY;
|
||||
}
|
||||
|
||||
data = (GL_TextureData *) SDL_calloc(1, sizeof(*data));
|
||||
if (!data) {
|
||||
|
@ -701,10 +372,8 @@ GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
|||
return -1;
|
||||
}
|
||||
|
||||
data->shader = shader;
|
||||
|
||||
if (texture->access == SDL_TEXTUREACCESS_STREAMING) {
|
||||
data->pitch = texture->w * bytes_per_pixel(texture->format);
|
||||
data->pitch = texture->w * SDL_BYTESPERPIXEL(texture->format);
|
||||
data->pixels = SDL_malloc(texture->h * data->pitch);
|
||||
if (!data->pixels) {
|
||||
SDL_OutOfMemory();
|
||||
|
@ -731,17 +400,6 @@ GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
|||
data->texh = (GLfloat) texture->h / texture_h;
|
||||
}
|
||||
|
||||
/* YUV formats use RGBA but are really two bytes per pixel */
|
||||
if (internalFormat == GL_RGBA && bytes_per_pixel(texture->format) < 4) {
|
||||
texture_w /= 2;
|
||||
if (data->type == GL_TEXTURE_2D) {
|
||||
data->texw *= 2.0f;
|
||||
}
|
||||
data->HACK_RYAN_FIXME = 2;
|
||||
} else {
|
||||
data->HACK_RYAN_FIXME = 1;
|
||||
}
|
||||
|
||||
data->format = format;
|
||||
data->formattype = type;
|
||||
renderdata->glEnable(data->type);
|
||||
|
@ -771,22 +429,13 @@ GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
|||
renderdata->glTexParameteri(data->type, GL_TEXTURE_STORAGE_HINT_APPLE,
|
||||
GL_STORAGE_CACHED_APPLE);
|
||||
}
|
||||
/* This causes a crash in testoverlay for some reason. Apple bug? */
|
||||
#if 0
|
||||
if (texture->access == SDL_TEXTUREACCESS_STREAMING
|
||||
&& texture->format == SDL_PIXELFORMAT_ARGB8888) {
|
||||
/*
|
||||
if (renderdata->glTextureRangeAPPLE) {
|
||||
renderdata->glTextureRangeAPPLE(data->type,
|
||||
texture->h * data->pitch,
|
||||
data->pixels);
|
||||
}
|
||||
*/
|
||||
renderdata->glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE);
|
||||
renderdata->glTexImage2D(data->type, 0, internalFormat, texture_w,
|
||||
texture_h, 0, format, type, data->pixels);
|
||||
} else
|
||||
#endif
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
renderdata->glTexImage2D(data->type, 0, internalFormat, texture_w,
|
||||
|
@ -801,26 +450,13 @@ GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
GL_QueryTexturePixels(SDL_Renderer * renderer, SDL_Texture * texture,
|
||||
void **pixels, int *pitch)
|
||||
{
|
||||
GL_TextureData *data = (GL_TextureData *) texture->driverdata;
|
||||
|
||||
*pixels = data->pixels;
|
||||
*pitch = data->pitch;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
SetupTextureUpdate(GL_RenderData * renderdata, SDL_Texture * texture,
|
||||
int pitch)
|
||||
{
|
||||
renderdata->glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
renderdata->glPixelStorei(GL_UNPACK_ROW_LENGTH,
|
||||
(pitch / bytes_per_pixel(texture->format)) /
|
||||
((GL_TextureData *) texture->driverdata)->
|
||||
HACK_RYAN_FIXME);
|
||||
(pitch / SDL_BYTESPERPIXEL(texture->format)));
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -851,18 +487,13 @@ GL_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
|
|||
|
||||
static int
|
||||
GL_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
|
||||
const SDL_Rect * rect, int markDirty, void **pixels,
|
||||
int *pitch)
|
||||
const SDL_Rect * rect, void **pixels, int *pitch)
|
||||
{
|
||||
GL_TextureData *data = (GL_TextureData *) texture->driverdata;
|
||||
|
||||
if (markDirty) {
|
||||
SDL_AddDirtyRect(&data->dirty, rect);
|
||||
}
|
||||
|
||||
*pixels =
|
||||
(void *) ((Uint8 *) data->pixels + rect->y * data->pitch +
|
||||
rect->x * bytes_per_pixel(texture->format));
|
||||
rect->x * SDL_BYTESPERPIXEL(texture->format));
|
||||
*pitch = data->pitch;
|
||||
return 0;
|
||||
}
|
||||
|
@ -870,18 +501,17 @@ GL_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
|
|||
static void
|
||||
GL_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
GL_DirtyTexture(SDL_Renderer * renderer, SDL_Texture * texture, int numrects,
|
||||
const SDL_Rect * rects)
|
||||
{
|
||||
GL_RenderData *renderdata = (GL_RenderData *) renderer->driverdata;
|
||||
GL_TextureData *data = (GL_TextureData *) texture->driverdata;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < numrects; ++i) {
|
||||
SDL_AddDirtyRect(&data->dirty, &rects[i]);
|
||||
}
|
||||
GL_ActivateRenderer(renderer);
|
||||
|
||||
SetupTextureUpdate(renderdata, texture, data->pitch);
|
||||
renderdata->glEnable(data->type);
|
||||
renderdata->glBindTexture(data->type, data->texture);
|
||||
renderdata->glTexSubImage2D(data->type, 0, 0, 0, texture->w, texture->h,
|
||||
data->format, data->formattype, data->pixels);
|
||||
renderdata->glDisable(data->type);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1056,28 +686,6 @@ GL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
|
|||
|
||||
GL_ActivateRenderer(renderer);
|
||||
|
||||
if (texturedata->dirty.list) {
|
||||
SDL_DirtyRect *dirty;
|
||||
void *pixels;
|
||||
int bpp = bytes_per_pixel(texture->format);
|
||||
int pitch = texturedata->pitch;
|
||||
|
||||
SetupTextureUpdate(data, texture, pitch);
|
||||
data->glEnable(texturedata->type);
|
||||
data->glBindTexture(texturedata->type, texturedata->texture);
|
||||
for (dirty = texturedata->dirty.list; dirty; dirty = dirty->next) {
|
||||
SDL_Rect *rect = &dirty->rect;
|
||||
pixels =
|
||||
(void *) ((Uint8 *) texturedata->pixels + rect->y * pitch +
|
||||
rect->x * bpp);
|
||||
data->glTexSubImage2D(texturedata->type, 0, rect->x, rect->y,
|
||||
rect->w / texturedata->HACK_RYAN_FIXME,
|
||||
rect->h, texturedata->format,
|
||||
texturedata->formattype, pixels);
|
||||
}
|
||||
SDL_ClearDirtyRects(&texturedata->dirty);
|
||||
}
|
||||
|
||||
minx = dstrect->x;
|
||||
miny = dstrect->y;
|
||||
maxx = dstrect->x + dstrect->w;
|
||||
|
@ -1106,12 +714,6 @@ GL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
|
|||
|
||||
GL_SetBlendMode(data, texture->blendMode);
|
||||
|
||||
/* Set up the shader for the copy, if any */
|
||||
if (texturedata->shader) {
|
||||
data->glEnable(GL_FRAGMENT_PROGRAM_ARB);
|
||||
data->glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, texturedata->shader);
|
||||
}
|
||||
|
||||
data->glBegin(GL_TRIANGLE_STRIP);
|
||||
data->glTexCoord2f(minu, minv);
|
||||
data->glVertex2f((GLfloat) minx, (GLfloat) miny);
|
||||
|
@ -1123,10 +725,6 @@ GL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
|
|||
data->glVertex2f((GLfloat) maxx, (GLfloat) maxy);
|
||||
data->glEnd();
|
||||
|
||||
if (texturedata->shader) {
|
||||
data->glDisable(GL_FRAGMENT_PROGRAM_ARB);
|
||||
}
|
||||
|
||||
data->glDisable(texturedata->type);
|
||||
|
||||
return 0;
|
||||
|
@ -1155,13 +753,13 @@ GL_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
|
|||
|
||||
data->glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||
data->glPixelStorei(GL_PACK_ROW_LENGTH,
|
||||
(pitch / bytes_per_pixel(pixel_format)));
|
||||
(pitch / SDL_BYTESPERPIXEL(pixel_format)));
|
||||
|
||||
data->glReadPixels(rect->x, (h-rect->y)-rect->h, rect->w, rect->h,
|
||||
format, type, pixels);
|
||||
|
||||
/* Flip the rows to be top-down */
|
||||
length = rect->w * bytes_per_pixel(pixel_format);
|
||||
length = rect->w * SDL_BYTESPERPIXEL(pixel_format);
|
||||
src = (Uint8*)pixels + (rect->h-1)*pitch;
|
||||
dst = (Uint8*)pixels;
|
||||
tmp = SDL_stack_alloc(Uint8, length);
|
||||
|
@ -1201,7 +799,7 @@ GL_RenderWritePixels(SDL_Renderer * renderer, const SDL_Rect * rect,
|
|||
|
||||
data->glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
data->glPixelStorei(GL_UNPACK_ROW_LENGTH,
|
||||
(pitch / bytes_per_pixel(pixel_format)));
|
||||
(pitch / SDL_BYTESPERPIXEL(pixel_format)));
|
||||
|
||||
/* Flip the rows to be bottom-up */
|
||||
length = rect->h * rect->w * pitch;
|
||||
|
@ -1244,13 +842,9 @@ GL_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
|||
if (data->texture) {
|
||||
renderdata->glDeleteTextures(1, &data->texture);
|
||||
}
|
||||
if (data->palette) {
|
||||
SDL_free(data->palette);
|
||||
}
|
||||
if (data->pixels) {
|
||||
SDL_free(data->pixels);
|
||||
}
|
||||
SDL_FreeDirtyRects(&data->dirty);
|
||||
SDL_free(data);
|
||||
texture->driverdata = NULL;
|
||||
}
|
||||
|
@ -1262,16 +856,6 @@ GL_DestroyRenderer(SDL_Renderer * renderer)
|
|||
|
||||
if (data) {
|
||||
if (data->context) {
|
||||
if (data->GL_ARB_fragment_program_supported) {
|
||||
data->glDisable(GL_FRAGMENT_PROGRAM_ARB);
|
||||
data->glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, 0);
|
||||
if (data->fragment_program_UYVY &&
|
||||
data->fragment_program_UYVY != ~0) {
|
||||
data->glDeleteProgramsARB(1,
|
||||
&data->fragment_program_UYVY);
|
||||
}
|
||||
}
|
||||
|
||||
/* SDL_GL_MakeCurrent(0, NULL); *//* doesn't do anything */
|
||||
SDL_GL_DeleteContext(data->context);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue