summaryrefslogtreecommitdiff
path: root/Source/3rdParty/SDL2/src/render/metal/SDL_render_metal.m
diff options
context:
space:
mode:
Diffstat (limited to 'Source/3rdParty/SDL2/src/render/metal/SDL_render_metal.m')
-rw-r--r--Source/3rdParty/SDL2/src/render/metal/SDL_render_metal.m44
1 files changed, 35 insertions, 9 deletions
diff --git a/Source/3rdParty/SDL2/src/render/metal/SDL_render_metal.m b/Source/3rdParty/SDL2/src/render/metal/SDL_render_metal.m
index f7af72d..5b4d8ea 100644
--- a/Source/3rdParty/SDL2/src/render/metal/SDL_render_metal.m
+++ b/Source/3rdParty/SDL2/src/render/metal/SDL_render_metal.m
@@ -752,8 +752,7 @@ METAL_ActivateRenderCommandEncoder(SDL_Renderer * renderer, MTLLoadAction load)
static void
METAL_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event)
{
- if (event->event == SDL_WINDOWEVENT_SIZE_CHANGED ||
- event->event == SDL_WINDOWEVENT_SHOWN ||
+ if (event->event == SDL_WINDOWEVENT_SHOWN ||
event->event == SDL_WINDOWEVENT_HIDDEN) {
// !!! FIXME: write me
}
@@ -844,17 +843,24 @@ METAL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
mtltexdesc.height = (texture->h + 1) / 2;
mtltexdesc.textureType = MTLTextureType2DArray;
mtltexdesc.arrayLength = 2;
- mtltexture_uv = [data.mtldevice newTextureWithDescriptor:mtltexdesc];
} else if (nv12) {
mtltexdesc.pixelFormat = MTLPixelFormatRG8Unorm;
mtltexdesc.width = (texture->w + 1) / 2;
mtltexdesc.height = (texture->h + 1) / 2;
+ }
+
+ 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");
+ }
}
METAL_TextureData *texturedata = [[METAL_TextureData alloc] init];
- const char *hint = SDL_GetHint(SDL_HINT_RENDER_SCALE_QUALITY);
- if (!hint || *hint == '0' || SDL_strcasecmp(hint, "nearest") == 0) {
+ if (texture->scaleMode == SDL_ScaleModeNearest) {
texturedata.mtlsampler = data.mtlsamplernearest;
} else {
texturedata.mtlsampler = data.mtlsamplerlinear;
@@ -957,8 +963,8 @@ METAL_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * texture,
const Uint8 *Vplane, int Vpitch)
{ @autoreleasepool {
METAL_TextureData *texturedata = (__bridge METAL_TextureData *)texture->driverdata;
- int Uslice = texture->format == SDL_PIXELFORMAT_YV12 ? 1 : 0;
- int Vslice = texture->format == SDL_PIXELFORMAT_YV12 ? 0 : 1;
+ const int Uslice = 0;
+ const int Vslice = 1;
/* Bail out if we're supposed to update an empty rectangle */
if (rect->w <= 0 || rect->h <= 0) {
@@ -1345,10 +1351,23 @@ static int
METAL_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
Uint32 pixel_format, void * pixels, int pitch)
{ @autoreleasepool {
+ METAL_RenderData *data = (__bridge METAL_RenderData *) renderer->driverdata;
+
+ /* Make sure we have a valid MTLTexture to read from, and an active command
+ * buffer we can wait for. */
METAL_ActivateRenderCommandEncoder(renderer, MTLLoadActionLoad);
- // !!! FIXME: this probably needs to commit the current command buffer, and probably waitUntilCompleted
- METAL_RenderData *data = (__bridge METAL_RenderData *) renderer->driverdata;
+ /* Wait for the current command buffer to finish, so we don't read from the
+ * texture before the GPU finishes rendering to it. */
+ if (data.mtlcmdencoder) {
+ [data.mtlcmdencoder endEncoding];
+ [data.mtlcmdbuffer commit];
+ [data.mtlcmdbuffer waitUntilCompleted];
+
+ data.mtlcmdencoder = nil;
+ data.mtlcmdbuffer = nil;
+ }
+
id<MTLTexture> mtltexture = data.mtlpassdesc.colorAttachments[0].texture;
MTLRegion mtlregion = MTLRegionMake2D(rect->x, rect->y, rect->w, rect->h);
@@ -1364,6 +1383,13 @@ METAL_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
const Uint32 temp_format = (mtltexture.pixelFormat == MTLPixelFormatBGRA8Unorm) ? SDL_PIXELFORMAT_ARGB8888 : SDL_PIXELFORMAT_ABGR8888;
const int status = SDL_ConvertPixels(rect->w, rect->h, temp_format, temp_pixels, temp_pitch, pixel_format, pixels, pitch);
SDL_free(temp_pixels);
+
+ /* Set up an active command buffer and encoder once we're done. It will use
+ * the same texture that was active before (even if it's part of the swap
+ * chain), since we didn't clear that when waiting for the command buffer to
+ * complete. */
+ METAL_ActivateRenderCommandEncoder(renderer, MTLLoadActionLoad);
+
return status;
}}