Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions include/Inventor/SoRenderManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ class COIN_DLL_API SoRenderManager {
uint64_t backendResourcePreparationNanoseconds = 0;
uint64_t backendCommandExecutionNanoseconds = 0;
uint64_t backendSelectionNanoseconds = 0;
uint64_t drawListRebuilds = 0;
uint64_t pickPlanConstructionNanoseconds = 0;
uint64_t pickBufferUpdateNanoseconds = 0;
uint64_t pickQueryNanoseconds = 0;
Expand Down
2 changes: 2 additions & 0 deletions include/Inventor/rendering/SoRenderIR.h
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,8 @@ enum SoAlphaTestPolicy : uint8_t {
// --- Render param flags (SoRenderParams::flags) ---
static constexpr uint32_t SO_PARAM_CLEAR_WINDOW = 1u;
static constexpr uint32_t SO_PARAM_CLEAR_DEPTH = 4u; //!< Clear depth buffer before rendering
//! The owning caller guarantees that this exact draw list is unchanged.
static constexpr uint32_t SO_PARAM_REUSE_DRAW_LIST = 8u;

/*!
\struct SoTextureData
Expand Down
25 changes: 21 additions & 4 deletions src/rendering/SoGLRenderBackend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1454,10 +1454,24 @@ SoGLRenderBackend::textureDescriptionMatches(
entry.textureAnisotropic == texture.anisotropic;
}

void
SoGLRenderBackend::prepareGeometryCache(const SoDrawList & drawlist,
const bool allowReuse)
{
const size_t commandCount = static_cast<size_t>(drawlist.getNumCommands());
if (allowReuse && this->haveCacheGeneration &&
this->cacheGeneration == drawlist.getGeneration() &&
this->cachedCommandCount == commandCount) {
return;
}
this->updateGeometryCache(drawlist);
}

void
SoGLRenderBackend::updateGeometryCache(const SoDrawList & drawlist)
{
const uint32_t generation = drawlist.getGeneration();
const size_t commandCount = static_cast<size_t>(drawlist.getNumCommands());
if (!this->haveCacheGeneration || this->cacheGeneration != generation) {
for (CachedCommand & entry : this->gpuCache) {
if (!entry.persistent) this->destroyCacheEntry(entry);
Expand All @@ -1476,7 +1490,7 @@ SoGLRenderBackend::updateGeometryCache(const SoDrawList & drawlist)
}
this->cacheGeneration = generation;
this->haveCacheGeneration = true;
this->cachedCommandCount = static_cast<size_t>(drawlist.getNumCommands());
this->cachedCommandCount = commandCount;

for (int i = 0; i < drawlist.getNumCommands(); ++i) {
const SoRenderCommand & command = drawlist.getCommand(i);
Expand Down Expand Up @@ -2939,7 +2953,8 @@ SoGLRenderBackend::updatePickBuffer(const SoDrawList & drawlist,
const SbVec2s size = params.viewport.getViewportSizePixels();
if (!this->ensurePickFramebuffer(size)) return FALSE;

this->updateGeometryCache(drawlist);
this->prepareGeometryCache(
drawlist, (params.flags & SO_PARAM_REUSE_DRAW_LIST) != 0);

cc_glglue_glBindFramebuffer(this->glue, GL_FRAMEBUFFER,
this->pickTarget.framebuffer);
Expand Down Expand Up @@ -3409,7 +3424,8 @@ SoGLRenderBackend::renderSelection(const SoDrawList & drawlist,
}

ScopedGLState state(this->glue);
this->updateGeometryCache(drawlist);
this->prepareGeometryCache(
drawlist, (params.flags & SO_PARAM_REUSE_DRAW_LIST) != 0);
applyViewport(params);
glEnable(GL_BLEND);
cc_glglue_glBlendFuncSeparate(this->glue, GL_SRC_ALPHA,
Expand Down Expand Up @@ -3504,7 +3520,8 @@ SoGLRenderBackend::render(const SoDrawList & drawlist,
}
const BackendPhaseClock::time_point resourceStart = measurePhases
? BackendPhaseClock::now() : BackendPhaseClock::time_point();
this->updateGeometryCache(drawlist);
this->prepareGeometryCache(
drawlist, (params.flags & SO_PARAM_REUSE_DRAW_LIST) != 0);
if (measurePhases) {
this->phaseStatistics.resourcePreparationNanoseconds =
elapsedNanoseconds(resourceStart);
Expand Down
1 change: 1 addition & 0 deletions src/rendering/SoGLRenderBackend.h
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,7 @@ class SoGLRenderBackend : public SoRenderBackend {
bool selection);
void beginFrame(const SoRenderParams & params);
void invalidateCache();
void prepareGeometryCache(const SoDrawList & drawlist, bool allowReuse);
void updateGeometryCache(const SoDrawList & drawlist);
void updateLineDistances(CachedCommand & entry,
const SoRenderCommand & command,
Expand Down
91 changes: 77 additions & 14 deletions src/rendering/SoRenderManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,9 @@ retainedRenderParams(const SoRenderManagerP * manager)
params.devicePixelRatio = manager->devicePixelRatio;
params.clearColor = manager->backgroundcolor;
params.clearDepth = 1.0f;
if (manager->drawListValid && !manager->drawListDirty) {
params.flags |= SO_PARAM_REUSE_DRAW_LIST;
}
return params;
}

Expand Down Expand Up @@ -406,6 +409,12 @@ SoRenderManager::SoRenderManager(void)
PRIVATE(this)->renderPhaseStatistics = RenderPhaseStatistics();
PRIVATE(this)->renderBackendContextId = 0;
PRIVATE(this)->drawListCallbackScope = FALSE;
PRIVATE(this)->drawListValid = FALSE;
PRIVATE(this)->drawListDirty = TRUE;
PRIVATE(this)->drawListSceneRevision = 0;
PRIVATE(this)->drawListCameraRevision = 0;
PRIVATE(this)->drawListBackgroundRevision = 0;
PRIVATE(this)->drawListForegroundRevision = 0;
PRIVATE(this)->pickTargetDirty = TRUE;
PRIVATE(this)->pickTargetGeneration = 0;
PRIVATE(this)->viewport = SbViewportRegion(SbVec2s(400, 400));
Expand Down Expand Up @@ -512,6 +521,7 @@ SoRenderManager::setSceneGraph(SoNode * const sceneroot)
PRIVATE(this)->cameraInSceneGraph = FALSE;

PRIVATE(this)->scene = sceneroot;
PRIVATE(this)->drawListDirty = TRUE;

if (PRIVATE(this)->scene) {
PRIVATE(this)->scene->ref();
Expand Down Expand Up @@ -544,6 +554,7 @@ SoRenderManager::setCamera(SoCamera * camera)
PRIVATE(this)->camera->unref();
}
PRIVATE(this)->camera = camera;
PRIVATE(this)->drawListDirty = TRUE;
if (camera) camera->ref();
}

Expand All @@ -559,7 +570,9 @@ SoRenderManager::getCamera(void) const
void
SoRenderManager::setCameraInSceneGraph(SbBool inSceneGraph)
{
if (PRIVATE(this)->cameraInSceneGraph == inSceneGraph) return;
PRIVATE(this)->cameraInSceneGraph = inSceneGraph;
PRIVATE(this)->drawListDirty = TRUE;
}

SbBool
Expand All @@ -582,7 +595,9 @@ SoRenderManager::nodesensorCB(void * data, SoSensor * /* sensor */)
SoDebugError::postInfo("SoRenderManager::nodesensorCB",
"detected change in scene graph");
#endif // debug
((SoRenderManager *)data)->scheduleRedraw();
SoRenderManager * manager = static_cast<SoRenderManager *>(data);
PRIVATE(manager)->drawListDirty = TRUE;
manager->scheduleRedraw();
}

