40
40
#define PP_COORD_TYPE float
41
41
#endif
42
42
43
+ #ifndef PP_TILE_BUFFER_SIZE
44
+ #define PP_TILE_BUFFER_SIZE 64
45
+ #endif
46
+
43
47
#ifndef PP_SCALE_TO_ALPHA
44
48
#define PP_SCALE_TO_ALPHA 1
45
49
#endif
@@ -118,8 +122,6 @@ void pp_poly_merge(pp_poly_t *p, pp_poly_t *m);
118
122
// user settings
119
123
typedef void (* pp_tile_callback_t )(const pp_tile_t * tile );
120
124
121
- extern uint32_t _pp_tile_buffer_size ;
122
-
123
125
extern pp_rect_t _pp_clip ;
124
126
extern pp_tile_callback_t _pp_tile_callback ;
125
127
extern pp_antialias_t _pp_antialias ;
@@ -131,7 +133,7 @@ void pp_antialias(pp_antialias_t antialias);
131
133
pp_mat3_t * pp_transform (pp_mat3_t * transform );
132
134
void pp_render (pp_poly_t * polygon );
133
135
134
- void pp_init (uint32_t tile_buffer_size , uint32_t max_nodes_per_scanline );
136
+ void pp_init (uint32_t max_nodes_per_scanline );
135
137
void pp_deinit ();
136
138
137
139
@@ -254,7 +256,7 @@ pp_rect_t pp_rect_transform(pp_rect_t *r, pp_mat3_t *m) {
254
256
255
257
// pp_tile_t implementation
256
258
uint8_t pp_tile_get (const pp_tile_t * tile , const int32_t x , const int32_t y ) {
257
- return tile -> data [(x - tile -> x ) + (y - tile -> y ) * _pp_tile_buffer_size ];
259
+ return tile -> data [(x - tile -> x ) + (y - tile -> y ) * PP_TILE_BUFFER_SIZE ];
258
260
}
259
261
260
262
pp_poly_t * pp_poly_new () {
@@ -377,36 +379,29 @@ pp_rect_t pp_poly_bounds(pp_poly_t *p) {
377
379
return b ;
378
380
}
379
381
380
- uint32_t _pp_tile_buffer_size = 0 ;
381
382
uint32_t _pp_max_nodes_per_scanline = 0 ;
382
383
383
384
// buffer that each tile is rendered into before callback
384
- // allocate one extra byte to allow a small optimization in the row renderer
385
- uint8_t * pp_tile_buffer ;
386
- // uint8_t pp_tile_buffer[PP_TILE_BUFFER_SIZE * PP_TILE_BUFFER_SIZE];
385
+ // This allocates 4k up-front to ensure it's stored in Pico's RAM
386
+ // Rather than potentially allocating into PSRAM at runtime and trashing perf
387
+ uint8_t pp_tile_buffer [PP_TILE_BUFFER_SIZE * PP_TILE_BUFFER_SIZE ];
387
388
388
389
// polygon node buffer handles at most 16 line intersections per scanline
389
390
// is this enough for cjk/emoji? (requires a 2kB buffer)
390
391
int32_t * pp_nodes ;
391
392
uint32_t * pp_node_counts ;
392
- //int32_t pp_nodes[PP_TILE_BUFFER_SIZE * 4][PP_MAX_NODES_PER_SCANLINE * 2];
393
- //uint32_t pp_node_counts[PP_TILE_BUFFER_SIZE * 4];
394
393
395
394
uint8_t _pp_alpha_map_none [2 ] = {0 , 255 };
396
395
uint8_t _pp_alpha_map_x4 [5 ] = {0 , 63 , 127 , 190 , 255 };
397
396
uint8_t _pp_alpha_map_x16 [17 ] = {0 , 16 , 32 , 48 , 64 , 80 , 96 , 112 , 128 , 144 , 160 , 176 , 192 , 208 , 224 , 240 , 255 };
398
397
399
- void pp_init (uint32_t tile_buffer_size , uint32_t max_nodes_per_scanline ) {
400
- _pp_tile_buffer_size = tile_buffer_size ;
398
+ void pp_init (uint32_t max_nodes_per_scanline ) {
401
399
_pp_max_nodes_per_scanline = max_nodes_per_scanline ;
402
- pp_tile_buffer = (uint8_t * )PP_MALLOC (tile_buffer_size * tile_buffer_size );
403
- // tile_buffer_size * 4 | max_nodes_per_scanline * 2
404
- pp_nodes = (int32_t * )PP_MALLOC (tile_buffer_size * 4 * max_nodes_per_scanline * 2 * sizeof (int32_t ));
405
- pp_node_counts = (uint32_t * )PP_MALLOC (tile_buffer_size * 4 * sizeof (uint32_t ));
400
+ pp_nodes = (int32_t * )PP_MALLOC (PP_TILE_BUFFER_SIZE * 4 * max_nodes_per_scanline * 2 * sizeof (int32_t ));
401
+ pp_node_counts = (uint32_t * )PP_MALLOC (PP_TILE_BUFFER_SIZE * 4 * sizeof (uint32_t ));
406
402
}
407
403
408
404
void pp_deinit () {
409
- PP_FREE (pp_tile_buffer );
410
405
PP_FREE (pp_nodes );
411
406
PP_FREE (pp_node_counts );
412
407
}
@@ -546,11 +541,11 @@ int compare_nodes(const void* a, const void* b) {
546
541
}
547
542
548
543
pp_rect_t render_nodes (pp_rect_t * tb ) {
549
- pp_rect_t rb = {_pp_tile_buffer_size << _pp_antialias , _pp_tile_buffer_size << _pp_antialias , 0 , 0 }; // render bounds
550
- int maxx = 0 , minx = _pp_tile_buffer_size << _pp_antialias ;
544
+ pp_rect_t rb = {PP_TILE_BUFFER_SIZE << _pp_antialias , PP_TILE_BUFFER_SIZE << _pp_antialias , 0 , 0 }; // render bounds
545
+ int maxx = 0 , minx = PP_TILE_BUFFER_SIZE << _pp_antialias ;
551
546
debug (" + render tile %d, %d - %d, %d\n" , tb -> x , tb -> y , tb -> w , tb -> h );
552
547
553
- for (int y = 0 ; y < ((int )_pp_tile_buffer_size << _pp_antialias ); y ++ ) {
548
+ for (int y = 0 ; y < ((int )PP_TILE_BUFFER_SIZE << _pp_antialias ); y ++ ) {
554
549
int32_t * pp_scanline_nodes = & pp_nodes [y * 4 * _pp_max_nodes_per_scanline * 2 ];
555
550
556
551
// debug(" : row %d node count %d\n", y, pp_node_counts[y]);
@@ -559,7 +554,7 @@ pp_rect_t render_nodes(pp_rect_t *tb) {
559
554
560
555
qsort (pp_scanline_nodes , pp_node_counts [y ], sizeof (int ), compare_nodes );
561
556
562
- unsigned char * row_data = & pp_tile_buffer [(y >> _pp_antialias ) * _pp_tile_buffer_size ];
557
+ unsigned char * row_data = & pp_tile_buffer [(y >> _pp_antialias ) * PP_TILE_BUFFER_SIZE ];
563
558
564
559
for (uint32_t i = 0 ; i < pp_node_counts [y ]; i += 2 ) {
565
560
int sx = * pp_scanline_nodes ++ ;
@@ -606,7 +601,7 @@ pp_rect_t render_nodes(pp_rect_t *tb) {
606
601
if (_pp_antialias == 2 ) p_alpha_map = _pp_alpha_map_x16 ;
607
602
#if PP_SCALE_TO_ALPHA == 1
608
603
for (int y = rb .y ; y < rb .y + rb .h ; y ++ ) {
609
- unsigned char * row_data = & pp_tile_buffer [y * _pp_tile_buffer_size + rb .x ];
604
+ unsigned char * row_data = & pp_tile_buffer [y * PP_TILE_BUFFER_SIZE + rb .x ];
610
605
for (int x = rb .x ; x < rb .x + rb .w ; x ++ ) {
611
606
* row_data = p_alpha_map [* row_data ];
612
607
row_data ++ ;
@@ -648,18 +643,18 @@ void pp_render(pp_poly_t *polygon) {
648
643
649
644
// iterate over tiles
650
645
debug (" - processing tiles\n" );
651
- for (int32_t y = pb .y ; y < pb .y + pb .h ; y += _pp_tile_buffer_size ) {
652
- for (int32_t x = pb .x ; x < pb .x + pb .w ; x += _pp_tile_buffer_size ) {
653
- pp_rect_t tb = (pp_rect_t ){.x = x , .y = y , .w = _pp_tile_buffer_size , .h = _pp_tile_buffer_size };
646
+ for (int32_t y = pb .y ; y < pb .y + pb .h ; y += PP_TILE_BUFFER_SIZE ) {
647
+ for (int32_t x = pb .x ; x < pb .x + pb .w ; x += PP_TILE_BUFFER_SIZE ) {
648
+ pp_rect_t tb = (pp_rect_t ){.x = x , .y = y , .w = PP_TILE_BUFFER_SIZE , .h = PP_TILE_BUFFER_SIZE };
654
649
tb = pp_rect_intersection (& tb , & _pp_clip );
655
650
debug (" : %d, %d (%d x %d)\n" , tb .x , tb .y , tb .w , tb .h );
656
651
657
652
// if no intersection then skip tile
658
653
if (pp_rect_empty (& tb )) { debug (" : empty when clipped, skipping\n" ); continue ; }
659
654
660
655
// clear existing tile data and nodes
661
- memset (pp_node_counts , 0 , _pp_tile_buffer_size * 4 * sizeof (uint32_t ));
662
- memset (pp_tile_buffer , 0 , _pp_tile_buffer_size * _pp_tile_buffer_size );
656
+ memset (pp_node_counts , 0 , PP_TILE_BUFFER_SIZE * 4 * sizeof (uint32_t ));
657
+ memset (pp_tile_buffer , 0 , sizeof ( pp_tile_buffer ) );
663
658
664
659
// build the nodes for each pp_path_t
665
660
pp_path_t * path = polygon -> paths ;
@@ -680,8 +675,8 @@ void pp_render(pp_poly_t *polygon) {
680
675
681
676
pp_tile_t tile = {
682
677
.x = tb .x , .y = tb .y , .w = tb .w , .h = tb .h ,
683
- .stride = _pp_tile_buffer_size ,
684
- .data = pp_tile_buffer + rb .x + (_pp_tile_buffer_size * rb .y )
678
+ .stride = PP_TILE_BUFFER_SIZE ,
679
+ .data = pp_tile_buffer + rb .x + (PP_TILE_BUFFER_SIZE * rb .y )
685
680
};
686
681
687
682
_pp_tile_callback (& tile );
0 commit comments