Absolute File Name: | /home/qt/qt5_coco/qt5/qtbase/src/gui/opengl/qopenglframebufferobject.cpp |
Switch to Source code | Preprocessed file |
Line | Source | Count | ||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | - | |||||||||||||||||||
2 | - | |||||||||||||||||||
3 | - | |||||||||||||||||||
4 | - | |||||||||||||||||||
5 | void QOpenGLFramebufferObjectFormat::detach() | - | ||||||||||||||||||
6 | { | - | ||||||||||||||||||
7 | if (d->ref.load() != 1) { | - | ||||||||||||||||||
8 | QOpenGLFramebufferObjectFormatPrivate *newd | - | ||||||||||||||||||
9 | = new QOpenGLFramebufferObjectFormatPrivate(d); | - | ||||||||||||||||||
10 | if (!d->ref.deref()) | - | ||||||||||||||||||
11 | delete d; | - | ||||||||||||||||||
12 | d = newd; | - | ||||||||||||||||||
13 | } | - | ||||||||||||||||||
14 | } | - | ||||||||||||||||||
15 | QOpenGLFramebufferObjectFormat::QOpenGLFramebufferObjectFormat() | - | ||||||||||||||||||
16 | { | - | ||||||||||||||||||
17 | d = new QOpenGLFramebufferObjectFormatPrivate; | - | ||||||||||||||||||
18 | } | - | ||||||||||||||||||
19 | - | |||||||||||||||||||
20 | - | |||||||||||||||||||
21 | - | |||||||||||||||||||
22 | - | |||||||||||||||||||
23 | - | |||||||||||||||||||
24 | QOpenGLFramebufferObjectFormat::QOpenGLFramebufferObjectFormat(const QOpenGLFramebufferObjectFormat &other) | - | ||||||||||||||||||
25 | { | - | ||||||||||||||||||
26 | d = other.d; | - | ||||||||||||||||||
27 | d->ref.ref(); | - | ||||||||||||||||||
28 | } | - | ||||||||||||||||||
29 | - | |||||||||||||||||||
30 | - | |||||||||||||||||||
31 | - | |||||||||||||||||||
32 | - | |||||||||||||||||||
33 | - | |||||||||||||||||||
34 | QOpenGLFramebufferObjectFormat &QOpenGLFramebufferObjectFormat::operator=(const QOpenGLFramebufferObjectFormat &other) | - | ||||||||||||||||||
35 | { | - | ||||||||||||||||||
36 | if (d != other.d) { | - | ||||||||||||||||||
37 | other.d->ref.ref(); | - | ||||||||||||||||||
38 | if (!d->ref.deref()) | - | ||||||||||||||||||
39 | delete d; | - | ||||||||||||||||||
40 | d = other.d; | - | ||||||||||||||||||
41 | } | - | ||||||||||||||||||
42 | return *this; | - | ||||||||||||||||||
43 | } | - | ||||||||||||||||||
44 | - | |||||||||||||||||||
45 | - | |||||||||||||||||||
46 | - | |||||||||||||||||||
47 | - | |||||||||||||||||||
48 | QOpenGLFramebufferObjectFormat::~QOpenGLFramebufferObjectFormat() | - | ||||||||||||||||||
49 | { | - | ||||||||||||||||||
50 | if (!d->ref.deref()) | - | ||||||||||||||||||
51 | delete d; | - | ||||||||||||||||||
52 | } | - | ||||||||||||||||||
53 | void QOpenGLFramebufferObjectFormat::setSamples(int samples) | - | ||||||||||||||||||
54 | { | - | ||||||||||||||||||
55 | detach(); | - | ||||||||||||||||||
56 | d->samples = samples; | - | ||||||||||||||||||
57 | } | - | ||||||||||||||||||
58 | int QOpenGLFramebufferObjectFormat::samples() const | - | ||||||||||||||||||
59 | { | - | ||||||||||||||||||
60 | return d->samples; | - | ||||||||||||||||||
61 | } | - | ||||||||||||||||||
62 | void QOpenGLFramebufferObjectFormat::setMipmap(bool enabled) | - | ||||||||||||||||||
63 | { | - | ||||||||||||||||||
64 | detach(); | - | ||||||||||||||||||
65 | d->mipmap = enabled; | - | ||||||||||||||||||
66 | } | - | ||||||||||||||||||
67 | - | |||||||||||||||||||
68 | - | |||||||||||||||||||
69 | - | |||||||||||||||||||
70 | - | |||||||||||||||||||
71 | - | |||||||||||||||||||
72 | - | |||||||||||||||||||
73 | bool QOpenGLFramebufferObjectFormat::mipmap() const | - | ||||||||||||||||||
74 | { | - | ||||||||||||||||||
75 | return d->mipmap; | - | ||||||||||||||||||
76 | } | - | ||||||||||||||||||
77 | - | |||||||||||||||||||
78 | - | |||||||||||||||||||
79 | - | |||||||||||||||||||
80 | - | |||||||||||||||||||
81 | - | |||||||||||||||||||
82 | - | |||||||||||||||||||
83 | void QOpenGLFramebufferObjectFormat::setAttachment(QOpenGLFramebufferObject::Attachment attachment) | - | ||||||||||||||||||
84 | { | - | ||||||||||||||||||
85 | detach(); | - | ||||||||||||||||||
86 | d->attachment = attachment; | - | ||||||||||||||||||
87 | } | - | ||||||||||||||||||
88 | - | |||||||||||||||||||
89 | - | |||||||||||||||||||
90 | - | |||||||||||||||||||
91 | - | |||||||||||||||||||
92 | - | |||||||||||||||||||
93 | - | |||||||||||||||||||
94 | - | |||||||||||||||||||
95 | QOpenGLFramebufferObject::Attachment QOpenGLFramebufferObjectFormat::attachment() const | - | ||||||||||||||||||
96 | { | - | ||||||||||||||||||
97 | return d->attachment; | - | ||||||||||||||||||
98 | } | - | ||||||||||||||||||
99 | - | |||||||||||||||||||
100 | - | |||||||||||||||||||
101 | - | |||||||||||||||||||
102 | - | |||||||||||||||||||
103 | - | |||||||||||||||||||
104 | - | |||||||||||||||||||
105 | - | |||||||||||||||||||
106 | void QOpenGLFramebufferObjectFormat::setTextureTarget(GLenum target) | - | ||||||||||||||||||
107 | { | - | ||||||||||||||||||
108 | detach(); | - | ||||||||||||||||||
109 | d->target = target; | - | ||||||||||||||||||
110 | } | - | ||||||||||||||||||
111 | GLenum QOpenGLFramebufferObjectFormat::textureTarget() const | - | ||||||||||||||||||
112 | { | - | ||||||||||||||||||
113 | return d->target; | - | ||||||||||||||||||
114 | } | - | ||||||||||||||||||
115 | void QOpenGLFramebufferObjectFormat::setInternalTextureFormat(GLenum internalTextureFormat) | - | ||||||||||||||||||
116 | { | - | ||||||||||||||||||
117 | detach(); | - | ||||||||||||||||||
118 | d->internal_format = internalTextureFormat; | - | ||||||||||||||||||
119 | } | - | ||||||||||||||||||
120 | GLenum QOpenGLFramebufferObjectFormat::internalTextureFormat() const | - | ||||||||||||||||||
121 | { | - | ||||||||||||||||||
122 | return d->internal_format; | - | ||||||||||||||||||
123 | } | - | ||||||||||||||||||
124 | - | |||||||||||||||||||
125 | - | |||||||||||||||||||
126 | - | |||||||||||||||||||
127 | - | |||||||||||||||||||
128 | - | |||||||||||||||||||
129 | bool QOpenGLFramebufferObjectFormat::operator==(const QOpenGLFramebufferObjectFormat& other) const | - | ||||||||||||||||||
130 | { | - | ||||||||||||||||||
131 | if (d == other.d) | - | ||||||||||||||||||
132 | return true; | - | ||||||||||||||||||
133 | else | - | ||||||||||||||||||
134 | return d->equals(other.d); | - | ||||||||||||||||||
135 | } | - | ||||||||||||||||||
136 | - | |||||||||||||||||||
137 | - | |||||||||||||||||||
138 | - | |||||||||||||||||||
139 | - | |||||||||||||||||||
140 | - | |||||||||||||||||||
141 | bool QOpenGLFramebufferObjectFormat::operator!=(const QOpenGLFramebufferObjectFormat& other) const | - | ||||||||||||||||||
142 | { | - | ||||||||||||||||||
143 | return !(*this == other); | - | ||||||||||||||||||
144 | } | - | ||||||||||||||||||
145 | - | |||||||||||||||||||
146 | bool QOpenGLFramebufferObjectPrivate::checkFramebufferStatus(QOpenGLContext *ctx) const | - | ||||||||||||||||||
147 | { | - | ||||||||||||||||||
148 | if (!ctx) | - | ||||||||||||||||||
149 | return false; | - | ||||||||||||||||||
150 | GLenum status = ctx->functions()->glCheckFramebufferStatus(0x8D40); | - | ||||||||||||||||||
151 | switch(status) { | - | ||||||||||||||||||
152 | case 0: | - | ||||||||||||||||||
153 | case 0x8CD5: | - | ||||||||||||||||||
154 | return true; | - | ||||||||||||||||||
155 | case 0x8CDD: | - | ||||||||||||||||||
156 | QMessageLogger(__FILE__, 377383, __PRETTY_FUNCTION__).debug("QOpenGLFramebufferObject: Unsupported framebuffer format."); | - | ||||||||||||||||||
157 | break; | - | ||||||||||||||||||
158 | case 0x8CD6: | - | ||||||||||||||||||
159 | QMessageLogger(__FILE__, 380386, __PRETTY_FUNCTION__).debug("QOpenGLFramebufferObject: Framebuffer incomplete attachment."); | - | ||||||||||||||||||
160 | break; | - | ||||||||||||||||||
161 | case 0x8CD7: | - | ||||||||||||||||||
162 | QMessageLogger(__FILE__, 383389, __PRETTY_FUNCTION__).debug("QOpenGLFramebufferObject: Framebuffer incomplete, missing attachment."); | - | ||||||||||||||||||
163 | break; | - | ||||||||||||||||||
164 | case 0x8CDB: | - | ||||||||||||||||||
165 | QMessageLogger(__FILE__, 402408, __PRETTY_FUNCTION__).debug("QOpenGLFramebufferObject: Framebuffer incomplete, missing draw buffer."); | - | ||||||||||||||||||
166 | break; | - | ||||||||||||||||||
167 | - | |||||||||||||||||||
168 | - | |||||||||||||||||||
169 | case 0x8CDC: | - | ||||||||||||||||||
170 | QMessageLogger(__FILE__, 407413, __PRETTY_FUNCTION__).debug("QOpenGLFramebufferObject: Framebuffer incomplete, missing read buffer."); | - | ||||||||||||||||||
171 | break; | - | ||||||||||||||||||
172 | - | |||||||||||||||||||
173 | - | |||||||||||||||||||
174 | case 0x8D56: | - | ||||||||||||||||||
175 | QMessageLogger(__FILE__, 412418, __PRETTY_FUNCTION__).debug("QOpenGLFramebufferObject: Framebuffer incomplete, attachments must have same number of samples per pixel."); | - | ||||||||||||||||||
176 | break; | - | ||||||||||||||||||
177 | - | |||||||||||||||||||
178 | default: | - | ||||||||||||||||||
179 | QMessageLogger(__FILE__, 416422, __PRETTY_FUNCTION__).debug() <<"QOpenGLFramebufferObject: An undefined error has occurred: "<< status; | - | ||||||||||||||||||
180 | break; | - | ||||||||||||||||||
181 | } | - | ||||||||||||||||||
182 | return false; | - | ||||||||||||||||||
183 | } | - | ||||||||||||||||||
184 | - | |||||||||||||||||||
185 | namespace | - | ||||||||||||||||||
186 | { | - | ||||||||||||||||||
187 | void freeFramebufferFunc(QOpenGLFunctions *funcs, GLuint id) | - | ||||||||||||||||||
188 | { | - | ||||||||||||||||||
189 | funcs->glDeleteFramebuffers(1, &id); | - | ||||||||||||||||||
190 | } | - | ||||||||||||||||||
191 | - | |||||||||||||||||||
192 | void freeRenderbufferFunc(QOpenGLFunctions *funcs, GLuint id) | - | ||||||||||||||||||
193 | { | - | ||||||||||||||||||
194 | funcs->glDeleteRenderbuffers(1, &id); | - | ||||||||||||||||||
195 | } | - | ||||||||||||||||||
196 | - | |||||||||||||||||||
197 | void freeTextureFunc(QOpenGLFunctions *funcs, GLuint id) | - | ||||||||||||||||||
198 | { | - | ||||||||||||||||||
199 | funcs->glDeleteTextures(1, &id); | - | ||||||||||||||||||
200 | } | - | ||||||||||||||||||
201 | } | - | ||||||||||||||||||
202 | - | |||||||||||||||||||
203 | void QOpenGLFramebufferObjectPrivate::init(QOpenGLFramebufferObject *, const QSize &size, | - | ||||||||||||||||||
204 | QOpenGLFramebufferObject::Attachment attachment, | - | ||||||||||||||||||
205 | GLenum texture_target, GLenum internal_format, | - | ||||||||||||||||||
206 | GLint samples, bool mipmap) | - | ||||||||||||||||||
207 | { | - | ||||||||||||||||||
208 | QOpenGLContext *ctx = QOpenGLContext::currentContext(); | - | ||||||||||||||||||
209 | - | |||||||||||||||||||
210 | funcs.initializeOpenGLFunctions(); | - | ||||||||||||||||||
211 | - | |||||||||||||||||||
212 | if (!funcs.hasOpenGLFeature(QOpenGLFunctions::Framebuffers)) | - | ||||||||||||||||||
213 | return; | - | ||||||||||||||||||
214 | - | |||||||||||||||||||
215 | - | |||||||||||||||||||
216 | if (!funcs.hasOpenGLExtension(QOpenGLExtensions::FramebufferMultisample) | - | ||||||||||||||||||
217 | || !funcs.hasOpenGLExtension(QOpenGLExtensions::FramebufferBlit)) { | - | ||||||||||||||||||
218 | samples = 0; | - | ||||||||||||||||||
219 | } else if (!ctx->isOpenGLES() || ctx->format().majorVersion() >= 3) { | - | ||||||||||||||||||
220 | GLint maxSamples; | - | ||||||||||||||||||
221 | funcs.glGetIntegerv(0x8D57, &maxSamples); | - | ||||||||||||||||||
222 | samples = qBound(0, int(samples), int(maxSamples)); | - | ||||||||||||||||||
223 | } | - | ||||||||||||||||||
224 | - | |||||||||||||||||||
225 | colorAttachments.append(ColorAttachment(size, internal_format)); | - | ||||||||||||||||||
226 | - | |||||||||||||||||||
227 | dsSize = size; | - | ||||||||||||||||||
228 | - | |||||||||||||||||||
229 | samples = qMax(0, samples); | - | ||||||||||||||||||
230 | requestedSamples = samples; | - | ||||||||||||||||||
231 | - | |||||||||||||||||||
232 | target = texture_target; | - | ||||||||||||||||||
233 | - | |||||||||||||||||||
234 | { while (QOpenGLContext::currentContext()->functions()->glGetError() != 0) {} }; | - | ||||||||||||||||||
235 | GLuint fbo = 0; | - | ||||||||||||||||||
236 | - | |||||||||||||||||||
237 | funcs.glGenFramebuffers(1, &fbo); | - | ||||||||||||||||||
238 | funcs.glBindFramebuffer(0x8D40, fbo); | - | ||||||||||||||||||
239 | - | |||||||||||||||||||
240 | QOpenGLContextPrivate::get(ctx)->qgl_current_fbo_invalid = true; | - | ||||||||||||||||||
241 | - | |||||||||||||||||||
242 | { GLenum err = QOpenGLContext::currentContext()->functions()->glGetError(); if (err != 0) { QMessageLogger(__FILE__, 479485, __PRETTY_FUNCTION__).debug("[%s line %d] OpenGL Error: %d", __FILE__, 479485, (int)err); } }; | - | ||||||||||||||||||
243 | - | |||||||||||||||||||
244 | format.setTextureTarget(target); | - | ||||||||||||||||||
245 | format.setInternalTextureFormat(internal_format); | - | ||||||||||||||||||
246 | format.setMipmap(mipmap); | - | ||||||||||||||||||
247 | - | |||||||||||||||||||
248 | if (samples == 0) | - | ||||||||||||||||||
249 | initTexture(0); | - | ||||||||||||||||||
250 | else | - | ||||||||||||||||||
251 | initColorBuffer(0, &samples); | - | ||||||||||||||||||
252 | - | |||||||||||||||||||
253 | format.setSamples(int(samples)); | - | ||||||||||||||||||
254 | - | |||||||||||||||||||
255 | initDepthStencilAttachments(ctx, attachment); | - | ||||||||||||||||||
256 | - | |||||||||||||||||||
257 | if (valid) | - | ||||||||||||||||||
258 | fbo_guard = new QOpenGLSharedResourceGuard(ctx, fbo, freeFramebufferFunc); | - | ||||||||||||||||||
259 | else | - | ||||||||||||||||||
260 | funcs.glDeleteFramebuffers(1, &fbo); | - | ||||||||||||||||||
261 | - | |||||||||||||||||||
262 | { GLenum err = QOpenGLContext::currentContext()->functions()->glGetError(); if (err != 0) { QMessageLogger(__FILE__, 499505, __PRETTY_FUNCTION__).debug("[%s line %d] OpenGL Error: %d", __FILE__, 499505, (int)err); } }; | - | ||||||||||||||||||
263 | } | - | ||||||||||||||||||
264 | - | |||||||||||||||||||
265 | void QOpenGLFramebufferObjectPrivate::initTexture(int idx) | - | ||||||||||||||||||
266 | { | - | ||||||||||||||||||
267 | QOpenGLContext *ctx = QOpenGLContext::currentContext(); | - | ||||||||||||||||||
268 | GLuint texture = 0; | - | ||||||||||||||||||
269 | - | |||||||||||||||||||
270 | funcs.glGenTextures(1, &texture); | - | ||||||||||||||||||
271 | funcs.glBindTexture(target, texture); | - | ||||||||||||||||||
272 | - | |||||||||||||||||||
273 | funcs.glTexParameteri(target, 0x2801, 0x2600); | - | ||||||||||||||||||
274 | funcs.glTexParameteri(target, 0x2800, 0x2600); | - | ||||||||||||||||||
275 | funcs.glTexParameteri(target, 0x2802, 0x812F); | - | ||||||||||||||||||
276 | funcs.glTexParameteri(target, 0x2803, 0x812F); | - | ||||||||||||||||||
277 | - | |||||||||||||||||||
278 | ColorAttachment &color(colorAttachments[idx]); | - | ||||||||||||||||||
279 | - | |||||||||||||||||||
280 | GLuint pixelType = 0x1401; | - | ||||||||||||||||||
281 | if (color.internalFormat == 0x8059 || color.internalFormat == 0x8052) | - | ||||||||||||||||||
282 | pixelType = 0x8368; | - | ||||||||||||||||||
283 | - | |||||||||||||||||||
284 | funcs.glTexImage2D(target, 0, color.internalFormat, color.size.width(), color.size.height(), 0, | - | ||||||||||||||||||
285 | 0x1908, pixelType, __null); | - | ||||||||||||||||||
286 | if (format.mipmap()) { | - | ||||||||||||||||||
287 | int width = color.size.width(); | - | ||||||||||||||||||
288 | int height = color.size.height(); | - | ||||||||||||||||||
289 | int level = 0; | - | ||||||||||||||||||
290 | while (width > 1 || height > 1) { | - | ||||||||||||||||||
291 | width = qMax(1, width >> 1); | - | ||||||||||||||||||
292 | height = qMax(1, height >> 1); | - | ||||||||||||||||||
293 | ++level; | - | ||||||||||||||||||
294 | funcs.glTexImage2D(target, level, color.internalFormat, width, height, 0, | - | ||||||||||||||||||
295 | 0x1908, pixelType, __null); | - | ||||||||||||||||||
296 | } | - | ||||||||||||||||||
297 | } | - | ||||||||||||||||||
298 | funcs.glFramebufferTexture2D(0x8D40, 0x8CE0 + idx, | - | ||||||||||||||||||
299 | target, texture, 0); | - | ||||||||||||||||||
300 | - | |||||||||||||||||||
301 | { GLenum err = QOpenGLContext::currentContext()->functions()->glGetError(); if (err != 0) { QMessageLogger(__FILE__, 538544, __PRETTY_FUNCTION__).debug("[%s line %d] OpenGL Error: %d", __FILE__, 538544, (int)err); } }; | - | ||||||||||||||||||
302 | funcs.glBindTexture(target, 0); | - | ||||||||||||||||||
303 | valid = checkFramebufferStatus(ctx); | - | ||||||||||||||||||
304 | if (valid) { | - | ||||||||||||||||||
305 | color.guard = new QOpenGLSharedResourceGuard(ctx, texture, freeTextureFunc); | - | ||||||||||||||||||
306 | } else { | - | ||||||||||||||||||
307 | funcs.glDeleteTextures(1, &texture); | - | ||||||||||||||||||
308 | } | - | ||||||||||||||||||
309 | } | - | ||||||||||||||||||
310 | - | |||||||||||||||||||
311 | void QOpenGLFramebufferObjectPrivate::initColorBuffer(int idx, GLint *samples) | - | ||||||||||||||||||
312 | { | - | ||||||||||||||||||
313 | QOpenGLContext *ctx = QOpenGLContext::currentContext(); | - | ||||||||||||||||||
314 | GLuint color_buffer = 0; | - | ||||||||||||||||||
315 | - | |||||||||||||||||||
316 | ColorAttachment &color(colorAttachments[idx]); | - | ||||||||||||||||||
317 | - | |||||||||||||||||||
318 | GLenum storageFormat = color.internalFormat; | - | ||||||||||||||||||
319 | - | |||||||||||||||||||
320 | if (ctx->isOpenGLES() && color.internalFormat == 0x1908) { | - | ||||||||||||||||||
321 | if (funcs.hasOpenGLExtension(QOpenGLExtensions::Sized8Formats)) | - | ||||||||||||||||||
322 | storageFormat = 0x8058; | - | ||||||||||||||||||
323 | else | - | ||||||||||||||||||
324 | storageFormat = 0x8056; | - | ||||||||||||||||||
325 | } | - | ||||||||||||||||||
326 | - | |||||||||||||||||||
327 | funcs.glGenRenderbuffers(1, &color_buffer); | - | ||||||||||||||||||
328 | funcs.glBindRenderbuffer(0x8D41, color_buffer); | - | ||||||||||||||||||
329 | funcs.glRenderbufferStorageMultisample(0x8D41, *samples, storageFormat, color.size.width(), color.size.height()); | - | ||||||||||||||||||
330 | funcs.glFramebufferRenderbuffer(0x8D40, 0x8CE0 + idx, | - | ||||||||||||||||||
331 | 0x8D41, color_buffer); | - | ||||||||||||||||||
332 | - | |||||||||||||||||||
333 | { GLenum err = QOpenGLContext::currentContext()->functions()->glGetError(); if (err != 0) { QMessageLogger(__FILE__, 570576, __PRETTY_FUNCTION__).debug("[%s line %d] OpenGL Error: %d", __FILE__, 570576, (int)err); } }; | - | ||||||||||||||||||
334 | valid = checkFramebufferStatus(ctx); | - | ||||||||||||||||||
335 | if (valid) { | - | ||||||||||||||||||
336 | - | |||||||||||||||||||
337 | - | |||||||||||||||||||
338 | - | |||||||||||||||||||
339 | funcs.glGetRenderbufferParameteriv(0x8D41, 0x8CAB, samples); | - | ||||||||||||||||||
340 | color.guard = new QOpenGLSharedResourceGuard(ctx, color_buffer, freeRenderbufferFunc); | - | ||||||||||||||||||
341 | } else { | - | ||||||||||||||||||
342 | funcs.glDeleteRenderbuffers(1, &color_buffer); | - | ||||||||||||||||||
343 | } | - | ||||||||||||||||||
344 | } | - | ||||||||||||||||||
345 | - | |||||||||||||||||||
346 | void QOpenGLFramebufferObjectPrivate::initDepthStencilAttachments(QOpenGLContext *ctx, | - | ||||||||||||||||||
347 | QOpenGLFramebufferObject::Attachment attachment) | - | ||||||||||||||||||
348 | { | - | ||||||||||||||||||
349 | - | |||||||||||||||||||
350 | - | |||||||||||||||||||
351 | - | |||||||||||||||||||
352 | const int samples = requestedSamples; | - | ||||||||||||||||||
353 | - | |||||||||||||||||||
354 | - | |||||||||||||||||||
355 | if (depth_buffer_guard) { | - | ||||||||||||||||||
356 | funcs.glFramebufferRenderbuffer(0x8D40, 0x8D00, 0x8D41, 0); | - | ||||||||||||||||||
357 | depth_buffer_guard->free(); | - | ||||||||||||||||||
358 | } | - | ||||||||||||||||||
359 | if (stencil_buffer_guard) { | - | ||||||||||||||||||
360 | funcs.glFramebufferRenderbuffer(0x8D40, 0x8D20, 0x8D41, 0); | - | ||||||||||||||||||
361 | if (stencil_buffer_guard != depth_buffer_guard) | - | ||||||||||||||||||
362 | stencil_buffer_guard->free(); | - | ||||||||||||||||||
363 | } | - | ||||||||||||||||||
364 | - | |||||||||||||||||||
365 | depth_buffer_guard = 0; | - | ||||||||||||||||||
366 | stencil_buffer_guard = 0; | - | ||||||||||||||||||
367 | - | |||||||||||||||||||
368 | GLuint depth_buffer = 0; | - | ||||||||||||||||||
369 | GLuint stencil_buffer = 0; | - | ||||||||||||||||||
370 | - | |||||||||||||||||||
371 | - | |||||||||||||||||||
372 | - | |||||||||||||||||||
373 | - | |||||||||||||||||||
374 | - | |||||||||||||||||||
375 | if (attachment == QOpenGLFramebufferObject::CombinedDepthStencil | - | ||||||||||||||||||
376 | && funcs.hasOpenGLExtension(QOpenGLExtensions::PackedDepthStencil)) | - | ||||||||||||||||||
377 | { | - | ||||||||||||||||||
378 | - | |||||||||||||||||||
379 | funcs.glGenRenderbuffers(1, &depth_buffer); | - | ||||||||||||||||||
380 | funcs.glBindRenderbuffer(0x8D41, depth_buffer); | - | ||||||||||||||||||
381 | ((!(funcs.glIsRenderbuffer(depth_buffer))) ? qt_assert("funcs.glIsRenderbuffer(depth_buffer)",__FILE__,618624) : qt_noop()); | - | ||||||||||||||||||
382 | if (samples != 0 && funcs.hasOpenGLExtension(QOpenGLExtensions::FramebufferMultisample)) | - | ||||||||||||||||||
383 | funcs.glRenderbufferStorageMultisample(0x8D41, samples, | - | ||||||||||||||||||
384 | 0x88F0, dsSize.width(), dsSize.height()); | - | ||||||||||||||||||
385 | else | - | ||||||||||||||||||
386 | funcs.glRenderbufferStorage(0x8D41, | - | ||||||||||||||||||
387 | 0x88F0, dsSize.width(), dsSize.height()); | - | ||||||||||||||||||
388 | - | |||||||||||||||||||
389 | stencil_buffer = depth_buffer; | - | ||||||||||||||||||
390 | funcs.glFramebufferRenderbuffer(0x8D40, 0x8D00, | - | ||||||||||||||||||
391 | 0x8D41, depth_buffer); | - | ||||||||||||||||||
392 | funcs.glFramebufferRenderbuffer(0x8D40, 0x8D20, | - | ||||||||||||||||||
393 | 0x8D41, stencil_buffer); | - | ||||||||||||||||||
394 | - | |||||||||||||||||||
395 | valid = checkFramebufferStatus(ctx); | - | ||||||||||||||||||
396 | if (!valid) { | - | ||||||||||||||||||
397 | funcs.glDeleteRenderbuffers(1, &depth_buffer); | - | ||||||||||||||||||
398 | stencil_buffer = depth_buffer = 0; | - | ||||||||||||||||||
399 | } | - | ||||||||||||||||||
400 | } | - | ||||||||||||||||||
401 | - | |||||||||||||||||||
402 | if (depth_buffer == 0 && (attachment == QOpenGLFramebufferObject::CombinedDepthStencil | - | ||||||||||||||||||
403 | || (attachment == QOpenGLFramebufferObject::Depth))) | - | ||||||||||||||||||
404 | { | - | ||||||||||||||||||
405 | funcs.glGenRenderbuffers(1, &depth_buffer); | - | ||||||||||||||||||
406 | funcs.glBindRenderbuffer(0x8D41, depth_buffer); | - | ||||||||||||||||||
407 | ((!(funcs.glIsRenderbuffer(depth_buffer))) ? qt_assert("funcs.glIsRenderbuffer(depth_buffer)",__FILE__,644650) : qt_noop()); | - | ||||||||||||||||||
408 | if (samples != 0 && funcs.hasOpenGLExtension(QOpenGLExtensions::FramebufferMultisample)) { | - | ||||||||||||||||||
409 | if (ctx->isOpenGLES()) { | - | ||||||||||||||||||
410 | if (funcs.hasOpenGLExtension(QOpenGLExtensions::Depth24)) | - | ||||||||||||||||||
411 | funcs.glRenderbufferStorageMultisample(0x8D41, samples, | - | ||||||||||||||||||
412 | 0x81A6, dsSize.width(), dsSize.height()); | - | ||||||||||||||||||
413 | else | - | ||||||||||||||||||
414 | funcs.glRenderbufferStorageMultisample(0x8D41, samples, | - | ||||||||||||||||||
415 | 0x81A5, dsSize.width(), dsSize.height()); | - | ||||||||||||||||||
416 | } else { | - | ||||||||||||||||||
417 | funcs.glRenderbufferStorageMultisample(0x8D41, samples, | - | ||||||||||||||||||
418 | 0x1902, dsSize.width(), dsSize.height()); | - | ||||||||||||||||||
419 | } | - | ||||||||||||||||||
420 | } else { | - | ||||||||||||||||||
421 | if (ctx->isOpenGLES()) { | - | ||||||||||||||||||
422 | if (funcs.hasOpenGLExtension(QOpenGLExtensions::Depth24)) { | - | ||||||||||||||||||
423 | funcs.glRenderbufferStorage(0x8D41, 0x81A6, | - | ||||||||||||||||||
424 | dsSize.width(), dsSize.height()); | - | ||||||||||||||||||
425 | } else { | - | ||||||||||||||||||
426 | funcs.glRenderbufferStorage(0x8D41, 0x81A5, | - | ||||||||||||||||||
427 | dsSize.width(), dsSize.height()); | - | ||||||||||||||||||
428 | } | - | ||||||||||||||||||
429 | } else { | - | ||||||||||||||||||
430 | funcs.glRenderbufferStorage(0x8D41, 0x1902, dsSize.width(), dsSize.height()); | - | ||||||||||||||||||
431 | } | - | ||||||||||||||||||
432 | } | - | ||||||||||||||||||
433 | funcs.glFramebufferRenderbuffer(0x8D40, 0x8D00, | - | ||||||||||||||||||
434 | 0x8D41, depth_buffer); | - | ||||||||||||||||||
435 | valid = checkFramebufferStatus(ctx); | - | ||||||||||||||||||
436 | if (!valid) { | - | ||||||||||||||||||
437 | funcs.glDeleteRenderbuffers(1, &depth_buffer); | - | ||||||||||||||||||
438 | depth_buffer = 0; | - | ||||||||||||||||||
439 | } | - | ||||||||||||||||||
440 | } | - | ||||||||||||||||||
441 | - | |||||||||||||||||||
442 | if (stencil_buffer == 0 && (attachment == QOpenGLFramebufferObject::CombinedDepthStencil)) { | - | ||||||||||||||||||
443 | funcs.glGenRenderbuffers(1, &stencil_buffer); | - | ||||||||||||||||||
444 | funcs.glBindRenderbuffer(0x8D41, stencil_buffer); | - | ||||||||||||||||||
445 | ((!(funcs.glIsRenderbuffer(stencil_buffer))) ? qt_assert("funcs.glIsRenderbuffer(stencil_buffer)",__FILE__,682688) : qt_noop()); | - | ||||||||||||||||||
446 | - | |||||||||||||||||||
447 | - | |||||||||||||||||||
448 | - | |||||||||||||||||||
449 | - | |||||||||||||||||||
450 | GLenum storage = ctx->isOpenGLES() ? 0x8D48 : 0x1901; | - | ||||||||||||||||||
451 | - | |||||||||||||||||||
452 | - | |||||||||||||||||||
453 | if (samples != 0 && funcs.hasOpenGLExtension(QOpenGLExtensions::FramebufferMultisample)) | - | ||||||||||||||||||
454 | funcs.glRenderbufferStorageMultisample(0x8D41, samples, storage, dsSize.width(), dsSize.height()); | - | ||||||||||||||||||
455 | else | - | ||||||||||||||||||
456 | funcs.glRenderbufferStorage(0x8D41, storage, dsSize.width(), dsSize.height()); | - | ||||||||||||||||||
457 | - | |||||||||||||||||||
458 | funcs.glFramebufferRenderbuffer(0x8D40, 0x8D20, | - | ||||||||||||||||||
459 | 0x8D41, stencil_buffer); | - | ||||||||||||||||||
460 | valid = checkFramebufferStatus(ctx); | - | ||||||||||||||||||
461 | if (!valid) { | - | ||||||||||||||||||
462 | funcs.glDeleteRenderbuffers(1, &stencil_buffer); | - | ||||||||||||||||||
463 | stencil_buffer = 0; | - | ||||||||||||||||||
464 | } | - | ||||||||||||||||||
465 | } | - | ||||||||||||||||||
466 | - | |||||||||||||||||||
467 | - | |||||||||||||||||||
468 | valid = checkFramebufferStatus(ctx); | - | ||||||||||||||||||
469 | - | |||||||||||||||||||
470 | if (depth_buffer && stencil_buffer) { | - | ||||||||||||||||||
471 | fbo_attachment = QOpenGLFramebufferObject::CombinedDepthStencil; | - | ||||||||||||||||||
472 | } else if (depth_buffer) { | - | ||||||||||||||||||
473 | fbo_attachment = QOpenGLFramebufferObject::Depth; | - | ||||||||||||||||||
474 | } else { | - | ||||||||||||||||||
475 | fbo_attachment = QOpenGLFramebufferObject::NoAttachment; | - | ||||||||||||||||||
476 | } | - | ||||||||||||||||||
477 | - | |||||||||||||||||||
478 | if (valid) { | - | ||||||||||||||||||
479 | if (depth_buffer) | - | ||||||||||||||||||
480 | depth_buffer_guard = new QOpenGLSharedResourceGuard(ctx, depth_buffer, freeRenderbufferFunc); | - | ||||||||||||||||||
481 | if (stencil_buffer) { | - | ||||||||||||||||||
482 | if (stencil_buffer == depth_buffer) | - | ||||||||||||||||||
483 | stencil_buffer_guard = depth_buffer_guard; | - | ||||||||||||||||||
484 | else | - | ||||||||||||||||||
485 | stencil_buffer_guard = new QOpenGLSharedResourceGuard(ctx, stencil_buffer, freeRenderbufferFunc); | - | ||||||||||||||||||
486 | } | - | ||||||||||||||||||
487 | } else { | - | ||||||||||||||||||
488 | if (depth_buffer) | - | ||||||||||||||||||
489 | funcs.glDeleteRenderbuffers(1, &depth_buffer); | - | ||||||||||||||||||
490 | if (stencil_buffer && depth_buffer != stencil_buffer) | - | ||||||||||||||||||
491 | funcs.glDeleteRenderbuffers(1, &stencil_buffer); | - | ||||||||||||||||||
492 | } | - | ||||||||||||||||||
493 | { GLenum err = QOpenGLContext::currentContext()->functions()->glGetError(); if (err != 0) { QMessageLogger(__FILE__, 730736, __PRETTY_FUNCTION__).debug("[%s line %d] OpenGL Error: %d", __FILE__, 730736, (int)err); } }; | - | ||||||||||||||||||
494 | - | |||||||||||||||||||
495 | format.setAttachment(fbo_attachment); | - | ||||||||||||||||||
496 | } | - | ||||||||||||||||||
497 | static inline GLenum effectiveInternalFormat(GLenum internalFormat) | - | ||||||||||||||||||
498 | { | - | ||||||||||||||||||
499 | if (!internalFormat) | - | ||||||||||||||||||
500 | - | |||||||||||||||||||
501 | - | |||||||||||||||||||
502 | - | |||||||||||||||||||
503 | internalFormat = QOpenGLContext::currentContext()->isOpenGLES() ? 0x1908 : 0x8058; | - | ||||||||||||||||||
504 | - | |||||||||||||||||||
505 | return internalFormat; | - | ||||||||||||||||||
506 | } | - | ||||||||||||||||||
507 | QOpenGLFramebufferObject::QOpenGLFramebufferObject(const QSize &size, GLenum target) | - | ||||||||||||||||||
508 | : d_ptr(new QOpenGLFramebufferObjectPrivate) | - | ||||||||||||||||||
509 | { | - | ||||||||||||||||||
510 | QOpenGLFramebufferObjectPrivate * const d = d_func(); | - | ||||||||||||||||||
511 | d->init(this, size, NoAttachment, target, effectiveInternalFormat(0)); | - | ||||||||||||||||||
512 | } | - | ||||||||||||||||||
513 | QOpenGLFramebufferObject::QOpenGLFramebufferObject(int width, int height, GLenum target) | - | ||||||||||||||||||
514 | : d_ptr(new QOpenGLFramebufferObjectPrivate) | - | ||||||||||||||||||
515 | { | - | ||||||||||||||||||
516 | QOpenGLFramebufferObjectPrivate * const d = d_func(); | - | ||||||||||||||||||
517 | d->init(this, QSize(width, height), NoAttachment, target, effectiveInternalFormat(0)); | - | ||||||||||||||||||
518 | } | - | ||||||||||||||||||
519 | - | |||||||||||||||||||
520 | - | |||||||||||||||||||
521 | - | |||||||||||||||||||
522 | - | |||||||||||||||||||
523 | - | |||||||||||||||||||
524 | - | |||||||||||||||||||
525 | - | |||||||||||||||||||
526 | QOpenGLFramebufferObject::QOpenGLFramebufferObject(const QSize &size, const QOpenGLFramebufferObjectFormat &format) | - | ||||||||||||||||||
527 | : d_ptr(new QOpenGLFramebufferObjectPrivate) | - | ||||||||||||||||||
528 | { | - | ||||||||||||||||||
529 | QOpenGLFramebufferObjectPrivate * const d = d_func(); | - | ||||||||||||||||||
530 | d->init(this, size, format.attachment(), format.textureTarget(), format.internalTextureFormat(), | - | ||||||||||||||||||
531 | format.samples(), format.mipmap()); | - | ||||||||||||||||||
532 | } | - | ||||||||||||||||||
533 | - | |||||||||||||||||||
534 | - | |||||||||||||||||||
535 | - | |||||||||||||||||||
536 | - | |||||||||||||||||||
537 | - | |||||||||||||||||||
538 | - | |||||||||||||||||||
539 | - | |||||||||||||||||||
540 | QOpenGLFramebufferObject::QOpenGLFramebufferObject(int width, int height, const QOpenGLFramebufferObjectFormat &format) | - | ||||||||||||||||||
541 | : d_ptr(new QOpenGLFramebufferObjectPrivate) | - | ||||||||||||||||||
542 | { | - | ||||||||||||||||||
543 | QOpenGLFramebufferObjectPrivate * const d = d_func(); | - | ||||||||||||||||||
544 | d->init(this, QSize(width, height), format.attachment(), format.textureTarget(), | - | ||||||||||||||||||
545 | format.internalTextureFormat(), format.samples(), format.mipmap()); | - | ||||||||||||||||||
546 | } | - | ||||||||||||||||||
547 | QOpenGLFramebufferObject::QOpenGLFramebufferObject(int width, int height, Attachment attachment, | - | ||||||||||||||||||
548 | GLenum target, GLenum internalFormat) | - | ||||||||||||||||||
549 | : d_ptr(new QOpenGLFramebufferObjectPrivate) | - | ||||||||||||||||||
550 | { | - | ||||||||||||||||||
551 | QOpenGLFramebufferObjectPrivate * const d = d_func(); | - | ||||||||||||||||||
552 | d->init(this, QSize(width, height), attachment, target, effectiveInternalFormat(internalFormat)); | - | ||||||||||||||||||
553 | } | - | ||||||||||||||||||
554 | QOpenGLFramebufferObject::QOpenGLFramebufferObject(const QSize &size, Attachment attachment, | - | ||||||||||||||||||
555 | GLenum target, GLenum internalFormat) | - | ||||||||||||||||||
556 | : d_ptr(new QOpenGLFramebufferObjectPrivate) | - | ||||||||||||||||||
557 | { | - | ||||||||||||||||||
558 | QOpenGLFramebufferObjectPrivate * const d = d_func(); | - | ||||||||||||||||||
559 | d->init(this, size, attachment, target, effectiveInternalFormat(internalFormat)); | - | ||||||||||||||||||
560 | } | - | ||||||||||||||||||
561 | - | |||||||||||||||||||
562 | - | |||||||||||||||||||
563 | - | |||||||||||||||||||
564 | - | |||||||||||||||||||
565 | - | |||||||||||||||||||
566 | - | |||||||||||||||||||
567 | QOpenGLFramebufferObject::~QOpenGLFramebufferObject() | - | ||||||||||||||||||
568 | { | - | ||||||||||||||||||
569 | QOpenGLFramebufferObjectPrivate * const d = d_func(); | - | ||||||||||||||||||
570 | if (isBound()
| 0 | ||||||||||||||||||
571 | release(); never executed: release(); | 0 | ||||||||||||||||||
572 | - | |||||||||||||||||||
573 | for (QForeachContainer<typename QtPrivate::remove_reference<decltypeconst auto &color : qAsConst(d->colorAttachments)>::type> _container_((d->colorAttachments)); _container_.control && _container_.i != _container_.e; ++_container_.i, _container_.control ^= 1) for (const QOpenGLFramebufferObjectPrivate::ColorAttachment &color = *_container_.i; _container_.control; _container_.control = 0))) { | - | ||||||||||||||||||
574 | if (color.guard
| 0 | ||||||||||||||||||
575 | color.guard->free(); never executed: color.guard->free(); | 0 | ||||||||||||||||||
576 | } never executed: end of block | 0 | ||||||||||||||||||
577 | d->colorAttachments.clear(); | - | ||||||||||||||||||
578 | - | |||||||||||||||||||
579 | if (d->depth_buffer_guard
| 0 | ||||||||||||||||||
580 | d->depth_buffer_guard->free(); never executed: d->depth_buffer_guard->free(); | 0 | ||||||||||||||||||
581 | if (d->stencil_buffer_guard
| 0 | ||||||||||||||||||
582 | d->stencil_buffer_guard->free(); never executed: d->stencil_buffer_guard->free(); | 0 | ||||||||||||||||||
583 | if (d->fbo_guard
| 0 | ||||||||||||||||||
584 | d->fbo_guard->free(); never executed: d->fbo_guard->free(); | 0 | ||||||||||||||||||
585 | - | |||||||||||||||||||
586 | QOpenGLContextPrivate *contextPrv = QOpenGLContextPrivate::get(QOpenGLContext::currentContext()); | - | ||||||||||||||||||
587 | if (contextPrv
| 0 | ||||||||||||||||||
588 | contextPrv->qgl_current_fbo_invalid = true; | - | ||||||||||||||||||
589 | contextPrv->qgl_current_fbo = nullptr; | - | ||||||||||||||||||
590 | } never executed: end of block | 0 | ||||||||||||||||||
591 | } never executed: end of block | 0 | ||||||||||||||||||
592 | void QOpenGLFramebufferObject::addColorAttachment(const QSize &size, GLenum internalFormat) | - | ||||||||||||||||||
593 | { | - | ||||||||||||||||||
594 | QOpenGLFramebufferObjectPrivate * const d = d_func(); | - | ||||||||||||||||||
595 | - | |||||||||||||||||||
596 | if (!QOpenGLContext::currentContext()->functions()->hasOpenGLFeature(QOpenGLFunctions::MultipleRenderTargets)) { | - | ||||||||||||||||||
597 | QMessageLogger(__FILE__, 9941000, __PRETTY_FUNCTION__).warning("Multiple render targets not supported, ignoring extra color attachment request"); | - | ||||||||||||||||||
598 | return; | - | ||||||||||||||||||
599 | } | - | ||||||||||||||||||
600 | - | |||||||||||||||||||
601 | QOpenGLFramebufferObjectPrivate::ColorAttachment color(size, effectiveInternalFormat(internalFormat)); | - | ||||||||||||||||||
602 | d->colorAttachments.append(color); | - | ||||||||||||||||||
603 | const int idx = d->colorAttachments.count() - 1; | - | ||||||||||||||||||
604 | - | |||||||||||||||||||
605 | if (d->requestedSamples == 0) { | - | ||||||||||||||||||
606 | d->initTexture(idx); | - | ||||||||||||||||||
607 | } else { | - | ||||||||||||||||||
608 | GLint samples = d->requestedSamples; | - | ||||||||||||||||||
609 | d->initColorBuffer(idx, &samples); | - | ||||||||||||||||||
610 | } | - | ||||||||||||||||||
611 | } | - | ||||||||||||||||||
612 | void QOpenGLFramebufferObject::addColorAttachment(int width, int height, GLenum internalFormat) | - | ||||||||||||||||||
613 | { | - | ||||||||||||||||||
614 | addColorAttachment(QSize(width, height), internalFormat); | - | ||||||||||||||||||
615 | } | - | ||||||||||||||||||
616 | bool QOpenGLFramebufferObject::isValid() const | - | ||||||||||||||||||
617 | { | - | ||||||||||||||||||
618 | const QOpenGLFramebufferObjectPrivate * const d = d_func(); | - | ||||||||||||||||||
619 | return d->valid && d->fbo_guard && d->fbo_guard->id(); | - | ||||||||||||||||||
620 | } | - | ||||||||||||||||||
621 | bool QOpenGLFramebufferObject::bind() | - | ||||||||||||||||||
622 | { | - | ||||||||||||||||||
623 | if (!isValid()
| 0 | ||||||||||||||||||
624 | return never executed: false;return false; never executed: return false; | 0 | ||||||||||||||||||
625 | QOpenGLFramebufferObjectPrivate * const d = d_func(); | - | ||||||||||||||||||
626 | QOpenGLContext *current = QOpenGLContext::currentContext(); | - | ||||||||||||||||||
627 | if (!current
| 0 | ||||||||||||||||||
628 | return never executed: false;return false; never executed: return false; | 0 | ||||||||||||||||||
629 | - | |||||||||||||||||||
630 | if (current->shareGroup() != d->fbo_guard->group()
| 0 | ||||||||||||||||||
631 | QMessageLogger(__FILE__, 10711077, __PRETTY_FUNCTION__).warning("QOpenGLFramebufferObject::bind() called from incompatible context"); never executed: QMessageLogger(__FILE__, 1077, __PRETTY_FUNCTION__).warning("QOpenGLFramebufferObject::bind() called from incompatible context"); | 0 | ||||||||||||||||||
632 | - | |||||||||||||||||||
633 | - | |||||||||||||||||||
634 | d->funcs.glBindFramebuffer(0x8D40, d->fbo()); | - | ||||||||||||||||||
635 | - | |||||||||||||||||||
636 | QOpenGLContextPrivate::get(current)->qgl_current_fbo_invalid = true; | - | ||||||||||||||||||
637 | QOpenGLContextPrivate::get(current)->qgl_current_fbo = this; | - | ||||||||||||||||||
638 | - | |||||||||||||||||||
639 | if (d->format.samples() == 0
| 0 | ||||||||||||||||||
640 | - | |||||||||||||||||||
641 | for (int i = 0; i < d->colorAttachments.count()
| 0 | ||||||||||||||||||
642 | if (!d->colorAttachments[.at(i].).guard
| 0 | ||||||||||||||||||
643 | d->initTexture(i); never executed: d->initTexture(i); | 0 | ||||||||||||||||||
644 | } never executed: end of block | 0 | ||||||||||||||||||
645 | } never executed: end of block | 0 | ||||||||||||||||||
646 | - | |||||||||||||||||||
647 | return never executed: d->valid;return d->valid; never executed: return d->valid; | 0 | ||||||||||||||||||
648 | } | - | ||||||||||||||||||
649 | bool QOpenGLFramebufferObject::release() | - | ||||||||||||||||||
650 | { | - | ||||||||||||||||||
651 | if (!isValid()) | - | ||||||||||||||||||
652 | return false; | - | ||||||||||||||||||
653 | - | |||||||||||||||||||
654 | QOpenGLContext *current = QOpenGLContext::currentContext(); | - | ||||||||||||||||||
655 | if (!current) | - | ||||||||||||||||||
656 | return false; | - | ||||||||||||||||||
657 | - | |||||||||||||||||||
658 | QOpenGLFramebufferObjectPrivate * const d = d_func(); | - | ||||||||||||||||||
659 | - | |||||||||||||||||||
660 | if (current->shareGroup() != d->fbo_guard->group()) | - | ||||||||||||||||||
661 | QMessageLogger(__FILE__, 11111117, __PRETTY_FUNCTION__).warning("QOpenGLFramebufferObject::release() called from incompatible context"); | - | ||||||||||||||||||
662 | - | |||||||||||||||||||
663 | - | |||||||||||||||||||
664 | if (current) { | - | ||||||||||||||||||
665 | d->funcs.glBindFramebuffer(0x8D40, current->defaultFramebufferObject()); | - | ||||||||||||||||||
666 | - | |||||||||||||||||||
667 | QOpenGLContextPrivate *contextPrv = QOpenGLContextPrivate::get(current); | - | ||||||||||||||||||
668 | contextPrv->qgl_current_fbo_invalid = true; | - | ||||||||||||||||||
669 | contextPrv->qgl_current_fbo = nullptr; | - | ||||||||||||||||||
670 | } | - | ||||||||||||||||||
671 | - | |||||||||||||||||||
672 | return true; | - | ||||||||||||||||||
673 | } | - | ||||||||||||||||||
674 | GLuint QOpenGLFramebufferObject::texture() const | - | ||||||||||||||||||
675 | { | - | ||||||||||||||||||
676 | const QOpenGLFramebufferObjectPrivate * const d = d_func(); | - | ||||||||||||||||||
677 | return d->colorAttachments[0].guard ? d->colorAttachments[0].guard->id() : 0; | - | ||||||||||||||||||
678 | } | - | ||||||||||||||||||
679 | QVector<GLuint> QOpenGLFramebufferObject::textures() const | - | ||||||||||||||||||
680 | { | - | ||||||||||||||||||
681 | const QOpenGLFramebufferObjectPrivate * const d = d_func(); | - | ||||||||||||||||||
682 | QVector<GLuint> ids; | - | ||||||||||||||||||
683 | if (d->format.samples() != 0
| 0 | ||||||||||||||||||
684 | return never executed: ids;return ids; never executed: return ids; | 0 | ||||||||||||||||||
685 | ids.reserve(d->colorAttachments.count()); | - | ||||||||||||||||||
686 | for (QForeachContainer<typename QtPrivate::remove_reference<decltype(d->colorAttachments)>::type> _container_((const auto &color : d->colorAttachments)); _container_.control && _container_.i != _container_.e; ++_container_.i, _container_.control ^= 1) for (const QOpenGLFramebufferObjectPrivate::ColorAttachment &color = *_container_.i; _container_.control; _container_.control = 0) | - | ||||||||||||||||||
687 | ids.append(color.guard ? color.guard->id() : 0); never executed: ids.append(color.guard ? color.guard->id() : 0); | 0 | ||||||||||||||||||
688 | return never executed: ids;return ids; never executed: return ids; | 0 | ||||||||||||||||||
689 | } | - | ||||||||||||||||||
690 | GLuint QOpenGLFramebufferObject::takeTexture() | - | ||||||||||||||||||
691 | { | - | ||||||||||||||||||
692 | return takeTexture(0); | - | ||||||||||||||||||
693 | } | - | ||||||||||||||||||
694 | GLuint QOpenGLFramebufferObject::takeTexture(int colorAttachmentIndex) | - | ||||||||||||||||||
695 | { | - | ||||||||||||||||||
696 | QOpenGLFramebufferObjectPrivate * const d = d_func(); | - | ||||||||||||||||||
697 | GLuint id = 0; | - | ||||||||||||||||||
698 | if (isValid()
| 0 | ||||||||||||||||||
699 | QOpenGLContext *current = QOpenGLContext::currentContext(); | - | ||||||||||||||||||
700 | if (current
| 0 | ||||||||||||||||||
701 | release(); never executed: release(); | 0 | ||||||||||||||||||
702 | idauto &guard = d->colorAttachments[colorAttachmentIndex].guard; | - | ||||||||||||||||||
703 | id = guard
| 0 | ||||||||||||||||||
704 | - | |||||||||||||||||||
705 | - | |||||||||||||||||||
706 | d->colorAttachments[colorAttachmentIndex].guard = 0; | - | ||||||||||||||||||
707 | } never executed: end of block | 0 | ||||||||||||||||||
708 | return never executed: id;return id; never executed: return id; | 0 | ||||||||||||||||||
709 | } | - | ||||||||||||||||||
710 | - | |||||||||||||||||||
711 | - | |||||||||||||||||||
712 | - | |||||||||||||||||||
713 | - | |||||||||||||||||||
714 | - | |||||||||||||||||||
715 | QSize QOpenGLFramebufferObject::size() const | - | ||||||||||||||||||
716 | { | - | ||||||||||||||||||
717 | const QOpenGLFramebufferObjectPrivate * const d = d_func(); | - | ||||||||||||||||||
718 | return d->dsSize; | - | ||||||||||||||||||
719 | } | - | ||||||||||||||||||
720 | - | |||||||||||||||||||
721 | - | |||||||||||||||||||
722 | - | |||||||||||||||||||
723 | - | |||||||||||||||||||
724 | - | |||||||||||||||||||
725 | - | |||||||||||||||||||
726 | - | |||||||||||||||||||
727 | QVector<QSize> QOpenGLFramebufferObject::sizes() const | - | ||||||||||||||||||
728 | { | - | ||||||||||||||||||
729 | const QOpenGLFramebufferObjectPrivate * const d = d_func(); | - | ||||||||||||||||||
730 | QVector<QSize> sz; | - | ||||||||||||||||||
731 | sz.reserve(d->colorAttachments.size()); | - | ||||||||||||||||||
732 | for (QForeachContainer<typename QtPrivate::remove_reference<decltype(d->colorAttachments)>::type> _container_((const auto &color : d->colorAttachments)); _container_.control && _container_.i != _container_.e; ++_container_.i, _container_.control ^= 1) for (const QOpenGLFramebufferObjectPrivate::ColorAttachment &color = *_container_.i; _container_.control; _container_.control = 0) | - | ||||||||||||||||||
733 | sz.append(color.size); never executed: sz.append(color.size); | 0 | ||||||||||||||||||
734 | return never executed: sz;return sz; never executed: return sz; | 0 | ||||||||||||||||||
735 | } | - | ||||||||||||||||||
736 | QOpenGLFramebufferObjectFormat QOpenGLFramebufferObject::format() const | - | ||||||||||||||||||
737 | { | - | ||||||||||||||||||
738 | const QOpenGLFramebufferObjectPrivate * const d = d_func(); | - | ||||||||||||||||||
739 | return d->format; | - | ||||||||||||||||||
740 | } | - | ||||||||||||||||||
741 | - | |||||||||||||||||||
742 | static inline QImage qt_gl_read_framebuffer_rgba8(const QSize &size, bool include_alpha, QOpenGLContext *context) | - | ||||||||||||||||||
743 | { | - | ||||||||||||||||||
744 | QOpenGLFunctions *funcs = context->functions(); | - | ||||||||||||||||||
745 | const int w = size.width(); | - | ||||||||||||||||||
746 | const int h = size.height(); | - | ||||||||||||||||||
747 | bool isOpenGL12orBetter = !context->isOpenGLES() && (context->format().majorVersion() >= 2 || context->format().minorVersion() >= 2); | - | ||||||||||||||||||
748 | if (isOpenGL12orBetter) { | - | ||||||||||||||||||
749 | QImage img(size, include_alpha ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32); | - | ||||||||||||||||||
750 | funcs->glReadPixels(0, 0, w, h, 0x80E1, 0x8367, img.bits()); | - | ||||||||||||||||||
751 | return img; | - | ||||||||||||||||||
752 | } | - | ||||||||||||||||||
753 | - | |||||||||||||||||||
754 | - | |||||||||||||||||||
755 | - | |||||||||||||||||||
756 | const bool has_bgra_ext = context->isOpenGLES() | - | ||||||||||||||||||
757 | ? context->hasExtension(([]() -> QByteArray { enum { Size = sizeof("GL_EXT_read_format_bgra") - 1 }; static const QStaticByteArrayData<Size> qbytearray_literal = { { { { -1 } }, Size, 0, 0, sizeof(QByteArrayData) }, "GL_EXT_read_format_bgra" }; QByteArrayDataPtr holder = { qbytearray_literal.data_ptr() }; const QByteArray ba(holder); return ba; }())) | - | ||||||||||||||||||
758 | : context->hasExtension(([]() -> QByteArray { enum { Size = sizeof("GL_EXT_bgra") - 1 }; static const QStaticByteArrayData<Size> qbytearray_literal = { { { { -1 } }, Size, 0, 0, sizeof(QByteArrayData) }, "GL_EXT_bgra" }; QByteArrayDataPtr holder = { qbytearray_literal.data_ptr() }; const QByteArray ba(holder); return ba; }())); | - | ||||||||||||||||||
759 | - | |||||||||||||||||||
760 | - | |||||||||||||||||||
761 | const char *renderer = reinterpret_cast<const char *>(funcs->glGetString(0x1F01)); | - | ||||||||||||||||||
762 | const char *ver = reinterpret_cast<const char *>(funcs->glGetString(0x1F02)); | - | ||||||||||||||||||
763 | - | |||||||||||||||||||
764 | - | |||||||||||||||||||
765 | const bool blackListed = (qstrcmp(renderer, "PowerVR Rogue G6200") == 0 | - | ||||||||||||||||||
766 | && ::strstr(ver, "1.3") != 0) || | - | ||||||||||||||||||
767 | (qstrcmp(renderer, "Mali-T760") == 0 | - | ||||||||||||||||||
768 | && ::strstr(ver, "3.1") != 0) || | - | ||||||||||||||||||
769 | (qstrcmp(renderer, "Mali-T720") == 0 | - | ||||||||||||||||||
770 | && ::strstr(ver, "3.1") != 0) || | - | ||||||||||||||||||
771 | qstrcmp(renderer, "PowerVR SGX 554") == 0; | - | ||||||||||||||||||
772 | - | |||||||||||||||||||
773 | - | |||||||||||||||||||
774 | - | |||||||||||||||||||
775 | const bool supports_bgra = has_bgra_ext && !blackListed; | - | ||||||||||||||||||
776 | - | |||||||||||||||||||
777 | if (supports_bgra) { | - | ||||||||||||||||||
778 | QImage img(size, include_alpha ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32); | - | ||||||||||||||||||
779 | funcs->glReadPixels(0, 0, w, h, 0x80E1, 0x1401, img.bits()); | - | ||||||||||||||||||
780 | return img; | - | ||||||||||||||||||
781 | } | - | ||||||||||||||||||
782 | - | |||||||||||||||||||
783 | QImage rgbaImage(size, include_alpha ? QImage::Format_RGBA8888_Premultiplied : QImage::Format_RGBX8888); | - | ||||||||||||||||||
784 | funcs->glReadPixels(0, 0, w, h, 0x1908, 0x1401, rgbaImage.bits()); | - | ||||||||||||||||||
785 | return rgbaImage; | - | ||||||||||||||||||
786 | } | - | ||||||||||||||||||
787 | - | |||||||||||||||||||
788 | static inline QImage qt_gl_read_framebuffer_rgb10a2(const QSize &size, bool include_alpha, QOpenGLContext *context) | - | ||||||||||||||||||
789 | { | - | ||||||||||||||||||
790 | - | |||||||||||||||||||
791 | QImage img(size, include_alpha ? QImage::Format_A2BGR30_Premultiplied : QImage::Format_BGR30); | - | ||||||||||||||||||
792 | context->functions()->glReadPixels(0, 0, size.width(), size.height(), 0x1908, 0x8368, img.bits()); | - | ||||||||||||||||||
793 | return img; | - | ||||||||||||||||||
794 | } | - | ||||||||||||||||||
795 | - | |||||||||||||||||||
796 | static QImage qt_gl_read_framebuffer(const QSize &size, GLenum internal_format, bool include_alpha, bool flip) | - | ||||||||||||||||||
797 | { | - | ||||||||||||||||||
798 | QOpenGLContext *ctx = QOpenGLContext::currentContext(); | - | ||||||||||||||||||
799 | QOpenGLFunctions *funcs = ctx->functions(); | - | ||||||||||||||||||
800 | while (funcs->glGetError()); | - | ||||||||||||||||||
801 | - | |||||||||||||||||||
802 | switch (internal_format) { | - | ||||||||||||||||||
803 | case 0x1907: | - | ||||||||||||||||||
804 | case 0x8051: | - | ||||||||||||||||||
805 | return qt_gl_read_framebuffer_rgba8(size, false, ctx).mirrored(false, flip); | - | ||||||||||||||||||
806 | case 0x8052: | - | ||||||||||||||||||
807 | return qt_gl_read_framebuffer_rgb10a2(size, false, ctx).mirrored(false, flip); | - | ||||||||||||||||||
808 | case 0x8059: | - | ||||||||||||||||||
809 | return qt_gl_read_framebuffer_rgb10a2(size, include_alpha, ctx).mirrored(false, flip); | - | ||||||||||||||||||
810 | case 0x1908: | - | ||||||||||||||||||
811 | case 0x8058: | - | ||||||||||||||||||
812 | default: | - | ||||||||||||||||||
813 | return qt_gl_read_framebuffer_rgba8(size, include_alpha, ctx).mirrored(false, flip); | - | ||||||||||||||||||
814 | } | - | ||||||||||||||||||
815 | - | |||||||||||||||||||
816 | do dead code: { ((!(false)) ? qt_assert_x("Q_UNREACHABLE()", "Q_UNREACHABLE was reached",__FILE__,13461353) : qt_noop()); __builtin_unreachable(); } while (0);do { ((!(false)) ? qt_assert_x("Q_UNREACHABLE()", "Q_UNREACHABLE was reached",__FILE__,1353) : qt_noop()); __builtin_unreachable(); } while (0); dead code: do { ((!(false)) ? qt_assert_x("Q_UNREACHABLE()", "Q_UNREACHABLE was reached",__FILE__,1353) : qt_noop()); __builtin_unreachable(); } while (0); | - | ||||||||||||||||||
817 | return dead code: QImage();return QImage(); dead code: return QImage(); | - | ||||||||||||||||||
818 | } | - | ||||||||||||||||||
819 | - | |||||||||||||||||||
820 | __attribute__((visibility("default"))) QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_format, bool include_alpha) | - | ||||||||||||||||||
821 | { | - | ||||||||||||||||||
822 | return qt_gl_read_framebuffer(size, alpha_format ? 0x1908 : 0x1907, include_alpha, true); | - | ||||||||||||||||||
823 | } | - | ||||||||||||||||||
824 | QImage QOpenGLFramebufferObject::toImage(bool flipped) const | - | ||||||||||||||||||
825 | { | - | ||||||||||||||||||
826 | return toImage(flipped, 0); | - | ||||||||||||||||||
827 | } | - | ||||||||||||||||||
828 | QImage QOpenGLFramebufferObject::toImage() const | - | ||||||||||||||||||
829 | { | - | ||||||||||||||||||
830 | return toImage(true, 0); | - | ||||||||||||||||||
831 | } | - | ||||||||||||||||||
832 | QImage QOpenGLFramebufferObject::toImage(bool flipped, int colorAttachmentIndex) const | - | ||||||||||||||||||
833 | { | - | ||||||||||||||||||
834 | const QOpenGLFramebufferObjectPrivate * const d = d_func(); | - | ||||||||||||||||||
835 | if (!d->valid) | - | ||||||||||||||||||
836 | return QImage(); | - | ||||||||||||||||||
837 | - | |||||||||||||||||||
838 | QOpenGLContext *ctx = QOpenGLContext::currentContext(); | - | ||||||||||||||||||
839 | if (!ctx) { | - | ||||||||||||||||||
840 | QMessageLogger(__FILE__, 14321439, __PRETTY_FUNCTION__).warning("QOpenGLFramebufferObject::toImage() called without a current context"); | - | ||||||||||||||||||
841 | return QImage(); | - | ||||||||||||||||||
842 | } | - | ||||||||||||||||||
843 | - | |||||||||||||||||||
844 | if (d->colorAttachments.count() <= colorAttachmentIndex) { | - | ||||||||||||||||||
845 | QMessageLogger(__FILE__, 14371444, __PRETTY_FUNCTION__).warning("QOpenGLFramebufferObject::toImage() called for missing color attachment"); | - | ||||||||||||||||||
846 | return QImage(); | - | ||||||||||||||||||
847 | } | - | ||||||||||||||||||
848 | - | |||||||||||||||||||
849 | GLuint prevFbo = 0; | - | ||||||||||||||||||
850 | ctx->functions()->glGetIntegerv(0x8CA6, (GLint *) &prevFbo); | - | ||||||||||||||||||
851 | - | |||||||||||||||||||
852 | if (prevFbo != d->fbo()) | - | ||||||||||||||||||
853 | const_cast<QOpenGLFramebufferObject *>(this)->bind(); | - | ||||||||||||||||||
854 | - | |||||||||||||||||||
855 | QImage image; | - | ||||||||||||||||||
856 | QOpenGLExtraFunctions *extraFuncs = ctx->extraFunctions(); | - | ||||||||||||||||||
857 | - | |||||||||||||||||||
858 | if (format().samples() != 0) { | - | ||||||||||||||||||
859 | QRect rect(QPoint(0, 0), size()); | - | ||||||||||||||||||
860 | if (extraFuncs->hasOpenGLFeature(QOpenGLFunctions::MultipleRenderTargets)) { | - | ||||||||||||||||||
861 | QOpenGLFramebufferObject temp(d->colorAttachments[colorAttachmentIndex].size, QOpenGLFramebufferObjectFormat()); | - | ||||||||||||||||||
862 | blitFramebuffer(&temp, rect, const_cast<QOpenGLFramebufferObject *>(this), rect, | - | ||||||||||||||||||
863 | 0x00004000, 0x2600, | - | ||||||||||||||||||
864 | colorAttachmentIndex, 0); | - | ||||||||||||||||||
865 | image = temp.toImage(flipped); | - | ||||||||||||||||||
866 | } else { | - | ||||||||||||||||||
867 | QOpenGLFramebufferObject temp(size(), QOpenGLFramebufferObjectFormat()); | - | ||||||||||||||||||
868 | blitFramebuffer(&temp, rect, const_cast<QOpenGLFramebufferObject *>(this), rect); | - | ||||||||||||||||||
869 | image = temp.toImage(flipped); | - | ||||||||||||||||||
870 | } | - | ||||||||||||||||||
871 | } else { | - | ||||||||||||||||||
872 | if (extraFuncs->hasOpenGLFeature(QOpenGLFunctions::MultipleRenderTargets)) { | - | ||||||||||||||||||
873 | extraFuncs->glReadBuffer(0x8CE0 + colorAttachmentIndex); | - | ||||||||||||||||||
874 | image = qt_gl_read_framebuffer(d->colorAttachments[colorAttachmentIndex].size, | - | ||||||||||||||||||
875 | d->colorAttachments[colorAttachmentIndex].internalFormat, | - | ||||||||||||||||||
876 | true, flipped); | - | ||||||||||||||||||
877 | extraFuncs->glReadBuffer(0x8CE0); | - | ||||||||||||||||||
878 | } else { | - | ||||||||||||||||||
879 | image = qt_gl_read_framebuffer(d->colorAttachments[0].size, | - | ||||||||||||||||||
880 | d->colorAttachments[0].internalFormat, | - | ||||||||||||||||||
881 | true, flipped); | - | ||||||||||||||||||
882 | } | - | ||||||||||||||||||
883 | } | - | ||||||||||||||||||
884 | - | |||||||||||||||||||
885 | if (prevFbo != d->fbo()) | - | ||||||||||||||||||
886 | ctx->functions()->glBindFramebuffer(0x8D40, prevFbo); | - | ||||||||||||||||||
887 | - | |||||||||||||||||||
888 | return image; | - | ||||||||||||||||||
889 | } | - | ||||||||||||||||||
890 | bool QOpenGLFramebufferObject::bindDefault() | - | ||||||||||||||||||
891 | { | - | ||||||||||||||||||
892 | QOpenGLContext *ctx = const_cast<QOpenGLContext *>(QOpenGLContext::currentContext()); | - | ||||||||||||||||||
893 | - | |||||||||||||||||||
894 | if (ctx) { | - | ||||||||||||||||||
895 | ctx->functions()->glBindFramebuffer(0x8D40, ctx->defaultFramebufferObject()); | - | ||||||||||||||||||
896 | QOpenGLContextPrivate::get(ctx)->qgl_current_fbo_invalid = true; | - | ||||||||||||||||||
897 | QOpenGLContextPrivate::get(ctx)->qgl_current_fbo = nullptr; | - | ||||||||||||||||||
898 | } | - | ||||||||||||||||||
899 | - | |||||||||||||||||||
900 | else | - | ||||||||||||||||||
901 | QMessageLogger(__FILE__, 15031510, __PRETTY_FUNCTION__).warning("QOpenGLFramebufferObject::bindDefault() called without current context."); | - | ||||||||||||||||||
902 | - | |||||||||||||||||||
903 | - | |||||||||||||||||||
904 | return ctx != 0; | - | ||||||||||||||||||
905 | } | - | ||||||||||||||||||
906 | - | |||||||||||||||||||
907 | - | |||||||||||||||||||
908 | - | |||||||||||||||||||
909 | - | |||||||||||||||||||
910 | - | |||||||||||||||||||
911 | - | |||||||||||||||||||
912 | - | |||||||||||||||||||
913 | bool QOpenGLFramebufferObject::hasOpenGLFramebufferObjects() | - | ||||||||||||||||||
914 | { | - | ||||||||||||||||||
915 | return QOpenGLContext::currentContext()->functions()->hasOpenGLFeature(QOpenGLFunctions::Framebuffers); | - | ||||||||||||||||||
916 | } | - | ||||||||||||||||||
917 | GLuint QOpenGLFramebufferObject::handle() const | - | ||||||||||||||||||
918 | { | - | ||||||||||||||||||
919 | const QOpenGLFramebufferObjectPrivate * const d = d_func(); | - | ||||||||||||||||||
920 | return d->fbo(); | - | ||||||||||||||||||
921 | } | - | ||||||||||||||||||
922 | - | |||||||||||||||||||
923 | - | |||||||||||||||||||
924 | - | |||||||||||||||||||
925 | - | |||||||||||||||||||
926 | - | |||||||||||||||||||
927 | - | |||||||||||||||||||
928 | QOpenGLFramebufferObject::Attachment QOpenGLFramebufferObject::attachment() const | - | ||||||||||||||||||
929 | { | - | ||||||||||||||||||
930 | const QOpenGLFramebufferObjectPrivate * const d = d_func(); | - | ||||||||||||||||||
931 | if (d->valid) | - | ||||||||||||||||||
932 | return d->fbo_attachment; | - | ||||||||||||||||||
933 | return NoAttachment; | - | ||||||||||||||||||
934 | } | - | ||||||||||||||||||
935 | void QOpenGLFramebufferObject::setAttachment(QOpenGLFramebufferObject::Attachment attachment) | - | ||||||||||||||||||
936 | { | - | ||||||||||||||||||
937 | QOpenGLFramebufferObjectPrivate * const d = d_func(); | - | ||||||||||||||||||
938 | if (attachment == d->fbo_attachment || !isValid()) | - | ||||||||||||||||||
939 | return; | - | ||||||||||||||||||
940 | QOpenGLContext *current = QOpenGLContext::currentContext(); | - | ||||||||||||||||||
941 | if (!current) | - | ||||||||||||||||||
942 | return; | - | ||||||||||||||||||
943 | - | |||||||||||||||||||
944 | if (current->shareGroup() != d->fbo_guard->group()) | - | ||||||||||||||||||
945 | QMessageLogger(__FILE__, 15661573, __PRETTY_FUNCTION__).warning("QOpenGLFramebufferObject::setAttachment() called from incompatible context"); | - | ||||||||||||||||||
946 | - | |||||||||||||||||||
947 | d->funcs.glBindFramebuffer(0x8D40, d->fbo()); | - | ||||||||||||||||||
948 | QOpenGLContextPrivate::get(current)->qgl_current_fbo_invalid = true; | - | ||||||||||||||||||
949 | d->initDepthStencilAttachments(current, attachment); | - | ||||||||||||||||||
950 | } | - | ||||||||||||||||||
951 | - | |||||||||||||||||||
952 | - | |||||||||||||||||||
953 | - | |||||||||||||||||||
954 | - | |||||||||||||||||||
955 | - | |||||||||||||||||||
956 | bool QOpenGLFramebufferObject::isBound() const | - | ||||||||||||||||||
957 | { | - | ||||||||||||||||||
958 | const QOpenGLFramebufferObjectPrivate * const d = d_func(); | - | ||||||||||||||||||
959 | QOpenGLContext *ctx = QOpenGLContext::currentContext(); | - | ||||||||||||||||||
960 | if (!ctx) | - | ||||||||||||||||||
961 | return false; | - | ||||||||||||||||||
962 | GLint fbo = 0; | - | ||||||||||||||||||
963 | ctx->functions()->glGetIntegerv(0x8CA6, &fbo); | - | ||||||||||||||||||
964 | return GLuint(fbo) == d->fbo(); | - | ||||||||||||||||||
965 | } | - | ||||||||||||||||||
966 | bool QOpenGLFramebufferObject::hasOpenGLFramebufferBlit() | - | ||||||||||||||||||
967 | { | - | ||||||||||||||||||
968 | return QOpenGLExtensions(QOpenGLContext::currentContext()).hasOpenGLExtension(QOpenGLExtensions::FramebufferBlit); | - | ||||||||||||||||||
969 | } | - | ||||||||||||||||||
970 | - | |||||||||||||||||||
971 | - | |||||||||||||||||||
972 | - | |||||||||||||||||||
973 | - | |||||||||||||||||||
974 | - | |||||||||||||||||||
975 | - | |||||||||||||||||||
976 | - | |||||||||||||||||||
977 | void QOpenGLFramebufferObject::blitFramebuffer(QOpenGLFramebufferObject *target, | - | ||||||||||||||||||
978 | QOpenGLFramebufferObject *source, | - | ||||||||||||||||||
979 | GLbitfield buffers, GLenum filter) | - | ||||||||||||||||||
980 | { | - | ||||||||||||||||||
981 | if (!target && !source) | - | ||||||||||||||||||
982 | return; | - | ||||||||||||||||||
983 | - | |||||||||||||||||||
984 | QSize targetSize; | - | ||||||||||||||||||
985 | QSize sourceSize; | - | ||||||||||||||||||
986 | - | |||||||||||||||||||
987 | if (target) | - | ||||||||||||||||||
988 | targetSize = target->size(); | - | ||||||||||||||||||
989 | if (source) | - | ||||||||||||||||||
990 | sourceSize = source->size(); | - | ||||||||||||||||||
991 | - | |||||||||||||||||||
992 | if (targetSize.isEmpty()) | - | ||||||||||||||||||
993 | targetSize = sourceSize; | - | ||||||||||||||||||
994 | else if (sourceSize.isEmpty()) | - | ||||||||||||||||||
995 | sourceSize = targetSize; | - | ||||||||||||||||||
996 | - | |||||||||||||||||||
997 | blitFramebuffer(target, QRect(QPoint(0, 0), targetSize), | - | ||||||||||||||||||
998 | source, QRect(QPoint(0, 0), sourceSize), | - | ||||||||||||||||||
999 | buffers, filter); | - | ||||||||||||||||||
1000 | } | - | ||||||||||||||||||
1001 | - | |||||||||||||||||||
1002 | - | |||||||||||||||||||
1003 | - | |||||||||||||||||||
1004 | - | |||||||||||||||||||
1005 | - | |||||||||||||||||||
1006 | void QOpenGLFramebufferObject::blitFramebuffer(QOpenGLFramebufferObject *target, const QRect &targetRect, | - | ||||||||||||||||||
1007 | QOpenGLFramebufferObject *source, const QRect &sourceRect, | - | ||||||||||||||||||
1008 | GLbitfield buffers, | - | ||||||||||||||||||
1009 | GLenum filter) | - | ||||||||||||||||||
1010 | { | - | ||||||||||||||||||
1011 | blitFramebuffer(target, targetRect, source, sourceRect, buffers, filter, 0, 0); | - | ||||||||||||||||||
1012 | } | - | ||||||||||||||||||
1013 | void QOpenGLFramebufferObject::blitFramebuffer(QOpenGLFramebufferObject *target, const QRect &targetRect, | - | ||||||||||||||||||
1014 | QOpenGLFramebufferObject *source, const QRect &sourceRect, | - | ||||||||||||||||||
1015 | GLbitfield buffers, | - | ||||||||||||||||||
1016 | GLenum filter, | - | ||||||||||||||||||
1017 | int readColorAttachmentIndex, | - | ||||||||||||||||||
1018 | int drawColorAttachmentIndex, | - | ||||||||||||||||||
1019 | QOpenGLFramebufferObject::FramebufferRestorePolicy restorePolicy) | - | ||||||||||||||||||
1020 | { | - | ||||||||||||||||||
1021 | QOpenGLContext *ctx = QOpenGLContext::currentContext(); | - | ||||||||||||||||||
1022 | if (!ctx
| 0 | ||||||||||||||||||
1023 | return; never executed: return; | 0 | ||||||||||||||||||
1024 | - | |||||||||||||||||||
1025 | QOpenGLExtensions extensions(ctx); | - | ||||||||||||||||||
1026 | if (!extensions.hasOpenGLExtension(QOpenGLExtensions::FramebufferBlit)
| 0 | ||||||||||||||||||
1027 | return; never executed: return; | 0 | ||||||||||||||||||
1028 | - | |||||||||||||||||||
1029 | GLuint prevFbo = 0; | - | ||||||||||||||||||
1030 | if (restorePolicy == RestoreFrameBufferBinding
| 0 | ||||||||||||||||||
1031 | ctx->functions()->glGetIntegerv(0x8CA6, (GLint *) &prevFbo); never executed: ctx->functions()->glGetIntegerv(0x8CA6, (GLint *) &prevFbo); | 0 | ||||||||||||||||||
1032 | - | |||||||||||||||||||
1033 | const int sx0 = sourceRect.left(); | - | ||||||||||||||||||
1034 | const int sx1 = sourceRect.left() + sourceRect.width(); | - | ||||||||||||||||||
1035 | const int sy0 = sourceRect.top(); | - | ||||||||||||||||||
1036 | const int sy1 = sourceRect.top() + sourceRect.height(); | - | ||||||||||||||||||
1037 | - | |||||||||||||||||||
1038 | const int tx0 = targetRect.left(); | - | ||||||||||||||||||
1039 | const int tx1 = targetRect.left() + targetRect.width(); | - | ||||||||||||||||||
1040 | const int ty0 = targetRect.top(); | - | ||||||||||||||||||
1041 | const int ty1 = targetRect.top() + targetRect.height(); | - | ||||||||||||||||||
1042 | - | |||||||||||||||||||
1043 | const GLuint defaultFboId = ctx->defaultFramebufferObject(); | - | ||||||||||||||||||
1044 | - | |||||||||||||||||||
1045 | extensions.glBindFramebuffer(0x8CA8, source ? source->handle() : defaultFboId); | - | ||||||||||||||||||
1046 | extensions.glBindFramebuffer(0x8CA9, target ? target->handle() : defaultFboId); | - | ||||||||||||||||||
1047 | - | |||||||||||||||||||
1048 | if (const bool supportsMRT = extensions.hasOpenGLFeature(QOpenGLFunctions::MultipleRenderTargets))); | - | ||||||||||||||||||
1049 | if (supportsMRT
| 0 | ||||||||||||||||||
1050 | extensions.glReadBuffer(0x8CE0 + readColorAttachmentIndex); | - | ||||||||||||||||||
1051 | if (target
| 0 | ||||||||||||||||||
1052 | GLenum drawBuf = 0x8CE0 + drawColorAttachmentIndex; | - | ||||||||||||||||||
1053 | extensions.glDrawBuffers(1, &drawBuf); | - | ||||||||||||||||||
1054 | } never executed: end of block | 0 | ||||||||||||||||||
1055 | } never executed: end of block | 0 | ||||||||||||||||||
1056 | - | |||||||||||||||||||
1057 | extensions.glBlitFramebuffer(sx0, sy0, sx1, sy1, | - | ||||||||||||||||||
1058 | tx0, ty0, tx1, ty1, | - | ||||||||||||||||||
1059 | buffers, filter); | - | ||||||||||||||||||
1060 | - | |||||||||||||||||||
1061 | if (extensions.hasOpenGLFeature(QOpenGLFunctions::MultipleRenderTargets))supportsMRT
| 0 | ||||||||||||||||||
1062 | extensions.glReadBuffer(0x8CE0); never executed: extensions.glReadBuffer(0x8CE0); | 0 | ||||||||||||||||||
1063 | - | |||||||||||||||||||
1064 | switch (restorePolicy) { | - | ||||||||||||||||||
1065 | case never executed: RestoreFrameBufferBinding:case RestoreFrameBufferBinding: never executed: case RestoreFrameBufferBinding: | 0 | ||||||||||||||||||
1066 | ctx->functions()->glBindFramebuffer(0x8D40, prevFbo); | - | ||||||||||||||||||
1067 | break; never executed: break; | 0 | ||||||||||||||||||
1068 | - | |||||||||||||||||||
1069 | case never executed: RestoreFramebufferBindingToDefault:case RestoreFramebufferBindingToDefault: never executed: case RestoreFramebufferBindingToDefault: | 0 | ||||||||||||||||||
1070 | ctx->functions()->glBindFramebuffer(0x8D40, ctx->defaultFramebufferObject()); | - | ||||||||||||||||||
1071 | break; never executed: break; | 0 | ||||||||||||||||||
1072 | - | |||||||||||||||||||
1073 | case never executed: DontRestoreFramebufferBinding:case DontRestoreFramebufferBinding: never executed: case DontRestoreFramebufferBinding: | 0 | ||||||||||||||||||
1074 | break; never executed: break; | 0 | ||||||||||||||||||
1075 | } | - | ||||||||||||||||||
1076 | } never executed: end of block | 0 | ||||||||||||||||||
1077 | void QOpenGLFramebufferObject::blitFramebuffer(QOpenGLFramebufferObject *target, const QRect &targetRect, | - | ||||||||||||||||||
1078 | QOpenGLFramebufferObject *source, const QRect &sourceRect, | - | ||||||||||||||||||
1079 | GLbitfield buffers, | - | ||||||||||||||||||
1080 | GLenum filter, | - | ||||||||||||||||||
1081 | int readColorAttachmentIndex, | - | ||||||||||||||||||
1082 | int drawColorAttachmentIndex) | - | ||||||||||||||||||
1083 | { | - | ||||||||||||||||||
1084 | blitFramebuffer(target, targetRect, source, sourceRect, | - | ||||||||||||||||||
1085 | buffers, filter, | - | ||||||||||||||||||
1086 | readColorAttachmentIndex, | - | ||||||||||||||||||
1087 | drawColorAttachmentIndex, | - | ||||||||||||||||||
1088 | RestoreFrameBufferBinding); | - | ||||||||||||||||||
1089 | } never executed: end of block | 0 | ||||||||||||||||||
1090 | - | |||||||||||||||||||
1091 | - | |||||||||||||||||||
Switch to Source code | Preprocessed file |