6#include "QskTextureRenderer.h"
9#include <qopenglcontext.h>
10#include <qopenglframebufferobject.h>
11#include <qopenglpaintdevice.h>
16#include <qquickwindow.h>
19#include <private/qsgplaintexture_p.h>
20#include <private/qopenglframebufferobject_p.h>
23#if QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 )
24 #include <qquickopenglutils.h>
27static GLuint qskTakeTexture( QOpenGLFramebufferObject& fbo )
38 virtual ~MyFBO() =
default;
39 QScopedPointer< QOpenGLFramebufferObjectPrivate > d_ptr;
42 static_assert(
sizeof( MyFBO ) ==
sizeof( QOpenGLFramebufferObject ),
43 "Bad cast: QOpenGLFramebufferObject does not match" );
45 auto& attachment =
reinterpret_cast< MyFBO*
>( &fbo )->d_ptr->colorAttachments[0];
46 auto guard = attachment.guard;
48 const auto textureId = fbo.takeTexture();
52 class MyGuard :
public QOpenGLSharedResourceGuard
55 void invalidateTexture() { invalidateResource(); }
58 reinterpret_cast< MyGuard*
>( guard )->invalidateTexture();
61 attachment.guard = guard;
66bool QskTextureRenderer::isOpenGLWindow(
const QQuickWindow* window )
68 if ( window ==
nullptr )
71 const auto renderer = window->rendererInterface();
72 switch( renderer->graphicsApi() )
74 case QSGRendererInterface::OpenGL:
75#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
76 case QSGRendererInterface::OpenGLRhi:
85void QskTextureRenderer::setTextureId( QQuickWindow* window,
86 quint32 textureId,
const QSize& size, QSGTexture* texture )
88 auto plainTexture = qobject_cast< QSGPlainTexture* >( texture );
89 if ( plainTexture ==
nullptr )
92 auto rhi = qskRenderingHardwareInterface( window );
94#if QT_VERSION >= QT_VERSION_CHECK( 6, 4, 0 )
96 const uint nativeFormat = 0;
97 plainTexture->setTextureFromNativeTexture(
98 rhi, quint64( textureId ), 0, nativeFormat, size, {}, {} );
100#elif QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 )
101 plainTexture->setTextureFromNativeTexture(
102 rhi, quint64( textureId ), 0, size, {}, {} );
107 plainTexture->setTextureFromNativeObject( rhi,
108 QQuickWindow::NativeObjectTexture, &textureId, 0, size,
false );
112 plainTexture->setTextureId( textureId );
113 plainTexture->setTextureSize( size );
118quint32 QskTextureRenderer::createPaintedTextureGL(
136 window->beginExternalCommands();
138#if QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 )
139 QQuickOpenGLUtils::resetOpenGLState();
141 window->resetOpenGLState();
144 auto context = QOpenGLContext::currentContext();
146 QOpenGLFramebufferObjectFormat format1;
147 format1.setAttachment( QOpenGLFramebufferObject::CombinedDepthStencil );
149 format1.setSamples( context->format().samples() );
151 QOpenGLFramebufferObject multisampledFbo( size, format1 );
153 QOpenGLPaintDevice pd( size );
154 pd.setPaintFlipped(
true );
157 QPainter painter( &pd );
159 painter.setCompositionMode( QPainter::CompositionMode_Source );
160 painter.fillRect( 0, 0, size.width(), size.height(), Qt::transparent );
161 painter.setCompositionMode( QPainter::CompositionMode_SourceOver );
163 const auto ratio = window->effectiveDevicePixelRatio();
165 painter.scale( ratio, ratio );
166 helper->paint( &painter, size / ratio );
169 if ( format1.samples() > 0 )
176 painter.setRenderHint( QPainter::Antialiasing,
true );
181 QOpenGLFramebufferObjectFormat format2;
182 format2.setAttachment( QOpenGLFramebufferObject::NoAttachment );
184 QOpenGLFramebufferObject fbo( size, format2 );
186 const QRect fboRect( 0, 0, size.width(), size.height() );
188 QOpenGLFramebufferObject::blitFramebuffer(
189 &fbo, fboRect, &multisampledFbo, fboRect );
191 window->endExternalCommands();
193 return qskTakeTexture( fbo );
196static QSGTexture* qskCreateTextureRaster( QQuickWindow* window,
199 const auto ratio = window ? window->effectiveDevicePixelRatio() : 1.0;
201 QImage image( size * ratio, QImage::Format_RGBA8888_Premultiplied );
202 image.fill( Qt::transparent );
205 QPainter painter( &image );
211 painter.scale( ratio, ratio );
213 helper->paint( &painter, size );
216 return window->createTextureFromImage( image, QQuickWindow::TextureHasAlphaChannel );
219QSGTexture* QskTextureRenderer::createPaintedTexture(
220 QQuickWindow* window,
const QSize& size, PaintHelper* helper )
222 if ( isOpenGLWindow( window ) )
224 const auto textureId = createPaintedTextureGL( window, size, helper );
226 auto texture =
new QSGPlainTexture;
227 texture->setHasAlphaChannel(
true );
228 texture->setOwnsTexture(
true );
230 setTextureId( window, textureId, size, texture );
236 return qskCreateTextureRaster( window, size, helper );