Added a helper function SDL_LockTextureToSurface() Similar to SDL_LockTexture(), except the locked area is exposed as a SDL surface.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
diff --git a/WhatsNew.txt b/WhatsNew.txt
index faecf1d..ef2b07b 100644
--- a/WhatsNew.txt
+++ b/WhatsNew.txt
@@ -2,6 +2,13 @@
This is a list of major changes in SDL's version history.
---------------------------------------------------------------------------
+2.0.11/12:
+---------------------------------------------------------------------------
+
+General:
+* Added SDL_LockTextureToSurface(), similar to SDL_LockTexture() but the locked area is exposed as a SDL surface.
+
+---------------------------------------------------------------------------
2.0.10:
---------------------------------------------------------------------------
diff --git a/include/SDL_render.h b/include/SDL_render.h
index 096b4a5..c2a995a 100644
--- a/include/SDL_render.h
+++ b/include/SDL_render.h
@@ -431,9 +431,30 @@ extern DECLSPEC int SDLCALL SDL_LockTexture(SDL_Texture * texture,
void **pixels, int *pitch);
/**
+ * \brief Lock a portion of the texture for write-only pixel access.
+ * Expose it as a SDL surface.
+ *
+ * \param texture The texture to lock for access, which was created with
+ * ::SDL_TEXTUREACCESS_STREAMING.
+ * \param rect A pointer to the rectangle to lock for access. If the rect
+ * is NULL, the entire texture will be locked.
+ * \param surface This is filled in with a SDL surface representing the locked area
+ * Surface is freed internally after calling SDL_UnlockTexture or SDL_DestroyTexture.
+ *
+ * \return 0 on success, or -1 if the texture is not valid or was not created with ::SDL_TEXTUREACCESS_STREAMING.
+ *
+ * \sa SDL_UnlockTexture()
+ */
+extern DECLSPEC int SDLCALL SDL_LockTextureToSurface(SDL_Texture *texture,
+ const SDL_Rect *rect,
+ SDL_Surface **surface);
+
+/**
* \brief Unlock a texture, uploading the changes to video memory, if needed.
+ * If SDL_LockTextureToSurface() was called for locking, the SDL surface is freed.
*
* \sa SDL_LockTexture()
+ * \sa SDL_LockTextureToSurface()
*/
extern DECLSPEC void SDLCALL SDL_UnlockTexture(SDL_Texture * texture);
diff --git a/src/dynapi/SDL_dynapi_overrides.h b/src/dynapi/SDL_dynapi_overrides.h
index c769582..caab1c8 100644
--- a/src/dynapi/SDL_dynapi_overrides.h
+++ b/src/dynapi/SDL_dynapi_overrides.h
@@ -315,6 +315,7 @@
#define SDL_UpdateTexture SDL_UpdateTexture_REAL
#define SDL_UpdateYUVTexture SDL_UpdateYUVTexture_REAL
#define SDL_LockTexture SDL_LockTexture_REAL
+#define SDL_LockTextureToSurface SDL_LockTextureToSurface_REAL
#define SDL_UnlockTexture SDL_UnlockTexture_REAL
#define SDL_RenderTargetSupported SDL_RenderTargetSupported_REAL
#define SDL_SetRenderTarget SDL_SetRenderTarget_REAL
diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h
index e94d5de..01e1f39 100644
--- a/src/dynapi/SDL_dynapi_procs.h
+++ b/src/dynapi/SDL_dynapi_procs.h
@@ -346,6 +346,7 @@ SDL_DYNAPI_PROC(int,SDL_GetTextureBlendMode,(SDL_Texture *a, SDL_BlendMode *b),(
SDL_DYNAPI_PROC(int,SDL_UpdateTexture,(SDL_Texture *a, const SDL_Rect *b, const void *c, int d),(a,b,c,d),return)
SDL_DYNAPI_PROC(int,SDL_UpdateYUVTexture,(SDL_Texture *a, const SDL_Rect *b, const Uint8 *c, int d, const Uint8 *e, int f, const Uint8 *g, int h),(a,b,c,d,e,f,g,h),return)
SDL_DYNAPI_PROC(int,SDL_LockTexture,(SDL_Texture *a, const SDL_Rect *b, void **c, int *d),(a,b,c,d),return)
+SDL_DYNAPI_PROC(int,SDL_LockTextureToSurface,(SDL_Texture *a, const SDL_Rect *b, SDL_Surface **c),(a,b,c),return)
SDL_DYNAPI_PROC(void,SDL_UnlockTexture,(SDL_Texture *a),(a),)
SDL_DYNAPI_PROC(SDL_bool,SDL_RenderTargetSupported,(SDL_Renderer *a),(a),return)
SDL_DYNAPI_PROC(int,SDL_SetRenderTarget,(SDL_Renderer *a, SDL_Texture *b),(a,b),return)
diff --git a/src/render/SDL_render.c b/src/render/SDL_render.c
index 2b5b4c2..2ea2504 100644
--- a/src/render/SDL_render.c
+++ b/src/render/SDL_render.c
@@ -1680,6 +1680,45 @@ SDL_LockTexture(SDL_Texture * texture, const SDL_Rect * rect,
}
}
+int
+SDL_LockTextureToSurface(SDL_Texture *texture, const SDL_Rect *rect,
+ SDL_Surface **surface)
+{
+ SDL_Rect r;
+ void *pixels = NULL;
+ int pitch, ret;
+
+ if (texture == NULL || surface == NULL) {
+ return -1;
+ }
+
+ if (rect == NULL) {
+ r.x = 0;
+ r.y = 0;
+ r.w = texture->w;
+ r.h = texture->h;
+ } else {
+ r.x = rect->x;
+ r.y = rect->y;
+ r.w = SDL_min(texture->w - rect->x, rect->w);
+ r.h = SDL_min(texture->h - rect->y, rect->h);
+ }
+
+ ret = SDL_LockTexture(texture, &r, &pixels, &pitch);
+ if (ret < 0) {
+ return ret;
+ }
+
+ texture->locked_surface = SDL_CreateRGBSurfaceWithFormatFrom(pixels, r.w, r.h, 0, pitch, texture->format);
+ if (texture->locked_surface == NULL) {
+ SDL_UnlockTexture(texture);
+ return -1;
+ }
+
+ *surface = texture->locked_surface;
+ return 0;
+}
+
static void
SDL_UnlockTextureYUV(SDL_Texture * texture)
{
@@ -1738,6 +1777,9 @@ SDL_UnlockTexture(SDL_Texture * texture)
SDL_Renderer *renderer = texture->renderer;
renderer->UnlockTexture(renderer, texture);
}
+
+ SDL_FreeSurface(texture->locked_surface);
+ texture->locked_surface = NULL;
}
SDL_bool
@@ -3090,6 +3132,10 @@ SDL_DestroyTexture(SDL_Texture * texture)
SDL_free(texture->pixels);
renderer->DestroyTexture(renderer, texture);
+
+ SDL_FreeSurface(texture->locked_surface);
+ texture->locked_surface = NULL;
+
SDL_free(texture);
}
diff --git a/src/render/SDL_sysrender.h b/src/render/SDL_sysrender.h
index dedd642..a93e21c 100644
--- a/src/render/SDL_sysrender.h
+++ b/src/render/SDL_sysrender.h
@@ -60,6 +60,7 @@ struct SDL_Texture
void *pixels;
int pitch;
SDL_Rect locked_rect;
+ SDL_Surface *locked_surface; /**< Locked region exposed as a SDL surface */
Uint32 last_command_generation; /* last command queue generation this texture was in. */