9 #include "flutter/fml/closure.h"
10 #include "flutter/fml/trace_event.h"
23 static constexpr
const char*
kVertShader = R
"IMPELLER_SHADER(#version 100
25 precision mediump float;
27 attribute vec2 aPosition;
28 attribute vec2 aTexCoord;
30 varying vec2 vTexCoord;
33 gl_Position = vec4(aPosition, 0.0, 1.0);
34 vTexCoord = aTexCoord;
39 static constexpr
const char*
kFragShader = R
"IMPELLER_SHADER(#version 100
41 #extension GL_OES_EGL_image_external : require
43 precision mediump float;
45 uniform samplerExternalOES uTexture;
46 uniform mat4 uUVTransformation;
48 varying vec2 vTexCoord;
51 vec2 texture_coords = (uUVTransformation * vec4(vTexCoord, 0, 1)).xy;
52 gl_FragColor = texture2D(uTexture, texture_coords);
58 auto egl_display = std::make_unique<egl::Display>();
59 if (!egl_display->IsValid()) {
61 <<
"Could not create EGL display for external texture interop.";
72 auto egl_config = egl_display->ChooseConfig(egl_config_desc);
75 <<
"Could not choose EGL config for external texture interop.";
79 auto egl_surface = egl_display->CreatePixelBufferSurface(*egl_config, 1u, 1u);
80 auto egl_context = egl_display->CreateContext(*egl_config,
nullptr);
82 if (!egl_surface || !egl_context) {
83 VALIDATION_LOG <<
"Could not create EGL surface and/or context for "
84 "external texture interop.";
89 if (!egl_context->MakeCurrent(*egl_surface)) {
97 egl_context->ClearCurrent();
103 auto vert_shader = gl->CreateShader(GL_VERTEX_SHADER);
104 auto frag_shader = gl->CreateShader(GL_FRAGMENT_SHADER);
109 gl->ShaderSource(vert_shader, 1u, &
kVertShader, &vert_shader_size);
110 gl->ShaderSource(frag_shader, 1u, &
kFragShader, &frag_shader_size);
112 gl->CompileShader(vert_shader);
113 gl->CompileShader(frag_shader);
115 GLint vert_status = GL_FALSE;
116 GLint frag_status = GL_FALSE;
118 gl->GetShaderiv(vert_shader, GL_COMPILE_STATUS, &vert_status);
119 gl->GetShaderiv(frag_shader, GL_COMPILE_STATUS, &frag_status);
121 FML_CHECK(vert_status == GL_TRUE);
122 FML_CHECK(frag_status == GL_TRUE);
124 program_ = gl->CreateProgram();
125 gl->AttachShader(program_, vert_shader);
126 gl->AttachShader(program_, frag_shader);
131 gl->LinkProgram(program_);
133 GLint link_status = GL_FALSE;
134 gl->GetProgramiv(program_, GL_LINK_STATUS, &link_status);
135 FML_CHECK(link_status == GL_TRUE);
137 texture_uniform_location_ = gl->GetUniformLocation(program_,
"uTexture");
138 uv_transformation_location_ =
139 gl->GetUniformLocation(program_,
"uUVTransformation");
141 gl->DeleteShader(vert_shader);
142 gl->DeleteShader(frag_shader);
144 egl_context->ClearCurrent();
147 egl_display_ = std::move(egl_display);
148 egl_context_ = std::move(egl_context);
149 egl_surface_ = std::move(egl_surface);
158 gl_->DeleteProgram(program_);
166 const EGLDisplay& display,
173 EGLClientBuffer client_buffer =
177 if (!client_buffer) {
179 <<
"Could not get client buffer from Android hardware buffer.";
183 auto image = ::eglCreateImageKHR(display,
185 EGL_NATIVE_BUFFER_ANDROID,
200 TRACE_EVENT0(
"impeller", __FUNCTION__);
205 FML_DCHECK(egl_context_->IsCurrent());
209 if (!dst_egl_image.is_valid()) {
214 const auto& gl = *gl_;
216 GLuint dst_gl_texture = GL_NONE;
217 gl.GenTextures(1u, &dst_gl_texture);
218 gl.BindTexture(GL_TEXTURE_2D, dst_gl_texture);
219 gl.EGLImageTargetTexture2DOES(GL_TEXTURE_2D, dst_egl_image.get().image);
221 GLuint offscreen_fbo = GL_NONE;
222 gl.GenFramebuffers(1u, &offscreen_fbo);
223 gl.BindFramebuffer(GL_FRAMEBUFFER, offscreen_fbo);
224 gl.FramebufferTexture2D(GL_FRAMEBUFFER,
225 GL_COLOR_ATTACHMENT0,
231 FML_CHECK(gl.CheckFramebufferStatus(GL_FRAMEBUFFER) ==
232 GL_FRAMEBUFFER_COMPLETE);
234 gl.Disable(GL_BLEND);
235 gl.Disable(GL_SCISSOR_TEST);
236 gl.Disable(GL_DITHER);
237 gl.Disable(GL_CULL_FACE);
238 gl.ColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
240 gl.ClearColor(0.0f, 0.0f, 0.0f, 1.0f);
241 gl.Clear(GL_COLOR_BUFFER_BIT);
244 gl.Viewport(0, 0, fb_size.width, fb_size.height);
246 gl.UseProgram(program_);
260 static constexpr
const VertexData kVertData[] = {
269 GLuint vertex_buffer = GL_NONE;
270 gl.GenBuffers(1u, &vertex_buffer);
271 gl.BindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
272 gl.BufferData(GL_ARRAY_BUFFER,
sizeof(kVertData), kVertData, GL_STATIC_DRAW);
277 (
void*)offsetof(VertexData, position));
280 (
void*)offsetof(VertexData, tex_coord));
282 gl.ActiveTexture(GL_TEXTURE0);
284 gl.TexParameteri(src_texture.
target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
285 gl.TexParameteri(src_texture.
target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
286 gl.TexParameteri(src_texture.
target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
287 gl.TexParameteri(src_texture.
target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
288 gl.Uniform1i(texture_uniform_location_, 0u);
292 gl.UniformMatrix4fv(uv_transformation_location_, 1u, GL_FALSE,
293 reinterpret_cast<GLfloat*
>(&gl_uv_transformation));
295 gl.DrawArrays(GL_TRIANGLE_FAN, 0, 4);
297 gl.UseProgram(GL_NONE);
301 gl.DeleteFramebuffers(1u, &offscreen_fbo);
302 gl.DeleteTextures(1u, &dst_gl_texture);
303 gl.DeleteBuffers(1u, &vertex_buffer);
308 eglSwapBuffers(egl_display_->GetHandle(), egl_surface_->GetHandle());
314 FML_DCHECK(is_valid_);
319 : context_(trampoline.egl_context_.get()),
320 surface_(trampoline.egl_surface_.get()) {