Add EGL_PLATFORM_ANGLE_DISPLAY_KEY_ANGLE

To allow the creation of multiple EGLDisplays on the same graphics
device, we need a value to key for the display cache. When the
display key is specified, the cache will return a new display for
that key, even if there is an existing display on the same graphics
device.

Bug: chromium:1251724
Change-Id: I55e169776770734fc33b8bc8e1265ea6f7472fe3
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/4255730
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Commit-Queue: Geoff Lang <geofflang@chromium.org>
diff --git a/extensions/EGL_ANGLE_platform_angle_device_id.txt b/extensions/EGL_ANGLE_platform_angle_device_id.txt
index aa2c302..27a5a5e 100644
--- a/extensions/EGL_ANGLE_platform_angle_device_id.txt
+++ b/extensions/EGL_ANGLE_platform_angle_device_id.txt
@@ -57,6 +57,7 @@
 
         EGL_PLATFORM_ANGLE_DEVICE_ID_HIGH_ANGLE          0x34D6
         EGL_PLATFORM_ANGLE_DEVICE_ID_LOW_ANGLE           0x34D7
+        EGL_PLATFORM_ANGLE_DISPLAY_KEY_ANGLE             0x34DA
 
 Additions to the EGL Specification
 
@@ -77,12 +78,22 @@
     If the ID specified doesn't match any devices on the system, the device
     is selected as described in the EGL_ANGLE_display_power_preference extension.
 
+    To select a distinct display on a graphics device that may already have
+    an existing display in ANGLE's cache, use EGL_PLATFORM_ANGLE_DISPLAY_KEY_ANGLE
+    to add a key to the cache entry for this display. The same cached display can
+    be re-requested by specifying the same cache value. If this parameter is not
+    included, the default value used will be 0.
+
 Issues
 
     None
 
 Revision History
 
+    Version 3, 2023-02-15
+      - Add EGL_PLATFORM_ANGLE_DISPLAY_KEY_ANGLE to allow selection of
+        multiple EGLDisplays from the same graphics device.
+
     Version 2, 2022-04-09 (Kimmo Kinnunen)
       - Describe interaction with EGL_ANGLE_display_power_preference,
         EGL_ANGLE_platform_angle_device_id takes precedence.
diff --git a/include/EGL/eglext_angle.h b/include/EGL/eglext_angle.h
index fa9a346..2fb20ea 100644
--- a/include/EGL/eglext_angle.h
+++ b/include/EGL/eglext_angle.h
@@ -134,6 +134,7 @@
 #define EGL_ANGLE_platform_angle_device_id
 #define EGL_PLATFORM_ANGLE_DEVICE_ID_HIGH_ANGLE 0x34D6
 #define EGL_PLATFORM_ANGLE_DEVICE_ID_LOW_ANGLE 0x34D7
+#define EGL_PLATFORM_ANGLE_DISPLAY_KEY_ANGLE 0x34DA
 #endif /* EGL_ANGLE_platform_angle_device_id */
 
 #ifndef EGL_ANGLE_x11_visual
diff --git a/src/libANGLE/Display.cpp b/src/libANGLE/Display.cpp
index f980ad2..49a09c4 100644
--- a/src/libANGLE/Display.cpp
+++ b/src/libANGLE/Display.cpp
@@ -124,18 +124,20 @@
                          EGLAttrib powerPreference,
                          EGLAttrib platformANGLEType,
                          EGLAttrib deviceIdHigh,
-                         EGLAttrib deviceIdLow)
+                         EGLAttrib deviceIdLow,
+                         EGLAttrib displayKey)
         : nativeDisplayType(nativeDisplayType),
           powerPreference(powerPreference),
           platformANGLEType(platformANGLEType),
           deviceIdHigh(deviceIdHigh),
-          deviceIdLow(deviceIdLow)
+          deviceIdLow(deviceIdLow),
+          displayKey(displayKey)
     {}
 
     auto tie() const
     {
         return std::tie(nativeDisplayType, powerPreference, platformANGLEType, deviceIdHigh,
-                        deviceIdLow);
+                        deviceIdLow, displayKey);
     }
 
     EGLNativeDisplayType nativeDisplayType{EGL_DEFAULT_DISPLAY};
@@ -143,6 +145,7 @@
     EGLAttrib platformANGLEType{EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE};
     EGLAttrib deviceIdHigh{0};
     EGLAttrib deviceIdLow{0};
+    EGLAttrib displayKey{0};
 };
 
 inline bool operator==(const ANGLEPlatformDisplay &a, const ANGLEPlatformDisplay &b)
@@ -717,10 +720,11 @@
         updatedAttribMap.get(EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE);
     EGLAttrib deviceIdHigh = updatedAttribMap.get(EGL_PLATFORM_ANGLE_DEVICE_ID_HIGH_ANGLE, 0);
     EGLAttrib deviceIdLow  = updatedAttribMap.get(EGL_PLATFORM_ANGLE_DEVICE_ID_LOW_ANGLE, 0);
+    EGLAttrib displayKey   = updatedAttribMap.get(EGL_PLATFORM_ANGLE_DISPLAY_KEY_ANGLE, 0);
     ANGLEPlatformDisplayMap *displays = GetANGLEPlatformDisplayMap();
-    ANGLEPlatformDisplay displayKey(nativeDisplay, powerPreference, platformANGLEType, deviceIdHigh,
-                                    deviceIdLow);
-    const auto &iter = displays->find(displayKey);
+    ANGLEPlatformDisplay combinedDisplayKey(nativeDisplay, powerPreference, platformANGLEType,
+                                            deviceIdHigh, deviceIdLow, displayKey);
+    const auto &iter = displays->find(combinedDisplayKey);
     if (iter != displays->end())
     {
         display = iter->second;
@@ -735,7 +739,7 @@
         }
 
         display = new Display(platform, nativeDisplay, nullptr);
-        displays->insert(std::make_pair(displayKey, display));
+        displays->insert(std::make_pair(combinedDisplayKey, display));
     }
     // Apply new attributes if the display is not initialized yet.
     if (!display->isInitialized())
@@ -902,7 +906,8 @@
                 mAttributeMap.get(EGL_PLATFORM_ANGLE_TYPE_ANGLE,
                                   EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE),
                 mAttributeMap.get(EGL_PLATFORM_ANGLE_DEVICE_ID_HIGH_ANGLE, 0),
-                mAttributeMap.get(EGL_PLATFORM_ANGLE_DEVICE_ID_LOW_ANGLE, 0)));
+                mAttributeMap.get(EGL_PLATFORM_ANGLE_DEVICE_ID_LOW_ANGLE, 0),
+                mAttributeMap.get(EGL_PLATFORM_ANGLE_DISPLAY_KEY_ANGLE, 0)));
             if (iter != displays->end())
             {
                 displays->erase(iter);
diff --git a/src/libANGLE/validationEGL.cpp b/src/libANGLE/validationEGL.cpp
index 401a182..c22fe859 100644
--- a/src/libANGLE/validationEGL.cpp
+++ b/src/libANGLE/validationEGL.cpp
@@ -782,6 +782,7 @@
                     break;
                 case EGL_PLATFORM_ANGLE_DEVICE_ID_HIGH_ANGLE:
                 case EGL_PLATFORM_ANGLE_DEVICE_ID_LOW_ANGLE:
+                case EGL_PLATFORM_ANGLE_DISPLAY_KEY_ANGLE:
                     if (!clientExtensions.platformANGLEDeviceId)
                     {
                         val->setError(EGL_BAD_ATTRIBUTE,