GN: ANGLE

Angle's existing GN files only work in Chrome, so I've written a new one.

This won't work on Windows, but our GN build doesn't work on Windows anyway.  So this CL is an attempt to get a ahead of that curve on ANGLE.  It looks large but fairly straightforward.

Now working on Linux:
  $ gn gen angle --args=skia_use_angle=true
  $ ninja -C angle
  $ angle/dm --config angle-gl --src gm -w dm-out

BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2361983002

Review-Url: https://codereview.chromium.org/2361983002
diff --git a/BUILD.gn b/BUILD.gn
index 26a23be..66795fd 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -10,6 +10,7 @@
 }
 
 declare_args() {
+  skia_use_angle = false
   skia_use_expat = true
   skia_use_fontconfig = is_linux
   skia_use_freetype = is_android || is_fuchsia || is_linux
@@ -631,6 +632,8 @@
     if (skia_enable_gpu) {
       public_defines = []
       public_include_dirs += [ "tools/gpu" ]
+
+      deps = []
       sources = [
         "tools/gpu/GrContextFactory.cpp",
         "tools/gpu/GrTest.cpp",
@@ -656,14 +659,19 @@
         sources += [ "tools/gpu/gl/mac/CreatePlatformGLTestContext_mac.cpp" ]
       }
 
-      if (skia_use_vulkan) {
-        sources += [ "tools/gpu/vk/VkTestContext.cpp" ]
+      if (skia_use_angle) {
+        public_defines += [ "SK_ANGLE" ]
+        deps += [ "//third_party/angle2" ]
+        sources += [ "tools/gpu/gl/angle/GLTestContext_angle.cpp" ]
       }
       if (skia_use_mesa) {
         public_defines += [ "SK_MESA" ]
         sources += [ "tools/gpu/gl/mesa/GLTestContext_mesa.cpp" ]
         libs += [ "OSMesa" ]
       }
+      if (skia_use_vulkan) {
+        sources += [ "tools/gpu/vk/VkTestContext.cpp" ]
+      }
     }
   }
 
diff --git a/infra/bots/recipe_modules/flavor/gn_flavor.py b/infra/bots/recipe_modules/flavor/gn_flavor.py
index 81aa121..185ef7e 100644
--- a/infra/bots/recipe_modules/flavor/gn_flavor.py
+++ b/infra/bots/recipe_modules/flavor/gn_flavor.py
@@ -14,6 +14,7 @@
     return any([
       'CT' in extra_config,
       'SAN' in extra_config,
+      extra_config == 'ANGLE' and 'Win' not in os,
       extra_config == 'CommandBuffer',
       extra_config == 'Fast',
       extra_config == 'GN',
@@ -73,6 +74,8 @@
 
     if configuration != 'Debug':
       args['is_debug'] = 'false'
+    if extra_config == 'ANGLE':
+      args['skia_use_angle'] = 'true'
     if extra_config == 'CommandBuffer':
       self.m.run.run_once(self.build_command_buffer)
     if extra_config == 'MSAN':
diff --git a/infra/bots/recipes/swarm_compile.expected/Build-Ubuntu-GCC-x86_64-Release-ANGLE.json b/infra/bots/recipes/swarm_compile.expected/Build-Ubuntu-GCC-x86_64-Release-ANGLE.json
index 3c9b54e..05ea9e4 100644
--- a/infra/bots/recipes/swarm_compile.expected/Build-Ubuntu-GCC-x86_64-Release-ANGLE.json
+++ b/infra/bots/recipes/swarm_compile.expected/Build-Ubuntu-GCC-x86_64-Release-ANGLE.json
@@ -121,19 +121,38 @@
   },
   {
     "cmd": [
-      "make",
-      "most"
+      "[CUSTOM_/_B_WORK]/skia/bin/fetch-gn"
     ],
     "cwd": "[CUSTOM_/_B_WORK]/skia",
     "env": {
-      "BUILDTYPE": "Release",
-      "CHROME_HEADLESS": "1",
-      "CHROME_PATH": "[SLAVE_BUILD]/src",
-      "GYP_DEFINES": "chromeos=0 skia_angle=1 skia_arch_type=x86_64 skia_warnings_as_errors=1 use_x11=1",
-      "PATH": "%(PATH)s:RECIPE_PACKAGE_REPO[depot_tools]:RECIPE_PACKAGE_REPO[depot_tools]:RECIPE_PACKAGE_REPO[depot_tools]:RECIPE_PACKAGE_REPO[depot_tools]",
-      "SKIA_OUT": "[CUSTOM_/_B_WORK]/skia/out/Build-Ubuntu-GCC-x86_64-Release-ANGLE"
+      "PATH": "%(PATH)s:RECIPE_PACKAGE_REPO[depot_tools]:RECIPE_PACKAGE_REPO[depot_tools]:RECIPE_PACKAGE_REPO[depot_tools]:RECIPE_PACKAGE_REPO[depot_tools]"
     },
-    "name": "build most"
+    "name": "fetch-gn"
+  },
+  {
+    "cmd": [
+      "gn",
+      "gen",
+      "[CUSTOM_/_B_WORK]/skia/out/Build-Ubuntu-GCC-x86_64-Release-ANGLE/Release",
+      "--args=cc=\"gcc\" cxx=\"g++\" is_debug=false skia_use_angle=true"
+    ],
+    "cwd": "[CUSTOM_/_B_WORK]/skia",
+    "env": {
+      "PATH": "%(PATH)s:RECIPE_PACKAGE_REPO[depot_tools]:RECIPE_PACKAGE_REPO[depot_tools]:RECIPE_PACKAGE_REPO[depot_tools]:RECIPE_PACKAGE_REPO[depot_tools]"
+    },
+    "name": "gn gen"
+  },
+  {
+    "cmd": [
+      "ninja",
+      "-C",
+      "[CUSTOM_/_B_WORK]/skia/out/Build-Ubuntu-GCC-x86_64-Release-ANGLE/Release"
+    ],
+    "cwd": "[CUSTOM_/_B_WORK]/skia",
+    "env": {
+      "PATH": "%(PATH)s:RECIPE_PACKAGE_REPO[depot_tools]:RECIPE_PACKAGE_REPO[depot_tools]:RECIPE_PACKAGE_REPO[depot_tools]:RECIPE_PACKAGE_REPO[depot_tools]"
+    },
+    "name": "ninja"
   },
   {
     "cmd": [
diff --git a/third_party/angle2/BUILD.gn b/third_party/angle2/BUILD.gn
new file mode 100644
index 0000000..3ae0f8e
--- /dev/null
+++ b/third_party/angle2/BUILD.gn
@@ -0,0 +1,115 @@
+# Copyright 2016 Google Inc.
+#
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+declare_args() {
+}
+
+angle_root = "../externals/angle2"
+
+import("../third_party.gni")
+
+third_party("angle2") {
+  public_include_dirs = [ "$angle_root/include" ]
+  deps = [
+    ":libEGL",
+    ":libGLESv2",
+  ]
+}
+
+compiler_gypi = exec_script("//gn/gypi_to_gn.py",
+                            [ rebase_path("$angle_root/src/compiler.gypi") ],
+                            "scope",
+                            [])
+
+gles_gypi = exec_script("//gn/gypi_to_gn.py",
+                        [ rebase_path("$angle_root/src/libGLESv2.gypi") ],
+                        "scope",
+                        [])
+
+config("common") {
+  cflags = [ "-w" ]
+  defines = [
+    "ANGLE_ENABLE_ESSL",
+    "ANGLE_ENABLE_GLSL",
+    "GL_GLEXT_PROTOTYPES",
+    "EGL_EGLEXT_PROTOTYPES",
+  ]
+  include_dirs = [
+    "$root_gen_dir/angle2",
+    "$angle_root/include",
+    "$angle_root/src",
+    "$angle_root/src/common/third_party/numerics",
+  ]
+
+  assert(is_linux)  # TODO: is_win, of course, maybe is_mac?
+  if (is_linux) {
+    defines += [
+      "ANGLE_ENABLE_OPENGL",
+      "ANGLE_USE_X11",
+      "GL_APICALL=__attribute__((visibility(\"default\")))",
+      "EGLAPI=__attribute__((visibility(\"default\")))",
+    ]
+  }
+}
+
+copy("commit_id") {
+  sources = [
+    "$angle_root/src/commit.h",
+  ]
+  outputs = [
+    "$root_gen_dir/angle2/id/commit.h",
+  ]
+}
+
+shared_library("libGLESv2") {
+  configs += [ ":common" ]
+  defines = [ "LIBGLESV2_IMPLEMENTATION" ]
+  deps = [
+    ":commit_id",
+  ]
+  libs = []
+  sources = rebase_path(compiler_gypi.angle_preprocessor_sources +
+                            compiler_gypi.angle_translator_lib_sources +
+                            compiler_gypi.angle_translator_lib_essl_sources +
+                            compiler_gypi.angle_translator_lib_glsl_sources +
+                            gles_gypi.libangle_sources +
+                            gles_gypi.libangle_common_sources +
+                            gles_gypi.libangle_image_util_sources +
+                            gles_gypi.libglesv2_sources,
+                        ".",
+                        "$angle_root/src") +
+            [
+              "$angle_root/src/compiler/translator/ShaderLang.cpp",
+              "$angle_root/src/compiler/translator/ShaderVars.cpp",
+            ]
+  if (!is_win) {
+    sources -= [ "$angle_root/src/libGLESv2/libGLESv2.def" ]
+  }
+
+  if (is_linux) {
+    libs += [
+      "X11",
+      "Xi",
+      "Xext",
+    ]
+    sources += rebase_path(gles_gypi.libangle_gl_sources +
+                               gles_gypi.libangle_gl_glx_sources,
+                           ".",
+                           "$angle_root/src") +
+               [ "$angle_root/src/third_party/libXNVCtrl/NVCtrl.c" ]
+  }
+}
+
+shared_library("libEGL") {
+  configs += [ ":common" ]
+  defines = [ "LIBEGL_IMPLEMENTATION" ]
+  deps = [
+    ":libGLESv2",
+  ]
+  sources = rebase_path(gles_gypi.libegl_sources, ".", "$angle_root/src")
+  if (!is_win) {
+    sources -= [ "$angle_root/src/libEGL/libEGL.def" ]
+  }
+}