/*
 *  Copyright 2021 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "modules/desktop_capture/linux/wayland/egl_dmabuf.h"

#include <asm/ioctl.h>
#include <dlfcn.h>
#include <fcntl.h>
#include <libdrm/drm_fourcc.h>
#include <linux/types.h>
#include <spa/param/video/format-utils.h>
#include <unistd.h>
#include <xf86drm.h>

#include "absl/memory/memory.h"
#include "absl/types/optional.h"
#include "rtc_base/checks.h"
#include "rtc_base/logging.h"
#include "rtc_base/sanitizer.h"
#include "rtc_base/string_encode.h"

namespace webrtc {

// EGL
typedef EGLBoolean (*eglBindAPI_func)(EGLenum api);
typedef EGLContext (*eglCreateContext_func)(EGLDisplay dpy,
                                            EGLConfig config,
                                            EGLContext share_context,
                                            const EGLint* attrib_list);
typedef EGLBoolean (*eglDestroyContext_func)(EGLDisplay display,
                                             EGLContext context);
typedef EGLBoolean (*eglTerminate_func)(EGLDisplay display);
typedef EGLImageKHR (*eglCreateImageKHR_func)(EGLDisplay dpy,
                                              EGLContext ctx,
                                              EGLenum target,
                                              EGLClientBuffer buffer,
                                              const EGLint* attrib_list);
typedef EGLBoolean (*eglDestroyImageKHR_func)(EGLDisplay dpy,
                                              EGLImageKHR image);
typedef EGLint (*eglGetError_func)(void);
typedef void* (*eglGetProcAddress_func)(const char*);
typedef EGLDisplay (*eglGetPlatformDisplayEXT_func)(EGLenum platform,
                                                    void* native_display,
                                                    const EGLint* attrib_list);
typedef EGLDisplay (*eglGetPlatformDisplay_func)(EGLenum platform,
                                                 void* native_display,
                                                 const EGLAttrib* attrib_list);

typedef EGLBoolean (*eglInitialize_func)(EGLDisplay dpy,
                                         EGLint* major,
                                         EGLint* minor);
typedef EGLBoolean (*eglMakeCurrent_func)(EGLDisplay dpy,
                                          EGLSurface draw,
                                          EGLSurface read,
                                          EGLContext ctx);
typedef EGLBoolean (*eglQueryDmaBufFormatsEXT_func)(EGLDisplay dpy,
                                                    EGLint max_formats,
                                                    EGLint* formats,
                                                    EGLint* num_formats);
typedef EGLBoolean (*eglQueryDmaBufModifiersEXT_func)(EGLDisplay dpy,
                                                      EGLint format,
                                                      EGLint max_modifiers,
                                                      EGLuint64KHR* modifiers,
                                                      EGLBoolean* external_only,
                                                      EGLint* num_modifiers);
typedef const char* (*eglQueryString_func)(EGLDisplay dpy, EGLint name);
typedef void (*glEGLImageTargetTexture2DOES_func)(GLenum target,
                                                  GLeglImageOES image);

// This doesn't follow naming conventions in WebRTC, where the naming
// should look like e.g. egl_bind_api instead of EglBindAPI, however
// we named them according to the exported functions they map to for
// consistency.
eglBindAPI_func EglBindAPI = nullptr;
eglCreateContext_func EglCreateContext = nullptr;
eglDestroyContext_func EglDestroyContext = nullptr;
eglTerminate_func EglTerminate = nullptr;
eglCreateImageKHR_func EglCreateImageKHR = nullptr;
eglDestroyImageKHR_func EglDestroyImageKHR = nullptr;
eglGetError_func EglGetError = nullptr;
eglGetProcAddress_func EglGetProcAddress = nullptr;
eglGetPlatformDisplayEXT_func EglGetPlatformDisplayEXT = nullptr;
eglGetPlatformDisplay_func EglGetPlatformDisplay = nullptr;
eglInitialize_func EglInitialize = nullptr;
eglMakeCurrent_func EglMakeCurrent = nullptr;
eglQueryDmaBufFormatsEXT_func EglQueryDmaBufFormatsEXT = nullptr;
eglQueryDmaBufModifiersEXT_func EglQueryDmaBufModifiersEXT = nullptr;
eglQueryString_func EglQueryString = nullptr;
glEGLImageTargetTexture2DOES_func GlEGLImageTargetTexture2DOES = nullptr;

// GL
typedef void (*glBindTexture_func)(GLenum target, GLuint texture);
typedef void (*glDeleteTextures_func)(GLsizei n, const GLuint* textures);
typedef void (*glGenTextures_func)(GLsizei n, GLuint* textures);
typedef GLenum (*glGetError_func)(void);
typedef const GLubyte* (*glGetString_func)(GLenum name);
typedef void (*glGetTexImage_func)(GLenum target,
                                   GLint level,
                                   GLenum format,
                                   GLenum type,
                                   void* pixels);
typedef void (*glTexParameteri_func)(GLenum target, GLenum pname, GLint param);
typedef void* (*glXGetProcAddressARB_func)(const char*);

// This doesn't follow naming conventions in WebRTC, where the naming
// should look like e.g. egl_bind_api instead of EglBindAPI, however
// we named them according to the exported functions they map to for
// consistency.
glBindTexture_func GlBindTexture = nullptr;
glDeleteTextures_func GlDeleteTextures = nullptr;
glGenTextures_func GlGenTextures = nullptr;
glGetError_func GlGetError = nullptr;
glGetString_func GlGetString = nullptr;
glGetTexImage_func GlGetTexImage = nullptr;
glTexParameteri_func GlTexParameteri = nullptr;
glXGetProcAddressARB_func GlXGetProcAddressARB = nullptr;

static const std::string FormatGLError(GLenum err) {
  switch (err) {
    case GL_NO_ERROR:
      return "GL_NO_ERROR";
    case GL_INVALID_ENUM:
      return "GL_INVALID_ENUM";
    case GL_INVALID_VALUE:
      return "GL_INVALID_VALUE";
    case GL_INVALID_OPERATION:
      return "GL_INVALID_OPERATION";
    case GL_STACK_OVERFLOW:
      return "GL_STACK_OVERFLOW";
    case GL_STACK_UNDERFLOW:
      return "GL_STACK_UNDERFLOW";
    case GL_OUT_OF_MEMORY:
      return "GL_OUT_OF_MEMORY";
    default:
      return "GL error code: " + std::to_string(err);
  }
}

static const std::string FormatEGLError(EGLint err) {
  switch (err) {
    case EGL_NOT_INITIALIZED:
      return "EGL_NOT_INITIALIZED";
    case EGL_BAD_ACCESS:
      return "EGL_BAD_ACCESS";
    case EGL_BAD_ALLOC:
      return "EGL_BAD_ALLOC";
    case EGL_BAD_ATTRIBUTE:
      return "EGL_BAD_ATTRIBUTE";
    case EGL_BAD_CONTEXT:
      return "EGL_BAD_CONTEXT";
    case EGL_BAD_CONFIG:
      return "EGL_BAD_CONFIG";
    case EGL_BAD_CURRENT_SURFACE:
      return "EGL_BAD_CURRENT_SURFACE";
    case EGL_BAD_DISPLAY:
      return "EGL_BAD_DISPLAY";
    case EGL_BAD_SURFACE:
      return "EGL_BAD_SURFACE";
    case EGL_BAD_MATCH:
      return "EGL_BAD_MATCH";
    case EGL_BAD_PARAMETER:
      return "EGL_BAD_PARAMETER";
    case EGL_BAD_NATIVE_PIXMAP:
      return "EGL_BAD_NATIVE_PIXMAP";
    case EGL_BAD_NATIVE_WINDOW:
      return "EGL_BAD_NATIVE_WINDOW";
    case EGL_CONTEXT_LOST:
      return "EGL_CONTEXT_LOST";
    default:
      return "EGL error code: " + std::to_string(err);
  }
}

static uint32_t SpaPixelFormatToDrmFormat(uint32_t spa_format) {
  switch (spa_format) {
    case SPA_VIDEO_FORMAT_RGBA:
      return DRM_FORMAT_ABGR8888;
    case SPA_VIDEO_FORMAT_RGBx:
      return DRM_FORMAT_XBGR8888;
    case SPA_VIDEO_FORMAT_BGRA:
      return DRM_FORMAT_ARGB8888;
    case SPA_VIDEO_FORMAT_BGRx:
      return DRM_FORMAT_XRGB8888;
    default:
      return DRM_FORMAT_INVALID;
  }
}

static void CloseLibrary(void* library) {
  if (library) {
    dlclose(library);
    library = nullptr;
  }
}

static void* g_lib_egl = nullptr;

RTC_NO_SANITIZE("cfi-icall")
static bool OpenEGL() {
  g_lib_egl = dlopen("libEGL.so.1", RTLD_NOW | RTLD_GLOBAL);
  if (g_lib_egl) {
    EglGetProcAddress =
        (eglGetProcAddress_func)dlsym(g_lib_egl, "eglGetProcAddress");
    return EglGetProcAddress;
  }

  return false;
}

RTC_NO_SANITIZE("cfi-icall")
static bool LoadEGL() {
  if (OpenEGL()) {
    EglBindAPI = (eglBindAPI_func)EglGetProcAddress("eglBindAPI");
    EglCreateContext =
        (eglCreateContext_func)EglGetProcAddress("eglCreateContext");
    EglDestroyContext =
        (eglDestroyContext_func)EglGetProcAddress("eglDestroyContext");
    EglTerminate = (eglTerminate_func)EglGetProcAddress("eglTerminate");
    EglCreateImageKHR =
        (eglCreateImageKHR_func)EglGetProcAddress("eglCreateImageKHR");
    EglDestroyImageKHR =
        (eglDestroyImageKHR_func)EglGetProcAddress("eglDestroyImageKHR");
    EglGetError = (eglGetError_func)EglGetProcAddress("eglGetError");
    EglGetPlatformDisplayEXT = (eglGetPlatformDisplayEXT_func)EglGetProcAddress(
        "eglGetPlatformDisplayEXT");
    EglGetPlatformDisplay =
        (eglGetPlatformDisplay_func)EglGetProcAddress("eglGetPlatformDisplay");
    EglInitialize = (eglInitialize_func)EglGetProcAddress("eglInitialize");
    EglMakeCurrent = (eglMakeCurrent_func)EglGetProcAddress("eglMakeCurrent");
    EglQueryString = (eglQueryString_func)EglGetProcAddress("eglQueryString");
    GlEGLImageTargetTexture2DOES =
        (glEGLImageTargetTexture2DOES_func)EglGetProcAddress(
            "glEGLImageTargetTexture2DOES");

    return EglBindAPI && EglCreateContext && EglCreateImageKHR &&
           EglTerminate && EglDestroyContext && EglDestroyImageKHR &&
           EglGetError && EglGetPlatformDisplayEXT && EglGetPlatformDisplay &&
           EglInitialize && EglMakeCurrent && EglQueryString &&
           GlEGLImageTargetTexture2DOES;
  }

  return false;
}

static void* g_lib_gl = nullptr;

RTC_NO_SANITIZE("cfi-icall")
static bool OpenGL() {
  std::vector<std::string> names = {"libGL.so.1", "libGL.so"};
  for (const std::string& name : names) {
    g_lib_gl = dlopen(name.c_str(), RTLD_NOW | RTLD_GLOBAL);
    if (g_lib_gl) {
      GlXGetProcAddressARB =
          (glXGetProcAddressARB_func)dlsym(g_lib_gl, "glXGetProcAddressARB");
      return GlXGetProcAddressARB;
    }
  }

  return false;
}

RTC_NO_SANITIZE("cfi-icall")
static bool LoadGL() {
  if (OpenGL()) {
    GlGetString = (glGetString_func)GlXGetProcAddressARB("glGetString");
    if (!GlGetString) {
      return false;
    }

    GlBindTexture = (glBindTexture_func)GlXGetProcAddressARB("glBindTexture");
    GlDeleteTextures =
        (glDeleteTextures_func)GlXGetProcAddressARB("glDeleteTextures");
    GlGenTextures = (glGenTextures_func)GlXGetProcAddressARB("glGenTextures");
    GlGetError = (glGetError_func)GlXGetProcAddressARB("glGetError");
    GlGetTexImage = (glGetTexImage_func)GlXGetProcAddressARB("glGetTexImage");
    GlTexParameteri =
        (glTexParameteri_func)GlXGetProcAddressARB("glTexParameteri");

    return GlBindTexture && GlDeleteTextures && GlGenTextures && GlGetError &&
           GlGetTexImage && GlTexParameteri;
  }

  return false;
}

RTC_NO_SANITIZE("cfi-icall")
EglDmaBuf::EglDmaBuf() {
  if (!LoadEGL()) {
    RTC_LOG(LS_ERROR) << "Unable to load EGL entry functions.";
    CloseLibrary(g_lib_egl);
    return;
  }

  if (!LoadGL()) {
    RTC_LOG(LS_ERROR) << "Failed to load OpenGL entry functions.";
    CloseLibrary(g_lib_gl);
    return;
  }

  if (!GetClientExtensions(EGL_NO_DISPLAY, EGL_EXTENSIONS)) {
    return;
  }

  bool has_platform_base_ext = false;
  bool has_platform_gbm_ext = false;
  bool has_khr_platform_gbm_ext = false;

  for (const auto& extension : egl_.extensions) {
    if (extension == "EGL_EXT_platform_base") {
      has_platform_base_ext = true;
      continue;
    } else if (extension == "EGL_MESA_platform_gbm") {
      has_platform_gbm_ext = true;
      continue;
    } else if (extension == "EGL_KHR_platform_gbm") {
      has_khr_platform_gbm_ext = true;
      continue;
    }
  }

  if (!has_platform_base_ext || !has_platform_gbm_ext ||
      !has_khr_platform_gbm_ext) {
    RTC_LOG(LS_ERROR) << "One of required EGL extensions is missing";
    return;
  }

  egl_.display = EglGetPlatformDisplay(EGL_PLATFORM_WAYLAND_KHR,
                                       (void*)EGL_DEFAULT_DISPLAY, nullptr);

  if (egl_.display == EGL_NO_DISPLAY) {
    RTC_LOG(LS_ERROR) << "Failed to obtain default EGL display: "
                      << FormatEGLError(EglGetError()) << "\n"
                      << "Defaulting to using first available render node";
    absl::optional<std::string> render_node = GetRenderNode();
    if (!render_node) {
      return;
    }

    drm_fd_ = open(render_node->c_str(), O_RDWR);

    if (drm_fd_ < 0) {
      RTC_LOG(LS_ERROR) << "Failed to open drm render node: "
                        << strerror(errno);
      return;
    }

    gbm_device_ = gbm_create_device(drm_fd_);

    if (!gbm_device_) {
      RTC_LOG(LS_ERROR) << "Cannot create GBM device: " << strerror(errno);
      close(drm_fd_);
      return;
    }

    // Use eglGetPlatformDisplayEXT() to get the display pointer
    // if the implementation supports it.
    egl_.display =
        EglGetPlatformDisplayEXT(EGL_PLATFORM_GBM_KHR, gbm_device_, nullptr);
  }

  if (egl_.display == EGL_NO_DISPLAY) {
    RTC_LOG(LS_ERROR) << "Error during obtaining EGL display: "
                      << FormatEGLError(EglGetError());
    return;
  }

  EGLint major, minor;
  if (EglInitialize(egl_.display, &major, &minor) == EGL_FALSE) {
    RTC_LOG(LS_ERROR) << "Error during eglInitialize: "
                      << FormatEGLError(EglGetError());
    return;
  }

  if (EglBindAPI(EGL_OPENGL_API) == EGL_FALSE) {
    RTC_LOG(LS_ERROR) << "bind OpenGL API failed";
    return;
  }

  egl_.context =
      EglCreateContext(egl_.display, nullptr, EGL_NO_CONTEXT, nullptr);

  if (egl_.context == EGL_NO_CONTEXT) {
    RTC_LOG(LS_ERROR) << "Couldn't create EGL context: "
                      << FormatGLError(EglGetError());
    return;
  }

  if (!GetClientExtensions(egl_.display, EGL_EXTENSIONS)) {
    return;
  }

  bool has_image_dma_buf_import_modifiers_ext = false;

  for (const auto& extension : egl_.extensions) {
    if (extension == "EGL_EXT_image_dma_buf_import") {
      has_image_dma_buf_import_ext_ = true;
      continue;
    } else if (extension == "EGL_EXT_image_dma_buf_import_modifiers") {
      has_image_dma_buf_import_modifiers_ext = true;
      continue;
    }
  }

  if (has_image_dma_buf_import_ext_ && has_image_dma_buf_import_modifiers_ext) {
    EglQueryDmaBufFormatsEXT = (eglQueryDmaBufFormatsEXT_func)EglGetProcAddress(
        "eglQueryDmaBufFormatsEXT");
    EglQueryDmaBufModifiersEXT =
        (eglQueryDmaBufModifiersEXT_func)EglGetProcAddress(
            "eglQueryDmaBufModifiersEXT");
  }

  RTC_LOG(LS_INFO) << "Egl initialization succeeded";
  egl_initialized_ = true;
}

RTC_NO_SANITIZE("cfi-icall")
EglDmaBuf::~EglDmaBuf() {
  if (gbm_device_) {
    gbm_device_destroy(gbm_device_);
    close(drm_fd_);
  }

  if (egl_.context != EGL_NO_CONTEXT) {
    EglDestroyContext(egl_.display, egl_.context);
  }

  if (egl_.display != EGL_NO_DISPLAY) {
    EglTerminate(egl_.display);
  }

  // BUG: crbug.com/1290566
  // Closing libEGL.so.1 when using NVidia drivers causes a crash
  // when EglGetPlatformDisplayEXT() is used, at least this one is enough
  // to be called to make it crash.
  // It also looks that libepoxy and glad don't dlclose it either
  // CloseLibrary(g_lib_egl);
  // CloseLibrary(g_lib_gl);
}

RTC_NO_SANITIZE("cfi-icall")
bool EglDmaBuf::GetClientExtensions(EGLDisplay dpy, EGLint name) {
  // Get the list of client extensions
  const char* client_extensions_cstring = EglQueryString(dpy, name);
  if (!client_extensions_cstring) {
    // If eglQueryString() returned NULL, the implementation doesn't support
    // EGL_EXT_client_extensions. Expect an EGL_BAD_DISPLAY error.
    RTC_LOG(LS_ERROR) << "No client extensions defined! "
                      << FormatEGLError(EglGetError());
    return false;
  }

  std::vector<absl::string_view> client_extensions =
      rtc::split(client_extensions_cstring, ' ');
  for (const auto& extension : client_extensions) {
    egl_.extensions.push_back(std::string(extension));
  }

  return true;
}

RTC_NO_SANITIZE("cfi-icall")
std::unique_ptr<uint8_t[]> EglDmaBuf::ImageFromDmaBuf(
    const DesktopSize& size,
    uint32_t format,
    const std::vector<PlaneData>& plane_datas,
    uint64_t modifier) {
  std::unique_ptr<uint8_t[]> src;

  if (!egl_initialized_) {
    return src;
  }

  if (plane_datas.size() <= 0) {
    RTC_LOG(LS_ERROR) << "Failed to process buffer: invalid number of planes";
    return src;
  }

  EGLint attribs[47];
  int atti = 0;

  attribs[atti++] = EGL_WIDTH;
  attribs[atti++] = static_cast<EGLint>(size.width());
  attribs[atti++] = EGL_HEIGHT;
  attribs[atti++] = static_cast<EGLint>(size.height());
  attribs[atti++] = EGL_LINUX_DRM_FOURCC_EXT;
  attribs[atti++] = SpaPixelFormatToDrmFormat(format);

  if (plane_datas.size() > 0) {
    attribs[atti++] = EGL_DMA_BUF_PLANE0_FD_EXT;
    attribs[atti++] = plane_datas[0].fd;
    attribs[atti++] = EGL_DMA_BUF_PLANE0_OFFSET_EXT;
    attribs[atti++] = plane_datas[0].offset;
    attribs[atti++] = EGL_DMA_BUF_PLANE0_PITCH_EXT;
    attribs[atti++] = plane_datas[0].stride;

    if (modifier != DRM_FORMAT_MOD_INVALID) {
      attribs[atti++] = EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT;
      attribs[atti++] = modifier & 0xFFFFFFFF;
      attribs[atti++] = EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT;
      attribs[atti++] = modifier >> 32;
    }
  }

  if (plane_datas.size() > 1) {
    attribs[atti++] = EGL_DMA_BUF_PLANE1_FD_EXT;
    attribs[atti++] = plane_datas[1].fd;
    attribs[atti++] = EGL_DMA_BUF_PLANE1_OFFSET_EXT;
    attribs[atti++] = plane_datas[1].offset;
    attribs[atti++] = EGL_DMA_BUF_PLANE1_PITCH_EXT;
    attribs[atti++] = plane_datas[1].stride;

    if (modifier != DRM_FORMAT_MOD_INVALID) {
      attribs[atti++] = EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT;
      attribs[atti++] = modifier & 0xFFFFFFFF;
      attribs[atti++] = EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT;
      attribs[atti++] = modifier >> 32;
    }
  }

  if (plane_datas.size() > 2) {
    attribs[atti++] = EGL_DMA_BUF_PLANE2_FD_EXT;
    attribs[atti++] = plane_datas[2].fd;
    attribs[atti++] = EGL_DMA_BUF_PLANE2_OFFSET_EXT;
    attribs[atti++] = plane_datas[2].offset;
    attribs[atti++] = EGL_DMA_BUF_PLANE2_PITCH_EXT;
    attribs[atti++] = plane_datas[2].stride;

    if (modifier != DRM_FORMAT_MOD_INVALID) {
      attribs[atti++] = EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT;
      attribs[atti++] = modifier & 0xFFFFFFFF;
      attribs[atti++] = EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT;
      attribs[atti++] = modifier >> 32;
    }
  }

  if (plane_datas.size() > 3) {
    attribs[atti++] = EGL_DMA_BUF_PLANE3_FD_EXT;
    attribs[atti++] = plane_datas[3].fd;
    attribs[atti++] = EGL_DMA_BUF_PLANE3_OFFSET_EXT;
    attribs[atti++] = plane_datas[3].offset;
    attribs[atti++] = EGL_DMA_BUF_PLANE3_PITCH_EXT;
    attribs[atti++] = plane_datas[3].stride;

    if (modifier != DRM_FORMAT_MOD_INVALID) {
      attribs[atti++] = EGL_DMA_BUF_PLANE3_MODIFIER_LO_EXT;
      attribs[atti++] = modifier & 0xFFFFFFFF;
      attribs[atti++] = EGL_DMA_BUF_PLANE3_MODIFIER_HI_EXT;
      attribs[atti++] = modifier >> 32;
    }
  }

  attribs[atti++] = EGL_NONE;

  // bind context to render thread
  EglMakeCurrent(egl_.display, EGL_NO_SURFACE, EGL_NO_SURFACE, egl_.context);

  // create EGL image from attribute list
  EGLImageKHR image = EglCreateImageKHR(
      egl_.display, EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, nullptr, attribs);

  if (image == EGL_NO_IMAGE) {
    RTC_LOG(LS_ERROR) << "Failed to record frame: Error creating EGLImage - "
                      << FormatEGLError(EglGetError());
    return src;
  }

  // create GL 2D texture for framebuffer
  GLuint texture;
  GlGenTextures(1, &texture);
  GlTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  GlTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  GlTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  GlTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  GlBindTexture(GL_TEXTURE_2D, texture);
  GlEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image);

  src = std::make_unique<uint8_t[]>(plane_datas[0].stride * size.height());

  GLenum gl_format = GL_BGRA;
  switch (format) {
    case SPA_VIDEO_FORMAT_RGBx:
      gl_format = GL_RGBA;
      break;
    case SPA_VIDEO_FORMAT_RGBA:
      gl_format = GL_RGBA;
      break;
    case SPA_VIDEO_FORMAT_BGRx:
      gl_format = GL_BGRA;
      break;
    default:
      gl_format = GL_BGRA;
      break;
  }
  GlGetTexImage(GL_TEXTURE_2D, 0, gl_format, GL_UNSIGNED_BYTE, src.get());

  if (GlGetError()) {
    RTC_LOG(LS_ERROR) << "Failed to get image from DMA buffer.";
    return src;
  }

  GlDeleteTextures(1, &texture);
  EglDestroyImageKHR(egl_.display, image);

  return src;
}

RTC_NO_SANITIZE("cfi-icall")
std::vector<uint64_t> EglDmaBuf::QueryDmaBufModifiers(uint32_t format) {
  if (!egl_initialized_) {
    return {};
  }

  // Explicit modifiers not supported, return just DRM_FORMAT_MOD_INVALID as we
  // can still use modifier-less DMA-BUFs if we have required extension
  if (EglQueryDmaBufFormatsEXT == nullptr ||
      EglQueryDmaBufModifiersEXT == nullptr) {
    return has_image_dma_buf_import_ext_
               ? std::vector<uint64_t>{DRM_FORMAT_MOD_INVALID}
               : std::vector<uint64_t>{};
  }

  uint32_t drm_format = SpaPixelFormatToDrmFormat(format);
  // Should never happen as it's us who controls the list of supported formats
  RTC_DCHECK(drm_format != DRM_FORMAT_INVALID);

  EGLint count = 0;
  EGLBoolean success =
      EglQueryDmaBufFormatsEXT(egl_.display, 0, nullptr, &count);

  if (!success || !count) {
    RTC_LOG(LS_WARNING) << "Cannot query the number of formats.";
    return {DRM_FORMAT_MOD_INVALID};
  }

  std::vector<uint32_t> formats(count);
  if (!EglQueryDmaBufFormatsEXT(egl_.display, count,
                                reinterpret_cast<EGLint*>(formats.data()),
                                &count)) {
    RTC_LOG(LS_WARNING) << "Cannot query a list of formats.";
    return {DRM_FORMAT_MOD_INVALID};
  }

  if (std::find(formats.begin(), formats.end(), drm_format) == formats.end()) {
    RTC_LOG(LS_WARNING) << "Format " << drm_format
                        << " not supported for modifiers.";
    return {DRM_FORMAT_MOD_INVALID};
  }

  success = EglQueryDmaBufModifiersEXT(egl_.display, drm_format, 0, nullptr,
                                       nullptr, &count);

  if (!success || !count) {
    RTC_LOG(LS_WARNING) << "Cannot query the number of modifiers.";
    return {DRM_FORMAT_MOD_INVALID};
  }

  std::vector<uint64_t> modifiers(count);
  if (!EglQueryDmaBufModifiersEXT(egl_.display, drm_format, count,
                                  modifiers.data(), nullptr, &count)) {
    RTC_LOG(LS_WARNING) << "Cannot query a list of modifiers.";
  }

  // Support modifier-less buffers
  modifiers.push_back(DRM_FORMAT_MOD_INVALID);
  return modifiers;
}

absl::optional<std::string> EglDmaBuf::GetRenderNode() {
  int max_devices = drmGetDevices2(0, nullptr, 0);
  if (max_devices <= 0) {
    RTC_LOG(LS_ERROR) << "drmGetDevices2() has not found any devices (errno="
                      << -max_devices << ")";
    return absl::nullopt;
  }

  std::vector<drmDevicePtr> devices(max_devices);
  int ret = drmGetDevices2(0, devices.data(), max_devices);
  if (ret < 0) {
    RTC_LOG(LS_ERROR) << "drmGetDevices2() returned an error " << ret;
    return absl::nullopt;
  }

  std::string render_node;

  for (const drmDevicePtr& device : devices) {
    if (device->available_nodes & (1 << DRM_NODE_RENDER)) {
      render_node = device->nodes[DRM_NODE_RENDER];
      break;
    }
  }

  drmFreeDevices(devices.data(), ret);
  return render_node;
}

}  // namespace webrtc
