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:
Sam Lantinga 2011-02-03 00:19:40 -08:00
parent 613d92a832
commit d2b54f7d24
20 changed files with 585 additions and 1315 deletions

View file

@ -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);
}