Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Laszlo Agocs
qtrhi
Commits
7873f256
Commit
7873f256
authored
Mar 04, 2019
by
Laszlo Agocs
Browse files
Add releaseAndDestroyLater()
Inspired by QObject::deleteLater()...
parent
eba81cf0
Changes
4
Hide whitespace changes
Inline
Side-by-side
src/rhi/qrhi.cpp
View file @
7873f256
...
...
@@ -130,7 +130,10 @@ QT_BEGIN_NAMESPACE
\l{QRhiCommandBuffer::beginFrame()}{beginFrame()} -
\l{QRhiCommandBuffer::endFrame()}{endFrame()} section). As a general rule,
all referenced QRhiResource objects must stay unchanged until the frame is
submitted by calling \l{QRhiCommandBuffer::endFrame()}{endFrame()}.
submitted by calling \l{QRhiCommandBuffer::endFrame()}{endFrame()}. To ease
this, QRhiResource::releaseAndDestroyLater() is provided as a convenience.
This allows applications to safely issue a (defered) releaseAndDestroy()
while recording a frame.
\endlist
...
...
@@ -157,9 +160,16 @@ QT_BEGIN_NAMESPACE
frame. Reusing a QRhiResource instance within a frame (by rebuilding it and
then referencing it again in the same \c{beginFrame - endFrame} section)
should be avoided as it may lead to unexpected results, depending on the
backend. As a general rule, all referenced QRhiResource objects must stay
unchanged until the frame is submitted by calling
\l{QRhiCommandBuffer::endFrame()}{endFrame()}.
backend.
As a general rule, all referenced QRhiResource objects must stay valid and
unmodified until the frame is submitted by calling
\l{QRhiCommandBuffer::endFrame()}{endFrame()}. On the other hand,
\l{QRhiResource::release()}{release()} or
\l{QRhiResource::releaseAndDestroy()}{releaseAndDestroy()} are always safe
to call once the frame is submitted, regardless of the status of the
underlying native resources (which may still be in use by the GPU - but
that is taken care of internally).
Unlike APIs like OpenGL, upload and copy type of commands cannot be mixed
with draw commands. The typical renderer will involve a sequence similar to
...
...
@@ -187,15 +197,15 @@ QT_BEGIN_NAMESPACE
The importance of reusing the same object lies in the fact that some
objects reference other objects: for example, a QRhiShaderResourceBindings
can reference QRhiBuffer, QRhiTexture, and QRhiSampler instances. If
now
one of these buffers need to be resized or a sampler parameter
needs
changing, destroying and creating a whole new QRhiBuffer or
QRhiSampler
would invalidate all references to the old instance. By just
changing the
appropriate parameters via QRhiBuffer::setSize() or similar
and then
calling QRhiBuffer::build(), everything works as expected and
there is no
need to touch the QRhiShaderResourceBindings at all, even
though there is a
good chance that under the hood the QRhiBuffer is now
backed by a whole new
native buffer.
can reference QRhiBuffer, QRhiTexture, and QRhiSampler instances. If
in a
later frame
one of these buffers need to be resized or a sampler parameter
needs
changing, destroying and creating a whole new QRhiBuffer or
QRhiSampler
would invalidate all references to the old instance. By just
changing the
appropriate parameters via QRhiBuffer::setSize() or similar
and then
calling QRhiBuffer::build(), everything works as expected and
there is no
need to touch the QRhiShaderResourceBindings at all, even
though there is a
good chance that under the hood the QRhiBuffer is now
backed by a whole new
native buffer.
\badcode
ubuf = rhi->newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::UniformBuffer, 256);
...
...
@@ -1592,16 +1602,28 @@ QRhiResource::~QRhiResource()
/*!
\fn void QRhiResource::release()
Releases the underlying native graphics resources. Safe to call multiple
times, subsequent invocations will be a no-op then.
Releases (or requests defered releasing of) the underlying native graphics
resources. Safe to call multiple times, subsequent invocations will be a
no-op then.
Once release() is called, the QRhiResource instance can be reused, by
calling the appropriate \c build() function again, or destroyed.
\note Resources referenced by commands for the current frame should not be
released until the frame is submitted by QRhi::endFrame().
\sa releaseAndDestroy(), releaseAndDestroyLater()
*/
/*!
Releases native graphics resources, if there is any, and destroys the
QRhiResource. Equivalent to \c{r->release(); delete r; }.
Releases (or requests defered releasing of) the native graphics resources,
if there are any, and destroys the QRhiResource. Equivalent to
\c{r->release(); delete r; }.
\note Resources referenced by commands for the current frame should not be
released until the frame is submitted by QRhi::endFrame().
\sa release(), releaseAndDestroyLater()
*/
void
QRhiResource
::
releaseAndDestroy
()
{
...
...
@@ -1609,6 +1631,21 @@ void QRhiResource::releaseAndDestroy()
delete
this
;
}
/*!
When called without a frame being recorded, this function is equivalent to
releaseAndDestroy(). Between a QRhi::beginFrame() and QRhi::endFrame()
however the behavior is different: the QRhiResource will not be destroyed
until the frame is submitted via QRhi::endFrame(), thus satisfying the QRhi
requirement of not altering QRhiResource objects that are referenced by the
frame being recorded.
\sa release(), releaseAndDestroy()
*/
void
QRhiResource
::
releaseAndDestroyLater
()
{
m_rhi
->
addReleaseAndDestroyLater
(
this
);
}
/*!
\return the currently set object name. By default the name is empty.
*/
...
...
@@ -4436,6 +4473,8 @@ QRhiSwapChain *QRhi::newSwapChain()
*/
QRhi
::
FrameOpResult
QRhi
::
beginFrame
(
QRhiSwapChain
*
swapChain
,
BeginFrameFlags
flags
)
{
Q_ASSERT
(
!
d
->
inFrame
);
d
->
inFrame
=
true
;
return
d
->
beginFrame
(
swapChain
,
flags
);
}
...
...
@@ -4454,7 +4493,17 @@ QRhi::FrameOpResult QRhi::beginFrame(QRhiSwapChain *swapChain, BeginFrameFlags f
*/
QRhi
::
FrameOpResult
QRhi
::
endFrame
(
QRhiSwapChain
*
swapChain
,
EndFrameFlags
flags
)
{
return
d
->
endFrame
(
swapChain
,
flags
);
Q_ASSERT
(
d
->
inFrame
);
QRhi
::
FrameOpResult
r
=
d
->
endFrame
(
swapChain
,
flags
);
// releaseAndDestroyLater is a high level QRhi concept the backends know
// nothing about - handle it here.
d
->
inFrame
=
false
;
for
(
QRhiResource
*
res
:
qAsConst
(
d
->
pendingReleaseAndDestroyResources
))
res
->
releaseAndDestroy
();
d
->
pendingReleaseAndDestroyResources
.
clear
();
return
r
;
}
/*!
...
...
src/rhi/qrhi.h
View file @
7873f256
...
...
@@ -566,6 +566,7 @@ public:
virtual
void
release
()
=
0
;
void
releaseAndDestroy
();
void
releaseAndDestroyLater
();
QByteArray
name
()
const
;
void
setName
(
const
QByteArray
&
name
);
...
...
src/rhi/qrhi_p.h
View file @
7873f256
...
...
@@ -187,15 +187,27 @@ public:
return
true
;
}
void
addReleaseAndDestroyLater
(
QRhiResource
*
res
)
{
if
(
inFrame
)
pendingReleaseAndDestroyResources
.
insert
(
res
);
else
res
->
releaseAndDestroy
();
}
QRhi
*
q
;
protected:
QRhiResourceSharingHostPrivate
*
rsh
=
nullptr
;
bool
debugMarkers
=
false
;
private:
QRhiProfiler
profiler
;
QVector
<
QRhiResourceUpdateBatch
*>
resUpdPool
;
QBitArray
resUpdPoolMap
;
QRhiProfiler
profiler
;
bool
debugMarkers
=
false
;
QSet
<
QRhiResource
*>
resources
;
QSet
<
QRhiResource
*>
pendingReleaseAndDestroyResources
;
bool
inFrame
=
false
;
friend
class
QRhi
;
friend
class
QRhiResourceUpdateBatchPrivate
;
...
...
src/rhi/qrhigles2.cpp
View file @
7873f256
...
...
@@ -372,17 +372,6 @@ void QRhiGles2::destroy()
f
=
nullptr
;
}
// Deferred releases may seem unncessary. But consider:
//
// - it is kind of nice that no release() ever requires a current context and
// so GL calls are isolated to specific places (build, beginFrame, endFrame) as
// much as possible.
//
// - while not strictly required, it ensures that the native object survives
// the current frame, so if the application releases a QRhiResource, like
// texture or buffer, within a frame where the resource is used, it won't blow
// up in in endFrame().
void
QRhiGles2
::
executeDeferredReleases
()
{
for
(
int
i
=
releaseQueue
.
count
()
-
1
;
i
>=
0
;
--
i
)
{
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment