void GLGSRender::synchronize_buffers() { if (flush_draw_buffers) { write_buffers(); flush_draw_buffers = false; } }
void on_idle() { scoped_lock with(lock); make_new_connections(); close_connections(); write_buffers(); start_reads(); start_timers(); close_idle_if_stop(); }
int PluginArray::run_plugins() { // Length to write after process_loop int64_t write_length; done = 0; // for when done error = 0; if(plugin_server->realtime) { int64_t len; MainProgressBar *progress; char string[BCTEXTLEN], string2[BCTEXTLEN]; sprintf(string, _("%s..."), plugin_server->title); progress = mwindow->mainprogress->start_progress(string, end - start); for(int current_position = start; current_position < end && !done && !error; current_position += len) { len = buffer_size; if(current_position + len > end) len = end - current_position; // Process in plugin. This pulls data from the modules get_buffers(); for(int i = 0; i < total; i++) { process_realtime(i, current_position, len); } // Write to file error = write_buffers(len); done = progress->update(current_position - start + len); } progress->get_time(string2); progress->stop_progress(); delete progress; sprintf(string, _("%s took %s"), plugin_server->title, string2); mwindow->gui->lock_window(); mwindow->gui->show_message(string2); mwindow->gui->unlock_window(); } else { // Run main loop once for multichannel plugins. // Run multiple times for single channel plugins. // Each write to the file must contain all the channels while(!done && !error) { for(int i = 0; i < total; i++) { write_length = 0; done += process_loop(i, write_length); } if(write_length) error = write_buffers(write_length); } } return error; }
void GLGSRender::end() { if (!draw_fbo) { rsx::thread::end(); return; } if (manually_flush_ring_buffers) { //Use approximations to reseve space. This path is mostly for debug purposes anyway u32 approx_vertex_count = rsx::method_registers.current_draw_clause.get_elements_count(); u32 approx_working_buffer_size = approx_vertex_count * 256; //Allocate 256K heap if we have no approximation at this time (inlined array) m_attrib_ring_buffer->reserve_storage_on_heap(std::max(approx_working_buffer_size, 256 * 1024U)); m_index_ring_buffer->reserve_storage_on_heap(16 * 1024); } draw_fbo.bind(); //Check if depth buffer is bound and valid //If ds is not initialized clear it; it seems new depth textures should have depth cleared gl::render_target *ds = std::get<1>(m_rtts.m_bound_depth_stencil); if (ds && !ds->cleared()) { glDepthMask(GL_TRUE); glClearDepth(1.f); glClear(GL_DEPTH_BUFFER_BIT); glDepthMask(rsx::method_registers.depth_write_enabled()); ds->set_cleared(); } std::chrono::time_point<std::chrono::system_clock> textures_start = std::chrono::system_clock::now(); //Setup textures for (int i = 0; i < rsx::limits::fragment_textures_count; ++i) { int location; if (!rsx::method_registers.fragment_textures[i].enabled()) { glActiveTexture(GL_TEXTURE0 + i); glBindTexture(GL_TEXTURE_2D, 0); continue; } if (m_program->uniforms.has_location("tex" + std::to_string(i), &location)) { m_gl_textures[i].set_target(get_gl_target_for_texture(rsx::method_registers.fragment_textures[i])); __glcheck m_gl_texture_cache.upload_texture(i, rsx::method_registers.fragment_textures[i], m_gl_textures[i], m_rtts); } } //Vertex textures for (int i = 0; i < rsx::limits::vertex_textures_count; ++i) { int texture_index = i + rsx::limits::fragment_textures_count; int location; if (!rsx::method_registers.vertex_textures[i].enabled()) { glActiveTexture(GL_TEXTURE0 + texture_index); glBindTexture(GL_TEXTURE_2D, 0); continue; } if (m_program->uniforms.has_location("vtex" + std::to_string(i), &location)) { m_gl_vertex_textures[i].set_target(get_gl_target_for_texture(rsx::method_registers.vertex_textures[i])); __glcheck m_gl_texture_cache.upload_texture(texture_index, rsx::method_registers.vertex_textures[i], m_gl_vertex_textures[i], m_rtts); } } std::chrono::time_point<std::chrono::system_clock> textures_end = std::chrono::system_clock::now(); m_textures_upload_time += (u32)std::chrono::duration_cast<std::chrono::microseconds>(textures_end - textures_start).count(); u32 vertex_draw_count; std::optional<std::tuple<GLenum, u32> > indexed_draw_info; std::tie(vertex_draw_count, indexed_draw_info) = set_vertex_buffer(); m_vao.bind(); std::chrono::time_point<std::chrono::system_clock> draw_start = std::chrono::system_clock::now(); if (g_cfg_rsx_debug_output) { m_program->validate(); } if (manually_flush_ring_buffers) { m_attrib_ring_buffer->unmap(); m_index_ring_buffer->unmap(); } if (indexed_draw_info) { if (__glcheck enable(rsx::method_registers.restart_index_enabled(), GL_PRIMITIVE_RESTART)) { GLenum index_type = std::get<0>(indexed_draw_info.value()); __glcheck glPrimitiveRestartIndex((index_type == GL_UNSIGNED_SHORT)? 0xffff: 0xffffffff); } __glcheck glDrawElements(gl::draw_mode(rsx::method_registers.current_draw_clause.primitive), vertex_draw_count, std::get<0>(indexed_draw_info.value()), (GLvoid *)(std::ptrdiff_t)std::get<1>(indexed_draw_info.value())); } else { draw_fbo.draw_arrays(rsx::method_registers.current_draw_clause.primitive, vertex_draw_count); } std::chrono::time_point<std::chrono::system_clock> draw_end = std::chrono::system_clock::now(); m_draw_time += (u32)std::chrono::duration_cast<std::chrono::microseconds>(draw_end - draw_start).count(); write_buffers(); rsx::thread::end(); }
void write( const std::vector<std::int16_t*> buffers, std::size_t frames ) { write_buffers( buffers, frames ); }
void write( const std::vector<float*> buffers, std::size_t frames ) { write_buffers( buffers, frames ); }