Flutter Engine Uber Docs
Docs for the entire Flutter Engine repo.
 
Loading...
Searching...
No Matches
fl_compositor_opengl.cc File Reference

Go to the source code of this file.

Classes

struct  _FlCompositorOpenGL
 

Functions

 G_DEFINE_TYPE (FlCompositorOpenGL, fl_compositor_opengl, fl_compositor_get_type()) static gchar *get_shader_log(GLuint shader)
 
static gchar * get_program_log (GLuint program)
 
static void setup_shader (FlCompositorOpenGL *self)
 
static void cleanup_shader (FlCompositorOpenGL *self)
 
static void composite_layer (FlCompositorOpenGL *self, FlFramebuffer *framebuffer, double x, double y, int width, int height)
 
static gboolean fl_compositor_opengl_present_layers (FlCompositor *compositor, const FlutterLayer **layers, size_t layers_count)
 
static void fl_compositor_opengl_get_frame_size (FlCompositor *compositor, size_t *width, size_t *height)
 
static gboolean fl_compositor_opengl_render (FlCompositor *compositor, cairo_t *cr, GdkWindow *window, gboolean wait_for_frame)
 
static void fl_compositor_opengl_dispose (GObject *object)
 
static void fl_compositor_opengl_class_init (FlCompositorOpenGLClass *klass)
 
static void fl_compositor_opengl_init (FlCompositorOpenGL *self)
 
FlCompositorOpenGL * fl_compositor_opengl_new (FlTaskRunner *task_runner, FlOpenGLManager *opengl_manager, gboolean shareable)
 

Variables

static const char * vertex_shader_src
 
static const char * fragment_shader_src
 

Function Documentation

◆ cleanup_shader()

static void cleanup_shader ( FlCompositorOpenGL *  self)
static

Definition at line 171 of file fl_compositor_opengl.cc.

171 {
172 if (!fl_opengl_manager_make_platform_current(self->opengl_manager)) {
173 g_warning(
174 "Failed to cleanup compositor shaders, unable to make OpenGL context "
175 "current");
176 return;
177 }
178
179 if (self->program != 0) {
180 glDeleteProgram(self->program);
181 }
182 if (self->vertex_buffer != 0) {
183 glDeleteBuffers(1, &self->vertex_buffer);
184 }
185}
gboolean fl_opengl_manager_make_platform_current(FlOpenGLManager *self)

References fl_opengl_manager_make_platform_current(), and self.

Referenced by fl_compositor_opengl_dispose().

◆ composite_layer()

static void composite_layer ( FlCompositorOpenGL *  self,
FlFramebuffer *  framebuffer,
double  x,
double  y,
int  width,
int  height 
)
static

Definition at line 187 of file fl_compositor_opengl.cc.

192 {
193 size_t texture_width = fl_framebuffer_get_width(framebuffer);
194 size_t texture_height = fl_framebuffer_get_height(framebuffer);
195 glUniform2f(self->offset_location, (2 * x / width) - 1.0,
196 (2 * y / width) - 1.0);
197 glUniform2f(self->scale_location, texture_width / width,
198 texture_height / height);
199
200 GLuint texture_id = fl_framebuffer_get_texture_id(framebuffer);
201 glBindTexture(GL_TEXTURE_2D, texture_id);
202
203 glDrawArrays(GL_TRIANGLES, 0, 6);
204}
int32_t x
size_t fl_framebuffer_get_height(FlFramebuffer *self)
size_t fl_framebuffer_get_width(FlFramebuffer *self)
GLuint fl_framebuffer_get_texture_id(FlFramebuffer *self)
double y
int32_t height
int32_t width
int64_t texture_id

References fl_framebuffer_get_height(), fl_framebuffer_get_texture_id(), fl_framebuffer_get_width(), height, self, texture_id, width, x, and y.

Referenced by fl_compositor_opengl_present_layers().

◆ fl_compositor_opengl_class_init()

static void fl_compositor_opengl_class_init ( FlCompositorOpenGLClass *  klass)
static

