// Copyright (c) 2012 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 "gpu/config/gpu_info_collector.h"

#include <stddef.h>
#include <stdint.h>

#include <string>
#include <vector>

#include "base/command_line.h"
#include "base/logging.h"
#include "base/metrics/histogram_functions.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_piece.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/trace_event/trace_event.h"
#include "gpu/config/gpu_switches.h"
#include "third_party/angle/src/gpu_info_util/SystemInfo.h"  // nogncheck
#include "ui/gl/gl_bindings.h"
#include "ui/gl/gl_context.h"
#include "ui/gl/gl_implementation.h"
#include "ui/gl/gl_surface.h"
#include "ui/gl/gl_version_info.h"
#include "ui/gl/init/gl_factory.h"

#if defined(OS_ANDROID)
#include "ui/gl/gl_surface_egl.h"
#endif  // OS_ANDROID

#if defined(USE_X11)
#include "ui/gl/gl_visual_picker_glx.h"
#endif

namespace {

scoped_refptr<gl::GLSurface> InitializeGLSurface() {
  scoped_refptr<gl::GLSurface> surface(
      gl::init::CreateOffscreenGLSurface(gfx::Size()));
  if (!surface.get()) {
    LOG(ERROR) << "gl::GLContext::CreateOffscreenGLSurface failed";
    return NULL;
  }

  return surface;
}

scoped_refptr<gl::GLContext> InitializeGLContext(gl::GLSurface* surface) {
  gl::GLContextAttribs attribs;
  attribs.client_major_es_version = 2;
  scoped_refptr<gl::GLContext> context(
      gl::init::CreateGLContext(nullptr, surface, attribs));
  if (!context.get()) {
    LOG(ERROR) << "gl::init::CreateGLContext failed";
    return NULL;
  }

  if (!context->MakeCurrent(surface)) {
    LOG(ERROR) << "gl::GLContext::MakeCurrent() failed";
    return NULL;
  }

  return context;
}

std::string GetGLString(unsigned int pname) {
  const char* gl_string =
      reinterpret_cast<const char*>(glGetString(pname));
  if (gl_string)
    return std::string(gl_string);
  return std::string();
}

// Return a version string in the format of "major.minor".
std::string GetVersionFromString(const std::string& version_string) {
  size_t begin = version_string.find_first_of("0123456789");
  if (begin != std::string::npos) {
    size_t end = version_string.find_first_not_of("01234567890.", begin);
    std::string sub_string;
    if (end != std::string::npos)
      sub_string = version_string.substr(begin, end - begin);
    else
      sub_string = version_string.substr(begin);
    std::vector<std::string> pieces = base::SplitString(
        sub_string, ".", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
    if (pieces.size() >= 2)
      return pieces[0] + "." + pieces[1];
  }
  return std::string();
}

// Return the array index of the found name, or return -1.
int StringContainsName(
    const std::string& str, const std::string* names, size_t num_names) {
  std::vector<std::string> tokens = base::SplitString(
      str, " .,()-_", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
  for (size_t ii = 0; ii < tokens.size(); ++ii) {
    for (size_t name_index = 0; name_index < num_names; ++name_index) {
      if (tokens[ii] == names[name_index]) {
        return base::checked_cast<int>(name_index);
      }
    }
  }
  return -1;
}

}  // namespace

namespace gpu {

CollectInfoResult CollectGraphicsInfoGL(GPUInfo* gpu_info) {
  TRACE_EVENT0("startup", "gpu_info_collector::CollectGraphicsInfoGL");
  DCHECK_NE(gl::GetGLImplementation(), gl::kGLImplementationNone);

  scoped_refptr<gl::GLSurface> surface(InitializeGLSurface());
  if (!surface.get()) {
    LOG(ERROR) << "Could not create surface for info collection.";
    return kCollectInfoFatalFailure;
  }

  scoped_refptr<gl::GLContext> context(InitializeGLContext(surface.get()));
  if (!context.get()) {
    LOG(ERROR) << "Could not create context for info collection.";
    return kCollectInfoFatalFailure;
  }

  gpu_info->gl_renderer = GetGLString(GL_RENDERER);
  gpu_info->gl_vendor = GetGLString(GL_VENDOR);
  gpu_info->gl_version = GetGLString(GL_VERSION);
  std::string glsl_version_string = GetGLString(GL_SHADING_LANGUAGE_VERSION);

  gpu_info->gl_extensions = gl::GetGLExtensionsFromCurrentContext();
  gl::ExtensionSet extension_set =
      gl::MakeExtensionSet(gpu_info->gl_extensions);

  gl::GLVersionInfo gl_info(gpu_info->gl_version.c_str(),
                            gpu_info->gl_renderer.c_str(), extension_set);
  GLint max_samples = 0;
  if (gl_info.IsAtLeastGL(3, 0) || gl_info.IsAtLeastGLES(3, 0) ||
      gl::HasExtension(extension_set, "GL_ANGLE_framebuffer_multisample") ||
      gl::HasExtension(extension_set, "GL_APPLE_framebuffer_multisample") ||
      gl::HasExtension(extension_set, "GL_EXT_framebuffer_multisample") ||
      gl::HasExtension(extension_set,
                       "GL_EXT_multisampled_render_to_texture") ||
      gl::HasExtension(extension_set, "GL_NV_framebuffer_multisample")) {
    glGetIntegerv(GL_MAX_SAMPLES, &max_samples);
  }
  gpu_info->max_msaa_samples = base::IntToString(max_samples);
  base::UmaHistogramSparse("GPU.MaxMSAASampleCount", max_samples);

#if defined(OS_ANDROID)
  gpu_info->can_support_threaded_texture_mailbox =
      gl::GLSurfaceEGL::HasEGLExtension("EGL_KHR_fence_sync") &&
      gl::GLSurfaceEGL::HasEGLExtension("EGL_KHR_image_base") &&
      gl::GLSurfaceEGL::HasEGLExtension("EGL_KHR_gl_texture_2D_image") &&
      gl::HasExtension(extension_set, "GL_OES_EGL_image");
#else
  gl::GLWindowSystemBindingInfo window_system_binding_info;
  if (gl::init::GetGLWindowSystemBindingInfo(&window_system_binding_info)) {
    gpu_info->gl_ws_vendor = window_system_binding_info.vendor;
    gpu_info->gl_ws_version = window_system_binding_info.version;
    gpu_info->gl_ws_extensions = window_system_binding_info.extensions;
    gpu_info->direct_rendering = window_system_binding_info.direct_rendering;
  }
#endif  // OS_ANDROID

  bool supports_robustness =
      gl::HasExtension(extension_set, "GL_EXT_robustness") ||
      gl::HasExtension(extension_set, "GL_KHR_robustness") ||
      gl::HasExtension(extension_set, "GL_ARB_robustness");
  if (supports_robustness) {
    glGetIntegerv(GL_RESET_NOTIFICATION_STRATEGY_ARB,
        reinterpret_cast<GLint*>(&gpu_info->gl_reset_notification_strategy));
  }

#if defined(USE_X11)
  if (gl::GetGLImplementation() == gl::kGLImplementationDesktopGL) {
    gl::GLVisualPickerGLX* visual_picker = gl::GLVisualPickerGLX::GetInstance();
    gpu_info->system_visual = visual_picker->system_visual().visualid;
    gpu_info->rgba_visual = visual_picker->rgba_visual().visualid;
  }
#endif

  // TODO(kbr): remove once the destruction of a current context automatically
  // clears the current context.
  context->ReleaseCurrent(surface.get());

  std::string glsl_version = GetVersionFromString(glsl_version_string);
  gpu_info->pixel_shader_version = glsl_version;
  gpu_info->vertex_shader_version = glsl_version;

  IdentifyActiveGPU(gpu_info);
  return CollectDriverInfoGL(gpu_info);
}

void MergeGPUInfoGL(GPUInfo* basic_gpu_info,
                    const GPUInfo& context_gpu_info) {
  DCHECK(basic_gpu_info);
  // Copy over GPUs because which one is active could change.
  basic_gpu_info->gpu = context_gpu_info.gpu;
  basic_gpu_info->secondary_gpus = context_gpu_info.secondary_gpus;

  basic_gpu_info->gl_renderer = context_gpu_info.gl_renderer;
  basic_gpu_info->gl_vendor = context_gpu_info.gl_vendor;
  basic_gpu_info->gl_version = context_gpu_info.gl_version;
  basic_gpu_info->gl_extensions = context_gpu_info.gl_extensions;
  basic_gpu_info->pixel_shader_version =
      context_gpu_info.pixel_shader_version;
  basic_gpu_info->vertex_shader_version =
      context_gpu_info.vertex_shader_version;
  basic_gpu_info->max_msaa_samples =
      context_gpu_info.max_msaa_samples;
  basic_gpu_info->gl_ws_vendor = context_gpu_info.gl_ws_vendor;
  basic_gpu_info->gl_ws_version = context_gpu_info.gl_ws_version;
  basic_gpu_info->gl_ws_extensions = context_gpu_info.gl_ws_extensions;
  basic_gpu_info->gl_reset_notification_strategy =
      context_gpu_info.gl_reset_notification_strategy;
  basic_gpu_info->software_rendering = context_gpu_info.software_rendering;

  if (!context_gpu_info.driver_vendor.empty())
    basic_gpu_info->driver_vendor = context_gpu_info.driver_vendor;
  if (!context_gpu_info.driver_version.empty())
    basic_gpu_info->driver_version = context_gpu_info.driver_version;

  basic_gpu_info->sandboxed = context_gpu_info.sandboxed;
  basic_gpu_info->direct_rendering = context_gpu_info.direct_rendering;
  basic_gpu_info->in_process_gpu = context_gpu_info.in_process_gpu;
  basic_gpu_info->passthrough_cmd_decoder =
      context_gpu_info.passthrough_cmd_decoder;
  basic_gpu_info->direct_composition = context_gpu_info.direct_composition;
  basic_gpu_info->supports_overlays = context_gpu_info.supports_overlays;
  basic_gpu_info->context_info_state = context_gpu_info.context_info_state;
  basic_gpu_info->initialization_time = context_gpu_info.initialization_time;
  basic_gpu_info->video_decode_accelerator_capabilities =
      context_gpu_info.video_decode_accelerator_capabilities;
  basic_gpu_info->video_encode_accelerator_supported_profiles =
      context_gpu_info.video_encode_accelerator_supported_profiles;
  basic_gpu_info->jpeg_decode_accelerator_supported =
      context_gpu_info.jpeg_decode_accelerator_supported;

#if defined(USE_X11)
  basic_gpu_info->system_visual = context_gpu_info.system_visual;
  basic_gpu_info->rgba_visual = context_gpu_info.rgba_visual;
#endif
}

void IdentifyActiveGPU(GPUInfo* gpu_info) {
  const std::string kNVidiaName = "nvidia";
  const std::string kNouveauName = "nouveau";
  const std::string kIntelName = "intel";
  const std::string kAMDName = "amd";
  const std::string kATIName = "ati";
  const std::string kVendorNames[] = {kNVidiaName, kNouveauName, kIntelName,
                                      kAMDName, kATIName};

  const uint32_t kNVidiaID = 0x10de;
  const uint32_t kIntelID = 0x8086;
  const uint32_t kAMDID = 0x1002;
  const uint32_t kATIID = 0x1002;
  const uint32_t kVendorIDs[] = {kNVidiaID, kNVidiaID, kIntelID, kAMDID,
                                 kATIID};

  DCHECK(gpu_info);
  if (gpu_info->secondary_gpus.size() == 0) {
    // If there is only a single GPU, that GPU is active.
    gpu_info->gpu.active = true;
    return;
  }

  uint32_t active_vendor_id = 0;
  if (!gpu_info->gl_vendor.empty()) {
    std::string gl_vendor_lower = base::ToLowerASCII(gpu_info->gl_vendor);
    int index = StringContainsName(
        gl_vendor_lower, kVendorNames, arraysize(kVendorNames));
    if (index >= 0) {
      active_vendor_id = kVendorIDs[index];
    }
  }
  if (active_vendor_id == 0 && !gpu_info->gl_renderer.empty()) {
    std::string gl_renderer_lower = base::ToLowerASCII(gpu_info->gl_renderer);
    int index = StringContainsName(
        gl_renderer_lower, kVendorNames, arraysize(kVendorNames));
    if (index >= 0) {
      active_vendor_id = kVendorIDs[index];
    }
  }
  if (active_vendor_id == 0) {
    // We fail to identify the GPU vendor through GL_VENDOR/GL_RENDERER.
    return;
  }
  gpu_info->gpu.active = false;
  for (size_t ii = 0; ii < gpu_info->secondary_gpus.size(); ++ii)
    gpu_info->secondary_gpus[ii].active = false;

  // TODO(zmo): if two GPUs are from the same vendor, this code will always
  // set the first GPU as active, which could be wrong.
  if (active_vendor_id == gpu_info->gpu.vendor_id) {
    gpu_info->gpu.active = true;
    return;
  }
  for (size_t ii = 0; ii < gpu_info->secondary_gpus.size(); ++ii) {
    if (active_vendor_id == gpu_info->secondary_gpus[ii].vendor_id) {
      gpu_info->secondary_gpus[ii].active = true;
      return;
    }
  }
}

void FillGPUInfoFromSystemInfo(GPUInfo* gpu_info,
                               angle::SystemInfo* system_info) {
  // We fill gpu_info even when angle::GetSystemInfo failed so that we can see
  // partial information even when GPU info collection fails. Handle malformed
  // angle::SystemInfo first.
  if (system_info->gpus.empty()) {
    return;
  }
  if (system_info->primaryGPUIndex < 0) {
    system_info->primaryGPUIndex = 0;
  }

  angle::GPUDeviceInfo* primary =
      &system_info->gpus[system_info->primaryGPUIndex];

  gpu_info->gpu.vendor_id = primary->vendorId;
  gpu_info->gpu.device_id = primary->deviceId;
  if (system_info->primaryGPUIndex == system_info->activeGPUIndex) {
    gpu_info->gpu.active = true;
  }

  gpu_info->driver_vendor = std::move(primary->driverVendor);
  gpu_info->driver_version = std::move(primary->driverVersion);
  gpu_info->driver_date = std::move(primary->driverDate);

  for (size_t i = 0; i < system_info->gpus.size(); i++) {
    if (static_cast<int>(i) == system_info->primaryGPUIndex) {
      continue;
    }

    GPUInfo::GPUDevice device;
    device.vendor_id = system_info->gpus[i].vendorId;
    device.device_id = system_info->gpus[i].deviceId;
    if (static_cast<int>(i) == system_info->activeGPUIndex) {
      device.active = true;
    }

    gpu_info->secondary_gpus.push_back(device);
  }

  gpu_info->optimus = system_info->isOptimus;
  gpu_info->amd_switchable = system_info->isAMDSwitchable;

  gpu_info->machine_model_name = system_info->machineModelName;
  gpu_info->machine_model_version = system_info->machineModelVersion;
}

}  // namespace gpu
