The rendering functions take a context so it's clear what window they're drawing to. This also potentially opens to the door to multi-threaded rendering in the future.

This commit is contained in:
Sam Lantinga 2011-02-01 19:19:43 -08:00
parent 52cf8a6451
commit df94d4c6a4
15 changed files with 617 additions and 690 deletions

View file

@ -31,7 +31,7 @@
#include "video/SDL_yuv_sw_c.h"
static SDL_Window *SDL_VideoWindow = NULL;
static SDL_RendererInfo SDL_VideoRendererInfo;
static SDL_Renderer *SDL_VideoRenderer = NULL;
static SDL_Texture *SDL_VideoTexture = NULL;
static SDL_Surface *SDL_VideoSurface = NULL;
static SDL_Surface *SDL_ShadowSurface = NULL;
@ -467,7 +467,8 @@ SDL_ResizeVideoMode(int width, int height, int bpp, Uint32 flags)
/* Destroy the screen texture and recreate it */
SDL_QueryTexture(SDL_VideoTexture, &format, &access, &w, &h);
SDL_DestroyTexture(SDL_VideoTexture);
SDL_VideoTexture = SDL_CreateTexture(format, access, width, height);
SDL_VideoTexture = SDL_CreateTexture(SDL_VideoRenderer, format,
access, width, height);
if (!SDL_VideoTexture) {
return -1;
}
@ -667,20 +668,20 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags)
}
/* Create a renderer for the window */
if (SDL_CreateRenderer(SDL_VideoWindow, -1, 0) < 0) {
SDL_VideoRenderer = SDL_CreateRenderer(SDL_VideoWindow, -1, 0);
if (!SDL_VideoRenderer) {
return NULL;
}
SDL_GetRendererInfo(&SDL_VideoRendererInfo);
/* Create a texture for the screen surface */
SDL_VideoTexture =
SDL_CreateTexture(desired_format, SDL_TEXTUREACCESS_STREAMING, width,
height);
SDL_VideoTexture = SDL_CreateTexture(SDL_VideoRenderer, desired_format,
SDL_TEXTUREACCESS_STREAMING,
width, height);
if (!SDL_VideoTexture) {
SDL_VideoTexture =
SDL_CreateTexture(desktop_format,
SDL_TEXTUREACCESS_STREAMING, width, height);
SDL_VideoTexture = SDL_CreateTexture(SDL_VideoRenderer, desktop_format,
SDL_TEXTUREACCESS_STREAMING,
width, height);
}
if (!SDL_VideoTexture) {
return NULL;
@ -890,8 +891,8 @@ SDL_UpdateRects(SDL_Surface * screen, int numrects, SDL_Rect * rects)
rect.y = 0;
rect.w = screen->w;
rect.h = screen->h;
SDL_RenderCopy(SDL_VideoTexture, &rect, &rect);
SDL_RenderPresent();
SDL_RenderCopy(SDL_VideoRenderer, SDL_VideoTexture, &rect, &rect);
SDL_RenderPresent(SDL_VideoRenderer);
}
}
@ -1584,7 +1585,8 @@ SDL_CreateYUVOverlay(int w, int h, Uint32 format, SDL_Surface * display)
}
overlay->hwdata->texture =
SDL_CreateTexture(texture_format, SDL_TEXTUREACCESS_STREAMING, w, h);
SDL_CreateTexture(SDL_VideoRenderer, texture_format,
SDL_TEXTUREACCESS_STREAMING, w, h);
if (overlay->hwdata->texture) {
overlay->hwdata->sw = NULL;
} else {
@ -1600,7 +1602,7 @@ SDL_CreateYUVOverlay(int w, int h, Uint32 format, SDL_Surface * display)
SDL_GetCurrentDisplayMode(&current_mode);
texture_format = current_mode.format;
overlay->hwdata->texture =
SDL_CreateTexture(texture_format,
SDL_CreateTexture(SDL_VideoRenderer, texture_format,
SDL_TEXTUREACCESS_STREAMING, w, h);
}
if (!overlay->hwdata->texture) {
@ -1688,10 +1690,10 @@ SDL_DisplayYUVOverlay(SDL_Overlay * overlay, SDL_Rect * dstrect)
SDL_SetError("Passed a NULL overlay or dstrect");
return -1;
}
if (SDL_RenderCopy(overlay->hwdata->texture, NULL, dstrect) < 0) {
if (SDL_RenderCopy(SDL_VideoRenderer, overlay->hwdata->texture, NULL, dstrect) < 0) {
return -1;
}
SDL_RenderPresent();
SDL_RenderPresent(SDL_VideoRenderer);
return 0;
}

View file

@ -106,7 +106,6 @@ SDL_SendWindowEvent(SDL_Window * window, Uint8 windowevent, int data1,
}
window->w = data1;
window->h = data2;
SDL_OnWindowResized(window);
break;
case SDL_WINDOWEVENT_MINIMIZED:
if (window->flags & SDL_WINDOW_MINIMIZED) {

View file

@ -66,8 +66,8 @@ bytes_per_pixel(const Uint32 format)
static const float inv255f = 1.0f / 255.0f;
static SDL_Renderer *GL_CreateRenderer(SDL_Window * window, Uint32 flags);
static int GL_ActivateRenderer(SDL_Renderer * renderer);
static int GL_DisplayModeChanged(SDL_Renderer * renderer);
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,
@ -277,8 +277,7 @@ GL_CreateRenderer(SDL_Window * window, Uint32 flags)
return NULL;
}
renderer->ActivateRenderer = GL_ActivateRenderer;
renderer->DisplayModeChanged = GL_DisplayModeChanged;
renderer->WindowEvent = GL_WindowEvent;
renderer->CreateTexture = GL_CreateTexture;
renderer->QueryTexturePixels = GL_QueryTexturePixels;
renderer->SetTexturePalette = GL_SetTexturePalette;
@ -408,14 +407,19 @@ GL_CreateRenderer(SDL_Window * window, Uint32 flags)
return renderer;
}
static SDL_GLContext SDL_CurrentContext = NULL;
static int
GL_ActivateRenderer(SDL_Renderer * renderer)
{
GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
SDL_Window *window = renderer->window;
if (SDL_GL_MakeCurrent(window, data->context) < 0) {
return -1;
if (SDL_CurrentContext != data->context) {
if (SDL_GL_MakeCurrent(window, data->context) < 0) {
return -1;
}
SDL_CurrentContext = data->context;
}
if (data->updateSize) {
data->glMatrixMode(GL_PROJECTION);
@ -430,14 +434,16 @@ GL_ActivateRenderer(SDL_Renderer * renderer)
return 0;
}
static int
GL_DisplayModeChanged(SDL_Renderer * renderer)
static void
GL_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event)
{
GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
/* Rebind the context to the window area and update matrices */
data->updateSize = SDL_TRUE;
return GL_ActivateRenderer(renderer);
if (event->event == SDL_WINDOWEVENT_RESIZED) {
/* Rebind the context to the window area and update matrices */
SDL_CurrentContext = NULL;
data->updateSize = SDL_TRUE;
}
}
static __inline__ int
@ -717,6 +723,8 @@ GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
GLuint shader = 0;
GLenum result;
GL_ActivateRenderer(renderer);
if (!convert_format(renderdata, texture->format, &internalFormat,
&format, &type)) {
SDL_SetError("Texture format %s not supported by OpenGL",
@ -874,6 +882,8 @@ GL_SetTexturePalette(SDL_Renderer * renderer, SDL_Texture * texture,
GL_TextureData *data = (GL_TextureData *) texture->driverdata;
Uint8 *palette;
GL_ActivateRenderer(renderer);
if (!data->palette) {
SDL_SetError("Texture doesn't have a palette");
return -1;
@ -938,6 +948,8 @@ GL_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
GL_TextureData *data = (GL_TextureData *) texture->driverdata;
GLenum result;
GL_ActivateRenderer(renderer);
renderdata->glGetError();
SetupTextureUpdate(renderdata, texture, pitch);
renderdata->glEnable(data->type);
@ -1018,6 +1030,8 @@ GL_RenderClear(SDL_Renderer * renderer)
{
GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
GL_ActivateRenderer(renderer);
data->glClearColor((GLfloat) renderer->r * inv255f,
(GLfloat) renderer->g * inv255f,
(GLfloat) renderer->b * inv255f,
@ -1035,6 +1049,8 @@ GL_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points,
GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
int i;
GL_ActivateRenderer(renderer);
GL_SetBlendMode(data, renderer->blendMode);
data->glColor4f((GLfloat) renderer->r * inv255f,
@ -1058,6 +1074,8 @@ GL_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points,
GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
int i;
GL_ActivateRenderer(renderer);
GL_SetBlendMode(data, renderer->blendMode);
data->glColor4f((GLfloat) renderer->r * inv255f,
@ -1126,6 +1144,8 @@ GL_RenderDrawRects(SDL_Renderer * renderer, const SDL_Rect ** rects, int count)
GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
int i, x, y;
GL_ActivateRenderer(renderer);
GL_SetBlendMode(data, renderer->blendMode);
data->glColor4f((GLfloat) renderer->r * inv255f,
@ -1164,6 +1184,8 @@ GL_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect ** rects, int count)
GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
int i;
GL_ActivateRenderer(renderer);
GL_SetBlendMode(data, renderer->blendMode);
data->glColor4f((GLfloat) renderer->r * inv255f,
@ -1189,6 +1211,8 @@ GL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
int minx, miny, maxx, maxy;
GLfloat minu, maxu, minv, maxv;
GL_ActivateRenderer(renderer);
if (texturedata->dirty.list) {
SDL_DirtyRect *dirty;
void *pixels;
@ -1276,6 +1300,8 @@ GL_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
Uint8 *src, *dst, *tmp;
int length, rows;
GL_ActivateRenderer(renderer);
if (!convert_format(data, pixel_format, &internalFormat, &format, &type)) {
/* FIXME: Do a temp copy to a format that is supported */
SDL_SetError("Unsupported pixel format");
@ -1323,6 +1349,8 @@ GL_RenderWritePixels(SDL_Renderer * renderer, const SDL_Rect * rect,
Uint8 *src, *dst, *tmp;
int length, rows;
GL_ActivateRenderer(renderer);
if (!convert_format(data, pixel_format, &internalFormat, &format, &type)) {
/* FIXME: Do a temp copy to a format that is supported */
SDL_SetError("Unsupported pixel format");
@ -1360,6 +1388,8 @@ GL_RenderWritePixels(SDL_Renderer * renderer, const SDL_Rect * rect,
static void
GL_RenderPresent(SDL_Renderer * renderer)
{
GL_ActivateRenderer(renderer);
SDL_GL_SwapWindow(renderer->window);
}
@ -1369,6 +1399,8 @@ GL_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture)
GL_RenderData *renderdata = (GL_RenderData *) renderer->driverdata;
GL_TextureData *data = (GL_TextureData *) texture->driverdata;
GL_ActivateRenderer(renderer);
if (!data) {
return;
}

View file

@ -54,8 +54,8 @@ glDrawTexiOES(GLint x, GLint y, GLint z, GLint width, GLint height)
static const float inv255f = 1.0f / 255.0f;
static SDL_Renderer *GLES_CreateRenderer(SDL_Window * window, Uint32 flags);
static int GLES_ActivateRenderer(SDL_Renderer * renderer);
static int GLES_DisplayModeChanged(SDL_Renderer * renderer);
static void GLES_WindowEvent(SDL_Renderer * renderer,
const SDL_WindowEvent *event);
static int GLES_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture);
static int GLES_QueryTexturePixels(SDL_Renderer * renderer,
SDL_Texture * texture, void **pixels,
@ -218,8 +218,7 @@ GLES_CreateRenderer(SDL_Window * window, Uint32 flags)
return NULL;
}
renderer->ActivateRenderer = GLES_ActivateRenderer;
renderer->DisplayModeChanged = GLES_DisplayModeChanged;
renderer->WindowEvent = GLES_WindowEvent;
renderer->CreateTexture = GLES_CreateTexture;
renderer->QueryTexturePixels = GLES_QueryTexturePixels;
renderer->SetTexturePalette = GLES_SetTexturePalette;
@ -311,6 +310,8 @@ GLES_CreateRenderer(SDL_Window * window, Uint32 flags)
return renderer;
}
static SDL_GLContext SDL_CurrentContext = NULL;
static int
GLES_ActivateRenderer(SDL_Renderer * renderer)
{
@ -318,8 +319,11 @@ GLES_ActivateRenderer(SDL_Renderer * renderer)
GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
SDL_Window *window = renderer->window;
if (SDL_GL_MakeCurrent(window, data->context) < 0) {
return -1;
if (SDL_CurrentContext != data->context) {
if (SDL_GL_MakeCurrent(window, data->context) < 0) {
return -1;
}
SDL_CurrentContext = data->context;
}
if (data->updateSize) {
data->glMatrixMode(GL_PROJECTION);
@ -334,13 +338,16 @@ GLES_ActivateRenderer(SDL_Renderer * renderer)
return 0;
}
static int
GLES_DisplayModeChanged(SDL_Renderer * renderer)
static void
GLES_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event)
{
GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
data->updateSize = SDL_TRUE;
return 0;
if (event->event == SDL_WINDOWEVENT_RESIZED) {
/* Rebind the context to the window area and update matrices */
SDL_CurrentContext = NULL;
data->updateSize = SDL_TRUE;
}
}
static __inline__ int
@ -364,6 +371,8 @@ GLES_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
int texture_w, texture_h;
GLenum result;
GLES_ActivateRenderer(renderer);
switch (texture->format) {
case SDL_PIXELFORMAT_RGB24:
internalFormat = GL_RGB;
@ -498,6 +507,8 @@ GLES_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
void * temp_ptr;
int i;
GLES_ActivateRenderer(renderer);
renderdata->glGetError();
renderdata->glEnable(data->type);
SetupTextureUpdate(renderdata, texture, pitch);
@ -599,6 +610,8 @@ GLES_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points,
int i;
GLshort *vertices;
GLES_ActivateRenderer(renderer);
GLES_SetBlendMode(data, renderer->blendMode);
data->glColor4f((GLfloat) renderer->r * inv255f,
@ -626,6 +639,8 @@ GLES_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points,
int i;
GLshort *vertices;
GLES_ActivateRenderer(renderer);
GLES_SetBlendMode(data, renderer->blendMode);
data->glColor4f((GLfloat) renderer->r * inv255f,
@ -659,6 +674,8 @@ GLES_RenderDrawRects(SDL_Renderer * renderer, const SDL_Rect ** rects,
GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
int i;
GLES_ActivateRenderer(renderer);
GLES_SetBlendMode(data, renderer->blendMode);
data->glColor4f((GLfloat) renderer->r * inv255f,
@ -696,6 +713,8 @@ GLES_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect ** rects,
GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
int i;
GLES_ActivateRenderer(renderer);
GLES_SetBlendMode(data, renderer->blendMode);
data->glColor4f((GLfloat) renderer->r * inv255f,
@ -739,6 +758,8 @@ GLES_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
void *temp_buffer; /* used for reformatting dirty rect pixels */
void *temp_ptr;
GLES_ActivateRenderer(renderer);
data->glEnable(GL_TEXTURE_2D);
if (texturedata->dirty.list) {
@ -859,6 +880,8 @@ GLES_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
static void
GLES_RenderPresent(SDL_Renderer * renderer)
{
GLES_ActivateRenderer(renderer);
SDL_GL_SwapWindow(renderer->window);
}
@ -867,6 +890,8 @@ GLES_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture)
{
GLES_TextureData *data = (GLES_TextureData *) texture->driverdata;
GLES_ActivateRenderer(renderer);
if (!data) {
return;
}

View file

@ -32,8 +32,8 @@
/* SDL surface based renderer implementation */
static SDL_Renderer *SW_CreateRenderer(SDL_Window * window, Uint32 flags);
static int SW_ActivateRenderer(SDL_Renderer * renderer);
static int SW_DisplayModeChanged(SDL_Renderer * renderer);
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,
@ -212,8 +212,7 @@ SW_CreateRenderer(SDL_Window * window, Uint32 flags)
SDL_OutOfMemory();
return NULL;
}
renderer->ActivateRenderer = SW_ActivateRenderer;
renderer->DisplayModeChanged = SW_DisplayModeChanged;
renderer->WindowEvent = SW_WindowEvent;
renderer->RenderDrawPoints = SW_RenderDrawPoints;
renderer->RenderDrawLines = SW_RenderDrawLines;
@ -287,47 +286,34 @@ SW_CreateRenderer(SDL_Window * window, Uint32 flags)
return renderer;
}
static int
static SDL_Texture *
SW_ActivateRenderer(SDL_Renderer * renderer)
{
SW_RenderData *data = (SW_RenderData *) renderer->driverdata;
SDL_Window *window = renderer->window;
int i, n;
if (data->renderer && data->renderer->ActivateRenderer) {
if (data->renderer->ActivateRenderer(data->renderer) < 0) {
return -1;
}
}
if (data->updateSize) {
/* Recreate the textures for the new window size */
if (data->texture) {
DestroyTexture(data->renderer, data->texture);
data->texture = 0;
}
data->texture = CreateTexture(data->renderer, data->format,
window->w, window->h);
if (!data->texture) {
return -1;
if (data->texture) {
data->updateSize = SDL_FALSE;
}
data->updateSize = SDL_FALSE;
}
return 0;
return data->texture;
}
static int
SW_DisplayModeChanged(SDL_Renderer * renderer)
static void
SW_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event)
{
SW_RenderData *data = (SW_RenderData *) renderer->driverdata;
if (data->renderer && data->renderer->DisplayModeChanged) {
if (data->renderer->DisplayModeChanged(data->renderer) < 0) {
return -1;
}
if (event->event == SDL_WINDOWEVENT_RESIZED) {
data->updateSize = SDL_TRUE;
}
/* Rebind the context to the window area */
data->updateSize = SDL_TRUE;
return SW_ActivateRenderer(renderer);
}
static int
@ -496,12 +482,16 @@ SW_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points,
int count)
{
SW_RenderData *data = (SW_RenderData *) renderer->driverdata;
SDL_Texture *texture = data->texture;
SDL_Texture *texture = SW_ActivateRenderer(renderer);
SDL_Rect rect;
int i;
int x, y;
int status = 0;
if (!texture) {
return -1;
}
/* Get the smallest rectangle that contains everything */
rect.x = 0;
rect.y = 0;
@ -555,12 +545,16 @@ SW_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points,
int count)
{
SW_RenderData *data = (SW_RenderData *) renderer->driverdata;
SDL_Texture *texture = data->texture;
SDL_Texture *texture = SW_ActivateRenderer(renderer);
SDL_Rect clip, rect;
int i;
int x1, y1, x2, y2;
int status = 0;
if (!texture) {
return -1;
}
/* Get the smallest rectangle that contains everything */
clip.x = 0;
clip.y = 0;
@ -619,12 +613,16 @@ SW_RenderDrawRects(SDL_Renderer * renderer, const SDL_Rect ** rects,
int count)
{
SW_RenderData *data = (SW_RenderData *) renderer->driverdata;
SDL_Texture *texture = data->texture;
SDL_Texture *texture = SW_ActivateRenderer(renderer);
SDL_Rect clip, rect;
Uint32 color = 0;
int i;
int status = 0;
if (!texture) {
return -1;
}
clip.x = 0;
clip.y = 0;
clip.w = texture->w;
@ -671,12 +669,16 @@ SW_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect ** rects,
int count)
{
SW_RenderData *data = (SW_RenderData *) renderer->driverdata;
SDL_Texture *texture = data->texture;
SDL_Texture *texture = SW_ActivateRenderer(renderer);
SDL_Rect clip, rect;
Uint32 color = 0;
int i;
int status = 0;
if (!texture) {
return -1;
}
clip.x = 0;
clip.y = 0;
clip.w = texture->w;
@ -724,6 +726,10 @@ SW_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
SW_RenderData *data = (SW_RenderData *) renderer->driverdata;
int status;
if (!SW_ActivateRenderer(renderer)) {
return -1;
}
if (data->renderer->LockTexture(data->renderer, data->texture,
dstrect, 1, &data->surface.pixels,
&data->surface.pitch) < 0) {
@ -760,6 +766,10 @@ SW_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
{
SW_RenderData *data = (SW_RenderData *) renderer->driverdata;
if (!SW_ActivateRenderer(renderer)) {
return -1;
}
if (data->renderer->LockTexture(data->renderer, data->texture,
rect, 0, &data->surface.pixels,
&data->surface.pitch) < 0) {
@ -780,6 +790,10 @@ SW_RenderWritePixels(SDL_Renderer * renderer, const SDL_Rect * rect,
{
SW_RenderData *data = (SW_RenderData *) renderer->driverdata;
if (!SW_ActivateRenderer(renderer)) {
return -1;
}
if (data->renderer->LockTexture(data->renderer, data->texture,
rect, 1, &data->surface.pixels,
&data->surface.pitch) < 0) {
@ -797,9 +811,13 @@ static void
SW_RenderPresent(SDL_Renderer * renderer)
{
SW_RenderData *data = (SW_RenderData *) renderer->driverdata;
SDL_Texture *texture = data->texture;
SDL_Texture *texture = SW_ActivateRenderer(renderer);
SDL_Rect rect;
if (!texture) {
return;
}
/* Send the data to the display */
rect.x = 0;
rect.y = 0;

View file

@ -24,6 +24,7 @@
#ifndef _SDL_sysvideo_h
#define _SDL_sysvideo_h
#include "SDL_events.h"
#include "SDL_mouse.h"
#include "SDL_keysym.h"
#include "SDL_render.h"
@ -31,7 +32,6 @@
/* The SDL video driver */
typedef struct SDL_Renderer SDL_Renderer;
typedef struct SDL_RenderDriver SDL_RenderDriver;
typedef struct SDL_WindowShaper SDL_WindowShaper;
typedef struct SDL_ShapeDriver SDL_ShapeDriver;
@ -61,8 +61,9 @@ struct SDL_Texture
/* Define the SDL renderer structure */
struct SDL_Renderer
{
int (*ActivateRenderer) (SDL_Renderer * renderer);
int (*DisplayModeChanged) (SDL_Renderer * renderer);
const void *magic;
void (*WindowEvent) (SDL_Renderer * renderer, const SDL_WindowEvent *event);
int (*CreateTexture) (SDL_Renderer * renderer, SDL_Texture * texture);
int (*QueryTexturePixels) (SDL_Renderer * renderer, SDL_Texture * texture,
void **pixels, int *pitch);
@ -168,7 +169,6 @@ struct SDL_Window
Uint32 flags;
SDL_VideoDisplay *display;
SDL_Renderer *renderer;
SDL_DisplayMode fullscreen_mode;
@ -208,8 +208,6 @@ struct SDL_VideoDisplay
SDL_Window *windows;
SDL_Window *fullscreen_window;
SDL_Renderer *current_renderer;
SDL_VideoDevice *device;
void *driverdata;
@ -344,6 +342,7 @@ struct SDL_VideoDevice
SDL_VideoDisplay *displays;
int current_display;
Uint8 window_magic;
Uint8 renderer_magic;
Uint8 texture_magic;
Uint32 next_object_id;
char * clipboard_text;
@ -439,7 +438,6 @@ extern VideoBootStrap Android_bootstrap;
#endif
#define SDL_CurrentDisplay (&_this->displays[_this->current_display])
#define SDL_CurrentRenderer (SDL_CurrentDisplay->current_renderer)
extern SDL_VideoDevice *SDL_GetVideoDevice(void);
extern int SDL_AddBasicVideoDisplay(const SDL_DisplayMode * desktop_mode);
@ -461,7 +459,6 @@ extern int SDL_RecreateWindow(SDL_Window * window, Uint32 flags);
extern void SDL_OnWindowShown(SDL_Window * window);
extern void SDL_OnWindowHidden(SDL_Window * window);
extern void SDL_OnWindowResized(SDL_Window * window);
extern void SDL_OnWindowMinimized(SDL_Window * window);
extern void SDL_OnWindowRestored(SDL_Window * window);
extern void SDL_OnWindowFocusGained(SDL_Window * window);

View file

@ -109,6 +109,12 @@ static SDL_VideoDevice *_this = NULL;
return retval; \
}
#define CHECK_RENDERER_MAGIC(renderer, retval) \
if (!renderer || renderer->magic != &_this->renderer_magic) { \
SDL_SetError("Invalid renderer"); \
return retval; \
}
#define CHECK_TEXTURE_MAGIC(texture, retval) \
if (!_this) { \
SDL_UninitializedVideo(); \
@ -1023,33 +1029,6 @@ SDL_RecreateWindow(SDL_Window * window, Uint32 flags)
return 0;
}
static __inline__ SDL_Renderer *
SDL_GetCurrentRenderer(SDL_bool create)
{
if (!_this) {
SDL_UninitializedVideo();
return NULL;
}
if (!SDL_CurrentRenderer) {
SDL_Window *window = NULL;
if (!create) {
SDL_SetError("Use SDL_CreateRenderer() to create a renderer");
return NULL;
}
/* Get the first window on the first display */
if (_this->num_displays > 0) {
window = _this->displays[0].windows;
}
if (SDL_CreateRenderer(window, -1, 0) < 0) {
return NULL;
}
}
return SDL_CurrentRenderer;
}
Uint32
SDL_GetWindowID(SDL_Window * window)
{
@ -1184,7 +1163,7 @@ SDL_SetWindowSize(SDL_Window * window, int w, int h)
if (_this->SetWindowSize) {
_this->SetWindowSize(_this, window);
}
SDL_OnWindowResized(window);
SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, w, h);
}
void
@ -1366,16 +1345,6 @@ SDL_OnWindowHidden(SDL_Window * window)
SDL_UpdateFullscreenMode(window, SDL_FALSE);
}
void
SDL_OnWindowResized(SDL_Window * window)
{
SDL_Renderer *renderer = window->renderer;
if (renderer && renderer->DisplayModeChanged) {
renderer->DisplayModeChanged(renderer);
}
}
void
SDL_OnWindowMinimized(SDL_Window * window)
{
@ -1451,9 +1420,6 @@ SDL_DestroyWindow(SDL_Window * window)
if (window->title) {
SDL_free(window->title);
}
if (window->renderer) {
SDL_DestroyRenderer(window);
}
/* Restore video mode, etc. */
SDL_UpdateFullscreenMode(window, SDL_FALSE);
@ -1523,13 +1489,26 @@ SDL_GetRenderDriverInfo(int index, SDL_RendererInfo * info)
return 0;
}
int
static int
SDL_RendererEventWatch(void *userdata, SDL_Event *event)
{
SDL_Renderer *renderer = (SDL_Renderer *)userdata;
if (event->type == SDL_WINDOWEVENT && renderer->WindowEvent) {
SDL_Window *window = SDL_GetWindowFromID(event->window.windowID);
if (window == renderer->window) {
renderer->WindowEvent(renderer, &event->window);
}
}
return 0;
}
SDL_Renderer *
SDL_CreateRenderer(SDL_Window * window, int index, Uint32 flags)
{
CHECK_WINDOW_MAGIC(window, -1);
SDL_Renderer *renderer = NULL;
/* Free any existing renderer */
SDL_DestroyRenderer(window);
CHECK_WINDOW_MAGIC(window, NULL);
if (index < 0) {
char *override = SDL_getenv("SDL_VIDEO_RENDERER");
@ -1552,7 +1531,7 @@ SDL_CreateRenderer(SDL_Window * window, int index, Uint32 flags)
if (SDL_strcasecmp(override, driver->info.name) == 0) {
/* Create a new renderer instance */
window->renderer = driver->CreateRenderer(window, flags);
renderer = driver->CreateRenderer(window, flags);
break;
}
}
@ -1563,8 +1542,8 @@ SDL_CreateRenderer(SDL_Window * window, int index, Uint32 flags)
if ((driver->info.flags & flags) == flags) {
/* Create a new renderer instance */
window->renderer = driver->CreateRenderer(window, flags);
if (window->renderer) {
renderer = driver->CreateRenderer(window, flags);
if (renderer) {
/* Yay, we got one! */
break;
}
@ -1573,74 +1552,42 @@ SDL_CreateRenderer(SDL_Window * window, int index, Uint32 flags)
}
if (index == n) {
SDL_SetError("Couldn't find matching render driver");
return -1;
return NULL;
}
} else {
if (index >= SDL_GetNumRenderDrivers()) {
SDL_SetError("index must be -1 or in the range of 0 - %d",
SDL_GetNumRenderDrivers() - 1);
return -1;
return NULL;
}
/* Create a new renderer instance */
window->renderer = SDL_CurrentDisplay->render_drivers[index].CreateRenderer(window, flags);
renderer = SDL_CurrentDisplay->render_drivers[index].CreateRenderer(window, flags);
}
if (window->renderer == NULL) {
/* Assuming renderer set its error */
return -1;
if (renderer) {
renderer->magic = &_this->renderer_magic;
SDL_AddEventWatch(SDL_RendererEventWatch, renderer);
}
SDL_SelectRenderer(window);
return 0;
return renderer;
}
int
SDL_SelectRenderer(SDL_Window * window)
SDL_GetRendererInfo(SDL_Renderer * renderer, SDL_RendererInfo * info)
{
SDL_Renderer *renderer;
CHECK_RENDERER_MAGIC(renderer, -1);
CHECK_WINDOW_MAGIC(window, -1);
renderer = window->renderer;
if (!renderer) {
SDL_SetError("Use SDL_CreateRenderer() to create a renderer");
return -1;
}
if (renderer->ActivateRenderer) {
if (renderer->ActivateRenderer(renderer) < 0) {
return -1;
}
}
SDL_CurrentDisplay->current_renderer = renderer;
return 0;
}
int
SDL_GetRendererInfo(SDL_RendererInfo * info)
{
SDL_Renderer *renderer = SDL_GetCurrentRenderer(SDL_FALSE);
if (!renderer) {
return -1;
}
*info = renderer->info;
return 0;
}
SDL_Texture *
SDL_CreateTexture(Uint32 format, int access, int w, int h)
SDL_CreateTexture(SDL_Renderer * renderer, Uint32 format, int access, int w, int h)
{
SDL_Renderer *renderer;
SDL_Texture *texture;
renderer = SDL_GetCurrentRenderer(SDL_TRUE);
if (!renderer) {
return 0;
}
if (!renderer->CreateTexture) {
SDL_Unsupported();
return 0;
}
CHECK_RENDERER_MAGIC(renderer, NULL);
if (w <= 0 || h <= 0) {
SDL_SetError("Texture dimensions can't be 0");
return 0;
@ -1674,26 +1621,22 @@ SDL_CreateTexture(Uint32 format, int access, int w, int h)
}
SDL_Texture *
SDL_CreateTextureFromSurface(Uint32 format, SDL_Surface * surface)
SDL_CreateTextureFromSurface(SDL_Renderer * renderer, Uint32 format, SDL_Surface * surface)
{
SDL_Texture *texture;
Uint32 requested_format = format;
SDL_PixelFormat *fmt;
SDL_Renderer *renderer;
int bpp;
Uint32 Rmask, Gmask, Bmask, Amask;
CHECK_RENDERER_MAGIC(renderer, NULL);
if (!surface) {
SDL_SetError("SDL_CreateTextureFromSurface() passed NULL surface");
return 0;
return NULL;
}
fmt = surface->format;
renderer = SDL_GetCurrentRenderer(SDL_TRUE);
if (!renderer) {
return 0;
}
if (format) {
if (!SDL_PixelFormatEnumToMasks
(format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) {
@ -1902,15 +1845,14 @@ SDL_CreateTextureFromSurface(Uint32 format, SDL_Surface * surface)
}
texture =
SDL_CreateTexture(format, SDL_TEXTUREACCESS_STATIC, surface->w,
surface->h);
SDL_CreateTexture(renderer, format, SDL_TEXTUREACCESS_STATIC,
surface->w, surface->h);
if (!texture && !requested_format) {
SDL_DisplayMode desktop_mode;
SDL_GetDesktopDisplayMode(&desktop_mode);
format = desktop_mode.format;
texture =
SDL_CreateTexture(format, SDL_TEXTUREACCESS_STATIC, surface->w,
surface->h);
texture = SDL_CreateTexture(renderer, format, SDL_TEXTUREACCESS_STATIC,
surface->w, surface->h);
}
if (!texture) {
return 0;
@ -2246,14 +2188,11 @@ SDL_DirtyTexture(SDL_Texture * texture, int numrects,
}
int
SDL_SetRenderDrawColor(Uint8 r, Uint8 g, Uint8 b, Uint8 a)
SDL_SetRenderDrawColor(SDL_Renderer * renderer,
Uint8 r, Uint8 g, Uint8 b, Uint8 a)
{
SDL_Renderer *renderer;
CHECK_RENDERER_MAGIC(renderer, -1);
renderer = SDL_GetCurrentRenderer(SDL_TRUE);
if (!renderer) {
return -1;
}
renderer->r = r;
renderer->g = g;
renderer->b = b;
@ -2262,14 +2201,11 @@ SDL_SetRenderDrawColor(Uint8 r, Uint8 g, Uint8 b, Uint8 a)
}
int
SDL_GetRenderDrawColor(Uint8 * r, Uint8 * g, Uint8 * b, Uint8 * a)
SDL_GetRenderDrawColor(SDL_Renderer * renderer,
Uint8 * r, Uint8 * g, Uint8 * b, Uint8 * a)
{
SDL_Renderer *renderer;
CHECK_RENDERER_MAGIC(renderer, -1);
renderer = SDL_GetCurrentRenderer(SDL_TRUE);
if (!renderer) {
return -1;
}
if (r) {
*r = renderer->r;
}
@ -2286,52 +2222,40 @@ SDL_GetRenderDrawColor(Uint8 * r, Uint8 * g, Uint8 * b, Uint8 * a)
}
int
SDL_SetRenderDrawBlendMode(SDL_BlendMode blendMode)
SDL_SetRenderDrawBlendMode(SDL_Renderer * renderer, SDL_BlendMode blendMode)
{
SDL_Renderer *renderer;
CHECK_RENDERER_MAGIC(renderer, -1);
renderer = SDL_GetCurrentRenderer(SDL_TRUE);
if (!renderer) {
return -1;
}
renderer->blendMode = blendMode;
return 0;
}
int
SDL_GetRenderDrawBlendMode(SDL_BlendMode *blendMode)
SDL_GetRenderDrawBlendMode(SDL_Renderer * renderer, SDL_BlendMode *blendMode)
{
SDL_Renderer *renderer;
CHECK_RENDERER_MAGIC(renderer, -1);
renderer = SDL_GetCurrentRenderer(SDL_TRUE);
if (!renderer) {
return -1;
}
*blendMode = renderer->blendMode;
return 0;
}
int
SDL_RenderClear()
SDL_RenderClear(SDL_Renderer * renderer)
{
SDL_Renderer *renderer;
CHECK_RENDERER_MAGIC(renderer, -1);
renderer = SDL_GetCurrentRenderer(SDL_TRUE);
if (!renderer) {
return -1;
}
if (!renderer->RenderClear) {
SDL_BlendMode blendMode = renderer->blendMode;
int status;
if (blendMode >= SDL_BLENDMODE_BLEND) {
SDL_SetRenderDrawBlendMode(SDL_BLENDMODE_NONE);
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_NONE);
}
status = SDL_RenderFillRect(NULL);
status = SDL_RenderFillRect(renderer, NULL);
if (blendMode >= SDL_BLENDMODE_BLEND) {
SDL_SetRenderDrawBlendMode(blendMode);
SDL_SetRenderDrawBlendMode(renderer, blendMode);
}
return status;
}
@ -2339,33 +2263,25 @@ SDL_RenderClear()
}
int
SDL_RenderDrawPoint(int x, int y)
SDL_RenderDrawPoint(SDL_Renderer * renderer, int x, int y)
{
SDL_Point point;
point.x = x;
point.y = y;
return SDL_RenderDrawPoints(&point, 1);
return SDL_RenderDrawPoints(renderer, &point, 1);
}
int
SDL_RenderDrawPoints(const SDL_Point * points, int count)
SDL_RenderDrawPoints(SDL_Renderer * renderer,
const SDL_Point * points, int count)
{
SDL_Renderer *renderer;
CHECK_RENDERER_MAGIC(renderer, -1);
if (!points) {
SDL_SetError("SDL_RenderDrawPoints(): Passed NULL points");
return -1;
}
renderer = SDL_GetCurrentRenderer(SDL_TRUE);
if (!renderer) {
return -1;
}
if (!renderer->RenderDrawPoints) {
SDL_Unsupported();
return -1;
}
if (count < 1) {
return 0;
}
@ -2373,7 +2289,7 @@ SDL_RenderDrawPoints(const SDL_Point * points, int count)
}
int
SDL_RenderDrawLine(int x1, int y1, int x2, int y2)
SDL_RenderDrawLine(SDL_Renderer * renderer, int x1, int y1, int x2, int y2)
{
SDL_Point points[2];
@ -2381,27 +2297,19 @@ SDL_RenderDrawLine(int x1, int y1, int x2, int y2)
points[0].y = y1;
points[1].x = x2;
points[1].y = y2;
return SDL_RenderDrawLines(points, 2);
return SDL_RenderDrawLines(renderer, points, 2);
}
int
SDL_RenderDrawLines(const SDL_Point * points, int count)
SDL_RenderDrawLines(SDL_Renderer * renderer,
const SDL_Point * points, int count)
{
SDL_Renderer *renderer;
CHECK_RENDERER_MAGIC(renderer, -1);
if (!points) {
SDL_SetError("SDL_RenderDrawLines(): Passed NULL points");
return -1;
}
renderer = SDL_GetCurrentRenderer(SDL_TRUE);
if (!renderer) {
return -1;
}
if (!renderer->RenderDrawLines) {
SDL_Unsupported();
return -1;
}
if (count < 2) {
return 0;
}
@ -2409,33 +2317,27 @@ SDL_RenderDrawLines(const SDL_Point * points, int count)
}
int
SDL_RenderDrawRect(const SDL_Rect * rect)
SDL_RenderDrawRect(SDL_Renderer * renderer, const SDL_Rect * rect)
{
return SDL_RenderDrawRects(&rect, 1);
return SDL_RenderDrawRects(renderer, &rect, 1);
}
int
SDL_RenderDrawRects(const SDL_Rect ** rects, int count)
SDL_RenderDrawRects(SDL_Renderer * renderer,
const SDL_Rect ** rects, int count)
{
SDL_Renderer *renderer;
int i;
CHECK_RENDERER_MAGIC(renderer, -1);
if (!rects) {
SDL_SetError("SDL_RenderDrawRects(): Passed NULL rects");
return -1;
}
renderer = SDL_GetCurrentRenderer(SDL_TRUE);
if (!renderer) {
return -1;
}
if (!renderer->RenderDrawRects) {
SDL_Unsupported();
return -1;
}
if (count < 1) {
return 0;
}
/* Check for NULL rect, which means fill entire window */
for (i = 0; i < count; ++i) {
if (rects[i] == NULL) {
@ -2455,33 +2357,27 @@ SDL_RenderDrawRects(const SDL_Rect ** rects, int count)
}
int
SDL_RenderFillRect(const SDL_Rect * rect)
SDL_RenderFillRect(SDL_Renderer * renderer, const SDL_Rect * rect)
{
return SDL_RenderFillRects(&rect, 1);
return SDL_RenderFillRects(renderer, &rect, 1);
}
int
SDL_RenderFillRects(const SDL_Rect ** rects, int count)
SDL_RenderFillRects(SDL_Renderer * renderer,
const SDL_Rect ** rects, int count)
{
SDL_Renderer *renderer;
int i;
CHECK_RENDERER_MAGIC(renderer, -1);
if (!rects) {
SDL_SetError("SDL_RenderFillRects(): Passed NULL rects");
return -1;
}
renderer = SDL_GetCurrentRenderer(SDL_TRUE);
if (!renderer) {
return -1;
}
if (!renderer->RenderFillRects) {
SDL_Unsupported();
return -1;
}
if (count < 1) {
return 0;
}
/* Check for NULL rect, which means fill entire window */
for (i = 0; i < count; ++i) {
if (rects[i] == NULL) {
@ -2501,28 +2397,20 @@ SDL_RenderFillRects(const SDL_Rect ** rects, int count)
}
int
SDL_RenderCopy(SDL_Texture * texture, const SDL_Rect * srcrect,
const SDL_Rect * dstrect)
SDL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
const SDL_Rect * srcrect, const SDL_Rect * dstrect)
{
SDL_Renderer *renderer;
SDL_Window *window;
SDL_Rect real_srcrect;
SDL_Rect real_dstrect;
CHECK_RENDERER_MAGIC(renderer, -1);
CHECK_TEXTURE_MAGIC(texture, -1);
renderer = SDL_GetCurrentRenderer(SDL_TRUE);
if (!renderer) {
return -1;
}
if (texture->renderer != renderer) {
if (renderer != texture->renderer) {
SDL_SetError("Texture was not created with this renderer");
return -1;
}
if (!renderer->RenderCopy) {
SDL_Unsupported();
return -1;
}
window = renderer->window;
real_srcrect.x = 0;
@ -2563,17 +2451,14 @@ SDL_RenderCopy(SDL_Texture * texture, const SDL_Rect * srcrect,
}
int
SDL_RenderReadPixels(const SDL_Rect * rect, Uint32 format,
void * pixels, int pitch)
SDL_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
Uint32 format, void * pixels, int pitch)
{
SDL_Renderer *renderer;
SDL_Window *window;
SDL_Rect real_rect;
renderer = SDL_GetCurrentRenderer(SDL_TRUE);
if (!renderer) {
return -1;
}
CHECK_RENDERER_MAGIC(renderer, -1);
if (!renderer->RenderReadPixels) {
SDL_Unsupported();
return -1;
@ -2607,17 +2492,14 @@ SDL_RenderReadPixels(const SDL_Rect * rect, Uint32 format,
}
int
SDL_RenderWritePixels(const SDL_Rect * rect, Uint32 format,
const void * pixels, int pitch)
SDL_RenderWritePixels(SDL_Renderer * renderer, const SDL_Rect * rect,
Uint32 format, const void * pixels, int pitch)
{
SDL_Renderer *renderer;
SDL_Window *window;
SDL_Rect real_rect;
renderer = SDL_GetCurrentRenderer(SDL_TRUE);
if (!renderer) {
return -1;
}
CHECK_RENDERER_MAGIC(renderer, -1);
if (!renderer->RenderWritePixels) {
SDL_Unsupported();
return -1;
@ -2651,14 +2533,10 @@ SDL_RenderWritePixels(const SDL_Rect * rect, Uint32 format,
}
void
SDL_RenderPresent(void)
SDL_RenderPresent(SDL_Renderer * renderer)
{
SDL_Renderer *renderer;
CHECK_RENDERER_MAGIC(renderer, );
renderer = SDL_GetCurrentRenderer(SDL_TRUE);
if (!renderer || !renderer->RenderPresent) {
return;
}
#if SDL_VIDEO_DRIVER_WINDOWS
IME_Present((SDL_VideoData *)_this->driverdata);
#endif
@ -2688,30 +2566,22 @@ SDL_DestroyTexture(SDL_Texture * texture)
}
void
SDL_DestroyRenderer(SDL_Window * window)
SDL_DestroyRenderer(SDL_Renderer * renderer)
{
SDL_Renderer *renderer;
CHECK_RENDERER_MAGIC(renderer, );
CHECK_WINDOW_MAGIC(window, );
renderer = window->renderer;
if (!renderer) {
return;
}
SDL_DelEventWatch(SDL_RendererEventWatch, renderer);
/* Free existing textures for this renderer */
while (renderer->textures) {
SDL_DestroyTexture(renderer->textures);
}
/* It's no longer magical... */
renderer->magic = NULL;
/* Free the renderer instance */
renderer->DestroyRenderer(renderer);
/* Clear references */
window->renderer = NULL;
if (SDL_CurrentDisplay->current_renderer == renderer) {
SDL_CurrentDisplay->current_renderer = NULL;
}
}
SDL_bool