1 /* Copyright (c) 2013-2015 Jeffrey Pfau 2 * 3 * This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 #pragma once 7 8 #if defined(BUILD_GL) || defined(BUILD_GLES2) 9 10 #include "Display.h" 11 12 #ifdef USE_EPOXY 13 #include <epoxy/gl.h> 14 #ifndef GLdouble 15 #define GLdouble GLdouble 16 #endif 17 #endif 18 19 #include <QAtomicInt> 20 #include <QElapsedTimer> 21 #include <QHash> 22 #include <QList> 23 #include <QMouseEvent> 24 #include <QOpenGLContext> 25 #include <QPainter> 26 #include <QQueue> 27 #include <QThread> 28 #include <QTimer> 29 30 #include <array> 31 32 #include "CoreController.h" 33 #include "VideoProxy.h" 34 35 #include "platform/video-backend.h" 36 37 class QOpenGLPaintDevice; 38 39 uint qHash(const QSurfaceFormat&, uint seed = 0); 40 41 namespace QGBA { 42 43 class PainterGL; 44 class DisplayGL : public Display { 45 Q_OBJECT 46 47 public: 48 DisplayGL(const QSurfaceFormat& format, QWidget* parent = nullptr); 49 ~DisplayGL(); 50 51 void startDrawing(std::shared_ptr<CoreController>) override; isDrawing()52 bool isDrawing() const override { return m_isDrawing; } 53 bool supportsShaders() const override; 54 VideoShader* shaders() override; 55 void setVideoProxy(std::shared_ptr<VideoProxy>) override; 56 int framebufferHandle() override; 57 58 static bool supportsFormat(const QSurfaceFormat&); 59 60 public slots: 61 void stopDrawing() override; 62 void pauseDrawing() override; 63 void unpauseDrawing() override; 64 void forceDraw() override; 65 void lockAspectRatio(bool lock) override; 66 void lockIntegerScaling(bool lock) override; 67 void interframeBlending(bool enable) override; 68 void showOSDMessages(bool enable) override; 69 void filter(bool filter) override; 70 void framePosted() override; 71 void setShaders(struct VDir*) override; 72 void clearShaders() override; 73 void resizeContext() override; 74 void setVideoScale(int scale) override; 75 76 protected: paintEvent(QPaintEvent *)77 virtual void paintEvent(QPaintEvent*) override { forceDraw(); } 78 virtual void resizeEvent(QResizeEvent*) override; 79 80 private: 81 void resizePainter(); 82 83 static QHash<QSurfaceFormat, bool> s_supports; 84 85 bool m_isDrawing = false; 86 bool m_hasStarted = false; 87 std::unique_ptr<PainterGL> m_painter; 88 QThread m_drawThread; 89 std::shared_ptr<CoreController> m_context; 90 }; 91 92 class PainterGL : public QObject { 93 Q_OBJECT 94 95 public: 96 PainterGL(QWindow* surface, const QSurfaceFormat& format); 97 ~PainterGL(); 98 99 void setThread(QThread*); 100 void setContext(std::shared_ptr<CoreController>); 101 void setMessagePainter(MessagePainter*); 102 void enqueue(const uint32_t* backing); 103 supportsShaders()104 bool supportsShaders() const { return m_supportsShaders; } 105 int glTex(); 106 107 void setVideoProxy(std::shared_ptr<VideoProxy>); 108 void interrupt(); 109 110 public slots: 111 void create(); 112 void destroy(); 113 114 void forceDraw(); 115 void draw(); 116 void start(); 117 void stop(); 118 void pause(); 119 void unpause(); 120 void resize(const QSize& size); 121 void lockAspectRatio(bool lock); 122 void lockIntegerScaling(bool lock); 123 void interframeBlending(bool enable); 124 void showOSD(bool enable); 125 void filter(bool filter); 126 void resizeContext(); 127 128 void setShaders(struct VDir*); 129 void clearShaders(); 130 VideoShader* shaders(); 131 132 signals: 133 void started(); 134 135 private: 136 void makeCurrent(); 137 void performDraw(); 138 void dequeue(); 139 void dequeueAll(bool keep = false); 140 141 std::array<std::array<uint32_t, 0x100000>, 3> m_buffers; 142 QList<uint32_t*> m_free; 143 QQueue<uint32_t*> m_queue; 144 uint32_t* m_buffer = nullptr; 145 QPainter m_painter; 146 QMutex m_mutex; 147 QWindow* m_surface; 148 QSurfaceFormat m_format; 149 std::unique_ptr<QOpenGLPaintDevice> m_window; 150 std::unique_ptr<QOpenGLContext> m_gl; 151 bool m_active = false; 152 bool m_started = false; 153 QTimer m_drawTimer; 154 std::shared_ptr<CoreController> m_context; 155 CoreController::Interrupter m_interrupter; 156 bool m_supportsShaders; 157 bool m_showOSD; 158 VideoShader m_shader{}; 159 VideoBackend* m_backend = nullptr; 160 QSize m_size; 161 QSize m_dims; 162 MessagePainter* m_messagePainter = nullptr; 163 QElapsedTimer m_delayTimer; 164 std::shared_ptr<VideoProxy> m_videoProxy; 165 }; 166 167 } 168 169 #endif 170