0028572: Modeling Algorithms - Wrong result of the mkface command
[occt.git] / src / OpenGl / OpenGl_FrameStats.cxx
1 // Copyright (c) 2017 OPEN CASCADE SAS
2 //
3 // This file is part of Open CASCADE Technology software library.
4 //
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.
10 //
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
13
14 #include <OpenGl_FrameStats.hxx>
15
16 #include <OpenGl_GlCore20.hxx>
17 #include <OpenGl_View.hxx>
18 #include <OpenGl_Workspace.hxx>
19
20 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_FrameStats, Graphic3d_FrameStats)
21
22 namespace
23 {
24   //! Return estimated data size.
25   static Standard_Size estimatedDataSize (const Handle(OpenGl_Resource)& theRes)
26   {
27     return !theRes.IsNull() ? theRes->EstimatedDataSize() : 0;
28   }
29 }
30
31 // =======================================================================
32 // function : OpenGl_FrameStats
33 // purpose  :
34 // =======================================================================
35 OpenGl_FrameStats::OpenGl_FrameStats()
36 {
37   //
38 }
39
40 // =======================================================================
41 // function : ~OpenGl_FrameStats
42 // purpose  :
43 // =======================================================================
44 OpenGl_FrameStats::~OpenGl_FrameStats()
45 {
46   //
47 }
48
49 // =======================================================================
50 // function : IsFrameUpdated
51 // purpose  :
52 // =======================================================================
53 bool OpenGl_FrameStats::IsFrameUpdated (Handle(OpenGl_FrameStats)& thePrev) const
54 {
55   const Graphic3d_FrameStatsData& aFrame = LastDataFrame();
56   if (thePrev.IsNull())
57   {
58     thePrev = new OpenGl_FrameStats();
59   }
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         && Abs (aFrame.ImmediateFrameRate()    - thePrev->myCountersTmp.ImmediateFrameRate())    <= 0.001
65         && Abs (aFrame.ImmediateFrameRateCpu() - thePrev->myCountersTmp.ImmediateFrameRateCpu()) <= 0.001
66         && aFrame[Graphic3d_FrameStatsCounter_NbLayers]           == thePrev->myCountersTmp[Graphic3d_FrameStatsCounter_NbLayers]
67         && aFrame[Graphic3d_FrameStatsCounter_NbLayersNotCulled]  == thePrev->myCountersTmp[Graphic3d_FrameStatsCounter_NbLayersNotCulled]
68         && aFrame[Graphic3d_FrameStatsCounter_NbStructs]          == thePrev->myCountersTmp[Graphic3d_FrameStatsCounter_NbStructs]
69         && aFrame[Graphic3d_FrameStatsCounter_NbStructsNotCulled] == thePrev->myCountersTmp[Graphic3d_FrameStatsCounter_NbStructsNotCulled])
70   {
71     return false;
72   }
73
74   thePrev->myLastFrameIndex = myLastFrameIndex;
75   thePrev->myCountersTmp = aFrame;
76   return true;
77 }
78
79 // =======================================================================
80 // function : updateStatistics
81 // purpose  :
82 // =======================================================================
83 void OpenGl_FrameStats::updateStatistics (const Handle(Graphic3d_CView)& theView,
84                                           bool theIsImmediateOnly)
85 {
86   const OpenGl_View* aView = dynamic_cast<const OpenGl_View*> (theView.get());
87   if (aView == NULL)
88   {
89     myCounters.SetValue (myLastFrameIndex, myCountersTmp);
90     myCountersTmp.Reset();
91     return;
92   }
93
94   const Graphic3d_RenderingParams::PerfCounters aBits = theView->RenderingParams().CollectedStats;
95   const Standard_Boolean toCountMem     = (aBits & Graphic3d_RenderingParams::PerfCounters_EstimMem)  != 0;
96   const Standard_Boolean toCountTris    = (aBits & Graphic3d_RenderingParams::PerfCounters_Triangles) != 0
97                                        || (aBits & Graphic3d_RenderingParams::PerfCounters_Lines)     != 0
98                                        || (aBits & Graphic3d_RenderingParams::PerfCounters_Points)    != 0;
99   const Standard_Boolean toCountElems   = (aBits & Graphic3d_RenderingParams::PerfCounters_GroupArrays) != 0 || toCountTris || toCountMem;
100   const Standard_Boolean toCountGroups  = (aBits & Graphic3d_RenderingParams::PerfCounters_Groups)      != 0 || toCountElems;
101   const Standard_Boolean toCountStructs = (aBits & Graphic3d_RenderingParams::PerfCounters_Structures)  != 0
102                                        || (aBits & Graphic3d_RenderingParams::PerfCounters_Layers)      != 0 || toCountGroups;
103
104   myCountersTmp[Graphic3d_FrameStatsCounter_NbLayers] = aView->LayerList().Layers().Size();
105   if (toCountStructs
106    || (aBits & Graphic3d_RenderingParams::PerfCounters_Layers)    != 0)
107   {
108     const Standard_Integer aViewId = aView->Identification();
109     for (NCollection_List<Handle(Graphic3d_Layer)>::Iterator aLayerIter (aView->LayerList().Layers()); aLayerIter.More(); aLayerIter.Next())
110     {
111       const Handle(OpenGl_Layer)& aLayer = aLayerIter.Value();
112       myCountersTmp[Graphic3d_FrameStatsCounter_NbStructs] += aLayer->NbStructures();
113       if (theIsImmediateOnly && !aLayer->LayerSettings().IsImmediate())
114       {
115         continue;
116       }
117
118       if (!aLayer->IsCulled())
119       {
120         ++myCountersTmp[Graphic3d_FrameStatsCounter_NbLayersNotCulled];
121       }
122       myCountersTmp[Graphic3d_FrameStatsCounter_NbStructsNotCulled] += aLayer->NbStructuresNotCulled();
123       if (toCountGroups)
124       {
125         updateStructures (aViewId, aLayer->CullableStructuresBVH().Structures(), toCountElems, toCountTris, toCountMem);
126         updateStructures (aViewId, aLayer->CullableTrsfPersStructuresBVH().Structures(), toCountElems, toCountTris, toCountMem);
127         updateStructures (aViewId, aLayer->NonCullableStructures(), toCountElems, toCountTris, toCountMem);
128       }
129     }
130   }
131   if (toCountMem)
132   {
133     for (OpenGl_Context::OpenGl_ResourcesMap::Iterator aResIter (aView->GlWindow()->GetGlContext()->SharedResources());
134          aResIter.More(); aResIter.Next())
135     {
136       myCountersTmp[Graphic3d_FrameStatsCounter_EstimatedBytesTextures] += aResIter.Value()->EstimatedDataSize();
137     }
138
139     {
140       Standard_Size& aMemFbos = myCountersTmp[Graphic3d_FrameStatsCounter_EstimatedBytesFbos];
141       // main FBOs
142       aMemFbos += estimatedDataSize (aView->myMainSceneFbos[0]);
143       aMemFbos += estimatedDataSize (aView->myMainSceneFbos[1]);
144       aMemFbos += estimatedDataSize (aView->myImmediateSceneFbos[0]);
145       aMemFbos += estimatedDataSize (aView->myImmediateSceneFbos[1]);
146       // OIT FBOs
147       aMemFbos += estimatedDataSize (aView->myMainSceneFbosOit[0]);
148       aMemFbos += estimatedDataSize (aView->myMainSceneFbosOit[1]);
149       aMemFbos += estimatedDataSize (aView->myImmediateSceneFbosOit[0]);
150       aMemFbos += estimatedDataSize (aView->myImmediateSceneFbosOit[1]);
151       // dump FBO
152       aMemFbos += estimatedDataSize (aView->myFBO);
153       // RayTracing FBO
154       aMemFbos += estimatedDataSize (aView->myOpenGlFBO);
155       aMemFbos += estimatedDataSize (aView->myOpenGlFBO2);
156       aMemFbos += estimatedDataSize (aView->myRaytraceFBO1[0]);
157       aMemFbos += estimatedDataSize (aView->myRaytraceFBO1[1]);
158       aMemFbos += estimatedDataSize (aView->myRaytraceFBO2[0]);
159       aMemFbos += estimatedDataSize (aView->myRaytraceFBO2[1]);
160       // also RayTracing
161       aMemFbos += estimatedDataSize (aView->myRaytraceOutputTexture[0]);
162       aMemFbos += estimatedDataSize (aView->myRaytraceOutputTexture[1]);
163       aMemFbos += estimatedDataSize (aView->myRaytraceVisualErrorTexture[0]);
164       aMemFbos += estimatedDataSize (aView->myRaytraceVisualErrorTexture[1]);
165       aMemFbos += estimatedDataSize (aView->myRaytraceTileOffsetsTexture[0]);
166       aMemFbos += estimatedDataSize (aView->myRaytraceTileOffsetsTexture[1]);
167       aMemFbos += estimatedDataSize (aView->myRaytraceTileSamplesTexture[0]);
168       aMemFbos += estimatedDataSize (aView->myRaytraceTileSamplesTexture[1]);
169     }
170     {
171       // Ray Tracing geometry
172       Standard_Size& aMemGeom = myCountersTmp[Graphic3d_FrameStatsCounter_EstimatedBytesGeom];
173       aMemGeom += estimatedDataSize (aView->mySceneNodeInfoTexture);
174       aMemGeom += estimatedDataSize (aView->mySceneMinPointTexture);
175       aMemGeom += estimatedDataSize (aView->mySceneMaxPointTexture);
176       aMemGeom += estimatedDataSize (aView->mySceneTransformTexture);
177       aMemGeom += estimatedDataSize (aView->myGeometryVertexTexture);
178       aMemGeom += estimatedDataSize (aView->myGeometryNormalTexture);
179       aMemGeom += estimatedDataSize (aView->myGeometryTexCrdTexture);
180       aMemGeom += estimatedDataSize (aView->myGeometryTriangTexture);
181       aMemGeom += estimatedDataSize (aView->myRaytraceMaterialTexture);
182       aMemGeom += estimatedDataSize (aView->myRaytraceLightSrcTexture);
183     }
184   }
185 }
186
187 // =======================================================================
188 // function : updateStructures
189 // purpose  :
190 // =======================================================================
191 void OpenGl_FrameStats::updateStructures (Standard_Integer theViewId,
192                                           const NCollection_IndexedMap<const Graphic3d_CStructure*>& theStructures,
193                                           Standard_Boolean theToCountElems,
194                                           Standard_Boolean theToCountTris,
195                                           Standard_Boolean theToCountMem)
196 {
197   for (OpenGl_Structure::StructIterator aStructIter (theStructures); aStructIter.More(); aStructIter.Next())
198   {
199     const OpenGl_Structure* aStruct = aStructIter.Value();
200     const bool isStructHidden = aStruct->IsCulled()
201                             || !aStruct->IsVisible (theViewId);
202     for (; aStruct != NULL; aStruct = aStruct->InstancedStructure())
203     {
204       if (isStructHidden)
205       {
206         if (theToCountMem)
207         {
208           for (OpenGl_Structure::GroupIterator aGroupIter (aStruct->Groups()); aGroupIter.More(); aGroupIter.Next())
209           {
210             const OpenGl_Group* aGroup = aGroupIter.Value();
211             for (const OpenGl_ElementNode* aNodeIter = aGroup->FirstNode(); aNodeIter != NULL; aNodeIter = aNodeIter->next)
212             {
213               aNodeIter->elem->UpdateMemStats (myCountersTmp);
214             }
215           }
216         }
217         continue;
218       }
219
220       myCountersTmp[Graphic3d_FrameStatsCounter_NbGroupsNotCulled] += aStruct->Groups().Size();
221       if (!theToCountElems)
222       {
223         continue;
224       }
225
226       for (OpenGl_Structure::GroupIterator aGroupIter (aStruct->Groups()); aGroupIter.More(); aGroupIter.Next())
227       {
228         const OpenGl_Group* aGroup = aGroupIter.Value();
229         for (const OpenGl_ElementNode* aNodeIter = aGroup->FirstNode(); aNodeIter != NULL; aNodeIter = aNodeIter->next)
230         {
231           if (theToCountMem)
232           {
233             aNodeIter->elem->UpdateMemStats (myCountersTmp);
234           }
235           aNodeIter->elem->UpdateDrawStats (myCountersTmp, theToCountTris);
236         }
237       }
238     }
239   }
240 }