# Copyright 2016 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import("//device/vr/buildflags/buildflags.gni")

if (is_android) {
  import("//build/config/android/rules.gni")  # For generate_jni().
}

config("vr_gl_mode") {
  if (use_command_buffer) {
    defines = [
      "VR_USE_COMMAND_BUFFER",
      "GL_GLEXT_PROTOTYPES",
    ]
  } else {
    defines = [ "VR_USE_NATIVE_GL" ]
  }
}

source_set("vr_gl_bindings") {
  sources = [ "gl_bindings.h" ]
  public_configs = [ ":vr_gl_mode" ]
  if (use_command_buffer) {
    public_deps = [ "//gpu/command_buffer/client:gles2_c_lib" ]
  } else {
    public_deps = [ "//ui/gl" ]
  }
}

if (enable_vr) {
  # This target is intended to contain generic base classes or utils that are
  # used by ALL (or almost All) XR devices/runtimes.
  # TODO(https://crbug.com/1073113): Flesh out and cleanup this target, this
  # includes determination of which things (if any) should be in the public
  # target.
  component("vr_base") {
    # This list should not be expanded, ideally all references outside of this
    # directory would be removed; we should consider moving the classes that
    # the isolated_xr_device service needs to the public target, or document why
    # we opted to leave the exception.
    visibility = [
      # TODO(https://crbug.com/843374): Move arcore_device
      "//chrome/browser/*",
      "//content/services/isolated_xr_device/*",
      "//device/vr/*",
    ]

    output_name = "device_vr_base"

    defines = [ "IS_DEVICE_VR_BASE_IMPL" ]
    sources = [
      "create_anchor_request.cc",
      "create_anchor_request.h",
      "vr_device.h",
      "vr_device_base.cc",
      "vr_device_base.h",
      "vr_gl_util.cc",
      "vr_gl_util.h",
    ]

    public_configs = [ ":vr_gl_mode" ]
    public_deps = [
      ":vr_gl_bindings",
      "//device/vr/public/cpp",
      "//device/vr/public/mojom:isolated_xr_service",
    ]
    deps = [
      "//base",
      "//mojo/public/cpp/bindings",
    ]
  }

  # Contains useful helper classes that are used by either multiple XR Devices,
  # or are useful to classes interacting with them (e.g. to measure performance
  # or to ease working with data coming in/out of mojom).
  component("vr_util") {
    output_name = "device_vr_util"
    defines = [ "IS_DEVICE_VR_UTIL_IMPL" ]

    sources = [
      "util/fps_meter.cc",
      "util/fps_meter.h",
      "util/gamepad_builder.cc",
      "util/gamepad_builder.h",
      "util/hit_test_subscription_data.cc",
      "util/hit_test_subscription_data.h",
      "util/sample_queue.cc",
      "util/sample_queue.h",
      "util/sliding_average.cc",
      "util/sliding_average.h",
      "util/stage_utils.cc",
      "util/stage_utils.h",
      "util/transform_utils.cc",
      "util/transform_utils.h",
      "util/xr_standard_gamepad_builder.cc",
      "util/xr_standard_gamepad_builder.h",
    ]

    deps = [
      "//base",
      "//device/vr/public/mojom:isolated_xr_service",
      "//ui/gfx",
    ]
  }

  if (enable_openxr) {
    source_set("openxr_data") {
      sources = [
        "openxr/openxr_defs.h",
        "openxr/openxr_interaction_profile_type.h",
      ]

      deps = [
        "//base",
        "//device/gamepad/public/cpp:shared_with_blink",
        "//third_party/openxr:openxr_headers",
      ]
    }
  }

  # TODO(alcooper): Ultimately, this component should be either deleted entirely
  # or used as a helper component aggregating all XR Runtimes that are in use.
  # Each XR Device should be split into its own component.
  component("vr") {
    output_name = "device_vr"

    defines = [ "DEVICE_VR_IMPLEMENTATION" ]
    sources = [ "vr_export.h" ]

    public_deps = [ "//device/vr/public/cpp" ]
    deps = [
      ":vr_base",
      ":vr_util",
      "//base",
      "//components/ukm:ukm",
      "//device/base",
      "//device/vr/buildflags",
      "//device/vr/public/mojom:isolated_xr_service",
      "//gpu/ipc/common:interfaces",
      "//mojo/public/cpp/bindings",
      "//services/device/public/cpp/generic_sensor",
      "//services/metrics/public/cpp:ukm_builders",
      "//ui/display",
      "//ui/gfx",
      "//ui/gfx/mojom",
    ]

    if (enable_gvr_services) {
      sources += [
        "android/gvr/gvr_delegate.cc",
        "android/gvr/gvr_delegate.h",
        "android/gvr/gvr_delegate_provider.h",
        "android/gvr/gvr_delegate_provider_factory.cc",
        "android/gvr/gvr_delegate_provider_factory.h",
        "android/gvr/gvr_device.cc",
        "android/gvr/gvr_device.h",
        "android/gvr/gvr_device_provider.cc",
        "android/gvr/gvr_device_provider.h",
        "android/gvr/gvr_utils.cc",
        "android/gvr/gvr_utils.h",
      ]

      deps += [
        ":jni_headers",
        "//third_party/blink/public:blink_headers",
        "//third_party/gvr-android-sdk:gvr_shim",
      ]
      ldflags = [ "-landroid" ]
      configs += [ "//third_party/gvr-android-sdk:libgvr_config" ]
    }

    if (enable_openxr) {
      if (is_win) {
        libs = [
          "d3d11.lib",
          "DXGI.lib",
        ]

        sources += [
          "windows/d3d11_texture_helper.cc",
          "windows/d3d11_texture_helper.h",
          "windows/flip_pixel_shader.h",
          "windows/geometry_shader.h",
          "windows/vertex_shader.h",
        ]

        deps += [ ":directx_helpers" ]
      }

      sources += [
        "openxr/context_provider_callbacks.h",
        "openxr/openxr_anchor_manager.cc",
        "openxr/openxr_anchor_manager.h",
        "openxr/openxr_api_wrapper.cc",
        "openxr/openxr_api_wrapper.h",
        "openxr/openxr_controller.cc",
        "openxr/openxr_controller.h",
        "openxr/openxr_debug_util.cc",
        "openxr/openxr_debug_util.h",
        "openxr/openxr_device.cc",
        "openxr/openxr_device.h",
        "openxr/openxr_extension_handle.h",
        "openxr/openxr_extension_helper.cc",
        "openxr/openxr_extension_helper.h",
        "openxr/openxr_input_helper.cc",
        "openxr/openxr_input_helper.h",
        "openxr/openxr_interaction_profiles.cc",
        "openxr/openxr_interaction_profiles.h",
        "openxr/openxr_path_helper.cc",
        "openxr/openxr_path_helper.h",
        "openxr/openxr_platform.h",
        "openxr/openxr_render_loop.cc",
        "openxr/openxr_render_loop.h",
        "openxr/openxr_scene.cc",
        "openxr/openxr_scene.h",
        "openxr/openxr_scene_bounds.cc",
        "openxr/openxr_scene_bounds.h",
        "openxr/openxr_scene_object.cc",
        "openxr/openxr_scene_object.h",
        "openxr/openxr_scene_observer.cc",
        "openxr/openxr_scene_observer.h",
        "openxr/openxr_scene_plane.cc",
        "openxr/openxr_scene_plane.h",
        "openxr/openxr_scene_understanding_manager.cc",
        "openxr/openxr_scene_understanding_manager.h",
        "openxr/openxr_statics.cc",
        "openxr/openxr_statics.h",
        "openxr/openxr_util.cc",
        "openxr/openxr_util.h",
        "openxr/openxr_view_configuration.cc",
        "openxr/openxr_view_configuration.h",
        "test/test_hook.h",
        "windows/compositor_base.cc",
        "windows/compositor_base.h",
      ]

      deps += [
        ":openxr_data",
        "//components/version_info",
        "//device/base",
        "//third_party/openxr",
      ]
    }
  }

  component("vr_fakes") {
    testonly = true

    defines = [ "DEVICE_VR_IMPLEMENTATION" ]

    sources = [
      "test/fake_orientation_provider.cc",
      "test/fake_orientation_provider.h",
      "test/fake_sensor_provider.cc",
      "test/fake_sensor_provider.h",
      "test/fake_vr_device.cc",
      "test/fake_vr_device.h",
      "test/fake_vr_device_provider.cc",
      "test/fake_vr_device_provider.h",
      "test/fake_vr_service_client.cc",
      "test/fake_vr_service_client.h",
      "vr_export.h",
    ]

    public_deps = [
      ":vr",
      ":vr_base",
      "//base",
      "//device/vr/orientation",
      "//device/vr/public/mojom:isolated_xr_service",
      "//mojo/public/cpp/bindings",
      "//services/device/public/cpp/generic_sensor",
      "//testing/gmock",
    ]
  }

  if (is_win) {
    static_library("directx_helpers") {
      sources = [
        "windows/d3d11_device_helpers.cc",
        "windows/d3d11_device_helpers.h",
      ]

      libs = [
        "d3d11.lib",
        "DXGI.lib",
      ]

      deps = [ "//base" ]
    }
  }
} else {
  source_set("vr") {
    # We need to include an empty .cc file so that mac and windows don't fall over when trying to
    # compile this when webvr is disabled.
    sources = [ "empty.cc" ]
  }
}