Definition at line 470 of file fl_compositor_opengl.cc.

470 {
471 FL_COMPOSITOR_CLASS(klass)->present_layers =
473 FL_COMPOSITOR_CLASS(klass)->get_frame_size =
475 FL_COMPOSITOR_CLASS(klass)->render = fl_compositor_opengl_render;
476
477 G_OBJECT_CLASS(klass)->dispose = fl_compositor_opengl_dispose;
478}
static void fl_compositor_opengl_dispose(GObject *object)
static gboolean fl_compositor_opengl_present_layers(FlCompositor *compositor, const FlutterLayer **layers, size_t layers_count)
static gboolean fl_compositor_opengl_render(FlCompositor *compositor, cairo_t *cr, GdkWindow *window, gboolean wait_for_frame)
static void fl_compositor_opengl_get_frame_size(FlCompositor *compositor, size_t *width, size_t *height)

References fl_compositor_opengl_dispose(), fl_compositor_opengl_get_frame_size(), fl_compositor_opengl_present_layers(), and fl_compositor_opengl_render().

◆ fl_compositor_opengl_dispose()

static void fl_compositor_opengl_dispose ( GObject *  object)
static

Definition at line 456 of file fl_compositor_opengl.cc.

456 {
457 FlCompositorOpenGL* self = FL_COMPOSITOR_OPENGL(object);
458
460
461 g_clear_object(&self->task_runner);
462 g_clear_object(&self->opengl_manager);
463 g_clear_object(&self->framebuffer);
464 g_clear_pointer(&self->pixels, g_free);
465 g_mutex_clear(&self->frame_mutex);
466
467 G_OBJECT_CLASS(fl_compositor_opengl_parent_class)->dispose(object);
468}
static void cleanup_shader(FlCompositorOpenGL *self)

References cleanup_shader(), and self.

Referenced by fl_compositor_opengl_class_init().

◆ fl_compositor_opengl_get_frame_size()

static void fl_compositor_opengl_get_frame_size ( FlCompositor *  compositor,
size_t *  width,
size_t *  height 
)
static

Definition at line 365 of file fl_compositor_opengl.cc.

367 {
368 FlCompositorOpenGL* self = FL_COMPOSITOR_OPENGL(compositor);
369
370 g_autoptr(GMutexLocker) locker = g_mutex_locker_new(&self->frame_mutex);
371
372 if (width != nullptr) {
373 *width = self->framebuffer != nullptr
374 ? fl_framebuffer_get_width(self->framebuffer)
375 : 0;
376 }
377 if (height != nullptr) {
378 *height = self->framebuffer != nullptr
379 ? fl_framebuffer_get_height(self->framebuffer)
380 : 0;
381 }
382}
g_autoptr(FlEngine) engine

References fl_framebuffer_get_height(), fl_framebuffer_get_width(), g_autoptr(), height, self, and width.

Referenced by fl_compositor_opengl_class_init().

◆ fl_compositor_opengl_init()

static void fl_compositor_opengl_init ( FlCompositorOpenGL *  self)
static

Definition at line 480 of file fl_compositor_opengl.cc.

480 {
481 g_mutex_init(&self->frame_mutex);
482}

References self.

◆ fl_compositor_opengl_new()

FlCompositorOpenGL * fl_compositor_opengl_new ( FlTaskRunner *  task_runner,
FlOpenGLManager *  opengl_manager,
gboolean  shareable 
)

Definition at line 484 of file fl_compositor_opengl.cc.

486 {
487 FlCompositorOpenGL* self = FL_COMPOSITOR_OPENGL(
488 g_object_new(fl_compositor_opengl_get_type(), nullptr));
489
490 self->task_runner = FL_TASK_RUNNER(g_object_ref(task_runner));
491 self->shareable = shareable;
492 self->opengl_manager = FL_OPENGL_MANAGER(g_object_ref(opengl_manager));
493
495
496 return self;
497}
static void setup_shader(FlCompositorOpenGL *self)
G_BEGIN_DECLS FlOpenGLManager gboolean shareable
G_BEGIN_DECLS FlOpenGLManager * opengl_manager

