// 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.h"

namespace {

void EnumerateGPUDevice(gpu::GPUInfo::Enumerator* enumerator,
                        const gpu::GPUInfo::GPUDevice& device) {
  enumerator->BeginGPUDevice();
  enumerator->AddInt("vendorId", device.vendor_id);
  enumerator->AddInt("deviceId", device.device_id);
  enumerator->AddBool("active", device.active);
  enumerator->AddString("vendorString", device.vendor_string);
  enumerator->AddString("deviceString", device.device_string);
  enumerator->EndGPUDevice();
}

void EnumerateVideoEncodeAcceleratorSupportedProfile(
    gpu::GPUInfo::Enumerator* enumerator,
    const media::VideoEncodeAccelerator::SupportedProfile profile) {
  enumerator->BeginVideoEncodeAcceleratorSupportedProfile();
  enumerator->AddInt("profile", profile.profile);
  enumerator->AddInt("maxResolutionWidth", profile.max_resolution.width());
  enumerator->AddInt("maxResolutionHeight", profile.max_resolution.height());
  enumerator->AddInt("maxFramerateNumerator", profile.max_framerate_numerator);
  enumerator->AddInt("maxFramerateDenominator",
                     profile.max_framerate_denominator);
  enumerator->EndVideoEncodeAcceleratorSupportedProfile();
}

}  // namespace

namespace gpu {

GPUInfo::GPUDevice::GPUDevice()
    : vendor_id(0),
      device_id(0),
      active(false) {
}

GPUInfo::GPUDevice::~GPUDevice() { }

GPUInfo::GPUInfo()
    : optimus(false),
      amd_switchable(false),
      lenovo_dcute(false),
      adapter_luid(0),
      gl_reset_notification_strategy(0),
      can_lose_context(false),
      software_rendering(false),
      direct_rendering(true),
      sandboxed(false),
      process_crash_count(0),
      basic_info_state(kCollectInfoNone),
#if defined(OS_WIN)
      context_info_state(kCollectInfoNone),
      dx_diagnostics_info_state(kCollectInfoNone) {
#else
      context_info_state(kCollectInfoNone) {
#endif
}

GPUInfo::~GPUInfo() { }

void GPUInfo::EnumerateFields(Enumerator* enumerator) const {
  struct GPUInfoKnownFields {
    base::TimeDelta initialization_time;
    bool optimus;
    bool amd_switchable;
    bool lenovo_dcute;
    Version display_link_version;
    GPUDevice gpu;
    std::vector<GPUDevice> secondary_gpus;
    uint64 adapter_luid;
    std::string driver_vendor;
    std::string driver_version;
    std::string driver_date;
    std::string pixel_shader_version;
    std::string vertex_shader_version;
    std::string machine_model_name;
    std::string machine_model_version;
    std::string gl_version_string;
    std::string gl_vendor;
    std::string gl_renderer;
    std::string gl_extensions;
    std::string gl_ws_vendor;
    std::string gl_ws_version;
    std::string gl_ws_extensions;
    uint32 gl_reset_notification_strategy;
    bool can_lose_context;
    GpuPerformanceStats performance_stats;
    bool software_rendering;
    bool direct_rendering;
    bool sandboxed;
    int process_crash_count;
    CollectInfoResult basic_info_state;
    CollectInfoResult context_info_state;
#if defined(OS_WIN)
    CollectInfoResult dx_diagnostics_info_state;
    DxDiagNode dx_diagnostics;
#endif
    std::vector<media::VideoEncodeAccelerator::SupportedProfile>
        video_encode_accelerator_supported_profiles;
  };

  // If this assert fails then most likely something below needs to be updated.
  // Note that this assert is only approximate. If a new field is added to
  // GPUInfo which fits within the current padding then it will not be caught.
  COMPILE_ASSERT(
      sizeof(GPUInfo) == sizeof(GPUInfoKnownFields),
      Fields_Have_Changed_In_GPUInfo_So_Update_Below);

  // Required fields (according to DevTools protocol) first.
  enumerator->AddString("machineModelName", machine_model_name);
  enumerator->AddString("machineModelVersion", machine_model_version);
  EnumerateGPUDevice(enumerator, gpu);
  for (size_t ii = 0; ii < secondary_gpus.size(); ++ii) {
    EnumerateGPUDevice(enumerator, secondary_gpus[ii]);
  }

  enumerator->BeginAuxAttributes();
  enumerator->AddTimeDeltaInSecondsF("initializationTime",
                                     initialization_time);
  enumerator->AddBool("optimus", optimus);
  enumerator->AddBool("amdSwitchable", amd_switchable);
  enumerator->AddBool("lenovoDcute", lenovo_dcute);
  if (display_link_version.IsValid()) {
    enumerator->AddString("displayLinkVersion",
                          display_link_version.GetString());
  }
  enumerator->AddInt64("adapterLuid", adapter_luid);
  enumerator->AddString("driverVendor", driver_vendor);
  enumerator->AddString("driverVersion", driver_version);
  enumerator->AddString("driverDate", driver_date);
  enumerator->AddString("pixelShaderVersion", pixel_shader_version);
  enumerator->AddString("vertexShaderVersion", vertex_shader_version);
  enumerator->AddString("glVersion", gl_version);
  enumerator->AddString("glVendor", gl_vendor);
  enumerator->AddString("glRenderer", gl_renderer);
  enumerator->AddString("glExtensions", gl_extensions);
  enumerator->AddString("glWsVendor", gl_ws_vendor);
  enumerator->AddString("glWsVersion", gl_ws_version);
  enumerator->AddString("glWsExtensions", gl_ws_extensions);
  enumerator->AddInt(
      "glResetNotificationStrategy",
      static_cast<int>(gl_reset_notification_strategy));
  enumerator->AddBool("can_lose_context", can_lose_context);
  // TODO(kbr): add performance_stats.
  enumerator->AddBool("softwareRendering", software_rendering);
  enumerator->AddBool("directRendering", direct_rendering);
  enumerator->AddBool("sandboxed", sandboxed);
  enumerator->AddInt("processCrashCount", process_crash_count);
  enumerator->AddInt("basicInfoState", basic_info_state);
  enumerator->AddInt("contextInfoState", context_info_state);
#if defined(OS_WIN)
  enumerator->AddInt("DxDiagnosticsInfoState", dx_diagnostics_info_state);
#endif
  // TODO(kbr): add dx_diagnostics on Windows.
  for (size_t ii = 0; ii < video_encode_accelerator_supported_profiles.size();
       ++ii) {
    EnumerateVideoEncodeAcceleratorSupportedProfile(
        enumerator, video_encode_accelerator_supported_profiles[ii]);
  }
  enumerator->EndAuxAttributes();
}

}  // namespace gpu
