blob: 4bb078807bc9ca3b91fb3fcee7c3aaa3caeb220d [file] [log] [blame]
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef FLUTTER_IMPELLER_TOOLKIT_GLVK_TRAMPOLINE_H_
#define FLUTTER_IMPELLER_TOOLKIT_GLVK_TRAMPOLINE_H_
#include "impeller/base/thread_safety.h"
#include "impeller/renderer/backend/vulkan/android/ahb_texture_source_vk.h"
#include "impeller/toolkit/egl/context.h"
#include "impeller/toolkit/egl/display.h"
#include "impeller/toolkit/egl/surface.h"
#include "impeller/toolkit/glvk/proc_table.h"
namespace impeller::glvk {
class AutoTrampolineContext;
//------------------------------------------------------------------------------
/// @brief An object used to interoperate between OpenGL and Vulkan.
///
/// While these are not super expensive to create, they do manage an
/// internal EGL context as well as some OpenGL state. For this
/// reason, it is recommended that callers cache these for the
/// duration of the lifecycle of main rendering context.
///
class Trampoline {
public:
//----------------------------------------------------------------------------
/// @brief Constructs a new trampoline. It is recommended that these
/// objects be cached and reused for all conversion operations.
///
/// EGL contexts on already bound to the callers thread may become
/// unbound after a call to this method.
///
Trampoline();
//----------------------------------------------------------------------------
/// @brief Destroys the trampoline. There are no threading restrictions.
/// EGL contexts on already bound to the callers thread may become
/// unbound after a call to this method.
///
~Trampoline();
Trampoline(const Trampoline&) = delete;
Trampoline& operator=(const Trampoline&) = delete;
//----------------------------------------------------------------------------
/// @brief Determines if this is a valid trampoline. There is no error
/// recovery mechanism if a trampoline cannot be constructed and
/// an invalid trampoline must be immediately discarded.
///
/// @return True if valid, False otherwise.
///
bool IsValid() const;
//----------------------------------------------------------------------------
/// @brief Describes an OpenGL texture along with information on how to
/// sample from it.
///
struct GLTextureInfo {
//--------------------------------------------------------------------------
/// The OpenGL texture handle.
///
GLuint texture = 0;
//--------------------------------------------------------------------------
/// The OpenGL texture target enum. For instance, GL_TEXTURE_2D or
/// GL_TEXTURE_EXTERNAL_OES.
///
GLenum target = 0;
//--------------------------------------------------------------------------
/// A transformation applied to the texture coordinates in the form of (u,
/// v, 0, 1) when sampling from the texture.
///
Matrix uv_transformation;
};
//----------------------------------------------------------------------------
/// @brief Perform a blit operation from the source OpenGL texture to a
/// target Vulkan texture.
///
/// It is the callers responsibility to ensure that the EGL
/// context associated with the trampoline is already current
/// before making this call.
///
/// It is also the responsibility of the caller to ensure that the
/// destination texture is the color-attachment-optimal layout.
/// Failure to ensure this will lead to validation error.
///
/// @see `MakeCurrentContext`
///
/// @param[in] src_texture The source OpenGL texture.
/// @param[in] dst_texture The destination Vulkan texture.
///
/// @return True if the blit was successful, False otherwise.
///
bool BlitTextureOpenGLToVulkan(const GLTextureInfo& src_texture,
const AHBTextureSourceVK& dst_texture) const;
//----------------------------------------------------------------------------
/// @brief Make the EGL context associated with this trampoline current
/// on the calling thread.
///
/// @return The automatic trampoline context. The collection of this
/// context clears the threads EGL binding.
///
[[nodiscard]] AutoTrampolineContext MakeCurrentContext() const;
private:
friend class AutoTrampolineContext;
std::unique_ptr<egl::Display> egl_display_;
std::unique_ptr<egl::Context> egl_context_;
std::unique_ptr<egl::Surface> egl_surface_;
std::unique_ptr<ProcTable> gl_;
GLuint program_ = GL_NONE;
GLint texture_uniform_location_ = 0;
GLint uv_transformation_location_ = 0;
bool is_valid_ = false;
};
//------------------------------------------------------------------------------
/// @brief An RAII object that makes the trampolines EGL context current
/// when constructed and clears the EGL binding on destruction.
///
class AutoTrampolineContext final {
public:
//----------------------------------------------------------------------------
/// @brief Constructs a new instance and makes the trampolines EGL
/// context current on the calling thread.
///
/// @param[in] trampoline The trampoline.
///
explicit AutoTrampolineContext(const Trampoline& trampoline);
//----------------------------------------------------------------------------
/// @brief Destroys the object and clears the previous EGL binding.
///
~AutoTrampolineContext();
AutoTrampolineContext(const AutoTrampolineContext&) = delete;
AutoTrampolineContext& operator=(const AutoTrampolineContext&) = delete;
private:
const egl::Context* context_ = nullptr;
const egl::Surface* surface_ = nullptr;
};
} // namespace impeller::glvk
#endif // FLUTTER_IMPELLER_TOOLKIT_GLVK_TRAMPOLINE_H_