chromium/ui/gl/BUILD.gn

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

import("//build/buildflag_header.gni")
import("//build/config/chrome_build.gni")
import("//build/config/chromeos/ui_mode.gni")
import("//build/config/linux/pkg_config.gni")
import("//build/config/ozone.gni")
import("//build/config/ui.gni")
import("//gpu/vulkan/features.gni")
import("//testing/test.gni")
import("//third_party/angle/gni/angle.gni")
import("//third_party/dawn/scripts/dawn_features.gni")
import("//ui/gl/features.gni")

declare_args() {
  # Whether service side logging (actual calls into the GL driver) is enabled
  # or not.
  enable_gpu_service_logging = false
}

if (is_android) {
  import("//build/config/android/config.gni")
  import("//build/config/android/rules.gni")
  import("//third_party/jni_zero/jni_zero.gni")
}

buildflag_header("buildflags") {
  header = "buildflags.h"
  flags = [
    "DAWN_ENABLE_BACKEND_OPENGLES=$dawn_enable_opengles",
    "ENABLE_SWIFTSHADER=$enable_swiftshader",
    "USE_DAWN=$use_dawn",
    "USE_STATIC_ANGLE=$use_static_angle",
    "USE_OPENGL_APITRACE=$enable_opengl_apitrace",
    "ENABLE_VALIDATING_COMMAND_DECODER=$enable_validating_command_decoder",
  ]
}

component("gl_enums") {
  sources = [
    "gl_enums.cc",
    "gl_enums.h",
    "gl_enums_implementation_autogen.h",
    "gl_export.h",
  ]

  defines = [ "GL_IMPLEMENTATION" ]

  public_deps = [ "//third_party/angle:includes" ]
}

