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 ¶ms)
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 ¶ms)
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