void ImageBufferDataPrivateAccelerated::draw(GraphicsContext* destContext, ColorSpace styleColorSpace, const FloatRect& destRect, const FloatRect& srcRect, CompositeOperator op, BlendMode blendMode, bool useLowQualityScale, bool ownContext) { if (destContext->isAcceleratedContext()) { QOpenGLContext *previousContext = QOpenGLContext::currentContext(); GLSharedContext::makeCurrent(); commitChanges(); previousContext->makeCurrent(previousContext->surface()); QOpenGL2PaintEngineEx* acceleratedPaintEngine = static_cast<QOpenGL2PaintEngineEx*>(destContext->platformContext()->paintEngine()); FloatRect flippedSrc = srcRect; flippedSrc.setY(m_fbo->size().height() - flippedSrc.height() - flippedSrc.y()); acceleratedPaintEngine->drawTexture(destRect, m_fbo->texture(), m_fbo->size(), flippedSrc); } else { RefPtr<Image> image = StillImage::create(QPixmap::fromImage(toQImage())); destContext->drawImage(image.get(), styleColorSpace, destRect, srcRect, op, blendMode, DoNotRespectImageOrientation, useLowQualityScale); } }
void ImageBufferDataPrivateAccelerated::draw(GraphicsContext* destContext, ColorSpace styleColorSpace, const FloatRect& destRect, const FloatRect& srcRect, CompositeOperator op, BlendMode blendMode, bool useLowQualityScale, bool /*ownContext*/) { if (destContext->isAcceleratedContext()) { invalidateState(); // If accelerated compositing is disabled, this may be the painter of the QGLWidget, which is a QGL2PaintEngineEx. QOpenGL2PaintEngineEx* acceleratedPaintEngine = dynamic_cast<QOpenGL2PaintEngineEx*>(destContext->platformContext()->paintEngine()); if (acceleratedPaintEngine) { QPaintDevice* targetPaintDevice = acceleratedPaintEngine->paintDevice(); QRect rect(QPoint(), m_paintDevice->size()); // drawTexture's rendering is flipped relative to QtWebKit's convention, so we need to compensate FloatRect srcRectFlipped = m_paintDevice->paintFlipped() ? FloatRect(srcRect.x(), srcRect.maxY(), srcRect.width(), -srcRect.height()) : FloatRect(srcRect.x(), rect.height() - srcRect.maxY(), srcRect.width(), srcRect.height()); // Using the same texture as source and target of a rendering operation is undefined in OpenGL, // so if that's the case we need to use a temporary intermediate buffer. if (m_paintDevice == targetPaintDevice) { m_context->makeCurrentIfNeeded(); QFramebufferPaintDevice device(rect.size(), QOpenGLFramebufferObject::NoAttachment, false); // We disable flipping in order to do a pure blit into the intermediate buffer device.setPaintFlipped(false); QPainter painter(&device); QOpenGL2PaintEngineEx* pe = static_cast<QOpenGL2PaintEngineEx*>(painter.paintEngine()); pe->drawTexture(rect, m_paintDevice->texture(), rect.size(), rect); painter.end(); acceleratedPaintEngine->drawTexture(destRect, device.texture(), rect.size(), srcRectFlipped); } else { acceleratedPaintEngine->drawTexture(destRect, m_paintDevice->texture(), rect.size(), srcRectFlipped); } return; } } RefPtr<Image> image = StillImage::create(QPixmap::fromImage(toQImage())); destContext->drawImage(image.get(), styleColorSpace, destRect, srcRect, op, blendMode, DoNotRespectImageOrientation, useLowQualityScale); }
void ImageBufferDataPrivateAccelerated::invalidateState() const { // This will flush pending QPainter operations and force ensureActiveTarget() to be called on the next paint. QOpenGL2PaintEngineEx* acceleratedPaintEngine = static_cast<QOpenGL2PaintEngineEx*>(m_paintDevice->paintEngine()); acceleratedPaintEngine->invalidateState(); }