Commit cf3d450313d2745b7d9e71a357e50722e1c53da0

Sam Lantinga 2017-12-08T14:30:10

Added SDL_RenderGetMetalLayer() and SDL_RenderGetMetalCommandEncoder()

diff --git a/include/SDL_render.h b/include/SDL_render.h
index ea6ef9f..e38e64b 100644
--- a/include/SDL_render.h
+++ b/include/SDL_render.h
@@ -898,6 +898,27 @@ extern DECLSPEC int SDLCALL SDL_GL_BindTexture(SDL_Texture *texture, float *texw
  */
 extern DECLSPEC int SDLCALL SDL_GL_UnbindTexture(SDL_Texture *texture);
 
+/**
+ *  \brief Get the CAMetalLayer associated with the given Metal renderer
+ *
+ *  \param renderer The renderer to query
+ *
+ *  \return CAMetalLayer* on success, or NULL if the renderer isn't a Metal renderer
+ *
+ *  \sa SDL_RenderGetMetalCommandEncoder()
+ */
+extern DECLSPEC void *SDLCALL SDL_RenderGetMetalLayer(SDL_Renderer * renderer);
+
+/**
+ *  \brief Get the Metal command encoder for the current frame
+ *
+ *  \param renderer The renderer to query
+ *
+ *  \return id<MTLRenderCommandEncoder> on success, or NULL if the renderer isn't a Metal renderer
+ *
+ *  \sa SDL_RenderGetMetalLayer()
+ */
+extern DECLSPEC void *SDLCALL SDL_RenderGetMetalCommandEncoder(SDL_Renderer * renderer);
 
 /* Ends C function definitions when using C++ */
 #ifdef __cplusplus
diff --git a/src/dynapi/SDL_dynapi_overrides.h b/src/dynapi/SDL_dynapi_overrides.h
index cf61acf..4189290 100644
--- a/src/dynapi/SDL_dynapi_overrides.h
+++ b/src/dynapi/SDL_dynapi_overrides.h
@@ -663,3 +663,5 @@
 #define SDL_SetYUVConversionMode SDL_SetYUVConversionMode_REAL
 #define SDL_GetYUVConversionMode SDL_GetYUVConversionMode_REAL
 #define SDL_GetYUVConversionModeForResolution SDL_GetYUVConversionModeForResolution_REAL
+#define SDL_RenderGetMetalLayer SDL_RenderGetMetalLayer_REAL
+#define SDL_RenderGetMetalCommandEncoder SDL_RenderGetMetalCommandEncoder_REAL
diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h
index de2d488..a7983ed 100644
--- a/src/dynapi/SDL_dynapi_procs.h
+++ b/src/dynapi/SDL_dynapi_procs.h
@@ -697,3 +697,5 @@ SDL_DYNAPI_PROC(float,SDL_fmodf,(float a, float b),(a,b),return)
 SDL_DYNAPI_PROC(void,SDL_SetYUVConversionMode,(SDL_YUV_CONVERSION_MODE a),(a),)
 SDL_DYNAPI_PROC(SDL_YUV_CONVERSION_MODE,SDL_GetYUVConversionMode,(void),(),return)
 SDL_DYNAPI_PROC(SDL_YUV_CONVERSION_MODE,SDL_GetYUVConversionModeForResolution,(int a, int b),(a,b),return)
+SDL_DYNAPI_PROC(void*,SDL_RenderGetMetalLayer,(SDL_Renderer *a),(a),return)
+SDL_DYNAPI_PROC(void*,SDL_RenderGetMetalCommandEncoder,(SDL_Renderer *a),(a),return)
diff --git a/src/render/SDL_render.c b/src/render/SDL_render.c
index e93d307..ef1c4c3 100644
--- a/src/render/SDL_render.c
+++ b/src/render/SDL_render.c
@@ -2123,6 +2123,28 @@ int SDL_GL_UnbindTexture(SDL_Texture *texture)
     return SDL_Unsupported();
 }
 
