early-access version 2847

This commit is contained in:
pineappleEA
2022-07-19 05:48:31 +02:00
parent ba74a2373c
commit 05e3c38e7f
498 changed files with 16027 additions and 27028 deletions

View File

@@ -20,7 +20,7 @@
*/
#include "../SDL_internal.h"
#if (SDL_VIDEO_RENDER_D3D || SDL_VIDEO_RENDER_D3D11 || SDL_VIDEO_RENDER_D3D12) && !SDL_RENDER_DISABLED
#if (SDL_VIDEO_RENDER_D3D || SDL_VIDEO_RENDER_D3D11) && !SDL_RENDER_DISABLED
#include "SDL_stdinc.h"
#include "SDL_d3dmath.h"
@@ -131,6 +131,6 @@ Float4X4 MatrixRotationZ(float r)
}
#endif /* (SDL_VIDEO_RENDER_D3D || SDL_VIDEO_RENDER_D3D11 || SDL_VIDEO_RENDER_D3D12) && !SDL_RENDER_DISABLED */
#endif /* (SDL_VIDEO_RENDER_D3D || SDL_VIDEO_RENDER_D3D11) && !SDL_RENDER_DISABLED */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -20,7 +20,7 @@
*/
#include "../SDL_internal.h"
#if (SDL_VIDEO_RENDER_D3D || SDL_VIDEO_RENDER_D3D11 || SDL_VIDEO_RENDER_D3D12) && !SDL_RENDER_DISABLED
#if (SDL_VIDEO_RENDER_D3D || SDL_VIDEO_RENDER_D3D11) && !SDL_RENDER_DISABLED
/* Direct3D matrix math functions */
@@ -67,6 +67,6 @@ Float4X4 MatrixRotationX(float r);
Float4X4 MatrixRotationY(float r);
Float4X4 MatrixRotationZ(float r);
#endif /* (SDL_VIDEO_RENDER_D3D || SDL_VIDEO_RENDER_D3D11 || SDL_VIDEO_RENDER_D3D12) && !SDL_RENDER_DISABLED */
#endif /* (SDL_VIDEO_RENDER_D3D || SDL_VIDEO_RENDER_D3D11) && !SDL_RENDER_DISABLED */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -48,13 +48,13 @@ this should probably be removed at some point in the future. --ryan. */
#define CHECK_RENDERER_MAGIC(renderer, retval) \
if (!renderer || renderer->magic != &renderer_magic) { \
SDL_InvalidParamError("renderer"); \
SDL_SetError("Invalid renderer"); \
return retval; \
}
#define CHECK_TEXTURE_MAGIC(texture, retval) \
if (!texture || texture->magic != &texture_magic) { \
SDL_InvalidParamError("texture"); \
SDL_SetError("Invalid texture"); \
return retval; \
}
@@ -96,9 +96,6 @@ static const SDL_RenderDriver *render_drivers[] = {
#if SDL_VIDEO_RENDER_D3D11
&D3D11_RenderDriver,
#endif
#if SDL_VIDEO_RENDER_D3D12
&D3D12_RenderDriver,
#endif
#if SDL_VIDEO_RENDER_METAL
&METAL_RenderDriver,
#endif
@@ -353,13 +350,13 @@ static int
QueueCmdSetViewport(SDL_Renderer *renderer)
{
int retval = 0;
if (!renderer->viewport_queued || (SDL_memcmp(&renderer->viewport, &renderer->last_queued_viewport, sizeof (SDL_DRect)) != 0)) {
if (!renderer->viewport_queued || (SDL_memcmp(&renderer->viewport, &renderer->last_queued_viewport, sizeof (SDL_Rect)) != 0)) {
SDL_RenderCommand *cmd = AllocateRenderCommand(renderer);
retval = -1;
if (cmd != NULL) {
cmd->command = SDL_RENDERCMD_SETVIEWPORT;
cmd->data.viewport.first = 0; /* render backend will fill this in. */
/* Convert SDL_DRect to SDL_Rect */
/* Convert SDL_FRect to SDL_Rect */
cmd->data.viewport.rect.x = (int)SDL_floor(renderer->viewport.x);
cmd->data.viewport.rect.y = (int)SDL_floor(renderer->viewport.y);
cmd->data.viewport.rect.w = (int)SDL_floor(renderer->viewport.w);
@@ -368,7 +365,7 @@ QueueCmdSetViewport(SDL_Renderer *renderer)
if (retval < 0) {
cmd->command = SDL_RENDERCMD_NO_OP;
} else {
SDL_memcpy(&renderer->last_queued_viewport, &renderer->viewport, sizeof (SDL_DRect));
SDL_memcpy(&renderer->last_queued_viewport, &renderer->viewport, sizeof (SDL_Rect));
renderer->viewport_queued = SDL_TRUE;
}
}
@@ -382,19 +379,19 @@ QueueCmdSetClipRect(SDL_Renderer *renderer)
int retval = 0;
if ((!renderer->cliprect_queued) ||
(renderer->clipping_enabled != renderer->last_queued_cliprect_enabled) ||
(SDL_memcmp(&renderer->clip_rect, &renderer->last_queued_cliprect, sizeof (SDL_DRect)) != 0)) {
(SDL_memcmp(&renderer->clip_rect, &renderer->last_queued_cliprect, sizeof (SDL_Rect)) != 0)) {
SDL_RenderCommand *cmd = AllocateRenderCommand(renderer);
if (cmd == NULL) {
retval = -1;
} else {
cmd->command = SDL_RENDERCMD_SETCLIPRECT;
cmd->data.cliprect.enabled = renderer->clipping_enabled;
/* Convert SDL_DRect to SDL_Rect */
/* Convert SDL_FRect to SDL_Rect */
cmd->data.cliprect.rect.x = (int)SDL_floor(renderer->clip_rect.x);
cmd->data.cliprect.rect.y = (int)SDL_floor(renderer->clip_rect.y);
cmd->data.cliprect.rect.w = (int)SDL_floor(renderer->clip_rect.w);
cmd->data.cliprect.rect.h = (int)SDL_floor(renderer->clip_rect.h);
SDL_memcpy(&renderer->last_queued_cliprect, &renderer->clip_rect, sizeof (SDL_DRect));
SDL_memcpy(&renderer->last_queued_cliprect, &renderer->clip_rect, sizeof (SDL_Rect));
renderer->last_queued_cliprect_enabled = renderer->clipping_enabled;
renderer->cliprect_queued = SDL_TRUE;
}
@@ -583,10 +580,10 @@ QueueCmdFillRects(SDL_Renderer *renderer, const SDL_FRect * rects, const int cou
if (retval < 0) {
cmd->command = SDL_RENDERCMD_NO_OP;
}
SDL_small_free(xy, isstack1);
SDL_small_free(indices, isstack2);
}
SDL_small_free(xy, isstack1);
SDL_small_free(indices, isstack2);
} else {
retval = renderer->QueueFillRects(renderer, cmd, rects, count);
if (retval < 0) {
@@ -614,12 +611,12 @@ QueueCmdCopy(SDL_Renderer *renderer, SDL_Texture * texture, const SDL_Rect * src
static int
QueueCmdCopyEx(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, float scale_x, float scale_y)
const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip)
{
SDL_RenderCommand *cmd = PrepQueueCmdDraw(renderer, SDL_RENDERCMD_COPY_EX, texture);
int retval = -1;
if (cmd != NULL) {
retval = renderer->QueueCopyEx(renderer, cmd, texture, srcquad, dstrect, angle, center, flip, scale_x, scale_y);
retval = renderer->QueueCopyEx(renderer, cmd, texture, srcquad, dstrect, angle, center, flip);
if (retval < 0) {
cmd->command = SDL_RENDERCMD_NO_OP;
}
@@ -679,7 +676,7 @@ SDL_GetRenderDriverInfo(int index, SDL_RendererInfo * info)
#endif
}
static void GetWindowViewportValues(SDL_Renderer *renderer, int *logical_w, int *logical_h, SDL_DRect *viewport, SDL_FPoint *scale)
static void GetWindowViewportValues(SDL_Renderer *renderer, int *logical_w, int *logical_h, SDL_FRect *viewport, SDL_FPoint *scale)
{
SDL_LockMutex(renderer->target_mutex);
*logical_w = renderer->target ? renderer->logical_w_backup : renderer->logical_w;
@@ -701,17 +698,7 @@ SDL_RendererEventWatch(void *userdata, SDL_Event *event)
renderer->WindowEvent(renderer, &event->window);
}
/* In addition to size changes, we also want to do this block for
* moves as well, for two reasons:
*
* 1. The window could be moved to a new display, which has a new
* DPI and therefore a new window/drawable ratio
* 2. For whatever reason, the viewport can get messed up during
* window movement (this has been observed on macOS), so this is
* also a good opportunity to force viewport updates
*/
if (event->window.event == SDL_WINDOWEVENT_SIZE_CHANGED ||
event->window.event == SDL_WINDOWEVENT_MOVED) {
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) {
@@ -741,12 +728,19 @@ SDL_RendererEventWatch(void *userdata, SDL_Event *event)
SDL_GetWindowSize(renderer->window, &w, &h);
}
renderer->viewport.x = (double)0;
renderer->viewport.y = (double)0;
renderer->viewport.w = (double)w;
renderer->viewport.h = (double)h;
QueueCmdSetViewport(renderer);
FlushRenderCommandsIfNotBatching(renderer);
if (renderer->target) {
renderer->viewport_backup.x = 0;
renderer->viewport_backup.y = 0;
renderer->viewport_backup.w = (float) w;
renderer->viewport_backup.h = (float) h;
} else {
renderer->viewport.x = 0;
renderer->viewport.y = 0;
renderer->viewport.w = (float) w;
renderer->viewport.h = (float) h;
QueueCmdSetViewport(renderer);
FlushRenderCommandsIfNotBatching(renderer);
}
}
if (saved_target) {
@@ -771,7 +765,7 @@ SDL_RendererEventWatch(void *userdata, SDL_Event *event)
SDL_Window *window = SDL_GetWindowFromID(event->motion.windowID);
if (window == renderer->window) {
int logical_w, logical_h;
SDL_DRect viewport;
SDL_FRect viewport;
SDL_FPoint scale;
GetWindowViewportValues(renderer, &logical_w, &logical_h, &viewport, &scale);
if (logical_w) {
@@ -798,7 +792,7 @@ SDL_RendererEventWatch(void *userdata, SDL_Event *event)
SDL_Window *window = SDL_GetWindowFromID(event->button.windowID);
if (window == renderer->window) {
int logical_w, logical_h;
SDL_DRect viewport;
SDL_FRect viewport;
SDL_FPoint scale;
GetWindowViewportValues(renderer, &logical_w, &logical_h, &viewport, &scale);
if (logical_w) {
@@ -813,7 +807,7 @@ SDL_RendererEventWatch(void *userdata, SDL_Event *event)
event->type == SDL_FINGERMOTION) {
int logical_w, logical_h;
float physical_w, physical_h;
SDL_DRect viewport;
SDL_FRect viewport;
SDL_FPoint scale;
GetWindowViewportValues(renderer, &logical_w, &logical_h, &viewport, &scale);
@@ -936,7 +930,7 @@ SDL_CreateRenderer(SDL_Window * window, int index, Uint32 flags)
#endif
if (!window) {
SDL_InvalidParamError("window");
SDL_SetError("Invalid window");
goto error;
}
@@ -985,24 +979,24 @@ SDL_CreateRenderer(SDL_Window * window, int index, Uint32 flags)
}
}
}
if (!renderer) {
if (index == n) {
SDL_SetError("Couldn't find matching render driver");
goto error;
}
} else {
if (index >= n) {
if (index >= SDL_GetNumRenderDrivers()) {
SDL_SetError("index must be -1 or in the range of 0 - %d",
n - 1);
SDL_GetNumRenderDrivers() - 1);
goto error;
}
/* Create a new renderer instance */
renderer = render_drivers[index]->CreateRenderer(window, flags);
batching = SDL_FALSE;
if (!renderer) {
goto error;
}
}
if (!renderer) {
goto error;
}
VerifyDrawQueueFunctions(renderer);
@@ -1108,13 +1102,6 @@ SDL_GetRenderer(SDL_Window * window)
return (SDL_Renderer *)SDL_GetWindowData(window, SDL_WINDOWRENDERDATA);
}
SDL_Window *
SDL_RenderGetWindow(SDL_Renderer *renderer)
{
CHECK_RENDERER_MAGIC(renderer, NULL);
return renderer->window;
}
int
SDL_GetRendererInfo(SDL_Renderer * renderer, SDL_RendererInfo * info)
{
@@ -1339,7 +1326,7 @@ SDL_CreateTextureFromSurface(SDL_Renderer * renderer, SDL_Surface * surface)
CHECK_RENDERER_MAGIC(renderer, NULL);
if (!surface) {
SDL_InvalidParamError("SDL_CreateTextureFromSurface(): surface");
SDL_SetError("SDL_CreateTextureFromSurface() passed NULL surface");
return NULL;
}
@@ -1605,11 +1592,10 @@ SDL_SetTextureScaleMode(SDL_Texture * texture, SDL_ScaleMode scaleMode)
CHECK_TEXTURE_MAGIC(texture, -1);
renderer = texture->renderer;
renderer->SetTextureScaleMode(renderer, texture, scaleMode);
texture->scaleMode = scaleMode;
if (texture->native) {
return SDL_SetTextureScaleMode(texture->native, scaleMode);
} else {
renderer->SetTextureScaleMode(renderer, texture, scaleMode);
}
return 0;
}
@@ -2231,10 +2217,10 @@ SDL_SetRenderTarget(SDL_Renderer *renderer, SDL_Texture *texture)
}
if (texture) {
renderer->viewport.x = (double)0;
renderer->viewport.y = (double)0;
renderer->viewport.w = (double)texture->w;
renderer->viewport.h = (double)texture->h;
renderer->viewport.x = 0.0f;
renderer->viewport.y = 0.0f;
renderer->viewport.w = (float) texture->w;
renderer->viewport.h = (float) texture->h;
SDL_zero(renderer->clip_rect);
renderer->clipping_enabled = SDL_FALSE;
renderer->scale.x = 1.0f;
@@ -2266,8 +2252,6 @@ SDL_SetRenderTarget(SDL_Renderer *renderer, SDL_Texture *texture)
SDL_Texture *
SDL_GetRenderTarget(SDL_Renderer *renderer)
{
CHECK_RENDERER_MAGIC(renderer, NULL);
return renderer->target;
}
@@ -2443,19 +2427,19 @@ SDL_RenderSetViewport(SDL_Renderer * renderer, const SDL_Rect * rect)
CHECK_RENDERER_MAGIC(renderer, -1);
if (rect) {
renderer->viewport.x = (double)rect->x * renderer->scale.x;
renderer->viewport.y = (double)rect->y * renderer->scale.y;
renderer->viewport.w = (double)rect->w * renderer->scale.x;
renderer->viewport.h = (double)rect->h * renderer->scale.y;
renderer->viewport.x = rect->x * renderer->scale.x;
renderer->viewport.y = rect->y * renderer->scale.y;
renderer->viewport.w = rect->w * renderer->scale.x;
renderer->viewport.h = rect->h * renderer->scale.y;
} else {
int w, h;
if (SDL_GetRendererOutputSize(renderer, &w, &h) < 0) {
return -1;
}
renderer->viewport.x = (double)0;
renderer->viewport.y = (double)0;
renderer->viewport.w = (double)w;
renderer->viewport.h = (double)h;
renderer->viewport.x = 0.0f;
renderer->viewport.y = 0.0f;
renderer->viewport.w = (float) w;
renderer->viewport.h = (float) h;
}
retval = QueueCmdSetViewport(renderer);
return retval < 0 ? retval : FlushRenderCommandsIfNotBatching(renderer);
@@ -2479,8 +2463,8 @@ RenderGetViewportSize(SDL_Renderer * renderer, SDL_FRect * rect)
{
rect->x = 0.0f;
rect->y = 0.0f;
rect->w = (float)(renderer->viewport.w / renderer->scale.x);
rect->h = (float)(renderer->viewport.h / renderer->scale.y);
rect->w = renderer->viewport.w / renderer->scale.x;
rect->h = renderer->viewport.h / renderer->scale.y;
}
int
@@ -2491,10 +2475,10 @@ SDL_RenderSetClipRect(SDL_Renderer * renderer, const SDL_Rect * rect)
if (rect) {
renderer->clipping_enabled = SDL_TRUE;
renderer->clip_rect.x = (double)rect->x * renderer->scale.x;
renderer->clip_rect.y = (double)rect->y * renderer->scale.y;
renderer->clip_rect.w = (double)rect->w * renderer->scale.x;
renderer->clip_rect.h = (double)rect->h * renderer->scale.y;
renderer->clip_rect.x = rect->x * renderer->scale.x;
renderer->clip_rect.y = rect->y * renderer->scale.y;
renderer->clip_rect.w = rect->w * renderer->scale.x;
renderer->clip_rect.h = rect->h * renderer->scale.y;
} else {
renderer->clipping_enabled = SDL_FALSE;
SDL_zero(renderer->clip_rect);
@@ -2558,10 +2542,10 @@ SDL_RenderWindowToLogical(SDL_Renderer * renderer, int windowX, int windowY, flo
window_physical_y = ((float) windowY) / renderer->dpi_scale.y;
if (logicalX) {
*logicalX = (float)((window_physical_x - renderer->viewport.x) / renderer->scale.x);
*logicalX = (window_physical_x - renderer->viewport.x) / renderer->scale.x;
}
if (logicalY) {
*logicalY = (float)((window_physical_y - renderer->viewport.y) / renderer->scale.y);
*logicalY = (window_physical_y - renderer->viewport.y) / renderer->scale.y;
}
}
@@ -2572,8 +2556,8 @@ SDL_RenderLogicalToWindow(SDL_Renderer * renderer, float logicalX, float logical
CHECK_RENDERER_MAGIC(renderer, );
window_physical_x = (float)((logicalX * renderer->scale.x) + renderer->viewport.x);
window_physical_y = (float)((logicalY * renderer->scale.y) + renderer->viewport.y);
window_physical_x = (logicalX * renderer->scale.x) + renderer->viewport.x;
window_physical_y = (logicalY * renderer->scale.y) + renderer->viewport.y;
if (windowX) {
*windowX = (int)(window_physical_x * renderer->dpi_scale.x);
@@ -2673,16 +2657,11 @@ static int
RenderDrawPointsWithRects(SDL_Renderer * renderer,
const SDL_Point * points, const int count)
{
int retval;
int retval = -1;
SDL_bool isstack;
SDL_FRect *frects;
SDL_FRect *frects = SDL_small_alloc(SDL_FRect, count, &isstack);
int i;
if (count < 1) {
return 0;
}
frects = SDL_small_alloc(SDL_FRect, count, &isstack);
if (!frects) {
return SDL_OutOfMemory();
}
@@ -2694,7 +2673,9 @@ RenderDrawPointsWithRects(SDL_Renderer * renderer,
frects[i].h = renderer->scale.y;
}
retval = QueueCmdFillRects(renderer, frects, count);
if (count) {
retval = QueueCmdFillRects(renderer, frects, count);
}
SDL_small_free(frects, isstack);
@@ -2713,7 +2694,7 @@ SDL_RenderDrawPoints(SDL_Renderer * renderer,
CHECK_RENDERER_MAGIC(renderer, -1);
if (!points) {
return SDL_InvalidParamError("SDL_RenderDrawPoints(): points");
return SDL_SetError("SDL_RenderDrawPoints(): Passed NULL points");
}
if (count < 1) {
return 0;
@@ -2749,16 +2730,11 @@ static int
RenderDrawPointsWithRectsF(SDL_Renderer * renderer,
const SDL_FPoint * fpoints, const int count)
{
int retval;
int retval = -1;
SDL_bool isstack;
SDL_FRect *frects;
SDL_FRect *frects = SDL_small_alloc(SDL_FRect, count, &isstack);
int i;
if (count < 1) {
return 0;
}
frects = SDL_small_alloc(SDL_FRect, count, &isstack);
if (!frects) {
return SDL_OutOfMemory();
}
@@ -2770,7 +2746,9 @@ RenderDrawPointsWithRectsF(SDL_Renderer * renderer,
frects[i].h = renderer->scale.y;
}
retval = QueueCmdFillRects(renderer, frects, count);
if (count) {
retval = QueueCmdFillRects(renderer, frects, count);
}
SDL_small_free(frects, isstack);
@@ -2786,7 +2764,7 @@ SDL_RenderDrawPointsF(SDL_Renderer * renderer,
CHECK_RENDERER_MAGIC(renderer, -1);
if (!points) {
return SDL_InvalidParamError("SDL_RenderDrawPointsF(): points");
return SDL_SetError("SDL_RenderDrawPointsF(): Passed NULL points");
}
if (count < 1) {
return 0;
@@ -2995,7 +2973,7 @@ SDL_RenderDrawLines(SDL_Renderer * renderer,
CHECK_RENDERER_MAGIC(renderer, -1);
if (!points) {
return SDL_InvalidParamError("SDL_RenderDrawLines(): points");
return SDL_SetError("SDL_RenderDrawLines(): Passed NULL points");
}
if (count < 2) {
return 0;
@@ -3034,7 +3012,7 @@ SDL_RenderDrawLinesF(SDL_Renderer * renderer,
CHECK_RENDERER_MAGIC(renderer, -1);
if (!points) {
return SDL_InvalidParamError("SDL_RenderDrawLinesF(): points");
return SDL_SetError("SDL_RenderDrawLinesF(): Passed NULL points");
}
if (count < 2) {
return 0;
@@ -3167,11 +3145,10 @@ SDL_RenderDrawLinesF(SDL_Renderer * renderer,
num_vertices, indices, num_indices, size_indices,
1.0f, 1.0f);
SDL_small_free(xy, isstack1);
SDL_small_free(indices, isstack2);
}
SDL_small_free(xy, isstack1);
SDL_small_free(indices, isstack2);
} else if (renderer->scale.x != 1.0f || renderer->scale.y != 1.0f) {
retval = RenderDrawLinesWithRectsF(renderer, points, count);
} else {
@@ -3234,7 +3211,7 @@ SDL_RenderDrawRects(SDL_Renderer * renderer,
CHECK_RENDERER_MAGIC(renderer, -1);
if (!rects) {
return SDL_InvalidParamError("SDL_RenderDrawRects(): rects");
return SDL_SetError("SDL_RenderDrawRects(): Passed NULL rects");
}
if (count < 1) {
return 0;
@@ -3264,7 +3241,7 @@ SDL_RenderDrawRectsF(SDL_Renderer * renderer,
CHECK_RENDERER_MAGIC(renderer, -1);
if (!rects) {
return SDL_InvalidParamError("SDL_RenderDrawRectsF(): rects");
return SDL_SetError("SDL_RenderDrawRects(): Passed NULL rects");
}
if (count < 1) {
return 0;
@@ -3331,7 +3308,7 @@ SDL_RenderFillRects(SDL_Renderer * renderer,
CHECK_RENDERER_MAGIC(renderer, -1);
if (!rects) {
return SDL_InvalidParamError("SDL_RenderFillRects(): rects");
return SDL_SetError("SDL_RenderFillRects(): Passed NULL rects");
}
if (count < 1) {
return 0;
@@ -3374,7 +3351,7 @@ SDL_RenderFillRectsF(SDL_Renderer * renderer,
CHECK_RENDERER_MAGIC(renderer, -1);
if (!rects) {
return SDL_InvalidParamError("SDL_RenderFillRectsF(): rects");
return SDL_SetError("SDL_RenderFillFRects(): Passed NULL rects");
}
if (count < 1) {
return 0;
@@ -3405,6 +3382,60 @@ SDL_RenderFillRectsF(SDL_Renderer * renderer,
return retval < 0 ? retval : FlushRenderCommandsIfNotBatching(renderer);
}
/* !!! FIXME: move this to a public API if we want to do float versions of all of these later */
SDL_FORCE_INLINE SDL_bool SDL_FRectEmpty(const SDL_FRect *r)
{
return ((!r) || (r->w <= 0.0f) || (r->h <= 0.0f)) ? SDL_TRUE : SDL_FALSE;
}
/* !!! FIXME: move this to a public API if we want to do float versions of all of these later */
static SDL_bool
SDL_HasIntersectionF(const SDL_FRect * A, const SDL_FRect * B)
{
float Amin, Amax, Bmin, Bmax;
if (!A) {
SDL_InvalidParamError("A");
return SDL_FALSE;
}
if (!B) {
SDL_InvalidParamError("B");
return SDL_FALSE;
}
/* Special cases for empty rects */
if (SDL_FRectEmpty(A) || SDL_FRectEmpty(B)) {
return SDL_FALSE;
}
/* Horizontal intersection */
Amin = A->x;
Amax = Amin + A->w;
Bmin = B->x;
Bmax = Bmin + B->w;
if (Bmin > Amin)
Amin = Bmin;
if (Bmax < Amax)
Amax = Bmax;
if (Amax <= Amin)
return SDL_FALSE;
/* Vertical intersection */
Amin = A->y;
Amax = Amin + A->h;
Bmin = B->y;
Bmax = Bmin + B->h;
if (Bmin > Amin)
Amin = Bmin;
if (Bmax < Amax)
Amax = Bmax;
if (Amax <= Amin)
return SDL_FALSE;
return SDL_TRUE;
}
int
SDL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
const SDL_Rect * srcrect, const SDL_Rect * dstrect)
@@ -3703,7 +3734,15 @@ SDL_RenderCopyExF(SDL_Renderer * renderer, SDL_Texture * texture,
renderer->scale.x, renderer->scale.y);
} else {
retval = QueueCmdCopyEx(renderer, texture, &real_srcrect, &real_dstrect, angle, &real_center, flip, renderer->scale.x, renderer->scale.y);
real_dstrect.x *= renderer->scale.x;
real_dstrect.y *= renderer->scale.y;
real_dstrect.w *= renderer->scale.x;
real_dstrect.h *= renderer->scale.y;
real_center.x *= renderer->scale.x;
real_center.y *= renderer->scale.y;
retval = QueueCmdCopyEx(renderer, texture, &real_srcrect, &real_dstrect, angle, &real_center, flip);
}
return retval < 0 ? retval : FlushRenderCommandsIfNotBatching(renderer);
}
@@ -4007,23 +4046,7 @@ SDL_SW_RenderGeometryRaw(SDL_Renderer *renderer,
if (texture && s.w != 0 && s.h != 0) {
SDL_SetTextureAlphaMod(texture, col0_.a);
SDL_SetTextureColorMod(texture, col0_.r, col0_.g, col0_.b);
if (s.w > 0 && s.h > 0) {
SDL_RenderCopyF(renderer, texture, &s, &d);
} else {
int flags = 0;
if (s.w < 0) {
flags |= SDL_FLIP_HORIZONTAL;
s.w *= -1;
s.x -= s.w;
}
if (s.h < 0) {
flags |= SDL_FLIP_VERTICAL;
s.h *= -1;
s.y -= s.h;
}
SDL_RenderCopyExF(renderer, texture, &s, &d, 0, NULL, flags);
}
SDL_RenderCopyF(renderer, texture, &s, &d);
#if DEBUG_SW_RENDER_GEOMETRY
SDL_Log("Rect-COPY: RGB %d %d %d - Alpha:%d - texture=%p: src=(%d,%d, %d x %d) dst (%f, %f, %f x %f)", col0_.r, col0_.g, col0_.b, col0_.a,
(void *)texture, s.x, s.y, s.w, s.h, d.x, d.y, d.w, d.h);
@@ -4033,8 +4056,8 @@ SDL_SW_RenderGeometryRaw(SDL_Renderer *renderer,
SDL_SetRenderDrawColor(renderer, col0_.r, col0_.g, col0_.b, col0_.a);
SDL_RenderFillRectF(renderer, &d);
#if DEBUG_SW_RENDER_GEOMETRY
SDL_Log("Rect-FILL: RGB %d %d %d - Alpha:%d - texture=%p: dst (%f, %f, %f x %f)", col0_.r, col0_.g, col0_.b, col0_.a,
(void *)texture, d.x, d.y, d.w, d.h);
SDL_Log("Rect-FILL: RGB %d %d %d - Alpha:%d - texture=%p: src=(%d,%d, %d x %d) dst (%f, %f, %f x %f)", col0_.r, col0_.g, col0_.b, col0_.a,
(void *)texture, s.x, s.y, s.w, s.h, d.x, d.y, d.w, d.h);
} else {
SDL_Log("Rect-DISMISS: RGB %d %d %d - Alpha:%d - texture=%p: src=(%d,%d, %d x %d) dst (%f, %f, %f x %f)", col0_.r, col0_.g, col0_.b, col0_.a,
(void *)texture, s.x, s.y, s.w, s.h, d.x, d.y, d.w, d.h);
@@ -4216,11 +4239,7 @@ SDL_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
FlushRenderCommands(renderer); /* we need to render before we read the results. */
if (!format) {
if (renderer->target == NULL) {
format = SDL_GetWindowPixelFormat(renderer->window);
} else {
format = renderer->target->format;
}
format = SDL_GetWindowPixelFormat(renderer->window);
}
real_rect.x = (int)SDL_floor(renderer->viewport.x);

View File

@@ -28,19 +28,6 @@
#include "SDL_mutex.h"
#include "SDL_yuv_sw_c.h"
/**
* A rectangle, with the origin at the upper left (double precision).
*/
typedef struct SDL_DRect
{
double x;
double y;
double w;
double h;
} SDL_DRect;
/* The SDL 2D rendering system */
typedef struct SDL_RenderDriver SDL_RenderDriver;
@@ -156,7 +143,7 @@ struct SDL_Renderer
const SDL_Rect * srcrect, const SDL_FRect * dstrect);
int (*QueueCopyEx) (SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * texture,
const SDL_Rect * srcquad, const SDL_FRect * dstrect,
const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip, float scale_x, float scale_y);
const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip);
int (*QueueGeometry) (SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture,
const float *xy, int xy_stride, const SDL_Color *color, int color_stride, const float *uv, int uv_stride,
int num_vertices, const void *indices, int num_indices, int size_indices,
@@ -214,12 +201,12 @@ struct SDL_Renderer
SDL_bool integer_scale;
/* The drawable area within the window */
SDL_DRect viewport;
SDL_DRect viewport_backup;
SDL_FRect viewport;
SDL_FRect viewport_backup;
/* The clip rectangle within the window */
SDL_DRect clip_rect;
SDL_DRect clip_rect_backup;
SDL_FRect clip_rect;
SDL_FRect clip_rect_backup;
/* Wether or not the clipping rectangle is used. */
SDL_bool clipping_enabled;
@@ -257,8 +244,8 @@ struct SDL_Renderer
SDL_RenderCommand *render_commands_pool;
Uint32 render_command_generation;
Uint32 last_queued_color;
SDL_DRect last_queued_viewport;
SDL_DRect last_queued_cliprect;
SDL_FRect last_queued_viewport;
SDL_FRect last_queued_cliprect;
SDL_bool last_queued_cliprect_enabled;
SDL_bool color_queued;
SDL_bool viewport_queued;
@@ -283,7 +270,6 @@ struct SDL_RenderDriver
/* Not all of these are available in a given build. Use #ifdefs, etc. */
extern SDL_RenderDriver D3D_RenderDriver;
extern SDL_RenderDriver D3D11_RenderDriver;
extern SDL_RenderDriver D3D12_RenderDriver;
extern SDL_RenderDriver GL_RenderDriver;
extern SDL_RenderDriver GLES2_RenderDriver;
extern SDL_RenderDriver GLES_RenderDriver;

View File

@@ -41,13 +41,6 @@
#include "SDL_shaders_d3d.h"
#ifdef __WATCOMC__
/* FIXME: Remove this once https://github.com/open-watcom/open-watcom-v2/pull/868 is merged */
#define D3DBLENDOP_REVSUBTRACT 3
/* FIXME: Remove this once https://github.com/open-watcom/open-watcom-v2/pull/869 is merged */
#define D3DERR_UNSUPPORTEDCOLOROPERATION MAKE_D3DHRESULT( 2073 )
#endif
typedef struct
{
SDL_Rect viewport;
@@ -78,9 +71,7 @@ typedef struct
IDirect3DSurface9 *defaultRenderTarget;
IDirect3DSurface9 *currentRenderTarget;
void* d3dxDLL;
#if SDL_HAVE_YUV
LPDIRECT3DPIXELSHADER9 shaders[NUM_SHADERS];
#endif
LPDIRECT3DVERTEXBUFFER9 vertexBuffers[8];
size_t vertexBufferSize[8];
int currentVertexBuffer;
@@ -104,7 +95,6 @@ typedef struct
D3D_TextureRep texture;
D3DTEXTUREFILTERTYPE scaleMode;
#if SDL_HAVE_YUV
/* YV12 texture support */
SDL_bool yuv;
D3D_TextureRep utexture;
@@ -112,7 +102,6 @@ typedef struct
Uint8 *pixels;
int pitch;
SDL_Rect locked_rect;
#endif
} D3D_TextureData;
typedef struct
@@ -308,7 +297,7 @@ D3D_ActivateRenderer(SDL_Renderer * renderer)
int w, h;
Uint32 window_flags = SDL_GetWindowFlags(window);
WIN_GetDrawableSize(window, &w, &h);
SDL_GetWindowSize(window, &w, &h);
data->pparams.BackBufferWidth = w;
data->pparams.BackBufferHeight = h;
if (window_flags & SDL_WINDOW_FULLSCREEN && (window_flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != SDL_WINDOW_FULLSCREEN_DESKTOP) {
@@ -354,15 +343,7 @@ D3D_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event)
}
}
static int
D3D_GetOutputSize(SDL_Renderer * renderer, int *w, int *h)
{
WIN_GetDrawableSize(renderer->window, w, h);
return 0;
}
static D3DBLEND
GetBlendFunc(SDL_BlendFactor factor)
static D3DBLEND GetBlendFunc(SDL_BlendFactor factor)
{
switch (factor) {
case SDL_BLENDFACTOR_ZERO:
@@ -385,28 +366,9 @@ GetBlendFunc(SDL_BlendFactor factor)
return D3DBLEND_DESTALPHA;
case SDL_BLENDFACTOR_ONE_MINUS_DST_ALPHA:
return D3DBLEND_INVDESTALPHA;
default: break;
default:
return (D3DBLEND)0;
}
return (D3DBLEND) 0;
}
static D3DBLENDOP
GetBlendEquation(SDL_BlendOperation operation)
{
switch (operation) {
case SDL_BLENDOPERATION_ADD:
return D3DBLENDOP_ADD;
case SDL_BLENDOPERATION_SUBTRACT:
return D3DBLENDOP_SUBTRACT;
case SDL_BLENDOPERATION_REV_SUBTRACT:
return D3DBLENDOP_REVSUBTRACT;
case SDL_BLENDOPERATION_MINIMUM:
return D3DBLENDOP_MIN;
case SDL_BLENDOPERATION_MAXIMUM:
return D3DBLENDOP_MAX;
default: break;
}
return (D3DBLENDOP) 0;
}
static SDL_bool
@@ -421,16 +383,14 @@ D3D_SupportsBlendMode(SDL_Renderer * renderer, SDL_BlendMode blendMode)
SDL_BlendOperation alphaOperation = SDL_GetBlendModeAlphaOperation(blendMode);
if (!GetBlendFunc(srcColorFactor) || !GetBlendFunc(srcAlphaFactor) ||
!GetBlendEquation(colorOperation) ||
!GetBlendFunc(dstColorFactor) || !GetBlendFunc(dstAlphaFactor) ||
!GetBlendEquation(alphaOperation)) {
!GetBlendFunc(dstColorFactor) || !GetBlendFunc(dstAlphaFactor)) {
return SDL_FALSE;
}
if (!data->enableSeparateAlphaBlend) {
if ((srcColorFactor != srcAlphaFactor) || (dstColorFactor != dstAlphaFactor) || (colorOperation != alphaOperation)) {
return SDL_FALSE;
}
if ((srcColorFactor != srcAlphaFactor || dstColorFactor != dstAlphaFactor) && !data->enableSeparateAlphaBlend) {
return SDL_FALSE;
}
if (colorOperation != SDL_BLENDOPERATION_ADD || alphaOperation != SDL_BLENDOPERATION_ADD) {
return SDL_FALSE;
}
return SDL_TRUE;
}
@@ -574,7 +534,7 @@ D3D_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
if (D3D_CreateTextureRep(data->device, &texturedata->texture, usage, texture->format, PixelFormatToD3DFMT(texture->format), texture->w, texture->h) < 0) {
return -1;
}
#if SDL_HAVE_YUV
if (texture->format == SDL_PIXELFORMAT_YV12 ||
texture->format == SDL_PIXELFORMAT_IYUV) {
texturedata->yuv = SDL_TRUE;
@@ -587,7 +547,6 @@ D3D_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
return -1;
}
}
#endif
return 0;
}
@@ -604,7 +563,7 @@ D3D_RecreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
if (D3D_RecreateTextureRep(data->device, &texturedata->texture) < 0) {
return -1;
}
#if SDL_HAVE_YUV
if (texturedata->yuv) {
if (D3D_RecreateTextureRep(data->device, &texturedata->utexture) < 0) {
return -1;
@@ -614,7 +573,6 @@ D3D_RecreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
return -1;
}
}
#endif
return 0;
}
@@ -626,13 +584,14 @@ D3D_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
D3D_TextureData *texturedata = (D3D_TextureData *) texture->driverdata;
if (!texturedata) {
return SDL_SetError("Texture is not currently available");
SDL_SetError("Texture is not currently available");
return -1;
}
if (D3D_UpdateTextureRep(data->device, &texturedata->texture, rect->x, rect->y, rect->w, rect->h, pixels, pitch) < 0) {
return -1;
}
#if SDL_HAVE_YUV
if (texturedata->yuv) {
/* Skip to the correct offset into the next texture */
pixels = (const void*)((const Uint8*)pixels + rect->h * pitch);
@@ -647,7 +606,6 @@ D3D_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
return -1;
}
}
#endif
return 0;
}
@@ -663,7 +621,8 @@ D3D_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * texture,
D3D_TextureData *texturedata = (D3D_TextureData *) texture->driverdata;
if (!texturedata) {
return SDL_SetError("Texture is not currently available");
SDL_SetError("Texture is not currently available");
return -1;
}
if (D3D_UpdateTextureRep(data->device, &texturedata->texture, rect->x, rect->y, rect->w, rect->h, Yplane, Ypitch) < 0) {
@@ -688,9 +647,10 @@ D3D_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
IDirect3DDevice9 *device = data->device;
if (!texturedata) {
return SDL_SetError("Texture is not currently available");
SDL_SetError("Texture is not currently available");
return -1;
}
#if SDL_HAVE_YUV
texturedata->locked_rect = *rect;
if (texturedata->yuv) {
@@ -706,9 +666,7 @@ D3D_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
(void *) ((Uint8 *) texturedata->pixels + rect->y * texturedata->pitch +
rect->x * SDL_BYTESPERPIXEL(texture->format));
*pitch = texturedata->pitch;
} else
#endif
{
} else {
RECT d3drect;
D3DLOCKED_RECT locked;
HRESULT result;
@@ -741,17 +699,14 @@ D3D_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
if (!texturedata) {
return;
}
#if SDL_HAVE_YUV
if (texturedata->yuv) {
const SDL_Rect *rect = &texturedata->locked_rect;
void *pixels =
(void *) ((Uint8 *) texturedata->pixels + rect->y * texturedata->pitch +
rect->x * SDL_BYTESPERPIXEL(texture->format));
D3D_UpdateTexture(renderer, texture, rect, pixels, texturedata->pitch);
}
else
#endif
{
} else {
IDirect3DTexture9_UnlockRect(texturedata->texture.staging, 0);
texturedata->texture.dirty = SDL_TRUE;
if (data->drawstate.texture == texture) {
@@ -759,6 +714,10 @@ D3D_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
data->drawstate.shader = NULL;
IDirect3DDevice9_SetPixelShader(data->device, NULL);
IDirect3DDevice9_SetTexture(data->device, 0, NULL);
if (texturedata->yuv) {
IDirect3DDevice9_SetTexture(data->device, 1, NULL);
IDirect3DDevice9_SetTexture(data->device, 2, NULL);
}
}
}
}
@@ -797,7 +756,8 @@ D3D_SetRenderTargetInternal(SDL_Renderer * renderer, SDL_Texture * texture)
texturedata = (D3D_TextureData *)texture->driverdata;
if (!texturedata) {
return SDL_SetError("Texture is not currently available");
SDL_SetError("Texture is not currently available");
return -1;
}
/* Make sure the render target is updated if it was locked and written to */
@@ -982,7 +942,8 @@ SetupTextureState(D3D_RenderData *data, SDL_Texture * texture, LPDIRECT3DPIXELSH
SDL_assert(*shader == NULL);
if (!texturedata) {
return SDL_SetError("Texture is not currently available");
SDL_SetError("Texture is not currently available");
return -1;
}
UpdateTextureScaleMode(data, texturedata, 0);
@@ -990,7 +951,7 @@ SetupTextureState(D3D_RenderData *data, SDL_Texture * texture, LPDIRECT3DPIXELSH
if (BindTextureRep(data->device, &texturedata->texture, 0) < 0) {
return -1;
}
#if SDL_HAVE_YUV
if (texturedata->yuv) {
switch (SDL_GetYUVConversionModeForResolution(texture->w, texture->h)) {
case SDL_YUV_CONVERSION_JPEG:
@@ -1016,7 +977,6 @@ SetupTextureState(D3D_RenderData *data, SDL_Texture * texture, LPDIRECT3DPIXELSH
return -1;
}
}
#endif
return 0;
}
@@ -1027,22 +987,18 @@ SetDrawState(D3D_RenderData *data, const SDL_RenderCommand *cmd)
const SDL_BlendMode blend = cmd->data.draw.blend;
if (texture != data->drawstate.texture) {
#if SDL_HAVE_YUV
D3D_TextureData *oldtexturedata = data->drawstate.texture ? (D3D_TextureData *) data->drawstate.texture->driverdata : NULL;
D3D_TextureData *newtexturedata = texture ? (D3D_TextureData *) texture->driverdata : NULL;
#endif
LPDIRECT3DPIXELSHADER9 shader = NULL;
/* disable any enabled textures we aren't going to use, let SetupTextureState() do the rest. */
if (texture == NULL) {
IDirect3DDevice9_SetTexture(data->device, 0, NULL);
}
#if SDL_HAVE_YUV
if ((!newtexturedata || !newtexturedata->yuv) && (oldtexturedata && oldtexturedata->yuv)) {
IDirect3DDevice9_SetTexture(data->device, 1, NULL);
IDirect3DDevice9_SetTexture(data->device, 2, NULL);
}
#endif
if (texture && SetupTextureState(data, texture, &shader) < 0) {
return -1;
}
@@ -1059,12 +1015,10 @@ SetDrawState(D3D_RenderData *data, const SDL_RenderCommand *cmd)
} else if (texture) {
D3D_TextureData *texturedata = (D3D_TextureData *) texture->driverdata;
UpdateDirtyTexture(data->device, &texturedata->texture);
#if SDL_HAVE_YUV
if (texturedata->yuv) {
UpdateDirtyTexture(data->device, &texturedata->utexture);
UpdateDirtyTexture(data->device, &texturedata->vtexture);
}
#endif
}
if (blend != data->drawstate.blend) {
@@ -1076,15 +1030,11 @@ SetDrawState(D3D_RenderData *data, const SDL_RenderCommand *cmd)
GetBlendFunc(SDL_GetBlendModeSrcColorFactor(blend)));
IDirect3DDevice9_SetRenderState(data->device, D3DRS_DESTBLEND,
GetBlendFunc(SDL_GetBlendModeDstColorFactor(blend)));
IDirect3DDevice9_SetRenderState(data->device, D3DRS_BLENDOP,
GetBlendEquation(SDL_GetBlendModeColorOperation(blend)));
if (data->enableSeparateAlphaBlend) {
IDirect3DDevice9_SetRenderState(data->device, D3DRS_SRCBLENDALPHA,
GetBlendFunc(SDL_GetBlendModeSrcAlphaFactor(blend)));
IDirect3DDevice9_SetRenderState(data->device, D3DRS_DESTBLENDALPHA,
GetBlendFunc(SDL_GetBlendModeDstAlphaFactor(blend)));
IDirect3DDevice9_SetRenderState(data->device, D3DRS_BLENDOPALPHA,
GetBlendEquation(SDL_GetBlendModeAlphaOperation(blend)));
}
}
@@ -1093,13 +1043,7 @@ SetDrawState(D3D_RenderData *data, const SDL_RenderCommand *cmd)
if (data->drawstate.viewport_dirty) {
const SDL_Rect *viewport = &data->drawstate.viewport;
D3DVIEWPORT9 d3dviewport;
d3dviewport.X = viewport->x;
d3dviewport.Y = viewport->y;
d3dviewport.Width = viewport->w;
d3dviewport.Height = viewport->h;
d3dviewport.MinZ = 0.0f;
d3dviewport.MaxZ = 1.0f;
const D3DVIEWPORT9 d3dviewport = { viewport->x, viewport->y, viewport->w, viewport->h, 0.0f, 1.0f };
IDirect3DDevice9_SetViewport(data->device, &d3dviewport);
/* Set an orthographic projection matrix */
@@ -1126,11 +1070,7 @@ SetDrawState(D3D_RenderData *data, const SDL_RenderCommand *cmd)
if (data->drawstate.cliprect_dirty) {
const SDL_Rect *viewport = &data->drawstate.viewport;
const SDL_Rect *rect = &data->drawstate.cliprect;
RECT d3drect;
d3drect.left = viewport->x + rect->x;
d3drect.top = viewport->y + rect->y;
d3drect.right = viewport->x + rect->x + rect->w;
d3drect.bottom = viewport->y + rect->y + rect->h;
const RECT d3drect = { viewport->x + rect->x, viewport->y + rect->y, viewport->x + rect->x + rect->w, viewport->y + rect->y + rect->h };
IDirect3DDevice9_SetScissorRect(data->device, &d3drect);
data->drawstate.cliprect_dirty = SDL_FALSE;
}
@@ -1245,9 +1185,7 @@ D3D_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *verti
IDirect3DDevice9_Clear(data->device, 0, NULL, D3DCLEAR_TARGET, color, 0.0f, 0);
} else {
/* Clear is defined to clear the entire render target */
D3DVIEWPORT9 wholeviewport = { 0, 0, 0, 0, 0.0f, 1.0f };
wholeviewport.Width = backw;
wholeviewport.Height = backh;
const D3DVIEWPORT9 wholeviewport = { 0, 0, backw, backh, 0.0f, 1.0f };
IDirect3DDevice9_SetViewport(data->device, &wholeviewport);
data->drawstate.viewport_dirty = SDL_TRUE; /* we still need to (re)set orthographic projection, so always mark it dirty. */
IDirect3DDevice9_Clear(data->device, 0, NULL, D3DCLEAR_TARGET, color, 0.0f, 0);
@@ -1338,7 +1276,6 @@ D3D_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
RECT d3drect;
D3DLOCKED_RECT locked;
HRESULT result;
int status;
if (data->currentRenderTarget) {
backBuffer = data->currentRenderTarget;
@@ -1373,7 +1310,7 @@ D3D_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
return D3D_SetError("LockRect()", result);
}
status = SDL_ConvertPixels(rect->w, rect->h,
SDL_ConvertPixels(rect->w, rect->h,
D3DFMTToPixelFormat(desc.Format), locked.pBits, locked.Pitch,
format, pixels, pitch);
@@ -1381,7 +1318,7 @@ D3D_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
IDirect3DSurface9_Release(surface);
return status;
return 0;
}
static void
@@ -1420,12 +1357,10 @@ D3D_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture)
renderdata->drawstate.shader = NULL;
IDirect3DDevice9_SetPixelShader(renderdata->device, NULL);
IDirect3DDevice9_SetTexture(renderdata->device, 0, NULL);
#if SDL_HAVE_YUV
if (data->yuv) {
IDirect3DDevice9_SetTexture(renderdata->device, 1, NULL);
IDirect3DDevice9_SetTexture(renderdata->device, 2, NULL);
}
#endif
}
if (!data) {
@@ -1433,11 +1368,9 @@ D3D_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture)
}
D3D_DestroyTextureRep(&data->texture);
#if SDL_HAVE_YUV
D3D_DestroyTextureRep(&data->utexture);
D3D_DestroyTextureRep(&data->vtexture);
SDL_free(data->pixels);
#endif
SDL_free(data);
texture->driverdata = NULL;
}
@@ -1459,14 +1392,12 @@ D3D_DestroyRenderer(SDL_Renderer * renderer)
IDirect3DSurface9_Release(data->currentRenderTarget);
data->currentRenderTarget = NULL;
}
#if SDL_HAVE_YUV
for (i = 0; i < SDL_arraysize(data->shaders); ++i) {
if (data->shaders[i]) {
IDirect3DPixelShader9_Release(data->shaders[i]);
data->shaders[i] = NULL;
}
}
#endif
/* Release all vertex buffers */
for (i = 0; i < SDL_arraysize(data->vertexBuffers); ++i) {
if (data->vertexBuffers[i]) {
@@ -1623,7 +1554,6 @@ D3D_CreateRenderer(SDL_Window * window, Uint32 flags)
}
renderer->WindowEvent = D3D_WindowEvent;
renderer->GetOutputSize = D3D_GetOutputSize;
renderer->SupportsBlendMode = D3D_SupportsBlendMode;
renderer->CreateTexture = D3D_CreateTexture;
renderer->UpdateTexture = D3D_UpdateTexture;
@@ -1653,7 +1583,7 @@ D3D_CreateRenderer(SDL_Window * window, Uint32 flags)
SDL_GetWindowWMInfo(window, &windowinfo);
window_flags = SDL_GetWindowFlags(window);
WIN_GetDrawableSize(window, &w, &h);
SDL_GetWindowSize(window, &w, &h);
SDL_GetWindowDisplayMode(window, &fullscreen_mode);
SDL_zero(pparams);
@@ -1740,7 +1670,7 @@ D3D_CreateRenderer(SDL_Window * window, Uint32 flags)
/* Set up parameters for rendering */
D3D_InitRenderState(data);
#if SDL_HAVE_YUV
if (caps.MaxSimultaneousTextures >= 3) {
int i;
for (i = 0; i < SDL_arraysize(data->shaders); ++i) {
@@ -1754,10 +1684,7 @@ D3D_CreateRenderer(SDL_Window * window, Uint32 flags)
renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_IYUV;
}
}
#endif
data->drawstate.viewport_dirty = SDL_TRUE;
data->drawstate.cliprect_dirty = SDL_TRUE;
data->drawstate.cliprect_enabled_dirty = SDL_TRUE;
data->drawstate.blend = SDL_BLENDMODE_INVALID;
return renderer;

View File

@@ -27,9 +27,6 @@
#define COBJMACROS
#include "../../core/windows/SDL_windows.h"
#if !defined(__WINRT__)
#include "../../video/windows/SDL_windowswindow.h"
#endif
#include "SDL_hints.h"
#include "SDL_loadso.h"
#include "SDL_syswm.h"
@@ -94,7 +91,7 @@ typedef struct
int lockedTexturePositionX;
int lockedTexturePositionY;
D3D11_FILTER scaleMode;
#if SDL_HAVE_YUV
/* YV12 texture support */
SDL_bool yuv;
ID3D11Texture2D *mainTextureU;
@@ -110,7 +107,6 @@ typedef struct
Uint8 *pixels;
int pitch;
SDL_Rect locked_rect;
#endif
} D3D11_TextureData;
/* Blend mode data */
@@ -491,11 +487,6 @@ D3D11_CreateDeviceResources(SDL_Renderer * renderer)
creationFlags |= D3D11_CREATE_DEVICE_DEBUG;
}
/* Create a single-threaded device unless the app requests otherwise. */
if (!SDL_GetHintBoolean(SDL_HINT_RENDER_DIRECT3D_THREADSAFE, SDL_FALSE)) {
creationFlags |= D3D11_CREATE_DEVICE_SINGLETHREADED;
}
/* Create the Direct3D 11 API device object and a corresponding context. */
result = D3D11CreateDeviceFunc(
data->dxgiAdapter,
@@ -913,11 +904,7 @@ D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer)
/* The width and height of the swap chain must be based on the display's
* non-rotated size.
*/
#if defined(__WINRT__)
SDL_GetWindowSize(renderer->window, &w, &h);
#else
WIN_GetDrawableSize(renderer->window, &w, &h);
#endif
data->rotation = D3D11_GetCurrentRotation();
/* SDL_Log("%s: windowSize={%d,%d}, orientation=%d\n", __FUNCTION__, w, h, (int)data->rotation); */
if (D3D11_IsDisplayRotated90Degrees(data->rotation)) {
@@ -1005,16 +992,6 @@ D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer)
goto done;
}
/* Set the swap chain target immediately, so that a target is always set
* even before we get to SetDrawState. Without this it's possible to hit
* null references in places like ReadPixels!
*/
ID3D11DeviceContext_OMSetRenderTargets(data->d3dContext,
1,
&data->mainRenderTargetView,
NULL
);
data->viewportDirty = SDL_TRUE;
done:
@@ -1058,15 +1035,6 @@ D3D11_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event)
}
}
#if !defined(__WINRT__)
static int
D3D11_GetOutputSize(SDL_Renderer * renderer, int *w, int *h)
{
WIN_GetDrawableSize(renderer->window, w, h);
return 0;
}
#endif
static SDL_bool
D3D11_SupportsBlendMode(SDL_Renderer * renderer, SDL_BlendMode blendMode)
{
@@ -1141,9 +1109,10 @@ D3D11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
);
if (FAILED(result)) {
D3D11_DestroyTexture(renderer, texture);
return WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateTexture2D"), result);
WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateTexture2D"), result);
return -1;
}
#if SDL_HAVE_YUV
if (texture->format == SDL_PIXELFORMAT_YV12 ||
texture->format == SDL_PIXELFORMAT_IYUV) {
textureData->yuv = SDL_TRUE;
@@ -1158,7 +1127,8 @@ D3D11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
);
if (FAILED(result)) {
D3D11_DestroyTexture(renderer, texture);
return WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateTexture2D"), result);
WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateTexture2D"), result);
return -1;
}
result = ID3D11Device_CreateTexture2D(rendererData->d3dDevice,
@@ -1168,7 +1138,8 @@ D3D11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
);
if (FAILED(result)) {
D3D11_DestroyTexture(renderer, texture);
return WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateTexture2D"), result);
WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateTexture2D"), result);
return -1;
}
}
@@ -1189,11 +1160,11 @@ D3D11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
);
if (FAILED(result)) {
D3D11_DestroyTexture(renderer, texture);
return WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateTexture2D"), result);
WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateTexture2D"), result);
return -1;
}
}
#endif /* SDL_HAVE_YUV */
SDL_zero(resourceViewDesc);
resourceViewDesc.Format = textureDesc.Format;
resourceViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
resourceViewDesc.Texture2D.MostDetailedMip = 0;
@@ -1205,9 +1176,10 @@ D3D11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
);
if (FAILED(result)) {
D3D11_DestroyTexture(renderer, texture);
return WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateShaderResourceView"), result);
WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateShaderResourceView"), result);
return -1;
}
#if SDL_HAVE_YUV
if (textureData->yuv) {
result = ID3D11Device_CreateShaderResourceView(rendererData->d3dDevice,
(ID3D11Resource *)textureData->mainTextureU,
@@ -1216,7 +1188,8 @@ D3D11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
);
if (FAILED(result)) {
D3D11_DestroyTexture(renderer, texture);
return WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateShaderResourceView"), result);
WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateShaderResourceView"), result);
return -1;
}
result = ID3D11Device_CreateShaderResourceView(rendererData->d3dDevice,
(ID3D11Resource *)textureData->mainTextureV,
@@ -1225,7 +1198,8 @@ D3D11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
);
if (FAILED(result)) {
D3D11_DestroyTexture(renderer, texture);
return WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateShaderResourceView"), result);
WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateShaderResourceView"), result);
return -1;
}
}
@@ -1241,14 +1215,13 @@ D3D11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
);
if (FAILED(result)) {
D3D11_DestroyTexture(renderer, texture);
return WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateShaderResourceView"), result);
WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateShaderResourceView"), result);
return -1;
}
}
#endif /* SDL_HAVE_YUV */
if (texture->access & SDL_TEXTUREACCESS_TARGET) {
D3D11_RENDER_TARGET_VIEW_DESC renderTargetViewDesc;
SDL_zero(renderTargetViewDesc);
renderTargetViewDesc.Format = textureDesc.Format;
renderTargetViewDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
renderTargetViewDesc.Texture2D.MipSlice = 0;
@@ -1259,7 +1232,8 @@ D3D11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
&textureData->mainTextureRenderTargetView);
if (FAILED(result)) {
D3D11_DestroyTexture(renderer, texture);
return WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateRenderTargetView"), result);
WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateRenderTargetView"), result);
return -1;
}
}
@@ -1280,7 +1254,6 @@ D3D11_DestroyTexture(SDL_Renderer * renderer,
SAFE_RELEASE(data->mainTextureResourceView);
SAFE_RELEASE(data->mainTextureRenderTargetView);
SAFE_RELEASE(data->stagingTexture);
#if SDL_HAVE_YUV
SAFE_RELEASE(data->mainTextureU);
SAFE_RELEASE(data->mainTextureResourceViewU);
SAFE_RELEASE(data->mainTextureV);
@@ -1288,7 +1261,6 @@ D3D11_DestroyTexture(SDL_Renderer * renderer,
SAFE_RELEASE(data->mainTextureNV);
SAFE_RELEASE(data->mainTextureResourceViewNV);
SDL_free(data->pixels);
#endif
SDL_free(data);
texture->driverdata = NULL;
}
@@ -1318,7 +1290,8 @@ D3D11_UpdateTextureInternal(D3D11_RenderData *rendererData, ID3D11Texture2D *tex
NULL,
&stagingTexture);
if (FAILED(result)) {
return WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateTexture2D [create staging texture]"), result);
WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateTexture2D [create staging texture]"), result);
return -1;
}
/* Get a write-only pointer to data in the staging texture: */
@@ -1330,8 +1303,9 @@ D3D11_UpdateTextureInternal(D3D11_RenderData *rendererData, ID3D11Texture2D *tex
&textureMemory
);
if (FAILED(result)) {
WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11DeviceContext1::Map [map staging texture]"), result);
SAFE_RELEASE(stagingTexture);
return WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11DeviceContext1::Map [map staging texture]"), result);
return -1;
}
src = (const Uint8 *)pixels;
@@ -1383,13 +1357,14 @@ D3D11_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
D3D11_TextureData *textureData = (D3D11_TextureData *)texture->driverdata;
if (!textureData) {
return SDL_SetError("Texture is not currently available");
SDL_SetError("Texture is not currently available");
return -1;
}
if (D3D11_UpdateTextureInternal(rendererData, textureData->mainTexture, SDL_BYTESPERPIXEL(texture->format), rect->x, rect->y, rect->w, rect->h, srcPixels, srcPitch) < 0) {
return -1;
}
#if SDL_HAVE_YUV
if (textureData->yuv) {
/* Skip to the correct offset into the next texture */
srcPixels = (const void*)((const Uint8*)srcPixels + rect->h * srcPitch);
@@ -1413,7 +1388,6 @@ D3D11_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
return -1;
}
}
#endif /* SDL_HAVE_YUV */
return 0;
}
@@ -1429,7 +1403,8 @@ D3D11_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * texture,
D3D11_TextureData *textureData = (D3D11_TextureData *)texture->driverdata;
if (!textureData) {
return SDL_SetError("Texture is not currently available");
SDL_SetError("Texture is not currently available");
return -1;
}
if (D3D11_UpdateTextureInternal(rendererData, textureData->mainTexture, SDL_BYTESPERPIXEL(texture->format), rect->x, rect->y, rect->w, rect->h, Yplane, Ypitch) < 0) {
@@ -1454,7 +1429,8 @@ D3D11_UpdateTextureNV(SDL_Renderer * renderer, SDL_Texture * texture,
D3D11_TextureData *textureData = (D3D11_TextureData *)texture->driverdata;
if (!textureData) {
return SDL_SetError("Texture is not currently available");
SDL_SetError("Texture is not currently available");
return -1;
}
if (D3D11_UpdateTextureInternal(rendererData, textureData->mainTexture, SDL_BYTESPERPIXEL(texture->format), rect->x, rect->y, rect->w, rect->h, Yplane, Ypitch) < 0) {
@@ -1479,9 +1455,10 @@ D3D11_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
D3D11_MAPPED_SUBRESOURCE textureMemory;
if (!textureData) {
return SDL_SetError("Texture is not currently available");
SDL_SetError("Texture is not currently available");
return -1;
}
#if SDL_HAVE_YUV
if (textureData->yuv || textureData->nv12) {
/* It's more efficient to upload directly... */
if (!textureData->pixels) {
@@ -1498,7 +1475,7 @@ D3D11_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
*pitch = textureData->pitch;
return 0;
}
#endif
if (textureData->stagingTexture) {
return SDL_SetError("texture is already locked");
}
@@ -1523,7 +1500,8 @@ D3D11_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
NULL,
&textureData->stagingTexture);
if (FAILED(result)) {
return WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateTexture2D [create staging texture]"), result);
WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateTexture2D [create staging texture]"), result);
return -1;
}
/* Get a write-only pointer to data in the staging texture: */
@@ -1535,8 +1513,9 @@ D3D11_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
&textureMemory
);
if (FAILED(result)) {
WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11DeviceContext1::Map [map staging texture]"), result);
SAFE_RELEASE(textureData->stagingTexture);
return WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11DeviceContext1::Map [map staging texture]"), result);
return -1;
}
/* Make note of where the staging texture will be written to
@@ -1562,7 +1541,7 @@ D3D11_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
if (!textureData) {
return;
}
#if SDL_HAVE_YUV
if (textureData->yuv || textureData->nv12) {
const SDL_Rect *rect = &textureData->locked_rect;
void *pixels =
@@ -1571,7 +1550,7 @@ D3D11_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
D3D11_UpdateTexture(renderer, texture, rect, pixels, textureData->pitch);
return;
}
#endif
/* Commit the pixel buffer's changes back to the staging texture: */
ID3D11DeviceContext_Unmap(rendererData->d3dContext,
(ID3D11Resource *)textureData->stagingTexture,
@@ -1734,7 +1713,8 @@ D3D11_UpdateVertexBuffer(SDL_Renderer *renderer,
&mappedResource
);
if (FAILED(result)) {
return WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11DeviceContext1::Map [vertex buffer]"), result);
WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11DeviceContext1::Map [vertex buffer]"), result);
return -1;
}
SDL_memcpy(mappedResource.pData, vertexData, dataSizeInBytes);
ID3D11DeviceContext_Unmap(rendererData->d3dContext, (ID3D11Resource *)rendererData->vertexBuffers[vbidx], 0);
@@ -1761,7 +1741,8 @@ D3D11_UpdateVertexBuffer(SDL_Renderer *renderer,
&rendererData->vertexBuffers[vbidx]
);
if (FAILED(result)) {
return WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateBuffer [vertex buffer]"), result);
WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateBuffer [vertex buffer]"), result);
return -1;
}
rendererData->vertexBufferSizes[vbidx] = dataSizeInBytes;
@@ -2014,7 +1995,7 @@ D3D11_SetCopyState(SDL_Renderer * renderer, const SDL_RenderCommand *cmd, const
default:
return SDL_SetError("Unknown scale mode: %d\n", textureData->scaleMode);
}
#if SDL_HAVE_YUV
if (textureData->yuv) {
ID3D11ShaderResourceView *shaderResources[] = {
textureData->mainTextureResourceView,
@@ -2065,7 +2046,7 @@ D3D11_SetCopyState(SDL_Renderer * renderer, const SDL_RenderCommand *cmd, const
SDL_arraysize(shaderResources), shaderResources, textureSampler, matrix);
}
#endif /* SDL_HAVE_YUV */
return D3D11_SetDrawState(renderer, cmd, rendererData->pixelShaders[SHADER_RGB],
1, &textureData->mainTextureResourceView, textureSampler, matrix);
}
@@ -2268,20 +2249,30 @@ D3D11_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
/* Copy the data into the desired buffer, converting pixels to the
* desired format at the same time:
*/
status = SDL_ConvertPixels(
if (SDL_ConvertPixels(
rect->w, rect->h,
D3D11_DXGIFormatToSDLPixelFormat(stagingTextureDesc.Format),
textureMemory.pData,
textureMemory.RowPitch,
format,
pixels,
pitch);
pitch) != 0) {
/* When SDL_ConvertPixels fails, it'll have already set the format.
* Get the error message, and attach some extra data to it.
*/
char errorMessage[1024];
SDL_snprintf(errorMessage, sizeof(errorMessage), "%s, Convert Pixels failed: %s", __FUNCTION__, SDL_GetError());
SDL_SetError("%s", errorMessage);
goto done;
}
/* Unmap the texture: */
ID3D11DeviceContext_Unmap(data->d3dContext,
(ID3D11Resource *)stagingTexture,
0);
status = 0;
done:
SAFE_RELEASE(backBuffer);
SAFE_RELEASE(stagingTexture);
@@ -2374,7 +2365,6 @@ D3D11_CreateRenderer(SDL_Window * window, Uint32 flags)
data = (D3D11_RenderData *) SDL_calloc(1, sizeof(*data));
if (!data) {
SDL_free(renderer);
SDL_OutOfMemory();
return NULL;
}
@@ -2382,9 +2372,6 @@ D3D11_CreateRenderer(SDL_Window * window, Uint32 flags)
data->identity = MatrixIdentity();
renderer->WindowEvent = D3D11_WindowEvent;
#if !defined(__WINRT__)
renderer->GetOutputSize = D3D11_GetOutputSize;
#endif
renderer->SupportsBlendMode = D3D11_SupportsBlendMode;
renderer->CreateTexture = D3D11_CreateTexture;
renderer->UpdateTexture = D3D11_UpdateTexture;

View File

@@ -1886,10 +1886,9 @@ static struct
{
const void *shader_data;
SIZE_T shader_size;
} D3D11_shaders[NUM_SHADERS] = {
} D3D11_shaders[] = {
{ D3D11_PixelShader_Colors, sizeof(D3D11_PixelShader_Colors) },
{ D3D11_PixelShader_Textures, sizeof(D3D11_PixelShader_Textures) },
#if SDL_HAVE_YUV
{ D3D11_PixelShader_YUV_JPEG, sizeof(D3D11_PixelShader_YUV_JPEG) },
{ D3D11_PixelShader_YUV_BT601, sizeof(D3D11_PixelShader_YUV_BT601) },
{ D3D11_PixelShader_YUV_BT709, sizeof(D3D11_PixelShader_YUV_BT709) },
@@ -1899,7 +1898,6 @@ static struct
{ D3D11_PixelShader_NV21_JPEG, sizeof(D3D11_PixelShader_NV21_JPEG) },
{ D3D11_PixelShader_NV21_BT601, sizeof(D3D11_PixelShader_NV21_BT601) },
{ D3D11_PixelShader_NV21_BT709, sizeof(D3D11_PixelShader_NV21_BT709) },
#endif
};
int D3D11_CreateVertexShader(ID3D11Device1 *d3dDevice, ID3D11VertexShader **vertexShader, ID3D11InputLayout **inputLayout)

View File

@@ -25,7 +25,6 @@
typedef enum {
SHADER_SOLID,
SHADER_RGB,
#if SDL_HAVE_YUV
SHADER_YUV_JPEG,
SHADER_YUV_BT601,
SHADER_YUV_BT709,
@@ -35,7 +34,6 @@ typedef enum {
SHADER_NV21_JPEG,
SHADER_NV21_BT601,
SHADER_NV21_BT709,
#endif
NUM_SHADERS
} D3D11_Shader;

View File

@@ -142,6 +142,24 @@ typedef struct METAL_ShaderPipelines
@end
@implementation METAL_RenderData
#if !__has_feature(objc_arc)
- (void)dealloc
{
[_mtldevice release];
[_mtlcmdqueue release];
[_mtlcmdbuffer release];
[_mtlcmdencoder release];
[_mtllibrary release];
[_mtlbackbuffer release];
[_mtlsamplernearest release];
[_mtlsamplerlinear release];
[_mtlbufconstants release];
[_mtlbufquadindices release];
[_mtllayer release];
[_mtlpassdesc release];
[super dealloc];
}
#endif
@end
@interface METAL_TextureData : NSObject
@@ -149,17 +167,26 @@ typedef struct METAL_ShaderPipelines
@property (nonatomic, retain) id<MTLTexture> mtltexture_uv;
@property (nonatomic, retain) id<MTLSamplerState> mtlsampler;
@property (nonatomic, assign) SDL_MetalFragmentFunction fragmentFunction;
#if SDL_HAVE_YUV
@property (nonatomic, assign) BOOL yuv;
@property (nonatomic, assign) BOOL nv12;
@property (nonatomic, assign) size_t conversionBufferOffset;
#endif
@property (nonatomic, assign) BOOL hasdata;
@property (nonatomic, retain) id<MTLBuffer> lockedbuffer;
@property (nonatomic, assign) SDL_Rect lockedrect;
@end
@implementation METAL_TextureData
#if !__has_feature(objc_arc)
- (void)dealloc
{
[_mtltexture release];
[_mtltexture_uv release];
[_mtlsampler release];
[_lockedbuffer release];
[super dealloc];
}
#endif
@end
static int
@@ -314,6 +341,13 @@ MakePipelineState(METAL_RenderData *data, METAL_PipelineCache *cache,
METAL_PipelineState *states = SDL_realloc(cache->states, (cache->count + 1) * sizeof(pipeline));
#if !__has_feature(objc_arc)
[mtlpipedesc release]; // !!! FIXME: can these be reused for each creation, or does the pipeline obtain it?
[mtlvertfn release];
[mtlfragfn release];
[state release];
#endif
if (states) {
states[cache->count++] = pipeline;
cache->states = states;
@@ -571,14 +605,14 @@ METAL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
mtltexdesc.usage = MTLTextureUsageShaderRead;
}
}
id<MTLTexture> mtltexture = [data.mtldevice newTextureWithDescriptor:mtltexdesc];
if (mtltexture == nil) {
return SDL_SetError("Texture allocation failed");
}
id<MTLTexture> mtltexture_uv = nil;
#if SDL_HAVE_YUV
BOOL yuv = (texture->format == SDL_PIXELFORMAT_IYUV) || (texture->format == SDL_PIXELFORMAT_YV12);
BOOL nv12 = (texture->format == SDL_PIXELFORMAT_NV12) || (texture->format == SDL_PIXELFORMAT_NV21);
@@ -597,10 +631,13 @@ METAL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
if (yuv || nv12) {
mtltexture_uv = [data.mtldevice newTextureWithDescriptor:mtltexdesc];
if (mtltexture_uv == nil) {
#if !__has_feature(objc_arc)
[mtltexture release];
#endif
return SDL_SetError("Texture allocation failed");
}
}
#endif /* SDL_HAVE_YUV */
METAL_TextureData *texturedata = [[METAL_TextureData alloc] init];
if (texture->scaleMode == SDL_ScaleModeNearest) {
texturedata.mtlsampler = data.mtlsamplernearest;
@@ -609,7 +646,7 @@ METAL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
}
texturedata.mtltexture = mtltexture;
texturedata.mtltexture_uv = mtltexture_uv;
#if SDL_HAVE_YUV
texturedata.yuv = yuv;
texturedata.nv12 = nv12;
@@ -619,12 +656,10 @@ METAL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
texturedata.fragmentFunction = SDL_METAL_FRAGMENT_NV12;
} else if (texture->format == SDL_PIXELFORMAT_NV21) {
texturedata.fragmentFunction = SDL_METAL_FRAGMENT_NV21;
} else
#endif
{
} else {
texturedata.fragmentFunction = SDL_METAL_FRAGMENT_COPY;
}
#if SDL_HAVE_YUV
if (yuv || nv12) {
size_t offset = 0;
SDL_YUV_CONVERSION_MODE mode = SDL_GetYUVConversionModeForResolution(texture->w, texture->h);
@@ -636,9 +671,15 @@ METAL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
}
texturedata.conversionBufferOffset = offset;
}
#endif
texture->driverdata = (void*)CFBridgingRetain(texturedata);
#if !__has_feature(objc_arc)
[texturedata release];
[mtltexture release];
[mtltexture_uv release];
#endif
return 0;
}}
@@ -698,6 +739,10 @@ METAL_UpdateTextureInternal(SDL_Renderer * renderer, METAL_TextureData *textured
return SDL_OutOfMemory();
}
#if !__has_feature(objc_arc)
[stagingtex autorelease];
#endif
METAL_UploadTextureData(stagingtex, stagingrect, 0, pixels, pitch);
if (data.mtlcmdencoder != nil) {
@@ -740,7 +785,7 @@ METAL_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
if (METAL_UpdateTextureInternal(renderer, texturedata, texturedata.mtltexture, *rect, 0, pixels, pitch) < 0) {
return -1;
}
#if SDL_HAVE_YUV
if (texturedata.yuv) {
int Uslice = texture->format == SDL_PIXELFORMAT_YV12 ? 1 : 0;
int Vslice = texture->format == SDL_PIXELFORMAT_YV12 ? 0 : 1;
@@ -770,7 +815,7 @@ METAL_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
return -1;
}
}
#endif
texturedata.hasdata = YES;
return 0;
@@ -851,12 +896,10 @@ METAL_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
}
*pitch = SDL_BYTESPERPIXEL(texture->format) * rect->w;
#if SDL_HAVE_YUV
if (texturedata.yuv || texturedata.nv12) {
buffersize = ((*pitch) * rect->h) + (2 * (*pitch + 1) / 2) * ((rect->h + 1) / 2);
} else
#endif
{
} else {
buffersize = (*pitch) * rect->h;
}
@@ -869,6 +912,11 @@ METAL_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
texturedata.lockedbuffer = lockedbuffer;
*pixels = [lockedbuffer contents];
/* METAL_TextureData.lockedbuffer retains. */
#if !__has_feature(objc_arc)
[lockedbuffer release];
#endif
return 0;
}}
@@ -905,7 +953,7 @@ METAL_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
destinationSlice:0
destinationLevel:0
destinationOrigin:MTLOriginMake(rect.x, rect.y, 0)];
#if SDL_HAVE_YUV
if (texturedata.yuv) {
int Uslice = texture->format == SDL_PIXELFORMAT_YV12 ? 1 : 0;
int Vslice = texture->format == SDL_PIXELFORMAT_YV12 ? 0 : 1;
@@ -945,7 +993,7 @@ METAL_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
destinationLevel:0
destinationOrigin:MTLOriginMake(UVrect.x, UVrect.y, 0)];
}
#endif
[blitcmd endEncoding];
[data.mtlcmdbuffer commit];
@@ -1156,8 +1204,13 @@ METAL_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture
typedef struct
{
#if __has_feature(objc_arc)
__unsafe_unretained id<MTLRenderPipelineState> pipeline;
__unsafe_unretained id<MTLBuffer> vertex_buffer;
#else
id<MTLRenderPipelineState> pipeline;
id<MTLBuffer> vertex_buffer;
#endif
size_t constants_offset;
SDL_Texture *texture;
SDL_bool cliprect_dirty;
@@ -1197,29 +1250,22 @@ SetDrawState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, const SDL_Met
}
if (statecache->cliprect_dirty) {
SDL_Rect output;
SDL_Rect clip;
MTLScissorRect mtlrect;
if (statecache->cliprect_enabled) {
clip = statecache->cliprect;
clip.x += statecache->viewport.x;
clip.y += statecache->viewport.y;
const SDL_Rect *rect = &statecache->cliprect;
mtlrect.x = statecache->viewport.x + rect->x;
mtlrect.y = statecache->viewport.y + rect->y;
mtlrect.width = rect->w;
mtlrect.height = rect->h;
} else {
clip = statecache->viewport;
mtlrect.x = statecache->viewport.x;
mtlrect.y = statecache->viewport.y;
mtlrect.width = statecache->viewport.w;
mtlrect.height = statecache->viewport.h;
}
/* Set Scissor Rect Validation: w/h must be <= render pass */
SDL_zero(output);
METAL_GetOutputSize(renderer, &output.w, &output.h);
if (SDL_IntersectRect(&output, &clip, &clip)) {
MTLScissorRect mtlrect;
mtlrect.x = clip.x;
mtlrect.y = clip.y;
mtlrect.width = clip.w;
mtlrect.height = clip.h;
if (mtlrect.width > 0 && mtlrect.height > 0) {
[data.mtlcmdencoder setScissorRect:mtlrect];
}
statecache->cliprect_dirty = SDL_FALSE;
}
@@ -1267,12 +1313,10 @@ SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, const size_t
}
[data.mtlcmdencoder setFragmentTexture:texturedata.mtltexture atIndex:0];
#if SDL_HAVE_YUV
if (texturedata.yuv || texturedata.nv12) {
[data.mtlcmdencoder setFragmentTexture:texturedata.mtltexture_uv atIndex:1];
[data.mtlcmdencoder setFragmentBuffer:data.mtlbufconstants offset:texturedata.conversionBufferOffset atIndex:1];
}
#endif
statecache->texture = texture;
}
return SDL_TRUE;
@@ -1307,6 +1351,9 @@ METAL_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *ver
* TODO: this buffer is also used for constants. Is performance still
* good for those, or should we have a managed buffer for them? */
mtlbufvertex = [data.mtldevice newBufferWithLength:vertsize options:MTLResourceStorageModeShared];
#if !__has_feature(objc_arc)
[mtlbufvertex autorelease];
#endif
mtlbufvertex.label = @"SDL vertex data";
SDL_memcpy([mtlbufvertex contents], vertices, vertsize);
@@ -1650,6 +1697,9 @@ METAL_CreateRenderer(SDL_Window * window, Uint32 flags)
}
if (view == NULL) {
#if !__has_feature(objc_arc)
[mtldevice release];
#endif
SDL_free(renderer);
if (changed_window) {
SDL_RecreateWindow(window, window_flags);
@@ -1661,6 +1711,9 @@ METAL_CreateRenderer(SDL_Window * window, Uint32 flags)
data = [[METAL_RenderData alloc] init];
if (data == nil) {
#if !__has_feature(objc_arc)
[mtldevice release];
#endif
/* Release the metal view instead of destroying it,
in case we want to use it later (recreating the renderer)
*/
@@ -1679,7 +1732,7 @@ METAL_CreateRenderer(SDL_Window * window, Uint32 flags)
data.mtlview = view;
#ifdef __MACOSX__
layer = (CAMetalLayer *)[(__bridge NSView *)view layer];
layer = (CAMetalLayer *)[(NSView *)view layer];
#else
layer = (CAMetalLayer *)[(__bridge UIView *)view layer];
#endif
@@ -1704,6 +1757,9 @@ METAL_CreateRenderer(SDL_Window * window, Uint32 flags)
id<MTLLibrary> mtllibrary = [data.mtldevice newLibraryWithData:mtllibdata error:&err];
data.mtllibrary = mtllibrary;
SDL_assert(err == nil);
#if !__has_feature(objc_arc)
dispatch_release(mtllibdata);
#endif
data.mtllibrary.label = @"SDL Metal renderer shader library";
/* Do some shader pipeline state loading up-front rather than on demand. */
@@ -1761,6 +1817,9 @@ METAL_CreateRenderer(SDL_Window * window, Uint32 flags)
};
id<MTLBuffer> mtlbufconstantstaging = [data.mtldevice newBufferWithLength:CONSTANTS_LENGTH options:MTLResourceStorageModeShared];
#if !__has_feature(objc_arc)
[mtlbufconstantstaging autorelease];
#endif
char *constantdata = [mtlbufconstantstaging contents];
SDL_memcpy(constantdata + CONSTANTS_OFFSET_IDENTITY, identitytransform, sizeof(identitytransform));
@@ -1772,6 +1831,9 @@ METAL_CreateRenderer(SDL_Window * window, Uint32 flags)
int quadcount = UINT16_MAX / 4;
size_t indicessize = sizeof(UInt16) * quadcount * 6;
id<MTLBuffer> mtlbufquadindicesstaging = [data.mtldevice newBufferWithLength:indicessize options:MTLResourceStorageModeShared];
#if !__has_feature(objc_arc)
[mtlbufquadindicesstaging autorelease];
#endif
/* Quads in the following vertex order (matches the FillRects vertices):
* 1---3
@@ -1889,6 +1951,18 @@ METAL_CreateRenderer(SDL_Window * window, Uint32 flags)
renderer->info.max_texture_width = maxtexsize;
renderer->info.max_texture_height = maxtexsize;
#if !__has_feature(objc_arc)
[mtlcmdqueue release];
[mtllibrary release];
[samplerdesc release];
[mtlsamplernearest release];
[mtlsamplerlinear release];
[mtlbufconstants release];
[mtlbufquadindices release];
[data release];
[mtldevice release];
#endif
return renderer;
}}

View File

@@ -30,11 +30,6 @@
#include <OpenGL/OpenGL.h>
#endif
#ifdef SDL_VIDEO_VITA_PVR_OGL
#include <GL/gl.h>
#include <GL/glext.h>
#endif
/* To prevent unnecessary window recreation,
* these should match the defaults selected in SDL_GL_ResetAttributes
*/
@@ -324,20 +319,6 @@ GL_GetFBO(GL_RenderData *data, Uint32 w, Uint32 h)
return result;
}
static void
GL_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event)
{
/* If the window x/y/w/h changed at all, assume the viewport has been
* changed behind our backs. x/y changes might seem weird but viewport
* resets have been observed on macOS at minimum!
*/
if (event->event == SDL_WINDOWEVENT_SIZE_CHANGED ||
event->event == SDL_WINDOWEVENT_MOVED) {
GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
data->drawstate.viewport_dirty = SDL_TRUE;
}
}
static int
GL_GetOutputSize(SDL_Renderer * renderer, int *w, int *h)
{
@@ -1057,7 +1038,7 @@ GL_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *te
return 0;
}
static int
static void
SetDrawState(GL_RenderData *data, const SDL_RenderCommand *cmd, const GL_Shader shader)
{
const SDL_BlendMode blend = cmd->data.draw.blend;
@@ -1130,8 +1111,7 @@ SetDrawState(GL_RenderData *data, const SDL_RenderCommand *cmd, const GL_Shader
}
}
vertex_array = cmd->command == SDL_RENDERCMD_DRAW_POINTS
|| cmd->command == SDL_RENDERCMD_DRAW_LINES
vertex_array = cmd->command == SDL_RENDERCMD_DRAW_LINES
|| cmd->command == SDL_RENDERCMD_GEOMETRY;
color_array = cmd->command == SDL_RENDERCMD_GEOMETRY;
texture_array = cmd->data.draw.texture != NULL;
@@ -1164,11 +1144,9 @@ SetDrawState(GL_RenderData *data, const SDL_RenderCommand *cmd, const GL_Shader
}
data->drawstate.texture_array = texture_array;
}
return 0;
}
static int
static void
SetCopyState(GL_RenderData *data, const SDL_RenderCommand *cmd)
{
SDL_Texture *texture = cmd->data.draw.texture;
@@ -1204,8 +1182,6 @@ SetCopyState(GL_RenderData *data, const SDL_RenderCommand *cmd)
data->drawstate.texture = texture;
}
return 0;
}
static int
@@ -1213,6 +1189,7 @@ GL_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertic
{
/* !!! FIXME: it'd be nice to use a vertex buffer instead of immediate mode... */
GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
size_t i;
if (GL_ActivateRenderer(renderer) < 0) {
return -1;
@@ -1231,9 +1208,9 @@ GL_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertic
}
#ifdef __MACOSX__
// On macOS on older systems, the OpenGL view change and resize events aren't
// necessarily synchronized, so just always reset it.
// Workaround for: https://discourse.libsdl.org/t/sdl-2-0-22-prerelease/35306/6
// On macOS, moving the window seems to invalidate the OpenGL viewport state,
// so don't bother trying to persist it across frames; always reset it.
// Workaround for: https://github.com/libsdl-org/SDL/issues/1504
data->drawstate.viewport_dirty = SDL_TRUE;
#endif
@@ -1267,7 +1244,6 @@ GL_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertic
data->drawstate.cliprect_enabled = cmd->data.cliprect.enabled;
data->drawstate.cliprect_enabled_dirty = SDL_TRUE;
}
if (SDL_memcmp(&data->drawstate.cliprect, rect, sizeof (SDL_Rect)) != 0) {
SDL_memcpy(&data->drawstate.cliprect, rect, sizeof (SDL_Rect));
data->drawstate.cliprect_dirty = SDL_TRUE;
@@ -1296,6 +1272,31 @@ GL_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertic
}
data->glClear(GL_COLOR_BUFFER_BIT);
break;
}
case SDL_RENDERCMD_DRAW_POINTS: {
const size_t count = cmd->data.draw.count;
const GLfloat *verts = (GLfloat *) (((Uint8 *) vertices) + cmd->data.draw.first);
SetDrawState(data, cmd, SHADER_SOLID);
data->glBegin(GL_POINTS);
for (i = 0; i < count; i++, verts += 2) {
data->glVertex2f(verts[0], verts[1]);
}
data->glEnd();
break;
}
case SDL_RENDERCMD_DRAW_LINES: {
const GLfloat *verts = (GLfloat *) (((Uint8 *) vertices) + cmd->data.draw.first);
const size_t count = cmd->data.draw.count;
SDL_assert(count >= 2);
SetDrawState(data, cmd, SHADER_SOLID);
/* SetDrawState handles glEnableClientState. */
data->glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, verts);
data->glDrawArrays(GL_LINE_STRIP, 0, (GLsizei) count);
break;
}
@@ -1308,113 +1309,42 @@ GL_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertic
case SDL_RENDERCMD_COPY_EX: /* unused */
break;
case SDL_RENDERCMD_DRAW_LINES: {
if (SetDrawState(data, cmd, SHADER_SOLID) == 0) {
size_t count = cmd->data.draw.count;
const GLfloat *verts = (GLfloat *) (((Uint8 *) vertices) + cmd->data.draw.first);
case SDL_RENDERCMD_GEOMETRY: {
const GLfloat *verts = (GLfloat *) (((Uint8 *) vertices) + cmd->data.draw.first);
SDL_Texture *texture = cmd->data.draw.texture;
const size_t count = cmd->data.draw.count;
if (texture) {
SetCopyState(data, cmd);
} else {
SetDrawState(data, cmd, SHADER_SOLID);
}
{
Uint32 color = data->drawstate.color;
GLubyte a = (GLubyte)((color >> 24) & 0xFF);
GLubyte r = (GLubyte)((color >> 16) & 0xFF);
GLubyte g = (GLubyte)((color >> 8) & 0xFF);
GLubyte b = (GLubyte)((color >> 0) & 0xFF);
/* SetDrawState handles glEnableClientState. */
data->glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, verts);
if (count > 2) {
/* joined lines cannot be grouped */
data->glDrawArrays(GL_LINE_STRIP, 0, (GLsizei)count);
if (texture) {
data->glVertexPointer(2, GL_FLOAT, sizeof(float) * 5, verts + 0);
data->glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(float) * 5, verts + 2);
data->glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 5, verts + 3);
} else {
/* let's group non joined lines */
SDL_RenderCommand *finalcmd = cmd;
SDL_RenderCommand *nextcmd = cmd->next;
SDL_BlendMode thisblend = cmd->data.draw.blend;
while (nextcmd != NULL) {
const SDL_RenderCommandType nextcmdtype = nextcmd->command;
if (nextcmdtype != SDL_RENDERCMD_DRAW_LINES) {
break; /* can't go any further on this draw call, different render command up next. */
} else if (nextcmd->data.draw.count != 2) {
break; /* can't go any further on this draw call, those are joined lines */
} else if (nextcmd->data.draw.blend != thisblend) {
break; /* can't go any further on this draw call, different blendmode copy up next. */
} else {
finalcmd = nextcmd; /* we can combine copy operations here. Mark this one as the furthest okay command. */
count += nextcmd->data.draw.count;
}
nextcmd = nextcmd->next;
}
data->glDrawArrays(GL_LINES, 0, (GLsizei)count);
cmd = finalcmd; /* skip any copy commands we just combined in here. */
}
}
break;
}
case SDL_RENDERCMD_DRAW_POINTS:
case SDL_RENDERCMD_GEOMETRY: {
/* as long as we have the same copy command in a row, with the
same texture, we can combine them all into a single draw call. */
SDL_Texture *thistexture = cmd->data.draw.texture;
SDL_BlendMode thisblend = cmd->data.draw.blend;
const SDL_RenderCommandType thiscmdtype = cmd->command;
SDL_RenderCommand *finalcmd = cmd;
SDL_RenderCommand *nextcmd = cmd->next;
size_t count = cmd->data.draw.count;
int ret;
while (nextcmd != NULL) {
const SDL_RenderCommandType nextcmdtype = nextcmd->command;
if (nextcmdtype != thiscmdtype) {
break; /* can't go any further on this draw call, different render command up next. */
} else if (nextcmd->data.draw.texture != thistexture || nextcmd->data.draw.blend != thisblend) {
break; /* can't go any further on this draw call, different texture/blendmode copy up next. */
} else {
finalcmd = nextcmd; /* we can combine copy operations here. Mark this one as the furthest okay command. */
count += nextcmd->data.draw.count;
}
nextcmd = nextcmd->next;
}
if (thistexture) {
ret = SetCopyState(data, cmd);
} else {
ret = SetDrawState(data, cmd, SHADER_SOLID);
}
if (ret == 0) {
const GLfloat *verts = (GLfloat *) (((Uint8 *) vertices) + cmd->data.draw.first);
int op = GL_TRIANGLES; /* SDL_RENDERCMD_GEOMETRY */
if (thiscmdtype == SDL_RENDERCMD_DRAW_POINTS) {
op = GL_POINTS;
data->glVertexPointer(2, GL_FLOAT, sizeof(float) * 3, verts + 0);
data->glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(float) * 3, verts + 2);
}
if (thiscmdtype == SDL_RENDERCMD_DRAW_POINTS) {
/* SetDrawState handles glEnableClientState. */
data->glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, verts);
} else {
/* SetDrawState handles glEnableClientState. */
if (thistexture) {
data->glVertexPointer(2, GL_FLOAT, sizeof(float) * 5, verts + 0);
data->glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(float) * 5, verts + 2);
data->glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 5, verts + 3);
} else {
data->glVertexPointer(2, GL_FLOAT, sizeof(float) * 3, verts + 0);
data->glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(float) * 3, verts + 2);
}
}
data->glDrawArrays(op, 0, (GLsizei) count);
data->glDrawArrays(GL_TRIANGLES, 0, (GLsizei) count);
/* Restore previously set color when we're done. */
if (thiscmdtype != SDL_RENDERCMD_DRAW_POINTS) {
Uint32 color = data->drawstate.color;
GLubyte a = (GLubyte)((color >> 24) & 0xFF);
GLubyte r = (GLubyte)((color >> 16) & 0xFF);
GLubyte g = (GLubyte)((color >> 8) & 0xFF);
GLubyte b = (GLubyte)((color >> 0) & 0xFF);
data->glColor4ub(r, g, b, a);
}
data->glColor4ub(r, g, b, a);
}
cmd = finalcmd; /* skip any copy commands we just combined in here. */
break;
}
}
case SDL_RENDERCMD_NO_OP:
break;
@@ -1709,32 +1639,6 @@ GL_SetVSync(SDL_Renderer * renderer, const int vsync)
return retval;
}
static SDL_bool
GL_IsProbablyAccelerated(const GL_RenderData *data)
{
/*const char *vendor = (const char *) data->glGetString(GL_VENDOR);*/
const char *renderer = (const char *) data->glGetString(GL_RENDERER);
#ifdef __WINDOWS__
if (SDL_strcmp(renderer, "GDI Generic") == 0) {
return SDL_FALSE; /* Microsoft's fallback software renderer. Fix your system! */
}
#endif
#ifdef __APPLE__
if (SDL_strcmp(renderer, "Apple Software Renderer") == 0) {
return SDL_FALSE; /* (a probably very old) Apple software-based OpenGL. */
}
#endif
if (SDL_strcmp(renderer, "Software Rasterizer") == 0) {
return SDL_FALSE; /* (a probably very old) Software Mesa, or some other generic thing. */
}
/* !!! FIXME: swrast? llvmpipe? softpipe? */
return SDL_TRUE;
}
static SDL_Renderer *
GL_CreateRenderer(SDL_Window * window, Uint32 flags)
@@ -1745,14 +1649,11 @@ GL_CreateRenderer(SDL_Window * window, Uint32 flags)
Uint32 window_flags;
int profile_mask = 0, major = 0, minor = 0;
SDL_bool changed_window = SDL_FALSE;
const char *hint;
SDL_bool non_power_of_two_supported = SDL_FALSE;
SDL_GL_GetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, &profile_mask);
SDL_GL_GetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, &major);
SDL_GL_GetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, &minor);
#ifndef SDL_VIDEO_VITA_PVR_OGL
window_flags = SDL_GetWindowFlags(window);
if (!(window_flags & SDL_WINDOW_OPENGL) ||
profile_mask == SDL_GL_CONTEXT_PROFILE_ES || major != RENDERER_CONTEXT_MAJOR || minor != RENDERER_CONTEXT_MINOR) {
@@ -1766,7 +1667,6 @@ GL_CreateRenderer(SDL_Window * window, Uint32 flags)
goto error;
}
}
#endif
renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer));
if (!renderer) {
@@ -1781,7 +1681,6 @@ GL_CreateRenderer(SDL_Window * window, Uint32 flags)
goto error;
}
renderer->WindowEvent = GL_WindowEvent;
renderer->GetOutputSize = GL_GetOutputSize;
renderer->SupportsBlendMode = GL_SupportsBlendMode;
renderer->CreateTexture = GL_CreateTexture;
@@ -1808,7 +1707,7 @@ GL_CreateRenderer(SDL_Window * window, Uint32 flags)
renderer->GL_BindTexture = GL_BindTexture;
renderer->GL_UnbindTexture = GL_UnbindTexture;
renderer->info = GL_RenderDriver.info;
renderer->info.flags = 0; /* will set some flags below. */
renderer->info.flags = SDL_RENDERER_ACCELERATED;
renderer->driverdata = data;
renderer->window = window;
@@ -1832,10 +1731,6 @@ GL_CreateRenderer(SDL_Window * window, Uint32 flags)
goto error;
}
if (GL_IsProbablyAccelerated(data)) {
renderer->info.flags |= SDL_RENDERER_ACCELERATED;
}
#ifdef __MACOSX__
/* Enable multi-threaded rendering */
/* Disabled until Ryan finishes his VBO/PBO code...
@@ -1869,37 +1764,15 @@ GL_CreateRenderer(SDL_Window * window, Uint32 flags)
data->glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
}
hint = SDL_getenv("GL_ARB_texture_non_power_of_two");
if (!hint || *hint != '0') {
SDL_bool isGL2 = SDL_FALSE;
const char *verstr = (const char *)data->glGetString(GL_VERSION);
if (verstr) {
char verbuf[16];
char *ptr;
SDL_strlcpy(verbuf, verstr, sizeof (verbuf));
ptr = SDL_strchr(verbuf, '.');
if (ptr) {
*ptr = '\0';
if (SDL_atoi(verbuf) >= 2) {
isGL2 = SDL_TRUE;
}
}
}
if (isGL2 || SDL_GL_ExtensionSupported("GL_ARB_texture_non_power_of_two")) {
non_power_of_two_supported = SDL_TRUE;
}
}
data->textype = GL_TEXTURE_2D;
if (non_power_of_two_supported) {
if (SDL_GL_ExtensionSupported("GL_ARB_texture_non_power_of_two")) {
data->GL_ARB_texture_non_power_of_two_supported = SDL_TRUE;
data->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &value);
renderer->info.max_texture_width = value;
renderer->info.max_texture_height = value;
} else if (SDL_GL_ExtensionSupported("GL_ARB_texture_rectangle") ||
SDL_GL_ExtensionSupported("GL_EXT_texture_rectangle")) {
data->GL_ARB_texture_rectangle_supported = SDL_TRUE;
data->textype = GL_TEXTURE_RECTANGLE_ARB;
}
if (data->GL_ARB_texture_rectangle_supported) {
data->glGetIntegerv(GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB, &value);
renderer->info.max_texture_width = value;
renderer->info.max_texture_height = value;
@@ -1924,7 +1797,7 @@ GL_CreateRenderer(SDL_Window * window, Uint32 flags)
}
SDL_LogInfo(SDL_LOG_CATEGORY_RENDER, "OpenGL shaders: %s",
data->shaders ? "ENABLED" : "DISABLED");
#if SDL_HAVE_YUV
/* We support YV12 textures using 3 textures and a shader */
if (data->shaders && data->num_texture_units >= 3) {
renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_YV12;
@@ -1932,7 +1805,7 @@ GL_CreateRenderer(SDL_Window * window, Uint32 flags)
renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_NV12;
renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_NV21;
}
#endif
#ifdef __MACOSX__
renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_UYVY;
#endif