component("gl") {
  output_name = "gl_wrapper"  # Avoid colliding with OS X"s libGL.dylib.

  sources = [
    "angle_implementation.h",
    "angle_platform_impl.cc",
    "angle_platform_impl.h",
    "egl_timestamps.h",
    "egl_util.cc",
    "egl_util.h",
    "gl_bindings.cc",
    "gl_bindings.h",
    "gl_bindings_autogen_egl.cc",
    "gl_bindings_autogen_egl.h",
    "gl_bindings_autogen_gl.cc",
    "gl_bindings_autogen_gl.h",
    "gl_context.cc",
    "gl_context.h",
    "gl_context_egl.cc",
    "gl_context_egl.h",
    "gl_context_stub.cc",
    "gl_context_stub.h",
    "gl_display.cc",
    "gl_display.h",
    "gl_display_egl_util.cc",
    "gl_display_egl_util.h",
    "gl_display_manager.cc",
    "gl_display_manager.h",
    "gl_egl_api_implementation.cc",
    "gl_egl_api_implementation.h",
    "gl_features.cc",
    "gl_features.h",
    "gl_fence.cc",
    "gl_fence.h",
    "gl_fence_arb.cc",
    "gl_fence_arb.h",
    "gl_fence_egl.cc",
    "gl_fence_egl.h",
    "gl_fence_nv.cc",
    "gl_fence_nv.h",
    "gl_gl_api_implementation.cc",
    "gl_gl_api_implementation.h",
    "gl_helper.cc",
    "gl_helper.h",
    "gl_implementation.cc",
    "gl_implementation.h",
    "gl_implementation_wrapper.h",
    "gl_share_group.cc",
    "gl_share_group.h",
    "gl_state_restorer.cc",
    "gl_state_restorer.h",
    "gl_stub_api.cc",
    "gl_stub_api.h",
    "gl_stub_api_base.h",
    "gl_stub_autogen_gl.cc",
    "gl_stub_autogen_gl.h",
    "gl_surface.cc",
    "gl_surface.h",
    "gl_surface_egl.cc",
    "gl_surface_egl.h",
    "gl_surface_format.cc",
    "gl_surface_format.h",
    "gl_surface_overlay.cc",
    "gl_surface_overlay.h",
    "gl_surface_presentation_helper.cc",
    "gl_surface_presentation_helper.h",
    "gl_surface_stub.cc",
    "gl_surface_stub.h",
    "gl_switches.cc",
    "gl_switches.h",
    "gl_utils.cc",
    "gl_utils.h",
    "gl_version_info.cc",
    "gl_version_info.h",
    "gpu_switching_manager.cc",
    "gpu_switching_manager.h",
    "gpu_timing.cc",
    "gpu_timing.h",
    "presenter.cc",
    "presenter.h",
    "progress_reporter.h",
    "scoped_binders.cc",
    "scoped_binders.h",
    "scoped_egl_image.cc",
    "scoped_egl_image.h",
    "scoped_make_current.cc",
    "scoped_make_current.h",
    "scoped_make_current_unsafe.cc",
    "scoped_make_current_unsafe.h",
    "scoped_restore_texture.cc",
    "scoped_restore_texture.h",
    "shader_tracking.cc",
    "shader_tracking.h",
    "shared_gl_fence_egl.cc",
    "shared_gl_fence_egl.h",
    "sync_control_vsync_provider.cc",
    "sync_control_vsync_provider.h",
    "trace_util.cc",
    "trace_util.h",
  ]

  configs += [ "//build/config:precompiled_headers" ]
  defines = [ "GL_IMPLEMENTATION" ]
  if (enable_gpu_service_logging) {
    defines += [ "GPU_ENABLE_SERVICE_LOGGING" ]
  }

  deps = [
    ":buildflags",
    "//build:chromeos_buildflags",
    "//mojo/public/cpp/bindings",
    "//ui/base:ozone_buildflags",
    "//ui/gfx/mojom",
  ]
  public_deps = [
    ":gl_enums",
    "//base",
    "//third_party/mesa_headers",
    "//ui/events/platform",
    "//ui/gfx",
    "//ui/gfx/geometry",
  ]

  data_deps = []
  if (enable_swiftshader) {
    data_deps += [
      "//third_party/swiftshader/src/Vulkan:icd_file",
      "//third_party/swiftshader/src/Vulkan:swiftshader_libvulkan",
    ]
  }

  if (enable_vulkan) {
    sources += [
      "gl_angle_util_vulkan.cc",
      "gl_angle_util_vulkan.h",
    ]
  }

  if (use_ozone) {
    if (!is_fuchsia) {
      data_deps += [
        "//third_party/angle:libEGL",
        "//third_party/angle:libGLESv2",
      ]
      if (angle_shared_libvulkan && !is_chromeos) {
        data_deps += [ "//third_party/vulkan-loader/src:libvulkan" ]
      }
    }
  }

  if (ozone_platform_x11) {
    sources += [
      "gl_surface_egl_x11.cc",
      "gl_surface_egl_x11.h",
      "gl_surface_egl_x11_gles2.cc",
      "gl_surface_egl_x11_gles2.h",
    ]

    deps += [
      "//ui/base:features",
      "//ui/base/x",
      "//ui/events/platform/x11:x11",
      "//ui/gfx/linux:gpu_memory_buffer_support_x11",
    ]

    data_deps += [
      "//third_party/angle:libEGL",
      "//third_party/angle:libGLESv2",
    ]
    if (angle_shared_libvulkan && !is_chromeos) {
      data_deps += [ "//third_party/vulkan-loader/src:libvulkan" ]
    }
  }

  if (is_win) {
    sources += [
      "child_window_win.cc",
      "child_window_win.h",
      "dc_layer_overlay_image.cc",
      "dc_layer_overlay_image.h",
      "dc_layer_overlay_params.cc",
      "dc_layer_overlay_params.h",
      "dc_layer_tree.cc",
      "dc_layer_tree.h",
      "dcomp_presenter.cc",
      "dcomp_presenter.h",
      "dcomp_surface_proxy.h",
      "dcomp_surface_registry.cc",
      "dcomp_surface_registry.h",
      "debug_utils.cc",
      "debug_utils.h",
      "delegated_ink_point_renderer_gpu.cc",
      "delegated_ink_point_renderer_gpu.h",
      "direct_composition_support.cc",
      "direct_composition_support.h",
      "gl_angle_util_win.cc",
      "gl_angle_util_win.h",
      "gl_fence_win.cc",
      "gl_fence_win.h",
      "hdr_metadata_helper_win.cc",
      "hdr_metadata_helper_win.h",
      "swap_chain_presenter.cc",
      "swap_chain_presenter.h",
      "vsync_provider_win.cc",
      "vsync_provider_win.h",
      "vsync_thread_win.cc",
      "vsync_thread_win.h",
    ]

    libs = [
      "dxgi.lib",
      "dxguid.lib",
      "dwmapi.lib",
    ]
    ldflags = [
      "/DELAYLOAD:dwmapi.dll",
      "/DELAYLOAD:dxgi.dll",
    ]
    deps += [
      "//ui/base",
      "//ui/display:display",
      "//ui/gfx/mojom:dxgi_info",
    ]

    data_deps += [
      "//third_party/angle:libEGL",
      "//third_party/angle:libGLESv2",
      "//third_party/swiftshader/src/Vulkan:icd_file",
      "//third_party/swiftshader/src/Vulkan:swiftshader_libvulkan",
    ]
    if (angle_shared_libvulkan && !is_chromeos) {
      data_deps += [ "//third_party/vulkan-loader/src:libvulkan" ]
    }
  }

  if (is_apple) {
    sources += [
      "ca_renderer_layer_params.cc",
      "ca_renderer_layer_params.h",
      "egl_surface_io_surface.cc",
      "egl_surface_io_surface.h",
      "gl_display_egl.mm",
    ]

    # Do not compile with ARC because //gpu/command_buffer code is not able to
    # be compiled with ARC due to Dawn, and if this code were to be compiled
    # with ARC, it would not link with that code due to mismatches of
    # autoreleasing out parameters.
    configs -= [ "//build/config/compiler:enable_arc" ]

    frameworks = [
      "CoreFoundation.framework",
      "IOSurface.framework",
    ]
  }

  if (is_mac) {
    frameworks += [
      "OpenGL.framework",
      "Quartz.framework",
    ]

    data_deps += [
      "//third_party/angle:libEGL",
      "//third_party/angle:libGLESv2",
      "//third_party/mesa_headers",
    ]
    if (enable_swiftshader) {
      data_deps += [
        "//third_party/swiftshader/src/Vulkan:icd_file",
        "//third_party/swiftshader/src/Vulkan:swiftshader_libvulkan",
      ]
    }

    defines += [ "GL_SILENCE_DEPRECATION" ]
  }

  if (is_android) {
    sources += [
      "android/egl_fence_utils.cc",
      "android/egl_fence_utils.h",
      "android/scoped_a_native_window.cc",
      "android/scoped_a_native_window.h",
      "android/scoped_java_surface.cc",
      "android/scoped_java_surface.h",
      "android/scoped_java_surface_control.cc",
      "android/scoped_java_surface_control.h",
      "android/surface_texture.cc",
      "android/surface_texture.h",
      "android/surface_texture_listener.cc",
      "android/surface_texture_listener.h",
      "gl_surface_egl_surface_control.cc",
      "gl_surface_egl_surface_control.h",
    ]

    defines += [
      "GL_GLEXT_PROTOTYPES",
      "EGL_EGLEXT_PROTOTYPES",
    ]

    libs = [ "android" ]

    deps += [ ":gl_jni_headers" ]
  }

  if (is_android || is_chromeos || is_linux) {
    # Windows doesn't support base::FileDescriptor.
    # libsync isn't supported or needed on MacOSX.
    # Fuchsia is excluded due to a libsync dependency and because it's
    # unknown if the required EGL_ANDROID_native_fence_sync extension works
    # there. If it does and there's a use case, this could be revisited.
    sources += [
      "gl_fence_android_native_fence_sync.cc",
      "gl_fence_android_native_fence_sync.h",
    ]

    deps += [ "//third_party/libsync" ]
  }

  if (is_linux || is_chromeos) {
    deps += [ "//third_party/angle:angle_gpu_info_util" ]
  }
}