References opengl_manager, self, setup_shader(), and shareable.

Referenced by setup_opengl(), TEST(), TEST(), TEST(), TEST(), TEST(), TEST(), and TEST().

◆ fl_compositor_opengl_present_layers()

static gboolean fl_compositor_opengl_present_layers ( FlCompositor *  compositor,
const FlutterLayer **  layers,
size_t  layers_count 
)
static

Definition at line 206 of file fl_compositor_opengl.cc.

208 {
209 FlCompositorOpenGL* self = FL_COMPOSITOR_OPENGL(compositor);
210
211 g_mutex_lock(&self->frame_mutex);
212 if (layers_count == 0) {
213 g_mutex_unlock(&self->frame_mutex);
214 return TRUE;
215 }
216
217 GLint general_format = GL_RGBA;
218 if (epoxy_has_gl_extension("GL_EXT_texture_format_BGRA8888")) {
219 general_format = GL_BGRA_EXT;
220 }
221
222 // Save bindings that are set by this function. All bindings must be restored
223 // to their original values because Skia expects that its bindings have not
224 // been altered.
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);
239 GLint saved_src_rgb;
240 glGetIntegerv(GL_BLEND_SRC_RGB, &saved_src_rgb);
241 GLint saved_src_alpha;
242 glGetIntegerv(GL_BLEND_SRC_ALPHA, &saved_src_alpha);
243 GLint saved_dst_rgb;
244 glGetIntegerv(GL_BLEND_DST_RGB, &saved_dst_rgb);
245 GLint saved_dst_alpha;
246 glGetIntegerv(GL_BLEND_DST_ALPHA, &saved_dst_alpha);
247
248 // Update framebuffer to write into.
249 size_t width = layers[0]->size.width;
250 size_t height = layers[0]->size.height;
251 if (self->framebuffer == nullptr ||
252 fl_framebuffer_get_width(self->framebuffer) != width ||
253 fl_framebuffer_get_height(self->framebuffer) != height) {
254 g_clear_object(&self->framebuffer);
255 self->framebuffer =
256 fl_framebuffer_new(general_format, width, height, self->shareable);
257
258 // If not shareable make buffer to copy frame pixels into.
259 if (!self->shareable) {
260 size_t data_length = width * height * 4;
261 self->pixels =
262 static_cast<uint8_t*>(g_realloc(self->pixels, data_length));
263 }
264 }
265
266 self->had_first_frame = true;
267
268 // FIXME(robert-ancell): The vertex array is the same for all views, but
269 // cannot be shared in OpenGL. Find a way to not generate this every time.
270 GLuint vao;
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,
281 sizeof(GLfloat) * 4,
282 reinterpret_cast<void*>(sizeof(GLfloat) * 2));
283
284 glEnable(GL_BLEND);
285 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
286
287 glUseProgram(self->program);
288
289 // Disable the scissor test as it can affect blit operations.
290 // Prevents regressions like: https://github.com/flutter/flutter/issues/140828
291 // See OpenGL specification version 4.6, section 18.3.1.
292 glDisable(GL_SCISSOR_TEST);
293
294 glBindFramebuffer(GL_DRAW_FRAMEBUFFER,
295 fl_framebuffer_get_id(self->framebuffer));
296 gboolean first_layer = TRUE;
297 for (size_t i = 0; i < layers_count; ++i) {
298 const FlutterLayer* layer = layers[i];
299 switch (layer->type) {
301 const FlutterBackingStore* backing_store = layer->backing_store;
302 FlFramebuffer* framebuffer =
303 FL_FRAMEBUFFER(backing_store->open_gl.framebuffer.user_data);
304 glBindFramebuffer(GL_READ_FRAMEBUFFER,
305 fl_framebuffer_get_id(framebuffer));
306 // The first layer can be blitted, and following layers composited with
307 // this.
308 if (first_layer) {
309 glBlitFramebuffer(layer->offset.x, layer->offset.y, layer->size.width,
310 layer->size.height, layer->offset.x,
311 layer->offset.y, layer->size.width,
312 layer->size.height, GL_COLOR_BUFFER_BIT,
313 GL_NEAREST);
314 first_layer = FALSE;
315 } else {
316 composite_layer(self, framebuffer, layer->offset.x, layer->offset.y,
317 width, height);
318 }
319 } break;
321 // TODO(robert-ancell) Not implemented -
322 // https://github.com/flutter/flutter/issues/41724
323 } break;
324 }
325 }
326 glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
327 glFlush();
328
329 glDeleteVertexArrays(1, &vao);
330
331 if (saved_blend) {
332 glEnable(GL_BLEND);
333 } else {
334 glDisable(GL_BLEND);
335 }
336 if (saved_scissor_test) {
337 glEnable(GL_SCISSOR_TEST);
338 } else {
339 glDisable(GL_SCISSOR_TEST);
340 }
341
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,
348 saved_dst_alpha);
349
350 if (!self->shareable) {
351 glBindFramebuffer(GL_READ_FRAMEBUFFER,
352 fl_framebuffer_get_id(self->framebuffer));
353 glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, self->pixels);
354 glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
355 }
356 glBindFramebuffer(GL_READ_FRAMEBUFFER, saved_read_framebuffer_binding);
357
358 g_mutex_unlock(&self->frame_mutex);
359
360 fl_task_runner_stop_wait(self->task_runner);
361
362 return TRUE;
363}
@ kFlutterLayerContentTypePlatformView
Indicates that the contents of this layer are determined by the embedder.
Definition embedder.h:2142
@ kFlutterLayerContentTypeBackingStore
Definition embedder.h:2140
static void composite_layer(FlCompositorOpenGL *self, FlFramebuffer *framebuffer, double x, double y, int width, int height)
const FlutterLayer size_t layers_count
const FlutterLayer ** layers
return TRUE
fl_task_runner_stop_wait(self->task_runner)
FlFramebuffer * fl_framebuffer_new(GLint format, size_t width, size_t height, gboolean shareable)
GLuint fl_framebuffer_get_id(FlFramebuffer *self)
bool epoxy_has_gl_extension(const char *extension)
FlutterOpenGLBackingStore open_gl
The description of the OpenGL backing store.
Definition embedder.h:2115
FlutterPoint offset
Definition embedder.h:2183
FlutterLayerContentType type
Definition embedder.h:2172
const FlutterBackingStore * backing_store
Definition embedder.h:2176
FlutterSize size
The size of the layer (in physical pixels).
Definition embedder.h:2185
FlutterOpenGLFramebuffer framebuffer
Definition embedder.h:1958
void * user_data
User data to be returned on the invocation of the destruction callback.
Definition embedder.h:554
double height
Definition embedder.h:636
double width
Definition embedder.h:635

