From: Steinar H. Gunderson Date: Sun, 4 Oct 2015 14:07:24 +0000 (+0200) Subject: Add a wrapper to make fences refcounted, as we will soon be needing to split them... X-Git-Tag: 1.0.0~314 X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;ds=sidebyside;h=6531415ce7a0010195cb3267c6898475d38922ac;p=nageru Add a wrapper to make fences refcounted, as we will soon be needing to split them for several users. --- diff --git a/h264encode.cpp b/h264encode.cpp index fe51b9e..83de3bd 100644 --- a/h264encode.cpp +++ b/h264encode.cpp @@ -1874,7 +1874,7 @@ bool H264Encoder::begin_frame(GLuint *y_tex, GLuint *cbcr_tex) return true; } -void H264Encoder::end_frame(GLsync fence, const std::vector &input_frames_to_release) +void H264Encoder::end_frame(RefCountedGLsync fence, const std::vector &input_frames_to_release) { { unique_lock lock(frame_queue_mutex); @@ -1904,8 +1904,7 @@ void H264Encoder::copy_thread_func() } // Wait for the GPU to be done with the frame. - glClientWaitSync(frame.fence, 0, 0); - glDeleteSync(frame.fence); + glClientWaitSync(frame.fence.get(), 0, 0); // Release back any input frames we needed to render this frame. // (Actually, those that were needed one output frame ago.) diff --git a/h264encode.h b/h264encode.h index 5409d17..b14ca6f 100644 --- a/h264encode.h +++ b/h264encode.h @@ -35,13 +35,11 @@ extern "C" { #include #include #include -#include -#include -#include #include #include "pbo_frame_allocator.h" #include "context.h" +#include "ref_counted_gl_sync.h" #define SURFACE_NUM 16 /* 16 surfaces for source YUV */ @@ -63,7 +61,7 @@ public: void #endif bool begin_frame(GLuint *y_tex, GLuint *cbcr_tex); - void end_frame(GLsync fence, const std::vector &input_frames_to_release); + void end_frame(RefCountedGLsync fence, const std::vector &input_frames_to_release); private: struct storage_task { @@ -94,7 +92,7 @@ private: int current_storage_frame; struct PendingFrame { - GLsync fence; + RefCountedGLsync fence; std::vector input_frames_to_release; }; std::map pending_frames; diff --git a/mixer.cpp b/mixer.cpp index d7726f3..05b3287 100644 --- a/mixer.cpp +++ b/mixer.cpp @@ -50,6 +50,7 @@ #include "context.h" #include "bmusb.h" #include "pbo_frame_allocator.h" +#include "ref_counted_gl_sync.h" using namespace movit; using namespace std; @@ -436,42 +437,40 @@ void mixer_thread_func(QSurface *surface, QSurface *surface2, QSurface *surface3 glBindFramebuffer(GL_FRAMEBUFFER, cbcr_fbo); glViewport(0, 0, WIDTH/2, HEIGHT/2); check_error(); - GLsync fence; - { - glUseProgram(cbcr_program_num); - check_error(); - glActiveTexture(GL_TEXTURE0); - check_error(); - glBindTexture(GL_TEXTURE_2D, chroma_tex); - check_error(); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - check_error(); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - check_error(); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - check_error(); + glUseProgram(cbcr_program_num); + check_error(); - float chroma_offset_0[] = { -0.5f / WIDTH, 0.0f }; - set_uniform_vec2(cbcr_program_num, "foo", "chroma_offset_0", chroma_offset_0); + glActiveTexture(GL_TEXTURE0); + check_error(); + glBindTexture(GL_TEXTURE_2D, chroma_tex); + check_error(); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + check_error(); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + check_error(); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + check_error(); - GLuint position_vbo = fill_vertex_attribute(cbcr_program_num, "position", 2, GL_FLOAT, sizeof(vertices), vertices); - GLuint texcoord_vbo = fill_vertex_attribute(cbcr_program_num, "texcoord", 2, GL_FLOAT, sizeof(vertices), vertices); // Same as vertices. + float chroma_offset_0[] = { -0.5f / WIDTH, 0.0f }; + set_uniform_vec2(cbcr_program_num, "foo", "chroma_offset_0", chroma_offset_0); - glDrawArrays(GL_TRIANGLES, 0, 3); - check_error(); + GLuint position_vbo = fill_vertex_attribute(cbcr_program_num, "position", 2, GL_FLOAT, sizeof(vertices), vertices); + GLuint texcoord_vbo = fill_vertex_attribute(cbcr_program_num, "texcoord", 2, GL_FLOAT, sizeof(vertices), vertices); // Same as vertices. - cleanup_vertex_attribute(cbcr_program_num, "position", position_vbo); - cleanup_vertex_attribute(cbcr_program_num, "texcoord", texcoord_vbo); + glDrawArrays(GL_TRIANGLES, 0, 3); + check_error(); - glUseProgram(0); - check_error(); + cleanup_vertex_attribute(cbcr_program_num, "position", position_vbo); + cleanup_vertex_attribute(cbcr_program_num, "texcoord", texcoord_vbo); - fence = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, /*flags=*/0); - check_error(); + glUseProgram(0); + check_error(); - resource_pool->release_fbo(cbcr_fbo); - } + RefCountedGLsync fence(GL_SYNC_GPU_COMMANDS_COMPLETE, /*flags=*/0); + check_error(); + + resource_pool->release_fbo(cbcr_fbo); h264_encoder.end_frame(fence, input_frames_to_release); diff --git a/ref_counted_gl_sync.h b/ref_counted_gl_sync.h new file mode 100644 index 0000000..5e23752 --- /dev/null +++ b/ref_counted_gl_sync.h @@ -0,0 +1,22 @@ +#ifndef _REF_COUNTED_GL_SYNC_H +#define _REF_COUNTED_GL_SYNC_H 1 + +// A wrapper around GLsync (OpenGL fences) that is automatically refcounted. +// Useful since we sometimes want to use the same fence two entirely different +// places. (We could set two fences at the same time, but they are not an +// unlimited hardware resource, so it would be a bit wasteful.) + +#include +#include + +typedef std::shared_ptr<__GLsync> RefCountedGLsyncBase; + +class RefCountedGLsync : public RefCountedGLsyncBase { +public: + RefCountedGLsync() {} + + RefCountedGLsync(GLenum condition, GLbitfield flags) + : RefCountedGLsyncBase(glFenceSync(condition, flags), glDeleteSync) {} +}; + +#endif // !defined(_REF_COUNTED_GL_SYNC_H)