Make FlatInput and YCbCrInput release the texture to the pool on invalidate_pixel_data().
authorSteinar H. Gunderson <sgunderson@bigfoot.com>
Tue, 21 Jan 2014 22:09:59 +0000 (23:09 +0100)
committerSteinar H. Gunderson <sgunderson@bigfoot.com>
Tue, 21 Jan 2014 22:25:52 +0000 (23:25 +0100)
flat_input.cpp
flat_input.h
ycbcr_input.cpp
ycbcr_input.h

index 5323dac..0a81392 100644 (file)
@@ -13,7 +13,6 @@ FlatInput::FlatInput(ImageFormat image_format, MovitPixelFormat pixel_format, GL
          type(type),
          pbo(0),
          texture_num(0),
-         needs_update(false),
          finalized(false),
          output_linear_gamma(false),
          needs_mipmaps(false),
@@ -37,7 +36,6 @@ FlatInput::~FlatInput()
 void FlatInput::finalize()
 {
        // Translate the input format to OpenGL's enums.
-       GLenum internal_format;
        if (type == GL_FLOAT) {
                internal_format = GL_RGBA32F_ARB;
        } else if (output_linear_gamma) {
@@ -63,16 +61,6 @@ void FlatInput::finalize()
                assert(false);
        }
 
-       // Create the texture itself.
-       texture_num = resource_pool->create_2d_texture(internal_format, width, height);
-       glBindTexture(GL_TEXTURE_2D, texture_num);
-       check_error();
-       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, needs_mipmaps ? GL_LINEAR_MIPMAP_NEAREST : GL_LINEAR);
-       check_error();
-       glBindTexture(GL_TEXTURE_2D, 0);
-       check_error();
-
-       needs_update = true;
        finalized = true;
 }
        
