-#include "resource_pool.h"
-
-#include <stdio.h>
+#include <assert.h>
#include <pthread.h>
-
+#include <stdio.h>
+#include <stdlib.h>
#include <algorithm>
#include <map>
#include <string>
#include <utility>
+#include <epoxy/gl.h>
#include "init.h"
+#include "resource_pool.h"
#include "util.h"
using namespace std;
+namespace movit {
+
ResourcePool::ResourcePool(size_t program_freelist_max_length,
size_t texture_freelist_max_bytes)
: program_freelist_max_length(program_freelist_max_length),
for (list<GLuint>::const_iterator freelist_it = texture_freelist.begin();
freelist_it != texture_freelist.end();
++freelist_it) {
- GLuint free_texture_num = program_freelist.front();
- program_freelist.pop_front();
+ GLuint free_texture_num = *freelist_it;
assert(texture_formats.count(free_texture_num) != 0);
texture_freelist_bytes -= estimate_texture_size(texture_formats[free_texture_num]);
texture_formats.erase(free_texture_num);
void ResourcePool::delete_program(GLuint glsl_program_num)
{
bool found_program = false;
- for (std::map<std::pair<std::string, std::string>, GLuint>::iterator program_it = programs.begin();
+ for (map<pair<string, string>, GLuint>::iterator program_it = programs.begin();
program_it != programs.end();
++program_it) {
if (program_it->second == glsl_program_num) {
assert(found_program);
glDeleteProgram(glsl_program_num);
- std::map<GLuint, std::pair<GLuint, GLuint> >::iterator shader_it =
+ map<GLuint, pair<GLuint, GLuint> >::iterator shader_it =
program_shaders.find(glsl_program_num);
assert(shader_it != program_shaders.end());
glLinkProgram(glsl_program_num);
check_error();
+ GLint success;
+ glGetProgramiv(glsl_program_num, GL_LINK_STATUS, &success);
+ if (success == GL_FALSE) {
+ GLchar error_log[1024] = {0};
+ glGetProgramInfoLog(glsl_program_num, 1024, NULL, error_log);
+ fprintf(stderr, "Error linking program: %s\n", error_log);
+ exit(1);
+ }
+
if (movit_debug_level == MOVIT_DEBUG_ON) {
// Output shader to a temporary file, for easier debugging.
static int compiled_shader_num = 0;
case GL_SRGB8_ALPHA8:
format = GL_RGBA;
break;
+ case GL_RGB32F:
+ case GL_RGB16F:
+ case GL_RGB8:
+ format = GL_RGB;
+ break;
case GL_RG32F:
case GL_RG16F:
+ case GL_RG8:
format = GL_RG;
break;
- case GL_LUMINANCE8:
- format = GL_LUMINANCE;
+ case GL_R32F:
+ case GL_R16F:
+ case GL_R8:
+ format = GL_RED;
+ break;
+ default:
+ // TODO: Add more here as needed.
+ assert(false);
+ }
+
+ // Same with type; GLES is stricter than desktop OpenGL here.
+ GLenum type;
+ switch (internal_format) {
+ case GL_RGBA32F_ARB:
+ case GL_RGBA16F_ARB:
+ case GL_RGB32F:
+ case GL_RGB16F:
+ case GL_RG32F:
+ case GL_RG16F:
+ case GL_R32F:
+ case GL_R16F:
+ type = GL_FLOAT;
+ break;
+ case GL_SRGB8_ALPHA8:
+ case GL_RGBA8:
+ case GL_RGB8:
+ case GL_RG8:
+ case GL_R8:
+ type = GL_UNSIGNED_BYTE;
break;
default:
// TODO: Add more here as needed.
assert(false);
}
+
GLuint texture_num;
glGenTextures(1, &texture_num);
check_error();
glBindTexture(GL_TEXTURE_2D, texture_num);
check_error();
- glTexImage2D(GL_TEXTURE_2D, 0, internal_format, width, height, 0, format, GL_UNSIGNED_BYTE, NULL);
+ glTexImage2D(GL_TEXTURE_2D, 0, internal_format, width, height, 0, format, type, NULL);
check_error();
glBindTexture(GL_TEXTURE_2D, 0);
check_error();
case GL_RGBA16F_ARB:
bytes_per_pixel = 8;
break;
+ case GL_RGB32F_ARB:
+ bytes_per_pixel = 12;
+ break;
+ case GL_RGB16F_ARB:
+ bytes_per_pixel = 6;
+ break;
case GL_RGBA8:
case GL_SRGB8_ALPHA8:
bytes_per_pixel = 4;
break;
+ case GL_RGB8:
+ case GL_SRGB8:
+ bytes_per_pixel = 3;
+ break;
case GL_RG32F:
bytes_per_pixel = 8;
break;
case GL_RG16F:
bytes_per_pixel = 4;
break;
- case GL_LUMINANCE8:
+ case GL_R32F:
+ bytes_per_pixel = 4;
+ break;
+ case GL_R16F:
+ bytes_per_pixel = 2;
+ break;
+ case GL_R8:
bytes_per_pixel = 1;
break;
default:
return texture_format.width * texture_format.height * bytes_per_pixel;
}
+
+} // namespace movit