X-Git-Url: https://git.sesse.net/?p=movit;a=blobdiff_plain;f=resource_pool.cpp;h=f82996e4d24d13081f4f3dfbd981cea6e891fb49;hp=eba79237678611bf474c065f81111e49531cfb94;hb=84412c6d89fbe3563bab0b151274eb56c2ddd35c;hpb=599d6cf4bf3f7d063bf96dd626ff9fb1574fe032 diff --git a/resource_pool.cpp b/resource_pool.cpp index eba7923..f82996e 100644 --- a/resource_pool.cpp +++ b/resource_pool.cpp @@ -124,8 +124,11 @@ GLuint ResourcePool::compile_glsl_program(const string& vertex_shader, const str } else { // Not in the cache. Compile the shaders. glsl_program_num = glCreateProgram(); + check_error(); GLuint vs_obj = compile_shader(vertex_shader, GL_VERTEX_SHADER); + check_error(); GLuint fs_obj = compile_shader(fragment_shader, GL_FRAGMENT_SHADER); + check_error(); glAttachShader(glsl_program_num, vs_obj); check_error(); glAttachShader(glsl_program_num, fs_obj); @@ -309,18 +312,29 @@ void ResourcePool::release_2d_texture(GLuint texture_num) for (map, FBO>::iterator format_it = fbo_formats.begin(); format_it != fbo_formats.end(); ++format_it) { - if (format_it->second.texture_num == free_texture_num) { - format_it->second.texture_num = 0; + for (unsigned i = 0; i < num_fbo_attachments; ++i) { + if (format_it->second.texture_num[i] == free_texture_num) { + format_it->second.texture_num[i] = GL_INVALID_INDEX; + } } } } pthread_mutex_unlock(&lock); } -GLuint ResourcePool::create_fbo(GLuint texture_num) +GLuint ResourcePool::create_fbo(GLuint texture0_num, GLuint texture1_num, GLuint texture2_num, GLuint texture3_num) { void *context = get_gl_context_identifier(); + // Make sure we are filled from the bottom. + assert(texture0_num != 0); + if (texture1_num == 0) { + assert(texture2_num == 0); + } + if (texture2_num == 0) { + assert(texture3_num == 0); + } + pthread_mutex_lock(&lock); if (fbo_freelist.count(context) != 0) { // See if there's an FBO on the freelist we can use. @@ -331,7 +345,10 @@ GLuint ResourcePool::create_fbo(GLuint texture_num) map, FBO>::const_iterator format_it = fbo_formats.find(make_pair(context, fbo_num)); assert(format_it != fbo_formats.end()); - if (format_it->second.texture_num == texture_num) { + if (format_it->second.texture_num[0] == texture0_num && + format_it->second.texture_num[1] == texture1_num && + format_it->second.texture_num[2] == texture2_num && + format_it->second.texture_num[3] == texture3_num) { fbo_freelist[context].erase(freelist_it); pthread_mutex_unlock(&lock); return fbo_num; @@ -340,25 +357,42 @@ GLuint ResourcePool::create_fbo(GLuint texture_num) } // Create a new one. + FBO fbo_format; + fbo_format.texture_num[0] = texture0_num; + fbo_format.texture_num[1] = texture1_num; + fbo_format.texture_num[2] = texture2_num; + fbo_format.texture_num[3] = texture3_num; + GLuint fbo_num; glGenFramebuffers(1, &fbo_num); check_error(); glBindFramebuffer(GL_FRAMEBUFFER, fbo_num); check_error(); - glFramebufferTexture2D( - GL_FRAMEBUFFER, - GL_COLOR_ATTACHMENT0, - GL_TEXTURE_2D, - texture_num, - 0); + + GLenum bufs[num_fbo_attachments]; + unsigned num_active_attachments = 0; + for (unsigned i = 0; i < num_fbo_attachments; ++i, ++num_active_attachments) { + if (fbo_format.texture_num[i] == 0) { + break; + } + glFramebufferTexture2D( + GL_FRAMEBUFFER, + GL_COLOR_ATTACHMENT0 + i, + GL_TEXTURE_2D, + fbo_format.texture_num[i], + 0); + check_error(); + bufs[i] = GL_COLOR_ATTACHMENT0 + i; + } + + glDrawBuffers(num_active_attachments, bufs); check_error(); + GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); assert(status == GL_FRAMEBUFFER_COMPLETE); glBindFramebuffer(GL_FRAMEBUFFER, 0); check_error(); - FBO fbo_format; - fbo_format.texture_num = texture_num; pair key(context, fbo_num); assert(fbo_formats.count(key) == 0); fbo_formats.insert(make_pair(key, fbo_format)); @@ -400,7 +434,16 @@ void ResourcePool::cleanup_unlinked_fbos(void *context) GLuint fbo_num = *freelist_it; pair key(context, fbo_num); assert(fbo_formats.count(key) != 0); - if (fbo_formats[key].texture_num == 0) { + + bool all_unlinked = true; + for (unsigned i = 0; i < num_fbo_attachments; ++i) { + if (fbo_formats[key].texture_num[i] != 0 && + fbo_formats[key].texture_num[i] != GL_INVALID_INDEX) { + all_unlinked = false; + break; + } + } + if (all_unlinked) { fbo_formats.erase(key); glDeleteFramebuffers(1, &fbo_num); check_error(); @@ -461,6 +504,9 @@ size_t ResourcePool::estimate_texture_size(const Texture2D &texture_format) case GL_R16F: bytes_per_pixel = 2; break; + case GL_RG8: + bytes_per_pixel = 2; + break; case GL_R8: bytes_per_pixel = 1; break;