qmk_firmware

QMK firmware for my keyboards (Corne, Sweep Ferris) and trackball (Ploopy Adept)
Log | Files | Refs | Submodules | LICENSE

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     }