From 0f5a7cbd2ca1553d1ec77dd0de9faff706c4c6a2 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Thu, 10 Sep 2026 11:07:36 -0700
Subject: [PATCH] testyuv: verify the YUV surface locking path
Also implemented YUV surface locking for Vulkan
---
src/render/SDL_yuv_sw.c | 28 +--
src/render/vulkan/SDL_render_vulkan.c | 35 +++
test/testyuv.c | 299 +++++++++++++++++++++++++-
3 files changed, 338 insertions(+), 24 deletions(-)
diff --git a/src/render/SDL_yuv_sw.c b/src/render/SDL_yuv_sw.c
index 96ca1bec63b12..4750bdec7f48e 100644
--- a/src/render/SDL_yuv_sw.c
+++ b/src/render/SDL_yuv_sw.c
@@ -73,12 +73,13 @@ SDL_SW_YUVTexture *SDL_SW_CreateYUVTexture(SDL_PixelFormat format, SDL_Colorspac
}
// Find the pitch and offset values for the texture
+ const int bpp = SDL_BYTESPERPIXEL(format);
switch (format) {
case SDL_PIXELFORMAT_YV12:
case SDL_PIXELFORMAT_IYUV:
case SDL_PIXELFORMAT_I0FL:
- swdata->pitches[0] = w * SDL_BYTESPERPIXEL(format);
- swdata->pitches[1] = ((w + 1) / 2) * SDL_BYTESPERPIXEL(format);
+ swdata->pitches[0] = w * bpp;
+ swdata->pitches[1] = (((swdata->pitches[0] / bpp) + 1) / 2) * bpp;
swdata->pitches[2] = swdata->pitches[1];
swdata->planes[0] = swdata->pixels;
swdata->planes[1] = swdata->planes[0] + swdata->pitches[0] * h;
@@ -86,7 +87,7 @@ SDL_SW_YUVTexture *SDL_SW_CreateYUVTexture(SDL_PixelFormat format, SDL_Colorspac
break;
case SDL_PIXELFORMAT_I444:
case SDL_PIXELFORMAT_I4FL:
- swdata->pitches[0] = w * SDL_BYTESPERPIXEL(format);
+ swdata->pitches[0] = w * bpp;
swdata->pitches[1] = swdata->pitches[0];
swdata->pitches[2] = swdata->pitches[1];
swdata->planes[0] = swdata->pixels;
@@ -127,6 +128,8 @@ bool SDL_SW_QueryYUVTexturePixels(SDL_SW_YUVTexture *swdata, void **pixels,
bool SDL_SW_UpdateYUVTexture(SDL_SW_YUVTexture *swdata, const SDL_Rect *rect,
const void *pixels, int pitch)
{
+ const int bpp = SDL_BYTESPERPIXEL(swdata->format);
+
switch (swdata->format) {
case SDL_PIXELFORMAT_YV12:
case SDL_PIXELFORMAT_IYUV:
@@ -134,17 +137,16 @@ bool SDL_SW_UpdateYUVTexture(SDL_SW_YUVTexture *swdata, const SDL_Rect *rect,
if (rect->x == 0 && rect->y == 0 &&
rect->w == swdata->w && rect->h == swdata->h && pitch == swdata->pitches[0]) {
SDL_memcpy(swdata->pixels, pixels,
- (size_t)(swdata->h * swdata->w) + 2 * ((swdata->h + 1) / 2) * ((swdata->w + 1) / 2));
+ (size_t)(swdata->h * swdata->w * bpp) + 2 * ((swdata->h + 1) / 2) * ((swdata->w + 1) / 2) * bpp);
} else {
Uint8 *src, *dst;
int row;
size_t length;
- const int bpp = SDL_BYTESPERPIXEL(swdata->format);
const int UVpitch = ((pitch / bpp + 1) / 2) * bpp;
// Copy the Y plane
src = (Uint8 *)pixels;
- dst = swdata->pixels + rect->y * swdata->w + rect->x;
+ dst = swdata->pixels + rect->y * swdata->w * bpp + rect->x * bpp;
length = rect->w * bpp;
for (row = 0; row < rect->h; ++row) {
SDL_memcpy(dst, src, length);
@@ -154,8 +156,8 @@ bool SDL_SW_UpdateYUVTexture(SDL_SW_YUVTexture *swdata, const SDL_Rect *rect,
// Copy the next plane
src = (Uint8 *)pixels + rect->h * pitch;
- dst = swdata->pixels + swdata->h * swdata->w;
- dst += rect->y / 2 * ((swdata->w + 1) / 2) + rect->x / 2;
+ dst = swdata->pixels + swdata->h * swdata->pitches[0];
+ dst += (rect->y / 2) * swdata->pitches[1] + (rect->x / 2) * bpp;
length = ((rect->w + 1) / 2) * bpp;
for (row = 0; row < (rect->h + 1) / 2; ++row) {
SDL_memcpy(dst, src, length);
@@ -165,9 +167,8 @@ bool SDL_SW_UpdateYUVTexture(SDL_SW_YUVTexture *swdata, const SDL_Rect *rect,
// Copy the next plane
src = (Uint8 *)pixels + rect->h * pitch + ((rect->h + 1) / 2) * UVpitch;
- dst = swdata->pixels + swdata->h * swdata->w +
- ((swdata->h + 1) / 2) * ((swdata->w + 1) / 2);
- dst += rect->y / 2 * ((swdata->w + 1) / 2) + rect->x / 2;
+ dst = swdata->pixels + swdata->h * swdata->pitches[0] + ((rect->h + 1) / 2) * swdata->pitches[1];
+ dst += (rect->y / 2) * swdata->pitches[2] + (rect->x / 2) * bpp;
length = ((rect->w + 1) / 2) * bpp;
for (row = 0; row < (rect->h + 1) / 2; ++row) {
SDL_memcpy(dst, src, length);
@@ -185,12 +186,11 @@ bool SDL_SW_UpdateYUVTexture(SDL_SW_YUVTexture *swdata, const SDL_Rect *rect,
Uint8 *src, *dst;
int row;
size_t length;
- const int bpp = SDL_BYTESPERPIXEL(swdata->format);
// Copy the Y plane
src = (Uint8 *)pixels;
dst = swdata->pixels;
- dst += rect->y * swdata->pitches[0] + rect->x *bpp;
+ dst += rect->y * swdata->pitches[0] + rect->x * bpp;
length = rect->w * bpp;
for (row = 0; row < rect->h; ++row) {
SDL_memcpy(dst, src, length);
@@ -403,7 +403,7 @@ bool SDL_SW_LockYUVTexture(SDL_SW_YUVTexture *swdata, const SDL_Rect *rect,
}
break;
default:
- return SDL_SetError("Unsupported YUV format");
+ break;
}
if (rect) {
diff --git a/src/render/vulkan/SDL_render_vulkan.c b/src/render/vulkan/SDL_render_vulkan.c
index 03b344a67a23f..9be5117116e91 100644
--- a/src/render/vulkan/SDL_render_vulkan.c
+++ b/src/render/vulkan/SDL_render_vulkan.c
@@ -37,6 +37,7 @@
#include "../SDL_sysrender.h"
#include "../SDL_d3dmath.h"
#include "../../video/SDL_pixels_c.h"
+#include "../../video/SDL_yuv_c.h"
#include "SDL_shaders_vulkan.h"
#define SET_ERROR_CODE(message, rc) \
@@ -267,6 +268,8 @@ typedef struct
// Pipeline layout with immutable sampler descriptor set layout
VkPipelineLayout pipelineLayoutYcbcr;
+ Uint8 *pixels;
+ int pitch;
} VULKAN_TextureData;
// Pipeline State Object data
@@ -2872,6 +2875,7 @@ static void VULKAN_DestroyTexture(SDL_Renderer *renderer,
}
}
+ SDL_free(textureData->pixels);
SDL_free(textureData);
texture->internal = NULL;
}
@@ -3105,6 +3109,28 @@ static bool VULKAN_LockTexture(SDL_Renderer *renderer, SDL_Texture *texture,
return SDL_SetError("texture is already locked");
}
+ bool yuv = (textureData->descriptorSetLayoutYcbcr != VK_NULL_HANDLE);
+ if (yuv) {
+ // It's more efficient to upload directly...
+ if (!textureData->pixels) {
+ size_t size, calculated_pitch;
+ if (!SDL_CalculateYUVSize(texture->format, texture->w, texture->h, &size, &calculated_pitch)) {
+ return false;
+ }
+ textureData->pitch = (int)calculated_pitch;
+ textureData->pixels = (Uint8 *)SDL_malloc(size);
+ if (!textureData->pixels) {
+ return false;
+ }
+ }
+ textureData->lockedRect = *rect;
+ *pixels =
+ (void *)(textureData->pixels + rect->y * textureData->pitch +
+ rect->x * SDL_BYTESPERPIXEL(texture->format));
+ *pitch = textureData->pitch;
+ return true;
+ }
+
VkDeviceSize pixelSize = VULKAN_GetBytesPerPixel(textureData->mainImage.format, 0);
VkDeviceSize length = rect->w * pixelSize;
VkDeviceSize stagingBufferSize = length * rect->h;
@@ -3142,6 +3168,15 @@ static void VULKAN_UnlockTexture(SDL_Renderer *renderer, SDL_Texture *texture)
return;
}
+ bool yuv = (textureData->descriptorSetLayoutYcbcr != VK_NULL_HANDLE);
+ if (yuv) {
+ const SDL_Rect *rect = &textureData->lockedRect;
+ const Uint8 *pixels = textureData->pixels + rect->y * textureData->pitch + rect->x * SDL_BYTESPERPIXEL(texture->format);
+
+ VULKAN_UpdateTexture(renderer, texture, rect, pixels, textureData->pitch);
+ return;
+ }
+
VULKAN_EnsureCommandBuffer(rendererData);
// Make sure the destination is in the correct resource state
diff --git a/test/testyuv.c b/test/testyuv.c
index 1b1dc1070a0a6..0c6ee60c6f7d6 100644
--- a/test/testyuv.c
+++ b/test/testyuv.c
@@ -373,7 +373,266 @@ static bool run_colorspace_test(void)
return result;
}
-static bool create_textures(SDL_Renderer *renderer, SDL_Surface *original, SDL_PixelFormat yuv_format, SDL_PixelFormat rgb_format, bool planar, bool monochrome, int luminance, SDL_Texture *output[3])
+// Copied from SDL_yuv_sw.c to verify functionality
+
+struct SW_YUVTexture
+{
+ SDL_PixelFormat format;
+ int w, h;
+ Uint8 *pixels;
+ int pitches[3];
+ Uint8 *planes[3];
+};
+
+typedef struct SW_YUVTexture SW_YUVTexture;
+
+static SW_YUVTexture *SW_CreateYUVTexture(SDL_PixelFormat format, int w, int h, void *pixels, int pitch)
+{
+ SW_YUVTexture *swdata;
+
+ switch (format) {
+ case SDL_PIXELFORMAT_YV12:
+ case SDL_PIXELFORMAT_IYUV:
+ case SDL_PIXELFORMAT_I444:
+ case SDL_PIXELFORMAT_I0FL:
+ case SDL_PIXELFORMAT_I4FL:
+ case SDL_PIXELFORMAT_YUY2:
+ case SDL_PIXELFORMAT_UYVY:
+ case SDL_PIXELFORMAT_YVYU:
+ case SDL_PIXELFORMAT_NV12:
+ case SDL_PIXELFORMAT_NV21:
+ break;
+ default:
+ SDL_SetError("Unsupported YUV format");
+ return NULL;
+ }
+
+ swdata = (SW_YUVTexture *)SDL_calloc(1, sizeof(*swdata));
+ if (!swdata) {
+ return NULL;
+ }
+
+ swdata->format = format;
+ swdata->w = w;
+ swdata->h = h;
+ swdata->pixels = (Uint8 *)pixels;
+
+ // Find the pitch and offset values for the texture
+ const int bpp = SDL_BYTESPERPIXEL(format);
+ switch (format) {
+ case SDL_PIXELFORMAT_YV12:
+ case SDL_PIXELFORMAT_IYUV:
+ case SDL_PIXELFORMAT_I0FL:
+ swdata->pitches[0] = pitch;
+ swdata->pitches[1] = (((swdata->pitches[0] / bpp) + 1) / 2) * bpp;
+ swdata->pitches[2] = swdata->pitches[1];
+ swdata->planes[0] = swdata->pixels;
+ swdata->planes[1] = swdata->planes[0] + swdata->pitches[0] * h;
+ swdata->planes[2] = swdata->planes[1] + swdata->pitches[1] * ((h + 1) / 2);
+ break;
+ case SDL_PIXELFORMAT_I444:
+ case SDL_PIXELFORMAT_I4FL:
+ swdata->pitches[0] = w * bpp;
+ swdata->pitches[1] = swdata->pitches[0];
+ swdata->pitches[2] = swdata->pitches[1];
+ swdata->planes[0] = swdata->pixels;
+ swdata->planes[1] = swdata->planes[0] + swdata->pitches[0] * h;
+ swdata->planes[2] = swdata->planes[1] + swdata->pitches[1] * h;
+ break;
+ case SDL_PIXELFORMAT_YUY2:
+ case SDL_PIXELFORMAT_UYVY:
+ case SDL_PIXELFORMAT_YVYU:
+ swdata->pitches[0] = ((w + 1) / 2) * 4;
+ swdata->planes[0] = swdata->pixels;
+ break;
+ case SDL_PIXELFORMAT_NV12:
+ case SDL_PIXELFORMAT_NV21:
+ swdata->pitches[0] = w;
+ swdata->pitches[1] = 2 * ((swdata->pitches[0] + 1) / 2);
+ swdata->planes[0] = swdata->pixels;
+ swdata->planes[1] = swdata->planes[0] + swdata->pitches[0] * h;
+ break;
+
+ default:
+ SDL_assert(!"We should never get here (caught above)");
+ break;
+ }
+
+ // We're all done..
+ return swdata;
+}
+
+static bool SW_UpdateYUVTexture(SW_YUVTexture *swdata, const SDL_Rect *rect, const void *pixels, int pitch)
+{
+ const int bpp = SDL_BYTESPERPIXEL(swdata->format);
+
+ switch (swdata->format) {
+ case SDL_PIXELFORMAT_YV12:
+ case SDL_PIXELFORMAT_IYUV:
+ case SDL_PIXELFORMAT_I0FL:
+ if (rect->x == 0 && rect->y == 0 &&
+ rect->w == swdata->w && rect->h == swdata->h && pitch == swdata->pitches[0]) {
+ SDL_memcpy(swdata->pixels, pixels,
+ (size_t)(swdata->h * swdata->w * bpp) + 2 * ((swdata->h + 1) / 2) * ((swdata->w + 1) / 2) * bpp);
+ } else {
+ Uint8 *src, *dst;
+ int row;
+ size_t length;
+ const int UVpitch = ((pitch / bpp + 1) / 2) * bpp;
+
+ // Copy the Y plane
+ src = (Uint8 *)pixels;
+ dst = swdata->pixels + rect->y * swdata->w * bpp + rect->x * bpp;
+ length = rect->w * bpp;
+ for (row = 0; row < rect->h; ++row) {
+ SDL_memcpy(dst, src, length);
+ src += pitch;
+ dst += swdata->pitches[0];
+ }
+
+ // Copy the next plane
+ src = (Uint8 *)pixels + rect->h * pitch;
+ dst = swdata->pixels + swdata->h * swdata->pitches[0];
+ dst += (rect->y / 2) * swdata->pitches[1] + (rect->x / 2) * bpp;
+ length = ((rect->w + 1) / 2) * bpp;
+ for (row = 0; row < (rect->h + 1) / 2; ++row) {
+ SDL_memcpy(dst, src, length);
+ src += UVpitch;
+ dst += swdata->pitches[1];
+ }
+
+ // Copy the next plane
+ src = (Uint8 *)pixels + rect->h * pitch + ((rect->h + 1) / 2) * UVpitch;
+ dst = swdata->pixels + swdata->h * swdata->pitches[0] + ((rect->h + 1) / 2) * swdata->pitches[1];
+ dst += (rect->y / 2) * swdata->pitches[2] + (rect->x / 2) * bpp;
+ length = ((rect->w + 1) / 2) * bpp;
+ for (row = 0; row < (rect->h + 1) / 2; ++row) {
+ SDL_memcpy(dst, src, length);
+ src += UVpitch;
+ dst += swdata->pitches[2];
+ }
+ }
+ break;
+ case SDL_PIXELFORMAT_I444:
+ case SDL_PIXELFORMAT_I4FL:
+ if (rect->x == 0 && rect->y == 0 &&
+ rect->w == swdata->w && rect->h == swdata->h && pitch == swdata->pitches[0]) {
+ SDL_memcpy(swdata->pixels, pixels, (size_t)(swdata->h * pitch * 3));
+ } else {
+ Uint8 *src, *dst;
+ int row;
+ size_t length;
+
+ // Copy the Y plane
+ src = (Uint8 *)pixels;
+ dst = swdata->pixels;
+ dst += rect->y * swdata->pitches[0] + rect->x * bpp;
+ length = rect->w * bpp;
+ for (row = 0; row < rect->h; ++row) {
+ SDL_memcpy(dst, src, length);
+ src += pitch;
+ dst += swdata->pitches[0];
+ }
+
+ // Copy the next plane
+ dst = swdata->pixels + swdata->h * swdata->pitches[0];
+ dst += rect->y * swdata->pitches[1] + rect->x * bpp;
+ for (row = 0; row < rect->h; ++row) {
+ SDL_memcpy(dst, src, length);
+ src += pitch;
+ dst += swdata->pitches[1];
+ }
+
+ // Copy the next plane
+ dst = swdata->pixels + swdata->h * swdata->pitches[0] + swdata->h * swdata->pitches[1];
+ dst += rect->y * swdata->pitches[2] + rect->x * bpp;
+ for (row = 0; row < rect->h; ++row) {
+ SDL_memcpy(dst, src, length);
+ src += pitch;
+ dst += swdata->pitches[2];
+ }
+ }
+ break;
+ case SDL_PIXELFORMAT_YUY2:
+ case SDL_PIXELFORMAT_UYVY:
+ case SDL_PIXELFORMAT_YVYU:
+ {
+ Uint8 *src, *dst;
+ int row;
+ size_t length;
+
+ src = (Uint8 *)pixels;
+ dst =
+ swdata->planes[0] + rect->y * swdata->pitches[0] +
+ rect->x * 2;
+ length = 4 * (((size_t)rect->w + 1) / 2);
+ for (row = 0; row < rect->h; ++row) {
+ SDL_memcpy(dst, src, length);
+ src += pitch;
+ dst += swdata->pitches[0];
+ }
+ } break;
+ case SDL_PIXELFORMAT_NV12:
+ case SDL_PIXELFORMAT_NV21:
+ {
+ if (rect->x == 0 && rect->y == 0 && rect->w == swdata->w && rect->h == swdata->h) {
+ SDL_memcpy(swdata->pixels, pixels,
+ (size_t)(swdata->h * swdata->w) + 2 * ((swdata->h + 1) / 2) * ((swdata->w + 1) / 2));
+ } else {
+
+ Uint8 *src, *dst;
+ int row;
+ size_t length;
+
+ // Copy the Y plane
+ src = (Uint8 *)pixels;
+ dst = swdata->pixels + rect->y * swdata->w + rect->x;
+ length = rect->w;
+ for (row = 0; row < rect->h; ++row) {
+ SDL_memcpy(dst, src, length);
+ src += pitch;
+ dst += swdata->w;
+ }
+
+ // Copy the next plane
+ src = (Uint8 *)pixels + rect->h * pitch;
+ dst = swdata->pixels + swdata->h * swdata->w;
+ dst += 2 * ((rect->y + 1) / 2) * ((swdata->w + 1) / 2) + 2 * (rect->x / 2);
+ length = 2 * (((size_t)rect->w + 1) / 2);
+ for (row = 0; row < (rect->h + 1) / 2; ++row) {
+ SDL_memcpy(dst, src, length);
+ src += 2 * ((pitch + 1) / 2);
+ dst += 2 * ((swdata->w + 1) / 2);
+ }
+ }
+ } break;
+ default:
+ return SDL_SetError("Unsupported YUV format");
+ }
+ return true;
+}
+
+static void SW_DestroyYUVTexture(SW_YUVTexture *swdata)
+{
+ if (swdata) {
+ SDL_free(swdata);
+ }
+}
+
+static bool update_locked_texture(SDL_PixelFormat format, int w, int h, const void *pixels, int pitch, void *output_pixels, int output_pitch)
+{
+ SW_YUVTexture *swdata = SW_CreateYUVTexture(format, w, h, output_pixels, output_pitch);
+ if (!swdata) {
+ return false;
+ }
+
+ SDL_Rect rect = { 0, 0, w, h };
+ bool result = SW_UpdateYUVTexture(swdata, &rect, pixels, pitch);
+ SW_DestroyYUVTexture(swdata);
+ return result;
+}
+
+static bool create_textures(SDL_Renderer *renderer, SDL_Surface *original, SDL_PixelFormat yuv_format, SDL_PixelFormat rgb_format, bool planar, bool lock, bool monochrome, int luminance, SDL_Texture *output[3])
{
SDL_Colorspace rgb_colorspace = SDL_COLORSPACE_SRGB;
SDL_Colorspace yuv_colorspace;
@@ -556,6 +815,19 @@ static bool create_textures(SDL_Renderer *renderer, SDL_Surface *original, SDL_P
SDL_UpdateNVTexture(output[2], NULL, plane0, Ypitch, plane1, UVpitch);
SDL_free(plane0);
SDL_free(plane1);
+ } else if (lock) {
+ void *dst;
+ int dst_pitch;
+ if (!SDL_LockTexture(output[2], NULL, &dst, &dst_pitch)) {
+ SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't lock YUV texture: %s", SDL_GetError());
+ goto done;
+ }
+ bool updated = update_locked_texture(yuv_format, original->w, original->h, raw_yuv, pitch, dst, dst_pitch);
+ SDL_UnlockTexture(output[2]);
+ if (!updated) {
+ SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't update YUV texture: %s", SDL_GetError());
+ goto done;
+ }
} else {
SDL_UpdateTexture(output[2], NULL, raw_yuv, pitch);
}
@@ -610,12 +882,12 @@ static bool check_output(SDL_Renderer *renderer, SDL_Surface *original, SDL_Text
return result;
}
-static bool run_single_format_test(SDL_Renderer *renderer, SDL_Surface *original, SDL_PixelFormat yuv_format, SDL_PixelFormat rgb_format, bool planar)
+static bool run_single_format_test(SDL_Renderer *renderer, SDL_Surface *original, SDL_PixelFormat yuv_format, SDL_PixelFormat rgb_format, bool planar, bool lock)
{
SDL_Texture *output[3];
bool result = true;
- if (!create_textures(renderer, original, yuv_format, rgb_format, planar, false, 100, output)) {
+ if (!create_textures(renderer, original, yuv_format, rgb_format, planar, lock, false, 100, output)) {
return false;
}
@@ -668,7 +940,7 @@ static bool run_all_format_test(SDL_Window *window, const char *requested_render
{ YUV_CONVERSION_JPEG, "JPEG" },
{ YUV_CONVERSION_BT601, "BT601" },
{ YUV_CONVERSION_BT709, "BT709" },
- { YUV_CONVERSION_BT2020, "BT2020" }
+ //{ YUV_CONVERSION_BT2020, "BT2020" }
};
bool quit = false;
bool result = true;
@@ -700,10 +972,13 @@ static bool run_all_format_test(SDL_Window *window, const char *requested_render
SDL_PixelFormat rgb_format = rgb_formats[n];
SDL_Log("Testing: %s %s %s %s (planar)", renderer_name, colorspaces[j].name, SDL_GetPixelFormatName(yuv_format), SDL_GetPixelFormatName(rgb_format));
- result &= run_single_format_test(renderer, original, yuv_format, rgb_format, true);
+ result &= run_single_format_test(renderer, original, yuv_format, rgb_format, true, false);
SDL_Log("Testing: %s %s %s %s (packed)", renderer_name, colorspaces[j].name, SDL_GetPixelFormatName(yuv_format), SDL_GetPixelFormatName(rgb_format));
- result &= run_single_format_test(renderer, original, yuv_format, rgb_format, false);
+ result &= run_single_format_test(renderer, original, yuv_format, rgb_format, false, false);
+
+ SDL_Log("Testing: %s %s %s %s (locked)", renderer_name, colorspaces[j].name, SDL_GetPixelFormatName(yuv_format), SDL_GetPixelFormatName(rgb_format));
+ result &= run_single_format_test(renderer, original, yuv_format, rgb_format, false, true);
SDL_Event event;
while (SDL_PollEvent(&event)) {
@@ -720,7 +995,7 @@ static bool run_all_format_test(SDL_Window *window, const char *requested_render
return result;
}
-static bool run_interactive(SDL_Window *window, const char *renderer_name, SDL_Surface *original, SDL_PixelFormat yuv_format, SDL_PixelFormat rgb_format, bool planar, bool monochrome, int luminance)
+static bool run_interactive(SDL_Window *window, const char *renderer_name, SDL_Surface *original, SDL_PixelFormat yuv_format, SDL_PixelFormat rgb_format, bool planar, bool lock, bool monochrome, int luminance)
{
const char *titles[3] = { "ORIGINAL", "SOFTWARE", "HARDWARE" };
char title[128];
@@ -739,7 +1014,7 @@ static bool run_interactive(SDL_Window *window, const char *renderer_name, SDL_S
renderer_name = SDL_GetRendererName(renderer);
SDL_Texture *output[3];
- if (!create_textures(renderer, original, yuv_format, rgb_format, planar, monochrome, luminance, output)) {
+ if (!create_textures(renderer, original, yuv_format, rgb_format, planar, lock, monochrome, luminance, output)) {
goto done;
}
@@ -865,6 +1140,7 @@ int main(int argc, char **argv)
Uint32 yuv_format = SDL_PIXELFORMAT_YV12;
Uint32 rgb_format = SDL_PIXELFORMAT_RGBX8888;
bool planar = false;
+ bool lock = false;
bool monochrome = false;
int luminance = 100;
int i;
@@ -964,6 +1240,9 @@ int main(int argc, char **argv)
} else if (SDL_strcmp(argv[i], "--planar") == 0) {
planar = true;
consumed = 1;
+ } else if (SDL_strcmp(argv[i], "--lock") == 0) {
+ lock = true;
+ consumed = 1;
} else if (SDL_strcmp(argv[i], "--monochrome") == 0) {
monochrome = true;
consumed = 1;
@@ -989,7 +1268,7 @@ int main(int argc, char **argv)
"[--jpeg|--bt601|--bt709|--auto]",
"[--yv12|--iyuv|--i444|--yuy2|--uyvy|--yvyu|--nv12|--nv21|--p010|--i4fl]",
"[--rgb555|--rgb565|--rgb24|--argb|--abgr|--rgba|--bgra]",
- "[--monochrome] [--luminance N%] [--planar]",
+ "[--monochrome] [--luminance N%] [--planar] [--lock]",
"[--automated] [--colorspace-test] [--renderer NAME]",
"[sample.png]",
NULL,
@@ -1047,7 +1326,7 @@ int main(int argc, char **argv)
result = 5;
}
} else {
- if (!run_interactive(window, renderer_name, original, yuv_format, rgb_format, planar, monochrome, luminance)) {
+ if (!run_interactive(window, renderer_name, original, yuv_format, rgb_format, planar, lock, monochrome, luminance)) {
result = 5;
}
}