Overte C++ Documentation
plugins/src/plugins/DisplayPlugin.h
1 //
2 // Created by Bradley Austin Davis on 2015/05/29
3 // Copyright 2015 High Fidelity, Inc.
4 //
5 // Distributed under the Apache License, Version 2.0.
6 // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
7 //
8 #pragma once
9 
10 #include <functional>
11 #include <atomic>
12 
13 #include <glm/glm.hpp>
14 #include <glm/gtc/quaternion.hpp>
15 
16 #include <QtCore/QSize>
17 #include <QtCore/QPoint>
18 #include <QtCore/QElapsedTimer>
19 #include <QtCore/QJsonObject>
20 #include <QtCore/QMutex>
21 #include <QtCore/QSharedPointer>
22 #include <QtCore/QWaitCondition>
23 
24 #include <GLMHelpers.h>
25 #include <NumericalConstants.h>
26 #include <RegisteredMetaTypes.h>
27 #include <shared/Bilateral.h>
28 #include <SimpleMovingAverage.h>
29 #include <gpu/Forward.h>
30 #include "Plugin.h"
31 #include "StencilMaskMode.h"
32 
33 class QOpenGLFramebufferObject;
34 
35 class QImage;
36 
37 enum Eye {
38  Left = (int)bilateral::Side::Left,
39  Right = (int)bilateral::Side::Right
40 };
41 
42 /*
43  * Helper method to iterate over each eye
44  */
45 template <typename F>
46 void for_each_eye(F f) {
47  f(Left);
48  f(Right);
49 }
50 
51 /*
52  * Helper method to iterate over each eye, with an additional lambda to take action between the eyes
53  */
54 template <typename F, typename FF>
55 void for_each_eye(F f, FF ff) {
56  f(Eye::Left);
57  ff();
58  f(Eye::Right);
59 }
60 
61 class QWindow;
62 
63 #define AVERAGE_HUMAN_IPD 0.064f
64 
65 namespace gpu {
66  class Texture;
67  using TexturePointer = std::shared_ptr<Texture>;
68 }
69 
70 class NetworkTexture;
71 using NetworkTexturePointer = QSharedPointer<NetworkTexture>;
72 typedef struct __GLsync *GLsync;
73 
74 // Stereo display functionality
75 // TODO move out of this file don't derive DisplayPlugin from this. Instead use dynamic casting when
76 // displayPlugin->isStereo returns true
77 class StereoDisplay {
78 public:
79  // Stereo specific methods
80  virtual glm::mat4 getEyeProjection(Eye eye, const glm::mat4& baseProjection) const {
81  return baseProjection;
82  }
83 
84  virtual glm::mat4 getCullingProjection(const glm::mat4& baseProjection) const {
85  return baseProjection;
86  }
87 
88  virtual float getIPD() const { return AVERAGE_HUMAN_IPD; }
89 };
90 
91 // HMD display functionality
92 // TODO move out of this file don't derive DisplayPlugin from this. Instead use dynamic casting when
93 // displayPlugin->isHmd returns true
94 class RefreshRateController;
95 class HmdDisplay : public StereoDisplay {
96 public:
97  // HMD specific methods
98  // TODO move these into another class?
99  virtual glm::mat4 getEyeToHeadTransform(Eye eye) const;
100 
101  // returns a copy of the most recent head pose, computed via updateHeadPose
102  virtual glm::mat4 getHeadPose() const {
103  return glm::mat4();
104  }
105 
106  virtual void abandonCalibration() {}
107 
108  virtual void resetSensors() {}
109 
110  enum Hand {
111  LeftHand = 0x01,
112  RightHand = 0x02,
113  };
114 
115  virtual bool suppressKeyboard() { return false; }
116  virtual void unsuppressKeyboard() {};
117  virtual bool isKeyboardVisible() { return false; }
118 
119  virtual QRectF getPlayAreaRect() { return QRectF(); }
120  virtual QVector<glm::vec3> getSensorPositions() { return QVector<glm::vec3>(); }
121 };
122 
123 class DisplayPlugin : public Plugin, public HmdDisplay {
124  Q_OBJECT
125  using Parent = Plugin;
126 public:
127  virtual int getRequiredThreadCount() const { return 0; }
128  virtual bool isHmd() const { return false; }
129  virtual int getHmdScreen() const { return -1; }
131  virtual bool isStereo() const { return isHmd(); }
132  virtual bool isThrottled() const { return false; }
133 
134  virtual float getTargetFrameRate() const { return 1.0f; }
135  virtual bool hasAsyncReprojection() const { return false; }
136 
141  virtual bool isDisplayVisible() const { return false; }
142 
143  virtual QString getPreferredAudioInDevice() const { return QString(); }
144  virtual QString getPreferredAudioOutDevice() const { return QString(); }
145 
146  // Rendering support
147  virtual void setContext(const gpu::ContextPointer& context) final { _gpuContext = context; }
148  virtual void submitFrame(const gpu::FramePointer& newFrame) = 0;
149  virtual void captureFrame(const std::string& outputName) const { }
150 
151  // The size of the rendering target (may be larger than the device size due to distortion)
152  virtual glm::uvec2 getRecommendedRenderSize() const = 0;
153 
154  // The size of the UI
155  virtual glm::uvec2 getRecommendedUiSize() const {
156  return getRecommendedRenderSize();
157  }
158 
159  // By default the aspect ratio is just the render size
160  virtual float getRecommendedAspectRatio() const {
161  return aspect(getRecommendedRenderSize());
162  }
163 
164  // The recommended bounds for primary HUD placement
165  virtual QRect getRecommendedHUDRect() const {
166  const int DESKTOP_SCREEN_PADDING = 50;
167  auto recommendedSize = getRecommendedUiSize() - glm::uvec2(DESKTOP_SCREEN_PADDING);
168  return QRect(0, 0, recommendedSize.x, recommendedSize.y);
169  }
170 
171  // will query the underlying hmd api to compute the most recent head pose
172  virtual bool beginFrameRender(uint32_t frameIndex) { return true; }
173 
174  // Set the texture to display on the monitor and return true, if allowed. Empty string resets.
175  virtual bool setDisplayTexture(const QString& name) { return false; }
176 
177  virtual float devicePixelRatio() { return 1.0f; }
178  // Rate at which we render frames
179  virtual float renderRate() const { return -1.0f; }
180  // Rate at which we present to the display device
181  virtual float presentRate() const { return -1.0f; }
182  // Reset the present rate tracking (useful for if the target frame rate changes as in ASW for Oculus)
183  virtual void resetPresentRate() {}
184  // Return the present rate as fraction of the target present rate (hopefully 0.0 and 1.0)
185  virtual float normalizedPresentRate() const { return presentRate() / getTargetFrameRate(); }
186 
187  // Rate at which old frames are presented to the device display
188  virtual float stutterRate() const { return -1.0f; }
189  // Rate at which new frames are being presented to the display device
190  virtual float newFramePresentRate() const { return -1.0f; }
191  // Rate at which rendered frames are being skipped
192  virtual float droppedFrameRate() const { return -1.0f; }
193  virtual bool getSupportsAutoSwitch() { return false; }
194 
195  // Hardware specific stats
196  virtual QJsonObject getHardwareStats() const { return QJsonObject(); }
197 
198  virtual void copyTextureToQuickFramebuffer(NetworkTexturePointer source, QOpenGLFramebufferObject* target, GLsync* fenceSync) = 0;
199 
200  uint32_t presentCount() const { return _presentedFrameIndex; }
201  // Time since last call to incrementPresentCount (only valid if DEBUG_PAINT_DELAY is defined)
202  int64_t getPaintDelayUsecs() const;
203 
204  virtual void cycleDebugOutput() {}
205 
206  void waitForPresent();
207  float getAveragePresentTime() { return _movingAveragePresent.average / (float)USECS_PER_MSEC; } // in msec
208 
209  static const QString& MENU_PATH();
210 
211  // for updating plugin-related commands. Mimics the input plugin.
212  virtual void pluginUpdate() = 0;
213 
214  virtual std::function<void(gpu::Batch&, const gpu::TexturePointer&)> getHUDOperator() { return nullptr; }
215  virtual StencilMaskMode getStencilMaskMode() const { return StencilMaskMode::NONE; }
216  using StencilMaskMeshOperator = std::function<void(gpu::Batch&)>;
217  virtual StencilMaskMeshOperator getStencilMaskMeshOperator() { return nullptr; }
218  virtual void updateParameters(float visionSqueezeX, float visionSqueezeY, float visionSqueezeTransition,
219  int visionSqueezePerEye, float visionSqueezeGroundPlaneY,
220  float visionSqueezeSpotlightSize) {}
221 
222 signals:
223  void recommendedFramebufferSizeChanged(const QSize& size);
224  void resetSensorsRequested();
225  void presented(quint32 frame);
226 
227 protected:
228  void incrementPresentCount();
229 
230  gpu::ContextPointer _gpuContext;
231 
232  MovingAverage<float, 10> _movingAveragePresent;
233 
234 private:
235  QMutex _presentMutex;
236  QWaitCondition _presentCondition;
237  std::atomic<uint32_t> _presentedFrameIndex;
238  mutable std::mutex _paintDelayMutex;
239  QElapsedTimer _paintDelayTimer;
240 };
241 
A texture loaded from the network.
Definition: material-networking/src/material-networking/TextureCache.h:52
A simple object wrapper for an OpenGL texture.
Definition: material-networking/src/material-networking/TextureCache.h:39