if (is_mac) {
  # We need to copy the ANGLE and SwiftShader libraries so that the
  # bundle_data dependencies have a "copy" target type. Otherwise for
  # "shared_library" target types it will try to link things into
  # Chromium Framework when we want to keep the ANGLE and SwiftShader
  # libraries separate instead.
  copy("angle_library_copy") {
    sources = [
      "$root_out_dir/libEGL.dylib",
      "$root_out_dir/libGLESv2.dylib",
    ]
    outputs = [ "$root_out_dir/egl_intermediates/{{source_file_part}}" ]
    deps = [
      "//third_party/angle:libEGL",
      "//third_party/angle:libGLESv2",
    ]
  }

  if (enable_swiftshader) {
    copy("swiftshader_vk_library_copy") {
      sources = [
        "$root_out_dir/libvk_swiftshader.dylib",
        "$root_out_dir/vk_swiftshader_icd.json",
      ]
      outputs = [ "$root_out_dir/vk_intermediates/{{source_file_part}}" ]
      deps = [
        "//third_party/swiftshader/src/Vulkan:icd_file",
        "//third_party/swiftshader/src/Vulkan:swiftshader_libvulkan",
      ]
    }
  }
}

static_library("gl_unittest_utils") {
  testonly = true
  sources = [
    "egl_bindings_autogen_mock.cc",
    "egl_bindings_autogen_mock.h",
    "egl_mock.cc",
    "egl_mock.h",
    "gl_bindings_autogen_mock.cc",
    "gl_bindings_autogen_mock.h",
    "gl_mock.cc",
    "gl_mock.h",
    "gl_mock_autogen_egl.h",
    "gl_mock_autogen_gl.h",
    "gpu_timing_fake.cc",
    "gpu_timing_fake.h",
  ]

  deps = [
    ":gl",
    "//testing/gmock",
    "//testing/gtest",
    "//third_party/angle:includes",
  ]
}

