]> git.sesse.net Git - nageru/commitdiff
Add a wrapper to make fences refcounted, as we will soon be needing to split them...
authorSteinar H. Gunderson <sgunderson@bigfoot.com>
Sun, 4 Oct 2015 14:07:24 +0000 (16:07 +0200)
committerSteinar H. Gunderson <sgunderson@bigfoot.com>
Sun, 4 Oct 2015 14:07:24 +0000 (16:07 +0200)
h264encode.cpp
h264encode.h
mixer.cpp
ref_counted_gl_sync.h [new file with mode: 0644]

index fe51b9e8d06a50ae4739c676d039a497fa058a12..83de3bd32c61ffe30687c234775db5299801b7c1 100644 (file)
@@ -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<FrameAllocator::Frame> &input_frames_to_release)
+void H264Encoder::end_frame(RefCountedGLsync fence, const std::vector<FrameAllocator::Frame> &input_frames_to_release)
 {
        {
                unique_lock<mutex> 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.)
index 5409d17421c3fb8b047c94911908c2243864d7f4..b14ca6f4690643d6281be45c0dbd27e19b49f3a5 100644 (file)
@@ -35,13 +35,11 @@ extern "C" {
 #include <memory>
 #include <mutex>
 #include <thread>
-#include <thread>
-#include <thread>
-#include <thread>
 #include <condition_variable>
 
 #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<FrameAllocator::Frame> &input_frames_to_release);
+       void end_frame(RefCountedGLsync fence, const std::vector<FrameAllocator::Frame> &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<FrameAllocator::Frame> input_frames_to_release;
        };
        std::map<int, PendingFrame> pending_frames;
index d7726f3cc15c7a4136272086c386f0b53c82417a..05b32871d3f528cc1e767c842713467fe4b0e687 100644 (file)
--- 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 (file)
index 0000000..5e23752
--- /dev/null
@@ -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 <GL/gl.h>
+#include <memory>
+
+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)