| 1907 | |
| 1908 | |
| 1909 | G4ThreadFunReturnType G4VisManager::G4VisSubThread(G4ThreadFunArgType p) |
| 1910 | { |
| 1911 | #ifdef G4MULTITHREADED |
| 1912 | G4VisManager* pVisManager = (G4VisManager*)p; |
| 1913 | G4VSceneHandler* pSceneHandler = pVisManager->GetCurrentSceneHandler(); |
| 1914 | if (!pSceneHandler) return 0; |
| 1915 | G4Scene* pScene = pSceneHandler->GetScene(); |
| 1916 | if (!pScene) return 0; |
| 1917 | G4VViewer* pViewer = pVisManager->GetCurrentViewer(); |
| 1918 | if (!pViewer) return 0; |
| 1919 | |
| 1920 | G4UImanager::GetUIpointer()->SetUpForSpecialThread("G4VIS"); |
| 1921 | |
| 1922 | // Set up geometry and navigation for a thread |
| 1923 | G4GeometryWorkspace::GetPool()->CreateAndUseWorkspace(); |
| 1924 | G4SolidsWorkspace::GetPool()->CreateAndUseWorkspace(); |
| 1925 | G4Navigator* navigator = G4TransportationManager::GetTransportationManager() |
| 1926 | ->GetNavigatorForTracking(); |
| 1927 | navigator->SetWorldVolume( |
| 1928 | G4RunManagerFactory::GetMasterRunManagerKernel()->GetCurrentWorld()); |
| 1929 | |
| 1930 | pViewer->SwitchToVisSubThread(); |
| 1931 | |
| 1932 | while (true) { |
| 1933 | |
| 1934 | G4MUTEXLOCK(&mtVisSubThreadMutex); |
| 1935 | std::size_t eventQueueSize = mtVisEventQueue.size(); |
| 1936 | G4MUTEXUNLOCK(&mtVisSubThreadMutex); |
| 1937 | // G4cout << "Event queue size (A): " << eventQueueSize << G4endl; |
| 1938 | |
| 1939 | while (eventQueueSize) { |
| 1940 | |
| 1941 | G4MUTEXLOCK(&mtVisSubThreadMutex); |
| 1942 | const G4Event* event = mtVisEventQueue.front(); |
| 1943 | G4MUTEXUNLOCK(&mtVisSubThreadMutex); |
| 1944 | |
| 1945 | // Here comes the event drawing |
| 1946 | pVisManager->SetTransientsDrawnThisEvent(false); |
| 1947 | pSceneHandler->SetTransientsDrawnThisEvent(false); |
| 1948 | |
| 1949 | // We are about to draw the event (trajectories, etc.), but first we |
| 1950 | // have to clear the previous event(s) if necessary. If this event |
| 1951 | // needs to be drawn afresh, e.g., the first event or any event when |
| 1952 | // "accumulate" is not requested, the old event has to be cleared. |
| 1953 | // We have postponed this so that, for normal viewers like OGL, the |
| 1954 | // previous event(s) stay on screen until this new event comes |
| 1955 | // along. For a file-writing viewer the geometry has to be drawn. |
| 1956 | // See, for example, G4FRSCENEHANDLER::ClearTransientStore. |
| 1957 | pVisManager->ClearTransientStoreIfMarked(); |
| 1958 | |
| 1959 | // Now draw the event... |
| 1960 | pSceneHandler->DrawEvent(event); |
| 1961 | ++pVisManager->fNoOfEventsDrawnThisRun; |
| 1962 | |
| 1963 | // Then pop and release event |
| 1964 | G4MUTEXLOCK(&mtVisSubThreadMutex); |
| 1965 | mtVisEventQueue.pop_front(); |
| 1966 | pVisManager->EndOfEventCleanup(event); |
nothing calls this directly
no test coverage detected