Fixed bug 1622 - SDL_RenderSetViewport with empty SDL_Rect raises wrong error for OpenGL rendering backend
It's now legal to set an empty viewport rect - it will prevent any rendering.
Also added an API to query the output size: SDL_GetRendererOutputSize()
--- a/include/SDL_render.h Mon May 27 21:44:16 2013 -0700
+++ b/include/SDL_render.h Wed May 29 03:07:55 2013 -0700
@@ -212,6 +212,12 @@
SDL_RendererInfo * info);
/**
+ * \brief Get the output size of a rendering context.
+ */
+extern DECLSPEC int SDLCALL SDL_GetRendererOutputSize(SDL_Renderer * renderer,
+ int *w, int *h);
+
+/**
* \brief Create a texture for a rendering context.
*
* \param renderer The renderer.
--- a/src/render/SDL_render.c Mon May 27 21:44:16 2013 -0700
+++ b/src/render/SDL_render.c Wed May 29 03:07:55 2013 -0700
@@ -337,6 +337,25 @@
return 0;
}
+int
+SDL_GetRendererOutputSize(SDL_Renderer * renderer, int *w, int *h)
+{
+ CHECK_RENDERER_MAGIC(renderer, -1);
+
+ if (renderer->target) {
+ return SDL_QueryTexture(renderer->target, NULL, NULL, w, h);
+ } else if (renderer->window) {
+ SDL_GetWindowSize(renderer->window, w, h);
+ return 0;
+ } else if (renderer->GetOutputSize) {
+ return renderer->GetOutputSize(renderer, w, h);
+ } else {
+ /* This should never happen */
+ SDL_SetError("Renderer doesn't support querying output size");
+ return -1;
+ }
+}
+
static SDL_bool
IsSupportedFormat(SDL_Renderer * renderer, Uint32 format)
{
@@ -985,13 +1004,8 @@
float scale;
SDL_Rect viewport;
- if (renderer->target) {
- SDL_QueryTexture(renderer->target, NULL, NULL, &w, &h);
- } else if (renderer->window) {
- SDL_GetWindowSize(renderer->window, &w, &h);
- } else {
- /* FIXME */
- return SDL_SetError("Internal error: No way to get output resolution");
+ if (SDL_GetRendererOutputSize(renderer, &w, &h) < 0) {
+ return -1;
}
want_aspect = (float)renderer->logical_w / renderer->logical_h;
@@ -1074,16 +1088,8 @@
} else {
renderer->viewport.x = 0;
renderer->viewport.y = 0;
- if (renderer->target) {
- SDL_QueryTexture(renderer->target, NULL, NULL,
- &renderer->viewport.w, &renderer->viewport.h);
- } else if (renderer->window) {
- SDL_GetWindowSize(renderer->window,
- &renderer->viewport.w, &renderer->viewport.h);
- } else {
- /* This will be filled in by UpdateViewport() */
- renderer->viewport.w = 0;
- renderer->viewport.h = 0;
+ if (SDL_GetRendererOutputSize(renderer, &renderer->viewport.w, &renderer->viewport.h) < 0) {
+ return -1;
}
}
return renderer->UpdateViewport(renderer);
--- a/src/render/SDL_sysrender.h Mon May 27 21:44:16 2013 -0700
+++ b/src/render/SDL_sysrender.h Wed May 29 03:07:55 2013 -0700
@@ -78,6 +78,7 @@
const void *magic;
void (*WindowEvent) (SDL_Renderer * renderer, const SDL_WindowEvent *event);
+ int (*GetOutputSize) (SDL_Renderer * renderer, int *w, int *h);
int (*CreateTexture) (SDL_Renderer * renderer, SDL_Texture * texture);
int (*SetTextureColorMod) (SDL_Renderer * renderer,
SDL_Texture * texture);
--- a/src/render/direct3d/SDL_render_d3d.c Mon May 27 21:44:16 2013 -0700
+++ b/src/render/direct3d/SDL_render_d3d.c Wed May 29 03:07:55 2013 -0700
@@ -866,23 +866,25 @@
IDirect3DDevice9_SetViewport(data->device, &viewport);
/* Set an orthographic projection matrix */
- matrix.m[0][0] = 2.0f / renderer->viewport.w;
- matrix.m[0][1] = 0.0f;
- matrix.m[0][2] = 0.0f;
- matrix.m[0][3] = 0.0f;
- matrix.m[1][0] = 0.0f;
- matrix.m[1][1] = -2.0f / renderer->viewport.h;
- matrix.m[1][2] = 0.0f;
- matrix.m[1][3] = 0.0f;
- matrix.m[2][0] = 0.0f;
- matrix.m[2][1] = 0.0f;
- matrix.m[2][2] = 1.0f;
- matrix.m[2][3] = 0.0f;
- matrix.m[3][0] = -1.0f;
- matrix.m[3][1] = 1.0f;
- matrix.m[3][2] = 0.0f;
- matrix.m[3][3] = 1.0f;
- IDirect3DDevice9_SetTransform(data->device, D3DTS_PROJECTION, &matrix);
+ if (renderer->viewport.w && renderer->viewport.h) {
+ matrix.m[0][0] = 2.0f / renderer->viewport.w;
+ matrix.m[0][1] = 0.0f;
+ matrix.m[0][2] = 0.0f;
+ matrix.m[0][3] = 0.0f;
+ matrix.m[1][0] = 0.0f;
+ matrix.m[1][1] = -2.0f / renderer->viewport.h;
+ matrix.m[1][2] = 0.0f;
+ matrix.m[1][3] = 0.0f;
+ matrix.m[2][0] = 0.0f;
+ matrix.m[2][1] = 0.0f;
+ matrix.m[2][2] = 1.0f;
+ matrix.m[2][3] = 0.0f;
+ matrix.m[3][0] = -1.0f;
+ matrix.m[3][1] = 1.0f;
+ matrix.m[3][2] = 0.0f;
+ matrix.m[3][3] = 1.0f;
+ IDirect3DDevice9_SetTransform(data->device, D3DTS_PROJECTION, &matrix);
+ }
return 0;
}
--- a/src/render/opengl/SDL_render_gl.c Mon May 27 21:44:16 2013 -0700
+++ b/src/render/opengl/SDL_render_gl.c Wed May 29 03:07:55 2013 -0700
@@ -849,28 +849,25 @@
return 0;
}
- if (!renderer->viewport.w || !renderer->viewport.h) {
- /* The viewport isn't set up yet, ignore it */
- return -1;
- }
-
data->glViewport(renderer->viewport.x, renderer->viewport.y,
renderer->viewport.w, renderer->viewport.h);
data->glMatrixMode(GL_PROJECTION);
data->glLoadIdentity();
- if (renderer->target) {
- data->glOrtho((GLdouble) 0,
- (GLdouble) renderer->viewport.w,
- (GLdouble) 0,
- (GLdouble) renderer->viewport.h,
- 0.0, 1.0);
- } else {
- data->glOrtho((GLdouble) 0,
- (GLdouble) renderer->viewport.w,
- (GLdouble) renderer->viewport.h,
- (GLdouble) 0,
- 0.0, 1.0);
+ if (renderer->viewport.w && renderer->viewport.h) {
+ if (renderer->target) {
+ data->glOrtho((GLdouble) 0,
+ (GLdouble) renderer->viewport.w,
+ (GLdouble) 0,
+ (GLdouble) renderer->viewport.h,
+ 0.0, 1.0);
+ } else {
+ data->glOrtho((GLdouble) 0,
+ (GLdouble) renderer->viewport.w,
+ (GLdouble) renderer->viewport.h,
+ (GLdouble) 0,
+ 0.0, 1.0);
+ }
}
return GL_CheckError("", renderer);
}
--- a/src/render/opengles/SDL_render_gles.c Mon May 27 21:44:16 2013 -0700
+++ b/src/render/opengles/SDL_render_gles.c Wed May 29 03:07:55 2013 -0700
@@ -623,12 +623,14 @@
data->glViewport(renderer->viewport.x, renderer->viewport.y,
renderer->viewport.w, renderer->viewport.h);
- data->glMatrixMode(GL_PROJECTION);
- data->glLoadIdentity();
- data->glOrthof((GLfloat) 0,
- (GLfloat) renderer->viewport.w,
- (GLfloat) renderer->viewport.h,
- (GLfloat) 0, 0.0, 1.0);
+ if (renderer->viewport.w && renderer->viewport.h) {
+ data->glMatrixMode(GL_PROJECTION);
+ data->glLoadIdentity();
+ data->glOrthof((GLfloat) 0,
+ (GLfloat) renderer->viewport.w,
+ (GLfloat) renderer->viewport.h,
+ (GLfloat) 0, 0.0, 1.0);
+ }
return 0;
}
--- a/src/render/opengles2/SDL_render_gles2.c Mon May 27 21:44:16 2013 -0700
+++ b/src/render/opengles2/SDL_render_gles2.c Wed May 29 03:07:55 2013 -0700
@@ -906,6 +906,10 @@
GLfloat projection[4][4];
GLuint locProjection;
+ if (!renderer->viewport.w || !renderer->viewport.h) {
+ return 0;
+ }
+
/* Prepare an orthographic projection */
projection[0][0] = 2.0f / renderer->viewport.w;
projection[0][1] = 0.0f;
--- a/src/render/software/SDL_render_sw.c Mon May 27 21:44:16 2013 -0700
+++ b/src/render/software/SDL_render_sw.c Wed May 29 03:07:55 2013 -0700
@@ -39,6 +39,7 @@
static SDL_Renderer *SW_CreateRenderer(SDL_Window * window, Uint32 flags);
static void SW_WindowEvent(SDL_Renderer * renderer,
const SDL_WindowEvent *event);
+static int SW_GetOutputSize(SDL_Renderer * renderer, int *w, int *h);
static int SW_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture);
static int SW_SetTextureColorMod(SDL_Renderer * renderer,
SDL_Texture * texture);
@@ -110,9 +111,14 @@
data->surface = data->window;
}
if (!data->surface) {
- data->surface = data->window = SDL_GetWindowSurface(renderer->window);
+ SDL_Surface *surface = SDL_GetWindowSurface(renderer->window);
+ if (surface) {
+ data->surface = data->window = surface;
+ renderer->viewport.w = surface->w;
+ renderer->viewport.h = surface->h;
- SW_UpdateViewport(renderer);
+ SW_UpdateViewport(renderer);
+ }
}
return data->surface;
}
@@ -143,6 +149,7 @@
data->surface = surface;
renderer->WindowEvent = SW_WindowEvent;
+ renderer->GetOutputSize = SW_GetOutputSize;
renderer->CreateTexture = SW_CreateTexture;
renderer->SetTextureColorMod = SW_SetTextureColorMod;
renderer->SetTextureAlphaMod = SW_SetTextureAlphaMod;
@@ -195,6 +202,25 @@
}
static int
+SW_GetOutputSize(SDL_Renderer * renderer, int *w, int *h)
+{
+ SDL_Surface *surface = SW_ActivateRenderer(renderer);
+
+ if (surface) {
+ if (w) {
+ *w = surface->w;
+ }
+ if (h) {
+ *h = surface->h;
+ }
+ return 0;
+ } else {
+ SDL_SetError("Software renderer doesn't have an output surface");
+ return -1;
+ }
+}
+
+static int
SW_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
{
int bpp;
@@ -313,11 +339,6 @@
return 0;
}
- if (!renderer->viewport.w && !renderer->viewport.h) {
- /* There may be no window, so update the viewport directly */
- renderer->viewport.w = surface->w;
- renderer->viewport.h = surface->h;
- }
SDL_SetClipRect(data->surface, &renderer->viewport);
return 0;
}