qp_surface_internal.h (7773B)
1 // Copyright 2022 Nick Brassel (@tzarc) 2 // SPDX-License-Identifier: GPL-2.0-or-later 3 #pragma once 4 5 #ifdef QUANTUM_PAINTER_SURFACE_ENABLE 6 7 # include "qp_surface.h" 8 9 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 10 // Internal declarations 11 12 // Surface vtable 13 typedef struct surface_painter_driver_vtable_t { 14 painter_driver_vtable_t base; // must be first, so it can be cast to/from the painter_driver_vtable_t* type 15 16 bool (*target_pixdata_transfer)(painter_driver_t *surface_driver, painter_driver_t *target_driver, uint16_t x, uint16_t y, bool entire_surface); 17 } surface_painter_driver_vtable_t; 18 19 typedef struct surface_dirty_data_t { 20 bool is_dirty; 21 uint16_t l; 22 uint16_t t; 23 uint16_t r; 24 uint16_t b; 25 } surface_dirty_data_t; 26 27 typedef struct surface_viewport_data_t { 28 // Manually manage the viewport for streaming pixel data to the display 29 uint16_t viewport_l; 30 uint16_t viewport_t; 31 uint16_t viewport_r; 32 uint16_t viewport_b; 33 34 // Current write location to the display when streaming pixel data 35 uint16_t pixdata_x; 36 uint16_t pixdata_y; 37 } surface_viewport_data_t; 38 39 // Surface struct 40 typedef struct surface_painter_device_t { 41 painter_driver_t base; // must be first, so it can be cast to/from the painter_device_t* type 42 43 // The target buffer 44 union { 45 void *buffer; 46 uint8_t *u8buffer; 47 uint16_t *u16buffer; 48 rgb_t *rgbbuffer; 49 }; 50 51 // Manually manage the viewport for streaming pixel data to the display 52 surface_viewport_data_t viewport; 53 54 // Maintain a dirty region so we can stream only what we need 55 surface_dirty_data_t dirty; 56 } surface_painter_device_t; 57 58 /** 59 * Factory method for an RGB565 surface (aka framebuffer). Accepts an external device table. 60 * 61 * @param device_table[in] the table of devices to use for instantiation 62 * @param device_table_len[in] the length of the table of devices 63 * @param panel_width[in] the width of the display panel 64 * @param panel_height[in] the height of the display panel 65 * @param buffer[in] pointer to a preallocated uint8_t buffer of size `SURFACE_REQUIRED_BUFFER_BYTE_SIZE(panel_width, panel_height, 16)` 66 * @return the device handle used with all drawing routines in Quantum Painter 67 */ 68 painter_device_t qp_make_rgb565_surface_advanced(surface_painter_device_t *device_table, size_t device_table_len, uint16_t panel_width, uint16_t panel_height, void *buffer); 69 70 /** 71 * Factory method for a 1bpp monochrome surface (aka framebuffer). 72 * 73 * @param device_table[in] the table of devices to use for instantiation 74 * @param device_table_len[in] the length of the table of devices 75 * @param panel_width[in] the width of the display panel 76 * @param panel_height[in] the height of the display panel 77 * @param buffer[in] pointer to a preallocated uint8_t buffer of size `SURFACE_REQUIRED_BUFFER_BYTE_SIZE(panel_width, panel_height, 16)` 78 * @return the device handle used with all drawing routines in Quantum Painter 79 */ 80 painter_device_t qp_make_mono1bpp_surface_advanced(surface_painter_device_t *device_table, size_t device_table_len, uint16_t panel_width, uint16_t panel_height, void *buffer); 81 82 // Driver storage 83 extern surface_painter_device_t surface_drivers[SURFACE_NUM_DEVICES]; 84 85 // Surface common APIs 86 bool qp_surface_init(painter_device_t device, painter_rotation_t rotation); 87 bool qp_surface_power(painter_device_t device, bool power_on); 88 bool qp_surface_clear(painter_device_t device); 89 bool qp_surface_flush(painter_device_t device); 90 bool qp_surface_viewport(painter_device_t device, uint16_t left, uint16_t top, uint16_t right, uint16_t bottom); 91 void qp_surface_increment_pixdata_location(surface_viewport_data_t *viewport); 92 void qp_surface_update_dirty(surface_dirty_data_t *dirty, uint16_t x, uint16_t y); 93 94 #endif // QUANTUM_PAINTER_SURFACE_ENABLE 95 96 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 97 // Factory functions for creating a handle to a surface 98 99 #define SURFACE_FACTORY_FUNCTION_IMPL(function_name, vtable, bpp) \ 100 painter_device_t(function_name##_advanced)(surface_painter_device_t * device_table, size_t device_table_len, uint16_t panel_width, uint16_t panel_height, void *buffer) { \ 101 for (uint32_t i = 0; i < device_table_len; ++i) { \ 102 surface_painter_device_t *driver = &device_table[i]; \ 103 if (!driver->base.driver_vtable) { \ 104 driver->base.driver_vtable = (painter_driver_vtable_t *)&(vtable); \ 105 driver->base.native_bits_per_pixel = (bpp); \ 106 driver->base.comms_vtable = &dummy_comms_vtable; \ 107 driver->base.panel_width = panel_width; \ 108 driver->base.panel_height = panel_height; \ 109 driver->base.rotation = QP_ROTATION_0; \ 110 driver->base.offset_x = 0; \ 111 driver->base.offset_y = 0; \ 112 driver->buffer = buffer; \ 113 return (painter_device_t)driver; \ 114 } \ 115 } \ 116 return NULL; \ 117 } \ 118 painter_device_t(function_name)(uint16_t panel_width, uint16_t panel_height, void *buffer) { \ 119 return (function_name##_advanced)(surface_drivers, SURFACE_NUM_DEVICES, panel_width, panel_height, buffer); \ 120 }