Fix clearing Rendertarget multiple times

This fixes a bug Renderer clearing a render target multiple times when the first time and back again.

Usually the default RenderTarget is unintentionally cleared/discarded in the current behavior.
1) Renderer renders a view without custom RenderTarget having full-screen viewport,
2) Renderer renders a view with custom RenderTarget
3) And Renderer renders an another view without custom RenderTarget having different viewport from 1)
You may see junk or empty pixels in outside of the viewport of the view 3), depending on ClearOptions and the backend.

This fix make Renderer put cleared RenderTargets into a set and check them to be cleared only for the first time, instead of comparing the previous RenderTarget to the current RenderTarget.
This commit is contained in:
MasTraER
2020-11-27 17:38:46 +09:00
committed by Philip Rideout
parent b3d7819e78
commit 61d473887f
2 changed files with 6 additions and 4 deletions

View File

@@ -229,9 +229,9 @@ void FRenderer::renderJob(ArenaScope& arena, FView& view) {
}
FRenderTarget* currentRenderTarget = upcast(view.getRenderTarget());
if (mPreviousRenderTarget != currentRenderTarget) {
if (mPreviousRenderTargets.find(currentRenderTarget) == mPreviousRenderTargets.end()) {
mPreviousRenderTargets.insert(currentRenderTarget);
initializeClearFlags();
mPreviousRenderTarget = currentRenderTarget;
}
view.prepare(engine, driver, arena, svp, getShaderUserTime());
@@ -906,7 +906,7 @@ bool FRenderer::beginFrame(FSwapChain* swapChain, uint64_t vsyncSteadyClockTimeN
mShaderUserTime = { h, l, 0, 0 };
initializeClearFlags();
mPreviousRenderTarget = nullptr;
mPreviousRenderTargets.clear();
mBeginFrameInternal = {};

View File

@@ -40,6 +40,8 @@
#include <utils/JobSystem.h>
#include <utils/Slice.h>
#include <tsl/robin_set.h>
namespace filament {
namespace backend {
@@ -192,7 +194,7 @@ private:
ClearOptions mClearOptions;
backend::TargetBufferFlags mDiscardedFlags{};
backend::TargetBufferFlags mClearFlags{};
FRenderTarget* mPreviousRenderTarget = nullptr;
tsl::robin_set<FRenderTarget*> mPreviousRenderTargets;
std::function<void()> mBeginFrameInternal;
// per-frame arena for this Renderer