qp_surface_internal.h 7.6 KB

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