# Copyright 2014 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.

import("//build/buildflag_header.gni")
import("//build/config/chrome_build.gni")
import("//build/config/linux/pkg_config.gni")
import("//build/config/ui.gni")
import("//ui/ozone/ozone.gni")
import("//testing/test.gni")

declare_args() {
  enable_swiftshader = is_chrome_branded && is_win
}

use_egl = is_win || is_android || is_linux
use_glx = use_x11 || ozone_platform_x11

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

buildflag_header("gl_features") {
  header = "gl_features.h"
  flags = [ "ENABLE_SWIFTSHADER=$enable_swiftshader" ]
}

config("gl_config") {
  defines = []
  if (use_glx) {
    defines += [
      "GL_GLEXT_PROTOTYPES",
      "USE_GLX",
    ]
  }
  if (use_egl) {
    defines += [ "USE_EGL" ]
  }
}

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

  sources = [
    "android/gl_jni_registrar.cc",
    "android/gl_jni_registrar.h",
    "android/scoped_java_surface.cc",
    "android/scoped_java_surface.h",
    "android/surface_texture.cc",
    "android/surface_texture.h",
    "android/surface_texture_listener.cc",
    "android/surface_texture_listener.h",
    "ca_renderer_layer_params.cc",
    "ca_renderer_layer_params.h",
    "gl_bindings.cc",
    "gl_bindings.h",
    "gl_bindings_autogen_gl.cc",
    "gl_bindings_autogen_gl.h",
    "gl_bindings_autogen_osmesa.cc",
    "gl_bindings_autogen_osmesa.h",
    "gl_context.cc",
    "gl_context.h",
    "gl_context_osmesa.cc",
    "gl_context_osmesa.h",
    "gl_context_stub.cc",
    "gl_context_stub.h",
    "gl_context_stub_with_extensions.cc",
    "gl_context_stub_with_extensions.h",
    "gl_enums.cc",
    "gl_enums.h",
    "gl_enums_implementation_autogen.h",
    "gl_export.h",
    "gl_fence.cc",
    "gl_fence.h",
    "gl_fence_arb.cc",
    "gl_fence_arb.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_image.cc",
    "gl_image.h",
    "gl_image_memory.cc",
    "gl_image_memory.h",
    "gl_image_ref_counted_memory.cc",
    "gl_image_ref_counted_memory.h",
    "gl_image_shared_memory.cc",
    "gl_image_shared_memory.h",
    "gl_image_stub.cc",
    "gl_image_stub.h",
    "gl_implementation.cc",
    "gl_implementation.h",
    "gl_osmesa_api_implementation.cc",
    "gl_osmesa_api_implementation.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_osmesa.cc",
    "gl_surface_osmesa.h",
    "gl_surface_overlay.cc",
    "gl_surface_overlay.h",
    "gl_surface_stub.cc",
    "gl_surface_stub.h",
    "gl_switches.cc",
    "gl_switches.h",
    "gl_version_info.cc",
    "gl_version_info.h",
    "gpu_switching_manager.cc",
    "gpu_switching_manager.h",
    "gpu_timing.cc",
    "gpu_timing.h",
    "scoped_api.cc",
    "scoped_api.h",
    "scoped_binders.cc",
    "scoped_binders.h",
    "scoped_make_current.cc",
    "scoped_make_current.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" ]

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

  all_dependent_configs = [ ":gl_config" ]

  public_configs = [ "//third_party/khronos:khronos_headers" ]

  deps = [
    "//base/third_party/dynamic_annotations",
  ]
  public_deps = [
    "//base",
    "//third_party/mesa:mesa_headers",
    "//ui/events/platform",
    "//ui/gfx",
    "//ui/gfx/geometry",
  ]

  if (use_egl) {
    sources += [
      "egl_util.cc",
      "egl_util.h",
      "gl_bindings_autogen_egl.cc",
      "gl_bindings_autogen_egl.h",
      "gl_context_egl.cc",
      "gl_context_egl.h",
      "gl_egl_api_implementation.cc",
      "gl_egl_api_implementation.h",
      "gl_fence_egl.cc",
      "gl_fence_egl.h",
      "gl_image_egl.cc",
      "gl_image_egl.h",
      "gl_surface_egl.cc",
      "gl_surface_egl.h",
    ]
  }
  if (is_android || is_linux) {
    sources += [
      "gl_implementation_osmesa.cc",
      "gl_implementation_osmesa.h",
    ]
  }
  if (use_x11) {
    sources += [
      "gl_surface_egl_x11.cc",
      "gl_surface_egl_x11.h",
      "gl_surface_glx_x11.cc",
      "gl_surface_glx_x11.h",
      "gl_surface_osmesa_x11.cc",
      "gl_surface_osmesa_x11.h",
    ]

    deps += [ "//ui/base/x" ]

    data_deps = [
      "//third_party/angle:libEGL",
      "//third_party/angle:libGLESv2",
    ]
  }
  if (use_glx) {
    sources += [
      "gl_bindings_autogen_glx.cc",
      "gl_bindings_autogen_glx.h",
      "gl_context_glx.cc",
      "gl_context_glx.h",
      "gl_glx_api_implementation.cc",
      "gl_glx_api_implementation.h",
      "gl_image_glx.cc",
      "gl_image_glx.h",
      "gl_surface_glx.cc",
      "gl_surface_glx.h",
      "gl_visual_picker_glx.cc",
      "gl_visual_picker_glx.h",
    ]

    configs += [
      "//build/config/linux:x11",
      "//build/config/linux:xcomposite",
      "//build/config/linux:xext",
    ]

    deps += [ "//ui/gfx/x" ]
  }
  if (is_win) {
    sources += [
      "angle_platform_impl.cc",
      "angle_platform_impl.h",
      "gl_bindings_autogen_wgl.cc",
      "gl_bindings_autogen_wgl.h",
      "gl_context_wgl.cc",
      "gl_context_wgl.h",
      "gl_surface_osmesa_win.cc",
      "gl_surface_osmesa_win.h",
      "gl_surface_wgl.cc",
      "gl_surface_wgl.h",
      "gl_wgl_api_implementation.cc",
      "gl_wgl_api_implementation.h",
      "vsync_provider_win.cc",
      "vsync_provider_win.h",
    ]

    libs = [ "dwmapi.lib" ]
    ldflags = [ "/DELAYLOAD:dwmapi.dll" ]

    data_deps = [
      "//third_party/angle:libEGL",
      "//third_party/angle:libGLESv2",
      "//third_party/mesa:osmesa",
    ]
  }
  if (is_mac) {
    sources += [
      "gl_context_cgl.cc",
      "gl_context_cgl.h",
      "gl_fence_apple.cc",
      "gl_fence_apple.h",
      "gl_image_io_surface.h",
      "gl_image_io_surface.mm",
      "scoped_cgl.cc",
      "scoped_cgl.h",
      "yuv_to_rgb_converter.cc",
      "yuv_to_rgb_converter.h",
    ]

    libs = [
      "CoreFoundation.framework",
      "IOSurface.framework",
      "OpenGL.framework",
      "Quartz.framework",
    ]
  }
  if (is_android) {
    sources += [
      "gl_image_surface_texture.cc",
      "gl_image_surface_texture.h",
    ]

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

    libs = [ "android" ]

    deps += [ ":gl_jni_headers" ]
  }

  if (use_qt) {
    if (is_win || use_x11) {
      data_deps -= [
        "//third_party/angle:libEGL",
        "//third_party/angle:libGLESv2",
      ]
    }
    if (is_win) {
      data_deps -= [
        "//third_party/mesa:osmesa",
      ]
    }
    if (is_linux) {
      sources -= [
        "gl_surface_egl.cc",
        "gl_surface_egl.h",
      ]
    }
    if (use_x11) {
      sources -= [
        "gl_surface_egl_x11.cc",
        "gl_surface_egl_x11.h",
        "gl_surface_glx.cc",
        "gl_surface_glx.h",
      ]
    }
  }
}

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

  configs += [ "//third_party/khronos:khronos_headers" ]

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

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

  configs += [ "//third_party/khronos:khronos_headers" ]

  public_deps = [
    ":gl",
    "//ui/gl/init",
  ]
  deps = [
    "//testing/gtest",
  ]

  if (use_x11) {
    configs += [ "//build/config/linux:x11" ]
    deps += [ "//ui/platform_window/x11" ]
  }

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

source_set("run_all_unittests") {
  testonly = true

  sources = [
    "test/run_all_unittests.cc",
  ]

  deps = [
    "//base",
  ]

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

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

test("gl_unittests") {
  sources = [
    "gl_api_unittest.cc",
    "gl_image_ref_counted_memory_unittest.cc",
    "gl_image_shared_memory_unittest.cc",
    "gl_version_info_unittest.cc",
    "gpu_timing_unittest.cc",
  ]

  if (use_egl) {
    sources += [
      "egl_api_unittest.cc",
      "test/egl_initialization_displays_unittest.cc",
    ]
  }

  if (use_glx) {
    sources += [ "glx_api_unittest.cc" ]
  }

  if (is_mac) {
    sources += [ "gl_image_io_surface_unittest.cc" ]
    libs = [ "IOSurface.framework" ]
  }

  if (is_win) {
    sources += [ "wgl_api_unittest.cc" ]
  }

  include_dirs = [ "//third_party/khronos" ]

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

  data_deps = [
    "//third_party/mesa:osmesa",
  ]
}

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

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