+ // Create and upload the texture. We always make mipmaps, since we have
+ // generally no idea of all the different chains that might crop up.
+ GLuint tex;
+ glGenTextures(1, &tex);
+ check_error();
+ glBindTexture(GL_TEXTURE_2D, tex);
+ check_error();
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
+ check_error();
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ check_error();
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ check_error();
+
+ // Actual upload.
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ check_error();
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, linesizes[0] / 4);
+ check_error();
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_SRGB8_ALPHA8, frame->width, frame->height, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, image_data.get());
+ check_error();
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+ check_error();
+
+ glGenerateMipmap(GL_TEXTURE_2D);
+ check_error();
+ glBindTexture(GL_TEXTURE_2D, 0);
+ check_error();
+
+ shared_ptr<Image> image(new Image{unsigned(frame->width), unsigned(frame->height), UniqueTexture(new GLuint(tex)), last_modified});