diff options
| author | degasus <wickmarkus@web.de> | 2016-10-08 02:11:24 +0200 |
|---|---|---|
| committer | degasus <wickmarkus@web.de> | 2016-11-07 22:17:32 +0100 |
| commit | f6a6cc9c6743c1f9e9262775a6da7afbd153b19c (patch) | |
| tree | 58d74d7b4d3b651ddddc43a331912490c0d8cc95 /Source/Core/VideoBackends/OGL/Render.cpp | |
| parent | 136a10482f099aec67cebd8673388f54b78458b6 (diff) | |
OGL: Use PBO for framedump, with async readback.
Diffstat (limited to 'Source/Core/VideoBackends/OGL/Render.cpp')
| -rw-r--r-- | Source/Core/VideoBackends/OGL/Render.cpp | 66 |
1 files changed, 54 insertions, 12 deletions
diff --git a/Source/Core/VideoBackends/OGL/Render.cpp b/Source/Core/VideoBackends/OGL/Render.cpp index e3d3bea2d5..f0ab819815 100644 --- a/Source/Core/VideoBackends/OGL/Render.cpp +++ b/Source/Core/VideoBackends/OGL/Render.cpp @@ -767,6 +767,9 @@ Renderer::Renderer() Renderer::~Renderer() { + FlushFrameDump(); + if (m_frame_dumping_pbo[0]) + glDeleteBuffers(2, m_frame_dumping_pbo.data()); } void Renderer::Shutdown() @@ -1447,19 +1450,9 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); - if (IsFrameDumping()) - { - std::vector<u8> image(flipped_trc.GetWidth() * flipped_trc.GetHeight() * 4); - - glPixelStorei(GL_PACK_ALIGNMENT, 1); - glReadPixels(flipped_trc.left, flipped_trc.bottom, flipped_trc.GetWidth(), - flipped_trc.GetHeight(), GL_RGBA, GL_UNSIGNED_BYTE, image.data()); + FlushFrameDump(); + DumpFrame(flipped_trc, ticks); - AVIDump::Frame state = AVIDump::FetchState(ticks); - DumpFrameData(image.data(), flipped_trc.GetWidth(), flipped_trc.GetHeight(), - flipped_trc.GetWidth() * 4, state, true); - FinishFrameData(); - } // Finish up the current frame, print some stats SetWindowSize(fbStride, fbHeight); @@ -1588,6 +1581,55 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, ClearEFBCache(); } +void Renderer::FlushFrameDump() +{ + if (!m_last_frame_exported) + return; + + FinishFrameData(); + glBindBuffer(GL_PIXEL_PACK_BUFFER, m_frame_dumping_pbo[0]); + m_frame_pbo_is_mapped[0] = true; + void* data = glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, + m_last_frame_width * m_last_frame_height * 4, GL_MAP_READ_BIT); + DumpFrameData(reinterpret_cast<u8*>(data), m_last_frame_width, m_last_frame_height, + m_last_frame_width * 4, m_last_frame_state, true); + glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); + m_last_frame_exported = false; +} + +void Renderer::DumpFrame(const TargetRectangle& flipped_trc, u64 ticks) +{ + if (!IsFrameDumping()) + return; + + if (!m_frame_dumping_pbo[0]) + { + glGenBuffers(2, m_frame_dumping_pbo.data()); + glBindBuffer(GL_PIXEL_PACK_BUFFER, m_frame_dumping_pbo[0]); + } + else + { + std::swap(m_frame_dumping_pbo[0], m_frame_dumping_pbo[1]); + std::swap(m_frame_pbo_is_mapped[0], m_frame_pbo_is_mapped[1]); + glBindBuffer(GL_PIXEL_PACK_BUFFER, m_frame_dumping_pbo[0]); + if (m_frame_pbo_is_mapped[0]) + glUnmapBuffer(GL_PIXEL_PACK_BUFFER); + m_frame_pbo_is_mapped[0] = false; + } + + m_last_frame_width = flipped_trc.GetWidth(); + m_last_frame_height = flipped_trc.GetHeight(); + m_last_frame_state = AVIDump::FetchState(ticks); + m_last_frame_exported = true; + + glBufferData(GL_PIXEL_PACK_BUFFER, m_last_frame_width * m_last_frame_height * 4, nullptr, + GL_STREAM_READ); + glPixelStorei(GL_PACK_ALIGNMENT, 1); + glReadPixels(flipped_trc.left, flipped_trc.bottom, m_last_frame_width, m_last_frame_height, + GL_RGBA, GL_UNSIGNED_BYTE, 0); + glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); +} + // ALWAYS call RestoreAPIState for each ResetAPIState call you're doing void Renderer::ResetAPIState() { |
