CVB++ 15.0
decl_opengl_image_renderer_factory.hpp
1#pragma once
2
3#ifdef _MSC_VER
4# pragma warning(push, 1)
5# pragma warning(disable : 4127)
6# pragma warning(disable : 4005) // macro redefinition // TODO
7#endif
8
9#include <QSurfaceFormat>
10#include <QOffscreenSurface>
11#include <QScreen>
12#include <QSysInfo>
13
14#if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)
15# include <QOpenGLExtraFunctions>
16#endif
17
18#ifdef _MSC_VER
19# pragma warning(pop)
20#endif
21
22#include "../../global.hpp"
23
24#include "../ui.hpp"
25
26#include "decl_opengl_image_renderer.hpp"
27
28namespace Cvb
29{
30
31 CVB_BEGIN_INLINE_NS
32
33 namespace UI
34 {
35
37
45 class OpenGLImageRendererFactory final
46 {
47 public:
49
55
57
62 static QSurfaceFormat CreateFormat(int version);
63
65
71 static bool TryVersion(int version) noexcept;
72
74
80 static bool TryVersion(int version, QSurfaceFormat &format) noexcept;
81
83
88 static String VendorName(int version);
89
91
97 static String RendererName(int version);
98
99 private:
100#if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)
101 class GL3ImageRenderer : public OpenGLImageRenderer
102 {
103 public:
104 GL3ImageRenderer() noexcept;
105
106 void UpdateBufferFormat(const OpenGLBufferFormat &bufferFormat) noexcept override;
107
108 void *BeginBufferAccess(int &linePad) noexcept override
109 {
110
111 linePad = BufferFormat().LinePad;
112 BindTexture();
113 pixelBuffer_.Bind();
114 pixelBuffer_.Data();
115 return pixelBuffer_.Map();
116 }
117
118 void EndBufferAccess() noexcept override
119 {
120
121 pixelBuffer_.Unmap();
122
123 Image2DTexture(nullptr, true);
124 pixelBuffer_.Release();
125 ReleaseTexture();
126 }
127
128 bool MonoUploadSupported() const noexcept override
129 {
130 return true;
131 }
132
133 private:
134 class GLPixelBuffer : public QOpenGLExtraFunctions
135 {
136 public:
137 GLPixelBuffer() noexcept;
138 GLPixelBuffer(const GLPixelBuffer &other) = delete;
139 GLPixelBuffer &operator=(const GLPixelBuffer &other) = delete;
140 GLPixelBuffer(GLPixelBuffer &&other) = delete;
141 GLPixelBuffer &operator=(GLPixelBuffer &&other) = delete;
142 ~GLPixelBuffer();
143
144 void Bind() noexcept;
145 void Release() noexcept;
146
147 void Data() noexcept;
148 void Data(int size) noexcept;
149
150 void *Map() noexcept;
151 void Unmap() noexcept;
152
153 private:
154 GLuint handle_ = 0;
155
156 int size_ = 0;
157 };
158 GLPixelBuffer pixelBuffer_;
159 };
160#endif
161
162 class GL2ImageRenderer : public OpenGLImageRenderer
163 {
164 public:
165 GL2ImageRenderer() noexcept
167 {
168 }
169
170 void UpdateBufferFormat(const OpenGLBufferFormat &bufferFormat) noexcept override;
171
172 void *BeginBufferAccess(int & /*linePad*/) noexcept override
173 {
174 return &pixelBuffer_[0];
175 }
176
177 void EndBufferAccess() noexcept override
178 {
179 BindTexture();
180 Image2DTexture(BufferFormat(), &pixelBuffer_[0], false);
181 ReleaseTexture();
182 }
183
184 bool MonoUploadSupported() const noexcept override
185 {
186 return false;
187 }
188
189 private:
190 std::vector<std::uint8_t> pixelBuffer_;
191 };
192
193 OpenGLImageRendererFactory() noexcept = delete;
194
195 static bool TryFormat(const QSurfaceFormat &format, int minVersion) noexcept
196 {
197 QOpenGLContext context;
198 context.setFormat(format);
199 if (!context.create())
200 return false;
201
202 auto effectiveFormat = context.format();
203 if (effectiveFormat.majorVersion() < minVersion // we did not get what is needed
204 // we got OpenGL ES 3 outside arm, this will not work
205 || (effectiveFormat.majorVersion() == 3 && effectiveFormat.renderableType() == QSurfaceFormat::OpenGLES
206 && !(QSysInfo::currentCpuArchitecture().startsWith("arm")))
207 // we got OpenGL 2 (not ES) this will not work either
208 || (effectiveFormat.majorVersion() == 2 && effectiveFormat.renderableType() != QSurfaceFormat::OpenGLES))
209 return false;
210 if (effectiveFormat.profile() == QSurfaceFormat::CoreProfile)
211 return false;
212
213 return true;
214 }
215
216 static String ReadString(int version, int value)
217 {
218 auto format = CreateFormat(version);
219
220 QOpenGLContext context;
221 context.setFormat(format);
222 if (!context.create())
223 throw std::runtime_error("failed to create context for already verified OpenGL version.");
224
225 QOffscreenSurface surface;
226 context.makeCurrent(&surface);
227 QOpenGLFunctions fnc;
228 fnc.initializeOpenGLFunctions();
229
230 QString vendor(reinterpret_cast<const char *>(fnc.glGetString(static_cast<GLenum>(value))));
231 return QtToCvb(vendor);
232 }
233 };
234
235 } // namespace UI
236
237 CVB_END_INLINE_NS
238
239} // namespace Cvb
static QSurfaceFormat CreateFormat(int version)
Create a OpenGL format for the given version.
Definition detail_opengl_image_renderer_factory.hpp:35
static String VendorName(int version)
Get the name of the OpenGL vendor.
Definition detail_opengl_image_renderer_factory.hpp:82
static bool TryVersion(int version) noexcept
Test if a OpenGL version is implemented on your system.
Definition detail_opengl_image_renderer_factory.hpp:47
static String RendererName(int version)
Gets the name of the OpenGL renderer.
Definition detail_opengl_image_renderer_factory.hpp:87
static std::unique_ptr< OpenGLImageRenderer > CreateRenderer(int version)
Create a renderer.
Definition detail_opengl_image_renderer_factory.hpp:18
Base class for OpenGL image renderer.
Definition decl_opengl_image_renderer.hpp:43
OpenGLBufferFormat BufferFormat() const noexcept
Returns the current buffer format.
Definition decl_opengl_image_renderer.hpp:75
Namespace for user interface components.
Definition decl_image_scene.hpp:39
Cvb::String QtToCvb(const QString text) noexcept
Convenience converter for strings.
Definition ui.hpp:219
Root namespace for the Image Manager interface.
Definition c_bayer_to_rgb.h:17
std::string String
String for wide characters or unicode characters.
Definition string.hpp:49
Buffer format description for a texture to hold the pixel data.
Definition ui.hpp:128
int LinePad
Definition ui.hpp:142