mirror of
				https://github.com/mfulz/qmk_firmware.git
				synced 2025-10-31 13:22:31 +01:00 
			
		
		
		
	 8e614250b4
			
		
	
	
		8e614250b4
		
			
		
	
	
	
	
		
			
			Co-authored-by: Pablo Martínez <58857054+elpekenin@users.noreply.github.com> Co-authored-by: Dasky <32983009+daskygit@users.noreply.github.com> Fixup delta frame coordinates after #20296.
		
			
				
	
	
		
			120 lines
		
	
	
		
			7.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			120 lines
		
	
	
		
			7.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| // Copyright 2022 Nick Brassel (@tzarc)
 | |
| // SPDX-License-Identifier: GPL-2.0-or-later
 | |
| #pragma once
 | |
| 
 | |
| #ifdef QUANTUM_PAINTER_SURFACE_ENABLE
 | |
| 
 | |
| #    include "qp_surface.h"
 | |
| 
 | |
| ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 | |
| // Internal declarations
 | |
| 
 | |
| // Surface vtable
 | |
| typedef struct surface_painter_driver_vtable_t {
 | |
|     painter_driver_vtable_t base; // must be first, so it can be cast to/from the painter_driver_vtable_t* type
 | |
| 
 | |
|     bool (*target_pixdata_transfer)(painter_driver_t *surface_driver, painter_driver_t *target_driver, uint16_t x, uint16_t y, bool entire_surface);
 | |
| } surface_painter_driver_vtable_t;
 | |
| 
 | |
| typedef struct surface_dirty_data_t {
 | |
|     bool     is_dirty;
 | |
|     uint16_t l;
 | |
|     uint16_t t;
 | |
|     uint16_t r;
 | |
|     uint16_t b;
 | |
| } surface_dirty_data_t;
 | |
| 
 | |
| typedef struct surface_viewport_data_t {
 | |
|     // Manually manage the viewport for streaming pixel data to the display
 | |
|     uint16_t viewport_l;
 | |
|     uint16_t viewport_t;
 | |
|     uint16_t viewport_r;
 | |
|     uint16_t viewport_b;
 | |
| 
 | |
|     // Current write location to the display when streaming pixel data
 | |
|     uint16_t pixdata_x;
 | |
|     uint16_t pixdata_y;
 | |
| } surface_viewport_data_t;
 | |
| 
 | |
| // Surface struct
 | |
| typedef struct surface_painter_device_t {
 | |
|     painter_driver_t base; // must be first, so it can be cast to/from the painter_device_t* type
 | |
| 
 | |
|     // The target buffer
 | |
|     union {
 | |
|         void *    buffer;
 | |
|         uint8_t * u8buffer;
 | |
|         uint16_t *u16buffer;
 | |
|     };
 | |
| 
 | |
|     // Manually manage the viewport for streaming pixel data to the display
 | |
|     surface_viewport_data_t viewport;
 | |
| 
 | |
|     // Maintain a dirty region so we can stream only what we need
 | |
|     surface_dirty_data_t dirty;
 | |
| } surface_painter_device_t;
 | |
| 
 | |
| /**
 | |
|  * Factory method for an RGB565 surface (aka framebuffer). Accepts an external device table.
 | |
|  *
 | |
|  * @param device_table[in] the table of devices to use for instantiation
 | |
|  * @param device_table_len[in] the length of the table of devices
 | |
|  * @param panel_width[in] the width of the display panel
 | |
|  * @param panel_height[in] the height of the display panel
 | |
|  * @param buffer[in] pointer to a preallocated uint8_t buffer of size `SURFACE_REQUIRED_BUFFER_BYTE_SIZE(panel_width, panel_height, 16)`
 | |
|  * @return the device handle used with all drawing routines in Quantum Painter
 | |
|  */
 | |
| 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);
 | |
| 
 | |
| /**
 | |
|  * Factory method for a 1bpp monochrome surface (aka framebuffer).
 | |
|  *
 | |
|  * @param device_table[in] the table of devices to use for instantiation
 | |
|  * @param device_table_len[in] the length of the table of devices
 | |
|  * @param panel_width[in] the width of the display panel
 | |
|  * @param panel_height[in] the height of the display panel
 | |
|  * @param buffer[in] pointer to a preallocated uint8_t buffer of size `SURFACE_REQUIRED_BUFFER_BYTE_SIZE(panel_width, panel_height, 16)`
 | |
|  * @return the device handle used with all drawing routines in Quantum Painter
 | |
|  */
 | |
| 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);
 | |
| 
 | |
| // Driver storage
 | |
| extern surface_painter_device_t surface_drivers[SURFACE_NUM_DEVICES];
 | |
| 
 | |
| // Surface common APIs
 | |
| bool qp_surface_init(painter_device_t device, painter_rotation_t rotation);
 | |
| bool qp_surface_power(painter_device_t device, bool power_on);
 | |
| bool qp_surface_clear(painter_device_t device);
 | |
| bool qp_surface_flush(painter_device_t device);
 | |
| bool qp_surface_viewport(painter_device_t device, uint16_t left, uint16_t top, uint16_t right, uint16_t bottom);
 | |
| void qp_surface_increment_pixdata_location(surface_viewport_data_t *viewport);
 | |
| void qp_surface_update_dirty(surface_dirty_data_t *dirty, uint16_t x, uint16_t y);
 | |
| 
 | |
| #endif // QUANTUM_PAINTER_SURFACE_ENABLE
 | |
| 
 | |
| ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 | |
| // Factory functions for creating a handle to a surface
 | |
| 
 | |
| #define SURFACE_FACTORY_FUNCTION_IMPL(function_name, vtable, bpp)                                                                                                             \
 | |
|     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) { \
 | |
|         for (uint32_t i = 0; i < device_table_len; ++i) {                                                                                                                     \
 | |
|             surface_painter_device_t *driver = &device_table[i];                                                                                                              \
 | |
|             if (!driver->base.driver_vtable) {                                                                                                                                \
 | |
|                 driver->base.driver_vtable         = (painter_driver_vtable_t *)&(vtable);                                                                                    \
 | |
|                 driver->base.native_bits_per_pixel = (bpp);                                                                                                                   \
 | |
|                 driver->base.comms_vtable          = &dummy_comms_vtable;                                                                                                     \
 | |
|                 driver->base.panel_width           = panel_width;                                                                                                             \
 | |
|                 driver->base.panel_height          = panel_height;                                                                                                            \
 | |
|                 driver->base.rotation              = QP_ROTATION_0;                                                                                                           \
 | |
|                 driver->base.offset_x              = 0;                                                                                                                       \
 | |
|                 driver->base.offset_y              = 0;                                                                                                                       \
 | |
|                 driver->buffer                     = buffer;                                                                                                                  \
 | |
|                 return (painter_device_t)driver;                                                                                                                              \
 | |
|             }                                                                                                                                                                 \
 | |
|         }                                                                                                                                                                     \
 | |
|         return NULL;                                                                                                                                                          \
 | |
|     }                                                                                                                                                                         \
 | |
|     painter_device_t(function_name)(uint16_t panel_width, uint16_t panel_height, void *buffer) {                                                                              \
 | |
|         return (function_name##_advanced)(surface_drivers, SURFACE_NUM_DEVICES, panel_width, panel_height, buffer);                                                           \
 | |
|     }
 |