summaryrefslogtreecommitdiffstats
path: root/src/gui
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@qt.io>2021-03-25 12:39:02 +0100
committerLaszlo Agocs <laszlo.agocs@qt.io>2021-05-19 17:35:35 +0200
commit8827cd657d12a037deb3e6f4f76271ee0bbd0b13 (patch)
tree6acbccb6ceda0714740a813da14a6f1abd139672 /src/gui
parent2d9cc639a4a7a5e97979a6034364bd67dfa10c23 (diff)
rhi: gl: Add support for importing an existing renderbuffer object
Normally we only allow creating wrappers for texture objects. These can then be used with a QRhiTextureRenderTarget to allow rendering into an externally created texture. With OpenGL (ES), there are additional, special cases, especially on embedded. Consider EGLImages for example. An EGLImageKHR can be bound to a renderbuffer object (glEGLImageTargetRenderbufferStorageOES), which can then be associated with a framebuffer object to allow rendering into the external buffer represented by the EGLImage. To implement the same via QRhi one needs a way to create a wrapping QRhiRenderBuffer for the native OpenGL renderbuffer object. Here we add a createFrom() to QRhiRenderBuffer, while providing a dummy, default implementation. The only real implementation is in the OpenGL backend, which simply takes a renderbuffer id, without taking ownership. Task-number: QTBUG-92116 Change-Id: I4e68e665fb35a7d7803b7780db901c8bed5740e2 Reviewed-by: Andy Nichols <andy.nichols@qt.io>
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/rhi/qrhi.cpp47
-rw-r--r--src/gui/rhi/qrhi_p.h8
-rw-r--r--src/gui/rhi/qrhid3d11.cpp2
-rw-r--r--src/gui/rhi/qrhigles2.cpp33
-rw-r--r--src/gui/rhi/qrhigles2_p_p.h2
-rw-r--r--src/gui/rhi/qrhimetal.mm2
-rw-r--r--src/gui/rhi/qrhivulkan.cpp2
7 files changed, 94 insertions, 2 deletions
diff --git a/src/gui/rhi/qrhi.cpp b/src/gui/rhi/qrhi.cpp
index 8c24f11079..242f244c1d 100644
--- a/src/gui/rhi/qrhi.cpp
+++ b/src/gui/rhi/qrhi.cpp
@@ -642,6 +642,15 @@ Q_LOGGING_CATEGORY(QRHI_LOG_INFO, "qt.rhi.general")
supported (which can happen when the underlying API is OpenGL ES 2.0 without
support for GL_UNPACK_ROW_LENGTH),
QRhiTextureSubresourceUploadDescription::setDataStride() must not be used.
+
+ \value RenderBufferImport Indicates that QRhiRenderBuffer::createFrom() is
+ supported. For most graphics APIs this is not sensible because
+ QRhiRenderBuffer encapsulates texture objects internally, just like
+ QRhiTexture. With OpenGL however, renderbuffer object exist as a separate
+ object type in the API, and in certain environments (for example, where one
+ may want to associated a renderbuffer object with an EGLImage object) it is
+ important to allow wrapping an existing OpenGL renderbuffer object with a
+ QRhiRenderBuffer.
*/
/*!
@@ -2306,6 +2315,44 @@ QRhiResource::Type QRhiRenderBuffer::resourceType() const
*/
/*!
+ Similar to create() except that no new native renderbuffer objects are
+ created. Instead, the native renderbuffer object specified by \a src is
+ used.
+
+ This allows importing an existing renderbuffer object (which must belong to
+ the same device or sharing context, depending on the graphics API) from an
+ external graphics engine.
+
+ \note This is currently applicable to OpenGL only. This function exists
+ solely to allow importing a renderbuffer object that is bound to some
+ special, external object, such as an EGLImageKHR. Once the application
+ performed the glEGLImageTargetRenderbufferStorageOES call, the renderbuffer
+ object can be passed to this function to create a wrapping
+ QRhiRenderBuffer, which in turn can be passed in as a color attachment to
+ a QRhiTextureRenderTarget to enable rendering to the EGLImage.
+
+ \note pixelSize(), sampleCount(), and flags() must still be set correctly.
+ Passing incorrect sizes and other values to QRhi::newRenderBuffer() and
+ then following it with a createFrom() expecting that the native
+ renderbuffer object alone is sufficient to deduce such values is \b wrong
+ and will lead to problems.
+
+ \note QRhiRenderBuffer does not take ownership of the native object, and
+ destroy() will not release that object.
+
+ \note This function is only implemented when the QRhi::RenderBufferImport
+ feature is reported as \l{QRhi::isFeatureSupported()}{supported}. Otherwise,
+ the function does nothing and the return value is \c false.
+
+ \return \c true when successful, \c false when not supported.
+ */
+bool QRhiRenderBuffer::createFrom(NativeRenderBuffer src)
+{
+ Q_UNUSED(src);
+ return false;
+}
+
+/*!
\fn QRhiTexture::Format QRhiRenderBuffer::backingFormat() const
\internal
diff --git a/src/gui/rhi/qrhi_p.h b/src/gui/rhi/qrhi_p.h
index b43d490ea9..c915f8df0d 100644
--- a/src/gui/rhi/qrhi_p.h
+++ b/src/gui/rhi/qrhi_p.h
@@ -918,6 +918,10 @@ public:
};
Q_DECLARE_FLAGS(Flags, Flag)
+ struct NativeRenderBuffer {
+ quint64 object;
+ };
+
QRhiResource::Type resourceType() const override;
Type type() const { return m_type; }
@@ -933,6 +937,7 @@ public:
void setFlags(Flags h) { m_flags = h; }
virtual bool create() = 0;
+ virtual bool createFrom(NativeRenderBuffer src);
virtual QRhiTexture::Format backingFormat() const = 0;
@@ -1534,7 +1539,8 @@ public:
ScreenSpaceDerivatives,
ReadBackAnyTextureFormat,
PipelineCacheDataLoadSave,
- ImageDataStride
+ ImageDataStride,
+ RenderBufferImport
};
enum BeginFrameFlag {
diff --git a/src/gui/rhi/qrhid3d11.cpp b/src/gui/rhi/qrhid3d11.cpp
index 46851ad612..8d15f2622f 100644
--- a/src/gui/rhi/qrhid3d11.cpp
+++ b/src/gui/rhi/qrhid3d11.cpp
@@ -544,6 +544,8 @@ bool QRhiD3D11::isFeatureSupported(QRhi::Feature feature) const
return false;
case QRhi::ImageDataStride:
return true;
+ case QRhi::RenderBufferImport:
+ return false;
default:
Q_UNREACHABLE();
return false;
diff --git a/src/gui/rhi/qrhigles2.cpp b/src/gui/rhi/qrhigles2.cpp
index 43569d3752..8a5361b29a 100644
--- a/src/gui/rhi/qrhigles2.cpp
+++ b/src/gui/rhi/qrhigles2.cpp
@@ -1011,6 +1011,8 @@ bool QRhiGles2::isFeatureSupported(QRhi::Feature feature) const
return caps.programBinary;
case QRhi::ImageDataStride:
return !caps.gles || caps.ctxMajor >= 3;
+ case QRhi::RenderBufferImport:
+ return true;
default:
Q_UNREACHABLE();
return false;
@@ -4287,7 +4289,8 @@ void QGles2RenderBuffer::destroy()
stencilRenderbuffer = 0;
QRHI_RES_RHI(QRhiGles2);
- rhiD->releaseQueue.append(e);
+ if (owns)
+ rhiD->releaseQueue.append(e);
QRHI_PROF;
QRHI_PROF_F(releaseRenderBuffer(this));
rhiD->unregisterResource(this);
@@ -4375,6 +4378,34 @@ bool QGles2RenderBuffer::create()
break;
}
+ owns = true;
+ rhiD->registerResource(this);
+ return true;
+}
+
+bool QGles2RenderBuffer::createFrom(NativeRenderBuffer src)
+{
+ if (!src.object)
+ return false;
+
+ if (renderbuffer)
+ destroy();
+
+ QRHI_RES_RHI(QRhiGles2);
+ samples = rhiD->effectiveSampleCount(m_sampleCount);
+
+ if (m_flags.testFlag(UsedWithSwapChainOnly))
+ qWarning("RenderBuffer: UsedWithSwapChainOnly is meaningless when importing an existing native object");
+
+ if (!rhiD->ensureContext())
+ return false;
+
+ renderbuffer = src.object;
+
+ QRHI_PROF;
+ QRHI_PROF_F(newRenderBuffer(this, false, false, samples));
+
+ owns = false;
rhiD->registerResource(this);
return true;
}
diff --git a/src/gui/rhi/qrhigles2_p_p.h b/src/gui/rhi/qrhigles2_p_p.h
index 3d9fba80dc..cb6cd241ff 100644
--- a/src/gui/rhi/qrhigles2_p_p.h
+++ b/src/gui/rhi/qrhigles2_p_p.h
@@ -100,11 +100,13 @@ struct QGles2RenderBuffer : public QRhiRenderBuffer
~QGles2RenderBuffer();
void destroy() override;
bool create() override;
+ bool createFrom(NativeRenderBuffer src) override;
QRhiTexture::Format backingFormat() const override;
GLuint renderbuffer = 0;
GLuint stencilRenderbuffer = 0; // when packed depth-stencil not supported
int samples;
+ bool owns = true;
friend class QRhiGles2;
};
diff --git a/src/gui/rhi/qrhimetal.mm b/src/gui/rhi/qrhimetal.mm
index 850b3a91aa..384e23598c 100644
--- a/src/gui/rhi/qrhimetal.mm
+++ b/src/gui/rhi/qrhimetal.mm
@@ -595,6 +595,8 @@ bool QRhiMetal::isFeatureSupported(QRhi::Feature feature) const
return false;
case QRhi::ImageDataStride:
return true;
+ case QRhi::RenderBufferImport:
+ return false;
default:
Q_UNREACHABLE();
return false;
diff --git a/src/gui/rhi/qrhivulkan.cpp b/src/gui/rhi/qrhivulkan.cpp
index e7e31b1b2d..73288cb4a1 100644
--- a/src/gui/rhi/qrhivulkan.cpp
+++ b/src/gui/rhi/qrhivulkan.cpp
@@ -4243,6 +4243,8 @@ bool QRhiVulkan::isFeatureSupported(QRhi::Feature feature) const
return true;
case QRhi::ImageDataStride:
return true;
+ case QRhi::RenderBufferImport:
+ return false;
default:
Q_UNREACHABLE();
return false;