15 #include "DisplayPlugin.h"
17 #include <condition_variable>
21 #include <QtCore/QThread>
22 #include <QtCore/QTimer>
23 #include <QtGui/QImage>
25 #include <GLMHelpers.h>
26 #include <SimpleMovingAverage.h>
27 #include <shared/RateCounter.h>
29 #include <gpu/Batch.h>
30 #include <vk/VKWindow.h>
32 class RefreshRateController;
34 class VulkanDisplayPlugin :
public DisplayPlugin {
36 Q_PROPERTY(
float hudAlpha MEMBER _hudAlpha)
37 using Parent = DisplayPlugin;
40 using Mutex = std::mutex;
41 using Lock = std::unique_lock<Mutex>;
42 using Condition = std::condition_variable;
45 ~VulkanDisplayPlugin();
49 static std::function<void(
int)> getRefreshRateOperator();
51 bool activate() override final;
52 void deactivate() override final;
53 bool startStandBySession() override final;
54 void endSession() override final;
55 bool eventFilter(QObject* receiver, QEvent* event) override;
56 bool isDisplayVisible()
const override {
return true; }
57 bool isSupported()
const override;
58 void captureFrame(
const std::string& outputName)
const override;
59 void submitFrame(
const gpu::FramePointer& newFrame)
override;
61 glm::uvec2 getRecommendedRenderSize()
const override {
return getSurfacePixels(); }
63 glm::uvec2 getRecommendedUiSize()
const override {
return getSurfaceSize(); }
65 virtual bool setDisplayTexture(
const QString& name)
override;
66 virtual bool onDisplayTextureReset() {
return false; };
68 float presentRate()
const override;
70 void resetPresentRate()
override;
72 float newFramePresentRate()
const override;
74 float droppedFrameRate()
const override;
76 float renderRate()
const override;
78 bool beginFrameRender(uint32_t frameIndex)
override;
80 virtual bool wantVsync()
const {
return true; }
81 void setVsyncEnabled(
bool vsyncEnabled) { _vsyncEnabled = vsyncEnabled; }
82 bool isVsyncEnabled()
const {
return _vsyncEnabled; }
85 int getRequiredThreadCount()
const override {
return 1; }
87 virtual std::function<void(gpu::Batch&,
const gpu::TexturePointer&)> getHUDOperator()
override;
88 void copyTextureToQuickFramebuffer(NetworkTexturePointer source,
89 QOpenGLFramebufferObject* target,
90 GLsync* fenceSync)
override;
92 virtual const QString getName()
const override {
return "Vulkan window"; }
93 virtual void pluginUpdate()
override {};
96 friend class VulkanPresentThread;
98 glm::uvec2 getSurfaceSize()
const;
99 glm::uvec2 getSurfacePixels()
const;
104 virtual bool alwaysPresent()
const {
return false; }
106 void updateCompositeFramebuffer();
108 virtual QThread::Priority getPresentPriority() {
return QThread::HighPriority; }
109 virtual void compositeLayers();
110 virtual void setupCompositeScenePipeline(gpu::Batch& batch);
111 virtual void compositeScene();
112 virtual void compositePointer();
113 virtual void compositeExtra(){};
116 virtual void customizeContext();
117 virtual void uncustomizeContext();
120 virtual bool internalActivate() {
return true; }
121 virtual void internalDeactivate() {}
124 virtual bool activateStandBySession() {
return true; }
125 virtual void deactivateSession() {}
128 virtual void internalPresent();
130 void renderFromTexture(gpu::Batch& batch,
131 const gpu::TexturePointer& texture,
132 const glm::ivec4& viewport,
133 const glm::ivec4& scissor,
134 const gpu::FramebufferPointer& fbo);
135 void renderFromTexture(gpu::Batch& batch,
136 const gpu::TexturePointer& texture,
137 const glm::ivec4& viewport,
138 const glm::ivec4& scissor);
139 virtual void updateFrameData();
140 virtual glm::mat4 getViewCorrection() {
return glm::mat4(); }
142 void withOtherThreadContext(std::function<
void()> f)
const;
144 void present(
const std::shared_ptr<RefreshRateController>& refreshRateController);
145 virtual void swapBuffers();
147 void render(std::function<
void(gpu::Batch& batch)> f);
149 bool _vsyncEnabled{
true };
150 QThread* _presentThread{
nullptr };
151 std::queue<gpu::FramePointer> _newFrameQueue;
152 RateCounter<200> _droppedFrameRate;
153 RateCounter<200> _newFrameRate;
154 RateCounter<200> _presentRate;
155 RateCounter<200> _renderRate;
157 gpu::FramePointer _currentFrame;
158 gpu::Frame* _lastFrame{
nullptr };
159 mat4 _prevRenderView;
160 gpu::FramebufferPointer _compositeFramebuffer;
161 gpu::PipelinePointer _hudPipeline;
162 gpu::PipelinePointer _mirrorHUDPipeline;
163 gpu::ShaderPointer _mirrorHUDPS;
164 gpu::PipelinePointer _drawTexturePipeline;
165 gpu::PipelinePointer _drawTextureSqueezePipeline;
166 gpu::PipelinePointer _linearToSRGBPipeline;
167 gpu::PipelinePointer _SRGBToLinearPipeline;
168 gpu::PipelinePointer _cursorPipeline;
169 gpu::TexturePointer _displayTexture{};
170 float _compositeHUDAlpha{ 1.0f };
172 virtual gpu::PipelinePointer getRenderTexturePipeline();
178 gpu::TexturePointer texture;
181 std::map<uint16_t, CursorData> _cursorsData;
182 bool _lockCurrentTexture{
false };
184 void assertNotPresentThread()
const;
185 void assertIsPresentThread()
const;
187 template <
typename F>
188 void withPresentThreadLock(F f)
const {
189 assertIsPresentThread();
190 Lock lock(_presentMutex);
194 template <
typename F>
195 void withNonPresentThreadLock(F f)
const {
196 assertNotPresentThread();
197 Lock lock(_presentMutex);
201 const gpu::BackendPointer& getBackend()
const;
205 mutable Mutex _presentMutex;
206 float _hudAlpha{ 1.0f };
208 QImage getScreenshot(
float aspectRatio);
209 QImage getSecondaryCameraScreenshot();
212 VKWindow *_vkWindow{ 0 };
213 int _renderedFrameCount{ 0 };