FabGL
ESP32 Display Controller and Graphics Library
vgacontroller.h
Go to the documentation of this file.
1 /*
2  Created by Fabrizio Di Vittorio (fdivitto2013@gmail.com) - <http://www.fabgl.com>
3  Copyright (c) 2019 Fabrizio Di Vittorio.
4  All rights reserved.
5 
6  This file is part of FabGL Library.
7 
8  FabGL 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  FabGL 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 FabGL. If not, see <http://www.gnu.org/licenses/>.
20  */
21 
22 
23 #pragma once
24 
25 
26 
34 #include <stdint.h>
35 #include <stddef.h>
36 #include <atomic>
37 
38 #include "rom/lldesc.h"
39 #include "driver/gpio.h"
40 
41 #include "freertos/FreeRTOS.h"
42 #include "freertos/queue.h"
43 
44 #include "fabglconf.h"
45 #include "fabutils.h"
46 #include "devdrivers/swgenerator.h"
47 #include "displaycontroller.h"
48 
49 
50 
51 
52 namespace fabgl {
53 
54 
55 #define VGA_RED_BIT 0
56 #define VGA_GREEN_BIT 2
57 #define VGA_BLUE_BIT 4
58 #define VGA_HSYNC_BIT 6
59 #define VGA_VSYNC_BIT 7
60 
61 #define VGA_SYNC_MASK ((1 << VGA_HSYNC_BIT) | (1 << VGA_VSYNC_BIT))
62 
63 
64 // pixel 0 = byte 2, pixel 1 = byte 3, pixel 2 = byte 0, pixel 3 = byte 1 :
65 // pixel : 0 1 2 3 4 5 6 7 8 9 10 11 ...etc...
66 // byte : 2 3 0 1 6 7 4 5 10 11 8 9 ...etc...
67 // dword : 0 1 2 ...etc...
68 // Thanks to https://github.com/paulscottrobson for the new macro. Before was: (row[((X) & 0xFFFC) + ((2 + (X)) & 3)])
69 #define VGA_PIXELINROW(row, X) (row[(X) ^ 2])
70 
71 // requires variables: m_viewPort
72 #define VGA_PIXEL(X, Y) VGA_PIXELINROW(m_viewPort[(Y)], X)
73 
74 
75 
81  Sync,
84 };
85 
86 
88 struct VGATimings {
89  char label[22];
90  int frequency;
91  int16_t HVisibleArea;
92  int16_t HFrontPorch;
93  int16_t HSyncPulse;
94  int16_t HBackPorch;
95  int16_t VVisibleArea;
96  int16_t VFrontPorch;
97  int16_t VSyncPulse;
98  int16_t VBackPorch;
99  char HSyncLogic;
100  char VSyncLogic;
101  uint8_t scanCount;
102  uint8_t multiScanBlack;
104 };
105 
106 
107 
137 
138 public:
139 
140  VGAController();
141 
142  // unwanted methods
143  VGAController(VGAController const&) = delete;
144  void operator=(VGAController const&) = delete;
145 
146 
152  static VGAController * instance() { return s_instance; }
153 
154 
171  void begin(gpio_num_t redGPIO, gpio_num_t greenGPIO, gpio_num_t blueGPIO, gpio_num_t HSyncGPIO, gpio_num_t VSyncGPIO);
172 
192  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);
193 
204  void begin();
205 
206  // abstract method of DisplayController
208 
209  // abstract method of DisplayController
211 
219  uint8_t getBitsPerChannel() { return m_bitsPerChannel; }
220 
221  // abstract method of DisplayController
223 
251  void setResolution(char const * modeline, int viewPortWidth = -1, int viewPortHeight = -1, bool doubleBuffered = false);
252 
253  void setResolution(VGATimings const& timings, int viewPortWidth = -1, int viewPortHeight = -1, bool doubleBuffered = false);
254 
255  VGATimings * getResolutionTimings() { return &m_timings; }
256 
257  // abstract method of DisplayController
258  int getScreenWidth() { return m_timings.HVisibleArea; }
259 
260  // abstract method of DisplayController
261  int getScreenHeight() { return m_timings.VVisibleArea; }
262 
268  int getViewPortCol() { return m_viewPortCol; }
269 
275  int getViewPortRow() { return m_viewPortRow; }
276 
277  // abstract method of DisplayController
278  int getViewPortWidth() { return m_viewPortWidth; }
279 
280  // abstract method of DisplayController
281  int getViewPortHeight() { return m_viewPortHeight; }
282 
296  void moveScreen(int offsetX, int offsetY);
297 
312  void shrinkScreen(int shrinkX, int shrinkY);
313 
340  void readScreen(Rect const & rect, RGB222 * destBuf);
341 
342  void readScreen(Rect const & rect, RGB888 * destBuf);
343 
370  void writeScreen(Rect const & rect, RGB222 * srcBuf);
371 
384  uint8_t createRawPixel(RGB222 rgb) { return preparePixel(rgb); }
385 
400  void setRawPixel(int x, int y, uint8_t rgb) { VGA_PIXEL(x, y) = rgb; }
401 
415  uint8_t * getScanline(int y) { return (uint8_t*) m_viewPort[y]; }
416 
417 private:
418 
419  void init(gpio_num_t VSyncGPIO);
420 
421  uint8_t packHVSync(bool HSync = false, bool VSync = false);
422  uint8_t preparePixel(RGB222 rgb, bool HSync = false, bool VSync = false);
423 
424  void freeBuffers();
425  void fillHorizBuffers(int offsetX);
426  void fillVertBuffers(int offsetY);
427  int fill(uint8_t volatile * buffer, int startPos, int length, uint8_t red, uint8_t green, uint8_t blue, bool hsync, bool vsync);
428  void allocateViewPort();
429  void freeViewPort();
430  int calcRequiredDMABuffersCount(int viewPortHeight);
431 
432  // abstract method of DisplayController
433  void setPixelAt(PixelDesc const & pixelDesc);
434 
435  // abstract method of DisplayController
436  void drawEllipse(Size const & size);
437 
438  // abstract method of DisplayController
439  void clear();
440 
441  // abstract method of DisplayController
442  void VScroll(int scroll);
443 
444  // abstract method of DisplayController
445  void HScroll(int scroll);
446 
447  // abstract method of DisplayController
448  void drawGlyph(Glyph const & glyph, GlyphOptions glyphOptions, RGB888 penColor, RGB888 brushColor);
449 
450  void drawGlyph_full(Glyph const & glyph, GlyphOptions glyphOptions, RGB888 penColor, RGB888 brushColor);
451 
452  void drawGlyph_light(Glyph const & glyph, GlyphOptions glyphOptions, RGB888 penColor, RGB888 brushColor);
453 
454  // abstract method of DisplayController
455  void invertRect(Rect const & rect);
456 
457  // abstract method of DisplayController
458  void copyRect(Rect const & source);
459 
460  // abstract method of DisplayController
461  void swapFGBG(Rect const & rect);
462 
463  // abstract method of DisplayController
464  void swapBuffers();
465 
466  // abstract method of DisplayController
467  void drawBitmap_Mask(int destX, int destY, Bitmap const * bitmap, uint8_t * saveBackground, int X1, int Y1, int XCount, int YCount);
468 
469  // abstract method of DisplayController
470  void drawBitmap_RGBA2222(int destX, int destY, Bitmap const * bitmap, uint8_t * saveBackground, int X1, int Y1, int XCount, int YCount);
471 
472  // abstract method of DisplayController
473  void drawBitmap_RGBA8888(int destX, int destY, Bitmap const * bitmap, uint8_t * saveBackground, int X1, int Y1, int XCount, int YCount);
474 
475  // abstract method of DisplayController
476  void fillRow(int y, int x1, int x2, RGB888 color);
477 
478  void swapRows(int yA, int yB, int x1, int x2);
479 
480  // abstract method of DisplayController
481  void drawLine(int X1, int Y1, int X2, int Y2, RGB888 color);
482 
483  // abstract method of DisplayController
484  PixelFormat getBitmapSavePixelFormat() { return PixelFormat::RGBA2222; }
485 
486  static void VSyncInterrupt();
487 
488  static void setupGPIO(gpio_num_t gpio, int bit, gpio_mode_t mode);
489 
490  // DMA related methods
491  bool setDMABuffersCount(int buffersCount);
492  void setDMABufferBlank(int index, void volatile * address, int length);
493  void setDMABufferView(int index, int row, int scan, volatile uint8_t * * viewPort, bool onVisibleDMA);
494  void setDMABufferView(int index, int row, int scan);
495  void volatile * getDMABuffer(int index, int * length);
496 
497 
498  static VGAController * s_instance;
499 
500  int m_VSyncInterruptSuspended; // 0 = enabled, >0 suspended
501 
502  GPIOStream m_GPIOStream;
503 
504  int m_bitsPerChannel; // 1 = 8 colors, 2 = 64 colors, set by begin()
505  VGATimings m_timings;
506  int16_t m_linesCount;
507  volatile int16_t m_maxVSyncISRTime; // Maximum us VSync interrupt routine can run
508 
509  // These buffers contains a full line, with FrontPorch, Sync, BackPorch and blank visible area, in the
510  // order specified by timings.HStartingBlock
511  volatile uint8_t * m_HBlankLine_withVSync;
512  volatile uint8_t * m_HBlankLine;
513  int16_t m_HLineSize;
514 
515  volatile int16_t m_viewPortCol;
516  volatile int16_t m_viewPortRow;
517  volatile int16_t m_viewPortWidth;
518  volatile int16_t m_viewPortHeight;
519 
520  // when double buffer is enabled the "drawing" view port is always m_viewPort, while the "visible" view port is always m_viewPortVisible
521  // when double buffer is not enabled then m_viewPort = m_viewPortVisible
522  volatile uint8_t * * m_viewPort;
523  volatile uint8_t * * m_viewPortVisible;
524 
525  uint8_t * m_viewPortMemoryPool[FABGLIB_VIEWPORT_MEMORY_POOL_COUNT + 1]; // last allocated pool is nullptr
526 
527  // when double buffer is enabled the running DMA buffer is always m_DMABuffersRunning
528  // when double buffer is not enabled then m_DMABuffers = m_DMABuffersRunning
529  lldesc_t volatile * m_DMABuffersHead;
530  lldesc_t volatile * m_DMABuffers;
531  lldesc_t volatile * m_DMABuffersVisible;
532 
533  int m_DMABuffersCount;
534 
535  gpio_num_t m_VSyncGPIO;
536 
537 };
538 
539 
540 
541 } // end of namespace
542 
543 
544 
545 
546 
547 
548 
Represents a 24 bit RGB color.
Definition: displaycontroller.h:206
void begin()
This is the 64 colors (8 GPIOs) initializer using default pinout.
Definition: vgacontroller.cpp:118
int getViewPortRow()
Determines vertical position of the viewport.
Definition: vgacontroller.h:275
char label[22]
Definition: vgacontroller.h:89
int16_t HFrontPorch
Definition: vgacontroller.h:92
uint8_t * getScanline(int y)
Gets a raw scanline pointer.
Definition: vgacontroller.h:415
int getScreenHeight()
Determines the screen height in pixels.
Definition: vgacontroller.h:261
int getViewPortWidth()
Determines horizontal size of the viewport.
Definition: vgacontroller.h:278
void suspendBackgroundPrimitiveExecution()
Suspends drawings.
Definition: vgacontroller.cpp:136
void readScreen(Rect const &rect, RGB222 *destBuf)
Reads pixels inside the specified rectangle.
Definition: vgacontroller.cpp:1563
int16_t VVisibleArea
Definition: vgacontroller.h:95
char HSyncLogic
Definition: vgacontroller.h:99
uint8_t getBitsPerChannel()
Gets number of bits allocated for each channel.
Definition: vgacontroller.h:219
void writeScreen(Rect const &rect, RGB222 *srcBuf)
Writes pixels inside the specified rectangle.
Definition: vgacontroller.cpp:1575
PixelFormat
This enum defines a pixel format.
Definition: displaycontroller.h:399
int16_t HBackPorch
Definition: vgacontroller.h:94
This file contains fabgl::GPIOStream definition.
int getViewPortCol()
Determines horizontal position of the viewport.
Definition: vgacontroller.h:268
void resumeBackgroundPrimitiveExecution()
Resumes drawings after suspendBackgroundPrimitiveExecution().
Definition: vgacontroller.cpp:146
Definition: vgacontroller.h:83
This file contains fabgl::DisplayController definition.
NativePixelFormat
This enum defines the display controller native pixel format.
Definition: displaycontroller.h:390
void moveScreen(int offsetX, int offsetY)
Moves screen by specified horizontal and vertical offset.
Definition: vgacontroller.cpp:541
int16_t HSyncPulse
Definition: vgacontroller.h:93
void shrinkScreen(int shrinkX, int shrinkY)
Reduces or expands screen size by the specified horizontal and vertical offset.
Definition: vgacontroller.cpp:550
Definition: vgacontroller.h:81
Specifies the VGA timings. This is a modeline decoded.
Definition: vgacontroller.h:88
Represents a glyph position, size and binary data.
Definition: displaycontroller.h:299
Represents an image.
Definition: displaycontroller.h:414
This file contains some utility classes and functions.
Definition: canvas.cpp:31
char VSyncLogic
Definition: vgacontroller.h:100
Specifies various glyph painting options.
Definition: displaycontroller.h:315
Represents a rectangle.
Definition: fabutils.h:158
Represents the VGA controller.
Definition: vgacontroller.h:136
Definition: vgacontroller.h:82
static VGAController * instance()
Returns the singleton instance of VGAController class.
Definition: vgacontroller.h:152
void setRawPixel(int x, int y, uint8_t rgb)
Sets a raw pixel prepared using VGAController.createRawPixel.
Definition: vgacontroller.h:400
Definition: vgacontroller.h:80
int getScreenWidth()
Determines the screen width in pixels.
Definition: vgacontroller.h:258
This file contains FabGL library configuration settings, like number of supported colors...
void setResolution(char const *modeline, int viewPortWidth=-1, int viewPortHeight=-1, bool doubleBuffered=false)
Sets current resolution using linux-like modeline.
Definition: vgacontroller.cpp:245
Represents a bidimensional size.
Definition: fabutils.h:143
int16_t VSyncPulse
Definition: vgacontroller.h:97
uint8_t multiScanBlack
Definition: vgacontroller.h:102
Represents the base abstract class for display controllers.
Definition: displaycontroller.h:596
int frequency
Definition: vgacontroller.h:90
VGAScanStart HStartingBlock
Definition: vgacontroller.h:103
Represents a 6 bit RGB color.
Definition: displaycontroller.h:252
int16_t VFrontPorch
Definition: vgacontroller.h:96
uint8_t scanCount
Definition: vgacontroller.h:101
NativePixelFormat nativePixelFormat()
Represents the native pixel format used by this display.
Definition: vgacontroller.h:222
uint8_t createRawPixel(RGB222 rgb)
Creates a raw pixel to use with VGAController.setRawPixel.
Definition: vgacontroller.h:384
VGAScanStart
Represents one of the four blocks of horizontal or vertical line.
Definition: vgacontroller.h:79
int16_t VBackPorch
Definition: vgacontroller.h:98
#define FABGLIB_VIEWPORT_MEMORY_POOL_COUNT
Definition: fabglconf.h:111
int getViewPortHeight()
Determines vertical size of the viewport.
Definition: vgacontroller.h:281
int16_t HVisibleArea
Definition: vgacontroller.h:91