SDL_render.c
Go to the documentation of this file.
/*
Simple DirectMedia Layer
Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../SDL_internal.h"
/* The SDL 2D rendering system */
#include "SDL_assert.h"
#include "SDL_hints.h"
#include "SDL_log.h"
#include "SDL_render.h"
#include "SDL_sysrender.h"
#include "software/SDL_render_sw_c.h"
#define SDL_WINDOWRENDERDATA "_SDL_WindowRenderData"
#define CHECK_RENDERER_MAGIC(renderer, retval) \
if (!renderer || renderer->magic != &renderer_magic) { \
SDL_SetError("Invalid renderer"); \
return retval; \
}
#define CHECK_TEXTURE_MAGIC(texture, retval) \
if (!texture || texture->magic != &texture_magic) { \
SDL_SetError("Invalid texture"); \
return retval; \
}
#if !SDL_RENDER_DISABLED
static const SDL_RenderDriver *render_drivers[] = {
#if SDL_VIDEO_RENDER_D3D
&D3D_RenderDriver,
#endif
#if SDL_VIDEO_RENDER_D3D11
&D3D11_RenderDriver,
#endif
#if SDL_VIDEO_RENDER_OGL
&GL_RenderDriver,
#endif
#if SDL_VIDEO_RENDER_OGL_ES2
&GLES2_RenderDriver,
#endif
#if SDL_VIDEO_RENDER_OGL_ES
&GLES_RenderDriver,
#endif
#if SDL_VIDEO_RENDER_DIRECTFB
&DirectFB_RenderDriver,
#endif
#if SDL_VIDEO_RENDER_PSP
&PSP_RenderDriver,
#endif
&SW_RenderDriver
};
#endif /* !SDL_RENDER_DISABLED */
static char renderer_magic;
static char texture_magic;
static int UpdateLogicalSize(SDL_Renderer *renderer);
int
SDL_GetNumRenderDrivers(void)
{
#if !SDL_RENDER_DISABLED
return SDL_arraysize(render_drivers);
#else
return 0;
#endif
}
int
SDL_GetRenderDriverInfo(int index, SDL_RendererInfo * info)
{
#if !SDL_RENDER_DISABLED
if (index < 0 || index >= SDL_GetNumRenderDrivers()) {
return SDL_SetError("index must be in the range of 0 - %d",
SDL_GetNumRenderDrivers() - 1);
}
*info = render_drivers[index]->info;
return 0;
#else
return SDL_SetError("SDL not built with rendering support");
#endif
}
static int
SDL_RendererEventWatch(void *userdata, SDL_Event *event)
{
SDL_Renderer *renderer = (SDL_Renderer *)userdata;
if (event->type == SDL_WINDOWEVENT) {
SDL_Window *window = SDL_GetWindowFromID(event->window.windowID);
if (window == renderer->window) {
if (renderer->WindowEvent) {
renderer->WindowEvent(renderer, &event->window);
}
if (event->window.event == SDL_WINDOWEVENT_SIZE_CHANGED) {
/* Make sure we're operating on the default render target */
SDL_Texture *saved_target = SDL_GetRenderTarget(renderer);
if (saved_target) {
SDL_SetRenderTarget(renderer, NULL);
}
if (renderer->logical_w) {
UpdateLogicalSize(renderer);
} else {
/* Window was resized, reset viewport */
int w, h;
if (renderer->GetOutputSize) {
renderer->GetOutputSize(renderer, &w, &h);
} else {
SDL_GetWindowSize(renderer->window, &w, &h);
}
if (renderer->target) {
renderer->viewport_backup.x = 0;
renderer->viewport_backup.y = 0;
renderer->viewport_backup.w = w;
renderer->viewport_backup.h = h;
} else {
renderer->viewport.x = 0;
renderer->viewport.y = 0;
renderer->viewport.w = w;
renderer->viewport.h = h;
renderer->UpdateViewport(renderer);
}
}
if (saved_target) {
SDL_SetRenderTarget(renderer, saved_target);
}
} else if (event->window.event == SDL_WINDOWEVENT_HIDDEN) {
renderer->hidden = SDL_TRUE;
} else if (event->window.event == SDL_WINDOWEVENT_SHOWN) {
if (!(SDL_GetWindowFlags(window) & SDL_WINDOW_MINIMIZED)) {
renderer->hidden = SDL_FALSE;
}
} else if (event->window.event == SDL_WINDOWEVENT_MINIMIZED) {
renderer->hidden = SDL_TRUE;
} else if (event->window.event == SDL_WINDOWEVENT_RESTORED ||
event->window.event == SDL_WINDOWEVENT_MAXIMIZED) {
if (!(SDL_GetWindowFlags(window) & SDL_WINDOW_HIDDEN)) {
renderer->hidden = SDL_FALSE;
}
}
}
} else if (event->type == SDL_MOUSEMOTION) {
SDL_Window *window = SDL_GetWindowFromID(event->motion.windowID);
if (renderer->logical_w && window == renderer->window) {
event->motion.x -= renderer->viewport.x;
event->motion.y -= renderer->viewport.y;
event->motion.x = (int)(event->motion.x / renderer->scale.x);
event->motion.y = (int)(event->motion.y / renderer->scale.y);
if (event->motion.xrel > 0) {
event->motion.xrel = SDL_max(1, (int)(event->motion.xrel / renderer->scale.x));
} else if (event->motion.xrel < 0) {
event->motion.xrel = SDL_min(-1, (int)(event->motion.xrel / renderer->scale.x));
}
if (event->motion.yrel > 0) {
event->motion.yrel = SDL_max(1, (int)(event->motion.yrel / renderer->scale.y));
} else if (event->motion.yrel < 0) {
event->motion.yrel = SDL_min(-1, (int)(event->motion.yrel / renderer->scale.y));
}
}
} else if (event->type == SDL_MOUSEBUTTONDOWN ||
event->type == SDL_MOUSEBUTTONUP) {
SDL_Window *window = SDL_GetWindowFromID(event->button.windowID);
if (renderer->logical_w && window == renderer->window) {
event->button.x -= renderer->viewport.x;
event->button.y -= renderer->viewport.y;
event->button.x = (int)(event->button.x / renderer->scale.x);
event->button.y = (int)(event->button.y / renderer->scale.y);
}
}
return 0;
}
int
SDL_CreateWindowAndRenderer(int width, int height, Uint32 window_flags,
SDL_Window **window, SDL_Renderer **renderer)
{
*window = SDL_CreateWindow(NULL, SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
width, height, window_flags);
if (!*window) {
*renderer = NULL;
return -1;
}
*renderer = SDL_CreateRenderer(*window, -1, 0);
if (!*renderer) {
return -1;
}
return 0;
}
SDL_Renderer *
SDL_CreateRenderer(SDL_Window * window, int index, Uint32 flags)
{
#if !SDL_RENDER_DISABLED
SDL_Renderer *renderer = NULL;
int n = SDL_GetNumRenderDrivers();
const char *hint;
if (!window) {
SDL_SetError("Invalid window");
return NULL;
}
if (SDL_GetRenderer(window)) {
SDL_SetError("Renderer already associated with window");
return NULL;
}
hint = SDL_GetHint(SDL_HINT_RENDER_VSYNC);
if (hint) {
if (*hint == '0') {
flags &= ~SDL_RENDERER_PRESENTVSYNC;
} else {
flags |= SDL_RENDERER_PRESENTVSYNC;
}
}
if (index < 0) {
hint = SDL_GetHint(SDL_HINT_RENDER_DRIVER);
if (hint) {
for (index = 0; index < n; ++index) {
const SDL_RenderDriver *driver = render_drivers[index];
if (SDL_strcasecmp(hint, driver->info.name) == 0) {
/* Create a new renderer instance */
renderer = driver->CreateRenderer(window, flags);
break;
}
}
}
if (!renderer) {
for (index = 0; index < n; ++index) {
const SDL_RenderDriver *driver = render_drivers[index];
if ((driver->info.flags & flags) == flags) {
/* Create a new renderer instance */
renderer = driver->CreateRenderer(window, flags);
if (renderer) {
/* Yay, we got one! */
break;
}
}
}
}
if (index == n) {
SDL_SetError("Couldn't find matching render driver");
return NULL;
}
} else {
if (index >= SDL_GetNumRenderDrivers()) {
SDL_SetError("index must be -1 or in the range of 0 - %d",
SDL_GetNumRenderDrivers() - 1);
return NULL;
}
/* Create a new renderer instance */
renderer = render_drivers[index]->CreateRenderer(window, flags);
}
if (renderer) {
renderer->magic = &renderer_magic;
renderer->window = window;
renderer->scale.x = 1.0f;
renderer->scale.y = 1.0f;
if (SDL_GetWindowFlags(window) & (SDL_WINDOW_HIDDEN|SDL_WINDOW_MINIMIZED)) {
renderer->hidden = SDL_TRUE;
} else {
renderer->hidden = SDL_FALSE;
}
SDL_SetWindowData(window, SDL_WINDOWRENDERDATA, renderer);
SDL_RenderSetViewport(renderer, NULL);
SDL_AddEventWatch(SDL_RendererEventWatch, renderer);
SDL_LogInfo(SDL_LOG_CATEGORY_RENDER,
"Created renderer: %s", renderer->info.name);
}
return renderer;
#else
SDL_SetError("SDL not built with rendering support");
return NULL;
#endif
}
SDL_Renderer *
SDL_CreateSoftwareRenderer(SDL_Surface * surface)
{
#if !SDL_RENDER_DISABLED
SDL_Renderer *renderer;
renderer = SW_CreateRendererForSurface(surface);
if (renderer) {
renderer->magic = &renderer_magic;
renderer->scale.x = 1.0f;
renderer->scale.y = 1.0f;
SDL_RenderSetViewport(renderer, NULL);
}
return renderer;
#else
SDL_SetError("SDL not built with rendering support");
return NULL;
#endif /* !SDL_RENDER_DISABLED */
}
SDL_Renderer *
SDL_GetRenderer(SDL_Window * window)
{
return (SDL_Renderer *)SDL_GetWindowData(window, SDL_WINDOWRENDERDATA);
}
int
SDL_GetRendererInfo(SDL_Renderer * renderer, SDL_RendererInfo * info)
{
CHECK_RENDERER_MAGIC(renderer, -1);
*info = renderer->info;
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->GetOutputSize) {
return renderer->GetOutputSize(renderer, w, h);
} else if (renderer->window) {
SDL_GetWindowSize(renderer->window, w, h);
return 0;
} else {
SDL_assert(0 && "This should never happen");
return SDL_SetError("Renderer doesn't support querying output size");
}
}
static SDL_bool
IsSupportedFormat(SDL_Renderer * renderer, Uint32 format)
{
Uint32 i;
for (i = 0; i < renderer->info.num_texture_formats; ++i) {
if (renderer->info.texture_formats[i] == format) {
return SDL_TRUE;
}
}
return SDL_FALSE;
}
static Uint32
GetClosestSupportedFormat(SDL_Renderer * renderer, Uint32 format)
{
Uint32 i;
if (SDL_ISPIXELFORMAT_FOURCC(format)) {
/* Look for an exact match */
for (i = 0; i < renderer->info.num_texture_formats; ++i) {
if (renderer->info.texture_formats[i] == format) {
return renderer->info.texture_formats[i];
}
}
} else {
SDL_bool hasAlpha = SDL_ISPIXELFORMAT_ALPHA(format);
/* We just want to match the first format that has the same channels */
for (i = 0; i < renderer->info.num_texture_formats; ++i) {
if (!SDL_ISPIXELFORMAT_FOURCC(renderer->info.texture_formats[i]) &&
SDL_ISPIXELFORMAT_ALPHA(renderer->info.texture_formats[i]) == hasAlpha) {
return renderer->info.texture_formats[i];
}
}
}
return renderer->info.texture_formats[0];
}
SDL_Texture *
SDL_CreateTexture(SDL_Renderer * renderer, Uint32 format, int access, int w, int h)
{
SDL_Texture *texture;
CHECK_RENDERER_MAGIC(renderer, NULL);
if (!format) {
format = renderer->info.texture_formats[0];
}
if (SDL_BYTESPERPIXEL(format) == 0) {
SDL_SetError("Invalid texture format");
return NULL;
}
if (SDL_ISPIXELFORMAT_INDEXED(format)) {
SDL_SetError("Palettized textures are not supported");
return NULL;
}
if (w <= 0 || h <= 0) {
SDL_SetError("Texture dimensions can't be 0");
return NULL;
}
if ((renderer->info.max_texture_width && w > renderer->info.max_texture_width) ||
(renderer->info.max_texture_height && h > renderer->info.max_texture_height)) {
SDL_SetError("Texture dimensions are limited to %dx%d", renderer->info.max_texture_width, renderer->info.max_texture_height);
return NULL;
}
texture = (SDL_Texture *) SDL_calloc(1, sizeof(*texture));
if (!texture) {
SDL_OutOfMemory();
return NULL;
}
texture->magic = &texture_magic;
texture->format = format;
texture->access = access;
texture->w = w;
texture->h = h;
texture->r = 255;
texture->g = 255;
texture->b = 255;
texture->a = 255;
texture->renderer = renderer;
texture->next = renderer->textures;
if (renderer->textures) {
renderer->textures->prev = texture;
}
renderer->textures = texture;
if (IsSupportedFormat(renderer, format)) {
if (renderer->CreateTexture(renderer, texture) < 0) {
SDL_DestroyTexture(texture);
return NULL;
}
} else {
texture->native = SDL_CreateTexture(renderer,
GetClosestSupportedFormat(renderer, format),
access, w, h);
if (!texture->native) {
SDL_DestroyTexture(texture);
return NULL;
}
/* Swap textures to have texture before texture->native in the list */
texture->native->next = texture->next;
if (texture->native->next) {
texture->native->next->prev = texture->native;
}
texture->prev = texture->native->prev;
if (texture->prev) {
texture->prev->next = texture;
}
texture->native->prev = texture;
texture->next = texture->native;
renderer->textures = texture;
if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
texture->yuv = SDL_SW_CreateYUVTexture(format, w, h);
if (!texture->yuv) {
SDL_DestroyTexture(texture);
return NULL;
}
} else if (access == SDL_TEXTUREACCESS_STREAMING) {
/* The pitch is 4 byte aligned */
texture->pitch = (((w * SDL_BYTESPERPIXEL(format)) + 3) & ~3);
texture->pixels = SDL_calloc(1, texture->pitch * h);
if (!texture->pixels) {
SDL_DestroyTexture(texture);
return NULL;
}
}
}
return texture;
}
SDL_Texture *
SDL_CreateTextureFromSurface(SDL_Renderer * renderer, SDL_Surface * surface)
{
const SDL_PixelFormat *fmt;
SDL_bool needAlpha;
Uint32 i;
Uint32 format;
SDL_Texture *texture;
CHECK_RENDERER_MAGIC(renderer, NULL);
if (!surface) {
SDL_SetError("SDL_CreateTextureFromSurface() passed NULL surface");
return NULL;
}
/* See what the best texture format is */
fmt = surface->format;
if (fmt->Amask || SDL_GetColorKey(surface, NULL) == 0) {
needAlpha = SDL_TRUE;
} else {
needAlpha = SDL_FALSE;
}
format = renderer->info.texture_formats[0];
for (i = 0; i < renderer->info.num_texture_formats; ++i) {
if (!SDL_ISPIXELFORMAT_FOURCC(renderer->info.texture_formats[i]) &&
SDL_ISPIXELFORMAT_ALPHA(renderer->info.texture_formats[i]) == needAlpha) {
format = renderer->info.texture_formats[i];
break;
}
}
texture = SDL_CreateTexture(renderer, format, SDL_TEXTUREACCESS_STATIC,
surface->w, surface->h);
if (!texture) {
return NULL;
}
if (format == surface->format->format) {
if (SDL_MUSTLOCK(surface)) {
SDL_LockSurface(surface);
SDL_UpdateTexture(texture, NULL, surface->pixels, surface->pitch);
SDL_UnlockSurface(surface);
} else {
SDL_UpdateTexture(texture, NULL, surface->pixels, surface->pitch);
}
} else {
SDL_PixelFormat *dst_fmt;
SDL_Surface *temp = NULL;
/* Set up a destination surface for the texture update */
dst_fmt = SDL_AllocFormat(format);
if (!dst_fmt) {
SDL_DestroyTexture(texture);
return NULL;
}
temp = SDL_ConvertSurface(surface, dst_fmt, 0);
SDL_FreeFormat(dst_fmt);
if (temp) {
SDL_UpdateTexture(texture, NULL, temp->pixels, temp->pitch);
SDL_FreeSurface(temp);
} else {
SDL_DestroyTexture(texture);
return NULL;
}
}
{
Uint8 r, g, b, a;
SDL_BlendMode blendMode;
SDL_GetSurfaceColorMod(surface, &r, &g, &b);
SDL_SetTextureColorMod(texture, r, g, b);
SDL_GetSurfaceAlphaMod(surface, &a);
SDL_SetTextureAlphaMod(texture, a);
if (SDL_GetColorKey(surface, NULL) == 0) {
/* We converted to a texture with alpha format */
SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND);
} else {
SDL_GetSurfaceBlendMode(surface, &blendMode);
SDL_SetTextureBlendMode(texture, blendMode);
}
}
return texture;
}
int
SDL_QueryTexture(SDL_Texture * texture, Uint32 * format, int *access,
int *w, int *h)
{
CHECK_TEXTURE_MAGIC(texture, -1);
if (format) {
*format = texture->format;
}
if (access) {
*access = texture->access;
}
if (w) {
*w = texture->w;
}
if (h) {
*h = texture->h;
}
return 0;
}
int
SDL_SetTextureColorMod(SDL_Texture * texture, Uint8 r, Uint8 g, Uint8 b)
{
SDL_Renderer *renderer;
CHECK_TEXTURE_MAGIC(texture, -1);
renderer = texture->renderer;
if (r < 255 || g < 255 || b < 255) {
texture->modMode |= SDL_TEXTUREMODULATE_COLOR;
} else {
texture->modMode &= ~SDL_TEXTUREMODULATE_COLOR;
}
texture->r = r;
texture->g = g;
texture->b = b;
if (texture->native) {
return SDL_SetTextureColorMod(texture->native, r, g, b);
} else if (renderer->SetTextureColorMod) {
return renderer->SetTextureColorMod(renderer, texture);
} else {
return 0;
}
}
int
SDL_GetTextureColorMod(SDL_Texture * texture, Uint8 * r, Uint8 * g,
Uint8 * b)
{
CHECK_TEXTURE_MAGIC(texture, -1);
if (r) {
*r = texture->r;
}
if (g) {
*g = texture->g;
}
if (b) {
*b = texture->b;
}
return 0;
}
int
SDL_SetTextureAlphaMod(SDL_Texture * texture, Uint8 alpha)
{
SDL_Renderer *renderer;
CHECK_TEXTURE_MAGIC(texture, -1);
renderer = texture->renderer;
if (alpha < 255) {
texture->modMode |= SDL_TEXTUREMODULATE_ALPHA;
} else {
texture->modMode &= ~SDL_TEXTUREMODULATE_ALPHA;
}
texture->a = alpha;
if (texture->native) {
return SDL_SetTextureAlphaMod(texture->native, alpha);
} else if (renderer->SetTextureAlphaMod) {
return renderer->SetTextureAlphaMod(renderer, texture);
} else {
return 0;
}
}
int
SDL_GetTextureAlphaMod(SDL_Texture * texture, Uint8 * alpha)
{
CHECK_TEXTURE_MAGIC(texture, -1);
if (alpha) {
*alpha = texture->a;
}
return 0;
}
int
SDL_SetTextureBlendMode(SDL_Texture * texture, SDL_BlendMode blendMode)
{
SDL_Renderer *renderer;
CHECK_TEXTURE_MAGIC(texture, -1);
renderer = texture->renderer;
texture->blendMode = blendMode;
if (texture->native) {
return SDL_SetTextureBlendMode(texture->native, blendMode);
} else if (renderer->SetTextureBlendMode) {
return renderer->SetTextureBlendMode(renderer, texture);
} else {
return 0;
}
}
int
SDL_GetTextureBlendMode(SDL_Texture * texture, SDL_BlendMode *blendMode)
{
CHECK_TEXTURE_MAGIC(texture, -1);
if (blendMode) {
*blendMode = texture->blendMode;
}
return 0;
}
static int
SDL_UpdateTextureYUV(SDL_Texture * texture, const SDL_Rect * rect,
const void *pixels, int pitch)
{
SDL_Texture *native = texture->native;
SDL_Rect full_rect;
if (SDL_SW_UpdateYUVTexture(texture->yuv, rect, pixels, pitch) < 0) {
return -1;
}
full_rect.x = 0;
full_rect.y = 0;
full_rect.w = texture->w;
full_rect.h = texture->h;
rect = &full_rect;
if (texture->access == SDL_TEXTUREACCESS_STREAMING) {
/* We can lock the texture and copy to it */
void *native_pixels;
int native_pitch;
if (SDL_LockTexture(native, rect, &native_pixels, &native_pitch) < 0) {
return -1;
}
SDL_SW_CopyYUVToRGB(texture->yuv, rect, native->format,
rect->w, rect->h, native_pixels, native_pitch);
SDL_UnlockTexture(native);
} else {
/* Use a temporary buffer for updating */
void *temp_pixels;
int temp_pitch;
temp_pitch = (((rect->w * SDL_BYTESPERPIXEL(native->format)) + 3) & ~3);
temp_pixels = SDL_malloc(rect->h * temp_pitch);
if (!temp_pixels) {
return SDL_OutOfMemory();
}
SDL_SW_CopyYUVToRGB(texture->yuv, rect, native->format,
rect->w, rect->h, temp_pixels, temp_pitch);
SDL_UpdateTexture(native, rect, temp_pixels, temp_pitch);
SDL_free(temp_pixels);
}
return 0;
}
static int
SDL_UpdateTextureNative(SDL_Texture * texture, const SDL_Rect * rect,
const void *pixels, int pitch)
{
SDL_Texture *native = texture->native;
if (texture->access == SDL_TEXTUREACCESS_STREAMING) {
/* We can lock the texture and copy to it */
void *native_pixels;
int native_pitch;
if (SDL_LockTexture(native, rect, &native_pixels, &native_pitch) < 0) {
return -1;
}
SDL_ConvertPixels(rect->w, rect->h,
texture->format, pixels, pitch,
native->format, native_pixels, native_pitch);
SDL_UnlockTexture(native);
} else {
/* Use a temporary buffer for updating */
void *temp_pixels;
int temp_pitch;
temp_pitch = (((rect->w * SDL_BYTESPERPIXEL(native->format)) + 3) & ~3);
temp_pixels = SDL_malloc(rect->h * temp_pitch);
if (!temp_pixels) {
return SDL_OutOfMemory();
}
SDL_ConvertPixels(rect->w, rect->h,
texture->format, pixels, pitch,
native->format, temp_pixels, temp_pitch);
SDL_UpdateTexture(native, rect, temp_pixels, temp_pitch);
SDL_free(temp_pixels);
}
return 0;
}
int
SDL_UpdateTexture(SDL_Texture * texture, const SDL_Rect * rect,
const void *pixels, int pitch)
{
SDL_Renderer *renderer;
SDL_Rect full_rect;
CHECK_TEXTURE_MAGIC(texture, -1);
if (!pixels) {
return SDL_InvalidParamError("pixels");
}
if (!pitch) {
return SDL_InvalidParamError("pitch");
}
if (!rect) {
full_rect.x = 0;
full_rect.y = 0;
full_rect.w = texture->w;
full_rect.h = texture->h;
rect = &full_rect;
}
if ((rect->w == 0) || (rect->h == 0)) {
return 0; /* nothing to do. */
} else if (texture->yuv) {
return SDL_UpdateTextureYUV(texture, rect, pixels, pitch);
} else if (texture->native) {
return SDL_UpdateTextureNative(texture, rect, pixels, pitch);
} else {
renderer = texture->renderer;
return renderer->UpdateTexture(renderer, texture, rect, pixels, pitch);
}
}
static int
SDL_UpdateTextureYUVPlanar(SDL_Texture * texture, const SDL_Rect * rect,
const Uint8 *Yplane, int Ypitch,
const Uint8 *Uplane, int Upitch,
const Uint8 *Vplane, int Vpitch)
{
SDL_Texture *native = texture->native;
SDL_Rect full_rect;
if (SDL_SW_UpdateYUVTexturePlanar(texture->yuv, rect, Yplane, Ypitch, Uplane, Upitch, Vplane, Vpitch) < 0) {
return -1;
}
full_rect.x = 0;
full_rect.y = 0;
full_rect.w = texture->w;
full_rect.h = texture->h;
rect = &full_rect;
if (texture->access == SDL_TEXTUREACCESS_STREAMING) {
/* We can lock the texture and copy to it */
void *native_pixels;
int native_pitch;
if (SDL_LockTexture(native, rect, &native_pixels, &native_pitch) < 0) {
return -1;
}
SDL_SW_CopyYUVToRGB(texture->yuv, rect, native->format,
rect->w, rect->h, native_pixels, native_pitch);
SDL_UnlockTexture(native);
} else {
/* Use a temporary buffer for updating */
void *temp_pixels;
int temp_pitch;
temp_pitch = (((rect->w * SDL_BYTESPERPIXEL(native->format)) + 3) & ~3);
temp_pixels = SDL_malloc(rect->h * temp_pitch);
if (!temp_pixels) {
return SDL_OutOfMemory();
}
SDL_SW_CopyYUVToRGB(texture->yuv, rect, native->format,
rect->w, rect->h, temp_pixels, temp_pitch);
SDL_UpdateTexture(native, rect, temp_pixels, temp_pitch);
SDL_free(temp_pixels);
}
return 0;
}
int SDL_UpdateYUVTexture(SDL_Texture * texture, const SDL_Rect * rect,
const Uint8 *Yplane, int Ypitch,
const Uint8 *Uplane, int Upitch,
const Uint8 *Vplane, int Vpitch)
{
SDL_Renderer *renderer;
SDL_Rect full_rect;
CHECK_TEXTURE_MAGIC(texture, -1);
if (!Yplane) {
return SDL_InvalidParamError("Yplane");
}
if (!Ypitch) {
return SDL_InvalidParamError("Ypitch");
}
if (!Uplane) {
return SDL_InvalidParamError("Uplane");
}
if (!Upitch) {
return SDL_InvalidParamError("Upitch");
}
if (!Vplane) {
return SDL_InvalidParamError("Vplane");
}
if (!Vpitch) {
return SDL_InvalidParamError("Vpitch");
}
if (texture->format != SDL_PIXELFORMAT_YV12 &&
texture->format != SDL_PIXELFORMAT_IYUV) {
return SDL_SetError("Texture format must by YV12 or IYUV");
}
if (!rect) {
full_rect.x = 0;
full_rect.y = 0;
full_rect.w = texture->w;
full_rect.h = texture->h;
rect = &full_rect;
}
if (texture->yuv) {
return SDL_UpdateTextureYUVPlanar(texture, rect, Yplane, Ypitch, Uplane, Upitch, Vplane, Vpitch);
} else {
SDL_assert(!texture->native);
renderer = texture->renderer;
SDL_assert(renderer->UpdateTextureYUV);
if (renderer->UpdateTextureYUV) {
return renderer->UpdateTextureYUV(renderer, texture, rect, Yplane, Ypitch, Uplane, Upitch, Vplane, Vpitch);
} else {
return SDL_Unsupported();
}
}
}
static int
SDL_LockTextureYUV(SDL_Texture * texture, const SDL_Rect * rect,
void **pixels, int *pitch)
{
return SDL_SW_LockYUVTexture(texture->yuv, rect, pixels, pitch);
}
static int
SDL_LockTextureNative(SDL_Texture * texture, const SDL_Rect * rect,
void **pixels, int *pitch)
{
texture->locked_rect = *rect;
*pixels = (void *) ((Uint8 *) texture->pixels +
rect->y * texture->pitch +
rect->x * SDL_BYTESPERPIXEL(texture->format));
*pitch = texture->pitch;
return 0;
}
int
SDL_LockTexture(SDL_Texture * texture, const SDL_Rect * rect,
void **pixels, int *pitch)
{
SDL_Renderer *renderer;
SDL_Rect full_rect;
CHECK_TEXTURE_MAGIC(texture, -1);
if (texture->access != SDL_TEXTUREACCESS_STREAMING) {
return SDL_SetError("SDL_LockTexture(): texture must be streaming");
}
if (!rect) {
full_rect.x = 0;
full_rect.y = 0;
full_rect.w = texture->w;
full_rect.h = texture->h;
rect = &full_rect;
}
if (texture->yuv) {
return SDL_LockTextureYUV(texture, rect, pixels, pitch);
} else if (texture->native) {
return SDL_LockTextureNative(texture, rect, pixels, pitch);
} else {
renderer = texture->renderer;
return renderer->LockTexture(renderer, texture, rect, pixels, pitch);
}
}
static void
SDL_UnlockTextureYUV(SDL_Texture * texture)
{
SDL_Texture *native = texture->native;
void *native_pixels = NULL;
int native_pitch = 0;
SDL_Rect rect;
rect.x = 0;
rect.y = 0;
rect.w = texture->w;
rect.h = texture->h;
if (SDL_LockTexture(native, &rect, &native_pixels, &native_pitch) < 0) {
return;
}
SDL_SW_CopyYUVToRGB(texture->yuv, &rect, native->format,
rect.w, rect.h, native_pixels, native_pitch);
SDL_UnlockTexture(native);
}
static void
SDL_UnlockTextureNative(SDL_Texture * texture)
{
SDL_Texture *native = texture->native;
void *native_pixels = NULL;
int native_pitch = 0;
const SDL_Rect *rect = &texture->locked_rect;
const void* pixels = (void *) ((Uint8 *) texture->pixels +
rect->y * texture->pitch +
rect->x * SDL_BYTESPERPIXEL(texture->format));
int pitch = texture->pitch;
if (SDL_LockTexture(native, rect, &native_pixels, &native_pitch) < 0) {
return;
}
SDL_ConvertPixels(rect->w, rect->h,
texture->format, pixels, pitch,
native->format, native_pixels, native_pitch);
SDL_UnlockTexture(native);
}
void
SDL_UnlockTexture(SDL_Texture * texture)
{
SDL_Renderer *renderer;
CHECK_TEXTURE_MAGIC(texture, );
if (texture->access != SDL_TEXTUREACCESS_STREAMING) {
return;
}
if (texture->yuv) {
SDL_UnlockTextureYUV(texture);
} else if (texture->native) {
SDL_UnlockTextureNative(texture);
} else {
renderer = texture->renderer;
renderer->UnlockTexture(renderer, texture);
}
}
SDL_bool
SDL_RenderTargetSupported(SDL_Renderer *renderer)
{
if (!renderer || !renderer->SetRenderTarget) {
return SDL_FALSE;
}
return (renderer->info.flags & SDL_RENDERER_TARGETTEXTURE) != 0;
}
int
SDL_SetRenderTarget(SDL_Renderer *renderer, SDL_Texture *texture)
{
if (!SDL_RenderTargetSupported(renderer)) {
return SDL_Unsupported();
}
if (texture == renderer->target) {
/* Nothing to do! */
return 0;
}
/* texture == NULL is valid and means reset the target to the window */
if (texture) {
CHECK_TEXTURE_MAGIC(texture, -1);
if (renderer != texture->renderer) {
return SDL_SetError("Texture was not created with this renderer");
}
if (texture->access != SDL_TEXTUREACCESS_TARGET) {
return SDL_SetError("Texture not created with SDL_TEXTUREACCESS_TARGET");
}
if (texture->native) {
/* Always render to the native texture */
texture = texture->native;
}
}
if (texture && !renderer->target) {
/* Make a backup of the viewport */
renderer->viewport_backup = renderer->viewport;
renderer->clip_rect_backup = renderer->clip_rect;
renderer->clipping_enabled_backup = renderer->clipping_enabled;
renderer->scale_backup = renderer->scale;
renderer->logical_w_backup = renderer->logical_w;
renderer->logical_h_backup = renderer->logical_h;
}
renderer->target = texture;
if (renderer->SetRenderTarget(renderer, texture) < 0) {
return -1;
}
if (texture) {
renderer->viewport.x = 0;
renderer->viewport.y = 0;
renderer->viewport.w = texture->w;
renderer->viewport.h = texture->h;
renderer->scale.x = 1.0f;
renderer->scale.y = 1.0f;
renderer->logical_w = texture->w;
renderer->logical_h = texture->h;
} else {
renderer->viewport = renderer->viewport_backup;
renderer->clip_rect = renderer->clip_rect_backup;
renderer->clipping_enabled = renderer->clipping_enabled_backup;
renderer->scale = renderer->scale_backup;
renderer->logical_w = renderer->logical_w_backup;
renderer->logical_h = renderer->logical_h_backup;
}
if (renderer->UpdateViewport(renderer) < 0) {
return -1;
}
if (renderer->UpdateClipRect(renderer) < 0) {
return -1;
}
/* All set! */
return 0;
}
SDL_Texture *
SDL_GetRenderTarget(SDL_Renderer *renderer)
{
return renderer->target;
}
static int
UpdateLogicalSize(SDL_Renderer *renderer)
{
int w = 1, h = 1;
float want_aspect;
float real_aspect;
float scale;
SDL_Rect viewport;
if (SDL_GetRendererOutputSize(renderer, &w, &h) < 0) {
return -1;
}
want_aspect = (float)renderer->logical_w / renderer->logical_h;
real_aspect = (float)w / h;
/* Clear the scale because we're setting viewport in output coordinates */
SDL_RenderSetScale(renderer, 1.0f, 1.0f);
if (SDL_fabs(want_aspect-real_aspect) < 0.0001) {
/* The aspect ratios are the same, just scale appropriately */
scale = (float)w / renderer->logical_w;
SDL_RenderSetViewport(renderer, NULL);
} else if (want_aspect > real_aspect) {
/* We want a wider aspect ratio than is available - letterbox it */
scale = (float)w / renderer->logical_w;
viewport.x = 0;
viewport.w = w;
viewport.h = (int)SDL_ceil(renderer->logical_h * scale);
viewport.y = (h - viewport.h) / 2;
SDL_RenderSetViewport(renderer, &viewport);
} else {
/* We want a narrower aspect ratio than is available - use side-bars */
scale = (float)h / renderer->logical_h;
viewport.y = 0;
viewport.h = h;
viewport.w = (int)SDL_ceil(renderer->logical_w * scale);
viewport.x = (w - viewport.w) / 2;
SDL_RenderSetViewport(renderer, &viewport);
}
/* Set the new scale */
SDL_RenderSetScale(renderer, scale, scale);
return 0;
}
int
SDL_RenderSetLogicalSize(SDL_Renderer * renderer, int w, int h)
{
CHECK_RENDERER_MAGIC(renderer, -1);
if (!w || !h) {
/* Clear any previous logical resolution */
renderer->logical_w = 0;
renderer->logical_h = 0;
SDL_RenderSetViewport(renderer, NULL);
SDL_RenderSetScale(renderer, 1.0f, 1.0f);
return 0;
}
renderer->logical_w = w;
renderer->logical_h = h;
return UpdateLogicalSize(renderer);
}
void
SDL_RenderGetLogicalSize(SDL_Renderer * renderer, int *w, int *h)
{
CHECK_RENDERER_MAGIC(renderer, );
if (w) {
*w = renderer->logical_w;
}
if (h) {
*h = renderer->logical_h;
}
}
int
SDL_RenderSetViewport(SDL_Renderer * renderer, const SDL_Rect * rect)
{
CHECK_RENDERER_MAGIC(renderer, -1);
if (rect) {
renderer->viewport.x = (int)SDL_floor(rect->x * renderer->scale.x);
renderer->viewport.y = (int)SDL_floor(rect->y * renderer->scale.y);
renderer->viewport.w = (int)SDL_ceil(rect->w * renderer->scale.x);
renderer->viewport.h = (int)SDL_ceil(rect->h * renderer->scale.y);
} else {
renderer->viewport.x = 0;
renderer->viewport.y = 0;
if (SDL_GetRendererOutputSize(renderer, &renderer->viewport.w, &renderer->viewport.h) < 0) {
return -1;
}
}
return renderer->UpdateViewport(renderer);
}
void
SDL_RenderGetViewport(SDL_Renderer * renderer, SDL_Rect * rect)
{
CHECK_RENDERER_MAGIC(renderer, );
if (rect) {
rect->x = (int)(renderer->viewport.x / renderer->scale.x);
rect->y = (int)(renderer->viewport.y / renderer->scale.y);
rect->w = (int)(renderer->viewport.w / renderer->scale.x);
rect->h = (int)(renderer->viewport.h / renderer->scale.y);
}
}
int
SDL_RenderSetClipRect(SDL_Renderer * renderer, const SDL_Rect * rect)
{
CHECK_RENDERER_MAGIC(renderer, -1)
if (rect) {
renderer->clipping_enabled = SDL_TRUE;
renderer->clip_rect.x = (int)SDL_floor(rect->x * renderer->scale.x);
renderer->clip_rect.y = (int)SDL_floor(rect->y * renderer->scale.y);
renderer->clip_rect.w = (int)SDL_ceil(rect->w * renderer->scale.x);
renderer->clip_rect.h = (int)SDL_ceil(rect->h * renderer->scale.y);
} else {
renderer->clipping_enabled = SDL_FALSE;
SDL_zero(renderer->clip_rect);
}
return renderer->UpdateClipRect(renderer);
}
void
SDL_RenderGetClipRect(SDL_Renderer * renderer, SDL_Rect * rect)
{
CHECK_RENDERER_MAGIC(renderer, )
if (rect) {
rect->x = (int)(renderer->clip_rect.x / renderer->scale.x);
rect->y = (int)(renderer->clip_rect.y / renderer->scale.y);
rect->w = (int)(renderer->clip_rect.w / renderer->scale.x);
rect->h = (int)(renderer->clip_rect.h / renderer->scale.y);
}
}
SDL_bool
SDL_RenderIsClipEnabled(SDL_Renderer * renderer)
{
CHECK_RENDERER_MAGIC(renderer, SDL_FALSE)
return renderer->clipping_enabled;
}
int
SDL_RenderSetScale(SDL_Renderer * renderer, float scaleX, float scaleY)
{
CHECK_RENDERER_MAGIC(renderer, -1);
renderer->scale.x = scaleX;
renderer->scale.y = scaleY;
return 0;
}
void
SDL_RenderGetScale(SDL_Renderer * renderer, float *scaleX, float *scaleY)
{
CHECK_RENDERER_MAGIC(renderer, );
if (scaleX) {
*scaleX = renderer->scale.x;
}
if (scaleY) {
*scaleY = renderer->scale.y;
}
}
int
SDL_SetRenderDrawColor(SDL_Renderer * renderer,
Uint8 r, Uint8 g, Uint8 b, Uint8 a)
{
CHECK_RENDERER_MAGIC(renderer, -1);
renderer->r = r;
renderer->g = g;
renderer->b = b;
renderer->a = a;
return 0;
}
int
SDL_GetRenderDrawColor(SDL_Renderer * renderer,
Uint8 * r, Uint8 * g, Uint8 * b, Uint8 * a)
{
CHECK_RENDERER_MAGIC(renderer, -1);
if (r) {
*r = renderer->r;
}
if (g) {
*g = renderer->g;
}
if (b) {
*b = renderer->b;
}
if (a) {
*a = renderer->a;
}
return 0;
}
int
SDL_SetRenderDrawBlendMode(SDL_Renderer * renderer, SDL_BlendMode blendMode)
{
CHECK_RENDERER_MAGIC(renderer, -1);
renderer->blendMode = blendMode;
return 0;
}
int
SDL_GetRenderDrawBlendMode(SDL_Renderer * renderer, SDL_BlendMode *blendMode)
{
CHECK_RENDERER_MAGIC(renderer, -1);
*blendMode = renderer->blendMode;
return 0;
}
int
SDL_RenderClear(SDL_Renderer * renderer)
{
CHECK_RENDERER_MAGIC(renderer, -1);
/* Don't draw while we're hidden */
if (renderer->hidden) {
return 0;
}
return renderer->RenderClear(renderer);
}
int
SDL_RenderDrawPoint(SDL_Renderer * renderer, int x, int y)
{
SDL_Point point;
point.x = x;
point.y = y;
return SDL_RenderDrawPoints(renderer, &point, 1);
}
static int
RenderDrawPointsWithRects(SDL_Renderer * renderer,
const SDL_Point * points, int count)
{
SDL_FRect *frects;
int i;
int status;
frects = SDL_stack_alloc(SDL_FRect, count);
if (!frects) {
return SDL_OutOfMemory();
}
for (i = 0; i < count; ++i) {
frects[i].x = points[i].x * renderer->scale.x;
frects[i].y = points[i].y * renderer->scale.y;
frects[i].w = renderer->scale.x;
frects[i].h = renderer->scale.y;
}
status = renderer->RenderFillRects(renderer, frects, count);
SDL_stack_free(frects);
return status;
}
int
SDL_RenderDrawPoints(SDL_Renderer * renderer,
const SDL_Point * points, int count)
{
SDL_FPoint *fpoints;
int i;
int status;
CHECK_RENDERER_MAGIC(renderer, -1);
if (!points) {
return SDL_SetError("SDL_RenderDrawPoints(): Passed NULL points");
}
if (count < 1) {
return 0;
}
/* Don't draw while we're hidden */
if (renderer->hidden) {
return 0;
}
if (renderer->scale.x != 1.0f || renderer->scale.y != 1.0f) {
return RenderDrawPointsWithRects(renderer, points, count);
}
fpoints = SDL_stack_alloc(SDL_FPoint, count);
if (!fpoints) {
return SDL_OutOfMemory();
}
for (i = 0; i < count; ++i) {
fpoints[i].x = points[i].x * renderer->scale.x;
fpoints[i].y = points[i].y * renderer->scale.y;
}
status = renderer->RenderDrawPoints(renderer, fpoints, count);
SDL_stack_free(fpoints);
return status;
}
int
SDL_RenderDrawLine(SDL_Renderer * renderer, int x1, int y1, int x2, int y2)
{
SDL_Point points[2];
points[0].x = x1;
points[0].y = y1;
points[1].x = x2;
points[1].y = y2;
return SDL_RenderDrawLines(renderer, points, 2);
}
static int
RenderDrawLinesWithRects(SDL_Renderer * renderer,
const SDL_Point * points, int count)
{
SDL_FRect *frect;
SDL_FRect *frects;
SDL_FPoint fpoints[2];
int i, nrects;
int status;
frects = SDL_stack_alloc(SDL_FRect, count-1);
if (!frects) {
return SDL_OutOfMemory();
}
status = 0;
nrects = 0;
for (i = 0; i < count-1; ++i) {
if (points[i].x == points[i+1].x) {
int minY = SDL_min(points[i].y, points[i+1].y);
int maxY = SDL_max(points[i].y, points[i+1].y);
frect = &frects[nrects++];
frect->x = points[i].x * renderer->scale.x;
frect->y = minY * renderer->scale.y;
frect->w = renderer->scale.x;
frect->h = (maxY - minY + 1) * renderer->scale.y;
} else if (points[i].y == points[i+1].y) {
int minX = SDL_min(points[i].x, points[i+1].x);
int maxX = SDL_max(points[i].x, points[i+1].x);
frect = &frects[nrects++];
frect->x = minX * renderer->scale.x;
frect->y = points[i].y * renderer->scale.y;
frect->w = (maxX - minX + 1) * renderer->scale.x;
frect->h = renderer->scale.y;
} else {
/* FIXME: We can't use a rect for this line... */
fpoints[0].x = points[i].x * renderer->scale.x;
fpoints[0].y = points[i].y * renderer->scale.y;
fpoints[1].x = points[i+1].x * renderer->scale.x;
fpoints[1].y = points[i+1].y * renderer->scale.y;
status += renderer->RenderDrawLines(renderer, fpoints, 2);
}
}
status += renderer->RenderFillRects(renderer, frects, nrects);
SDL_stack_free(frects);
if (status < 0) {
status = -1;
}
return status;
}
int
SDL_RenderDrawLines(SDL_Renderer * renderer,
const SDL_Point * points, int count)
{
SDL_FPoint *fpoints;
int i;
int status;
CHECK_RENDERER_MAGIC(renderer, -1);
if (!points) {
return SDL_SetError("SDL_RenderDrawLines(): Passed NULL points");
}
if (count < 2) {
return 0;
}
/* Don't draw while we're hidden */
if (renderer->hidden) {
return 0;
}
if (renderer->scale.x != 1.0f || renderer->scale.y != 1.0f) {
return RenderDrawLinesWithRects(renderer, points, count);
}
fpoints = SDL_stack_alloc(SDL_FPoint, count);
if (!fpoints) {
return SDL_OutOfMemory();
}
for (i = 0; i < count; ++i) {
fpoints[i].x = points[i].x * renderer->scale.x;
fpoints[i].y = points[i].y * renderer->scale.y;
}
status = renderer->RenderDrawLines(renderer, fpoints, count);
SDL_stack_free(fpoints);
return status;
}
int
SDL_RenderDrawRect(SDL_Renderer * renderer, const SDL_Rect * rect)
{
SDL_Rect full_rect;
SDL_Point points[5];
CHECK_RENDERER_MAGIC(renderer, -1);
/* If 'rect' == NULL, then outline the whole surface */
if (!rect) {
SDL_RenderGetViewport(renderer, &full_rect);
full_rect.x = 0;
full_rect.y = 0;
rect = &full_rect;
}
points[0].x = rect->x;
points[0].y = rect->y;
points[1].x = rect->x+rect->w-1;
points[1].y = rect->y;
points[2].x = rect->x+rect->w-1;
points[2].y = rect->y+rect->h-1;
points[3].x = rect->x;
points[3].y = rect->y+rect->h-1;
points[4].x = rect->x;
points[4].y = rect->y;
return SDL_RenderDrawLines(renderer, points, 5);
}
int
SDL_RenderDrawRects(SDL_Renderer * renderer,
const SDL_Rect * rects, int count)
{
int i;
CHECK_RENDERER_MAGIC(renderer, -1);
if (!rects) {
return SDL_SetError("SDL_RenderDrawRects(): Passed NULL rects");
}
if (count < 1) {
return 0;
}
/* Don't draw while we're hidden */
if (renderer->hidden) {
return 0;
}
for (i = 0; i < count; ++i) {
if (SDL_RenderDrawRect(renderer, &rects[i]) < 0) {
return -1;
}
}
return 0;
}
int
SDL_RenderFillRect(SDL_Renderer * renderer, const SDL_Rect * rect)
{
SDL_Rect full_rect = { 0, 0, 0, 0 };
CHECK_RENDERER_MAGIC(renderer, -1);
/* If 'rect' == NULL, then outline the whole surface */
if (!rect) {
SDL_RenderGetViewport(renderer, &full_rect);
full_rect.x = 0;
full_rect.y = 0;
rect = &full_rect;
}
return SDL_RenderFillRects(renderer, rect, 1);
}
int
SDL_RenderFillRects(SDL_Renderer * renderer,
const SDL_Rect * rects, int count)
{
SDL_FRect *frects;
int i;
int status;
CHECK_RENDERER_MAGIC(renderer, -1);
if (!rects) {
return SDL_SetError("SDL_RenderFillRects(): Passed NULL rects");
}
if (count < 1) {
return 0;
}
/* Don't draw while we're hidden */
if (renderer->hidden) {
return 0;
}
frects = SDL_stack_alloc(SDL_FRect, count);
if (!frects) {
return SDL_OutOfMemory();
}
for (i = 0; i < count; ++i) {
frects[i].x = rects[i].x * renderer->scale.x;
frects[i].y = rects[i].y * renderer->scale.y;
frects[i].w = rects[i].w * renderer->scale.x;
frects[i].h = rects[i].h * renderer->scale.y;
}
status = renderer->RenderFillRects(renderer, frects, count);
SDL_stack_free(frects);
return status;
}
int
SDL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
const SDL_Rect * srcrect, const SDL_Rect * dstrect)
{
SDL_Rect real_srcrect = { 0, 0, 0, 0 };
SDL_Rect real_dstrect = { 0, 0, 0, 0 };
SDL_FRect frect;
CHECK_RENDERER_MAGIC(renderer, -1);
CHECK_TEXTURE_MAGIC(texture, -1);
if (renderer != texture->renderer) {
return SDL_SetError("Texture was not created with this renderer");
}
real_srcrect.x = 0;
real_srcrect.y = 0;
real_srcrect.w = texture->w;
real_srcrect.h = texture->h;
if (srcrect) {
if (!SDL_IntersectRect(srcrect, &real_srcrect, &real_srcrect)) {
return 0;
}
}
SDL_RenderGetViewport(renderer, &real_dstrect);
real_dstrect.x = 0;
real_dstrect.y = 0;
if (dstrect) {
if (!SDL_HasIntersection(dstrect, &real_dstrect)) {
return 0;
}
real_dstrect = *dstrect;
}
if (texture->native) {
texture = texture->native;
}
/* Don't draw while we're hidden */
if (renderer->hidden) {
return 0;
}
frect.x = real_dstrect.x * renderer->scale.x;
frect.y = real_dstrect.y * renderer->scale.y;
frect.w = real_dstrect.w * renderer->scale.x;
frect.h = real_dstrect.h * renderer->scale.y;
return renderer->RenderCopy(renderer, texture, &real_srcrect, &frect);
}
int
SDL_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture,
const SDL_Rect * srcrect, const SDL_Rect * dstrect,
const double angle, const SDL_Point *center, const SDL_RendererFlip flip)
{
SDL_Rect real_srcrect = { 0, 0, 0, 0 };
SDL_Rect real_dstrect = { 0, 0, 0, 0 };
SDL_Point real_center;
SDL_FRect frect;
SDL_FPoint fcenter;
if (flip == SDL_FLIP_NONE && angle == 0) { /* fast path when we don't need rotation or flipping */
return SDL_RenderCopy(renderer, texture, srcrect, dstrect);
}
CHECK_RENDERER_MAGIC(renderer, -1);
CHECK_TEXTURE_MAGIC(texture, -1);
if (renderer != texture->renderer) {
return SDL_SetError("Texture was not created with this renderer");
}
if (!renderer->RenderCopyEx) {
return SDL_SetError("Renderer does not support RenderCopyEx");
}
real_srcrect.x = 0;
real_srcrect.y = 0;
real_srcrect.w = texture->w;
real_srcrect.h = texture->h;
if (srcrect) {
if (!SDL_IntersectRect(srcrect, &real_srcrect, &real_srcrect)) {
return 0;
}
}
/* We don't intersect the dstrect with the viewport as RenderCopy does because of potential rotation clipping issues... TODO: should we? */
if (dstrect) {
real_dstrect = *dstrect;
} else {
SDL_RenderGetViewport(renderer, &real_dstrect);
real_dstrect.x = 0;
real_dstrect.y = 0;
}
if (texture->native) {
texture = texture->native;
}
if(center) real_center = *center;
else {
real_center.x = real_dstrect.w/2;
real_center.y = real_dstrect.h/2;
}
frect.x = real_dstrect.x * renderer->scale.x;
frect.y = real_dstrect.y * renderer->scale.y;
frect.w = real_dstrect.w * renderer->scale.x;
frect.h = real_dstrect.h * renderer->scale.y;
fcenter.x = real_center.x * renderer->scale.x;
fcenter.y = real_center.y * renderer->scale.y;
return renderer->RenderCopyEx(renderer, texture, &real_srcrect, &frect, angle, &fcenter, flip);
}
int
SDL_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
Uint32 format, void * pixels, int pitch)
{
SDL_Rect real_rect;
CHECK_RENDERER_MAGIC(renderer, -1);
if (!renderer->RenderReadPixels) {
return SDL_Unsupported();
}
if (!format) {
format = SDL_GetWindowPixelFormat(renderer->window);
}
real_rect.x = renderer->viewport.x;
real_rect.y = renderer->viewport.y;
real_rect.w = renderer->viewport.w;
real_rect.h = renderer->viewport.h;
if (rect) {
if (!SDL_IntersectRect(rect, &real_rect, &real_rect)) {
return 0;
}
if (real_rect.y > rect->y) {
pixels = (Uint8 *)pixels + pitch * (real_rect.y - rect->y);
}
if (real_rect.x > rect->x) {
int bpp = SDL_BYTESPERPIXEL(format);
pixels = (Uint8 *)pixels + bpp * (real_rect.x - rect->x);
}
}
return renderer->RenderReadPixels(renderer, &real_rect,
format, pixels, pitch);
}
void
SDL_RenderPresent(SDL_Renderer * renderer)
{
CHECK_RENDERER_MAGIC(renderer, );
/* Don't draw while we're hidden */
if (renderer->hidden) {
return;
}
renderer->RenderPresent(renderer);
}
void
SDL_DestroyTexture(SDL_Texture * texture)
{
SDL_Renderer *renderer;
CHECK_TEXTURE_MAGIC(texture, );
renderer = texture->renderer;
if (texture == renderer->target) {
SDL_SetRenderTarget(renderer, NULL);
}
texture->magic = NULL;
if (texture->next) {
texture->next->prev = texture->prev;
}
if (texture->prev) {
texture->prev->next = texture->next;
} else {
renderer->textures = texture->next;
}
if (texture->native) {
SDL_DestroyTexture(texture->native);
}
if (texture->yuv) {
SDL_SW_DestroyYUVTexture(texture->yuv);
}
SDL_free(texture->pixels);
renderer->DestroyTexture(renderer, texture);
SDL_free(texture);
}
void
SDL_DestroyRenderer(SDL_Renderer * renderer)
{
CHECK_RENDERER_MAGIC(renderer, );
SDL_DelEventWatch(SDL_RendererEventWatch, renderer);
/* Free existing textures for this renderer */
while (renderer->textures) {
SDL_DestroyTexture(renderer->textures);
}
if (renderer->window) {
SDL_SetWindowData(renderer->window, SDL_WINDOWRENDERDATA, NULL);
}
/* It's no longer magical... */
renderer->magic = NULL;
/* Free the renderer instance */
renderer->DestroyRenderer(renderer);
}
int SDL_GL_BindTexture(SDL_Texture *texture, float *texw, float *texh)
{
SDL_Renderer *renderer;
CHECK_TEXTURE_MAGIC(texture, -1);
renderer = texture->renderer;
if (texture->native) {
return SDL_GL_BindTexture(texture->native, texw, texh);
} else if (renderer && renderer->GL_BindTexture) {
return renderer->GL_BindTexture(renderer, texture, texw, texh);
} else {
return SDL_Unsupported();
}
}
int SDL_GL_UnbindTexture(SDL_Texture *texture)
{
SDL_Renderer *renderer;
CHECK_TEXTURE_MAGIC(texture, -1);
renderer = texture->renderer;
if (texture->native) {
return SDL_GL_UnbindTexture(texture->native);
} else if (renderer && renderer->GL_UnbindTexture) {
return renderer->GL_UnbindTexture(renderer, texture);
}
return SDL_Unsupported();
}
/* vi: set ts=4 sw=4 expandtab: */
SDL_CreateWindowAndRenderer
int SDL_CreateWindowAndRenderer(int width, int height, Uint32 window_flags, SDL_Window **window, SDL_Renderer **renderer)
Create a window and default renderer.
Definition: SDL_render.c:200
SDL_Renderer::RenderDrawLines
int(* RenderDrawLines)(SDL_Renderer *renderer, const SDL_FPoint *points, int count)
Definition: SDL_sysrender.h:106
SDL_Texture::pixels
void * pixels
Definition: SDL_sysrender.h:65
scale
GLenum GLenum GLenum GLenum GLenum scale
Definition: SDL_opengl_glext.h:9375
SDL_Texture::blendMode
SDL_BlendMode blendMode
Definition: SDL_sysrender.h:57
SDL_Event::motion
SDL_MouseMotionEvent motion
Definition: SDL_events.h:529
SDL_FRect::w
float w
Definition: SDL_sysrender.h:44
SDL_DelEventWatch
#define SDL_DelEventWatch
Definition: SDL_dynapi_overrides.h:135
format
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: SDL_opengl.h:1565
SDL_GetWindowData
#define SDL_GetWindowData
Definition: SDL_dynapi_overrides.h:527
SDL_Renderer::RenderDrawPoints
int(* RenderDrawPoints)(SDL_Renderer *renderer, const SDL_FPoint *points, int count)
Definition: SDL_sysrender.h:104
SDL_Renderer::LockTexture
int(* LockTexture)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, void **pixels, int *pitch)
Definition: SDL_sysrender.h:97
SDL_HasIntersection
#define SDL_HasIntersection
Definition: SDL_dynapi_overrides.h:299
SDL_Texture::pitch
int pitch
Definition: SDL_sysrender.h:66
x1
GLuint GLfloat GLfloat GLfloat x1
Definition: SDL_opengl_glext.h:8583
SDL_SW_CreateYUVTexture
SDL_SW_YUVTexture * SDL_SW_CreateYUVTexture(Uint32 format, int w, int h)
Definition: SDL_yuv_sw.c:1021
SDL_min
#define SDL_min(x, y)
Definition: SDL_stdinc.h:345
SDL_RendererInfo::max_texture_width
int max_texture_width
Definition: SDL_render.h:84
SDL_render_sw_c.h
SDL_UnlockSurface
#define SDL_UnlockSurface
Definition: SDL_dynapi_overrides.h:453
r
GLdouble GLdouble GLdouble r
Definition: SDL_opengl.h:2072
SDL_ceil
#define SDL_ceil
Definition: SDL_dynapi_overrides.h:432
GetClosestSupportedFormat
static Uint32 GetClosestSupportedFormat(SDL_Renderer *renderer, Uint32 format)
Definition: SDL_render.c:385
SDL_UpdateTextureYUVPlanar
static int SDL_UpdateTextureYUVPlanar(SDL_Texture *texture, const SDL_Rect *rect, const Uint8 *Yplane, int Ypitch, const Uint8 *Uplane, int Upitch, const Uint8 *Vplane, int Vpitch)
Definition: SDL_render.c:839
SDL_render.h
SDL_RenderCopy
int SDL_RenderCopy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *srcrect, const SDL_Rect *dstrect)
Copy a portion of the texture to the current rendering target.
Definition: SDL_render.c:1675
width
GLint GLint GLsizei width
Definition: SDL_opengl.h:1565
n
GLdouble n
Definition: SDL_opengl_glext.h:1952
SDL_MouseMotionEvent::y
Sint32 y
Definition: SDL_events.h:237
SDL_HINT_RENDER_VSYNC
#define SDL_HINT_RENDER_VSYNC
A variable controlling whether updates to the SDL screen surface should be synchronized with the vert...
Definition: SDL_hints.h:142
Uint32
uint32_t Uint32
An unsigned 32-bit integer type.
Definition: SDL_stdinc.h:155
SDL_MOUSEBUTTONUP
Definition: SDL_events.h:104
SDL_Renderer::RenderReadPixels
int(* RenderReadPixels)(SDL_Renderer *renderer, const SDL_Rect *rect, Uint32 format, void *pixels, int pitch)
Definition: SDL_sysrender.h:115
SDL_SetRenderDrawBlendMode
int SDL_SetRenderDrawBlendMode(SDL_Renderer *renderer, SDL_BlendMode blendMode)
Set the blend mode used for drawing operations (Fill and Line).
Definition: SDL_render.c:1347
SDL_WINDOWEVENT_MINIMIZED
Definition: SDL_video.h:149
SDL_Renderer::info
SDL_RendererInfo info
Definition: SDL_sysrender.h:126
SDL_RENDERER_TARGETTEXTURE
Definition: SDL_render.h:71
SDL_RendererInfo::flags
Uint32 flags
Definition: SDL_render.h:81
SDL_log.h
SDL_GetRendererInfo
int SDL_GetRendererInfo(SDL_Renderer *renderer, SDL_RendererInfo *info)
Get information about a rendering context.
Definition: SDL_render.c:345
SDL_Renderer::clip_rect_backup
SDL_Rect clip_rect_backup
Definition: SDL_sysrender.h:144
SDL_Surface::h
int h
Definition: SDL_surface.h:73
SDL_ISPIXELFORMAT_INDEXED
#define SDL_ISPIXELFORMAT_INDEXED(format)
Definition: SDL_pixels.h:133
SDL_MouseButtonEvent::y
Sint32 y
Definition: SDL_events.h:256
x
GLint GLint GLint GLint GLint x
Definition: SDL_opengl.h:1567
SDL_BlendMode
SDL_BlendMode
The blend mode used in SDL_RenderCopy() and drawing operations.
Definition: SDL_blendmode.h:40
SDL_Texture::g
Uint8 g
Definition: SDL_sysrender.h:58
SDL_ConvertSurface
#define SDL_ConvertSurface
Definition: SDL_dynapi_overrides.h:467
count
GLuint GLuint GLsizei count
Definition: SDL_opengl.h:1564
rect
SDL_Rect rect
Definition: testrelative.c:27
SDL_FLIP_NONE
Definition: SDL_render.h:113
window
SDL_Window * window
Definition: testautomation_render.c:26
SDL_fabs
#define SDL_fabs
Definition: SDL_dynapi_overrides.h:436
SDL_Renderer::hidden
SDL_bool hidden
Definition: SDL_sysrender.h:130
texture
GLenum GLenum GLuint texture
Definition: SDL_opengl_glext.h:1178
SDL_RENDERER_PRESENTVSYNC
Definition: SDL_render.h:69
SDL_GetRenderTarget
SDL_Texture * SDL_GetRenderTarget(SDL_Renderer *renderer)
Get the current render target or NULL for the default render target.
Definition: SDL_render.c:1133
y2
GLfixed GLfixed GLfixed y2
Definition: SDL_opengl_glext.h:4583
SDL_MOUSEBUTTONDOWN
Definition: SDL_events.h:103
SDL_Point
The structure that defines a point.
Definition: SDL_rect.h:48
SDL_Surface
A collection of pixels used in software blitting.
Definition: SDL_surface.h:69
SDL_Renderer::scale
SDL_FPoint scale
Definition: SDL_sysrender.h:151
SDL_RendererInfo::texture_formats
Uint32 texture_formats[16]
Definition: SDL_render.h:83
SDL_GetHint
#define SDL_GetHint
Definition: SDL_dynapi_overrides.h:197
SDL_Renderer::logical_h
int logical_h
Definition: SDL_sysrender.h:134
SDL_GetWindowFlags
#define SDL_GetWindowFlags
Definition: SDL_dynapi_overrides.h:522
SDL_Renderer
Definition: SDL_sysrender.h:76
SDL_SW_LockYUVTexture
int SDL_SW_LockYUVTexture(SDL_SW_YUVTexture *swdata, const SDL_Rect *rect, void **pixels, int *pitch)
Definition: SDL_yuv_sw.c:1243
SDL_GetRenderDrawColor
int SDL_GetRenderDrawColor(SDL_Renderer *renderer, Uint8 *r, Uint8 *g, Uint8 *b, Uint8 *a)
Get the color used for drawing operations (Rect, Line and Clear).
Definition: SDL_render.c:1326
SDL_MouseMotionEvent::x
Sint32 x
Definition: SDL_events.h:236
SDL_WINDOWEVENT_MAXIMIZED
Definition: SDL_video.h:150
f
GLfloat f
Definition: SDL_opengl_glext.h:1870
SDL_BYTESPERPIXEL
#define SDL_BYTESPERPIXEL(X)
Definition: SDL_pixels.h:127
SDL_Texture::locked_rect
SDL_Rect locked_rect
Definition: SDL_sysrender.h:67
SDL_TEXTUREMODULATE_COLOR
Definition: SDL_render.h:104
SDL_Renderer::RenderFillRects
int(* RenderFillRects)(SDL_Renderer *renderer, const SDL_FRect *rects, int count)
Definition: SDL_sysrender.h:108
pixels
GLint GLint GLsizei GLsizei GLsizei GLint GLenum GLenum const GLvoid * pixels
Definition: SDL_opengl.h:1565
SDL_CreateWindow
#define SDL_CreateWindow
Definition: SDL_dynapi_overrides.h:518
SDL_UpdateTextureNative
static int SDL_UpdateTextureNative(SDL_Texture *texture, const SDL_Rect *rect, const void *pixels, int pitch)
Definition: SDL_render.c:766
SDL_RenderDrawPoint
int SDL_RenderDrawPoint(SDL_Renderer *renderer, int x, int y)
Draw a point on the current rendering target.
Definition: SDL_render.c:1377
SDL_AllocFormat
#define SDL_AllocFormat
Definition: SDL_dynapi_overrides.h:286
SDL_WINDOWPOS_UNDEFINED
#define SDL_WINDOWPOS_UNDEFINED
Definition: SDL_video.h:120
SDL_ISPIXELFORMAT_ALPHA
#define SDL_ISPIXELFORMAT_ALPHA(format)
Definition: SDL_pixels.h:153
SDL_Renderer::clip_rect
SDL_Rect clip_rect
Definition: SDL_sysrender.h:143
RenderDrawPointsWithRects
static int RenderDrawPointsWithRects(SDL_Renderer *renderer, const SDL_Point *points, int count)
Definition: SDL_render.c:1387
SDL_InvalidParamError
#define SDL_InvalidParamError(param)
Definition: SDL_error.h:54
SDL_RenderSetViewport
int SDL_RenderSetViewport(SDL_Renderer *renderer, const SDL_Rect *rect)
Set the drawing area for rendering on the current target.
Definition: SDL_render.c:1219
SDL_strcasecmp
#define SDL_strcasecmp
Definition: SDL_dynapi_overrides.h:425
height
GLint GLint GLsizei GLsizei height
Definition: SDL_opengl.h:1565
SDL_Surface::w
int w
Definition: SDL_surface.h:73
SDL_RenderPresent
void SDL_RenderPresent(SDL_Renderer *renderer)
Update the screen with rendering performed.
Definition: SDL_render.c:1830
SDL_RendererInfo::name
const char * name
Definition: SDL_render.h:80
SDL_RenderReadPixels
int SDL_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rect *rect, Uint32 format, void *pixels, int pitch)
Read pixels from the current rendering target.
Definition: SDL_render.c:1793
SDL_IntersectRect
#define SDL_IntersectRect
Definition: SDL_dynapi_overrides.h:300
SDL_Renderer::textures
SDL_Texture * textures
Definition: SDL_sysrender.h:155
SDL_WINDOWEVENT_SIZE_CHANGED
Definition: SDL_video.h:146
SDL_floor
#define SDL_floor
Definition: SDL_dynapi_overrides.h:437
SDL_WINDOW_HIDDEN
Definition: SDL_video.h:101
SDL_RendererInfo::max_texture_height
int max_texture_height
Definition: SDL_render.h:85
SDL_FRect::y
float y
Definition: SDL_sysrender.h:43
texture_magic
static char texture_magic
Definition: SDL_render.c:76
SDL_Renderer::window
SDL_Window * window
Definition: SDL_sysrender.h:129
SDL_RenderGetLogicalSize
void SDL_RenderGetLogicalSize(SDL_Renderer *renderer, int *w, int *h)
Get device independent resolution for rendering.
Definition: SDL_render.c:1206
SDL_RenderDriver::info
SDL_RendererInfo info
Definition: SDL_sysrender.h:170
SDL_GetRendererOutputSize
int SDL_GetRendererOutputSize(SDL_Renderer *renderer, int *w, int *h)
Get the output size in pixels of a rendering context.
Definition: SDL_render.c:354
SDL_max
#define SDL_max(x, y)
Definition: SDL_stdinc.h:346
x2
GLfixed GLfixed x2
Definition: SDL_opengl_glext.h:4583
SDL_LockTextureYUV
static int SDL_LockTextureYUV(SDL_Texture *texture, const SDL_Rect *rect, void **pixels, int *pitch)
Definition: SDL_render.c:943
SDL_Renderer::RenderClear
int(* RenderClear)(SDL_Renderer *renderer)
Definition: SDL_sysrender.h:103
SDL_Texture::a
Uint8 a
Definition: SDL_sysrender.h:58
SDL_WINDOWEVENT_HIDDEN
Definition: SDL_video.h:140
alpha
GLfloat GLfloat GLfloat alpha
Definition: SDL_opengl_glext.h:412
access
GLuint GLint GLboolean GLint GLenum access
Definition: SDL_opengl_glext.h:2162
RenderDrawLinesWithRects
static int RenderDrawLinesWithRects(SDL_Renderer *renderer, const SDL_Point *points, int count)
Definition: SDL_render.c:1466
SDL_RenderFillRect
int SDL_RenderFillRect(SDL_Renderer *renderer, const SDL_Rect *rect)
Fill a rectangle on the current rendering target with the drawing color.
Definition: SDL_render.c:1619
SDL_Renderer::DestroyRenderer
void(* DestroyRenderer)(SDL_Renderer *renderer)
Definition: SDL_sysrender.h:120
points
GLfixed GLfixed GLint GLint GLfixed points
Definition: SDL_opengl_glext.h:4558
SDL_Texture
Definition: SDL_sysrender.h:49
SDL_Renderer::GetOutputSize
int(* GetOutputSize)(SDL_Renderer *renderer, int *w, int *h)
Definition: SDL_sysrender.h:81
SDL_Renderer::SetTextureBlendMode
int(* SetTextureBlendMode)(SDL_Renderer *renderer, SDL_Texture *texture)
Definition: SDL_sysrender.h:87
SDL_QueryTexture
int SDL_QueryTexture(SDL_Texture *texture, Uint32 *format, int *access, int *w, int *h)
Query the attributes of a texture.
Definition: SDL_render.c:593
y1
GLfixed y1
Definition: SDL_opengl_glext.h:4583
SDL_GetSurfaceBlendMode
#define SDL_GetSurfaceBlendMode
Definition: SDL_dynapi_overrides.h:464
SW_CreateRendererForSurface
SDL_Renderer * SW_CreateRendererForSurface(SDL_Surface *surface)
Definition: SDL_render_sw.c:126
SDL_Renderer::scale_backup
SDL_FPoint scale_backup
Definition: SDL_sysrender.h:152
SDL_UnlockTextureNative
static void SDL_UnlockTextureNative(SDL_Texture *texture)
Definition: SDL_render.c:1014
blendMode
static SDL_BlendMode blendMode
Definition: testdraw2.c:34
SDL_GetTextureBlendMode
int SDL_GetTextureBlendMode(SDL_Texture *texture, SDL_BlendMode *blendMode)
Get the blend mode used for texture copy operations.
Definition: SDL_render.c:709
SDL_bool
SDL_bool
Definition: SDL_stdinc.h:126
g
GLboolean GLboolean g
Definition: SDL_opengl_glext.h:1109
SDL_SetWindowData
#define SDL_SetWindowData
Definition: SDL_dynapi_overrides.h:526
SDL_Event::window
SDL_WindowEvent window
Definition: SDL_events.h:525
SDL_CreateSoftwareRenderer
SDL_Renderer * SDL_CreateSoftwareRenderer(SDL_Surface *surface)
Create a 2D software rendering context for a surface.
Definition: SDL_render.c:317
SDL_Renderer::UpdateTexture
int(* UpdateTexture)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, const void *pixels, int pitch)
Definition: SDL_sysrender.h:89
SDL_SW_UpdateYUVTexture
int SDL_SW_UpdateYUVTexture(SDL_SW_YUVTexture *swdata, const SDL_Rect *rect, const void *pixels, int pitch)
Definition: SDL_yuv_sw.c:1114
SDL_Point::x
int x
Definition: SDL_rect.h:50
SDL_Renderer::UpdateTextureYUV
int(* UpdateTextureYUV)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, const Uint8 *Yplane, int Ypitch, const Uint8 *Uplane, int Upitch, const Uint8 *Vplane, int Vpitch)
Definition: SDL_sysrender.h:92
renderer
SDL_Renderer * renderer
Definition: testautomation_render.c:27
SDL_GetWindowSize
#define SDL_GetWindowSize
Definition: SDL_dynapi_overrides.h:531
SDL_MouseMotionEvent::yrel
Sint32 yrel
Definition: SDL_events.h:239
SDL_SetTextureBlendMode
int SDL_SetTextureBlendMode(SDL_Texture *texture, SDL_BlendMode blendMode)
Set the blend mode used for texture copy operations.
Definition: SDL_render.c:691
SDL_Renderer::SetTextureColorMod
int(* SetTextureColorMod)(SDL_Renderer *renderer, SDL_Texture *texture)
Definition: SDL_sysrender.h:83
SDL_Texture::next
SDL_Texture * next
Definition: SDL_sysrender.h:72
SDL_calloc
void * SDL_calloc(size_t nmemb, size_t size)
CHECK_RENDERER_MAGIC
#define CHECK_RENDERER_MAGIC(renderer, retval)
Definition: SDL_render.c:35
SDL_MouseMotionEvent::xrel
Sint32 xrel
Definition: SDL_events.h:238
SDL_TEXTUREMODULATE_ALPHA
Definition: SDL_render.h:105
SDL_DestroyTexture
void SDL_DestroyTexture(SDL_Texture *texture)
Destroy the specified texture.
Definition: SDL_render.c:1842
SDL_Texture::prev
SDL_Texture * prev
Definition: SDL_sysrender.h:71
SDL_DestroyRenderer
void SDL_DestroyRenderer(SDL_Renderer *renderer)
Destroy the rendering context for a window and free associated textures.
Definition: SDL_render.c:1877
SW_RenderDriver
SDL_RenderDriver SW_RenderDriver
Definition: SDL_render_sw.c:78
y
GLint GLint GLint GLint GLint GLint y
Definition: SDL_opengl.h:1567
SDL_RenderDrawRects
int SDL_RenderDrawRects(SDL_Renderer *renderer, const SDL_Rect *rects, int count)
Draw some number of rectangles on the current rendering target.
Definition: SDL_render.c:1592
SDL_Renderer::target
SDL_Texture * target
Definition: SDL_sysrender.h:156
SDL_Renderer::g
Uint8 g
Definition: SDL_sysrender.h:158
SDL_Point::y
int y
Definition: SDL_rect.h:51
SDL_Surface::pixels
void * pixels
Definition: SDL_surface.h:75
SDL_GetColorKey
#define SDL_GetColorKey
Definition: SDL_dynapi_overrides.h:458
SDL_WINDOWEVENT_RESTORED
Definition: SDL_video.h:151
SDL_FreeSurface
#define SDL_FreeSurface
Definition: SDL_dynapi_overrides.h:450
SDL_Renderer::logical_w_backup
int logical_w_backup
Definition: SDL_sysrender.h:135
SDL_RenderDrawPoints
int SDL_RenderDrawPoints(SDL_Renderer *renderer, const SDL_Point *points, int count)
Draw multiple points on the current rendering target.
Definition: SDL_render.c:1413
Uint8
uint8_t Uint8
An unsigned 8-bit integer type.
Definition: SDL_stdinc.h:139
SDL_stack_alloc
#define SDL_stack_alloc(type, count)
Definition: SDL_stdinc.h:324
event
struct _cl_event * event
Definition: SDL_opengl_glext.h:2649
SDL_Renderer::logical_h_backup
int logical_h_backup
Definition: SDL_sysrender.h:136
SDL_Texture::yuv
SDL_SW_YUVTexture * yuv
Definition: SDL_sysrender.h:64
SDL_UnlockTexture
void SDL_UnlockTexture(SDL_Texture *texture)
Unlock a texture, uploading the changes to video memory, if needed.
Definition: SDL_render.c:1035
SDL_Renderer::blendMode
SDL_BlendMode blendMode
Definition: SDL_sysrender.h:159
SDL_free
void SDL_free(void *mem)
SDL_LockTexture
int SDL_LockTexture(SDL_Texture *texture, const SDL_Rect *rect, void **pixels, int *pitch)
Lock a portion of the texture for write-only pixel access.
Definition: SDL_render.c:962
SDL_GetRenderDrawBlendMode
int SDL_GetRenderDrawBlendMode(SDL_Renderer *renderer, SDL_BlendMode *blendMode)
Get the blend mode used for drawing operations.
Definition: SDL_render.c:1356
SDL_CreateTextureFromSurface
SDL_Texture * SDL_CreateTextureFromSurface(SDL_Renderer *renderer, SDL_Surface *surface)
Create a texture from an existing surface.
Definition: SDL_render.c:505
SDL_TEXTUREACCESS_STATIC
Definition: SDL_render.h:93
SDL_FreeFormat
#define SDL_FreeFormat
Definition: SDL_dynapi_overrides.h:287
SDL_Renderer::b
Uint8 b
Definition: SDL_sysrender.h:158
SDL_TEXTUREACCESS_STREAMING
Definition: SDL_render.h:94
SDL_Renderer::GL_BindTexture
int(* GL_BindTexture)(SDL_Renderer *renderer, SDL_Texture *texture, float *texw, float *texh)
Definition: SDL_sysrender.h:122
SDL_hints.h
SDL_Texture::w
int w
Definition: SDL_sysrender.h:54
SDL_Renderer::UnlockTexture
void(* UnlockTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
Definition: SDL_sysrender.h:99
SDL_WINDOWEVENT
Definition: SDL_events.h:89
SDL_RenderDriver::CreateRenderer
SDL_Renderer *(* CreateRenderer)(SDL_Window *window, Uint32 flags)
Definition: SDL_sysrender.h:167
SDL_zero
#define SDL_zero(x)
Definition: SDL_stdinc.h:355
SDL_RenderDrawRect
int SDL_RenderDrawRect(SDL_Renderer *renderer, const SDL_Rect *rect)
Draw a rectangle on the current rendering target.
Definition: SDL_render.c:1563
SDL_WINDOW_MINIMIZED
Definition: SDL_video.h:104
SDL_GetNumRenderDrivers
int SDL_GetNumRenderDrivers(void)
Get the number of 2D rendering drivers available for the current display.
Definition: SDL_render.c:81
SDL_SW_DestroyYUVTexture
void SDL_SW_DestroyYUVTexture(SDL_SW_YUVTexture *swdata)
Definition: SDL_yuv_sw.c:1393
SDL_Rect::x
int x
Definition: SDL_rect.h:66
SDL_WindowEvent::event
Uint8 event
Definition: SDL_events.h:176
SDL_UpdateYUVTexture
int SDL_UpdateYUVTexture(SDL_Texture *texture, const SDL_Rect *rect, const Uint8 *Yplane, int Ypitch, const Uint8 *Uplane, int Upitch, const Uint8 *Vplane, int Vpitch)
Update a rectangle within a planar YV12 or IYUV texture with new pixel data.
Definition: SDL_render.c:886
SDL_Renderer::SetRenderTarget
int(* SetRenderTarget)(SDL_Renderer *renderer, SDL_Texture *texture)
Definition: SDL_sysrender.h:100
SDL_Renderer::UpdateViewport
int(* UpdateViewport)(SDL_Renderer *renderer)
Definition: SDL_sysrender.h:101
SDL_GetWindowFromID
#define SDL_GetWindowFromID
Definition: SDL_dynapi_overrides.h:521
SDL_TRUE
Definition: SDL_stdinc.h:129
SDL_GetTextureColorMod
int SDL_GetTextureColorMod(SDL_Texture *texture, Uint8 *r, Uint8 *g, Uint8 *b)
Get the additional color value used in render copy operations.
Definition: SDL_render.c:639
SDL_sysrender.h
SDL_GL_BindTexture
int SDL_GL_BindTexture(SDL_Texture *texture, float *texw, float *texh)
Bind the texture to the current OpenGL/ES/ES2 context for use with OpenGL instructions.
Definition: SDL_render.c:1899
SDL_Rect::w
int w
Definition: SDL_rect.h:67
SDL_RenderTargetSupported
SDL_bool SDL_RenderTargetSupported(SDL_Renderer *renderer)
Determines whether a window supports the use of render targets.
Definition: SDL_render.c:1055
SDL_Renderer::GL_UnbindTexture
int(* GL_UnbindTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
Definition: SDL_sysrender.h:123
SDL_FRect::h
float h
Definition: SDL_sysrender.h:45
index
GLuint index
Definition: SDL_opengl_glext.h:660
UpdateLogicalSize
static int UpdateLogicalSize(SDL_Renderer *renderer)
Definition: SDL_render.c:1139
SDL_GetSurfaceAlphaMod
#define SDL_GetSurfaceAlphaMod
Definition: SDL_dynapi_overrides.h:462
SDL_RendererFlip
SDL_RendererFlip
Flip constants for SDL_RenderCopyEx.
Definition: SDL_render.h:111
SDL_UpdateTextureYUV
static int SDL_UpdateTextureYUV(SDL_Texture *texture, const SDL_Rect *rect, const void *pixels, int pitch)
Definition: SDL_render.c:720
SDL_Renderer::RenderCopy
int(* RenderCopy)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *srcrect, const SDL_FRect *dstrect)
Definition: SDL_sysrender.h:110
SDL_RenderSetScale
int SDL_RenderSetScale(SDL_Renderer *renderer, float scaleX, float scaleY)
Set the drawing scale for rendering on the current target.
Definition: SDL_render.c:1290
SDL_SetTextureAlphaMod
int SDL_SetTextureAlphaMod(SDL_Texture *texture, Uint8 alpha)
Set an additional alpha value used in render copy operations.
Definition: SDL_render.c:657
i
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
Definition: SDL_x11sym.h:42
SDL_RenderGetClipRect
void SDL_RenderGetClipRect(SDL_Renderer *renderer, SDL_Rect *rect)
Get the clip rectangle for the current target.
Definition: SDL_render.c:1270
SDL_assert
#define SDL_assert(condition)
Definition: SDL_assert.h:167
SDL_UpdateTexture
int SDL_UpdateTexture(SDL_Texture *texture, const SDL_Rect *rect, const void *pixels, int pitch)
Update the given texture rectangle with new pixel data.
Definition: SDL_render.c:803
SDL_RenderClear
int SDL_RenderClear(SDL_Renderer *renderer)
Clear the current rendering target with the drawing color.
Definition: SDL_render.c:1365
SDL_RenderIsClipEnabled
SDL_bool SDL_RenderIsClipEnabled(SDL_Renderer *renderer)
Get whether clipping is enabled on the given renderer.
Definition: SDL_render.c:1283
NULL
#define NULL
Definition: begin_code.h:143
SDL_OutOfMemory
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
SDL_Texture::b
Uint8 b
Definition: SDL_sysrender.h:58
SDL_Surface::format
SDL_PixelFormat * format
Definition: SDL_surface.h:72
SDL_SetError
#define SDL_SetError
Definition: SDL_dynapi_overrides.h:36
SDL_LockSurface
#define SDL_LockSurface
Definition: SDL_dynapi_overrides.h:452
SDL_RendererInfo
Information on the capabilities of a render driver or context.
Definition: SDL_render.h:78
render_drivers
static const SDL_RenderDriver * render_drivers[]
Definition: SDL_render.c:49
SDL_WINDOWRENDERDATA
#define SDL_WINDOWRENDERDATA
Definition: SDL_render.c:33
SDL_MOUSEMOTION
Definition: SDL_events.h:102
SDL_RenderDriver
Definition: SDL_sysrender.h:165
IsSupportedFormat
static SDL_bool IsSupportedFormat(SDL_Renderer *renderer, Uint32 format)
Definition: SDL_render.c:372
SDL_Texture::renderer
SDL_Renderer * renderer
Definition: SDL_sysrender.h:60
SDL_CreateRenderer
SDL_Renderer * SDL_CreateRenderer(SDL_Window *window, int index, Uint32 flags)
Create a 2D rendering context for a window.
Definition: SDL_render.c:220
SDL_Renderer::RenderCopyEx
int(* RenderCopyEx)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *srcquad, const SDL_FRect *dstrect, const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip)
Definition: SDL_sysrender.h:112
SDL_WINDOWEVENT_SHOWN
Definition: SDL_video.h:139
SDL_PIXELFORMAT_YV12
Definition: SDL_pixels.h:263
SDL_GetSurfaceColorMod
#define SDL_GetSurfaceColorMod
Definition: SDL_dynapi_overrides.h:460
CHECK_TEXTURE_MAGIC
#define CHECK_TEXTURE_MAGIC(texture, retval)
Definition: SDL_render.c:41
SDL_AddEventWatch
#define SDL_AddEventWatch
Definition: SDL_dynapi_overrides.h:134
SDL_SW_UpdateYUVTexturePlanar
int SDL_SW_UpdateYUVTexturePlanar(SDL_SW_YUVTexture *swdata, const SDL_Rect *rect, const Uint8 *Yplane, int Ypitch, const Uint8 *Uplane, int Upitch, const Uint8 *Vplane, int Vpitch)
Definition: SDL_yuv_sw.c:1188
SDL_MUSTLOCK
#define SDL_MUSTLOCK(S)
Definition: SDL_surface.h:61
SDL_LogInfo
#define SDL_LogInfo
Definition: SDL_dynapi_overrides.h:40
SDL_Renderer::viewport
SDL_Rect viewport
Definition: SDL_sysrender.h:139
SDL_RenderDrawLines
int SDL_RenderDrawLines(SDL_Renderer *renderer, const SDL_Point *points, int count)
Draw a series of connected lines on the current rendering target.
Definition: SDL_render.c:1522
SDL_Rect::h
int h
Definition: SDL_rect.h:67
SDL_PIXELFORMAT_IYUV
Definition: SDL_pixels.h:265
SDL_Renderer::SetTextureAlphaMod
int(* SetTextureAlphaMod)(SDL_Renderer *renderer, SDL_Texture *texture)
Definition: SDL_sysrender.h:85
SDL_MouseMotionEvent::windowID
Uint32 windowID
Definition: SDL_events.h:233
SDL_RenderFillRects
int SDL_RenderFillRects(SDL_Renderer *renderer, const SDL_Rect *rects, int count)
Fill some number of rectangles on the current rendering target with the drawing color.
Definition: SDL_render.c:1636
SDL_Window
The type used to identify a window.
Definition: SDL_sysvideo.h:71
rects
SDL_Rect rects[MAX_RECTS]
Definition: testintersections.c:129
SDL_GetWindowPixelFormat
#define SDL_GetWindowPixelFormat
Definition: SDL_dynapi_overrides.h:517
SDL_GetRenderer
SDL_Renderer * SDL_GetRenderer(SDL_Window *window)
Get the renderer associated with a window.
Definition: SDL_render.c:339
viewport
SDL_Rect viewport
Definition: testviewport.c:28
SDL_PixelFormat
Definition: SDL_pixels.h:299
SDL_FALSE
Definition: SDL_stdinc.h:128
SDL_RenderGetViewport
void SDL_RenderGetViewport(SDL_Renderer *renderer, SDL_Rect *rect)
Get the drawing area for the current target.
Definition: SDL_render.c:1239
SDL_SW_CopyYUVToRGB
int SDL_SW_CopyYUVToRGB(SDL_SW_YUVTexture *swdata, const SDL_Rect *srcrect, Uint32 target_format, int w, int h, void *pixels, int pitch)
Definition: SDL_yuv_sw.c:1273
SDL_HINT_RENDER_DRIVER
#define SDL_HINT_RENDER_DRIVER
A variable specifying which render driver to use.
Definition: SDL_hints.h:84
SDL_Renderer::WindowEvent
void(* WindowEvent)(SDL_Renderer *renderer, const SDL_WindowEvent *event)
Definition: SDL_sysrender.h:80
SDL_RenderGetScale
void SDL_RenderGetScale(SDL_Renderer *renderer, float *scaleX, float *scaleY)
Get the drawing scale for the current target.
Definition: SDL_render.c:1300
SDL_Surface::pitch
int pitch
Definition: SDL_surface.h:74
SDL_SetTextureColorMod
int SDL_SetTextureColorMod(SDL_Texture *texture, Uint8 r, Uint8 g, Uint8 b)
Set an additional color value used in render copy operations.
Definition: SDL_render.c:614
SDL_TEXTUREACCESS_TARGET
Definition: SDL_render.h:95
angle
GLfloat angle
Definition: SDL_opengl_glext.h:6097
SDL_Event::button
SDL_MouseButtonEvent button
Definition: SDL_events.h:530
SDL_MouseButtonEvent::x
Sint32 x
Definition: SDL_events.h:255
SDL_Renderer::magic
const void * magic
Definition: SDL_sysrender.h:78
SDL_RendererInfo::num_texture_formats
Uint32 num_texture_formats
Definition: SDL_render.h:82
SDL_RenderSetClipRect
int SDL_RenderSetClipRect(SDL_Renderer *renderer, const SDL_Rect *rect)
Set the clip rectangle for the current target.
Definition: SDL_render.c:1252
SDL_RenderCopyEx
int SDL_RenderCopyEx(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *srcrect, const SDL_Rect *dstrect, const double angle, const SDL_Point *center, const SDL_RendererFlip flip)
Copy a portion of the source texture to the current rendering target, rotating it by angle around the...
Definition: SDL_render.c:1728
SDL_Texture::format
Uint32 format
Definition: SDL_sysrender.h:52
SDL_Texture::modMode
int modMode
Definition: SDL_sysrender.h:56
SDL_arraysize
#define SDL_arraysize(array)
Definition: SDL_stdinc.h:93
flags
GLbitfield flags
Definition: SDL_opengl_glext.h:1480
renderer_magic
static char renderer_magic
Definition: SDL_render.c:75
SDL_Event
General event structure.
Definition: SDL_events.h:521
SDL_malloc
#define SDL_malloc
Definition: SDL_dynapi_overrides.h:380
SDL_SetRenderDrawColor
int SDL_SetRenderDrawColor(SDL_Renderer *renderer, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
Set the color used for drawing operations (Rect, Line and Clear).
Definition: SDL_render.c:1313
SDL_PixelFormat::Amask
Uint32 Amask
Definition: SDL_pixels.h:309
w
GLubyte GLubyte GLubyte GLubyte w
Definition: SDL_opengl_glext.h:731
SDL_Renderer::logical_w
int logical_w
Definition: SDL_sysrender.h:133
SDL_ConvertPixels
#define SDL_ConvertPixels
Definition: SDL_dynapi_overrides.h:469
SDL_Renderer::DestroyTexture
void(* DestroyTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
Definition: SDL_sysrender.h:118
SDL_Renderer::CreateTexture
int(* CreateTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
Definition: SDL_sysrender.h:82
SDL_Texture::native
SDL_Texture * native
Definition: SDL_sysrender.h:63
SDL_Renderer::RenderPresent
void(* RenderPresent)(SDL_Renderer *renderer)
Definition: SDL_sysrender.h:117
SDL_ISPIXELFORMAT_FOURCC
#define SDL_ISPIXELFORMAT_FOURCC(format)
Definition: SDL_pixels.h:166
SDL_Renderer::r
Uint8 r
Definition: SDL_sysrender.h:158
SDL_PixelFormat::format
Uint32 format
Definition: SDL_pixels.h:301
SDL_stack_free
#define SDL_stack_free(data)
Definition: SDL_stdinc.h:325
SDL_FRect::x
float x
Definition: SDL_sysrender.h:42
SDL_Renderer::viewport_backup
SDL_Rect viewport_backup
Definition: SDL_sysrender.h:140
SDL_RenderSetLogicalSize
int SDL_RenderSetLogicalSize(SDL_Renderer *renderer, int w, int h)
Set device independent resolution for rendering.
Definition: SDL_render.c:1186
SDL_Renderer::a
Uint8 a
Definition: SDL_sysrender.h:158
a
GLboolean GLboolean GLboolean GLboolean a
Definition: SDL_opengl_glext.h:1109
SDL_MouseButtonEvent::windowID
Uint32 windowID
Definition: SDL_events.h:249
SDL_SetRenderTarget
int SDL_SetRenderTarget(SDL_Renderer *renderer, SDL_Texture *texture)
Set a texture as the current rendering target.
Definition: SDL_render.c:1064
SDL_Texture::magic
const void * magic
Definition: SDL_sysrender.h:51
SDL_LOG_CATEGORY_RENDER
Definition: SDL_log.h:72
SDL_RenderDrawLine
int SDL_RenderDrawLine(SDL_Renderer *renderer, int x1, int y1, int x2, int y2)
Draw a line on the current rendering target.
Definition: SDL_render.c:1454
SDL_Renderer::UpdateClipRect
int(* UpdateClipRect)(SDL_Renderer *renderer)
Definition: SDL_sysrender.h:102
SDL_UnlockTextureYUV
static void SDL_UnlockTextureYUV(SDL_Texture *texture)
Definition: SDL_render.c:993
b
GLboolean GLboolean GLboolean b
Definition: SDL_opengl_glext.h:1109
SDL_Renderer::clipping_enabled_backup
SDL_bool clipping_enabled_backup
Definition: SDL_sysrender.h:148
SDL_Texture::access
int access
Definition: SDL_sysrender.h:53
SDL_Rect::y
int y
Definition: SDL_rect.h:66
SDL_Unsupported
#define SDL_Unsupported()
Definition: SDL_error.h:53
SDL_WindowEvent::windowID
Uint32 windowID
Definition: SDL_events.h:175
SDL_CreateTexture
SDL_Texture * SDL_CreateTexture(SDL_Renderer *renderer, Uint32 format, int access, int w, int h)
Create a texture for a rendering context.
Definition: SDL_render.c:411
SDL_GetTextureAlphaMod
int SDL_GetTextureAlphaMod(SDL_Texture *texture, Uint8 *alpha)
Get the additional alpha value used in render copy operations.
Definition: SDL_render.c:680
SDL_FPoint::x
float x
Definition: SDL_sysrender.h:36
h
GLfloat GLfloat GLfloat GLfloat h
Definition: SDL_opengl_glext.h:1946
SDL_Renderer::clipping_enabled
SDL_bool clipping_enabled
Definition: SDL_sysrender.h:147
SDL_FRect
Definition: SDL_sysrender.h:40
SDL_RendererEventWatch
static int SDL_RendererEventWatch(void *userdata, SDL_Event *event)
Definition: SDL_render.c:106
SDL_FPoint
Definition: SDL_sysrender.h:34
SDL_Rect
A rectangle, with the origin at the upper left.
Definition: SDL_rect.h:64
SDL_GL_UnbindTexture
int SDL_GL_UnbindTexture(SDL_Texture *texture)
Unbind a texture from the current OpenGL/ES/ES2 context.
Definition: SDL_render.c:1914
SDL_LockTextureNative
static int SDL_LockTextureNative(SDL_Texture *texture, const SDL_Rect *rect, void **pixels, int *pitch)
Definition: SDL_render.c:950
SDL_Event::type
Uint32 type
Definition: SDL_events.h:523
SDL_assert.h
SDL_BLENDMODE_BLEND
Definition: SDL_blendmode.h:44
SDL_GetRenderDriverInfo
int SDL_GetRenderDriverInfo(int index, SDL_RendererInfo *info)
Get information about a specific 2D rendering driver for the current display.
Definition: SDL_render.c:91
SDL_Texture::h
int h
Definition: SDL_sysrender.h:55
SDL_FPoint::y
float y
Definition: SDL_sysrender.h:37
SDL_Texture::r
Uint8 r
Definition: SDL_sysrender.h:58