View File

@@ -284,7 +284,7 @@ static const char *shader_source[NUM_SHADERS][2] =
" gl_FragColor = texture2D(tex0, v_texCoord) * v_color;\n"
"}"
},
#if SDL_HAVE_YUV
/* SHADER_YUV_JPEG */
{
/* vertex shader */
@@ -384,7 +384,6 @@ static const char *shader_source[NUM_SHADERS][2] =
BT709_SHADER_CONSTANTS
NV21_SHADER_BODY
},
#endif /* SDL_HAVE_YUV */
};
static SDL_bool

View File

@@ -32,7 +32,6 @@ typedef enum {
SHADER_SOLID,
SHADER_RGB,
SHADER_RGBA,
#if SDL_HAVE_YUV
SHADER_YUV_JPEG,
SHADER_YUV_BT601,
SHADER_YUV_BT709,
@@ -44,7 +43,6 @@ typedef enum {
SHADER_NV21_JPEG,
SHADER_NV21_BT601,
SHADER_NV21_BT709,
#endif
NUM_SHADERS
} GL_Shader;

View File

@@ -28,17 +28,6 @@
#include "../../video/SDL_blit.h"
#include "SDL_shaders_gles2.h"
/* WebGL doesn't offer client-side arrays, so use Vertex Buffer Objects
on Emscripten, which converts GLES2 into WebGL calls.
In all other cases, attempt to use client-side arrays, as they tend to
be dramatically faster when not batching, and about the same when
we are. */
#if defined(__EMSCRIPTEN__)
#define USE_VERTEX_BUFFER_OBJECTS 1
#else
#define USE_VERTEX_BUFFER_OBJECTS 0
#endif
/* To prevent unnecessary window recreation,
* these should match the defaults selected in SDL_GL_ResetAttributes
*/
@@ -162,12 +151,9 @@ typedef struct GLES2_RenderData
GLES2_ProgramCache program_cache;
Uint8 clear_r, clear_g, clear_b, clear_a;
#if USE_VERTEX_BUFFER_OBJECTS
GLuint vertex_buffers[8];
size_t vertex_buffer_size[8];
int current_vertex_buffer;
#endif
GLES2_DrawStateCache drawstate;
} GLES2_RenderData;
@@ -561,7 +547,6 @@ GLES2_SelectProgram(GLES2_RenderData *data, GLES2_ImageSource source, int w, int
case GLES2_IMAGESOURCE_TEXTURE_BGR:
ftype = GLES2_SHADER_FRAGMENT_TEXTURE_BGR;
break;
#if SDL_HAVE_YUV
case GLES2_IMAGESOURCE_TEXTURE_YUV:
switch (SDL_GetYUVConversionModeForResolution(w, h)) {
case SDL_YUV_CONVERSION_JPEG:
@@ -618,7 +603,6 @@ GLES2_SelectProgram(GLES2_RenderData *data, GLES2_ImageSource source, int w, int
goto fault;
}
break;
#endif /* SDL_HAVE_YUV */
case GLES2_IMAGESOURCE_TEXTURE_EXTERNAL_OES:
ftype = GLES2_SHADER_FRAGMENT_TEXTURE_EXTERNAL_OES;
break;
@@ -860,7 +844,7 @@ GLES2_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture
}
static int
SetDrawState(GLES2_RenderData *data, const SDL_RenderCommand *cmd, const GLES2_ImageSource imgsrc, void *vertices)
SetDrawState(GLES2_RenderData *data, const SDL_RenderCommand *cmd, const GLES2_ImageSource imgsrc)
{
SDL_Texture *texture = cmd->data.draw.texture;
const SDL_BlendMode blend = cmd->data.draw.blend;
@@ -900,14 +884,39 @@ SetDrawState(GLES2_RenderData *data, const SDL_RenderCommand *cmd, const GLES2_I
data->drawstate.cliprect_dirty = SDL_FALSE;
}
if ((texture != NULL) != data->drawstate.texturing) {
if (texture == NULL) {
data->glDisableVertexAttribArray((GLenum) GLES2_ATTRIBUTE_TEXCOORD);
data->drawstate.texturing = SDL_FALSE;
} else {
data->glEnableVertexAttribArray((GLenum) GLES2_ATTRIBUTE_TEXCOORD);
data->drawstate.texturing = SDL_TRUE;
if (texture != data->drawstate.texture) {
if ((texture != NULL) != data->drawstate.texturing) {
if (texture == NULL) {
data->glDisableVertexAttribArray((GLenum) GLES2_ATTRIBUTE_TEXCOORD);
data->drawstate.texturing = SDL_FALSE;
} else {
data->glEnableVertexAttribArray((GLenum) GLES2_ATTRIBUTE_TEXCOORD);
data->drawstate.texturing = SDL_TRUE;
}
}
if (texture) {
GLES2_TextureData *tdata = (GLES2_TextureData *) texture->driverdata;
#if SDL_HAVE_YUV
if (tdata->yuv) {
data->glActiveTexture(GL_TEXTURE2);
data->glBindTexture(tdata->texture_type, tdata->texture_v);
data->glActiveTexture(GL_TEXTURE1);
data->glBindTexture(tdata->texture_type, tdata->texture_u);
data->glActiveTexture(GL_TEXTURE0);
} else if (tdata->nv12) {
data->glActiveTexture(GL_TEXTURE1);
data->glBindTexture(tdata->texture_type, tdata->texture_u);
data->glActiveTexture(GL_TEXTURE0);
}
#endif
data->glBindTexture(tdata->texture_type, tdata->texture);
}
data->drawstate.texture = texture;
}
if (texture) {
@@ -917,7 +926,7 @@ SetDrawState(GLES2_RenderData *data, const SDL_RenderCommand *cmd, const GLES2_I
}
if (texture) {
SDL_Vertex *verts = (SDL_Vertex *) (((Uint8 *) vertices) + cmd->data.draw.first);
SDL_Vertex *verts = (SDL_Vertex *) (cmd->data.draw.first);
data->glVertexAttribPointer(GLES2_ATTRIBUTE_TEXCOORD, 2, GL_FLOAT, GL_FALSE, stride, (const GLvoid *)&verts->tex_coord);
}
@@ -951,7 +960,7 @@ SetDrawState(GLES2_RenderData *data, const SDL_RenderCommand *cmd, const GLES2_I
/* all drawing commands use this */
{
SDL_VertexSolid *verts = (SDL_VertexSolid *) (((Uint8 *) vertices) + cmd->data.draw.first);
SDL_VertexSolid *verts = (SDL_VertexSolid *) (cmd->data.draw.first);
data->glVertexAttribPointer(GLES2_ATTRIBUTE_POSITION, 2, GL_FLOAT, GL_FALSE, stride, (const GLvoid *) &verts->position);
data->glVertexAttribPointer(GLES2_ATTRIBUTE_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE /* Normalized */, stride, (const GLvoid *) &verts->color);
}
@@ -960,12 +969,11 @@ SetDrawState(GLES2_RenderData *data, const SDL_RenderCommand *cmd, const GLES2_I
}
static int
SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, void *vertices)
SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd)
{
GLES2_RenderData *data = (GLES2_RenderData *) renderer->driverdata;
GLES2_ImageSource sourceType = GLES2_IMAGESOURCE_TEXTURE_ABGR;
SDL_Texture *texture = cmd->data.draw.texture;
int ret;
/* Pick an appropriate shader */
if (renderer->target) {
@@ -1020,7 +1028,6 @@ SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, void *vertice
break;
}
break;
#if SDL_HAVE_YUV
case SDL_PIXELFORMAT_IYUV:
case SDL_PIXELFORMAT_YV12:
sourceType = GLES2_IMAGESOURCE_TEXTURE_YUV;
@@ -1031,7 +1038,6 @@ SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, void *vertice
case SDL_PIXELFORMAT_NV21:
sourceType = GLES2_IMAGESOURCE_TEXTURE_NV21;
break;
#endif
case SDL_PIXELFORMAT_EXTERNAL_OES:
sourceType = GLES2_IMAGESOURCE_TEXTURE_EXTERNAL_OES;
break;
@@ -1055,7 +1061,6 @@ SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, void *vertice
case SDL_PIXELFORMAT_BGR888:
sourceType = GLES2_IMAGESOURCE_TEXTURE_BGR;
break;
#if SDL_HAVE_YUV
case SDL_PIXELFORMAT_IYUV:
case SDL_PIXELFORMAT_YV12:
sourceType = GLES2_IMAGESOURCE_TEXTURE_YUV;
@@ -1066,7 +1071,6 @@ SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, void *vertice
case SDL_PIXELFORMAT_NV21:
sourceType = GLES2_IMAGESOURCE_TEXTURE_NV21;
break;
#endif
case SDL_PIXELFORMAT_EXTERNAL_OES:
sourceType = GLES2_IMAGESOURCE_TEXTURE_EXTERNAL_OES;
break;
@@ -1075,31 +1079,7 @@ SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, void *vertice
}
}
ret = SetDrawState(data, cmd, sourceType, vertices);
if (texture != data->drawstate.texture) {
GLES2_TextureData *tdata = (GLES2_TextureData *) texture->driverdata;
#if SDL_HAVE_YUV
if (tdata->yuv) {
data->glActiveTexture(GL_TEXTURE2);
data->glBindTexture(tdata->texture_type, tdata->texture_v);
data->glActiveTexture(GL_TEXTURE1);
data->glBindTexture(tdata->texture_type, tdata->texture_u);
data->glActiveTexture(GL_TEXTURE0);
} else if (tdata->nv12) {
data->glActiveTexture(GL_TEXTURE1);
data->glBindTexture(tdata->texture_type, tdata->texture_u);
data->glActiveTexture(GL_TEXTURE0);
}
#endif
data->glBindTexture(tdata->texture_type, tdata->texture);
data->drawstate.texture = texture;
}
return ret;
return SetDrawState(data, cmd, sourceType);
}
static int
@@ -1107,11 +1087,8 @@ GLES2_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *ver
{
GLES2_RenderData *data = (GLES2_RenderData *) renderer->driverdata;
const SDL_bool colorswap = (renderer->target && (renderer->target->format == SDL_PIXELFORMAT_ARGB8888 || renderer->target->format == SDL_PIXELFORMAT_RGB888));
#if USE_VERTEX_BUFFER_OBJECTS
const int vboidx = data->current_vertex_buffer;
const GLuint vbo = data->vertex_buffers[vboidx];
#endif
if (GLES2_ActivateRenderer(renderer) < 0) {
return -1;
@@ -1129,7 +1106,6 @@ GLES2_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *ver
}
}
#if USE_VERTEX_BUFFER_OBJECTS
/* upload the new VBO data for this set of commands. */
data->glBindBuffer(GL_ARRAY_BUFFER, vbo);
if (data->vertex_buffer_size[vboidx] < vertsize) {
@@ -1144,8 +1120,6 @@ GLES2_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *ver
if (data->current_vertex_buffer >= SDL_arraysize(data->vertex_buffers)) {
data->current_vertex_buffer = 0;
}
vertices = NULL; /* attrib pointers will be offsets into the VBO. */
#endif
while (cmd) {
switch (cmd->command) {
@@ -1210,7 +1184,7 @@ GLES2_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *ver
break;
case SDL_RENDERCMD_DRAW_LINES: {
if (SetDrawState(data, cmd, GLES2_IMAGESOURCE_SOLID, vertices) == 0) {
if (SetDrawState(data, cmd, GLES2_IMAGESOURCE_SOLID) == 0) {
size_t count = cmd->data.draw.count;
if (count > 2) {
/* joined lines cannot be grouped */
@@ -1268,9 +1242,9 @@ GLES2_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *ver
}
if (thistexture) {
ret = SetCopyState(renderer, cmd, vertices);
ret = SetCopyState(renderer, cmd);
} else {
ret = SetDrawState(data, cmd, GLES2_IMAGESOURCE_SOLID, vertices);
ret = SetDrawState(data, cmd, GLES2_IMAGESOURCE_SOLID);
}
if (ret == 0) {
@@ -1334,10 +1308,8 @@ GLES2_DestroyRenderer(SDL_Renderer *renderer)
data->framebuffers = nextnode;
}
#if USE_VERTEX_BUFFER_OBJECTS
data->glDeleteBuffers(SDL_arraysize(data->vertex_buffers), data->vertex_buffers);
GL_CheckError("", renderer);
#endif
SDL_GL_DeleteContext(data->context);
}
@@ -1370,7 +1342,6 @@ GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture)
format = GL_RGBA;
type = GL_UNSIGNED_BYTE;
break;
#if SDL_HAVE_YUV
case SDL_PIXELFORMAT_IYUV:
case SDL_PIXELFORMAT_YV12:
case SDL_PIXELFORMAT_NV12:
@@ -1378,7 +1349,6 @@ GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture)
format = GL_LUMINANCE;
type = GL_UNSIGNED_BYTE;
break;
#endif
#ifdef GL_TEXTURE_EXTERNAL_OES
case SDL_PIXELFORMAT_EXTERNAL_OES:
format = GL_NONE;
@@ -2101,10 +2071,8 @@ GLES2_CreateRenderer(SDL_Window *window, Uint32 flags)
data->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &value);
renderer->info.max_texture_height = value;
#if USE_VERTEX_BUFFER_OBJECTS
/* we keep a few of these and cycle through them, so data can live for a few frames. */
data->glGenBuffers(SDL_arraysize(data->vertex_buffers), data->vertex_buffers);
#endif
data->framebuffers = NULL;
data->glGetIntegerv(GL_FRAMEBUFFER_BINDING, &window_framebuffer);
@@ -2137,12 +2105,11 @@ GLES2_CreateRenderer(SDL_Window *window, Uint32 flags)
renderer->SetVSync = GLES2_SetVSync;
renderer->GL_BindTexture = GLES2_BindTexture;
renderer->GL_UnbindTexture = GLES2_UnbindTexture;
#if SDL_HAVE_YUV
renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_YV12;
renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_IYUV;
renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_NV12;
renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_NV21;
#endif
#ifdef GL_TEXTURE_EXTERNAL_OES
renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_EXTERNAL_OES;
#endif
@@ -2198,4 +2165,3 @@ SDL_RenderDriver GLES2_RenderDriver = {
#endif /* SDL_VIDEO_RENDER_OGL_ES2 && !SDL_RENDER_DISABLED */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -121,8 +121,6 @@ static const Uint8 GLES2_Fragment_TextureBGR[] = " \
} \
";
#if SDL_HAVE_YUV
#define JPEG_SHADER_CONSTANTS \
"// YUV offset \n" \
"const vec3 offset = vec3(0, -0.501960814, -0.501960814);\n" \
@@ -301,7 +299,6 @@ static const Uint8 GLES2_Fragment_TextureNV21BT709[] = \
BT709_SHADER_CONSTANTS \
NV21_SHADER_BODY \
;
#endif
/* Custom Android video format texture */
static const Uint8 GLES2_Fragment_TextureExternalOES[] = " \
@@ -338,7 +335,6 @@ const Uint8 *GLES2_GetShader(GLES2_ShaderType type)
return GLES2_Fragment_TextureRGB;
case GLES2_SHADER_FRAGMENT_TEXTURE_BGR:
return GLES2_Fragment_TextureBGR;
#if SDL_HAVE_YUV
case GLES2_SHADER_FRAGMENT_TEXTURE_YUV_JPEG:
return GLES2_Fragment_TextureYUVJPEG;
case GLES2_SHADER_FRAGMENT_TEXTURE_YUV_BT601:
@@ -361,7 +357,6 @@ const Uint8 *GLES2_GetShader(GLES2_ShaderType type)
return GLES2_Fragment_TextureNV21BT601;
case GLES2_SHADER_FRAGMENT_TEXTURE_NV21_BT709:
return GLES2_Fragment_TextureNV21BT709;
#endif
case GLES2_SHADER_FRAGMENT_TEXTURE_EXTERNAL_OES:
return GLES2_Fragment_TextureExternalOES;
default:

View File

@@ -34,7 +34,6 @@ typedef enum
GLES2_SHADER_FRAGMENT_TEXTURE_ARGB,
GLES2_SHADER_FRAGMENT_TEXTURE_BGR,
GLES2_SHADER_FRAGMENT_TEXTURE_RGB,
#if SDL_HAVE_YUV
GLES2_SHADER_FRAGMENT_TEXTURE_YUV_JPEG,
GLES2_SHADER_FRAGMENT_TEXTURE_YUV_BT601,
GLES2_SHADER_FRAGMENT_TEXTURE_YUV_BT709,
@@ -46,7 +45,6 @@ typedef enum
GLES2_SHADER_FRAGMENT_TEXTURE_NV21_JPEG,
GLES2_SHADER_FRAGMENT_TEXTURE_NV21_BT601,
GLES2_SHADER_FRAGMENT_TEXTURE_NV21_BT709,
#endif
GLES2_SHADER_FRAGMENT_TEXTURE_EXTERNAL_OES,
GLES2_SHADER_COUNT
} GLES2_ShaderType;

View File

@@ -442,8 +442,8 @@ TextureSpillLRU(PSP_RenderData* data, size_t wanted) {
}
LRUTargetRemove(data, lru);
} else {
// Asked to spill but there nothing to spill
return SDL_SetError("Could not spill more VRAM to system memory. VRAM : %dKB,(%dKB), wanted %dKB", vmemavail()/1024, vlargestblock()/1024, wanted/1024);
SDL_SetError("Could not spill more VRAM to system memory. VRAM : %dKB,(%dKB), wanted %dKB", vmemavail()/1024, vlargestblock()/1024, wanted/1024);
return -1; //Asked to spill but there nothing to spill
}
return 0;
}
@@ -556,8 +556,7 @@ static int
TextureShouldSwizzle(PSP_TextureData* psp_texture, SDL_Texture *texture)
{
return !((texture->access == SDL_TEXTUREACCESS_TARGET) && InVram(psp_texture->data))
&& texture->access != SDL_TEXTUREACCESS_STREAMING
&& (texture->w >= 16 || texture->h >= 16);
&& (texture->w >= 16 || texture->h >= 16);
}
static void
@@ -775,13 +774,14 @@ PSP_QueueFillRects(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FR
cmd->data.draw.count = count;
for (i = 0; i < count; i++, rects++) {
verts->x = rects->x;
verts->y = rects->y;
const SDL_FRect *rect = &rects[i];
verts->x = rect->x;
verts->y = rect->y;
verts->z = 0.0f;
verts++;
verts->x = rects->x + rects->w + 0.5f;
verts->y = rects->y + rects->h + 0.5f;
verts->x = rect->x + rect->w;
verts->y = rect->y + rect->h;
verts->z = 0.0f;
verts++;
}
@@ -881,7 +881,7 @@ PSP_QueueCopy(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * tex
static int
PSP_QueueCopyEx(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * texture,
const SDL_Rect * srcrect, const SDL_FRect * dstrect,
const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip, float scale_x, float scale_y)
const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip)
{
VertTV *verts = (VertTV *) SDL_AllocateRenderVertices(renderer, 4 * sizeof (VertTV), 4, &cmd->data.draw.first);
const float centerx = center->x;
@@ -891,29 +891,27 @@ PSP_QueueCopyEx(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * t
const float width = dstrect->w - centerx;
const float height = dstrect->h - centery;
float s, c;
float cw1, sw1, ch1, sh1, cw2, sw2, ch2, sh2;
float cw, sw, ch, sh;
float u0 = srcrect->x;
float v0 = srcrect->y;
float u1 = srcrect->x + srcrect->w;
float v1 = srcrect->y + srcrect->h;
if (!verts) {
return -1;
}
cmd->data.draw.count = 1;
MathSincos(degToRad(360-angle), &s, &c);
MathSincos(degToRad(angle), &s, &c);
cw1 = c * -centerx;
sw1 = s * -centerx;
ch1 = c * -centery;
sh1 = s * -centery;
cw2 = c * width;
sw2 = s * width;
ch2 = c * height;
sh2 = s * height;
cw = c * width;
sw = s * width;
ch = c * height;
sh = s * height;
if (flip & SDL_FLIP_VERTICAL) {
Swap(&v0, &v1);
@@ -925,44 +923,31 @@ PSP_QueueCopyEx(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * t
verts->u = u0;
verts->v = v0;
verts->x = x + cw1 + sh1;
verts->y = y - sw1 + ch1;
verts->x = x - cw + sh;
verts->y = y - sw - ch;
verts->z = 0;
verts++;
verts->u = u0;
verts->v = v1;
verts->x = x + cw1 + sh2;
verts->y = y - sw1 + ch2;
verts->x = x - cw - sh;
verts->y = y - sw + ch;
verts->z = 0;
verts++;
verts->u = u1;
verts->v = v1;
verts->x = x + cw2 + sh2;
verts->y = y - sw2 + ch2;
verts->x = x + cw - sh;
verts->y = y + sw + ch;
verts->z = 0;
verts++;
verts->u = u1;
verts->v = v0;
verts->x = x + cw2 + sh1;
verts->y = y - sw2 + ch1;
verts->x = x + cw + sh;
verts->y = y + sw - ch;
verts->z = 0;
if (scale_x != 1.0f || scale_y != 1.0f) {
verts->x *= scale_x;
verts->y *= scale_y;
verts--;
verts->x *= scale_x;
verts->y *= scale_y;
verts--;
verts->x *= scale_x;
verts->y *= scale_y;
verts--;
verts->x *= scale_x;
verts->y *= scale_y;
}
verts++;
return 0;
}

View File

@@ -220,7 +220,7 @@ SDL_BlendFillRect(SDL_Surface * dst, const SDL_Rect * rect,
SDL_Rect clipped;
if (!dst) {
return SDL_InvalidParamError("SDL_BlendFillRect(): dst");
return SDL_SetError("Passed NULL destination surface");
}
/* This function doesn't work on surfaces < 8 bpp */
@@ -291,7 +291,7 @@ SDL_BlendFillRects(SDL_Surface * dst, const SDL_Rect * rects, int count,
int status = 0;
if (!dst) {
return SDL_InvalidParamError("SDL_BlendFillRects(): dst");
return SDL_SetError("Passed NULL destination surface");
}
/* This function doesn't work on surfaces < 8 bpp */

View File

@@ -809,7 +809,7 @@ SDL_BlendLine(SDL_Surface * dst, int x1, int y1, int x2, int y2,
BlendLineFunc func;
if (!dst) {
return SDL_InvalidParamError("SDL_BlendLine(): dst");
return SDL_SetError("SDL_BlendLine(): Passed NULL destination surface");
}
func = SDL_CalculateBlendLineFunc(dst->format);

View File

@@ -218,7 +218,7 @@ SDL_BlendPoint(SDL_Surface * dst, int x, int y, SDL_BlendMode blendMode, Uint8 r
Uint8 g, Uint8 b, Uint8 a)
{
if (!dst) {
return SDL_InvalidParamError("SDL_BlendPoint(): dst");
return SDL_SetError("Passed NULL destination surface");
}
/* This function doesn't work on surfaces < 8 bpp */
@@ -287,7 +287,7 @@ SDL_BlendPoints(SDL_Surface * dst, const SDL_Point * points, int count,
int status = 0;
if (!dst) {
return SDL_InvalidParamError("SDL_BlendPoints(): dst");
return SDL_SetError("Passed NULL destination surface");
}
/* This function doesn't work on surfaces < 8 bpp */

View File

@@ -144,7 +144,7 @@ SDL_DrawLine(SDL_Surface * dst, int x1, int y1, int x2, int y2, Uint32 color)
DrawLineFunc func;
if (!dst) {
return SDL_InvalidParamError("SDL_DrawLine(): dst");
return SDL_SetError("SDL_DrawLine(): Passed NULL destination surface");
}
func = SDL_CalculateDrawLineFunc(dst->format);
@@ -173,7 +173,7 @@ SDL_DrawLines(SDL_Surface * dst, const SDL_Point * points, int count,
DrawLineFunc func;
if (!dst) {
return SDL_InvalidParamError("SDL_DrawLines(): dst");
return SDL_SetError("SDL_DrawLines(): Passed NULL destination surface");
}
func = SDL_CalculateDrawLineFunc(dst->format);

View File

@@ -30,7 +30,7 @@ int
SDL_DrawPoint(SDL_Surface * dst, int x, int y, Uint32 color)
{
if (!dst) {
return SDL_InvalidParamError("SDL_DrawPoint(): dst");
return SDL_SetError("Passed NULL destination surface");
}
/* This function doesn't work on surfaces < 8 bpp */
@@ -71,7 +71,7 @@ SDL_DrawPoints(SDL_Surface * dst, const SDL_Point * points, int count,
int x, y;
if (!dst) {
return SDL_InvalidParamError("SDL_DrawPoints(): dst");
return SDL_SetError("Passed NULL destination surface");
}
/* This function doesn't work on surfaces < 8 bpp */

View File

@@ -99,7 +99,8 @@ SW_GetOutputSize(SDL_Renderer * renderer, int *w, int *h)
return 0;
}
return SDL_SetError("Software renderer doesn't have an output surface");
SDL_SetError("Software renderer doesn't have an output surface");
return -1;
}
static int
@@ -273,14 +274,12 @@ typedef struct CopyExData
double angle;
SDL_FPoint center;
SDL_RendererFlip flip;
float scale_x;
float scale_y;
} CopyExData;
static int
SW_QueueCopyEx(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * texture,
const SDL_Rect * srcrect, const SDL_FRect * dstrect,
const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip, float scale_x, float scale_y)
const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip)
{
CopyExData *verts = (CopyExData *) SDL_AllocateRenderVertices(renderer, sizeof (CopyExData), 0, &cmd->data.draw.first);
@@ -299,41 +298,21 @@ SW_QueueCopyEx(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * te
verts->angle = angle;
SDL_memcpy(&verts->center, center, sizeof (SDL_FPoint));
verts->flip = flip;
verts->scale_x = scale_x;
verts->scale_y = scale_y;
return 0;
}
static int
Blit_to_Screen(SDL_Surface *src, SDL_Rect *srcrect, SDL_Surface *surface, SDL_Rect *dstrect,
float scale_x, float scale_y, SDL_ScaleMode scaleMode)
{
int retval;
/* Renderer scaling, if needed */
if (scale_x != 1.0f || scale_y != 1.0f) {
SDL_Rect r;
r.x = (int)((float) dstrect->x * scale_x);
r.y = (int)((float) dstrect->y * scale_y);
r.w = (int)((float) dstrect->w * scale_x);
r.h = (int)((float) dstrect->h * scale_y);
retval = SDL_PrivateUpperBlitScaled(src, srcrect, surface, &r, scaleMode);
} else {
retval = SDL_BlitSurface(src, srcrect, surface, dstrect);
}
return retval;
}
static int
SW_RenderCopyEx(SDL_Renderer * renderer, SDL_Surface *surface, SDL_Texture * texture,
const SDL_Rect * srcrect, const SDL_Rect * final_rect,
const double angle, const SDL_FPoint * center, const SDL_RendererFlip flip, float scale_x, float scale_y)
const double angle, const SDL_FPoint * center, const SDL_RendererFlip flip)
{
SDL_Surface *src = (SDL_Surface *) texture->driverdata;
SDL_Rect tmp_rect;
SDL_Surface *src_clone, *src_rotated, *src_scaled;
SDL_Surface *mask = NULL, *mask_rotated = NULL;
int retval = 0;
int retval = 0, dstwidth, dstheight, abscenterx, abscentery;
double cangle, sangle, px, py, p1x, p1y, p2x, p2y, p3x, p3y, p4x, p4y;
SDL_BlendMode blendmode;
Uint8 alphaMod, rMod, gMod, bMod;
int applyModulation = SDL_FALSE;
@@ -435,32 +414,53 @@ SW_RenderCopyEx(SDL_Renderer * renderer, SDL_Surface *surface, SDL_Texture * tex
SDL_SetSurfaceBlendMode(src_clone, blendmode);
if (!retval) {
SDL_Rect rect_dest;
double cangle, sangle;
SDLgfx_rotozoomSurfaceSizeTrig(tmp_rect.w, tmp_rect.h, angle, center,
&rect_dest, &cangle, &sangle);
src_rotated = SDLgfx_rotateSurface(src_clone, angle,
(texture->scaleMode == SDL_ScaleModeNearest) ? 0 : 1, flip & SDL_FLIP_HORIZONTAL, flip & SDL_FLIP_VERTICAL,
&rect_dest, cangle, sangle, center);
SDLgfx_rotozoomSurfaceSizeTrig(tmp_rect.w, tmp_rect.h, angle, &dstwidth, &dstheight, &cangle, &sangle);
src_rotated = SDLgfx_rotateSurface(src_clone, angle, dstwidth/2, dstheight/2, (texture->scaleMode == SDL_ScaleModeNearest) ? 0 : 1, flip & SDL_FLIP_HORIZONTAL, flip & SDL_FLIP_VERTICAL, dstwidth, dstheight, cangle, sangle);
if (src_rotated == NULL) {
retval = -1;
}
if (!retval && mask != NULL) {
/* The mask needed for the NONE blend mode gets rotated with the same parameters. */
mask_rotated = SDLgfx_rotateSurface(mask, angle,
SDL_FALSE, 0, 0,
&rect_dest, cangle, sangle, center);
mask_rotated = SDLgfx_rotateSurface(mask, angle, dstwidth/2, dstheight/2, SDL_FALSE, 0, 0, dstwidth, dstheight, cangle, sangle);
if (mask_rotated == NULL) {
retval = -1;
}
}
if (!retval) {
/* Find out where the new origin is by rotating the four final_rect points around the center and then taking the extremes */
abscenterx = final_rect->x + (int)center->x;
abscentery = final_rect->y + (int)center->y;
/* Compensate the angle inversion to match the behaviour of the other backends */
sangle = -sangle;
tmp_rect.x = final_rect->x + rect_dest.x;
tmp_rect.y = final_rect->y + rect_dest.y;
tmp_rect.w = rect_dest.w;
tmp_rect.h = rect_dest.h;
/* Top Left */
px = final_rect->x - abscenterx;
py = final_rect->y - abscentery;
p1x = px * cangle - py * sangle + abscenterx;
p1y = px * sangle + py * cangle + abscentery;
/* Top Right */
px = final_rect->x + final_rect->w - abscenterx;
py = final_rect->y - abscentery;
p2x = px * cangle - py * sangle + abscenterx;
p2y = px * sangle + py * cangle + abscentery;
/* Bottom Left */
px = final_rect->x - abscenterx;
py = final_rect->y + final_rect->h - abscentery;
p3x = px * cangle - py * sangle + abscenterx;
p3y = px * sangle + py * cangle + abscentery;
/* Bottom Right */
px = final_rect->x + final_rect->w - abscenterx;
py = final_rect->y + final_rect->h - abscentery;
p4x = px * cangle - py * sangle + abscenterx;
p4y = px * sangle + py * cangle + abscentery;
tmp_rect.x = (int)MIN(MIN(p1x, p2x), MIN(p3x, p4x));
tmp_rect.y = (int)MIN(MIN(p1y, p2y), MIN(p3y, p4y));
tmp_rect.w = dstwidth;
tmp_rect.h = dstheight;
/* The NONE blend mode needs some special care with non-opaque surfaces.
* Other blend modes or opaque surfaces can be blitted directly.
@@ -471,8 +471,7 @@ SW_RenderCopyEx(SDL_Renderer * renderer, SDL_Surface *surface, SDL_Texture * tex
SDL_SetSurfaceAlphaMod(src_rotated, alphaMod);
SDL_SetSurfaceColorMod(src_rotated, rMod, gMod, bMod);
}
/* Renderer scaling, if needed */
retval = Blit_to_Screen(src_rotated, NULL, surface, &tmp_rect, scale_x, scale_y, texture->scaleMode);
retval = SDL_BlitSurface(src_rotated, NULL, surface, &tmp_rect);
} else {
/* The NONE blend mode requires three steps to get the pixels onto the destination surface.
* First, the area where the rotated pixels will be blitted to get set to zero.
@@ -481,8 +480,7 @@ SW_RenderCopyEx(SDL_Renderer * renderer, SDL_Surface *surface, SDL_Texture * tex
*/
SDL_Rect mask_rect = tmp_rect;
SDL_SetSurfaceBlendMode(mask_rotated, SDL_BLENDMODE_NONE);
/* Renderer scaling, if needed */
retval = Blit_to_Screen(mask_rotated, NULL, surface, &mask_rect, scale_x, scale_y, texture->scaleMode);
retval = SDL_BlitSurface(mask_rotated, NULL, surface, &mask_rect);
if (!retval) {
/* The next step copies the alpha value. This is done with the BLEND blend mode and
* by modulating the source colors with 0. Since the destination is all zeros, this
@@ -490,8 +488,7 @@ SW_RenderCopyEx(SDL_Renderer * renderer, SDL_Surface *surface, SDL_Texture * tex
*/
SDL_SetSurfaceColorMod(src_rotated, 0, 0, 0);
mask_rect = tmp_rect;
/* Renderer scaling, if needed */
retval = Blit_to_Screen(src_rotated, NULL, surface, &mask_rect, scale_x, scale_y, texture->scaleMode);
retval = SDL_BlitSurface(src_rotated, NULL, surface, &mask_rect);
if (!retval) {
/* The last step gets the color values in place. The ADD blend mode simply adds them to
* the destination (where the color values are all zero). However, because the ADD blend
@@ -507,8 +504,7 @@ SW_RenderCopyEx(SDL_Renderer * renderer, SDL_Surface *surface, SDL_Texture * tex
retval = -1;
} else {
SDL_SetSurfaceBlendMode(src_rotated_rgb, SDL_BLENDMODE_ADD);
/* Renderer scaling, if needed */
retval = Blit_to_Screen(src_rotated_rgb, NULL, surface, &tmp_rect, scale_x, scale_y, texture->scaleMode);
retval = SDL_BlitSurface(src_rotated_rgb, NULL, surface, &tmp_rect);
SDL_FreeSurface(src_rotated_rgb);
}
}
@@ -827,42 +823,7 @@ SW_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertic
* to avoid potentially frequent RLE encoding/decoding.
*/
SDL_SetSurfaceRLE(surface, 0);
/* Prevent to do scaling + clipping on viewport boundaries as it may lose proportion */
if (dstrect->x < 0 || dstrect->y < 0 || dstrect->x + dstrect->w > surface->w || dstrect->y + dstrect->h > surface->h) {
SDL_Surface *tmp = SDL_CreateRGBSurfaceWithFormat(0, dstrect->w, dstrect->h, 0, src->format->format);
/* Scale to an intermediate surface, then blit */
if (tmp) {
SDL_Rect r;
SDL_BlendMode blendmode;
Uint8 alphaMod, rMod, gMod, bMod;
SDL_GetSurfaceBlendMode(src, &blendmode);
SDL_GetSurfaceAlphaMod(src, &alphaMod);
SDL_GetSurfaceColorMod(src, &rMod, &gMod, &bMod);
r.x = 0;
r.y = 0;
r.w = dstrect->w;
r.h = dstrect->h;
SDL_SetSurfaceBlendMode(src, SDL_BLENDMODE_NONE);
SDL_SetSurfaceColorMod(src, 255, 255, 255);
SDL_SetSurfaceAlphaMod(src, 255);
SDL_PrivateUpperBlitScaled(src, srcrect, tmp, &r, texture->scaleMode);
SDL_SetSurfaceColorMod(tmp, rMod, gMod, bMod);
SDL_SetSurfaceAlphaMod(tmp, alphaMod);
SDL_SetSurfaceBlendMode(tmp, blendmode);
SDL_BlitSurface(tmp, NULL, surface, dstrect);
SDL_FreeSurface(tmp);
/* No need to set back r/g/b/a/blendmode to 'src' since it's done in PrepTextureForCopy() */
}
} else{
SDL_PrivateUpperBlitScaled(src, srcrect, surface, dstrect, texture->scaleMode);
}
SDL_PrivateUpperBlitScaled(src, srcrect, surface, dstrect, texture->scaleMode);
}
break;
}
@@ -879,8 +840,7 @@ SW_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertic
}
SW_RenderCopyEx(renderer, surface, cmd->data.draw.texture, &copydata->srcrect,
&copydata->dstrect, copydata->angle, &copydata->center, copydata->flip,
copydata->scale_x, copydata->scale_y);
&copydata->dstrect, copydata->angle, &copydata->center, copydata->flip);
break;
}
@@ -1017,7 +977,7 @@ SW_CreateRendererForSurface(SDL_Surface * surface)
SW_RenderData *data;
if (!surface) {
SDL_InvalidParamError("surface");
SDL_SetError("Can't create renderer for NULL surface");
return NULL;
}

View File

@@ -61,6 +61,11 @@ typedef struct tColorY {
Uint8 y;
} tColorY;
/* !
\brief Returns maximum of two numbers a and b.
*/
#define MAX(a,b) (((a) > (b)) ? (a) : (b))
/* !
\brief Number of guard rows added to destination surfaces.
@@ -77,7 +82,7 @@ to a situation where the program can segfault.
\brief Returns colorkey info for a surface
*/
static Uint32
get_colorkey(SDL_Surface *src)
_colorkey(SDL_Surface *src)
{
Uint32 key = 0;
if (SDL_HasColorKey(src)) {
@@ -86,18 +91,6 @@ get_colorkey(SDL_Surface *src)
return key;
}
/* rotate (sx, sy) by (angle, center) into (dx, dy) */
static void
rotate(double sx, double sy, double sinangle, double cosangle, const SDL_FPoint *center, double *dx, double *dy) {
sx -= center->x;
sy -= center->y;
*dx = cosangle * sx - sinangle * sy;
*dy = sinangle * sx + cosangle * sy;
*dx += center->x;
*dy += center->y;
}
/* !
\brief Internal target surface sizing function for rotations with trig result return.
@@ -112,61 +105,49 @@ rotate(double sx, double sy, double sinangle, double cosangle, const SDL_FPoint
*/
void
SDLgfx_rotozoomSurfaceSizeTrig(int width, int height, double angle, const SDL_FPoint *center,
SDL_Rect *rect_dest, double *cangle, double *sangle)
SDLgfx_rotozoomSurfaceSizeTrig(int width, int height, double angle,
int *dstwidth, int *dstheight,
double *cangle, double *sangle)
{
int minx, maxx, miny, maxy;
double radangle;
double x0, x1, x2, x3;
double y0, y1, y2, y3;
double sinangle;
double cosangle;
radangle = angle * (M_PI / 180.0);
sinangle = SDL_sin(radangle);
cosangle = SDL_cos(radangle);
/*
* Determine destination width and height by rotating a source box, at pixel center
*/
rotate(0.5, 0.5, sinangle, cosangle, center, &x0, &y0);
rotate(width - 0.5, 0.5, sinangle, cosangle, center, &x1, &y1);
rotate(0.5, height - 0.5, sinangle, cosangle, center, &x2, &y2);
rotate(width - 0.5, height - 0.5, sinangle, cosangle, center, &x3, &y3);
minx = (int)SDL_floor( SDL_min( SDL_min(x0, x1), SDL_min(x2, x3) ) );
maxx = (int)SDL_ceil( SDL_max( SDL_max(x0, x1), SDL_max(x2, x3) ) );
miny = (int)SDL_floor( SDL_min( SDL_min(y0, y1), SDL_min(y2, y3) ) );
maxy = (int)SDL_ceil( SDL_max( SDL_max(y0, y1), SDL_max(y2, y3) ) );
rect_dest->w = maxx - minx;
rect_dest->h = maxy - miny;
rect_dest->x = minx;
rect_dest->y = miny;
/* reverse the angle because our rotations are clockwise */
*sangle = -sinangle;
*cangle = cosangle;
{
/* The trig code below gets the wrong size (due to FP inaccuracy?) when angle is a multiple of 90 degrees */
int angle90 = (int)(angle/90);
if(angle90 == angle/90) { /* if the angle is a multiple of 90 degrees */
angle90 %= 4;
if(angle90 < 0) angle90 += 4; /* 0:0 deg, 1:90 deg, 2:180 deg, 3:270 deg */
if(angle90 & 1) {
rect_dest->w = height;
rect_dest->h = width;
*cangle = 0;
*sangle = angle90 == 1 ? -1 : 1; /* reversed because our rotations are clockwise */
} else {
rect_dest->w = width;
rect_dest->h = height;
*cangle = angle90 == 0 ? 1 : -1;
*sangle = 0;
}
/* The trig code below gets the wrong size (due to FP inaccuracy?) when angle is a multiple of 90 degrees */
int angle90 = (int)(angle/90);
if(angle90 == angle/90) { /* if the angle is a multiple of 90 degrees */
angle90 %= 4;
if(angle90 < 0) angle90 += 4; /* 0:0 deg, 1:90 deg, 2:180 deg, 3:270 deg */
if(angle90 & 1) {
*dstwidth = height;
*dstheight = width;
*cangle = 0;
*sangle = angle90 == 1 ? -1 : 1; /* reversed because our rotations are clockwise */
} else {
*dstwidth = width;
*dstheight = height;
*cangle = angle90 == 0 ? 1 : -1;
*sangle = 0;
}
} else {
double x, y, cx, cy, sx, sy;
double radangle;
int dstwidthhalf, dstheighthalf;
/*
* Determine destination width and height by rotating a centered source box
*/
radangle = angle * (M_PI / -180.0); /* reverse the angle because our rotations are clockwise */
*sangle = SDL_sin(radangle);
*cangle = SDL_cos(radangle);
x = (double)(width / 2);
y = (double)(height / 2);
cx = *cangle * x;
cy = *cangle * y;
sx = *sangle * x;
sy = *sangle * y;
dstwidthhalf = MAX((int)
SDL_ceil(MAX(MAX(MAX(SDL_fabs(cx + sy), SDL_fabs(cx - sy)), SDL_fabs(-cx + sy)), SDL_fabs(-cx - sy))), 1);
dstheighthalf = MAX((int)
SDL_ceil(MAX(MAX(MAX(SDL_fabs(sx + cy), SDL_fabs(sx - cy)), SDL_fabs(-sx + cy)), SDL_fabs(-sx - cy))), 1);
*dstwidth = 2 * dstwidthhalf;
*dstheight = 2 * dstheighthalf;
}
}
@@ -239,56 +220,48 @@ Assumes dst surface was allocated with the correct dimensions.
\param src Source surface.
\param dst Destination surface.
\param cx Horizontal center coordinate.
\param cy Vertical center coordinate.
\param isin Integer version of sine of angle.
\param icos Integer version of cosine of angle.
\param flipx Flag indicating horizontal mirroring should be applied.
\param flipy Flag indicating vertical mirroring should be applied.
\param smooth Flag indicating anti-aliasing should be used.
\param dst_rect destination coordinates
\param center true center.
*/
static void
transformSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int isin, int icos,
int flipx, int flipy, int smooth,
const SDL_Rect *rect_dest,
const SDL_FPoint *center)
_transformSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int cx, int cy, int isin, int icos, int flipx, int flipy, int smooth)
{
int sw, sh;
int cx, cy;
int x, y, t1, t2, dx, dy, xd, yd, sdx, sdy, ax, ay, ex, ey, sw, sh;
tColorRGBA c00, c01, c10, c11, cswap;
tColorRGBA *pc, *sp;
int gap;
const int fp_half = (1<<15);
/*
* Variable setup
*/
xd = ((src->w - dst->w) << 15);
yd = ((src->h - dst->h) << 15);
ax = (cx << 16) - (icos * cx);
ay = (cy << 16) - (isin * cx);
sw = src->w - 1;
sh = src->h - 1;
pc = (tColorRGBA*) dst->pixels;
gap = dst->pitch - dst->w * 4;
cx = (int)(center->x * 65536.0);
cy = (int)(center->y * 65536.0);
/*
* Switch between interpolating and non-interpolating code
*/
if (smooth) {
int y;
for (y = 0; y < dst->h; y++) {
int x;
double src_x = (rect_dest->x + 0 + 0.5 - center->x);
double src_y = (rect_dest->y + y + 0.5 - center->y);
int sdx = (int)((icos * src_x - isin * src_y) + cx - fp_half);
int sdy = (int)((isin * src_x + icos * src_y) + cy - fp_half);
dy = cy - y;
sdx = (ax + (isin * dy)) + xd;
sdy = (ay - (icos * dy)) + yd;
for (x = 0; x < dst->w; x++) {
int dx = (sdx >> 16);
int dy = (sdy >> 16);
dx = (sdx >> 16);
dy = (sdy >> 16);
if (flipx) dx = sw - dx;
if (flipy) dy = sh - dy;
if ((dx > -1) && (dy > -1) && (dx < (src->w-1)) && (dy < (src->h-1))) {
int ex, ey;
int t1, t2;
sp = (tColorRGBA *) ((Uint8 *) src->pixels + src->pitch * dy) + dx;
c00 = *sp;
sp += 1;
@@ -330,16 +303,13 @@ transformSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int isin, int icos,
pc = (tColorRGBA *) ((Uint8 *) pc + gap);
}
} else {
int y;
for (y = 0; y < dst->h; y++) {
int x;
double src_x = (rect_dest->x + 0 + 0.5 - center->x);
double src_y = (rect_dest->y + y + 0.5 - center->y);
int sdx = (int)((icos * src_x - isin * src_y) + cx - fp_half);
int sdy = (int)((isin * src_x + icos * src_y) + cy - fp_half);
dy = cy - y;
sdx = (ax + (isin * dy)) + xd;
sdy = (ay - (icos * dy)) + yd;
for (x = 0; x < dst->w; x++) {
int dx = (sdx >> 16);
int dy = (sdy >> 16);
dx = (sdx >> 16);
dy = (sdy >> 16);
if ((unsigned)dx < (unsigned)src->w && (unsigned)dy < (unsigned)src->h) {
if(flipx) dx = sw - dx;
if(flipy) dy = sh - dy;
@@ -365,54 +335,46 @@ Assumes dst surface was allocated with the correct dimensions.
\param src Source surface.
\param dst Destination surface.
\param cx Horizontal center coordinate.
\param cy Vertical center coordinate.
\param isin Integer version of sine of angle.
\param icos Integer version of cosine of angle.
\param flipx Flag indicating horizontal mirroring should be applied.
\param flipy Flag indicating vertical mirroring should be applied.
\param dst_rect destination coordinates
\param center true center.
*/
static void
transformSurfaceY(SDL_Surface * src, SDL_Surface * dst, int isin, int icos, int flipx, int flipy,
const SDL_Rect *rect_dest,
const SDL_FPoint *center)
transformSurfaceY(SDL_Surface * src, SDL_Surface * dst, int cx, int cy, int isin, int icos, int flipx, int flipy)
{
int sw, sh;
int cx, cy;
int x, y, dx, dy, xd, yd, sdx, sdy, ax, ay;
tColorY *pc;
int gap;
const int fp_half = (1<<15);
int y;
/*
* Variable setup
*/
sw = src->w - 1;
sh = src->h - 1;
xd = ((src->w - dst->w) << 15);
yd = ((src->h - dst->h) << 15);
ax = (cx << 16) - (icos * cx);
ay = (cy << 16) - (isin * cx);
pc = (tColorY*) dst->pixels;
gap = dst->pitch - dst->w;
cx = (int)(center->x * 65536.0);
cy = (int)(center->y * 65536.0);
/*
* Clear surface to colorkey
*/
SDL_memset(pc, (int)(get_colorkey(src) & 0xff), dst->pitch * dst->h);
SDL_memset(pc, (int)(_colorkey(src) & 0xff), dst->pitch * dst->h);
/*
* Iterate through destination surface
*/
for (y = 0; y < dst->h; y++) {
int x;
double src_x = (rect_dest->x + 0 + 0.5 - center->x);
double src_y = (rect_dest->y + y + 0.5 - center->y);
int sdx = (int)((icos * src_x - isin * src_y) + cx - fp_half);
int sdy = (int)((isin * src_x + icos * src_y) + cy - fp_half);
dy = cy - y;
sdx = (ax + (isin * dy)) + xd;
sdy = (ay - (icos * dy)) + yd;
for (x = 0; x < dst->w; x++) {
int dx = (sdx >> 16);
int dy = (sdy >> 16);
dx = (sdx >> 16);
dy = (sdy >> 16);
if ((unsigned)dx < (unsigned)src->w && (unsigned)dy < (unsigned)src->h) {
if (flipx) dx = sw - dx;
if (flipy) dy = sh- dy;
if (flipx) dx = (src->w-1)-dx;
if (flipy) dy = (src->h-1)-dy;
*pc = *((tColorY *)src->pixels + src->pitch * dy + dx);
}
sdx += icos;
@@ -428,7 +390,7 @@ transformSurfaceY(SDL_Surface * src, SDL_Surface * dst, int isin, int icos, int
\brief Rotates and zooms a surface with different horizontal and vertival scaling factors and optional anti-aliasing.
Rotates a 32-bit or 8-bit 'src' surface to newly created 'dst' surface.
'angle' is the rotation in degrees, 'center' the rotation center. If 'smooth' is set
'angle' is the rotation in degrees, 'centerx' and 'centery' the rotation center. If 'smooth' is set
then the destination 32-bit surface is anti-aliased. 8-bit surfaces must have a colorkey. 32-bit
surfaces must have a 8888 layout with red, green, blue and alpha masks (any ordering goes).
The blend mode of the 'src' surface has some effects on generation of the 'dst' surface: The NONE
@@ -438,21 +400,21 @@ When using the NONE and MOD modes, color and alpha modulation must be applied be
\param src The surface to rotozoom.
\param angle The angle to rotate in degrees.
\param centerx The horizontal coordinate of the center of rotation
\param zoomy The vertical coordinate of the center of rotation
\param smooth Antialiasing flag; set to SMOOTHING_ON to enable.
\param flipx Set to 1 to flip the image horizontally
\param flipy Set to 1 to flip the image vertically
\param rect_dest The destination rect bounding box
\param dstwidth The destination surface width
\param dstheight The destination surface height
\param cangle The angle cosine
\param sangle The angle sine
\param center The true coordinate of the center of rotation
\return The new rotated surface.
*/
SDL_Surface *
SDLgfx_rotateSurface(SDL_Surface * src, double angle, int smooth, int flipx, int flipy,
const SDL_Rect *rect_dest, double cangle, double sangle, const SDL_FPoint *center)
SDLgfx_rotateSurface(SDL_Surface * src, double angle, int centerx, int centery, int smooth, int flipx, int flipy, int dstwidth, int dstheight, double cangle, double sangle)
{
SDL_Surface *rz_dst;
int is8bit, angle90;
@@ -471,6 +433,7 @@ SDLgfx_rotateSurface(SDL_Surface * src, double angle, int smooth, int flipx, int
colorKeyAvailable = SDL_TRUE;
}
}
/* This function requires a 32-bit surface or 8-bit surface with a colorkey */
is8bit = src->format->BitsPerPixel == 8 && colorKeyAvailable;
if (!(is8bit || (src->format->BitsPerPixel == 32 && src->format->Amask)))
@@ -484,18 +447,16 @@ SDLgfx_rotateSurface(SDL_Surface * src, double angle, int smooth, int flipx, int
rz_dst = NULL;
if (is8bit) {
/* Target surface is 8 bit */
rz_dst = SDL_CreateRGBSurfaceWithFormat(0, rect_dest->w, rect_dest->h + GUARD_ROWS, 8, src->format->format);
rz_dst = SDL_CreateRGBSurface(0, dstwidth, dstheight + GUARD_ROWS, 8, 0, 0, 0, 0);
if (rz_dst != NULL) {
if (src->format->palette) {
for (i = 0; i < src->format->palette->ncolors; i++) {
rz_dst->format->palette->colors[i] = src->format->palette->colors[i];
}
rz_dst->format->palette->ncolors = src->format->palette->ncolors;
for (i = 0; i < src->format->palette->ncolors; i++) {
rz_dst->format->palette->colors[i] = src->format->palette->colors[i];
}
rz_dst->format->palette->ncolors = src->format->palette->ncolors;
}
} else {
/* Target surface is 32 bit with source RGBA ordering */
rz_dst = SDL_CreateRGBSurface(0, rect_dest->w, rect_dest->h + GUARD_ROWS, 32,
rz_dst = SDL_CreateRGBSurface(0, dstwidth, dstheight + GUARD_ROWS, 32,
src->format->Rmask, src->format->Gmask,
src->format->Bmask, src->format->Amask);
}
@@ -505,7 +466,7 @@ SDLgfx_rotateSurface(SDL_Surface * src, double angle, int smooth, int flipx, int
return NULL;
/* Adjust for guard rows */
rz_dst->h = rect_dest->h;
rz_dst->h = dstheight;
SDL_GetSurfaceBlendMode(src, &blendmode);
@@ -536,7 +497,7 @@ SDLgfx_rotateSurface(SDL_Surface * src, double angle, int smooth, int flipx, int
}
/* check if the rotation is a multiple of 90 degrees so we can take a fast path and also somewhat reduce
* the off-by-one problem in transformSurfaceRGBA that expresses itself when the rotation is near
* the off-by-one problem in _transformSurfaceRGBA that expresses itself when the rotation is near
* multiples of 90 degrees.
*/
angle90 = (int)(angle/90);
@@ -552,16 +513,16 @@ SDLgfx_rotateSurface(SDL_Surface * src, double angle, int smooth, int flipx, int
if(angle90 >= 0) {
transformSurfaceY90(src, rz_dst, angle90, flipx, flipy);
} else {
transformSurfaceY(src, rz_dst, (int)sangleinv, (int)cangleinv,
flipx, flipy, rect_dest, center);
transformSurfaceY(src, rz_dst, centerx, centery, (int)sangleinv, (int)cangleinv,
flipx, flipy);
}
} else {
/* Call the 32-bit transformation routine to do the rotation */
if (angle90 >= 0) {
transformSurfaceRGBA90(src, rz_dst, angle90, flipx, flipy);
} else {
transformSurfaceRGBA(src, rz_dst, (int)sangleinv, (int)cangleinv,
flipx, flipy, smooth, rect_dest, center);
_transformSurfaceRGBA(src, rz_dst, centerx, centery, (int)sangleinv, (int)cangleinv,
flipx, flipy, smooth);
}
}

View File

@@ -22,9 +22,11 @@
#ifndef SDL_rotate_h_
#define SDL_rotate_h_
extern SDL_Surface *SDLgfx_rotateSurface(SDL_Surface * src, double angle, int smooth, int flipx, int flipy,
const SDL_Rect *rect_dest, double cangle, double sangle, const SDL_FPoint *center);
extern void SDLgfx_rotozoomSurfaceSizeTrig(int width, int height, double angle, const SDL_FPoint *center,
SDL_Rect *rect_dest, double *cangle, double *sangle);
#ifndef MIN
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
#endif
extern SDL_Surface *SDLgfx_rotateSurface(SDL_Surface * src, double angle, int centerx, int centery, int smooth, int flipx, int flipy, int dstwidth, int dstheight, double cangle, double sangle);
extern void SDLgfx_rotozoomSurfaceSizeTrig(int width, int height, double angle, int *dstwidth, int *dstheight, double *cangle, double *sangle);
#endif /* SDL_rotate_h_ */

View File

@@ -718,21 +718,6 @@ end:
}
#define FORMAT_ALPHA 0
#define FORMAT_NO_ALPHA -1
#define FORMAT_2101010 1
#define FORMAT_HAS_ALPHA(format) format == 0
#define FORMAT_HAS_NO_ALPHA(format) format < 0
static int SDL_INLINE detect_format(SDL_PixelFormat *pf) {
if (pf->format == SDL_PIXELFORMAT_ARGB2101010) {
return FORMAT_2101010;
} else if (pf->Amask) {
return FORMAT_ALPHA;
} else {
return FORMAT_NO_ALPHA;
}
}
static void
SDL_BlitTriangle_Slow(SDL_BlitInfo *info,
SDL_Point s2_x_area, SDL_Rect dstrect, int area, int bias_w0, int bias_w1, int bias_w2,
@@ -753,32 +738,25 @@ SDL_BlitTriangle_Slow(SDL_BlitInfo *info,
SDL_PixelFormat *dst_fmt = info->dst_fmt;
int srcbpp = src_fmt->BytesPerPixel;
int dstbpp = dst_fmt->BytesPerPixel;
int srcfmt_val;
int dstfmt_val;
Uint32 rgbmask = ~src_fmt->Amask;
Uint32 ckey = info->colorkey & rgbmask;
Uint8 *dst_ptr = info->dst;
int dst_pitch = info->dst_pitch;;
srcfmt_val = detect_format(src_fmt);
dstfmt_val = detect_format(dst_fmt);
TRIANGLE_BEGIN_LOOP
{
Uint8 *src;
Uint8 *dst = dptr;
TRIANGLE_GET_TEXTCOORD
src = (info->src + (srcy * info->src_pitch) + (srcx * srcbpp));
if (FORMAT_HAS_ALPHA(srcfmt_val)) {
DISEMBLE_RGBA(src, srcbpp, src_fmt, srcpixel, srcR, srcG, srcB, srcA);
} else if (FORMAT_HAS_NO_ALPHA(srcfmt_val)) {
DISEMBLE_RGB(src, srcbpp, src_fmt, srcpixel, srcR, srcG, srcB);
srcA = 0xFF;
if (src_fmt->Amask) {
DISEMBLE_RGBA(src, srcbpp, src_fmt, srcpixel, srcR, srcG,
srcB, srcA);
} else {
/* SDL_PIXELFORMAT_ARGB2101010 */
srcpixel = *((Uint32 *)(src));
RGBA_FROM_ARGB2101010(srcpixel, srcR, srcG, srcB, srcA);
DISEMBLE_RGB(src, srcbpp, src_fmt, srcpixel, srcR, srcG,
srcB);
srcA = 0xFF;
}
if (flags & SDL_COPY_COLORKEY) {
/* srcpixel isn't set for 24 bpp */
@@ -790,15 +768,13 @@ SDL_BlitTriangle_Slow(SDL_BlitInfo *info,
continue;
}
}
if (FORMAT_HAS_ALPHA(dstfmt_val)) {
DISEMBLE_RGBA(dst, dstbpp, dst_fmt, dstpixel, dstR, dstG, dstB, dstA);
} else if (FORMAT_HAS_NO_ALPHA(dstfmt_val)) {
DISEMBLE_RGB(dst, dstbpp, dst_fmt, dstpixel, dstR, dstG, dstB);
dstA = 0xFF;
if (dst_fmt->Amask) {
DISEMBLE_RGBA(dst, dstbpp, dst_fmt, dstpixel, dstR, dstG,
dstB, dstA);
} else {
/* SDL_PIXELFORMAT_ARGB2101010 */
dstpixel = *((Uint32 *)(dst));
RGBA_FROM_ARGB2101010(dstpixel, dstR, dstG, dstB, dstA);
DISEMBLE_RGB(dst, dstbpp, dst_fmt, dstpixel, dstR, dstG,
dstB);
dstA = 0xFF;
}
if (! is_uniform) {
@@ -869,15 +845,10 @@ SDL_BlitTriangle_Slow(SDL_BlitInfo *info,
dstA = 255;
break;
}
if (FORMAT_HAS_ALPHA(dstfmt_val)) {
if (dst_fmt->Amask) {
ASSEMBLE_RGBA(dst, dstbpp, dst_fmt, dstR, dstG, dstB, dstA);
} else if (FORMAT_HAS_NO_ALPHA(dstfmt_val)) {
ASSEMBLE_RGB(dst, dstbpp, dst_fmt, dstR, dstG, dstB);
} else {
/* SDL_PIXELFORMAT_ARGB2101010 */
Uint32 pixel;
ARGB2101010_FROM_RGBA(pixel, dstR, dstG, dstB, dstA);
*(Uint32 *)dst = pixel;
ASSEMBLE_RGB(dst, dstbpp, dst_fmt, dstR, dstG, dstB);
}
}
TRIANGLE_END_LOOP

View File

@@ -61,11 +61,6 @@ static int VITA_GXM_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * text
const Uint8 *Uplane, int Upitch,
const Uint8 *Vplane, int Vpitch);
static int VITA_GXM_UpdateTextureNV(SDL_Renderer * renderer, SDL_Texture * texture,
const SDL_Rect * rect,
const Uint8 *Yplane, int Ypitch,
const Uint8 *UVplane, int UVpitch);
static int VITA_GXM_LockTexture(SDL_Renderer *renderer, SDL_Texture *texture,
const SDL_Rect *rect, void **pixels, int *pitch);
@@ -110,16 +105,12 @@ SDL_RenderDriver VITA_GXM_RenderDriver = {
.info = {
.name = "VITA gxm",
.flags = SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_TARGETTEXTURE,
.num_texture_formats = 8,
.num_texture_formats = 4,
.texture_formats = {
[0] = SDL_PIXELFORMAT_ABGR8888,
[1] = SDL_PIXELFORMAT_ARGB8888,
[2] = SDL_PIXELFORMAT_RGB565,
[3] = SDL_PIXELFORMAT_BGR565,
[4] = SDL_PIXELFORMAT_YV12,
[5] = SDL_PIXELFORMAT_IYUV,
[6] = SDL_PIXELFORMAT_NV12,
[7] = SDL_PIXELFORMAT_NV21,
[3] = SDL_PIXELFORMAT_BGR565
},
.max_texture_width = 4096,
.max_texture_height = 4096,
@@ -142,15 +133,6 @@ PixelFormatToVITAFMT(Uint32 format)
return SCE_GXM_TEXTURE_FORMAT_U5U6U5_RGB;
case SDL_PIXELFORMAT_BGR565:
return SCE_GXM_TEXTURE_FORMAT_U5U6U5_BGR;
case SDL_PIXELFORMAT_YV12:
return SCE_GXM_TEXTURE_FORMAT_YVU420P3_CSC0;
case SDL_PIXELFORMAT_IYUV:
return SCE_GXM_TEXTURE_FORMAT_YUV420P3_CSC0;
// should be the other way around. looks like SCE bug.
case SDL_PIXELFORMAT_NV12:
return SCE_GXM_TEXTURE_FORMAT_YVU420P2_CSC0;
case SDL_PIXELFORMAT_NV21:
return SCE_GXM_TEXTURE_FORMAT_YUV420P2_CSC0;
default:
return SCE_GXM_TEXTURE_FORMAT_U8U8U8U8_ABGR;
}
@@ -235,7 +217,7 @@ VITA_GXM_CreateRenderer(SDL_Window *window, Uint32 flags)
data = (VITA_GXM_RenderData *) SDL_calloc(1, sizeof(VITA_GXM_RenderData));
if (!data) {
SDL_free(renderer);
VITA_GXM_DestroyRenderer(renderer);
SDL_OutOfMemory();
return NULL;
}
@@ -244,10 +226,7 @@ VITA_GXM_CreateRenderer(SDL_Window *window, Uint32 flags)
renderer->SupportsBlendMode = VITA_GXM_SupportsBlendMode;
renderer->CreateTexture = VITA_GXM_CreateTexture;
renderer->UpdateTexture = VITA_GXM_UpdateTexture;
#if SDL_HAVE_YUV
renderer->UpdateTextureYUV = VITA_GXM_UpdateTextureYUV;
renderer->UpdateTextureNV = VITA_GXM_UpdateTextureNV;
#endif
renderer->LockTexture = VITA_GXM_LockTexture;
renderer->UnlockTexture = VITA_GXM_UnlockTexture;
renderer->SetTextureScaleMode = VITA_GXM_SetTextureScaleMode;
@@ -314,17 +293,7 @@ VITA_GXM_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture)
return SDL_OutOfMemory();
}
vita_texture->tex = create_gxm_texture(
data,
texture->w,
texture->h,
PixelFormatToVITAFMT(texture->format),
(texture->access == SDL_TEXTUREACCESS_TARGET),
&(vita_texture->w),
&(vita_texture->h),
&(vita_texture->pitch),
&(vita_texture->wscale)
);
vita_texture->tex = create_gxm_texture(data, texture->w, texture->h, PixelFormatToVITAFMT(texture->format), (texture->access == SDL_TEXTUREACCESS_TARGET));
if (!vita_texture->tex) {
SDL_free(vita_texture);
@@ -335,129 +304,38 @@ VITA_GXM_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture)
VITA_GXM_SetTextureScaleMode(renderer, texture, texture->scaleMode);
#if SDL_HAVE_YUV
vita_texture->yuv = ((texture->format == SDL_PIXELFORMAT_IYUV) || (texture->format == SDL_PIXELFORMAT_YV12));
vita_texture->nv12 = ((texture->format == SDL_PIXELFORMAT_NV12) || (texture->format == SDL_PIXELFORMAT_NV21));
#endif
vita_texture->w = gxm_texture_get_width(vita_texture->tex);
vita_texture->h = gxm_texture_get_height(vita_texture->tex);
vita_texture->pitch = gxm_texture_get_stride(vita_texture->tex);
return 0;
}
static void VITA_GXM_SetYUVProfile(SDL_Renderer * renderer, SDL_Texture *texture)
{
VITA_GXM_RenderData *data = (VITA_GXM_RenderData *) renderer->driverdata;
int ret = 0;
switch (SDL_GetYUVConversionModeForResolution(texture->w, texture->h)) {
case SDL_YUV_CONVERSION_BT601:
ret = sceGxmSetYuvProfile(data->gxm_context, 0, SCE_GXM_YUV_PROFILE_BT601_STANDARD);
break;
case SDL_YUV_CONVERSION_BT709:
ret = sceGxmSetYuvProfile(data->gxm_context, 0, SCE_GXM_YUV_PROFILE_BT709_STANDARD);
break;
case SDL_YUV_CONVERSION_JPEG:
default:
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "Unsupported YUV profile: %d\n", SDL_GetYUVConversionModeForResolution(texture->w, texture->h));
break;
}
if (ret < 0) {
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "Setting YUV profile failed: %x\n", ret);
}
}
static int
VITA_GXM_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture,
const SDL_Rect *rect, const void *pixels, int pitch)
{
VITA_GXM_TextureData *vita_texture = (VITA_GXM_TextureData *) texture->driverdata;
const Uint8 *src;
Uint8 *dst;
int row, length, dpitch;
#if SDL_HAVE_YUV
if (vita_texture->yuv || vita_texture->nv12) {
VITA_GXM_SetYUVProfile(renderer, texture);
}
#endif
int row, length,dpitch;
src = pixels;
VITA_GXM_LockTexture(renderer, texture, rect, (void **)&dst, &dpitch);
length = rect->w * SDL_BYTESPERPIXEL(texture->format);
if (length == pitch && length == dpitch) {
SDL_memcpy(dst, pixels, length*rect->h);
SDL_memcpy(dst, src, length*rect->h);
} else {
for (row = 0; row < rect->h; ++row) {
SDL_memcpy(dst, pixels, length);
pixels += pitch;
SDL_memcpy(dst, src, length);
src += pitch;
dst += dpitch;
}
}
#if SDL_HAVE_YUV
if (vita_texture->yuv) {
void *Udst;
void *Vdst;
int uv_pitch = (dpitch+1) / 2;
int uv_src_pitch = (pitch+1) / 2;
SDL_Rect UVrect = {rect->x / 2, rect->y / 2, (rect->w + 1) / 2, (rect->h + 1) / 2};
// skip Y plane
Uint8 *Dpixels = gxm_texture_get_datap(vita_texture->tex) + (vita_texture->pitch * vita_texture->h);
Udst = Dpixels + (UVrect.y * uv_pitch) + UVrect.x;
Vdst = Dpixels + (uv_pitch * ((vita_texture->h + 1) / 2)) + (UVrect.y * uv_pitch) + UVrect.x;
length = UVrect.w;
// U plane
if (length == uv_src_pitch && length == uv_pitch) {
SDL_memcpy(Udst, pixels, length*UVrect.h);
} else {
for (row = 0; row < UVrect.h; ++row) {
SDL_memcpy(Udst, pixels, length);
pixels += uv_src_pitch;
Udst += uv_pitch;
}
}
// V plane
if (length == uv_src_pitch && length == uv_pitch) {
SDL_memcpy(Vdst, pixels, length*UVrect.h);
} else {
for (row = 0; row < UVrect.h; ++row) {
SDL_memcpy(Vdst, pixels, length);
pixels += uv_src_pitch;
Vdst += uv_pitch;
}
}
} else if (vita_texture->nv12) {
void *UVdst;
int uv_pitch = 2 * ((dpitch+1) / 2);
int uv_src_pitch = 2 * ((pitch+1) / 2);
SDL_Rect UVrect = {rect->x / 2, rect->y / 2, (rect->w + 1) / 2 , (rect->h + 1) / 2};
// skip Y plane
void *Dpixels = (void *) ((Uint8 *) gxm_texture_get_datap(vita_texture->tex) + (vita_texture->pitch * vita_texture->h));
UVdst = Dpixels + (UVrect.y * uv_pitch) + UVrect.x;
length = UVrect.w*2;
// UV plane
if (length == uv_src_pitch && length == uv_pitch) {
SDL_memcpy(UVdst, pixels, length*UVrect.h);
} else {
for (row = 0; row < UVrect.h; ++row) {
SDL_memcpy(UVdst, pixels, length);
pixels += uv_src_pitch;
UVdst += uv_pitch;
}
}
}
#endif
return 0;
}
#if SDL_HAVE_YUV
static int
VITA_GXM_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * texture,
const SDL_Rect * rect,
@@ -465,133 +343,9 @@ VITA_GXM_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * texture,
const Uint8 *Uplane, int Upitch,
const Uint8 *Vplane, int Vpitch)
{
Uint8 *dst;
int row, length, dpitch;
SDL_Rect UVrect = {rect->x / 2, rect->y / 2, (rect->w + 1) / 2, (rect->h + 1) / 2};
VITA_GXM_SetYUVProfile(renderer, texture);
// copy Y plane
// obtain pixels via locking so that texture is flushed
VITA_GXM_LockTexture(renderer, texture, rect, (void **)&dst, &dpitch);
length = rect->w;
if (length == Ypitch && length == dpitch) {
SDL_memcpy(dst, Yplane, length*rect->h);
} else {
for (row = 0; row < rect->h; ++row) {
SDL_memcpy(dst, Yplane, length);
Yplane += Ypitch;
dst += dpitch;
}
}
// U/V planes
{
void *Udst;
void *Vdst;
VITA_GXM_TextureData *vita_texture = (VITA_GXM_TextureData *) texture->driverdata;
int uv_pitch = (dpitch+1) / 2;
// skip Y plane
void *pixels = (void *) ((Uint8 *) gxm_texture_get_datap(vita_texture->tex) + (vita_texture->pitch * vita_texture->h));
if (texture->format == SDL_PIXELFORMAT_YV12) { // YVU
Vdst = pixels + (UVrect.y * uv_pitch) + UVrect.x;
Udst = pixels + (uv_pitch * ((vita_texture->h + 1) / 2)) + (UVrect.y * uv_pitch) + UVrect.x;
} else { // YUV
Udst = pixels + (UVrect.y * uv_pitch) + UVrect.x;
Vdst = pixels + (uv_pitch * ((vita_texture->h + 1) / 2)) + (UVrect.y * uv_pitch) + UVrect.x;
}
length = UVrect.w;
// U plane
if (length == Upitch && length == uv_pitch) {
SDL_memcpy(Udst, Uplane, length*UVrect.h);
} else {
for (row = 0; row < UVrect.h; ++row) {
SDL_memcpy(Udst, Uplane, length);
Uplane += Upitch;
Udst += uv_pitch;
}
}
// V plane
if (length == Vpitch && length == uv_pitch) {
SDL_memcpy(Vdst, Vplane, length*UVrect.h);
} else {
for (row = 0; row < UVrect.h; ++row) {
SDL_memcpy(Vdst, Vplane, length);
Vplane += Vpitch;
Vdst += uv_pitch;
}
}
}
return 0;
}
static int
VITA_GXM_UpdateTextureNV(SDL_Renderer * renderer, SDL_Texture * texture,
const SDL_Rect * rect,
const Uint8 *Yplane, int Ypitch,
const Uint8 *UVplane, int UVpitch)
{
Uint8 *dst;
int row, length, dpitch;
SDL_Rect UVrect = {rect->x / 2, rect->y / 2, (rect->w + 1) / 2, (rect->h + 1) / 2};
VITA_GXM_SetYUVProfile(renderer, texture);
// copy Y plane
VITA_GXM_LockTexture(renderer, texture, rect, (void **)&dst, &dpitch);
length = rect->w * SDL_BYTESPERPIXEL(texture->format);
if (length == Ypitch && length == dpitch) {
SDL_memcpy(dst, Yplane, length*rect->h);
} else {
for (row = 0; row < rect->h; ++row) {
SDL_memcpy(dst, Yplane, length);
Yplane += Ypitch;
dst += dpitch;
}
}
// UV plane
{
void *UVdst;
VITA_GXM_TextureData *vita_texture = (VITA_GXM_TextureData *) texture->driverdata;
int uv_pitch = 2 * ((dpitch+1) / 2);
// skip Y plane
void *pixels = (void *) ((Uint8 *) gxm_texture_get_datap(vita_texture->tex) + (vita_texture->pitch * vita_texture->h));
UVdst = pixels + (UVrect.y * uv_pitch) + UVrect.x;
length = UVrect.w * 2;
// UV plane
if (length == UVpitch && length == uv_pitch) {
SDL_memcpy(UVdst, UVplane, length*UVrect.h);
} else {
for (row = 0; row < UVrect.h; ++row) {
SDL_memcpy(UVdst, UVplane, length);
UVplane += UVpitch;
UVdst += uv_pitch;
}
}
}
return 0;
}
#endif
static int
VITA_GXM_LockTexture(SDL_Renderer *renderer, SDL_Texture *texture,
const SDL_Rect *rect, void **pixels, int *pitch)
@@ -763,7 +517,6 @@ VITA_GXM_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Textu
size_indices = indices ? size_indices : 0;
if (texture) {
VITA_GXM_TextureData* vita_texture = (VITA_GXM_TextureData*) texture->driverdata;
texture_vertex *vertices;
vertices = (texture_vertex *)pool_malloc(
@@ -796,7 +549,7 @@ VITA_GXM_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Textu
vertices[i].x = xy_[0] * scale_x;
vertices[i].y = xy_[1] * scale_y;
vertices[i].u = uv_[0] * vita_texture->wscale;
vertices[i].u = uv_[0];
vertices[i].v = uv_[1];
vertices[i].color = col_;
}
@@ -975,6 +728,14 @@ SetDrawState(VITA_GXM_RenderData *data, const SDL_RenderCommand *cmd)
return 0;
}
static int
SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd)
{
VITA_GXM_RenderData *data = (VITA_GXM_RenderData *) renderer->driverdata;
return SetDrawState(data, cmd);
}
static int
VITA_GXM_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize)
{
@@ -1061,7 +822,11 @@ VITA_GXM_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *
nextcmd = nextcmd->next;
}
ret = SetDrawState(data, cmd);
if (thistexture) {
ret = SetCopyState(renderer, cmd);
} else {
ret = SetDrawState(data, cmd);
}
if (ret == 0) {
int op = SCE_GXM_PRIMITIVE_TRIANGLES;
@@ -1246,7 +1011,7 @@ VITA_GXM_DestroyTexture(SDL_Renderer *renderer, SDL_Texture *texture)
sceGxmFinish(data->gxm_context);
free_gxm_texture(data, vita_texture->tex);
free_gxm_texture(vita_texture->tex);
SDL_free(vita_texture);

View File

@@ -26,7 +26,7 @@
#include "SDL_render_vita_gxm_memory.h"
void *
vita_mem_alloc(unsigned int type, unsigned int size, unsigned int alignment, unsigned int attribs, SceUID *uid)
mem_gpu_alloc(SceKernelMemBlockType type, unsigned int size, unsigned int alignment, unsigned int attribs, SceUID *uid)
{
void *mem;
@@ -51,7 +51,7 @@ vita_mem_alloc(unsigned int type, unsigned int size, unsigned int alignment, uns
}
void
vita_mem_free(SceUID uid)
mem_gpu_free(SceUID uid)
{
void *mem = NULL;
if (sceKernelGetMemBlockBase(uid, &mem) < 0)
@@ -61,71 +61,7 @@ vita_mem_free(SceUID uid)
}
void *
vita_gpu_mem_alloc(VITA_GXM_RenderData *data, unsigned int size)
{
void *mem;
if (data->texturePool == NULL) {
int poolsize;
int ret;
SceKernelFreeMemorySizeInfo info;
info.size = sizeof(SceKernelFreeMemorySizeInfo);
sceKernelGetFreeMemorySize(&info);
poolsize = ALIGN(info.size_cdram, 256*1024);
if (poolsize > info.size_cdram) {
poolsize = ALIGN(info.size_cdram - 256*1024, 256*1024);
}
data->texturePoolUID = sceKernelAllocMemBlock("gpu_texture_pool", SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW, poolsize, NULL);
if (data->texturePoolUID < 0) {
return NULL;
}
ret = sceKernelGetMemBlockBase(data->texturePoolUID, &mem);
if ( ret < 0)
{
return NULL;
}
data->texturePool = sceClibMspaceCreate(mem, poolsize);
if (data->texturePool == NULL) {
return NULL;
}
ret = sceGxmMapMemory(mem, poolsize, SCE_GXM_MEMORY_ATTRIB_READ | SCE_GXM_MEMORY_ATTRIB_WRITE);
if (ret < 0)
{
return NULL;
}
}
return sceClibMspaceMemalign(data->texturePool, SCE_GXM_TEXTURE_ALIGNMENT, size);
}
void
vita_gpu_mem_free(VITA_GXM_RenderData *data, void* ptr)
{
if (data->texturePool != NULL)
{
sceClibMspaceFree(data->texturePool, ptr);
}
}
void
vita_gpu_mem_destroy(VITA_GXM_RenderData *data)
{
void *mem = NULL;
if (data->texturePool != NULL)
{
sceClibMspaceDestroy(data->texturePool);
data->texturePool = NULL;
if (sceKernelGetMemBlockBase(data->texturePoolUID, &mem) < 0)
return;
sceGxmUnmapMemory(mem);
sceKernelFreeMemBlock(data->texturePoolUID);
}
}
void *
vita_mem_vertex_usse_alloc(unsigned int size, SceUID *uid, unsigned int *usse_offset)
mem_vertex_usse_alloc(unsigned int size, SceUID *uid, unsigned int *usse_offset)
{
void *mem = NULL;
@@ -141,7 +77,7 @@ vita_mem_vertex_usse_alloc(unsigned int size, SceUID *uid, unsigned int *usse_of
}
void
vita_mem_vertex_usse_free(SceUID uid)
mem_vertex_usse_free(SceUID uid)
{
void *mem = NULL;
if (sceKernelGetMemBlockBase(uid, &mem) < 0)
@@ -151,7 +87,7 @@ vita_mem_vertex_usse_free(SceUID uid)
}
void *
vita_mem_fragment_usse_alloc(unsigned int size, SceUID *uid, unsigned int *usse_offset)
mem_fragment_usse_alloc(unsigned int size, SceUID *uid, unsigned int *usse_offset)
{
void *mem = NULL;
@@ -167,7 +103,7 @@ vita_mem_fragment_usse_alloc(unsigned int size, SceUID *uid, unsigned int *usse_
}
void
vita_mem_fragment_usse_free(SceUID uid)
mem_fragment_usse_free(SceUID uid)
{
void *mem = NULL;
if (sceKernelGetMemBlockBase(uid, &mem) < 0)

View File

@@ -25,19 +25,15 @@
#include <psp2/gxm.h>
#include <psp2/types.h>
#include <psp2/kernel/sysmem.h>
#include "SDL_render_vita_gxm_types.h"
#define ALIGN(x, a) (((x) + ((a) - 1)) & ~((a) - 1))
void *vita_mem_alloc(unsigned int type, unsigned int size, unsigned int alignment, unsigned int attribs, SceUID *uid);
void vita_mem_free(SceUID uid);
void *vita_gpu_mem_alloc(VITA_GXM_RenderData *data, unsigned int size);
void vita_gpu_mem_free(VITA_GXM_RenderData *data, void* ptr);
void vita_gpu_mem_destroy(VITA_GXM_RenderData *data);
void *vita_mem_vertex_usse_alloc(unsigned int size, SceUID *uid, unsigned int *usse_offset);
void vita_mem_vertex_usse_free(SceUID uid);
void *vita_mem_fragment_usse_alloc(unsigned int size, SceUID *uid, unsigned int *usse_offset);
void vita_mem_fragment_usse_free(SceUID uid);
void *mem_gpu_alloc(SceKernelMemBlockType type, unsigned int size, unsigned int alignment, unsigned int attribs, SceUID *uid);
void mem_gpu_free(SceUID uid);
void *mem_vertex_usse_alloc(unsigned int size, SceUID *uid, unsigned int *usse_offset);
void mem_vertex_usse_free(SceUID uid);
void *mem_fragment_usse_alloc(unsigned int size, SceUID *uid, unsigned int *usse_offset);
void mem_fragment_usse_free(SceUID uid);
#endif /* SDL_RENDER_VITA_GXM_MEMORY_H */

View File

@@ -117,8 +117,6 @@ tex_format_to_bytespp(SceGxmTextureFormat format)
case SCE_GXM_TEXTURE_BASE_FORMAT_U8:
case SCE_GXM_TEXTURE_BASE_FORMAT_S8:
case SCE_GXM_TEXTURE_BASE_FORMAT_P8:
case SCE_GXM_TEXTURE_BASE_FORMAT_YUV420P2: // YUV actually uses 12 bits per pixel. UV planes bits/mem are handled elsewhere
case SCE_GXM_TEXTURE_BASE_FORMAT_YUV420P3:
return 1;
case SCE_GXM_TEXTURE_BASE_FORMAT_U4U4U4U4:
case SCE_GXM_TEXTURE_BASE_FORMAT_U8U3U3U2:
@@ -416,28 +414,28 @@ gxm_init(SDL_Renderer *renderer)
}
// allocate ring buffer memory using default sizes
vdmRingBuffer = vita_mem_alloc(
vdmRingBuffer = mem_gpu_alloc(
SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE,
SCE_GXM_DEFAULT_VDM_RING_BUFFER_SIZE,
4,
SCE_GXM_MEMORY_ATTRIB_READ,
&data->vdmRingBufferUid);
vertexRingBuffer = vita_mem_alloc(
vertexRingBuffer = mem_gpu_alloc(
SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE,
SCE_GXM_DEFAULT_VERTEX_RING_BUFFER_SIZE,
4,
SCE_GXM_MEMORY_ATTRIB_READ,
&data->vertexRingBufferUid);
fragmentRingBuffer = vita_mem_alloc(
fragmentRingBuffer = mem_gpu_alloc(
SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE,
SCE_GXM_DEFAULT_FRAGMENT_RING_BUFFER_SIZE,
4,
SCE_GXM_MEMORY_ATTRIB_READ,
&data->fragmentRingBufferUid);
fragmentUsseRingBuffer = vita_mem_fragment_usse_alloc(
fragmentUsseRingBuffer = mem_fragment_usse_alloc(
SCE_GXM_DEFAULT_FRAGMENT_USSE_RING_BUFFER_SIZE,
&data->fragmentUsseRingBufferUid,
&fragmentUsseRingBufferOffset);
@@ -482,7 +480,7 @@ gxm_init(SDL_Renderer *renderer)
for (i = 0; i < VITA_GXM_BUFFERS; i++) {
// allocate memory for display
data->displayBufferData[i] = vita_mem_alloc(
data->displayBufferData[i] = mem_gpu_alloc(
SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW,
4 * VITA_GXM_SCREEN_STRIDE * VITA_GXM_SCREEN_HEIGHT,
SCE_GXM_COLOR_SURFACE_ALIGNMENT,
@@ -527,7 +525,7 @@ gxm_init(SDL_Renderer *renderer)
// allocate the depth buffer
data->depthBufferData = vita_mem_alloc(
data->depthBufferData = mem_gpu_alloc(
SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE,
4 * sampleCount,
SCE_GXM_DEPTHSTENCIL_SURFACE_ALIGNMENT,
@@ -535,7 +533,7 @@ gxm_init(SDL_Renderer *renderer)
&data->depthBufferUid);
// allocate the stencil buffer
data->stencilBufferData = vita_mem_alloc(
data->stencilBufferData = mem_gpu_alloc(
SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE,
4 * sampleCount,
SCE_GXM_DEPTHSTENCIL_SURFACE_ALIGNMENT,
@@ -567,19 +565,19 @@ gxm_init(SDL_Renderer *renderer)
// allocate memory for buffers and USSE code
patcherBuffer = vita_mem_alloc(
patcherBuffer = mem_gpu_alloc(
SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE,
patcherBufferSize,
4,
SCE_GXM_MEMORY_ATTRIB_READ | SCE_GXM_MEMORY_ATTRIB_WRITE,
&data->patcherBufferUid);
patcherVertexUsse = vita_mem_vertex_usse_alloc(
patcherVertexUsse = mem_vertex_usse_alloc(
patcherVertexUsseSize,
&data->patcherVertexUsseUid,
&patcherVertexUsseOffset);
patcherFragmentUsse = vita_mem_fragment_usse_alloc(
patcherFragmentUsse = mem_fragment_usse_alloc(
patcherFragmentUsseSize,
&data->patcherFragmentUsseUid,
&patcherFragmentUsseOffset);
@@ -730,7 +728,7 @@ gxm_init(SDL_Renderer *renderer)
}
// create the clear triangle vertex/index data
data->clearVertices = (clear_vertex *)vita_mem_alloc(
data->clearVertices = (clear_vertex *)mem_gpu_alloc(
SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE,
3*sizeof(clear_vertex),
4,
@@ -742,7 +740,7 @@ gxm_init(SDL_Renderer *renderer)
// Allocate a 64k * 2 bytes = 128 KiB buffer and store all possible
// 16-bit indices in linear ascending order, so we can use this for
// all drawing operations where we don't want to use indexing.
data->linearIndices = (uint16_t *)vita_mem_alloc(
data->linearIndices = (uint16_t *)mem_gpu_alloc(
SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE,
UINT16_MAX*sizeof(uint16_t),
sizeof(uint16_t),
@@ -873,7 +871,7 @@ gxm_init(SDL_Renderer *renderer)
data->textureWvpParam = (SceGxmProgramParameter *)sceGxmProgramFindParameterByName(textureVertexProgramGxp, "wvp");
// Allocate memory for the memory pool
data->pool_addr[0] = vita_mem_alloc(
data->pool_addr[0] = mem_gpu_alloc(
SCE_KERNEL_MEMBLOCK_TYPE_USER_RW,
VITA_GXM_POOL_SIZE,
sizeof(void *),
@@ -881,7 +879,7 @@ gxm_init(SDL_Renderer *renderer)
&data->poolUid[0]
);
data->pool_addr[1] = vita_mem_alloc(
data->pool_addr[1] = mem_gpu_alloc(
SCE_KERNEL_MEMBLOCK_TYPE_USER_RW,
VITA_GXM_POOL_SIZE,
sizeof(void *),
@@ -920,28 +918,28 @@ void gxm_finish(SDL_Renderer *renderer)
free_fragment_programs(data, &data->blendFragmentPrograms.blend_mode_mod);
free_fragment_programs(data, &data->blendFragmentPrograms.blend_mode_mul);
vita_mem_free(data->linearIndicesUid);
vita_mem_free(data->clearVerticesUid);
mem_gpu_free(data->linearIndicesUid);
mem_gpu_free(data->clearVerticesUid);
// wait until display queue is finished before deallocating display buffers
sceGxmDisplayQueueFinish();
// clean up display queue
vita_mem_free(data->depthBufferUid);
mem_gpu_free(data->depthBufferUid);
for (size_t i = 0; i < VITA_GXM_BUFFERS; i++)
{
// clear the buffer then deallocate
SDL_memset(data->displayBufferData[i], 0, VITA_GXM_SCREEN_HEIGHT * VITA_GXM_SCREEN_STRIDE * 4);
vita_mem_free(data->displayBufferUid[i]);
mem_gpu_free(data->displayBufferUid[i]);
// destroy the sync object
sceGxmSyncObjectDestroy(data->displayBufferSync[i]);
}
// Free the depth and stencil buffer
vita_mem_free(data->depthBufferUid);
vita_mem_free(data->stencilBufferUid);
mem_gpu_free(data->depthBufferUid);
mem_gpu_free(data->stencilBufferUid);
// unregister programs and destroy shader patcher
sceGxmShaderPatcherUnregisterProgram(data->shaderPatcher, data->clearFragmentProgramId);
@@ -952,24 +950,23 @@ void gxm_finish(SDL_Renderer *renderer)
sceGxmShaderPatcherUnregisterProgram(data->shaderPatcher, data->textureVertexProgramId);
sceGxmShaderPatcherDestroy(data->shaderPatcher);
vita_mem_fragment_usse_free(data->patcherFragmentUsseUid);
vita_mem_vertex_usse_free(data->patcherVertexUsseUid);
vita_mem_free(data->patcherBufferUid);
mem_fragment_usse_free(data->patcherFragmentUsseUid);
mem_vertex_usse_free(data->patcherVertexUsseUid);
mem_gpu_free(data->patcherBufferUid);
// destroy the render target
sceGxmDestroyRenderTarget(data->renderTarget);
// destroy the gxm context
sceGxmDestroyContext(data->gxm_context);
vita_mem_fragment_usse_free(data->fragmentUsseRingBufferUid);
vita_mem_free(data->fragmentRingBufferUid);
vita_mem_free(data->vertexRingBufferUid);
vita_mem_free(data->vdmRingBufferUid);
mem_fragment_usse_free(data->fragmentUsseRingBufferUid);
mem_gpu_free(data->fragmentRingBufferUid);
mem_gpu_free(data->vertexRingBufferUid);
mem_gpu_free(data->vdmRingBufferUid);
SDL_free(data->contextParams.hostMem);
vita_mem_free(data->poolUid[0]);
vita_mem_free(data->poolUid[1]);
vita_gpu_mem_destroy(data);
mem_gpu_free(data->poolUid[0]);
mem_gpu_free(data->poolUid[1]);
// terminate libgxm
sceGxmTerminate();
@@ -978,20 +975,16 @@ void gxm_finish(SDL_Renderer *renderer)
// textures
void
free_gxm_texture(VITA_GXM_RenderData *data, gxm_texture *texture)
free_gxm_texture(gxm_texture *texture)
{
if (texture) {
if (texture->gxm_rendertarget) {
sceGxmDestroyRenderTarget(texture->gxm_rendertarget);
}
if (texture->depth_UID) {
vita_mem_free(texture->depth_UID);
}
if (texture->cdram) {
vita_gpu_mem_free(data, sceGxmTextureGetData(&texture->gxm_tex));
} else {
vita_mem_free(texture->data_UID);
mem_gpu_free(texture->depth_UID);
}
mem_gpu_free(texture->data_UID);
SDL_free(texture);
}
}
@@ -1002,6 +995,25 @@ gxm_texture_get_format(const gxm_texture *texture)
return sceGxmTextureGetFormat(&texture->gxm_tex);
}
unsigned int
gxm_texture_get_width(const gxm_texture *texture)
{
return sceGxmTextureGetWidth(&texture->gxm_tex);
}
unsigned int
gxm_texture_get_height(const gxm_texture *texture)
{
return sceGxmTextureGetHeight(&texture->gxm_tex);
}
unsigned int
gxm_texture_get_stride(const gxm_texture *texture)
{
return ((gxm_texture_get_width(texture) + 7) & ~7)
* tex_format_to_bytespp(gxm_texture_get_format(texture));
}
void *
gxm_texture_get_datap(const gxm_texture *texture)
{
@@ -1009,53 +1021,34 @@ gxm_texture_get_datap(const gxm_texture *texture)
}
gxm_texture *
create_gxm_texture(VITA_GXM_RenderData *data, unsigned int w, unsigned int h, SceGxmTextureFormat format, unsigned int isRenderTarget, unsigned int *return_w, unsigned int *return_h, unsigned int *return_pitch, float *return_wscale)
create_gxm_texture(VITA_GXM_RenderData *data, unsigned int w, unsigned int h, SceGxmTextureFormat format, unsigned int isRenderTarget)
{
gxm_texture *texture = SDL_calloc(1, sizeof(gxm_texture));
int aligned_w = ALIGN(w, 8);
int texture_w = w;
int tex_size = aligned_w * h * tex_format_to_bytespp(format);
const int tex_size = ((w + 7) & ~ 7) * h * tex_format_to_bytespp(format);
void *texture_data;
int ret;
*return_wscale = 1.0f;
// SCE_GXM_TEXTURE_BASE_FORMAT_YUV420P3/P2 based formats require width aligned to 16
if ( (format & 0x9f000000U) == SCE_GXM_TEXTURE_BASE_FORMAT_YUV420P3 || (format & 0x9f000000U) == SCE_GXM_TEXTURE_BASE_FORMAT_YUV420P2) {
aligned_w = ALIGN(w, 16);
texture_w = aligned_w;
tex_size = aligned_w * h * tex_format_to_bytespp(format);
*return_wscale = (float) (w) / texture_w;
// add storage for UV planes
tex_size += (((aligned_w + 1) / 2) * ((h + 1) / 2)) * 2;
}
if (!texture)
return NULL;
*return_w = w;
*return_h = h;
*return_pitch = aligned_w * tex_format_to_bytespp(format);
/* Allocate a GPU buffer for the texture */
texture_data = vita_gpu_mem_alloc(
data,
tex_size
texture_data = mem_gpu_alloc(
SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW,
tex_size,
SCE_GXM_TEXTURE_ALIGNMENT,
SCE_GXM_MEMORY_ATTRIB_READ | SCE_GXM_MEMORY_ATTRIB_WRITE,
&texture->data_UID
);
/* Try SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE in case we're out of VRAM */
if (!texture_data) {
SDL_LogWarn(SDL_LOG_CATEGORY_RENDER, "CDRAM texture allocation failed\n");
texture_data = vita_mem_alloc(
texture_data = mem_gpu_alloc(
SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE,
tex_size,
SCE_GXM_TEXTURE_ALIGNMENT,
SCE_GXM_MEMORY_ATTRIB_READ | SCE_GXM_MEMORY_ATTRIB_WRITE,
&texture->data_UID
);
texture->cdram = 0;
} else {
texture->cdram = 1;
}
if (!texture_data) {
@@ -1067,12 +1060,7 @@ create_gxm_texture(VITA_GXM_RenderData *data, unsigned int w, unsigned int h, Sc
SDL_memset(texture_data, 0, tex_size);
/* Create the gxm texture */
ret = sceGxmTextureInitLinear( &texture->gxm_tex, texture_data, format, texture_w, h, 0);
if (ret < 0) {
free_gxm_texture(data, texture);
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "texture init failed: %x\n", ret);
return NULL;
}
sceGxmTextureInitLinear( &texture->gxm_tex, texture_data, format, w, h, 0);
if (isRenderTarget) {
void *depthBufferData;
@@ -1095,13 +1083,13 @@ create_gxm_texture(VITA_GXM_RenderData *data, unsigned int w, unsigned int h, Sc
);
if (err < 0) {
free_gxm_texture(data, texture);
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "color surface init failed: %x\n", err);
free_gxm_texture(texture);
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "color surface init failed: %d\n", err);
return NULL;
}
// allocate it
depthBufferData = vita_mem_alloc(
depthBufferData = mem_gpu_alloc(
SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE,
4*sampleCount,
SCE_GXM_DEPTHSTENCIL_SURFACE_ALIGNMENT,
@@ -1118,8 +1106,8 @@ create_gxm_texture(VITA_GXM_RenderData *data, unsigned int w, unsigned int h, Sc
NULL);
if (err < 0) {
free_gxm_texture(data, texture);
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "depth stencil init failed: %x\n", err);
free_gxm_texture(texture);
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "depth stencil init failed: %d\n", err);
return NULL;
}
@@ -1143,8 +1131,8 @@ create_gxm_texture(VITA_GXM_RenderData *data, unsigned int w, unsigned int h, Sc
texture->gxm_rendertarget = tgt;
if (err < 0) {
free_gxm_texture(data, texture);
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "create render target failed: %x\n", err);
free_gxm_texture(texture);
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "create render target failed: %d\n", err);
return NULL;
}
}
@@ -1193,7 +1181,7 @@ void gxm_init_for_common_dialog(void)
for (int i = 0; i < VITA_GXM_BUFFERS; i += 1)
{
buffer_for_common_dialog[i].displayData.wait_vblank = SDL_TRUE;
buffer_for_common_dialog[i].displayData.address = vita_mem_alloc(
buffer_for_common_dialog[i].displayData.address = mem_gpu_alloc(
SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW,
4 * VITA_GXM_SCREEN_STRIDE * VITA_GXM_SCREEN_HEIGHT,
SCE_GXM_COLOR_SURFACE_ALIGNMENT,
@@ -1241,7 +1229,7 @@ void gxm_term_for_common_dialog(void)
sceGxmDisplayQueueFinish();
for (int i = 0; i < VITA_GXM_BUFFERS; i += 1)
{
vita_mem_free(buffer_for_common_dialog[i].uid);
mem_gpu_free(buffer_for_common_dialog[i].uid);
sceGxmSyncObjectDestroy(buffer_for_common_dialog[i].sync);
}
}

View File

@@ -48,12 +48,15 @@ void unset_clip_rectangle(VITA_GXM_RenderData *data);
int gxm_init(SDL_Renderer *renderer);
void gxm_finish(SDL_Renderer *renderer);
gxm_texture *create_gxm_texture(VITA_GXM_RenderData *data, unsigned int w, unsigned int h, SceGxmTextureFormat format, unsigned int isRenderTarget, unsigned int *return_w, unsigned int *return_h, unsigned int *return_pitch, float *return_wscale);
void free_gxm_texture(VITA_GXM_RenderData *data, gxm_texture *texture);
gxm_texture *create_gxm_texture(VITA_GXM_RenderData *data, unsigned int w, unsigned int h, SceGxmTextureFormat format, unsigned int isRenderTarget);
void free_gxm_texture(gxm_texture *texture);
void gxm_texture_set_filters(gxm_texture *texture, SceGxmTextureFilter min_filter, SceGxmTextureFilter mag_filter);
SceGxmTextureFormat gxm_texture_get_format(const gxm_texture *texture);
unsigned int gxm_texture_get_width(const gxm_texture *texture);
unsigned int gxm_texture_get_height(const gxm_texture *texture);
unsigned int gxm_texture_get_stride(const gxm_texture *texture);
void *gxm_texture_get_datap(const gxm_texture *texture);
void gxm_minimal_init_for_common_dialog(void);

View File

@@ -33,7 +33,6 @@
#include <psp2/gxm.h>
#include <psp2/types.h>
#include <psp2/kernel/sysmem.h>
#include <psp2/kernel/clib.h>
#include <string.h>
@@ -80,7 +79,6 @@ typedef struct gxm_texture {
SceGxmColorSurface gxm_colorsurface;
SceGxmDepthStencilSurface gxm_depthstencil;
SceUID depth_UID;
SDL_bool cdram;
} gxm_texture;
typedef struct fragment_programs {
@@ -188,19 +186,14 @@ typedef struct
blend_fragment_programs blendFragmentPrograms;
gxm_drawstate_cache drawstate;
SceClibMspace texturePool;
SceUID texturePoolUID;
} VITA_GXM_RenderData;
typedef struct
{
gxm_texture *tex;
unsigned int pitch;
unsigned int w;
unsigned int h;
float wscale;
SDL_bool yuv;
SDL_bool nv12;
unsigned int pitch;
unsigned int w;
unsigned int h;
} VITA_GXM_TextureData;
#endif /* SDL_RENDER_VITA_GXM_TYPES_H */