References FlutterLayer::backing_store, composite_layer(), epoxy_has_gl_extension(), fl_framebuffer_get_height(), fl_framebuffer_get_id(), fl_framebuffer_get_width(), fl_framebuffer_new(), fl_task_runner_stop_wait(), FlutterOpenGLBackingStore::framebuffer, height, FlutterSize::height, i, kFlutterLayerContentTypeBackingStore, kFlutterLayerContentTypePlatformView, layers, layers_count, FlutterLayer::offset, FlutterBackingStore::open_gl, self, FlutterLayer::size, TRUE, FlutterLayer::type, FlutterOpenGLFramebuffer::user_data, width, FlutterSize::width, FlutterPoint::x, and FlutterPoint::y.

Referenced by fl_compositor_opengl_class_init().

◆ fl_compositor_opengl_render()

static gboolean fl_compositor_opengl_render ( FlCompositor *  compositor,
cairo_t *  cr,
GdkWindow *  window,
gboolean  wait_for_frame 
)
static

Definition at line 384 of file fl_compositor_opengl.cc.

387 {
388 FlCompositorOpenGL* self = FL_COMPOSITOR_OPENGL(compositor);
389
390 g_mutex_lock(&self->frame_mutex);
391 if (self->framebuffer == nullptr) {
392 g_mutex_unlock(&self->frame_mutex);
393 return FALSE;
394 }
395
396 // If frame not ready, then wait for it.
397 gint scale_factor = gdk_window_get_scale_factor(window);
398 size_t width, height;
399 gint64 expiry_time =
400 g_get_monotonic_time() + kCompositorRenderTimeoutMicroseconds;
401 while (true) {
402 width = gdk_window_get_width(window) * scale_factor;
403 height = gdk_window_get_height(window) * scale_factor;
404 if (!wait_for_frame) {
405 break;
406 }
407
408 size_t framebuffer_width = fl_framebuffer_get_width(self->framebuffer);
409 size_t framebuffer_height = fl_framebuffer_get_height(self->framebuffer);
410 if (framebuffer_width == width && framebuffer_height == height) {
411 break;
412 }
413
414 if (g_get_monotonic_time() > expiry_time) {
415 g_warning(
416 "Timed out waiting for OpenGL frame of size %zdx%zd (have %zdx%zd)",
417 width, height, framebuffer_width, framebuffer_height);
418 break;
419 }
420
421 g_mutex_unlock(&self->frame_mutex);
422 fl_task_runner_wait(self->task_runner, expiry_time);
423 g_mutex_lock(&self->frame_mutex);
424 }
425
426 if (fl_framebuffer_get_shareable(self->framebuffer)) {
427 g_autoptr(FlFramebuffer) sibling =
430 GL_TEXTURE, scale_factor, 0, 0, width, height);
431 } else {
432 GLint saved_texture_binding;
433 glGetIntegerv(GL_TEXTURE_BINDING_2D, &saved_texture_binding);
434
435 GLuint texture_id;
436 glGenTextures(1, &texture_id);
437 glBindTexture(GL_TEXTURE_2D, texture_id);
438 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA,
439 GL_UNSIGNED_BYTE, self->pixels);
440
441 gdk_cairo_draw_from_gl(cr, window, texture_id, GL_TEXTURE, scale_factor, 0,
442 0, width, height);
443
444 glDeleteTextures(1, &texture_id);
445
446 glBindTexture(GL_TEXTURE_2D, saved_texture_binding);
447 }
448
449 glFlush();
450
451 g_mutex_unlock(&self->frame_mutex);
452
453 return TRUE;
454}
GLFWwindow * window
Definition main.cc:60
G_BEGIN_DECLS constexpr gint64 kCompositorRenderTimeoutMicroseconds
FlFramebuffer * fl_framebuffer_create_sibling(FlFramebuffer *self)
gboolean fl_framebuffer_get_shareable(FlFramebuffer *self)
void fl_task_runner_wait(FlTaskRunner *self, gint64 expiry_time)
void gdk_cairo_draw_from_gl(cairo_t *cr, GdkWindow *window, int source, int source_type, int buffer_scale, int x, int y, int width, int height)
Definition mock_gtk.cc:160
int gdk_window_get_width(GdkWindow *window)
Definition mock_gtk.cc:75
gint gdk_window_get_scale_factor(GdkWindow *window)
Definition mock_gtk.cc:85
int gdk_window_get_height(GdkWindow *window)
Definition mock_gtk.cc:80

