Flutter Engine Uber Docs
Docs for the entire Flutter Engine repo.
 
Loading...
Searching...
No Matches
fl_framebuffer.cc
Go to the documentation of this file.
1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "fl_framebuffer.h"
6
7#include <epoxy/egl.h>
8#include <epoxy/gl.h>
9
11
14
15 // Width of framebuffer in pixels.
16 size_t width;
17
18 // Height of framebuffer in pixels.
19 size_t height;
20
21 // Framebuffer ID.
23
24 // Texture backing framebuffer.
25 GLuint texture_id;
26
27 // Stencil buffer associated with this framebuffer.
29
30 // EGL image for this texture.
31 FlEGLImage* image;
32};
33
34G_DEFINE_TYPE(FlFramebuffer, fl_framebuffer, G_TYPE_OBJECT)
35
36static void fl_framebuffer_dispose(GObject* object) {
37 FlFramebuffer* self = FL_FRAMEBUFFER(object);
38
39 glDeleteFramebuffers(1, &self->framebuffer_id);
40 glDeleteTextures(1, &self->texture_id);
41 glDeleteRenderbuffers(1, &self->depth_stencil);
42 g_clear_object(&self->image);
43
44 G_OBJECT_CLASS(fl_framebuffer_parent_class)->dispose(object);
45}
46
47static void fl_framebuffer_class_init(FlFramebufferClass* klass) {
48 G_OBJECT_CLASS(klass)->dispose = fl_framebuffer_dispose;
49}
50
51static void fl_framebuffer_init(FlFramebuffer* self) {}
52
53FlFramebuffer* fl_framebuffer_new(GLint format,
54 size_t width,
55 size_t height,
56 gboolean shareable) {
57 FlFramebuffer* self =
58 FL_FRAMEBUFFER(g_object_new(fl_framebuffer_get_type(), nullptr));
59
60 self->width = width;
61 self->height = height;
62
63 glGenTextures(1, &self->texture_id);
64 glGenFramebuffers(1, &self->framebuffer_id);
65
66 glBindFramebuffer(GL_FRAMEBUFFER, self->framebuffer_id);
67
68 glBindTexture(GL_TEXTURE_2D, self->texture_id);
69 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
70 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
71 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
72 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
73 glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format,
74 GL_UNSIGNED_BYTE, NULL);
75 glBindTexture(GL_TEXTURE_2D, 0);
76
77 if (shareable) {
78 self->image = fl_egl_image_new(self->texture_id);
79 }
80
81 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
82 self->texture_id, 0);
83
84 glGenRenderbuffers(1, &self->depth_stencil);
85 glBindRenderbuffer(GL_RENDERBUFFER, self->depth_stencil);
86 glRenderbufferStorage(GL_RENDERBUFFER, // target
87 GL_DEPTH24_STENCIL8, // internal format
88 width, // width
89 height // height
90 );
91 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
92 GL_RENDERBUFFER, self->depth_stencil);
93 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
94 GL_RENDERBUFFER, self->depth_stencil);
95
96 return self;
97}
98
99gboolean fl_framebuffer_get_shareable(FlFramebuffer* self) {
100 g_return_val_if_fail(FL_IS_FRAMEBUFFER(self), FALSE);
101 return self->image != nullptr;
102}
103
104FlFramebuffer* fl_framebuffer_create_sibling(FlFramebuffer* self) {
105 g_return_val_if_fail(FL_IS_FRAMEBUFFER(self), nullptr);
106 g_return_val_if_fail(self->image != nullptr, nullptr);
107
108 FlFramebuffer* sibling =
109 FL_FRAMEBUFFER(g_object_new(fl_framebuffer_get_type(), nullptr));
110
111 sibling->width = self->width;
112 sibling->height = self->height;
113 sibling->image = FL_EGL_IMAGE(g_object_ref(self->image));
114
115 // Make texture from existing image.
116 glGenTextures(1, &sibling->texture_id);
117 glBindTexture(GL_TEXTURE_2D, sibling->texture_id);
118 glEGLImageTargetTexture2DOES(GL_TEXTURE_2D,
120
121 // Make framebuffer that uses this texture.
122 glGenFramebuffers(1, &sibling->framebuffer_id);
123 GLint saved_framebuffer_binding;
124 glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &saved_framebuffer_binding);
125 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, sibling->framebuffer_id);
126 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
127 sibling->texture_id, 0);
128 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, saved_framebuffer_binding);
129
130 return sibling;
131}
132
133GLuint fl_framebuffer_get_id(FlFramebuffer* self) {
134 return self->framebuffer_id;
135}
136
137GLuint fl_framebuffer_get_texture_id(FlFramebuffer* self) {
138 return self->texture_id;
139}
140
141size_t fl_framebuffer_get_width(FlFramebuffer* self) {
142 return self->width;
143}
144
145size_t fl_framebuffer_get_height(FlFramebuffer* self) {
146 return self->height;
147}
G_DEFINE_TYPE(FlBasicMessageChannelResponseHandle, fl_basic_message_channel_response_handle, G_TYPE_OBJECT) static void fl_basic_message_channel_response_handle_dispose(GObject *object)
G_BEGIN_DECLS FlOpenGLManager gboolean shareable
FlEGLImage * fl_egl_image_new(GLuint texture)
EGLImage fl_egl_image_get_image(FlEGLImage *image)
size_t fl_framebuffer_get_height(FlFramebuffer *self)
FlFramebuffer * fl_framebuffer_new(GLint format, size_t width, size_t height, gboolean shareable)
static void fl_framebuffer_init(FlFramebuffer *self)
GLuint fl_framebuffer_get_id(FlFramebuffer *self)
static void fl_framebuffer_class_init(FlFramebufferClass *klass)
static void fl_framebuffer_dispose(GObject *object)
FlFramebuffer * fl_framebuffer_create_sibling(FlFramebuffer *self)
gboolean fl_framebuffer_get_shareable(FlFramebuffer *self)
size_t fl_framebuffer_get_width(FlFramebuffer *self)
GLuint fl_framebuffer_get_texture_id(FlFramebuffer *self)
uint32_t uint32_t * format
int32_t height
int32_t width
GObject parent_instance
FlEGLImage * image