@@ -1544,24 +1544,21 @@ surf_set_alpha(pgSurfaceObject *self, PyObject *args)
1544
1544
bool success =
1545
1545
PG_SetSurfaceRLE (surf , (flags & PGS_RLEACCEL ) ? SDL_TRUE : SDL_FALSE );
1546
1546
/* 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 ))) {
1550
1548
/* hack to strip SDL_RLEACCEL flag off surface immediately when
1551
1549
it is not requested */
1552
1550
SDL_Rect sdlrect ;
1553
1551
sdlrect .x = 0 ;
1554
1552
sdlrect .y = 0 ;
1555
- sdlrect .h = 0 ;
1556
- sdlrect .w = 0 ;
1553
+ sdlrect .h = 1 ;
1554
+ sdlrect .w = 1 ;
1557
1555
1558
1556
SDL_Surface * surface =
1559
1557
PG_CreateSurface (1 , 1 , PG_SURF_FORMATENUM (surf ));
1560
1558
1561
1559
SDL_LowerBlit (surf , & sdlrect , surface , & sdlrect );
1562
1560
SDL_FreeSurface (surface );
1563
1561
}
1564
- #endif
1565
1562
/* HACK HACK HACK */
1566
1563
if (success ) {
1567
1564
success = PG_SetSurfaceAlphaMod (surf , alpha );
@@ -1623,7 +1620,7 @@ surf_copy(pgSurfaceObject *self, PyObject *_null)
1623
1620
SURF_INIT_CHECK (surf )
1624
1621
1625
1622
pgSurface_Prep (self );
1626
- newsurf = PG_ConvertSurface (surf , surf -> format );
1623
+ newsurf = PG_ConvertSurface (surf , surf );
1627
1624
pgSurface_Unprep (self );
1628
1625
1629
1626
final = surf_subtype_new (Py_TYPE (self ), newsurf , 1 );
@@ -1683,7 +1680,7 @@ surf_convert(pgSurfaceObject *self, PyObject *args)
1683
1680
if (argobject ) {
1684
1681
if (pgSurface_Check (argobject )) {
1685
1682
src = pgSurface_AsSurface (argobject );
1686
- newsurf = PG_ConvertSurface (surf , src -> format );
1683
+ newsurf = PG_ConvertSurface (surf , src );
1687
1684
}
1688
1685
else {
1689
1686
/* will be updated later, initialize to make static analyzer happy
@@ -1837,7 +1834,7 @@ surf_convert(pgSurfaceObject *self, PyObject *args)
1837
1834
if (argobject ) {
1838
1835
if (pgSurface_Check (argobject )) {
1839
1836
src = pgSurface_AsSurface (argobject );
1840
- newsurf = PG_ConvertSurface (surf , src -> format );
1837
+ newsurf = PG_ConvertSurface (surf , src );
1841
1838
}
1842
1839
else {
1843
1840
/* will be updated later, initialize to make static analyzer happy
@@ -1961,7 +1958,7 @@ surf_convert(pgSurfaceObject *self, PyObject *args)
1961
1958
SDL_SetPixelFormatPalette (& format , palette );
1962
1959
}
1963
1960
}
1964
- newsurf = PG_ConvertSurface (surf , & format );
1961
+ newsurf = SDL_ConvertSurface (surf , & format , 0 );
1965
1962
SDL_SetSurfaceBlendMode (newsurf , SDL_BLENDMODE_NONE );
1966
1963
SDL_FreePalette (palette );
1967
1964
}
@@ -3016,20 +3013,15 @@ surf_get_flags(PyObject *self, PyObject *_null)
3016
3013
if (sdl_flags & SDL_PREALLOC ) {
3017
3014
flags |= PGS_PREALLOC ;
3018
3015
}
3016
+ /* This checks if RLE was requested on the surface */
3019
3017
if (PG_SurfaceHasRLE (surf )) {
3020
3018
flags |= PGS_RLEACCELOK ;
3021
3019
}
3022
- // TODO SDL3: figure out how to properly emulate SDL2 check/relevance
3023
- // Current implementation is just a placeholder.
3024
- #if SDL_VERSION_ATLEAST (3 , 0 , 0 )
3025
- if (SDL_SurfaceHasRLE (surf )) {
3026
- flags |= PGS_RLEACCEL ;
3027
- }
3028
- #else
3029
- if ((sdl_flags & SDL_RLEACCEL )) {
3020
+ /* this checks if the surface actually has RLE.
3021
+ * On SDL2: SDL_MUSTLOCK is (flags & SDL_RLEACCEL) */
3022
+ if (SDL_MUSTLOCK (surf )) {
3030
3023
flags |= PGS_RLEACCEL ;
3031
3024
}
3032
- #endif
3033
3025
if (is_window_surf ) {
3034
3026
if (window_flags & PG_WINDOW_FULLSCREEN_INCLUSIVE ) {
3035
3027
flags |= PGS_FULLSCREEN ;
@@ -3767,7 +3759,7 @@ surf_premul_alpha(pgSurfaceObject *self, PyObject *_null)
3767
3759
3768
3760
pgSurface_Prep (self );
3769
3761
// Make a copy of the surface first
3770
- newsurf = PG_ConvertSurface (surf , surf -> format );
3762
+ newsurf = PG_ConvertSurface (surf , surf );
3771
3763
3772
3764
if ((surf -> w > 0 && surf -> h > 0 )) {
3773
3765
// If the surface has no pixels we don't need to premul
@@ -4461,6 +4453,76 @@ surface_do_overlap(SDL_Surface *src, SDL_Rect *srcrect, SDL_Surface *dst,
4461
4453
return dstoffset < span || dstoffset > src -> pitch - span ;
4462
4454
}
4463
4455
4456
+ int
4457
+ PG_BlitSurface (SDL_Surface * src , const SDL_Rect * srcrect , SDL_Surface * dst ,
4458
+ SDL_Rect * dstrect )
4459
+ {
4460
+ #if SDL_VERSION_ATLEAST (3 , 0 , 0 )
4461
+ /* SDL3 doesn't modify dstrect, so compat for that.
4462
+ * Below logic taken from SDL2 source with slight modifications */
4463
+ SDL_Rect r_src , r_dst ;
4464
+
4465
+ r_src .x = 0 ;
4466
+ r_src .y = 0 ;
4467
+ r_src .w = src -> w ;
4468
+ r_src .h = src -> h ;
4469
+
4470
+ if (dstrect ) {
4471
+ r_dst .x = dstrect -> x ;
4472
+ r_dst .y = dstrect -> y ;
4473
+ }
4474
+ else {
4475
+ r_dst .x = 0 ;
4476
+ r_dst .y = 0 ;
4477
+ }
4478
+
4479
+ /* clip the source rectangle to the source surface */
4480
+ if (srcrect ) {
4481
+ SDL_Rect tmp ;
4482
+ if (SDL_IntersectRect (srcrect , & r_src , & tmp ) == SDL_FALSE ) {
4483
+ goto end ;
4484
+ }
4485
+
4486
+ /* Shift dstrect, if srcrect origin has changed */
4487
+ r_dst .x += tmp .x - srcrect -> x ;
4488
+ r_dst .y += tmp .y - srcrect -> y ;
4489
+
4490
+ /* Update srcrect */
4491
+ r_src = tmp ;
4492
+ }
4493
+
4494
+ /* There're no dstrect.w/h parameters. It's the same as srcrect */
4495
+ r_dst .w = r_src .w ;
4496
+ r_dst .h = r_src .h ;
4497
+
4498
+ /* clip the destination rectangle against the clip rectangle */
4499
+ {
4500
+ SDL_Rect tmp , clip_rect ;
4501
+ SDL_GetSurfaceClipRect (dst , & clip_rect );
4502
+ if (SDL_IntersectRect (& r_dst , & clip_rect , & tmp ) == SDL_FALSE ) {
4503
+ goto end ;
4504
+ }
4505
+
4506
+ /* Update dstrect */
4507
+ r_dst = tmp ;
4508
+ }
4509
+
4510
+ if (r_dst .w > 0 && r_dst .h > 0 ) {
4511
+ if (dstrect ) { /* update output parameter */
4512
+ * dstrect = r_dst ;
4513
+ }
4514
+ return SDL_BlitSurface (src , srcrect , dst , dstrect ) ? 0 : -1 ;
4515
+ }
4516
+ end :
4517
+ if (dstrect ) {
4518
+ dstrect -> w = dstrect -> h = 0 ;
4519
+ }
4520
+ return 0 ;
4521
+ #else
4522
+ return SDL_BlitSurface (src , srcrect , dst , dstrect );
4523
+ #endif
4524
+ }
4525
+
4464
4526
/*this internal blit function is accessible through the C api*/
4465
4527
int
4466
4528
pgSurface_Blit (pgSurfaceObject * dstobj , pgSurfaceObject * srcobj ,
@@ -4471,13 +4533,11 @@ pgSurface_Blit(pgSurfaceObject *dstobj, pgSurfaceObject *srcobj,
4471
4533
SDL_Surface * subsurface = NULL ;
4472
4534
int result , suboffsetx = 0 , suboffsety = 0 ;
4473
4535
SDL_Rect orig_clip , sub_clip , dstclip ;
4474
- #if !SDL_VERSION_ATLEAST (3 , 0 , 0 )
4475
4536
Uint8 alpha ;
4476
- #endif
4477
4537
4478
4538
if (!PG_GetSurfaceClipRect (dst , & dstclip )) {
4479
4539
PyErr_SetString (pgExc_SDLError , SDL_GetError ());
4480
- return 0 ;
4540
+ return 1 ;
4481
4541
}
4482
4542
4483
4543
/* passthrough blits to the real surface */
@@ -4528,8 +4588,6 @@ pgSurface_Blit(pgSurfaceObject *dstobj, pgSurfaceObject *srcobj,
4528
4588
result = pygame_Blit (src , srcrect , dst , dstrect , blend_flags );
4529
4589
/* Py_END_ALLOW_THREADS */
4530
4590
}
4531
- // TODO SDL3: port the below bit of code. Skipping for initial surface port.
4532
- #if !SDL_VERSION_ATLEAST (3 , 0 , 0 )
4533
4591
/* can't blit alpha to 8bit, crashes SDL */
4534
4592
else if (PG_SURF_BytesPerPixel (dst ) == 1 &&
4535
4593
(SDL_ISPIXELFORMAT_ALPHA (PG_SURF_FORMATENUM (src )) ||
@@ -4539,17 +4597,22 @@ pgSurface_Blit(pgSurfaceObject *dstobj, pgSurfaceObject *srcobj,
4539
4597
result = pygame_Blit (src , srcrect , dst , dstrect , 0 );
4540
4598
}
4541
4599
else {
4600
+ #if SDL_VERSION_ATLEAST (3 , 0 , 0 )
4601
+ const SDL_PixelFormatDetails * fmt =
4602
+ SDL_GetPixelFormatDetails (src -> format );
4603
+ src = fmt ? SDL_ConvertSurface (src ,
4604
+ SDL_GetPixelFormatForMasks (
4605
+ fmt -> bits_per_pixel , fmt -> Rmask ,
4606
+ fmt -> Gmask , fmt -> Bmask , 0 ))
4607
+ : NULL ;
4608
+
4609
+ #else
4542
4610
SDL_PixelFormat * fmt = src -> format ;
4543
4611
SDL_PixelFormat newfmt ;
4544
4612
4545
4613
newfmt .palette = 0 ; /* Set NULL (or SDL gets confused) */
4546
- #if SDL_VERSION_ATLEAST (3 , 0 , 0 )
4547
- newfmt .bits_per_pixel = fmt -> bits_per_pixel ;
4548
- newfmt .bytes_per_pixel = fmt -> bytes_per_pixel ;
4549
- #else
4550
4614
newfmt .BitsPerPixel = fmt -> BitsPerPixel ;
4551
4615
newfmt .BytesPerPixel = fmt -> BytesPerPixel ;
4552
- #endif
4553
4616
newfmt .Amask = 0 ;
4554
4617
newfmt .Rmask = fmt -> Rmask ;
4555
4618
newfmt .Gmask = fmt -> Gmask ;
@@ -4562,13 +4625,10 @@ pgSurface_Blit(pgSurfaceObject *dstobj, pgSurfaceObject *srcobj,
4562
4625
newfmt .Rloss = fmt -> Rloss ;
4563
4626
newfmt .Gloss = fmt -> Gloss ;
4564
4627
newfmt .Bloss = fmt -> Bloss ;
4565
- src = PG_ConvertSurface (src , & newfmt );
4566
- if (src ) {
4567
- #if SDL_VERSION_ATLEAST (3 , 0 , 0 )
4568
- result = SDL_BlitSurface (src , srcrect , dst , dstrect ) ? 0 : -1 ;
4569
- #else
4570
- result = SDL_BlitSurface (src , srcrect , dst , dstrect );
4628
+ src = SDL_ConvertSurface (src , & newfmt , 0 );
4571
4629
#endif
4630
+ if (src ) {
4631
+ result = PG_BlitSurface (src , srcrect , dst , dstrect );
4572
4632
SDL_FreeSurface (src );
4573
4633
}
4574
4634
else {
@@ -4577,32 +4637,22 @@ pgSurface_Blit(pgSurfaceObject *dstobj, pgSurfaceObject *srcobj,
4577
4637
}
4578
4638
/* Py_END_ALLOW_THREADS */
4579
4639
}
4580
- #endif
4581
4640
else if (blend_flags != PYGAME_BLEND_ALPHA_SDL2 &&
4582
4641
!(pg_EnvShouldBlendAlphaSDL2 ()) && !SDL_HasColorKey (src ) &&
4583
4642
(PG_SURF_BytesPerPixel (dst ) == 4 ||
4584
4643
PG_SURF_BytesPerPixel (dst ) == 2 ) &&
4585
4644
_PgSurface_SrcAlpha (src ) &&
4586
4645
(SDL_ISPIXELFORMAT_ALPHA (PG_SURF_FORMATENUM (src ))) &&
4587
4646
!PG_SurfaceHasRLE (src ) && !PG_SurfaceHasRLE (dst ) &&
4588
- #if SDL_VERSION_ATLEAST (3 , 0 , 0 )
4589
- 1
4590
- #else
4591
- !(src -> flags & SDL_RLEACCEL ) && !(dst -> flags & SDL_RLEACCEL )
4592
- #endif
4593
- ) {
4647
+ !SDL_MUSTLOCK (src ) && !SDL_MUSTLOCK (dst )) {
4594
4648
/* If we have a 32bit source surface with per pixel alpha
4595
4649
and no RLE we'll use pygame_Blit so we can mimic how SDL1
4596
4650
behaved */
4597
4651
result = pygame_Blit (src , srcrect , dst , dstrect , blend_flags );
4598
4652
}
4599
4653
else {
4600
4654
/* Py_BEGIN_ALLOW_THREADS */
4601
- #if SDL_VERSION_ATLEAST (3 , 0 , 0 )
4602
- result = SDL_BlitSurface (src , srcrect , dst , dstrect ) ? 0 : -1 ;
4603
- #else
4604
- result = SDL_BlitSurface (src , srcrect , dst , dstrect );
4605
- #endif
4655
+ result = PG_BlitSurface (src , srcrect , dst , dstrect );
4606
4656
/* Py_END_ALLOW_THREADS */
4607
4657
}
4608
4658
0 commit comments