References fl_framebuffer_create_sibling(), fl_framebuffer_get_height(), fl_framebuffer_get_shareable(), fl_framebuffer_get_texture_id(), fl_framebuffer_get_width(), fl_task_runner_wait(), g_autoptr(), gdk_cairo_draw_from_gl(), gdk_window_get_height(), gdk_window_get_scale_factor(), gdk_window_get_width(), height, kCompositorRenderTimeoutMicroseconds, self, texture_id, TRUE, width, and window.

Referenced by fl_compositor_opengl_class_init().

◆ G_DEFINE_TYPE()

G_DEFINE_TYPE ( FlCompositorOpenGL  ,
fl_compositor_opengl  ,
fl_compositor_get_type()   
)

Definition at line 82 of file fl_compositor_opengl.cc.

87 {
88 GLint log_length;
89 gchar* log;
90
91 glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &log_length);
92
93 log = static_cast<gchar*>(g_malloc(log_length + 1));
94 glGetShaderInfoLog(shader, log_length, nullptr, log);
95
96 return log;
97}

◆ get_program_log()

static gchar * get_program_log ( GLuint  program)
static

Definition at line 100 of file fl_compositor_opengl.cc.

100 {
101 GLint log_length;
102 gchar* log;
103
104 glGetProgramiv(program, GL_INFO_LOG_LENGTH, &log_length);
105
106 log = static_cast<gchar*>(g_malloc(log_length + 1));
107 glGetProgramInfoLog(program, log_length, nullptr, log);
108
109 return log;
110}

