Add SDL_RenderReadPixels
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
diff --git a/src/render/vitagxm/SDL_render_vita_gxm.c b/src/render/vitagxm/SDL_render_vita_gxm.c
index d271743..88ecf70 100644
--- a/src/render/vitagxm/SDL_render_vita_gxm.c
+++ b/src/render/vitagxm/SDL_render_vita_gxm.c
@@ -959,19 +959,85 @@ VITA_GXM_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *
return 0;
}
+void read_pixels(int x, int y, size_t width, size_t height, void *data) {
+ SceDisplayFrameBuf pParam;
+ pParam.size = sizeof(SceDisplayFrameBuf);
+
+ sceDisplayGetFrameBuf(&pParam, SCE_DISPLAY_SETBUF_NEXTFRAME);
+
+ int i, j;
+ Uint32 *out32 = (Uint32 *)data;
+ Uint32 *in32 = (Uint32 *)pParam.base;
+
+ in32 += (x + y * pParam.pitch);
+
+ for (i = 0; i < height; i++) {
+ for (j = 0; j < width; j++) {
+ out32[(height - (i + 1)) * width + j] = in32[j];
+ }
+ in32 += pParam.pitch;
+ }
+}
+
+
static int
VITA_GXM_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rect *rect,
Uint32 pixel_format, void *pixels, int pitch)
{
- SceDisplayFrameBuf framebuf;
- SDL_memset(&framebuf, 0x00, sizeof(SceDisplayFrameBuf));
- sceDisplayGetFrameBuf(&framebuf, SCE_DISPLAY_SETBUF_IMMEDIATE);
+ // TODO: read from texture rendertarget. Although no-one sane should do it.
+ if (render->target) {
+ return SDL_Unsupported();
+ }
+
+ Uint32 temp_format = renderer->target ? renderer->target->format : SDL_PIXELFORMAT_ABGR8888;
+ size_t buflen;
+ void *temp_pixels;
+ int temp_pitch;
+ Uint8 *src, *dst, *tmp;
+ int w, h, length, rows;
+ int status;
+
+ temp_pitch = rect->w * SDL_BYTESPERPIXEL(temp_format);
+ buflen = rect->h * temp_pitch;
+ if (buflen == 0) {
+ return 0; /* nothing to do. */
+ }
+
+ temp_pixels = SDL_malloc(buflen);
+ if (!temp_pixels) {
+ return SDL_OutOfMemory();
+ }
- // TODO
- //pixels = framebuf.base;
+ SDL_GetRendererOutputSize(renderer, &w, &h);
- return 0;
+ read_pixels(rect->x, renderer->target ? rect->y : (h-rect->y)-rect->h,
+ rect->w, rect->h, temp_pixels);
+
+ /* Flip the rows to be top-down if necessary */
+
+ if (!renderer->target) {
+ SDL_bool isstack;
+ length = rect->w * SDL_BYTESPERPIXEL(temp_format);
+ src = (Uint8*)temp_pixels + (rect->h-1)*temp_pitch;
+ dst = (Uint8*)temp_pixels;
+ tmp = SDL_small_alloc(Uint8, length, &isstack);
+ rows = rect->h / 2;
+ while (rows--) {
+ SDL_memcpy(tmp, dst, length);
+ SDL_memcpy(dst, src, length);
+ SDL_memcpy(src, tmp, length);
+ dst += temp_pitch;
+ src -= temp_pitch;
+ }
+ SDL_small_free(tmp, isstack);
+ }
+
+ status = SDL_ConvertPixels(rect->w, rect->h,
+ temp_format, temp_pixels, temp_pitch,
+ pixel_format, pixels, pitch);
+ SDL_free(temp_pixels);
+ return status;
}