diff --git a/src/render/vitagxm/SDL_render_vita_gxm.c b/src/render/vitagxm/SDL_render_vita_gxm.c index d27174357..88ecf704f 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(); + } - // TODO - //pixels = framebuf.base; + 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; - return 0; + 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(); + } + + SDL_GetRendererOutputSize(renderer, &w, &h); + + 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; }