40
40
#define PP_COORD_TYPE float
41
41
#endif
42
42
43
- #ifndef PP_MAX_NODES_PER_SCANLINE
44
- #define PP_MAX_NODES_PER_SCANLINE 16
45
- #endif
46
-
47
- #ifndef PP_TILE_BUFFER_SIZE
48
- #define PP_TILE_BUFFER_SIZE 64
49
- #endif
50
-
51
43
#ifndef PP_SCALE_TO_ALPHA
52
44
#define PP_SCALE_TO_ALPHA 1
53
45
#endif
@@ -126,6 +118,8 @@ void pp_poly_merge(pp_poly_t *p, pp_poly_t *m);
126
118
// user settings
127
119
typedef void (* pp_tile_callback_t )(const pp_tile_t * tile );
128
120
121
+ extern uint32_t _pp_tile_buffer_size ;
122
+
129
123
extern pp_rect_t _pp_clip ;
130
124
extern pp_tile_callback_t _pp_tile_callback ;
131
125
extern pp_antialias_t _pp_antialias ;
@@ -137,6 +131,9 @@ void pp_antialias(pp_antialias_t antialias);
137
131
pp_mat3_t * pp_transform (pp_mat3_t * transform );
138
132
void pp_render (pp_poly_t * polygon );
139
133
134
+ void pp_init (uint32_t tile_buffer_size , uint32_t max_nodes_per_scanline );
135
+ void pp_deinit ();
136
+
140
137
141
138
#ifdef __cplusplus
142
139
}
@@ -257,7 +254,7 @@ pp_rect_t pp_rect_transform(pp_rect_t *r, pp_mat3_t *m) {
257
254
258
255
// pp_tile_t implementation
259
256
uint8_t pp_tile_get (const pp_tile_t * tile , const int32_t x , const int32_t y ) {
260
- return tile -> data [(x - tile -> x ) + (y - tile -> y ) * PP_TILE_BUFFER_SIZE ];
257
+ return tile -> data [(x - tile -> x ) + (y - tile -> y ) * _pp_tile_buffer_size ];
261
258
}
262
259
263
260
pp_poly_t * pp_poly_new () {
@@ -380,19 +377,40 @@ pp_rect_t pp_poly_bounds(pp_poly_t *p) {
380
377
return b ;
381
378
}
382
379
380
+ uint32_t _pp_tile_buffer_size = 0 ;
381
+ uint32_t _pp_max_nodes_per_scanline = 0 ;
382
+
383
383
// buffer that each tile is rendered into before callback
384
384
// allocate one extra byte to allow a small optimization in the row renderer
385
- uint8_t pp_tile_buffer [PP_TILE_BUFFER_SIZE * PP_TILE_BUFFER_SIZE ];
385
+ uint8_t * pp_tile_buffer ;
386
+ //uint8_t pp_tile_buffer[PP_TILE_BUFFER_SIZE * PP_TILE_BUFFER_SIZE];
386
387
387
388
// polygon node buffer handles at most 16 line intersections per scanline
388
389
// is this enough for cjk/emoji? (requires a 2kB buffer)
389
- int32_t pp_nodes [PP_TILE_BUFFER_SIZE * 4 ][PP_MAX_NODES_PER_SCANLINE * 2 ];
390
- uint32_t pp_node_counts [PP_TILE_BUFFER_SIZE * 4 ];
390
+ int32_t * pp_nodes ;
391
+ 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];
391
394
392
395
uint8_t _pp_alpha_map_none [2 ] = {0 , 255 };
393
396
uint8_t _pp_alpha_map_x4 [5 ] = {0 , 63 , 127 , 190 , 255 };
394
397
uint8_t _pp_alpha_map_x16 [17 ] = {0 , 16 , 32 , 48 , 64 , 80 , 96 , 112 , 128 , 144 , 160 , 176 , 192 , 208 , 224 , 240 , 255 };
395
398
399
+ void pp_init (uint32_t tile_buffer_size , uint32_t max_nodes_per_scanline ) {
400
+ _pp_tile_buffer_size = tile_buffer_size ;
401
+ _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 ));
406
+ }
407
+
408
+ void pp_deinit () {
409
+ PP_FREE (pp_tile_buffer );
410
+ PP_FREE (pp_nodes );
411
+ PP_FREE (pp_node_counts );
412
+ }
413
+
396
414
void pp_clip (int32_t x , int32_t y , int32_t w , int32_t h ) {
397
415
_pp_clip = (pp_rect_t ){.x = x , .y = y , .w = w , .h = h };
398
416
}
@@ -482,15 +500,18 @@ void add_line_segment_to_nodes(const pp_point_t start, const pp_point_t end, pp_
482
500
// }
483
501
// #else
484
502
// loop over scanlines
503
+
485
504
while (count -- ) {
505
+ int32_t * pp_scanline_nodes = & pp_nodes [y * _pp_max_nodes_per_scanline * 2 ];
506
+
486
507
// consume accumulated error
487
508
while (e > dy ) {e -= dy ; x += xinc ;}
488
509
489
510
// clamp node x value to tile bounds
490
511
int nx = _pp_max (_pp_min (x , (tb -> w << _pp_antialias )), 0 );
491
512
//debug(" + adding node at %d, %d\n", x, y);
492
513
// add node to node list
493
- pp_nodes [ y ] [pp_node_counts [y ]++ ] = nx ;
514
+ pp_scanline_nodes [pp_node_counts [y ]++ ] = nx ;
494
515
495
516
// step to next scanline and accumulate error
496
517
y ++ ;
@@ -525,23 +546,24 @@ int compare_nodes(const void* a, const void* b) {
525
546
}
526
547
527
548
pp_rect_t render_nodes (pp_rect_t * tb ) {
528
- pp_rect_t rb = {PP_TILE_BUFFER_SIZE << _pp_antialias , PP_TILE_BUFFER_SIZE << _pp_antialias , 0 , 0 }; // render bounds
529
- int maxx = 0 , minx = PP_TILE_BUFFER_SIZE << _pp_antialias ;
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 ;
530
551
debug (" + render tile %d, %d - %d, %d\n" , tb -> x , tb -> y , tb -> w , tb -> h );
531
552
532
- for (int y = 0 ; y < ((int )PP_TILE_BUFFER_SIZE << _pp_antialias ); y ++ ) {
553
+ for (int y = 0 ; y < ((int )_pp_tile_buffer_size << _pp_antialias ); y ++ ) {
554
+ int32_t * pp_scanline_nodes = & pp_nodes [y * _pp_max_nodes_per_scanline * 2 ];
533
555
534
556
// debug(" : row %d node count %d\n", y, pp_node_counts[y]);
535
557
536
558
if (pp_node_counts [y ] == 0 ) continue ; // no nodes on this raster line
537
559
538
- qsort (& pp_nodes [ y ][ 0 ] , pp_node_counts [y ], sizeof (int ), compare_nodes );
560
+ qsort (pp_scanline_nodes , pp_node_counts [y ], sizeof (int ), compare_nodes );
539
561
540
- unsigned char * row_data = & pp_tile_buffer [(y >> _pp_antialias ) * PP_TILE_BUFFER_SIZE ];
562
+ unsigned char * row_data = & pp_tile_buffer [(y >> _pp_antialias ) * _pp_tile_buffer_size ];
541
563
542
564
for (uint32_t i = 0 ; i < pp_node_counts [y ]; i += 2 ) {
543
- int sx = pp_nodes [ y ][ i + 0 ] ;
544
- int ex = pp_nodes [ y ][ i + 1 ] ;
565
+ int sx = * pp_scanline_nodes ++ ;
566
+ int ex = * pp_scanline_nodes ++ ;
545
567
546
568
if (sx == ex ) { // empty span, nothing to do
547
569
continue ;
@@ -584,7 +606,7 @@ pp_rect_t render_nodes(pp_rect_t *tb) {
584
606
if (_pp_antialias == 2 ) p_alpha_map = _pp_alpha_map_x16 ;
585
607
#if PP_SCALE_TO_ALPHA == 1
586
608
for (int y = rb .y ; y < rb .y + rb .h ; y ++ ) {
587
- unsigned char * row_data = & pp_tile_buffer [y * PP_TILE_BUFFER_SIZE + rb .x ];
609
+ unsigned char * row_data = & pp_tile_buffer [y * _pp_tile_buffer_size + rb .x ];
588
610
for (int x = rb .x ; x < rb .x + rb .w ; x ++ ) {
589
611
* row_data = p_alpha_map [* row_data ];
590
612
row_data ++ ;
@@ -626,18 +648,18 @@ void pp_render(pp_poly_t *polygon) {
626
648
627
649
// iterate over tiles
628
650
debug (" - processing tiles\n" );
629
- for (int32_t y = pb .y ; y < pb .y + pb .h ; y += PP_TILE_BUFFER_SIZE ) {
630
- for (int32_t x = pb .x ; x < pb .x + pb .w ; x += PP_TILE_BUFFER_SIZE ) {
631
- pp_rect_t tb = (pp_rect_t ){.x = x , .y = y , .w = PP_TILE_BUFFER_SIZE , .h = PP_TILE_BUFFER_SIZE };
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 };
632
654
tb = pp_rect_intersection (& tb , & _pp_clip );
633
655
debug (" : %d, %d (%d x %d)\n" , tb .x , tb .y , tb .w , tb .h );
634
656
635
657
// if no intersection then skip tile
636
658
if (pp_rect_empty (& tb )) { debug (" : empty when clipped, skipping\n" ); continue ; }
637
659
638
660
// clear existing tile data and nodes
639
- memset (pp_node_counts , 0 , sizeof (pp_node_counts ));
640
- memset (pp_tile_buffer , 0 , PP_TILE_BUFFER_SIZE * PP_TILE_BUFFER_SIZE );
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 );
641
663
642
664
// build the nodes for each pp_path_t
643
665
pp_path_t * path = polygon -> paths ;
@@ -658,8 +680,8 @@ void pp_render(pp_poly_t *polygon) {
658
680
659
681
pp_tile_t tile = {
660
682
.x = tb .x , .y = tb .y , .w = tb .w , .h = tb .h ,
661
- .stride = PP_TILE_BUFFER_SIZE ,
662
- .data = pp_tile_buffer + rb .x + (PP_TILE_BUFFER_SIZE * rb .y )
683
+ .stride = _pp_tile_buffer_size ,
684
+ .data = pp_tile_buffer + rb .x + (_pp_tile_buffer_size * rb .y )
663
685
};
664
686
665
687
_pp_tile_callback (& tile );
0 commit comments