diff --git a/selfdrive/ui/SConscript b/selfdrive/ui/SConscript index b8f3593e74..d5ab9e46ef 100644 --- a/selfdrive/ui/SConscript +++ b/selfdrive/ui/SConscript @@ -78,7 +78,7 @@ else: LIBS=qt_libs) qt_libs.append("qt_widgets") - qt_src = ["qt/ui.cc", "qt/window.cc", "qt/offroad/settings.cc", "qt/offroad/onboarding.cc"] + src + qt_src = ["qt/ui.cc", "qt/window.cc", "qt/home.cc", "qt/offroad/settings.cc", "qt/offroad/onboarding.cc"] + src qt_env.Program("_ui", qt_src, LIBS=qt_libs + libs) # spinner and text window diff --git a/selfdrive/ui/qt/home.cc b/selfdrive/ui/qt/home.cc new file mode 100644 index 0000000000..6f5f9bf125 --- /dev/null +++ b/selfdrive/ui/qt/home.cc @@ -0,0 +1,220 @@ +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "common/params.h" + +#include "home.hpp" +#include "paint.hpp" +#include "qt_window.hpp" + +#define BACKLIGHT_DT 0.25 +#define BACKLIGHT_TS 2.00 + + +QWidget * home_widget() { + QVBoxLayout *main_layout = new QVBoxLayout(); + main_layout->setContentsMargins(sbr_w + 50, 50, 50, 50); + + // header + QHBoxLayout *header_layout = new QHBoxLayout(); + QString date_str = QDateTime::currentDateTime().toString("dddd, MMMM d"); + QLabel *date = new QLabel(date_str); + date->setStyleSheet(R"(font-size: 55px;)"); + header_layout->addWidget(date, 0, Qt::AlignTop | Qt::AlignLeft); + + QLabel *version = new QLabel(QString::fromStdString("openpilot v" + Params().get("Version"))); + version->setStyleSheet(R"(font-size: 45px;)"); + header_layout->addWidget(version, 0, Qt::AlignTop | Qt::AlignRight); + + main_layout->addLayout(header_layout); + + // center + QLabel *drive = new QLabel("Drive me"); + drive->setStyleSheet(R"(font-size: 175px;)"); + main_layout->addWidget(drive, 1, Qt::AlignHCenter); + + QWidget *w = new QWidget(); + w->setLayout(main_layout); + w->setStyleSheet(R"( + * { + background-color: none; + } + )"); + return w; +} + +HomeWindow::HomeWindow(QWidget *parent) : QWidget(parent) { + + layout = new QGridLayout; + layout->setMargin(0); + + glWindow = new GLWindow(this); + layout->addWidget(glWindow, 0, 0); + + home = home_widget(); + layout->addWidget(home, 0, 0); + QObject::connect(glWindow, SIGNAL(offroadTransition(bool)), this, SLOT(setVisibility(bool))); + + setLayout(layout); + setStyleSheet(R"( + * { + color: white; + } + )"); +} + +void HomeWindow::setVisibility(bool offroad) { + home->setVisible(offroad); +} + +void HomeWindow::mousePressEvent(QMouseEvent *e) { + UIState *ui_state = glWindow->ui_state; + + glWindow->wake(); + + // Settings button click + if (!ui_state->scene.uilayout_sidebarcollapsed && settings_btn.ptInRect(e->x(), e->y())) { + emit openSettings(); + } + + // Vision click + if (ui_state->started && (e->x() >= ui_state->scene.viz_rect.x - bdr_s)){ + ui_state->scene.uilayout_sidebarcollapsed = !ui_state->scene.uilayout_sidebarcollapsed; + } +} + + +static void handle_display_state(UIState *s, int dt, bool user_input) { + static int awake_timeout = 0; + awake_timeout = std::max(awake_timeout-dt, 0); + + if (user_input || s->ignition || s->started) { + s->awake = true; + awake_timeout = 30*UI_FREQ; + } else if (awake_timeout == 0){ + s->awake = false; + } +} + +static void set_backlight(int brightness){ + std::ofstream brightness_control("/sys/class/backlight/panel0-backlight/brightness"); + if (brightness_control.is_open()){ + brightness_control << brightness << "\n"; + brightness_control.close(); + } +} + + +GLWindow::GLWindow(QWidget *parent) : QOpenGLWidget(parent) { + timer = new QTimer(this); + QObject::connect(timer, SIGNAL(timeout()), this, SLOT(timerUpdate())); + + backlight_timer = new QTimer(this); + QObject::connect(backlight_timer, SIGNAL(timeout()), this, SLOT(backlightUpdate())); + + int result = read_param(&brightness_b, "BRIGHTNESS_B", true); + result += read_param(&brightness_m, "BRIGHTNESS_M", true); + if(result != 0) { + brightness_b = 200.0; + brightness_m = 10.0; + } + smooth_brightness = 512; +} + +GLWindow::~GLWindow() { + makeCurrent(); + doneCurrent(); +} + +void GLWindow::initializeGL() { + initializeOpenGLFunctions(); + std::cout << "OpenGL version: " << glGetString(GL_VERSION) << std::endl; + std::cout << "OpenGL vendor: " << glGetString(GL_VENDOR) << std::endl; + std::cout << "OpenGL renderer: " << glGetString(GL_RENDERER) << std::endl; + std::cout << "OpenGL language version: " << glGetString(GL_SHADING_LANGUAGE_VERSION) << std::endl; + + ui_state = new UIState(); + ui_state->sound = &sound; + ui_state->fb_w = vwp_w; + ui_state->fb_h = vwp_h; + ui_init(ui_state); + + wake(); + + timer->start(0); + backlight_timer->start(BACKLIGHT_DT * 100); +} + +void GLWindow::backlightUpdate(){ + // Update brightness + float k = (BACKLIGHT_DT / BACKLIGHT_TS) / (1.0f + BACKLIGHT_DT / BACKLIGHT_TS); + + float clipped_brightness = std::min(1023.0f, (ui_state->light_sensor*brightness_m) + brightness_b); + smooth_brightness = clipped_brightness * k + smooth_brightness * (1.0f - k); + int brightness = smooth_brightness; + + if (!ui_state->awake){ + brightness = 0; + } + + std::thread{set_backlight, brightness}.detach(); +} + +void GLWindow::timerUpdate() { + if (ui_state->started != onroad){ + onroad = ui_state->started; + emit offroadTransition(!onroad); +#ifdef QCOM2 + timer->setInterval(onroad ? 0 : 1000); +#endif + } + + // Fix awake timeout if running 1 Hz when offroad + int dt = timer->interval() == 0 ? 1 : 20; + handle_display_state(ui_state, dt, false); + + ui_update(ui_state); + repaint(); +} + +void GLWindow::resizeGL(int w, int h) { + std::cout << "resize " << w << "x" << h << std::endl; +} + +void GLWindow::paintGL() { + ui_draw(ui_state); +} + +void GLWindow::wake(){ + // UI state might not be initialized yet + if (ui_state != nullptr){ + handle_display_state(ui_state, 1, true); + } +} + +GLuint visionimg_to_gl(const VisionImg *img, EGLImageKHR *pkhr, void **pph) { + unsigned int texture; + glGenTextures(1, &texture); + glBindTexture(GL_TEXTURE_2D, texture); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, img->width, img->height, 0, GL_RGB, GL_UNSIGNED_BYTE, *pph); + glGenerateMipmap(GL_TEXTURE_2D); + *pkhr = (EGLImageKHR)1; // not NULL + return texture; +} + +void visionimg_destroy_gl(EGLImageKHR khr, void *ph) { + // empty +} + +FramebufferState* framebuffer_init(const char* name, int32_t layer, int alpha, + int *out_w, int *out_h) { + return (FramebufferState*)1; // not null +} diff --git a/selfdrive/ui/qt/home.hpp b/selfdrive/ui/qt/home.hpp new file mode 100644 index 0000000000..e159668cc6 --- /dev/null +++ b/selfdrive/ui/qt/home.hpp @@ -0,0 +1,73 @@ +#pragma once + +#include +#include +#include +#include +#include +#include + +#include "qt_sound.hpp" +#include "ui/ui.hpp" + + +// container window for onroad NVG UI +class GLWindow : public QOpenGLWidget, protected QOpenGLFunctions { + Q_OBJECT + +public: + using QOpenGLWidget::QOpenGLWidget; + explicit GLWindow(QWidget *parent = 0); + void wake(); + ~GLWindow(); + + UIState *ui_state = nullptr; + +signals: + void offroadTransition(bool offroad); + +protected: + void initializeGL() override; + void resizeGL(int w, int h) override; + void paintGL() override; + +private: + QTimer *timer; + QTimer *backlight_timer; + + QtSound sound; + + bool onroad = true; + + // TODO: this shouldn't be here + float brightness_b = 0; + float brightness_m = 0; + float smooth_brightness = 0; + +public slots: + void timerUpdate(); + void backlightUpdate(); +}; + + +class HomeWindow : public QWidget { + Q_OBJECT + +public: + explicit HomeWindow(QWidget *parent = 0); + GLWindow *glWindow; + +signals: + void openSettings(); + +protected: + void mousePressEvent(QMouseEvent *e) override; + +private: + QWidget *home; + QGridLayout *layout; + +private slots: + void setVisibility(bool offroad); +}; + diff --git a/selfdrive/ui/qt/offroad/settings.cc b/selfdrive/ui/qt/offroad/settings.cc index a2bedb5818..20c5ce5918 100644 --- a/selfdrive/ui/qt/offroad/settings.cc +++ b/selfdrive/ui/qt/offroad/settings.cc @@ -18,7 +18,6 @@ #include "common/params.h" #include "common/utilpp.h" -const int SIDEBAR_WIDTH = 400; ParamsToggle::ParamsToggle(QString param, QString title, QString description, QString icon_path, QWidget *parent): QFrame(parent) , param(param) { QHBoxLayout *hlayout = new QHBoxLayout; @@ -56,20 +55,9 @@ ParamsToggle::ParamsToggle(QString param, QString title, QString description, QS } setStyleSheet(R"( - QCheckBox { - font-size: 70px; - } - QCheckBox::indicator { - width: 100px; - height: 100px; - } - QCheckBox::indicator:unchecked { - image: url(../assets/offroad/circled-checkmark-empty.png); - } - QCheckBox::indicator:checked { - image: url(../assets/offroad/circled-checkmark.png); + QLabel { + font-size: 50px; } - QLabel { font-size: 50px } * { background-color: #114265; } @@ -182,15 +170,18 @@ QWidget * developer_panel() { Params params = Params(); std::string brand = params.read_db_bool("Passive") ? "dashcam" : "openpilot"; - std::string os_version = util::read_file("/VERSION"); std::vector> labels = { {"Version", brand + " v" + params.get("Version", false)}, - {"OS Version", os_version}, {"Git Branch", params.get("GitBranch", false)}, {"Git Commit", params.get("GitCommit", false).substr(0, 10)}, {"Panda Firmware", params.get("PandaFirmwareHex", false)}, }; + std::string os_version = util::read_file("/VERSION"); + if (os_version.size()) { + labels.push_back({"OS Version", "AGNOS " + os_version}); + } + for (auto l : labels) { QString text = QString::fromStdString(l.first + ": " + l.second); main_layout->addWidget(new QLabel(text)); @@ -198,12 +189,16 @@ QWidget * developer_panel() { QWidget *widget = new QWidget; widget->setLayout(main_layout); + widget->setStyleSheet(R"( + QLabel { + font-size: 50px; + } + )"); return widget; } QWidget * network_panel(QWidget * parent) { WifiUI *w = new WifiUI(); - QObject::connect(w, SIGNAL(openKeyboard()), parent, SLOT(closeSidebar())); QObject::connect(w, SIGNAL(closeKeyboard()), parent, SLOT(openSidebar())); return w; @@ -267,7 +262,7 @@ SettingsWindow::SettingsWindow(QWidget *parent) : QWidget(parent) { panel_layout->addWidget(panel.second); QObject::connect(btn, SIGNAL(released()), this, SLOT(setActivePanel())); } - + // We either show the alerts, or the developer panel if (alerts_widget->show_alert){ panel_layout->setCurrentWidget(alerts_widget); @@ -275,16 +270,16 @@ SettingsWindow::SettingsWindow(QWidget *parent) : QWidget(parent) { QHBoxLayout *settings_layout = new QHBoxLayout(); settings_layout->addSpacing(45); + sidebar_widget = new QWidget; sidebar_widget->setLayout(sidebar_layout); - sidebar_widget->setFixedWidth(SIDEBAR_WIDTH); settings_layout->addWidget(sidebar_widget); settings_layout->addSpacing(45); settings_layout->addLayout(panel_layout); settings_layout->addSpacing(45); + setLayout(settings_layout); - setStyleSheet(R"( * { color: white; @@ -295,7 +290,7 @@ SettingsWindow::SettingsWindow(QWidget *parent) : QWidget(parent) { // Refreshes the offroad alerts from the params folder and sets up the sidebar alerts widget. // The function gets called every time a user opens the settings page -void SettingsWindow::refreshParams(){ +void SettingsWindow::refreshParams() { alerts_widget->refresh(); if (!alerts_widget->show_alert){ sidebar_alert_widget->setFixedHeight(0); @@ -303,21 +298,22 @@ void SettingsWindow::refreshParams(){ return; } - // Panel 0 contains the alerts or release notes. + // Panel 0 contains the alerts or release notes. panel_layout->setCurrentIndex(0); sidebar_alert_widget->setFixedHeight(100); sidebar_alert_widget->setStyleSheet(R"( background-color: #114267; )"); // light blue - + // Check for alerts int alerts = alerts_widget->alerts.size(); if (!alerts){ - //There is a new release + // There is a new release sidebar_alert_widget->setText("UPDATE"); return; } - //Check if there is an important alert + + // Check if there is an important alert bool existsImportantAlert = false; for (auto alert : alerts_widget->alerts){ if (alert.severity){ @@ -332,15 +328,19 @@ void SettingsWindow::refreshParams(){ )"); //dark red } } -void SettingsWindow::closeAlerts(){ + +void SettingsWindow::closeAlerts() { panel_layout->setCurrentIndex(1); } -void SettingsWindow::openAlerts(){ + +void SettingsWindow::openAlerts() { panel_layout->setCurrentIndex(0); } -void SettingsWindow::closeSidebar(){ - sidebar_widget->setFixedWidth(0); + +void SettingsWindow::closeSidebar() { + sidebar_widget->setVisible(false); } -void SettingsWindow::openSidebar(){ - sidebar_widget->setFixedWidth(SIDEBAR_WIDTH); + +void SettingsWindow::openSidebar() { + sidebar_widget->setVisible(true); } diff --git a/selfdrive/ui/qt/offroad/settings.hpp b/selfdrive/ui/qt/offroad/settings.hpp index a34f6bec75..a0be4712dd 100644 --- a/selfdrive/ui/qt/offroad/settings.hpp +++ b/selfdrive/ui/qt/offroad/settings.hpp @@ -1,30 +1,33 @@ #pragma once - #include #include #include -#include -#include #include +#include #include "wifi.hpp" #include "widgets/offroad_alerts.hpp" +// *** settings widgets *** + class ParamsToggle : public QFrame { Q_OBJECT public: - explicit ParamsToggle(QString param, QString title, QString description, QString icon, QWidget *parent = 0); + explicit ParamsToggle(QString param, QString title, QString description, + QString icon, QWidget *parent = 0); private: - QCheckBox *checkbox; QString param; public slots: void checkboxClicked(int state); }; + +// *** settings window *** + class SettingsWindow : public QWidget { Q_OBJECT @@ -42,7 +45,6 @@ private: std::map panels; QStackedLayout *panel_layout; - public slots: void setActivePanel(); void closeAlerts(); diff --git a/selfdrive/ui/qt/ui.cc b/selfdrive/ui/qt/ui.cc index 28b673a75f..93eb77f911 100644 --- a/selfdrive/ui/qt/ui.cc +++ b/selfdrive/ui/qt/ui.cc @@ -4,7 +4,6 @@ #include "qt_window.hpp" int main(int argc, char *argv[]) { - // TODO: should probably be done in gl window QSurfaceFormat fmt; #ifdef __APPLE__ fmt.setVersion(3, 2); diff --git a/selfdrive/ui/qt/window.cc b/selfdrive/ui/qt/window.cc index c3b1993ea9..78fe877c82 100644 --- a/selfdrive/ui/qt/window.cc +++ b/selfdrive/ui/qt/window.cc @@ -1,57 +1,10 @@ -#include -#include -#include -#include -#include -#include -#include - -#include -#include - #include "window.hpp" -#include "qt_window.hpp" -#include "offroad/settings.hpp" -#include "offroad/onboarding.hpp" - -#include "paint.hpp" -#include "common/util.h" -#include "common/timing.h" - -#define BACKLIGHT_DT 0.25 -#define BACKLIGHT_TS 2.00 - -volatile sig_atomic_t do_exit = 0; - -static void handle_display_state(UIState *s, int dt, bool user_input) { - static int awake_timeout = 0; - awake_timeout = std::max(awake_timeout-dt, 0); - - if (user_input || s->ignition || s->started) { - s->awake = true; - awake_timeout = 30*UI_FREQ; - } else if (awake_timeout == 0){ - s->awake = false; - } -} - -static void set_backlight(int brightness){ - std::ofstream brightness_control("/sys/class/backlight/panel0-backlight/brightness"); - if (brightness_control.is_open()){ - brightness_control << brightness << "\n"; - brightness_control.close(); - } -} MainWindow::MainWindow(QWidget *parent) : QWidget(parent) { main_layout = new QStackedLayout; -#ifdef QCOM2 - set_core_affinity(7); -#endif - - glWindow = new GLWindow(this); - main_layout->addWidget(glWindow); + homeWindow = new HomeWindow(this); + main_layout->addWidget(homeWindow); settingsWindow = new SettingsWindow(this); main_layout->addWidget(settingsWindow); @@ -61,7 +14,7 @@ MainWindow::MainWindow(QWidget *parent) : QWidget(parent) { main_layout->setMargin(0); setLayout(main_layout); - QObject::connect(glWindow, SIGNAL(openSettings()), this, SLOT(openSettings())); + QObject::connect(homeWindow, SIGNAL(openSettings()), this, SLOT(openSettings())); QObject::connect(settingsWindow, SIGNAL(closeSettings()), this, SLOT(closeSettings())); // start at onboarding @@ -78,139 +31,17 @@ MainWindow::MainWindow(QWidget *parent) : QWidget(parent) { } void MainWindow::openSettings() { - main_layout->setCurrentIndex(1); + main_layout->setCurrentWidget(settingsWindow); settingsWindow->refreshParams(); } void MainWindow::closeSettings() { - main_layout->setCurrentIndex(0); + main_layout->setCurrentWidget(homeWindow); } - bool MainWindow::eventFilter(QObject *obj, QEvent *event){ if (event->type() == QEvent::MouseButtonPress) { - glWindow->wake(); + homeWindow->glWindow->wake(); } return false; } - - -GLWindow::GLWindow(QWidget *parent) : QOpenGLWidget(parent) { - timer = new QTimer(this); - QObject::connect(timer, SIGNAL(timeout()), this, SLOT(timerUpdate())); - - backlight_timer = new QTimer(this); - QObject::connect(backlight_timer, SIGNAL(timeout()), this, SLOT(backlightUpdate())); - - int result = read_param(&brightness_b, "BRIGHTNESS_B", true); - result += read_param(&brightness_m, "BRIGHTNESS_M", true); - if(result != 0) { - brightness_b = 200.0; - brightness_m = 10.0; - } - smooth_brightness = 512; -} - -GLWindow::~GLWindow() { - makeCurrent(); - doneCurrent(); -} - -void GLWindow::initializeGL() { - initializeOpenGLFunctions(); - std::cout << "OpenGL version: " << glGetString(GL_VERSION) << std::endl; - std::cout << "OpenGL vendor: " << glGetString(GL_VENDOR) << std::endl; - std::cout << "OpenGL renderer: " << glGetString(GL_RENDERER) << std::endl; - std::cout << "OpenGL language version: " << glGetString(GL_SHADING_LANGUAGE_VERSION) << std::endl; - - ui_state = new UIState(); - ui_state->sound = &sound; - ui_state->fb_w = vwp_w; - ui_state->fb_h = vwp_h; - ui_init(ui_state); - - wake(); - - timer->start(0); - backlight_timer->start(BACKLIGHT_DT * 100); -} - -void GLWindow::backlightUpdate(){ - // Update brightness - float k = (BACKLIGHT_DT / BACKLIGHT_TS) / (1.0f + BACKLIGHT_DT / BACKLIGHT_TS); - - float clipped_brightness = std::min(1023.0f, (ui_state->light_sensor*brightness_m) + brightness_b); - smooth_brightness = clipped_brightness * k + smooth_brightness * (1.0f - k); - int brightness = smooth_brightness; - - if (!ui_state->awake){ - brightness = 0; - } - - std::thread{set_backlight, brightness}.detach(); -} - -void GLWindow::timerUpdate(){ -#ifdef QCOM2 - if (ui_state->started != onroad){ - onroad = ui_state->started; - timer->setInterval(onroad ? 0 : 1000); - } -#endif - - // Fix awake timeout if running 1 Hz when offroad - int dt = timer->interval() == 0 ? 1 : 20; - handle_display_state(ui_state, dt, false); - - ui_update(ui_state); - repaint(); -} - -void GLWindow::resizeGL(int w, int h) { - std::cout << "resize " << w << "x" << h << std::endl; -} - -void GLWindow::paintGL() { - ui_draw(ui_state); -} - -void GLWindow::wake(){ - // UI state might not be initialized yet - if (ui_state != nullptr){ - handle_display_state(ui_state, 1, true); - } -} - -void GLWindow::mousePressEvent(QMouseEvent *e) { - wake(); - - // Settings button click - if (!ui_state->scene.uilayout_sidebarcollapsed && settings_btn.ptInRect(e->x(), e->y())) { - emit openSettings(); - } - - // Vision click - if (ui_state->started && (e->x() >= ui_state->scene.viz_rect.x - bdr_s)){ - ui_state->scene.uilayout_sidebarcollapsed = !ui_state->scene.uilayout_sidebarcollapsed; - } -} - - -GLuint visionimg_to_gl(const VisionImg *img, EGLImageKHR *pkhr, void **pph) { - unsigned int texture; - glGenTextures(1, &texture); - glBindTexture(GL_TEXTURE_2D, texture); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, img->width, img->height, 0, GL_RGB, GL_UNSIGNED_BYTE, *pph); - glGenerateMipmap(GL_TEXTURE_2D); - *pkhr = (EGLImageKHR)1; // not NULL - return texture; -} - -void visionimg_destroy_gl(EGLImageKHR khr, void *ph) { - // empty -} - -FramebufferState* framebuffer_init(const char* name, int32_t layer, int alpha, - int *out_w, int *out_h) { - return (FramebufferState*)1; // not null -} diff --git a/selfdrive/ui/qt/window.hpp b/selfdrive/ui/qt/window.hpp index d97572b5b5..10822f1fbc 100644 --- a/selfdrive/ui/qt/window.hpp +++ b/selfdrive/ui/qt/window.hpp @@ -1,55 +1,11 @@ #pragma once -#include - #include -#include -#include -#include #include -#include "qt/qt_sound.hpp" #include "offroad/settings.hpp" #include "offroad/onboarding.hpp" -#include "ui/ui.hpp" - - -class GLWindow : public QOpenGLWidget, protected QOpenGLFunctions { - Q_OBJECT - -public: - using QOpenGLWidget::QOpenGLWidget; - explicit GLWindow(QWidget *parent = 0); - void wake(); - ~GLWindow(); - -protected: - void mousePressEvent(QMouseEvent *e) override; - void initializeGL() override; - void resizeGL(int w, int h) override; - void paintGL() override; - -private: - QTimer * timer; - QTimer * backlight_timer; - - UIState * ui_state = nullptr; - QtSound sound; - - bool onroad = true; - - // TODO: this shouldn't be here - float brightness_b = 0; - float brightness_m = 0; - float smooth_brightness = 0; - -public slots: - void timerUpdate(); - void backlightUpdate(); - -signals: - void openSettings(); -}; +#include "home.hpp" class MainWindow : public QWidget { Q_OBJECT @@ -62,7 +18,7 @@ public: private: QStackedLayout *main_layout; - GLWindow *glWindow; + HomeWindow *homeWindow; SettingsWindow *settingsWindow; OnboardingWindow *onboardingWindow; diff --git a/selfdrive/ui/ui.hpp b/selfdrive/ui/ui.hpp index 023bc86672..eccb4c1655 100644 --- a/selfdrive/ui/ui.hpp +++ b/selfdrive/ui/ui.hpp @@ -7,7 +7,6 @@ #define nvgCreate nvgCreateGL3 #else #include -#include #define NANOVG_GLES3_IMPLEMENTATION #define nvgCreate nvgCreateGLES3 #endif