diff options
| author | sommersoft <sommersoft@users.noreply.github.com> | 2019-07-27 10:46:53 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-07-27 10:46:53 -0500 |
| commit | cebdadd0f6122826337c962b3d443bd41d1de69d (patch) | |
| tree | e2aeb661c3760f7aaf152bc1bbd95fd120161ab8 /shared-module/displayio/TileGrid.c | |
| parent | c335f170d7d561d07ca7412da60c260e13c5e746 (diff) | |
| parent | d99d3bd471920cdd9b2683b7dbd538551f7aee43 (diff) | |
Merge branch 'master' into dynamic_support_matrix
Diffstat (limited to 'shared-module/displayio/TileGrid.c')
| -rw-r--r-- | shared-module/displayio/TileGrid.c | 54 |
1 files changed, 35 insertions, 19 deletions
diff --git a/shared-module/displayio/TileGrid.c b/shared-module/displayio/TileGrid.c index cdca45a29..88873d3a9 100644 --- a/shared-module/displayio/TileGrid.c +++ b/shared-module/displayio/TileGrid.c @@ -291,7 +291,7 @@ void common_hal_displayio_tilegrid_set_top_left(displayio_tilegrid_t *self, uint self->full_change = true; } -bool displayio_tilegrid_fill_area(displayio_tilegrid_t *self, const displayio_area_t* area, uint32_t* mask, uint32_t *buffer) { +bool displayio_tilegrid_fill_area(displayio_tilegrid_t *self, const _displayio_colorspace_t* colorspace, const displayio_area_t* area, uint32_t* mask, uint32_t *buffer) { // If no tiles are present we have no impact. uint8_t* tiles = self->tiles; if (self->inline_tiles) { @@ -371,14 +371,15 @@ bool displayio_tilegrid_fill_area(displayio_tilegrid_t *self, const displayio_ar y_shift = temp_shift; } + uint8_t pixels_per_byte = 8 / colorspace->depth; for (int16_t y = start_y; y < end_y; y++) { - int16_t row_start = start + (y - start_y + y_shift) * y_stride; + int16_t row_start = start + (y - start_y + y_shift) * y_stride; // in pixels int16_t local_y = y / self->absolute_transform->scale; for (int16_t x = start_x; x < end_x; x++) { // Compute the destination pixel in the buffer and mask based on the transformations. - int16_t offset = row_start + (x - start_x + x_shift) * x_stride; + int16_t offset = row_start + (x - start_x + x_shift) * x_stride; // in pixels - // This is super useful for debugging out range accesses. Uncomment to use. + // This is super useful for debugging out of range accesses. Uncomment to use. // if (offset < 0 || offset >= (int32_t) displayio_area_size(area)) { // asm("bkpt"); // } @@ -404,23 +405,38 @@ bool displayio_tilegrid_fill_area(displayio_tilegrid_t *self, const displayio_ar value = common_hal_displayio_ondiskbitmap_get_pixel(self->bitmap, tile_x, tile_y); } - uint16_t* pixel = ((uint16_t*) buffer) + offset; + uint32_t pixel; + bool opaque = true; if (self->pixel_shader == mp_const_none) { - *pixel = value; - return true; + pixel = value; } else if (MP_OBJ_IS_TYPE(self->pixel_shader, &displayio_palette_type)) { - if (!displayio_palette_get_color(self->pixel_shader, value, pixel)) { - // A pixel is transparent so we haven't fully covered the area ourselves. - full_coverage = false; - } else { - mask[offset / 32] |= 1 << (offset % 32); - } + opaque = displayio_palette_get_color(self->pixel_shader, colorspace, value, &pixel); } else if (MP_OBJ_IS_TYPE(self->pixel_shader, &displayio_colorconverter_type)) { - if (!common_hal_displayio_colorconverter_convert(self->pixel_shader, value, pixel)) { - // A pixel is transparent so we haven't fully covered the area ourselves. - full_coverage = false; - } else { - mask[offset / 32] |= 1 << (offset % 32); + opaque = displayio_colorconverter_convert(self->pixel_shader, colorspace, value, &pixel); + } + if (!opaque) { + // A pixel is transparent so we haven't fully covered the area ourselves. + full_coverage = false; + } else { + mask[offset / 32] |= 1 << (offset % 32); + if (colorspace->depth == 16) { + *(((uint16_t*) buffer) + offset) = pixel; + } else if (colorspace->depth == 8) { + *(((uint8_t*) buffer) + offset) = pixel; + } else if (colorspace->depth < 8) { + // Reorder the offsets to pack multiple rows into a byte (meaning they share a column). + if (!colorspace->pixels_in_byte_share_row) { + uint16_t width = displayio_area_width(area); + uint16_t row = offset / width; + uint16_t col = offset % width; + // Dividing by pixels_per_byte does truncated division even if we multiply it back out. + offset = col * pixels_per_byte + (row / pixels_per_byte) * pixels_per_byte * width + row % pixels_per_byte; + // Also useful for validating that the bitpacking worked correctly. + // if (offset > displayio_area_size(area)) { + // asm("bkpt"); + // } + } + ((uint8_t*)buffer)[offset / pixels_per_byte] |= pixel << ((offset % pixels_per_byte) * colorspace->depth); } } } @@ -449,7 +465,7 @@ void displayio_tilegrid_finish_refresh(displayio_tilegrid_t *self) { displayio_area_t* displayio_tilegrid_get_refresh_areas(displayio_tilegrid_t *self, displayio_area_t* tail) { if (self->moved && !self->first_draw) { displayio_area_union(&self->previous_area, &self->current_area, &self->dirty_area); - if (displayio_area_size(&self->dirty_area) <= 2 * self->pixel_width * self->pixel_height) { + if (displayio_area_size(&self->dirty_area) <= 2U * self->pixel_width * self->pixel_height) { self->dirty_area.next = tail; return &self->dirty_area; } |
