// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ui/gfx/linux/gpu_memory_buffer_support_x11.h"

#include <fcntl.h>
#include <xcb/xcb.h>

#include <memory>

#include "base/containers/contains.h"
#include "base/debug/crash_logging.h"
#include "base/posix/eintr_wrapper.h"
#include "ui/gfx/buffer_format_util.h"
#include "ui/gfx/buffer_types.h"
#include "ui/gfx/buffer_usage_util.h"
#include "ui/gfx/linux/drm_util_linux.h"
#include "ui/gfx/linux/gbm_buffer.h"
#include "ui/gfx/linux/gbm_device.h"
#include "ui/gfx/linux/gbm_util.h"
#include "ui/gfx/linux/gbm_wrapper.h"
#include "ui/gfx/x/connection.h"
#include "ui/gfx/x/dri3.h"
#include "ui/gfx/x/future.h"

namespace ui {

namespace {

// Obtain an authenticated DRM fd from X11 and create a GbmDevice with it.
std::unique_ptr<ui::GbmDevice> CreateX11GbmDevice() {
  auto* connection = x11::Connection::Get();
  // |connection| may be nullptr in headless mode.
  if (!connection)
    return nullptr;

  auto& dri3 = connection->dri3();
  if (!dri3.present())
    return nullptr;

  // Let the X11 server know the DRI3 client version. This is required to use
  // the DRI3 extension. We don't care about the returned server version because
  // we only use features from the original DRI3 interface.
  dri3.QueryVersion({x11::Dri3::major_version, x11::Dri3::minor_version});

  // Obtain an authenticated DRM fd.
  auto reply = dri3.Open({connection->default_root(), 0}).Sync();
  if (!reply)
    return nullptr;

  base::ScopedFD fd(HANDLE_EINTR(dup(reply->device_fd.get())));
  if (!fd.is_valid())
    return nullptr;
  if (HANDLE_EINTR(fcntl(fd.get(), F_SETFD, FD_CLOEXEC)) == -1)
    return nullptr;

  return ui::CreateGbmDevice(fd.release());
}

std::vector<gfx::BufferUsageAndFormat> CreateSupportedConfigList(
    ui::GbmDevice* device) {
  if (!device)
    return {};

  std::vector<gfx::BufferUsageAndFormat> configs;
  for (gfx::BufferUsage usage : {
           gfx::BufferUsage::GPU_READ,
           gfx::BufferUsage::SCANOUT,
           gfx::BufferUsage::SCANOUT_CPU_READ_WRITE,
           gfx::BufferUsage::GPU_READ_CPU_READ_WRITE,
       }) {
    for (gfx::BufferFormat format : {
             gfx::BufferFormat::R_8,
             gfx::BufferFormat::RG_88,
             gfx::BufferFormat::RGBA_8888,
             gfx::BufferFormat::RGBX_8888,
             gfx::BufferFormat::BGRA_8888,
             gfx::BufferFormat::BGRX_8888,
             gfx::BufferFormat::BGRA_1010102,

             // On some Intel setups calling gbm_bo_create() with this format
             // results in a crash caused by an integer-divide-by-zero.
             // TODO(thomasanderson): Enable this format.
             // gfx::BufferFormat::RGBA_1010102,
             gfx::BufferFormat::BGR_565,
             gfx::BufferFormat::YUV_420_BIPLANAR,
             gfx::BufferFormat::YVU_420,
             gfx::BufferFormat::P010,
         }) {
      // At least on mesa/amdgpu, gbm_device_is_format_supported() lies.  Test
      // format support by creating a buffer directly.  Use a 2x2 buffer so that
      // YUV420 formats get properly tested.
      if (device->CreateBuffer(GetFourCCFormatFromBufferFormat(format),
                               gfx::Size(2, 2), BufferUsageToGbmFlags(usage))) {
        configs.push_back(gfx::BufferUsageAndFormat(usage, format));
      }
    }
  }
  return configs;
}

}  // namespace

// static
GpuMemoryBufferSupportX11* GpuMemoryBufferSupportX11::GetInstance() {
  static base::NoDestructor<GpuMemoryBufferSupportX11> instance;
  return instance.get();
}

GpuMemoryBufferSupportX11::GpuMemoryBufferSupportX11()
    : device_(CreateX11GbmDevice()),
      supported_configs_(CreateSupportedConfigList(device_.get())) {}

GpuMemoryBufferSupportX11::~GpuMemoryBufferSupportX11() = default;

std::unique_ptr<GbmBuffer> GpuMemoryBufferSupportX11::CreateBuffer(
    gfx::BufferFormat format,
    const gfx::Size& size,
    gfx::BufferUsage usage) {
  DCHECK(device_);
  DCHECK(base::Contains(supported_configs_,
                        gfx::BufferUsageAndFormat(usage, format)));

  static base::debug::CrashKeyString* crash_key_string =
      base::debug::AllocateCrashKeyString("buffer_usage_and_format",
                                          base::debug::CrashKeySize::Size64);
  std::string buffer_usage_and_format = gfx::BufferFormatToString(format) +
                                        std::string(",") +
                                        gfx::BufferUsageToString(usage);
  base::debug::ScopedCrashKeyString scoped_crash_key(
      crash_key_string, buffer_usage_and_format.c_str());

  return device_->CreateBuffer(GetFourCCFormatFromBufferFormat(format), size,
                               BufferUsageToGbmFlags(usage));
}

}  // namespace ui