/*!
Expand Down Expand Up @@ -1012,9 +1027,8 @@ SoRenderManager::renderDrawListPipeline(const SbBool clearwindow,
phaseStatistics.backendResourcePreparationNanoseconds = 0;
phaseStatistics.backendCommandExecutionNanoseconds = 0;
phaseStatistics.backendSelectionNanoseconds = 0;
phaseStatistics.drawListRebuilds = 0;
const SbBool measurePhases = PRIVATE(this)->renderPhaseTimingEnabled;
const RenderPhaseClock::time_point drawListStart = measurePhases
? RenderPhaseClock::now() : RenderPhaseClock::time_point();
const SoRenderManager::RenderMode renderMode = PRIVATE(this)->rendermode;
const SoRenderManager::StereoMode stereoMode = PRIVATE(this)->stereomode;
const SbBool hasSuperimpositions =
Expand Down Expand Up @@ -1161,7 +1175,29 @@ SoRenderManager::renderDrawListPipeline(const SbBool clearwindow,
SoIRRenderAction * action = PRIVATE(this)->irAction;
action->setConstructionTimingEnabled(measurePhases);
SoState * state = action->getState();
action->beginFrame();
const uint64_t sceneRevision = PRIVATE(this)->scene
? static_cast<uint64_t>(PRIVATE(this)->scene->getNodeId()) : 0;
const uint64_t cameraRevision = PRIVATE(this)->camera
? static_cast<uint64_t>(PRIVATE(this)->camera->getNodeId()) : 0;
const uint64_t backgroundRevision = PRIVATE(this)->renderLayerBackgroundRoot
? static_cast<uint64_t>(
PRIVATE(this)->renderLayerBackgroundRoot->getNodeId()) : 0;
const uint64_t foregroundRevision = PRIVATE(this)->renderLayerForegroundRoot
? static_cast<uint64_t>(
PRIVATE(this)->renderLayerForegroundRoot->getNodeId()) : 0;
const SbBool rebuildDrawList =
!PRIVATE(this)->drawListValid || PRIVATE(this)->drawListDirty ||
!PRIVATE(this)->afterMainSceneCallbacks.empty() ||
PRIVATE(this)->drawListSceneRevision != sceneRevision ||
PRIVATE(this)->drawListCameraRevision != cameraRevision ||
PRIVATE(this)->drawListBackgroundRevision != backgroundRevision ||
PRIVATE(this)->drawListForegroundRevision != foregroundRevision;
phaseStatistics.drawListRebuilds = rebuildDrawList ? 1 : 0;
const RenderPhaseClock::time_point drawListStart =
measurePhases && rebuildDrawList
? RenderPhaseClock::now() : RenderPhaseClock::time_point();

if (rebuildDrawList) action->beginFrame();

const auto applyTraversalState = [this, renderMode](SoState * traversalState) {
SoNode * stateNode = PRIVATE(this)->dummynode;
Expand Down Expand Up @@ -1199,7 +1235,7 @@ SoRenderManager::renderDrawListPipeline(const SbBool clearwindow,
}
};

if (PRIVATE(this)->renderLayerBackgroundRoot) {
if (rebuildDrawList && PRIVATE(this)->renderLayerBackgroundRoot) {
SoIRRenderStageScope backgroundScope(*action, SoRenderStage::Background);
state->push();
SoDevicePixelRatioElement::set(state,
Expand All @@ -1213,7 +1249,7 @@ SoRenderManager::renderDrawListPipeline(const SbBool clearwindow,
}
}

if (PRIVATE(this)->scene) {
if (rebuildDrawList && PRIVATE(this)->scene) {
state->push();
SoDevicePixelRatioElement::set(state,
PRIVATE(this)->dummynode,
Expand All @@ -1227,7 +1263,7 @@ SoRenderManager::renderDrawListPipeline(const SbBool clearwindow,
state->pop();
}

{
if (rebuildDrawList) {
SoIRRenderStageScope afterMainScope(*action, SoRenderStage::AfterMain);
state->push();
SoDevicePixelRatioElement::set(state,
Expand All @@ -1238,7 +1274,7 @@ SoRenderManager::renderDrawListPipeline(const SbBool clearwindow,
state->pop();
}

if (PRIVATE(this)->renderLayerForegroundRoot) {
if (rebuildDrawList && PRIVATE(this)->renderLayerForegroundRoot) {
SoIRRenderStageScope foregroundScope(*action, SoRenderStage::Foreground);
state->push();
SoDevicePixelRatioElement::set(state,
Expand All @@ -1249,8 +1285,8 @@ SoRenderManager::renderDrawListPipeline(const SbBool clearwindow,
state->pop();
}

if (action->hasUnsupportedRendering()) {
const char * reason = action->getUnsupportedReason();
if (rebuildDrawList && PRIVATE(this)->irAction->hasUnsupportedRendering()) {
const char * reason = PRIVATE(this)->irAction->getUnsupportedReason();
#if COIN_BUILD_LEGACY_GL_RENDERER
if (currentContextSupportsLegacyRendering()) {
SoDebugError::postWarning(
Expand Down Expand Up @@ -1282,9 +1318,18 @@ SoRenderManager::renderDrawListPipeline(const SbBool clearwindow,
return;
}

if (rebuildDrawList) {
PRIVATE(this)->drawListValid = TRUE;
PRIVATE(this)->drawListDirty = FALSE;
PRIVATE(this)->drawListSceneRevision = sceneRevision;
PRIVATE(this)->drawListCameraRevision = cameraRevision;
PRIVATE(this)->drawListBackgroundRevision = backgroundRevision;
PRIVATE(this)->drawListForegroundRevision = foregroundRevision;
}

SoDrawList & drawlist = PRIVATE(this)->irAction->getMutableDrawList();

if (measurePhases) {
if (measurePhases && rebuildDrawList) {
const SoIRRenderAction::ConstructionStatistics & construction =
action->getConstructionStatistics();
phaseStatistics.drawListConstructionNanoseconds =
Expand Down Expand Up @@ -1320,7 +1365,8 @@ SoRenderManager::renderDrawListPipeline(const SbBool clearwindow,
params.clearColor = PRIVATE(this)->backgroundcolor;
params.clearDepth = 1.0f;
params.flags = (clearwindow ? SO_PARAM_CLEAR_WINDOW : 0u) |
(clearzbuffer ? SO_PARAM_CLEAR_DEPTH : 0u);
(clearzbuffer ? SO_PARAM_CLEAR_DEPTH : 0u) |
(!rebuildDrawList ? SO_PARAM_REUSE_DRAW_LIST : 0u);
SoRenderPlanner planner;
SoRenderPlan plan;
const RenderPhaseClock::time_point planStart = measurePhases
Expand Down Expand Up @@ -1350,8 +1396,10 @@ SoRenderManager::renderDrawListPipeline(const SbBool clearwindow,
phaseStatistics.backendSelectionNanoseconds =
backendPhases.selectionNanoseconds;
}
PRIVATE(this)->pickTargetDirty = TRUE;
PRIVATE(this)->pickTargetGeneration = 0;
if (rebuildDrawList) {
PRIVATE(this)->pickTargetDirty = TRUE;
PRIVATE(this)->pickTargetGeneration = 0;
}

if (SoRenderManager::isRealTimeUpdateEnabled()) {
SoField * realtime = SoDB::getGlobalField("realTime");
Expand Down Expand Up @@ -1909,6 +1957,7 @@ SoRenderManager::setWindowSize(const SbVec2s & newsize)
SbViewportRegion region = PRIVATE(this)->viewport;
region.setWindowSize(newsize[0], newsize[1]);
PRIVATE(this)->viewport = region;
PRIVATE(this)->drawListDirty = TRUE;
#if COIN_BUILD_LEGACY_GL_RENDERER
PRIVATE(this)->glaction->setViewportRegion(region);
#endif
Expand All @@ -1930,6 +1979,7 @@ SoRenderManager::setDevicePixelRatio(float dpr)
{
if (PRIVATE(this)->devicePixelRatio == dpr) return;
PRIVATE(this)->devicePixelRatio = dpr;
PRIVATE(this)->drawListDirty = TRUE;
this->scheduleRedraw();
}

Expand All @@ -1955,6 +2005,7 @@ SoRenderManager::setSize(const SbVec2s & newsize)
SbVec2s origin = region.getViewportOriginPixels();
region.setViewportPixels(origin, newsize);
PRIVATE(this)->viewport = region;
PRIVATE(this)->drawListDirty = TRUE;
#if COIN_BUILD_LEGACY_GL_RENDERER
PRIVATE(this)->glaction->setViewportRegion(region);
#endif
Expand Down Expand Up @@ -1987,6 +2038,7 @@ SoRenderManager::setOrigin(const SbVec2s & newOrigin)
SbVec2s size = region.getViewportSizePixels();
region.setViewportPixels(newOrigin, size);
PRIVATE(this)->viewport = region;
PRIVATE(this)->drawListDirty = TRUE;
#if COIN_BUILD_LEGACY_GL_RENDERER
PRIVATE(this)->glaction->setViewportRegion(region);
#endif
Expand Down Expand Up @@ -2015,6 +2067,7 @@ void
SoRenderManager::setViewportRegion(const SbViewportRegion & newregion)
{
PRIVATE(this)->viewport = newregion;
PRIVATE(this)->drawListDirty = TRUE;
#if COIN_BUILD_LEGACY_GL_RENDERER
PRIVATE(this)->glaction->setViewportRegion(newregion);
#endif
Expand Down Expand Up @@ -2202,7 +2255,9 @@ SoRenderManager::isAutoRedraw(void) const
void
SoRenderManager::setRenderMode(const RenderMode mode)
{
if (PRIVATE(this)->rendermode == mode) return;
PRIVATE(this)->rendermode = mode;
PRIVATE(this)->drawListDirty = TRUE;
this->scheduleRedraw();
PRIVATE(this)->dummynode->touch();
}
Expand All @@ -2221,6 +2276,7 @@ SoRenderManager::setLightingMode(const LightingMode mode)
{
if (PRIVATE(this)->lightingmode == mode) return;
PRIVATE(this)->lightingmode = mode;
PRIVATE(this)->drawListDirty = TRUE;
#if COIN_BUILD_LEGACY_GL_RENDERER
if (PRIVATE(this)->glaction) {
PRIVATE(this)->glaction->invalidateState();
Expand Down Expand Up @@ -2427,6 +2483,7 @@ SoRenderManager::setRenderLayerRoot(RenderLayer layer, SoNode * root)
if (*slot) (*slot)->unref();

*slot = root;
PRIVATE(this)->drawListDirty = TRUE;
if (root) {
root->ref();
if (!*sensorSlot) {
Expand Down Expand Up @@ -2661,12 +2718,14 @@ SoRenderManager::invalidateDrawList(void)
void
SoRenderManager::invalidateScene(void)
{
PRIVATE(this)->drawListDirty = TRUE;
this->scheduleRedraw();
}

void
SoRenderManager::invalidateForeground(void)
{
PRIVATE(this)->drawListDirty = TRUE;
this->scheduleRedraw();
}

Expand Down Expand Up @@ -2720,7 +2779,9 @@ SoRenderManager::getNearPlaneValue(void) const
void
SoRenderManager::setTexturesEnabled(const SbBool onoff)
{
if (PRIVATE(this)->texturesenabled == onoff) return;
PRIVATE(this)->texturesenabled = onoff;
PRIVATE(this)->drawListDirty = TRUE;
}

/*!
Expand Down Expand Up @@ -2907,6 +2968,7 @@ SoRenderManager::addAfterMainSceneCallback(SoRenderManagerStageCB * cb, void * d
{
PRIVATE(this)->afterMainSceneCallbacks.push_back(
SoRenderManagerP::StageCBTouple(cb, data));
PRIVATE(this)->drawListDirty = TRUE;
}

void
Expand All @@ -2920,6 +2982,7 @@ SoRenderManager::removeAfterMainSceneCallback(SoRenderManagerStageCB * cb, void
"Tried to remove an after-main-scene callback which doesn't exist");
if (findit != PRIVATE(this)->afterMainSceneCallbacks.end()) {
PRIVATE(this)->afterMainSceneCallbacks.erase(findit);
PRIVATE(this)->drawListDirty = TRUE;
}
}

Expand Down
Loading