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);
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);
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);
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);
275 gl.VertexAttribPointer(
277 reinterpret_cast<void*
>(offsetof(VertexData, position)));
278 gl.VertexAttribPointer(
280 reinterpret_cast<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());
A texture source that wraps an instance of AHardwareBuffer.
const android::HardwareBuffer * GetBackingStore() const
const TextureDescriptor & GetTextureDescriptor() const
Gets the texture descriptor for this image source.
bool MakeCurrent(const Surface &surface) const
Make the context current on the calling thread. It is the caller responsibility to ensure that any co...
bool ClearCurrent() const
Clear the thread association of this context.
An RAII object that makes the trampolines EGL context current when constructed and clears the EGL bin...
~AutoTrampolineContext()
Destroys the object and clears the previous EGL binding.
AutoTrampolineContext(const Trampoline &trampoline)
Constructs a new instance and makes the trampolines EGL context current on the calling thread.
Describes an OpenGL texture along with information on how to sample from it.