115 "Failed to setup compositor shaders, unable to make OpenGL context "
120 GLuint vertex_shader = glCreateShader(GL_VERTEX_SHADER);
122 glCompileShader(vertex_shader);
123 GLint vertex_compile_status;
124 glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &vertex_compile_status);
125 if (vertex_compile_status == GL_FALSE) {
126 g_autofree gchar* shader_log = get_shader_log(vertex_shader);
127 g_warning(
"Failed to compile vertex shader: %s", shader_log);
130 GLuint fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
132 glCompileShader(fragment_shader);
133 GLint fragment_compile_status;
134 glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &fragment_compile_status);
135 if (fragment_compile_status == GL_FALSE) {
136 g_autofree gchar* shader_log = get_shader_log(fragment_shader);
137 g_warning(
"Failed to compile fragment shader: %s", shader_log);
140 self->program = glCreateProgram();
141 glAttachShader(
self->program, vertex_shader);
142 glAttachShader(
self->program, fragment_shader);
143 glLinkProgram(
self->program);
146 glGetProgramiv(
self->program, GL_LINK_STATUS, &link_status);
147 if (link_status == GL_FALSE) {
149 g_warning(
"Failed to link program: %s", program_log);
152 self->offset_location = glGetUniformLocation(
self->program,
"offset");
153 self->scale_location = glGetUniformLocation(
self->program,
"scale");
155 glDeleteShader(vertex_shader);
156 glDeleteShader(fragment_shader);
162 GLfloat vertex_data[] = {-1, -1, 0, 0, 1, 1, 1, 1, -1, 1, 0, 1,
163 -1, -1, 0, 0, 1, -1, 1, 0, 1, 1, 1, 1};
165 glGenBuffers(1, &
self->vertex_buffer);
166 glBindBuffer(GL_ARRAY_BUFFER,
self->vertex_buffer);
167 glBufferData(GL_ARRAY_BUFFER,
sizeof(vertex_data), vertex_data,
209 FlCompositorOpenGL*
self = FL_COMPOSITOR_OPENGL(compositor);
211 g_mutex_lock(&
self->frame_mutex);
213 g_mutex_unlock(&
self->frame_mutex);
217 GLint general_format = GL_RGBA;
219 general_format = GL_BGRA_EXT;
225 GLint saved_texture_binding;
226 glGetIntegerv(GL_TEXTURE_BINDING_2D, &saved_texture_binding);
227 GLint saved_vao_binding;
228 glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &saved_vao_binding);
229 GLint saved_array_buffer_binding;
230 glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &saved_array_buffer_binding);
231 GLint saved_draw_framebuffer_binding;
232 glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &saved_draw_framebuffer_binding);
233 GLint saved_read_framebuffer_binding;
234 glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &saved_read_framebuffer_binding);
235 GLint saved_current_program;
236 glGetIntegerv(GL_CURRENT_PROGRAM, &saved_current_program);
237 GLboolean saved_scissor_test = glIsEnabled(GL_SCISSOR_TEST);
238 GLboolean saved_blend = glIsEnabled(GL_BLEND);
240 glGetIntegerv(GL_BLEND_SRC_RGB, &saved_src_rgb);
241 GLint saved_src_alpha;
242 glGetIntegerv(GL_BLEND_SRC_ALPHA, &saved_src_alpha);
244 glGetIntegerv(GL_BLEND_DST_RGB, &saved_dst_rgb);
245 GLint saved_dst_alpha;
246 glGetIntegerv(GL_BLEND_DST_ALPHA, &saved_dst_alpha);
251 if (
self->framebuffer ==
nullptr ||
254 g_clear_object(&
self->framebuffer);
259 if (!
self->shareable) {
262 static_cast<uint8_t*
>(g_realloc(
self->pixels, data_length));
266 self->had_first_frame =
true;
271 glGenVertexArrays(1, &vao);
272 glBindVertexArray(vao);
273 glBindBuffer(GL_ARRAY_BUFFER,
self->vertex_buffer);
274 GLint position_location = glGetAttribLocation(
self->program,
"position");
275 glEnableVertexAttribArray(position_location);
276 glVertexAttribPointer(position_location, 2, GL_FLOAT, GL_FALSE,
277 sizeof(GLfloat) * 4, 0);
278 GLint texcoord_location = glGetAttribLocation(
self->program,
"in_texcoord");
279 glEnableVertexAttribArray(texcoord_location);
280 glVertexAttribPointer(texcoord_location, 2, GL_FLOAT, GL_FALSE,
282 reinterpret_cast<void*
>(
sizeof(GLfloat) * 2));
285 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
287 glUseProgram(
self->program);
292 glDisable(GL_SCISSOR_TEST);
294 glBindFramebuffer(GL_DRAW_FRAMEBUFFER,
296 gboolean first_layer =
TRUE;
299 switch (layer->
type) {
302 FlFramebuffer* framebuffer =
304 glBindFramebuffer(GL_READ_FRAMEBUFFER,
326 glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
329 glDeleteVertexArrays(1, &vao);
336 if (saved_scissor_test) {
337 glEnable(GL_SCISSOR_TEST);
339 glDisable(GL_SCISSOR_TEST);
342 glBindTexture(GL_TEXTURE_2D, saved_texture_binding);
343 glBindVertexArray(saved_vao_binding);
344 glBindBuffer(GL_ARRAY_BUFFER, saved_array_buffer_binding);
345 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, saved_draw_framebuffer_binding);
346 glUseProgram(saved_current_program);
347 glBlendFuncSeparate(saved_src_rgb, saved_dst_rgb, saved_src_alpha,
350 if (!
self->shareable) {
351 glBindFramebuffer(GL_READ_FRAMEBUFFER,
353 glReadPixels(0, 0,
width,
height, GL_RGBA, GL_UNSIGNED_BYTE,
self->pixels);
354 glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
356 glBindFramebuffer(GL_READ_FRAMEBUFFER, saved_read_framebuffer_binding);
358 g_mutex_unlock(&
self->frame_mutex);
387 gboolean wait_for_frame) {
388 FlCompositorOpenGL*
self = FL_COMPOSITOR_OPENGL(compositor);
390 g_mutex_lock(&
self->frame_mutex);
391 if (
self->framebuffer ==
nullptr) {
392 g_mutex_unlock(&
self->frame_mutex);
404 if (!wait_for_frame) {
410 if (framebuffer_width ==
width && framebuffer_height ==
height) {
414 if (g_get_monotonic_time() > expiry_time) {
416 "Timed out waiting for OpenGL frame of size %zdx%zd (have %zdx%zd)",
417 width,
height, framebuffer_width, framebuffer_height);
421 g_mutex_unlock(&
self->frame_mutex);
423 g_mutex_lock(&
self->frame_mutex);
432 GLint saved_texture_binding;
433 glGetIntegerv(GL_TEXTURE_BINDING_2D, &saved_texture_binding);
438 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
width,
height, 0, GL_RGBA,
439 GL_UNSIGNED_BYTE,
self->pixels);
446 glBindTexture(GL_TEXTURE_2D, saved_texture_binding);
451 g_mutex_unlock(&
self->frame_mutex);