xref: /aosp_15_r20/external/angle/src/libANGLE/Display.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2002 The ANGLE Project Authors. All rights reserved.
3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker //
6*8975f5c5SAndroid Build Coastguard Worker 
7*8975f5c5SAndroid Build Coastguard Worker // Display.cpp: Implements the egl::Display class, representing the abstract
8*8975f5c5SAndroid Build Coastguard Worker // display on which graphics are drawn. Implements EGLDisplay.
9*8975f5c5SAndroid Build Coastguard Worker // [EGL 1.4] section 2.1.2 page 3.
10*8975f5c5SAndroid Build Coastguard Worker 
11*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Display.h"
12*8975f5c5SAndroid Build Coastguard Worker 
13*8975f5c5SAndroid Build Coastguard Worker #include <algorithm>
14*8975f5c5SAndroid Build Coastguard Worker #include <iterator>
15*8975f5c5SAndroid Build Coastguard Worker #include <sstream>
16*8975f5c5SAndroid Build Coastguard Worker #include <vector>
17*8975f5c5SAndroid Build Coastguard Worker 
18*8975f5c5SAndroid Build Coastguard Worker #include <EGL/eglext.h>
19*8975f5c5SAndroid Build Coastguard Worker #include <platform/PlatformMethods.h>
20*8975f5c5SAndroid Build Coastguard Worker 
21*8975f5c5SAndroid Build Coastguard Worker #include "anglebase/no_destructor.h"
22*8975f5c5SAndroid Build Coastguard Worker #include "common/android_util.h"
23*8975f5c5SAndroid Build Coastguard Worker #include "common/debug.h"
24*8975f5c5SAndroid Build Coastguard Worker #include "common/mathutil.h"
25*8975f5c5SAndroid Build Coastguard Worker #include "common/platform_helpers.h"
26*8975f5c5SAndroid Build Coastguard Worker #include "common/string_utils.h"
27*8975f5c5SAndroid Build Coastguard Worker #include "common/system_utils.h"
28*8975f5c5SAndroid Build Coastguard Worker #include "common/tls.h"
29*8975f5c5SAndroid Build Coastguard Worker #include "common/utilities.h"
30*8975f5c5SAndroid Build Coastguard Worker #include "gpu_info_util/SystemInfo.h"
31*8975f5c5SAndroid Build Coastguard Worker #include "image_util/loadimage.h"
32*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Context.h"
33*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Device.h"
34*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/EGLSync.h"
35*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Image.h"
36*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/ResourceManager.h"
37*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Stream.h"
38*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Surface.h"
39*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Thread.h"
40*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/capture/FrameCapture.h"
41*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/histogram_macros.h"
42*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/DeviceImpl.h"
43*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/DisplayImpl.h"
44*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/ImageImpl.h"
45*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/trace.h"
46*8975f5c5SAndroid Build Coastguard Worker 
47*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_PLATFORM_APPLE)
48*8975f5c5SAndroid Build Coastguard Worker #    include <dispatch/dispatch.h>
49*8975f5c5SAndroid Build Coastguard Worker #    include "common/tls.h"
50*8975f5c5SAndroid Build Coastguard Worker #endif
51*8975f5c5SAndroid Build Coastguard Worker 
52*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_ENABLE_D3D9) || defined(ANGLE_ENABLE_D3D11)
53*8975f5c5SAndroid Build Coastguard Worker #    include "libANGLE/renderer/d3d/DisplayD3D.h"
54*8975f5c5SAndroid Build Coastguard Worker #endif
55*8975f5c5SAndroid Build Coastguard Worker 
56*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_ENABLE_OPENGL)
57*8975f5c5SAndroid Build Coastguard Worker #    if defined(ANGLE_PLATFORM_WINDOWS)
58*8975f5c5SAndroid Build Coastguard Worker #        include "libANGLE/renderer/gl/wgl/DisplayWGL.h"
59*8975f5c5SAndroid Build Coastguard Worker #    elif ANGLE_ENABLE_CGL
60*8975f5c5SAndroid Build Coastguard Worker #        include "libANGLE/renderer/gl/cgl/DisplayCGL.h"
61*8975f5c5SAndroid Build Coastguard Worker #    elif defined(ANGLE_PLATFORM_LINUX)
62*8975f5c5SAndroid Build Coastguard Worker #        include "libANGLE/renderer/gl/egl/DisplayEGL.h"
63*8975f5c5SAndroid Build Coastguard Worker #        if defined(ANGLE_USE_X11)
64*8975f5c5SAndroid Build Coastguard Worker #            include "libANGLE/renderer/gl/glx/DisplayGLX_api.h"
65*8975f5c5SAndroid Build Coastguard Worker #        endif
66*8975f5c5SAndroid Build Coastguard Worker #    elif defined(ANGLE_PLATFORM_ANDROID)
67*8975f5c5SAndroid Build Coastguard Worker #        include "libANGLE/renderer/gl/egl/android/DisplayAndroid.h"
68*8975f5c5SAndroid Build Coastguard Worker #    else
69*8975f5c5SAndroid Build Coastguard Worker #        error Unsupported OpenGL platform.
70*8975f5c5SAndroid Build Coastguard Worker #    endif
71*8975f5c5SAndroid Build Coastguard Worker #endif
72*8975f5c5SAndroid Build Coastguard Worker 
73*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_ENABLE_NULL)
74*8975f5c5SAndroid Build Coastguard Worker #    include "libANGLE/renderer/null/DisplayNULL.h"
75*8975f5c5SAndroid Build Coastguard Worker #endif  // defined(ANGLE_ENABLE_NULL)
76*8975f5c5SAndroid Build Coastguard Worker 
77*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_ENABLE_WGPU)
78*8975f5c5SAndroid Build Coastguard Worker #    include "libANGLE/renderer/wgpu/DisplayWgpu_api.h"
79*8975f5c5SAndroid Build Coastguard Worker #endif
80*8975f5c5SAndroid Build Coastguard Worker 
81*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_ENABLE_VULKAN)
82*8975f5c5SAndroid Build Coastguard Worker #    include "libANGLE/renderer/vulkan/DisplayVk_api.h"
83*8975f5c5SAndroid Build Coastguard Worker #endif  // defined(ANGLE_ENABLE_VULKAN)
84*8975f5c5SAndroid Build Coastguard Worker 
85*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_ENABLE_METAL)
86*8975f5c5SAndroid Build Coastguard Worker #    include "libANGLE/renderer/metal/DisplayMtl_api.h"
87*8975f5c5SAndroid Build Coastguard Worker #endif  // defined(ANGLE_ENABLE_METAL)
88*8975f5c5SAndroid Build Coastguard Worker 
89*8975f5c5SAndroid Build Coastguard Worker namespace egl
90*8975f5c5SAndroid Build Coastguard Worker {
91*8975f5c5SAndroid Build Coastguard Worker 
92*8975f5c5SAndroid Build Coastguard Worker namespace
93*8975f5c5SAndroid Build Coastguard Worker {
94*8975f5c5SAndroid Build Coastguard Worker struct TLSData
95*8975f5c5SAndroid Build Coastguard Worker {
96*8975f5c5SAndroid Build Coastguard Worker     angle::UnlockedTailCall unlockedTailCall;
97*8975f5c5SAndroid Build Coastguard Worker     Error errorScratchSpace;
98*8975f5c5SAndroid Build Coastguard Worker 
99*8975f5c5SAndroid Build Coastguard Worker     TLSData();
100*8975f5c5SAndroid Build Coastguard Worker };
101*8975f5c5SAndroid Build Coastguard Worker 
TLSData()102*8975f5c5SAndroid Build Coastguard Worker TLSData::TLSData() : errorScratchSpace(0) {}
103*8975f5c5SAndroid Build Coastguard Worker 
104*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_PLATFORM_APPLE)
105*8975f5c5SAndroid Build Coastguard Worker // TODO(angleproject:6479): Due to a bug in Apple's dyld loader, `thread_local` will cause
106*8975f5c5SAndroid Build Coastguard Worker // excessive memory use. Temporarily avoid it by using pthread's thread
107*8975f5c5SAndroid Build Coastguard Worker // local storage instead.
GetDisplayTLSIndex()108*8975f5c5SAndroid Build Coastguard Worker static angle::TLSIndex GetDisplayTLSIndex()
109*8975f5c5SAndroid Build Coastguard Worker {
110*8975f5c5SAndroid Build Coastguard Worker     static angle::TLSIndex DisplayIndex = TLS_INVALID_INDEX;
111*8975f5c5SAndroid Build Coastguard Worker     static dispatch_once_t once;
112*8975f5c5SAndroid Build Coastguard Worker     dispatch_once(&once, ^{
113*8975f5c5SAndroid Build Coastguard Worker       ASSERT(DisplayIndex == TLS_INVALID_INDEX);
114*8975f5c5SAndroid Build Coastguard Worker       DisplayIndex = angle::CreateTLSIndex(nullptr);
115*8975f5c5SAndroid Build Coastguard Worker     });
116*8975f5c5SAndroid Build Coastguard Worker     return DisplayIndex;
117*8975f5c5SAndroid Build Coastguard Worker }
GetDisplayTLS()118*8975f5c5SAndroid Build Coastguard Worker TLSData *GetDisplayTLS()
119*8975f5c5SAndroid Build Coastguard Worker {
120*8975f5c5SAndroid Build Coastguard Worker     angle::TLSIndex DisplayIndex = GetDisplayTLSIndex();
121*8975f5c5SAndroid Build Coastguard Worker     ASSERT(DisplayIndex != TLS_INVALID_INDEX);
122*8975f5c5SAndroid Build Coastguard Worker     return static_cast<TLSData *>(angle::GetTLSValue(DisplayIndex));
123*8975f5c5SAndroid Build Coastguard Worker }
SetDisplayTLS(TLSData * tlsData)124*8975f5c5SAndroid Build Coastguard Worker void SetDisplayTLS(TLSData *tlsData)
125*8975f5c5SAndroid Build Coastguard Worker {
126*8975f5c5SAndroid Build Coastguard Worker     angle::TLSIndex DisplayIndex = GetDisplayTLSIndex();
127*8975f5c5SAndroid Build Coastguard Worker     ASSERT(DisplayIndex != TLS_INVALID_INDEX);
128*8975f5c5SAndroid Build Coastguard Worker     angle::SetTLSValue(DisplayIndex, tlsData);
129*8975f5c5SAndroid Build Coastguard Worker }
130*8975f5c5SAndroid Build Coastguard Worker #else
131*8975f5c5SAndroid Build Coastguard Worker // Tail calls generated during execution of the entry point, to be run at the end of the entry
132*8975f5c5SAndroid Build Coastguard Worker // point.  gTLSData->unlockedTailCall.run() is called at the end of any EGL entry point that is
133*8975f5c5SAndroid Build Coastguard Worker // expected to generate such calls.  At the end of every other call, it is asserted that this is
134*8975f5c5SAndroid Build Coastguard Worker // empty.
135*8975f5c5SAndroid Build Coastguard Worker thread_local TLSData *gDisplayTLS = nullptr;
136*8975f5c5SAndroid Build Coastguard Worker 
GetDisplayTLS()137*8975f5c5SAndroid Build Coastguard Worker TLSData *GetDisplayTLS()
138*8975f5c5SAndroid Build Coastguard Worker {
139*8975f5c5SAndroid Build Coastguard Worker     return gDisplayTLS;
140*8975f5c5SAndroid Build Coastguard Worker }
141*8975f5c5SAndroid Build Coastguard Worker #endif
142*8975f5c5SAndroid Build Coastguard Worker 
143*8975f5c5SAndroid Build Coastguard Worker constexpr angle::SubjectIndex kGPUSwitchedSubjectIndex = 0;
144*8975f5c5SAndroid Build Coastguard Worker 
145*8975f5c5SAndroid Build Coastguard Worker static constexpr size_t kWindowSurfaceMapSize = 32;
146*8975f5c5SAndroid Build Coastguard Worker typedef angle::FlatUnorderedMap<EGLNativeWindowType, Surface *, kWindowSurfaceMapSize>
147*8975f5c5SAndroid Build Coastguard Worker     WindowSurfaceMap;
148*8975f5c5SAndroid Build Coastguard Worker // Get a map of all EGL window surfaces to validate that no window has more than one EGL surface
149*8975f5c5SAndroid Build Coastguard Worker // associated with it.
GetWindowSurfaces()150*8975f5c5SAndroid Build Coastguard Worker static WindowSurfaceMap *GetWindowSurfaces()
151*8975f5c5SAndroid Build Coastguard Worker {
152*8975f5c5SAndroid Build Coastguard Worker     static angle::base::NoDestructor<WindowSurfaceMap> windowSurfaces;
153*8975f5c5SAndroid Build Coastguard Worker     return windowSurfaces.get();
154*8975f5c5SAndroid Build Coastguard Worker }
155*8975f5c5SAndroid Build Coastguard Worker 
EGLStringArrayHash(const char ** ary)156*8975f5c5SAndroid Build Coastguard Worker size_t EGLStringArrayHash(const char **ary)
157*8975f5c5SAndroid Build Coastguard Worker {
158*8975f5c5SAndroid Build Coastguard Worker     size_t hash = 0;
159*8975f5c5SAndroid Build Coastguard Worker     if (ary != nullptr)
160*8975f5c5SAndroid Build Coastguard Worker     {
161*8975f5c5SAndroid Build Coastguard Worker         for (; *ary != nullptr; ary++)
162*8975f5c5SAndroid Build Coastguard Worker         {
163*8975f5c5SAndroid Build Coastguard Worker             hash ^= std::hash<std::string>{}(std::string(*ary));
164*8975f5c5SAndroid Build Coastguard Worker         }
165*8975f5c5SAndroid Build Coastguard Worker     }
166*8975f5c5SAndroid Build Coastguard Worker     return hash;
167*8975f5c5SAndroid Build Coastguard Worker }
168*8975f5c5SAndroid Build Coastguard Worker 
169*8975f5c5SAndroid Build Coastguard Worker struct ANGLEPlatformDisplay
170*8975f5c5SAndroid Build Coastguard Worker {
171*8975f5c5SAndroid Build Coastguard Worker     ANGLEPlatformDisplay() = default;
172*8975f5c5SAndroid Build Coastguard Worker 
ANGLEPlatformDisplayegl::__anon42684e880111::ANGLEPlatformDisplay173*8975f5c5SAndroid Build Coastguard Worker     ANGLEPlatformDisplay(EGLNativeDisplayType nativeDisplayType)
174*8975f5c5SAndroid Build Coastguard Worker         : nativeDisplayType(nativeDisplayType)
175*8975f5c5SAndroid Build Coastguard Worker     {}
176*8975f5c5SAndroid Build Coastguard Worker 
ANGLEPlatformDisplayegl::__anon42684e880111::ANGLEPlatformDisplay177*8975f5c5SAndroid Build Coastguard Worker     ANGLEPlatformDisplay(EGLNativeDisplayType nativeDisplayType,
178*8975f5c5SAndroid Build Coastguard Worker                          EGLAttrib powerPreference,
179*8975f5c5SAndroid Build Coastguard Worker                          EGLAttrib platformANGLEType,
180*8975f5c5SAndroid Build Coastguard Worker                          EGLAttrib deviceIdHigh,
181*8975f5c5SAndroid Build Coastguard Worker                          EGLAttrib deviceIdLow,
182*8975f5c5SAndroid Build Coastguard Worker                          EGLAttrib displayKey,
183*8975f5c5SAndroid Build Coastguard Worker                          EGLAttrib enabledFeatureOverrides,
184*8975f5c5SAndroid Build Coastguard Worker                          EGLAttrib disabledFeatureOverrides,
185*8975f5c5SAndroid Build Coastguard Worker                          EGLAttrib disableAllNonOverriddenFeatures)
186*8975f5c5SAndroid Build Coastguard Worker         : nativeDisplayType(nativeDisplayType),
187*8975f5c5SAndroid Build Coastguard Worker           powerPreference(powerPreference),
188*8975f5c5SAndroid Build Coastguard Worker           platformANGLEType(platformANGLEType),
189*8975f5c5SAndroid Build Coastguard Worker           deviceIdHigh(deviceIdHigh),
190*8975f5c5SAndroid Build Coastguard Worker           deviceIdLow(deviceIdLow),
191*8975f5c5SAndroid Build Coastguard Worker           displayKey(displayKey),
192*8975f5c5SAndroid Build Coastguard Worker           disableAllNonOverriddenFeatures(static_cast<bool>(disableAllNonOverriddenFeatures))
193*8975f5c5SAndroid Build Coastguard Worker     {
194*8975f5c5SAndroid Build Coastguard Worker         enabledFeatureOverridesHash =
195*8975f5c5SAndroid Build Coastguard Worker             EGLStringArrayHash(reinterpret_cast<const char **>(enabledFeatureOverrides));
196*8975f5c5SAndroid Build Coastguard Worker         disabledFeatureOverridesHash =
197*8975f5c5SAndroid Build Coastguard Worker             EGLStringArrayHash(reinterpret_cast<const char **>(disabledFeatureOverrides));
198*8975f5c5SAndroid Build Coastguard Worker     }
199*8975f5c5SAndroid Build Coastguard Worker 
tieegl::__anon42684e880111::ANGLEPlatformDisplay200*8975f5c5SAndroid Build Coastguard Worker     auto tie() const
201*8975f5c5SAndroid Build Coastguard Worker     {
202*8975f5c5SAndroid Build Coastguard Worker         return std::tie(nativeDisplayType, powerPreference, platformANGLEType, deviceIdHigh,
203*8975f5c5SAndroid Build Coastguard Worker                         deviceIdLow, displayKey, enabledFeatureOverridesHash,
204*8975f5c5SAndroid Build Coastguard Worker                         disabledFeatureOverridesHash, disableAllNonOverriddenFeatures);
205*8975f5c5SAndroid Build Coastguard Worker     }
206*8975f5c5SAndroid Build Coastguard Worker 
207*8975f5c5SAndroid Build Coastguard Worker     EGLNativeDisplayType nativeDisplayType{EGL_DEFAULT_DISPLAY};
208*8975f5c5SAndroid Build Coastguard Worker     EGLAttrib powerPreference{EGL_LOW_POWER_ANGLE};
209*8975f5c5SAndroid Build Coastguard Worker     EGLAttrib platformANGLEType{EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE};
210*8975f5c5SAndroid Build Coastguard Worker     EGLAttrib deviceIdHigh{0};
211*8975f5c5SAndroid Build Coastguard Worker     EGLAttrib deviceIdLow{0};
212*8975f5c5SAndroid Build Coastguard Worker     EGLAttrib displayKey{0};
213*8975f5c5SAndroid Build Coastguard Worker     size_t enabledFeatureOverridesHash;
214*8975f5c5SAndroid Build Coastguard Worker     size_t disabledFeatureOverridesHash;
215*8975f5c5SAndroid Build Coastguard Worker     bool disableAllNonOverriddenFeatures;
216*8975f5c5SAndroid Build Coastguard Worker };
217*8975f5c5SAndroid Build Coastguard Worker 
operator ==(const ANGLEPlatformDisplay & a,const ANGLEPlatformDisplay & b)218*8975f5c5SAndroid Build Coastguard Worker inline bool operator==(const ANGLEPlatformDisplay &a, const ANGLEPlatformDisplay &b)
219*8975f5c5SAndroid Build Coastguard Worker {
220*8975f5c5SAndroid Build Coastguard Worker     return a.tie() == b.tie();
221*8975f5c5SAndroid Build Coastguard Worker }
222*8975f5c5SAndroid Build Coastguard Worker 
DevicePlatformDisplayMapMutex()223*8975f5c5SAndroid Build Coastguard Worker static angle::SimpleMutex *DevicePlatformDisplayMapMutex()
224*8975f5c5SAndroid Build Coastguard Worker {
225*8975f5c5SAndroid Build Coastguard Worker     static angle::base::NoDestructor<angle::SimpleMutex> devicePlatformDisplayMapMutex;
226*8975f5c5SAndroid Build Coastguard Worker     return devicePlatformDisplayMapMutex.get();
227*8975f5c5SAndroid Build Coastguard Worker }
228*8975f5c5SAndroid Build Coastguard Worker 
ANGLEPlatformDisplayMapMutex()229*8975f5c5SAndroid Build Coastguard Worker static angle::SimpleMutex *ANGLEPlatformDisplayMapMutex()
230*8975f5c5SAndroid Build Coastguard Worker {
231*8975f5c5SAndroid Build Coastguard Worker     static angle::base::NoDestructor<angle::SimpleMutex> anglePlatformDisplayMapMutex;
232*8975f5c5SAndroid Build Coastguard Worker     return anglePlatformDisplayMapMutex.get();
233*8975f5c5SAndroid Build Coastguard Worker }
234*8975f5c5SAndroid Build Coastguard Worker 
235*8975f5c5SAndroid Build Coastguard Worker static constexpr size_t kANGLEPlatformDisplayMapSize = 9;
236*8975f5c5SAndroid Build Coastguard Worker typedef angle::FlatUnorderedMap<ANGLEPlatformDisplay, Display *, kANGLEPlatformDisplayMapSize>
237*8975f5c5SAndroid Build Coastguard Worker     ANGLEPlatformDisplayMap;
GetANGLEPlatformDisplayMap()238*8975f5c5SAndroid Build Coastguard Worker static ANGLEPlatformDisplayMap *GetANGLEPlatformDisplayMap()
239*8975f5c5SAndroid Build Coastguard Worker {
240*8975f5c5SAndroid Build Coastguard Worker     static angle::base::NoDestructor<ANGLEPlatformDisplayMap> displays;
241*8975f5c5SAndroid Build Coastguard Worker     return displays.get();
242*8975f5c5SAndroid Build Coastguard Worker }
243*8975f5c5SAndroid Build Coastguard Worker 
244*8975f5c5SAndroid Build Coastguard Worker static constexpr size_t kDevicePlatformDisplayMapSize = 8;
245*8975f5c5SAndroid Build Coastguard Worker typedef angle::FlatUnorderedMap<Device *, Display *, kDevicePlatformDisplayMapSize>
246*8975f5c5SAndroid Build Coastguard Worker     DevicePlatformDisplayMap;
GetDevicePlatformDisplayMap()247*8975f5c5SAndroid Build Coastguard Worker static DevicePlatformDisplayMap *GetDevicePlatformDisplayMap()
248*8975f5c5SAndroid Build Coastguard Worker {
249*8975f5c5SAndroid Build Coastguard Worker     static angle::base::NoDestructor<DevicePlatformDisplayMap> displays;
250*8975f5c5SAndroid Build Coastguard Worker     return displays.get();
251*8975f5c5SAndroid Build Coastguard Worker }
252*8975f5c5SAndroid Build Coastguard Worker 
CreateDisplayFromDevice(Device * eglDevice,const DisplayState & state)253*8975f5c5SAndroid Build Coastguard Worker rx::DisplayImpl *CreateDisplayFromDevice(Device *eglDevice, const DisplayState &state)
254*8975f5c5SAndroid Build Coastguard Worker {
255*8975f5c5SAndroid Build Coastguard Worker     rx::DisplayImpl *impl = nullptr;
256*8975f5c5SAndroid Build Coastguard Worker 
257*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_ENABLE_D3D11)
258*8975f5c5SAndroid Build Coastguard Worker     if (eglDevice->getExtensions().deviceD3D11)
259*8975f5c5SAndroid Build Coastguard Worker     {
260*8975f5c5SAndroid Build Coastguard Worker         impl = new rx::DisplayD3D(state);
261*8975f5c5SAndroid Build Coastguard Worker     }
262*8975f5c5SAndroid Build Coastguard Worker #endif
263*8975f5c5SAndroid Build Coastguard Worker 
264*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_ENABLE_D3D9)
265*8975f5c5SAndroid Build Coastguard Worker     if (eglDevice->getExtensions().deviceD3D9)
266*8975f5c5SAndroid Build Coastguard Worker     {
267*8975f5c5SAndroid Build Coastguard Worker         // Currently the only way to get EGLDeviceEXT representing a D3D9 device
268*8975f5c5SAndroid Build Coastguard Worker         // is to retrieve one from an already-existing EGLDisplay.
269*8975f5c5SAndroid Build Coastguard Worker         // When eglGetPlatformDisplayEXT is called with a D3D9 EGLDeviceEXT,
270*8975f5c5SAndroid Build Coastguard Worker         // the already-existing display should be returned.
271*8975f5c5SAndroid Build Coastguard Worker         // Therefore this codepath to create a new display from the device
272*8975f5c5SAndroid Build Coastguard Worker         // should never be hit.
273*8975f5c5SAndroid Build Coastguard Worker         UNREACHABLE();
274*8975f5c5SAndroid Build Coastguard Worker     }
275*8975f5c5SAndroid Build Coastguard Worker #endif
276*8975f5c5SAndroid Build Coastguard Worker 
277*8975f5c5SAndroid Build Coastguard Worker     ASSERT(impl != nullptr);
278*8975f5c5SAndroid Build Coastguard Worker     return impl;
279*8975f5c5SAndroid Build Coastguard Worker }
280*8975f5c5SAndroid Build Coastguard Worker 
281*8975f5c5SAndroid Build Coastguard Worker // On platforms with support for multiple back-ends, allow an environment variable to control
282*8975f5c5SAndroid Build Coastguard Worker // the default.  This is useful to run angle with benchmarks without having to modify the
283*8975f5c5SAndroid Build Coastguard Worker // benchmark source.  Possible values for this environment variable (ANGLE_DEFAULT_PLATFORM)
284*8975f5c5SAndroid Build Coastguard Worker // are: vulkan, gl, d3d11, null.
GetDisplayTypeFromEnvironment()285*8975f5c5SAndroid Build Coastguard Worker EGLAttrib GetDisplayTypeFromEnvironment()
286*8975f5c5SAndroid Build Coastguard Worker {
287*8975f5c5SAndroid Build Coastguard Worker     std::string angleDefaultEnv = angle::GetEnvironmentVar("ANGLE_DEFAULT_PLATFORM");
288*8975f5c5SAndroid Build Coastguard Worker     angle::ToLower(&angleDefaultEnv);
289*8975f5c5SAndroid Build Coastguard Worker 
290*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_ENABLE_VULKAN)
291*8975f5c5SAndroid Build Coastguard Worker     if ((angleDefaultEnv == "vulkan") || (angleDefaultEnv == "vulkan-null") ||
292*8975f5c5SAndroid Build Coastguard Worker         (angleDefaultEnv == "swiftshader"))
293*8975f5c5SAndroid Build Coastguard Worker     {
294*8975f5c5SAndroid Build Coastguard Worker         return EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE;
295*8975f5c5SAndroid Build Coastguard Worker     }
296*8975f5c5SAndroid Build Coastguard Worker #endif
297*8975f5c5SAndroid Build Coastguard Worker 
298*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_ENABLE_WGPU)
299*8975f5c5SAndroid Build Coastguard Worker     if (angleDefaultEnv == "webgpu")
300*8975f5c5SAndroid Build Coastguard Worker     {
301*8975f5c5SAndroid Build Coastguard Worker         return EGL_PLATFORM_ANGLE_TYPE_WEBGPU_ANGLE;
302*8975f5c5SAndroid Build Coastguard Worker     }
303*8975f5c5SAndroid Build Coastguard Worker #endif
304*8975f5c5SAndroid Build Coastguard Worker 
305*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_ENABLE_OPENGL)
306*8975f5c5SAndroid Build Coastguard Worker     if (angleDefaultEnv == "gl")
307*8975f5c5SAndroid Build Coastguard Worker     {
308*8975f5c5SAndroid Build Coastguard Worker         return EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE;
309*8975f5c5SAndroid Build Coastguard Worker     }
310*8975f5c5SAndroid Build Coastguard Worker #endif
311*8975f5c5SAndroid Build Coastguard Worker 
312*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_ENABLE_D3D11)
313*8975f5c5SAndroid Build Coastguard Worker     if (angleDefaultEnv == "d3d11")
314*8975f5c5SAndroid Build Coastguard Worker     {
315*8975f5c5SAndroid Build Coastguard Worker         return EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE;
316*8975f5c5SAndroid Build Coastguard Worker     }
317*8975f5c5SAndroid Build Coastguard Worker #endif
318*8975f5c5SAndroid Build Coastguard Worker 
319*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_ENABLE_METAL)
320*8975f5c5SAndroid Build Coastguard Worker     if (angleDefaultEnv == "metal")
321*8975f5c5SAndroid Build Coastguard Worker     {
322*8975f5c5SAndroid Build Coastguard Worker         return EGL_PLATFORM_ANGLE_TYPE_METAL_ANGLE;
323*8975f5c5SAndroid Build Coastguard Worker     }
324*8975f5c5SAndroid Build Coastguard Worker #endif
325*8975f5c5SAndroid Build Coastguard Worker 
326*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_ENABLE_NULL)
327*8975f5c5SAndroid Build Coastguard Worker     if (angleDefaultEnv == "null")
328*8975f5c5SAndroid Build Coastguard Worker     {
329*8975f5c5SAndroid Build Coastguard Worker         return EGL_PLATFORM_ANGLE_TYPE_NULL_ANGLE;
330*8975f5c5SAndroid Build Coastguard Worker     }
331*8975f5c5SAndroid Build Coastguard Worker #endif
332*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_ENABLE_D3D11)
333*8975f5c5SAndroid Build Coastguard Worker     return EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE;
334*8975f5c5SAndroid Build Coastguard Worker #elif defined(ANGLE_ENABLE_D3D9)
335*8975f5c5SAndroid Build Coastguard Worker     return EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE;
336*8975f5c5SAndroid Build Coastguard Worker #elif defined(ANGLE_ENABLE_VULKAN) && defined(ANGLE_PLATFORM_ANDROID)
337*8975f5c5SAndroid Build Coastguard Worker     return EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE;
338*8975f5c5SAndroid Build Coastguard Worker #elif defined(ANGLE_ENABLE_OPENGL)
339*8975f5c5SAndroid Build Coastguard Worker #    if defined(ANGLE_PLATFORM_ANDROID) || defined(ANGLE_USE_GBM)
340*8975f5c5SAndroid Build Coastguard Worker     return EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE;
341*8975f5c5SAndroid Build Coastguard Worker #    else
342*8975f5c5SAndroid Build Coastguard Worker     return EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE;
343*8975f5c5SAndroid Build Coastguard Worker #    endif
344*8975f5c5SAndroid Build Coastguard Worker #elif defined(ANGLE_ENABLE_METAL)
345*8975f5c5SAndroid Build Coastguard Worker     return EGL_PLATFORM_ANGLE_TYPE_METAL_ANGLE;
346*8975f5c5SAndroid Build Coastguard Worker #elif defined(ANGLE_ENABLE_VULKAN)
347*8975f5c5SAndroid Build Coastguard Worker     return EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE;
348*8975f5c5SAndroid Build Coastguard Worker #elif defined(ANGLE_ENABLE_NULL)
349*8975f5c5SAndroid Build Coastguard Worker     return EGL_PLATFORM_ANGLE_TYPE_NULL_ANGLE;
350*8975f5c5SAndroid Build Coastguard Worker #else
351*8975f5c5SAndroid Build Coastguard Worker #    error No default ANGLE platform type
352*8975f5c5SAndroid Build Coastguard Worker #endif
353*8975f5c5SAndroid Build Coastguard Worker }
354*8975f5c5SAndroid Build Coastguard Worker 
GetDeviceTypeFromEnvironment()355*8975f5c5SAndroid Build Coastguard Worker EGLAttrib GetDeviceTypeFromEnvironment()
356*8975f5c5SAndroid Build Coastguard Worker {
357*8975f5c5SAndroid Build Coastguard Worker     std::string angleDefaultEnv = angle::GetEnvironmentVar("ANGLE_DEFAULT_PLATFORM");
358*8975f5c5SAndroid Build Coastguard Worker     angle::ToLower(&angleDefaultEnv);
359*8975f5c5SAndroid Build Coastguard Worker 
360*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_ENABLE_VULKAN)
361*8975f5c5SAndroid Build Coastguard Worker     if (angleDefaultEnv == "vulkan-null")
362*8975f5c5SAndroid Build Coastguard Worker     {
363*8975f5c5SAndroid Build Coastguard Worker         return EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE;
364*8975f5c5SAndroid Build Coastguard Worker     }
365*8975f5c5SAndroid Build Coastguard Worker     else if (angleDefaultEnv == "swiftshader")
366*8975f5c5SAndroid Build Coastguard Worker     {
367*8975f5c5SAndroid Build Coastguard Worker         return EGL_PLATFORM_ANGLE_DEVICE_TYPE_SWIFTSHADER_ANGLE;
368*8975f5c5SAndroid Build Coastguard Worker     }
369*8975f5c5SAndroid Build Coastguard Worker #endif
370*8975f5c5SAndroid Build Coastguard Worker     return EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE;
371*8975f5c5SAndroid Build Coastguard Worker }
372*8975f5c5SAndroid Build Coastguard Worker 
GetPlatformTypeFromEnvironment()373*8975f5c5SAndroid Build Coastguard Worker EGLAttrib GetPlatformTypeFromEnvironment()
374*8975f5c5SAndroid Build Coastguard Worker {
375*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_USE_OZONE)
376*8975f5c5SAndroid Build Coastguard Worker     return 0;
377*8975f5c5SAndroid Build Coastguard Worker #elif defined(ANGLE_USE_X11)
378*8975f5c5SAndroid Build Coastguard Worker     return EGL_PLATFORM_X11_EXT;
379*8975f5c5SAndroid Build Coastguard Worker #elif defined(ANGLE_USE_WAYLAND)
380*8975f5c5SAndroid Build Coastguard Worker     return EGL_PLATFORM_WAYLAND_EXT;
381*8975f5c5SAndroid Build Coastguard Worker #elif defined(ANGLE_USE_VULKAN_DISPLAY) && defined(ANGLE_VULKAN_DISPLAY_MODE_SIMPLE)
382*8975f5c5SAndroid Build Coastguard Worker     return EGL_PLATFORM_VULKAN_DISPLAY_MODE_SIMPLE_ANGLE;
383*8975f5c5SAndroid Build Coastguard Worker #elif defined(ANGLE_USE_VULKAN_DISPLAY) && defined(ANGLE_VULKAN_DISPLAY_MODE_HEADLESS)
384*8975f5c5SAndroid Build Coastguard Worker     return EGL_PLATFORM_VULKAN_DISPLAY_MODE_HEADLESS_ANGLE;
385*8975f5c5SAndroid Build Coastguard Worker #else
386*8975f5c5SAndroid Build Coastguard Worker     return 0;
387*8975f5c5SAndroid Build Coastguard Worker #endif  // defined(ANGLE_USE_OZONE)
388*8975f5c5SAndroid Build Coastguard Worker }
389*8975f5c5SAndroid Build Coastguard Worker 
CreateDisplayFromAttribs(EGLAttrib displayType,EGLAttrib deviceType,EGLAttrib platformType,const DisplayState & state)390*8975f5c5SAndroid Build Coastguard Worker rx::DisplayImpl *CreateDisplayFromAttribs(EGLAttrib displayType,
391*8975f5c5SAndroid Build Coastguard Worker                                           EGLAttrib deviceType,
392*8975f5c5SAndroid Build Coastguard Worker                                           EGLAttrib platformType,
393*8975f5c5SAndroid Build Coastguard Worker                                           const DisplayState &state)
394*8975f5c5SAndroid Build Coastguard Worker {
395*8975f5c5SAndroid Build Coastguard Worker     ASSERT(displayType != EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE);
396*8975f5c5SAndroid Build Coastguard Worker     rx::DisplayImpl *impl = nullptr;
397*8975f5c5SAndroid Build Coastguard Worker 
398*8975f5c5SAndroid Build Coastguard Worker     switch (displayType)
399*8975f5c5SAndroid Build Coastguard Worker     {
400*8975f5c5SAndroid Build Coastguard Worker         case EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE:
401*8975f5c5SAndroid Build Coastguard Worker             UNREACHABLE();
402*8975f5c5SAndroid Build Coastguard Worker             break;
403*8975f5c5SAndroid Build Coastguard Worker 
404*8975f5c5SAndroid Build Coastguard Worker         case EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE:
405*8975f5c5SAndroid Build Coastguard Worker         case EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE:
406*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_ENABLE_D3D9) || defined(ANGLE_ENABLE_D3D11)
407*8975f5c5SAndroid Build Coastguard Worker             impl = new rx::DisplayD3D(state);
408*8975f5c5SAndroid Build Coastguard Worker             break;
409*8975f5c5SAndroid Build Coastguard Worker #else
410*8975f5c5SAndroid Build Coastguard Worker             // A D3D display was requested on a platform that doesn't support it
411*8975f5c5SAndroid Build Coastguard Worker             UNREACHABLE();
412*8975f5c5SAndroid Build Coastguard Worker             break;
413*8975f5c5SAndroid Build Coastguard Worker #endif
414*8975f5c5SAndroid Build Coastguard Worker 
415*8975f5c5SAndroid Build Coastguard Worker         case EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE:
416*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_ENABLE_OPENGL)
417*8975f5c5SAndroid Build Coastguard Worker #    if defined(ANGLE_PLATFORM_WINDOWS)
418*8975f5c5SAndroid Build Coastguard Worker             impl = new rx::DisplayWGL(state);
419*8975f5c5SAndroid Build Coastguard Worker             break;
420*8975f5c5SAndroid Build Coastguard Worker 
421*8975f5c5SAndroid Build Coastguard Worker #    elif ANGLE_ENABLE_CGL
422*8975f5c5SAndroid Build Coastguard Worker             impl = new rx::DisplayCGL(state);
423*8975f5c5SAndroid Build Coastguard Worker             break;
424*8975f5c5SAndroid Build Coastguard Worker 
425*8975f5c5SAndroid Build Coastguard Worker #    elif defined(ANGLE_PLATFORM_LINUX)
426*8975f5c5SAndroid Build Coastguard Worker #        if defined(ANGLE_USE_GBM)
427*8975f5c5SAndroid Build Coastguard Worker             if (platformType == 0)
428*8975f5c5SAndroid Build Coastguard Worker             {
429*8975f5c5SAndroid Build Coastguard Worker                 impl = new rx::DisplayEGL(state);
430*8975f5c5SAndroid Build Coastguard Worker                 break;
431*8975f5c5SAndroid Build Coastguard Worker             }
432*8975f5c5SAndroid Build Coastguard Worker #        endif
433*8975f5c5SAndroid Build Coastguard Worker             if (deviceType == EGL_PLATFORM_ANGLE_DEVICE_TYPE_EGL_ANGLE)
434*8975f5c5SAndroid Build Coastguard Worker             {
435*8975f5c5SAndroid Build Coastguard Worker                 impl = new rx::DisplayEGL(state);
436*8975f5c5SAndroid Build Coastguard Worker                 break;
437*8975f5c5SAndroid Build Coastguard Worker             }
438*8975f5c5SAndroid Build Coastguard Worker #        if defined(ANGLE_USE_X11)
439*8975f5c5SAndroid Build Coastguard Worker             if (platformType == EGL_PLATFORM_X11_EXT)
440*8975f5c5SAndroid Build Coastguard Worker             {
441*8975f5c5SAndroid Build Coastguard Worker                 impl = rx::CreateGLXDisplay(state);
442*8975f5c5SAndroid Build Coastguard Worker                 break;
443*8975f5c5SAndroid Build Coastguard Worker             }
444*8975f5c5SAndroid Build Coastguard Worker #        endif
445*8975f5c5SAndroid Build Coastguard Worker             if (platformType == EGL_PLATFORM_SURFACELESS_MESA)
446*8975f5c5SAndroid Build Coastguard Worker             {
447*8975f5c5SAndroid Build Coastguard Worker                 impl = new rx::DisplayEGL(state);
448*8975f5c5SAndroid Build Coastguard Worker                 break;
449*8975f5c5SAndroid Build Coastguard Worker             }
450*8975f5c5SAndroid Build Coastguard Worker             break;
451*8975f5c5SAndroid Build Coastguard Worker 
452*8975f5c5SAndroid Build Coastguard Worker #    elif defined(ANGLE_PLATFORM_ANDROID)
453*8975f5c5SAndroid Build Coastguard Worker             // No GL support on this platform, fail display creation.
454*8975f5c5SAndroid Build Coastguard Worker             impl = nullptr;
455*8975f5c5SAndroid Build Coastguard Worker             break;
456*8975f5c5SAndroid Build Coastguard Worker 
457*8975f5c5SAndroid Build Coastguard Worker #    else
458*8975f5c5SAndroid Build Coastguard Worker #        error Unsupported OpenGL platform.
459*8975f5c5SAndroid Build Coastguard Worker #    endif
460*8975f5c5SAndroid Build Coastguard Worker #else
461*8975f5c5SAndroid Build Coastguard Worker             // No display available
462*8975f5c5SAndroid Build Coastguard Worker             UNREACHABLE();
463*8975f5c5SAndroid Build Coastguard Worker             break;
464*8975f5c5SAndroid Build Coastguard Worker 
465*8975f5c5SAndroid Build Coastguard Worker #endif  // defined(ANGLE_ENABLE_OPENGL)
466*8975f5c5SAndroid Build Coastguard Worker 
467*8975f5c5SAndroid Build Coastguard Worker         case EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE:
468*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_ENABLE_OPENGL)
469*8975f5c5SAndroid Build Coastguard Worker #    if defined(ANGLE_PLATFORM_WINDOWS)
470*8975f5c5SAndroid Build Coastguard Worker             impl = new rx::DisplayWGL(state);
471*8975f5c5SAndroid Build Coastguard Worker #    elif defined(ANGLE_PLATFORM_LINUX)
472*8975f5c5SAndroid Build Coastguard Worker #        if defined(ANGLE_USE_GBM)
473*8975f5c5SAndroid Build Coastguard Worker             if (platformType == 0)
474*8975f5c5SAndroid Build Coastguard Worker             {
475*8975f5c5SAndroid Build Coastguard Worker                 impl = new rx::DisplayEGL(state);
476*8975f5c5SAndroid Build Coastguard Worker                 break;
477*8975f5c5SAndroid Build Coastguard Worker             }
478*8975f5c5SAndroid Build Coastguard Worker #        endif
479*8975f5c5SAndroid Build Coastguard Worker             if (deviceType == EGL_PLATFORM_ANGLE_DEVICE_TYPE_EGL_ANGLE)
480*8975f5c5SAndroid Build Coastguard Worker             {
481*8975f5c5SAndroid Build Coastguard Worker                 impl = new rx::DisplayEGL(state);
482*8975f5c5SAndroid Build Coastguard Worker                 break;
483*8975f5c5SAndroid Build Coastguard Worker             }
484*8975f5c5SAndroid Build Coastguard Worker             else
485*8975f5c5SAndroid Build Coastguard Worker             {
486*8975f5c5SAndroid Build Coastguard Worker #        if defined(ANGLE_USE_X11)
487*8975f5c5SAndroid Build Coastguard Worker                 if (platformType == EGL_PLATFORM_X11_EXT)
488*8975f5c5SAndroid Build Coastguard Worker                 {
489*8975f5c5SAndroid Build Coastguard Worker                     impl = rx::CreateGLXDisplay(state);
490*8975f5c5SAndroid Build Coastguard Worker                     break;
491*8975f5c5SAndroid Build Coastguard Worker                 }
492*8975f5c5SAndroid Build Coastguard Worker #        endif
493*8975f5c5SAndroid Build Coastguard Worker                 if (platformType == EGL_PLATFORM_SURFACELESS_MESA)
494*8975f5c5SAndroid Build Coastguard Worker                 {
495*8975f5c5SAndroid Build Coastguard Worker                     impl = new rx::DisplayEGL(state);
496*8975f5c5SAndroid Build Coastguard Worker                     break;
497*8975f5c5SAndroid Build Coastguard Worker                 }
498*8975f5c5SAndroid Build Coastguard Worker             }
499*8975f5c5SAndroid Build Coastguard Worker #    elif defined(ANGLE_PLATFORM_ANDROID)
500*8975f5c5SAndroid Build Coastguard Worker             impl = new rx::DisplayAndroid(state);
501*8975f5c5SAndroid Build Coastguard Worker #    else
502*8975f5c5SAndroid Build Coastguard Worker             // No GLES support on this platform, fail display creation.
503*8975f5c5SAndroid Build Coastguard Worker             impl = nullptr;
504*8975f5c5SAndroid Build Coastguard Worker #    endif
505*8975f5c5SAndroid Build Coastguard Worker #endif  // defined(ANGLE_ENABLE_OPENGL)
506*8975f5c5SAndroid Build Coastguard Worker             break;
507*8975f5c5SAndroid Build Coastguard Worker 
508*8975f5c5SAndroid Build Coastguard Worker         case EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE:
509*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_ENABLE_VULKAN)
510*8975f5c5SAndroid Build Coastguard Worker #    if defined(ANGLE_USE_VULKAN_NULL_DISPLAY)
511*8975f5c5SAndroid Build Coastguard Worker             if (rx::IsVulkanNullDisplayAvailable())
512*8975f5c5SAndroid Build Coastguard Worker             {
513*8975f5c5SAndroid Build Coastguard Worker                 impl = rx::CreateVulkanNullDisplay(state);
514*8975f5c5SAndroid Build Coastguard Worker             }
515*8975f5c5SAndroid Build Coastguard Worker             break;
516*8975f5c5SAndroid Build Coastguard Worker #    elif defined(ANGLE_PLATFORM_WINDOWS)
517*8975f5c5SAndroid Build Coastguard Worker             if (rx::IsVulkanWin32DisplayAvailable())
518*8975f5c5SAndroid Build Coastguard Worker             {
519*8975f5c5SAndroid Build Coastguard Worker                 impl = rx::CreateVulkanWin32Display(state);
520*8975f5c5SAndroid Build Coastguard Worker             }
521*8975f5c5SAndroid Build Coastguard Worker             break;
522*8975f5c5SAndroid Build Coastguard Worker #    elif defined(ANGLE_PLATFORM_LINUX)
523*8975f5c5SAndroid Build Coastguard Worker #        if defined(ANGLE_USE_GBM)
524*8975f5c5SAndroid Build Coastguard Worker             if (platformType == EGL_PLATFORM_GBM_KHR && rx::IsVulkanGbmDisplayAvailable())
525*8975f5c5SAndroid Build Coastguard Worker             {
526*8975f5c5SAndroid Build Coastguard Worker                 impl = rx::CreateVulkanGbmDisplay(state);
527*8975f5c5SAndroid Build Coastguard Worker                 break;
528*8975f5c5SAndroid Build Coastguard Worker             }
529*8975f5c5SAndroid Build Coastguard Worker #        endif
530*8975f5c5SAndroid Build Coastguard Worker #        if defined(ANGLE_USE_X11)
531*8975f5c5SAndroid Build Coastguard Worker             if (platformType == EGL_PLATFORM_X11_EXT && rx::IsVulkanXcbDisplayAvailable())
532*8975f5c5SAndroid Build Coastguard Worker             {
533*8975f5c5SAndroid Build Coastguard Worker                 impl = rx::CreateVulkanXcbDisplay(state);
534*8975f5c5SAndroid Build Coastguard Worker                 break;
535*8975f5c5SAndroid Build Coastguard Worker             }
536*8975f5c5SAndroid Build Coastguard Worker #        endif
537*8975f5c5SAndroid Build Coastguard Worker #        if defined(ANGLE_USE_WAYLAND)
538*8975f5c5SAndroid Build Coastguard Worker             if (platformType == EGL_PLATFORM_WAYLAND_EXT && rx::IsVulkanWaylandDisplayAvailable())
539*8975f5c5SAndroid Build Coastguard Worker             {
540*8975f5c5SAndroid Build Coastguard Worker                 impl = rx::CreateVulkanWaylandDisplay(state);
541*8975f5c5SAndroid Build Coastguard Worker                 break;
542*8975f5c5SAndroid Build Coastguard Worker             }
543*8975f5c5SAndroid Build Coastguard Worker #        endif
544*8975f5c5SAndroid Build Coastguard Worker             if (platformType == EGL_PLATFORM_SURFACELESS_MESA &&
545*8975f5c5SAndroid Build Coastguard Worker                 rx::IsVulkanOffscreenDisplayAvailable())
546*8975f5c5SAndroid Build Coastguard Worker             {
547*8975f5c5SAndroid Build Coastguard Worker                 impl = rx::CreateVulkanOffscreenDisplay(state);
548*8975f5c5SAndroid Build Coastguard Worker                 break;
549*8975f5c5SAndroid Build Coastguard Worker             }
550*8975f5c5SAndroid Build Coastguard Worker #        if defined(ANGLE_USE_VULKAN_DISPLAY)
551*8975f5c5SAndroid Build Coastguard Worker             if (platformType == EGL_PLATFORM_VULKAN_DISPLAY_MODE_SIMPLE_ANGLE &&
552*8975f5c5SAndroid Build Coastguard Worker                 rx::IsVulkanSimpleDisplayAvailable())
553*8975f5c5SAndroid Build Coastguard Worker             {
554*8975f5c5SAndroid Build Coastguard Worker                 impl = rx::CreateVulkanSimpleDisplay(state);
555*8975f5c5SAndroid Build Coastguard Worker             }
556*8975f5c5SAndroid Build Coastguard Worker             else if (platformType == EGL_PLATFORM_VULKAN_DISPLAY_MODE_HEADLESS_ANGLE &&
557*8975f5c5SAndroid Build Coastguard Worker                      rx::IsVulkanHeadlessDisplayAvailable())
558*8975f5c5SAndroid Build Coastguard Worker             {
559*8975f5c5SAndroid Build Coastguard Worker                 impl = rx::CreateVulkanHeadlessDisplay(state);
560*8975f5c5SAndroid Build Coastguard Worker             }
561*8975f5c5SAndroid Build Coastguard Worker             else if (rx::IsVulkanOffscreenDisplayAvailable())
562*8975f5c5SAndroid Build Coastguard Worker             {
563*8975f5c5SAndroid Build Coastguard Worker                 impl = rx::CreateVulkanOffscreenDisplay(state);
564*8975f5c5SAndroid Build Coastguard Worker             }
565*8975f5c5SAndroid Build Coastguard Worker             else
566*8975f5c5SAndroid Build Coastguard Worker             {
567*8975f5c5SAndroid Build Coastguard Worker                 // Not supported creation type on vulkan display, fail display creation.
568*8975f5c5SAndroid Build Coastguard Worker                 impl = nullptr;
569*8975f5c5SAndroid Build Coastguard Worker             }
570*8975f5c5SAndroid Build Coastguard Worker #        endif
571*8975f5c5SAndroid Build Coastguard Worker             break;
572*8975f5c5SAndroid Build Coastguard Worker #    elif defined(ANGLE_PLATFORM_ANDROID)
573*8975f5c5SAndroid Build Coastguard Worker             if (rx::IsVulkanAndroidDisplayAvailable())
574*8975f5c5SAndroid Build Coastguard Worker             {
575*8975f5c5SAndroid Build Coastguard Worker                 impl = rx::CreateVulkanAndroidDisplay(state);
576*8975f5c5SAndroid Build Coastguard Worker             }
577*8975f5c5SAndroid Build Coastguard Worker             break;
578*8975f5c5SAndroid Build Coastguard Worker #    elif defined(ANGLE_PLATFORM_FUCHSIA)
579*8975f5c5SAndroid Build Coastguard Worker             if (rx::IsVulkanFuchsiaDisplayAvailable())
580*8975f5c5SAndroid Build Coastguard Worker             {
581*8975f5c5SAndroid Build Coastguard Worker                 impl = rx::CreateVulkanFuchsiaDisplay(state);
582*8975f5c5SAndroid Build Coastguard Worker             }
583*8975f5c5SAndroid Build Coastguard Worker             break;
584*8975f5c5SAndroid Build Coastguard Worker #    elif defined(ANGLE_PLATFORM_GGP)
585*8975f5c5SAndroid Build Coastguard Worker             if (rx::IsVulkanGGPDisplayAvailable())
586*8975f5c5SAndroid Build Coastguard Worker             {
587*8975f5c5SAndroid Build Coastguard Worker                 impl = rx::CreateVulkanGGPDisplay(state);
588*8975f5c5SAndroid Build Coastguard Worker             }
589*8975f5c5SAndroid Build Coastguard Worker             break;
590*8975f5c5SAndroid Build Coastguard Worker #    elif defined(ANGLE_PLATFORM_APPLE)
591*8975f5c5SAndroid Build Coastguard Worker             if (rx::IsVulkanMacDisplayAvailable())
592*8975f5c5SAndroid Build Coastguard Worker             {
593*8975f5c5SAndroid Build Coastguard Worker                 impl = rx::CreateVulkanMacDisplay(state);
594*8975f5c5SAndroid Build Coastguard Worker             }
595*8975f5c5SAndroid Build Coastguard Worker             break;
596*8975f5c5SAndroid Build Coastguard Worker #    else
597*8975f5c5SAndroid Build Coastguard Worker #        error Unsupported Vulkan platform.
598*8975f5c5SAndroid Build Coastguard Worker #    endif
599*8975f5c5SAndroid Build Coastguard Worker #else
600*8975f5c5SAndroid Build Coastguard Worker             // Vulkan isn't available
601*8975f5c5SAndroid Build Coastguard Worker             break;
602*8975f5c5SAndroid Build Coastguard Worker #endif  // defined(ANGLE_ENABLE_VULKAN)
603*8975f5c5SAndroid Build Coastguard Worker 
604*8975f5c5SAndroid Build Coastguard Worker         case EGL_PLATFORM_ANGLE_TYPE_METAL_ANGLE:
605*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_ENABLE_METAL)
606*8975f5c5SAndroid Build Coastguard Worker             if (rx::IsMetalDisplayAvailable())
607*8975f5c5SAndroid Build Coastguard Worker             {
608*8975f5c5SAndroid Build Coastguard Worker                 impl = rx::CreateMetalDisplay(state);
609*8975f5c5SAndroid Build Coastguard Worker                 break;
610*8975f5c5SAndroid Build Coastguard Worker             }
611*8975f5c5SAndroid Build Coastguard Worker #endif
612*8975f5c5SAndroid Build Coastguard Worker             // Metal isn't available.
613*8975f5c5SAndroid Build Coastguard Worker             break;
614*8975f5c5SAndroid Build Coastguard Worker 
615*8975f5c5SAndroid Build Coastguard Worker         case EGL_PLATFORM_ANGLE_TYPE_WEBGPU_ANGLE:
616*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_ENABLE_WGPU)
617*8975f5c5SAndroid Build Coastguard Worker             impl = rx::CreateWgpuDisplay(state);
618*8975f5c5SAndroid Build Coastguard Worker #endif  // defined(ANGLE_ENABLE_WGPU)
619*8975f5c5SAndroid Build Coastguard Worker         // WebGPU isn't available.
620*8975f5c5SAndroid Build Coastguard Worker             break;
621*8975f5c5SAndroid Build Coastguard Worker 
622*8975f5c5SAndroid Build Coastguard Worker         case EGL_PLATFORM_ANGLE_TYPE_NULL_ANGLE:
623*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_ENABLE_NULL)
624*8975f5c5SAndroid Build Coastguard Worker             impl = new rx::DisplayNULL(state);
625*8975f5c5SAndroid Build Coastguard Worker             break;
626*8975f5c5SAndroid Build Coastguard Worker #else
627*8975f5c5SAndroid Build Coastguard Worker             // No display available
628*8975f5c5SAndroid Build Coastguard Worker             UNREACHABLE();
629*8975f5c5SAndroid Build Coastguard Worker             break;
630*8975f5c5SAndroid Build Coastguard Worker #endif  // defined(ANGLE_ENABLE_NULL)
631*8975f5c5SAndroid Build Coastguard Worker 
632*8975f5c5SAndroid Build Coastguard Worker         default:
633*8975f5c5SAndroid Build Coastguard Worker             UNREACHABLE();
634*8975f5c5SAndroid Build Coastguard Worker             break;
635*8975f5c5SAndroid Build Coastguard Worker     }
636*8975f5c5SAndroid Build Coastguard Worker 
637*8975f5c5SAndroid Build Coastguard Worker     return impl;
638*8975f5c5SAndroid Build Coastguard Worker }
639*8975f5c5SAndroid Build Coastguard Worker 
Display_logError(angle::PlatformMethods * platform,const char * errorMessage)640*8975f5c5SAndroid Build Coastguard Worker void Display_logError(angle::PlatformMethods *platform, const char *errorMessage)
641*8975f5c5SAndroid Build Coastguard Worker {
642*8975f5c5SAndroid Build Coastguard Worker     gl::Trace(gl::LOG_ERR, errorMessage);
643*8975f5c5SAndroid Build Coastguard Worker }
644*8975f5c5SAndroid Build Coastguard Worker 
Display_logWarning(angle::PlatformMethods * platform,const char * warningMessage)645*8975f5c5SAndroid Build Coastguard Worker void Display_logWarning(angle::PlatformMethods *platform, const char *warningMessage)
646*8975f5c5SAndroid Build Coastguard Worker {
647*8975f5c5SAndroid Build Coastguard Worker     gl::Trace(gl::LOG_WARN, warningMessage);
648*8975f5c5SAndroid Build Coastguard Worker }
649*8975f5c5SAndroid Build Coastguard Worker 
Display_logInfo(angle::PlatformMethods * platform,const char * infoMessage)650*8975f5c5SAndroid Build Coastguard Worker void Display_logInfo(angle::PlatformMethods *platform, const char *infoMessage)
651*8975f5c5SAndroid Build Coastguard Worker {
652*8975f5c5SAndroid Build Coastguard Worker     // Uncomment to get info spam
653*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_ENABLE_DEBUG_TRACE)
654*8975f5c5SAndroid Build Coastguard Worker     gl::Trace(gl::LOG_INFO, infoMessage);
655*8975f5c5SAndroid Build Coastguard Worker #endif
656*8975f5c5SAndroid Build Coastguard Worker }
657*8975f5c5SAndroid Build Coastguard Worker 
EGLStringArrayToStringVector(const char ** ary)658*8975f5c5SAndroid Build Coastguard Worker const std::vector<std::string> EGLStringArrayToStringVector(const char **ary)
659*8975f5c5SAndroid Build Coastguard Worker {
660*8975f5c5SAndroid Build Coastguard Worker     std::vector<std::string> vec;
661*8975f5c5SAndroid Build Coastguard Worker     if (ary != nullptr)
662*8975f5c5SAndroid Build Coastguard Worker     {
663*8975f5c5SAndroid Build Coastguard Worker         for (; *ary != nullptr; ary++)
664*8975f5c5SAndroid Build Coastguard Worker         {
665*8975f5c5SAndroid Build Coastguard Worker             vec.push_back(std::string(*ary));
666*8975f5c5SAndroid Build Coastguard Worker         }
667*8975f5c5SAndroid Build Coastguard Worker     }
668*8975f5c5SAndroid Build Coastguard Worker     return vec;
669*8975f5c5SAndroid Build Coastguard Worker }
670*8975f5c5SAndroid Build Coastguard Worker 
ANGLESetDefaultDisplayPlatform(angle::EGLDisplayType display)671*8975f5c5SAndroid Build Coastguard Worker void ANGLESetDefaultDisplayPlatform(angle::EGLDisplayType display)
672*8975f5c5SAndroid Build Coastguard Worker {
673*8975f5c5SAndroid Build Coastguard Worker     angle::PlatformMethods *platformMethods = ANGLEPlatformCurrent();
674*8975f5c5SAndroid Build Coastguard Worker 
675*8975f5c5SAndroid Build Coastguard Worker     ANGLEResetDisplayPlatform(display);
676*8975f5c5SAndroid Build Coastguard Worker     platformMethods->logError   = Display_logError;
677*8975f5c5SAndroid Build Coastguard Worker     platformMethods->logWarning = Display_logWarning;
678*8975f5c5SAndroid Build Coastguard Worker     platformMethods->logInfo    = Display_logInfo;
679*8975f5c5SAndroid Build Coastguard Worker }
680*8975f5c5SAndroid Build Coastguard Worker 
UpdateAttribsFromEnvironment(AttributeMap & attribMap)681*8975f5c5SAndroid Build Coastguard Worker void UpdateAttribsFromEnvironment(AttributeMap &attribMap)
682*8975f5c5SAndroid Build Coastguard Worker {
683*8975f5c5SAndroid Build Coastguard Worker     EGLAttrib displayType =
684*8975f5c5SAndroid Build Coastguard Worker         attribMap.get(EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE);
685*8975f5c5SAndroid Build Coastguard Worker     if (displayType == EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE)
686*8975f5c5SAndroid Build Coastguard Worker     {
687*8975f5c5SAndroid Build Coastguard Worker         displayType = GetDisplayTypeFromEnvironment();
688*8975f5c5SAndroid Build Coastguard Worker         attribMap.insert(EGL_PLATFORM_ANGLE_TYPE_ANGLE, displayType);
689*8975f5c5SAndroid Build Coastguard Worker     }
690*8975f5c5SAndroid Build Coastguard Worker     EGLAttrib deviceType = attribMap.get(EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, 0);
691*8975f5c5SAndroid Build Coastguard Worker     if (deviceType == 0)
692*8975f5c5SAndroid Build Coastguard Worker     {
693*8975f5c5SAndroid Build Coastguard Worker         deviceType = GetDeviceTypeFromEnvironment();
694*8975f5c5SAndroid Build Coastguard Worker         attribMap.insert(EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, deviceType);
695*8975f5c5SAndroid Build Coastguard Worker     }
696*8975f5c5SAndroid Build Coastguard Worker     EGLAttrib platformType = attribMap.get(EGL_PLATFORM_ANGLE_NATIVE_PLATFORM_TYPE_ANGLE, 0);
697*8975f5c5SAndroid Build Coastguard Worker     if (platformType == 0)
698*8975f5c5SAndroid Build Coastguard Worker     {
699*8975f5c5SAndroid Build Coastguard Worker         platformType = GetPlatformTypeFromEnvironment();
700*8975f5c5SAndroid Build Coastguard Worker         attribMap.insert(EGL_PLATFORM_ANGLE_NATIVE_PLATFORM_TYPE_ANGLE, platformType);
701*8975f5c5SAndroid Build Coastguard Worker     }
702*8975f5c5SAndroid Build Coastguard Worker }
703*8975f5c5SAndroid Build Coastguard Worker 
704*8975f5c5SAndroid Build Coastguard Worker static constexpr uint32_t kScratchBufferLifetime = 64u;
705*8975f5c5SAndroid Build Coastguard Worker 
706*8975f5c5SAndroid Build Coastguard Worker }  // anonymous namespace
707*8975f5c5SAndroid Build Coastguard Worker 
708*8975f5c5SAndroid Build Coastguard Worker // DisplayState
DisplayState(EGLNativeDisplayType nativeDisplayId)709*8975f5c5SAndroid Build Coastguard Worker DisplayState::DisplayState(EGLNativeDisplayType nativeDisplayId)
710*8975f5c5SAndroid Build Coastguard Worker     : label(nullptr),
711*8975f5c5SAndroid Build Coastguard Worker       displayId(nativeDisplayId),
712*8975f5c5SAndroid Build Coastguard Worker       singleThreadPool(nullptr),
713*8975f5c5SAndroid Build Coastguard Worker       multiThreadPool(nullptr),
714*8975f5c5SAndroid Build Coastguard Worker       deviceLost(false)
715*8975f5c5SAndroid Build Coastguard Worker {}
716*8975f5c5SAndroid Build Coastguard Worker 
~DisplayState()717*8975f5c5SAndroid Build Coastguard Worker DisplayState::~DisplayState() {}
718*8975f5c5SAndroid Build Coastguard Worker 
notifyDeviceLost() const719*8975f5c5SAndroid Build Coastguard Worker void DisplayState::notifyDeviceLost() const
720*8975f5c5SAndroid Build Coastguard Worker {
721*8975f5c5SAndroid Build Coastguard Worker     if (deviceLost)
722*8975f5c5SAndroid Build Coastguard Worker     {
723*8975f5c5SAndroid Build Coastguard Worker         return;
724*8975f5c5SAndroid Build Coastguard Worker     }
725*8975f5c5SAndroid Build Coastguard Worker 
726*8975f5c5SAndroid Build Coastguard Worker     {
727*8975f5c5SAndroid Build Coastguard Worker         std::lock_guard<angle::SimpleMutex> lock(contextMapMutex);
728*8975f5c5SAndroid Build Coastguard Worker         for (auto context = contextMap.begin(); context != contextMap.end(); context++)
729*8975f5c5SAndroid Build Coastguard Worker         {
730*8975f5c5SAndroid Build Coastguard Worker             context->second->markContextLost(gl::GraphicsResetStatus::UnknownContextReset);
731*8975f5c5SAndroid Build Coastguard Worker         }
732*8975f5c5SAndroid Build Coastguard Worker     }
733*8975f5c5SAndroid Build Coastguard Worker 
734*8975f5c5SAndroid Build Coastguard Worker     deviceLost = true;
735*8975f5c5SAndroid Build Coastguard Worker }
736*8975f5c5SAndroid Build Coastguard Worker 
737*8975f5c5SAndroid Build Coastguard Worker // Note that ANGLE support on Ozone platform is limited. Our preferred support Matrix for
738*8975f5c5SAndroid Build Coastguard Worker // EGL_ANGLE_platform_angle on Linux and Ozone/Linux/Fuchsia platforms should be the following:
739*8975f5c5SAndroid Build Coastguard Worker //
740*8975f5c5SAndroid Build Coastguard Worker // |--------------------------------------------------------|
741*8975f5c5SAndroid Build Coastguard Worker // | ANGLE type | DEVICE type |  PLATFORM type   | Display  |
742*8975f5c5SAndroid Build Coastguard Worker // |--------------------------------------------------------|
743*8975f5c5SAndroid Build Coastguard Worker // |   OPENGL   |     EGL     |       ANY        |   EGL    |
744*8975f5c5SAndroid Build Coastguard Worker // |   OPENGL   |   HARDWARE  |     X11_EXT      |   GLX    |
745*8975f5c5SAndroid Build Coastguard Worker // |  OPENGLES  |   HARDWARE  |     X11_EXT      |   GLX    |
746*8975f5c5SAndroid Build Coastguard Worker // |  OPENGLES  |     EGL     |       ANY        |   EGL    |
747*8975f5c5SAndroid Build Coastguard Worker // |   VULKAN   |   HARDWARE  |     X11_EXT      |  VkXcb   |
748*8975f5c5SAndroid Build Coastguard Worker // |   VULKAN   | SWIFTSHADER |     X11_EXT      |  VkXcb   |
749*8975f5c5SAndroid Build Coastguard Worker // |  OPENGLES  |   HARDWARE  | SURFACELESS_MESA |   EGL*   |
750*8975f5c5SAndroid Build Coastguard Worker // |  OPENGLES  |   HARDWARE  |    DEVICE_EXT    |   EGL    |
751*8975f5c5SAndroid Build Coastguard Worker // |   VULKAN   |   HARDWARE  | SURFACELESS_MESA | VkBase** |
752*8975f5c5SAndroid Build Coastguard Worker // |   VULKAN   | SWIFTSHADER | SURFACELESS_MESA | VkBase** |
753*8975f5c5SAndroid Build Coastguard Worker // |--------------------------------------------------------|
754*8975f5c5SAndroid Build Coastguard Worker //
755*8975f5c5SAndroid Build Coastguard Worker // * No surfaceless support yet.
756*8975f5c5SAndroid Build Coastguard Worker // ** Not implemented yet.
757*8975f5c5SAndroid Build Coastguard Worker //
758*8975f5c5SAndroid Build Coastguard Worker // |-----------------------------------------------|
759*8975f5c5SAndroid Build Coastguard Worker // |   OS    | BUILD type |  Default PLATFORM type |
760*8975f5c5SAndroid Build Coastguard Worker // |-----------------------------------------------|
761*8975f5c5SAndroid Build Coastguard Worker // |  Linux  |    X11     |        X11_EXT         |
762*8975f5c5SAndroid Build Coastguard Worker // |  Linux  |   Ozone    |    SURFACELESS_MESA    |
763*8975f5c5SAndroid Build Coastguard Worker // | Fuchsia |   Ozone    |        FUCHSIA***      |
764*8975f5c5SAndroid Build Coastguard Worker // |-----------------------------------------------|
765*8975f5c5SAndroid Build Coastguard Worker //
766*8975f5c5SAndroid Build Coastguard Worker // *** Chosen implicitly. No EGLAttrib available.
767*8975f5c5SAndroid Build Coastguard Worker //
768*8975f5c5SAndroid Build Coastguard Worker // For more details, please refer to
769*8975f5c5SAndroid Build Coastguard Worker // https://docs.google.com/document/d/1XjHiDZQISq1AMrg_l1TX1_kIKvDpU76hidn9i4cAjl8/edit?disco=AAAAJl9V_YY
770*8975f5c5SAndroid Build Coastguard Worker //
771*8975f5c5SAndroid Build Coastguard Worker // static
GetDisplayFromNativeDisplay(EGLenum platform,EGLNativeDisplayType nativeDisplay,const AttributeMap & attribMap)772*8975f5c5SAndroid Build Coastguard Worker Display *Display::GetDisplayFromNativeDisplay(EGLenum platform,
773*8975f5c5SAndroid Build Coastguard Worker                                               EGLNativeDisplayType nativeDisplay,
774*8975f5c5SAndroid Build Coastguard Worker                                               const AttributeMap &attribMap)
775*8975f5c5SAndroid Build Coastguard Worker {
776*8975f5c5SAndroid Build Coastguard Worker     Display *display = nullptr;
777*8975f5c5SAndroid Build Coastguard Worker 
778*8975f5c5SAndroid Build Coastguard Worker     AttributeMap updatedAttribMap(attribMap);
779*8975f5c5SAndroid Build Coastguard Worker     UpdateAttribsFromEnvironment(updatedAttribMap);
780*8975f5c5SAndroid Build Coastguard Worker 
781*8975f5c5SAndroid Build Coastguard Worker     EGLAttrib powerPreference =
782*8975f5c5SAndroid Build Coastguard Worker         updatedAttribMap.get(EGL_POWER_PREFERENCE_ANGLE, EGL_LOW_POWER_ANGLE);
783*8975f5c5SAndroid Build Coastguard Worker     EGLAttrib platformANGLEType =
784*8975f5c5SAndroid Build Coastguard Worker         updatedAttribMap.get(EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE);
785*8975f5c5SAndroid Build Coastguard Worker     EGLAttrib deviceIdHigh = updatedAttribMap.get(EGL_PLATFORM_ANGLE_DEVICE_ID_HIGH_ANGLE, 0);
786*8975f5c5SAndroid Build Coastguard Worker     EGLAttrib deviceIdLow  = updatedAttribMap.get(EGL_PLATFORM_ANGLE_DEVICE_ID_LOW_ANGLE, 0);
787*8975f5c5SAndroid Build Coastguard Worker     EGLAttrib displayKey   = updatedAttribMap.get(EGL_PLATFORM_ANGLE_DISPLAY_KEY_ANGLE, 0);
788*8975f5c5SAndroid Build Coastguard Worker     EGLAttrib enabledFeatureOverrides =
789*8975f5c5SAndroid Build Coastguard Worker         updatedAttribMap.get(EGL_FEATURE_OVERRIDES_ENABLED_ANGLE, 0);
790*8975f5c5SAndroid Build Coastguard Worker     EGLAttrib disabledFeatureOverrides =
791*8975f5c5SAndroid Build Coastguard Worker         updatedAttribMap.get(EGL_FEATURE_OVERRIDES_DISABLED_ANGLE, 0);
792*8975f5c5SAndroid Build Coastguard Worker     EGLAttrib disableAllNonOverriddenFeatures =
793*8975f5c5SAndroid Build Coastguard Worker         updatedAttribMap.get(EGL_FEATURE_ALL_DISABLED_ANGLE, 0);
794*8975f5c5SAndroid Build Coastguard Worker     ANGLEPlatformDisplay combinedDisplayKey(
795*8975f5c5SAndroid Build Coastguard Worker         nativeDisplay, powerPreference, platformANGLEType, deviceIdHigh, deviceIdLow, displayKey,
796*8975f5c5SAndroid Build Coastguard Worker         enabledFeatureOverrides, disabledFeatureOverrides, disableAllNonOverriddenFeatures);
797*8975f5c5SAndroid Build Coastguard Worker 
798*8975f5c5SAndroid Build Coastguard Worker     {
799*8975f5c5SAndroid Build Coastguard Worker         std::lock_guard<angle::SimpleMutex> lock(*ANGLEPlatformDisplayMapMutex());
800*8975f5c5SAndroid Build Coastguard Worker 
801*8975f5c5SAndroid Build Coastguard Worker         ANGLEPlatformDisplayMap *displays = GetANGLEPlatformDisplayMap();
802*8975f5c5SAndroid Build Coastguard Worker         const auto &iter                  = displays->find(combinedDisplayKey);
803*8975f5c5SAndroid Build Coastguard Worker 
804*8975f5c5SAndroid Build Coastguard Worker         if (iter != displays->end())
805*8975f5c5SAndroid Build Coastguard Worker         {
806*8975f5c5SAndroid Build Coastguard Worker             display = iter->second;
807*8975f5c5SAndroid Build Coastguard Worker         }
808*8975f5c5SAndroid Build Coastguard Worker 
809*8975f5c5SAndroid Build Coastguard Worker         if (display == nullptr)
810*8975f5c5SAndroid Build Coastguard Worker         {
811*8975f5c5SAndroid Build Coastguard Worker             // Validate the native display
812*8975f5c5SAndroid Build Coastguard Worker             if (!Display::isValidNativeDisplay(nativeDisplay))
813*8975f5c5SAndroid Build Coastguard Worker             {
814*8975f5c5SAndroid Build Coastguard Worker                 return nullptr;
815*8975f5c5SAndroid Build Coastguard Worker             }
816*8975f5c5SAndroid Build Coastguard Worker 
817*8975f5c5SAndroid Build Coastguard Worker             display = new Display(platform, nativeDisplay, nullptr);
818*8975f5c5SAndroid Build Coastguard Worker             displays->insert(std::make_pair(combinedDisplayKey, display));
819*8975f5c5SAndroid Build Coastguard Worker         }
820*8975f5c5SAndroid Build Coastguard Worker     }
821*8975f5c5SAndroid Build Coastguard Worker     // Apply new attributes if the display is not initialized yet.
822*8975f5c5SAndroid Build Coastguard Worker     if (!display->isInitialized())
823*8975f5c5SAndroid Build Coastguard Worker     {
824*8975f5c5SAndroid Build Coastguard Worker         display->setAttributes(updatedAttribMap);
825*8975f5c5SAndroid Build Coastguard Worker 
826*8975f5c5SAndroid Build Coastguard Worker         EGLAttrib displayType  = display->mAttributeMap.get(EGL_PLATFORM_ANGLE_TYPE_ANGLE);
827*8975f5c5SAndroid Build Coastguard Worker         EGLAttrib deviceType   = display->mAttributeMap.get(EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE);
828*8975f5c5SAndroid Build Coastguard Worker         EGLAttrib platformType = platform;
829*8975f5c5SAndroid Build Coastguard Worker         if (platform == EGL_PLATFORM_ANGLE_ANGLE)
830*8975f5c5SAndroid Build Coastguard Worker         {
831*8975f5c5SAndroid Build Coastguard Worker             platformType =
832*8975f5c5SAndroid Build Coastguard Worker                 display->mAttributeMap.get(EGL_PLATFORM_ANGLE_NATIVE_PLATFORM_TYPE_ANGLE);
833*8975f5c5SAndroid Build Coastguard Worker         }
834*8975f5c5SAndroid Build Coastguard Worker         rx::DisplayImpl *impl =
835*8975f5c5SAndroid Build Coastguard Worker             CreateDisplayFromAttribs(displayType, deviceType, platformType, display->getState());
836*8975f5c5SAndroid Build Coastguard Worker         if (impl == nullptr)
837*8975f5c5SAndroid Build Coastguard Worker         {
838*8975f5c5SAndroid Build Coastguard Worker             // No valid display implementation for these attributes
839*8975f5c5SAndroid Build Coastguard Worker             return nullptr;
840*8975f5c5SAndroid Build Coastguard Worker         }
841*8975f5c5SAndroid Build Coastguard Worker 
842*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_USE_ANDROID_TLS_SLOT)
843*8975f5c5SAndroid Build Coastguard Worker         angle::gUseAndroidOpenGLTlsSlot = displayType == EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE;
844*8975f5c5SAndroid Build Coastguard Worker #endif  // defined(ANGLE_PLATFORM_ANDROID)
845*8975f5c5SAndroid Build Coastguard Worker 
846*8975f5c5SAndroid Build Coastguard Worker         display->setupDisplayPlatform(impl);
847*8975f5c5SAndroid Build Coastguard Worker     }
848*8975f5c5SAndroid Build Coastguard Worker 
849*8975f5c5SAndroid Build Coastguard Worker     return display;
850*8975f5c5SAndroid Build Coastguard Worker }
851*8975f5c5SAndroid Build Coastguard Worker 
852*8975f5c5SAndroid Build Coastguard Worker // static
GetExistingDisplayFromNativeDisplay(EGLNativeDisplayType nativeDisplay)853*8975f5c5SAndroid Build Coastguard Worker Display *Display::GetExistingDisplayFromNativeDisplay(EGLNativeDisplayType nativeDisplay)
854*8975f5c5SAndroid Build Coastguard Worker {
855*8975f5c5SAndroid Build Coastguard Worker     std::lock_guard<angle::SimpleMutex> lock(*ANGLEPlatformDisplayMapMutex());
856*8975f5c5SAndroid Build Coastguard Worker     ANGLEPlatformDisplayMap *displays = GetANGLEPlatformDisplayMap();
857*8975f5c5SAndroid Build Coastguard Worker     const auto &iter                  = displays->find(nativeDisplay);
858*8975f5c5SAndroid Build Coastguard Worker 
859*8975f5c5SAndroid Build Coastguard Worker     // Check that there is a matching display
860*8975f5c5SAndroid Build Coastguard Worker     if (iter == displays->end())
861*8975f5c5SAndroid Build Coastguard Worker     {
862*8975f5c5SAndroid Build Coastguard Worker         return nullptr;
863*8975f5c5SAndroid Build Coastguard Worker     }
864*8975f5c5SAndroid Build Coastguard Worker 
865*8975f5c5SAndroid Build Coastguard Worker     return iter->second;
866*8975f5c5SAndroid Build Coastguard Worker }
867*8975f5c5SAndroid Build Coastguard Worker 
868*8975f5c5SAndroid Build Coastguard Worker // static
GetDisplayFromDevice(Device * device,const AttributeMap & attribMap)869*8975f5c5SAndroid Build Coastguard Worker Display *Display::GetDisplayFromDevice(Device *device, const AttributeMap &attribMap)
870*8975f5c5SAndroid Build Coastguard Worker {
871*8975f5c5SAndroid Build Coastguard Worker     Display *display = nullptr;
872*8975f5c5SAndroid Build Coastguard Worker 
873*8975f5c5SAndroid Build Coastguard Worker     ASSERT(Device::IsValidDevice(device));
874*8975f5c5SAndroid Build Coastguard Worker 
875*8975f5c5SAndroid Build Coastguard Worker     {
876*8975f5c5SAndroid Build Coastguard Worker         // First see if this eglDevice is in use by a Display created using ANGLE platform
877*8975f5c5SAndroid Build Coastguard Worker         std::lock_guard<angle::SimpleMutex> lock(*ANGLEPlatformDisplayMapMutex());
878*8975f5c5SAndroid Build Coastguard Worker         ANGLEPlatformDisplayMap *anglePlatformDisplays = GetANGLEPlatformDisplayMap();
879*8975f5c5SAndroid Build Coastguard Worker         for (auto &displayMapEntry : *anglePlatformDisplays)
880*8975f5c5SAndroid Build Coastguard Worker         {
881*8975f5c5SAndroid Build Coastguard Worker             egl::Display *iterDisplay = displayMapEntry.second;
882*8975f5c5SAndroid Build Coastguard Worker             if (iterDisplay->getDevice() == device)
883*8975f5c5SAndroid Build Coastguard Worker             {
884*8975f5c5SAndroid Build Coastguard Worker                 display = iterDisplay;
885*8975f5c5SAndroid Build Coastguard Worker             }
886*8975f5c5SAndroid Build Coastguard Worker         }
887*8975f5c5SAndroid Build Coastguard Worker     }
888*8975f5c5SAndroid Build Coastguard Worker 
889*8975f5c5SAndroid Build Coastguard Worker     if (display == nullptr)
890*8975f5c5SAndroid Build Coastguard Worker     {
891*8975f5c5SAndroid Build Coastguard Worker         // Next see if this eglDevice is in use by a Display created using the DEVICE platform
892*8975f5c5SAndroid Build Coastguard Worker         std::lock_guard<angle::SimpleMutex> lock(*DevicePlatformDisplayMapMutex());
893*8975f5c5SAndroid Build Coastguard Worker         DevicePlatformDisplayMap *devicePlatformDisplays = GetDevicePlatformDisplayMap();
894*8975f5c5SAndroid Build Coastguard Worker 
895*8975f5c5SAndroid Build Coastguard Worker         // See if the eglDevice is in use by a Display created using the DEVICE platform
896*8975f5c5SAndroid Build Coastguard Worker         const auto &iter = devicePlatformDisplays->find(device);
897*8975f5c5SAndroid Build Coastguard Worker         if (iter != devicePlatformDisplays->end())
898*8975f5c5SAndroid Build Coastguard Worker         {
899*8975f5c5SAndroid Build Coastguard Worker             display = iter->second;
900*8975f5c5SAndroid Build Coastguard Worker         }
901*8975f5c5SAndroid Build Coastguard Worker 
902*8975f5c5SAndroid Build Coastguard Worker         if (display == nullptr)
903*8975f5c5SAndroid Build Coastguard Worker         {
904*8975f5c5SAndroid Build Coastguard Worker             // Otherwise create a new Display
905*8975f5c5SAndroid Build Coastguard Worker             display = new Display(EGL_PLATFORM_DEVICE_EXT, 0, device);
906*8975f5c5SAndroid Build Coastguard Worker             devicePlatformDisplays->insert(std::make_pair(device, display));
907*8975f5c5SAndroid Build Coastguard Worker         }
908*8975f5c5SAndroid Build Coastguard Worker     }
909*8975f5c5SAndroid Build Coastguard Worker 
910*8975f5c5SAndroid Build Coastguard Worker     // Apply new attributes if the display is not initialized yet.
911*8975f5c5SAndroid Build Coastguard Worker     if (!display->isInitialized())
912*8975f5c5SAndroid Build Coastguard Worker     {
913*8975f5c5SAndroid Build Coastguard Worker         display->setAttributes(attribMap);
914*8975f5c5SAndroid Build Coastguard Worker         rx::DisplayImpl *impl = CreateDisplayFromDevice(device, display->getState());
915*8975f5c5SAndroid Build Coastguard Worker         display->setupDisplayPlatform(impl);
916*8975f5c5SAndroid Build Coastguard Worker     }
917*8975f5c5SAndroid Build Coastguard Worker 
918*8975f5c5SAndroid Build Coastguard Worker     return display;
919*8975f5c5SAndroid Build Coastguard Worker }
920*8975f5c5SAndroid Build Coastguard Worker 
Display(EGLenum platform,EGLNativeDisplayType displayId,Device * eglDevice)921*8975f5c5SAndroid Build Coastguard Worker Display::Display(EGLenum platform, EGLNativeDisplayType displayId, Device *eglDevice)
922*8975f5c5SAndroid Build Coastguard Worker     : mState(displayId),
923*8975f5c5SAndroid Build Coastguard Worker       mImplementation(nullptr),
924*8975f5c5SAndroid Build Coastguard Worker       mGPUSwitchedBinding(this, kGPUSwitchedSubjectIndex),
925*8975f5c5SAndroid Build Coastguard Worker       mAttributeMap(),
926*8975f5c5SAndroid Build Coastguard Worker       mConfigSet(),
927*8975f5c5SAndroid Build Coastguard Worker       mStreamSet(),
928*8975f5c5SAndroid Build Coastguard Worker       mInvalidContextMap(),
929*8975f5c5SAndroid Build Coastguard Worker       mInvalidImageMap(),
930*8975f5c5SAndroid Build Coastguard Worker       mInvalidStreamSet(),
931*8975f5c5SAndroid Build Coastguard Worker       mInvalidSurfaceMap(),
932*8975f5c5SAndroid Build Coastguard Worker       mInvalidSyncMap(),
933*8975f5c5SAndroid Build Coastguard Worker       mInitialized(false),
934*8975f5c5SAndroid Build Coastguard Worker       mCaps(),
935*8975f5c5SAndroid Build Coastguard Worker       mDisplayExtensions(),
936*8975f5c5SAndroid Build Coastguard Worker       mDisplayExtensionString(),
937*8975f5c5SAndroid Build Coastguard Worker       mVendorString(),
938*8975f5c5SAndroid Build Coastguard Worker       mVersionString(),
939*8975f5c5SAndroid Build Coastguard Worker       mDevice(eglDevice),
940*8975f5c5SAndroid Build Coastguard Worker       mSurface(nullptr),
941*8975f5c5SAndroid Build Coastguard Worker       mPlatform(platform),
942*8975f5c5SAndroid Build Coastguard Worker       mManagersMutex(nullptr),
943*8975f5c5SAndroid Build Coastguard Worker       mTextureManager(nullptr),
944*8975f5c5SAndroid Build Coastguard Worker       mSemaphoreManager(nullptr),
945*8975f5c5SAndroid Build Coastguard Worker       mBlobCache(gl::kDefaultMaxProgramCacheMemoryBytes),
946*8975f5c5SAndroid Build Coastguard Worker       mMemoryProgramCache(mBlobCache),
947*8975f5c5SAndroid Build Coastguard Worker       mMemoryShaderCache(mBlobCache),
948*8975f5c5SAndroid Build Coastguard Worker       mGlobalTextureShareGroupUsers(0),
949*8975f5c5SAndroid Build Coastguard Worker       mGlobalSemaphoreShareGroupUsers(0),
950*8975f5c5SAndroid Build Coastguard Worker       mTerminatedByApi(false)
951*8975f5c5SAndroid Build Coastguard Worker {}
952*8975f5c5SAndroid Build Coastguard Worker 
~Display()953*8975f5c5SAndroid Build Coastguard Worker Display::~Display()
954*8975f5c5SAndroid Build Coastguard Worker {
955*8975f5c5SAndroid Build Coastguard Worker     switch (mPlatform)
956*8975f5c5SAndroid Build Coastguard Worker     {
957*8975f5c5SAndroid Build Coastguard Worker         case EGL_PLATFORM_ANGLE_ANGLE:
958*8975f5c5SAndroid Build Coastguard Worker         case EGL_PLATFORM_GBM_KHR:
959*8975f5c5SAndroid Build Coastguard Worker         case EGL_PLATFORM_WAYLAND_EXT:
960*8975f5c5SAndroid Build Coastguard Worker         case EGL_PLATFORM_SURFACELESS_MESA:
961*8975f5c5SAndroid Build Coastguard Worker         {
962*8975f5c5SAndroid Build Coastguard Worker             std::lock_guard<angle::SimpleMutex> lock(*ANGLEPlatformDisplayMapMutex());
963*8975f5c5SAndroid Build Coastguard Worker             ANGLEPlatformDisplayMap *displays      = GetANGLEPlatformDisplayMap();
964*8975f5c5SAndroid Build Coastguard Worker             ANGLEPlatformDisplayMap::iterator iter = displays->find(ANGLEPlatformDisplay(
965*8975f5c5SAndroid Build Coastguard Worker                 mState.displayId,
966*8975f5c5SAndroid Build Coastguard Worker                 mAttributeMap.get(EGL_POWER_PREFERENCE_ANGLE, EGL_LOW_POWER_ANGLE),
967*8975f5c5SAndroid Build Coastguard Worker                 mAttributeMap.get(EGL_PLATFORM_ANGLE_TYPE_ANGLE,
968*8975f5c5SAndroid Build Coastguard Worker                                   EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE),
969*8975f5c5SAndroid Build Coastguard Worker                 mAttributeMap.get(EGL_PLATFORM_ANGLE_DEVICE_ID_HIGH_ANGLE, 0),
970*8975f5c5SAndroid Build Coastguard Worker                 mAttributeMap.get(EGL_PLATFORM_ANGLE_DEVICE_ID_LOW_ANGLE, 0),
971*8975f5c5SAndroid Build Coastguard Worker                 mAttributeMap.get(EGL_PLATFORM_ANGLE_DISPLAY_KEY_ANGLE, 0),
972*8975f5c5SAndroid Build Coastguard Worker                 mAttributeMap.get(EGL_FEATURE_OVERRIDES_ENABLED_ANGLE, 0),
973*8975f5c5SAndroid Build Coastguard Worker                 mAttributeMap.get(EGL_FEATURE_OVERRIDES_DISABLED_ANGLE, 0),
974*8975f5c5SAndroid Build Coastguard Worker                 mAttributeMap.get(EGL_FEATURE_ALL_DISABLED_ANGLE, 0)));
975*8975f5c5SAndroid Build Coastguard Worker             if (iter != displays->end())
976*8975f5c5SAndroid Build Coastguard Worker             {
977*8975f5c5SAndroid Build Coastguard Worker                 displays->erase(iter);
978*8975f5c5SAndroid Build Coastguard Worker             }
979*8975f5c5SAndroid Build Coastguard Worker             break;
980*8975f5c5SAndroid Build Coastguard Worker         }
981*8975f5c5SAndroid Build Coastguard Worker         case EGL_PLATFORM_DEVICE_EXT:
982*8975f5c5SAndroid Build Coastguard Worker         {
983*8975f5c5SAndroid Build Coastguard Worker             std::lock_guard<angle::SimpleMutex> lock(*DevicePlatformDisplayMapMutex());
984*8975f5c5SAndroid Build Coastguard Worker             DevicePlatformDisplayMap *displays      = GetDevicePlatformDisplayMap();
985*8975f5c5SAndroid Build Coastguard Worker             DevicePlatformDisplayMap::iterator iter = displays->find(mDevice);
986*8975f5c5SAndroid Build Coastguard Worker             if (iter != displays->end())
987*8975f5c5SAndroid Build Coastguard Worker             {
988*8975f5c5SAndroid Build Coastguard Worker                 displays->erase(iter);
989*8975f5c5SAndroid Build Coastguard Worker             }
990*8975f5c5SAndroid Build Coastguard Worker             break;
991*8975f5c5SAndroid Build Coastguard Worker         }
992*8975f5c5SAndroid Build Coastguard Worker         default:
993*8975f5c5SAndroid Build Coastguard Worker         {
994*8975f5c5SAndroid Build Coastguard Worker             UNREACHABLE();
995*8975f5c5SAndroid Build Coastguard Worker         }
996*8975f5c5SAndroid Build Coastguard Worker     }
997*8975f5c5SAndroid Build Coastguard Worker 
998*8975f5c5SAndroid Build Coastguard Worker     SafeDelete(mDevice);
999*8975f5c5SAndroid Build Coastguard Worker     SafeDelete(mImplementation);
1000*8975f5c5SAndroid Build Coastguard Worker }
1001*8975f5c5SAndroid Build Coastguard Worker 
setLabel(EGLLabelKHR label)1002*8975f5c5SAndroid Build Coastguard Worker void Display::setLabel(EGLLabelKHR label)
1003*8975f5c5SAndroid Build Coastguard Worker {
1004*8975f5c5SAndroid Build Coastguard Worker     mState.label = label;
1005*8975f5c5SAndroid Build Coastguard Worker }
1006*8975f5c5SAndroid Build Coastguard Worker 
getLabel() const1007*8975f5c5SAndroid Build Coastguard Worker EGLLabelKHR Display::getLabel() const
1008*8975f5c5SAndroid Build Coastguard Worker {
1009*8975f5c5SAndroid Build Coastguard Worker     return mState.label;
1010*8975f5c5SAndroid Build Coastguard Worker }
1011*8975f5c5SAndroid Build Coastguard Worker 
onSubjectStateChange(angle::SubjectIndex index,angle::SubjectMessage message)1012*8975f5c5SAndroid Build Coastguard Worker void Display::onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message)
1013*8975f5c5SAndroid Build Coastguard Worker {
1014*8975f5c5SAndroid Build Coastguard Worker     ASSERT(index == kGPUSwitchedSubjectIndex);
1015*8975f5c5SAndroid Build Coastguard Worker     ASSERT(message == angle::SubjectMessage::SubjectChanged);
1016*8975f5c5SAndroid Build Coastguard Worker     std::lock_guard<angle::SimpleMutex> lock(mState.contextMapMutex);
1017*8975f5c5SAndroid Build Coastguard Worker     for (auto context : mState.contextMap)
1018*8975f5c5SAndroid Build Coastguard Worker     {
1019*8975f5c5SAndroid Build Coastguard Worker         context.second->onGPUSwitch();
1020*8975f5c5SAndroid Build Coastguard Worker     }
1021*8975f5c5SAndroid Build Coastguard Worker }
1022*8975f5c5SAndroid Build Coastguard Worker 
setupDisplayPlatform(rx::DisplayImpl * impl)1023*8975f5c5SAndroid Build Coastguard Worker void Display::setupDisplayPlatform(rx::DisplayImpl *impl)
1024*8975f5c5SAndroid Build Coastguard Worker {
1025*8975f5c5SAndroid Build Coastguard Worker     ASSERT(!mInitialized);
1026*8975f5c5SAndroid Build Coastguard Worker 
1027*8975f5c5SAndroid Build Coastguard Worker     ASSERT(impl != nullptr);
1028*8975f5c5SAndroid Build Coastguard Worker     SafeDelete(mImplementation);
1029*8975f5c5SAndroid Build Coastguard Worker     mImplementation = impl;
1030*8975f5c5SAndroid Build Coastguard Worker 
1031*8975f5c5SAndroid Build Coastguard Worker     // TODO(anglebug.com/42265835): Remove PlatformMethods.
1032*8975f5c5SAndroid Build Coastguard Worker     const angle::PlatformMethods *platformMethods =
1033*8975f5c5SAndroid Build Coastguard Worker         reinterpret_cast<const angle::PlatformMethods *>(
1034*8975f5c5SAndroid Build Coastguard Worker             mAttributeMap.get(EGL_PLATFORM_ANGLE_PLATFORM_METHODS_ANGLEX, 0));
1035*8975f5c5SAndroid Build Coastguard Worker     if (platformMethods != nullptr)
1036*8975f5c5SAndroid Build Coastguard Worker     {
1037*8975f5c5SAndroid Build Coastguard Worker         *ANGLEPlatformCurrent() = *platformMethods;
1038*8975f5c5SAndroid Build Coastguard Worker     }
1039*8975f5c5SAndroid Build Coastguard Worker     else
1040*8975f5c5SAndroid Build Coastguard Worker     {
1041*8975f5c5SAndroid Build Coastguard Worker         ANGLESetDefaultDisplayPlatform(this);
1042*8975f5c5SAndroid Build Coastguard Worker     }
1043*8975f5c5SAndroid Build Coastguard Worker 
1044*8975f5c5SAndroid Build Coastguard Worker     const char **featuresForceEnabled =
1045*8975f5c5SAndroid Build Coastguard Worker         reinterpret_cast<const char **>(mAttributeMap.get(EGL_FEATURE_OVERRIDES_ENABLED_ANGLE, 0));
1046*8975f5c5SAndroid Build Coastguard Worker     const char **featuresForceDisabled =
1047*8975f5c5SAndroid Build Coastguard Worker         reinterpret_cast<const char **>(mAttributeMap.get(EGL_FEATURE_OVERRIDES_DISABLED_ANGLE, 0));
1048*8975f5c5SAndroid Build Coastguard Worker     mState.featureOverrides.enabled  = EGLStringArrayToStringVector(featuresForceEnabled);
1049*8975f5c5SAndroid Build Coastguard Worker     mState.featureOverrides.disabled = EGLStringArrayToStringVector(featuresForceDisabled);
1050*8975f5c5SAndroid Build Coastguard Worker     mState.featureOverrides.allDisabled =
1051*8975f5c5SAndroid Build Coastguard Worker         static_cast<bool>(mAttributeMap.get(EGL_FEATURE_ALL_DISABLED_ANGLE, 0));
1052*8975f5c5SAndroid Build Coastguard Worker     mImplementation->addObserver(&mGPUSwitchedBinding);
1053*8975f5c5SAndroid Build Coastguard Worker }
1054*8975f5c5SAndroid Build Coastguard Worker 
initialize()1055*8975f5c5SAndroid Build Coastguard Worker Error Display::initialize()
1056*8975f5c5SAndroid Build Coastguard Worker {
1057*8975f5c5SAndroid Build Coastguard Worker     mTerminatedByApi = false;
1058*8975f5c5SAndroid Build Coastguard Worker 
1059*8975f5c5SAndroid Build Coastguard Worker     ASSERT(mImplementation != nullptr);
1060*8975f5c5SAndroid Build Coastguard Worker     mImplementation->setBlobCache(&mBlobCache);
1061*8975f5c5SAndroid Build Coastguard Worker 
1062*8975f5c5SAndroid Build Coastguard Worker     // Enable shader caching if debug layers are turned on. This allows us to test that shaders are
1063*8975f5c5SAndroid Build Coastguard Worker     // properly saved & restored on all platforms. The cache won't allocate space until it's used
1064*8975f5c5SAndroid Build Coastguard Worker     // and will be ignored entirely if the application / system sets it's own cache functions.
1065*8975f5c5SAndroid Build Coastguard Worker     if (rx::ShouldUseDebugLayers(mAttributeMap))
1066*8975f5c5SAndroid Build Coastguard Worker     {
1067*8975f5c5SAndroid Build Coastguard Worker         mBlobCache.resize(1024 * 1024);
1068*8975f5c5SAndroid Build Coastguard Worker     }
1069*8975f5c5SAndroid Build Coastguard Worker 
1070*8975f5c5SAndroid Build Coastguard Worker     setGlobalDebugAnnotator();
1071*8975f5c5SAndroid Build Coastguard Worker 
1072*8975f5c5SAndroid Build Coastguard Worker     gl::InitializeDebugMutexIfNeeded();
1073*8975f5c5SAndroid Build Coastguard Worker 
1074*8975f5c5SAndroid Build Coastguard Worker     ANGLE_TRACE_EVENT0("gpu.angle", "egl::Display::initialize");
1075*8975f5c5SAndroid Build Coastguard Worker 
1076*8975f5c5SAndroid Build Coastguard Worker     if (isInitialized())
1077*8975f5c5SAndroid Build Coastguard Worker     {
1078*8975f5c5SAndroid Build Coastguard Worker         return NoError();
1079*8975f5c5SAndroid Build Coastguard Worker     }
1080*8975f5c5SAndroid Build Coastguard Worker 
1081*8975f5c5SAndroid Build Coastguard Worker     Error error = mImplementation->initialize(this);
1082*8975f5c5SAndroid Build Coastguard Worker     if (error.isError())
1083*8975f5c5SAndroid Build Coastguard Worker     {
1084*8975f5c5SAndroid Build Coastguard Worker         // Log extended error message here
1085*8975f5c5SAndroid Build Coastguard Worker         ERR() << "ANGLE Display::initialize error " << error.getID() << ": " << error.getMessage();
1086*8975f5c5SAndroid Build Coastguard Worker         return error;
1087*8975f5c5SAndroid Build Coastguard Worker     }
1088*8975f5c5SAndroid Build Coastguard Worker 
1089*8975f5c5SAndroid Build Coastguard Worker     mCaps = mImplementation->getCaps();
1090*8975f5c5SAndroid Build Coastguard Worker 
1091*8975f5c5SAndroid Build Coastguard Worker     mConfigSet = mImplementation->generateConfigs();
1092*8975f5c5SAndroid Build Coastguard Worker     if (mConfigSet.size() == 0)
1093*8975f5c5SAndroid Build Coastguard Worker     {
1094*8975f5c5SAndroid Build Coastguard Worker         mImplementation->terminate();
1095*8975f5c5SAndroid Build Coastguard Worker         return EglNotInitialized() << "No configs were generated.";
1096*8975f5c5SAndroid Build Coastguard Worker     }
1097*8975f5c5SAndroid Build Coastguard Worker 
1098*8975f5c5SAndroid Build Coastguard Worker     // OpenGL ES1 is implemented in the frontend, explicitly add ES1 support to all configs
1099*8975f5c5SAndroid Build Coastguard Worker     for (auto &config : mConfigSet)
1100*8975f5c5SAndroid Build Coastguard Worker     {
1101*8975f5c5SAndroid Build Coastguard Worker         // TODO(geofflang): Enable the conformant bit once we pass enough tests
1102*8975f5c5SAndroid Build Coastguard Worker         // config.second.conformant |= EGL_OPENGL_ES_BIT;
1103*8975f5c5SAndroid Build Coastguard Worker 
1104*8975f5c5SAndroid Build Coastguard Worker         config.second.renderableType |= EGL_OPENGL_ES_BIT;
1105*8975f5c5SAndroid Build Coastguard Worker     }
1106*8975f5c5SAndroid Build Coastguard Worker 
1107*8975f5c5SAndroid Build Coastguard Worker     mFrontendFeatures.reset();
1108*8975f5c5SAndroid Build Coastguard Worker     rx::ApplyFeatureOverrides(&mFrontendFeatures, mState.featureOverrides);
1109*8975f5c5SAndroid Build Coastguard Worker     if (!mState.featureOverrides.allDisabled)
1110*8975f5c5SAndroid Build Coastguard Worker     {
1111*8975f5c5SAndroid Build Coastguard Worker         initializeFrontendFeatures();
1112*8975f5c5SAndroid Build Coastguard Worker     }
1113*8975f5c5SAndroid Build Coastguard Worker 
1114*8975f5c5SAndroid Build Coastguard Worker     mFeatures.clear();
1115*8975f5c5SAndroid Build Coastguard Worker     mFrontendFeatures.populateFeatureList(&mFeatures);
1116*8975f5c5SAndroid Build Coastguard Worker     mImplementation->populateFeatureList(&mFeatures);
1117*8975f5c5SAndroid Build Coastguard Worker 
1118*8975f5c5SAndroid Build Coastguard Worker     initDisplayExtensions();
1119*8975f5c5SAndroid Build Coastguard Worker     initVendorString();
1120*8975f5c5SAndroid Build Coastguard Worker     initVersionString();
1121*8975f5c5SAndroid Build Coastguard Worker     initClientAPIString();
1122*8975f5c5SAndroid Build Coastguard Worker 
1123*8975f5c5SAndroid Build Coastguard Worker     // Populate the Display's EGLDeviceEXT if the Display wasn't created using one
1124*8975f5c5SAndroid Build Coastguard Worker     if (mPlatform == EGL_PLATFORM_DEVICE_EXT)
1125*8975f5c5SAndroid Build Coastguard Worker     {
1126*8975f5c5SAndroid Build Coastguard Worker         // For EGL_PLATFORM_DEVICE_EXT, mDevice should always be populated using
1127*8975f5c5SAndroid Build Coastguard Worker         // an external device
1128*8975f5c5SAndroid Build Coastguard Worker         ASSERT(mDevice != nullptr);
1129*8975f5c5SAndroid Build Coastguard Worker     }
1130*8975f5c5SAndroid Build Coastguard Worker     else if (GetClientExtensions().deviceQueryEXT)
1131*8975f5c5SAndroid Build Coastguard Worker     {
1132*8975f5c5SAndroid Build Coastguard Worker         std::unique_ptr<rx::DeviceImpl> impl(mImplementation->createDevice());
1133*8975f5c5SAndroid Build Coastguard Worker         ASSERT(impl);
1134*8975f5c5SAndroid Build Coastguard Worker         error = impl->initialize();
1135*8975f5c5SAndroid Build Coastguard Worker         if (error.isError())
1136*8975f5c5SAndroid Build Coastguard Worker         {
1137*8975f5c5SAndroid Build Coastguard Worker             ERR() << "Failed to initialize display because device creation failed: "
1138*8975f5c5SAndroid Build Coastguard Worker                   << error.getMessage();
1139*8975f5c5SAndroid Build Coastguard Worker             mImplementation->terminate();
1140*8975f5c5SAndroid Build Coastguard Worker             return error;
1141*8975f5c5SAndroid Build Coastguard Worker         }
1142*8975f5c5SAndroid Build Coastguard Worker         // Don't leak Device memory.
1143*8975f5c5SAndroid Build Coastguard Worker         ASSERT(mDevice == nullptr);
1144*8975f5c5SAndroid Build Coastguard Worker         mDevice = new Device(this, impl.release());
1145*8975f5c5SAndroid Build Coastguard Worker     }
1146*8975f5c5SAndroid Build Coastguard Worker     else
1147*8975f5c5SAndroid Build Coastguard Worker     {
1148*8975f5c5SAndroid Build Coastguard Worker         mDevice = nullptr;
1149*8975f5c5SAndroid Build Coastguard Worker     }
1150*8975f5c5SAndroid Build Coastguard Worker 
1151*8975f5c5SAndroid Build Coastguard Worker     mState.singleThreadPool = angle::WorkerThreadPool::Create(1, ANGLEPlatformCurrent());
1152*8975f5c5SAndroid Build Coastguard Worker     mState.multiThreadPool  = angle::WorkerThreadPool::Create(0, ANGLEPlatformCurrent());
1153*8975f5c5SAndroid Build Coastguard Worker 
1154*8975f5c5SAndroid Build Coastguard Worker     if (kIsContextMutexEnabled)
1155*8975f5c5SAndroid Build Coastguard Worker     {
1156*8975f5c5SAndroid Build Coastguard Worker         ASSERT(mManagersMutex == nullptr);
1157*8975f5c5SAndroid Build Coastguard Worker         mManagersMutex = new ContextMutex();
1158*8975f5c5SAndroid Build Coastguard Worker         mManagersMutex->addRef();
1159*8975f5c5SAndroid Build Coastguard Worker     }
1160*8975f5c5SAndroid Build Coastguard Worker 
1161*8975f5c5SAndroid Build Coastguard Worker     mInitialized = true;
1162*8975f5c5SAndroid Build Coastguard Worker 
1163*8975f5c5SAndroid Build Coastguard Worker     return NoError();
1164*8975f5c5SAndroid Build Coastguard Worker }
1165*8975f5c5SAndroid Build Coastguard Worker 
destroyInvalidEglObjects()1166*8975f5c5SAndroid Build Coastguard Worker Error Display::destroyInvalidEglObjects()
1167*8975f5c5SAndroid Build Coastguard Worker {
1168*8975f5c5SAndroid Build Coastguard Worker     // Destroy invalid EGL objects
1169*8975f5c5SAndroid Build Coastguard Worker     // Note that we don't need to lock mState.contextMapMutex here.
1170*8975f5c5SAndroid Build Coastguard Worker     // Write and read access to mInvalidContextMap are coming from
1171*8975f5c5SAndroid Build Coastguard Worker     // EGL_Terminate, EGL_ReleaseThread, ThreadCleanupCallBACK.
1172*8975f5c5SAndroid Build Coastguard Worker     // Those functions are protected by egl global lock,
1173*8975f5c5SAndroid Build Coastguard Worker     // so there is no race condition on mInvalidContextMap.
1174*8975f5c5SAndroid Build Coastguard Worker     while (!mInvalidContextMap.empty())
1175*8975f5c5SAndroid Build Coastguard Worker     {
1176*8975f5c5SAndroid Build Coastguard Worker         gl::Context *context = mInvalidContextMap.begin()->second;
1177*8975f5c5SAndroid Build Coastguard Worker         // eglReleaseThread() may call to this method when there are still Contexts, that may
1178*8975f5c5SAndroid Build Coastguard Worker         // potentially acces shared state of the "context".
1179*8975f5c5SAndroid Build Coastguard Worker         // Need AddRefLock because there may be ContextMutex destruction.
1180*8975f5c5SAndroid Build Coastguard Worker         ScopedContextMutexAddRefLock lock(context->getContextMutex());
1181*8975f5c5SAndroid Build Coastguard Worker         context->setIsDestroyed();
1182*8975f5c5SAndroid Build Coastguard Worker         ANGLE_TRY(releaseContextImpl(eraseContextImpl(context, &mInvalidContextMap)));
1183*8975f5c5SAndroid Build Coastguard Worker     }
1184*8975f5c5SAndroid Build Coastguard Worker 
1185*8975f5c5SAndroid Build Coastguard Worker     while (!mInvalidImageMap.empty())
1186*8975f5c5SAndroid Build Coastguard Worker     {
1187*8975f5c5SAndroid Build Coastguard Worker         destroyImageImpl(mInvalidImageMap.begin()->second, &mInvalidImageMap);
1188*8975f5c5SAndroid Build Coastguard Worker     }
1189*8975f5c5SAndroid Build Coastguard Worker 
1190*8975f5c5SAndroid Build Coastguard Worker     while (!mInvalidStreamSet.empty())
1191*8975f5c5SAndroid Build Coastguard Worker     {
1192*8975f5c5SAndroid Build Coastguard Worker         destroyStreamImpl(*mInvalidStreamSet.begin(), &mInvalidStreamSet);
1193*8975f5c5SAndroid Build Coastguard Worker     }
1194*8975f5c5SAndroid Build Coastguard Worker 
1195*8975f5c5SAndroid Build Coastguard Worker     while (!mInvalidSurfaceMap.empty())
1196*8975f5c5SAndroid Build Coastguard Worker     {
1197*8975f5c5SAndroid Build Coastguard Worker         ANGLE_TRY(destroySurfaceImpl(mInvalidSurfaceMap.begin()->second, &mInvalidSurfaceMap));
1198*8975f5c5SAndroid Build Coastguard Worker     }
1199*8975f5c5SAndroid Build Coastguard Worker 
1200*8975f5c5SAndroid Build Coastguard Worker     while (!mInvalidSyncMap.empty())
1201*8975f5c5SAndroid Build Coastguard Worker     {
1202*8975f5c5SAndroid Build Coastguard Worker         destroySyncImpl(mInvalidSyncMap.begin()->second->id(), &mInvalidSyncMap);
1203*8975f5c5SAndroid Build Coastguard Worker     }
1204*8975f5c5SAndroid Build Coastguard Worker 
1205*8975f5c5SAndroid Build Coastguard Worker     return NoError();
1206*8975f5c5SAndroid Build Coastguard Worker }
1207*8975f5c5SAndroid Build Coastguard Worker 
terminate(Thread * thread,TerminateReason terminateReason)1208*8975f5c5SAndroid Build Coastguard Worker Error Display::terminate(Thread *thread, TerminateReason terminateReason)
1209*8975f5c5SAndroid Build Coastguard Worker {
1210*8975f5c5SAndroid Build Coastguard Worker 
1211*8975f5c5SAndroid Build Coastguard Worker     if (terminateReason == TerminateReason::Api)
1212*8975f5c5SAndroid Build Coastguard Worker     {
1213*8975f5c5SAndroid Build Coastguard Worker         mTerminatedByApi = true;
1214*8975f5c5SAndroid Build Coastguard Worker     }
1215*8975f5c5SAndroid Build Coastguard Worker 
1216*8975f5c5SAndroid Build Coastguard Worker     // All subsequent calls assume the display to be valid and terminated by app.
1217*8975f5c5SAndroid Build Coastguard Worker     // If it is not terminated or if it isn't even initialized, early return.
1218*8975f5c5SAndroid Build Coastguard Worker     if (!mTerminatedByApi || !mInitialized)
1219*8975f5c5SAndroid Build Coastguard Worker     {
1220*8975f5c5SAndroid Build Coastguard Worker         return NoError();
1221*8975f5c5SAndroid Build Coastguard Worker     }
1222*8975f5c5SAndroid Build Coastguard Worker 
1223*8975f5c5SAndroid Build Coastguard Worker     // EGL 1.5 Specification
1224*8975f5c5SAndroid Build Coastguard Worker     // 3.2 Initialization
1225*8975f5c5SAndroid Build Coastguard Worker     // Termination marks all EGL-specific resources, such as contexts and surfaces, associated
1226*8975f5c5SAndroid Build Coastguard Worker     // with the specified display for deletion. Handles to all such resources are invalid as
1227*8975f5c5SAndroid Build Coastguard Worker     // soon as eglTerminate returns. Cache EGL objects that are no longer valid.
1228*8975f5c5SAndroid Build Coastguard Worker     //
1229*8975f5c5SAndroid Build Coastguard Worker     // It is fairly common for apps to call eglTerminate while some contexts and/or surfaces are
1230*8975f5c5SAndroid Build Coastguard Worker     // still current on some thread. Since objects are refCounted, trying to destroy them right
1231*8975f5c5SAndroid Build Coastguard Worker     // away would only result in a decRef. We instead cache such invalid objects and use other
1232*8975f5c5SAndroid Build Coastguard Worker     // EGL entrypoints like eglReleaseThread or thread exit events (on the Android platform) to
1233*8975f5c5SAndroid Build Coastguard Worker     // perform the necessary cleanup.
1234*8975f5c5SAndroid Build Coastguard Worker     mInvalidImageMap.insert(mImageMap.begin(), mImageMap.end());
1235*8975f5c5SAndroid Build Coastguard Worker     mImageMap.clear();
1236*8975f5c5SAndroid Build Coastguard Worker 
1237*8975f5c5SAndroid Build Coastguard Worker     mInvalidStreamSet.insert(mStreamSet.begin(), mStreamSet.end());
1238*8975f5c5SAndroid Build Coastguard Worker     mStreamSet.clear();
1239*8975f5c5SAndroid Build Coastguard Worker 
1240*8975f5c5SAndroid Build Coastguard Worker     mInvalidSurfaceMap.insert(mState.surfaceMap.begin(), mState.surfaceMap.end());
1241*8975f5c5SAndroid Build Coastguard Worker     mState.surfaceMap.clear();
1242*8975f5c5SAndroid Build Coastguard Worker 
1243*8975f5c5SAndroid Build Coastguard Worker     mInvalidSyncMap.insert(std::make_move_iterator(mSyncMap.begin()),
1244*8975f5c5SAndroid Build Coastguard Worker                            std::make_move_iterator(mSyncMap.end()));
1245*8975f5c5SAndroid Build Coastguard Worker     mSyncMap.clear();
1246*8975f5c5SAndroid Build Coastguard Worker 
1247*8975f5c5SAndroid Build Coastguard Worker     {
1248*8975f5c5SAndroid Build Coastguard Worker         // Lock mState.contextMapMutex to protect mState.contextMap.
1249*8975f5c5SAndroid Build Coastguard Worker         // mInvalidContextMap does not need protection. It just happens to fall within this scope.
1250*8975f5c5SAndroid Build Coastguard Worker         std::lock_guard<angle::SimpleMutex> lock(mState.contextMapMutex);
1251*8975f5c5SAndroid Build Coastguard Worker         // Cache total number of contexts before invalidation. This is used as a check to verify
1252*8975f5c5SAndroid Build Coastguard Worker         // that no context is "lost" while being moved between the various sets.
1253*8975f5c5SAndroid Build Coastguard Worker         size_t contextSetSizeBeforeInvalidation =
1254*8975f5c5SAndroid Build Coastguard Worker             mState.contextMap.size() + mInvalidContextMap.size();
1255*8975f5c5SAndroid Build Coastguard Worker 
1256*8975f5c5SAndroid Build Coastguard Worker         // If app called eglTerminate and no active threads remain,
1257*8975f5c5SAndroid Build Coastguard Worker         // force release any context that is still current.
1258*8975f5c5SAndroid Build Coastguard Worker         ContextMap contextsStillCurrent = {};
1259*8975f5c5SAndroid Build Coastguard Worker         for (auto context : mState.contextMap)
1260*8975f5c5SAndroid Build Coastguard Worker         {
1261*8975f5c5SAndroid Build Coastguard Worker             if (context.second->isReferenced())
1262*8975f5c5SAndroid Build Coastguard Worker             {
1263*8975f5c5SAndroid Build Coastguard Worker                 contextsStillCurrent.emplace(context);
1264*8975f5c5SAndroid Build Coastguard Worker                 continue;
1265*8975f5c5SAndroid Build Coastguard Worker             }
1266*8975f5c5SAndroid Build Coastguard Worker 
1267*8975f5c5SAndroid Build Coastguard Worker             // Add context that is not current to mInvalidContextSet for cleanup.
1268*8975f5c5SAndroid Build Coastguard Worker             mInvalidContextMap.emplace(context);
1269*8975f5c5SAndroid Build Coastguard Worker         }
1270*8975f5c5SAndroid Build Coastguard Worker 
1271*8975f5c5SAndroid Build Coastguard Worker         // There are many methods that require contexts that are still current to be present in
1272*8975f5c5SAndroid Build Coastguard Worker         // display's contextSet like during context release or to notify of state changes in a
1273*8975f5c5SAndroid Build Coastguard Worker         // subject. So as to not interrupt this flow, do not remove contexts that are still
1274*8975f5c5SAndroid Build Coastguard Worker         // current on some thread from display's contextSet even though eglTerminate marks such
1275*8975f5c5SAndroid Build Coastguard Worker         // contexts as invalid.
1276*8975f5c5SAndroid Build Coastguard Worker         //
1277*8975f5c5SAndroid Build Coastguard Worker         // "mState.contextSet" will now contain only those contexts that are still current on
1278*8975f5c5SAndroid Build Coastguard Worker         // some thread.
1279*8975f5c5SAndroid Build Coastguard Worker         mState.contextMap = std::move(contextsStillCurrent);
1280*8975f5c5SAndroid Build Coastguard Worker 
1281*8975f5c5SAndroid Build Coastguard Worker         // Assert that the total number of contexts is the same before and after context
1282*8975f5c5SAndroid Build Coastguard Worker         // invalidation.
1283*8975f5c5SAndroid Build Coastguard Worker         ASSERT(contextSetSizeBeforeInvalidation ==
1284*8975f5c5SAndroid Build Coastguard Worker                mState.contextMap.size() + mInvalidContextMap.size());
1285*8975f5c5SAndroid Build Coastguard Worker 
1286*8975f5c5SAndroid Build Coastguard Worker         if (!mState.contextMap.empty())
1287*8975f5c5SAndroid Build Coastguard Worker         {
1288*8975f5c5SAndroid Build Coastguard Worker             // There was atleast 1 context that was current on some thread, early return.
1289*8975f5c5SAndroid Build Coastguard Worker             return NoError();
1290*8975f5c5SAndroid Build Coastguard Worker         }
1291*8975f5c5SAndroid Build Coastguard Worker     }
1292*8975f5c5SAndroid Build Coastguard Worker 
1293*8975f5c5SAndroid Build Coastguard Worker     // The global texture and semaphore managers should be deleted with the last context that uses
1294*8975f5c5SAndroid Build Coastguard Worker     // it.
1295*8975f5c5SAndroid Build Coastguard Worker     ASSERT(mGlobalTextureShareGroupUsers == 0 && mTextureManager == nullptr);
1296*8975f5c5SAndroid Build Coastguard Worker     ASSERT(mGlobalSemaphoreShareGroupUsers == 0 && mSemaphoreManager == nullptr);
1297*8975f5c5SAndroid Build Coastguard Worker 
1298*8975f5c5SAndroid Build Coastguard Worker     if (mManagersMutex != nullptr)
1299*8975f5c5SAndroid Build Coastguard Worker     {
1300*8975f5c5SAndroid Build Coastguard Worker         mManagersMutex->release();
1301*8975f5c5SAndroid Build Coastguard Worker         mManagersMutex = nullptr;
1302*8975f5c5SAndroid Build Coastguard Worker     }
1303*8975f5c5SAndroid Build Coastguard Worker 
1304*8975f5c5SAndroid Build Coastguard Worker     // Clean up all invalid objects
1305*8975f5c5SAndroid Build Coastguard Worker     ANGLE_TRY(destroyInvalidEglObjects());
1306*8975f5c5SAndroid Build Coastguard Worker 
1307*8975f5c5SAndroid Build Coastguard Worker     mSyncPools.clear();
1308*8975f5c5SAndroid Build Coastguard Worker 
1309*8975f5c5SAndroid Build Coastguard Worker     mConfigSet.clear();
1310*8975f5c5SAndroid Build Coastguard Worker 
1311*8975f5c5SAndroid Build Coastguard Worker     if (mDevice != nullptr && mDevice->getOwningDisplay() != nullptr)
1312*8975f5c5SAndroid Build Coastguard Worker     {
1313*8975f5c5SAndroid Build Coastguard Worker         // Don't delete the device if it was created externally using eglCreateDeviceANGLE
1314*8975f5c5SAndroid Build Coastguard Worker         // We also shouldn't set it to null in case eglInitialize() is called again later
1315*8975f5c5SAndroid Build Coastguard Worker         SafeDelete(mDevice);
1316*8975f5c5SAndroid Build Coastguard Worker     }
1317*8975f5c5SAndroid Build Coastguard Worker 
1318*8975f5c5SAndroid Build Coastguard Worker     // Before tearing down the backend device, ensure all deferred operations are run.  It is not
1319*8975f5c5SAndroid Build Coastguard Worker     // possible to defer them beyond this point.
1320*8975f5c5SAndroid Build Coastguard Worker     GetCurrentThreadUnlockedTailCall()->run(nullptr);
1321*8975f5c5SAndroid Build Coastguard Worker 
1322*8975f5c5SAndroid Build Coastguard Worker     mImplementation->terminate();
1323*8975f5c5SAndroid Build Coastguard Worker 
1324*8975f5c5SAndroid Build Coastguard Worker     mMemoryProgramCache.clear();
1325*8975f5c5SAndroid Build Coastguard Worker     mMemoryShaderCache.clear();
1326*8975f5c5SAndroid Build Coastguard Worker     mBlobCache.setBlobCacheFuncs(nullptr, nullptr);
1327*8975f5c5SAndroid Build Coastguard Worker 
1328*8975f5c5SAndroid Build Coastguard Worker     mState.singleThreadPool.reset();
1329*8975f5c5SAndroid Build Coastguard Worker     mState.multiThreadPool.reset();
1330*8975f5c5SAndroid Build Coastguard Worker 
1331*8975f5c5SAndroid Build Coastguard Worker     mState.deviceLost = false;
1332*8975f5c5SAndroid Build Coastguard Worker 
1333*8975f5c5SAndroid Build Coastguard Worker     mInitialized = false;
1334*8975f5c5SAndroid Build Coastguard Worker 
1335*8975f5c5SAndroid Build Coastguard Worker     gl::UninitializeDebugAnnotations();
1336*8975f5c5SAndroid Build Coastguard Worker 
1337*8975f5c5SAndroid Build Coastguard Worker     // TODO(jmadill): Store Platform in Display and deinit here.
1338*8975f5c5SAndroid Build Coastguard Worker     ANGLEResetDisplayPlatform(this);
1339*8975f5c5SAndroid Build Coastguard Worker 
1340*8975f5c5SAndroid Build Coastguard Worker     return NoError();
1341*8975f5c5SAndroid Build Coastguard Worker }
1342*8975f5c5SAndroid Build Coastguard Worker 
1343*8975f5c5SAndroid Build Coastguard Worker #if ANGLE_USE_DISPLAY_PREPARE_FOR_CALL
prepareForCall()1344*8975f5c5SAndroid Build Coastguard Worker Error Display::prepareForCall()
1345*8975f5c5SAndroid Build Coastguard Worker {
1346*8975f5c5SAndroid Build Coastguard Worker     return mImplementation->prepareForCall();
1347*8975f5c5SAndroid Build Coastguard Worker }
1348*8975f5c5SAndroid Build Coastguard Worker #endif
1349*8975f5c5SAndroid Build Coastguard Worker 
releaseThread()1350*8975f5c5SAndroid Build Coastguard Worker Error Display::releaseThread()
1351*8975f5c5SAndroid Build Coastguard Worker {
1352*8975f5c5SAndroid Build Coastguard Worker     // Need to check if initialized, because makeCurrent() may terminate the Display.
1353*8975f5c5SAndroid Build Coastguard Worker     if (!mInitialized)
1354*8975f5c5SAndroid Build Coastguard Worker     {
1355*8975f5c5SAndroid Build Coastguard Worker         return NoError();
1356*8975f5c5SAndroid Build Coastguard Worker     }
1357*8975f5c5SAndroid Build Coastguard Worker     ANGLE_TRY(mImplementation->releaseThread());
1358*8975f5c5SAndroid Build Coastguard Worker     return destroyInvalidEglObjects();
1359*8975f5c5SAndroid Build Coastguard Worker }
1360*8975f5c5SAndroid Build Coastguard Worker 
getConfigs(const egl::AttributeMap & attribs) const1361*8975f5c5SAndroid Build Coastguard Worker std::vector<const Config *> Display::getConfigs(const egl::AttributeMap &attribs) const
1362*8975f5c5SAndroid Build Coastguard Worker {
1363*8975f5c5SAndroid Build Coastguard Worker     return mConfigSet.filter(attribs);
1364*8975f5c5SAndroid Build Coastguard Worker }
1365*8975f5c5SAndroid Build Coastguard Worker 
chooseConfig(const egl::AttributeMap & attribs) const1366*8975f5c5SAndroid Build Coastguard Worker std::vector<const Config *> Display::chooseConfig(const egl::AttributeMap &attribs) const
1367*8975f5c5SAndroid Build Coastguard Worker {
1368*8975f5c5SAndroid Build Coastguard Worker     egl::AttributeMap attribsWithDefaults = AttributeMap();
1369*8975f5c5SAndroid Build Coastguard Worker 
1370*8975f5c5SAndroid Build Coastguard Worker     // Insert default values for attributes that have either an Exact or Mask selection criteria,
1371*8975f5c5SAndroid Build Coastguard Worker     // and a default value that matters (e.g. isn't EGL_DONT_CARE):
1372*8975f5c5SAndroid Build Coastguard Worker     attribsWithDefaults.insert(EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER);
1373*8975f5c5SAndroid Build Coastguard Worker     attribsWithDefaults.insert(EGL_LEVEL, 0);
1374*8975f5c5SAndroid Build Coastguard Worker     attribsWithDefaults.insert(EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT);
1375*8975f5c5SAndroid Build Coastguard Worker     attribsWithDefaults.insert(EGL_SURFACE_TYPE, EGL_WINDOW_BIT);
1376*8975f5c5SAndroid Build Coastguard Worker     attribsWithDefaults.insert(EGL_TRANSPARENT_TYPE, EGL_NONE);
1377*8975f5c5SAndroid Build Coastguard Worker     if (getExtensions().pixelFormatFloat)
1378*8975f5c5SAndroid Build Coastguard Worker     {
1379*8975f5c5SAndroid Build Coastguard Worker         attribsWithDefaults.insert(EGL_COLOR_COMPONENT_TYPE_EXT,
1380*8975f5c5SAndroid Build Coastguard Worker                                    EGL_COLOR_COMPONENT_TYPE_FIXED_EXT);
1381*8975f5c5SAndroid Build Coastguard Worker     }
1382*8975f5c5SAndroid Build Coastguard Worker 
1383*8975f5c5SAndroid Build Coastguard Worker     // Add the caller-specified values (Note: the poorly-named insert() method will replace any
1384*8975f5c5SAndroid Build Coastguard Worker     // of the default values from above):
1385*8975f5c5SAndroid Build Coastguard Worker     for (auto attribIter = attribs.begin(); attribIter != attribs.end(); attribIter++)
1386*8975f5c5SAndroid Build Coastguard Worker     {
1387*8975f5c5SAndroid Build Coastguard Worker         attribsWithDefaults.insert(attribIter->first, attribIter->second);
1388*8975f5c5SAndroid Build Coastguard Worker     }
1389*8975f5c5SAndroid Build Coastguard Worker 
1390*8975f5c5SAndroid Build Coastguard Worker     return mConfigSet.filter(attribsWithDefaults);
1391*8975f5c5SAndroid Build Coastguard Worker }
1392*8975f5c5SAndroid Build Coastguard Worker 
createWindowSurface(const Config * configuration,EGLNativeWindowType window,const AttributeMap & attribs,Surface ** outSurface)1393*8975f5c5SAndroid Build Coastguard Worker Error Display::createWindowSurface(const Config *configuration,
1394*8975f5c5SAndroid Build Coastguard Worker                                    EGLNativeWindowType window,
1395*8975f5c5SAndroid Build Coastguard Worker                                    const AttributeMap &attribs,
1396*8975f5c5SAndroid Build Coastguard Worker                                    Surface **outSurface)
1397*8975f5c5SAndroid Build Coastguard Worker {
1398*8975f5c5SAndroid Build Coastguard Worker     if (mImplementation->testDeviceLost())
1399*8975f5c5SAndroid Build Coastguard Worker     {
1400*8975f5c5SAndroid Build Coastguard Worker         ANGLE_TRY(restoreLostDevice());
1401*8975f5c5SAndroid Build Coastguard Worker     }
1402*8975f5c5SAndroid Build Coastguard Worker 
1403*8975f5c5SAndroid Build Coastguard Worker     SurfaceID id = {mSurfaceHandleAllocator.allocate()};
1404*8975f5c5SAndroid Build Coastguard Worker     SurfacePointer surface(new WindowSurface(mImplementation, id, configuration, window, attribs,
1405*8975f5c5SAndroid Build Coastguard Worker                                              mFrontendFeatures.forceRobustResourceInit.enabled),
1406*8975f5c5SAndroid Build Coastguard Worker                            this);
1407*8975f5c5SAndroid Build Coastguard Worker     ANGLE_TRY(surface->initialize(this));
1408*8975f5c5SAndroid Build Coastguard Worker 
1409*8975f5c5SAndroid Build Coastguard Worker     ASSERT(outSurface != nullptr);
1410*8975f5c5SAndroid Build Coastguard Worker     *outSurface = surface.release();
1411*8975f5c5SAndroid Build Coastguard Worker     mState.surfaceMap.insert(std::pair((*outSurface)->id().value, *outSurface));
1412*8975f5c5SAndroid Build Coastguard Worker 
1413*8975f5c5SAndroid Build Coastguard Worker     WindowSurfaceMap *windowSurfaces = GetWindowSurfaces();
1414*8975f5c5SAndroid Build Coastguard Worker     ASSERT(windowSurfaces && windowSurfaces->find(window) == windowSurfaces->end());
1415*8975f5c5SAndroid Build Coastguard Worker     windowSurfaces->insert(std::make_pair(window, *outSurface));
1416*8975f5c5SAndroid Build Coastguard Worker 
1417*8975f5c5SAndroid Build Coastguard Worker     mSurface = *outSurface;
1418*8975f5c5SAndroid Build Coastguard Worker 
1419*8975f5c5SAndroid Build Coastguard Worker     return NoError();
1420*8975f5c5SAndroid Build Coastguard Worker }
1421*8975f5c5SAndroid Build Coastguard Worker 
createPbufferSurface(const Config * configuration,const AttributeMap & attribs,Surface ** outSurface)1422*8975f5c5SAndroid Build Coastguard Worker Error Display::createPbufferSurface(const Config *configuration,
1423*8975f5c5SAndroid Build Coastguard Worker                                     const AttributeMap &attribs,
1424*8975f5c5SAndroid Build Coastguard Worker                                     Surface **outSurface)
1425*8975f5c5SAndroid Build Coastguard Worker {
1426*8975f5c5SAndroid Build Coastguard Worker     ASSERT(isInitialized());
1427*8975f5c5SAndroid Build Coastguard Worker 
1428*8975f5c5SAndroid Build Coastguard Worker     if (mImplementation->testDeviceLost())
1429*8975f5c5SAndroid Build Coastguard Worker     {
1430*8975f5c5SAndroid Build Coastguard Worker         ANGLE_TRY(restoreLostDevice());
1431*8975f5c5SAndroid Build Coastguard Worker     }
1432*8975f5c5SAndroid Build Coastguard Worker 
1433*8975f5c5SAndroid Build Coastguard Worker     SurfaceID id = {mSurfaceHandleAllocator.allocate()};
1434*8975f5c5SAndroid Build Coastguard Worker     SurfacePointer surface(new PbufferSurface(mImplementation, id, configuration, attribs,
1435*8975f5c5SAndroid Build Coastguard Worker                                               mFrontendFeatures.forceRobustResourceInit.enabled),
1436*8975f5c5SAndroid Build Coastguard Worker                            this);
1437*8975f5c5SAndroid Build Coastguard Worker     ANGLE_TRY(surface->initialize(this));
1438*8975f5c5SAndroid Build Coastguard Worker 
1439*8975f5c5SAndroid Build Coastguard Worker     ASSERT(outSurface != nullptr);
1440*8975f5c5SAndroid Build Coastguard Worker     *outSurface = surface.release();
1441*8975f5c5SAndroid Build Coastguard Worker     mState.surfaceMap.insert(std::pair((*outSurface)->id().value, *outSurface));
1442*8975f5c5SAndroid Build Coastguard Worker 
1443*8975f5c5SAndroid Build Coastguard Worker     return NoError();
1444*8975f5c5SAndroid Build Coastguard Worker }
1445*8975f5c5SAndroid Build Coastguard Worker 
createPbufferFromClientBuffer(const Config * configuration,EGLenum buftype,EGLClientBuffer clientBuffer,const AttributeMap & attribs,Surface ** outSurface)1446*8975f5c5SAndroid Build Coastguard Worker Error Display::createPbufferFromClientBuffer(const Config *configuration,
1447*8975f5c5SAndroid Build Coastguard Worker                                              EGLenum buftype,
1448*8975f5c5SAndroid Build Coastguard Worker                                              EGLClientBuffer clientBuffer,
1449*8975f5c5SAndroid Build Coastguard Worker                                              const AttributeMap &attribs,
1450*8975f5c5SAndroid Build Coastguard Worker                                              Surface **outSurface)
1451*8975f5c5SAndroid Build Coastguard Worker {
1452*8975f5c5SAndroid Build Coastguard Worker     ASSERT(isInitialized());
1453*8975f5c5SAndroid Build Coastguard Worker 
1454*8975f5c5SAndroid Build Coastguard Worker     if (mImplementation->testDeviceLost())
1455*8975f5c5SAndroid Build Coastguard Worker     {
1456*8975f5c5SAndroid Build Coastguard Worker         ANGLE_TRY(restoreLostDevice());
1457*8975f5c5SAndroid Build Coastguard Worker     }
1458*8975f5c5SAndroid Build Coastguard Worker 
1459*8975f5c5SAndroid Build Coastguard Worker     SurfaceID id = {mSurfaceHandleAllocator.allocate()};
1460*8975f5c5SAndroid Build Coastguard Worker     SurfacePointer surface(
1461*8975f5c5SAndroid Build Coastguard Worker         new PbufferSurface(mImplementation, id, configuration, buftype, clientBuffer, attribs,
1462*8975f5c5SAndroid Build Coastguard Worker                            mFrontendFeatures.forceRobustResourceInit.enabled),
1463*8975f5c5SAndroid Build Coastguard Worker         this);
1464*8975f5c5SAndroid Build Coastguard Worker     ANGLE_TRY(surface->initialize(this));
1465*8975f5c5SAndroid Build Coastguard Worker 
1466*8975f5c5SAndroid Build Coastguard Worker     ASSERT(outSurface != nullptr);
1467*8975f5c5SAndroid Build Coastguard Worker     *outSurface = surface.release();
1468*8975f5c5SAndroid Build Coastguard Worker     mState.surfaceMap.insert(std::pair((*outSurface)->id().value, *outSurface));
1469*8975f5c5SAndroid Build Coastguard Worker 
1470*8975f5c5SAndroid Build Coastguard Worker     return NoError();
1471*8975f5c5SAndroid Build Coastguard Worker }
1472*8975f5c5SAndroid Build Coastguard Worker 
createPixmapSurface(const Config * configuration,NativePixmapType nativePixmap,const AttributeMap & attribs,Surface ** outSurface)1473*8975f5c5SAndroid Build Coastguard Worker Error Display::createPixmapSurface(const Config *configuration,
1474*8975f5c5SAndroid Build Coastguard Worker                                    NativePixmapType nativePixmap,
1475*8975f5c5SAndroid Build Coastguard Worker                                    const AttributeMap &attribs,
1476*8975f5c5SAndroid Build Coastguard Worker                                    Surface **outSurface)
1477*8975f5c5SAndroid Build Coastguard Worker {
1478*8975f5c5SAndroid Build Coastguard Worker     ASSERT(isInitialized());
1479*8975f5c5SAndroid Build Coastguard Worker 
1480*8975f5c5SAndroid Build Coastguard Worker     if (mImplementation->testDeviceLost())
1481*8975f5c5SAndroid Build Coastguard Worker     {
1482*8975f5c5SAndroid Build Coastguard Worker         ANGLE_TRY(restoreLostDevice());
1483*8975f5c5SAndroid Build Coastguard Worker     }
1484*8975f5c5SAndroid Build Coastguard Worker 
1485*8975f5c5SAndroid Build Coastguard Worker     SurfaceID id = {mSurfaceHandleAllocator.allocate()};
1486*8975f5c5SAndroid Build Coastguard Worker     SurfacePointer surface(
1487*8975f5c5SAndroid Build Coastguard Worker         new PixmapSurface(mImplementation, id, configuration, nativePixmap, attribs,
1488*8975f5c5SAndroid Build Coastguard Worker                           mFrontendFeatures.forceRobustResourceInit.enabled),
1489*8975f5c5SAndroid Build Coastguard Worker         this);
1490*8975f5c5SAndroid Build Coastguard Worker     ANGLE_TRY(surface->initialize(this));
1491*8975f5c5SAndroid Build Coastguard Worker 
1492*8975f5c5SAndroid Build Coastguard Worker     ASSERT(outSurface != nullptr);
1493*8975f5c5SAndroid Build Coastguard Worker     *outSurface = surface.release();
1494*8975f5c5SAndroid Build Coastguard Worker     mState.surfaceMap.insert(std::pair((*outSurface)->id().value, *outSurface));
1495*8975f5c5SAndroid Build Coastguard Worker 
1496*8975f5c5SAndroid Build Coastguard Worker     return NoError();
1497*8975f5c5SAndroid Build Coastguard Worker }
1498*8975f5c5SAndroid Build Coastguard Worker 
createImage(const gl::Context * context,EGLenum target,EGLClientBuffer buffer,const AttributeMap & attribs,Image ** outImage)1499*8975f5c5SAndroid Build Coastguard Worker Error Display::createImage(const gl::Context *context,
1500*8975f5c5SAndroid Build Coastguard Worker                            EGLenum target,
1501*8975f5c5SAndroid Build Coastguard Worker                            EGLClientBuffer buffer,
1502*8975f5c5SAndroid Build Coastguard Worker                            const AttributeMap &attribs,
1503*8975f5c5SAndroid Build Coastguard Worker                            Image **outImage)
1504*8975f5c5SAndroid Build Coastguard Worker {
1505*8975f5c5SAndroid Build Coastguard Worker     ASSERT(isInitialized());
1506*8975f5c5SAndroid Build Coastguard Worker 
1507*8975f5c5SAndroid Build Coastguard Worker     if (mImplementation->testDeviceLost())
1508*8975f5c5SAndroid Build Coastguard Worker     {
1509*8975f5c5SAndroid Build Coastguard Worker         ANGLE_TRY(restoreLostDevice());
1510*8975f5c5SAndroid Build Coastguard Worker     }
1511*8975f5c5SAndroid Build Coastguard Worker 
1512*8975f5c5SAndroid Build Coastguard Worker     egl::ImageSibling *sibling = nullptr;
1513*8975f5c5SAndroid Build Coastguard Worker     if (IsTextureTarget(target))
1514*8975f5c5SAndroid Build Coastguard Worker     {
1515*8975f5c5SAndroid Build Coastguard Worker         sibling = context->getTexture({egl_gl::EGLClientBufferToGLObjectHandle(buffer)});
1516*8975f5c5SAndroid Build Coastguard Worker     }
1517*8975f5c5SAndroid Build Coastguard Worker     else if (IsRenderbufferTarget(target))
1518*8975f5c5SAndroid Build Coastguard Worker     {
1519*8975f5c5SAndroid Build Coastguard Worker         sibling = context->getRenderbuffer({egl_gl::EGLClientBufferToGLObjectHandle(buffer)});
1520*8975f5c5SAndroid Build Coastguard Worker     }
1521*8975f5c5SAndroid Build Coastguard Worker     else if (IsExternalImageTarget(target))
1522*8975f5c5SAndroid Build Coastguard Worker     {
1523*8975f5c5SAndroid Build Coastguard Worker         sibling = new ExternalImageSibling(mImplementation, context, target, buffer, attribs);
1524*8975f5c5SAndroid Build Coastguard Worker     }
1525*8975f5c5SAndroid Build Coastguard Worker     else
1526*8975f5c5SAndroid Build Coastguard Worker     {
1527*8975f5c5SAndroid Build Coastguard Worker         UNREACHABLE();
1528*8975f5c5SAndroid Build Coastguard Worker     }
1529*8975f5c5SAndroid Build Coastguard Worker     ASSERT(sibling != nullptr);
1530*8975f5c5SAndroid Build Coastguard Worker 
1531*8975f5c5SAndroid Build Coastguard Worker     ImageID id = {mImageHandleAllocator.allocate()};
1532*8975f5c5SAndroid Build Coastguard Worker     angle::UniqueObjectPointer<Image, Display> imagePtr(
1533*8975f5c5SAndroid Build Coastguard Worker         new Image(mImplementation, id, context, target, sibling, attribs), this);
1534*8975f5c5SAndroid Build Coastguard Worker     ANGLE_TRY(imagePtr->initialize(this, context));
1535*8975f5c5SAndroid Build Coastguard Worker 
1536*8975f5c5SAndroid Build Coastguard Worker     Image *image = imagePtr.release();
1537*8975f5c5SAndroid Build Coastguard Worker 
1538*8975f5c5SAndroid Build Coastguard Worker     ASSERT(outImage != nullptr);
1539*8975f5c5SAndroid Build Coastguard Worker     *outImage = image;
1540*8975f5c5SAndroid Build Coastguard Worker 
1541*8975f5c5SAndroid Build Coastguard Worker     // Add this image to the list of all images and hold a ref to it.
1542*8975f5c5SAndroid Build Coastguard Worker     image->addRef();
1543*8975f5c5SAndroid Build Coastguard Worker     mImageMap.insert(std::pair(image->id().value, image));
1544*8975f5c5SAndroid Build Coastguard Worker 
1545*8975f5c5SAndroid Build Coastguard Worker     return NoError();
1546*8975f5c5SAndroid Build Coastguard Worker }
1547*8975f5c5SAndroid Build Coastguard Worker 
createStream(const AttributeMap & attribs,Stream ** outStream)1548*8975f5c5SAndroid Build Coastguard Worker Error Display::createStream(const AttributeMap &attribs, Stream **outStream)
1549*8975f5c5SAndroid Build Coastguard Worker {
1550*8975f5c5SAndroid Build Coastguard Worker     ASSERT(isInitialized());
1551*8975f5c5SAndroid Build Coastguard Worker 
1552*8975f5c5SAndroid Build Coastguard Worker     Stream *stream = new Stream(this, attribs);
1553*8975f5c5SAndroid Build Coastguard Worker 
1554*8975f5c5SAndroid Build Coastguard Worker     ASSERT(stream != nullptr);
1555*8975f5c5SAndroid Build Coastguard Worker     mStreamSet.insert(stream);
1556*8975f5c5SAndroid Build Coastguard Worker 
1557*8975f5c5SAndroid Build Coastguard Worker     ASSERT(outStream != nullptr);
1558*8975f5c5SAndroid Build Coastguard Worker     *outStream = stream;
1559*8975f5c5SAndroid Build Coastguard Worker 
1560*8975f5c5SAndroid Build Coastguard Worker     return NoError();
1561*8975f5c5SAndroid Build Coastguard Worker }
1562*8975f5c5SAndroid Build Coastguard Worker 
createContext(const Config * configuration,gl::Context * shareContext,const AttributeMap & attribs,gl::Context ** outContext)1563*8975f5c5SAndroid Build Coastguard Worker Error Display::createContext(const Config *configuration,
1564*8975f5c5SAndroid Build Coastguard Worker                              gl::Context *shareContext,
1565*8975f5c5SAndroid Build Coastguard Worker                              const AttributeMap &attribs,
1566*8975f5c5SAndroid Build Coastguard Worker                              gl::Context **outContext)
1567*8975f5c5SAndroid Build Coastguard Worker {
1568*8975f5c5SAndroid Build Coastguard Worker     ASSERT(!mTerminatedByApi);
1569*8975f5c5SAndroid Build Coastguard Worker     ASSERT(isInitialized());
1570*8975f5c5SAndroid Build Coastguard Worker 
1571*8975f5c5SAndroid Build Coastguard Worker     if (mImplementation->testDeviceLost())
1572*8975f5c5SAndroid Build Coastguard Worker     {
1573*8975f5c5SAndroid Build Coastguard Worker         ANGLE_TRY(restoreLostDevice());
1574*8975f5c5SAndroid Build Coastguard Worker     }
1575*8975f5c5SAndroid Build Coastguard Worker 
1576*8975f5c5SAndroid Build Coastguard Worker     // This display texture sharing will allow the first context to create the texture share group.
1577*8975f5c5SAndroid Build Coastguard Worker     bool usingDisplayTextureShareGroup =
1578*8975f5c5SAndroid Build Coastguard Worker         attribs.get(EGL_DISPLAY_TEXTURE_SHARE_GROUP_ANGLE, EGL_FALSE) == EGL_TRUE;
1579*8975f5c5SAndroid Build Coastguard Worker     gl::TextureManager *shareTextures = nullptr;
1580*8975f5c5SAndroid Build Coastguard Worker 
1581*8975f5c5SAndroid Build Coastguard Worker     if (usingDisplayTextureShareGroup)
1582*8975f5c5SAndroid Build Coastguard Worker     {
1583*8975f5c5SAndroid Build Coastguard Worker         ASSERT((mTextureManager == nullptr) == (mGlobalTextureShareGroupUsers == 0));
1584*8975f5c5SAndroid Build Coastguard Worker         if (mTextureManager == nullptr)
1585*8975f5c5SAndroid Build Coastguard Worker         {
1586*8975f5c5SAndroid Build Coastguard Worker             mTextureManager = new gl::TextureManager();
1587*8975f5c5SAndroid Build Coastguard Worker         }
1588*8975f5c5SAndroid Build Coastguard Worker 
1589*8975f5c5SAndroid Build Coastguard Worker         mGlobalTextureShareGroupUsers++;
1590*8975f5c5SAndroid Build Coastguard Worker         shareTextures = mTextureManager;
1591*8975f5c5SAndroid Build Coastguard Worker     }
1592*8975f5c5SAndroid Build Coastguard Worker 
1593*8975f5c5SAndroid Build Coastguard Worker     // This display semaphore sharing will allow the first context to create the semaphore share
1594*8975f5c5SAndroid Build Coastguard Worker     // group.
1595*8975f5c5SAndroid Build Coastguard Worker     bool usingDisplaySemaphoreShareGroup =
1596*8975f5c5SAndroid Build Coastguard Worker         attribs.get(EGL_DISPLAY_SEMAPHORE_SHARE_GROUP_ANGLE, EGL_FALSE) == EGL_TRUE;
1597*8975f5c5SAndroid Build Coastguard Worker     gl::SemaphoreManager *shareSemaphores = nullptr;
1598*8975f5c5SAndroid Build Coastguard Worker     if (usingDisplaySemaphoreShareGroup)
1599*8975f5c5SAndroid Build Coastguard Worker     {
1600*8975f5c5SAndroid Build Coastguard Worker         ASSERT((mSemaphoreManager == nullptr) == (mGlobalSemaphoreShareGroupUsers == 0));
1601*8975f5c5SAndroid Build Coastguard Worker         if (mSemaphoreManager == nullptr)
1602*8975f5c5SAndroid Build Coastguard Worker         {
1603*8975f5c5SAndroid Build Coastguard Worker             mSemaphoreManager = new gl::SemaphoreManager();
1604*8975f5c5SAndroid Build Coastguard Worker         }
1605*8975f5c5SAndroid Build Coastguard Worker 
1606*8975f5c5SAndroid Build Coastguard Worker         mGlobalSemaphoreShareGroupUsers++;
1607*8975f5c5SAndroid Build Coastguard Worker         shareSemaphores = mSemaphoreManager;
1608*8975f5c5SAndroid Build Coastguard Worker     }
1609*8975f5c5SAndroid Build Coastguard Worker 
1610*8975f5c5SAndroid Build Coastguard Worker     ScopedContextMutexLock mutexLock;
1611*8975f5c5SAndroid Build Coastguard Worker     ContextMutex *sharedContextMutex = nullptr;
1612*8975f5c5SAndroid Build Coastguard Worker     if (kIsContextMutexEnabled)
1613*8975f5c5SAndroid Build Coastguard Worker     {
1614*8975f5c5SAndroid Build Coastguard Worker         ASSERT(mManagersMutex != nullptr);
1615*8975f5c5SAndroid Build Coastguard Worker         if (shareContext != nullptr)
1616*8975f5c5SAndroid Build Coastguard Worker         {
1617*8975f5c5SAndroid Build Coastguard Worker             sharedContextMutex = shareContext->getContextMutex().getRoot();
1618*8975f5c5SAndroid Build Coastguard Worker         }
1619*8975f5c5SAndroid Build Coastguard Worker         else if (shareTextures != nullptr || shareSemaphores != nullptr)
1620*8975f5c5SAndroid Build Coastguard Worker         {
1621*8975f5c5SAndroid Build Coastguard Worker             mutexLock          = ScopedContextMutexLock(mManagersMutex);
1622*8975f5c5SAndroid Build Coastguard Worker             sharedContextMutex = mManagersMutex->getRoot();
1623*8975f5c5SAndroid Build Coastguard Worker         }
1624*8975f5c5SAndroid Build Coastguard Worker         // When using shareTextures/Semaphores all Contexts in the Group must use mManagersMutex.
1625*8975f5c5SAndroid Build Coastguard Worker         ASSERT((shareTextures == nullptr && shareSemaphores == nullptr) ||
1626*8975f5c5SAndroid Build Coastguard Worker                sharedContextMutex == mManagersMutex->getRoot());
1627*8975f5c5SAndroid Build Coastguard Worker     }
1628*8975f5c5SAndroid Build Coastguard Worker 
1629*8975f5c5SAndroid Build Coastguard Worker     gl::MemoryProgramCache *programCachePointer = &mMemoryProgramCache;
1630*8975f5c5SAndroid Build Coastguard Worker     // Check context creation attributes to see if we are using EGL_ANGLE_program_cache_control.
1631*8975f5c5SAndroid Build Coastguard Worker     // If not, keep caching enabled for EGL_ANDROID_blob_cache, which can have its callbacks set
1632*8975f5c5SAndroid Build Coastguard Worker     // at any time.
1633*8975f5c5SAndroid Build Coastguard Worker     bool usesProgramCacheControl = attribs.contains(EGL_CONTEXT_PROGRAM_BINARY_CACHE_ENABLED_ANGLE);
1634*8975f5c5SAndroid Build Coastguard Worker     if (usesProgramCacheControl)
1635*8975f5c5SAndroid Build Coastguard Worker     {
1636*8975f5c5SAndroid Build Coastguard Worker         bool programCacheControlEnabled =
1637*8975f5c5SAndroid Build Coastguard Worker             (attribs.get(EGL_CONTEXT_PROGRAM_BINARY_CACHE_ENABLED_ANGLE, GL_FALSE) == GL_TRUE);
1638*8975f5c5SAndroid Build Coastguard Worker         // A program cache size of zero indicates it should be disabled.
1639*8975f5c5SAndroid Build Coastguard Worker         if (!programCacheControlEnabled || mMemoryProgramCache.maxSize() == 0)
1640*8975f5c5SAndroid Build Coastguard Worker         {
1641*8975f5c5SAndroid Build Coastguard Worker             programCachePointer = nullptr;
1642*8975f5c5SAndroid Build Coastguard Worker         }
1643*8975f5c5SAndroid Build Coastguard Worker     }
1644*8975f5c5SAndroid Build Coastguard Worker 
1645*8975f5c5SAndroid Build Coastguard Worker     gl::MemoryShaderCache *shaderCachePointer = &mMemoryShaderCache;
1646*8975f5c5SAndroid Build Coastguard Worker     // Check if shader caching frontend feature is enabled.
1647*8975f5c5SAndroid Build Coastguard Worker     if (!mFrontendFeatures.cacheCompiledShader.enabled)
1648*8975f5c5SAndroid Build Coastguard Worker     {
1649*8975f5c5SAndroid Build Coastguard Worker         shaderCachePointer = nullptr;
1650*8975f5c5SAndroid Build Coastguard Worker     }
1651*8975f5c5SAndroid Build Coastguard Worker 
1652*8975f5c5SAndroid Build Coastguard Worker     gl::Context *context =
1653*8975f5c5SAndroid Build Coastguard Worker         new gl::Context(this, configuration, shareContext, shareTextures, shareSemaphores,
1654*8975f5c5SAndroid Build Coastguard Worker                         sharedContextMutex, programCachePointer, shaderCachePointer, attribs,
1655*8975f5c5SAndroid Build Coastguard Worker                         mDisplayExtensions, GetClientExtensions());
1656*8975f5c5SAndroid Build Coastguard Worker     Error error = context->initialize();
1657*8975f5c5SAndroid Build Coastguard Worker     if (error.isError())
1658*8975f5c5SAndroid Build Coastguard Worker     {
1659*8975f5c5SAndroid Build Coastguard Worker         delete context;
1660*8975f5c5SAndroid Build Coastguard Worker         return error;
1661*8975f5c5SAndroid Build Coastguard Worker     }
1662*8975f5c5SAndroid Build Coastguard Worker 
1663*8975f5c5SAndroid Build Coastguard Worker     if (shareContext != nullptr)
1664*8975f5c5SAndroid Build Coastguard Worker     {
1665*8975f5c5SAndroid Build Coastguard Worker         shareContext->setShared();
1666*8975f5c5SAndroid Build Coastguard Worker     }
1667*8975f5c5SAndroid Build Coastguard Worker 
1668*8975f5c5SAndroid Build Coastguard Worker     ASSERT(context != nullptr);
1669*8975f5c5SAndroid Build Coastguard Worker     {
1670*8975f5c5SAndroid Build Coastguard Worker         std::lock_guard<angle::SimpleMutex> lock(mState.contextMapMutex);
1671*8975f5c5SAndroid Build Coastguard Worker         mState.contextMap.insert(std::pair(context->id().value, context));
1672*8975f5c5SAndroid Build Coastguard Worker     }
1673*8975f5c5SAndroid Build Coastguard Worker 
1674*8975f5c5SAndroid Build Coastguard Worker     ASSERT(outContext != nullptr);
1675*8975f5c5SAndroid Build Coastguard Worker     *outContext = context;
1676*8975f5c5SAndroid Build Coastguard Worker     return NoError();
1677*8975f5c5SAndroid Build Coastguard Worker }
1678*8975f5c5SAndroid Build Coastguard Worker 
createSync(const gl::Context * currentContext,EGLenum type,const AttributeMap & attribs,Sync ** outSync)1679*8975f5c5SAndroid Build Coastguard Worker Error Display::createSync(const gl::Context *currentContext,
1680*8975f5c5SAndroid Build Coastguard Worker                           EGLenum type,
1681*8975f5c5SAndroid Build Coastguard Worker                           const AttributeMap &attribs,
1682*8975f5c5SAndroid Build Coastguard Worker                           Sync **outSync)
1683*8975f5c5SAndroid Build Coastguard Worker {
1684*8975f5c5SAndroid Build Coastguard Worker     ASSERT(isInitialized());
1685*8975f5c5SAndroid Build Coastguard Worker 
1686*8975f5c5SAndroid Build Coastguard Worker     SyncID id = {mSyncHandleAllocator.allocate()};
1687*8975f5c5SAndroid Build Coastguard Worker 
1688*8975f5c5SAndroid Build Coastguard Worker     if (mImplementation->testDeviceLost())
1689*8975f5c5SAndroid Build Coastguard Worker     {
1690*8975f5c5SAndroid Build Coastguard Worker         ANGLE_TRY(restoreLostDevice());
1691*8975f5c5SAndroid Build Coastguard Worker     }
1692*8975f5c5SAndroid Build Coastguard Worker 
1693*8975f5c5SAndroid Build Coastguard Worker     std::unique_ptr<Sync> sync;
1694*8975f5c5SAndroid Build Coastguard Worker 
1695*8975f5c5SAndroid Build Coastguard Worker     SyncPool &pool = mSyncPools[type];
1696*8975f5c5SAndroid Build Coastguard Worker     if (!pool.empty())
1697*8975f5c5SAndroid Build Coastguard Worker     {
1698*8975f5c5SAndroid Build Coastguard Worker         sync = std::move(pool.back());
1699*8975f5c5SAndroid Build Coastguard Worker         pool.pop_back();
1700*8975f5c5SAndroid Build Coastguard Worker     }
1701*8975f5c5SAndroid Build Coastguard Worker     else
1702*8975f5c5SAndroid Build Coastguard Worker     {
1703*8975f5c5SAndroid Build Coastguard Worker         sync.reset(new Sync(mImplementation, type));
1704*8975f5c5SAndroid Build Coastguard Worker     }
1705*8975f5c5SAndroid Build Coastguard Worker 
1706*8975f5c5SAndroid Build Coastguard Worker     Error err = sync->initialize(this, currentContext, id, attribs);
1707*8975f5c5SAndroid Build Coastguard Worker     if (err.isError())
1708*8975f5c5SAndroid Build Coastguard Worker     {
1709*8975f5c5SAndroid Build Coastguard Worker         sync->onDestroy(this);
1710*8975f5c5SAndroid Build Coastguard Worker         return err;
1711*8975f5c5SAndroid Build Coastguard Worker     }
1712*8975f5c5SAndroid Build Coastguard Worker 
1713*8975f5c5SAndroid Build Coastguard Worker     *outSync = sync.get();
1714*8975f5c5SAndroid Build Coastguard Worker     mSyncMap.insert(std::pair(id.value, std::move(sync)));
1715*8975f5c5SAndroid Build Coastguard Worker 
1716*8975f5c5SAndroid Build Coastguard Worker     return NoError();
1717*8975f5c5SAndroid Build Coastguard Worker }
1718*8975f5c5SAndroid Build Coastguard Worker 
makeCurrent(Thread * thread,gl::Context * previousContext,egl::Surface * drawSurface,egl::Surface * readSurface,gl::Context * context)1719*8975f5c5SAndroid Build Coastguard Worker Error Display::makeCurrent(Thread *thread,
1720*8975f5c5SAndroid Build Coastguard Worker                            gl::Context *previousContext,
1721*8975f5c5SAndroid Build Coastguard Worker                            egl::Surface *drawSurface,
1722*8975f5c5SAndroid Build Coastguard Worker                            egl::Surface *readSurface,
1723*8975f5c5SAndroid Build Coastguard Worker                            gl::Context *context)
1724*8975f5c5SAndroid Build Coastguard Worker {
1725*8975f5c5SAndroid Build Coastguard Worker     if (!mInitialized)
1726*8975f5c5SAndroid Build Coastguard Worker     {
1727*8975f5c5SAndroid Build Coastguard Worker         return NoError();
1728*8975f5c5SAndroid Build Coastguard Worker     }
1729*8975f5c5SAndroid Build Coastguard Worker 
1730*8975f5c5SAndroid Build Coastguard Worker     bool contextChanged = context != previousContext;
1731*8975f5c5SAndroid Build Coastguard Worker     if (previousContext != nullptr && contextChanged)
1732*8975f5c5SAndroid Build Coastguard Worker     {
1733*8975f5c5SAndroid Build Coastguard Worker         // Need AddRefLock because there may be ContextMutex destruction.
1734*8975f5c5SAndroid Build Coastguard Worker         ScopedContextMutexAddRefLock lock(previousContext->getContextMutex());
1735*8975f5c5SAndroid Build Coastguard Worker 
1736*8975f5c5SAndroid Build Coastguard Worker         previousContext->release();
1737*8975f5c5SAndroid Build Coastguard Worker         thread->setCurrent(nullptr);
1738*8975f5c5SAndroid Build Coastguard Worker 
1739*8975f5c5SAndroid Build Coastguard Worker         auto error = previousContext->unMakeCurrent(this);
1740*8975f5c5SAndroid Build Coastguard Worker         if (!previousContext->isReferenced() && previousContext->isDestroyed())
1741*8975f5c5SAndroid Build Coastguard Worker         {
1742*8975f5c5SAndroid Build Coastguard Worker             // The previous Context may have been created with a different Display.
1743*8975f5c5SAndroid Build Coastguard Worker             Display *previousDisplay = previousContext->getDisplay();
1744*8975f5c5SAndroid Build Coastguard Worker             ANGLE_TRY(previousDisplay->releaseContext(previousContext, thread));
1745*8975f5c5SAndroid Build Coastguard Worker         }
1746*8975f5c5SAndroid Build Coastguard Worker         ANGLE_TRY(error);
1747*8975f5c5SAndroid Build Coastguard Worker     }
1748*8975f5c5SAndroid Build Coastguard Worker 
1749*8975f5c5SAndroid Build Coastguard Worker     {
1750*8975f5c5SAndroid Build Coastguard Worker         ScopedContextMutexLock lock(context != nullptr ? &context->getContextMutex() : nullptr);
1751*8975f5c5SAndroid Build Coastguard Worker 
1752*8975f5c5SAndroid Build Coastguard Worker         thread->setCurrent(context);
1753*8975f5c5SAndroid Build Coastguard Worker 
1754*8975f5c5SAndroid Build Coastguard Worker         ANGLE_TRY(mImplementation->makeCurrent(this, drawSurface, readSurface, context));
1755*8975f5c5SAndroid Build Coastguard Worker 
1756*8975f5c5SAndroid Build Coastguard Worker         if (context != nullptr)
1757*8975f5c5SAndroid Build Coastguard Worker         {
1758*8975f5c5SAndroid Build Coastguard Worker             ANGLE_TRY(context->makeCurrent(this, drawSurface, readSurface));
1759*8975f5c5SAndroid Build Coastguard Worker             if (contextChanged)
1760*8975f5c5SAndroid Build Coastguard Worker             {
1761*8975f5c5SAndroid Build Coastguard Worker                 context->addRef();
1762*8975f5c5SAndroid Build Coastguard Worker             }
1763*8975f5c5SAndroid Build Coastguard Worker         }
1764*8975f5c5SAndroid Build Coastguard Worker     }
1765*8975f5c5SAndroid Build Coastguard Worker 
1766*8975f5c5SAndroid Build Coastguard Worker     // Tick all the scratch buffers to make sure they get cleaned up eventually if they stop being
1767*8975f5c5SAndroid Build Coastguard Worker     // used.
1768*8975f5c5SAndroid Build Coastguard Worker     {
1769*8975f5c5SAndroid Build Coastguard Worker         std::lock_guard<angle::SimpleMutex> lock(mScratchBufferMutex);
1770*8975f5c5SAndroid Build Coastguard Worker 
1771*8975f5c5SAndroid Build Coastguard Worker         for (angle::ScratchBuffer &scatchBuffer : mScratchBuffers)
1772*8975f5c5SAndroid Build Coastguard Worker         {
1773*8975f5c5SAndroid Build Coastguard Worker             scatchBuffer.tick();
1774*8975f5c5SAndroid Build Coastguard Worker         }
1775*8975f5c5SAndroid Build Coastguard Worker         for (angle::ScratchBuffer &zeroFilledBuffer : mZeroFilledBuffers)
1776*8975f5c5SAndroid Build Coastguard Worker         {
1777*8975f5c5SAndroid Build Coastguard Worker             zeroFilledBuffer.tick();
1778*8975f5c5SAndroid Build Coastguard Worker         }
1779*8975f5c5SAndroid Build Coastguard Worker     }
1780*8975f5c5SAndroid Build Coastguard Worker 
1781*8975f5c5SAndroid Build Coastguard Worker     // If eglTerminate() has previously been called and Context was changed, perform InternalCleanup
1782*8975f5c5SAndroid Build Coastguard Worker     // to invalidate any non-current Contexts, and possibly fully terminate the Display and release
1783*8975f5c5SAndroid Build Coastguard Worker     // all of its resources.
1784*8975f5c5SAndroid Build Coastguard Worker     if (mTerminatedByApi && contextChanged)
1785*8975f5c5SAndroid Build Coastguard Worker     {
1786*8975f5c5SAndroid Build Coastguard Worker         return terminate(thread, TerminateReason::InternalCleanup);
1787*8975f5c5SAndroid Build Coastguard Worker     }
1788*8975f5c5SAndroid Build Coastguard Worker 
1789*8975f5c5SAndroid Build Coastguard Worker     return NoError();
1790*8975f5c5SAndroid Build Coastguard Worker }
1791*8975f5c5SAndroid Build Coastguard Worker 
restoreLostDevice()1792*8975f5c5SAndroid Build Coastguard Worker Error Display::restoreLostDevice()
1793*8975f5c5SAndroid Build Coastguard Worker {
1794*8975f5c5SAndroid Build Coastguard Worker     {
1795*8975f5c5SAndroid Build Coastguard Worker         std::lock_guard<angle::SimpleMutex> lock(mState.contextMapMutex);
1796*8975f5c5SAndroid Build Coastguard Worker         for (ContextMap::iterator ctx = mState.contextMap.begin(); ctx != mState.contextMap.end();
1797*8975f5c5SAndroid Build Coastguard Worker              ctx++)
1798*8975f5c5SAndroid Build Coastguard Worker         {
1799*8975f5c5SAndroid Build Coastguard Worker             if (ctx->second->isResetNotificationEnabled())
1800*8975f5c5SAndroid Build Coastguard Worker             {
1801*8975f5c5SAndroid Build Coastguard Worker                 // If reset notifications have been requested, application must delete all contexts
1802*8975f5c5SAndroid Build Coastguard Worker                 // first
1803*8975f5c5SAndroid Build Coastguard Worker                 return EglContextLost();
1804*8975f5c5SAndroid Build Coastguard Worker             }
1805*8975f5c5SAndroid Build Coastguard Worker         }
1806*8975f5c5SAndroid Build Coastguard Worker     }
1807*8975f5c5SAndroid Build Coastguard Worker 
1808*8975f5c5SAndroid Build Coastguard Worker     return mImplementation->restoreLostDevice(this);
1809*8975f5c5SAndroid Build Coastguard Worker }
1810*8975f5c5SAndroid Build Coastguard Worker 
destroySurfaceImpl(Surface * surface,SurfaceMap * surfaces)1811*8975f5c5SAndroid Build Coastguard Worker Error Display::destroySurfaceImpl(Surface *surface, SurfaceMap *surfaces)
1812*8975f5c5SAndroid Build Coastguard Worker {
1813*8975f5c5SAndroid Build Coastguard Worker     if (surface->getType() == EGL_WINDOW_BIT)
1814*8975f5c5SAndroid Build Coastguard Worker     {
1815*8975f5c5SAndroid Build Coastguard Worker         WindowSurfaceMap *windowSurfaces = GetWindowSurfaces();
1816*8975f5c5SAndroid Build Coastguard Worker         ASSERT(windowSurfaces);
1817*8975f5c5SAndroid Build Coastguard Worker 
1818*8975f5c5SAndroid Build Coastguard Worker         bool surfaceRemoved = false;
1819*8975f5c5SAndroid Build Coastguard Worker         for (WindowSurfaceMap::iterator iter = windowSurfaces->begin();
1820*8975f5c5SAndroid Build Coastguard Worker              iter != windowSurfaces->end(); iter++)
1821*8975f5c5SAndroid Build Coastguard Worker         {
1822*8975f5c5SAndroid Build Coastguard Worker             if (iter->second == surface)
1823*8975f5c5SAndroid Build Coastguard Worker             {
1824*8975f5c5SAndroid Build Coastguard Worker                 windowSurfaces->erase(iter);
1825*8975f5c5SAndroid Build Coastguard Worker                 surfaceRemoved = true;
1826*8975f5c5SAndroid Build Coastguard Worker                 break;
1827*8975f5c5SAndroid Build Coastguard Worker             }
1828*8975f5c5SAndroid Build Coastguard Worker         }
1829*8975f5c5SAndroid Build Coastguard Worker 
1830*8975f5c5SAndroid Build Coastguard Worker         ASSERT(surfaceRemoved);
1831*8975f5c5SAndroid Build Coastguard Worker     }
1832*8975f5c5SAndroid Build Coastguard Worker 
1833*8975f5c5SAndroid Build Coastguard Worker     auto iter = surfaces->find(surface->id().value);
1834*8975f5c5SAndroid Build Coastguard Worker     ASSERT(iter != surfaces->end());
1835*8975f5c5SAndroid Build Coastguard Worker     mSurfaceHandleAllocator.release(surface->id().value);
1836*8975f5c5SAndroid Build Coastguard Worker     surfaces->erase(iter);
1837*8975f5c5SAndroid Build Coastguard Worker     ANGLE_TRY(surface->onDestroy(this));
1838*8975f5c5SAndroid Build Coastguard Worker     return NoError();
1839*8975f5c5SAndroid Build Coastguard Worker }
1840*8975f5c5SAndroid Build Coastguard Worker 
destroyImageImpl(Image * image,ImageMap * images)1841*8975f5c5SAndroid Build Coastguard Worker void Display::destroyImageImpl(Image *image, ImageMap *images)
1842*8975f5c5SAndroid Build Coastguard Worker {
1843*8975f5c5SAndroid Build Coastguard Worker     auto iter = images->find(image->id().value);
1844*8975f5c5SAndroid Build Coastguard Worker     ASSERT(iter != images->end());
1845*8975f5c5SAndroid Build Coastguard Worker     mImageHandleAllocator.release(image->id().value);
1846*8975f5c5SAndroid Build Coastguard Worker     {
1847*8975f5c5SAndroid Build Coastguard Worker         // Need AddRefLock because there may be ContextMutex destruction.
1848*8975f5c5SAndroid Build Coastguard Worker         ScopedContextMutexAddRefLock lock(image->getContextMutex());
1849*8975f5c5SAndroid Build Coastguard Worker         iter->second->release(this);
1850*8975f5c5SAndroid Build Coastguard Worker     }
1851*8975f5c5SAndroid Build Coastguard Worker     images->erase(iter);
1852*8975f5c5SAndroid Build Coastguard Worker }
1853*8975f5c5SAndroid Build Coastguard Worker 
destroyStreamImpl(Stream * stream,StreamSet * streams)1854*8975f5c5SAndroid Build Coastguard Worker void Display::destroyStreamImpl(Stream *stream, StreamSet *streams)
1855*8975f5c5SAndroid Build Coastguard Worker {
1856*8975f5c5SAndroid Build Coastguard Worker     streams->erase(stream);
1857*8975f5c5SAndroid Build Coastguard Worker     SafeDelete(stream);
1858*8975f5c5SAndroid Build Coastguard Worker }
1859*8975f5c5SAndroid Build Coastguard Worker 
1860*8975f5c5SAndroid Build Coastguard Worker // releaseContext must be called with the context being deleted as current.
1861*8975f5c5SAndroid Build Coastguard Worker // To do that we can only call this in two places, Display::makeCurrent at the point where this
1862*8975f5c5SAndroid Build Coastguard Worker // context is being made uncurrent and in Display::destroyContext where we make the context current
1863*8975f5c5SAndroid Build Coastguard Worker // as part of destruction.
releaseContext(gl::Context * context,Thread * thread)1864*8975f5c5SAndroid Build Coastguard Worker Error Display::releaseContext(gl::Context *context, Thread *thread)
1865*8975f5c5SAndroid Build Coastguard Worker {
1866*8975f5c5SAndroid Build Coastguard Worker     // Use scoped_ptr to make sure the context is always freed.
1867*8975f5c5SAndroid Build Coastguard Worker     std::unique_ptr<gl::Context> uniqueContextPtr;
1868*8975f5c5SAndroid Build Coastguard Worker     {
1869*8975f5c5SAndroid Build Coastguard Worker         std::lock_guard<angle::SimpleMutex> lock(mState.contextMapMutex);
1870*8975f5c5SAndroid Build Coastguard Worker         uniqueContextPtr = eraseContextImpl(context, &mState.contextMap);
1871*8975f5c5SAndroid Build Coastguard Worker     }
1872*8975f5c5SAndroid Build Coastguard Worker     return releaseContextImpl(std::move(uniqueContextPtr));
1873*8975f5c5SAndroid Build Coastguard Worker }
1874*8975f5c5SAndroid Build Coastguard Worker 
eraseContextImpl(gl::Context * context,ContextMap * contexts)1875*8975f5c5SAndroid Build Coastguard Worker std::unique_ptr<gl::Context> Display::eraseContextImpl(gl::Context *context, ContextMap *contexts)
1876*8975f5c5SAndroid Build Coastguard Worker {
1877*8975f5c5SAndroid Build Coastguard Worker     ASSERT(!context->isReferenced());
1878*8975f5c5SAndroid Build Coastguard Worker 
1879*8975f5c5SAndroid Build Coastguard Worker     // Use scoped_ptr to make sure the context is always freed.
1880*8975f5c5SAndroid Build Coastguard Worker     std::unique_ptr<gl::Context> unique_context(context);
1881*8975f5c5SAndroid Build Coastguard Worker     ASSERT(contexts->find(context->id().value) != contexts->end());
1882*8975f5c5SAndroid Build Coastguard Worker     contexts->erase(context->id().value);
1883*8975f5c5SAndroid Build Coastguard Worker 
1884*8975f5c5SAndroid Build Coastguard Worker     return unique_context;
1885*8975f5c5SAndroid Build Coastguard Worker }
1886*8975f5c5SAndroid Build Coastguard Worker 
releaseContextImpl(std::unique_ptr<gl::Context> && context)1887*8975f5c5SAndroid Build Coastguard Worker Error Display::releaseContextImpl(std::unique_ptr<gl::Context> &&context)
1888*8975f5c5SAndroid Build Coastguard Worker {
1889*8975f5c5SAndroid Build Coastguard Worker     if (context->usingDisplayTextureShareGroup())
1890*8975f5c5SAndroid Build Coastguard Worker     {
1891*8975f5c5SAndroid Build Coastguard Worker         ASSERT(mGlobalTextureShareGroupUsers >= 1 && mTextureManager != nullptr);
1892*8975f5c5SAndroid Build Coastguard Worker         if (mGlobalTextureShareGroupUsers == 1)
1893*8975f5c5SAndroid Build Coastguard Worker         {
1894*8975f5c5SAndroid Build Coastguard Worker             // If this is the last context using the global share group, destroy the global
1895*8975f5c5SAndroid Build Coastguard Worker             // texture manager so that the textures can be destroyed while a context still
1896*8975f5c5SAndroid Build Coastguard Worker             // exists
1897*8975f5c5SAndroid Build Coastguard Worker             mTextureManager->release(context.get());
1898*8975f5c5SAndroid Build Coastguard Worker             mTextureManager = nullptr;
1899*8975f5c5SAndroid Build Coastguard Worker         }
1900*8975f5c5SAndroid Build Coastguard Worker         mGlobalTextureShareGroupUsers--;
1901*8975f5c5SAndroid Build Coastguard Worker     }
1902*8975f5c5SAndroid Build Coastguard Worker 
1903*8975f5c5SAndroid Build Coastguard Worker     if (context->usingDisplaySemaphoreShareGroup())
1904*8975f5c5SAndroid Build Coastguard Worker     {
1905*8975f5c5SAndroid Build Coastguard Worker         ASSERT(mGlobalSemaphoreShareGroupUsers >= 1 && mSemaphoreManager != nullptr);
1906*8975f5c5SAndroid Build Coastguard Worker         if (mGlobalSemaphoreShareGroupUsers == 1)
1907*8975f5c5SAndroid Build Coastguard Worker         {
1908*8975f5c5SAndroid Build Coastguard Worker             // If this is the last context using the global share group, destroy the global
1909*8975f5c5SAndroid Build Coastguard Worker             // semaphore manager so that the semaphores can be destroyed while a context still
1910*8975f5c5SAndroid Build Coastguard Worker             // exists
1911*8975f5c5SAndroid Build Coastguard Worker             mSemaphoreManager->release(context.get());
1912*8975f5c5SAndroid Build Coastguard Worker             mSemaphoreManager = nullptr;
1913*8975f5c5SAndroid Build Coastguard Worker         }
1914*8975f5c5SAndroid Build Coastguard Worker         mGlobalSemaphoreShareGroupUsers--;
1915*8975f5c5SAndroid Build Coastguard Worker     }
1916*8975f5c5SAndroid Build Coastguard Worker 
1917*8975f5c5SAndroid Build Coastguard Worker     ANGLE_TRY(context->onDestroy(this));
1918*8975f5c5SAndroid Build Coastguard Worker 
1919*8975f5c5SAndroid Build Coastguard Worker     return NoError();
1920*8975f5c5SAndroid Build Coastguard Worker }
1921*8975f5c5SAndroid Build Coastguard Worker 
destroyContext(Thread * thread,gl::Context * context)1922*8975f5c5SAndroid Build Coastguard Worker Error Display::destroyContext(Thread *thread, gl::Context *context)
1923*8975f5c5SAndroid Build Coastguard Worker {
1924*8975f5c5SAndroid Build Coastguard Worker     auto *currentContext     = thread->getContext();
1925*8975f5c5SAndroid Build Coastguard Worker     auto *currentDrawSurface = thread->getCurrentDrawSurface();
1926*8975f5c5SAndroid Build Coastguard Worker     auto *currentReadSurface = thread->getCurrentReadSurface();
1927*8975f5c5SAndroid Build Coastguard Worker 
1928*8975f5c5SAndroid Build Coastguard Worker     context->setIsDestroyed();
1929*8975f5c5SAndroid Build Coastguard Worker 
1930*8975f5c5SAndroid Build Coastguard Worker     // If the context is still current on at least 1 thread, just return since it'll be released
1931*8975f5c5SAndroid Build Coastguard Worker     // once no threads have it current anymore.
1932*8975f5c5SAndroid Build Coastguard Worker     if (context->isReferenced())
1933*8975f5c5SAndroid Build Coastguard Worker     {
1934*8975f5c5SAndroid Build Coastguard Worker         return NoError();
1935*8975f5c5SAndroid Build Coastguard Worker     }
1936*8975f5c5SAndroid Build Coastguard Worker 
1937*8975f5c5SAndroid Build Coastguard Worker     // For external context, we cannot change the current native context, and the API user should
1938*8975f5c5SAndroid Build Coastguard Worker     // make sure the native context is current.
1939*8975f5c5SAndroid Build Coastguard Worker     if (context->isExternal())
1940*8975f5c5SAndroid Build Coastguard Worker     {
1941*8975f5c5SAndroid Build Coastguard Worker         // Need AddRefLock because there may be ContextMutex destruction.
1942*8975f5c5SAndroid Build Coastguard Worker         ScopedContextMutexAddRefLock lock(context->getContextMutex());
1943*8975f5c5SAndroid Build Coastguard Worker         ANGLE_TRY(releaseContext(context, thread));
1944*8975f5c5SAndroid Build Coastguard Worker     }
1945*8975f5c5SAndroid Build Coastguard Worker     else
1946*8975f5c5SAndroid Build Coastguard Worker     {
1947*8975f5c5SAndroid Build Coastguard Worker         // Keep |currentContext| alive, while releasing |context|.
1948*8975f5c5SAndroid Build Coastguard Worker         gl::ScopedContextRef scopedContextRef(currentContext);
1949*8975f5c5SAndroid Build Coastguard Worker 
1950*8975f5c5SAndroid Build Coastguard Worker         // keep |currentDrawSurface| and |currentReadSurface| alive as well
1951*8975f5c5SAndroid Build Coastguard Worker         // while releasing |context|.
1952*8975f5c5SAndroid Build Coastguard Worker         ScopedSurfaceRef drawSurfaceRef(currentDrawSurface);
1953*8975f5c5SAndroid Build Coastguard Worker         ScopedSurfaceRef readSurfaceRef(
1954*8975f5c5SAndroid Build Coastguard Worker             currentReadSurface == currentDrawSurface ? nullptr : currentReadSurface);
1955*8975f5c5SAndroid Build Coastguard Worker 
1956*8975f5c5SAndroid Build Coastguard Worker         // Make the context current, so we can release resources belong to the context, and then
1957*8975f5c5SAndroid Build Coastguard Worker         // when context is released from the current, it will be destroyed.
1958*8975f5c5SAndroid Build Coastguard Worker         // TODO(http://anglebug.com/42264840): Don't require a Context to be current in order to
1959*8975f5c5SAndroid Build Coastguard Worker         // destroy it.
1960*8975f5c5SAndroid Build Coastguard Worker         ANGLE_TRY(makeCurrent(thread, currentContext, nullptr, nullptr, context));
1961*8975f5c5SAndroid Build Coastguard Worker         ANGLE_TRY(
1962*8975f5c5SAndroid Build Coastguard Worker             makeCurrent(thread, context, currentDrawSurface, currentReadSurface, currentContext));
1963*8975f5c5SAndroid Build Coastguard Worker     }
1964*8975f5c5SAndroid Build Coastguard Worker 
1965*8975f5c5SAndroid Build Coastguard Worker     return NoError();
1966*8975f5c5SAndroid Build Coastguard Worker }
1967*8975f5c5SAndroid Build Coastguard Worker 
destroySyncImpl(SyncID syncId,SyncMap * syncs)1968*8975f5c5SAndroid Build Coastguard Worker void Display::destroySyncImpl(SyncID syncId, SyncMap *syncs)
1969*8975f5c5SAndroid Build Coastguard Worker {
1970*8975f5c5SAndroid Build Coastguard Worker     auto iter = syncs->find(syncId.value);
1971*8975f5c5SAndroid Build Coastguard Worker     ASSERT(iter != syncs->end());
1972*8975f5c5SAndroid Build Coastguard Worker     mSyncHandleAllocator.release(syncId.value);
1973*8975f5c5SAndroid Build Coastguard Worker 
1974*8975f5c5SAndroid Build Coastguard Worker     auto &sync = iter->second;
1975*8975f5c5SAndroid Build Coastguard Worker     sync->onDestroy(this);
1976*8975f5c5SAndroid Build Coastguard Worker 
1977*8975f5c5SAndroid Build Coastguard Worker     SyncPool &pool = mSyncPools[sync->getType()];
1978*8975f5c5SAndroid Build Coastguard Worker     if (pool.size() < kMaxSyncPoolSizePerType)
1979*8975f5c5SAndroid Build Coastguard Worker     {
1980*8975f5c5SAndroid Build Coastguard Worker         pool.push_back(std::move(sync));
1981*8975f5c5SAndroid Build Coastguard Worker     }
1982*8975f5c5SAndroid Build Coastguard Worker 
1983*8975f5c5SAndroid Build Coastguard Worker     syncs->erase(iter);
1984*8975f5c5SAndroid Build Coastguard Worker }
1985*8975f5c5SAndroid Build Coastguard Worker 
destroyImage(Image * image)1986*8975f5c5SAndroid Build Coastguard Worker void Display::destroyImage(Image *image)
1987*8975f5c5SAndroid Build Coastguard Worker {
1988*8975f5c5SAndroid Build Coastguard Worker     return destroyImageImpl(image, &mImageMap);
1989*8975f5c5SAndroid Build Coastguard Worker }
1990*8975f5c5SAndroid Build Coastguard Worker 
destroyStream(Stream * stream)1991*8975f5c5SAndroid Build Coastguard Worker void Display::destroyStream(Stream *stream)
1992*8975f5c5SAndroid Build Coastguard Worker {
1993*8975f5c5SAndroid Build Coastguard Worker     return destroyStreamImpl(stream, &mStreamSet);
1994*8975f5c5SAndroid Build Coastguard Worker }
1995*8975f5c5SAndroid Build Coastguard Worker 
destroySurface(Surface * surface)1996*8975f5c5SAndroid Build Coastguard Worker Error Display::destroySurface(Surface *surface)
1997*8975f5c5SAndroid Build Coastguard Worker {
1998*8975f5c5SAndroid Build Coastguard Worker     return destroySurfaceImpl(surface, &mState.surfaceMap);
1999*8975f5c5SAndroid Build Coastguard Worker }
2000*8975f5c5SAndroid Build Coastguard Worker 
destroySync(Sync * sync)2001*8975f5c5SAndroid Build Coastguard Worker void Display::destroySync(Sync *sync)
2002*8975f5c5SAndroid Build Coastguard Worker {
2003*8975f5c5SAndroid Build Coastguard Worker     return destroySyncImpl(sync->id(), &mSyncMap);
2004*8975f5c5SAndroid Build Coastguard Worker }
2005*8975f5c5SAndroid Build Coastguard Worker 
isDeviceLost() const2006*8975f5c5SAndroid Build Coastguard Worker bool Display::isDeviceLost() const
2007*8975f5c5SAndroid Build Coastguard Worker {
2008*8975f5c5SAndroid Build Coastguard Worker     ASSERT(isInitialized());
2009*8975f5c5SAndroid Build Coastguard Worker     return mState.deviceLost;
2010*8975f5c5SAndroid Build Coastguard Worker }
2011*8975f5c5SAndroid Build Coastguard Worker 
testDeviceLost()2012*8975f5c5SAndroid Build Coastguard Worker bool Display::testDeviceLost()
2013*8975f5c5SAndroid Build Coastguard Worker {
2014*8975f5c5SAndroid Build Coastguard Worker     ASSERT(isInitialized());
2015*8975f5c5SAndroid Build Coastguard Worker 
2016*8975f5c5SAndroid Build Coastguard Worker     if (!mState.deviceLost && mImplementation->testDeviceLost())
2017*8975f5c5SAndroid Build Coastguard Worker     {
2018*8975f5c5SAndroid Build Coastguard Worker         notifyDeviceLost();
2019*8975f5c5SAndroid Build Coastguard Worker     }
2020*8975f5c5SAndroid Build Coastguard Worker 
2021*8975f5c5SAndroid Build Coastguard Worker     return mState.deviceLost;
2022*8975f5c5SAndroid Build Coastguard Worker }
2023*8975f5c5SAndroid Build Coastguard Worker 
notifyDeviceLost()2024*8975f5c5SAndroid Build Coastguard Worker void Display::notifyDeviceLost()
2025*8975f5c5SAndroid Build Coastguard Worker {
2026*8975f5c5SAndroid Build Coastguard Worker     mState.notifyDeviceLost();
2027*8975f5c5SAndroid Build Coastguard Worker }
2028*8975f5c5SAndroid Build Coastguard Worker 
setBlobCacheFuncs(EGLSetBlobFuncANDROID set,EGLGetBlobFuncANDROID get)2029*8975f5c5SAndroid Build Coastguard Worker void Display::setBlobCacheFuncs(EGLSetBlobFuncANDROID set, EGLGetBlobFuncANDROID get)
2030*8975f5c5SAndroid Build Coastguard Worker {
2031*8975f5c5SAndroid Build Coastguard Worker     mBlobCache.setBlobCacheFuncs(set, get);
2032*8975f5c5SAndroid Build Coastguard Worker     mImplementation->setBlobCacheFuncs(set, get);
2033*8975f5c5SAndroid Build Coastguard Worker }
2034*8975f5c5SAndroid Build Coastguard Worker 
2035*8975f5c5SAndroid Build Coastguard Worker // static
GetNativeClientBuffer(const AHardwareBuffer * buffer)2036*8975f5c5SAndroid Build Coastguard Worker EGLClientBuffer Display::GetNativeClientBuffer(const AHardwareBuffer *buffer)
2037*8975f5c5SAndroid Build Coastguard Worker {
2038*8975f5c5SAndroid Build Coastguard Worker     return angle::android::AHardwareBufferToClientBuffer(buffer);
2039*8975f5c5SAndroid Build Coastguard Worker }
2040*8975f5c5SAndroid Build Coastguard Worker 
2041*8975f5c5SAndroid Build Coastguard Worker // static
CreateNativeClientBuffer(const egl::AttributeMap & attribMap,EGLClientBuffer * eglClientBuffer)2042*8975f5c5SAndroid Build Coastguard Worker Error Display::CreateNativeClientBuffer(const egl::AttributeMap &attribMap,
2043*8975f5c5SAndroid Build Coastguard Worker                                         EGLClientBuffer *eglClientBuffer)
2044*8975f5c5SAndroid Build Coastguard Worker {
2045*8975f5c5SAndroid Build Coastguard Worker     int androidHardwareBufferFormat = gl::GetAndroidHardwareBufferFormatFromChannelSizes(attribMap);
2046*8975f5c5SAndroid Build Coastguard Worker     int width                       = attribMap.getAsInt(EGL_WIDTH, 0);
2047*8975f5c5SAndroid Build Coastguard Worker     int height                      = attribMap.getAsInt(EGL_HEIGHT, 0);
2048*8975f5c5SAndroid Build Coastguard Worker     int usage                       = attribMap.getAsInt(EGL_NATIVE_BUFFER_USAGE_ANDROID, 0);
2049*8975f5c5SAndroid Build Coastguard Worker 
2050*8975f5c5SAndroid Build Coastguard Worker     // https://developer.android.com/ndk/reference/group/a-hardware-buffer#ahardwarebuffer_lock
2051*8975f5c5SAndroid Build Coastguard Worker     // for AHardwareBuffer_lock()
2052*8975f5c5SAndroid Build Coastguard Worker     // The passed AHardwareBuffer must have one layer, otherwise the call will fail.
2053*8975f5c5SAndroid Build Coastguard Worker     constexpr int kLayerCount = 1;
2054*8975f5c5SAndroid Build Coastguard Worker 
2055*8975f5c5SAndroid Build Coastguard Worker     *eglClientBuffer = angle::android::CreateEGLClientBufferFromAHardwareBuffer(
2056*8975f5c5SAndroid Build Coastguard Worker         width, height, kLayerCount, androidHardwareBufferFormat, usage);
2057*8975f5c5SAndroid Build Coastguard Worker 
2058*8975f5c5SAndroid Build Coastguard Worker     return (*eglClientBuffer == nullptr)
2059*8975f5c5SAndroid Build Coastguard Worker                ? egl::EglBadParameter() << "native client buffer allocation failed."
2060*8975f5c5SAndroid Build Coastguard Worker                : NoError();
2061*8975f5c5SAndroid Build Coastguard Worker }
2062*8975f5c5SAndroid Build Coastguard Worker 
waitClient(const gl::Context * context)2063*8975f5c5SAndroid Build Coastguard Worker Error Display::waitClient(const gl::Context *context)
2064*8975f5c5SAndroid Build Coastguard Worker {
2065*8975f5c5SAndroid Build Coastguard Worker     return mImplementation->waitClient(context);
2066*8975f5c5SAndroid Build Coastguard Worker }
2067*8975f5c5SAndroid Build Coastguard Worker 
waitNative(const gl::Context * context,EGLint engine)2068*8975f5c5SAndroid Build Coastguard Worker Error Display::waitNative(const gl::Context *context, EGLint engine)
2069*8975f5c5SAndroid Build Coastguard Worker {
2070*8975f5c5SAndroid Build Coastguard Worker     return mImplementation->waitNative(context, engine);
2071*8975f5c5SAndroid Build Coastguard Worker }
2072*8975f5c5SAndroid Build Coastguard Worker 
getCaps() const2073*8975f5c5SAndroid Build Coastguard Worker const Caps &Display::getCaps() const
2074*8975f5c5SAndroid Build Coastguard Worker {
2075*8975f5c5SAndroid Build Coastguard Worker     return mCaps;
2076*8975f5c5SAndroid Build Coastguard Worker }
2077*8975f5c5SAndroid Build Coastguard Worker 
isInitialized() const2078*8975f5c5SAndroid Build Coastguard Worker bool Display::isInitialized() const
2079*8975f5c5SAndroid Build Coastguard Worker {
2080*8975f5c5SAndroid Build Coastguard Worker     return mInitialized;
2081*8975f5c5SAndroid Build Coastguard Worker }
2082*8975f5c5SAndroid Build Coastguard Worker 
isValidConfig(const Config * config) const2083*8975f5c5SAndroid Build Coastguard Worker bool Display::isValidConfig(const Config *config) const
2084*8975f5c5SAndroid Build Coastguard Worker {
2085*8975f5c5SAndroid Build Coastguard Worker     return mConfigSet.contains(config);
2086*8975f5c5SAndroid Build Coastguard Worker }
2087*8975f5c5SAndroid Build Coastguard Worker 
isValidContext(const gl::ContextID contextID) const2088*8975f5c5SAndroid Build Coastguard Worker bool Display::isValidContext(const gl::ContextID contextID) const
2089*8975f5c5SAndroid Build Coastguard Worker {
2090*8975f5c5SAndroid Build Coastguard Worker     return getContext(contextID) != nullptr;
2091*8975f5c5SAndroid Build Coastguard Worker }
2092*8975f5c5SAndroid Build Coastguard Worker 
isValidSurface(SurfaceID surfaceID) const2093*8975f5c5SAndroid Build Coastguard Worker bool Display::isValidSurface(SurfaceID surfaceID) const
2094*8975f5c5SAndroid Build Coastguard Worker {
2095*8975f5c5SAndroid Build Coastguard Worker     return getSurface(surfaceID) != nullptr;
2096*8975f5c5SAndroid Build Coastguard Worker }
2097*8975f5c5SAndroid Build Coastguard Worker 
isValidImage(ImageID imageID) const2098*8975f5c5SAndroid Build Coastguard Worker bool Display::isValidImage(ImageID imageID) const
2099*8975f5c5SAndroid Build Coastguard Worker {
2100*8975f5c5SAndroid Build Coastguard Worker     return getImage(imageID) != nullptr;
2101*8975f5c5SAndroid Build Coastguard Worker }
2102*8975f5c5SAndroid Build Coastguard Worker 
isValidStream(const Stream * stream) const2103*8975f5c5SAndroid Build Coastguard Worker bool Display::isValidStream(const Stream *stream) const
2104*8975f5c5SAndroid Build Coastguard Worker {
2105*8975f5c5SAndroid Build Coastguard Worker     return mStreamSet.find(const_cast<Stream *>(stream)) != mStreamSet.end();
2106*8975f5c5SAndroid Build Coastguard Worker }
2107*8975f5c5SAndroid Build Coastguard Worker 
isValidSync(SyncID syncID) const2108*8975f5c5SAndroid Build Coastguard Worker bool Display::isValidSync(SyncID syncID) const
2109*8975f5c5SAndroid Build Coastguard Worker {
2110*8975f5c5SAndroid Build Coastguard Worker     return getSync(syncID) != nullptr;
2111*8975f5c5SAndroid Build Coastguard Worker }
2112*8975f5c5SAndroid Build Coastguard Worker 
hasExistingWindowSurface(EGLNativeWindowType window)2113*8975f5c5SAndroid Build Coastguard Worker bool Display::hasExistingWindowSurface(EGLNativeWindowType window)
2114*8975f5c5SAndroid Build Coastguard Worker {
2115*8975f5c5SAndroid Build Coastguard Worker     WindowSurfaceMap *windowSurfaces = GetWindowSurfaces();
2116*8975f5c5SAndroid Build Coastguard Worker     ASSERT(windowSurfaces);
2117*8975f5c5SAndroid Build Coastguard Worker 
2118*8975f5c5SAndroid Build Coastguard Worker     return windowSurfaces->find(window) != windowSurfaces->end();
2119*8975f5c5SAndroid Build Coastguard Worker }
2120*8975f5c5SAndroid Build Coastguard Worker 
GenerateClientExtensions()2121*8975f5c5SAndroid Build Coastguard Worker static ClientExtensions GenerateClientExtensions()
2122*8975f5c5SAndroid Build Coastguard Worker {
2123*8975f5c5SAndroid Build Coastguard Worker     ClientExtensions extensions;
2124*8975f5c5SAndroid Build Coastguard Worker 
2125*8975f5c5SAndroid Build Coastguard Worker     extensions.clientExtensions = true;
2126*8975f5c5SAndroid Build Coastguard Worker     extensions.platformBase     = true;
2127*8975f5c5SAndroid Build Coastguard Worker     extensions.platformANGLE    = true;
2128*8975f5c5SAndroid Build Coastguard Worker 
2129*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_ENABLE_D3D9) || defined(ANGLE_ENABLE_D3D11)
2130*8975f5c5SAndroid Build Coastguard Worker     extensions.platformANGLED3D = true;
2131*8975f5c5SAndroid Build Coastguard Worker     extensions.platformDevice   = true;
2132*8975f5c5SAndroid Build Coastguard Worker #endif
2133*8975f5c5SAndroid Build Coastguard Worker 
2134*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_USE_GBM)
2135*8975f5c5SAndroid Build Coastguard Worker     extensions.platformGbmKHR = true;
2136*8975f5c5SAndroid Build Coastguard Worker #endif
2137*8975f5c5SAndroid Build Coastguard Worker 
2138*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_USE_WAYLAND)
2139*8975f5c5SAndroid Build Coastguard Worker     extensions.platformWaylandEXT = true;
2140*8975f5c5SAndroid Build Coastguard Worker #endif
2141*8975f5c5SAndroid Build Coastguard Worker 
2142*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_PLATFORM_LINUX) && (defined(ANGLE_ENABLE_OPENGL) || defined(ANGLE_ENABLE_VULKAN))
2143*8975f5c5SAndroid Build Coastguard Worker     extensions.platformSurfacelessMESA = true;
2144*8975f5c5SAndroid Build Coastguard Worker #endif
2145*8975f5c5SAndroid Build Coastguard Worker 
2146*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_ENABLE_D3D11)
2147*8975f5c5SAndroid Build Coastguard Worker     extensions.platformANGLED3D11ON12 = angle::IsWindows10OrLater();
2148*8975f5c5SAndroid Build Coastguard Worker     extensions.platformANGLED3DLUID   = true;
2149*8975f5c5SAndroid Build Coastguard Worker     extensions.platformANGLEDeviceId  = true;
2150*8975f5c5SAndroid Build Coastguard Worker #endif
2151*8975f5c5SAndroid Build Coastguard Worker 
2152*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_ENABLE_OPENGL)
2153*8975f5c5SAndroid Build Coastguard Worker     extensions.platformANGLEOpenGL = true;
2154*8975f5c5SAndroid Build Coastguard Worker #endif
2155*8975f5c5SAndroid Build Coastguard Worker 
2156*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_ENABLE_NULL)
2157*8975f5c5SAndroid Build Coastguard Worker     extensions.platformANGLENULL = true;
2158*8975f5c5SAndroid Build Coastguard Worker #endif
2159*8975f5c5SAndroid Build Coastguard Worker 
2160*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_ENABLE_WGPU)
2161*8975f5c5SAndroid Build Coastguard Worker     extensions.platformANGLEWebgpu = true;
2162*8975f5c5SAndroid Build Coastguard Worker #endif
2163*8975f5c5SAndroid Build Coastguard Worker 
2164*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_ENABLE_D3D11)
2165*8975f5c5SAndroid Build Coastguard Worker     extensions.deviceCreation          = true;
2166*8975f5c5SAndroid Build Coastguard Worker     extensions.deviceCreationD3D11     = true;
2167*8975f5c5SAndroid Build Coastguard Worker     extensions.experimentalPresentPath = true;
2168*8975f5c5SAndroid Build Coastguard Worker #endif
2169*8975f5c5SAndroid Build Coastguard Worker 
2170*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_ENABLE_VULKAN)
2171*8975f5c5SAndroid Build Coastguard Worker     extensions.platformANGLEVulkan   = true;
2172*8975f5c5SAndroid Build Coastguard Worker     extensions.platformANGLEDeviceId = true;
2173*8975f5c5SAndroid Build Coastguard Worker #endif
2174*8975f5c5SAndroid Build Coastguard Worker 
2175*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_ENABLE_SWIFTSHADER)
2176*8975f5c5SAndroid Build Coastguard Worker     extensions.platformANGLEDeviceTypeSwiftShader = true;
2177*8975f5c5SAndroid Build Coastguard Worker #endif
2178*8975f5c5SAndroid Build Coastguard Worker 
2179*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_ENABLE_METAL)
2180*8975f5c5SAndroid Build Coastguard Worker     extensions.platformANGLEMetal    = true;
2181*8975f5c5SAndroid Build Coastguard Worker     extensions.platformANGLEDeviceId = true;
2182*8975f5c5SAndroid Build Coastguard Worker #endif
2183*8975f5c5SAndroid Build Coastguard Worker 
2184*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_USE_X11)
2185*8975f5c5SAndroid Build Coastguard Worker     extensions.x11Visual = true;
2186*8975f5c5SAndroid Build Coastguard Worker #endif
2187*8975f5c5SAndroid Build Coastguard Worker 
2188*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_PLATFORM_LINUX)
2189*8975f5c5SAndroid Build Coastguard Worker     extensions.platformANGLEDeviceTypeEGLANGLE = true;
2190*8975f5c5SAndroid Build Coastguard Worker #endif
2191*8975f5c5SAndroid Build Coastguard Worker 
2192*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_ENABLE_CGL)
2193*8975f5c5SAndroid Build Coastguard Worker     extensions.platformANGLEDeviceContextVolatileCgl = true;
2194*8975f5c5SAndroid Build Coastguard Worker #endif
2195*8975f5c5SAndroid Build Coastguard Worker 
2196*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_ENABLE_METAL)
2197*8975f5c5SAndroid Build Coastguard Worker     extensions.displayPowerPreferenceANGLE = true;
2198*8975f5c5SAndroid Build Coastguard Worker #endif
2199*8975f5c5SAndroid Build Coastguard Worker 
2200*8975f5c5SAndroid Build Coastguard Worker     extensions.clientGetAllProcAddresses = true;
2201*8975f5c5SAndroid Build Coastguard Worker     extensions.debug                     = true;
2202*8975f5c5SAndroid Build Coastguard Worker     extensions.featureControlANGLE       = true;
2203*8975f5c5SAndroid Build Coastguard Worker     extensions.deviceQueryEXT            = true;
2204*8975f5c5SAndroid Build Coastguard Worker     extensions.noErrorANGLE              = true;
2205*8975f5c5SAndroid Build Coastguard Worker 
2206*8975f5c5SAndroid Build Coastguard Worker     return extensions;
2207*8975f5c5SAndroid Build Coastguard Worker }
2208*8975f5c5SAndroid Build Coastguard Worker 
2209*8975f5c5SAndroid Build Coastguard Worker template <typename T>
GenerateExtensionsString(const T & extensions)2210*8975f5c5SAndroid Build Coastguard Worker static std::string GenerateExtensionsString(const T &extensions)
2211*8975f5c5SAndroid Build Coastguard Worker {
2212*8975f5c5SAndroid Build Coastguard Worker     std::vector<std::string> extensionsVector = extensions.getStrings();
2213*8975f5c5SAndroid Build Coastguard Worker 
2214*8975f5c5SAndroid Build Coastguard Worker     std::ostringstream stream;
2215*8975f5c5SAndroid Build Coastguard Worker     std::copy(extensionsVector.begin(), extensionsVector.end(),
2216*8975f5c5SAndroid Build Coastguard Worker               std::ostream_iterator<std::string>(stream, " "));
2217*8975f5c5SAndroid Build Coastguard Worker     return stream.str();
2218*8975f5c5SAndroid Build Coastguard Worker }
2219*8975f5c5SAndroid Build Coastguard Worker 
2220*8975f5c5SAndroid Build Coastguard Worker // static
GetClientExtensions()2221*8975f5c5SAndroid Build Coastguard Worker const ClientExtensions &Display::GetClientExtensions()
2222*8975f5c5SAndroid Build Coastguard Worker {
2223*8975f5c5SAndroid Build Coastguard Worker     static const ClientExtensions clientExtensions = GenerateClientExtensions();
2224*8975f5c5SAndroid Build Coastguard Worker     return clientExtensions;
2225*8975f5c5SAndroid Build Coastguard Worker }
2226*8975f5c5SAndroid Build Coastguard Worker 
2227*8975f5c5SAndroid Build Coastguard Worker // static
GetClientExtensionString()2228*8975f5c5SAndroid Build Coastguard Worker const std::string &Display::GetClientExtensionString()
2229*8975f5c5SAndroid Build Coastguard Worker {
2230*8975f5c5SAndroid Build Coastguard Worker     static const angle::base::NoDestructor<std::string> clientExtensionsString(
2231*8975f5c5SAndroid Build Coastguard Worker         GenerateExtensionsString(GetClientExtensions()));
2232*8975f5c5SAndroid Build Coastguard Worker     return *clientExtensionsString;
2233*8975f5c5SAndroid Build Coastguard Worker }
2234*8975f5c5SAndroid Build Coastguard Worker 
initDisplayExtensions()2235*8975f5c5SAndroid Build Coastguard Worker void Display::initDisplayExtensions()
2236*8975f5c5SAndroid Build Coastguard Worker {
2237*8975f5c5SAndroid Build Coastguard Worker     mDisplayExtensions = mImplementation->getExtensions();
2238*8975f5c5SAndroid Build Coastguard Worker 
2239*8975f5c5SAndroid Build Coastguard Worker     // Some extensions are always available because they are implemented in the EGL layer.
2240*8975f5c5SAndroid Build Coastguard Worker     mDisplayExtensions.createContext        = true;
2241*8975f5c5SAndroid Build Coastguard Worker     mDisplayExtensions.createContextNoError = !mFrontendFeatures.forceGlErrorChecking.enabled;
2242*8975f5c5SAndroid Build Coastguard Worker     mDisplayExtensions.createContextWebGLCompatibility    = true;
2243*8975f5c5SAndroid Build Coastguard Worker     mDisplayExtensions.createContextBindGeneratesResource = true;
2244*8975f5c5SAndroid Build Coastguard Worker     mDisplayExtensions.createContextClientArrays          = true;
2245*8975f5c5SAndroid Build Coastguard Worker     mDisplayExtensions.pixelFormatFloat                   = true;
2246*8975f5c5SAndroid Build Coastguard Worker     mDisplayExtensions.reusableSyncKHR                    = true;
2247*8975f5c5SAndroid Build Coastguard Worker 
2248*8975f5c5SAndroid Build Coastguard Worker     // Force EGL_KHR_get_all_proc_addresses on.
2249*8975f5c5SAndroid Build Coastguard Worker     mDisplayExtensions.getAllProcAddresses = true;
2250*8975f5c5SAndroid Build Coastguard Worker 
2251*8975f5c5SAndroid Build Coastguard Worker     // Enable program cache control since it is not back-end dependent.
2252*8975f5c5SAndroid Build Coastguard Worker     mDisplayExtensions.programCacheControlANGLE = true;
2253*8975f5c5SAndroid Build Coastguard Worker 
2254*8975f5c5SAndroid Build Coastguard Worker     // Request extension is implemented in the ANGLE frontend
2255*8975f5c5SAndroid Build Coastguard Worker     mDisplayExtensions.createContextExtensionsEnabled = true;
2256*8975f5c5SAndroid Build Coastguard Worker 
2257*8975f5c5SAndroid Build Coastguard Worker     // Blob cache extension is provided by the ANGLE frontend
2258*8975f5c5SAndroid Build Coastguard Worker     mDisplayExtensions.blobCache = true;
2259*8975f5c5SAndroid Build Coastguard Worker 
2260*8975f5c5SAndroid Build Coastguard Worker     // The EGL_ANDROID_recordable extension is provided by the ANGLE frontend, and will always
2261*8975f5c5SAndroid Build Coastguard Worker     // say that ANativeWindow is not recordable.
2262*8975f5c5SAndroid Build Coastguard Worker     mDisplayExtensions.recordable = true;
2263*8975f5c5SAndroid Build Coastguard Worker 
2264*8975f5c5SAndroid Build Coastguard Worker     // All backends support specific context versions
2265*8975f5c5SAndroid Build Coastguard Worker     mDisplayExtensions.createContextBackwardsCompatible = true;
2266*8975f5c5SAndroid Build Coastguard Worker 
2267*8975f5c5SAndroid Build Coastguard Worker     mDisplayExtensionString = GenerateExtensionsString(mDisplayExtensions);
2268*8975f5c5SAndroid Build Coastguard Worker }
2269*8975f5c5SAndroid Build Coastguard Worker 
isValidNativeWindow(EGLNativeWindowType window) const2270*8975f5c5SAndroid Build Coastguard Worker bool Display::isValidNativeWindow(EGLNativeWindowType window) const
2271*8975f5c5SAndroid Build Coastguard Worker {
2272*8975f5c5SAndroid Build Coastguard Worker     return mImplementation->isValidNativeWindow(window);
2273*8975f5c5SAndroid Build Coastguard Worker }
2274*8975f5c5SAndroid Build Coastguard Worker 
validateClientBuffer(const Config * configuration,EGLenum buftype,EGLClientBuffer clientBuffer,const AttributeMap & attribs) const2275*8975f5c5SAndroid Build Coastguard Worker Error Display::validateClientBuffer(const Config *configuration,
2276*8975f5c5SAndroid Build Coastguard Worker                                     EGLenum buftype,
2277*8975f5c5SAndroid Build Coastguard Worker                                     EGLClientBuffer clientBuffer,
2278*8975f5c5SAndroid Build Coastguard Worker                                     const AttributeMap &attribs) const
2279*8975f5c5SAndroid Build Coastguard Worker {
2280*8975f5c5SAndroid Build Coastguard Worker     return mImplementation->validateClientBuffer(configuration, buftype, clientBuffer, attribs);
2281*8975f5c5SAndroid Build Coastguard Worker }
2282*8975f5c5SAndroid Build Coastguard Worker 
validateImageClientBuffer(const gl::Context * context,EGLenum target,EGLClientBuffer clientBuffer,const egl::AttributeMap & attribs) const2283*8975f5c5SAndroid Build Coastguard Worker Error Display::validateImageClientBuffer(const gl::Context *context,
2284*8975f5c5SAndroid Build Coastguard Worker                                          EGLenum target,
2285*8975f5c5SAndroid Build Coastguard Worker                                          EGLClientBuffer clientBuffer,
2286*8975f5c5SAndroid Build Coastguard Worker                                          const egl::AttributeMap &attribs) const
2287*8975f5c5SAndroid Build Coastguard Worker {
2288*8975f5c5SAndroid Build Coastguard Worker     return mImplementation->validateImageClientBuffer(context, target, clientBuffer, attribs);
2289*8975f5c5SAndroid Build Coastguard Worker }
2290*8975f5c5SAndroid Build Coastguard Worker 
valdiatePixmap(const Config * config,EGLNativePixmapType pixmap,const AttributeMap & attributes) const2291*8975f5c5SAndroid Build Coastguard Worker Error Display::valdiatePixmap(const Config *config,
2292*8975f5c5SAndroid Build Coastguard Worker                               EGLNativePixmapType pixmap,
2293*8975f5c5SAndroid Build Coastguard Worker                               const AttributeMap &attributes) const
2294*8975f5c5SAndroid Build Coastguard Worker {
2295*8975f5c5SAndroid Build Coastguard Worker     return mImplementation->validatePixmap(config, pixmap, attributes);
2296*8975f5c5SAndroid Build Coastguard Worker }
2297*8975f5c5SAndroid Build Coastguard Worker 
isValidDisplay(const egl::Display * display)2298*8975f5c5SAndroid Build Coastguard Worker bool Display::isValidDisplay(const egl::Display *display)
2299*8975f5c5SAndroid Build Coastguard Worker {
2300*8975f5c5SAndroid Build Coastguard Worker     {
2301*8975f5c5SAndroid Build Coastguard Worker         std::lock_guard<angle::SimpleMutex> lock(*ANGLEPlatformDisplayMapMutex());
2302*8975f5c5SAndroid Build Coastguard Worker         const ANGLEPlatformDisplayMap *anglePlatformDisplayMap = GetANGLEPlatformDisplayMap();
2303*8975f5c5SAndroid Build Coastguard Worker         for (const auto &displayPair : *anglePlatformDisplayMap)
2304*8975f5c5SAndroid Build Coastguard Worker         {
2305*8975f5c5SAndroid Build Coastguard Worker             if (displayPair.second == display)
2306*8975f5c5SAndroid Build Coastguard Worker             {
2307*8975f5c5SAndroid Build Coastguard Worker                 return true;
2308*8975f5c5SAndroid Build Coastguard Worker             }
2309*8975f5c5SAndroid Build Coastguard Worker         }
2310*8975f5c5SAndroid Build Coastguard Worker     }
2311*8975f5c5SAndroid Build Coastguard Worker 
2312*8975f5c5SAndroid Build Coastguard Worker     {
2313*8975f5c5SAndroid Build Coastguard Worker         std::lock_guard<angle::SimpleMutex> lock(*DevicePlatformDisplayMapMutex());
2314*8975f5c5SAndroid Build Coastguard Worker         const DevicePlatformDisplayMap *devicePlatformDisplayMap = GetDevicePlatformDisplayMap();
2315*8975f5c5SAndroid Build Coastguard Worker         for (const auto &displayPair : *devicePlatformDisplayMap)
2316*8975f5c5SAndroid Build Coastguard Worker         {
2317*8975f5c5SAndroid Build Coastguard Worker             if (displayPair.second == display)
2318*8975f5c5SAndroid Build Coastguard Worker             {
2319*8975f5c5SAndroid Build Coastguard Worker                 return true;
2320*8975f5c5SAndroid Build Coastguard Worker             }
2321*8975f5c5SAndroid Build Coastguard Worker         }
2322*8975f5c5SAndroid Build Coastguard Worker     }
2323*8975f5c5SAndroid Build Coastguard Worker 
2324*8975f5c5SAndroid Build Coastguard Worker     return false;
2325*8975f5c5SAndroid Build Coastguard Worker }
2326*8975f5c5SAndroid Build Coastguard Worker 
isValidNativeDisplay(EGLNativeDisplayType display)2327*8975f5c5SAndroid Build Coastguard Worker bool Display::isValidNativeDisplay(EGLNativeDisplayType display)
2328*8975f5c5SAndroid Build Coastguard Worker {
2329*8975f5c5SAndroid Build Coastguard Worker     // TODO(jmadill): handle this properly
2330*8975f5c5SAndroid Build Coastguard Worker     if (display == EGL_DEFAULT_DISPLAY)
2331*8975f5c5SAndroid Build Coastguard Worker     {
2332*8975f5c5SAndroid Build Coastguard Worker         return true;
2333*8975f5c5SAndroid Build Coastguard Worker     }
2334*8975f5c5SAndroid Build Coastguard Worker 
2335*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_PLATFORM_WINDOWS) && !defined(ANGLE_ENABLE_WINDOWS_UWP)
2336*8975f5c5SAndroid Build Coastguard Worker     if (display == EGL_SOFTWARE_DISPLAY_ANGLE || display == EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE ||
2337*8975f5c5SAndroid Build Coastguard Worker         display == EGL_D3D11_ONLY_DISPLAY_ANGLE)
2338*8975f5c5SAndroid Build Coastguard Worker     {
2339*8975f5c5SAndroid Build Coastguard Worker         return true;
2340*8975f5c5SAndroid Build Coastguard Worker     }
2341*8975f5c5SAndroid Build Coastguard Worker     return (WindowFromDC(display) != nullptr);
2342*8975f5c5SAndroid Build Coastguard Worker #else
2343*8975f5c5SAndroid Build Coastguard Worker     return true;
2344*8975f5c5SAndroid Build Coastguard Worker #endif
2345*8975f5c5SAndroid Build Coastguard Worker }
2346*8975f5c5SAndroid Build Coastguard Worker 
initVendorString()2347*8975f5c5SAndroid Build Coastguard Worker void Display::initVendorString()
2348*8975f5c5SAndroid Build Coastguard Worker {
2349*8975f5c5SAndroid Build Coastguard Worker     mVendorString                = "Google Inc.";
2350*8975f5c5SAndroid Build Coastguard Worker     std::string vendorStringImpl = mImplementation->getVendorString();
2351*8975f5c5SAndroid Build Coastguard Worker     if (!vendorStringImpl.empty())
2352*8975f5c5SAndroid Build Coastguard Worker     {
2353*8975f5c5SAndroid Build Coastguard Worker         mVendorString += " (" + vendorStringImpl + ")";
2354*8975f5c5SAndroid Build Coastguard Worker     }
2355*8975f5c5SAndroid Build Coastguard Worker }
2356*8975f5c5SAndroid Build Coastguard Worker 
initVersionString()2357*8975f5c5SAndroid Build Coastguard Worker void Display::initVersionString()
2358*8975f5c5SAndroid Build Coastguard Worker {
2359*8975f5c5SAndroid Build Coastguard Worker     mVersionString = mImplementation->getVersionString(true);
2360*8975f5c5SAndroid Build Coastguard Worker }
2361*8975f5c5SAndroid Build Coastguard Worker 
initClientAPIString()2362*8975f5c5SAndroid Build Coastguard Worker void Display::initClientAPIString()
2363*8975f5c5SAndroid Build Coastguard Worker {
2364*8975f5c5SAndroid Build Coastguard Worker     mClientAPIString = "OpenGL_ES";
2365*8975f5c5SAndroid Build Coastguard Worker }
2366*8975f5c5SAndroid Build Coastguard Worker 
initializeFrontendFeatures()2367*8975f5c5SAndroid Build Coastguard Worker void Display::initializeFrontendFeatures()
2368*8975f5c5SAndroid Build Coastguard Worker {
2369*8975f5c5SAndroid Build Coastguard Worker     // Enable on all Impls
2370*8975f5c5SAndroid Build Coastguard Worker     ANGLE_FEATURE_CONDITION(&mFrontendFeatures, loseContextOnOutOfMemory, true);
2371*8975f5c5SAndroid Build Coastguard Worker     ANGLE_FEATURE_CONDITION(&mFrontendFeatures, allowCompressedFormats, true);
2372*8975f5c5SAndroid Build Coastguard Worker 
2373*8975f5c5SAndroid Build Coastguard Worker     // Togglable until work on the extension is complete - anglebug.com/40096838.
2374*8975f5c5SAndroid Build Coastguard Worker     ANGLE_FEATURE_CONDITION(&mFrontendFeatures, emulatePixelLocalStorage, true);
2375*8975f5c5SAndroid Build Coastguard Worker 
2376*8975f5c5SAndroid Build Coastguard Worker     ANGLE_FEATURE_CONDITION(&mFrontendFeatures, forceMinimumMaxVertexAttributes, false);
2377*8975f5c5SAndroid Build Coastguard Worker 
2378*8975f5c5SAndroid Build Coastguard Worker     // Reject shaders with undefined behavior.  In the compiler, this only applies to WebGL.
2379*8975f5c5SAndroid Build Coastguard Worker     ANGLE_FEATURE_CONDITION(&mFrontendFeatures, rejectWebglShadersWithUndefinedBehavior, true);
2380*8975f5c5SAndroid Build Coastguard Worker 
2381*8975f5c5SAndroid Build Coastguard Worker     mImplementation->initializeFrontendFeatures(&mFrontendFeatures);
2382*8975f5c5SAndroid Build Coastguard Worker }
2383*8975f5c5SAndroid Build Coastguard Worker 
getExtensions() const2384*8975f5c5SAndroid Build Coastguard Worker const DisplayExtensions &Display::getExtensions() const
2385*8975f5c5SAndroid Build Coastguard Worker {
2386*8975f5c5SAndroid Build Coastguard Worker     return mDisplayExtensions;
2387*8975f5c5SAndroid Build Coastguard Worker }
2388*8975f5c5SAndroid Build Coastguard Worker 
getExtensionString() const2389*8975f5c5SAndroid Build Coastguard Worker const std::string &Display::getExtensionString() const
2390*8975f5c5SAndroid Build Coastguard Worker {
2391*8975f5c5SAndroid Build Coastguard Worker     return mDisplayExtensionString;
2392*8975f5c5SAndroid Build Coastguard Worker }
2393*8975f5c5SAndroid Build Coastguard Worker 
getVendorString() const2394*8975f5c5SAndroid Build Coastguard Worker const std::string &Display::getVendorString() const
2395*8975f5c5SAndroid Build Coastguard Worker {
2396*8975f5c5SAndroid Build Coastguard Worker     return mVendorString;
2397*8975f5c5SAndroid Build Coastguard Worker }
2398*8975f5c5SAndroid Build Coastguard Worker 
getVersionString() const2399*8975f5c5SAndroid Build Coastguard Worker const std::string &Display::getVersionString() const
2400*8975f5c5SAndroid Build Coastguard Worker {
2401*8975f5c5SAndroid Build Coastguard Worker     return mVersionString;
2402*8975f5c5SAndroid Build Coastguard Worker }
2403*8975f5c5SAndroid Build Coastguard Worker 
getClientAPIString() const2404*8975f5c5SAndroid Build Coastguard Worker const std::string &Display::getClientAPIString() const
2405*8975f5c5SAndroid Build Coastguard Worker {
2406*8975f5c5SAndroid Build Coastguard Worker     return mClientAPIString;
2407*8975f5c5SAndroid Build Coastguard Worker }
2408*8975f5c5SAndroid Build Coastguard Worker 
getBackendRendererDescription() const2409*8975f5c5SAndroid Build Coastguard Worker std::string Display::getBackendRendererDescription() const
2410*8975f5c5SAndroid Build Coastguard Worker {
2411*8975f5c5SAndroid Build Coastguard Worker     return mImplementation->getRendererDescription();
2412*8975f5c5SAndroid Build Coastguard Worker }
2413*8975f5c5SAndroid Build Coastguard Worker 
getBackendVendorString() const2414*8975f5c5SAndroid Build Coastguard Worker std::string Display::getBackendVendorString() const
2415*8975f5c5SAndroid Build Coastguard Worker {
2416*8975f5c5SAndroid Build Coastguard Worker     return mImplementation->getVendorString();
2417*8975f5c5SAndroid Build Coastguard Worker }
2418*8975f5c5SAndroid Build Coastguard Worker 
getBackendVersionString(bool includeFullVersion) const2419*8975f5c5SAndroid Build Coastguard Worker std::string Display::getBackendVersionString(bool includeFullVersion) const
2420*8975f5c5SAndroid Build Coastguard Worker {
2421*8975f5c5SAndroid Build Coastguard Worker     return mImplementation->getVersionString(includeFullVersion);
2422*8975f5c5SAndroid Build Coastguard Worker }
2423*8975f5c5SAndroid Build Coastguard Worker 
getDevice() const2424*8975f5c5SAndroid Build Coastguard Worker Device *Display::getDevice() const
2425*8975f5c5SAndroid Build Coastguard Worker {
2426*8975f5c5SAndroid Build Coastguard Worker     return mDevice;
2427*8975f5c5SAndroid Build Coastguard Worker }
2428*8975f5c5SAndroid Build Coastguard Worker 
getWGLSurface() const2429*8975f5c5SAndroid Build Coastguard Worker Surface *Display::getWGLSurface() const
2430*8975f5c5SAndroid Build Coastguard Worker {
2431*8975f5c5SAndroid Build Coastguard Worker     return mSurface;
2432*8975f5c5SAndroid Build Coastguard Worker }
2433*8975f5c5SAndroid Build Coastguard Worker 
getMaxSupportedESVersion() const2434*8975f5c5SAndroid Build Coastguard Worker gl::Version Display::getMaxSupportedESVersion() const
2435*8975f5c5SAndroid Build Coastguard Worker {
2436*8975f5c5SAndroid Build Coastguard Worker     return mImplementation->getMaxSupportedESVersion();
2437*8975f5c5SAndroid Build Coastguard Worker }
2438*8975f5c5SAndroid Build Coastguard Worker 
programCacheGetAttrib(EGLenum attrib) const2439*8975f5c5SAndroid Build Coastguard Worker EGLint Display::programCacheGetAttrib(EGLenum attrib) const
2440*8975f5c5SAndroid Build Coastguard Worker {
2441*8975f5c5SAndroid Build Coastguard Worker     switch (attrib)
2442*8975f5c5SAndroid Build Coastguard Worker     {
2443*8975f5c5SAndroid Build Coastguard Worker         case EGL_PROGRAM_CACHE_KEY_LENGTH_ANGLE:
2444*8975f5c5SAndroid Build Coastguard Worker             return static_cast<EGLint>(BlobCache::kKeyLength);
2445*8975f5c5SAndroid Build Coastguard Worker 
2446*8975f5c5SAndroid Build Coastguard Worker         case EGL_PROGRAM_CACHE_SIZE_ANGLE:
2447*8975f5c5SAndroid Build Coastguard Worker             return static_cast<EGLint>(mMemoryProgramCache.entryCount());
2448*8975f5c5SAndroid Build Coastguard Worker 
2449*8975f5c5SAndroid Build Coastguard Worker         default:
2450*8975f5c5SAndroid Build Coastguard Worker             UNREACHABLE();
2451*8975f5c5SAndroid Build Coastguard Worker             return 0;
2452*8975f5c5SAndroid Build Coastguard Worker     }
2453*8975f5c5SAndroid Build Coastguard Worker }
2454*8975f5c5SAndroid Build Coastguard Worker 
programCacheQuery(EGLint index,void * key,EGLint * keysize,void * binary,EGLint * binarysize)2455*8975f5c5SAndroid Build Coastguard Worker Error Display::programCacheQuery(EGLint index,
2456*8975f5c5SAndroid Build Coastguard Worker                                  void *key,
2457*8975f5c5SAndroid Build Coastguard Worker                                  EGLint *keysize,
2458*8975f5c5SAndroid Build Coastguard Worker                                  void *binary,
2459*8975f5c5SAndroid Build Coastguard Worker                                  EGLint *binarysize)
2460*8975f5c5SAndroid Build Coastguard Worker {
2461*8975f5c5SAndroid Build Coastguard Worker     ASSERT(index >= 0 && index < static_cast<EGLint>(mMemoryProgramCache.entryCount()));
2462*8975f5c5SAndroid Build Coastguard Worker 
2463*8975f5c5SAndroid Build Coastguard Worker     const BlobCache::Key *programHash = nullptr;
2464*8975f5c5SAndroid Build Coastguard Worker     BlobCache::Value programBinary;
2465*8975f5c5SAndroid Build Coastguard Worker     // TODO(jmadill): Make this thread-safe.
2466*8975f5c5SAndroid Build Coastguard Worker     bool result =
2467*8975f5c5SAndroid Build Coastguard Worker         mMemoryProgramCache.getAt(static_cast<size_t>(index), &programHash, &programBinary);
2468*8975f5c5SAndroid Build Coastguard Worker     if (!result)
2469*8975f5c5SAndroid Build Coastguard Worker     {
2470*8975f5c5SAndroid Build Coastguard Worker         return EglBadAccess() << "Program binary not accessible.";
2471*8975f5c5SAndroid Build Coastguard Worker     }
2472*8975f5c5SAndroid Build Coastguard Worker 
2473*8975f5c5SAndroid Build Coastguard Worker     ASSERT(keysize && binarysize);
2474*8975f5c5SAndroid Build Coastguard Worker 
2475*8975f5c5SAndroid Build Coastguard Worker     if (key)
2476*8975f5c5SAndroid Build Coastguard Worker     {
2477*8975f5c5SAndroid Build Coastguard Worker         ASSERT(*keysize == static_cast<EGLint>(BlobCache::kKeyLength));
2478*8975f5c5SAndroid Build Coastguard Worker         memcpy(key, programHash->data(), BlobCache::kKeyLength);
2479*8975f5c5SAndroid Build Coastguard Worker     }
2480*8975f5c5SAndroid Build Coastguard Worker 
2481*8975f5c5SAndroid Build Coastguard Worker     if (binary)
2482*8975f5c5SAndroid Build Coastguard Worker     {
2483*8975f5c5SAndroid Build Coastguard Worker         // Note: we check the size here instead of in the validation code, since we need to
2484*8975f5c5SAndroid Build Coastguard Worker         // access the cache as atomically as possible. It's possible that the cache contents
2485*8975f5c5SAndroid Build Coastguard Worker         // could change between the validation size check and the retrieval.
2486*8975f5c5SAndroid Build Coastguard Worker         if (programBinary.size() > static_cast<size_t>(*binarysize))
2487*8975f5c5SAndroid Build Coastguard Worker         {
2488*8975f5c5SAndroid Build Coastguard Worker             return EglBadAccess() << "Program binary too large or changed during access.";
2489*8975f5c5SAndroid Build Coastguard Worker         }
2490*8975f5c5SAndroid Build Coastguard Worker 
2491*8975f5c5SAndroid Build Coastguard Worker         memcpy(binary, programBinary.data(), programBinary.size());
2492*8975f5c5SAndroid Build Coastguard Worker     }
2493*8975f5c5SAndroid Build Coastguard Worker 
2494*8975f5c5SAndroid Build Coastguard Worker     *binarysize = static_cast<EGLint>(programBinary.size());
2495*8975f5c5SAndroid Build Coastguard Worker     *keysize    = static_cast<EGLint>(BlobCache::kKeyLength);
2496*8975f5c5SAndroid Build Coastguard Worker 
2497*8975f5c5SAndroid Build Coastguard Worker     return NoError();
2498*8975f5c5SAndroid Build Coastguard Worker }
2499*8975f5c5SAndroid Build Coastguard Worker 
programCachePopulate(const void * key,EGLint keysize,const void * binary,EGLint binarysize)2500*8975f5c5SAndroid Build Coastguard Worker Error Display::programCachePopulate(const void *key,
2501*8975f5c5SAndroid Build Coastguard Worker                                     EGLint keysize,
2502*8975f5c5SAndroid Build Coastguard Worker                                     const void *binary,
2503*8975f5c5SAndroid Build Coastguard Worker                                     EGLint binarysize)
2504*8975f5c5SAndroid Build Coastguard Worker {
2505*8975f5c5SAndroid Build Coastguard Worker     ASSERT(keysize == static_cast<EGLint>(BlobCache::kKeyLength));
2506*8975f5c5SAndroid Build Coastguard Worker 
2507*8975f5c5SAndroid Build Coastguard Worker     BlobCache::Key programHash;
2508*8975f5c5SAndroid Build Coastguard Worker     memcpy(programHash.data(), key, BlobCache::kKeyLength);
2509*8975f5c5SAndroid Build Coastguard Worker 
2510*8975f5c5SAndroid Build Coastguard Worker     if (!mMemoryProgramCache.putBinary(programHash, reinterpret_cast<const uint8_t *>(binary),
2511*8975f5c5SAndroid Build Coastguard Worker                                        static_cast<size_t>(binarysize)))
2512*8975f5c5SAndroid Build Coastguard Worker     {
2513*8975f5c5SAndroid Build Coastguard Worker         return EglBadAccess() << "Failed to copy program binary into the cache.";
2514*8975f5c5SAndroid Build Coastguard Worker     }
2515*8975f5c5SAndroid Build Coastguard Worker 
2516*8975f5c5SAndroid Build Coastguard Worker     return NoError();
2517*8975f5c5SAndroid Build Coastguard Worker }
2518*8975f5c5SAndroid Build Coastguard Worker 
programCacheResize(EGLint limit,EGLenum mode)2519*8975f5c5SAndroid Build Coastguard Worker EGLint Display::programCacheResize(EGLint limit, EGLenum mode)
2520*8975f5c5SAndroid Build Coastguard Worker {
2521*8975f5c5SAndroid Build Coastguard Worker     switch (mode)
2522*8975f5c5SAndroid Build Coastguard Worker     {
2523*8975f5c5SAndroid Build Coastguard Worker         case EGL_PROGRAM_CACHE_RESIZE_ANGLE:
2524*8975f5c5SAndroid Build Coastguard Worker         {
2525*8975f5c5SAndroid Build Coastguard Worker             size_t initialSize = mMemoryProgramCache.size();
2526*8975f5c5SAndroid Build Coastguard Worker             mMemoryProgramCache.resize(static_cast<size_t>(limit));
2527*8975f5c5SAndroid Build Coastguard Worker             return static_cast<EGLint>(initialSize);
2528*8975f5c5SAndroid Build Coastguard Worker         }
2529*8975f5c5SAndroid Build Coastguard Worker 
2530*8975f5c5SAndroid Build Coastguard Worker         case EGL_PROGRAM_CACHE_TRIM_ANGLE:
2531*8975f5c5SAndroid Build Coastguard Worker             return static_cast<EGLint>(mMemoryProgramCache.trim(static_cast<size_t>(limit)));
2532*8975f5c5SAndroid Build Coastguard Worker 
2533*8975f5c5SAndroid Build Coastguard Worker         default:
2534*8975f5c5SAndroid Build Coastguard Worker             UNREACHABLE();
2535*8975f5c5SAndroid Build Coastguard Worker             return 0;
2536*8975f5c5SAndroid Build Coastguard Worker     }
2537*8975f5c5SAndroid Build Coastguard Worker }
2538*8975f5c5SAndroid Build Coastguard Worker 
overrideFrontendFeatures(const std::vector<std::string> & featureNames,bool enabled)2539*8975f5c5SAndroid Build Coastguard Worker void Display::overrideFrontendFeatures(const std::vector<std::string> &featureNames, bool enabled)
2540*8975f5c5SAndroid Build Coastguard Worker {
2541*8975f5c5SAndroid Build Coastguard Worker     mFrontendFeatures.overrideFeatures(featureNames, enabled);
2542*8975f5c5SAndroid Build Coastguard Worker }
2543*8975f5c5SAndroid Build Coastguard Worker 
queryStringi(const EGLint name,const EGLint index)2544*8975f5c5SAndroid Build Coastguard Worker const char *Display::queryStringi(const EGLint name, const EGLint index)
2545*8975f5c5SAndroid Build Coastguard Worker {
2546*8975f5c5SAndroid Build Coastguard Worker     const char *result = nullptr;
2547*8975f5c5SAndroid Build Coastguard Worker     switch (name)
2548*8975f5c5SAndroid Build Coastguard Worker     {
2549*8975f5c5SAndroid Build Coastguard Worker         case EGL_FEATURE_NAME_ANGLE:
2550*8975f5c5SAndroid Build Coastguard Worker             result = mFeatures[index]->name;
2551*8975f5c5SAndroid Build Coastguard Worker             break;
2552*8975f5c5SAndroid Build Coastguard Worker         case EGL_FEATURE_CATEGORY_ANGLE:
2553*8975f5c5SAndroid Build Coastguard Worker             result = angle::FeatureCategoryToString(mFeatures[index]->category);
2554*8975f5c5SAndroid Build Coastguard Worker             break;
2555*8975f5c5SAndroid Build Coastguard Worker         case EGL_FEATURE_STATUS_ANGLE:
2556*8975f5c5SAndroid Build Coastguard Worker             result = angle::FeatureStatusToString(mFeatures[index]->enabled);
2557*8975f5c5SAndroid Build Coastguard Worker             break;
2558*8975f5c5SAndroid Build Coastguard Worker         default:
2559*8975f5c5SAndroid Build Coastguard Worker             UNREACHABLE();
2560*8975f5c5SAndroid Build Coastguard Worker             return nullptr;
2561*8975f5c5SAndroid Build Coastguard Worker     }
2562*8975f5c5SAndroid Build Coastguard Worker     return result;
2563*8975f5c5SAndroid Build Coastguard Worker }
2564*8975f5c5SAndroid Build Coastguard Worker 
queryAttrib(const EGLint attribute)2565*8975f5c5SAndroid Build Coastguard Worker EGLAttrib Display::queryAttrib(const EGLint attribute)
2566*8975f5c5SAndroid Build Coastguard Worker {
2567*8975f5c5SAndroid Build Coastguard Worker     EGLAttrib value = 0;
2568*8975f5c5SAndroid Build Coastguard Worker     switch (attribute)
2569*8975f5c5SAndroid Build Coastguard Worker     {
2570*8975f5c5SAndroid Build Coastguard Worker         case EGL_DEVICE_EXT:
2571*8975f5c5SAndroid Build Coastguard Worker             value = reinterpret_cast<EGLAttrib>(mDevice);
2572*8975f5c5SAndroid Build Coastguard Worker             break;
2573*8975f5c5SAndroid Build Coastguard Worker 
2574*8975f5c5SAndroid Build Coastguard Worker         case EGL_FEATURE_COUNT_ANGLE:
2575*8975f5c5SAndroid Build Coastguard Worker             value = mFeatures.size();
2576*8975f5c5SAndroid Build Coastguard Worker             break;
2577*8975f5c5SAndroid Build Coastguard Worker 
2578*8975f5c5SAndroid Build Coastguard Worker         default:
2579*8975f5c5SAndroid Build Coastguard Worker             UNREACHABLE();
2580*8975f5c5SAndroid Build Coastguard Worker     }
2581*8975f5c5SAndroid Build Coastguard Worker     return value;
2582*8975f5c5SAndroid Build Coastguard Worker }
2583*8975f5c5SAndroid Build Coastguard Worker 
requestScratchBuffer()2584*8975f5c5SAndroid Build Coastguard Worker angle::ScratchBuffer Display::requestScratchBuffer()
2585*8975f5c5SAndroid Build Coastguard Worker {
2586*8975f5c5SAndroid Build Coastguard Worker     return requestScratchBufferImpl(&mScratchBuffers);
2587*8975f5c5SAndroid Build Coastguard Worker }
2588*8975f5c5SAndroid Build Coastguard Worker 
returnScratchBuffer(angle::ScratchBuffer scratchBuffer)2589*8975f5c5SAndroid Build Coastguard Worker void Display::returnScratchBuffer(angle::ScratchBuffer scratchBuffer)
2590*8975f5c5SAndroid Build Coastguard Worker {
2591*8975f5c5SAndroid Build Coastguard Worker     returnScratchBufferImpl(std::move(scratchBuffer), &mScratchBuffers);
2592*8975f5c5SAndroid Build Coastguard Worker }
2593*8975f5c5SAndroid Build Coastguard Worker 
requestZeroFilledBuffer()2594*8975f5c5SAndroid Build Coastguard Worker angle::ScratchBuffer Display::requestZeroFilledBuffer()
2595*8975f5c5SAndroid Build Coastguard Worker {
2596*8975f5c5SAndroid Build Coastguard Worker     return requestScratchBufferImpl(&mZeroFilledBuffers);
2597*8975f5c5SAndroid Build Coastguard Worker }
2598*8975f5c5SAndroid Build Coastguard Worker 
returnZeroFilledBuffer(angle::ScratchBuffer zeroFilledBuffer)2599*8975f5c5SAndroid Build Coastguard Worker void Display::returnZeroFilledBuffer(angle::ScratchBuffer zeroFilledBuffer)
2600*8975f5c5SAndroid Build Coastguard Worker {
2601*8975f5c5SAndroid Build Coastguard Worker     returnScratchBufferImpl(std::move(zeroFilledBuffer), &mZeroFilledBuffers);
2602*8975f5c5SAndroid Build Coastguard Worker }
2603*8975f5c5SAndroid Build Coastguard Worker 
requestScratchBufferImpl(std::vector<angle::ScratchBuffer> * bufferVector)2604*8975f5c5SAndroid Build Coastguard Worker angle::ScratchBuffer Display::requestScratchBufferImpl(
2605*8975f5c5SAndroid Build Coastguard Worker     std::vector<angle::ScratchBuffer> *bufferVector)
2606*8975f5c5SAndroid Build Coastguard Worker {
2607*8975f5c5SAndroid Build Coastguard Worker     std::lock_guard<angle::SimpleMutex> lock(mScratchBufferMutex);
2608*8975f5c5SAndroid Build Coastguard Worker     if (!bufferVector->empty())
2609*8975f5c5SAndroid Build Coastguard Worker     {
2610*8975f5c5SAndroid Build Coastguard Worker         angle::ScratchBuffer buffer = std::move(bufferVector->back());
2611*8975f5c5SAndroid Build Coastguard Worker         bufferVector->pop_back();
2612*8975f5c5SAndroid Build Coastguard Worker         return buffer;
2613*8975f5c5SAndroid Build Coastguard Worker     }
2614*8975f5c5SAndroid Build Coastguard Worker 
2615*8975f5c5SAndroid Build Coastguard Worker     return angle::ScratchBuffer(kScratchBufferLifetime);
2616*8975f5c5SAndroid Build Coastguard Worker }
2617*8975f5c5SAndroid Build Coastguard Worker 
returnScratchBufferImpl(angle::ScratchBuffer scratchBuffer,std::vector<angle::ScratchBuffer> * bufferVector)2618*8975f5c5SAndroid Build Coastguard Worker void Display::returnScratchBufferImpl(angle::ScratchBuffer scratchBuffer,
2619*8975f5c5SAndroid Build Coastguard Worker                                       std::vector<angle::ScratchBuffer> *bufferVector)
2620*8975f5c5SAndroid Build Coastguard Worker {
2621*8975f5c5SAndroid Build Coastguard Worker     std::lock_guard<angle::SimpleMutex> lock(mScratchBufferMutex);
2622*8975f5c5SAndroid Build Coastguard Worker     bufferVector->push_back(std::move(scratchBuffer));
2623*8975f5c5SAndroid Build Coastguard Worker }
2624*8975f5c5SAndroid Build Coastguard Worker 
handleGPUSwitch()2625*8975f5c5SAndroid Build Coastguard Worker Error Display::handleGPUSwitch()
2626*8975f5c5SAndroid Build Coastguard Worker {
2627*8975f5c5SAndroid Build Coastguard Worker     ANGLE_TRY(mImplementation->handleGPUSwitch());
2628*8975f5c5SAndroid Build Coastguard Worker     initVendorString();
2629*8975f5c5SAndroid Build Coastguard Worker     return NoError();
2630*8975f5c5SAndroid Build Coastguard Worker }
2631*8975f5c5SAndroid Build Coastguard Worker 
forceGPUSwitch(EGLint gpuIDHigh,EGLint gpuIDLow)2632*8975f5c5SAndroid Build Coastguard Worker Error Display::forceGPUSwitch(EGLint gpuIDHigh, EGLint gpuIDLow)
2633*8975f5c5SAndroid Build Coastguard Worker {
2634*8975f5c5SAndroid Build Coastguard Worker     ANGLE_TRY(mImplementation->forceGPUSwitch(gpuIDHigh, gpuIDLow));
2635*8975f5c5SAndroid Build Coastguard Worker     initVendorString();
2636*8975f5c5SAndroid Build Coastguard Worker     return NoError();
2637*8975f5c5SAndroid Build Coastguard Worker }
2638*8975f5c5SAndroid Build Coastguard Worker 
waitUntilWorkScheduled()2639*8975f5c5SAndroid Build Coastguard Worker Error Display::waitUntilWorkScheduled()
2640*8975f5c5SAndroid Build Coastguard Worker {
2641*8975f5c5SAndroid Build Coastguard Worker     ANGLE_TRY(mImplementation->waitUntilWorkScheduled());
2642*8975f5c5SAndroid Build Coastguard Worker     return NoError();
2643*8975f5c5SAndroid Build Coastguard Worker }
2644*8975f5c5SAndroid Build Coastguard Worker 
supportsDmaBufFormat(EGLint format) const2645*8975f5c5SAndroid Build Coastguard Worker bool Display::supportsDmaBufFormat(EGLint format) const
2646*8975f5c5SAndroid Build Coastguard Worker {
2647*8975f5c5SAndroid Build Coastguard Worker     return mImplementation->supportsDmaBufFormat(format);
2648*8975f5c5SAndroid Build Coastguard Worker }
2649*8975f5c5SAndroid Build Coastguard Worker 
queryDmaBufFormats(EGLint max_formats,EGLint * formats,EGLint * num_formats)2650*8975f5c5SAndroid Build Coastguard Worker Error Display::queryDmaBufFormats(EGLint max_formats, EGLint *formats, EGLint *num_formats)
2651*8975f5c5SAndroid Build Coastguard Worker {
2652*8975f5c5SAndroid Build Coastguard Worker     ANGLE_TRY(mImplementation->queryDmaBufFormats(max_formats, formats, num_formats));
2653*8975f5c5SAndroid Build Coastguard Worker     return NoError();
2654*8975f5c5SAndroid Build Coastguard Worker }
2655*8975f5c5SAndroid Build Coastguard Worker 
queryDmaBufModifiers(EGLint format,EGLint max_modifiers,EGLuint64KHR * modifiers,EGLBoolean * external_only,EGLint * num_modifiers)2656*8975f5c5SAndroid Build Coastguard Worker Error Display::queryDmaBufModifiers(EGLint format,
2657*8975f5c5SAndroid Build Coastguard Worker                                     EGLint max_modifiers,
2658*8975f5c5SAndroid Build Coastguard Worker                                     EGLuint64KHR *modifiers,
2659*8975f5c5SAndroid Build Coastguard Worker                                     EGLBoolean *external_only,
2660*8975f5c5SAndroid Build Coastguard Worker                                     EGLint *num_modifiers)
2661*8975f5c5SAndroid Build Coastguard Worker {
2662*8975f5c5SAndroid Build Coastguard Worker     ANGLE_TRY(mImplementation->queryDmaBufModifiers(format, max_modifiers, modifiers, external_only,
2663*8975f5c5SAndroid Build Coastguard Worker                                                     num_modifiers));
2664*8975f5c5SAndroid Build Coastguard Worker     return NoError();
2665*8975f5c5SAndroid Build Coastguard Worker }
2666*8975f5c5SAndroid Build Coastguard Worker 
getImageLoadContext() const2667*8975f5c5SAndroid Build Coastguard Worker angle::ImageLoadContext Display::getImageLoadContext() const
2668*8975f5c5SAndroid Build Coastguard Worker {
2669*8975f5c5SAndroid Build Coastguard Worker     angle::ImageLoadContext imageLoadContext;
2670*8975f5c5SAndroid Build Coastguard Worker 
2671*8975f5c5SAndroid Build Coastguard Worker     imageLoadContext.singleThreadPool = mState.singleThreadPool;
2672*8975f5c5SAndroid Build Coastguard Worker     imageLoadContext.multiThreadPool  = mFrontendFeatures.singleThreadedTextureDecompression.enabled
2673*8975f5c5SAndroid Build Coastguard Worker                                             ? nullptr
2674*8975f5c5SAndroid Build Coastguard Worker                                             : mState.multiThreadPool;
2675*8975f5c5SAndroid Build Coastguard Worker 
2676*8975f5c5SAndroid Build Coastguard Worker     return imageLoadContext;
2677*8975f5c5SAndroid Build Coastguard Worker }
2678*8975f5c5SAndroid Build Coastguard Worker 
getContext(gl::ContextID contextID) const2679*8975f5c5SAndroid Build Coastguard Worker const gl::Context *Display::getContext(gl::ContextID contextID) const
2680*8975f5c5SAndroid Build Coastguard Worker {
2681*8975f5c5SAndroid Build Coastguard Worker     std::lock_guard<angle::SimpleMutex> lock(mState.contextMapMutex);
2682*8975f5c5SAndroid Build Coastguard Worker     auto iter = mState.contextMap.find(contextID.value);
2683*8975f5c5SAndroid Build Coastguard Worker     return iter != mState.contextMap.end() ? iter->second : nullptr;
2684*8975f5c5SAndroid Build Coastguard Worker }
2685*8975f5c5SAndroid Build Coastguard Worker 
getSurface(egl::SurfaceID surfaceID) const2686*8975f5c5SAndroid Build Coastguard Worker const egl::Surface *Display::getSurface(egl::SurfaceID surfaceID) const
2687*8975f5c5SAndroid Build Coastguard Worker {
2688*8975f5c5SAndroid Build Coastguard Worker     auto iter = mState.surfaceMap.find(surfaceID.value);
2689*8975f5c5SAndroid Build Coastguard Worker     return iter != mState.surfaceMap.end() ? iter->second : nullptr;
2690*8975f5c5SAndroid Build Coastguard Worker }
2691*8975f5c5SAndroid Build Coastguard Worker 
getImage(egl::ImageID imageID) const2692*8975f5c5SAndroid Build Coastguard Worker const egl::Image *Display::getImage(egl::ImageID imageID) const
2693*8975f5c5SAndroid Build Coastguard Worker {
2694*8975f5c5SAndroid Build Coastguard Worker     auto iter = mImageMap.find(imageID.value);
2695*8975f5c5SAndroid Build Coastguard Worker     return iter != mImageMap.end() ? iter->second : nullptr;
2696*8975f5c5SAndroid Build Coastguard Worker }
2697*8975f5c5SAndroid Build Coastguard Worker 
getSync(egl::SyncID syncID) const2698*8975f5c5SAndroid Build Coastguard Worker const egl::Sync *Display::getSync(egl::SyncID syncID) const
2699*8975f5c5SAndroid Build Coastguard Worker {
2700*8975f5c5SAndroid Build Coastguard Worker     auto iter = mSyncMap.find(syncID.value);
2701*8975f5c5SAndroid Build Coastguard Worker     return iter != mSyncMap.end() ? iter->second.get() : nullptr;
2702*8975f5c5SAndroid Build Coastguard Worker }
2703*8975f5c5SAndroid Build Coastguard Worker 
getContext(gl::ContextID contextID)2704*8975f5c5SAndroid Build Coastguard Worker gl::Context *Display::getContext(gl::ContextID contextID)
2705*8975f5c5SAndroid Build Coastguard Worker {
2706*8975f5c5SAndroid Build Coastguard Worker     std::lock_guard<angle::SimpleMutex> lock(mState.contextMapMutex);
2707*8975f5c5SAndroid Build Coastguard Worker     auto iter = mState.contextMap.find(contextID.value);
2708*8975f5c5SAndroid Build Coastguard Worker     return iter != mState.contextMap.end() ? iter->second : nullptr;
2709*8975f5c5SAndroid Build Coastguard Worker }
2710*8975f5c5SAndroid Build Coastguard Worker 
getSurface(egl::SurfaceID surfaceID)2711*8975f5c5SAndroid Build Coastguard Worker egl::Surface *Display::getSurface(egl::SurfaceID surfaceID)
2712*8975f5c5SAndroid Build Coastguard Worker {
2713*8975f5c5SAndroid Build Coastguard Worker     auto iter = mState.surfaceMap.find(surfaceID.value);
2714*8975f5c5SAndroid Build Coastguard Worker     return iter != mState.surfaceMap.end() ? iter->second : nullptr;
2715*8975f5c5SAndroid Build Coastguard Worker }
2716*8975f5c5SAndroid Build Coastguard Worker 
getImage(egl::ImageID imageID)2717*8975f5c5SAndroid Build Coastguard Worker egl::Image *Display::getImage(egl::ImageID imageID)
2718*8975f5c5SAndroid Build Coastguard Worker {
2719*8975f5c5SAndroid Build Coastguard Worker     auto iter = mImageMap.find(imageID.value);
2720*8975f5c5SAndroid Build Coastguard Worker     return iter != mImageMap.end() ? iter->second : nullptr;
2721*8975f5c5SAndroid Build Coastguard Worker }
2722*8975f5c5SAndroid Build Coastguard Worker 
getSync(egl::SyncID syncID)2723*8975f5c5SAndroid Build Coastguard Worker egl::Sync *Display::getSync(egl::SyncID syncID)
2724*8975f5c5SAndroid Build Coastguard Worker {
2725*8975f5c5SAndroid Build Coastguard Worker     auto iter = mSyncMap.find(syncID.value);
2726*8975f5c5SAndroid Build Coastguard Worker     return iter != mSyncMap.end() ? iter->second.get() : nullptr;
2727*8975f5c5SAndroid Build Coastguard Worker }
2728*8975f5c5SAndroid Build Coastguard Worker 
2729*8975f5c5SAndroid Build Coastguard Worker // static
InitTLS()2730*8975f5c5SAndroid Build Coastguard Worker void Display::InitTLS()
2731*8975f5c5SAndroid Build Coastguard Worker {
2732*8975f5c5SAndroid Build Coastguard Worker     TLSData *tlsData = new TLSData;
2733*8975f5c5SAndroid Build Coastguard Worker 
2734*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_PLATFORM_APPLE)
2735*8975f5c5SAndroid Build Coastguard Worker     SetDisplayTLS(tlsData);
2736*8975f5c5SAndroid Build Coastguard Worker #else
2737*8975f5c5SAndroid Build Coastguard Worker     gDisplayTLS = tlsData;
2738*8975f5c5SAndroid Build Coastguard Worker #endif
2739*8975f5c5SAndroid Build Coastguard Worker }
2740*8975f5c5SAndroid Build Coastguard Worker 
2741*8975f5c5SAndroid Build Coastguard Worker // static
GetCurrentThreadUnlockedTailCall()2742*8975f5c5SAndroid Build Coastguard Worker angle::UnlockedTailCall *Display::GetCurrentThreadUnlockedTailCall()
2743*8975f5c5SAndroid Build Coastguard Worker {
2744*8975f5c5SAndroid Build Coastguard Worker     return &GetDisplayTLS()->unlockedTailCall;
2745*8975f5c5SAndroid Build Coastguard Worker }
2746*8975f5c5SAndroid Build Coastguard Worker 
2747*8975f5c5SAndroid Build Coastguard Worker // static
GetCurrentThreadErrorScratchSpace()2748*8975f5c5SAndroid Build Coastguard Worker Error *Display::GetCurrentThreadErrorScratchSpace()
2749*8975f5c5SAndroid Build Coastguard Worker {
2750*8975f5c5SAndroid Build Coastguard Worker     return &GetDisplayTLS()->errorScratchSpace;
2751*8975f5c5SAndroid Build Coastguard Worker }
2752*8975f5c5SAndroid Build Coastguard Worker }  // namespace egl
2753