void MapAlignmentAlgorithmIdentification::alignPeptideIdentifications( vector<vector<PeptideIdentification> > & maps, vector<TransformationDescription> & transformations) { checkParameters_(maps.size()); startProgress(0, 3, "aligning peptide identifications"); if (reference_index_) // reference is one of the input files { SeqToList rt_data; getRetentionTimes_(maps[reference_index_ - 1], rt_data); computeMedians_(rt_data, reference_, true); } // one set of RT data for each input map, except reference: vector<SeqToList> rt_data(maps.size() - bool(reference_index_)); for (Size i = 0, j = 0; i < maps.size(); ++i) { if (i == reference_index_ - 1) continue; // skip reference map, if any getRetentionTimes_(maps[i], rt_data[j++]); } setProgress(1); computeTransformations_(rt_data, transformations, true); setProgress(2); // transformPeptideIdentifications(maps, transformations); setProgress(3); endProgress(); }
void call_drawable_loop( AppData& app_data, x11::Display& display, glx::Context& context, Drawable& drawable, DrawLoop drawable_loop ) { RaytracerData rt_data(app_data); ResourceAllocator res_alloc; RaytracerTarget rt_target(app_data, res_alloc); CommonData common( app_data, display, context, rt_data, rt_target ); std::vector<std::thread> threads; try { if(app_data.raytracer_params.empty()) { app_data.raytracer_params.push_back(std::string()); } for(auto& param : app_data.raytracer_params) { if(app_data.verbosity > 2) { app_data.logstr() << "Spawning raytracing thread on "; if(param.empty()) { app_data.logstr() << "the current X screen"; } else { app_data.logstr() << "X screen " << param; } app_data.logstr() << std::endl; } threads.push_back( std::thread( main_thread, std::ref(app_data), std::ref(common), std::cref(param) ) ); } } catch (...) { for(auto& t: threads) t.join(); throw; } try { common.thread_ready.Wait(threads.size()); common.master_ready.Signal(threads.size()); drawable_loop( drawable, app_data, common, rt_target, threads.size() ); for(auto& t: threads) t.join(); } catch (...) { common.Stop(); common.master_ready.Signal(threads.size()); for(auto& t: threads) t.join(); throw; } common.RethrowErrors(); }
// For performance, we're using multiple threads so that the game state can // be updating in the background while openGL renders. // The general plan is: // 1. Vsync happens. Everything begins. // 2. Renderthread activates. (The update thread is currently blocked.) // 3. Renderthread dumps everything into opengl, via RenderAllEntities. (And // any other similar calls, such as calls to IMGUI) Updatethread is // still blocked. When this is complete, OpenGL now has its own copy of // everything, and we can safely change world state data. // 4. Renderthread signals updatethread to wake up. // 5a.Renderthread calls gl_flush, (via Renderer.advanceframe) and waits for // everything render. Once complete, it goes to sleep and waits for the // next vsync event. // 5b.Updatethread goes and updates the game state and gets us all ready for // next frame. Once complete, it also goes to sleep and waits for the next // vsync event. void Game::Run() { // Start the update thread: UpdateThreadData rt_data(&game_exiting_, &world_, &state_machine_, &renderer_, &input_, &audio_engine_, &sync_); input_.AdvanceFrame(&renderer_.window_size()); state_machine_.AdvanceFrame(16); SDL_Thread* update_thread = SDL_CreateThread(UpdateThread, "Zooshi Update Thread", &rt_data); if (!update_thread) { LogError("Error creating update thread."); assert(false); } #if DISPLAY_FRAMERATE_HISTOGRAM for (int i = 0; i < kHistogramSize; i++) { histogram[i] = 0; } last_printout = 0; #endif // DISPLAY_FRAMERATE_HISTOGRAM // variables used for regulating our framerate: // Total size of our history, in frames: const int kHistorySize = 60 * 5; // Max number of frames we can have dropped in our history, before we // switch to queue-stuffing mode, and ignore vsync pauses. const int kMaxDroppedFrames = 3; // Variable bool missed_frame_history[kHistorySize]; for (int i = 0; i < kHistorySize; i++) { missed_frame_history[i] = false; } int history_index = 0; int total_dropped_frames = 0; global_vsync_context = &sync_; #ifdef __ANDROID__ fplbase::RegisterVsyncCallback(HandleVsync); #else // We don't need this on android because we'll just get vsync events directly. SDL_Thread* vsync_simulator_thread = SDL_CreateThread( VsyncSimulatorThread, "Zooshi Simulated Vsync Thread", nullptr); if (!vsync_simulator_thread) { LogError("Error creating vsync simulator thread."); assert(false); } #endif // __ANDROID__ int last_frame_id = 0; // We basically own the lock all the time, except when we're waiting // for a vsync event. SDL_LockMutex(sync_.renderthread_mutex_); while (!game_exiting_) { #ifdef __ANDROID__ int current_frame_id = fplbase::GetVsyncFrameId(); #else int current_frame_id = 0; #endif // __ANDROID__ // Update our framerate history: // The oldest value falls off and is replaced with the most recent frame. // Also, we update our counts. if (missed_frame_history[history_index]) { total_dropped_frames--; } // We count it as a dropped frame if more than one vsync event passed since // we started rendering it. The check is implemented via equality // comparisons because current_frame_id will eventually wrap.) missed_frame_history[history_index] = (current_frame_id != last_frame_id + 1) && (current_frame_id != last_frame_id); if (missed_frame_history[history_index]) { total_dropped_frames++; } history_index = (history_index + 1) % kHistorySize; last_frame_id = current_frame_id; // ------------------------------------------- // Steps 1, 2. // Wait for start of frame. (triggered at vsync start on android.) // For performance, we only wait if we're not dropping frames. Otherwise, // we just keep rendering as fast as we can and stuff the render queue. if (total_dropped_frames <= kMaxDroppedFrames) { SDL_CondWait(sync_.start_render_cv_, sync_.renderthread_mutex_); } // Grab the lock to make sure the game isn't still updating. SDL_LockMutex(sync_.gameupdate_mutex_); SystraceBegin("RenderFrame"); // Input update must happen from the render thread. // From the SDL documentation on SDL_PollEvent(), // https://wiki.libsdl.org/SDL_PollEvent): // "As this function implicitly calls SDL_PumpEvents(), you can only call // this function in the thread that set the video mode." SystraceBegin("Input::AdvanceFrame()"); input_.AdvanceFrame(&renderer_.window_size()); game_exiting_ |= input_.exit_requested(); SystraceEnd(); // Milliseconds elapsed since last update. rt_data.frame_start = CurrentWorldTimeSubFrame(input_); // ------------------------------------------- // Step 3. // Render everything. // ------------------------------------------- SystraceBegin("StateMachine::Render()"); fplbase::RenderTarget::ScreenRenderTarget(renderer_).SetAsRenderTarget(); renderer_.ClearDepthBuffer(); renderer_.SetCulling(fplbase::Renderer::kCullBack); state_machine_.Render(&renderer_); SystraceEnd(); SDL_UnlockMutex(sync_.gameupdate_mutex_); SystraceBegin("StateMachine::HandleUI()"); state_machine_.HandleUI(&renderer_); SystraceEnd(); // ------------------------------------------- // Step 4. // Signal the update thread that it is safe to start messing with // data, now that we've already handed it all off to openGL. // ------------------------------------------- SDL_CondBroadcast(sync_.start_update_cv_); // ------------------------------------------- // Step 5a. // Start openGL actually rendering. AdvanceFrame will (among other things) // trigger a gl_flush. This thread will block until it is completed, // but that's ok because the update thread is humming in the background // preparing the worlds tate for next frame. // ------------------------------------------- SystraceBegin("AdvanceFrame"); renderer_.AdvanceFrame(input_.minimized(), input_.Time()); SystraceEnd(); // AdvanceFrame SystraceEnd(); // RenderFrame gpg_manager_.Update(); // Process input device messages since the last game loop. // Update render window size. if (input_.GetButton(fplbase::FPLK_BACKQUOTE).went_down()) { ToggleRelativeMouseMode(); } int new_time = CurrentWorldTimeSubFrame(input_); int frame_time = new_time - rt_data.frame_start; #if DISPLAY_FRAMERATE_HISTOGRAM UpdateProfiling(frame_time); #endif // DISPLAY_FRAMERATE_HISTOGRAM SystraceCounter("FrameTime", frame_time); } SDL_UnlockMutex(sync_.renderthread_mutex_); // Clean up asynchronous callbacks to prevent crashing on garbage data. #ifdef __ANDROID__ fplbase::RegisterVsyncCallback(nullptr); #endif // __ANDROID__ input_.AddAppEventCallback(nullptr); }