Display_SITL.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. /*
  2. This program is free software: you can redistribute it and/or modify
  3. it under the terms of the GNU General Public License as published by
  4. the Free Software Foundation, either version 3 of the License, or
  5. (at your option) any later version.
  6. This program is distributed in the hope that it will be useful,
  7. but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  9. GNU General Public License for more details.
  10. You should have received a copy of the GNU General Public License
  11. along with this program. If not, see <http://www.gnu.org/licenses/>.
  12. */
  13. #ifdef WITH_SITL_OSD
  14. #include "Display_SITL.h"
  15. #include <AP_HAL/AP_HAL.h>
  16. #include <AP_Notify/AP_Notify.h>
  17. #include <stdio.h>
  18. #include <unistd.h>
  19. // constructor
  20. Display_SITL::Display_SITL()
  21. {
  22. }
  23. Display_SITL::~Display_SITL()
  24. {
  25. }
  26. Display_SITL *Display_SITL::probe()
  27. {
  28. Display_SITL *driver = new Display_SITL();
  29. if (!driver || !driver->hw_init()) {
  30. delete driver;
  31. return nullptr;
  32. }
  33. return driver;
  34. }
  35. // main loop of graphics thread
  36. void Display_SITL::update_thread(void)
  37. {
  38. {
  39. WITH_SEMAPHORE(AP::notify().sf_window_mutex);
  40. w = new sf::RenderWindow(sf::VideoMode(COLUMNS*SCALE, ROWS*SCALE), "Display");
  41. }
  42. if (!w) {
  43. AP_HAL::panic("Unable to create Display_SITL window");
  44. }
  45. const sf::Color color_black = sf::Color(0,0,0);
  46. const sf::Color color_white = sf::Color(255,255,255);
  47. const sf::Uint8 pixels[ROWS*COLUMNS*4]{};
  48. sf::Image image;
  49. image.create(COLUMNS, ROWS, pixels);
  50. while (true) {
  51. {
  52. WITH_SEMAPHORE(AP::notify().sf_window_mutex);
  53. sf::Event event;
  54. while (w->pollEvent(event)) {
  55. if (event.type == sf::Event::Closed) {
  56. w->close();
  57. }
  58. }
  59. if (!w->isOpen()) {
  60. break;
  61. }
  62. if (_need_hw_update) {
  63. _need_hw_update = false;
  64. uint8_t buffer2[ROWS*COLUMNS];
  65. {
  66. WITH_SEMAPHORE(mutex);
  67. memcpy(buffer2, _displaybuffer, sizeof(buffer2));
  68. }
  69. w->clear();
  70. for (uint16_t y=0; y<ROWS; y++) {
  71. for (uint16_t x=0; x<COLUMNS; x++) {
  72. if (buffer2[x+y/8*COLUMNS] & 1<<y%8) {
  73. image.setPixel(x, y, color_white);
  74. } else {
  75. image.setPixel(x, y, color_black);
  76. }
  77. }
  78. }
  79. sf::Texture texture;
  80. texture.loadFromImage(image);
  81. sf::Sprite sprite;
  82. sprite.setTexture(texture, true);
  83. sprite.setScale(SCALE, SCALE);
  84. w->draw(sprite);
  85. w->display();
  86. }
  87. }
  88. usleep(10000);
  89. }
  90. }
  91. // trampoline for update thread
  92. void *Display_SITL::update_thread_start(void *obj)
  93. {
  94. ((Display_SITL *)obj)->update_thread();
  95. return nullptr;
  96. }
  97. bool Display_SITL::hw_init()
  98. {
  99. pthread_create(&thread, NULL, update_thread_start, this);
  100. _need_hw_update = true;
  101. return true;
  102. }
  103. void Display_SITL::hw_update()
  104. {
  105. _need_hw_update = true;
  106. }
  107. void Display_SITL::set_pixel(uint16_t x, uint16_t y)
  108. {
  109. // check x, y range
  110. if ((x >= COLUMNS) || (y >= ROWS)) {
  111. return;
  112. }
  113. // set pixel in buffer
  114. WITH_SEMAPHORE(mutex);
  115. _displaybuffer[x + (y / 8 * COLUMNS)] |= 1 << (y % 8);
  116. _need_hw_update = true;
  117. }
  118. void Display_SITL::clear_pixel(uint16_t x, uint16_t y)
  119. {
  120. // check x, y range
  121. if ((x >= COLUMNS) || (y >= ROWS)) {
  122. return;
  123. }
  124. // clear pixel in buffer
  125. WITH_SEMAPHORE(mutex);
  126. _displaybuffer[x + (y / 8 * COLUMNS)] &= ~(1 << (y % 8));
  127. _need_hw_update = true;
  128. }
  129. void Display_SITL::clear_screen()
  130. {
  131. WITH_SEMAPHORE(mutex);
  132. memset(_displaybuffer, 0, sizeof(_displaybuffer));
  133. _need_hw_update = true;
  134. }
  135. #endif // WITH_SITL_OSD