Referenced by setup_shader().

◆ setup_shader()

static void setup_shader ( FlCompositorOpenGL *  self)
static

Definition at line 112 of file fl_compositor_opengl.cc.

112 {
113 if (!fl_opengl_manager_make_platform_current(self->opengl_manager)) {
114 g_warning(
115 "Failed to setup compositor shaders, unable to make OpenGL context "
116 "current");
117 return;
118 }
119
120 GLuint vertex_shader = glCreateShader(GL_VERTEX_SHADER);
121 glShaderSource(vertex_shader, 1, &vertex_shader_src, nullptr);
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);
128 }
129
130 GLuint fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
131 glShaderSource(fragment_shader, 1, &fragment_shader_src, nullptr);
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);
138 }
139
140 self->program = glCreateProgram();
141 glAttachShader(self->program, vertex_shader);
142 glAttachShader(self->program, fragment_shader);
143 glLinkProgram(self->program);
144
145 GLint link_status;
146 glGetProgramiv(self->program, GL_LINK_STATUS, &link_status);
147 if (link_status == GL_FALSE) {
148 g_autofree gchar* program_log = get_program_log(self->program);
149 g_warning("Failed to link program: %s", program_log);
150 }
151
152 self->offset_location = glGetUniformLocation(self->program, "offset");
153 self->scale_location = glGetUniformLocation(self->program, "scale");
154
155 glDeleteShader(vertex_shader);
156 glDeleteShader(fragment_shader);
157
158 // The uniform square abcd in two triangles cba + cdb
159 // a--b
160 // | |
161 // c--d
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};
164
165 glGenBuffers(1, &self->vertex_buffer);
166 glBindBuffer(GL_ARRAY_BUFFER, self->vertex_buffer);
167 glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data), vertex_data,
168 GL_STATIC_DRAW);
169}
static const char * fragment_shader_src
static gchar * get_program_log(GLuint program)
static const char * vertex_shader_src

References fl_opengl_manager_make_platform_current(), fragment_shader_src, get_program_log(), self, and vertex_shader_src.

Referenced by fl_compositor_opengl_new().

Variable Documentation

◆ fragment_shader_src

const char* fragment_shader_src
static
Initial value:
=
"#ifdef GL_ES\n"
"precision mediump float;\n"
"#endif\n"
"\n"
"uniform sampler2D texture;\n"
"varying vec2 texcoord;\n"
"\n"
"void main() {\n"
" gl_FragColor = texture2D(texture, texcoord);\n"
"}\n"

Definition at line 29 of file fl_compositor_opengl.cc.

Referenced by setup_shader().

◆ vertex_shader_src

const char* vertex_shader_src
static
Initial value:
=
"attribute vec2 position;\n"
"attribute vec2 in_texcoord;\n"
"uniform vec2 offset;\n"
"uniform vec2 scale;\n"
"varying vec2 texcoord;\n"
"\n"
"void main() {\n"
" gl_Position = vec4(offset + position * scale, 0, 1);\n"
" texcoord = in_texcoord;\n"
"}\n"

Definition at line 16 of file fl_compositor_opengl.cc.

Referenced by setup_shader().