Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pixelarray SDL3 #3309

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions src_c/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -249,8 +249,6 @@ bufferproxy = py.extension_module(
subdir: pg,
)

# TODO: support SDL3
if sdl_api != 3
pixelarray = py.extension_module(
'pixelarray',
'pixelarray.c',
Expand All @@ -259,7 +257,6 @@ pixelarray = py.extension_module(
install: true,
subdir: pg,
)
endif

math = py.extension_module(
'math',
Expand Down
95 changes: 61 additions & 34 deletions src_c/pixelarray.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "pygame.h"

#include "pgcompat.h"
#include <stddef.h>

#include "doc/pixelarray_doc.h"

Expand Down Expand Up @@ -971,6 +972,13 @@ _array_assign_array(pgPixelArrayObject *array, Py_ssize_t low, Py_ssize_t high,
return -1;
}

PG_PixelFormat *surf_format = PG_GetSurfaceFormat(surf);
PG_PixelFormat *val_surf_format = PG_GetSurfaceFormat(val_surf);
if (surf_format == NULL || val_surf_format == NULL) {
PyErr_SetString(pgExc_SDLError, SDL_GetError());
return -1;
}

/* If we reassign the same array, we need to copy the pixels
* first. */
if (SURFACE_EQUALS(array, val)) {
Expand Down Expand Up @@ -1021,20 +1029,23 @@ _array_assign_array(pgPixelArrayObject *array, Py_ssize_t low, Py_ssize_t high,
}
break;
case 3: {
// Note:
// Why is the 24 bit case pixelformat aware but none of the rest are?
// - Starbuck, jan. 2025
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How are the rest of the paths not pixelformat aware? I think they are assuming that source and destination pixelformats are same and therefore directly copying over the data. But I didn't find this check enforced in the code anywhere on a quick search?

#if (SDL_BYTEORDER == SDL_LIL_ENDIAN)
Uint32 Roffset = surf->format->Rshift >> 3;
Uint32 Goffset = surf->format->Gshift >> 3;
Uint32 Boffset = surf->format->Bshift >> 3;
Uint32 vRoffset = val_surf->format->Rshift >> 3;
Uint32 vGoffset = val_surf->format->Gshift >> 3;
Uint32 vBoffset = val_surf->format->Bshift >> 3;
Uint32 Roffset = surf_format->Rshift >> 3;
Uint32 Goffset = surf_format->Gshift >> 3;
Uint32 Boffset = surf_format->Bshift >> 3;
Uint32 vRoffset = val_surf_format->Rshift >> 3;
Uint32 vGoffset = val_surf_format->Gshift >> 3;
Uint32 vBoffset = val_surf_format->Bshift >> 3;
#else
Uint32 Roffset = 2 - (surf->format->Rshift >> 3);
Uint32 Goffset = 2 - (surf->format->Gshift >> 3);
Uint32 Boffset = 2 - (surf->format->Bshift >> 3);
Uint32 vRoffset = 2 - (val_surf->format->Rshift >> 3);
Uint32 vGoffset = 2 - (val_surf->format->Gshift >> 3);
Uint32 vBoffset = 2 - (val_surf->format->Bshift >> 3);
Uint32 Roffset = 2 - (surf_format->Rshift >> 3);
Uint32 Goffset = 2 - (surf_format->Gshift >> 3);
Uint32 Boffset = 2 - (surf_format->Bshift >> 3);
Uint32 vRoffset = 2 - (val_surf_format->Rshift >> 3);
Uint32 vGoffset = 2 - (val_surf_format->Gshift >> 3);
Uint32 vBoffset = 2 - (val_surf_format->Bshift >> 3);
#endif
for (y = 0; y < dim1; ++y) {
pixel_p = pixelrow;
Expand Down Expand Up @@ -1076,7 +1087,6 @@ _array_assign_sequence(pgPixelArrayObject *array, Py_ssize_t low,
Py_ssize_t high, PyObject *val)
{
SDL_Surface *surf = pgSurface_AsSurface(array->surface);
SDL_PixelFormat *format;
Py_ssize_t dim0 = ABS(high - low);
Py_ssize_t dim1 = array->shape[1];
Py_ssize_t stride0 = high >= low ? array->strides[0] : -array->strides[0];
Expand All @@ -1097,8 +1107,13 @@ _array_assign_sequence(pgPixelArrayObject *array, Py_ssize_t low,
return -1;
}

format = surf->format;
bpp = PG_FORMAT_BytesPerPixel(format);
PG_PixelFormat *surf_format = PG_GetSurfaceFormat(surf);
if (surf_format == NULL) {
PyErr_SetString(pgExc_SDLError, SDL_GetError());
return -1;
}

bpp = PG_FORMAT_BytesPerPixel(surf_format);

if (!dim1) {
dim1 = 1;
Expand Down Expand Up @@ -1150,13 +1165,13 @@ _array_assign_sequence(pgPixelArrayObject *array, Py_ssize_t low,
break;
case 3: {
#if (SDL_BYTEORDER == SDL_LIL_ENDIAN)
Uint32 Roffset = surf->format->Rshift >> 3;
Uint32 Goffset = surf->format->Gshift >> 3;
Uint32 Boffset = surf->format->Bshift >> 3;
Uint32 Roffset = surf_format->Rshift >> 3;
Uint32 Goffset = surf_format->Gshift >> 3;
Uint32 Boffset = surf_format->Bshift >> 3;
#else
Uint32 Roffset = 2 - (surf->format->Rshift >> 3);
Uint32 Goffset = 2 - (surf->format->Gshift >> 3);
Uint32 Boffset = 2 - (surf->format->Bshift >> 3);
Uint32 Roffset = 2 - (surf_format->Rshift >> 3);
Uint32 Goffset = 2 - (surf_format->Gshift >> 3);
Uint32 Boffset = 2 - (surf_format->Bshift >> 3);
#endif
for (y = 0; y < dim1; ++y) {
pixel_p = pixelrow;
Expand Down Expand Up @@ -1206,7 +1221,13 @@ _array_assign_slice(pgPixelArrayObject *array, Py_ssize_t low, Py_ssize_t high,
Py_ssize_t x;
Py_ssize_t y;

bpp = PG_SURF_BytesPerPixel(surf);
PG_PixelFormat *surf_format = PG_GetSurfaceFormat(surf);
if (surf_format == NULL) {
PyErr_SetString(pgExc_SDLError, SDL_GetError());
return -1;
}

bpp = PG_FORMAT_BytesPerPixel(surf_format);

if (!dim1) {
dim1 = 1;
Expand Down Expand Up @@ -1241,13 +1262,13 @@ _array_assign_slice(pgPixelArrayObject *array, Py_ssize_t low, Py_ssize_t high,
} break;
case 3: {
#if (SDL_BYTEORDER == SDL_LIL_ENDIAN)
Uint32 Roffset = surf->format->Rshift >> 3;
Uint32 Goffset = surf->format->Gshift >> 3;
Uint32 Boffset = surf->format->Bshift >> 3;
Uint32 Roffset = surf_format->Rshift >> 3;
Uint32 Goffset = surf_format->Gshift >> 3;
Uint32 Boffset = surf_format->Bshift >> 3;
#else
Uint32 Roffset = 2 - (surf->format->Rshift >> 3);
Uint32 Goffset = 2 - (surf->format->Gshift >> 3);
Uint32 Boffset = 2 - (surf->format->Bshift >> 3);
Uint32 Roffset = 2 - (surf_format->Rshift >> 3);
Uint32 Goffset = 2 - (surf_format->Gshift >> 3);
Uint32 Boffset = 2 - (surf_format->Bshift >> 3);
#endif
Uint8 r = (Uint8)(color >> 16);
Uint8 g = (Uint8)(color >> 8);
Expand Down Expand Up @@ -1352,6 +1373,12 @@ _pxarray_ass_item(pgPixelArrayObject *array, Py_ssize_t index, PyObject *value)
dim1 = 1;
}

PG_PixelFormat *surf_format = PG_GetSurfaceFormat(surf);
if (surf_format == NULL) {
PyErr_SetString(pgExc_SDLError, SDL_GetError());
return -1;
}

Py_BEGIN_ALLOW_THREADS;
/* Single value assignment. */
switch (bpp) {
Expand All @@ -1369,13 +1396,13 @@ _pxarray_ass_item(pgPixelArrayObject *array, Py_ssize_t index, PyObject *value)
break;
case 3: {
#if (SDL_BYTEORDER == SDL_LIL_ENDIAN)
Uint32 Roffset = surf->format->Rshift >> 3;
Uint32 Goffset = surf->format->Gshift >> 3;
Uint32 Boffset = surf->format->Bshift >> 3;
Uint32 Roffset = surf_format->Rshift >> 3;
Uint32 Goffset = surf_format->Gshift >> 3;
Uint32 Boffset = surf_format->Bshift >> 3;
#else
Uint32 Roffset = 2 - (surf->format->Rshift >> 3);
Uint32 Goffset = 2 - (surf->format->Gshift >> 3);
Uint32 Boffset = 2 - (surf->format->Bshift >> 3);
Uint32 Roffset = 2 - (surf_format->Rshift >> 3);
Uint32 Goffset = 2 - (surf_format->Gshift >> 3);
Uint32 Boffset = 2 - (surf_format->Bshift >> 3);
#endif
for (y = 0; y < dim1; ++y) {
pixel_p[Roffset] = (Uint8)(color >> 16);
Expand Down
Loading
Loading