1 // Copyright (c) 2017 OPEN CASCADE SAS
3 // This file is part of Open CASCADE Technology software library.
5 // This library is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU Lesser General Public License version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
14 #include <OpenGl_FrameStats.hxx>
16 #include <OpenGl_GlCore20.hxx>
17 #include <OpenGl_View.hxx>
18 #include <OpenGl_Workspace.hxx>
20 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_FrameStats, Graphic3d_FrameStats)
24 //! Return estimated data size.
25 static Standard_Size estimatedDataSize (const Handle(OpenGl_Resource)& theRes)
27 return !theRes.IsNull() ? theRes->EstimatedDataSize() : 0;
31 // =======================================================================
32 // function : OpenGl_FrameStats
34 // =======================================================================
35 OpenGl_FrameStats::OpenGl_FrameStats()
40 // =======================================================================
41 // function : ~OpenGl_FrameStats
43 // =======================================================================
44 OpenGl_FrameStats::~OpenGl_FrameStats()
49 // =======================================================================
50 // function : IsFrameUpdated
52 // =======================================================================
53 bool OpenGl_FrameStats::IsFrameUpdated (Handle(OpenGl_FrameStats)& thePrev) const
55 const Graphic3d_FrameStatsData& aFrame = LastDataFrame();
58 thePrev = new OpenGl_FrameStats();
60 // check just a couple of major counters
61 else if (myLastFrameIndex == thePrev->myLastFrameIndex
62 && Abs (aFrame.FrameRate() - thePrev->myCountersTmp.FrameRate()) <= 0.001
63 && Abs (aFrame.FrameRateCpu() - thePrev->myCountersTmp.FrameRateCpu()) <= 0.001
64 && aFrame[Graphic3d_FrameStatsCounter_NbLayers] == thePrev->myCountersTmp[Graphic3d_FrameStatsCounter_NbLayers]
65 && aFrame[Graphic3d_FrameStatsCounter_NbLayersNotCulled] == thePrev->myCountersTmp[Graphic3d_FrameStatsCounter_NbLayersNotCulled]
66 && aFrame[Graphic3d_FrameStatsCounter_NbStructs] == thePrev->myCountersTmp[Graphic3d_FrameStatsCounter_NbStructs]
67 && aFrame[Graphic3d_FrameStatsCounter_NbStructsNotCulled] == thePrev->myCountersTmp[Graphic3d_FrameStatsCounter_NbStructsNotCulled])
72 thePrev->myLastFrameIndex = myLastFrameIndex;
73 thePrev->myCountersTmp = aFrame;
77 // =======================================================================
78 // function : updateStatistics
80 // =======================================================================
81 void OpenGl_FrameStats::updateStatistics (const Handle(Graphic3d_CView)& theView,
82 bool theIsImmediateOnly)
84 const OpenGl_View* aView = dynamic_cast<const OpenGl_View*> (theView.get());
87 myCounters.SetValue (myLastFrameIndex, myCountersTmp);
88 myCountersTmp.Reset();
92 const Graphic3d_RenderingParams::PerfCounters aBits = theView->RenderingParams().CollectedStats;
93 const Standard_Boolean toCountMem = (aBits & Graphic3d_RenderingParams::PerfCounters_EstimMem) != 0;
94 const Standard_Boolean toCountTris = (aBits & Graphic3d_RenderingParams::PerfCounters_Triangles) != 0
95 || (aBits & Graphic3d_RenderingParams::PerfCounters_Points) != 0;
96 const Standard_Boolean toCountElems = (aBits & Graphic3d_RenderingParams::PerfCounters_GroupArrays) != 0 || toCountTris || toCountMem;
97 const Standard_Boolean toCountGroups = (aBits & Graphic3d_RenderingParams::PerfCounters_Groups) != 0 || toCountElems;
98 const Standard_Boolean toCountStructs = (aBits & Graphic3d_RenderingParams::PerfCounters_Structures) != 0
99 || (aBits & Graphic3d_RenderingParams::PerfCounters_Layers) != 0 || toCountGroups;
101 myCountersTmp[Graphic3d_FrameStatsCounter_NbLayers] = aView->LayerList().Layers().Size();
103 || (aBits & Graphic3d_RenderingParams::PerfCounters_Layers) != 0)
105 const Standard_Integer aViewId = aView->Identification();
106 for (OpenGl_SequenceOfLayers::Iterator aLayerIter (aView->LayerList().Layers()); aLayerIter.More(); aLayerIter.Next())
108 const Handle(OpenGl_Layer)& aLayer = aLayerIter.Value();
109 myCountersTmp[Graphic3d_FrameStatsCounter_NbStructs] += aLayer->NbStructures();
110 if (theIsImmediateOnly && !aLayer->LayerSettings().IsImmediate())
115 if (!aLayer->IsCulled())
117 ++myCountersTmp[Graphic3d_FrameStatsCounter_NbLayersNotCulled];
119 myCountersTmp[Graphic3d_FrameStatsCounter_NbStructsNotCulled] += aLayer->NbStructuresNotCulled();
122 updateStructures (aViewId, aLayer->CullableStructuresBVH().Structures(), toCountElems, toCountTris, toCountMem);
123 updateStructures (aViewId, aLayer->CullableTrsfPersStructuresBVH().Structures(), toCountElems, toCountTris, toCountMem);
124 updateStructures (aViewId, aLayer->NonCullableStructures(), toCountElems, toCountTris, toCountMem);
130 for (OpenGl_Context::OpenGl_ResourcesMap::Iterator aResIter (aView->GlWindow()->GetGlContext()->SharedResources());
131 aResIter.More(); aResIter.Next())
133 myCountersTmp[Graphic3d_FrameStatsCounter_EstimatedBytesTextures] += aResIter.Value()->EstimatedDataSize();
137 Standard_Size& aMemFbos = myCountersTmp[Graphic3d_FrameStatsCounter_EstimatedBytesFbos];
139 aMemFbos += estimatedDataSize (aView->myMainSceneFbos[0]);
140 aMemFbos += estimatedDataSize (aView->myMainSceneFbos[1]);
141 aMemFbos += estimatedDataSize (aView->myImmediateSceneFbos[0]);
142 aMemFbos += estimatedDataSize (aView->myImmediateSceneFbos[1]);
144 aMemFbos += estimatedDataSize (aView->myMainSceneFbosOit[0]);
145 aMemFbos += estimatedDataSize (aView->myMainSceneFbosOit[1]);
146 aMemFbos += estimatedDataSize (aView->myImmediateSceneFbosOit[0]);
147 aMemFbos += estimatedDataSize (aView->myImmediateSceneFbosOit[1]);
149 aMemFbos += estimatedDataSize (aView->myFBO);
151 aMemFbos += estimatedDataSize (aView->myOpenGlFBO);
152 aMemFbos += estimatedDataSize (aView->myOpenGlFBO2);
153 aMemFbos += estimatedDataSize (aView->myRaytraceFBO1[0]);
154 aMemFbos += estimatedDataSize (aView->myRaytraceFBO1[1]);
155 aMemFbos += estimatedDataSize (aView->myRaytraceFBO2[0]);
156 aMemFbos += estimatedDataSize (aView->myRaytraceFBO2[1]);
158 aMemFbos += estimatedDataSize (aView->myRaytraceOutputTexture[0]);
159 aMemFbos += estimatedDataSize (aView->myRaytraceOutputTexture[1]);
160 aMemFbos += estimatedDataSize (aView->myRaytraceVisualErrorTexture[0]);
161 aMemFbos += estimatedDataSize (aView->myRaytraceVisualErrorTexture[1]);
162 aMemFbos += estimatedDataSize (aView->myRaytraceTileOffsetsTexture[0]);
163 aMemFbos += estimatedDataSize (aView->myRaytraceTileOffsetsTexture[1]);
166 // Ray Tracing geometry
167 Standard_Size& aMemGeom = myCountersTmp[Graphic3d_FrameStatsCounter_EstimatedBytesGeom];
168 aMemGeom += estimatedDataSize (aView->mySceneNodeInfoTexture);
169 aMemGeom += estimatedDataSize (aView->mySceneMinPointTexture);
170 aMemGeom += estimatedDataSize (aView->mySceneMaxPointTexture);
171 aMemGeom += estimatedDataSize (aView->mySceneTransformTexture);
172 aMemGeom += estimatedDataSize (aView->myGeometryVertexTexture);
173 aMemGeom += estimatedDataSize (aView->myGeometryNormalTexture);
174 aMemGeom += estimatedDataSize (aView->myGeometryTexCrdTexture);
175 aMemGeom += estimatedDataSize (aView->myGeometryTriangTexture);
176 aMemGeom += estimatedDataSize (aView->myRaytraceMaterialTexture);
177 aMemGeom += estimatedDataSize (aView->myRaytraceLightSrcTexture);
182 // =======================================================================
183 // function : updateStructures
185 // =======================================================================
186 void OpenGl_FrameStats::updateStructures (Standard_Integer theViewId,
187 const OpenGl_IndexedMapOfStructure& theStructures,
188 Standard_Boolean theToCountElems,
189 Standard_Boolean theToCountTris,
190 Standard_Boolean theToCountMem)
192 for (OpenGl_IndexedMapOfStructure::Iterator aStructIter (theStructures); aStructIter.More(); aStructIter.Next())
194 const OpenGl_Structure* aStruct = aStructIter.Value();
195 const bool isStructHidden = aStruct->IsCulled()
196 || !aStruct->IsVisible (theViewId);
197 for (; aStruct != NULL; aStruct = aStruct->InstancedStructure())
203 for (OpenGl_Structure::GroupIterator aGroupIter (aStruct->Groups()); aGroupIter.More(); aGroupIter.Next())
205 const OpenGl_Group* aGroup = aGroupIter.Value();
206 for (const OpenGl_ElementNode* aNodeIter = aGroup->FirstNode(); aNodeIter != NULL; aNodeIter = aNodeIter->next)
208 if (const OpenGl_PrimitiveArray* aPrim = dynamic_cast<const OpenGl_PrimitiveArray*> (aNodeIter->elem))
210 myCountersTmp[Graphic3d_FrameStatsCounter_EstimatedBytesGeom] += estimatedDataSize (aPrim->AttributesVbo());
211 myCountersTmp[Graphic3d_FrameStatsCounter_EstimatedBytesGeom] += estimatedDataSize (aPrim->IndexVbo());
219 myCountersTmp[Graphic3d_FrameStatsCounter_NbGroupsNotCulled] += aStruct->Groups().Size();
220 if (!theToCountElems)
225 for (OpenGl_Structure::GroupIterator aGroupIter (aStruct->Groups()); aGroupIter.More(); aGroupIter.Next())
227 const OpenGl_Group* aGroup = aGroupIter.Value();
228 for (const OpenGl_ElementNode* aNodeIter = aGroup->FirstNode(); aNodeIter != NULL; aNodeIter = aNodeIter->next)
230 if (const OpenGl_PrimitiveArray* aPrim = dynamic_cast<const OpenGl_PrimitiveArray*> (aNodeIter->elem))
232 ++myCountersTmp[Graphic3d_FrameStatsCounter_NbElemsNotCulled];
235 myCountersTmp[Graphic3d_FrameStatsCounter_EstimatedBytesGeom] += estimatedDataSize (aPrim->AttributesVbo());
236 myCountersTmp[Graphic3d_FrameStatsCounter_EstimatedBytesGeom] += estimatedDataSize (aPrim->IndexVbo());
239 if (aPrim->IsFillDrawMode())
241 ++myCountersTmp[Graphic3d_FrameStatsCounter_NbElemsFillNotCulled];
247 const Handle(OpenGl_VertexBuffer)& anAttribs = aPrim->AttributesVbo();
248 if (anAttribs.IsNull()
249 || !anAttribs->IsValid())
254 const Handle(OpenGl_VertexBuffer)& anIndices = aPrim->IndexVbo();
255 const Standard_Integer aNbIndices = !anIndices.IsNull() ? anIndices->GetElemsNb() : anAttribs->GetElemsNb();
256 const Standard_Integer aNbBounds = !aPrim->Bounds().IsNull() ? aPrim->Bounds()->NbBounds : 1;
257 switch (aPrim->DrawMode())
261 myCountersTmp[Graphic3d_FrameStatsCounter_NbTrianglesNotCulled] += aNbIndices / 3;
264 case GL_TRIANGLE_STRIP:
265 case GL_TRIANGLE_FAN:
267 myCountersTmp[Graphic3d_FrameStatsCounter_NbTrianglesNotCulled] += aNbIndices - 2 * aNbBounds;
270 case GL_TRIANGLES_ADJACENCY:
272 myCountersTmp[Graphic3d_FrameStatsCounter_NbTrianglesNotCulled] += aNbIndices / 6;
275 case GL_TRIANGLE_STRIP_ADJACENCY:
277 myCountersTmp[Graphic3d_FrameStatsCounter_NbTrianglesNotCulled] += aNbIndices - 4 * aNbBounds;
280 #if !defined(GL_ES_VERSION_2_0)
283 myCountersTmp[Graphic3d_FrameStatsCounter_NbTrianglesNotCulled] += aNbIndices / 2;
288 myCountersTmp[Graphic3d_FrameStatsCounter_NbTrianglesNotCulled] += (aNbIndices / 2 - aNbBounds) * 2;
294 else if (aPrim->DrawMode() == GL_POINTS)
296 ++myCountersTmp[Graphic3d_FrameStatsCounter_NbElemsPointNotCulled];
299 const Handle(OpenGl_VertexBuffer)& anAttribs = aPrim->AttributesVbo();
300 if (!anAttribs.IsNull()
301 && anAttribs->IsValid())
303 const Handle(OpenGl_VertexBuffer)& anIndices = aPrim->IndexVbo();
304 const Standard_Integer aNbIndices = !anIndices.IsNull() ? anIndices->GetElemsNb() : anAttribs->GetElemsNb();
305 myCountersTmp[Graphic3d_FrameStatsCounter_NbPointsNotCulled] += aNbIndices;
311 ++myCountersTmp[Graphic3d_FrameStatsCounter_NbElemsLineNotCulled];
314 else if (const OpenGl_Text* aText = dynamic_cast<const OpenGl_Text*> (aNodeIter->elem))
317 ++myCountersTmp[Graphic3d_FrameStatsCounter_NbElemsNotCulled];
318 ++myCountersTmp[Graphic3d_FrameStatsCounter_NbElemsTextNotCulled];