static_library("test_support") {
  testonly = true
  sources = [
    "test/gl_surface_test_support.cc",
    "test/gl_surface_test_support.h",
    "test/gl_test_helper.cc",
    "test/gl_test_helper.h",
    "test/gl_test_support.cc",
    "test/gl_test_support.h",
  ]

  public_deps = [
    ":gl",
    "//ui/gl/init",
  ]
  deps = [
    "//base/test:test_support",
    "//testing/gtest",
    "//third_party/angle:includes",
    "//ui/base",
  ]

  if (is_linux || is_chromeos) {
    deps += [ "//ui/platform_window/common" ]
  }

  if (use_ozone) {
    deps += [ "//ui/ozone" ]
  }

  # If the run-time search path isn't set properly when we use ANGLE with its
  # Vulkan backend, it may end up finding the system libvulkan.so rather than
  # the one built in the output directory
  if ((is_linux || is_chromeos) && !is_component_build) {
    all_dependent_configs =
        [ "//build/config/gcc:rpath_for_built_shared_libraries" ]
  }
}

source_set("run_all_unittests") {
  testonly = true

  sources = [ "test/run_all_unittests.cc" ]

  deps = [
    "//base",
    "//ui/base:features",
  ]

  public_deps = [ "//base/test:test_support" ]

  if (use_ozone) {
    deps += [
      "//mojo/core/embedder",
      "//services/service_manager/public/cpp/test:test_support",
      "//ui/ozone",
    ]
  }
}

test("gl_unittests") {
  use_xvfb = use_xvfb_in_this_config

  sources = [
    "egl_api_unittest.cc",
    "gl_api_unittest.cc",
    "gl_display_manager_unittest.cc",
    "gl_version_info_unittest.cc",
    "gpu_timing_unittest.cc",
    "test/egl_initialization_displays_unittest.cc",
  ]

  if (!use_ozone) {
    sources += [ "gl_surface_egl_unittest.cc" ]
  }

  if (is_win) {
    sources += [
      "dcomp_presenter_unittest.cc",
      "delegated_ink_point_renderer_gpu_unittest.cc",
      "gl_fence_win_unittest.cc",
      "hdr_metadata_helper_win_unittest.cc",
    ]
  }

  deps = [
    ":gl",
    ":gl_unittest_utils",
    ":run_all_unittests",
    ":test_support",
    "//base",
    "//testing/gmock",
    "//testing/gtest",
    "//third_party/angle:includes",
    "//ui/base:base",
    "//ui/gfx",
    "//ui/gfx:test_support",
    "//ui/gfx/geometry",
    "//ui/gl/init",
    "//ui/platform_window",
    "//ui/platform_window:platform_impls",
  ]

  data_deps = [
    "//testing/buildbot/filters:gl_unittests_filters",
    "//third_party/mesa_headers",
  ]

  if (is_win) {
    deps += [
      "//media/base/win:test_support",
      "//ui/base:pixel_diff_test_support",
    ]
    libs = [ "dxguid.lib" ]
  }

  if (use_ozone) {
    deps += [ "//ui/ozone" ]
  }
}

# We can't run this test on real Chrome OS hardware for Ozone, so new target.
group("gl_unittests_ozone") {
  testonly = true
  data_deps = [ ":gl_unittests" ]
}

if (is_android) {
  generate_jar_jni("surface_jni_headers") {
    classes = [ "android/view/Surface.class" ]
  }

  generate_jni("gl_jni_headers") {
    sources = [
      "../android/java/src/org/chromium/ui/gl/ScopedJavaSurfaceControl.java",
      "../android/java/src/org/chromium/ui/gl/SurfaceTextureListener.java",
      "../android/java/src/org/chromium/ui/gl/SurfaceTexturePlatformWrapper.java",
    ]
    public_deps = [ ":surface_jni_headers" ]
  }
}