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

@ -23,7 +23,6 @@
#include "../SDL_sysrender.h"
#include "../../video/SDL_pixels_c.h"
#include "../../video/SDL_yuv_sw_c.h"
/* SDL surface based renderer implementation */
@ -32,9 +31,6 @@ static SDL_Renderer *SW_CreateRenderer(SDL_Window * window, Uint32 flags);
static void SW_WindowEvent(SDL_Renderer * renderer,
const SDL_WindowEvent *event);
static int SW_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture);
static int SW_QueryTexturePixels(SDL_Renderer * renderer,
SDL_Texture * texture, void **pixels,
int *pitch);
static int SW_SetTextureColorMod(SDL_Renderer * renderer,
SDL_Texture * texture);
static int SW_SetTextureAlphaMod(SDL_Renderer * renderer,
@ -45,8 +41,7 @@ static int SW_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
const SDL_Rect * rect, const void *pixels,
int pitch);
static int SW_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 SW_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture);
static int SW_RenderDrawPoints(SDL_Renderer * renderer,
const SDL_Point * points, int count);
@ -70,7 +65,7 @@ SDL_RenderDriver SW_RenderDriver = {
{
"software",
(SDL_RENDERER_PRESENTVSYNC),
13,
8,
{
SDL_PIXELFORMAT_RGB555,
SDL_PIXELFORMAT_RGB565,
@ -79,12 +74,8 @@ SDL_RenderDriver SW_RenderDriver = {
SDL_PIXELFORMAT_ARGB8888,
SDL_PIXELFORMAT_RGBA8888,
SDL_PIXELFORMAT_ABGR8888,
SDL_PIXELFORMAT_BGRA8888,
SDL_PIXELFORMAT_YV12,
SDL_PIXELFORMAT_IYUV,
SDL_PIXELFORMAT_YUY2,
SDL_PIXELFORMAT_UYVY,
SDL_PIXELFORMAT_YVYU},
SDL_PIXELFORMAT_BGRA8888
},
0,
0}
};
@ -96,7 +87,6 @@ typedef struct
SDL_Texture *texture;
SDL_Surface surface;
SDL_Renderer *renderer;
SDL_DirtyRectList dirty;
} SW_RenderData;
static SDL_Texture *
@ -136,6 +126,7 @@ SW_CreateRenderer(SDL_Window * window, Uint32 flags)
SDL_Renderer *renderer;
SW_RenderData *data;
int i;
int w, h;
Uint32 format;
int bpp;
Uint32 Rmask, Gmask, Bmask, Amask;
@ -163,7 +154,6 @@ SW_CreateRenderer(SDL_Window * window, Uint32 flags)
}
renderer->WindowEvent = SW_WindowEvent;
renderer->CreateTexture = SW_CreateTexture;
renderer->QueryTexturePixels = SW_QueryTexturePixels;
renderer->SetTextureColorMod = SW_SetTextureColorMod;
renderer->SetTextureAlphaMod = SW_SetTextureAlphaMod;
renderer->SetTextureBlendMode = SW_SetTextureBlendMode;
@ -217,8 +207,8 @@ SW_CreateRenderer(SDL_Window * window, Uint32 flags)
}
/* Create the textures we'll use for display */
data->texture =
CreateTexture(data->renderer, data->format, window->w, window->h);
SDL_GetWindowSize(window, &w, &h);
data->texture = CreateTexture(data->renderer, data->format, w, h);
if (!data->texture) {
SW_DestroyRenderer(renderer);
return NULL;
@ -243,11 +233,12 @@ SW_ActivateRenderer(SDL_Renderer * renderer)
if (data->updateSize) {
/* Recreate the textures for the new window size */
int w, h;
if (data->texture) {
DestroyTexture(data->renderer, data->texture);
}
data->texture = CreateTexture(data->renderer, data->format,
window->w, window->h);
SDL_GetWindowSize(window, &w, &h);
data->texture = CreateTexture(data->renderer, data->format, w, h);
if (data->texture) {
data->updateSize = SDL_FALSE;
}
@ -268,30 +259,25 @@ SW_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event)
static int
SW_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
{
if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
texture->driverdata =
SDL_SW_CreateYUVTexture(texture->format, texture->w, texture->h);
} else {
int bpp;
Uint32 Rmask, Gmask, Bmask, Amask;
int bpp;
Uint32 Rmask, Gmask, Bmask, Amask;
if (!SDL_PixelFormatEnumToMasks
(texture->format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) {
SDL_SetError("Unknown texture format");
return -1;
}
if (!SDL_PixelFormatEnumToMasks
(texture->format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) {
SDL_SetError("Unknown texture format");
return -1;
}
texture->driverdata =
SDL_CreateRGBSurface(0, texture->w, texture->h, bpp, Rmask, Gmask,
Bmask, Amask);
SDL_SetSurfaceColorMod(texture->driverdata, texture->r, texture->g,
texture->b);
SDL_SetSurfaceAlphaMod(texture->driverdata, texture->a);
SDL_SetSurfaceBlendMode(texture->driverdata, texture->blendMode);
texture->driverdata =
SDL_CreateRGBSurface(0, texture->w, texture->h, bpp, Rmask, Gmask,
Bmask, Amask);
SDL_SetSurfaceColorMod(texture->driverdata, texture->r, texture->g,
texture->b);
SDL_SetSurfaceAlphaMod(texture->driverdata, texture->a);
SDL_SetSurfaceBlendMode(texture->driverdata, texture->blendMode);
if (texture->access == SDL_TEXTUREACCESS_STATIC) {
SDL_SetSurfaceRLE(texture->driverdata, 1);
}
if (texture->access == SDL_TEXTUREACCESS_STATIC) {
SDL_SetSurfaceRLE(texture->driverdata, 1);
}
if (!texture->driverdata) {
@ -300,23 +286,6 @@ SW_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
return 0;
}
static int
SW_QueryTexturePixels(SDL_Renderer * renderer, SDL_Texture * texture,
void **pixels, int *pitch)
{
if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
return SDL_SW_QueryYUVTexturePixels((SDL_SW_YUVTexture *)
texture->driverdata, pixels,
pitch);
} else {
SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
*pixels = surface->pixels;
*pitch = surface->pitch;
return 0;
}
}
static int
SW_SetTextureColorMod(SDL_Renderer * renderer, SDL_Texture * texture)
{
@ -343,56 +312,40 @@ static int
SW_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
const SDL_Rect * rect, const void *pixels, int pitch)
{
if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
return SDL_SW_UpdateYUVTexture((SDL_SW_YUVTexture *)
texture->driverdata, rect, pixels,
pitch);
} else {
SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
Uint8 *src, *dst;
int row;
size_t length;
SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
Uint8 *src, *dst;
int row;
size_t length;
src = (Uint8 *) pixels;
dst =
(Uint8 *) surface->pixels + rect->y * surface->pitch +
rect->x * surface->format->BytesPerPixel;
length = rect->w * surface->format->BytesPerPixel;
for (row = 0; row < rect->h; ++row) {
SDL_memcpy(dst, src, length);
src += pitch;
dst += surface->pitch;
}
return 0;
src = (Uint8 *) pixels;
dst = (Uint8 *) surface->pixels +
rect->y * surface->pitch +
rect->x * surface->format->BytesPerPixel;
length = rect->w * surface->format->BytesPerPixel;
for (row = 0; row < rect->h; ++row) {
SDL_memcpy(dst, src, length);
src += pitch;
dst += surface->pitch;
}
return 0;
}
static int
SW_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)
{
if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
return SDL_SW_LockYUVTexture((SDL_SW_YUVTexture *)
texture->driverdata, rect, markDirty,
pixels, pitch);
} else {
SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
*pixels =
(void *) ((Uint8 *) surface->pixels + rect->y * surface->pitch +
rect->x * surface->format->BytesPerPixel);
*pitch = surface->pitch;
return 0;
}
*pixels =
(void *) ((Uint8 *) surface->pixels + rect->y * surface->pitch +
rect->x * surface->format->BytesPerPixel);
*pitch = surface->pitch;
return 0;
}
static void
SW_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
{
if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
SDL_SW_UnlockYUVTexture((SDL_SW_YUVTexture *) texture->driverdata);
}
}
static int
@ -420,7 +373,7 @@ SW_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points,
return 0;
}
if (data->renderer->LockTexture(data->renderer, texture, &rect, 1,
if (data->renderer->LockTexture(data->renderer, texture, &rect,
&data->surface.pixels,
&data->surface.pitch) < 0) {
return -1;
@ -484,7 +437,7 @@ SW_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points,
return 0;
}
if (data->renderer->LockTexture(data->renderer, texture, &rect, 1,
if (data->renderer->LockTexture(data->renderer, texture, &rect,
&data->surface.pixels,
&data->surface.pitch) < 0) {
return -1;
@ -558,7 +511,7 @@ SW_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect ** rects,
continue;
}
if (data->renderer->LockTexture(data->renderer, texture, &rect, 1,
if (data->renderer->LockTexture(data->renderer, texture, &rect,
&data->surface.pixels,
&data->surface.pitch) < 0) {
return -1;
@ -586,38 +539,31 @@ SW_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
const SDL_Rect * srcrect, const SDL_Rect * dstrect)
{
SW_RenderData *data = (SW_RenderData *) renderer->driverdata;
SDL_Surface *surface;
SDL_Rect real_srcrect;
SDL_Rect real_dstrect;
int status;
if (!SW_ActivateRenderer(renderer)) {
return -1;
}
if (data->renderer->LockTexture(data->renderer, data->texture,
dstrect, 1, &data->surface.pixels,
if (data->renderer->LockTexture(data->renderer, data->texture, dstrect,
&data->surface.pixels,
&data->surface.pitch) < 0) {
return -1;
}
if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
status =
SDL_SW_CopyYUVToRGB((SDL_SW_YUVTexture *) texture->driverdata,
srcrect, data->format, dstrect->w, dstrect->h,
data->surface.pixels, data->surface.pitch);
} else {
SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
SDL_Rect real_srcrect = *srcrect;
SDL_Rect real_dstrect;
surface = (SDL_Surface *) texture->driverdata;
real_srcrect = *srcrect;
data->surface.w = dstrect->w;
data->surface.h = dstrect->h;
data->surface.clip_rect.w = dstrect->w;
data->surface.clip_rect.h = dstrect->h;
real_dstrect = data->surface.clip_rect;
data->surface.w = dstrect->w;
data->surface.h = dstrect->h;
data->surface.clip_rect.w = dstrect->w;
data->surface.clip_rect.h = dstrect->h;
real_dstrect = data->surface.clip_rect;
status =
SDL_LowerBlit(surface, &real_srcrect, &data->surface,
&real_dstrect);
}
status = SDL_LowerBlit(surface, &real_srcrect, &data->surface, &real_dstrect);
data->renderer->UnlockTexture(data->renderer, data->texture);
return status;
}
@ -632,8 +578,8 @@ SW_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
return -1;
}
if (data->renderer->LockTexture(data->renderer, data->texture,
rect, 0, &data->surface.pixels,
if (data->renderer->LockTexture(data->renderer, data->texture, rect,
&data->surface.pixels,
&data->surface.pitch) < 0) {
return -1;
}
@ -656,8 +602,8 @@ SW_RenderWritePixels(SDL_Renderer * renderer, const SDL_Rect * rect,
return -1;
}
if (data->renderer->LockTexture(data->renderer, data->texture,
rect, 1, &data->surface.pixels,
if (data->renderer->LockTexture(data->renderer, data->texture, rect,
&data->surface.pixels,
&data->surface.pitch) < 0) {
return -1;
}
@ -692,13 +638,9 @@ SW_RenderPresent(SDL_Renderer * renderer)
static void
SW_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture)
{
if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
SDL_SW_DestroyYUVTexture((SDL_SW_YUVTexture *) texture->driverdata);
} else {
SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
SDL_FreeSurface(surface);
}
SDL_FreeSurface(surface);
}
static void
@ -717,7 +659,6 @@ SW_DestroyRenderer(SDL_Renderer * renderer)
if (data->renderer) {
data->renderer->DestroyRenderer(data->renderer);
}
SDL_FreeDirtyRects(&data->dirty);
SDL_free(data);
}
SDL_free(renderer);