ESP32VGA
ESP32 VGA Controller and Graphics Library
VGAController.h
Go to the documentation of this file.
1 /*
2  Created by Fabrizio Di Vittorio (fdivitto2013@gmail.com)
3  Copyright (c) 2018 Fabrizio Di Vittorio.
4  All rights reserved.
5 
6  This file is part of ESP32VGA Library.
7 
8  ESP32VGA is free software: you can redistribute it and/or modify
9  it under the terms of the GNU General Public License as published by
10  the Free Software Foundation, either version 3 of the License, or
11  (at your option) any later version.
12 
13  ESP32VGA is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  GNU General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with ESP32VGA. If not, see <http://www.gnu.org/licenses/>.
20  */
21 
22 
23 #ifndef _VGACONTROLLER_H_INCLUDED
24 #define _VGACONTROLLER_H_INCLUDED
25 
26 
34 #include "Arduino.h"
35 
36 #include <stdint.h>
37 #include <stddef.h>
38 
39 #include "rom/lldesc.h"
40 
41 #include "VGAConf.h"
42 
43 
44 
45 
46 
47 namespace ESP32VGA {
48 
49 
50 
51 
52 
54 enum class ScreenBlock {
55  FrontPorch,
56  Sync,
57  BackPorch,
58  VisibleArea
59 };
60 
61 
63 struct Timings_t {
64  char label[16];
65  uint32_t frequency;
66  uint16_t HVisibleArea;
67  uint16_t HFrontPorch;
68  uint16_t HSyncPulse;
69  uint16_t HBackPorch;
70  uint16_t VVisibleArea;
71  uint16_t VFrontPorch;
72  uint16_t VSyncPulse;
73  uint16_t VBackPorch;
74  char HSyncLogic;
75  char VSyncLogic;
76  bool doubleScan;
78 };
79 
80 
81 
82 /*
83  Notes:
84  - all positions can have negative and outofbound coordinates. Shapes are always clipped correctly.
85 */
86 enum class Primitive {
87  // Set current pen color
88  // params: color
89  SetPenColor,
90 
91  // Set current brush color
92  // params: color
93  SetBrushColor,
94 
95  // Paint a pixel at specified coordinates, using current pen color
96  // params: color
97  SetPixel,
98 
99  // Move current position to the specified one
100  // params: point
101  MoveTo,
102 
103  // Draw a line from current position to the specified one, using current pen color. Update current position.
104  // params: point
105  LineTo,
106 
107  // Fill a rectangle using current brush color
108  // params: rect
109  FillRect,
110 
111  // Fill an ellipse, current position is the center, using current brush color
112  // params: size
113  FillEllipse,
114 
115  // Draw an ellipse, current position is the center, using current pen color
116  // params: size
117  DrawEllipse,
118 
119  // Fill viewport with brush color
120  // params: none
121  Clear,
122 
123  // Scroll vertically without copying buffers
124  // params: ivalue (scroll amount, can be negative)
125  VScroll,
126 
127  // Scroll horizontally (time consuming operation!)
128  // params: ivalue (scroll amount, can be negative)
129  HScroll,
130 
131  // Draw a glyph (BW image)
132  // params: glyph
133  DrawGlyph,
134 
135  // Set paint options
136  // params: glyphOptions
137  SetGlyphOptions,
138 
139  // Set gluph options
140  // params: paintOptions
141  SetPaintOptions,
142 
143 #if VGAHAS_INVERTRECT
144  // Invert a rectangle
145  // params: rect
146  InvertRect,
147 #endif
148 
149  // Copy (overlapping) rectangle to current position
150  // params: rect (source rectangle)
151  CopyRect,
152 
153  // Set scrolling region
154  // params: rect
155  SetScrollingRegion,
156 
157  // Swap foreground (pen) and background (brush) colors of all pixels inside the specified rectangles. Other colors remain untaltered.
158  // params: rect
159  SwapFGBG,
160 
161 #if VGAHAS_READWRITERAWDATA
162  // Read raw viewport data
163  // params: rawData
164  ReadRawData,
165 
166  // Write raw viewport data
167  // params: rawData
168  WriteRawData,
169 #endif
170 
171  // Render glyphs buffer
172  // params: glyphsBufferRenderInfo
173  RenderGlyphsBuffer,
174 
175 };
176 
177 
178 
184 enum class Color {
185  Black,
186  Red,
187  Green,
188  Yellow,
189  Blue,
190  Magenta,
191  Cyan,
192  White,
193  BrightBlack,
194  BrightRed,
195  BrightGreen,
196  BrightYellow,
197  BrightBlue,
198  BrightMagenta,
199  BrightCyan,
200  BrightWhite,
201 };
202 
203 
204 
211 struct RGB_t {
212  uint8_t R : 2;
213  uint8_t G : 2;
214  uint8_t B : 2;
216  RGB_t() : R(0), G(0), B(0) { }
217  RGB_t(Color color);
218  RGB_t(uint8_t red, uint8_t green, uint8_t blue) : R(red), G(green), B(blue) { }
219  void operator = (const RGB_t& c) volatile { R = c.R; G = c.G; B = c.B; }
220 
221 };
222 
223 
224 
230 struct Rect_t {
231  int16_t X1;
232  int16_t Y1;
233  int16_t X2;
234  int16_t Y2;
236  Rect_t() { X1 = 0; Y1 = 0; X2 = 0; Y2 = 0; }
237  Rect_t(int16_t X1_, int16_t Y1_, int16_t X2_, int16_t Y2_) { X1 = X1_; Y1 = Y1_; X2 = X2_; Y2 = Y2_; }
238  void operator = (const Rect_t& c) volatile { X1 = c.X1; Y1 = c.Y1; X2 = c.X2; Y2 = c.Y2; }
239 };
240 
241 
242 
248 struct Point_t {
249  int16_t X;
250  int16_t Y;
252  void operator = (const Point_t & c) volatile { X = c.X; Y = c.Y; }
253 };
254 
255 
259 struct Size_t {
260  uint16_t width;
261  uint16_t height;
262 
263  void operator = (const Size_t & c) volatile { width = c.width; height = c.height; }
264 };
265 
266 
272 struct Glyph_t {
273  int16_t X;
274  int16_t Y;
275  uint16_t width;
276  uint16_t height;
277  uint8_t const * data;
278 
279  void operator = (const Glyph_t & c) volatile { X = c.X; Y = c.Y; width = c.width; height = c.height; data = c.data; }
280 };
281 
282 
283 
287 struct RawData_t {
288  int16_t X;
289  int16_t Y;
290  uint16_t width;
291  uint16_t height;
292  uint8_t * data;
293 
294  void operator = (const RawData_t & c) volatile { X = c.X; Y = c.Y; width = c.width; height = c.height; data = c.data; }
295 };
296 
297 
302  struct {
303  uint16_t fillBackground : 1;
304  uint16_t bold : 1;
305  uint16_t reduceLuminosity : 1;
306  uint16_t italic : 1;
307  uint16_t invert : 1;
308  uint16_t blank : 1;
309  uint16_t underline : 1;
310  uint16_t doubleWidth : 2;
311  uint16_t userOpt1 : 1;
312  };
313  uint16_t value;
314 
315  void operator = (const GlyphOptions_t & c) volatile { value = c.value; }
316  GlyphOptions_t & FillBackground(bool value) { fillBackground = value; return *this; }
317  GlyphOptions_t & Bold(bool value) { bold = value; return *this; }
318  GlyphOptions_t & Italic(bool value) { italic = value; return *this; }
319  GlyphOptions_t & Underline(bool value) { underline = value; return *this; }
320  GlyphOptions_t & DoubleWidth(uint8_t value) { doubleWidth = value; return *this; }
321  GlyphOptions_t & Invert(uint8_t value) { invert = value; return *this; }
322 };
323 
324 
325 
330  uint8_t swapFGBG : 1;
332  void operator = (const PaintOptions_t & c) volatile { swapFGBG = c.swapFGBG; }
333 };
334 
335 
336 #define VGAREDBIT 0
337 #define VGAGREENBIT 2
338 #define VGABLUEBIT 4
339 #define VGAHSYNCBIT 6
340 #define VGAVSYNCBIT 7
341 
342 
343 // GlyphsBuffer_t.map support functions
344 // 0 .. 7 : index
345 // 8 .. 11 : BG color (Color)
346 // 12 .. 15 : FG color (Color)
347 // 16 .. 31 : options (GlyphOptions_t)
348 // note: volatile pointer to avoid optimizer to get less than 32 bit from 32 bit access only memory
349 #define VGAMAPINDEXBIT 0
350 #define VGAMAPBGCOLORBIT 8
351 #define VGAMAPFGCOLORBIT 12
352 #define VGAMAPOPTIONSBIT 16
353 #define VGAGLYPHMAPITEM_MAKE(index, bgColor, fgColor, options) (((uint32_t)(index) << VGAMAPINDEXBIT) | ((uint32_t)(bgColor) << VGAMAPBGCOLORBIT) | ((uint32_t)(fgColor) << VGAMAPFGCOLORBIT) | ((uint32_t)((options).value) << VGAMAPOPTIONSBIT))
354 inline uint8_t VGAGLYPHMAPITEM_GETINDEX(uint32_t const volatile * mapItem) { return *mapItem >> VGAMAPINDEXBIT & 0xFF; }
355 inline Color VGAGLYPHMAPITEM_GETBGCOLOR(uint32_t const volatile * mapItem) { return (Color)(*mapItem >> VGAMAPBGCOLORBIT & 0x0F); }
356 inline Color VGAGLYPHMAPITEM_GETFGCOLOR(uint32_t const volatile * mapItem) { return (Color)(*mapItem >> VGAMAPFGCOLORBIT & 0x0F); }
357 inline GlyphOptions_t VGAGLYPHMAPITEM_GETOPTIONS(uint32_t const volatile * mapItem) { return (GlyphOptions_t){.value = (uint16_t)(*mapItem >> VGAMAPOPTIONSBIT & 0xFFFF)}; }
358 inline void VGAGLYPHMAPITEM_SETOPTIONS(uint32_t volatile * mapItem, GlyphOptions_t const & options) { *mapItem = (*mapItem & ~((uint32_t)0xFFFF << VGAMAPOPTIONSBIT)) | ((uint32_t)(options.value) << VGAMAPOPTIONSBIT); }
359 
360 
361 struct GlyphsBuffer_t {
362  uint16_t glyphsWidth;
363  uint16_t glyphsHeight;
364  uint8_t const * glyphsData;
365  uint16_t columns;
366  uint16_t rows;
367  uint32_t * map; // look at VGAGLYPHMAPITEM... macros
368 
369  void operator = (const GlyphsBuffer_t & c) volatile { glyphsWidth = c.glyphsWidth;
370  glyphsHeight = c.glyphsHeight;
371  glyphsData = c.glyphsData;
372  columns = c.columns;
373  rows = c.rows;
374  map = c.map; }
375 };
376 
377 
378 struct GlyphsBufferRenderInfo_t {
379  int16_t itemX; // starts from 0
380  int16_t itemY; // starts from 0
381  GlyphsBuffer_t const * glyphsBuffer;
382 };
383 
384 
385 struct Primitive_t {
386  Primitive cmd;
387  union {
388  int16_t ivalue;
389  RGB_t color;
390  Point_t position;
391  Size_t size;
392  Glyph_t glyph;
393  Rect_t rect;
394  GlyphOptions_t glyphOptions;
395  RawData_t rawData;
396  PaintOptions_t paintOptions;
397  GlyphsBufferRenderInfo_t glyphsBufferRenderInfo;
398  };
399 
400  Primitive_t() { }
401 };
402 
403 
404 struct PaintState_t {
405  RGB_t penColor;
406  RGB_t brushColor;
407  Point_t position;
408  GlyphOptions_t glyphOptions;
409  PaintOptions_t paintOptions;
410  Rect_t scrollingRegion;
411 
412  PaintState_t() { }
413  void operator = (const PaintState_t & c) volatile {
414  penColor = c.penColor;
415  brushColor = c.brushColor;
416  position = c.position;
417  glyphOptions = c.glyphOptions;
418  paintOptions = c.paintOptions;
419  scrollingRegion = c.scrollingRegion;
420  }
421 };
422 
423 
446 public:
447 
462  void begin(gpio_num_t redGPIO, gpio_num_t greenGPIO, gpio_num_t blueGPIO, gpio_num_t HSyncGPIO, gpio_num_t VSyncGPIO);
463 
481  void begin(gpio_num_t red1GPIO, gpio_num_t red0GPIO, gpio_num_t green1GPIO, gpio_num_t green0GPIO, gpio_num_t blue1GPIO, gpio_num_t blue0GPIO, gpio_num_t HSyncGPIO, gpio_num_t VSyncGPIO);
482 
490  uint8_t getBitsPerChannel() { return m_bitsPerChannel; }
491 
517  void setResolution(char const * modeline, int viewPortWidth = -1, int viewPortHeight = -1);
518  void setResolution(Timings_t const& timings, int viewPortWidth = -1, int viewPortHeight = -1);
519 
520  Timings_t * getResolutionTimings() { return &m_timings; }
521 
525  int getScreenWidth() { return m_timings.HVisibleArea; }
526 
530  int getScreenHeight() { return m_timings.VVisibleArea; }
531 
535  int getViewPortCol() { return m_viewPortCol; }
536 
540  int getViewPortRow() { return m_viewPortRow; }
541 
545  int getViewPortWidth() { return m_viewPortWidth; }
546 
550  int getViewPortHeight() { return m_viewPortHeight; }
551 
552  void addPrimitive(Primitive_t const & primitive);
553  void primitivesExecutionWait();
554 
566  void enableBackgroundPrimitiveExecution(bool value);
567 
577 
584 
591  void processPrimitives();
592 
606  void moveScreen(int16_t offsetX, int16_t offsetY);
607 
608 private:
609 
610  void init(gpio_num_t VSyncGPIO);
611 
612  uint8_t preparePixel(RGB_t rgb, bool HSync = false, bool VSync = false);
613 
614  void freeBuffers();
615  void fillHorizBuffers(int16_t offsetX);
616  void fillVertBuffers(int16_t offsetY);
617  int fill(uint8_t volatile * buffer, int startPos, int length, uint8_t red, uint8_t green, uint8_t blue, bool hsync, bool vsync);
618  void allocateViewPort();
619  void freeViewPort();
620  uint32_t calcRequiredDMABuffersCount(uint32_t viewPortHeight);
621 
622  void execPrimitive(Primitive_t const & prim);
623 
624  void execSetPixel(Point_t const & position);
625  void execLineTo(Point_t const & position);
626  void execFillRect(Rect_t const & rect);
627  void execFillEllipse(Size_t const & size);
628  void execDrawEllipse(Size_t const & size);
629  void execClear();
630  void execVScroll(int16_t scroll);
631  void execHScroll(int16_t scroll);
632  void execDrawGlyph(Glyph_t const & glyph, GlyphOptions_t glyphOptions, RGB_t penColor, RGB_t brushColor);
633  void execInvertRect(Rect_t const & rect);
634  void execCopyRect(Rect_t const & source);
635  void execSwapFGBG(Rect_t const & rect);
636  void execReadRawData(RawData_t const & rawData);
637  void execWriteRawData(RawData_t const & rawData);
638  void execRenderGlyphsBuffer(GlyphsBufferRenderInfo_t const & glyphsBufferRenderInfo);
639 
640  void clearRow(int row);
641 
642  static void VSyncInterrupt();
643 
644  static void setupGPIO(gpio_num_t gpio, int bit, gpio_mode_t mode);
645 
646  // DMA related methods
647  bool setDMABuffersCount(int buffersCount);
648  void setDMABuffer(int index, void volatile * address, int length);
649  void volatile * getDMABuffer(int index, int * length);
650 
651  uint8_t m_bitsPerChannel; // 1 = 8 colors, 2 = 64 colors, set by begin()
652  Timings_t m_timings;
653  uint16_t m_linesCount;
654  volatile uint16_t m_maxVSyncTicks;
655 
656  // These buffers contains a full line, with FrontPorch, Sync, BackPorch and blank visible area, in the
657  // order specified by timings.HStartingBlock
658  volatile uint8_t * m_HBlankLine_withVSync;
659  volatile uint8_t * m_HBlankLine;
660  uint16_t m_HLineSize;
661 
662  volatile uint16_t m_viewPortCol;
663  volatile uint16_t m_viewPortRow;
664  volatile uint16_t m_viewPortWidth;
665  volatile uint16_t m_viewPortHeight;
666  volatile uint8_t * * m_viewPort;
667  uint8_t * m_viewPortMemoryPool[VGAVIEWPORTMEMORYPOOLCOUNT + 1]; // last allocated pool is NULL
668 
669  volatile QueueHandle_t m_execQueue;
670  PaintState_t m_paintState;
671 
672  lldesc_t volatile * m_DMABuffers;
673  int m_DMABuffersCount;
674  gpio_num_t m_VSyncGPIO;
675  int m_VSyncInterruptSuspended; // 0 = enabled, >0 suspended
676  bool m_backgroundPrimitiveExecutionEnabled; // when False primitives are execute immediately
677 
678 };
679 
680 
681 inline bool operator==(RGB_t const& lhs, RGB_t const& rhs)
682 {
683  return lhs.R == rhs.R && lhs.G == rhs.G && lhs.B == rhs.B;
684 }
685 
686 
687 inline bool operator!=(RGB_t const& lhs, RGB_t const& rhs)
688 {
689  return lhs.R != rhs.R || lhs.G != rhs.G || lhs.B == rhs.B;
690 }
691 
692 
693 template <typename T> void swap(T & v1, T & v2)
694 {
695  T t = v1;
696  v1 = v2;
697  v2 = t;
698 }
699 
700 
701 } // end of namespace
702 
703 
704 extern ESP32VGA::VGAControllerClass VGAController;
705 
706 
707 
708 #endif
uint16_t invert
Definition: VGAController.h:307
Represents a glyph position, size and binary data.
Definition: VGAController.h:272
int getScreenWidth()
Returns the screen width in pixels.
Definition: VGAController.h:525
#define VGAVIEWPORTMEMORYPOOLCOUNT
Definition: VGAConf.h:122
void begin(gpio_num_t redGPIO, gpio_num_t greenGPIO, gpio_num_t blueGPIO, gpio_num_t HSyncGPIO, gpio_num_t VSyncGPIO)
This is the 8 colors (5 GPIOs) initializer.
Definition: VGAController.cpp:118
Color
This enum defines named colors.
Definition: VGAController.h:184
void resumeBackgroundPrimitiveExecution()
Resumes drawings after suspendBackgroundPrimitiveExecution().
Definition: VGAController.cpp:644
int getScreenHeight()
Returns the screen height in pixels.
Definition: VGAController.h:530
uint16_t VSyncPulse
Definition: VGAController.h:72
bool doubleScan
Definition: VGAController.h:76
Specifies the VGA timings. This is a modeline decoded.
Definition: VGAController.h:63
uint16_t userOpt1
Definition: VGAController.h:311
int16_t X2
Definition: VGAController.h:233
uint8_t R
Definition: VGAController.h:212
int16_t X1
Definition: VGAController.h:231
int16_t Y1
Definition: VGAController.h:232
uint16_t reduceLuminosity
Definition: VGAController.h:305
void processPrimitives()
Draws immediately all primitives in the queue.
Definition: VGAController.cpp:670
void setResolution(char const *modeline, int viewPortWidth=-1, int viewPortHeight=-1)
Sets current resolution using linux-like modeline.
Definition: VGAController.cpp:248
void moveScreen(int16_t offsetX, int16_t offsetY)
Moves screen by specified horizontal and vertical offset.
Definition: VGAController.cpp:532
This file contains ESP32VGA library configuration settings, like number of supported colors...
int16_t Y
Definition: VGAController.h:250
Definition: VGACanvas.cpp:29
uint16_t HFrontPorch
Definition: VGAController.h:67
Specifies general paint options.
Definition: VGAController.h:329
uint16_t VVisibleArea
Definition: VGAController.h:70
uint16_t fillBackground
Definition: VGAController.h:303
int16_t X
Definition: VGAController.h:249
int getViewPortWidth()
Returns horizontal size of the viewport.
Definition: VGAController.h:545
Represents a bidimensional size.
Definition: VGAController.h:259
int getViewPortCol()
Returns horizontal position of the viewport (in case viewport width is less than screen width)...
Definition: VGAController.h:535
void operator=(const PaintOptions_t &c) volatile
Definition: VGAController.h:332
Represents the VGA controller.
Definition: VGAController.h:445
int16_t Y2
Definition: VGAController.h:234
uint16_t HVisibleArea
Definition: VGAController.h:66
ScreenBlock HStartingBlock
Definition: VGAController.h:77
char HSyncLogic
Definition: VGAController.h:74
char label[16]
Definition: VGAController.h:64
int getViewPortHeight()
Returns vertical size of the viewport.
Definition: VGAController.h:550
Specifies various glyph painting options.
Definition: VGAController.h:301
Represents an RGB color.
Definition: VGAController.h:211
uint16_t HBackPorch
Definition: VGAController.h:69
Represents a rectangle.
Definition: VGAController.h:230
uint16_t HSyncPulse
Definition: VGAController.h:68
uint16_t bold
Definition: VGAController.h:304
uint8_t getBitsPerChannel()
Gets number of bits allocated for each channel.
Definition: VGAController.h:490
uint16_t VFrontPorch
Definition: VGAController.h:71
char VSyncLogic
Definition: VGAController.h:75
void suspendBackgroundPrimitiveExecution()
Suspends drawings.
Definition: VGAController.cpp:633
Represents the coordinate of a point.
Definition: VGAController.h:248
uint8_t G
Definition: VGAController.h:213
uint32_t frequency
Definition: VGAController.h:65
int getViewPortRow()
Returns vertical position of the viewport (in case viewport height is less than screen height)...
Definition: VGAController.h:540
uint16_t VBackPorch
Definition: VGAController.h:73
void enableBackgroundPrimitiveExecution(bool value)
Enables or disables drawings inside vertical retracing time.
Definition: VGAController.cpp:615
uint16_t doubleWidth
Definition: VGAController.h:310
Represents a region of raw screen buffer.
Definition: VGAController.h:287
uint16_t blank
Definition: VGAController.h:308
uint16_t italic
Definition: VGAController.h:306
ScreenBlock
Definition: VGAController.h:54
uint8_t B
Definition: VGAController.h:214
uint16_t underline
Definition: VGAController.h:309