CVB++ 14.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 ~GL3ImageRenderer() = default;
118
119 void UpdateBufferFormat(const OpenGLBufferFormat & bufferFormat) noexcept override;
120
121 void * BeginBufferAccess(int & linePad) noexcept override
122 {
123 if (pixelBuffer_)
124 {
125 linePad = BufferFormat().LinePad;
126 BindTexture();
127 pixelBuffer_->Bind();
128 pixelBuffer_->Data();
129 return pixelBuffer_->Map();
130 }
131 else
132 return nullptr;
133 }
134
135 void EndBufferAccess() noexcept override
136 {
137 if (pixelBuffer_)
138 {
139 pixelBuffer_->Unmap();
140
141 Image2DTexture(nullptr, true);
142 pixelBuffer_->Release();
143 ReleaseTexture();
144 }
145
146 }
147
148 bool MonoUploadSupported() const noexcept override
149 {
150 return true;
151 }
152
153 private:
154
155
156 class GLPixelBuffer
157 : public QOpenGLExtraFunctions
158 {
159 public:
160
161 GLPixelBuffer() noexcept;
162 ~GLPixelBuffer();
163
164 void Bind() noexcept;
165 void Release() noexcept;
166
167 void Data() noexcept;
168 void Data(int size) noexcept;
169
170 void * Map() noexcept;
171 void Unmap() noexcept;
172
173 private:
174
175 GLuint handle_ = 0;
176
177 int size_ = 0;
178 };
180
181
182 };
183#endif
184
185
186 class GL2ImageRenderer
187 : public OpenGLImageRenderer
188 {
189 public:
190
191 GL2ImageRenderer() noexcept
193 {
194 }
195
196 ~GL2ImageRenderer() = default;
197
198 void UpdateBufferFormat(const OpenGLBufferFormat & bufferFormat) noexcept override;
199
200 void * BeginBufferAccess(int & /*linePad*/) noexcept override
201 {
202 return &pixelBuffer_[0];
203 }
204
205 void EndBufferAccess() noexcept override
206 {
207 BindTexture();
208 Image2DTexture(BufferFormat(), &pixelBuffer_[0], false);
209 ReleaseTexture();
210 }
211
212 bool MonoUploadSupported() const noexcept override
213 {
214 return false;
215 }
216
217 private:
218
219 std::vector<std::uint8_t> pixelBuffer_;
220
221 };
222
223
224 OpenGLImageRendererFactory() noexcept = delete;
225
226
227
228 static bool TryFormat(const QSurfaceFormat& format, int minVersion) noexcept
229 {
230 QOpenGLContext context;
231 context.setFormat(format);
232 if (!context.create())
233 return false;
234
235
236
237 auto effectiveFormat = context.format();
238 if (effectiveFormat.majorVersion() < minVersion // we did not get what is needed
239 // we got OpenGL ES 3 outside arm, this will not work
240 || (effectiveFormat.majorVersion() == 3 && effectiveFormat.renderableType() == QSurfaceFormat::OpenGLES && !(QSysInfo::currentCpuArchitecture().startsWith("arm")))
241 // we got OpenGL 2 (not ES) this will not work either
242 || (effectiveFormat.majorVersion() == 2 && effectiveFormat.renderableType() != QSurfaceFormat::OpenGLES))
243 return false;
244 if (effectiveFormat.profile() == QSurfaceFormat::CoreProfile)
245 return false;
246
247
248 return true;
249 }
250
251 static String ReadString(int version, int value)
252 {
253 auto format = CreateFormat(version);
254
255 QOpenGLContext context;
256 context.setFormat(format);
257 if (!context.create())
258 throw std::runtime_error("failed to create context for already verified OpenGL version.");
259
260
261 QOffscreenSurface surface;
262 context.makeCurrent(&surface);
265
266 QString vendor(reinterpret_cast<const char*>(fnc.glGetString(static_cast<GLenum>(value))));
267 return QtToCvb(vendor);
268 }
269
270
271};
272
273}
274
275
276
277CVB_END_INLINE_NS
278
279
280
281}
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:239
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:139
int LinePad
Definition: ui.hpp:153