xref: /aosp_15_r20/external/angle/util/EGLWindow.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2013 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 #include "util/EGLWindow.h"
8*8975f5c5SAndroid Build Coastguard Worker 
9*8975f5c5SAndroid Build Coastguard Worker #include <cassert>
10*8975f5c5SAndroid Build Coastguard Worker #include <iostream>
11*8975f5c5SAndroid Build Coastguard Worker #include <vector>
12*8975f5c5SAndroid Build Coastguard Worker 
13*8975f5c5SAndroid Build Coastguard Worker #include <string.h>
14*8975f5c5SAndroid Build Coastguard Worker 
15*8975f5c5SAndroid Build Coastguard Worker #include "common/hash_containers.h"
16*8975f5c5SAndroid Build Coastguard Worker #include "common/system_utils.h"
17*8975f5c5SAndroid Build Coastguard Worker #include "platform/Feature.h"
18*8975f5c5SAndroid Build Coastguard Worker #include "platform/PlatformMethods.h"
19*8975f5c5SAndroid Build Coastguard Worker #include "util/OSWindow.h"
20*8975f5c5SAndroid Build Coastguard Worker 
21*8975f5c5SAndroid Build Coastguard Worker namespace
22*8975f5c5SAndroid Build Coastguard Worker {
23*8975f5c5SAndroid Build Coastguard Worker constexpr EGLint kDefaultSwapInterval = 1;
24*8975f5c5SAndroid Build Coastguard Worker }  // anonymous namespace
25*8975f5c5SAndroid Build Coastguard Worker 
26*8975f5c5SAndroid Build Coastguard Worker // ConfigParameters implementation.
ConfigParameters()27*8975f5c5SAndroid Build Coastguard Worker ConfigParameters::ConfigParameters()
28*8975f5c5SAndroid Build Coastguard Worker     : redBits(-1),
29*8975f5c5SAndroid Build Coastguard Worker       greenBits(-1),
30*8975f5c5SAndroid Build Coastguard Worker       blueBits(-1),
31*8975f5c5SAndroid Build Coastguard Worker       alphaBits(-1),
32*8975f5c5SAndroid Build Coastguard Worker       depthBits(-1),
33*8975f5c5SAndroid Build Coastguard Worker       stencilBits(-1),
34*8975f5c5SAndroid Build Coastguard Worker       componentType(EGL_COLOR_COMPONENT_TYPE_FIXED_EXT),
35*8975f5c5SAndroid Build Coastguard Worker       multisample(false),
36*8975f5c5SAndroid Build Coastguard Worker       debug(false),
37*8975f5c5SAndroid Build Coastguard Worker       noError(false),
38*8975f5c5SAndroid Build Coastguard Worker       bindGeneratesResource(true),
39*8975f5c5SAndroid Build Coastguard Worker       clientArraysEnabled(true),
40*8975f5c5SAndroid Build Coastguard Worker       robustAccess(false),
41*8975f5c5SAndroid Build Coastguard Worker       mutableRenderBuffer(false),
42*8975f5c5SAndroid Build Coastguard Worker       samples(-1),
43*8975f5c5SAndroid Build Coastguard Worker       resetStrategy(EGL_NO_RESET_NOTIFICATION_EXT),
44*8975f5c5SAndroid Build Coastguard Worker       colorSpace(EGL_COLORSPACE_LINEAR),
45*8975f5c5SAndroid Build Coastguard Worker       swapInterval(kDefaultSwapInterval)
46*8975f5c5SAndroid Build Coastguard Worker {}
47*8975f5c5SAndroid Build Coastguard Worker 
48*8975f5c5SAndroid Build Coastguard Worker ConfigParameters::~ConfigParameters() = default;
49*8975f5c5SAndroid Build Coastguard Worker 
reset()50*8975f5c5SAndroid Build Coastguard Worker void ConfigParameters::reset()
51*8975f5c5SAndroid Build Coastguard Worker {
52*8975f5c5SAndroid Build Coastguard Worker     *this = ConfigParameters();
53*8975f5c5SAndroid Build Coastguard Worker }
54*8975f5c5SAndroid Build Coastguard Worker 
55*8975f5c5SAndroid Build Coastguard Worker // GLWindowBase implementation.
GLWindowBase(GLint glesMajorVersion,EGLint glesMinorVersion)56*8975f5c5SAndroid Build Coastguard Worker GLWindowBase::GLWindowBase(GLint glesMajorVersion, EGLint glesMinorVersion)
57*8975f5c5SAndroid Build Coastguard Worker     : mClientMajorVersion(glesMajorVersion), mClientMinorVersion(glesMinorVersion)
58*8975f5c5SAndroid Build Coastguard Worker {}
59*8975f5c5SAndroid Build Coastguard Worker 
60*8975f5c5SAndroid Build Coastguard Worker GLWindowBase::~GLWindowBase() = default;
61*8975f5c5SAndroid Build Coastguard Worker 
62*8975f5c5SAndroid Build Coastguard Worker // EGLWindow implementation.
EGLWindow(EGLint glesMajorVersion,EGLint glesMinorVersion)63*8975f5c5SAndroid Build Coastguard Worker EGLWindow::EGLWindow(EGLint glesMajorVersion, EGLint glesMinorVersion)
64*8975f5c5SAndroid Build Coastguard Worker     : GLWindowBase(glesMajorVersion, glesMinorVersion),
65*8975f5c5SAndroid Build Coastguard Worker       mConfig(0),
66*8975f5c5SAndroid Build Coastguard Worker       mDisplay(EGL_NO_DISPLAY),
67*8975f5c5SAndroid Build Coastguard Worker       mSurface(EGL_NO_SURFACE),
68*8975f5c5SAndroid Build Coastguard Worker       mContext(EGL_NO_CONTEXT),
69*8975f5c5SAndroid Build Coastguard Worker       mEGLMajorVersion(0),
70*8975f5c5SAndroid Build Coastguard Worker       mEGLMinorVersion(0)
71*8975f5c5SAndroid Build Coastguard Worker {
72*8975f5c5SAndroid Build Coastguard Worker     std::fill(mFeatures.begin(), mFeatures.end(), ANGLEFeatureStatus::Unknown);
73*8975f5c5SAndroid Build Coastguard Worker }
74*8975f5c5SAndroid Build Coastguard Worker 
~EGLWindow()75*8975f5c5SAndroid Build Coastguard Worker EGLWindow::~EGLWindow()
76*8975f5c5SAndroid Build Coastguard Worker {
77*8975f5c5SAndroid Build Coastguard Worker     destroyGL();
78*8975f5c5SAndroid Build Coastguard Worker }
79*8975f5c5SAndroid Build Coastguard Worker 
swap()80*8975f5c5SAndroid Build Coastguard Worker void EGLWindow::swap()
81*8975f5c5SAndroid Build Coastguard Worker {
82*8975f5c5SAndroid Build Coastguard Worker     eglSwapBuffers(mDisplay, mSurface);
83*8975f5c5SAndroid Build Coastguard Worker }
84*8975f5c5SAndroid Build Coastguard Worker 
getConfig() const85*8975f5c5SAndroid Build Coastguard Worker EGLConfig EGLWindow::getConfig() const
86*8975f5c5SAndroid Build Coastguard Worker {
87*8975f5c5SAndroid Build Coastguard Worker     return mConfig;
88*8975f5c5SAndroid Build Coastguard Worker }
89*8975f5c5SAndroid Build Coastguard Worker 
getDisplay() const90*8975f5c5SAndroid Build Coastguard Worker EGLDisplay EGLWindow::getDisplay() const
91*8975f5c5SAndroid Build Coastguard Worker {
92*8975f5c5SAndroid Build Coastguard Worker     return mDisplay;
93*8975f5c5SAndroid Build Coastguard Worker }
94*8975f5c5SAndroid Build Coastguard Worker 
getSurface() const95*8975f5c5SAndroid Build Coastguard Worker EGLSurface EGLWindow::getSurface() const
96*8975f5c5SAndroid Build Coastguard Worker {
97*8975f5c5SAndroid Build Coastguard Worker     return mSurface;
98*8975f5c5SAndroid Build Coastguard Worker }
99*8975f5c5SAndroid Build Coastguard Worker 
getContext() const100*8975f5c5SAndroid Build Coastguard Worker EGLContext EGLWindow::getContext() const
101*8975f5c5SAndroid Build Coastguard Worker {
102*8975f5c5SAndroid Build Coastguard Worker     return mContext;
103*8975f5c5SAndroid Build Coastguard Worker }
104*8975f5c5SAndroid Build Coastguard Worker 
isContextVersion(EGLint glesMajorVersion,EGLint glesMinorVersion) const105*8975f5c5SAndroid Build Coastguard Worker bool EGLWindow::isContextVersion(EGLint glesMajorVersion, EGLint glesMinorVersion) const
106*8975f5c5SAndroid Build Coastguard Worker {
107*8975f5c5SAndroid Build Coastguard Worker     return mClientMajorVersion == glesMajorVersion && mClientMinorVersion == glesMinorVersion;
108*8975f5c5SAndroid Build Coastguard Worker }
109*8975f5c5SAndroid Build Coastguard Worker 
initializeGLWithResult(OSWindow * osWindow,angle::Library * glWindowingLibrary,angle::GLESDriverType driverType,const EGLPlatformParameters & platformParams,const ConfigParameters & configParams)110*8975f5c5SAndroid Build Coastguard Worker GLWindowResult EGLWindow::initializeGLWithResult(OSWindow *osWindow,
111*8975f5c5SAndroid Build Coastguard Worker                                                  angle::Library *glWindowingLibrary,
112*8975f5c5SAndroid Build Coastguard Worker                                                  angle::GLESDriverType driverType,
113*8975f5c5SAndroid Build Coastguard Worker                                                  const EGLPlatformParameters &platformParams,
114*8975f5c5SAndroid Build Coastguard Worker                                                  const ConfigParameters &configParams)
115*8975f5c5SAndroid Build Coastguard Worker {
116*8975f5c5SAndroid Build Coastguard Worker     if (!initializeDisplay(osWindow, glWindowingLibrary, driverType, platformParams))
117*8975f5c5SAndroid Build Coastguard Worker     {
118*8975f5c5SAndroid Build Coastguard Worker         return GLWindowResult::Error;
119*8975f5c5SAndroid Build Coastguard Worker     }
120*8975f5c5SAndroid Build Coastguard Worker     GLWindowResult res = initializeSurface(osWindow, glWindowingLibrary, configParams);
121*8975f5c5SAndroid Build Coastguard Worker     if (res != GLWindowResult::NoError)
122*8975f5c5SAndroid Build Coastguard Worker     {
123*8975f5c5SAndroid Build Coastguard Worker         return res;
124*8975f5c5SAndroid Build Coastguard Worker     }
125*8975f5c5SAndroid Build Coastguard Worker     if (!initializeContext())
126*8975f5c5SAndroid Build Coastguard Worker     {
127*8975f5c5SAndroid Build Coastguard Worker         return GLWindowResult::Error;
128*8975f5c5SAndroid Build Coastguard Worker     }
129*8975f5c5SAndroid Build Coastguard Worker     return GLWindowResult::NoError;
130*8975f5c5SAndroid Build Coastguard Worker }
131*8975f5c5SAndroid Build Coastguard Worker 
initializeGL(OSWindow * osWindow,angle::Library * glWindowingLibrary,angle::GLESDriverType driverType,const EGLPlatformParameters & platformParams,const ConfigParameters & configParams)132*8975f5c5SAndroid Build Coastguard Worker bool EGLWindow::initializeGL(OSWindow *osWindow,
133*8975f5c5SAndroid Build Coastguard Worker                              angle::Library *glWindowingLibrary,
134*8975f5c5SAndroid Build Coastguard Worker                              angle::GLESDriverType driverType,
135*8975f5c5SAndroid Build Coastguard Worker                              const EGLPlatformParameters &platformParams,
136*8975f5c5SAndroid Build Coastguard Worker                              const ConfigParameters &configParams)
137*8975f5c5SAndroid Build Coastguard Worker {
138*8975f5c5SAndroid Build Coastguard Worker     return initializeGLWithResult(osWindow, glWindowingLibrary, driverType, platformParams,
139*8975f5c5SAndroid Build Coastguard Worker                                   configParams) == GLWindowResult::NoError;
140*8975f5c5SAndroid Build Coastguard Worker }
141*8975f5c5SAndroid Build Coastguard Worker 
initializeDisplay(OSWindow * osWindow,angle::Library * glWindowingLibrary,angle::GLESDriverType driverType,const EGLPlatformParameters & params)142*8975f5c5SAndroid Build Coastguard Worker bool EGLWindow::initializeDisplay(OSWindow *osWindow,
143*8975f5c5SAndroid Build Coastguard Worker                                   angle::Library *glWindowingLibrary,
144*8975f5c5SAndroid Build Coastguard Worker                                   angle::GLESDriverType driverType,
145*8975f5c5SAndroid Build Coastguard Worker                                   const EGLPlatformParameters &params)
146*8975f5c5SAndroid Build Coastguard Worker {
147*8975f5c5SAndroid Build Coastguard Worker     if (driverType == angle::GLESDriverType::ZinkEGL)
148*8975f5c5SAndroid Build Coastguard Worker     {
149*8975f5c5SAndroid Build Coastguard Worker         std::stringstream driDirStream;
150*8975f5c5SAndroid Build Coastguard Worker         char s = angle::GetPathSeparator();
151*8975f5c5SAndroid Build Coastguard Worker         driDirStream << angle::GetModuleDirectory() << "mesa" << s << "src" << s << "gallium" << s
152*8975f5c5SAndroid Build Coastguard Worker                      << "targets" << s << "dri";
153*8975f5c5SAndroid Build Coastguard Worker 
154*8975f5c5SAndroid Build Coastguard Worker         std::string driDir = driDirStream.str();
155*8975f5c5SAndroid Build Coastguard Worker 
156*8975f5c5SAndroid Build Coastguard Worker         angle::SetEnvironmentVar("MESA_LOADER_DRIVER_OVERRIDE", "zink");
157*8975f5c5SAndroid Build Coastguard Worker         angle::SetEnvironmentVar("LIBGL_DRIVERS_PATH", driDir.c_str());
158*8975f5c5SAndroid Build Coastguard Worker     }
159*8975f5c5SAndroid Build Coastguard Worker 
160*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_USE_UTIL_LOADER)
161*8975f5c5SAndroid Build Coastguard Worker     PFNEGLGETPROCADDRESSPROC getProcAddress;
162*8975f5c5SAndroid Build Coastguard Worker     glWindowingLibrary->getAs("eglGetProcAddress", &getProcAddress);
163*8975f5c5SAndroid Build Coastguard Worker     if (!getProcAddress)
164*8975f5c5SAndroid Build Coastguard Worker     {
165*8975f5c5SAndroid Build Coastguard Worker         fprintf(stderr, "Cannot load eglGetProcAddress\n");
166*8975f5c5SAndroid Build Coastguard Worker         return false;
167*8975f5c5SAndroid Build Coastguard Worker     }
168*8975f5c5SAndroid Build Coastguard Worker 
169*8975f5c5SAndroid Build Coastguard Worker     // Likely we will need to use a fallback to Library::getAs on non-ANGLE platforms.
170*8975f5c5SAndroid Build Coastguard Worker     LoadUtilEGL(getProcAddress);
171*8975f5c5SAndroid Build Coastguard Worker #endif  // defined(ANGLE_USE_UTIL_LOADER)
172*8975f5c5SAndroid Build Coastguard Worker 
173*8975f5c5SAndroid Build Coastguard Worker     // EGL_NO_DISPLAY + EGL_EXTENSIONS returns NULL before Android 10
174*8975f5c5SAndroid Build Coastguard Worker     const char *extensionString =
175*8975f5c5SAndroid Build Coastguard Worker         static_cast<const char *>(eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS));
176*8975f5c5SAndroid Build Coastguard Worker     if (!extensionString)
177*8975f5c5SAndroid Build Coastguard Worker     {
178*8975f5c5SAndroid Build Coastguard Worker         // fallback to an empty string for strstr
179*8975f5c5SAndroid Build Coastguard Worker         extensionString = "";
180*8975f5c5SAndroid Build Coastguard Worker     }
181*8975f5c5SAndroid Build Coastguard Worker 
182*8975f5c5SAndroid Build Coastguard Worker     std::vector<EGLAttrib> displayAttributes;
183*8975f5c5SAndroid Build Coastguard Worker     displayAttributes.push_back(EGL_PLATFORM_ANGLE_TYPE_ANGLE);
184*8975f5c5SAndroid Build Coastguard Worker     displayAttributes.push_back(params.renderer);
185*8975f5c5SAndroid Build Coastguard Worker     displayAttributes.push_back(EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE);
186*8975f5c5SAndroid Build Coastguard Worker     displayAttributes.push_back(params.majorVersion);
187*8975f5c5SAndroid Build Coastguard Worker     displayAttributes.push_back(EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE);
188*8975f5c5SAndroid Build Coastguard Worker     displayAttributes.push_back(params.minorVersion);
189*8975f5c5SAndroid Build Coastguard Worker 
190*8975f5c5SAndroid Build Coastguard Worker     if (params.deviceType != EGL_DONT_CARE)
191*8975f5c5SAndroid Build Coastguard Worker     {
192*8975f5c5SAndroid Build Coastguard Worker         displayAttributes.push_back(EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE);
193*8975f5c5SAndroid Build Coastguard Worker         displayAttributes.push_back(params.deviceType);
194*8975f5c5SAndroid Build Coastguard Worker     }
195*8975f5c5SAndroid Build Coastguard Worker 
196*8975f5c5SAndroid Build Coastguard Worker     if (params.presentPath != EGL_DONT_CARE)
197*8975f5c5SAndroid Build Coastguard Worker     {
198*8975f5c5SAndroid Build Coastguard Worker         if (strstr(extensionString, "EGL_ANGLE_experimental_present_path") == nullptr)
199*8975f5c5SAndroid Build Coastguard Worker         {
200*8975f5c5SAndroid Build Coastguard Worker             destroyGL();
201*8975f5c5SAndroid Build Coastguard Worker             return false;
202*8975f5c5SAndroid Build Coastguard Worker         }
203*8975f5c5SAndroid Build Coastguard Worker 
204*8975f5c5SAndroid Build Coastguard Worker         displayAttributes.push_back(EGL_EXPERIMENTAL_PRESENT_PATH_ANGLE);
205*8975f5c5SAndroid Build Coastguard Worker         displayAttributes.push_back(params.presentPath);
206*8975f5c5SAndroid Build Coastguard Worker     }
207*8975f5c5SAndroid Build Coastguard Worker 
208*8975f5c5SAndroid Build Coastguard Worker     // Set debug layer settings if requested.
209*8975f5c5SAndroid Build Coastguard Worker     if (params.debugLayersEnabled != EGL_DONT_CARE)
210*8975f5c5SAndroid Build Coastguard Worker     {
211*8975f5c5SAndroid Build Coastguard Worker         displayAttributes.push_back(EGL_PLATFORM_ANGLE_DEBUG_LAYERS_ENABLED_ANGLE);
212*8975f5c5SAndroid Build Coastguard Worker         displayAttributes.push_back(params.debugLayersEnabled);
213*8975f5c5SAndroid Build Coastguard Worker     }
214*8975f5c5SAndroid Build Coastguard Worker 
215*8975f5c5SAndroid Build Coastguard Worker     if (params.platformMethods)
216*8975f5c5SAndroid Build Coastguard Worker     {
217*8975f5c5SAndroid Build Coastguard Worker         static_assert(sizeof(EGLAttrib) == sizeof(params.platformMethods),
218*8975f5c5SAndroid Build Coastguard Worker                       "Unexpected pointer size");
219*8975f5c5SAndroid Build Coastguard Worker         displayAttributes.push_back(EGL_PLATFORM_ANGLE_PLATFORM_METHODS_ANGLEX);
220*8975f5c5SAndroid Build Coastguard Worker         displayAttributes.push_back(reinterpret_cast<EGLAttrib>(params.platformMethods));
221*8975f5c5SAndroid Build Coastguard Worker     }
222*8975f5c5SAndroid Build Coastguard Worker 
223*8975f5c5SAndroid Build Coastguard Worker     if (params.displayPowerPreference != EGL_DONT_CARE)
224*8975f5c5SAndroid Build Coastguard Worker     {
225*8975f5c5SAndroid Build Coastguard Worker         displayAttributes.push_back(EGL_POWER_PREFERENCE_ANGLE);
226*8975f5c5SAndroid Build Coastguard Worker         displayAttributes.push_back(params.displayPowerPreference);
227*8975f5c5SAndroid Build Coastguard Worker     }
228*8975f5c5SAndroid Build Coastguard Worker 
229*8975f5c5SAndroid Build Coastguard Worker     std::vector<const char *> enabledFeatureOverrides;
230*8975f5c5SAndroid Build Coastguard Worker     std::vector<const char *> disabledFeatureOverrides;
231*8975f5c5SAndroid Build Coastguard Worker 
232*8975f5c5SAndroid Build Coastguard Worker     for (angle::Feature feature : params.enabledFeatureOverrides)
233*8975f5c5SAndroid Build Coastguard Worker     {
234*8975f5c5SAndroid Build Coastguard Worker         enabledFeatureOverrides.push_back(angle::GetFeatureName(feature));
235*8975f5c5SAndroid Build Coastguard Worker     }
236*8975f5c5SAndroid Build Coastguard Worker     for (angle::Feature feature : params.disabledFeatureOverrides)
237*8975f5c5SAndroid Build Coastguard Worker     {
238*8975f5c5SAndroid Build Coastguard Worker         disabledFeatureOverrides.push_back(angle::GetFeatureName(feature));
239*8975f5c5SAndroid Build Coastguard Worker     }
240*8975f5c5SAndroid Build Coastguard Worker 
241*8975f5c5SAndroid Build Coastguard Worker     const bool hasFeatureControlANGLE =
242*8975f5c5SAndroid Build Coastguard Worker         strstr(extensionString, "EGL_ANGLE_feature_control") != nullptr;
243*8975f5c5SAndroid Build Coastguard Worker 
244*8975f5c5SAndroid Build Coastguard Worker     if (!hasFeatureControlANGLE &&
245*8975f5c5SAndroid Build Coastguard Worker         (!enabledFeatureOverrides.empty() || !disabledFeatureOverrides.empty()))
246*8975f5c5SAndroid Build Coastguard Worker     {
247*8975f5c5SAndroid Build Coastguard Worker         fprintf(stderr, "Missing EGL_ANGLE_feature_control.\n");
248*8975f5c5SAndroid Build Coastguard Worker         destroyGL();
249*8975f5c5SAndroid Build Coastguard Worker         return false;
250*8975f5c5SAndroid Build Coastguard Worker     }
251*8975f5c5SAndroid Build Coastguard Worker 
252*8975f5c5SAndroid Build Coastguard Worker     if (!disabledFeatureOverrides.empty())
253*8975f5c5SAndroid Build Coastguard Worker     {
254*8975f5c5SAndroid Build Coastguard Worker         disabledFeatureOverrides.push_back(nullptr);
255*8975f5c5SAndroid Build Coastguard Worker 
256*8975f5c5SAndroid Build Coastguard Worker         displayAttributes.push_back(EGL_FEATURE_OVERRIDES_DISABLED_ANGLE);
257*8975f5c5SAndroid Build Coastguard Worker         displayAttributes.push_back(reinterpret_cast<EGLAttrib>(disabledFeatureOverrides.data()));
258*8975f5c5SAndroid Build Coastguard Worker     }
259*8975f5c5SAndroid Build Coastguard Worker 
260*8975f5c5SAndroid Build Coastguard Worker     if (hasFeatureControlANGLE)
261*8975f5c5SAndroid Build Coastguard Worker     {
262*8975f5c5SAndroid Build Coastguard Worker         // Always enable exposeNonConformantExtensionsAndVersions in ANGLE tests.
263*8975f5c5SAndroid Build Coastguard Worker         enabledFeatureOverrides.push_back("exposeNonConformantExtensionsAndVersions");
264*8975f5c5SAndroid Build Coastguard Worker         enabledFeatureOverrides.push_back(nullptr);
265*8975f5c5SAndroid Build Coastguard Worker 
266*8975f5c5SAndroid Build Coastguard Worker         displayAttributes.push_back(EGL_FEATURE_OVERRIDES_ENABLED_ANGLE);
267*8975f5c5SAndroid Build Coastguard Worker         displayAttributes.push_back(reinterpret_cast<EGLAttrib>(enabledFeatureOverrides.data()));
268*8975f5c5SAndroid Build Coastguard Worker     }
269*8975f5c5SAndroid Build Coastguard Worker 
270*8975f5c5SAndroid Build Coastguard Worker     displayAttributes.push_back(EGL_NONE);
271*8975f5c5SAndroid Build Coastguard Worker 
272*8975f5c5SAndroid Build Coastguard Worker     if (driverType == angle::GLESDriverType::SystemWGL)
273*8975f5c5SAndroid Build Coastguard Worker         return false;
274*8975f5c5SAndroid Build Coastguard Worker 
275*8975f5c5SAndroid Build Coastguard Worker     if (IsANGLE(driverType) && strstr(extensionString, "EGL_ANGLE_platform_angle"))
276*8975f5c5SAndroid Build Coastguard Worker     {
277*8975f5c5SAndroid Build Coastguard Worker         mDisplay = eglGetPlatformDisplay(EGL_PLATFORM_ANGLE_ANGLE,
278*8975f5c5SAndroid Build Coastguard Worker                                          reinterpret_cast<void *>(osWindow->getNativeDisplay()),
279*8975f5c5SAndroid Build Coastguard Worker                                          &displayAttributes[0]);
280*8975f5c5SAndroid Build Coastguard Worker     }
281*8975f5c5SAndroid Build Coastguard Worker     else
282*8975f5c5SAndroid Build Coastguard Worker     {
283*8975f5c5SAndroid Build Coastguard Worker         mDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
284*8975f5c5SAndroid Build Coastguard Worker     }
285*8975f5c5SAndroid Build Coastguard Worker 
286*8975f5c5SAndroid Build Coastguard Worker     if (mDisplay == EGL_NO_DISPLAY)
287*8975f5c5SAndroid Build Coastguard Worker     {
288*8975f5c5SAndroid Build Coastguard Worker         fprintf(stderr, "Failed to get display: 0x%X\n", eglGetError());
289*8975f5c5SAndroid Build Coastguard Worker         destroyGL();
290*8975f5c5SAndroid Build Coastguard Worker         return false;
291*8975f5c5SAndroid Build Coastguard Worker     }
292*8975f5c5SAndroid Build Coastguard Worker 
293*8975f5c5SAndroid Build Coastguard Worker     if (eglInitialize(mDisplay, &mEGLMajorVersion, &mEGLMinorVersion) == EGL_FALSE)
294*8975f5c5SAndroid Build Coastguard Worker     {
295*8975f5c5SAndroid Build Coastguard Worker         fprintf(stderr, "eglInitialize failed: 0x%X\n", eglGetError());
296*8975f5c5SAndroid Build Coastguard Worker         destroyGL();
297*8975f5c5SAndroid Build Coastguard Worker         return false;
298*8975f5c5SAndroid Build Coastguard Worker     }
299*8975f5c5SAndroid Build Coastguard Worker 
300*8975f5c5SAndroid Build Coastguard Worker     queryFeatures();
301*8975f5c5SAndroid Build Coastguard Worker 
302*8975f5c5SAndroid Build Coastguard Worker     mPlatform = params;
303*8975f5c5SAndroid Build Coastguard Worker     return true;
304*8975f5c5SAndroid Build Coastguard Worker }
305*8975f5c5SAndroid Build Coastguard Worker 
initializeSurface(OSWindow * osWindow,angle::Library * glWindowingLibrary,const ConfigParameters & params)306*8975f5c5SAndroid Build Coastguard Worker GLWindowResult EGLWindow::initializeSurface(OSWindow *osWindow,
307*8975f5c5SAndroid Build Coastguard Worker                                             angle::Library *glWindowingLibrary,
308*8975f5c5SAndroid Build Coastguard Worker                                             const ConfigParameters &params)
309*8975f5c5SAndroid Build Coastguard Worker {
310*8975f5c5SAndroid Build Coastguard Worker     mConfigParams                 = params;
311*8975f5c5SAndroid Build Coastguard Worker     const char *displayExtensions = eglQueryString(mDisplay, EGL_EXTENSIONS);
312*8975f5c5SAndroid Build Coastguard Worker 
313*8975f5c5SAndroid Build Coastguard Worker     bool hasMutableRenderBuffer =
314*8975f5c5SAndroid Build Coastguard Worker         strstr(displayExtensions, "EGL_KHR_mutable_render_buffer") != nullptr;
315*8975f5c5SAndroid Build Coastguard Worker     if (mConfigParams.mutableRenderBuffer && !hasMutableRenderBuffer)
316*8975f5c5SAndroid Build Coastguard Worker     {
317*8975f5c5SAndroid Build Coastguard Worker         fprintf(stderr, "Mising EGL_KHR_mutable_render_buffer.\n");
318*8975f5c5SAndroid Build Coastguard Worker         destroyGL();
319*8975f5c5SAndroid Build Coastguard Worker         return GLWindowResult::NoMutableRenderBufferSupport;
320*8975f5c5SAndroid Build Coastguard Worker     }
321*8975f5c5SAndroid Build Coastguard Worker 
322*8975f5c5SAndroid Build Coastguard Worker     std::vector<EGLint> configAttributes = {
323*8975f5c5SAndroid Build Coastguard Worker         EGL_SURFACE_TYPE,
324*8975f5c5SAndroid Build Coastguard Worker         EGL_WINDOW_BIT | (params.mutableRenderBuffer ? EGL_MUTABLE_RENDER_BUFFER_BIT_KHR : 0),
325*8975f5c5SAndroid Build Coastguard Worker         EGL_RED_SIZE,
326*8975f5c5SAndroid Build Coastguard Worker         (mConfigParams.redBits >= 0) ? mConfigParams.redBits : EGL_DONT_CARE,
327*8975f5c5SAndroid Build Coastguard Worker         EGL_GREEN_SIZE,
328*8975f5c5SAndroid Build Coastguard Worker         (mConfigParams.greenBits >= 0) ? mConfigParams.greenBits : EGL_DONT_CARE,
329*8975f5c5SAndroid Build Coastguard Worker         EGL_BLUE_SIZE,
330*8975f5c5SAndroid Build Coastguard Worker         (mConfigParams.blueBits >= 0) ? mConfigParams.blueBits : EGL_DONT_CARE,
331*8975f5c5SAndroid Build Coastguard Worker         EGL_ALPHA_SIZE,
332*8975f5c5SAndroid Build Coastguard Worker         (mConfigParams.alphaBits >= 0) ? mConfigParams.alphaBits : EGL_DONT_CARE,
333*8975f5c5SAndroid Build Coastguard Worker         EGL_DEPTH_SIZE,
334*8975f5c5SAndroid Build Coastguard Worker         (mConfigParams.depthBits >= 0) ? mConfigParams.depthBits : EGL_DONT_CARE,
335*8975f5c5SAndroid Build Coastguard Worker         EGL_STENCIL_SIZE,
336*8975f5c5SAndroid Build Coastguard Worker         (mConfigParams.stencilBits >= 0) ? mConfigParams.stencilBits : EGL_DONT_CARE,
337*8975f5c5SAndroid Build Coastguard Worker         EGL_SAMPLE_BUFFERS,
338*8975f5c5SAndroid Build Coastguard Worker         mConfigParams.multisample ? 1 : 0,
339*8975f5c5SAndroid Build Coastguard Worker         EGL_SAMPLES,
340*8975f5c5SAndroid Build Coastguard Worker         (mConfigParams.samples >= 0) ? mConfigParams.samples : EGL_DONT_CARE,
341*8975f5c5SAndroid Build Coastguard Worker     };
342*8975f5c5SAndroid Build Coastguard Worker 
343*8975f5c5SAndroid Build Coastguard Worker     // Add dynamic attributes
344*8975f5c5SAndroid Build Coastguard Worker     bool hasPixelFormatFloat = strstr(displayExtensions, "EGL_EXT_pixel_format_float") != nullptr;
345*8975f5c5SAndroid Build Coastguard Worker     if (!hasPixelFormatFloat && mConfigParams.componentType != EGL_COLOR_COMPONENT_TYPE_FIXED_EXT)
346*8975f5c5SAndroid Build Coastguard Worker     {
347*8975f5c5SAndroid Build Coastguard Worker         fprintf(stderr, "Mising EGL_EXT_pixel_format_float.\n");
348*8975f5c5SAndroid Build Coastguard Worker         destroyGL();
349*8975f5c5SAndroid Build Coastguard Worker         return GLWindowResult::Error;
350*8975f5c5SAndroid Build Coastguard Worker     }
351*8975f5c5SAndroid Build Coastguard Worker     if (hasPixelFormatFloat)
352*8975f5c5SAndroid Build Coastguard Worker     {
353*8975f5c5SAndroid Build Coastguard Worker         configAttributes.push_back(EGL_COLOR_COMPONENT_TYPE_EXT);
354*8975f5c5SAndroid Build Coastguard Worker         configAttributes.push_back(mConfigParams.componentType);
355*8975f5c5SAndroid Build Coastguard Worker     }
356*8975f5c5SAndroid Build Coastguard Worker 
357*8975f5c5SAndroid Build Coastguard Worker     // Finish the attribute list
358*8975f5c5SAndroid Build Coastguard Worker     configAttributes.push_back(EGL_NONE);
359*8975f5c5SAndroid Build Coastguard Worker 
360*8975f5c5SAndroid Build Coastguard Worker     if (!FindEGLConfig(mDisplay, configAttributes.data(), &mConfig))
361*8975f5c5SAndroid Build Coastguard Worker     {
362*8975f5c5SAndroid Build Coastguard Worker         fprintf(stderr, "Could not find a suitable EGL config!\n");
363*8975f5c5SAndroid Build Coastguard Worker         destroyGL();
364*8975f5c5SAndroid Build Coastguard Worker         return GLWindowResult::Error;
365*8975f5c5SAndroid Build Coastguard Worker     }
366*8975f5c5SAndroid Build Coastguard Worker 
367*8975f5c5SAndroid Build Coastguard Worker     eglGetConfigAttrib(mDisplay, mConfig, EGL_RED_SIZE, &mConfigParams.redBits);
368*8975f5c5SAndroid Build Coastguard Worker     eglGetConfigAttrib(mDisplay, mConfig, EGL_GREEN_SIZE, &mConfigParams.greenBits);
369*8975f5c5SAndroid Build Coastguard Worker     eglGetConfigAttrib(mDisplay, mConfig, EGL_BLUE_SIZE, &mConfigParams.blueBits);
370*8975f5c5SAndroid Build Coastguard Worker     eglGetConfigAttrib(mDisplay, mConfig, EGL_ALPHA_SIZE, &mConfigParams.alphaBits);
371*8975f5c5SAndroid Build Coastguard Worker     eglGetConfigAttrib(mDisplay, mConfig, EGL_DEPTH_SIZE, &mConfigParams.depthBits);
372*8975f5c5SAndroid Build Coastguard Worker     eglGetConfigAttrib(mDisplay, mConfig, EGL_STENCIL_SIZE, &mConfigParams.stencilBits);
373*8975f5c5SAndroid Build Coastguard Worker     eglGetConfigAttrib(mDisplay, mConfig, EGL_SAMPLES, &mConfigParams.samples);
374*8975f5c5SAndroid Build Coastguard Worker 
375*8975f5c5SAndroid Build Coastguard Worker     std::vector<EGLint> surfaceAttributes;
376*8975f5c5SAndroid Build Coastguard Worker     if (strstr(displayExtensions, "EGL_NV_post_sub_buffer") != nullptr)
377*8975f5c5SAndroid Build Coastguard Worker     {
378*8975f5c5SAndroid Build Coastguard Worker         surfaceAttributes.push_back(EGL_POST_SUB_BUFFER_SUPPORTED_NV);
379*8975f5c5SAndroid Build Coastguard Worker         surfaceAttributes.push_back(EGL_TRUE);
380*8975f5c5SAndroid Build Coastguard Worker     }
381*8975f5c5SAndroid Build Coastguard Worker 
382*8975f5c5SAndroid Build Coastguard Worker     bool hasRobustResourceInit =
383*8975f5c5SAndroid Build Coastguard Worker         strstr(displayExtensions, "EGL_ANGLE_robust_resource_initialization") != nullptr;
384*8975f5c5SAndroid Build Coastguard Worker     if (hasRobustResourceInit && mConfigParams.robustResourceInit.valid())
385*8975f5c5SAndroid Build Coastguard Worker     {
386*8975f5c5SAndroid Build Coastguard Worker         surfaceAttributes.push_back(EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE);
387*8975f5c5SAndroid Build Coastguard Worker         surfaceAttributes.push_back(mConfigParams.robustResourceInit.value() ? EGL_TRUE
388*8975f5c5SAndroid Build Coastguard Worker                                                                              : EGL_FALSE);
389*8975f5c5SAndroid Build Coastguard Worker     }
390*8975f5c5SAndroid Build Coastguard Worker 
391*8975f5c5SAndroid Build Coastguard Worker     bool hasGLColorSpace = strstr(displayExtensions, "EGL_KHR_gl_colorspace") != nullptr;
392*8975f5c5SAndroid Build Coastguard Worker     if (!hasGLColorSpace && mConfigParams.colorSpace != EGL_COLORSPACE_LINEAR)
393*8975f5c5SAndroid Build Coastguard Worker     {
394*8975f5c5SAndroid Build Coastguard Worker         fprintf(stderr, "Mising EGL_KHR_gl_colorspace.\n");
395*8975f5c5SAndroid Build Coastguard Worker         destroyGL();
396*8975f5c5SAndroid Build Coastguard Worker         return GLWindowResult::NoColorspaceSupport;
397*8975f5c5SAndroid Build Coastguard Worker     }
398*8975f5c5SAndroid Build Coastguard Worker     if (hasGLColorSpace)
399*8975f5c5SAndroid Build Coastguard Worker     {
400*8975f5c5SAndroid Build Coastguard Worker         surfaceAttributes.push_back(EGL_GL_COLORSPACE_KHR);
401*8975f5c5SAndroid Build Coastguard Worker         surfaceAttributes.push_back(mConfigParams.colorSpace);
402*8975f5c5SAndroid Build Coastguard Worker     }
403*8975f5c5SAndroid Build Coastguard Worker 
404*8975f5c5SAndroid Build Coastguard Worker     bool hasCreateSurfaceSwapInterval =
405*8975f5c5SAndroid Build Coastguard Worker         strstr(displayExtensions, "EGL_ANGLE_create_surface_swap_interval") != nullptr;
406*8975f5c5SAndroid Build Coastguard Worker     if (hasCreateSurfaceSwapInterval && mConfigParams.swapInterval != kDefaultSwapInterval)
407*8975f5c5SAndroid Build Coastguard Worker     {
408*8975f5c5SAndroid Build Coastguard Worker         surfaceAttributes.push_back(EGL_SWAP_INTERVAL_ANGLE);
409*8975f5c5SAndroid Build Coastguard Worker         surfaceAttributes.push_back(mConfigParams.swapInterval);
410*8975f5c5SAndroid Build Coastguard Worker     }
411*8975f5c5SAndroid Build Coastguard Worker 
412*8975f5c5SAndroid Build Coastguard Worker     surfaceAttributes.push_back(EGL_NONE);
413*8975f5c5SAndroid Build Coastguard Worker 
414*8975f5c5SAndroid Build Coastguard Worker     osWindow->resetNativeWindow();
415*8975f5c5SAndroid Build Coastguard Worker 
416*8975f5c5SAndroid Build Coastguard Worker     mSurface = eglCreateWindowSurface(mDisplay, mConfig, osWindow->getNativeWindow(),
417*8975f5c5SAndroid Build Coastguard Worker                                       &surfaceAttributes[0]);
418*8975f5c5SAndroid Build Coastguard Worker     if (eglGetError() != EGL_SUCCESS || (mSurface == EGL_NO_SURFACE))
419*8975f5c5SAndroid Build Coastguard Worker     {
420*8975f5c5SAndroid Build Coastguard Worker         fprintf(stderr, "eglCreateWindowSurface failed: 0x%X\n", eglGetError());
421*8975f5c5SAndroid Build Coastguard Worker         destroyGL();
422*8975f5c5SAndroid Build Coastguard Worker         return GLWindowResult::Error;
423*8975f5c5SAndroid Build Coastguard Worker     }
424*8975f5c5SAndroid Build Coastguard Worker 
425*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_USE_UTIL_LOADER)
426*8975f5c5SAndroid Build Coastguard Worker     LoadUtilGLES(eglGetProcAddress);
427*8975f5c5SAndroid Build Coastguard Worker #endif  // defined(ANGLE_USE_UTIL_LOADER)
428*8975f5c5SAndroid Build Coastguard Worker 
429*8975f5c5SAndroid Build Coastguard Worker     return GLWindowResult::NoError;
430*8975f5c5SAndroid Build Coastguard Worker }
431*8975f5c5SAndroid Build Coastguard Worker 
getCurrentContextGeneric()432*8975f5c5SAndroid Build Coastguard Worker GLWindowContext EGLWindow::getCurrentContextGeneric()
433*8975f5c5SAndroid Build Coastguard Worker {
434*8975f5c5SAndroid Build Coastguard Worker     return reinterpret_cast<GLWindowContext>(mContext);
435*8975f5c5SAndroid Build Coastguard Worker }
436*8975f5c5SAndroid Build Coastguard Worker 
createContextGeneric(GLWindowContext share)437*8975f5c5SAndroid Build Coastguard Worker GLWindowContext EGLWindow::createContextGeneric(GLWindowContext share)
438*8975f5c5SAndroid Build Coastguard Worker {
439*8975f5c5SAndroid Build Coastguard Worker     EGLContext shareContext = reinterpret_cast<EGLContext>(share);
440*8975f5c5SAndroid Build Coastguard Worker     return reinterpret_cast<GLWindowContext>(createContext(shareContext, nullptr));
441*8975f5c5SAndroid Build Coastguard Worker }
442*8975f5c5SAndroid Build Coastguard Worker 
createContext(EGLContext share,EGLint * extraAttributes)443*8975f5c5SAndroid Build Coastguard Worker EGLContext EGLWindow::createContext(EGLContext share, EGLint *extraAttributes)
444*8975f5c5SAndroid Build Coastguard Worker {
445*8975f5c5SAndroid Build Coastguard Worker     const char *displayExtensions = eglQueryString(mDisplay, EGL_EXTENSIONS);
446*8975f5c5SAndroid Build Coastguard Worker 
447*8975f5c5SAndroid Build Coastguard Worker     // EGL_KHR_create_context is required to request a ES3+ context.
448*8975f5c5SAndroid Build Coastguard Worker     bool hasKHRCreateContext = strstr(displayExtensions, "EGL_KHR_create_context") != nullptr;
449*8975f5c5SAndroid Build Coastguard Worker     if (mClientMajorVersion > 2 && !(mEGLMajorVersion > 1 || mEGLMinorVersion >= 5) &&
450*8975f5c5SAndroid Build Coastguard Worker         !hasKHRCreateContext)
451*8975f5c5SAndroid Build Coastguard Worker     {
452*8975f5c5SAndroid Build Coastguard Worker         fprintf(stderr, "EGL_KHR_create_context incompatibility.\n");
453*8975f5c5SAndroid Build Coastguard Worker         return EGL_NO_CONTEXT;
454*8975f5c5SAndroid Build Coastguard Worker     }
455*8975f5c5SAndroid Build Coastguard Worker 
456*8975f5c5SAndroid Build Coastguard Worker     // EGL_CONTEXT_OPENGL_DEBUG is only valid as of EGL 1.5.
457*8975f5c5SAndroid Build Coastguard Worker     bool hasDebug = mEGLMinorVersion >= 5;
458*8975f5c5SAndroid Build Coastguard Worker     if (mConfigParams.debug && !hasDebug)
459*8975f5c5SAndroid Build Coastguard Worker     {
460*8975f5c5SAndroid Build Coastguard Worker         fprintf(stderr, "EGL 1.5 is required for EGL_CONTEXT_OPENGL_DEBUG.\n");
461*8975f5c5SAndroid Build Coastguard Worker         return EGL_NO_CONTEXT;
462*8975f5c5SAndroid Build Coastguard Worker     }
463*8975f5c5SAndroid Build Coastguard Worker 
464*8975f5c5SAndroid Build Coastguard Worker     bool hasWebGLCompatibility =
465*8975f5c5SAndroid Build Coastguard Worker         strstr(displayExtensions, "EGL_ANGLE_create_context_webgl_compatibility") != nullptr;
466*8975f5c5SAndroid Build Coastguard Worker     if (mConfigParams.webGLCompatibility.valid() && !hasWebGLCompatibility)
467*8975f5c5SAndroid Build Coastguard Worker     {
468*8975f5c5SAndroid Build Coastguard Worker         fprintf(stderr, "EGL_ANGLE_create_context_webgl_compatibility missing.\n");
469*8975f5c5SAndroid Build Coastguard Worker         return EGL_NO_CONTEXT;
470*8975f5c5SAndroid Build Coastguard Worker     }
471*8975f5c5SAndroid Build Coastguard Worker 
472*8975f5c5SAndroid Build Coastguard Worker     bool hasCreateContextExtensionsEnabled =
473*8975f5c5SAndroid Build Coastguard Worker         strstr(displayExtensions, "EGL_ANGLE_create_context_extensions_enabled") != nullptr;
474*8975f5c5SAndroid Build Coastguard Worker     if (mConfigParams.extensionsEnabled.valid() && !hasCreateContextExtensionsEnabled)
475*8975f5c5SAndroid Build Coastguard Worker     {
476*8975f5c5SAndroid Build Coastguard Worker         fprintf(stderr, "EGL_ANGLE_create_context_extensions_enabled missing.\n");
477*8975f5c5SAndroid Build Coastguard Worker         return EGL_NO_CONTEXT;
478*8975f5c5SAndroid Build Coastguard Worker     }
479*8975f5c5SAndroid Build Coastguard Worker 
480*8975f5c5SAndroid Build Coastguard Worker     bool hasRobustness = strstr(displayExtensions, "EGL_EXT_create_context_robustness") != nullptr;
481*8975f5c5SAndroid Build Coastguard Worker     if ((mConfigParams.robustAccess ||
482*8975f5c5SAndroid Build Coastguard Worker          mConfigParams.resetStrategy != EGL_NO_RESET_NOTIFICATION_EXT) &&
483*8975f5c5SAndroid Build Coastguard Worker         !hasRobustness)
484*8975f5c5SAndroid Build Coastguard Worker     {
485*8975f5c5SAndroid Build Coastguard Worker         fprintf(stderr, "EGL_EXT_create_context_robustness missing.\n");
486*8975f5c5SAndroid Build Coastguard Worker         return EGL_NO_CONTEXT;
487*8975f5c5SAndroid Build Coastguard Worker     }
488*8975f5c5SAndroid Build Coastguard Worker 
489*8975f5c5SAndroid Build Coastguard Worker     bool hasBindGeneratesResource =
490*8975f5c5SAndroid Build Coastguard Worker         strstr(displayExtensions, "EGL_CHROMIUM_create_context_bind_generates_resource") != nullptr;
491*8975f5c5SAndroid Build Coastguard Worker     if (!mConfigParams.bindGeneratesResource && !hasBindGeneratesResource)
492*8975f5c5SAndroid Build Coastguard Worker     {
493*8975f5c5SAndroid Build Coastguard Worker         fprintf(stderr, "EGL_CHROMIUM_create_context_bind_generates_resource missing.\n");
494*8975f5c5SAndroid Build Coastguard Worker         return EGL_NO_CONTEXT;
495*8975f5c5SAndroid Build Coastguard Worker     }
496*8975f5c5SAndroid Build Coastguard Worker 
497*8975f5c5SAndroid Build Coastguard Worker     bool hasClientArraysExtension =
498*8975f5c5SAndroid Build Coastguard Worker         strstr(displayExtensions, "EGL_ANGLE_create_context_client_arrays") != nullptr;
499*8975f5c5SAndroid Build Coastguard Worker     if (!mConfigParams.clientArraysEnabled && !hasClientArraysExtension)
500*8975f5c5SAndroid Build Coastguard Worker     {
501*8975f5c5SAndroid Build Coastguard Worker         // Non-default state requested without the extension present
502*8975f5c5SAndroid Build Coastguard Worker         fprintf(stderr, "EGL_ANGLE_create_context_client_arrays missing.\n");
503*8975f5c5SAndroid Build Coastguard Worker         return EGL_NO_CONTEXT;
504*8975f5c5SAndroid Build Coastguard Worker     }
505*8975f5c5SAndroid Build Coastguard Worker 
506*8975f5c5SAndroid Build Coastguard Worker     bool hasProgramCacheControlExtension =
507*8975f5c5SAndroid Build Coastguard Worker         strstr(displayExtensions, "EGL_ANGLE_program_cache_control ") != nullptr;
508*8975f5c5SAndroid Build Coastguard Worker     if (mConfigParams.contextProgramCacheEnabled.valid() && !hasProgramCacheControlExtension)
509*8975f5c5SAndroid Build Coastguard Worker     {
510*8975f5c5SAndroid Build Coastguard Worker         fprintf(stderr, "EGL_ANGLE_program_cache_control missing.\n");
511*8975f5c5SAndroid Build Coastguard Worker         return EGL_NO_CONTEXT;
512*8975f5c5SAndroid Build Coastguard Worker     }
513*8975f5c5SAndroid Build Coastguard Worker 
514*8975f5c5SAndroid Build Coastguard Worker     bool hasKHRCreateContextNoError =
515*8975f5c5SAndroid Build Coastguard Worker         strstr(displayExtensions, "EGL_KHR_create_context_no_error") != nullptr;
516*8975f5c5SAndroid Build Coastguard Worker     if (mConfigParams.noError && !hasKHRCreateContextNoError)
517*8975f5c5SAndroid Build Coastguard Worker     {
518*8975f5c5SAndroid Build Coastguard Worker         fprintf(stderr, "EGL_KHR_create_context_no_error missing.\n");
519*8975f5c5SAndroid Build Coastguard Worker         return EGL_NO_CONTEXT;
520*8975f5c5SAndroid Build Coastguard Worker     }
521*8975f5c5SAndroid Build Coastguard Worker 
522*8975f5c5SAndroid Build Coastguard Worker     eglBindAPI(EGL_OPENGL_ES_API);
523*8975f5c5SAndroid Build Coastguard Worker     if (eglGetError() != EGL_SUCCESS)
524*8975f5c5SAndroid Build Coastguard Worker     {
525*8975f5c5SAndroid Build Coastguard Worker         fprintf(stderr, "Error on eglBindAPI.\n");
526*8975f5c5SAndroid Build Coastguard Worker         return EGL_NO_CONTEXT;
527*8975f5c5SAndroid Build Coastguard Worker     }
528*8975f5c5SAndroid Build Coastguard Worker 
529*8975f5c5SAndroid Build Coastguard Worker     std::vector<EGLint> contextAttributes;
530*8975f5c5SAndroid Build Coastguard Worker     for (EGLint *extraAttrib = extraAttributes;
531*8975f5c5SAndroid Build Coastguard Worker          extraAttrib != nullptr && extraAttrib[0] != EGL_NONE; extraAttrib += 2)
532*8975f5c5SAndroid Build Coastguard Worker     {
533*8975f5c5SAndroid Build Coastguard Worker         contextAttributes.push_back(extraAttrib[0]);
534*8975f5c5SAndroid Build Coastguard Worker         contextAttributes.push_back(extraAttrib[1]);
535*8975f5c5SAndroid Build Coastguard Worker     }
536*8975f5c5SAndroid Build Coastguard Worker 
537*8975f5c5SAndroid Build Coastguard Worker     if (hasKHRCreateContext)
538*8975f5c5SAndroid Build Coastguard Worker     {
539*8975f5c5SAndroid Build Coastguard Worker         contextAttributes.push_back(EGL_CONTEXT_MAJOR_VERSION_KHR);
540*8975f5c5SAndroid Build Coastguard Worker         contextAttributes.push_back(mClientMajorVersion);
541*8975f5c5SAndroid Build Coastguard Worker 
542*8975f5c5SAndroid Build Coastguard Worker         contextAttributes.push_back(EGL_CONTEXT_MINOR_VERSION_KHR);
543*8975f5c5SAndroid Build Coastguard Worker         contextAttributes.push_back(mClientMinorVersion);
544*8975f5c5SAndroid Build Coastguard Worker 
545*8975f5c5SAndroid Build Coastguard Worker         // Note that the Android loader currently doesn't handle this flag despite reporting 1.5.
546*8975f5c5SAndroid Build Coastguard Worker         // Work around this by only using the debug bit when we request a debug context.
547*8975f5c5SAndroid Build Coastguard Worker         if (hasDebug && mConfigParams.debug)
548*8975f5c5SAndroid Build Coastguard Worker         {
549*8975f5c5SAndroid Build Coastguard Worker             contextAttributes.push_back(EGL_CONTEXT_OPENGL_DEBUG);
550*8975f5c5SAndroid Build Coastguard Worker             contextAttributes.push_back(mConfigParams.debug ? EGL_TRUE : EGL_FALSE);
551*8975f5c5SAndroid Build Coastguard Worker         }
552*8975f5c5SAndroid Build Coastguard Worker 
553*8975f5c5SAndroid Build Coastguard Worker         // TODO (http://anglebug.com/42264345)
554*8975f5c5SAndroid Build Coastguard Worker         // Mesa does not allow EGL_CONTEXT_OPENGL_NO_ERROR_KHR for GLES1.
555*8975f5c5SAndroid Build Coastguard Worker         if (hasKHRCreateContextNoError && mConfigParams.noError)
556*8975f5c5SAndroid Build Coastguard Worker         {
557*8975f5c5SAndroid Build Coastguard Worker             contextAttributes.push_back(EGL_CONTEXT_OPENGL_NO_ERROR_KHR);
558*8975f5c5SAndroid Build Coastguard Worker             contextAttributes.push_back(mConfigParams.noError ? EGL_TRUE : EGL_FALSE);
559*8975f5c5SAndroid Build Coastguard Worker         }
560*8975f5c5SAndroid Build Coastguard Worker 
561*8975f5c5SAndroid Build Coastguard Worker         if (mConfigParams.webGLCompatibility.valid())
562*8975f5c5SAndroid Build Coastguard Worker         {
563*8975f5c5SAndroid Build Coastguard Worker             contextAttributes.push_back(EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE);
564*8975f5c5SAndroid Build Coastguard Worker             contextAttributes.push_back(mConfigParams.webGLCompatibility.value() ? EGL_TRUE
565*8975f5c5SAndroid Build Coastguard Worker                                                                                  : EGL_FALSE);
566*8975f5c5SAndroid Build Coastguard Worker         }
567*8975f5c5SAndroid Build Coastguard Worker 
568*8975f5c5SAndroid Build Coastguard Worker         if (mConfigParams.extensionsEnabled.valid())
569*8975f5c5SAndroid Build Coastguard Worker         {
570*8975f5c5SAndroid Build Coastguard Worker             contextAttributes.push_back(EGL_EXTENSIONS_ENABLED_ANGLE);
571*8975f5c5SAndroid Build Coastguard Worker             contextAttributes.push_back(mConfigParams.extensionsEnabled.value() ? EGL_TRUE
572*8975f5c5SAndroid Build Coastguard Worker                                                                                 : EGL_FALSE);
573*8975f5c5SAndroid Build Coastguard Worker         }
574*8975f5c5SAndroid Build Coastguard Worker 
575*8975f5c5SAndroid Build Coastguard Worker         if (hasRobustness)
576*8975f5c5SAndroid Build Coastguard Worker         {
577*8975f5c5SAndroid Build Coastguard Worker             contextAttributes.push_back(EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT);
578*8975f5c5SAndroid Build Coastguard Worker             contextAttributes.push_back(mConfigParams.robustAccess ? EGL_TRUE : EGL_FALSE);
579*8975f5c5SAndroid Build Coastguard Worker 
580*8975f5c5SAndroid Build Coastguard Worker             contextAttributes.push_back(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT);
581*8975f5c5SAndroid Build Coastguard Worker             contextAttributes.push_back(mConfigParams.resetStrategy);
582*8975f5c5SAndroid Build Coastguard Worker         }
583*8975f5c5SAndroid Build Coastguard Worker 
584*8975f5c5SAndroid Build Coastguard Worker         if (hasBindGeneratesResource)
585*8975f5c5SAndroid Build Coastguard Worker         {
586*8975f5c5SAndroid Build Coastguard Worker             contextAttributes.push_back(EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM);
587*8975f5c5SAndroid Build Coastguard Worker             contextAttributes.push_back(mConfigParams.bindGeneratesResource ? EGL_TRUE : EGL_FALSE);
588*8975f5c5SAndroid Build Coastguard Worker         }
589*8975f5c5SAndroid Build Coastguard Worker 
590*8975f5c5SAndroid Build Coastguard Worker         if (hasClientArraysExtension)
591*8975f5c5SAndroid Build Coastguard Worker         {
592*8975f5c5SAndroid Build Coastguard Worker             contextAttributes.push_back(EGL_CONTEXT_CLIENT_ARRAYS_ENABLED_ANGLE);
593*8975f5c5SAndroid Build Coastguard Worker             contextAttributes.push_back(mConfigParams.clientArraysEnabled ? EGL_TRUE : EGL_FALSE);
594*8975f5c5SAndroid Build Coastguard Worker         }
595*8975f5c5SAndroid Build Coastguard Worker 
596*8975f5c5SAndroid Build Coastguard Worker         if (mConfigParams.contextProgramCacheEnabled.valid())
597*8975f5c5SAndroid Build Coastguard Worker         {
598*8975f5c5SAndroid Build Coastguard Worker             contextAttributes.push_back(EGL_CONTEXT_PROGRAM_BINARY_CACHE_ENABLED_ANGLE);
599*8975f5c5SAndroid Build Coastguard Worker             contextAttributes.push_back(
600*8975f5c5SAndroid Build Coastguard Worker                 mConfigParams.contextProgramCacheEnabled.value() ? EGL_TRUE : EGL_FALSE);
601*8975f5c5SAndroid Build Coastguard Worker         }
602*8975f5c5SAndroid Build Coastguard Worker 
603*8975f5c5SAndroid Build Coastguard Worker         bool hasBackwardsCompatibleContextExtension =
604*8975f5c5SAndroid Build Coastguard Worker             strstr(displayExtensions, "EGL_ANGLE_create_context_backwards_compatible") != nullptr;
605*8975f5c5SAndroid Build Coastguard Worker         if (hasBackwardsCompatibleContextExtension)
606*8975f5c5SAndroid Build Coastguard Worker         {
607*8975f5c5SAndroid Build Coastguard Worker             // Always request the exact context version that the config wants
608*8975f5c5SAndroid Build Coastguard Worker             contextAttributes.push_back(EGL_CONTEXT_OPENGL_BACKWARDS_COMPATIBLE_ANGLE);
609*8975f5c5SAndroid Build Coastguard Worker             contextAttributes.push_back(EGL_FALSE);
610*8975f5c5SAndroid Build Coastguard Worker         }
611*8975f5c5SAndroid Build Coastguard Worker 
612*8975f5c5SAndroid Build Coastguard Worker         bool hasRobustResourceInit =
613*8975f5c5SAndroid Build Coastguard Worker             strstr(displayExtensions, "EGL_ANGLE_robust_resource_initialization") != nullptr;
614*8975f5c5SAndroid Build Coastguard Worker         if (hasRobustResourceInit && mConfigParams.robustResourceInit.valid())
615*8975f5c5SAndroid Build Coastguard Worker         {
616*8975f5c5SAndroid Build Coastguard Worker             contextAttributes.push_back(EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE);
617*8975f5c5SAndroid Build Coastguard Worker             contextAttributes.push_back(mConfigParams.robustResourceInit.value() ? EGL_TRUE
618*8975f5c5SAndroid Build Coastguard Worker                                                                                  : EGL_FALSE);
619*8975f5c5SAndroid Build Coastguard Worker         }
620*8975f5c5SAndroid Build Coastguard Worker     }
621*8975f5c5SAndroid Build Coastguard Worker     contextAttributes.push_back(EGL_NONE);
622*8975f5c5SAndroid Build Coastguard Worker 
623*8975f5c5SAndroid Build Coastguard Worker     EGLContext context = eglCreateContext(mDisplay, mConfig, share, &contextAttributes[0]);
624*8975f5c5SAndroid Build Coastguard Worker     if (context == EGL_NO_CONTEXT)
625*8975f5c5SAndroid Build Coastguard Worker     {
626*8975f5c5SAndroid Build Coastguard Worker         fprintf(stderr, "eglCreateContext failed: 0x%X\n", eglGetError());
627*8975f5c5SAndroid Build Coastguard Worker         return EGL_NO_CONTEXT;
628*8975f5c5SAndroid Build Coastguard Worker     }
629*8975f5c5SAndroid Build Coastguard Worker 
630*8975f5c5SAndroid Build Coastguard Worker     return context;
631*8975f5c5SAndroid Build Coastguard Worker }
632*8975f5c5SAndroid Build Coastguard Worker 
initializeContext()633*8975f5c5SAndroid Build Coastguard Worker bool EGLWindow::initializeContext()
634*8975f5c5SAndroid Build Coastguard Worker {
635*8975f5c5SAndroid Build Coastguard Worker     mContext = createContext(EGL_NO_CONTEXT, nullptr);
636*8975f5c5SAndroid Build Coastguard Worker     if (mContext == EGL_NO_CONTEXT)
637*8975f5c5SAndroid Build Coastguard Worker     {
638*8975f5c5SAndroid Build Coastguard Worker         destroyGL();
639*8975f5c5SAndroid Build Coastguard Worker         return false;
640*8975f5c5SAndroid Build Coastguard Worker     }
641*8975f5c5SAndroid Build Coastguard Worker 
642*8975f5c5SAndroid Build Coastguard Worker     if (!makeCurrent())
643*8975f5c5SAndroid Build Coastguard Worker     {
644*8975f5c5SAndroid Build Coastguard Worker         destroyGL();
645*8975f5c5SAndroid Build Coastguard Worker         return false;
646*8975f5c5SAndroid Build Coastguard Worker     }
647*8975f5c5SAndroid Build Coastguard Worker 
648*8975f5c5SAndroid Build Coastguard Worker     return true;
649*8975f5c5SAndroid Build Coastguard Worker }
650*8975f5c5SAndroid Build Coastguard Worker 
destroyGL()651*8975f5c5SAndroid Build Coastguard Worker void EGLWindow::destroyGL()
652*8975f5c5SAndroid Build Coastguard Worker {
653*8975f5c5SAndroid Build Coastguard Worker     destroyContext();
654*8975f5c5SAndroid Build Coastguard Worker     destroySurface();
655*8975f5c5SAndroid Build Coastguard Worker 
656*8975f5c5SAndroid Build Coastguard Worker     if (mDisplay != EGL_NO_DISPLAY)
657*8975f5c5SAndroid Build Coastguard Worker     {
658*8975f5c5SAndroid Build Coastguard Worker         eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
659*8975f5c5SAndroid Build Coastguard Worker         eglTerminate(mDisplay);
660*8975f5c5SAndroid Build Coastguard Worker         mDisplay = EGL_NO_DISPLAY;
661*8975f5c5SAndroid Build Coastguard Worker     }
662*8975f5c5SAndroid Build Coastguard Worker }
663*8975f5c5SAndroid Build Coastguard Worker 
destroySurface()664*8975f5c5SAndroid Build Coastguard Worker void EGLWindow::destroySurface()
665*8975f5c5SAndroid Build Coastguard Worker {
666*8975f5c5SAndroid Build Coastguard Worker     if (mSurface != EGL_NO_SURFACE)
667*8975f5c5SAndroid Build Coastguard Worker     {
668*8975f5c5SAndroid Build Coastguard Worker         eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
669*8975f5c5SAndroid Build Coastguard Worker         assert(mDisplay != EGL_NO_DISPLAY);
670*8975f5c5SAndroid Build Coastguard Worker         eglDestroySurface(mDisplay, mSurface);
671*8975f5c5SAndroid Build Coastguard Worker         mSurface = EGL_NO_SURFACE;
672*8975f5c5SAndroid Build Coastguard Worker     }
673*8975f5c5SAndroid Build Coastguard Worker }
674*8975f5c5SAndroid Build Coastguard Worker 
destroyContext()675*8975f5c5SAndroid Build Coastguard Worker void EGLWindow::destroyContext()
676*8975f5c5SAndroid Build Coastguard Worker {
677*8975f5c5SAndroid Build Coastguard Worker     if (mContext != EGL_NO_CONTEXT)
678*8975f5c5SAndroid Build Coastguard Worker     {
679*8975f5c5SAndroid Build Coastguard Worker         eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
680*8975f5c5SAndroid Build Coastguard Worker         assert(mDisplay != EGL_NO_DISPLAY);
681*8975f5c5SAndroid Build Coastguard Worker         eglDestroyContext(mDisplay, mContext);
682*8975f5c5SAndroid Build Coastguard Worker         mContext = EGL_NO_CONTEXT;
683*8975f5c5SAndroid Build Coastguard Worker     }
684*8975f5c5SAndroid Build Coastguard Worker }
685*8975f5c5SAndroid Build Coastguard Worker 
isGLInitialized() const686*8975f5c5SAndroid Build Coastguard Worker bool EGLWindow::isGLInitialized() const
687*8975f5c5SAndroid Build Coastguard Worker {
688*8975f5c5SAndroid Build Coastguard Worker     return mSurface != EGL_NO_SURFACE && mContext != EGL_NO_CONTEXT && mDisplay != EGL_NO_DISPLAY;
689*8975f5c5SAndroid Build Coastguard Worker }
690*8975f5c5SAndroid Build Coastguard Worker 
691*8975f5c5SAndroid Build Coastguard Worker // Find an EGLConfig that is an exact match for the specified attributes. EGL_FALSE is returned if
692*8975f5c5SAndroid Build Coastguard Worker // the EGLConfig is found.  This indicates that the EGLConfig is not supported.  Surface type is
693*8975f5c5SAndroid Build Coastguard Worker // special-cased as it's possible for a config to return support for both EGL_WINDOW_BIT and
694*8975f5c5SAndroid Build Coastguard Worker // EGL_PBUFFER_BIT even though only one of them is requested.
FindEGLConfig(EGLDisplay dpy,const EGLint * attrib_list,EGLConfig * config)695*8975f5c5SAndroid Build Coastguard Worker EGLBoolean EGLWindow::FindEGLConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *config)
696*8975f5c5SAndroid Build Coastguard Worker {
697*8975f5c5SAndroid Build Coastguard Worker     EGLint numConfigs = 0;
698*8975f5c5SAndroid Build Coastguard Worker     eglGetConfigs(dpy, nullptr, 0, &numConfigs);
699*8975f5c5SAndroid Build Coastguard Worker     std::vector<EGLConfig> allConfigs(numConfigs);
700*8975f5c5SAndroid Build Coastguard Worker     eglGetConfigs(dpy, allConfigs.data(), static_cast<EGLint>(allConfigs.size()), &numConfigs);
701*8975f5c5SAndroid Build Coastguard Worker 
702*8975f5c5SAndroid Build Coastguard Worker     for (size_t i = 0; i < allConfigs.size(); i++)
703*8975f5c5SAndroid Build Coastguard Worker     {
704*8975f5c5SAndroid Build Coastguard Worker         bool matchFound = true;
705*8975f5c5SAndroid Build Coastguard Worker         for (const EGLint *curAttrib = attrib_list; curAttrib[0] != EGL_NONE; curAttrib += 2)
706*8975f5c5SAndroid Build Coastguard Worker         {
707*8975f5c5SAndroid Build Coastguard Worker             if (curAttrib[1] == EGL_DONT_CARE)
708*8975f5c5SAndroid Build Coastguard Worker             {
709*8975f5c5SAndroid Build Coastguard Worker                 continue;
710*8975f5c5SAndroid Build Coastguard Worker             }
711*8975f5c5SAndroid Build Coastguard Worker 
712*8975f5c5SAndroid Build Coastguard Worker             EGLint actualValue = EGL_DONT_CARE;
713*8975f5c5SAndroid Build Coastguard Worker             eglGetConfigAttrib(dpy, allConfigs[i], curAttrib[0], &actualValue);
714*8975f5c5SAndroid Build Coastguard Worker             if ((curAttrib[0] == EGL_SURFACE_TYPE &&
715*8975f5c5SAndroid Build Coastguard Worker                  (curAttrib[1] & actualValue) != curAttrib[1]) ||
716*8975f5c5SAndroid Build Coastguard Worker                 (curAttrib[0] != EGL_SURFACE_TYPE && curAttrib[1] != actualValue))
717*8975f5c5SAndroid Build Coastguard Worker             {
718*8975f5c5SAndroid Build Coastguard Worker                 matchFound = false;
719*8975f5c5SAndroid Build Coastguard Worker                 break;
720*8975f5c5SAndroid Build Coastguard Worker             }
721*8975f5c5SAndroid Build Coastguard Worker         }
722*8975f5c5SAndroid Build Coastguard Worker 
723*8975f5c5SAndroid Build Coastguard Worker         if (matchFound)
724*8975f5c5SAndroid Build Coastguard Worker         {
725*8975f5c5SAndroid Build Coastguard Worker             *config = allConfigs[i];
726*8975f5c5SAndroid Build Coastguard Worker             return EGL_TRUE;
727*8975f5c5SAndroid Build Coastguard Worker         }
728*8975f5c5SAndroid Build Coastguard Worker     }
729*8975f5c5SAndroid Build Coastguard Worker 
730*8975f5c5SAndroid Build Coastguard Worker     return EGL_FALSE;
731*8975f5c5SAndroid Build Coastguard Worker }
732*8975f5c5SAndroid Build Coastguard Worker 
makeCurrentGeneric(GLWindowContext context)733*8975f5c5SAndroid Build Coastguard Worker bool EGLWindow::makeCurrentGeneric(GLWindowContext context)
734*8975f5c5SAndroid Build Coastguard Worker {
735*8975f5c5SAndroid Build Coastguard Worker     EGLContext eglContext = reinterpret_cast<EGLContext>(context);
736*8975f5c5SAndroid Build Coastguard Worker     return makeCurrent(eglContext);
737*8975f5c5SAndroid Build Coastguard Worker }
738*8975f5c5SAndroid Build Coastguard Worker 
makeCurrent()739*8975f5c5SAndroid Build Coastguard Worker bool EGLWindow::makeCurrent()
740*8975f5c5SAndroid Build Coastguard Worker {
741*8975f5c5SAndroid Build Coastguard Worker     return makeCurrent(mContext);
742*8975f5c5SAndroid Build Coastguard Worker }
743*8975f5c5SAndroid Build Coastguard Worker 
createImage(GLWindowContext context,Enum target,ClientBuffer buffer,const Attrib * attrib_list)744*8975f5c5SAndroid Build Coastguard Worker EGLWindow::Image EGLWindow::createImage(GLWindowContext context,
745*8975f5c5SAndroid Build Coastguard Worker                                         Enum target,
746*8975f5c5SAndroid Build Coastguard Worker                                         ClientBuffer buffer,
747*8975f5c5SAndroid Build Coastguard Worker                                         const Attrib *attrib_list)
748*8975f5c5SAndroid Build Coastguard Worker {
749*8975f5c5SAndroid Build Coastguard Worker     return eglCreateImage(getDisplay(), context, target, buffer, attrib_list);
750*8975f5c5SAndroid Build Coastguard Worker }
751*8975f5c5SAndroid Build Coastguard Worker 
createImageKHR(GLWindowContext context,Enum target,ClientBuffer buffer,const AttribKHR * attrib_list)752*8975f5c5SAndroid Build Coastguard Worker EGLWindow::Image EGLWindow::createImageKHR(GLWindowContext context,
753*8975f5c5SAndroid Build Coastguard Worker                                            Enum target,
754*8975f5c5SAndroid Build Coastguard Worker                                            ClientBuffer buffer,
755*8975f5c5SAndroid Build Coastguard Worker                                            const AttribKHR *attrib_list)
756*8975f5c5SAndroid Build Coastguard Worker {
757*8975f5c5SAndroid Build Coastguard Worker     return eglCreateImageKHR(getDisplay(), context, target, buffer, attrib_list);
758*8975f5c5SAndroid Build Coastguard Worker }
759*8975f5c5SAndroid Build Coastguard Worker 
destroyImage(Image image)760*8975f5c5SAndroid Build Coastguard Worker EGLBoolean EGLWindow::destroyImage(Image image)
761*8975f5c5SAndroid Build Coastguard Worker {
762*8975f5c5SAndroid Build Coastguard Worker     return eglDestroyImage(getDisplay(), image);
763*8975f5c5SAndroid Build Coastguard Worker }
764*8975f5c5SAndroid Build Coastguard Worker 
destroyImageKHR(Image image)765*8975f5c5SAndroid Build Coastguard Worker EGLBoolean EGLWindow::destroyImageKHR(Image image)
766*8975f5c5SAndroid Build Coastguard Worker {
767*8975f5c5SAndroid Build Coastguard Worker     return eglDestroyImageKHR(getDisplay(), image);
768*8975f5c5SAndroid Build Coastguard Worker }
769*8975f5c5SAndroid Build Coastguard Worker 
createSync(EGLDisplay dpy,EGLenum type,const EGLAttrib * attrib_list)770*8975f5c5SAndroid Build Coastguard Worker EGLWindow::Sync EGLWindow::createSync(EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list)
771*8975f5c5SAndroid Build Coastguard Worker {
772*8975f5c5SAndroid Build Coastguard Worker     return eglCreateSync(dpy, type, attrib_list);
773*8975f5c5SAndroid Build Coastguard Worker }
774*8975f5c5SAndroid Build Coastguard Worker 
createSyncKHR(EGLDisplay dpy,EGLenum type,const EGLint * attrib_list)775*8975f5c5SAndroid Build Coastguard Worker EGLWindow::Sync EGLWindow::createSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list)
776*8975f5c5SAndroid Build Coastguard Worker {
777*8975f5c5SAndroid Build Coastguard Worker     return eglCreateSyncKHR(dpy, type, attrib_list);
778*8975f5c5SAndroid Build Coastguard Worker }
779*8975f5c5SAndroid Build Coastguard Worker 
destroySync(EGLDisplay dpy,Sync sync)780*8975f5c5SAndroid Build Coastguard Worker EGLBoolean EGLWindow::destroySync(EGLDisplay dpy, Sync sync)
781*8975f5c5SAndroid Build Coastguard Worker {
782*8975f5c5SAndroid Build Coastguard Worker     return eglDestroySync(dpy, sync);
783*8975f5c5SAndroid Build Coastguard Worker }
784*8975f5c5SAndroid Build Coastguard Worker 
destroySyncKHR(EGLDisplay dpy,Sync sync)785*8975f5c5SAndroid Build Coastguard Worker EGLBoolean EGLWindow::destroySyncKHR(EGLDisplay dpy, Sync sync)
786*8975f5c5SAndroid Build Coastguard Worker {
787*8975f5c5SAndroid Build Coastguard Worker     return eglDestroySyncKHR(dpy, sync);
788*8975f5c5SAndroid Build Coastguard Worker }
789*8975f5c5SAndroid Build Coastguard Worker 
clientWaitSync(EGLDisplay dpy,Sync sync,EGLint flags,EGLTimeKHR timeout)790*8975f5c5SAndroid Build Coastguard Worker EGLint EGLWindow::clientWaitSync(EGLDisplay dpy, Sync sync, EGLint flags, EGLTimeKHR timeout)
791*8975f5c5SAndroid Build Coastguard Worker {
792*8975f5c5SAndroid Build Coastguard Worker     return eglClientWaitSync(dpy, sync, flags, timeout);
793*8975f5c5SAndroid Build Coastguard Worker }
794*8975f5c5SAndroid Build Coastguard Worker 
clientWaitSyncKHR(EGLDisplay dpy,Sync sync,EGLint flags,EGLTimeKHR timeout)795*8975f5c5SAndroid Build Coastguard Worker EGLint EGLWindow::clientWaitSyncKHR(EGLDisplay dpy, Sync sync, EGLint flags, EGLTimeKHR timeout)
796*8975f5c5SAndroid Build Coastguard Worker {
797*8975f5c5SAndroid Build Coastguard Worker     return eglClientWaitSyncKHR(dpy, sync, flags, timeout);
798*8975f5c5SAndroid Build Coastguard Worker }
799*8975f5c5SAndroid Build Coastguard Worker 
getEGLError()800*8975f5c5SAndroid Build Coastguard Worker EGLint EGLWindow::getEGLError()
801*8975f5c5SAndroid Build Coastguard Worker {
802*8975f5c5SAndroid Build Coastguard Worker     return eglGetError();
803*8975f5c5SAndroid Build Coastguard Worker }
804*8975f5c5SAndroid Build Coastguard Worker 
getCurrentDisplay()805*8975f5c5SAndroid Build Coastguard Worker EGLWindow::Display EGLWindow::getCurrentDisplay()
806*8975f5c5SAndroid Build Coastguard Worker {
807*8975f5c5SAndroid Build Coastguard Worker     return eglGetCurrentDisplay();
808*8975f5c5SAndroid Build Coastguard Worker }
809*8975f5c5SAndroid Build Coastguard Worker 
createPbufferSurface(const EGLint * attrib_list)810*8975f5c5SAndroid Build Coastguard Worker GLWindowBase::Surface EGLWindow::createPbufferSurface(const EGLint *attrib_list)
811*8975f5c5SAndroid Build Coastguard Worker {
812*8975f5c5SAndroid Build Coastguard Worker     return eglCreatePbufferSurface(getDisplay(), getConfig(), attrib_list);
813*8975f5c5SAndroid Build Coastguard Worker }
814*8975f5c5SAndroid Build Coastguard Worker 
destroySurface(Surface surface)815*8975f5c5SAndroid Build Coastguard Worker EGLBoolean EGLWindow::destroySurface(Surface surface)
816*8975f5c5SAndroid Build Coastguard Worker {
817*8975f5c5SAndroid Build Coastguard Worker     return eglDestroySurface(getDisplay(), surface);
818*8975f5c5SAndroid Build Coastguard Worker }
819*8975f5c5SAndroid Build Coastguard Worker 
bindTexImage(EGLSurface surface,EGLint buffer)820*8975f5c5SAndroid Build Coastguard Worker EGLBoolean EGLWindow::bindTexImage(EGLSurface surface, EGLint buffer)
821*8975f5c5SAndroid Build Coastguard Worker {
822*8975f5c5SAndroid Build Coastguard Worker     return eglBindTexImage(getDisplay(), surface, buffer);
823*8975f5c5SAndroid Build Coastguard Worker }
824*8975f5c5SAndroid Build Coastguard Worker 
releaseTexImage(EGLSurface surface,EGLint buffer)825*8975f5c5SAndroid Build Coastguard Worker EGLBoolean EGLWindow::releaseTexImage(EGLSurface surface, EGLint buffer)
826*8975f5c5SAndroid Build Coastguard Worker {
827*8975f5c5SAndroid Build Coastguard Worker     return eglReleaseTexImage(getDisplay(), surface, buffer);
828*8975f5c5SAndroid Build Coastguard Worker }
829*8975f5c5SAndroid Build Coastguard Worker 
makeCurrent(EGLSurface draw,EGLSurface read,EGLContext context)830*8975f5c5SAndroid Build Coastguard Worker bool EGLWindow::makeCurrent(EGLSurface draw, EGLSurface read, EGLContext context)
831*8975f5c5SAndroid Build Coastguard Worker {
832*8975f5c5SAndroid Build Coastguard Worker     if ((draw && !read) || (!draw && read))
833*8975f5c5SAndroid Build Coastguard Worker     {
834*8975f5c5SAndroid Build Coastguard Worker         fprintf(stderr, "eglMakeCurrent: setting only one of draw and read buffer is illegal\n");
835*8975f5c5SAndroid Build Coastguard Worker         return false;
836*8975f5c5SAndroid Build Coastguard Worker     }
837*8975f5c5SAndroid Build Coastguard Worker 
838*8975f5c5SAndroid Build Coastguard Worker     // if the draw buffer is a nullptr and a context is given, then we use mSurface,
839*8975f5c5SAndroid Build Coastguard Worker     // because we didn't add this the gSurfaceMap, and it is the most likely
840*8975f5c5SAndroid Build Coastguard Worker     // case that we actually wanted the default surface here.
841*8975f5c5SAndroid Build Coastguard Worker     // TODO: This will need additional work when we want to support capture/replay
842*8975f5c5SAndroid Build Coastguard Worker     // with a sourfaceless context.
843*8975f5c5SAndroid Build Coastguard Worker     //
844*8975f5c5SAndroid Build Coastguard Worker     // If no context is given then we also don't assign a surface
845*8975f5c5SAndroid Build Coastguard Worker     if (!draw)
846*8975f5c5SAndroid Build Coastguard Worker     {
847*8975f5c5SAndroid Build Coastguard Worker         draw = read = context != EGL_NO_CONTEXT ? mSurface : EGL_NO_SURFACE;
848*8975f5c5SAndroid Build Coastguard Worker     }
849*8975f5c5SAndroid Build Coastguard Worker 
850*8975f5c5SAndroid Build Coastguard Worker     if (isGLInitialized())
851*8975f5c5SAndroid Build Coastguard Worker     {
852*8975f5c5SAndroid Build Coastguard Worker         if (eglMakeCurrent(mDisplay, draw, read, context) == EGL_FALSE ||
853*8975f5c5SAndroid Build Coastguard Worker             eglGetError() != EGL_SUCCESS)
854*8975f5c5SAndroid Build Coastguard Worker         {
855*8975f5c5SAndroid Build Coastguard Worker             fprintf(stderr, "Error during eglMakeCurrent.\n");
856*8975f5c5SAndroid Build Coastguard Worker             return false;
857*8975f5c5SAndroid Build Coastguard Worker         }
858*8975f5c5SAndroid Build Coastguard Worker     }
859*8975f5c5SAndroid Build Coastguard Worker     return true;
860*8975f5c5SAndroid Build Coastguard Worker }
861*8975f5c5SAndroid Build Coastguard Worker 
makeCurrent(EGLContext context)862*8975f5c5SAndroid Build Coastguard Worker bool EGLWindow::makeCurrent(EGLContext context)
863*8975f5c5SAndroid Build Coastguard Worker {
864*8975f5c5SAndroid Build Coastguard Worker     return makeCurrent(mSurface, mSurface, context);
865*8975f5c5SAndroid Build Coastguard Worker }
866*8975f5c5SAndroid Build Coastguard Worker 
setSwapInterval(EGLint swapInterval)867*8975f5c5SAndroid Build Coastguard Worker bool EGLWindow::setSwapInterval(EGLint swapInterval)
868*8975f5c5SAndroid Build Coastguard Worker {
869*8975f5c5SAndroid Build Coastguard Worker     if (eglSwapInterval(mDisplay, swapInterval) == EGL_FALSE || eglGetError() != EGL_SUCCESS)
870*8975f5c5SAndroid Build Coastguard Worker     {
871*8975f5c5SAndroid Build Coastguard Worker         fprintf(stderr, "Error during eglSwapInterval.\n");
872*8975f5c5SAndroid Build Coastguard Worker         return false;
873*8975f5c5SAndroid Build Coastguard Worker     }
874*8975f5c5SAndroid Build Coastguard Worker 
875*8975f5c5SAndroid Build Coastguard Worker     return true;
876*8975f5c5SAndroid Build Coastguard Worker }
877*8975f5c5SAndroid Build Coastguard Worker 
hasError() const878*8975f5c5SAndroid Build Coastguard Worker bool EGLWindow::hasError() const
879*8975f5c5SAndroid Build Coastguard Worker {
880*8975f5c5SAndroid Build Coastguard Worker     return eglGetError() != EGL_SUCCESS;
881*8975f5c5SAndroid Build Coastguard Worker }
882*8975f5c5SAndroid Build Coastguard Worker 
getProcAddress(const char * name)883*8975f5c5SAndroid Build Coastguard Worker angle::GenericProc EGLWindow::getProcAddress(const char *name)
884*8975f5c5SAndroid Build Coastguard Worker {
885*8975f5c5SAndroid Build Coastguard Worker     return eglGetProcAddress(name);
886*8975f5c5SAndroid Build Coastguard Worker }
887*8975f5c5SAndroid Build Coastguard Worker 
888*8975f5c5SAndroid Build Coastguard Worker // static
Delete(GLWindowBase ** window)889*8975f5c5SAndroid Build Coastguard Worker void GLWindowBase::Delete(GLWindowBase **window)
890*8975f5c5SAndroid Build Coastguard Worker {
891*8975f5c5SAndroid Build Coastguard Worker     delete *window;
892*8975f5c5SAndroid Build Coastguard Worker     *window = nullptr;
893*8975f5c5SAndroid Build Coastguard Worker }
894*8975f5c5SAndroid Build Coastguard Worker 
895*8975f5c5SAndroid Build Coastguard Worker // static
New(EGLint glesMajorVersion,EGLint glesMinorVersion)896*8975f5c5SAndroid Build Coastguard Worker EGLWindow *EGLWindow::New(EGLint glesMajorVersion, EGLint glesMinorVersion)
897*8975f5c5SAndroid Build Coastguard Worker {
898*8975f5c5SAndroid Build Coastguard Worker     return new EGLWindow(glesMajorVersion, glesMinorVersion);
899*8975f5c5SAndroid Build Coastguard Worker }
900*8975f5c5SAndroid Build Coastguard Worker 
901*8975f5c5SAndroid Build Coastguard Worker // static
Delete(EGLWindow ** window)902*8975f5c5SAndroid Build Coastguard Worker void EGLWindow::Delete(EGLWindow **window)
903*8975f5c5SAndroid Build Coastguard Worker {
904*8975f5c5SAndroid Build Coastguard Worker     delete *window;
905*8975f5c5SAndroid Build Coastguard Worker     *window = nullptr;
906*8975f5c5SAndroid Build Coastguard Worker }
907*8975f5c5SAndroid Build Coastguard Worker 
queryFeatures()908*8975f5c5SAndroid Build Coastguard Worker void EGLWindow::queryFeatures()
909*8975f5c5SAndroid Build Coastguard Worker {
910*8975f5c5SAndroid Build Coastguard Worker     // EGL_NO_DISPLAY + EGL_EXTENSIONS returns NULL before Android 10
911*8975f5c5SAndroid Build Coastguard Worker     const char *extensionString =
912*8975f5c5SAndroid Build Coastguard Worker         static_cast<const char *>(eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS));
913*8975f5c5SAndroid Build Coastguard Worker     const bool hasFeatureControlANGLE =
914*8975f5c5SAndroid Build Coastguard Worker         extensionString && strstr(extensionString, "EGL_ANGLE_feature_control") != nullptr;
915*8975f5c5SAndroid Build Coastguard Worker 
916*8975f5c5SAndroid Build Coastguard Worker     if (!hasFeatureControlANGLE)
917*8975f5c5SAndroid Build Coastguard Worker     {
918*8975f5c5SAndroid Build Coastguard Worker         return;
919*8975f5c5SAndroid Build Coastguard Worker     }
920*8975f5c5SAndroid Build Coastguard Worker 
921*8975f5c5SAndroid Build Coastguard Worker     angle::HashMap<std::string, angle::Feature> featureFromName;
922*8975f5c5SAndroid Build Coastguard Worker     for (angle::Feature feature : angle::AllEnums<angle::Feature>())
923*8975f5c5SAndroid Build Coastguard Worker     {
924*8975f5c5SAndroid Build Coastguard Worker         featureFromName[angle::GetFeatureName(feature)] = feature;
925*8975f5c5SAndroid Build Coastguard Worker     }
926*8975f5c5SAndroid Build Coastguard Worker 
927*8975f5c5SAndroid Build Coastguard Worker     EGLAttrib featureCount = -1;
928*8975f5c5SAndroid Build Coastguard Worker     eglQueryDisplayAttribANGLE(mDisplay, EGL_FEATURE_COUNT_ANGLE, &featureCount);
929*8975f5c5SAndroid Build Coastguard Worker 
930*8975f5c5SAndroid Build Coastguard Worker     for (int index = 0; index < featureCount; index++)
931*8975f5c5SAndroid Build Coastguard Worker     {
932*8975f5c5SAndroid Build Coastguard Worker         const char *featureName   = eglQueryStringiANGLE(mDisplay, EGL_FEATURE_NAME_ANGLE, index);
933*8975f5c5SAndroid Build Coastguard Worker         const char *featureStatus = eglQueryStringiANGLE(mDisplay, EGL_FEATURE_STATUS_ANGLE, index);
934*8975f5c5SAndroid Build Coastguard Worker         ASSERT(featureName != nullptr);
935*8975f5c5SAndroid Build Coastguard Worker         ASSERT(featureStatus != nullptr);
936*8975f5c5SAndroid Build Coastguard Worker 
937*8975f5c5SAndroid Build Coastguard Worker         const angle::Feature feature = featureFromName[featureName];
938*8975f5c5SAndroid Build Coastguard Worker 
939*8975f5c5SAndroid Build Coastguard Worker         const bool isEnabled  = strcmp(featureStatus, angle::kFeatureStatusEnabled) == 0;
940*8975f5c5SAndroid Build Coastguard Worker         const bool isDisabled = strcmp(featureStatus, angle::kFeatureStatusDisabled) == 0;
941*8975f5c5SAndroid Build Coastguard Worker         ASSERT(isEnabled || isDisabled);
942*8975f5c5SAndroid Build Coastguard Worker 
943*8975f5c5SAndroid Build Coastguard Worker         mFeatures[feature] = isEnabled ? ANGLEFeatureStatus::Enabled : ANGLEFeatureStatus::Disabled;
944*8975f5c5SAndroid Build Coastguard Worker     }
945*8975f5c5SAndroid Build Coastguard Worker }
946*8975f5c5SAndroid Build Coastguard Worker 
isFeatureEnabled(angle::Feature feature)947*8975f5c5SAndroid Build Coastguard Worker bool EGLWindow::isFeatureEnabled(angle::Feature feature)
948*8975f5c5SAndroid Build Coastguard Worker {
949*8975f5c5SAndroid Build Coastguard Worker     return mFeatures[feature] == ANGLEFeatureStatus::Enabled;
950*8975f5c5SAndroid Build Coastguard Worker }
951