Implemented scRGB colorspace and HDR support on macOS
This commit is contained in:
1 parent
451dc41427
commit
ba074acad4
24 files changed
+10547
-8010
No files matched your search
@@ -295,6 +295,7 @@ static int FlushRenderCommands(SDL_Renderer *renderer)
|
||||
renderer->vertex_data_used = 0;
|
||||
renderer->render_command_generation++;
|
||||
renderer->color_queued = SDL_FALSE;
|
||||
renderer->color_scale_queued = SDL_FALSE;
|
||||
renderer->viewport_queued = SDL_FALSE;
|
||||
renderer->cliprect_queued = SDL_FALSE;
|
||||
return retval;
|
||||
@@ -481,6 +482,31 @@ static int QueueCmdSetDrawColor(SDL_Renderer *renderer, SDL_FColor *color)
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int QueueCmdSetColorScale(SDL_Renderer *renderer)
|
||||
{
|
||||
int retval = 0;
|
||||
|
||||
if (!renderer->color_scale_queued ||
|
||||
renderer->color_scale != renderer->last_queued_color_scale) {
|
||||
SDL_RenderCommand *cmd = AllocateRenderCommand(renderer);
|
||||
retval = -1;
|
||||
|
||||
if (cmd) {
|
||||
cmd->command = SDL_RENDERCMD_SETCOLORSCALE;
|
||||
cmd->data.color.first = 0; /* render backend will fill this in. */
|
||||
cmd->data.color.color_scale = renderer->color_scale;
|
||||
retval = renderer->QueueSetColorScale(renderer, cmd);
|
||||
if (retval < 0) {
|
||||
cmd->command = SDL_RENDERCMD_NO_OP;
|
||||
} else {
|
||||
renderer->last_queued_color_scale = renderer->color_scale;
|
||||
renderer->color_scale_queued = SDL_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int QueueCmdClear(SDL_Renderer *renderer)
|
||||
{
|
||||
SDL_RenderCommand *cmd = AllocateRenderCommand(renderer);
|
||||
@@ -514,6 +540,10 @@ static SDL_RenderCommand *PrepQueueCmdDraw(SDL_Renderer *renderer, const SDL_Ren
|
||||
retval = QueueCmdSetDrawColor(renderer, color);
|
||||
}
|
||||
|
||||
if (retval == 0) {
|
||||
retval = QueueCmdSetColorScale(renderer);
|
||||
}
|
||||
|
||||
/* Set the viewport and clip rect directly before draws, so the backends
|
||||
* don't have to worry about that state not being valid at draw time. */
|
||||
if (retval == 0 && !renderer->viewport_queued) {
|
||||
|
||||
@@ -99,6 +99,7 @@ typedef enum
|
||||
SDL_RENDERCMD_SETVIEWPORT,
|
||||
SDL_RENDERCMD_SETCLIPRECT,
|
||||
SDL_RENDERCMD_SETDRAWCOLOR,
|
||||
SDL_RENDERCMD_SETCOLORSCALE,
|
||||
SDL_RENDERCMD_CLEAR,
|
||||
SDL_RENDERCMD_DRAW_POINTS,
|
||||
SDL_RENDERCMD_DRAW_LINES,
|
||||
@@ -166,6 +167,7 @@ struct SDL_Renderer
|
||||
int (*CreateTexture)(SDL_Renderer *renderer, SDL_Texture *texture, SDL_PropertiesID create_props);
|
||||
int (*QueueSetViewport)(SDL_Renderer *renderer, SDL_RenderCommand *cmd);
|
||||
int (*QueueSetDrawColor)(SDL_Renderer *renderer, SDL_RenderCommand *cmd);
|
||||
int (*QueueSetColorScale)(SDL_Renderer *renderer, SDL_RenderCommand *cmd);
|
||||
int (*QueueDrawPoints)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FPoint *points,
|
||||
int count);
|
||||
int (*QueueDrawLines)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FPoint *points,
|
||||
@@ -262,10 +264,12 @@ struct SDL_Renderer
|
||||
SDL_RenderCommand *render_commands_pool;
|
||||
Uint32 render_command_generation;
|
||||
SDL_FColor last_queued_color;
|
||||
float last_queued_color_scale;
|
||||
SDL_Rect last_queued_viewport;
|
||||
SDL_Rect last_queued_cliprect;
|
||||
SDL_bool last_queued_cliprect_enabled;
|
||||
SDL_bool color_queued;
|
||||
SDL_bool color_scale_queued;
|
||||
SDL_bool viewport_queued;
|
||||
SDL_bool cliprect_queued;
|
||||
|
||||
|
||||
@@ -808,7 +808,7 @@ static int D3D_SetRenderTarget(SDL_Renderer *renderer, SDL_Texture *texture)
|
||||
return D3D_SetRenderTargetInternal(renderer, texture);
|
||||
}
|
||||
|
||||
static int D3D_QueueSetViewport(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
|
||||
static int D3D_QueueNoOp(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
|
||||
{
|
||||
return 0; /* nothing to do in this backend. */
|
||||
}
|
||||
@@ -1179,6 +1179,11 @@ static int D3D_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, v
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_RENDERCMD_SETCOLORSCALE:
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_RENDERCMD_SETVIEWPORT:
|
||||
{
|
||||
SDL_Rect *viewport = &data->drawstate.viewport;
|
||||
@@ -1615,8 +1620,9 @@ SDL_Renderer *D3D_CreateRenderer(SDL_Window *window, SDL_PropertiesID create_pro
|
||||
renderer->UnlockTexture = D3D_UnlockTexture;
|
||||
renderer->SetTextureScaleMode = D3D_SetTextureScaleMode;
|
||||
renderer->SetRenderTarget = D3D_SetRenderTarget;
|
||||
renderer->QueueSetViewport = D3D_QueueSetViewport;
|
||||
renderer->QueueSetDrawColor = D3D_QueueSetViewport; /* SetViewport and SetDrawColor are (currently) no-ops. */
|
||||
renderer->QueueSetViewport = D3D_QueueNoOp;
|
||||
renderer->QueueSetDrawColor = D3D_QueueNoOp;
|
||||
renderer->QueueSetColorScale = D3D_QueueNoOp;
|
||||
renderer->QueueDrawPoints = D3D_QueueDrawPoints;
|
||||
renderer->QueueDrawLines = D3D_QueueDrawPoints; /* lines and points queue vertices the same way. */
|
||||
renderer->QueueGeometry = D3D_QueueGeometry;
|
||||
|
||||
@@ -1851,7 +1851,7 @@ static int D3D11_SetRenderTarget(SDL_Renderer *renderer, SDL_Texture *texture)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int D3D11_QueueSetViewport(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
|
||||
static int D3D11_QueueNoOp(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
|
||||
{
|
||||
return 0; /* nothing to do in this backend. */
|
||||
}
|
||||
@@ -1860,6 +1860,7 @@ static int D3D11_QueueDrawPoints(SDL_Renderer *renderer, SDL_RenderCommand *cmd,
|
||||
{
|
||||
VertexPositionColor *verts = (VertexPositionColor *)SDL_AllocateRenderVertices(renderer, count * sizeof(VertexPositionColor), 0, &cmd->data.draw.first);
|
||||
int i;
|
||||
SDL_FColor color = cmd->data.draw.color;
|
||||
SDL_bool convert_color = SDL_RenderingLinearSpace(renderer);
|
||||
|
||||
if (!verts) {
|
||||
@@ -1868,15 +1869,16 @@ static int D3D11_QueueDrawPoints(SDL_Renderer *renderer, SDL_RenderCommand *cmd,
|
||||
|
||||
cmd->data.draw.count = count;
|
||||
|
||||
if (convert_color) {
|
||||
SDL_ConvertToLinear(&color);
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
verts->pos.x = points[i].x + 0.5f;
|
||||
verts->pos.y = points[i].y + 0.5f;
|
||||
verts->tex.x = 0.0f;
|
||||
verts->tex.y = 0.0f;
|
||||
verts->color = cmd->data.draw.color;
|
||||
if (convert_color) {
|
||||
SDL_ConvertToLinear(&verts->color);
|
||||
}
|
||||
verts->color = color;
|
||||
verts++;
|
||||
}
|
||||
|
||||
@@ -2358,6 +2360,11 @@ static int D3D11_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd,
|
||||
break; /* this isn't currently used in this render backend. */
|
||||
}
|
||||
|
||||
case SDL_RENDERCMD_SETCOLORSCALE:
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_RENDERCMD_SETVIEWPORT:
|
||||
{
|
||||
SDL_Rect *viewport = &rendererData->currentViewport;
|
||||
@@ -2661,8 +2668,9 @@ SDL_Renderer *D3D11_CreateRenderer(SDL_Window *window, SDL_PropertiesID create_p
|
||||
renderer->UnlockTexture = D3D11_UnlockTexture;
|
||||
renderer->SetTextureScaleMode = D3D11_SetTextureScaleMode;
|
||||
renderer->SetRenderTarget = D3D11_SetRenderTarget;
|
||||
renderer->QueueSetViewport = D3D11_QueueSetViewport;
|
||||
renderer->QueueSetDrawColor = D3D11_QueueSetViewport; /* SetViewport and SetDrawColor are (currently) no-ops. */
|
||||
renderer->QueueSetViewport = D3D11_QueueNoOp;
|
||||
renderer->QueueSetDrawColor = D3D11_QueueNoOp;
|
||||
renderer->QueueSetColorScale = D3D11_QueueNoOp;
|
||||
renderer->QueueDrawPoints = D3D11_QueueDrawPoints;
|
||||
renderer->QueueDrawLines = D3D11_QueueDrawPoints; /* lines and points queue vertices the same way. */
|
||||
renderer->QueueGeometry = D3D11_QueueGeometry;
|
||||
|
||||
@@ -2288,7 +2288,7 @@ static int D3D12_SetRenderTarget(SDL_Renderer *renderer, SDL_Texture *texture)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int D3D12_QueueSetViewport(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
|
||||
static int D3D12_QueueNoOp(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
|
||||
{
|
||||
return 0; /* nothing to do in this backend. */
|
||||
}
|
||||
@@ -2297,6 +2297,7 @@ static int D3D12_QueueDrawPoints(SDL_Renderer *renderer, SDL_RenderCommand *cmd,
|
||||
{
|
||||
VertexPositionColor *verts = (VertexPositionColor *)SDL_AllocateRenderVertices(renderer, count * sizeof(VertexPositionColor), 0, &cmd->data.draw.first);
|
||||
int i;
|
||||
SDL_FColor color = cmd->data.draw.color;
|
||||
SDL_bool convert_color = SDL_RenderingLinearSpace(renderer);
|
||||
|
||||
if (!verts) {
|
||||
@@ -2305,15 +2306,16 @@ static int D3D12_QueueDrawPoints(SDL_Renderer *renderer, SDL_RenderCommand *cmd,
|
||||
|
||||
cmd->data.draw.count = count;
|
||||
|
||||
if (convert_color) {
|
||||
SDL_ConvertToLinear(&color);
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
verts->pos.x = points[i].x + 0.5f;
|
||||
verts->pos.y = points[i].y + 0.5f;
|
||||
verts->tex.x = 0.0f;
|
||||
verts->tex.y = 0.0f;
|
||||
verts->color = cmd->data.draw.color;
|
||||
if (convert_color) {
|
||||
SDL_ConvertToLinear(&verts->color);
|
||||
}
|
||||
verts->color = color;
|
||||
verts++;
|
||||
}
|
||||
|
||||
@@ -2775,6 +2777,11 @@ static int D3D12_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd,
|
||||
break; /* this isn't currently used in this render backend. */
|
||||
}
|
||||
|
||||
case SDL_RENDERCMD_SETCOLORSCALE:
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_RENDERCMD_SETVIEWPORT:
|
||||
{
|
||||
SDL_Rect *viewport = &rendererData->currentViewport;
|
||||
@@ -3168,8 +3175,9 @@ SDL_Renderer *D3D12_CreateRenderer(SDL_Window *window, SDL_PropertiesID create_p
|
||||
renderer->UnlockTexture = D3D12_UnlockTexture;
|
||||
renderer->SetTextureScaleMode = D3D12_SetTextureScaleMode;
|
||||
renderer->SetRenderTarget = D3D12_SetRenderTarget;
|
||||
renderer->QueueSetViewport = D3D12_QueueSetViewport;
|
||||
renderer->QueueSetDrawColor = D3D12_QueueSetViewport; /* SetViewport and SetDrawColor are (currently) no-ops. */
|
||||
renderer->QueueSetViewport = D3D12_QueueNoOp;
|
||||
renderer->QueueSetDrawColor = D3D12_QueueNoOp;
|
||||
renderer->QueueSetColorScale = D3D12_QueueNoOp;
|
||||
renderer->QueueDrawPoints = D3D12_QueueDrawPoints;
|
||||
renderer->QueueDrawLines = D3D12_QueueDrawPoints; /* lines and points queue vertices the same way. */
|
||||
renderer->QueueGeometry = D3D12_QueueGeometry;
|
||||
|
||||
@@ -556,10 +556,18 @@ static int METAL_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL
|
||||
|
||||
switch (texture->format) {
|
||||
case SDL_PIXELFORMAT_ABGR8888:
|
||||
pixfmt = MTLPixelFormatRGBA8Unorm;
|
||||
if (renderer->output_colorspace == SDL_COLORSPACE_SCRGB) {
|
||||
pixfmt = MTLPixelFormatRGBA8Unorm_sRGB;
|
||||
} else {
|
||||
pixfmt = MTLPixelFormatRGBA8Unorm;
|
||||
}
|
||||
break;
|
||||
case SDL_PIXELFORMAT_ARGB8888:
|
||||
pixfmt = MTLPixelFormatBGRA8Unorm;
|
||||
if (renderer->output_colorspace == SDL_COLORSPACE_SCRGB) {
|
||||
pixfmt = MTLPixelFormatBGRA8Unorm_sRGB;
|
||||
} else {
|
||||
pixfmt = MTLPixelFormatBGRA8Unorm;
|
||||
}
|
||||
break;
|
||||
case SDL_PIXELFORMAT_IYUV:
|
||||
case SDL_PIXELFORMAT_YV12:
|
||||
@@ -567,6 +575,12 @@ static int METAL_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL
|
||||
case SDL_PIXELFORMAT_NV21:
|
||||
pixfmt = MTLPixelFormatR8Unorm;
|
||||
break;
|
||||
case SDL_PIXELFORMAT_RGBA64_FLOAT:
|
||||
pixfmt = MTLPixelFormatRGBA16Float;
|
||||
break;
|
||||
case SDL_PIXELFORMAT_RGBA128_FLOAT:
|
||||
pixfmt = MTLPixelFormatRGBA32Float;
|
||||
break;
|
||||
default:
|
||||
return SDL_SetError("Texture format %s not supported by Metal", SDL_GetPixelFormatName(texture->format));
|
||||
}
|
||||
@@ -1042,15 +1056,29 @@ static int METAL_QueueSetViewport(SDL_Renderer *renderer, SDL_RenderCommand *cmd
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int METAL_QueueSetDrawColor(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
|
||||
static int METAL_QueueNoOp(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
|
||||
{
|
||||
return 0; /* nothing to do in this backend. */
|
||||
}
|
||||
|
||||
static int METAL_QueueSetColorScale(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
|
||||
{
|
||||
const size_t vertlen = (2 * sizeof(float));
|
||||
float *verts = (float *)SDL_AllocateRenderVertices(renderer, vertlen, DEVICE_ALIGN(8), &cmd->data.color.first);
|
||||
if (!verts) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
*verts++ = (float)SDL_RenderingLinearSpace(renderer);
|
||||
*verts++ = cmd->data.color.color_scale;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int METAL_QueueDrawPoints(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FPoint *points, int count)
|
||||
{
|
||||
SDL_FColor color = cmd->data.draw.color;
|
||||
const float color_scale = cmd->data.draw.color_scale;
|
||||
SDL_bool convert_color = SDL_RenderingLinearSpace(renderer);
|
||||
|
||||
const size_t vertlen = (2 * sizeof(float) + 4 * sizeof(float)) * count;
|
||||
float *verts = (float *)SDL_AllocateRenderVertices(renderer, vertlen, DEVICE_ALIGN(8), &cmd->data.draw.first);
|
||||
@@ -1059,9 +1087,9 @@ static int METAL_QueueDrawPoints(SDL_Renderer *renderer, SDL_RenderCommand *cmd,
|
||||
}
|
||||
cmd->data.draw.count = count;
|
||||
|
||||
color.r *= color_scale;
|
||||
color.g *= color_scale;
|
||||
color.b *= color_scale;
|
||||
if (convert_color) {
|
||||
SDL_ConvertToLinear(&color);
|
||||
}
|
||||
|
||||
for (int i = 0; i < count; i++, points++) {
|
||||
*(verts++) = points->x;
|
||||
@@ -1077,7 +1105,7 @@ static int METAL_QueueDrawPoints(SDL_Renderer *renderer, SDL_RenderCommand *cmd,
|
||||
static int METAL_QueueDrawLines(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FPoint *points, int count)
|
||||
{
|
||||
SDL_FColor color = cmd->data.draw.color;
|
||||
const float color_scale = cmd->data.draw.color_scale;
|
||||
SDL_bool convert_color = SDL_RenderingLinearSpace(renderer);
|
||||
size_t vertlen;
|
||||
float *verts;
|
||||
|
||||
@@ -1090,9 +1118,9 @@ static int METAL_QueueDrawLines(SDL_Renderer *renderer, SDL_RenderCommand *cmd,
|
||||
}
|
||||
cmd->data.draw.count = count;
|
||||
|
||||
color.r *= color_scale;
|
||||
color.g *= color_scale;
|
||||
color.b *= color_scale;
|
||||
if (convert_color) {
|
||||
SDL_ConvertToLinear(&color);
|
||||
}
|
||||
|
||||
for (int i = 0; i < count; i++, points++) {
|
||||
*(verts++) = points->x;
|
||||
@@ -1135,7 +1163,7 @@ static int METAL_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, S
|
||||
int num_vertices, const void *indices, int num_indices, int size_indices,
|
||||
float scale_x, float scale_y)
|
||||
{
|
||||
const float color_scale = cmd->data.draw.color_scale;
|
||||
SDL_bool convert_color = SDL_RenderingLinearSpace(renderer);
|
||||
int count = indices ? num_indices : num_vertices;
|
||||
const size_t vertlen = (2 * sizeof(float) + 4 * sizeof(float) + (texture ? 2 : 0) * sizeof(float)) * count;
|
||||
float *verts = (float *)SDL_AllocateRenderVertices(renderer, vertlen, DEVICE_ALIGN(8), &cmd->data.draw.first);
|
||||
@@ -1149,7 +1177,7 @@ static int METAL_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, S
|
||||
for (int i = 0; i < count; i++) {
|
||||
int j;
|
||||
float *xy_;
|
||||
SDL_FColor *col_;
|
||||
SDL_FColor col_;
|
||||
if (size_indices == 4) {
|
||||
j = ((const Uint32 *)indices)[i];
|
||||
} else if (size_indices == 2) {
|
||||
@@ -1165,12 +1193,16 @@ static int METAL_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, S
|
||||
*(verts++) = xy_[0] * scale_x;
|
||||
*(verts++) = xy_[1] * scale_y;
|
||||
|
||||
col_ = (SDL_FColor *)((char *)color + j * color_stride);
|
||||
col_ = *(SDL_FColor *)((char *)color + j * color_stride);
|
||||
|
||||
*(verts++) = col_->r * color_scale;
|
||||
*(verts++) = col_->g * color_scale;
|
||||
*(verts++) = col_->b * color_scale;
|
||||
*(verts++) = col_->a;
|
||||
if (convert_color) {
|
||||
SDL_ConvertToLinear(&col_);
|
||||
}
|
||||
|
||||
*(verts++) = col_.r;
|
||||
*(verts++) = col_.g;
|
||||
*(verts++) = col_.b;
|
||||
*(verts++) = col_.a;
|
||||
|
||||
if (texture) {
|
||||
float *uv_ = (float *)((char *)uv + j * uv_stride);
|
||||
@@ -1196,6 +1228,8 @@ typedef struct
|
||||
size_t projection_offset;
|
||||
SDL_bool color_dirty;
|
||||
size_t color_offset;
|
||||
SDL_bool color_scale_dirty;
|
||||
size_t color_scale_offset;
|
||||
} METAL_DrawStateCache;
|
||||
|
||||
static SDL_bool SetDrawState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, const SDL_MetalFragmentFunction shader,
|
||||
@@ -1256,10 +1290,17 @@ static SDL_bool SetDrawState(SDL_Renderer *renderer, const SDL_RenderCommand *cm
|
||||
statecache->cliprect_dirty = SDL_FALSE;
|
||||
}
|
||||
|
||||
#if 0 /* Not used... */
|
||||
if (statecache->color_dirty) {
|
||||
[data.mtlcmdencoder setFragmentBufferOffset:statecache->color_offset atIndex:0];
|
||||
statecache->color_dirty = SDL_FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (statecache->color_scale_dirty) {
|
||||
[data.mtlcmdencoder setFragmentBufferOffset:statecache->color_scale_offset atIndex:0];
|
||||
statecache->color_dirty = SDL_FALSE;
|
||||
}
|
||||
|
||||
newpipeline = ChoosePipelineState(data, data.activepipelines, shader, blend);
|
||||
if (newpipeline != statecache->pipeline) {
|
||||
@@ -1381,6 +1422,13 @@ static int METAL_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd,
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_RENDERCMD_SETCOLORSCALE:
|
||||
{
|
||||
statecache.color_scale_offset = cmd->data.color.first;
|
||||
statecache.color_scale_dirty = SDL_TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_RENDERCMD_CLEAR:
|
||||
{
|
||||
/* If we're already encoding a command buffer, dump it without committing it. We'd just
|
||||
@@ -1404,15 +1452,19 @@ static int METAL_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd,
|
||||
statecache.viewport_dirty = SDL_TRUE;
|
||||
|
||||
{
|
||||
const float r = cmd->data.color.color.r * cmd->data.color.color_scale;
|
||||
const float g = cmd->data.color.color.g * cmd->data.color.color_scale;
|
||||
const float b = cmd->data.color.color.b * cmd->data.color.color_scale;
|
||||
const float a = cmd->data.color.color.a;
|
||||
MTLClearColor color = MTLClearColorMake(r, g, b, a);
|
||||
SDL_bool convert_color = SDL_RenderingLinearSpace(renderer);
|
||||
SDL_FColor color = cmd->data.color.color;
|
||||
if (convert_color) {
|
||||
SDL_ConvertToLinear(&color);
|
||||
}
|
||||
color.r *= cmd->data.color.color_scale;
|
||||
color.g *= cmd->data.color.color_scale;
|
||||
color.b *= cmd->data.color.color_scale;
|
||||
MTLClearColor mtlcolor = MTLClearColorMake(color.r, color.g, color.b, color.a);
|
||||
|
||||
// get new command encoder, set up with an initial clear operation.
|
||||
// (this might fail, and future draw operations will notice.)
|
||||
METAL_ActivateRenderCommandEncoder(renderer, MTLLoadActionClear, &color, mtlbufvertex);
|
||||
METAL_ActivateRenderCommandEncoder(renderer, MTLLoadActionClear, &mtlcolor, mtlbufvertex);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1502,7 +1554,22 @@ static SDL_Surface *METAL_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rec
|
||||
|
||||
mtlregion = MTLRegionMake2D(rect->x, rect->y, rect->w, rect->h);
|
||||
|
||||
format = (mtltexture.pixelFormat == MTLPixelFormatBGRA8Unorm) ? SDL_PIXELFORMAT_ARGB8888 : SDL_PIXELFORMAT_ABGR8888;
|
||||
switch (mtltexture.pixelFormat) {
|
||||
case MTLPixelFormatBGRA8Unorm:
|
||||
case MTLPixelFormatBGRA8Unorm_sRGB:
|
||||
format = SDL_PIXELFORMAT_ARGB8888;
|
||||
break;
|
||||
case MTLPixelFormatRGBA8Unorm:
|
||||
case MTLPixelFormatRGBA8Unorm_sRGB:
|
||||
format = SDL_PIXELFORMAT_ABGR8888;
|
||||
break;
|
||||
case MTLPixelFormatRGBA16Float:
|
||||
format = SDL_PIXELFORMAT_RGBA64_FLOAT;
|
||||
break;
|
||||
default:
|
||||
SDL_SetError("Unknown framebuffer pixel format");
|
||||
return NULL;
|
||||
}
|
||||
surface = SDL_CreateSurface(rect->w, rect->h, format);
|
||||
if (surface) {
|
||||
[mtltexture getBytes:surface->pixels bytesPerRow:surface->pitch fromRegion:mtlregion mipmapLevel:0];
|
||||
@@ -1672,6 +1739,7 @@ static SDL_Renderer *METAL_CreateRenderer(SDL_Window *window, SDL_PropertiesID c
|
||||
id<MTLBuffer> mtlbufconstantstaging, mtlbufquadindicesstaging, mtlbufconstants, mtlbufquadindices;
|
||||
id<MTLCommandBuffer> cmdbuffer;
|
||||
id<MTLBlitCommandEncoder> blitcmd;
|
||||
SDL_bool scRGB_supported = SDL_FALSE;
|
||||
|
||||
/* Note: matrices are column major. */
|
||||
float identitytransform[16] = {
|
||||
@@ -1726,10 +1794,19 @@ static SDL_Renderer *METAL_CreateRenderer(SDL_Window *window, SDL_PropertiesID c
|
||||
|
||||
SDL_SetupRendererColorspace(renderer, create_props);
|
||||
|
||||
#ifndef SDL_PLATFORM_TVOS
|
||||
if (@available(macos 10.11, iOS 16.0, *)) {
|
||||
scRGB_supported = SDL_TRUE;
|
||||
}
|
||||
#endif
|
||||
if (renderer->output_colorspace != SDL_COLORSPACE_SRGB) {
|
||||
SDL_SetError("Unsupported output colorspace");
|
||||
SDL_free(renderer);
|
||||
return NULL;
|
||||
if (renderer->output_colorspace == SDL_COLORSPACE_SCRGB && scRGB_supported) {
|
||||
/* This colorspace is supported */
|
||||
} else {
|
||||
SDL_SetError("Unsupported output colorspace");
|
||||
SDL_free(renderer);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef SDL_PLATFORM_MACOS
|
||||
@@ -1790,6 +1867,22 @@ static SDL_Renderer *METAL_CreateRenderer(SDL_Window *window, SDL_PropertiesID c
|
||||
layer = (CAMetalLayer *)[(__bridge UIView *)view layer];
|
||||
#endif
|
||||
|
||||
#ifndef SDL_PLATFORM_TVOS
|
||||
if (renderer->output_colorspace == SDL_COLORSPACE_SCRGB) {
|
||||
if (@available(macos 10.11, iOS 16.0, *)) {
|
||||
layer.wantsExtendedDynamicRangeContent = YES;
|
||||
} else {
|
||||
SDL_assert(!"Logic error, scRGB is not actually supported");
|
||||
}
|
||||
layer.pixelFormat = MTLPixelFormatRGBA16Float;
|
||||
|
||||
const CFStringRef name = kCGColorSpaceExtendedLinearSRGB;
|
||||
CGColorSpaceRef colorspace = CGColorSpaceCreateWithName(name);
|
||||
layer.colorspace = colorspace;
|
||||
CGColorSpaceRelease(colorspace);
|
||||
}
|
||||
#endif /* !SDL_PLATFORM_TVOS */
|
||||
|
||||
layer.device = mtldevice;
|
||||
|
||||
/* Necessary for RenderReadPixels. */
|
||||
@@ -1889,7 +1982,8 @@ static SDL_Renderer *METAL_CreateRenderer(SDL_Window *window, SDL_PropertiesID c
|
||||
renderer->SetTextureScaleMode = METAL_SetTextureScaleMode;
|
||||
renderer->SetRenderTarget = METAL_SetRenderTarget;
|
||||
renderer->QueueSetViewport = METAL_QueueSetViewport;
|
||||
renderer->QueueSetDrawColor = METAL_QueueSetDrawColor;
|
||||
renderer->QueueSetDrawColor = METAL_QueueNoOp;
|
||||
renderer->QueueSetColorScale = METAL_QueueSetColorScale;
|
||||
renderer->QueueDrawPoints = METAL_QueueDrawPoints;
|
||||
renderer->QueueDrawLines = METAL_QueueDrawLines;
|
||||
renderer->QueueGeometry = METAL_QueueGeometry;
|
||||
@@ -1964,9 +2058,11 @@ SDL_RenderDriver METAL_RenderDriver = {
|
||||
{
|
||||
"metal",
|
||||
(SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC),
|
||||
6,
|
||||
8,
|
||||
{ SDL_PIXELFORMAT_ARGB8888,
|
||||
SDL_PIXELFORMAT_ABGR8888,
|
||||
SDL_PIXELFORMAT_RGBA64_FLOAT,
|
||||
SDL_PIXELFORMAT_RGBA128_FLOAT,
|
||||
SDL_PIXELFORMAT_YV12,
|
||||
SDL_PIXELFORMAT_IYUV,
|
||||
SDL_PIXELFORMAT_NV12,
|
||||
|
||||
@@ -1,8 +1,88 @@
|
||||
#include <metal_common>
|
||||
#include <metal_texture>
|
||||
#include <metal_matrix>
|
||||
|
||||
using namespace metal;
|
||||
|
||||
float3 scRGBtoNits(float3 v)
|
||||
{
|
||||
return v * 80.0;
|
||||
}
|
||||
|
||||
float3 scRGBfromNits(float3 v)
|
||||
{
|
||||
return v / 80.0;
|
||||
}
|
||||
|
||||
float sRGBtoLinear(float v)
|
||||
{
|
||||
if (v <= 0.04045) {
|
||||
v = (v / 12.92);
|
||||
} else {
|
||||
v = pow(abs(v + 0.055) / 1.055, 2.4);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
float sRGBfromLinear(float v)
|
||||
{
|
||||
if (v <= 0.0031308) {
|
||||
v = (v * 12.92);
|
||||
} else {
|
||||
v = (pow(abs(v), 1.0 / 2.4) * 1.055 - 0.055);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
float4 GetOutputColor(float4 rgba, float color_scale)
|
||||
{
|
||||
float4 output;
|
||||
|
||||
output.rgb = rgba.rgb * color_scale;
|
||||
output.a = rgba.a;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
float4 GetOutputColorFromSRGB(float3 rgb, float scRGB_output, float color_scale)
|
||||
{
|
||||
float4 output;
|
||||
|
||||
if (scRGB_output) {
|
||||
rgb.r = sRGBtoLinear(rgb.r);
|
||||
rgb.g = sRGBtoLinear(rgb.g);
|
||||
rgb.b = sRGBtoLinear(rgb.b);
|
||||
}
|
||||
|
||||
output.rgb = rgb * color_scale;
|
||||
output.a = 1.0;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
float4 GetOutputColorFromSCRGB(float3 rgb, float scRGB_output, float color_scale)
|
||||
{
|
||||
float4 output;
|
||||
|
||||
output.rgb = rgb * color_scale;
|
||||
output.a = 1.0;
|
||||
|
||||
if (!scRGB_output) {
|
||||
output.r = sRGBfromLinear(output.r);
|
||||
output.g = sRGBfromLinear(output.g);
|
||||
output.b = sRGBfromLinear(output.b);
|
||||
output.rgb = clamp(output.rgb, 0.0, 1.0);
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
struct ShaderConstants
|
||||
{
|
||||
float scRGB_output;
|
||||
float color_scale;
|
||||
};
|
||||
|
||||
struct SolidVertexInput
|
||||
{
|
||||
float2 position [[attribute(0)]];
|
||||
@@ -27,9 +107,10 @@ vertex SolidVertexOutput SDL_Solid_vertex(SolidVertexInput in [[stage_in]],
|
||||
return v;
|
||||
}
|
||||
|
||||
fragment float4 SDL_Solid_fragment(SolidVertexInput in [[stage_in]])
|
||||
fragment float4 SDL_Solid_fragment(SolidVertexInput in [[stage_in]],
|
||||
constant ShaderConstants &c [[buffer(0)]])
|
||||
{
|
||||
return in.color;
|
||||
return GetOutputColor(1.0, c.color_scale) * in.color;
|
||||
}
|
||||
|
||||
struct CopyVertexInput
|
||||
@@ -58,10 +139,11 @@ vertex CopyVertexOutput SDL_Copy_vertex(CopyVertexInput in [[stage_in]],
|
||||
}
|
||||
|
||||
fragment float4 SDL_Copy_fragment(CopyVertexOutput vert [[stage_in]],
|
||||
constant ShaderConstants &c [[buffer(0)]],
|
||||
texture2d<float> tex [[texture(0)]],
|
||||
sampler s [[sampler(0)]])
|
||||
{
|
||||
return tex.sample(s, vert.texcoord) * vert.color;
|
||||
return GetOutputColor(tex.sample(s, vert.texcoord), c.color_scale) * vert.color;
|
||||
}
|
||||
|
||||
struct YUVDecode
|
||||
@@ -73,6 +155,7 @@ struct YUVDecode
|
||||
};
|
||||
|
||||
fragment float4 SDL_YUV_fragment(CopyVertexOutput vert [[stage_in]],
|
||||
constant ShaderConstants &c [[buffer(0)]],
|
||||
constant YUVDecode &decode [[buffer(1)]],
|
||||
texture2d<float> texY [[texture(0)]],
|
||||
texture2d_array<float> texUV [[texture(1)]],
|
||||
@@ -83,38 +166,52 @@ fragment float4 SDL_YUV_fragment(CopyVertexOutput vert [[stage_in]],
|
||||
yuv.y = texUV.sample(s, vert.texcoord, 0).r;
|
||||
yuv.z = texUV.sample(s, vert.texcoord, 1).r;
|
||||
|
||||
float3 rgb;
|
||||
yuv += decode.offset;
|
||||
rgb.r = dot(yuv, decode.Rcoeff);
|
||||
rgb.g = dot(yuv, decode.Gcoeff);
|
||||
rgb.b = dot(yuv, decode.Bcoeff);
|
||||
|
||||
return vert.color * float4(dot(yuv, decode.Rcoeff), dot(yuv, decode.Gcoeff), dot(yuv, decode.Bcoeff), 1.0);
|
||||
return GetOutputColorFromSRGB(rgb, c.scRGB_output, c.color_scale) * vert.color;
|
||||
}
|
||||
|
||||
fragment float4 SDL_NV12_fragment(CopyVertexOutput vert [[stage_in]],
|
||||
constant YUVDecode &decode [[buffer(1)]],
|
||||
texture2d<float> texY [[texture(0)]],
|
||||
texture2d<float> texUV [[texture(1)]],
|
||||
sampler s [[sampler(0)]])
|
||||
constant ShaderConstants &c [[buffer(0)]],
|
||||
constant YUVDecode &decode [[buffer(1)]],
|
||||
texture2d<float> texY [[texture(0)]],
|
||||
texture2d<float> texUV [[texture(1)]],
|
||||
sampler s [[sampler(0)]])
|
||||
{
|
||||
float3 yuv;
|
||||
yuv.x = texY.sample(s, vert.texcoord).r;
|
||||
yuv.yz = texUV.sample(s, vert.texcoord).rg;
|
||||
|
||||
float3 rgb;
|
||||
yuv += decode.offset;
|
||||
rgb.r = dot(yuv, decode.Rcoeff);
|
||||
rgb.g = dot(yuv, decode.Gcoeff);
|
||||
rgb.b = dot(yuv, decode.Bcoeff);
|
||||
|
||||
return vert.color * float4(dot(yuv, decode.Rcoeff), dot(yuv, decode.Gcoeff), dot(yuv, decode.Bcoeff), 1.0);
|
||||
return GetOutputColorFromSRGB(rgb, c.scRGB_output, c.color_scale) * vert.color;
|
||||
}
|
||||
|
||||
fragment float4 SDL_NV21_fragment(CopyVertexOutput vert [[stage_in]],
|
||||
constant YUVDecode &decode [[buffer(1)]],
|
||||
texture2d<float> texY [[texture(0)]],
|
||||
texture2d<float> texUV [[texture(1)]],
|
||||
sampler s [[sampler(0)]])
|
||||
constant ShaderConstants &c [[buffer(0)]],
|
||||
constant YUVDecode &decode [[buffer(1)]],
|
||||
texture2d<float> texY [[texture(0)]],
|
||||
texture2d<float> texUV [[texture(1)]],
|
||||
sampler s [[sampler(0)]])
|
||||
{
|
||||
float3 yuv;
|
||||
yuv.x = texY.sample(s, vert.texcoord).r;
|
||||
yuv.yz = texUV.sample(s, vert.texcoord).gr;
|
||||
|
||||
float3 rgb;
|
||||
yuv += decode.offset;
|
||||
rgb.r = dot(yuv, decode.Rcoeff);
|
||||
rgb.g = dot(yuv, decode.Gcoeff);
|
||||
rgb.b = dot(yuv, decode.Bcoeff);
|
||||
|
||||
return vert.color * float4(dot(yuv, decode.Rcoeff), dot(yuv, decode.Gcoeff), dot(yuv, decode.Bcoeff), 1.0);
|
||||
return GetOutputColorFromSRGB(rgb, c.scRGB_output, c.color_scale) * vert.color;
|
||||
}
|
||||
|
||||
+1943
-1531
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
+1779
-1464
File diff suppressed because it is too large.
Load diff
+1943
-1531
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -910,7 +910,7 @@ static int GL_SetRenderTarget(SDL_Renderer *renderer, SDL_Texture *texture)
|
||||
/* !!! FIXME: all these Queue* calls set up the vertex buffer the way the immediate mode
|
||||
!!! FIXME: renderer wants it, but this might want to operate differently if we move to
|
||||
!!! FIXME: VBOs at some point. */
|
||||
static int GL_QueueSetViewport(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
|
||||
static int GL_QueueNoOp(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
|
||||
{
|
||||
return 0; /* nothing to do in this backend. */
|
||||
}
|
||||
@@ -1251,6 +1251,11 @@ static int GL_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, vo
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_RENDERCMD_SETCOLORSCALE:
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_RENDERCMD_SETVIEWPORT:
|
||||
{
|
||||
SDL_Rect *viewport = &data->drawstate.viewport;
|
||||
@@ -1700,8 +1705,9 @@ static SDL_Renderer *GL_CreateRenderer(SDL_Window *window, SDL_PropertiesID crea
|
||||
renderer->UnlockTexture = GL_UnlockTexture;
|
||||
renderer->SetTextureScaleMode = GL_SetTextureScaleMode;
|
||||
renderer->SetRenderTarget = GL_SetRenderTarget;
|
||||
renderer->QueueSetViewport = GL_QueueSetViewport;
|
||||
renderer->QueueSetDrawColor = GL_QueueSetViewport; /* SetViewport and SetDrawColor are (currently) no-ops. */
|
||||
renderer->QueueSetViewport = GL_QueueNoOp;
|
||||
renderer->QueueSetDrawColor = GL_QueueNoOp;
|
||||
renderer->QueueSetColorScale = GL_QueueNoOp;
|
||||
renderer->QueueDrawPoints = GL_QueueDrawPoints;
|
||||
renderer->QueueDrawLines = GL_QueueDrawLines;
|
||||
renderer->QueueGeometry = GL_QueueGeometry;
|
||||
|
||||
@@ -733,7 +733,7 @@ fault:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int GLES2_QueueSetViewport(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
|
||||
static int GLES2_QueueNoOp(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
|
||||
{
|
||||
return 0; /* nothing to do in this backend. */
|
||||
}
|
||||
@@ -1238,6 +1238,11 @@ static int GLES2_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd,
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_RENDERCMD_SETCOLORSCALE:
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_RENDERCMD_SETVIEWPORT:
|
||||
{
|
||||
SDL_Rect *viewport = &data->drawstate.viewport;
|
||||
@@ -2181,8 +2186,9 @@ static SDL_Renderer *GLES2_CreateRenderer(SDL_Window *window, SDL_PropertiesID c
|
||||
renderer->UnlockTexture = GLES2_UnlockTexture;
|
||||
renderer->SetTextureScaleMode = GLES2_SetTextureScaleMode;
|
||||
renderer->SetRenderTarget = GLES2_SetRenderTarget;
|
||||
renderer->QueueSetViewport = GLES2_QueueSetViewport;
|
||||
renderer->QueueSetDrawColor = GLES2_QueueSetViewport; /* SetViewport and SetDrawColor are (currently) no-ops. */
|
||||
renderer->QueueSetViewport = GLES2_QueueNoOp;
|
||||
renderer->QueueSetDrawColor = GLES2_QueueNoOp;
|
||||
renderer->QueueSetColorScale = GLES2_QueueNoOp;
|
||||
renderer->QueueDrawPoints = GLES2_QueueDrawPoints;
|
||||
renderer->QueueDrawLines = GLES2_QueueDrawLines;
|
||||
renderer->QueueGeometry = GLES2_QueueGeometry;
|
||||
|
||||
@@ -228,7 +228,7 @@ static int PS2_QueueSetViewport(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int PS2_QueueSetDrawColor(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
|
||||
static int PS2_QueueNoOp(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
|
||||
{
|
||||
return 0; /* nothing to do in this backend. */
|
||||
}
|
||||
@@ -504,6 +504,10 @@ static int PS2_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, v
|
||||
PS2_RenderSetDrawColor(renderer, cmd);
|
||||
break;
|
||||
}
|
||||
case SDL_RENDERCMD_SETCOLORSCALE:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case SDL_RENDERCMD_CLEAR:
|
||||
{
|
||||
PS2_RenderClear(renderer, cmd);
|
||||
@@ -692,7 +696,8 @@ static SDL_Renderer *PS2_CreateRenderer(SDL_Window *window, SDL_PropertiesID cre
|
||||
renderer->SetTextureScaleMode = PS2_SetTextureScaleMode;
|
||||
renderer->SetRenderTarget = PS2_SetRenderTarget;
|
||||
renderer->QueueSetViewport = PS2_QueueSetViewport;
|
||||
renderer->QueueSetDrawColor = PS2_QueueSetDrawColor;
|
||||
renderer->QueueSetDrawColor = PS2_QueueNoOp;
|
||||
renderer->QueueSetColorScale = PS2_QueueNoOp;
|
||||
renderer->QueueDrawPoints = PS2_QueueDrawPoints;
|
||||
renderer->QueueDrawLines = PS2_QueueDrawPoints;
|
||||
renderer->QueueGeometry = PS2_QueueGeometry;
|
||||
|
||||
@@ -624,7 +624,7 @@ static int PSP_SetRenderTarget(SDL_Renderer *renderer, SDL_Texture *texture)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int PSP_QueueSetViewport(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
|
||||
static int PSP_QueueNoOp(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
|
||||
{
|
||||
return 0; /* nothing to do in this backend. */
|
||||
}
|
||||
@@ -1072,6 +1072,11 @@ static int PSP_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, v
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_RENDERCMD_SETCOLORSCALE:
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_RENDERCMD_SETVIEWPORT:
|
||||
{
|
||||
SDL_Rect *viewport = &cmd->data.viewport.rect;
|
||||
@@ -1320,8 +1325,9 @@ SDL_Renderer *PSP_CreateRenderer(SDL_Window *window, SDL_PropertiesID create_pro
|
||||
renderer->UnlockTexture = PSP_UnlockTexture;
|
||||
renderer->SetTextureScaleMode = PSP_SetTextureScaleMode;
|
||||
renderer->SetRenderTarget = PSP_SetRenderTarget;
|
||||
renderer->QueueSetViewport = PSP_QueueSetViewport;
|
||||
renderer->QueueSetDrawColor = PSP_QueueSetViewport; /* SetViewport and SetDrawColor are (currently) no-ops. */
|
||||
renderer->QueueSetViewport = PSP_QueueNoOp;
|
||||
renderer->QueueSetDrawColor = PSP_QueueNoOp;
|
||||
renderer->QueueSetColorScale = PSP_QueueNoOp;
|
||||
renderer->QueueDrawPoints = PSP_QueueDrawPoints;
|
||||
renderer->QueueDrawLines = PSP_QueueDrawPoints; /* lines and points queue vertices the same way. */
|
||||
renderer->QueueGeometry = PSP_QueueGeometry;
|
||||
|
||||
@@ -188,7 +188,7 @@ static int SW_SetRenderTarget(SDL_Renderer *renderer, SDL_Texture *texture)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int SW_QueueSetViewport(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
|
||||
static int SW_QueueNoOp(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
|
||||
{
|
||||
return 0; /* nothing to do in this backend. */
|
||||
}
|
||||
@@ -706,6 +706,11 @@ static int SW_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, vo
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_RENDERCMD_SETCOLORSCALE:
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_RENDERCMD_SETVIEWPORT:
|
||||
{
|
||||
drawstate.viewport = &cmd->data.viewport.rect;
|
||||
@@ -1149,8 +1154,9 @@ SDL_Renderer *SW_CreateRendererForSurface(SDL_Surface *surface)
|
||||
renderer->UnlockTexture = SW_UnlockTexture;
|
||||
renderer->SetTextureScaleMode = SW_SetTextureScaleMode;
|
||||
renderer->SetRenderTarget = SW_SetRenderTarget;
|
||||
renderer->QueueSetViewport = SW_QueueSetViewport;
|
||||
renderer->QueueSetDrawColor = SW_QueueSetViewport; /* SetViewport and SetDrawColor are (currently) no-ops. */
|
||||
renderer->QueueSetViewport = SW_QueueNoOp;
|
||||
renderer->QueueSetDrawColor = SW_QueueNoOp;
|
||||
renderer->QueueSetColorScale = SW_QueueNoOp;
|
||||
renderer->QueueDrawPoints = SW_QueueDrawPoints;
|
||||
renderer->QueueDrawLines = SW_QueueDrawPoints; /* lines and points queue vertices the same way. */
|
||||
renderer->QueueFillRects = SW_QueueFillRects;
|
||||
|
||||
@@ -75,7 +75,7 @@ static void VITA_GXM_SetTextureScaleMode(SDL_Renderer *renderer, SDL_Texture *te
|
||||
static int VITA_GXM_SetRenderTarget(SDL_Renderer *renderer,
|
||||
SDL_Texture *texture);
|
||||
|
||||
static int VITA_GXM_QueueSetViewport(SDL_Renderer *renderer, SDL_RenderCommand *cmd);
|
||||
static int VITA_GXM_QueueNoOp(SDL_Renderer *renderer, SDL_RenderCommand *cmd);
|
||||
|
||||
static int VITA_GXM_QueueSetDrawColor(SDL_Renderer *renderer, SDL_RenderCommand *cmd);
|
||||
|
||||
@@ -247,8 +247,9 @@ SDL_Renderer *VITA_GXM_CreateRenderer(SDL_Window *window, SDL_PropertiesID creat
|
||||
renderer->UnlockTexture = VITA_GXM_UnlockTexture;
|
||||
renderer->SetTextureScaleMode = VITA_GXM_SetTextureScaleMode;
|
||||
renderer->SetRenderTarget = VITA_GXM_SetRenderTarget;
|
||||
renderer->QueueSetViewport = VITA_GXM_QueueSetViewport;
|
||||
renderer->QueueSetViewport = VITA_GXM_QueueNoOp;
|
||||
renderer->QueueSetDrawColor = VITA_GXM_QueueSetDrawColor;
|
||||
renderer->QueueSetColorScale = VITA_GXM_QueueNoOp;
|
||||
renderer->QueueDrawPoints = VITA_GXM_QueueDrawPoints;
|
||||
renderer->QueueDrawLines = VITA_GXM_QueueDrawLines;
|
||||
renderer->QueueGeometry = VITA_GXM_QueueGeometry;
|
||||
@@ -661,7 +662,7 @@ static void VITA_GXM_SetBlendMode(VITA_GXM_RenderData *data, int blendMode)
|
||||
}
|
||||
}
|
||||
|
||||
static int VITA_GXM_QueueSetViewport(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
|
||||
static int VITA_GXM_QueueNoOp(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -1005,6 +1006,11 @@ static int VITA_GXM_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *c
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_RENDERCMD_SETCOLORSCALE:
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_RENDERCMD_CLEAR:
|
||||
{
|
||||
VITA_GXM_RenderClear(renderer, cmd);
|
||||
|
||||
@@ -156,6 +156,11 @@ static void Cocoa_DispatchEvent(NSEvent *theEvent)
|
||||
selector:@selector(focusSomeWindow:)
|
||||
name:NSApplicationDidBecomeActiveNotification
|
||||
object:nil];
|
||||
|
||||
[center addObserver:self
|
||||
selector:@selector(screenParametersChanged:)
|
||||
name:NSApplicationDidChangeScreenParametersNotification
|
||||
object:nil];
|
||||
}
|
||||
|
||||
[center addObserver:self
|
||||
@@ -178,6 +183,7 @@ static void Cocoa_DispatchEvent(NSEvent *theEvent)
|
||||
|
||||
[center removeObserver:self name:NSWindowWillCloseNotification object:nil];
|
||||
[center removeObserver:self name:NSApplicationDidBecomeActiveNotification object:nil];
|
||||
[center removeObserver:self name:NSApplicationDidChangeScreenParametersNotification object:nil];
|
||||
[center removeObserver:self name:NSCurrentLocaleDidChangeNotification object:nil];
|
||||
[NSApp removeObserver:self forKeyPath:@"effectiveAppearance"];
|
||||
|
||||
@@ -276,6 +282,11 @@ static void Cocoa_DispatchEvent(NSEvent *theEvent)
|
||||
}
|
||||
}
|
||||
|
||||
- (void)screenParametersChanged:(NSNotification *)aNotification
|
||||
{
|
||||
Cocoa_UpdateDisplays(SDL_GetVideoDevice());
|
||||
}
|
||||
|
||||
- (void)localeDidChange:(NSNotification *)notification
|
||||
{
|
||||
SDL_SendLocaleChangedEvent();
|
||||
|
||||
@@ -34,6 +34,7 @@ struct SDL_DisplayModeData
|
||||
};
|
||||
|
||||
extern void Cocoa_InitModes(SDL_VideoDevice *_this);
|
||||
extern void Cocoa_UpdateDisplays(SDL_VideoDevice *_this);
|
||||
extern int Cocoa_GetDisplayBounds(SDL_VideoDevice *_this, SDL_VideoDisplay *display, SDL_Rect *rect);
|
||||
extern int Cocoa_GetDisplayUsableBounds(SDL_VideoDevice *_this, SDL_VideoDisplay *display, SDL_Rect *rect);
|
||||
extern int Cocoa_GetDisplayModes(SDL_VideoDevice *_this, SDL_VideoDisplay *display);
|
||||
|
||||
@@ -83,6 +83,20 @@ static int CG_SetError(const char *prefix, CGDisplayErr result)
|
||||
return SDL_SetError("%s: %s", prefix, error);
|
||||
}
|
||||
|
||||
static NSScreen *GetNSScreenForDisplayID(CGDirectDisplayID displayID)
|
||||
{
|
||||
NSArray *screens = [NSScreen screens];
|
||||
|
||||
/* !!! FIXME: maybe track the NSScreen in SDL_DisplayData? */
|
||||
for (NSScreen *screen in screens) {
|
||||
const CGDirectDisplayID thisDisplay = (CGDirectDisplayID)[[[screen deviceDescription] objectForKey:@"NSScreenNumber"] unsignedIntValue];
|
||||
if (thisDisplay == displayID) {
|
||||
return screen;
|
||||
}
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
static float GetDisplayModeRefreshRate(CGDisplayModeRef vidmode, CVDisplayLinkRef link)
|
||||
{
|
||||
double refreshRate = CGDisplayModeGetRefreshRate(vidmode);
|
||||
@@ -261,13 +275,13 @@ static SDL_bool GetDisplayMode(SDL_VideoDevice *_this, CGDisplayModeRef vidmode,
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
static const char *Cocoa_GetDisplayName(CGDirectDisplayID displayID)
|
||||
static char *Cocoa_GetDisplayName(CGDirectDisplayID displayID)
|
||||
{
|
||||
/* This API is deprecated in 10.9 with no good replacement (as of 10.15). */
|
||||
io_service_t servicePort = CGDisplayIOServicePort(displayID);
|
||||
CFDictionaryRef deviceInfo = IODisplayCreateInfoDictionary(servicePort, kIODisplayOnlyPreferredName);
|
||||
NSDictionary *localizedNames = [(__bridge NSDictionary *)deviceInfo objectForKey:[NSString stringWithUTF8String:kDisplayProductName]];
|
||||
const char *displayName = NULL;
|
||||
char *displayName = NULL;
|
||||
|
||||
if ([localizedNames count] > 0) {
|
||||
displayName = SDL_strdup([[localizedNames objectForKey:[[localizedNames allKeys] objectAtIndex:0]] UTF8String]);
|
||||
@@ -276,6 +290,21 @@ static const char *Cocoa_GetDisplayName(CGDirectDisplayID displayID)
|
||||
return displayName;
|
||||
}
|
||||
|
||||
static void Cocoa_GetHDRProperties(CGDirectDisplayID displayID, SDL_HDRDisplayProperties *HDR)
|
||||
{
|
||||
HDR->enabled = SDL_FALSE;
|
||||
HDR->SDR_whitelevel = 0.0f;
|
||||
|
||||
if (@available(macOS 10.15, *)) {
|
||||
NSScreen *screen = GetNSScreenForDisplayID(displayID);
|
||||
|
||||
if (screen && screen.maximumPotentialExtendedDynamicRangeColorComponentValue > 1.0f) {
|
||||
HDR->enabled = SDL_TRUE;
|
||||
HDR->SDR_whitelevel = 80.0f; /* SDR content is always at scRGB 1.0 */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Cocoa_InitModes(SDL_VideoDevice *_this)
|
||||
{
|
||||
@autoreleasepool {
|
||||
@@ -337,8 +366,8 @@ void Cocoa_InitModes(SDL_VideoDevice *_this)
|
||||
CVDisplayLinkCreateWithCGDisplay(displays[i], &link);
|
||||
|
||||
SDL_zero(display);
|
||||
/* this returns a stddup'ed string */
|
||||
display.name = (char *)Cocoa_GetDisplayName(displays[i]);
|
||||
/* this returns a strdup'ed string */
|
||||
display.name = Cocoa_GetDisplayName(displays[i]);
|
||||
if (!GetDisplayMode(_this, moderef, SDL_TRUE, NULL, link, &mode)) {
|
||||
CVDisplayLinkRelease(link);
|
||||
CGDisplayModeRelease(moderef);
|
||||
@@ -350,6 +379,8 @@ void Cocoa_InitModes(SDL_VideoDevice *_this)
|
||||
CVDisplayLinkRelease(link);
|
||||
CGDisplayModeRelease(moderef);
|
||||
|
||||
Cocoa_GetHDRProperties(displaydata->display, &display.HDR);
|
||||
|
||||
display.desktop_mode = mode;
|
||||
display.driverdata = displaydata;
|
||||
SDL_AddVideoDisplay(&display, SDL_FALSE);
|
||||
@@ -360,6 +391,20 @@ void Cocoa_InitModes(SDL_VideoDevice *_this)
|
||||
}
|
||||
}
|
||||
|
||||
void Cocoa_UpdateDisplays(SDL_VideoDevice *_this)
|
||||
{
|
||||
SDL_HDRDisplayProperties HDR;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < _this->num_displays; ++i) {
|
||||
SDL_VideoDisplay *display = _this->displays[i];
|
||||
SDL_DisplayData *displaydata = (SDL_DisplayData *)display->driverdata;
|
||||
|
||||
Cocoa_GetHDRProperties(displaydata->display, &HDR);
|
||||
SDL_SetDisplayHDRProperties(display, &HDR);
|
||||
}
|
||||
}
|
||||
|
||||
int Cocoa_GetDisplayBounds(SDL_VideoDevice *_this, SDL_VideoDisplay *display, SDL_Rect *rect)
|
||||
{
|
||||
SDL_DisplayData *displaydata = (SDL_DisplayData *)display->driverdata;
|
||||
@@ -376,22 +421,10 @@ int Cocoa_GetDisplayBounds(SDL_VideoDevice *_this, SDL_VideoDisplay *display, SD
|
||||
int Cocoa_GetDisplayUsableBounds(SDL_VideoDevice *_this, SDL_VideoDisplay *display, SDL_Rect *rect)
|
||||
{
|
||||
SDL_DisplayData *displaydata = (SDL_DisplayData *)display->driverdata;
|
||||
const CGDirectDisplayID cgdisplay = displaydata->display;
|
||||
NSArray *screens = [NSScreen screens];
|
||||
NSScreen *screen = nil;
|
||||
NSScreen *screen = GetNSScreenForDisplayID(displaydata->display);
|
||||
|
||||
/* !!! FIXME: maybe track the NSScreen in SDL_DisplayData? */
|
||||
for (NSScreen *i in screens) {
|
||||
const CGDirectDisplayID thisDisplay = (CGDirectDisplayID)[[[i deviceDescription] objectForKey:@"NSScreenNumber"] unsignedIntValue];
|
||||
if (thisDisplay == cgdisplay) {
|
||||
screen = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_assert(screen != nil); /* didn't find it?! */
|
||||
if (screen == nil) {
|
||||
return -1;
|
||||
return SDL_SetError("Couldn't get NSScreen for display");
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
@@ -242,6 +242,15 @@ int UIKit_AddDisplay(UIScreen *uiscreen, SDL_bool send_event)
|
||||
}
|
||||
display.desktop_mode = mode;
|
||||
|
||||
#ifndef SDL_PLATFORM_TVOS
|
||||
if (@available(iOS 16.0, *)) {
|
||||
if (uiscreen.potentialEDRHeadroom > 1.0f) {
|
||||
display.HDR.enabled = SDL_TRUE;
|
||||
display.HDR.SDR_whitelevel = 80.0f; /* SDR content is always at scRGB 1.0 */
|
||||
}
|
||||
}
|
||||
#endif /* !SDL_PLATFORM_TVOS */
|
||||
|
||||
/* Allocate the display data */
|
||||
#ifdef SDL_PLATFORM_VISIONOS
|
||||
SDL_UIKitDisplayData *data = [[SDL_UIKitDisplayData alloc] init];
|
||||
@@ -273,13 +282,13 @@ int UIKit_AddDisplay(SDL_bool send_event){
|
||||
mode.pixel_density = 1;
|
||||
mode.format = SDL_PIXELFORMAT_ABGR8888;
|
||||
mode.refresh_rate = 60;
|
||||
|
||||
|
||||
display.natural_orientation = SDL_ORIENTATION_LANDSCAPE;
|
||||
|
||||
display.desktop_mode = mode;
|
||||
|
||||
|
||||
SDL_UIKitDisplayData *data = [[SDL_UIKitDisplayData alloc] init];
|
||||
|
||||
|
||||
if (!data) {
|
||||
UIKit_FreeDisplayModeData(&display.desktop_mode);
|
||||
return SDL_OutOfMemory();
|
||||
@@ -341,7 +350,7 @@ int UIKit_InitModes(SDL_VideoDevice *_this)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if !defined(SDL_PLATFORM_TVOS) && !defined(SDL_PLATFORM_VISIONOS)
|
||||
SDL_OnApplicationDidChangeStatusBarOrientation();
|
||||
#endif
|
||||
|
||||
@@ -145,6 +145,8 @@ static void CreateRenderer(void)
|
||||
renderer_name = info.name;
|
||||
|
||||
UpdateSDRWhiteLevel();
|
||||
|
||||
SDL_Log("HDR is %s\n", HDR_enabled ? "enabled" : "disabled");
|
||||
}
|
||||
|
||||
static void NextRenderer( void )
|
||||
@@ -745,6 +747,7 @@ static void loop(void)
|
||||
OnMouseHeld(event.button.x, event.button.y);
|
||||
}
|
||||
} else if (event.type == SDL_EVENT_DISPLAY_HDR_STATE_CHANGED) {
|
||||
SDL_Log("HDR %s\n", event.display.data1 ? "enabled" : "disabled");
|
||||
UpdateSDRWhiteLevel();
|
||||
} else if (event.type == SDL_EVENT_QUIT) {
|
||||
done = 1;
|
||||
|
||||
@@ -127,7 +127,9 @@ static void MoveSprites(SDL_Renderer *renderer, SDL_Texture *sprite)
|
||||
/* Test horizontal and vertical lines */
|
||||
SDL_SetRenderDrawColor(renderer, 0x00, 0xFF, 0x00, 0xFF);
|
||||
SDL_RenderLine(renderer, 1.0f, 0.0f, (float)(viewport.w - 2), 0.0f);
|
||||
SDL_SetRenderDrawColor(renderer, 0xFF, 0x00, 0x00, 0xFF);
|
||||
SDL_RenderLine(renderer, 1.0f, (float)(viewport.h - 1), (float)(viewport.w - 2), (float)(viewport.h - 1));
|
||||
SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0xFF, 0xFF);
|
||||
SDL_RenderLine(renderer, 0.0f, 1.0f, 0.0f, (float)(viewport.h - 2));
|
||||
SDL_RenderLine(renderer, (float)(viewport.w - 1), 1.0f, (float)(viewport.w - 1), (float)(viewport.h - 2));
|
||||
|
||||
|
||||
Reference in new issue
Block a user