@@ -1544,24 +1544,21 @@ surf_set_alpha(pgSurfaceObject *self, PyObject *args)
15441544 bool success =
15451545 PG_SetSurfaceRLE (surf , (flags & PGS_RLEACCEL ) ? SDL_TRUE : SDL_FALSE );
15461546 /* HACK HACK HACK */
1547- // TODO SDL3: figure out how to port this or if it's relevant to SDL3.
1548- #if !SDL_VERSION_ATLEAST (3 , 0 , 0 )
1549- if ((surf -> flags & SDL_RLEACCEL ) && (!(flags & PGS_RLEACCEL ))) {
1547+ if (SDL_MUSTLOCK (surf ) && (!(flags & PGS_RLEACCEL ))) {
15501548 /* hack to strip SDL_RLEACCEL flag off surface immediately when
15511549 it is not requested */
15521550 SDL_Rect sdlrect ;
15531551 sdlrect .x = 0 ;
15541552 sdlrect .y = 0 ;
1555- sdlrect .h = 0 ;
1556- sdlrect .w = 0 ;
1553+ sdlrect .h = 1 ;
1554+ sdlrect .w = 1 ;
15571555
15581556 SDL_Surface * surface =
15591557 PG_CreateSurface (1 , 1 , PG_SURF_FORMATENUM (surf ));
15601558
15611559 SDL_LowerBlit (surf , & sdlrect , surface , & sdlrect );
15621560 SDL_FreeSurface (surface );
15631561 }
1564- #endif
15651562 /* HACK HACK HACK */
15661563 if (success ) {
15671564 success = PG_SetSurfaceAlphaMod (surf , alpha );
@@ -1623,7 +1620,7 @@ surf_copy(pgSurfaceObject *self, PyObject *_null)
16231620 SURF_INIT_CHECK (surf )
16241621
16251622 pgSurface_Prep (self );
1626- newsurf = PG_ConvertSurface (surf , surf -> format );
1623+ newsurf = PG_ConvertSurface (surf , surf );
16271624 pgSurface_Unprep (self );
16281625
16291626 final = surf_subtype_new (Py_TYPE (self ), newsurf , 1 );
@@ -1683,7 +1680,7 @@ surf_convert(pgSurfaceObject *self, PyObject *args)
16831680 if (argobject ) {
16841681 if (pgSurface_Check (argobject )) {
16851682 src = pgSurface_AsSurface (argobject );
1686- newsurf = PG_ConvertSurface (surf , src -> format );
1683+ newsurf = PG_ConvertSurface (surf , src );
16871684 }
16881685 else {
16891686 /* will be updated later, initialize to make static analyzer happy
@@ -1837,7 +1834,7 @@ surf_convert(pgSurfaceObject *self, PyObject *args)
18371834 if (argobject ) {
18381835 if (pgSurface_Check (argobject )) {
18391836 src = pgSurface_AsSurface (argobject );
1840- newsurf = PG_ConvertSurface (surf , src -> format );
1837+ newsurf = PG_ConvertSurface (surf , src );
18411838 }
18421839 else {
18431840 /* will be updated later, initialize to make static analyzer happy
@@ -1954,7 +1951,7 @@ surf_convert(pgSurfaceObject *self, PyObject *args)
19541951 SDL_SetPixelFormatPalette (format , palette );
19551952 }
19561953 }
1957- newsurf = PG_ConvertSurface (surf , format );
1954+ newsurf = SDL_ConvertSurface (surf , format , 0 );
19581955 SDL_SetSurfaceBlendMode (newsurf , SDL_BLENDMODE_NONE );
19591956 SDL_FreeFormat (format );
19601957 SDL_FreePalette (palette );
@@ -3010,20 +3007,15 @@ surf_get_flags(PyObject *self, PyObject *_null)
30103007 if (sdl_flags & SDL_PREALLOC ) {
30113008 flags |= PGS_PREALLOC ;
30123009 }
3010+ /* This checks if RLE was requested on the surface */
30133011 if (PG_SurfaceHasRLE (surf )) {
30143012 flags |= PGS_RLEACCELOK ;
30153013 }
3016- // TODO SDL3: figure out how to properly emulate SDL2 check/relevance
3017- // Current implementation is just a placeholder.
3018- #if SDL_VERSION_ATLEAST (3 , 0 , 0 )
3019- if (SDL_SurfaceHasRLE (surf )) {
3020- flags |= PGS_RLEACCEL ;
3021- }
3022- #else
3023- if ((sdl_flags & SDL_RLEACCEL )) {
3014+ /* this checks if the surface actually has RLE.
3015+ * On SDL2: SDL_MUSTLOCK is (flags & SDL_RLEACCEL) */
3016+ if (SDL_MUSTLOCK (surf )) {
30243017 flags |= PGS_RLEACCEL ;
30253018 }
3026- #endif
30273019 if (is_window_surf ) {
30283020 if (window_flags & PG_WINDOW_FULLSCREEN_INCLUSIVE ) {
30293021 flags |= PGS_FULLSCREEN ;
@@ -3761,7 +3753,7 @@ surf_premul_alpha(pgSurfaceObject *self, PyObject *_null)
37613753
37623754 pgSurface_Prep (self );
37633755 // Make a copy of the surface first
3764- newsurf = PG_ConvertSurface (surf , surf -> format );
3756+ newsurf = PG_ConvertSurface (surf , surf );
37653757
37663758 if ((surf -> w > 0 && surf -> h > 0 )) {
37673759 // If the surface has no pixels we don't need to premul
@@ -4455,6 +4447,76 @@ surface_do_overlap(SDL_Surface *src, SDL_Rect *srcrect, SDL_Surface *dst,
44554447 return dstoffset < span || dstoffset > src -> pitch - span ;
44564448}
44574449
4450+ int
4451+ PG_BlitSurface (SDL_Surface * src , const SDL_Rect * srcrect , SDL_Surface * dst ,
4452+ SDL_Rect * dstrect )
4453+ {
4454+ #if SDL_VERSION_ATLEAST (3 , 0 , 0 )
4455+ /* SDL3 doesn't modify dstrect, so compat for that.
4456+ * Below logic taken from SDL2 source with slight modifications */
4457+ SDL_Rect r_src , r_dst ;
4458+
4459+ r_src .x = 0 ;
4460+ r_src .y = 0 ;
4461+ r_src .w = src -> w ;
4462+ r_src .h = src -> h ;
4463+
4464+ if (dstrect ) {
4465+ r_dst .x = dstrect -> x ;
4466+ r_dst .y = dstrect -> y ;
4467+ }
4468+ else {
4469+ r_dst .x = 0 ;
4470+ r_dst .y = 0 ;
4471+ }
4472+
4473+ /* clip the source rectangle to the source surface */
4474+ if (srcrect ) {
4475+ SDL_Rect tmp ;
4476+ if (SDL_IntersectRect (srcrect , & r_src , & tmp ) == SDL_FALSE ) {
4477+ goto end ;
4478+ }
4479+
4480+ /* Shift dstrect, if srcrect origin has changed */
4481+ r_dst .x += tmp .x - srcrect -> x ;
4482+ r_dst .y += tmp .y - srcrect -> y ;
4483+
4484+ /* Update srcrect */
4485+ r_src = tmp ;
4486+ }
4487+
4488+ /* There're no dstrect.w/h parameters. It's the same as srcrect */
4489+ r_dst .w = r_src .w ;
4490+ r_dst .h = r_src .h ;
4491+
4492+ /* clip the destination rectangle against the clip rectangle */
4493+ {
4494+ SDL_Rect tmp , clip_rect ;
4495+ SDL_GetSurfaceClipRect (dst , & clip_rect );
4496+ if (SDL_IntersectRect (& r_dst , & clip_rect , & tmp ) == SDL_FALSE ) {
4497+ goto end ;
4498+ }
4499+
4500+ /* Update dstrect */
4501+ r_dst = tmp ;
4502+ }
4503+
4504+ if (r_dst .w > 0 && r_dst .h > 0 ) {
4505+ if (dstrect ) { /* update output parameter */
4506+ * dstrect = r_dst ;
4507+ }
4508+ return SDL_BlitSurface (src , srcrect , dst , dstrect ) ? 0 : -1 ;
4509+ }
4510+ end :
4511+ if (dstrect ) {
4512+ dstrect -> w = dstrect -> h = 0 ;
4513+ }
4514+ return 0 ;
4515+ #else
4516+ return SDL_BlitSurface (src , srcrect , dst , dstrect );
4517+ #endif
4518+ }
4519+
44584520/*this internal blit function is accessible through the C api*/
44594521int
44604522pgSurface_Blit (pgSurfaceObject * dstobj , pgSurfaceObject * srcobj ,
@@ -4465,13 +4527,11 @@ pgSurface_Blit(pgSurfaceObject *dstobj, pgSurfaceObject *srcobj,
44654527 SDL_Surface * subsurface = NULL ;
44664528 int result , suboffsetx = 0 , suboffsety = 0 ;
44674529 SDL_Rect orig_clip , sub_clip , dstclip ;
4468- #if !SDL_VERSION_ATLEAST (3 , 0 , 0 )
44694530 Uint8 alpha ;
4470- #endif
44714531
44724532 if (!PG_GetSurfaceClipRect (dst , & dstclip )) {
44734533 PyErr_SetString (pgExc_SDLError , SDL_GetError ());
4474- return 0 ;
4534+ return 1 ;
44754535 }
44764536
44774537 /* passthrough blits to the real surface */
@@ -4522,8 +4582,6 @@ pgSurface_Blit(pgSurfaceObject *dstobj, pgSurfaceObject *srcobj,
45224582 result = pygame_Blit (src , srcrect , dst , dstrect , blend_flags );
45234583 /* Py_END_ALLOW_THREADS */
45244584 }
4525- // TODO SDL3: port the below bit of code. Skipping for initial surface port.
4526- #if !SDL_VERSION_ATLEAST (3 , 0 , 0 )
45274585 /* can't blit alpha to 8bit, crashes SDL */
45284586 else if (PG_SURF_BytesPerPixel (dst ) == 1 &&
45294587 (SDL_ISPIXELFORMAT_ALPHA (PG_SURF_FORMATENUM (src )) ||
@@ -4533,59 +4591,53 @@ pgSurface_Blit(pgSurfaceObject *dstobj, pgSurfaceObject *srcobj,
45334591 result = pygame_Blit (src , srcrect , dst , dstrect , 0 );
45344592 }
45354593 else {
4594+ #if SDL_VERSION_ATLEAST (3 , 0 , 0 )
4595+ const SDL_PixelFormatDetails * fmt =
4596+ SDL_GetPixelFormatDetails (src -> format );
4597+ src = fmt ? SDL_ConvertSurface (src ,
4598+ SDL_GetPixelFormatForMasks (
4599+ fmt -> bits_per_pixel , fmt -> Rmask ,
4600+ fmt -> Gmask , fmt -> Bmask , 0 ))
4601+ : NULL ;
4602+ #else
45364603 SDL_PixelFormat * fmt = src -> format ;
45374604 SDL_PixelFormat * newfmt =
45384605 SDL_AllocFormat (SDL_MasksToPixelFormatEnum (
45394606 fmt -> BitsPerPixel , fmt -> Rmask , fmt -> Gmask , fmt -> Bmask , 0 ));
45404607 if (!newfmt ) {
4541- result = -1 ;
4608+ src = NULL ;
45424609 }
45434610 else {
4544- src = PG_ConvertSurface (src , newfmt );
4545-
4611+ src = SDL_ConvertSurface (src , newfmt , 0 );
45464612 SDL_FreeFormat (newfmt );
4547- if (src ) {
4548- #if SDL_VERSION_ATLEAST (3 , 0 , 0 )
4549- result =
4550- SDL_BlitSurface (src , srcrect , dst , dstrect ) ? 0 : -1 ;
4551- #else
4552- result = SDL_BlitSurface (src , srcrect , dst , dstrect );
4613+ }
45534614#endif
4554- SDL_FreeSurface (src );
4555- }
4556- else {
4557- result = -1 ;
4558- }
4615+ if (src ) {
4616+ result = PG_BlitSurface (src , srcrect , dst , dstrect );
4617+ SDL_FreeSurface (src );
4618+ }
4619+ else {
4620+ result = -1 ;
45594621 }
45604622 }
45614623 /* Py_END_ALLOW_THREADS */
45624624 }
4563- #endif
45644625 else if (blend_flags != PYGAME_BLEND_ALPHA_SDL2 &&
45654626 !(pg_EnvShouldBlendAlphaSDL2 ()) && !SDL_HasColorKey (src ) &&
45664627 (PG_SURF_BytesPerPixel (dst ) == 4 ||
45674628 PG_SURF_BytesPerPixel (dst ) == 2 ) &&
45684629 _PgSurface_SrcAlpha (src ) &&
45694630 (SDL_ISPIXELFORMAT_ALPHA (PG_SURF_FORMATENUM (src ))) &&
45704631 !PG_SurfaceHasRLE (src ) && !PG_SurfaceHasRLE (dst ) &&
4571- #if SDL_VERSION_ATLEAST (3 , 0 , 0 )
4572- 1
4573- #else
4574- !(src -> flags & SDL_RLEACCEL ) && !(dst -> flags & SDL_RLEACCEL )
4575- #endif
4576- ) {
4632+ !SDL_MUSTLOCK (src ) && !SDL_MUSTLOCK (dst )) {
45774633 /* If we have a 32bit source surface with per pixel alpha
45784634 and no RLE we'll use pygame_Blit so we can mimic how SDL1
45794635 behaved */
45804636 result = pygame_Blit (src , srcrect , dst , dstrect , blend_flags );
45814637 }
45824638 else {
45834639 /* Py_BEGIN_ALLOW_THREADS */
4584- #if SDL_VERSION_ATLEAST (3 , 0 , 0 )
4585- result = SDL_BlitSurface (src , srcrect , dst , dstrect ) ? 0 : -1 ;
4586- #else
4587- result = SDL_BlitSurface (src , srcrect , dst , dstrect );
4588- #endif
4640+ result = PG_BlitSurface (src , srcrect , dst , dstrect );
45894641 /* Py_END_ALLOW_THREADS */
45904642 }
45914643
0 commit comments