@@ -80,21 +68,24 @@ void FlatInput::set_gl_state(GLuint glsl_program_num, const std::string& prefix,
 {
        glActiveTexture(GL_TEXTURE0 + *sampler_num);
        check_error();
-       glBindTexture(GL_TEXTURE_2D, texture_num);
-       check_error();
-       glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
-       check_error();
 
-       if (needs_update) {
-               // Re-upload the texture.
+       if (texture_num == 0) {
+               // (Re-)upload the texture.
+               texture_num = resource_pool->create_2d_texture(internal_format, width, height);
+               glBindTexture(GL_TEXTURE_2D, texture_num);
+               check_error();
                glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, pbo);
                check_error();
+               glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, needs_mipmaps ? GL_LINEAR_MIPMAP_NEAREST : GL_LINEAR);
+               check_error();
                glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
                check_error();
                glPixelStorei(GL_UNPACK_ROW_LENGTH, pitch);
                check_error();
                glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, format, type, pixel_data);
                check_error();
+               glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+               check_error();
                if (needs_mipmaps) {
                        glGenerateMipmap(GL_TEXTURE_2D);
                        check_error();
@@ -107,8 +98,9 @@ void FlatInput::set_gl_state(GLuint glsl_program_num, const std::string& prefix,
                check_error();
                glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
                check_error();
-
-               needs_update = false;
+       } else {
+               glBindTexture(GL_TEXTURE_2D, texture_num);
+               check_error();
        }
 
        // Bind it to a sampler.
@@ -120,3 +112,11 @@ std::string FlatInput::output_fragment_shader()
 {
        return read_file("flat_input.frag");
 }
+
+void FlatInput::invalidate_pixel_data()
+{
+       if (texture_num != 0) {
+               resource_pool->release_2d_texture(texture_num);
+               texture_num = 0;
+       }
+}
index 33c685b..7875e2c 100644 (file)
@@ -86,10 +86,7 @@ public:
                invalidate_pixel_data();
        }
 
-       void invalidate_pixel_data()
-       {
-               needs_update = true;
-       }
+       void invalidate_pixel_data();
 
        void set_pitch(unsigned pitch) {
                assert(!finalized);
@@ -104,9 +101,9 @@ public:
 private:
        ImageFormat image_format;
        MovitPixelFormat pixel_format;
-       GLenum format, type;
+       GLenum internal_format, format, type;
        GLuint pbo, texture_num;
-       bool needs_update, finalized;
+       bool finalized;
        int output_linear_gamma, needs_mipmaps;
        unsigned width, height, pitch;
        const void *pixel_data;
index eebb864..4166da9 100644 (file)
@@ -62,7 +62,6 @@ YCbCrInput::YCbCrInput(const ImageFormat &image_format,
                        unsigned width, unsigned height)
        : image_format(image_format),
          ycbcr_format(ycbcr_format),
-         needs_update(false),
          finalized(false),
          needs_mipmaps(false),
          width(width),
@@ -98,16 +97,6 @@ YCbCrInput::~YCbCrInput()
 
 void YCbCrInput::finalize()
 {
-       // Create the textures themselves.
-       for (unsigned channel = 0; channel < 3; ++channel) {
-               texture_num[channel] = resource_pool->create_2d_texture(GL_LUMINANCE8, widths[channel], heights[channel]);
-               glBindTexture(GL_TEXTURE_2D, texture_num[channel]);
-               check_error();
-               glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-               check_error();
-       }
-
-       needs_update = true;
        finalized = true;
 }
        
@@ -116,12 +105,14 @@ void YCbCrInput::set_gl_state(GLuint glsl_program_num, const std::string& prefix
        for (unsigned channel = 0; channel < 3; ++channel) {
                glActiveTexture(GL_TEXTURE0 + *sampler_num + channel);
                check_error();
-               glBindTexture(GL_TEXTURE_2D, texture_num[channel]);
-               check_error();
 
-               if (needs_update) {
-                       // Re-upload the texture.
-                       // Copy the pixel data into the PBO.
+               if (texture_num[channel] == 0) {
+                       // (Re-)upload the texture.
+                       texture_num[channel] = resource_pool->create_2d_texture(GL_LUMINANCE8, widths[channel], heights[channel]);
+                       glBindTexture(GL_TEXTURE_2D, texture_num[channel]);
+                       check_error();
+                       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+                       check_error();
                        glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, pbos[channel]);
                        check_error();
                        glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
@@ -136,6 +127,9 @@ void YCbCrInput::set_gl_state(GLuint glsl_program_num, const std::string& prefix
                        check_error();
                        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
                        check_error();
+               } else {
+                       glBindTexture(GL_TEXTURE_2D, texture_num[channel]);
+                       check_error();
                }
        }
 
@@ -148,7 +142,6 @@ void YCbCrInput::set_gl_state(GLuint glsl_program_num, const std::string& prefix
        set_uniform_int(glsl_program_num, prefix, "tex_cr", *sampler_num + 2);
 
        *sampler_num += 3;
-       needs_update = false;
 }
 
 std::string YCbCrInput::output_fragment_shader()
@@ -251,3 +244,13 @@ std::string YCbCrInput::output_fragment_shader()
        frag_shader += read_file("ycbcr_input.frag");
        return frag_shader;
 }
+
+void YCbCrInput::invalidate_pixel_data()
+{
+       for (unsigned channel = 0; channel < 3; ++channel) {
+               if (texture_num[channel] != 0) {
+                       resource_pool->release_2d_texture(texture_num[channel]);
+                       texture_num[channel] = 0;
+               }
+       }
+}
index eb8d0ec..9f4e320 100644 (file)
@@ -80,10 +80,7 @@ public:
                invalidate_pixel_data();
        }
 
-       void invalidate_pixel_data()
-       {
-               needs_update = true;
-       }
+       void invalidate_pixel_data();
 
        void set_pitch(unsigned channel, unsigned pitch) {
                assert(channel >= 0 && channel < 3);
@@ -99,7 +96,7 @@ private:
        ImageFormat image_format;
        YCbCrFormat ycbcr_format;
        GLuint pbos[3], texture_num[3];
-       bool needs_update, finalized;
+       bool finalized;
 
        int needs_mipmaps;