| 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 |