ParallelCompile: add GL backend support

For GL backend, at first each worker thread must have a naitve context
for its own to work in. These worker contexts have to be shared from
the main context, so that all shader and program objects are seen in
any context. This extends backend displays to create and destroy the
worker contexts. RendererGL manages and allocates them to the worker
threads. ShaderImpl has a new compile method added to do the actual
glCompile work in worker thread. The ProgramGL's link method is broken
down by introducing the LinkEventGL class.

Bug: chromium:849576

Change-Id: Idc2c51b4b6c978781ae77810e62c480acc67ebb5
Reviewed-on: https://chromium-review.googlesource.com/c/1373015
Commit-Queue: Jie A Chen <jie.a.chen@intel.com>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/tests/perf_tests/LinkProgramPerfTest.cpp b/src/tests/perf_tests/LinkProgramPerfTest.cpp
index 78dafcf..59cb0ac 100644
--- a/src/tests/perf_tests/LinkProgramPerfTest.cpp
+++ b/src/tests/perf_tests/LinkProgramPerfTest.cpp
@@ -19,7 +19,7 @@
 namespace
 {
 
-enum class LinkProgramOption
+enum class TaskOption
 {
     CompileOnly,
     CompileAndLink,
@@ -27,9 +27,17 @@
     Unspecified
 };
 
+enum class ThreadOption
+{
+    SingleThread,
+    MultiThread,
+
+    Unspecified
+};
+
 struct LinkProgramParams final : public RenderTestParams
 {
-    LinkProgramParams(LinkProgramOption optionIn)
+    LinkProgramParams(TaskOption taskOptionIn, ThreadOption threadOptionIn)
     {
         iterationsPerStep = 1;
 
@@ -37,7 +45,8 @@
         minorVersion = 0;
         windowWidth  = 256;
         windowHeight = 256;
-        option       = optionIn;
+        taskOption   = taskOptionIn;
+        threadOption = threadOptionIn;
     }
 
     std::string suffix() const override
@@ -45,10 +54,23 @@
         std::stringstream strstr;
         strstr << RenderTestParams::suffix();
 
-        if (option == LinkProgramOption::CompileOnly)
+        if (taskOption == TaskOption::CompileOnly)
         {
             strstr << "_compile_only";
         }
+        else if (taskOption == TaskOption::CompileAndLink)
+        {
+            strstr << "_compile_and_link";
+        }
+
+        if (threadOption == ThreadOption::SingleThread)
+        {
+            strstr << "_single_thread";
+        }
+        else if (threadOption == ThreadOption::MultiThread)
+        {
+            strstr << "_multi_thread";
+        }
 
         if (eglParameters.deviceType == EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE)
         {
@@ -58,7 +80,8 @@
         return strstr.str();
     }
 
-    LinkProgramOption option;
+    TaskOption taskOption;
+    ThreadOption threadOption;
 };
 
 std::ostream &operator<<(std::ostream &os, const LinkProgramParams &params)
@@ -85,6 +108,11 @@
 
 void LinkProgramBenchmark::initializeBenchmark()
 {
+    if (GetParam().threadOption == ThreadOption::SingleThread)
+    {
+        glMaxShaderCompilerThreadsKHR(0);
+    }
+
     std::array<Vector3, 6> vertices = {{Vector3(-1.0f, 1.0f, 0.5f), Vector3(-1.0f, -1.0f, 0.5f),
                                         Vector3(1.0f, -1.0f, 0.5f), Vector3(-1.0f, 1.0f, 0.5f),
                                         Vector3(1.0f, -1.0f, 0.5f), Vector3(1.0f, 1.0f, 0.5f)}};
@@ -117,7 +145,7 @@
 
     ASSERT_NE(0u, vs);
     ASSERT_NE(0u, fs);
-    if (GetParam().option == LinkProgramOption::CompileOnly)
+    if (GetParam().taskOption == TaskOption::CompileOnly)
     {
         glDeleteShader(vs);
         glDeleteShader(fs);
@@ -146,30 +174,30 @@
 
 using namespace egl_platform;
 
-LinkProgramParams LinkProgramD3D11Params(LinkProgramOption option)
+LinkProgramParams LinkProgramD3D11Params(TaskOption taskOption, ThreadOption threadOption)
 {
-    LinkProgramParams params(option);
+    LinkProgramParams params(taskOption, threadOption);
     params.eglParameters = D3D11();
     return params;
 }
 
-LinkProgramParams LinkProgramD3D9Params(LinkProgramOption option)
+LinkProgramParams LinkProgramD3D9Params(TaskOption taskOption, ThreadOption threadOption)
 {
-    LinkProgramParams params(option);
+    LinkProgramParams params(taskOption, threadOption);
     params.eglParameters = D3D9();
     return params;
 }
 
-LinkProgramParams LinkProgramOpenGLOrGLESParams(LinkProgramOption option)
+LinkProgramParams LinkProgramOpenGLOrGLESParams(TaskOption taskOption, ThreadOption threadOption)
 {
-    LinkProgramParams params(option);
+    LinkProgramParams params(taskOption, threadOption);
     params.eglParameters = OPENGL_OR_GLES(false);
     return params;
 }
 
-LinkProgramParams LinkProgramVulkanParams(LinkProgramOption option)
+LinkProgramParams LinkProgramVulkanParams(TaskOption taskOption, ThreadOption threadOption)
 {
-    LinkProgramParams params(option);
+    LinkProgramParams params(taskOption, threadOption);
     params.eglParameters = VULKAN();
     return params;
 }
@@ -179,14 +207,23 @@
     run();
 }
 
-ANGLE_INSTANTIATE_TEST(LinkProgramBenchmark,
-                       LinkProgramD3D11Params(LinkProgramOption::CompileOnly),
-                       LinkProgramD3D9Params(LinkProgramOption::CompileOnly),
-                       LinkProgramOpenGLOrGLESParams(LinkProgramOption::CompileOnly),
-                       LinkProgramVulkanParams(LinkProgramOption::CompileOnly),
-                       LinkProgramD3D11Params(LinkProgramOption::CompileAndLink),
-                       LinkProgramD3D9Params(LinkProgramOption::CompileAndLink),
-                       LinkProgramOpenGLOrGLESParams(LinkProgramOption::CompileAndLink),
-                       LinkProgramVulkanParams(LinkProgramOption::CompileAndLink));
+ANGLE_INSTANTIATE_TEST(
+    LinkProgramBenchmark,
+    LinkProgramD3D11Params(TaskOption::CompileOnly, ThreadOption::MultiThread),
+    LinkProgramD3D9Params(TaskOption::CompileOnly, ThreadOption::MultiThread),
+    LinkProgramOpenGLOrGLESParams(TaskOption::CompileOnly, ThreadOption::MultiThread),
+    LinkProgramVulkanParams(TaskOption::CompileOnly, ThreadOption::MultiThread),
+    LinkProgramD3D11Params(TaskOption::CompileAndLink, ThreadOption::MultiThread),
+    LinkProgramD3D9Params(TaskOption::CompileAndLink, ThreadOption::MultiThread),
+    LinkProgramOpenGLOrGLESParams(TaskOption::CompileAndLink, ThreadOption::MultiThread),
+    LinkProgramVulkanParams(TaskOption::CompileAndLink, ThreadOption::MultiThread),
+    LinkProgramD3D11Params(TaskOption::CompileOnly, ThreadOption::SingleThread),
+    LinkProgramD3D9Params(TaskOption::CompileOnly, ThreadOption::SingleThread),
+    LinkProgramOpenGLOrGLESParams(TaskOption::CompileOnly, ThreadOption::SingleThread),
+    LinkProgramVulkanParams(TaskOption::CompileOnly, ThreadOption::SingleThread),
+    LinkProgramD3D11Params(TaskOption::CompileAndLink, ThreadOption::SingleThread),
+    LinkProgramD3D9Params(TaskOption::CompileAndLink, ThreadOption::SingleThread),
+    LinkProgramOpenGLOrGLESParams(TaskOption::CompileAndLink, ThreadOption::SingleThread),
+    LinkProgramVulkanParams(TaskOption::CompileAndLink, ThreadOption::SingleThread));
 
 }  // anonymous namespace