]> git.sesse.net Git - nageru/commitdiff
Release flow textures when we are done with them.
authorSteinar H. Gunderson <sgunderson@bigfoot.com>
Wed, 12 Sep 2018 22:48:01 +0000 (00:48 +0200)
committerSteinar H. Gunderson <sgunderson@bigfoot.com>
Sat, 15 Sep 2018 17:39:49 +0000 (19:39 +0200)
flow.cpp
flow.h
video_stream.cpp
video_stream.h

index 873bdf294b1143aaf6eec681419419d5c513e844..ece0d518bcfd9a7650ba0d522d598e9e4d71d052 100644 (file)
--- a/flow.cpp
+++ b/flow.cpp
@@ -1019,11 +1019,14 @@ GLuint Interpolate::exec(GLuint image_tex, GLuint bidirectional_flow_tex, GLuint
 
 GLuint TexturePool::get_texture(GLenum format, GLuint width, GLuint height, GLuint num_layers)
 {
-       for (Texture &tex : textures) {
-               if (!tex.in_use && !tex.is_renderbuffer && tex.format == format &&
-                   tex.width == width && tex.height == height && tex.num_layers == num_layers) {
-                       tex.in_use = true;
-                       return tex.tex_num;
+       {
+               lock_guard<mutex> lock(mu);
+               for (Texture &tex : textures) {
+                       if (!tex.in_use && !tex.is_renderbuffer && tex.format == format &&
+                           tex.width == width && tex.height == height && tex.num_layers == num_layers) {
+                               tex.in_use = true;
+                               return tex.tex_num;
+                       }
                }
        }
 
@@ -1041,17 +1044,23 @@ GLuint TexturePool::get_texture(GLenum format, GLuint width, GLuint height, GLui
        tex.num_layers = num_layers;
        tex.in_use = true;
        tex.is_renderbuffer = false;
-       textures.push_back(tex);
+       {
+               lock_guard<mutex> lock(mu);
+               textures.push_back(tex);
+       }
        return tex.tex_num;
 }
 
 GLuint TexturePool::get_renderbuffer(GLenum format, GLuint width, GLuint height)
 {
-       for (Texture &tex : textures) {
-               if (!tex.in_use && tex.is_renderbuffer && tex.format == format &&
-                   tex.width == width && tex.height == height) {
-                       tex.in_use = true;
-                       return tex.tex_num;
+       {
+               lock_guard<mutex> lock(mu);
+               for (Texture &tex : textures) {
+                       if (!tex.in_use && tex.is_renderbuffer && tex.format == format &&
+                           tex.width == width && tex.height == height) {
+                               tex.in_use = true;
+                               return tex.tex_num;
+                       }
                }
        }
 
@@ -1064,12 +1073,16 @@ GLuint TexturePool::get_renderbuffer(GLenum format, GLuint width, GLuint height)
        tex.height = height;
        tex.in_use = true;
        tex.is_renderbuffer = true;
-       textures.push_back(tex);
+       {
+               lock_guard<mutex> lock(mu);
+               textures.push_back(tex);
+       }
        return tex.tex_num;
 }
 
 void TexturePool::release_texture(GLuint tex_num)
 {
+       lock_guard<mutex> lock(mu);
        for (Texture &tex : textures) {
                if (!tex.is_renderbuffer && tex.tex_num == tex_num) {
                        assert(tex.in_use);
@@ -1082,6 +1095,7 @@ void TexturePool::release_texture(GLuint tex_num)
 
 void TexturePool::release_renderbuffer(GLuint tex_num)
 {
+       lock_guard<mutex> lock(mu);
        for (Texture &tex : textures) {
                if (tex.is_renderbuffer && tex.tex_num == tex_num) {
                        assert(tex.in_use);
diff --git a/flow.h b/flow.h
index 6475d9b7116d7bff2d61b1769176efb2ea17a0ce..f268316bd6882e7ea0f3d1a4dd305af6a368b5d3 100644 (file)
--- a/flow.h
+++ b/flow.h
@@ -9,6 +9,7 @@
 #include <epoxy/gl.h>
 #include <array>
 #include <map>
+#include <mutex>
 #include <vector>
 #include <utility>
 
@@ -383,6 +384,7 @@ private:
        GLuint uniform_scale_factor;
 };
 
+// All operations, except construction and destruction, are thread-safe.
 class TexturePool {
 public:
        GLuint get_texture(GLenum format, GLuint width, GLuint height, GLuint num_layers = 0);
@@ -398,7 +400,8 @@ private:
                bool in_use = false;
                bool is_renderbuffer = false;
        };
-       std::vector<Texture> textures;
+       std::mutex mu;
+       std::vector<Texture> textures;  // Under mu.
 };
 
 class DISComputeFlow {
index 441e36a11c8b9bfbfc6a6e1a1473b2925f140f3e..820a9335846c9115ed2e2c5ac2bba96819bd330d 100644 (file)
@@ -318,12 +318,16 @@ void VideoStream::schedule_interpolated_frame(int64_t output_pts, unsigned strea
        check_error();
        glGenerateTextureMipmap(resources.gray_tex);
        check_error();
-       GLuint flow_tex = compute_flow->exec(resources.gray_tex, DISComputeFlow::FORWARD_AND_BACKWARD, DISComputeFlow::DO_NOT_RESIZE_FLOW);
+       qf.flow_tex = compute_flow->exec(resources.gray_tex, DISComputeFlow::FORWARD_AND_BACKWARD, DISComputeFlow::DO_NOT_RESIZE_FLOW);
        check_error();
 
-       qf.output_tex = interpolate->exec(resources.input_tex, flow_tex, 1280, 720, alpha);
+       qf.output_tex = interpolate->exec(resources.input_tex, qf.flow_tex, 1280, 720, alpha);
        check_error();
 
+       // We could have released qf.flow_tex here, but to make sure we don't cause a stall
+       // when trying to reuse it for the next frame, we can just as well hold on to it
+       // and release it only when the readback is done.
+
        // Read it down (asynchronously) to the CPU.
        glPixelStorei(GL_PACK_ROW_LENGTH, 0);
        glBindBuffer(GL_PIXEL_PACK_BUFFER, resources.pbo);
@@ -377,6 +381,8 @@ void VideoStream::encode_thread_func()
                        glClientWaitSync(qf.fence.get(), /*flags=*/0, GL_TIMEOUT_IGNORED);
 
                        vector<uint8_t> jpeg = encode_jpeg((const uint8_t *)qf.resources.pbo_contents, 1280, 720);
+                       compute_flow->release_texture(qf.flow_tex);
+                       interpolate->release_texture(qf.output_tex);
 
                        AVPacket pkt;
                        av_init_packet(&pkt);
index 953e28e661934b16105f429261494796344918b2..364512331ee10dbbb6843fdea3afa1bde4bd3b81 100644 (file)
@@ -66,8 +66,8 @@ private:
                int64_t input_second_pts;
                float alpha;
                InterpolatedFrameResources resources;
-               GLuint output_tex;
                RefCountedGLsync fence;  // Set when the interpolated image is read back to the CPU.
+               GLuint flow_tex, output_tex;  // Released in the receiving thread; not really used for anything else.
        };
        std::deque<QueuedFrame> frame_queue;  // Under <queue_lock>.
        std::mutex queue_lock;