+void *
+SDL_RenderGetMetalLayer(SDL_Renderer * renderer)
+{
+    CHECK_RENDERER_MAGIC(renderer, NULL);
+
+    if (renderer->GetMetalLayer) {
+        return renderer->GetMetalLayer(renderer);
+    }
+    return NULL;
+}
+
+void *
+SDL_RenderGetMetalCommandEncoder(SDL_Renderer * renderer)
+{
+    CHECK_RENDERER_MAGIC(renderer, NULL);
+
+    if (renderer->GetMetalCommandEncoder) {
+        return renderer->GetMetalCommandEncoder(renderer);
+    }
+    return NULL;
+}
+
 static SDL_BlendMode
 SDL_GetShortBlendMode(SDL_BlendMode blendMode)
 {
diff --git a/src/render/SDL_sysrender.h b/src/render/SDL_sysrender.h
index b204474..2f816ae 100644
--- a/src/render/SDL_sysrender.h
+++ b/src/render/SDL_sysrender.h
@@ -123,6 +123,9 @@ struct SDL_Renderer
     int (*GL_BindTexture) (SDL_Renderer * renderer, SDL_Texture *texture, float *texw, float *texh);
     int (*GL_UnbindTexture) (SDL_Renderer * renderer, SDL_Texture *texture);
 
+    void *(*GetMetalLayer) (SDL_Renderer * renderer);
+    void *(*GetMetalCommandEncoder) (SDL_Renderer * renderer);
+
     /* The current renderer info */
     SDL_RendererInfo info;
 
diff --git a/src/render/metal/SDL_render_metal.m b/src/render/metal/SDL_render_metal.m
index 30bdc54..efa9b67 100644
--- a/src/render/metal/SDL_render_metal.m
+++ b/src/render/metal/SDL_render_metal.m
@@ -81,6 +81,8 @@ static int METAL_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect
 static void METAL_RenderPresent(SDL_Renderer * renderer);
 static void METAL_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture);
 static void METAL_DestroyRenderer(SDL_Renderer * renderer);
+static void *METAL_GetMetalLayer(SDL_Renderer * renderer);
+static void *METAL_GetMetalCommandEncoder(SDL_Renderer * renderer);
 
 SDL_RenderDriver METAL_RenderDriver = {
     METAL_CreateRenderer,
@@ -328,6 +330,8 @@ METAL_CreateRenderer(SDL_Window * window, Uint32 flags)
     renderer->RenderPresent = METAL_RenderPresent;
     renderer->DestroyTexture = METAL_DestroyTexture;
     renderer->DestroyRenderer = METAL_DestroyRenderer;
+    renderer->GetMetalLayer = METAL_GetMetalLayer;
+    renderer->GetMetalCommandEncoder = METAL_GetMetalCommandEncoder;
 
     renderer->info = METAL_RenderDriver.info;
     renderer->info.flags = (SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE);
@@ -786,6 +790,19 @@ METAL_DestroyRenderer(SDL_Renderer * renderer)
     SDL_free(renderer);
 }}
 
+void *METAL_GetMetalLayer(SDL_Renderer * renderer)
+{ @autoreleasepool {
+    METAL_RenderData *data = (__bridge METAL_RenderData *) renderer->driverdata;
+    return (__bridge void*)data.mtllayer;
+}}
+
+void *METAL_GetMetalCommandEncoder(SDL_Renderer * renderer)
+{ @autoreleasepool {
+    METAL_ActivateRenderer(renderer);
+    METAL_RenderData *data = (__bridge METAL_RenderData *) renderer->driverdata;
+    return (__bridge void*)data.mtlcmdencoder;
+}}
+
 #endif /* SDL_VIDEO_RENDER_METAL && !SDL_RENDER_DISABLED */
 
 /* vi: set ts=4 sw=4 expandtab: */