X-Git-Url: https://git.sesse.net/?p=movit;a=blobdiff_plain;f=ycbcr_input.cpp;h=8d58c7de8ab10c6d09adf68fa0bc8ef467f8be51;hp=a625fe3474c70f712f14db97397fedd79682dfc0;hb=0490917aca6b8e6057c04c8becc820a8e849a801;hpb=ab636361e865c389fe60584562372ec39ac4c511 diff --git a/ycbcr_input.cpp b/ycbcr_input.cpp index a625fe3..8d58c7d 100644 --- a/ycbcr_input.cpp +++ b/ycbcr_input.cpp @@ -11,11 +11,15 @@ YCbCrInput::YCbCrInput(const ImageFormat &image_format, : image_format(image_format), ycbcr_format(ycbcr_format), needs_update(false), + needs_pbo_recreate(false), finalized(false), needs_mipmaps(false), width(width), height(height) { + pbos[0] = pbos[1] = pbos[2] = 0; + texture_num[0] = texture_num[1] = texture_num[2] = 0; + pitch[0] = pitch[1] = pitch[2] = width; assert(width % ycbcr_format.chroma_subsampling_x == 0); @@ -31,8 +35,23 @@ YCbCrInput::YCbCrInput(const ImageFormat &image_format, register_int("needs_mipmaps", &needs_mipmaps); } +YCbCrInput::~YCbCrInput() +{ + if (pbos[0] != 0) { + glDeleteBuffers(3, pbos); + check_error(); + } + if (texture_num[0] != 0) { + glDeleteTextures(3, texture_num); + check_error(); + } +} + void YCbCrInput::finalize() { + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + check_error(); + // Create PBOs to hold the textures holding the input image, and then the texture itself. glGenBuffers(3, pbos); check_error(); @@ -71,12 +90,20 @@ void YCbCrInput::set_gl_state(GLuint glsl_program_num, const std::string& prefix glBindTexture(GL_TEXTURE_2D, texture_num[channel]); check_error(); - if (needs_update) { + if (needs_update || needs_pbo_recreate) { // Copy the pixel data into the PBO. glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, pbos[channel]); check_error(); + + if (needs_pbo_recreate) { + // The pitch has changed; we need to reallocate this PBO. + glBufferData(GL_PIXEL_UNPACK_BUFFER_ARB, pitch[channel] * heights[channel], NULL, GL_STREAM_DRAW); + check_error(); + } + void *mapped_pbo = glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, GL_WRITE_ONLY); memcpy(mapped_pbo, pixel_data[channel], pitch[channel] * heights[channel]); + glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB); check_error(); @@ -103,6 +130,7 @@ void YCbCrInput::set_gl_state(GLuint glsl_program_num, const std::string& prefix *sampler_num += 3; needs_update = false; + needs_pbo_recreate = false; } std::string YCbCrInput::output_fragment_shader()