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
19#ifdef _MSC_VER
20#pragma warning ( pop)
21#endif
22
23#include "../../global.hpp"
24
25#include "../ui.hpp"
26
27#include "decl_opengl_image_renderer.hpp"
28
29namespace Cvb
30{
31
32CVB_BEGIN_INLINE_NS
33
34namespace UI
35{
36
37
38
40
48{
49 public:
50
52
58
59
60
62
67 static QSurfaceFormat CreateFormat(int version);
68
69
71
77 static bool TryVersion(int version) noexcept;
78
79
81
87 static bool TryVersion(int version, QSurfaceFormat& format) noexcept;
88
89
91
96 static String VendorName(int version);
97
98
100
105 static String RendererName(int version);
106
107 private:
108
109#if QT_VERSION >= QT_VERSION_CHECK(5,6,0)
110 class GL3ImageRenderer
111 : public OpenGLImageRenderer
112 {
113 public:
114
115 GL3ImageRenderer() noexcept;
116
117 void UpdateBufferFormat(const OpenGLBufferFormat & bufferFormat) noexcept override;
118
119 void * BeginBufferAccess(int & linePad) noexcept override
120 {
121
122 linePad = BufferFormat().LinePad;
123 BindTexture();
124 pixelBuffer_.Bind();
125 pixelBuffer_.Data();
126 return pixelBuffer_.Map();
127
128 }
129
130 void EndBufferAccess() noexcept override
131 {
132
133 pixelBuffer_.Unmap();
134
135 Image2DTexture(nullptr, true);
136 pixelBuffer_.Release();
137 ReleaseTexture();
138 }
139
140 bool MonoUploadSupported() const noexcept override
141 {
142 return true;
143 }
144
145 private:
146
147
148 class GLPixelBuffer
149 : public QOpenGLExtraFunctions
150 {
151 public:
152
153 GLPixelBuffer() noexcept;
154 GLPixelBuffer(const GLPixelBuffer& other) = delete;
155 GLPixelBuffer& operator=(const GLPixelBuffer& other) = delete;
156 GLPixelBuffer(GLPixelBuffer&& other) = delete;
157 GLPixelBuffer& operator=(GLPixelBuffer&& other) = delete;
158 ~GLPixelBuffer();
159
160 void Bind() noexcept;
161 void Release() noexcept;
162
163 void Data() noexcept;
164 void Data(int size) noexcept;
165
166 void * Map() noexcept;
167 void Unmap() noexcept;
168
169 private:
170
171 GLuint handle_ = 0;
172
173 int size_ = 0;
174 };
175 GLPixelBuffer pixelBuffer_;
176
177
178 };
179#endif
180
181
182 class GL2ImageRenderer
183 : public OpenGLImageRenderer
184 {
185 public:
186
187 GL2ImageRenderer() noexcept
189 {
190 }
191
192 void UpdateBufferFormat(const OpenGLBufferFormat & bufferFormat) noexcept override;
193
194 void * BeginBufferAccess(int & /*linePad*/) noexcept override
195 {
196 return &pixelBuffer_[0];
197 }
198
199 void EndBufferAccess() noexcept override
200 {
201 BindTexture();
202 Image2DTexture(BufferFormat(), &pixelBuffer_[0], false);
203 ReleaseTexture();
204 }
205
206 bool MonoUploadSupported() const noexcept override
207 {
208 return false;
209 }
210
211 private:
212
213 std::vector<std::uint8_t> pixelBuffer_;
214
215 };
216
217
218 OpenGLImageRendererFactory() noexcept = delete;
219
220
221
222 static bool TryFormat(const QSurfaceFormat& format, int minVersion) noexcept
223 {
224 QOpenGLContext context;
225 context.setFormat(format);
226 if (!context.create())
227 return false;
228
229
230
231 auto effectiveFormat = context.format();
232 if (effectiveFormat.majorVersion() < minVersion // we did not get what is needed
233 // we got OpenGL ES 3 outside arm, this will not work
234 || (effectiveFormat.majorVersion() == 3 && effectiveFormat.renderableType() == QSurfaceFormat::OpenGLES && !(QSysInfo::currentCpuArchitecture().startsWith("arm")))
235 // we got OpenGL 2 (not ES) this will not work either
236 || (effectiveFormat.majorVersion() == 2 && effectiveFormat.renderableType() != QSurfaceFormat::OpenGLES))
237 return false;
238 if (effectiveFormat.profile() == QSurfaceFormat::CoreProfile)
239 return false;
240
241
242 return true;
243 }
244
245 static String ReadString(int version, int value)
246 {
247 auto format = CreateFormat(version);
248
249 QOpenGLContext context;
250 context.setFormat(format);
251 if (!context.create())
252 throw std::runtime_error("failed to create context for already verified OpenGL version.");
253
254
255 QOffscreenSurface surface;
256 context.makeCurrent(&surface);
259
260 QString vendor(reinterpret_cast<const char*>(fnc.glGetString(static_cast<GLenum>(value))));
261 return QtToCvb(vendor);
262 }
263
264
265};
266
267}
268
269
270
271CVB_END_INLINE_NS
272
273
274
275}
Factory to create an OpenGL based image renderer.
Definition: decl_opengl_image_renderer_factory.hpp:48
static QSurfaceFormat CreateFormat(int version)
Create a OpenGL format for the given version.
Definition: detail_opengl_image_renderer_factory.hpp:36
static String VendorName(int version)
Get the name of the OpenGL vendor.
Definition: detail_opengl_image_renderer_factory.hpp:88
static bool TryVersion(int version) noexcept
Test if a OpenGL version is implemented on your system.
Definition: detail_opengl_image_renderer_factory.hpp:49
static String RendererName(int version)
Gets the name of the OpenGL renderer.
Definition: detail_opengl_image_renderer_factory.hpp:93
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:45
Cvb::String QtToCvb(const QString text) noexcept
Convenience converter for strings.
Definition: ui.hpp:238
Root namespace for the Image Manager interface.
Definition: c_barcode.h:24
QSurfaceFormat format() const const
bool makeCurrent(QSurface *surface)
void setFormat(const QSurfaceFormat &format)
const GLubyte * glGetString(GLenum name)
void initializeOpenGLFunctions()
bool startsWith(const QString &s, Qt::CaseSensitivity cs) const const
QString currentCpuArchitecture()
Buffer format description for a texture to hold the pixel data.
Definition: ui.hpp:138
int LinePad
Definition: ui.hpp:152