if (enable_openxr) {
  # The OpenXR Loader by default looks for the path to the OpenXR Runtime from a
  # registry key, which typically points to the OpenXR runtime installed on the
  # system. In test, we want to use the mock OpenXR runtime that is created
  # below in :openxr_mock. If the XR_RUNTIME_JSON environment variable is set,
  # the OpenXR loader instead looks for the path to the OpenXR runtime in the
  # json file instead of the registry key. This json file copied to the output
  # folder points to our mock OpenXR runtime.
  copy("json_mock") {
    sources = [ "openxr/test/openxr.json" ]
    outputs = [ "$root_out_dir/mock_vr_clients/bin/openxr/openxr.json" ]
  }

  shared_library("openxr_mock") {
    testonly = true
    output_name = "mock_vr_clients/bin/openxr/openxrruntime"

    include_dirs = [ "//third_party/openxr/src/include" ]

    sources = [
      "openxr/openxr_extension_helper.cc",
      "openxr/openxr_extension_helper.h",
      "openxr/openxr_platform.h",
      "openxr/openxr_util.cc",
      "openxr/openxr_util.h",
      "openxr/openxr_view_configuration.cc",
      "openxr/openxr_view_configuration.h",
      "openxr/test/fake_openxr_impl_api.cc",
      "openxr/test/openxr.def",
      "openxr/test/openxr_negotiate.h",
      "openxr/test/openxr_test_helper.cc",
      "openxr/test/openxr_test_helper.h",
      "test/test_hook.h",
    ]

    libs = [
      "d3d11.lib",
      "DXGI.lib",
    ]

    deps = [
      "//base",
      "//components/version_info",
      "//device/vr/public/mojom:test_mojom",
      "//third_party/openxr:openxr_headers",
    ]

    public_deps = [ ":openxr_data" ]

    data_deps = [ "//device/vr:json_mock" ]
  }
}

if (enable_gvr_services) {
  java_sources_needing_jni =
      [ "android/java/src/org/chromium/device/vr/NonPresentingGvrContext.java" ]

  generate_jni("jni_headers") {
    sources = java_sources_needing_jni
    split_name = "vr"
  }

  android_library("java") {
    sources = java_sources_needing_jni
    deps = [
      "//base:base_java",
      "//base:jni_java",
      "//build/android:build_java",
      "//third_party/gvr-android-sdk:gvr_common_java",
      "//ui/android:ui_java",
    ]
    annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ]
  }
}