Skip to content

Commit f194655

Browse files
committed
PicoVector: Revert the tile buffer to be fixed.
Ensure that MicroPython doesn't ever place the tile buffer into PSRAM and trash performance.
1 parent a6524a7 commit f194655

File tree

2 files changed

+25
-30
lines changed

2 files changed

+25
-30
lines changed

libraries/pico_vector/pico_vector.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ namespace pimoroni {
3939

4040
// TODO: Make these configurable?
4141
// Tile buffer size, Max nodes per scanline
42-
pp_init(16, 16);
42+
pp_init(16);
4343

4444
pp_tile_callback(PicoVector::tile_callback);
4545

libraries/pico_vector/pretty-poly.h

Lines changed: 24 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@
4040
#define PP_COORD_TYPE float
4141
#endif
4242

43+
#ifndef PP_TILE_BUFFER_SIZE
44+
#define PP_TILE_BUFFER_SIZE 64
45+
#endif
46+
4347
#ifndef PP_SCALE_TO_ALPHA
4448
#define PP_SCALE_TO_ALPHA 1
4549
#endif
@@ -118,8 +122,6 @@ void pp_poly_merge(pp_poly_t *p, pp_poly_t *m);
118122
// user settings
119123
typedef void (*pp_tile_callback_t)(const pp_tile_t *tile);
120124

121-
extern uint32_t _pp_tile_buffer_size;
122-
123125
extern pp_rect_t _pp_clip;
124126
extern pp_tile_callback_t _pp_tile_callback;
125127
extern pp_antialias_t _pp_antialias;
@@ -131,7 +133,7 @@ void pp_antialias(pp_antialias_t antialias);
131133
pp_mat3_t *pp_transform(pp_mat3_t *transform);
132134
void pp_render(pp_poly_t *polygon);
133135

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);
135137
void pp_deinit();
136138

137139

@@ -254,7 +256,7 @@ pp_rect_t pp_rect_transform(pp_rect_t *r, pp_mat3_t *m) {
254256

255257
// pp_tile_t implementation
256258
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];
258260
}
259261

260262
pp_poly_t *pp_poly_new() {
@@ -377,36 +379,29 @@ pp_rect_t pp_poly_bounds(pp_poly_t *p) {
377379
return b;
378380
}
379381

380-
uint32_t _pp_tile_buffer_size = 0;
381382
uint32_t _pp_max_nodes_per_scanline = 0;
382383

383384
// 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];
387388

388389
// polygon node buffer handles at most 16 line intersections per scanline
389390
// is this enough for cjk/emoji? (requires a 2kB buffer)
390391
int32_t *pp_nodes;
391392
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];
394393

395394
uint8_t _pp_alpha_map_none[2] = {0, 255};
396395
uint8_t _pp_alpha_map_x4[5] = {0, 63, 127, 190, 255};
397396
uint8_t _pp_alpha_map_x16[17] = {0, 16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 255};
398397

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) {
401399
_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));
406402
}
407403

408404
void pp_deinit() {
409-
PP_FREE(pp_tile_buffer);
410405
PP_FREE(pp_nodes);
411406
PP_FREE(pp_node_counts);
412407
}
@@ -546,11 +541,11 @@ int compare_nodes(const void* a, const void* b) {
546541
}
547542

548543
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;
551546
debug(" + render tile %d, %d - %d, %d\n", tb->x, tb->y, tb->w, tb->h);
552547

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++) {
554549
int32_t *pp_scanline_nodes = &pp_nodes[y * 4 * _pp_max_nodes_per_scanline * 2];
555550

556551
// 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) {
559554

560555
qsort(pp_scanline_nodes, pp_node_counts[y], sizeof(int), compare_nodes);
561556

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];
563558

564559
for(uint32_t i = 0; i < pp_node_counts[y]; i += 2) {
565560
int sx = *pp_scanline_nodes++;
@@ -606,7 +601,7 @@ pp_rect_t render_nodes(pp_rect_t *tb) {
606601
if(_pp_antialias == 2) p_alpha_map = _pp_alpha_map_x16;
607602
#if PP_SCALE_TO_ALPHA == 1
608603
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];
610605
for(int x = rb.x; x < rb.x + rb.w; x++) {
611606
*row_data = p_alpha_map[*row_data];
612607
row_data++;
@@ -648,18 +643,18 @@ void pp_render(pp_poly_t *polygon) {
648643

649644
// iterate over tiles
650645
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};
654649
tb = pp_rect_intersection(&tb, &_pp_clip);
655650
debug(" : %d, %d (%d x %d)\n", tb.x, tb.y, tb.w, tb.h);
656651

657652
// if no intersection then skip tile
658653
if(pp_rect_empty(&tb)) { debug(" : empty when clipped, skipping\n"); continue; }
659654

660655
// 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));
663658

664659
// build the nodes for each pp_path_t
665660
pp_path_t *path = polygon->paths;
@@ -680,8 +675,8 @@ void pp_render(pp_poly_t *polygon) {
680675

681676
pp_tile_t tile = {
682677
.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)
685680
};
686681

687682
_pp_tile_callback(&tile);

0 commit comments

Comments
 (0)