Skip to content

Commit

Permalink
Adding support for the pause/resume api. (#677)
Browse files Browse the repository at this point in the history
Fixes #595
  • Loading branch information
sirpalee committed Mar 1, 2021
1 parent fe23d56 commit 7b14072
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 8 deletions.
16 changes: 16 additions & 0 deletions render_delegate/render_delegate.cpp
Expand Up @@ -889,4 +889,20 @@ bool HdArnoldRenderDelegate::ShouldSkipIteration(HdRenderIndex* renderIndex, flo
return false;
}

bool HdArnoldRenderDelegate::IsPauseSupported() const
{
return true;
}

bool HdArnoldRenderDelegate::Pause()
{
_renderParam->Pause();
return true;
}

bool HdArnoldRenderDelegate::Resume()
{
_renderParam->Resume();
return true;
}
PXR_NAMESPACE_CLOSE_SCOPE
19 changes: 19 additions & 0 deletions render_delegate/render_delegate.h
Expand Up @@ -291,8 +291,27 @@ class HdArnoldRenderDelegate final : public HdRenderDelegate {
/// @param shutterOpen Shutter Open value of the active camera.
/// @param shutterClose Shutter Close value of the active camera.
/// @return True if the iteration should be skipped.
HDARNOLD_API
bool ShouldSkipIteration(HdRenderIndex* renderIndex, float shutterOpen, float shutterClose);

/// Advertise whether this delegate supports pausing and resuming of
/// background render threads. Default implementation returns false.
///
/// @return True if pause/restart is supported.
HDARNOLD_API
bool IsPauseSupported() const override;
/// Pause all of this delegate's background rendering threads. Default
/// implementation does nothing.
///
/// @return True if successful.
HDARNOLD_API
bool Pause() override;
/// Resume all of this delegate's background rendering threads previously
/// paused by a call to Pause. Default implementation does nothing.
///
/// @return True if successful.
HDARNOLD_API
bool Resume() override;
private:
HdArnoldRenderDelegate(const HdArnoldRenderDelegate&) = delete;
HdArnoldRenderDelegate& operator=(const HdArnoldRenderDelegate&) = delete;
Expand Down
33 changes: 31 additions & 2 deletions render_delegate/render_param.cpp
Expand Up @@ -52,6 +52,7 @@ HdArnoldRenderParam::Status HdArnoldRenderParam::Render()
// For the atomic operations we are using a release-acquire model.
const auto needsRestart = _needsRestart.exchange(false, std::memory_order_acq_rel);
if (needsRestart) {
_paused.store(false, std::memory_order_release);
AiRenderRestart();
return Status::Converging;
}
Expand All @@ -60,16 +61,24 @@ HdArnoldRenderParam::Status HdArnoldRenderParam::Render()
// Resetting the value.
_needsRestart.store(false, std::memory_order_release);
if (status == AI_RENDER_STATUS_PAUSED) {
AiRenderRestart();
const auto needsRestart = _needsRestart.exchange(false, std::memory_order_acq_rel);
if (needsRestart) {
_paused.store(false, std::memory_order_release);
AiRenderRestart();
} else if (!_paused.load(std::memory_order_acquire)) {
AiRenderResume();
}
return Status::Converging;
}

if (status == AI_RENDER_STATUS_RESTARTING) {
_paused.store(false, std::memory_order_release);
return Status::Converging;
}

if (status == AI_RENDER_STATUS_FAILED) {
_aborted.store(true, std::memory_order_release);
_paused.store(false, std::memory_order_release);
const auto errorCode = AiRenderEnd();
if (errorCode == AI_ABORT) {
TF_WARN("[arnold-usd] Render was aborted.");
Expand All @@ -92,20 +101,40 @@ HdArnoldRenderParam::Status HdArnoldRenderParam::Render()
}
return Status::Aborted;
}
_paused.store(false, std::memory_order_release);
AiRenderBegin();
return Status::Converging;
}

void HdArnoldRenderParam::Interrupt(bool clearStatus)
void HdArnoldRenderParam::Interrupt(bool needsRestart, bool clearStatus)
{
const auto status = AiRenderGetStatus();
if (status != AI_RENDER_STATUS_NOT_STARTED) {
AiRenderInterrupt(AI_BLOCKING);
}
if (needsRestart) {
_needsRestart.store(true, std::memory_order_release);
}
if (clearStatus) {
_aborted.store(false, std::memory_order_release);
}
}

void HdArnoldRenderParam::Pause()
{
Interrupt(false, false);
_paused.store(true, std::memory_order_release);
}

void HdArnoldRenderParam::Resume()
{
_paused.store(false, std::memory_order_release);
}

void HdArnoldRenderParam::Restart()
{
_paused.store(false, std::memory_order_release);
_needsRestart.store(true, std::memory_order_release);
}

PXR_NAMESPACE_CLOSE_SCOPE
18 changes: 16 additions & 2 deletions render_delegate/render_param.h
Expand Up @@ -68,16 +68,30 @@ class HdArnoldRenderParam final : public HdRenderParam {
///
/// Useful when there is new data to display, or the render settings have changed.
///
/// @param needsRestart Whether or not changes are applied to the scene and we need to restart rendering.
/// @param clearStatus Clears the internal failure status. Set it to false when no scene data changed, that could
/// affect the aborted internal status.
HDARNOLD_API
void Interrupt(bool clearStatus = true);

void Interrupt(bool needsRestart = true, bool clearStatus = true);
/// Pauses an ongoing render, does nothing if no render is running.
HDARNOLD_API
void Pause();
/// Resumes an already paused render, does nothing if no render is running, or the render is not paused.
HDARNOLD_API
void Resume();
/// Stops an ongoing render, does nothing if no render is running.
HDARNOLD_API
void Stop();
/// Resumes an already running,stopped/paused/finished render.
HDARNOLD_API
void Restart();
private:
/// Indicate if render needs restarting, in case interrupt is called after rendering has finished.
std::atomic<bool> _needsRestart;
/// Indicate if rendering has been aborted at one point or another.
std::atomic<bool> _aborted;
/// Indicate if rendering has been paused.
std::atomic<bool> _paused;
};

PXR_NAMESPACE_CLOSE_SCOPE
8 changes: 4 additions & 4 deletions render_delegate/render_pass.cpp
Expand Up @@ -365,7 +365,7 @@ void HdArnoldRenderPass::_Execute(const HdRenderPassStateSharedPtr& renderPassSt
if (projMtx != _projMtx || viewMtx != _viewMtx) {
_projMtx = projMtx;
_viewMtx = viewMtx;
renderParam->Interrupt(false);
renderParam->Interrupt(true, false);
AiNodeSetMatrix(_mainDriver, str::projMtx, HdArnoldConvertMatrix(_projMtx));
AiNodeSetMatrix(_mainDriver, str::viewMtx, HdArnoldConvertMatrix(_viewMtx));
if (useOwnedCamera) {
Expand All @@ -378,7 +378,7 @@ void HdArnoldRenderPass::_Execute(const HdRenderPassStateSharedPtr& renderPassSt
const auto width = static_cast<int>(dataWindow.GetWidth());
const auto height = static_cast<int>(dataWindow.GetHeight());
if (width != _width || height != _height) {
renderParam->Interrupt(false);
renderParam->Interrupt(true, false);
_width = width;
_height = height;
auto* options = _renderDelegate->GetOptions();
Expand Down Expand Up @@ -437,7 +437,7 @@ void HdArnoldRenderPass::_Execute(const HdRenderPassStateSharedPtr& renderPassSt
// If USD has the newer compositor class, we can allocate float buffers for the color, otherwise we need to
// stick to UNorm8.
if (!_usingFallbackBuffers) {
renderParam->Interrupt(false);
renderParam->Interrupt(true, false);
AiNodeSetArray(_renderDelegate->GetOptions(), str::outputs, AiArrayCopy(_fallbackOutputs));
_usingFallbackBuffers = true;
AiNodeSetPtr(_mainDriver, str::aov_pointer, &_fallbackBuffers);
Expand All @@ -446,7 +446,7 @@ void HdArnoldRenderPass::_Execute(const HdRenderPassStateSharedPtr& renderPassSt
AiNodeSetPtr(_mainDriver, str::id_pointer, &_fallbackPrimId);
}
if (_fallbackColor.GetWidth() != _width || _fallbackColor.GetHeight() != _height) {
renderParam->Interrupt(false);
renderParam->Interrupt(true, false);
#ifdef USD_HAS_UPDATED_COMPOSITOR
_fallbackColor.Allocate({_width, _height, 1}, HdFormatFloat32Vec4, false);
#else
Expand Down

0 comments on commit 7b14072

Please sign in to comment.