Skip to content

Commit c10b697

Browse files
authored
Merge pull request #3 from itzpr3d4t0r/blitter-remake
New Blitter
2 parents 462cd76 + 29644a2 commit c10b697

File tree

10 files changed

+1159
-245
lines changed

10 files changed

+1159
-245
lines changed

src/data_block.c

Lines changed: 546 additions & 178 deletions
Large diffs are not rendered by default.

src/effect_instance.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,11 @@ update_effect_instance(EffectInstance *instance, float dt)
4949
int
5050
draw_effect_instance(EffectInstance *instance, pgSurfaceObject *dest)
5151
{
52-
for (Py_ssize_t i = 0; i < instance->blocks_count; i++)
53-
if (!draw_data_block(&instance->p_data[i], dest,
54-
instance->p_data[i].blend_mode))
52+
for (Py_ssize_t i = 0; i < instance->blocks_count; i++) {
53+
DataBlock *block = &instance->p_data[i];
54+
if (!draw_data_block(block, dest, block->blend_mode))
5555
return 0;
56+
}
5657

5758
return 1;
5859
}

src/emitter.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ emitter_init(EmitterObject *self, PyObject *args, PyObject *kwds)
141141
}
142142

143143
switch (emitter->spawn_shape) {
144-
case POINT:
144+
case _POINT:
145145
break;
146146
default:
147147
PyErr_SetString(PyExc_ValueError, "Invalid emitter spawn area shape");
@@ -181,7 +181,13 @@ emitter_init(EmitterObject *self, PyObject *args, PyObject *kwds)
181181
return -1;
182182
}
183183

184-
SDL_Surface *surf = ((pgSurfaceObject *)img)->surf;
184+
pgSurfaceObject *surf_obj = (pgSurfaceObject *)img;
185+
if (!surf_obj->surf) {
186+
PyErr_SetString(PyExc_RuntimeError, "Surface is not initialized");
187+
return -1;
188+
}
189+
190+
SDL_Surface *surf = surf_obj->surf;
185191
Uint8 alpha;
186192

187193
/* Rule out unsupported image formats and flags */
@@ -324,7 +330,7 @@ emitter_str(EmitterObject *self)
324330

325331
char *spawn_shape_str;
326332
switch (e->spawn_shape) {
327-
case POINT:
333+
case _POINT:
328334
spawn_shape_str = "POINT";
329335
break;
330336
default:

src/include/data_block.h

Lines changed: 88 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,39 @@
44
#include "MT19937.h"
55
#include "emitter.h"
66

7+
#define UNROLL_2(x) \
8+
x; \
9+
x;
10+
11+
#define UNROLL_3(x) \
12+
x; \
13+
x; \
14+
x;
15+
16+
#define UNROLL_4(x) \
17+
x; \
18+
x; \
19+
x; \
20+
x;
21+
22+
typedef struct {
23+
int animation_index;
24+
int length;
25+
} Fragment;
26+
27+
typedef struct {
28+
uint32_t *pixels;
29+
int width, rows, src_offset;
30+
} BlitDestination;
31+
32+
typedef struct {
33+
Fragment *fragments;
34+
BlitDestination *destinations;
35+
int used_f;
36+
int alloc_f;
37+
int dest_count;
38+
} FragmentationMap;
39+
740
typedef struct DataBlock {
841
float_array positions_x;
942
float_array positions_y;
@@ -17,6 +50,7 @@ typedef struct DataBlock {
1750

1851
int num_frames;
1952
PyObject *animation;
53+
FragmentationMap frag_map;
2054

2155
int blend_mode;
2256
bool ended;
@@ -25,26 +59,50 @@ typedef struct DataBlock {
2559
void (*updater)(struct DataBlock *, float);
2660
} DataBlock;
2761

28-
void
29-
UDB_no_acceleration(DataBlock *block, float dt);
62+
/* ====================| Public facing DataBlock functions |==================== */
63+
int
64+
init_data_block(DataBlock *block, Emitter *emitter, vec2 position);
3065

3166
void
32-
UDB_acceleration_x(DataBlock *block, float dt);
67+
dealloc_data_block(DataBlock *block);
3368

3469
void
35-
UDB_acceleration_y(DataBlock *block, float dt);
70+
choose_and_set_update_function(DataBlock *block, Emitter *emitter);
3671

3772
void
38-
UDB_all(DataBlock *block, float dt);
73+
update_data_block(DataBlock *block, float dt);
74+
75+
int
76+
draw_data_block(DataBlock *block, pgSurfaceObject *dest, const int blend_flag);
77+
78+
/* ====================| Internal DataBlock functions |==================== */
79+
80+
int
81+
init_fragmentation_map(DataBlock *block);
3982

4083
void
41-
update_indices_scalar(DataBlock *block);
84+
dealloc_fragmentation_map(FragmentationMap *frag_map);
4285

4386
void
44-
update_indices(DataBlock *block);
87+
calculate_surface_index_occurrences(DataBlock *block);
4588

4689
int
47-
init_data_block(DataBlock *block, Emitter *emitter, vec2 position);
90+
populate_destinations_array(pgSurfaceObject *dest, DataBlock *block);
91+
92+
int
93+
calculate_fragmentation_map(pgSurfaceObject *dest, DataBlock *block);
94+
95+
void
96+
blit_fragments_blitcopy(FragmentationMap *frag_map, pgSurfaceObject *dest,
97+
DataBlock *block);
98+
99+
void
100+
blit_fragments_add(FragmentationMap *frag_map, pgSurfaceObject *dest,
101+
DataBlock *block);
102+
103+
void
104+
blit_fragments(pgSurfaceObject *dest, FragmentationMap *frag_map, DataBlock *block,
105+
int blend_flags);
48106

49107
int
50108
alloc_and_init_positions(DataBlock *block, Emitter *emitter, vec2 position);
@@ -62,16 +120,33 @@ int
62120
alloc_and_init_animation_indices(DataBlock *block, Emitter *emitter);
63121

64122
void
65-
update_data_block(DataBlock *block, float dt);
123+
update_with_acceleration(DataBlock *block, float dt);
66124

67125
void
68-
choose_and_set_update_function(DataBlock *block, Emitter *emitter);
126+
update_with_no_acceleration(DataBlock *block, float dt);
69127

70-
int
71-
draw_data_block(DataBlock *block, pgSurfaceObject *dest, const int blend_flag);
128+
void
129+
update_with_acceleration_x(DataBlock *block, float dt);
130+
131+
void
132+
update_with_acceleration_y(DataBlock *block, float dt);
133+
134+
void
135+
update_indices_scalar(DataBlock *block);
136+
137+
void
138+
update_indices(DataBlock *block);
72139

73140
void
74141
recalculate_particle_count(DataBlock *block);
75142

76143
void
77-
dealloc_data_block(DataBlock *block);
144+
blit_fragments_add_scalar(FragmentationMap *frag_map, PyObject **animation,
145+
int dst_skip);
146+
147+
int FORCEINLINE
148+
RectEmpty(const SDL_Rect *r);
149+
150+
int FORCEINLINE
151+
IntersectRect(int Amin_x, int Amax_x, const int Bmin_x, const int Bmax_x, int Amin_y,
152+
int Amax_y, const int Bmin_y, const int Bmax_y, SDL_Rect *result);

src/include/emitter.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,7 @@
55
#include "base.h"
66

77
typedef enum {
8-
POINT,
9-
CIRCLE,
10-
RECTANGLE,
8+
_POINT,
119
} EmitterSpawnShape;
1210

1311
typedef struct {

src/include/pygame.h

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -58,22 +58,8 @@ typedef struct {
5858
#define pgSurface_Type (*(PyTypeObject *)PYGAMEAPI_GET_SLOT(surface, 0))
5959

6060
#define pgSurface_Check(x) (PyObject_IsInstance((x), (PyObject *)&pgSurface_Type))
61-
#define pgSurface_New2 \
62-
(*(pgSurfaceObject * (*)(SDL_Surface *, int)) PYGAMEAPI_GET_SLOT(surface, 1))
63-
64-
#define pgSurface_SetSurface \
65-
(*(int (*)(pgSurfaceObject *, SDL_Surface *, int))PYGAMEAPI_GET_SLOT(surface, 3))
66-
67-
#define pgSurface_Blit \
68-
(*(int (*)(pgSurfaceObject *, pgSurfaceObject *, SDL_Rect *, SDL_Rect *, \
69-
int))PYGAMEAPI_GET_SLOT(surface, 2))
70-
7161
#define import_pygame_surface() _LOAD_SLOTS_FROM_PYGAME(surface)
7262

73-
#define pgSurface_New(surface) pgSurface_New2((surface), 1)
74-
#define pgSurface_NewNoOwn(surface) pgSurface_New2((surface), 0)
75-
#define pgSurface_AsSurface(x) (((pgSurfaceObject *)(x))->surf)
76-
7763
#define SURF_INIT_CHECK(surf) \
7864
if (!surf) { \
7965
PyErr_SetString(PyExc_RuntimeError, "Surface is not initialized"); \

src/include/simd_common.h

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,33 +24,41 @@ _HasSSE_NEON();
2424
/* =============| AVX2 |============= */
2525

2626
void
27-
UDB_all_avx2(DataBlock *block, float dt);
27+
update_with_acceleration_avx2(DataBlock *block, float dt);
2828

2929
void
30-
UDB_no_acceleration_avx2(DataBlock *block, float dt);
30+
update_with_no_acceleration_avx2(DataBlock *block, float dt);
3131

3232
void
33-
UDB_acceleration_x_avx2(DataBlock *block, float dt);
33+
update_with_acceleration_x_avx2(DataBlock *block, float dt);
3434

3535
void
36-
UDB_acceleration_y_avx2(DataBlock *block, float dt);
36+
update_with_acceleration_y_avx2(DataBlock *block, float dt);
3737

3838
void
3939
update_indices_avx2(DataBlock *block);
4040

41+
void
42+
blit_fragments_add_avx2(FragmentationMap *frag_map, PyObject **animation,
43+
int dst_skip);
44+
4145
/* =============| SSE2 |============= */
4246

4347
void
44-
UDB_all_sse2(DataBlock *block, float dt);
48+
update_with_acceleration_sse2(DataBlock *block, float dt);
4549

4650
void
47-
UDB_no_acceleration_sse2(DataBlock *block, float dt);
51+
update_with_no_acceleration_sse2(DataBlock *block, float dt);
4852

4953
void
50-
UDB_acceleration_x_sse2(DataBlock *block, float dt);
54+
update_with_acceleration_x_sse2(DataBlock *block, float dt);
5155

5256
void
53-
UDB_acceleration_y_sse2(DataBlock *block, float dt);
57+
update_with_acceleration_y_sse2(DataBlock *block, float dt);
5458

5559
void
5660
update_indices_sse2(DataBlock *block);
61+
62+
void
63+
blit_fragments_add_sse2(FragmentationMap *frag_map, PyObject **animation,
64+
int dst_skip);

src/module.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ PyInit_itz_particle_manager(void)
8989
Py_INCREF(&ParticleEffect_Type);
9090
PyModule_AddObject(module, "ParticleEffect", (PyObject *)&ParticleEffect_Type);
9191

92-
if (PyModule_AddIntConstant(module, "EMIT_POINT", POINT) == -1)
92+
if (PyModule_AddIntConstant(module, "EMIT_POINT", _POINT) == -1)
9393
return NULL;
9494

9595
init_genrand((uint32_t)time(NULL));

0 commit comments

Comments
 (0)