SDL_RenderReadPixels() now returns a surface
Fixes https://github.com/libsdl-org/SDL/issues/8977main
parent
ab571633d1
commit
89b9d6cbdc
|
@ -1053,6 +1053,8 @@ The viewport, clipping state, and scale for render targets are now persistent an
|
||||||
|
|
||||||
SDL_RenderGeometryRaw() and SDL_Vertex have been changed to use floating point colors, in the range of [0..1] for SDR content.
|
SDL_RenderGeometryRaw() and SDL_Vertex have been changed to use floating point colors, in the range of [0..1] for SDR content.
|
||||||
|
|
||||||
|
SDL_RenderReadPixels() returns a surface instead of filling in preallocated memory.
|
||||||
|
|
||||||
The following functions have been renamed:
|
The following functions have been renamed:
|
||||||
* SDL_GetRendererOutputSize() => SDL_GetCurrentRenderOutputSize()
|
* SDL_GetRendererOutputSize() => SDL_GetCurrentRenderOutputSize()
|
||||||
* SDL_RenderCopy() => SDL_RenderTexture()
|
* SDL_RenderCopy() => SDL_RenderTexture()
|
||||||
|
|
|
@ -1722,35 +1722,23 @@ extern DECLSPEC int SDLCALL SDL_RenderGeometryRaw(SDL_Renderer *renderer,
|
||||||
const void *indices, int num_indices, int size_indices);
|
const void *indices, int num_indices, int size_indices);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read pixels from the current rendering target to an array of pixels.
|
* Read pixels from the current rendering target.
|
||||||
|
*
|
||||||
|
* The returned surface should be freed with SDL_DestroySurface()
|
||||||
*
|
*
|
||||||
* **WARNING**: This is a very slow operation, and should not be used
|
* **WARNING**: This is a very slow operation, and should not be used
|
||||||
* frequently. If you're using this on the main rendering target, it should be
|
* frequently. If you're using this on the main rendering target, it should be
|
||||||
* called after rendering and before SDL_RenderPresent().
|
* called after rendering and before SDL_RenderPresent().
|
||||||
*
|
*
|
||||||
* `pitch` specifies the number of bytes between rows in the destination
|
|
||||||
* `pixels` data. This allows you to write to a subrectangle or have padded
|
|
||||||
* rows in the destination. Generally, `pitch` should equal the number of
|
|
||||||
* pixels per row in the `pixels` data times the number of bytes per pixel,
|
|
||||||
* but it might contain additional padding (for example, 24bit RGB Windows
|
|
||||||
* Bitmap data pads all rows to multiples of 4 bytes).
|
|
||||||
*
|
|
||||||
* \param renderer the rendering context
|
* \param renderer the rendering context
|
||||||
* \param rect an SDL_Rect structure representing the area in pixels relative
|
* \param rect an SDL_Rect structure representing the area in pixels relative
|
||||||
* to the to current viewport, or NULL for the entire viewport
|
* to the to current viewport, or NULL for the entire viewport
|
||||||
* \param format an SDL_PixelFormatEnum value of the desired format of the
|
* \returns a new SDL_Surface on success or NULL on failure; call
|
||||||
* pixel data, or 0 to use the format of the rendering target
|
|
||||||
* \param pixels a pointer to the pixel data to copy into
|
|
||||||
* \param pitch the pitch of the `pixels` parameter
|
|
||||||
* \returns 0 on success or a negative error code on failure; call
|
|
||||||
* SDL_GetError() for more information.
|
* SDL_GetError() for more information.
|
||||||
*
|
*
|
||||||
* \since This function is available since SDL 3.0.0.
|
* \since This function is available since SDL 3.0.0.
|
||||||
*/
|
*/
|
||||||
extern DECLSPEC int SDLCALL SDL_RenderReadPixels(SDL_Renderer *renderer,
|
extern DECLSPEC SDL_Surface * SDLCALL SDL_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rect *rect);
|
||||||
const SDL_Rect *rect,
|
|
||||||
Uint32 format,
|
|
||||||
void *pixels, int pitch);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the screen with any rendering performed since the previous call.
|
* Update the screen with any rendering performed since the previous call.
|
||||||
|
|
|
@ -568,7 +568,7 @@ SDL_DYNAPI_PROC(int,SDL_RenderLines,(SDL_Renderer *a, const SDL_FPoint *b, int c
|
||||||
SDL_DYNAPI_PROC(int,SDL_RenderPoint,(SDL_Renderer *a, float b, float c),(a,b,c),return)
|
SDL_DYNAPI_PROC(int,SDL_RenderPoint,(SDL_Renderer *a, float b, float c),(a,b,c),return)
|
||||||
SDL_DYNAPI_PROC(int,SDL_RenderPoints,(SDL_Renderer *a, const SDL_FPoint *b, int c),(a,b,c),return)
|
SDL_DYNAPI_PROC(int,SDL_RenderPoints,(SDL_Renderer *a, const SDL_FPoint *b, int c),(a,b,c),return)
|
||||||
SDL_DYNAPI_PROC(int,SDL_RenderPresent,(SDL_Renderer *a),(a),return)
|
SDL_DYNAPI_PROC(int,SDL_RenderPresent,(SDL_Renderer *a),(a),return)
|
||||||
SDL_DYNAPI_PROC(int,SDL_RenderReadPixels,(SDL_Renderer *a, const SDL_Rect *b, Uint32 c, void *d, int e),(a,b,c,d,e),return)
|
SDL_DYNAPI_PROC(SDL_Surface *,SDL_RenderReadPixels,(SDL_Renderer *a, const SDL_Rect *b),(a,b),return)
|
||||||
SDL_DYNAPI_PROC(int,SDL_RenderRect,(SDL_Renderer *a, const SDL_FRect *b),(a,b),return)
|
SDL_DYNAPI_PROC(int,SDL_RenderRect,(SDL_Renderer *a, const SDL_FRect *b),(a,b),return)
|
||||||
SDL_DYNAPI_PROC(int,SDL_RenderRects,(SDL_Renderer *a, const SDL_FRect *b, int c),(a,b,c),return)
|
SDL_DYNAPI_PROC(int,SDL_RenderRects,(SDL_Renderer *a, const SDL_FRect *b, int c),(a,b,c),return)
|
||||||
SDL_DYNAPI_PROC(int,SDL_RenderTexture,(SDL_Renderer *a, SDL_Texture *b, const SDL_FRect *c, const SDL_FRect *d),(a,b,c,d),return)
|
SDL_DYNAPI_PROC(int,SDL_RenderTexture,(SDL_Renderer *a, SDL_Texture *b, const SDL_FRect *c, const SDL_FRect *d),(a,b,c,d),return)
|
||||||
|
|
|
@ -4134,43 +4134,28 @@ int SDL_RenderGeometryRaw(SDL_Renderer *renderer,
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
int SDL_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rect *rect, Uint32 format, void *pixels, int pitch)
|
SDL_Surface *SDL_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rect *rect)
|
||||||
{
|
{
|
||||||
SDL_Rect real_rect;
|
SDL_Rect real_rect;
|
||||||
|
|
||||||
CHECK_RENDERER_MAGIC(renderer, -1);
|
CHECK_RENDERER_MAGIC(renderer, NULL);
|
||||||
|
|
||||||
if (!renderer->RenderReadPixels) {
|
if (!renderer->RenderReadPixels) {
|
||||||
return SDL_Unsupported();
|
SDL_Unsupported();
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
FlushRenderCommands(renderer); /* we need to render before we read the results. */
|
FlushRenderCommands(renderer); /* we need to render before we read the results. */
|
||||||
|
|
||||||
if (!format) {
|
|
||||||
if (!renderer->target) {
|
|
||||||
format = SDL_GetWindowPixelFormat(renderer->window);
|
|
||||||
} else {
|
|
||||||
format = renderer->target->format;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GetRenderViewportInPixels(renderer, &real_rect);
|
GetRenderViewportInPixels(renderer, &real_rect);
|
||||||
|
|
||||||
if (rect) {
|
if (rect) {
|
||||||
if (!SDL_GetRectIntersection(rect, &real_rect, &real_rect)) {
|
if (!SDL_GetRectIntersection(rect, &real_rect, &real_rect)) {
|
||||||
return 0;
|
return NULL;
|
||||||
}
|
|
||||||
if (real_rect.y > rect->y) {
|
|
||||||
pixels = (Uint8 *)pixels + pitch * (real_rect.y - rect->y);
|
|
||||||
}
|
|
||||||
if (real_rect.x > rect->x) {
|
|
||||||
int bpp = SDL_BYTESPERPIXEL(format);
|
|
||||||
pixels = (Uint8 *)pixels + bpp * (real_rect.x - rect->x);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return renderer->RenderReadPixels(renderer, &real_rect,
|
return renderer->RenderReadPixels(renderer, &real_rect);
|
||||||
format, pixels, pitch);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SDL_SimulateRenderVSync(SDL_Renderer *renderer)
|
static void SDL_SimulateRenderVSync(SDL_Renderer *renderer)
|
||||||
|
|
|
@ -201,8 +201,7 @@ struct SDL_Renderer
|
||||||
void (*UnlockTexture)(SDL_Renderer *renderer, SDL_Texture *texture);
|
void (*UnlockTexture)(SDL_Renderer *renderer, SDL_Texture *texture);
|
||||||
void (*SetTextureScaleMode)(SDL_Renderer *renderer, SDL_Texture *texture, SDL_ScaleMode scaleMode);
|
void (*SetTextureScaleMode)(SDL_Renderer *renderer, SDL_Texture *texture, SDL_ScaleMode scaleMode);
|
||||||
int (*SetRenderTarget)(SDL_Renderer *renderer, SDL_Texture *texture);
|
int (*SetRenderTarget)(SDL_Renderer *renderer, SDL_Texture *texture);
|
||||||
int (*RenderReadPixels)(SDL_Renderer *renderer, const SDL_Rect *rect,
|
SDL_Surface *(*RenderReadPixels)(SDL_Renderer *renderer, const SDL_Rect *rect);
|
||||||
Uint32 format, void *pixels, int pitch);
|
|
||||||
int (*RenderPresent)(SDL_Renderer *renderer);
|
int (*RenderPresent)(SDL_Renderer *renderer);
|
||||||
void (*DestroyTexture)(SDL_Renderer *renderer, SDL_Texture *texture);
|
void (*DestroyTexture)(SDL_Renderer *renderer, SDL_Texture *texture);
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include "../SDL_sysrender.h"
|
#include "../SDL_sysrender.h"
|
||||||
#include "../SDL_d3dmath.h"
|
#include "../SDL_d3dmath.h"
|
||||||
#include "../../video/windows/SDL_windowsvideo.h"
|
#include "../../video/windows/SDL_windowsvideo.h"
|
||||||
|
#include "../../video/SDL_pixels_c.h"
|
||||||
|
|
||||||
#ifdef SDL_VIDEO_RENDER_D3D
|
#ifdef SDL_VIDEO_RENDER_D3D
|
||||||
#define D3D_DEBUG_INFO
|
#define D3D_DEBUG_INFO
|
||||||
|
@ -1297,8 +1298,7 @@ static int D3D_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, v
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int D3D_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rect *rect,
|
static SDL_Surface *D3D_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rect *rect)
|
||||||
Uint32 format, void *pixels, int pitch)
|
|
||||||
{
|
{
|
||||||
D3D_RenderData *data = (D3D_RenderData *)renderer->driverdata;
|
D3D_RenderData *data = (D3D_RenderData *)renderer->driverdata;
|
||||||
D3DSURFACE_DESC desc;
|
D3DSURFACE_DESC desc;
|
||||||
|
@ -1307,7 +1307,7 @@ static int D3D_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rect *rect,
|
||||||
RECT d3drect;
|
RECT d3drect;
|
||||||
D3DLOCKED_RECT locked;
|
D3DLOCKED_RECT locked;
|
||||||
HRESULT result;
|
HRESULT result;
|
||||||
int status;
|
SDL_Surface *output;
|
||||||
|
|
||||||
if (data->currentRenderTarget) {
|
if (data->currentRenderTarget) {
|
||||||
backBuffer = data->currentRenderTarget;
|
backBuffer = data->currentRenderTarget;
|
||||||
|
@ -1317,18 +1317,21 @@ static int D3D_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rect *rect,
|
||||||
|
|
||||||
result = IDirect3DSurface9_GetDesc(backBuffer, &desc);
|
result = IDirect3DSurface9_GetDesc(backBuffer, &desc);
|
||||||
if (FAILED(result)) {
|
if (FAILED(result)) {
|
||||||
return D3D_SetError("GetDesc()", result);
|
D3D_SetError("GetDesc()", result);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = IDirect3DDevice9_CreateOffscreenPlainSurface(data->device, desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &surface, NULL);
|
result = IDirect3DDevice9_CreateOffscreenPlainSurface(data->device, desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &surface, NULL);
|
||||||
if (FAILED(result)) {
|
if (FAILED(result)) {
|
||||||
return D3D_SetError("CreateOffscreenPlainSurface()", result);
|
D3D_SetError("CreateOffscreenPlainSurface()", result);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = IDirect3DDevice9_GetRenderTargetData(data->device, backBuffer, surface);
|
result = IDirect3DDevice9_GetRenderTargetData(data->device, backBuffer, surface);
|
||||||
if (FAILED(result)) {
|
if (FAILED(result)) {
|
||||||
IDirect3DSurface9_Release(surface);
|
IDirect3DSurface9_Release(surface);
|
||||||
return D3D_SetError("GetRenderTargetData()", result);
|
D3D_SetError("GetRenderTargetData()", result);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
d3drect.left = rect->x;
|
d3drect.left = rect->x;
|
||||||
|
@ -1339,18 +1342,17 @@ static int D3D_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rect *rect,
|
||||||
result = IDirect3DSurface9_LockRect(surface, &locked, &d3drect, D3DLOCK_READONLY);
|
result = IDirect3DSurface9_LockRect(surface, &locked, &d3drect, D3DLOCK_READONLY);
|
||||||
if (FAILED(result)) {
|
if (FAILED(result)) {
|
||||||
IDirect3DSurface9_Release(surface);
|
IDirect3DSurface9_Release(surface);
|
||||||
return D3D_SetError("LockRect()", result);
|
D3D_SetError("LockRect()", result);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = SDL_ConvertPixels(rect->w, rect->h,
|
output = SDL_DuplicatePixels(rect->w, rect->h, D3DFMTToPixelFormat(desc.Format), SDL_COLORSPACE_SRGB, locked.pBits, locked.Pitch);
|
||||||
D3DFMTToPixelFormat(desc.Format), locked.pBits, locked.Pitch,
|
|
||||||
format, pixels, pitch);
|
|
||||||
|
|
||||||
IDirect3DSurface9_UnlockRect(surface);
|
IDirect3DSurface9_UnlockRect(surface);
|
||||||
|
|
||||||
IDirect3DSurface9_Release(surface);
|
IDirect3DSurface9_Release(surface);
|
||||||
|
|
||||||
return status;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int D3D_RenderPresent(SDL_Renderer *renderer)
|
static int D3D_RenderPresent(SDL_Renderer *renderer)
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#endif
|
#endif
|
||||||
#include "../SDL_sysrender.h"
|
#include "../SDL_sysrender.h"
|
||||||
#include "../SDL_d3dmath.h"
|
#include "../SDL_d3dmath.h"
|
||||||
|
#include "../../video/SDL_pixels_c.h"
|
||||||
|
|
||||||
#include <d3d11_1.h>
|
#include <d3d11_1.h>
|
||||||
#include <dxgi1_4.h>
|
#include <dxgi1_4.h>
|
||||||
|
@ -2342,19 +2343,18 @@ static int D3D11_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int D3D11_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rect *rect,
|
static SDL_Surface *D3D11_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rect *rect)
|
||||||
Uint32 format, void *pixels, int pitch)
|
|
||||||
{
|
{
|
||||||
D3D11_RenderData *data = (D3D11_RenderData *)renderer->driverdata;
|
D3D11_RenderData *data = (D3D11_RenderData *)renderer->driverdata;
|
||||||
ID3D11RenderTargetView *renderTargetView = NULL;
|
ID3D11RenderTargetView *renderTargetView = NULL;
|
||||||
ID3D11Texture2D *backBuffer = NULL;
|
ID3D11Texture2D *backBuffer = NULL;
|
||||||
ID3D11Texture2D *stagingTexture = NULL;
|
ID3D11Texture2D *stagingTexture = NULL;
|
||||||
HRESULT result;
|
HRESULT result;
|
||||||
int status = -1;
|
|
||||||
D3D11_TEXTURE2D_DESC stagingTextureDesc;
|
D3D11_TEXTURE2D_DESC stagingTextureDesc;
|
||||||
D3D11_RECT srcRect = { 0, 0, 0, 0 };
|
D3D11_RECT srcRect = { 0, 0, 0, 0 };
|
||||||
D3D11_BOX srcBox;
|
D3D11_BOX srcBox;
|
||||||
D3D11_MAPPED_SUBRESOURCE textureMemory;
|
D3D11_MAPPED_SUBRESOURCE textureMemory;
|
||||||
|
SDL_Surface *output = NULL;
|
||||||
|
|
||||||
renderTargetView = D3D11_GetCurrentRenderTargetView(renderer);
|
renderTargetView = D3D11_GetCurrentRenderTargetView(renderer);
|
||||||
if (!renderTargetView) {
|
if (!renderTargetView) {
|
||||||
|
@ -2417,19 +2417,12 @@ static int D3D11_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rect *rect,
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Copy the data into the desired buffer, converting pixels to the
|
output = SDL_DuplicatePixels(
|
||||||
* desired format at the same time:
|
|
||||||
*/
|
|
||||||
status = SDL_ConvertPixelsAndColorspace(
|
|
||||||
rect->w, rect->h,
|
rect->w, rect->h,
|
||||||
D3D11_DXGIFormatToSDLPixelFormat(stagingTextureDesc.Format),
|
D3D11_DXGIFormatToSDLPixelFormat(stagingTextureDesc.Format),
|
||||||
renderer->target ? renderer->target->colorspace : renderer->output_colorspace,
|
renderer->target ? renderer->target->colorspace : renderer->output_colorspace,
|
||||||
textureMemory.pData,
|
textureMemory.pData,
|
||||||
textureMemory.RowPitch,
|
textureMemory.RowPitch);
|
||||||
format,
|
|
||||||
SDL_COLORSPACE_SRGB,
|
|
||||||
pixels,
|
|
||||||
pitch);
|
|
||||||
|
|
||||||
/* Unmap the texture: */
|
/* Unmap the texture: */
|
||||||
ID3D11DeviceContext_Unmap(data->d3dContext,
|
ID3D11DeviceContext_Unmap(data->d3dContext,
|
||||||
|
@ -2439,7 +2432,7 @@ static int D3D11_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rect *rect,
|
||||||
done:
|
done:
|
||||||
SAFE_RELEASE(backBuffer);
|
SAFE_RELEASE(backBuffer);
|
||||||
SAFE_RELEASE(stagingTexture);
|
SAFE_RELEASE(stagingTexture);
|
||||||
return status;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int D3D11_RenderPresent(SDL_Renderer *renderer)
|
static int D3D11_RenderPresent(SDL_Renderer *renderer)
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include "../../video/windows/SDL_windowswindow.h"
|
#include "../../video/windows/SDL_windowswindow.h"
|
||||||
#include "../SDL_sysrender.h"
|
#include "../SDL_sysrender.h"
|
||||||
#include "../SDL_d3dmath.h"
|
#include "../SDL_d3dmath.h"
|
||||||
|
#include "../../video/SDL_pixels_c.h"
|
||||||
|
|
||||||
#if defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES)
|
#if defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES)
|
||||||
#include "SDL_render_d3d12_xbox.h"
|
#include "SDL_render_d3d12_xbox.h"
|
||||||
|
@ -2801,14 +2802,12 @@ static int D3D12_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int D3D12_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rect *rect,
|
static SDL_Surface *D3D12_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rect *rect)
|
||||||
Uint32 format, void *pixels, int pitch)
|
|
||||||
{
|
{
|
||||||
D3D12_RenderData *data = (D3D12_RenderData *)renderer->driverdata;
|
D3D12_RenderData *data = (D3D12_RenderData *)renderer->driverdata;
|
||||||
ID3D12Resource *backBuffer = NULL;
|
ID3D12Resource *backBuffer = NULL;
|
||||||
ID3D12Resource *readbackBuffer = NULL;
|
ID3D12Resource *readbackBuffer = NULL;
|
||||||
HRESULT result;
|
HRESULT result;
|
||||||
int status = -1;
|
|
||||||
D3D12_RESOURCE_DESC textureDesc;
|
D3D12_RESOURCE_DESC textureDesc;
|
||||||
D3D12_RESOURCE_DESC readbackDesc;
|
D3D12_RESOURCE_DESC readbackDesc;
|
||||||
D3D12_HEAP_PROPERTIES heapProps;
|
D3D12_HEAP_PROPERTIES heapProps;
|
||||||
|
@ -2820,6 +2819,7 @@ static int D3D12_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rect *rect,
|
||||||
D3D12_SUBRESOURCE_FOOTPRINT pitchedDesc;
|
D3D12_SUBRESOURCE_FOOTPRINT pitchedDesc;
|
||||||
BYTE *textureMemory;
|
BYTE *textureMemory;
|
||||||
int bpp;
|
int bpp;
|
||||||
|
SDL_Surface *output = NULL;
|
||||||
|
|
||||||
if (data->textureRenderTarget) {
|
if (data->textureRenderTarget) {
|
||||||
backBuffer = data->textureRenderTarget->mainTexture;
|
backBuffer = data->textureRenderTarget->mainTexture;
|
||||||
|
@ -2938,26 +2938,19 @@ static int D3D12_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rect *rect,
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Copy the data into the desired buffer, converting pixels to the
|
output = SDL_DuplicatePixels(
|
||||||
* desired format at the same time:
|
|
||||||
*/
|
|
||||||
status = SDL_ConvertPixelsAndColorspace(
|
|
||||||
rect->w, rect->h,
|
rect->w, rect->h,
|
||||||
D3D12_DXGIFormatToSDLPixelFormat(textureDesc.Format),
|
D3D12_DXGIFormatToSDLPixelFormat(textureDesc.Format),
|
||||||
renderer->target ? renderer->target->colorspace : renderer->output_colorspace,
|
renderer->target ? renderer->target->colorspace : renderer->output_colorspace,
|
||||||
textureMemory,
|
textureMemory,
|
||||||
pitchedDesc.RowPitch,
|
pitchedDesc.RowPitch);
|
||||||
format,
|
|
||||||
SDL_COLORSPACE_SRGB,
|
|
||||||
pixels,
|
|
||||||
pitch);
|
|
||||||
|
|
||||||
/* Unmap the texture: */
|
/* Unmap the texture: */
|
||||||
D3D_CALL(readbackBuffer, Unmap, 0, NULL);
|
D3D_CALL(readbackBuffer, Unmap, 0, NULL);
|
||||||
|
|
||||||
done:
|
done:
|
||||||
SAFE_RELEASE(readbackBuffer);
|
SAFE_RELEASE(readbackBuffer);
|
||||||
return status;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int D3D12_RenderPresent(SDL_Renderer *renderer)
|
static int D3D12_RenderPresent(SDL_Renderer *renderer)
|
||||||
|
|
|
@ -1451,19 +1451,18 @@ static int METAL_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int METAL_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rect *rect,
|
static SDL_Surface *METAL_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rect *rect)
|
||||||
Uint32 pixel_format, void *pixels, int pitch)
|
|
||||||
{
|
{
|
||||||
@autoreleasepool {
|
@autoreleasepool {
|
||||||
METAL_RenderData *data = (__bridge METAL_RenderData *)renderer->driverdata;
|
METAL_RenderData *data = (__bridge METAL_RenderData *)renderer->driverdata;
|
||||||
id<MTLTexture> mtltexture;
|
id<MTLTexture> mtltexture;
|
||||||
MTLRegion mtlregion;
|
MTLRegion mtlregion;
|
||||||
size_t temp_pitch;
|
Uint32 format;
|
||||||
int status;
|
SDL_Surface *surface;
|
||||||
Uint32 temp_format;
|
|
||||||
void *temp_pixels;
|
|
||||||
if (!METAL_ActivateRenderCommandEncoder(renderer, MTLLoadActionLoad, NULL, nil)) {
|
if (!METAL_ActivateRenderCommandEncoder(renderer, MTLLoadActionLoad, NULL, nil)) {
|
||||||
return SDL_SetError("Failed to activate render command encoder (is your window in the background?");
|
SDL_SetError("Failed to activate render command encoder (is your window in the background?");
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
[data.mtlcmdencoder endEncoding];
|
[data.mtlcmdencoder endEncoding];
|
||||||
|
@ -1490,19 +1489,12 @@ static int METAL_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rect *rect,
|
||||||
|
|
||||||
mtlregion = MTLRegionMake2D(rect->x, rect->y, rect->w, rect->h);
|
mtlregion = MTLRegionMake2D(rect->x, rect->y, rect->w, rect->h);
|
||||||
|
|
||||||
// we only do BGRA8 or RGBA8 at the moment, so 4 will do.
|
format = (mtltexture.pixelFormat == MTLPixelFormatBGRA8Unorm) ? SDL_PIXELFORMAT_ARGB8888 : SDL_PIXELFORMAT_ABGR8888;
|
||||||
temp_pitch = rect->w * 4UL;
|
surface = SDL_CreateSurface(rect->w, rect->h, format);
|
||||||
temp_pixels = SDL_malloc(temp_pitch * rect->h);
|
if (surface) {
|
||||||
if (!temp_pixels) {
|
[mtltexture getBytes:surface->pixels bytesPerRow:surface->pitch fromRegion:mtlregion mipmapLevel:0];
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
return surface;
|
||||||
[mtltexture getBytes:temp_pixels bytesPerRow:temp_pitch fromRegion:mtlregion mipmapLevel:0];
|
|
||||||
|
|
||||||
temp_format = (mtltexture.pixelFormat == MTLPixelFormatBGRA8Unorm) ? SDL_PIXELFORMAT_ARGB8888 : SDL_PIXELFORMAT_ABGR8888;
|
|
||||||
status = SDL_ConvertPixels(rect->w, rect->h, temp_format, temp_pixels, (int)temp_pitch, pixel_format, pixels, pitch);
|
|
||||||
SDL_free(temp_pixels);
|
|
||||||
return status;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1457,74 +1457,58 @@ static int GL_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, vo
|
||||||
return GL_CheckError("", renderer);
|
return GL_CheckError("", renderer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int GL_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rect *rect,
|
static SDL_Surface *GL_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rect *rect)
|
||||||
Uint32 pixel_format, void *pixels, int pitch)
|
|
||||||
{
|
{
|
||||||
GL_RenderData *data = (GL_RenderData *)renderer->driverdata;
|
GL_RenderData *data = (GL_RenderData *)renderer->driverdata;
|
||||||
Uint32 temp_format = renderer->target ? renderer->target->format : SDL_PIXELFORMAT_ARGB8888;
|
Uint32 format = renderer->target ? renderer->target->format : SDL_PIXELFORMAT_ARGB8888;
|
||||||
void *temp_pixels;
|
|
||||||
int temp_pitch;
|
|
||||||
GLint internalFormat;
|
GLint internalFormat;
|
||||||
GLenum format, type;
|
GLenum targetFormat, type;
|
||||||
Uint8 *src, *dst, *tmp;
|
int w, h;
|
||||||
int w, h, length, rows;
|
SDL_Surface *surface;
|
||||||
int status;
|
|
||||||
|
|
||||||
GL_ActivateRenderer(renderer);
|
GL_ActivateRenderer(renderer);
|
||||||
|
|
||||||
if (!convert_format(temp_format, &internalFormat, &format, &type)) {
|
if (!convert_format(format, &internalFormat, &targetFormat, &type)) {
|
||||||
return SDL_SetError("Texture format %s not supported by OpenGL",
|
SDL_SetError("Texture format %s not supported by OpenGL", SDL_GetPixelFormatName(format));
|
||||||
SDL_GetPixelFormatName(temp_format));
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rect->w == 0 || rect->h == 0) {
|
surface = SDL_CreateSurface(rect->w, rect->h, format);
|
||||||
return 0; /* nothing to do. */
|
if (!surface) {
|
||||||
}
|
return NULL;
|
||||||
|
|
||||||
temp_pitch = rect->w * SDL_BYTESPERPIXEL(temp_format);
|
|
||||||
temp_pixels = SDL_malloc((size_t)rect->h * temp_pitch);
|
|
||||||
if (!temp_pixels) {
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_GetCurrentRenderOutputSize(renderer, &w, &h);
|
SDL_GetCurrentRenderOutputSize(renderer, &w, &h);
|
||||||
|
|
||||||
data->glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
data->glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||||
data->glPixelStorei(GL_PACK_ROW_LENGTH,
|
data->glPixelStorei(GL_PACK_ROW_LENGTH, (surface->pitch / SDL_BYTESPERPIXEL(format)));
|
||||||
(temp_pitch / SDL_BYTESPERPIXEL(temp_format)));
|
|
||||||
|
|
||||||
data->glReadPixels(rect->x, renderer->target ? rect->y : (h - rect->y) - rect->h,
|
data->glReadPixels(rect->x, renderer->target ? rect->y : (h - rect->y) - rect->h,
|
||||||
rect->w, rect->h, format, type, temp_pixels);
|
rect->w, rect->h, targetFormat, type, surface->pixels);
|
||||||
|
|
||||||
if (GL_CheckError("glReadPixels()", renderer) < 0) {
|
if (GL_CheckError("glReadPixels()", renderer) < 0) {
|
||||||
SDL_free(temp_pixels);
|
SDL_DestroySurface(surface);
|
||||||
return -1;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Flip the rows to be top-down if necessary */
|
/* Flip the rows to be top-down if necessary */
|
||||||
if (!renderer->target) {
|
if (!renderer->target) {
|
||||||
SDL_bool isstack;
|
SDL_bool isstack;
|
||||||
length = rect->w * SDL_BYTESPERPIXEL(temp_format);
|
int length = rect->w * SDL_BYTESPERPIXEL(format);
|
||||||
src = (Uint8 *)temp_pixels + (rect->h - 1) * temp_pitch;
|
Uint8 *src = (Uint8 *)surface->pixels + (rect->h - 1) * surface->pitch;
|
||||||
dst = (Uint8 *)temp_pixels;
|
Uint8 *dst = (Uint8 *)surface->pixels;
|
||||||
tmp = SDL_small_alloc(Uint8, length, &isstack);
|
Uint8 *tmp = SDL_small_alloc(Uint8, length, &isstack);
|
||||||
rows = rect->h / 2;
|
int rows = rect->h / 2;
|
||||||
while (rows--) {
|
while (rows--) {
|
||||||
SDL_memcpy(tmp, dst, length);
|
SDL_memcpy(tmp, dst, length);
|
||||||
SDL_memcpy(dst, src, length);
|
SDL_memcpy(dst, src, length);
|
||||||
SDL_memcpy(src, tmp, length);
|
SDL_memcpy(src, tmp, length);
|
||||||
dst += temp_pitch;
|
dst += surface->pitch;
|
||||||
src -= temp_pitch;
|
src -= surface->pitch;
|
||||||
}
|
}
|
||||||
SDL_small_free(tmp, isstack);
|
SDL_small_free(tmp, isstack);
|
||||||
}
|
}
|
||||||
|
return surface;
|
||||||
status = SDL_ConvertPixels(rect->w, rect->h,
|
|
||||||
temp_format, temp_pixels, temp_pitch,
|
|
||||||
pixel_format, pixels, pitch);
|
|
||||||
SDL_free(temp_pixels);
|
|
||||||
|
|
||||||
return status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int GL_RenderPresent(SDL_Renderer *renderer)
|
static int GL_RenderPresent(SDL_Renderer *renderer)
|
||||||
|
|
|
@ -1923,61 +1923,45 @@ static void GLES2_DestroyTexture(SDL_Renderer *renderer, SDL_Texture *texture)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int GLES2_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rect *rect,
|
static SDL_Surface *GLES2_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rect *rect)
|
||||||
Uint32 pixel_format, void *pixels, int pitch)
|
|
||||||
{
|
{
|
||||||
GLES2_RenderData *data = (GLES2_RenderData *)renderer->driverdata;
|
GLES2_RenderData *data = (GLES2_RenderData *)renderer->driverdata;
|
||||||
Uint32 temp_format = renderer->target ? renderer->target->format : SDL_PIXELFORMAT_RGBA32;
|
Uint32 format = renderer->target ? renderer->target->format : SDL_PIXELFORMAT_RGBA32;
|
||||||
size_t buflen;
|
int w, h;
|
||||||
void *temp_pixels;
|
SDL_Surface *surface;
|
||||||
int temp_pitch;
|
|
||||||
Uint8 *src, *dst, *tmp;
|
|
||||||
int w, h, length, rows;
|
|
||||||
int status;
|
|
||||||
|
|
||||||
temp_pitch = rect->w * SDL_BYTESPERPIXEL(temp_format);
|
surface = SDL_CreateSurface(rect->w, rect->h, format);
|
||||||
buflen = (size_t)rect->h * temp_pitch;
|
if (!surface) {
|
||||||
if (buflen == 0) {
|
return NULL;
|
||||||
return 0; /* nothing to do. */
|
|
||||||
}
|
|
||||||
|
|
||||||
temp_pixels = SDL_malloc(buflen);
|
|
||||||
if (!temp_pixels) {
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_GetCurrentRenderOutputSize(renderer, &w, &h);
|
SDL_GetCurrentRenderOutputSize(renderer, &w, &h);
|
||||||
|
|
||||||
data->glReadPixels(rect->x, renderer->target ? rect->y : (h - rect->y) - rect->h,
|
data->glReadPixels(rect->x, renderer->target ? rect->y : (h - rect->y) - rect->h,
|
||||||
rect->w, rect->h, GL_RGBA, GL_UNSIGNED_BYTE, temp_pixels);
|
rect->w, rect->h, GL_RGBA, GL_UNSIGNED_BYTE, surface->pixels);
|
||||||
if (GL_CheckError("glReadPixels()", renderer) < 0) {
|
if (GL_CheckError("glReadPixels()", renderer) < 0) {
|
||||||
return -1;
|
SDL_DestroySurface(surface);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Flip the rows to be top-down if necessary */
|
/* Flip the rows to be top-down if necessary */
|
||||||
if (!renderer->target) {
|
if (!renderer->target) {
|
||||||
SDL_bool isstack;
|
SDL_bool isstack;
|
||||||
length = rect->w * SDL_BYTESPERPIXEL(temp_format);
|
int length = rect->w * SDL_BYTESPERPIXEL(format);
|
||||||
src = (Uint8 *)temp_pixels + (rect->h - 1) * temp_pitch;
|
Uint8 *src = (Uint8 *)surface->pixels + (rect->h - 1) * surface->pitch;
|
||||||
dst = (Uint8 *)temp_pixels;
|
Uint8 *dst = (Uint8 *)surface->pixels;
|
||||||
tmp = SDL_small_alloc(Uint8, length, &isstack);
|
Uint8 *tmp = SDL_small_alloc(Uint8, length, &isstack);
|
||||||
rows = rect->h / 2;
|
int rows = rect->h / 2;
|
||||||
while (rows--) {
|
while (rows--) {
|
||||||
SDL_memcpy(tmp, dst, length);
|
SDL_memcpy(tmp, dst, length);
|
||||||
SDL_memcpy(dst, src, length);
|
SDL_memcpy(dst, src, length);
|
||||||
SDL_memcpy(src, tmp, length);
|
SDL_memcpy(src, tmp, length);
|
||||||
dst += temp_pitch;
|
dst += surface->pitch;
|
||||||
src -= temp_pitch;
|
src -= surface->pitch;
|
||||||
}
|
}
|
||||||
SDL_small_free(tmp, isstack);
|
SDL_small_free(tmp, isstack);
|
||||||
}
|
}
|
||||||
|
return surface;
|
||||||
status = SDL_ConvertPixels(rect->w, rect->h,
|
|
||||||
temp_format, temp_pixels, temp_pitch,
|
|
||||||
pixel_format, pixels, pitch);
|
|
||||||
SDL_free(temp_pixels);
|
|
||||||
|
|
||||||
return status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int GLES2_RenderPresent(SDL_Renderer *renderer)
|
static int GLES2_RenderPresent(SDL_Renderer *renderer)
|
||||||
|
|
|
@ -537,12 +537,6 @@ static int PS2_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, v
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int PS2_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rect *rect,
|
|
||||||
Uint32 format, void *pixels, int pitch)
|
|
||||||
{
|
|
||||||
return SDL_Unsupported();
|
|
||||||
}
|
|
||||||
|
|
||||||
static int PS2_RenderPresent(SDL_Renderer *renderer)
|
static int PS2_RenderPresent(SDL_Renderer *renderer)
|
||||||
{
|
{
|
||||||
PS2_RenderData *data = (PS2_RenderData *)renderer->driverdata;
|
PS2_RenderData *data = (PS2_RenderData *)renderer->driverdata;
|
||||||
|
@ -703,7 +697,6 @@ static SDL_Renderer *PS2_CreateRenderer(SDL_Window *window, SDL_PropertiesID cre
|
||||||
renderer->QueueGeometry = PS2_QueueGeometry;
|
renderer->QueueGeometry = PS2_QueueGeometry;
|
||||||
renderer->InvalidateCachedState = PS2_InvalidateCachedState;
|
renderer->InvalidateCachedState = PS2_InvalidateCachedState;
|
||||||
renderer->RunCommandQueue = PS2_RunCommandQueue;
|
renderer->RunCommandQueue = PS2_RunCommandQueue;
|
||||||
renderer->RenderReadPixels = PS2_RenderReadPixels;
|
|
||||||
renderer->RenderPresent = PS2_RenderPresent;
|
renderer->RenderPresent = PS2_RenderPresent;
|
||||||
renderer->DestroyTexture = PS2_DestroyTexture;
|
renderer->DestroyTexture = PS2_DestroyTexture;
|
||||||
renderer->DestroyRenderer = PS2_DestroyRenderer;
|
renderer->DestroyRenderer = PS2_DestroyRenderer;
|
||||||
|
|
|
@ -1212,12 +1212,6 @@ static int PSP_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, v
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int PSP_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rect *rect,
|
|
||||||
Uint32 pixel_format, void *pixels, int pitch)
|
|
||||||
{
|
|
||||||
return SDL_Unsupported();
|
|
||||||
}
|
|
||||||
|
|
||||||
static int PSP_RenderPresent(SDL_Renderer *renderer)
|
static int PSP_RenderPresent(SDL_Renderer *renderer)
|
||||||
{
|
{
|
||||||
PSP_RenderData *data = (PSP_RenderData *)renderer->driverdata;
|
PSP_RenderData *data = (PSP_RenderData *)renderer->driverdata;
|
||||||
|
@ -1335,7 +1329,6 @@ SDL_Renderer *PSP_CreateRenderer(SDL_Window *window, SDL_PropertiesID create_pro
|
||||||
renderer->QueueCopyEx = PSP_QueueCopyEx;
|
renderer->QueueCopyEx = PSP_QueueCopyEx;
|
||||||
renderer->InvalidateCachedState = PSP_InvalidateCachedState;
|
renderer->InvalidateCachedState = PSP_InvalidateCachedState;
|
||||||
renderer->RunCommandQueue = PSP_RunCommandQueue;
|
renderer->RunCommandQueue = PSP_RunCommandQueue;
|
||||||
renderer->RenderReadPixels = PSP_RenderReadPixels;
|
|
||||||
renderer->RenderPresent = PSP_RenderPresent;
|
renderer->RenderPresent = PSP_RenderPresent;
|
||||||
renderer->DestroyTexture = PSP_DestroyTexture;
|
renderer->DestroyTexture = PSP_DestroyTexture;
|
||||||
renderer->DestroyRenderer = PSP_DestroyRenderer;
|
renderer->DestroyRenderer = PSP_DestroyRenderer;
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#include "SDL_drawpoint.h"
|
#include "SDL_drawpoint.h"
|
||||||
#include "SDL_rotate.h"
|
#include "SDL_rotate.h"
|
||||||
#include "SDL_triangle.h"
|
#include "SDL_triangle.h"
|
||||||
|
#include "../../video/SDL_pixels_c.h"
|
||||||
|
|
||||||
/* SDL surface based renderer implementation */
|
/* SDL surface based renderer implementation */
|
||||||
|
|
||||||
|
@ -967,15 +968,13 @@ static int SW_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, vo
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int SW_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rect *rect,
|
static SDL_Surface *SW_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rect *rect)
|
||||||
Uint32 format, void *pixels, int pitch)
|
|
||||||
{
|
{
|
||||||
SDL_Surface *surface = SW_ActivateRenderer(renderer);
|
SDL_Surface *surface = SW_ActivateRenderer(renderer);
|
||||||
Uint32 src_format;
|
void *pixels;
|
||||||
void *src_pixels;
|
|
||||||
|
|
||||||
if (!surface) {
|
if (!surface) {
|
||||||
return -1;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* NOTE: The rect is already adjusted according to the viewport by
|
/* NOTE: The rect is already adjusted according to the viewport by
|
||||||
|
@ -984,17 +983,15 @@ static int SW_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rect *rect,
|
||||||
|
|
||||||
if (rect->x < 0 || rect->x + rect->w > surface->w ||
|
if (rect->x < 0 || rect->x + rect->w > surface->w ||
|
||||||
rect->y < 0 || rect->y + rect->h > surface->h) {
|
rect->y < 0 || rect->y + rect->h > surface->h) {
|
||||||
return SDL_SetError("Tried to read outside of surface bounds");
|
SDL_SetError("Tried to read outside of surface bounds");
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
src_format = surface->format->format;
|
pixels = (void *)((Uint8 *)surface->pixels +
|
||||||
src_pixels = (void *)((Uint8 *)surface->pixels +
|
|
||||||
rect->y * surface->pitch +
|
rect->y * surface->pitch +
|
||||||
rect->x * surface->format->BytesPerPixel);
|
rect->x * surface->format->BytesPerPixel);
|
||||||
|
|
||||||
return SDL_ConvertPixels(rect->w, rect->h,
|
return SDL_DuplicatePixels(rect->w, rect->h, surface->format->format, SDL_COLORSPACE_SRGB, pixels, surface->pitch);
|
||||||
src_format, src_pixels, surface->pitch,
|
|
||||||
format, pixels, pitch);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int SW_RenderPresent(SDL_Renderer *renderer)
|
static int SW_RenderPresent(SDL_Renderer *renderer)
|
||||||
|
|
|
@ -93,8 +93,7 @@ static void VITA_GXM_InvalidateCachedState(SDL_Renderer *renderer);
|
||||||
|
|
||||||
static int VITA_GXM_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize);
|
static int VITA_GXM_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize);
|
||||||
|
|
||||||
static int VITA_GXM_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rect *rect,
|
static SDL_Surface *VITA_GXM_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rect *rect);
|
||||||
Uint32 pixel_format, void *pixels, int pitch);
|
|
||||||
|
|
||||||
static int VITA_GXM_RenderPresent(SDL_Renderer *renderer);
|
static int VITA_GXM_RenderPresent(SDL_Renderer *renderer);
|
||||||
static void VITA_GXM_DestroyTexture(SDL_Renderer *renderer, SDL_Texture *texture);
|
static void VITA_GXM_DestroyTexture(SDL_Renderer *renderer, SDL_Texture *texture);
|
||||||
|
@ -1089,63 +1088,47 @@ void read_pixels(int x, int y, size_t width, size_t height, void *data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int VITA_GXM_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rect *rect,
|
static SDL_Surface *VITA_GXM_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rect *rect)
|
||||||
Uint32 pixel_format, void *pixels, int pitch)
|
|
||||||
{
|
{
|
||||||
Uint32 temp_format = renderer->target ? renderer->target->format : SDL_PIXELFORMAT_ABGR8888;
|
Uint32 format = renderer->target ? renderer->target->format : SDL_PIXELFORMAT_ABGR8888;
|
||||||
size_t buflen;
|
int w, h;
|
||||||
void *temp_pixels;
|
SDL_Surface *surface;
|
||||||
int temp_pitch;
|
|
||||||
Uint8 *src, *dst, *tmp;
|
|
||||||
int w, h, length, rows;
|
|
||||||
int status;
|
|
||||||
|
|
||||||
// TODO: read from texture rendertarget. Although no-one sane should do it.
|
// TODO: read from texture rendertarget.
|
||||||
if (renderer->target) {
|
if (renderer->target) {
|
||||||
return SDL_Unsupported();
|
SDL_Unsupported();
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
temp_pitch = rect->w * SDL_BYTESPERPIXEL(temp_format);
|
surface = SDL_CreateSurface(rect->w, rect->h, format);
|
||||||
buflen = rect->h * temp_pitch;
|
if (!surface) {
|
||||||
if (buflen == 0) {
|
return NULL;
|
||||||
return 0; /* nothing to do. */
|
|
||||||
}
|
|
||||||
|
|
||||||
temp_pixels = SDL_malloc(buflen);
|
|
||||||
if (!temp_pixels) {
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_GetCurrentRenderOutputSize(renderer, &w, &h);
|
SDL_GetCurrentRenderOutputSize(renderer, &w, &h);
|
||||||
|
|
||||||
read_pixels(rect->x, renderer->target ? rect->y : (h - rect->y) - rect->h,
|
read_pixels(rect->x, renderer->target ? rect->y : (h - rect->y) - rect->h,
|
||||||
rect->w, rect->h, temp_pixels);
|
rect->w, rect->h, surface->pixels);
|
||||||
|
|
||||||
/* Flip the rows to be top-down if necessary */
|
/* Flip the rows to be top-down if necessary */
|
||||||
|
|
||||||
if (!renderer->target) {
|
if (!renderer->target) {
|
||||||
SDL_bool isstack;
|
SDL_bool isstack;
|
||||||
length = rect->w * SDL_BYTESPERPIXEL(temp_format);
|
int length = rect->w * SDL_BYTESPERPIXEL(format);
|
||||||
src = (Uint8 *)temp_pixels + (rect->h - 1) * temp_pitch;
|
Uint8 *src = (Uint8 *)surface->pixels + (rect->h - 1) * surface->pitch;
|
||||||
dst = (Uint8 *)temp_pixels;
|
Uint8 *dst = (Uint8 *)surface->pixels;
|
||||||
tmp = SDL_small_alloc(Uint8, length, &isstack);
|
Uint8 *tmp = SDL_small_alloc(Uint8, length, &isstack);
|
||||||
rows = rect->h / 2;
|
int rows = rect->h / 2;
|
||||||
while (rows--) {
|
while (rows--) {
|
||||||
SDL_memcpy(tmp, dst, length);
|
SDL_memcpy(tmp, dst, length);
|
||||||
SDL_memcpy(dst, src, length);
|
SDL_memcpy(dst, src, length);
|
||||||
SDL_memcpy(src, tmp, length);
|
SDL_memcpy(src, tmp, length);
|
||||||
dst += temp_pitch;
|
dst += surface->pitch;
|
||||||
src -= temp_pitch;
|
src -= surface->pitch;
|
||||||
}
|
}
|
||||||
SDL_small_free(tmp, isstack);
|
SDL_small_free(tmp, isstack);
|
||||||
}
|
}
|
||||||
|
return surface;
|
||||||
status = SDL_ConvertPixels(rect->w, rect->h,
|
|
||||||
temp_format, temp_pixels, temp_pitch,
|
|
||||||
pixel_format, pixels, pitch);
|
|
||||||
SDL_free(temp_pixels);
|
|
||||||
|
|
||||||
return status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int VITA_GXM_RenderPresent(SDL_Renderer *renderer)
|
static int VITA_GXM_RenderPresent(SDL_Renderer *renderer)
|
||||||
|
|
|
@ -2016,7 +2016,6 @@ static const void *SDLTest_ScreenShotClipboardProvider(void *context, const char
|
||||||
|
|
||||||
static void SDLTest_CopyScreenShot(SDL_Renderer *renderer)
|
static void SDLTest_CopyScreenShot(SDL_Renderer *renderer)
|
||||||
{
|
{
|
||||||
SDL_Rect viewport;
|
|
||||||
SDL_Surface *surface;
|
SDL_Surface *surface;
|
||||||
const char *image_formats[] = {
|
const char *image_formats[] = {
|
||||||
"text/plain;charset=utf-8",
|
"text/plain;charset=utf-8",
|
||||||
|
@ -2028,28 +2027,18 @@ static void SDLTest_CopyScreenShot(SDL_Renderer *renderer)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_GetRenderViewport(renderer, &viewport);
|
surface = SDL_RenderReadPixels(renderer, NULL);
|
||||||
|
|
||||||
surface = SDL_CreateSurface(viewport.w, viewport.h, SDL_PIXELFORMAT_BGR24);
|
|
||||||
|
|
||||||
if (!surface) {
|
if (!surface) {
|
||||||
SDL_Log("Couldn't create surface: %s\n", SDL_GetError());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SDL_RenderReadPixels(renderer, NULL, surface->format->format,
|
|
||||||
surface->pixels, surface->pitch) < 0) {
|
|
||||||
SDL_Log("Couldn't read screen: %s\n", SDL_GetError());
|
SDL_Log("Couldn't read screen: %s\n", SDL_GetError());
|
||||||
SDL_free(surface);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SDL_SaveBMP(surface, SCREENSHOT_FILE) < 0) {
|
if (SDL_SaveBMP(surface, SCREENSHOT_FILE) < 0) {
|
||||||
SDL_Log("Couldn't save %s: %s\n", SCREENSHOT_FILE, SDL_GetError());
|
SDL_Log("Couldn't save %s: %s\n", SCREENSHOT_FILE, SDL_GetError());
|
||||||
SDL_free(surface);
|
SDL_DestroySurface(surface);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
SDL_free(surface);
|
SDL_DestroySurface(surface);
|
||||||
|
|
||||||
clipboard_data = (SDLTest_ClipboardData *)SDL_calloc(1, sizeof(*clipboard_data));
|
clipboard_data = (SDLTest_ClipboardData *)SDL_calloc(1, sizeof(*clipboard_data));
|
||||||
if (!clipboard_data) {
|
if (!clipboard_data) {
|
||||||
|
|
|
@ -43,8 +43,6 @@ extern float SDL_PQfromNits(float v);
|
||||||
extern const float *SDL_GetColorPrimariesConversionMatrix(SDL_ColorPrimaries src, SDL_ColorPrimaries dst);
|
extern const float *SDL_GetColorPrimariesConversionMatrix(SDL_ColorPrimaries src, SDL_ColorPrimaries dst);
|
||||||
extern void SDL_ConvertColorPrimaries(float *fR, float *fG, float *fB, const float *matrix);
|
extern void SDL_ConvertColorPrimaries(float *fR, float *fG, float *fB, const float *matrix);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Blit mapping functions */
|
/* Blit mapping functions */
|
||||||
extern SDL_BlitMap *SDL_AllocBlitMap(void);
|
extern SDL_BlitMap *SDL_AllocBlitMap(void);
|
||||||
extern void SDL_InvalidateMap(SDL_BlitMap *map);
|
extern void SDL_InvalidateMap(SDL_BlitMap *map);
|
||||||
|
@ -57,5 +55,6 @@ extern void SDL_InvalidateAllBlitMap(SDL_Surface *surface);
|
||||||
extern void SDL_DitherColors(SDL_Color *colors, int bpp);
|
extern void SDL_DitherColors(SDL_Color *colors, int bpp);
|
||||||
extern Uint8 SDL_FindColor(SDL_Palette *pal, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
|
extern Uint8 SDL_FindColor(SDL_Palette *pal, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
|
||||||
extern void SDL_DetectPalette(SDL_Palette *pal, SDL_bool *is_opaque, SDL_bool *has_alpha_channel);
|
extern void SDL_DetectPalette(SDL_Palette *pal, SDL_bool *is_opaque, SDL_bool *has_alpha_channel);
|
||||||
|
extern SDL_Surface *SDL_DuplicatePixels(int width, int height, Uint32 format, SDL_Colorspace colorspace, void *pixels, int pitch);
|
||||||
|
|
||||||
#endif /* SDL_pixels_c_h_ */
|
#endif /* SDL_pixels_c_h_ */
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include "SDL_pixels_c.h"
|
#include "SDL_pixels_c.h"
|
||||||
#include "SDL_yuv_c.h"
|
#include "SDL_yuv_c.h"
|
||||||
#include "../render/SDL_sysrender.h"
|
#include "../render/SDL_sysrender.h"
|
||||||
|
#include "../video/SDL_pixels_c.h"
|
||||||
#include "../video/SDL_yuv_c.h"
|
#include "../video/SDL_yuv_c.h"
|
||||||
|
|
||||||
/* Check to make sure we can safely check multiplication of surface w and pitch and it won't overflow size_t */
|
/* Check to make sure we can safely check multiplication of surface w and pitch and it won't overflow size_t */
|
||||||
|
@ -1508,9 +1509,7 @@ SDL_Surface *SDL_ConvertSurfaceFormatAndColorspace(SDL_Surface *surface, Uint32
|
||||||
/*
|
/*
|
||||||
* Create a surface on the stack for quick blit operations
|
* Create a surface on the stack for quick blit operations
|
||||||
*/
|
*/
|
||||||
static SDL_INLINE SDL_bool SDL_CreateSurfaceOnStack(int width, int height, Uint32 pixel_format,
|
static SDL_bool SDL_CreateSurfaceOnStack(int width, int height, Uint32 pixel_format, SDL_Colorspace colorspace, void *pixels, int pitch, SDL_Surface *surface, SDL_PixelFormat *format, SDL_BlitMap *blitmap)
|
||||||
void *pixels, int pitch, SDL_Surface *surface,
|
|
||||||
SDL_PixelFormat *format, SDL_BlitMap *blitmap)
|
|
||||||
{
|
{
|
||||||
if (SDL_ISPIXELFORMAT_INDEXED(pixel_format)) {
|
if (SDL_ISPIXELFORMAT_INDEXED(pixel_format)) {
|
||||||
SDL_SetError("Indexed pixel formats not supported");
|
SDL_SetError("Indexed pixel formats not supported");
|
||||||
|
@ -1538,11 +1537,36 @@ static SDL_INLINE SDL_bool SDL_CreateSurfaceOnStack(int width, int height, Uint3
|
||||||
blitmap->info.a = 0xFF;
|
blitmap->info.a = 0xFF;
|
||||||
surface->map = blitmap;
|
surface->map = blitmap;
|
||||||
|
|
||||||
|
SDL_SetNumberProperty(SDL_GetSurfaceProperties(surface), SDL_PROP_SURFACE_COLORSPACE_NUMBER, colorspace);
|
||||||
|
|
||||||
/* The surface is ready to go */
|
/* The surface is ready to go */
|
||||||
surface->refcount = 1;
|
surface->refcount = 1;
|
||||||
return SDL_TRUE;
|
return SDL_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void SDL_DestroySurfaceOnStack(SDL_Surface *surface)
|
||||||
|
{
|
||||||
|
/* Free blitmap reference, after blitting between stack'ed surfaces */
|
||||||
|
SDL_InvalidateMap(surface->map);
|
||||||
|
|
||||||
|
SDL_DestroyProperties(SDL_GetSurfaceProperties(surface));
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_Surface *SDL_DuplicatePixels(int width, int height, Uint32 format, SDL_Colorspace colorspace, void *pixels, int pitch)
|
||||||
|
{
|
||||||
|
SDL_Surface surface;
|
||||||
|
SDL_PixelFormat fmt;
|
||||||
|
SDL_BlitMap blitmap;
|
||||||
|
SDL_Surface *result = NULL;
|
||||||
|
|
||||||
|
if (SDL_CreateSurfaceOnStack(width, height, format, colorspace, pixels, pitch, &surface, &fmt, &blitmap)) {
|
||||||
|
result = SDL_DuplicateSurface(&surface);
|
||||||
|
|
||||||
|
SDL_DestroySurfaceOnStack(&surface);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
int SDL_ConvertPixelsAndColorspace(int width, int height,
|
int SDL_ConvertPixelsAndColorspace(int width, int height,
|
||||||
Uint32 src_format, SDL_Colorspace src_colorspace, const void *src, int src_pitch,
|
Uint32 src_format, SDL_Colorspace src_colorspace, const void *src, int src_pitch,
|
||||||
Uint32 dst_format, SDL_Colorspace dst_colorspace, void *dst, int dst_pitch)
|
Uint32 dst_format, SDL_Colorspace dst_colorspace, void *dst, int dst_pitch)
|
||||||
|
@ -1601,18 +1625,13 @@ int SDL_ConvertPixelsAndColorspace(int width, int height,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!SDL_CreateSurfaceOnStack(width, height, src_format, nonconst_src,
|
if (!SDL_CreateSurfaceOnStack(width, height, src_format, src_colorspace, nonconst_src, src_pitch, &src_surface, &src_fmt, &src_blitmap)) {
|
||||||
src_pitch,
|
|
||||||
&src_surface, &src_fmt, &src_blitmap)) {
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
SDL_SetNumberProperty(SDL_GetSurfaceProperties(&src_surface), SDL_PROP_SURFACE_COLORSPACE_NUMBER, src_colorspace);
|
|
||||||
|
|
||||||
if (!SDL_CreateSurfaceOnStack(width, height, dst_format, dst, dst_pitch,
|
if (!SDL_CreateSurfaceOnStack(width, height, dst_format, dst_colorspace, dst, dst_pitch, &dst_surface, &dst_fmt, &dst_blitmap)) {
|
||||||
&dst_surface, &dst_fmt, &dst_blitmap)) {
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
SDL_SetNumberProperty(SDL_GetSurfaceProperties(&dst_surface), SDL_PROP_SURFACE_COLORSPACE_NUMBER, dst_colorspace);
|
|
||||||
|
|
||||||
/* Set up the rect and go! */
|
/* Set up the rect and go! */
|
||||||
rect.x = 0;
|
rect.x = 0;
|
||||||
|
@ -1621,15 +1640,9 @@ int SDL_ConvertPixelsAndColorspace(int width, int height,
|
||||||
rect.h = height;
|
rect.h = height;
|
||||||
ret = SDL_BlitSurfaceUnchecked(&src_surface, &rect, &dst_surface, &rect);
|
ret = SDL_BlitSurfaceUnchecked(&src_surface, &rect, &dst_surface, &rect);
|
||||||
|
|
||||||
/* Free blitmap reference, after blitting between stack'ed surfaces */
|
SDL_DestroySurfaceOnStack(&src_surface);
|
||||||
SDL_InvalidateMap(src_surface.map);
|
SDL_DestroySurfaceOnStack(&dst_surface);
|
||||||
|
|
||||||
if (src_colorspace != SDL_COLORSPACE_UNKNOWN) {
|
|
||||||
SDL_DestroyProperties(SDL_GetSurfaceProperties(&src_surface));
|
|
||||||
}
|
|
||||||
if (dst_colorspace != SDL_COLORSPACE_UNKNOWN) {
|
|
||||||
SDL_DestroyProperties(SDL_GetSurfaceProperties(&dst_surface));
|
|
||||||
}
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -343,7 +343,7 @@ static int render_testPrimitivesBlend(void *arg)
|
||||||
static int render_testPrimitivesWithViewport(void *arg)
|
static int render_testPrimitivesWithViewport(void *arg)
|
||||||
{
|
{
|
||||||
SDL_Rect viewport;
|
SDL_Rect viewport;
|
||||||
Uint32 pixel;
|
SDL_Surface *surface;
|
||||||
|
|
||||||
/* Clear surface. */
|
/* Clear surface. */
|
||||||
clearScreen();
|
clearScreen();
|
||||||
|
@ -363,9 +363,15 @@ static int render_testPrimitivesWithViewport(void *arg)
|
||||||
viewport.h = 1;
|
viewport.h = 1;
|
||||||
CHECK_FUNC(SDL_SetRenderViewport, (renderer, &viewport));
|
CHECK_FUNC(SDL_SetRenderViewport, (renderer, &viewport));
|
||||||
|
|
||||||
pixel = 0;
|
surface = SDL_RenderReadPixels(renderer, NULL);
|
||||||
CHECK_FUNC(SDL_RenderReadPixels, (renderer, NULL, SDL_PIXELFORMAT_RGBA8888, &pixel, sizeof(pixel)));
|
if (surface) {
|
||||||
SDLTest_AssertCheck(pixel == 0xFFFFFFFF, "Validate diagonal line drawing with viewport, expected 0xFFFFFFFF, got 0x%.8x", (unsigned int)pixel);
|
Uint8 r, g, b, a;
|
||||||
|
CHECK_FUNC(SDL_ReadSurfacePixel, (surface, 0, 0, &r, &g, &b, &a));
|
||||||
|
SDLTest_AssertCheck(r == 0xFF && g == 0xFF && b == 0xFF && a == 0xFF, "Validate diagonal line drawing with viewport, expected 0xFFFFFFFF, got 0x%.2x%.2x%.2x%.2x", r, g, b, a);
|
||||||
|
SDL_DestroySurface(surface);
|
||||||
|
} else {
|
||||||
|
SDLTest_AssertCheck(surface != NULL, "Validate result from SDL_RenderReadPixels, got NULL, %s", SDL_GetError());
|
||||||
|
}
|
||||||
|
|
||||||
return TEST_COMPLETED;
|
return TEST_COMPLETED;
|
||||||
}
|
}
|
||||||
|
@ -1207,33 +1213,32 @@ compare(SDL_Surface *referenceSurface, int allowable_error)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
SDL_Rect rect;
|
SDL_Rect rect;
|
||||||
Uint8 *pixels;
|
SDL_Surface *surface, *testSurface;
|
||||||
SDL_Surface *testSurface;
|
|
||||||
|
|
||||||
/* Read pixels. */
|
|
||||||
pixels = (Uint8 *)SDL_malloc(4*TESTRENDER_SCREEN_W*TESTRENDER_SCREEN_H);
|
|
||||||
SDLTest_AssertCheck(pixels != NULL, "Validate allocated temp pixel buffer");
|
|
||||||
if (pixels == NULL) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Explicitly specify the rect in case the window isn't the expected size... */
|
/* Explicitly specify the rect in case the window isn't the expected size... */
|
||||||
rect.x = 0;
|
rect.x = 0;
|
||||||
rect.y = 0;
|
rect.y = 0;
|
||||||
rect.w = TESTRENDER_SCREEN_W;
|
rect.w = TESTRENDER_SCREEN_W;
|
||||||
rect.h = TESTRENDER_SCREEN_H;
|
rect.h = TESTRENDER_SCREEN_H;
|
||||||
CHECK_FUNC(SDL_RenderReadPixels, (renderer, &rect, RENDER_COMPARE_FORMAT, pixels, 80*4 ))
|
|
||||||
|
|
||||||
/* Create surface. */
|
surface = SDL_RenderReadPixels(renderer, &rect);
|
||||||
testSurface = SDL_CreateSurfaceFrom(pixels, TESTRENDER_SCREEN_W, TESTRENDER_SCREEN_H, TESTRENDER_SCREEN_W*4, RENDER_COMPARE_FORMAT);
|
if (!surface) {
|
||||||
SDLTest_AssertCheck(testSurface != NULL, "Verify result from SDL_CreateSurfaceFrom is not NULL");
|
SDLTest_AssertCheck(surface != NULL, "Validate result from SDL_RenderReadPixels, got NULL, %s", SDL_GetError());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
testSurface = SDL_ConvertSurfaceFormat(surface, RENDER_COMPARE_FORMAT);
|
||||||
|
SDL_DestroySurface(surface);
|
||||||
|
if (!testSurface) {
|
||||||
|
SDLTest_AssertCheck(testSurface != NULL, "Validate result from SDL_ConvertSurfaceFormat, got NULL, %s", SDL_GetError());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* Compare surface. */
|
/* Compare surface. */
|
||||||
ret = SDLTest_CompareSurfaces( testSurface, referenceSurface, allowable_error );
|
ret = SDLTest_CompareSurfaces(testSurface, referenceSurface, allowable_error);
|
||||||
SDLTest_AssertCheck(ret == 0, "Validate result from SDLTest_CompareSurfaces, expected: 0, got: %i", ret);
|
SDLTest_AssertCheck(ret == 0, "Validate result from SDLTest_CompareSurfaces, expected: 0, got: %i", ret);
|
||||||
|
|
||||||
/* Clean up. */
|
/* Clean up. */
|
||||||
SDL_free(pixels);
|
|
||||||
SDL_DestroySurface(testSurface);
|
SDL_DestroySurface(testSurface);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -114,16 +114,27 @@ static void PrevStage(void)
|
||||||
|
|
||||||
static SDL_bool ReadPixel(int x, int y, SDL_Color *c)
|
static SDL_bool ReadPixel(int x, int y, SDL_Color *c)
|
||||||
{
|
{
|
||||||
|
SDL_Surface *surface;
|
||||||
SDL_Rect r;
|
SDL_Rect r;
|
||||||
|
SDL_bool result = SDL_FALSE;
|
||||||
|
|
||||||
r.x = x;
|
r.x = x;
|
||||||
r.y = y;
|
r.y = y;
|
||||||
r.w = 1;
|
r.w = 1;
|
||||||
r.h = 1;
|
r.h = 1;
|
||||||
if (SDL_RenderReadPixels(renderer, &r, SDL_PIXELFORMAT_RGBA32, c, sizeof(*c)) < 0) {
|
|
||||||
SDL_Log("Couldn't read back pixels: %s\n", SDL_GetError());
|
surface = SDL_RenderReadPixels(renderer, &r);
|
||||||
return SDL_FALSE;
|
if (surface) {
|
||||||
|
if (SDL_ReadSurfacePixel(surface, 0, 0, &c->r, &c->g, &c->b, &c->a) == 0) {
|
||||||
|
result = SDL_TRUE;
|
||||||
|
} else {
|
||||||
|
SDL_Log("Couldn't read pixel: %s\n", SDL_GetError());
|
||||||
}
|
}
|
||||||
return SDL_TRUE;
|
SDL_DestroySurface(surface);
|
||||||
|
} else {
|
||||||
|
SDL_Log("Couldn't read back pixels: %s\n", SDL_GetError());
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DrawText(float x, float y, const char *fmt, ...)
|
static void DrawText(float x, float y, const char *fmt, ...)
|
||||||
|
|
|
@ -52,15 +52,10 @@ static void draw(void)
|
||||||
|
|
||||||
static void save_surface_to_bmp(void)
|
static void save_surface_to_bmp(void)
|
||||||
{
|
{
|
||||||
SDL_Surface* surface;
|
SDL_Surface *surface;
|
||||||
Uint32 pixel_format;
|
|
||||||
char file[128];
|
char file[128];
|
||||||
|
|
||||||
pixel_format = SDL_GetWindowPixelFormat(window);
|
surface = SDL_RenderReadPixels(renderer, NULL);
|
||||||
|
|
||||||
surface = SDL_CreateSurface(width, height, pixel_format);
|
|
||||||
|
|
||||||
SDL_RenderReadPixels(renderer, NULL, pixel_format, surface->pixels, surface->pitch);
|
|
||||||
|
|
||||||
(void)SDL_snprintf(file, sizeof(file), "SDL_window%" SDL_PRIs32 "-%8.8d.bmp",
|
(void)SDL_snprintf(file, sizeof(file), "SDL_window%" SDL_PRIs32 "-%8.8d.bmp",
|
||||||
SDL_GetWindowID(window), ++frame_number);
|
SDL_GetWindowID(window), ++frame_number);
|
||||||
|
|
|
@ -54,11 +54,11 @@ DrawComposite(DrawState *s)
|
||||||
SDL_Rect viewport;
|
SDL_Rect viewport;
|
||||||
SDL_FRect R;
|
SDL_FRect R;
|
||||||
SDL_Texture *target;
|
SDL_Texture *target;
|
||||||
|
SDL_Surface *surface;
|
||||||
|
|
||||||
static SDL_bool blend_tested = SDL_FALSE;
|
static SDL_bool blend_tested = SDL_FALSE;
|
||||||
if (!blend_tested) {
|
if (!blend_tested) {
|
||||||
SDL_Texture *A, *B;
|
SDL_Texture *A, *B;
|
||||||
Uint32 P;
|
|
||||||
|
|
||||||
A = SDL_CreateTexture(s->renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, 1, 1);
|
A = SDL_CreateTexture(s->renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, 1, 1);
|
||||||
SDL_SetTextureBlendMode(A, SDL_BLENDMODE_BLEND);
|
SDL_SetTextureBlendMode(A, SDL_BLENDMODE_BLEND);
|
||||||
|
@ -74,9 +74,15 @@ DrawComposite(DrawState *s)
|
||||||
SDL_SetRenderDrawColor(s->renderer, 0x00, 0x00, 0x00, 0x00);
|
SDL_SetRenderDrawColor(s->renderer, 0x00, 0x00, 0x00, 0x00);
|
||||||
SDL_RenderFillRect(s->renderer, NULL);
|
SDL_RenderFillRect(s->renderer, NULL);
|
||||||
SDL_RenderTexture(s->renderer, A, NULL, NULL);
|
SDL_RenderTexture(s->renderer, A, NULL, NULL);
|
||||||
SDL_RenderReadPixels(s->renderer, NULL, SDL_PIXELFORMAT_ARGB8888, &P, sizeof(P));
|
|
||||||
|
|
||||||
SDL_Log("Blended pixel: 0x%8.8" SDL_PRIX32 "\n", P);
|
surface = SDL_RenderReadPixels(s->renderer, NULL);
|
||||||
|
if (surface) {
|
||||||
|
Uint8 r, g, b, a;
|
||||||
|
if (SDL_ReadSurfacePixel(surface, 0, 0, &r, &g, &b, &a) == 0) {
|
||||||
|
SDL_Log("Blended pixel: 0x%.2x%.2x%.2x%.2x\n", r, g, b, a);
|
||||||
|
}
|
||||||
|
SDL_DestroySurface(surface);
|
||||||
|
}
|
||||||
|
|
||||||
SDL_DestroyTexture(A);
|
SDL_DestroyTexture(A);
|
||||||
SDL_DestroyTexture(B);
|
SDL_DestroyTexture(B);
|
||||||
|
|
Loading…
Reference in New Issue