xref: /aosp_15_r20/external/angle/src/libANGLE/validationEGL.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2016 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 // validationEGL.cpp: Validation functions for generic EGL entry point parameters
8*8975f5c5SAndroid Build Coastguard Worker 
9*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/validationEGL_autogen.h"
10*8975f5c5SAndroid Build Coastguard Worker 
11*8975f5c5SAndroid Build Coastguard Worker #include "common/utilities.h"
12*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Config.h"
13*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Context.h"
14*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Device.h"
15*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Display.h"
16*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/EGLSync.h"
17*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Image.h"
18*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Stream.h"
19*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Surface.h"
20*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Texture.h"
21*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Thread.h"
22*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/formatutils.h"
23*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/DisplayImpl.h"
24*8975f5c5SAndroid Build Coastguard Worker 
25*8975f5c5SAndroid Build Coastguard Worker #include <EGL/eglext.h>
26*8975f5c5SAndroid Build Coastguard Worker 
27*8975f5c5SAndroid Build Coastguard Worker namespace egl
28*8975f5c5SAndroid Build Coastguard Worker {
29*8975f5c5SAndroid Build Coastguard Worker namespace
30*8975f5c5SAndroid Build Coastguard Worker {
GetMaximumMipLevel(const gl::Context * context,gl::TextureType type)31*8975f5c5SAndroid Build Coastguard Worker size_t GetMaximumMipLevel(const gl::Context *context, gl::TextureType type)
32*8975f5c5SAndroid Build Coastguard Worker {
33*8975f5c5SAndroid Build Coastguard Worker     const gl::Caps &caps = context->getCaps();
34*8975f5c5SAndroid Build Coastguard Worker 
35*8975f5c5SAndroid Build Coastguard Worker     int maxDimension = 0;
36*8975f5c5SAndroid Build Coastguard Worker     switch (type)
37*8975f5c5SAndroid Build Coastguard Worker     {
38*8975f5c5SAndroid Build Coastguard Worker         case gl::TextureType::_2D:
39*8975f5c5SAndroid Build Coastguard Worker         case gl::TextureType::_2DArray:
40*8975f5c5SAndroid Build Coastguard Worker         case gl::TextureType::_2DMultisample:
41*8975f5c5SAndroid Build Coastguard Worker             maxDimension = caps.max2DTextureSize;
42*8975f5c5SAndroid Build Coastguard Worker             break;
43*8975f5c5SAndroid Build Coastguard Worker         case gl::TextureType::Rectangle:
44*8975f5c5SAndroid Build Coastguard Worker             maxDimension = caps.maxRectangleTextureSize;
45*8975f5c5SAndroid Build Coastguard Worker             break;
46*8975f5c5SAndroid Build Coastguard Worker         case gl::TextureType::CubeMap:
47*8975f5c5SAndroid Build Coastguard Worker             maxDimension = caps.maxCubeMapTextureSize;
48*8975f5c5SAndroid Build Coastguard Worker             break;
49*8975f5c5SAndroid Build Coastguard Worker         case gl::TextureType::_3D:
50*8975f5c5SAndroid Build Coastguard Worker             maxDimension = caps.max3DTextureSize;
51*8975f5c5SAndroid Build Coastguard Worker             break;
52*8975f5c5SAndroid Build Coastguard Worker 
53*8975f5c5SAndroid Build Coastguard Worker         default:
54*8975f5c5SAndroid Build Coastguard Worker             UNREACHABLE();
55*8975f5c5SAndroid Build Coastguard Worker     }
56*8975f5c5SAndroid Build Coastguard Worker 
57*8975f5c5SAndroid Build Coastguard Worker     return gl::log2(maxDimension);
58*8975f5c5SAndroid Build Coastguard Worker }
59*8975f5c5SAndroid Build Coastguard Worker 
TextureHasNonZeroMipLevelsSpecified(const gl::Context * context,const gl::Texture * texture)60*8975f5c5SAndroid Build Coastguard Worker bool TextureHasNonZeroMipLevelsSpecified(const gl::Context *context, const gl::Texture *texture)
61*8975f5c5SAndroid Build Coastguard Worker {
62*8975f5c5SAndroid Build Coastguard Worker     size_t maxMip = GetMaximumMipLevel(context, texture->getType());
63*8975f5c5SAndroid Build Coastguard Worker     for (size_t level = 1; level < maxMip; level++)
64*8975f5c5SAndroid Build Coastguard Worker     {
65*8975f5c5SAndroid Build Coastguard Worker         if (texture->getType() == gl::TextureType::CubeMap)
66*8975f5c5SAndroid Build Coastguard Worker         {
67*8975f5c5SAndroid Build Coastguard Worker             for (gl::TextureTarget face : gl::AllCubeFaceTextureTargets())
68*8975f5c5SAndroid Build Coastguard Worker             {
69*8975f5c5SAndroid Build Coastguard Worker                 if (texture->getFormat(face, level).valid())
70*8975f5c5SAndroid Build Coastguard Worker                 {
71*8975f5c5SAndroid Build Coastguard Worker                     return true;
72*8975f5c5SAndroid Build Coastguard Worker                 }
73*8975f5c5SAndroid Build Coastguard Worker             }
74*8975f5c5SAndroid Build Coastguard Worker         }
75*8975f5c5SAndroid Build Coastguard Worker         else
76*8975f5c5SAndroid Build Coastguard Worker         {
77*8975f5c5SAndroid Build Coastguard Worker             if (texture->getFormat(gl::NonCubeTextureTypeToTarget(texture->getType()), level)
78*8975f5c5SAndroid Build Coastguard Worker                     .valid())
79*8975f5c5SAndroid Build Coastguard Worker             {
80*8975f5c5SAndroid Build Coastguard Worker                 return true;
81*8975f5c5SAndroid Build Coastguard Worker             }
82*8975f5c5SAndroid Build Coastguard Worker         }
83*8975f5c5SAndroid Build Coastguard Worker     }
84*8975f5c5SAndroid Build Coastguard Worker 
85*8975f5c5SAndroid Build Coastguard Worker     return false;
86*8975f5c5SAndroid Build Coastguard Worker }
87*8975f5c5SAndroid Build Coastguard Worker 
CubeTextureHasUnspecifiedLevel0Face(const gl::Texture * texture)88*8975f5c5SAndroid Build Coastguard Worker bool CubeTextureHasUnspecifiedLevel0Face(const gl::Texture *texture)
89*8975f5c5SAndroid Build Coastguard Worker {
90*8975f5c5SAndroid Build Coastguard Worker     ASSERT(texture->getType() == gl::TextureType::CubeMap);
91*8975f5c5SAndroid Build Coastguard Worker     for (gl::TextureTarget face : gl::AllCubeFaceTextureTargets())
92*8975f5c5SAndroid Build Coastguard Worker     {
93*8975f5c5SAndroid Build Coastguard Worker         if (!texture->getFormat(face, 0).valid())
94*8975f5c5SAndroid Build Coastguard Worker         {
95*8975f5c5SAndroid Build Coastguard Worker             return true;
96*8975f5c5SAndroid Build Coastguard Worker         }
97*8975f5c5SAndroid Build Coastguard Worker     }
98*8975f5c5SAndroid Build Coastguard Worker 
99*8975f5c5SAndroid Build Coastguard Worker     return false;
100*8975f5c5SAndroid Build Coastguard Worker }
101*8975f5c5SAndroid Build Coastguard Worker 
ValidateStreamAttribute(const ValidationContext * val,const EGLAttrib attribute,const EGLAttrib value,const DisplayExtensions & extensions)102*8975f5c5SAndroid Build Coastguard Worker bool ValidateStreamAttribute(const ValidationContext *val,
103*8975f5c5SAndroid Build Coastguard Worker                              const EGLAttrib attribute,
104*8975f5c5SAndroid Build Coastguard Worker                              const EGLAttrib value,
105*8975f5c5SAndroid Build Coastguard Worker                              const DisplayExtensions &extensions)
106*8975f5c5SAndroid Build Coastguard Worker {
107*8975f5c5SAndroid Build Coastguard Worker     switch (attribute)
108*8975f5c5SAndroid Build Coastguard Worker     {
109*8975f5c5SAndroid Build Coastguard Worker         case EGL_STREAM_STATE_KHR:
110*8975f5c5SAndroid Build Coastguard Worker         case EGL_PRODUCER_FRAME_KHR:
111*8975f5c5SAndroid Build Coastguard Worker         case EGL_CONSUMER_FRAME_KHR:
112*8975f5c5SAndroid Build Coastguard Worker             val->setError(EGL_BAD_ACCESS, "Attempt to initialize readonly parameter");
113*8975f5c5SAndroid Build Coastguard Worker             return false;
114*8975f5c5SAndroid Build Coastguard Worker         case EGL_CONSUMER_LATENCY_USEC_KHR:
115*8975f5c5SAndroid Build Coastguard Worker             // Technically not in spec but a latency < 0 makes no sense so we check it
116*8975f5c5SAndroid Build Coastguard Worker             if (value < 0)
117*8975f5c5SAndroid Build Coastguard Worker             {
118*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_PARAMETER, "Latency must be positive");
119*8975f5c5SAndroid Build Coastguard Worker                 return false;
120*8975f5c5SAndroid Build Coastguard Worker             }
121*8975f5c5SAndroid Build Coastguard Worker             break;
122*8975f5c5SAndroid Build Coastguard Worker         case EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR:
123*8975f5c5SAndroid Build Coastguard Worker             if (!extensions.streamConsumerGLTexture)
124*8975f5c5SAndroid Build Coastguard Worker             {
125*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE, "Consumer GL extension not enabled");
126*8975f5c5SAndroid Build Coastguard Worker                 return false;
127*8975f5c5SAndroid Build Coastguard Worker             }
128*8975f5c5SAndroid Build Coastguard Worker             // Again not in spec but it should be positive anyways
129*8975f5c5SAndroid Build Coastguard Worker             if (value < 0)
130*8975f5c5SAndroid Build Coastguard Worker             {
131*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_PARAMETER, "Timeout must be positive");
132*8975f5c5SAndroid Build Coastguard Worker                 return false;
133*8975f5c5SAndroid Build Coastguard Worker             }
134*8975f5c5SAndroid Build Coastguard Worker             break;
135*8975f5c5SAndroid Build Coastguard Worker         default:
136*8975f5c5SAndroid Build Coastguard Worker             val->setError(EGL_BAD_ATTRIBUTE, "Invalid stream attribute");
137*8975f5c5SAndroid Build Coastguard Worker             return false;
138*8975f5c5SAndroid Build Coastguard Worker     }
139*8975f5c5SAndroid Build Coastguard Worker     return true;
140*8975f5c5SAndroid Build Coastguard Worker }
141*8975f5c5SAndroid Build Coastguard Worker 
ValidateCreateImageMipLevelCommon(const ValidationContext * val,const gl::Context * context,const gl::Texture * texture,EGLAttrib level)142*8975f5c5SAndroid Build Coastguard Worker bool ValidateCreateImageMipLevelCommon(const ValidationContext *val,
143*8975f5c5SAndroid Build Coastguard Worker                                        const gl::Context *context,
144*8975f5c5SAndroid Build Coastguard Worker                                        const gl::Texture *texture,
145*8975f5c5SAndroid Build Coastguard Worker                                        EGLAttrib level)
146*8975f5c5SAndroid Build Coastguard Worker {
147*8975f5c5SAndroid Build Coastguard Worker     // Note that the spec EGL_create_image spec does not explicitly specify an error
148*8975f5c5SAndroid Build Coastguard Worker     // when the level is outside the base/max level range, but it does mention that the
149*8975f5c5SAndroid Build Coastguard Worker     // level "must be a part of the complete texture object <buffer>". It can be argued
150*8975f5c5SAndroid Build Coastguard Worker     // that out-of-range levels are not a part of the complete texture.
151*8975f5c5SAndroid Build Coastguard Worker     const GLuint effectiveBaseLevel = texture->getTextureState().getEffectiveBaseLevel();
152*8975f5c5SAndroid Build Coastguard Worker     if (level > 0 &&
153*8975f5c5SAndroid Build Coastguard Worker         (!texture->isMipmapComplete() || static_cast<GLuint>(level) < effectiveBaseLevel ||
154*8975f5c5SAndroid Build Coastguard Worker          static_cast<GLuint>(level) > texture->getTextureState().getMipmapMaxLevel()))
155*8975f5c5SAndroid Build Coastguard Worker     {
156*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_PARAMETER, "texture must be complete if level is non-zero.");
157*8975f5c5SAndroid Build Coastguard Worker         return false;
158*8975f5c5SAndroid Build Coastguard Worker     }
159*8975f5c5SAndroid Build Coastguard Worker 
160*8975f5c5SAndroid Build Coastguard Worker     if (level == 0 && !texture->isMipmapComplete() &&
161*8975f5c5SAndroid Build Coastguard Worker         TextureHasNonZeroMipLevelsSpecified(context, texture))
162*8975f5c5SAndroid Build Coastguard Worker     {
163*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_PARAMETER,
164*8975f5c5SAndroid Build Coastguard Worker                       "if level is zero and the texture is incomplete, it must "
165*8975f5c5SAndroid Build Coastguard Worker                       "have no mip levels specified except zero.");
166*8975f5c5SAndroid Build Coastguard Worker         return false;
167*8975f5c5SAndroid Build Coastguard Worker     }
168*8975f5c5SAndroid Build Coastguard Worker 
169*8975f5c5SAndroid Build Coastguard Worker     return true;
170*8975f5c5SAndroid Build Coastguard Worker }
171*8975f5c5SAndroid Build Coastguard Worker 
ValidateConfigAttribute(const ValidationContext * val,const Display * display,EGLAttrib attribute)172*8975f5c5SAndroid Build Coastguard Worker bool ValidateConfigAttribute(const ValidationContext *val,
173*8975f5c5SAndroid Build Coastguard Worker                              const Display *display,
174*8975f5c5SAndroid Build Coastguard Worker                              EGLAttrib attribute)
175*8975f5c5SAndroid Build Coastguard Worker {
176*8975f5c5SAndroid Build Coastguard Worker     switch (attribute)
177*8975f5c5SAndroid Build Coastguard Worker     {
178*8975f5c5SAndroid Build Coastguard Worker         case EGL_BUFFER_SIZE:
179*8975f5c5SAndroid Build Coastguard Worker         case EGL_ALPHA_SIZE:
180*8975f5c5SAndroid Build Coastguard Worker         case EGL_BLUE_SIZE:
181*8975f5c5SAndroid Build Coastguard Worker         case EGL_GREEN_SIZE:
182*8975f5c5SAndroid Build Coastguard Worker         case EGL_RED_SIZE:
183*8975f5c5SAndroid Build Coastguard Worker         case EGL_DEPTH_SIZE:
184*8975f5c5SAndroid Build Coastguard Worker         case EGL_STENCIL_SIZE:
185*8975f5c5SAndroid Build Coastguard Worker         case EGL_CONFIG_CAVEAT:
186*8975f5c5SAndroid Build Coastguard Worker         case EGL_CONFIG_ID:
187*8975f5c5SAndroid Build Coastguard Worker         case EGL_LEVEL:
188*8975f5c5SAndroid Build Coastguard Worker         case EGL_NATIVE_RENDERABLE:
189*8975f5c5SAndroid Build Coastguard Worker         case EGL_NATIVE_VISUAL_ID:
190*8975f5c5SAndroid Build Coastguard Worker         case EGL_NATIVE_VISUAL_TYPE:
191*8975f5c5SAndroid Build Coastguard Worker         case EGL_SAMPLES:
192*8975f5c5SAndroid Build Coastguard Worker         case EGL_SAMPLE_BUFFERS:
193*8975f5c5SAndroid Build Coastguard Worker         case EGL_SURFACE_TYPE:
194*8975f5c5SAndroid Build Coastguard Worker         case EGL_TRANSPARENT_TYPE:
195*8975f5c5SAndroid Build Coastguard Worker         case EGL_TRANSPARENT_BLUE_VALUE:
196*8975f5c5SAndroid Build Coastguard Worker         case EGL_TRANSPARENT_GREEN_VALUE:
197*8975f5c5SAndroid Build Coastguard Worker         case EGL_TRANSPARENT_RED_VALUE:
198*8975f5c5SAndroid Build Coastguard Worker         case EGL_BIND_TO_TEXTURE_RGB:
199*8975f5c5SAndroid Build Coastguard Worker         case EGL_BIND_TO_TEXTURE_RGBA:
200*8975f5c5SAndroid Build Coastguard Worker         case EGL_MIN_SWAP_INTERVAL:
201*8975f5c5SAndroid Build Coastguard Worker         case EGL_MAX_SWAP_INTERVAL:
202*8975f5c5SAndroid Build Coastguard Worker         case EGL_LUMINANCE_SIZE:
203*8975f5c5SAndroid Build Coastguard Worker         case EGL_ALPHA_MASK_SIZE:
204*8975f5c5SAndroid Build Coastguard Worker         case EGL_COLOR_BUFFER_TYPE:
205*8975f5c5SAndroid Build Coastguard Worker         case EGL_RENDERABLE_TYPE:
206*8975f5c5SAndroid Build Coastguard Worker         case EGL_MATCH_NATIVE_PIXMAP:
207*8975f5c5SAndroid Build Coastguard Worker         case EGL_CONFORMANT:
208*8975f5c5SAndroid Build Coastguard Worker         case EGL_MAX_PBUFFER_WIDTH:
209*8975f5c5SAndroid Build Coastguard Worker         case EGL_MAX_PBUFFER_HEIGHT:
210*8975f5c5SAndroid Build Coastguard Worker         case EGL_MAX_PBUFFER_PIXELS:
211*8975f5c5SAndroid Build Coastguard Worker             break;
212*8975f5c5SAndroid Build Coastguard Worker 
213*8975f5c5SAndroid Build Coastguard Worker         case EGL_OPTIMAL_SURFACE_ORIENTATION_ANGLE:
214*8975f5c5SAndroid Build Coastguard Worker             if (!display->getExtensions().surfaceOrientation)
215*8975f5c5SAndroid Build Coastguard Worker             {
216*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE, "EGL_ANGLE_surface_orientation is not enabled.");
217*8975f5c5SAndroid Build Coastguard Worker                 return false;
218*8975f5c5SAndroid Build Coastguard Worker             }
219*8975f5c5SAndroid Build Coastguard Worker             break;
220*8975f5c5SAndroid Build Coastguard Worker 
221*8975f5c5SAndroid Build Coastguard Worker         case EGL_COLOR_COMPONENT_TYPE_EXT:
222*8975f5c5SAndroid Build Coastguard Worker             if (!display->getExtensions().pixelFormatFloat)
223*8975f5c5SAndroid Build Coastguard Worker             {
224*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE, "EGL_EXT_pixel_format_float is not enabled.");
225*8975f5c5SAndroid Build Coastguard Worker                 return false;
226*8975f5c5SAndroid Build Coastguard Worker             }
227*8975f5c5SAndroid Build Coastguard Worker             break;
228*8975f5c5SAndroid Build Coastguard Worker 
229*8975f5c5SAndroid Build Coastguard Worker         case EGL_RECORDABLE_ANDROID:
230*8975f5c5SAndroid Build Coastguard Worker             if (!display->getExtensions().recordable)
231*8975f5c5SAndroid Build Coastguard Worker             {
232*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE, "EGL_ANDROID_recordable is not enabled.");
233*8975f5c5SAndroid Build Coastguard Worker                 return false;
234*8975f5c5SAndroid Build Coastguard Worker             }
235*8975f5c5SAndroid Build Coastguard Worker             break;
236*8975f5c5SAndroid Build Coastguard Worker 
237*8975f5c5SAndroid Build Coastguard Worker         case EGL_FRAMEBUFFER_TARGET_ANDROID:
238*8975f5c5SAndroid Build Coastguard Worker             if (!display->getExtensions().framebufferTargetANDROID)
239*8975f5c5SAndroid Build Coastguard Worker             {
240*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE, "EGL_ANDROID_framebuffer_target is not enabled.");
241*8975f5c5SAndroid Build Coastguard Worker                 return false;
242*8975f5c5SAndroid Build Coastguard Worker             }
243*8975f5c5SAndroid Build Coastguard Worker             break;
244*8975f5c5SAndroid Build Coastguard Worker 
245*8975f5c5SAndroid Build Coastguard Worker         case EGL_BIND_TO_TEXTURE_TARGET_ANGLE:
246*8975f5c5SAndroid Build Coastguard Worker             if (!display->getExtensions().iosurfaceClientBuffer)
247*8975f5c5SAndroid Build Coastguard Worker             {
248*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE,
249*8975f5c5SAndroid Build Coastguard Worker                               "EGL_ANGLE_iosurface_client_buffer is not enabled.");
250*8975f5c5SAndroid Build Coastguard Worker                 return false;
251*8975f5c5SAndroid Build Coastguard Worker             }
252*8975f5c5SAndroid Build Coastguard Worker             break;
253*8975f5c5SAndroid Build Coastguard Worker 
254*8975f5c5SAndroid Build Coastguard Worker         case EGL_Y_INVERTED_NOK:
255*8975f5c5SAndroid Build Coastguard Worker             if (!display->getExtensions().textureFromPixmapNOK)
256*8975f5c5SAndroid Build Coastguard Worker             {
257*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE, "EGL_NOK_texture_from_pixmap is not enabled.");
258*8975f5c5SAndroid Build Coastguard Worker                 return false;
259*8975f5c5SAndroid Build Coastguard Worker             }
260*8975f5c5SAndroid Build Coastguard Worker             break;
261*8975f5c5SAndroid Build Coastguard Worker 
262*8975f5c5SAndroid Build Coastguard Worker         case EGL_MATCH_FORMAT_KHR:
263*8975f5c5SAndroid Build Coastguard Worker             if (!display->getExtensions().lockSurface3KHR)
264*8975f5c5SAndroid Build Coastguard Worker             {
265*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE, "EGL_KHR_lock_surface3 is not enabled.");
266*8975f5c5SAndroid Build Coastguard Worker                 return false;
267*8975f5c5SAndroid Build Coastguard Worker             }
268*8975f5c5SAndroid Build Coastguard Worker             break;
269*8975f5c5SAndroid Build Coastguard Worker 
270*8975f5c5SAndroid Build Coastguard Worker         default:
271*8975f5c5SAndroid Build Coastguard Worker             val->setError(EGL_BAD_ATTRIBUTE, "Unknown attribute: 0x%04" PRIxPTR "X", attribute);
272*8975f5c5SAndroid Build Coastguard Worker             return false;
273*8975f5c5SAndroid Build Coastguard Worker     }
274*8975f5c5SAndroid Build Coastguard Worker 
275*8975f5c5SAndroid Build Coastguard Worker     return true;
276*8975f5c5SAndroid Build Coastguard Worker }
277*8975f5c5SAndroid Build Coastguard Worker 
ValidateConfigAttributeValue(const ValidationContext * val,const Display * display,EGLAttrib attribute,EGLAttrib value)278*8975f5c5SAndroid Build Coastguard Worker bool ValidateConfigAttributeValue(const ValidationContext *val,
279*8975f5c5SAndroid Build Coastguard Worker                                   const Display *display,
280*8975f5c5SAndroid Build Coastguard Worker                                   EGLAttrib attribute,
281*8975f5c5SAndroid Build Coastguard Worker                                   EGLAttrib value)
282*8975f5c5SAndroid Build Coastguard Worker {
283*8975f5c5SAndroid Build Coastguard Worker     switch (attribute)
284*8975f5c5SAndroid Build Coastguard Worker     {
285*8975f5c5SAndroid Build Coastguard Worker 
286*8975f5c5SAndroid Build Coastguard Worker         case EGL_BIND_TO_TEXTURE_RGB:
287*8975f5c5SAndroid Build Coastguard Worker         case EGL_BIND_TO_TEXTURE_RGBA:
288*8975f5c5SAndroid Build Coastguard Worker             switch (value)
289*8975f5c5SAndroid Build Coastguard Worker             {
290*8975f5c5SAndroid Build Coastguard Worker                 case EGL_DONT_CARE:
291*8975f5c5SAndroid Build Coastguard Worker                 case EGL_TRUE:
292*8975f5c5SAndroid Build Coastguard Worker                 case EGL_FALSE:
293*8975f5c5SAndroid Build Coastguard Worker                     break;
294*8975f5c5SAndroid Build Coastguard Worker                 default:
295*8975f5c5SAndroid Build Coastguard Worker                     val->setError(EGL_BAD_ATTRIBUTE, "EGL_bind_to_texture invalid attribute: 0x%X",
296*8975f5c5SAndroid Build Coastguard Worker                                   static_cast<uint32_t>(value));
297*8975f5c5SAndroid Build Coastguard Worker                     return false;
298*8975f5c5SAndroid Build Coastguard Worker             }
299*8975f5c5SAndroid Build Coastguard Worker             break;
300*8975f5c5SAndroid Build Coastguard Worker 
301*8975f5c5SAndroid Build Coastguard Worker         case EGL_COLOR_BUFFER_TYPE:
302*8975f5c5SAndroid Build Coastguard Worker             switch (value)
303*8975f5c5SAndroid Build Coastguard Worker             {
304*8975f5c5SAndroid Build Coastguard Worker                 case EGL_RGB_BUFFER:
305*8975f5c5SAndroid Build Coastguard Worker                 case EGL_LUMINANCE_BUFFER:
306*8975f5c5SAndroid Build Coastguard Worker                 // EGL_DONT_CARE doesn't match the spec, but does match dEQP usage
307*8975f5c5SAndroid Build Coastguard Worker                 case EGL_DONT_CARE:
308*8975f5c5SAndroid Build Coastguard Worker                     break;
309*8975f5c5SAndroid Build Coastguard Worker                 default:
310*8975f5c5SAndroid Build Coastguard Worker                     val->setError(EGL_BAD_ATTRIBUTE,
311*8975f5c5SAndroid Build Coastguard Worker                                   "EGL_color_buffer_type invalid attribute: 0x%X",
312*8975f5c5SAndroid Build Coastguard Worker                                   static_cast<uint32_t>(value));
313*8975f5c5SAndroid Build Coastguard Worker                     return false;
314*8975f5c5SAndroid Build Coastguard Worker             }
315*8975f5c5SAndroid Build Coastguard Worker             break;
316*8975f5c5SAndroid Build Coastguard Worker 
317*8975f5c5SAndroid Build Coastguard Worker         case EGL_NATIVE_RENDERABLE:
318*8975f5c5SAndroid Build Coastguard Worker             switch (value)
319*8975f5c5SAndroid Build Coastguard Worker             {
320*8975f5c5SAndroid Build Coastguard Worker                 case EGL_DONT_CARE:
321*8975f5c5SAndroid Build Coastguard Worker                 case EGL_TRUE:
322*8975f5c5SAndroid Build Coastguard Worker                 case EGL_FALSE:
323*8975f5c5SAndroid Build Coastguard Worker                     break;
324*8975f5c5SAndroid Build Coastguard Worker                 default:
325*8975f5c5SAndroid Build Coastguard Worker                     val->setError(EGL_BAD_ATTRIBUTE,
326*8975f5c5SAndroid Build Coastguard Worker                                   "EGL_native_renderable invalid attribute: 0x%X",
327*8975f5c5SAndroid Build Coastguard Worker                                   static_cast<uint32_t>(value));
328*8975f5c5SAndroid Build Coastguard Worker                     return false;
329*8975f5c5SAndroid Build Coastguard Worker             }
330*8975f5c5SAndroid Build Coastguard Worker             break;
331*8975f5c5SAndroid Build Coastguard Worker 
332*8975f5c5SAndroid Build Coastguard Worker         case EGL_TRANSPARENT_TYPE:
333*8975f5c5SAndroid Build Coastguard Worker             switch (value)
334*8975f5c5SAndroid Build Coastguard Worker             {
335*8975f5c5SAndroid Build Coastguard Worker                 case EGL_NONE:
336*8975f5c5SAndroid Build Coastguard Worker                 case EGL_TRANSPARENT_RGB:
337*8975f5c5SAndroid Build Coastguard Worker                 // EGL_DONT_CARE doesn't match the spec, but does match dEQP usage
338*8975f5c5SAndroid Build Coastguard Worker                 case EGL_DONT_CARE:
339*8975f5c5SAndroid Build Coastguard Worker                     break;
340*8975f5c5SAndroid Build Coastguard Worker                 default:
341*8975f5c5SAndroid Build Coastguard Worker                     val->setError(EGL_BAD_ATTRIBUTE, "EGL_transparent_type invalid attribute: 0x%X",
342*8975f5c5SAndroid Build Coastguard Worker                                   static_cast<uint32_t>(value));
343*8975f5c5SAndroid Build Coastguard Worker                     return false;
344*8975f5c5SAndroid Build Coastguard Worker             }
345*8975f5c5SAndroid Build Coastguard Worker             break;
346*8975f5c5SAndroid Build Coastguard Worker 
347*8975f5c5SAndroid Build Coastguard Worker         case EGL_RECORDABLE_ANDROID:
348*8975f5c5SAndroid Build Coastguard Worker             switch (value)
349*8975f5c5SAndroid Build Coastguard Worker             {
350*8975f5c5SAndroid Build Coastguard Worker                 case EGL_TRUE:
351*8975f5c5SAndroid Build Coastguard Worker                 case EGL_FALSE:
352*8975f5c5SAndroid Build Coastguard Worker                 case EGL_DONT_CARE:
353*8975f5c5SAndroid Build Coastguard Worker                     break;
354*8975f5c5SAndroid Build Coastguard Worker                 default:
355*8975f5c5SAndroid Build Coastguard Worker                     val->setError(EGL_BAD_ATTRIBUTE,
356*8975f5c5SAndroid Build Coastguard Worker                                   "EGL_RECORDABLE_ANDROID invalid attribute: 0x%X",
357*8975f5c5SAndroid Build Coastguard Worker                                   static_cast<uint32_t>(value));
358*8975f5c5SAndroid Build Coastguard Worker                     return false;
359*8975f5c5SAndroid Build Coastguard Worker             }
360*8975f5c5SAndroid Build Coastguard Worker             break;
361*8975f5c5SAndroid Build Coastguard Worker 
362*8975f5c5SAndroid Build Coastguard Worker         case EGL_COLOR_COMPONENT_TYPE_EXT:
363*8975f5c5SAndroid Build Coastguard Worker             switch (value)
364*8975f5c5SAndroid Build Coastguard Worker             {
365*8975f5c5SAndroid Build Coastguard Worker                 case EGL_COLOR_COMPONENT_TYPE_FIXED_EXT:
366*8975f5c5SAndroid Build Coastguard Worker                 case EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT:
367*8975f5c5SAndroid Build Coastguard Worker                 case EGL_DONT_CARE:
368*8975f5c5SAndroid Build Coastguard Worker                     break;
369*8975f5c5SAndroid Build Coastguard Worker                 default:
370*8975f5c5SAndroid Build Coastguard Worker                     val->setError(EGL_BAD_ATTRIBUTE,
371*8975f5c5SAndroid Build Coastguard Worker                                   "EGL_COLOR_COMPONENT_TYPE_EXT invalid attribute: 0x%X",
372*8975f5c5SAndroid Build Coastguard Worker                                   static_cast<uint32_t>(value));
373*8975f5c5SAndroid Build Coastguard Worker                     return false;
374*8975f5c5SAndroid Build Coastguard Worker             }
375*8975f5c5SAndroid Build Coastguard Worker             break;
376*8975f5c5SAndroid Build Coastguard Worker 
377*8975f5c5SAndroid Build Coastguard Worker         case EGL_MATCH_FORMAT_KHR:
378*8975f5c5SAndroid Build Coastguard Worker             switch (value)
379*8975f5c5SAndroid Build Coastguard Worker             {
380*8975f5c5SAndroid Build Coastguard Worker                 case EGL_FORMAT_RGB_565_KHR:
381*8975f5c5SAndroid Build Coastguard Worker                 case EGL_FORMAT_RGBA_8888_KHR:
382*8975f5c5SAndroid Build Coastguard Worker                 case EGL_FORMAT_RGB_565_EXACT_KHR:
383*8975f5c5SAndroid Build Coastguard Worker                 case EGL_FORMAT_RGBA_8888_EXACT_KHR:
384*8975f5c5SAndroid Build Coastguard Worker                     break;
385*8975f5c5SAndroid Build Coastguard Worker                 default:
386*8975f5c5SAndroid Build Coastguard Worker                     val->setError(EGL_BAD_ATTRIBUTE,
387*8975f5c5SAndroid Build Coastguard Worker                                   "EGL_KHR_lock_surface3 invalid attribute: 0x%X",
388*8975f5c5SAndroid Build Coastguard Worker                                   static_cast<uint32_t>(value));
389*8975f5c5SAndroid Build Coastguard Worker                     return false;
390*8975f5c5SAndroid Build Coastguard Worker             }
391*8975f5c5SAndroid Build Coastguard Worker             break;
392*8975f5c5SAndroid Build Coastguard Worker 
393*8975f5c5SAndroid Build Coastguard Worker         default:
394*8975f5c5SAndroid Build Coastguard Worker             break;
395*8975f5c5SAndroid Build Coastguard Worker     }
396*8975f5c5SAndroid Build Coastguard Worker 
397*8975f5c5SAndroid Build Coastguard Worker     return true;
398*8975f5c5SAndroid Build Coastguard Worker }
399*8975f5c5SAndroid Build Coastguard Worker 
ValidateConfigAttributes(const ValidationContext * val,const Display * display,const AttributeMap & attributes)400*8975f5c5SAndroid Build Coastguard Worker bool ValidateConfigAttributes(const ValidationContext *val,
401*8975f5c5SAndroid Build Coastguard Worker                               const Display *display,
402*8975f5c5SAndroid Build Coastguard Worker                               const AttributeMap &attributes)
403*8975f5c5SAndroid Build Coastguard Worker {
404*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(attributes.validate(val, display, ValidateConfigAttribute));
405*8975f5c5SAndroid Build Coastguard Worker 
406*8975f5c5SAndroid Build Coastguard Worker     for (const auto &attrib : attributes)
407*8975f5c5SAndroid Build Coastguard Worker     {
408*8975f5c5SAndroid Build Coastguard Worker         EGLAttrib pname = attrib.first;
409*8975f5c5SAndroid Build Coastguard Worker         EGLAttrib value = attrib.second;
410*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_TRY(ValidateConfigAttributeValue(val, display, pname, value));
411*8975f5c5SAndroid Build Coastguard Worker     }
412*8975f5c5SAndroid Build Coastguard Worker 
413*8975f5c5SAndroid Build Coastguard Worker     return true;
414*8975f5c5SAndroid Build Coastguard Worker }
415*8975f5c5SAndroid Build Coastguard Worker 
ValidateColorspaceAttribute(const ValidationContext * val,const DisplayExtensions & displayExtensions,EGLAttrib colorSpace)416*8975f5c5SAndroid Build Coastguard Worker bool ValidateColorspaceAttribute(const ValidationContext *val,
417*8975f5c5SAndroid Build Coastguard Worker                                  const DisplayExtensions &displayExtensions,
418*8975f5c5SAndroid Build Coastguard Worker                                  EGLAttrib colorSpace)
419*8975f5c5SAndroid Build Coastguard Worker {
420*8975f5c5SAndroid Build Coastguard Worker     switch (colorSpace)
421*8975f5c5SAndroid Build Coastguard Worker     {
422*8975f5c5SAndroid Build Coastguard Worker         case EGL_GL_COLORSPACE_SRGB:
423*8975f5c5SAndroid Build Coastguard Worker             break;
424*8975f5c5SAndroid Build Coastguard Worker         case EGL_GL_COLORSPACE_LINEAR:
425*8975f5c5SAndroid Build Coastguard Worker             break;
426*8975f5c5SAndroid Build Coastguard Worker         case EGL_GL_COLORSPACE_DISPLAY_P3_LINEAR_EXT:
427*8975f5c5SAndroid Build Coastguard Worker             if (!displayExtensions.glColorspaceDisplayP3Linear &&
428*8975f5c5SAndroid Build Coastguard Worker                 !displayExtensions.eglColorspaceAttributePassthroughANGLE)
429*8975f5c5SAndroid Build Coastguard Worker             {
430*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE,
431*8975f5c5SAndroid Build Coastguard Worker                               "EXT_gl_colorspace_display_p3_linear is not available.");
432*8975f5c5SAndroid Build Coastguard Worker                 return false;
433*8975f5c5SAndroid Build Coastguard Worker             }
434*8975f5c5SAndroid Build Coastguard Worker             break;
435*8975f5c5SAndroid Build Coastguard Worker         case EGL_GL_COLORSPACE_DISPLAY_P3_EXT:
436*8975f5c5SAndroid Build Coastguard Worker             if (!displayExtensions.glColorspaceDisplayP3 &&
437*8975f5c5SAndroid Build Coastguard Worker                 !displayExtensions.eglColorspaceAttributePassthroughANGLE)
438*8975f5c5SAndroid Build Coastguard Worker             {
439*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE, "EXT_gl_colorspace_display_p3 is not available.");
440*8975f5c5SAndroid Build Coastguard Worker                 return false;
441*8975f5c5SAndroid Build Coastguard Worker             }
442*8975f5c5SAndroid Build Coastguard Worker             break;
443*8975f5c5SAndroid Build Coastguard Worker         case EGL_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH_EXT:
444*8975f5c5SAndroid Build Coastguard Worker             if (!displayExtensions.glColorspaceDisplayP3Passthrough &&
445*8975f5c5SAndroid Build Coastguard Worker                 !displayExtensions.eglColorspaceAttributePassthroughANGLE)
446*8975f5c5SAndroid Build Coastguard Worker             {
447*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE,
448*8975f5c5SAndroid Build Coastguard Worker                               "EGL_EXT_gl_colorspace_display_p3_passthrough is not available.");
449*8975f5c5SAndroid Build Coastguard Worker                 return false;
450*8975f5c5SAndroid Build Coastguard Worker             }
451*8975f5c5SAndroid Build Coastguard Worker             break;
452*8975f5c5SAndroid Build Coastguard Worker         case EGL_GL_COLORSPACE_SCRGB_EXT:
453*8975f5c5SAndroid Build Coastguard Worker             if (!displayExtensions.glColorspaceScrgb &&
454*8975f5c5SAndroid Build Coastguard Worker                 !displayExtensions.eglColorspaceAttributePassthroughANGLE)
455*8975f5c5SAndroid Build Coastguard Worker             {
456*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE, "EXT_gl_colorspace_scrgb is not available.");
457*8975f5c5SAndroid Build Coastguard Worker                 return false;
458*8975f5c5SAndroid Build Coastguard Worker             }
459*8975f5c5SAndroid Build Coastguard Worker             break;
460*8975f5c5SAndroid Build Coastguard Worker         case EGL_GL_COLORSPACE_SCRGB_LINEAR_EXT:
461*8975f5c5SAndroid Build Coastguard Worker             if (!displayExtensions.glColorspaceScrgbLinear &&
462*8975f5c5SAndroid Build Coastguard Worker                 !displayExtensions.eglColorspaceAttributePassthroughANGLE)
463*8975f5c5SAndroid Build Coastguard Worker             {
464*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE,
465*8975f5c5SAndroid Build Coastguard Worker                               "EXT_gl_colorspace_scrgb_linear is not available.");
466*8975f5c5SAndroid Build Coastguard Worker                 return false;
467*8975f5c5SAndroid Build Coastguard Worker             }
468*8975f5c5SAndroid Build Coastguard Worker             break;
469*8975f5c5SAndroid Build Coastguard Worker         case EGL_GL_COLORSPACE_BT2020_LINEAR_EXT:
470*8975f5c5SAndroid Build Coastguard Worker             if (!displayExtensions.glColorspaceBt2020Linear &&
471*8975f5c5SAndroid Build Coastguard Worker                 !displayExtensions.eglColorspaceAttributePassthroughANGLE)
472*8975f5c5SAndroid Build Coastguard Worker             {
473*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE,
474*8975f5c5SAndroid Build Coastguard Worker                               "EXT_gl_colorspace_bt2020_linear is not available");
475*8975f5c5SAndroid Build Coastguard Worker                 return false;
476*8975f5c5SAndroid Build Coastguard Worker             }
477*8975f5c5SAndroid Build Coastguard Worker             break;
478*8975f5c5SAndroid Build Coastguard Worker         case EGL_GL_COLORSPACE_BT2020_PQ_EXT:
479*8975f5c5SAndroid Build Coastguard Worker             if (!displayExtensions.glColorspaceBt2020Pq &&
480*8975f5c5SAndroid Build Coastguard Worker                 !displayExtensions.eglColorspaceAttributePassthroughANGLE)
481*8975f5c5SAndroid Build Coastguard Worker             {
482*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE, "EXT_gl_colorspace_bt2020_pq is not available");
483*8975f5c5SAndroid Build Coastguard Worker                 return false;
484*8975f5c5SAndroid Build Coastguard Worker             }
485*8975f5c5SAndroid Build Coastguard Worker             break;
486*8975f5c5SAndroid Build Coastguard Worker         case EGL_GL_COLORSPACE_BT2020_HLG_EXT:
487*8975f5c5SAndroid Build Coastguard Worker             if (!displayExtensions.glColorspaceBt2020Hlg &&
488*8975f5c5SAndroid Build Coastguard Worker                 !displayExtensions.eglColorspaceAttributePassthroughANGLE)
489*8975f5c5SAndroid Build Coastguard Worker             {
490*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE, "EXT_gl_colorspace_bt2020_hlg is not available");
491*8975f5c5SAndroid Build Coastguard Worker                 return false;
492*8975f5c5SAndroid Build Coastguard Worker             }
493*8975f5c5SAndroid Build Coastguard Worker             break;
494*8975f5c5SAndroid Build Coastguard Worker         default:
495*8975f5c5SAndroid Build Coastguard Worker             val->setError(EGL_BAD_ATTRIBUTE);
496*8975f5c5SAndroid Build Coastguard Worker             return false;
497*8975f5c5SAndroid Build Coastguard Worker     }
498*8975f5c5SAndroid Build Coastguard Worker     return true;
499*8975f5c5SAndroid Build Coastguard Worker }
ValidatePlatformType(const ValidationContext * val,const ClientExtensions & clientExtensions,EGLAttrib platformType)500*8975f5c5SAndroid Build Coastguard Worker bool ValidatePlatformType(const ValidationContext *val,
501*8975f5c5SAndroid Build Coastguard Worker                           const ClientExtensions &clientExtensions,
502*8975f5c5SAndroid Build Coastguard Worker                           EGLAttrib platformType)
503*8975f5c5SAndroid Build Coastguard Worker {
504*8975f5c5SAndroid Build Coastguard Worker     switch (platformType)
505*8975f5c5SAndroid Build Coastguard Worker     {
506*8975f5c5SAndroid Build Coastguard Worker         case EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE:
507*8975f5c5SAndroid Build Coastguard Worker             break;
508*8975f5c5SAndroid Build Coastguard Worker 
509*8975f5c5SAndroid Build Coastguard Worker         case EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE:
510*8975f5c5SAndroid Build Coastguard Worker         case EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE:
511*8975f5c5SAndroid Build Coastguard Worker             if (!clientExtensions.platformANGLED3D)
512*8975f5c5SAndroid Build Coastguard Worker             {
513*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE, "Direct3D platform is unsupported.");
514*8975f5c5SAndroid Build Coastguard Worker                 return false;
515*8975f5c5SAndroid Build Coastguard Worker             }
516*8975f5c5SAndroid Build Coastguard Worker             break;
517*8975f5c5SAndroid Build Coastguard Worker 
518*8975f5c5SAndroid Build Coastguard Worker         case EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE:
519*8975f5c5SAndroid Build Coastguard Worker         case EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE:
520*8975f5c5SAndroid Build Coastguard Worker             if (!clientExtensions.platformANGLEOpenGL)
521*8975f5c5SAndroid Build Coastguard Worker             {
522*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE, "OpenGL platform is unsupported.");
523*8975f5c5SAndroid Build Coastguard Worker                 return false;
524*8975f5c5SAndroid Build Coastguard Worker             }
525*8975f5c5SAndroid Build Coastguard Worker             break;
526*8975f5c5SAndroid Build Coastguard Worker 
527*8975f5c5SAndroid Build Coastguard Worker         case EGL_PLATFORM_ANGLE_TYPE_NULL_ANGLE:
528*8975f5c5SAndroid Build Coastguard Worker             if (!clientExtensions.platformANGLENULL)
529*8975f5c5SAndroid Build Coastguard Worker             {
530*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE,
531*8975f5c5SAndroid Build Coastguard Worker                               "Display type EGL_PLATFORM_ANGLE_TYPE_NULL_ANGLE "
532*8975f5c5SAndroid Build Coastguard Worker                               "requires EGL_ANGLE_platform_angle_null.");
533*8975f5c5SAndroid Build Coastguard Worker                 return false;
534*8975f5c5SAndroid Build Coastguard Worker             }
535*8975f5c5SAndroid Build Coastguard Worker             break;
536*8975f5c5SAndroid Build Coastguard Worker 
537*8975f5c5SAndroid Build Coastguard Worker         case EGL_PLATFORM_ANGLE_TYPE_WEBGPU_ANGLE:
538*8975f5c5SAndroid Build Coastguard Worker             if (!clientExtensions.platformANGLEWebgpu)
539*8975f5c5SAndroid Build Coastguard Worker             {
540*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE, "WebGPU platform is unsupported.");
541*8975f5c5SAndroid Build Coastguard Worker                 return false;
542*8975f5c5SAndroid Build Coastguard Worker             }
543*8975f5c5SAndroid Build Coastguard Worker             break;
544*8975f5c5SAndroid Build Coastguard Worker 
545*8975f5c5SAndroid Build Coastguard Worker         case EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE:
546*8975f5c5SAndroid Build Coastguard Worker             if (!clientExtensions.platformANGLEVulkan)
547*8975f5c5SAndroid Build Coastguard Worker             {
548*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE, "Vulkan platform is unsupported.");
549*8975f5c5SAndroid Build Coastguard Worker                 return false;
550*8975f5c5SAndroid Build Coastguard Worker             }
551*8975f5c5SAndroid Build Coastguard Worker             break;
552*8975f5c5SAndroid Build Coastguard Worker 
553*8975f5c5SAndroid Build Coastguard Worker         case EGL_PLATFORM_ANGLE_TYPE_METAL_ANGLE:
554*8975f5c5SAndroid Build Coastguard Worker             if (!clientExtensions.platformANGLEMetal)
555*8975f5c5SAndroid Build Coastguard Worker             {
556*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE, "Metal platform is unsupported.");
557*8975f5c5SAndroid Build Coastguard Worker                 return false;
558*8975f5c5SAndroid Build Coastguard Worker             }
559*8975f5c5SAndroid Build Coastguard Worker             break;
560*8975f5c5SAndroid Build Coastguard Worker 
561*8975f5c5SAndroid Build Coastguard Worker         default:
562*8975f5c5SAndroid Build Coastguard Worker             val->setError(EGL_BAD_ATTRIBUTE, "Unknown platform type.");
563*8975f5c5SAndroid Build Coastguard Worker             return false;
564*8975f5c5SAndroid Build Coastguard Worker     }
565*8975f5c5SAndroid Build Coastguard Worker 
566*8975f5c5SAndroid Build Coastguard Worker     return true;
567*8975f5c5SAndroid Build Coastguard Worker }
568*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetPlatformDisplayCommon(const ValidationContext * val,EGLenum platform,const void * native_display,const AttributeMap & attribMap)569*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetPlatformDisplayCommon(const ValidationContext *val,
570*8975f5c5SAndroid Build Coastguard Worker                                       EGLenum platform,
571*8975f5c5SAndroid Build Coastguard Worker                                       const void *native_display,
572*8975f5c5SAndroid Build Coastguard Worker                                       const AttributeMap &attribMap)
573*8975f5c5SAndroid Build Coastguard Worker {
574*8975f5c5SAndroid Build Coastguard Worker     const ClientExtensions &clientExtensions = Display::GetClientExtensions();
575*8975f5c5SAndroid Build Coastguard Worker 
576*8975f5c5SAndroid Build Coastguard Worker     switch (platform)
577*8975f5c5SAndroid Build Coastguard Worker     {
578*8975f5c5SAndroid Build Coastguard Worker         case EGL_PLATFORM_ANGLE_ANGLE:
579*8975f5c5SAndroid Build Coastguard Worker             if (!clientExtensions.platformANGLE)
580*8975f5c5SAndroid Build Coastguard Worker             {
581*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_PARAMETER, "Platform ANGLE extension is not active");
582*8975f5c5SAndroid Build Coastguard Worker                 return false;
583*8975f5c5SAndroid Build Coastguard Worker             }
584*8975f5c5SAndroid Build Coastguard Worker             break;
585*8975f5c5SAndroid Build Coastguard Worker         case EGL_PLATFORM_DEVICE_EXT:
586*8975f5c5SAndroid Build Coastguard Worker             if (!clientExtensions.platformDevice)
587*8975f5c5SAndroid Build Coastguard Worker             {
588*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_PARAMETER, "Platform Device extension is not active");
589*8975f5c5SAndroid Build Coastguard Worker                 return false;
590*8975f5c5SAndroid Build Coastguard Worker             }
591*8975f5c5SAndroid Build Coastguard Worker             break;
592*8975f5c5SAndroid Build Coastguard Worker         case EGL_PLATFORM_GBM_KHR:
593*8975f5c5SAndroid Build Coastguard Worker             if (!clientExtensions.platformGbmKHR)
594*8975f5c5SAndroid Build Coastguard Worker             {
595*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_PARAMETER, "Platform GBM extension is not active");
596*8975f5c5SAndroid Build Coastguard Worker                 return false;
597*8975f5c5SAndroid Build Coastguard Worker             }
598*8975f5c5SAndroid Build Coastguard Worker             break;
599*8975f5c5SAndroid Build Coastguard Worker         case EGL_PLATFORM_WAYLAND_EXT:
600*8975f5c5SAndroid Build Coastguard Worker             if (!clientExtensions.platformWaylandEXT)
601*8975f5c5SAndroid Build Coastguard Worker             {
602*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_PARAMETER, "Platform Wayland extension is not active");
603*8975f5c5SAndroid Build Coastguard Worker                 return false;
604*8975f5c5SAndroid Build Coastguard Worker             }
605*8975f5c5SAndroid Build Coastguard Worker             break;
606*8975f5c5SAndroid Build Coastguard Worker         case EGL_PLATFORM_SURFACELESS_MESA:
607*8975f5c5SAndroid Build Coastguard Worker             if (!clientExtensions.platformSurfacelessMESA)
608*8975f5c5SAndroid Build Coastguard Worker             {
609*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_PARAMETER, "Platform Surfaceless extension is not active");
610*8975f5c5SAndroid Build Coastguard Worker                 return false;
611*8975f5c5SAndroid Build Coastguard Worker             }
612*8975f5c5SAndroid Build Coastguard Worker             break;
613*8975f5c5SAndroid Build Coastguard Worker         default:
614*8975f5c5SAndroid Build Coastguard Worker             val->setError(EGL_BAD_CONFIG, "Bad platform type.");
615*8975f5c5SAndroid Build Coastguard Worker             return false;
616*8975f5c5SAndroid Build Coastguard Worker     }
617*8975f5c5SAndroid Build Coastguard Worker 
618*8975f5c5SAndroid Build Coastguard Worker     attribMap.initializeWithoutValidation();
619*8975f5c5SAndroid Build Coastguard Worker 
620*8975f5c5SAndroid Build Coastguard Worker     if (platform != EGL_PLATFORM_DEVICE_EXT)
621*8975f5c5SAndroid Build Coastguard Worker     {
622*8975f5c5SAndroid Build Coastguard Worker         EGLAttrib platformType       = EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE;
623*8975f5c5SAndroid Build Coastguard Worker         bool enableAutoTrimSpecified = false;
624*8975f5c5SAndroid Build Coastguard Worker         bool enableD3D11on12         = false;
625*8975f5c5SAndroid Build Coastguard Worker         bool presentPathSpecified    = false;
626*8975f5c5SAndroid Build Coastguard Worker         bool luidSpecified           = false;
627*8975f5c5SAndroid Build Coastguard Worker         bool deviceIdSpecified       = false;
628*8975f5c5SAndroid Build Coastguard Worker 
629*8975f5c5SAndroid Build Coastguard Worker         Optional<EGLAttrib> majorVersion;
630*8975f5c5SAndroid Build Coastguard Worker         Optional<EGLAttrib> minorVersion;
631*8975f5c5SAndroid Build Coastguard Worker         Optional<EGLAttrib> deviceType;
632*8975f5c5SAndroid Build Coastguard Worker         Optional<EGLAttrib> eglHandle;
633*8975f5c5SAndroid Build Coastguard Worker 
634*8975f5c5SAndroid Build Coastguard Worker         for (const auto &curAttrib : attribMap)
635*8975f5c5SAndroid Build Coastguard Worker         {
636*8975f5c5SAndroid Build Coastguard Worker             const EGLAttrib value = curAttrib.second;
637*8975f5c5SAndroid Build Coastguard Worker 
638*8975f5c5SAndroid Build Coastguard Worker             switch (curAttrib.first)
639*8975f5c5SAndroid Build Coastguard Worker             {
640*8975f5c5SAndroid Build Coastguard Worker                 case EGL_PLATFORM_ANGLE_TYPE_ANGLE:
641*8975f5c5SAndroid Build Coastguard Worker                 {
642*8975f5c5SAndroid Build Coastguard Worker                     ANGLE_VALIDATION_TRY(ValidatePlatformType(val, clientExtensions, value));
643*8975f5c5SAndroid Build Coastguard Worker                     platformType = value;
644*8975f5c5SAndroid Build Coastguard Worker                     break;
645*8975f5c5SAndroid Build Coastguard Worker                 }
646*8975f5c5SAndroid Build Coastguard Worker 
647*8975f5c5SAndroid Build Coastguard Worker                 case EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE:
648*8975f5c5SAndroid Build Coastguard Worker                     if (value != EGL_DONT_CARE)
649*8975f5c5SAndroid Build Coastguard Worker                     {
650*8975f5c5SAndroid Build Coastguard Worker                         majorVersion = value;
651*8975f5c5SAndroid Build Coastguard Worker                     }
652*8975f5c5SAndroid Build Coastguard Worker                     break;
653*8975f5c5SAndroid Build Coastguard Worker 
654*8975f5c5SAndroid Build Coastguard Worker                 case EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE:
655*8975f5c5SAndroid Build Coastguard Worker                     if (value != EGL_DONT_CARE)
656*8975f5c5SAndroid Build Coastguard Worker                     {
657*8975f5c5SAndroid Build Coastguard Worker                         minorVersion = value;
658*8975f5c5SAndroid Build Coastguard Worker                     }
659*8975f5c5SAndroid Build Coastguard Worker                     break;
660*8975f5c5SAndroid Build Coastguard Worker 
661*8975f5c5SAndroid Build Coastguard Worker                 case EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE:
662*8975f5c5SAndroid Build Coastguard Worker                     switch (value)
663*8975f5c5SAndroid Build Coastguard Worker                     {
664*8975f5c5SAndroid Build Coastguard Worker                         case EGL_TRUE:
665*8975f5c5SAndroid Build Coastguard Worker                         case EGL_FALSE:
666*8975f5c5SAndroid Build Coastguard Worker                             break;
667*8975f5c5SAndroid Build Coastguard Worker                         default:
668*8975f5c5SAndroid Build Coastguard Worker                             val->setError(EGL_BAD_ATTRIBUTE, "Invalid automatic trim attribute");
669*8975f5c5SAndroid Build Coastguard Worker                             return false;
670*8975f5c5SAndroid Build Coastguard Worker                     }
671*8975f5c5SAndroid Build Coastguard Worker                     enableAutoTrimSpecified = true;
672*8975f5c5SAndroid Build Coastguard Worker                     break;
673*8975f5c5SAndroid Build Coastguard Worker 
674*8975f5c5SAndroid Build Coastguard Worker                 case EGL_PLATFORM_ANGLE_D3D11ON12_ANGLE:
675*8975f5c5SAndroid Build Coastguard Worker                     if (!clientExtensions.platformANGLED3D ||
676*8975f5c5SAndroid Build Coastguard Worker                         !clientExtensions.platformANGLED3D11ON12)
677*8975f5c5SAndroid Build Coastguard Worker                     {
678*8975f5c5SAndroid Build Coastguard Worker                         val->setError(EGL_BAD_ATTRIBUTE,
679*8975f5c5SAndroid Build Coastguard Worker                                       "EGL_PLATFORM_ANGLE_D3D11ON12_ANGLE extension not active.");
680*8975f5c5SAndroid Build Coastguard Worker                         return false;
681*8975f5c5SAndroid Build Coastguard Worker                     }
682*8975f5c5SAndroid Build Coastguard Worker 
683*8975f5c5SAndroid Build Coastguard Worker                     switch (value)
684*8975f5c5SAndroid Build Coastguard Worker                     {
685*8975f5c5SAndroid Build Coastguard Worker                         case EGL_TRUE:
686*8975f5c5SAndroid Build Coastguard Worker                         case EGL_FALSE:
687*8975f5c5SAndroid Build Coastguard Worker                             break;
688*8975f5c5SAndroid Build Coastguard Worker                         default:
689*8975f5c5SAndroid Build Coastguard Worker                             val->setError(EGL_BAD_ATTRIBUTE, "Invalid D3D11on12 attribute");
690*8975f5c5SAndroid Build Coastguard Worker                             return false;
691*8975f5c5SAndroid Build Coastguard Worker                     }
692*8975f5c5SAndroid Build Coastguard Worker                     enableD3D11on12 = true;
693*8975f5c5SAndroid Build Coastguard Worker                     break;
694*8975f5c5SAndroid Build Coastguard Worker 
695*8975f5c5SAndroid Build Coastguard Worker                 case EGL_EXPERIMENTAL_PRESENT_PATH_ANGLE:
696*8975f5c5SAndroid Build Coastguard Worker                     if (!clientExtensions.experimentalPresentPath)
697*8975f5c5SAndroid Build Coastguard Worker                     {
698*8975f5c5SAndroid Build Coastguard Worker                         val->setError(EGL_BAD_ATTRIBUTE,
699*8975f5c5SAndroid Build Coastguard Worker                                       "EGL_ANGLE_experimental_present_path extension not active");
700*8975f5c5SAndroid Build Coastguard Worker                         return false;
701*8975f5c5SAndroid Build Coastguard Worker                     }
702*8975f5c5SAndroid Build Coastguard Worker 
703*8975f5c5SAndroid Build Coastguard Worker                     switch (value)
704*8975f5c5SAndroid Build Coastguard Worker                     {
705*8975f5c5SAndroid Build Coastguard Worker                         case EGL_EXPERIMENTAL_PRESENT_PATH_FAST_ANGLE:
706*8975f5c5SAndroid Build Coastguard Worker                         case EGL_EXPERIMENTAL_PRESENT_PATH_COPY_ANGLE:
707*8975f5c5SAndroid Build Coastguard Worker                             break;
708*8975f5c5SAndroid Build Coastguard Worker                         default:
709*8975f5c5SAndroid Build Coastguard Worker                             val->setError(EGL_BAD_ATTRIBUTE,
710*8975f5c5SAndroid Build Coastguard Worker                                           "Invalid value for EGL_EXPERIMENTAL_PRESENT_PATH_ANGLE");
711*8975f5c5SAndroid Build Coastguard Worker                             return false;
712*8975f5c5SAndroid Build Coastguard Worker                     }
713*8975f5c5SAndroid Build Coastguard Worker                     presentPathSpecified = true;
714*8975f5c5SAndroid Build Coastguard Worker                     break;
715*8975f5c5SAndroid Build Coastguard Worker 
716*8975f5c5SAndroid Build Coastguard Worker                 case EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE:
717*8975f5c5SAndroid Build Coastguard Worker                     switch (value)
718*8975f5c5SAndroid Build Coastguard Worker                     {
719*8975f5c5SAndroid Build Coastguard Worker                         case EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE:
720*8975f5c5SAndroid Build Coastguard Worker                         case EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE:
721*8975f5c5SAndroid Build Coastguard Worker                             break;
722*8975f5c5SAndroid Build Coastguard Worker 
723*8975f5c5SAndroid Build Coastguard Worker                         case EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_WARP_ANGLE:
724*8975f5c5SAndroid Build Coastguard Worker                         case EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_REFERENCE_ANGLE:
725*8975f5c5SAndroid Build Coastguard Worker                             if (!clientExtensions.platformANGLED3D)
726*8975f5c5SAndroid Build Coastguard Worker                             {
727*8975f5c5SAndroid Build Coastguard Worker                                 val->setError(EGL_BAD_ATTRIBUTE,
728*8975f5c5SAndroid Build Coastguard Worker                                               "EGL_ANGLE_platform_angle_d3d is not supported");
729*8975f5c5SAndroid Build Coastguard Worker                                 return false;
730*8975f5c5SAndroid Build Coastguard Worker                             }
731*8975f5c5SAndroid Build Coastguard Worker                             break;
732*8975f5c5SAndroid Build Coastguard Worker 
733*8975f5c5SAndroid Build Coastguard Worker                         case EGL_PLATFORM_ANGLE_DEVICE_TYPE_EGL_ANGLE:
734*8975f5c5SAndroid Build Coastguard Worker                             if (!clientExtensions.platformANGLEDeviceTypeEGLANGLE)
735*8975f5c5SAndroid Build Coastguard Worker                             {
736*8975f5c5SAndroid Build Coastguard Worker                                 val->setError(EGL_BAD_ATTRIBUTE,
737*8975f5c5SAndroid Build Coastguard Worker                                               "EGL_ANGLE_platform_angle_device_type_"
738*8975f5c5SAndroid Build Coastguard Worker                                               "egl_angle is not supported");
739*8975f5c5SAndroid Build Coastguard Worker                                 return false;
740*8975f5c5SAndroid Build Coastguard Worker                             }
741*8975f5c5SAndroid Build Coastguard Worker                             break;
742*8975f5c5SAndroid Build Coastguard Worker 
743*8975f5c5SAndroid Build Coastguard Worker                         case EGL_PLATFORM_ANGLE_DEVICE_TYPE_SWIFTSHADER_ANGLE:
744*8975f5c5SAndroid Build Coastguard Worker                             if (!clientExtensions.platformANGLEDeviceTypeSwiftShader)
745*8975f5c5SAndroid Build Coastguard Worker                             {
746*8975f5c5SAndroid Build Coastguard Worker                                 val->setError(EGL_BAD_ATTRIBUTE,
747*8975f5c5SAndroid Build Coastguard Worker                                               "EGL_ANGLE_platform_angle_device_type_"
748*8975f5c5SAndroid Build Coastguard Worker                                               "swiftshader is not supported");
749*8975f5c5SAndroid Build Coastguard Worker                                 return false;
750*8975f5c5SAndroid Build Coastguard Worker                             }
751*8975f5c5SAndroid Build Coastguard Worker                             break;
752*8975f5c5SAndroid Build Coastguard Worker 
753*8975f5c5SAndroid Build Coastguard Worker                         default:
754*8975f5c5SAndroid Build Coastguard Worker                             val->setError(EGL_BAD_ATTRIBUTE,
755*8975f5c5SAndroid Build Coastguard Worker                                           "Invalid value for "
756*8975f5c5SAndroid Build Coastguard Worker                                           "EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE "
757*8975f5c5SAndroid Build Coastguard Worker                                           "attrib");
758*8975f5c5SAndroid Build Coastguard Worker                             return false;
759*8975f5c5SAndroid Build Coastguard Worker                     }
760*8975f5c5SAndroid Build Coastguard Worker                     deviceType = value;
761*8975f5c5SAndroid Build Coastguard Worker                     break;
762*8975f5c5SAndroid Build Coastguard Worker 
763*8975f5c5SAndroid Build Coastguard Worker                 case EGL_PLATFORM_ANGLE_DEBUG_LAYERS_ENABLED_ANGLE:
764*8975f5c5SAndroid Build Coastguard Worker                     if (!clientExtensions.platformANGLE)
765*8975f5c5SAndroid Build Coastguard Worker                     {
766*8975f5c5SAndroid Build Coastguard Worker                         val->setError(EGL_BAD_ATTRIBUTE,
767*8975f5c5SAndroid Build Coastguard Worker                                       "EGL_ANGLE_platform_angle extension not active");
768*8975f5c5SAndroid Build Coastguard Worker                         return false;
769*8975f5c5SAndroid Build Coastguard Worker                     }
770*8975f5c5SAndroid Build Coastguard Worker                     if (value != EGL_TRUE && value != EGL_FALSE && value != EGL_DONT_CARE)
771*8975f5c5SAndroid Build Coastguard Worker                     {
772*8975f5c5SAndroid Build Coastguard Worker                         val->setError(EGL_BAD_ATTRIBUTE,
773*8975f5c5SAndroid Build Coastguard Worker                                       "EGL_PLATFORM_ANGLE_DEBUG_LAYERS_ENABLED_ANGLE "
774*8975f5c5SAndroid Build Coastguard Worker                                       "must be EGL_TRUE, EGL_FALSE, or "
775*8975f5c5SAndroid Build Coastguard Worker                                       "EGL_DONT_CARE.");
776*8975f5c5SAndroid Build Coastguard Worker                         return false;
777*8975f5c5SAndroid Build Coastguard Worker                     }
778*8975f5c5SAndroid Build Coastguard Worker                     break;
779*8975f5c5SAndroid Build Coastguard Worker 
780*8975f5c5SAndroid Build Coastguard Worker                 case EGL_PLATFORM_ANGLE_EGL_HANDLE_ANGLE:
781*8975f5c5SAndroid Build Coastguard Worker                     if (value != EGL_DONT_CARE)
782*8975f5c5SAndroid Build Coastguard Worker                     {
783*8975f5c5SAndroid Build Coastguard Worker                         eglHandle = value;
784*8975f5c5SAndroid Build Coastguard Worker                     }
785*8975f5c5SAndroid Build Coastguard Worker                     break;
786*8975f5c5SAndroid Build Coastguard Worker 
787*8975f5c5SAndroid Build Coastguard Worker                 case EGL_PLATFORM_ANGLE_D3D_LUID_HIGH_ANGLE:
788*8975f5c5SAndroid Build Coastguard Worker                 case EGL_PLATFORM_ANGLE_D3D_LUID_LOW_ANGLE:
789*8975f5c5SAndroid Build Coastguard Worker                     luidSpecified = true;
790*8975f5c5SAndroid Build Coastguard Worker                     break;
791*8975f5c5SAndroid Build Coastguard Worker                 case EGL_PLATFORM_ANGLE_DEVICE_CONTEXT_VOLATILE_CGL_ANGLE:
792*8975f5c5SAndroid Build Coastguard Worker                     // The property does not have an effect if it's not active, so do not check
793*8975f5c5SAndroid Build Coastguard Worker                     // for non-support.
794*8975f5c5SAndroid Build Coastguard Worker                     switch (value)
795*8975f5c5SAndroid Build Coastguard Worker                     {
796*8975f5c5SAndroid Build Coastguard Worker                         case EGL_FALSE:
797*8975f5c5SAndroid Build Coastguard Worker                         case EGL_TRUE:
798*8975f5c5SAndroid Build Coastguard Worker                             break;
799*8975f5c5SAndroid Build Coastguard Worker                         default:
800*8975f5c5SAndroid Build Coastguard Worker                             val->setError(EGL_BAD_ATTRIBUTE,
801*8975f5c5SAndroid Build Coastguard Worker                                           "Invalid value for "
802*8975f5c5SAndroid Build Coastguard Worker                                           "EGL_PLATFORM_ANGLE_DEVICE_CONTEXT_VOLATILE_"
803*8975f5c5SAndroid Build Coastguard Worker                                           "CGL_ANGLE attrib");
804*8975f5c5SAndroid Build Coastguard Worker                             return false;
805*8975f5c5SAndroid Build Coastguard Worker                     }
806*8975f5c5SAndroid Build Coastguard Worker                     break;
807*8975f5c5SAndroid Build Coastguard Worker                 case EGL_PLATFORM_ANGLE_DEVICE_ID_HIGH_ANGLE:
808*8975f5c5SAndroid Build Coastguard Worker                 case EGL_PLATFORM_ANGLE_DEVICE_ID_LOW_ANGLE:
809*8975f5c5SAndroid Build Coastguard Worker                 case EGL_PLATFORM_ANGLE_DISPLAY_KEY_ANGLE:
810*8975f5c5SAndroid Build Coastguard Worker                     if (!clientExtensions.platformANGLEDeviceId)
811*8975f5c5SAndroid Build Coastguard Worker                     {
812*8975f5c5SAndroid Build Coastguard Worker                         val->setError(EGL_BAD_ATTRIBUTE,
813*8975f5c5SAndroid Build Coastguard Worker                                       "EGL_ANGLE_platform_angle_device_id is not supported");
814*8975f5c5SAndroid Build Coastguard Worker                         return false;
815*8975f5c5SAndroid Build Coastguard Worker                     }
816*8975f5c5SAndroid Build Coastguard Worker                     deviceIdSpecified = true;
817*8975f5c5SAndroid Build Coastguard Worker                     break;
818*8975f5c5SAndroid Build Coastguard Worker                 default:
819*8975f5c5SAndroid Build Coastguard Worker                     break;
820*8975f5c5SAndroid Build Coastguard Worker             }
821*8975f5c5SAndroid Build Coastguard Worker         }
822*8975f5c5SAndroid Build Coastguard Worker 
823*8975f5c5SAndroid Build Coastguard Worker         if (!majorVersion.valid() && minorVersion.valid())
824*8975f5c5SAndroid Build Coastguard Worker         {
825*8975f5c5SAndroid Build Coastguard Worker             val->setError(EGL_BAD_ATTRIBUTE,
826*8975f5c5SAndroid Build Coastguard Worker                           "Must specify major version if you specify a minor version.");
827*8975f5c5SAndroid Build Coastguard Worker             return false;
828*8975f5c5SAndroid Build Coastguard Worker         }
829*8975f5c5SAndroid Build Coastguard Worker 
830*8975f5c5SAndroid Build Coastguard Worker         if (deviceType == EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_WARP_ANGLE &&
831*8975f5c5SAndroid Build Coastguard Worker             platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
832*8975f5c5SAndroid Build Coastguard Worker         {
833*8975f5c5SAndroid Build Coastguard Worker             val->setError(EGL_BAD_ATTRIBUTE,
834*8975f5c5SAndroid Build Coastguard Worker                           "EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE requires a "
835*8975f5c5SAndroid Build Coastguard Worker                           "device type of EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE.");
836*8975f5c5SAndroid Build Coastguard Worker             return false;
837*8975f5c5SAndroid Build Coastguard Worker         }
838*8975f5c5SAndroid Build Coastguard Worker 
839*8975f5c5SAndroid Build Coastguard Worker         if (enableAutoTrimSpecified && platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
840*8975f5c5SAndroid Build Coastguard Worker         {
841*8975f5c5SAndroid Build Coastguard Worker             val->setError(EGL_BAD_ATTRIBUTE,
842*8975f5c5SAndroid Build Coastguard Worker                           "EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE "
843*8975f5c5SAndroid Build Coastguard Worker                           "requires a device type of "
844*8975f5c5SAndroid Build Coastguard Worker                           "EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE.");
845*8975f5c5SAndroid Build Coastguard Worker             return false;
846*8975f5c5SAndroid Build Coastguard Worker         }
847*8975f5c5SAndroid Build Coastguard Worker 
848*8975f5c5SAndroid Build Coastguard Worker         if (enableD3D11on12)
849*8975f5c5SAndroid Build Coastguard Worker         {
850*8975f5c5SAndroid Build Coastguard Worker             if (platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
851*8975f5c5SAndroid Build Coastguard Worker             {
852*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE,
853*8975f5c5SAndroid Build Coastguard Worker                               "EGL_PLATFORM_ANGLE_D3D11ON12_ANGLE "
854*8975f5c5SAndroid Build Coastguard Worker                               "requires a platform type of "
855*8975f5c5SAndroid Build Coastguard Worker                               "EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE.");
856*8975f5c5SAndroid Build Coastguard Worker                 return false;
857*8975f5c5SAndroid Build Coastguard Worker             }
858*8975f5c5SAndroid Build Coastguard Worker 
859*8975f5c5SAndroid Build Coastguard Worker             if (deviceType.valid() && deviceType != EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE &&
860*8975f5c5SAndroid Build Coastguard Worker                 deviceType != EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_WARP_ANGLE)
861*8975f5c5SAndroid Build Coastguard Worker             {
862*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE,
863*8975f5c5SAndroid Build Coastguard Worker                               "EGL_PLATFORM_ANGLE_D3D11ON12_ANGLE requires a device "
864*8975f5c5SAndroid Build Coastguard Worker                               "type of EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE "
865*8975f5c5SAndroid Build Coastguard Worker                               "or EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_WARP_ANGLE");
866*8975f5c5SAndroid Build Coastguard Worker                 return false;
867*8975f5c5SAndroid Build Coastguard Worker             }
868*8975f5c5SAndroid Build Coastguard Worker         }
869*8975f5c5SAndroid Build Coastguard Worker 
870*8975f5c5SAndroid Build Coastguard Worker         if (presentPathSpecified && platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
871*8975f5c5SAndroid Build Coastguard Worker         {
872*8975f5c5SAndroid Build Coastguard Worker             val->setError(EGL_BAD_ATTRIBUTE,
873*8975f5c5SAndroid Build Coastguard Worker                           "EGL_EXPERIMENTAL_PRESENT_PATH_ANGLE requires a "
874*8975f5c5SAndroid Build Coastguard Worker                           "device type of EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE.");
875*8975f5c5SAndroid Build Coastguard Worker             return false;
876*8975f5c5SAndroid Build Coastguard Worker         }
877*8975f5c5SAndroid Build Coastguard Worker 
878*8975f5c5SAndroid Build Coastguard Worker         if (luidSpecified)
879*8975f5c5SAndroid Build Coastguard Worker         {
880*8975f5c5SAndroid Build Coastguard Worker             if (platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
881*8975f5c5SAndroid Build Coastguard Worker             {
882*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE,
883*8975f5c5SAndroid Build Coastguard Worker                               "EGL_PLATFORM_ANGLE_D3D_LUID_HIGH_ANGLE and "
884*8975f5c5SAndroid Build Coastguard Worker                               "EGL_PLATFORM_ANGLE_D3D_LUID_LOW_ANGLE "
885*8975f5c5SAndroid Build Coastguard Worker                               "require a platform type of "
886*8975f5c5SAndroid Build Coastguard Worker                               "EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE.");
887*8975f5c5SAndroid Build Coastguard Worker                 return false;
888*8975f5c5SAndroid Build Coastguard Worker             }
889*8975f5c5SAndroid Build Coastguard Worker 
890*8975f5c5SAndroid Build Coastguard Worker             if (attribMap.get(EGL_PLATFORM_ANGLE_D3D_LUID_HIGH_ANGLE, 0) == 0 &&
891*8975f5c5SAndroid Build Coastguard Worker                 attribMap.get(EGL_PLATFORM_ANGLE_D3D_LUID_LOW_ANGLE, 0) == 0)
892*8975f5c5SAndroid Build Coastguard Worker             {
893*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE,
894*8975f5c5SAndroid Build Coastguard Worker                               "If either EGL_PLATFORM_ANGLE_D3D_LUID_HIGH_ANGLE "
895*8975f5c5SAndroid Build Coastguard Worker                               "and/or EGL_PLATFORM_ANGLE_D3D_LUID_LOW_ANGLE are "
896*8975f5c5SAndroid Build Coastguard Worker                               "specified, at least one must non-zero.");
897*8975f5c5SAndroid Build Coastguard Worker                 return false;
898*8975f5c5SAndroid Build Coastguard Worker             }
899*8975f5c5SAndroid Build Coastguard Worker         }
900*8975f5c5SAndroid Build Coastguard Worker 
901*8975f5c5SAndroid Build Coastguard Worker         if (deviceIdSpecified)
902*8975f5c5SAndroid Build Coastguard Worker         {
903*8975f5c5SAndroid Build Coastguard Worker             if (attribMap.get(EGL_PLATFORM_ANGLE_DEVICE_ID_HIGH_ANGLE, 0) == 0 &&
904*8975f5c5SAndroid Build Coastguard Worker                 attribMap.get(EGL_PLATFORM_ANGLE_DEVICE_ID_LOW_ANGLE, 0) == 0)
905*8975f5c5SAndroid Build Coastguard Worker             {
906*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE,
907*8975f5c5SAndroid Build Coastguard Worker                               "If either EGL_PLATFORM_ANGLE_DEVICE_ID_HIGH_ANGLE "
908*8975f5c5SAndroid Build Coastguard Worker                               "and/or EGL_PLATFORM_ANGLE_DEVICE_ID_LOW_ANGLE are "
909*8975f5c5SAndroid Build Coastguard Worker                               "specified, at least one must non-zero.");
910*8975f5c5SAndroid Build Coastguard Worker                 return false;
911*8975f5c5SAndroid Build Coastguard Worker             }
912*8975f5c5SAndroid Build Coastguard Worker         }
913*8975f5c5SAndroid Build Coastguard Worker 
914*8975f5c5SAndroid Build Coastguard Worker         if (deviceType.valid())
915*8975f5c5SAndroid Build Coastguard Worker         {
916*8975f5c5SAndroid Build Coastguard Worker             switch (deviceType.value())
917*8975f5c5SAndroid Build Coastguard Worker             {
918*8975f5c5SAndroid Build Coastguard Worker                 case EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_REFERENCE_ANGLE:
919*8975f5c5SAndroid Build Coastguard Worker                 case EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_WARP_ANGLE:
920*8975f5c5SAndroid Build Coastguard Worker                     if (platformType != EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE &&
921*8975f5c5SAndroid Build Coastguard Worker                         platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
922*8975f5c5SAndroid Build Coastguard Worker                     {
923*8975f5c5SAndroid Build Coastguard Worker                         val->setError(EGL_BAD_ATTRIBUTE,
924*8975f5c5SAndroid Build Coastguard Worker                                       "This device type requires a "
925*8975f5c5SAndroid Build Coastguard Worker                                       "platform type of EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE or "
926*8975f5c5SAndroid Build Coastguard Worker                                       "EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE.");
927*8975f5c5SAndroid Build Coastguard Worker                         return false;
928*8975f5c5SAndroid Build Coastguard Worker                     }
929*8975f5c5SAndroid Build Coastguard Worker                     break;
930*8975f5c5SAndroid Build Coastguard Worker 
931*8975f5c5SAndroid Build Coastguard Worker                 case EGL_PLATFORM_ANGLE_DEVICE_TYPE_SWIFTSHADER_ANGLE:
932*8975f5c5SAndroid Build Coastguard Worker                     if (platformType != EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE)
933*8975f5c5SAndroid Build Coastguard Worker                     {
934*8975f5c5SAndroid Build Coastguard Worker                         val->setError(EGL_BAD_ATTRIBUTE,
935*8975f5c5SAndroid Build Coastguard Worker                                       "This device type requires a "
936*8975f5c5SAndroid Build Coastguard Worker                                       "platform type of EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE.");
937*8975f5c5SAndroid Build Coastguard Worker                         return false;
938*8975f5c5SAndroid Build Coastguard Worker                     }
939*8975f5c5SAndroid Build Coastguard Worker                     break;
940*8975f5c5SAndroid Build Coastguard Worker 
941*8975f5c5SAndroid Build Coastguard Worker                 default:
942*8975f5c5SAndroid Build Coastguard Worker                     break;
943*8975f5c5SAndroid Build Coastguard Worker             }
944*8975f5c5SAndroid Build Coastguard Worker         }
945*8975f5c5SAndroid Build Coastguard Worker 
946*8975f5c5SAndroid Build Coastguard Worker         if (platformType == EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE)
947*8975f5c5SAndroid Build Coastguard Worker         {
948*8975f5c5SAndroid Build Coastguard Worker             if ((majorVersion.valid() && majorVersion.value() != 1) ||
949*8975f5c5SAndroid Build Coastguard Worker                 (minorVersion.valid() && minorVersion.value() != 0))
950*8975f5c5SAndroid Build Coastguard Worker             {
951*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE,
952*8975f5c5SAndroid Build Coastguard Worker                               "EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE currently "
953*8975f5c5SAndroid Build Coastguard Worker                               "only supports Vulkan 1.0.");
954*8975f5c5SAndroid Build Coastguard Worker                 return false;
955*8975f5c5SAndroid Build Coastguard Worker             }
956*8975f5c5SAndroid Build Coastguard Worker         }
957*8975f5c5SAndroid Build Coastguard Worker 
958*8975f5c5SAndroid Build Coastguard Worker         if (eglHandle.valid() && platformType != EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE &&
959*8975f5c5SAndroid Build Coastguard Worker             platformType != EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE)
960*8975f5c5SAndroid Build Coastguard Worker         {
961*8975f5c5SAndroid Build Coastguard Worker             val->setError(EGL_BAD_ATTRIBUTE,
962*8975f5c5SAndroid Build Coastguard Worker                           "EGL_PLATFORM_ANGLE_EGL_HANDLE_ANGLE requires a "
963*8975f5c5SAndroid Build Coastguard Worker                           "device type of EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE.");
964*8975f5c5SAndroid Build Coastguard Worker             return false;
965*8975f5c5SAndroid Build Coastguard Worker         }
966*8975f5c5SAndroid Build Coastguard Worker     }
967*8975f5c5SAndroid Build Coastguard Worker     else
968*8975f5c5SAndroid Build Coastguard Worker     {
969*8975f5c5SAndroid Build Coastguard Worker         const Device *eglDevice = static_cast<const Device *>(native_display);
970*8975f5c5SAndroid Build Coastguard Worker         if (eglDevice == nullptr || !Device::IsValidDevice(eglDevice))
971*8975f5c5SAndroid Build Coastguard Worker         {
972*8975f5c5SAndroid Build Coastguard Worker             val->setError(EGL_BAD_ATTRIBUTE,
973*8975f5c5SAndroid Build Coastguard Worker                           "native_display should be a valid EGL device if "
974*8975f5c5SAndroid Build Coastguard Worker                           "platform equals EGL_PLATFORM_DEVICE_EXT");
975*8975f5c5SAndroid Build Coastguard Worker             return false;
976*8975f5c5SAndroid Build Coastguard Worker         }
977*8975f5c5SAndroid Build Coastguard Worker     }
978*8975f5c5SAndroid Build Coastguard Worker 
979*8975f5c5SAndroid Build Coastguard Worker     if (attribMap.contains(EGL_POWER_PREFERENCE_ANGLE))
980*8975f5c5SAndroid Build Coastguard Worker     {
981*8975f5c5SAndroid Build Coastguard Worker         if (!clientExtensions.displayPowerPreferenceANGLE)
982*8975f5c5SAndroid Build Coastguard Worker         {
983*8975f5c5SAndroid Build Coastguard Worker             val->setError(EGL_BAD_ATTRIBUTE,
984*8975f5c5SAndroid Build Coastguard Worker                           "Attribute EGL_POWER_PREFERENCE_ANGLE "
985*8975f5c5SAndroid Build Coastguard Worker                           "requires EGL_ANGLE_display_power_preference.");
986*8975f5c5SAndroid Build Coastguard Worker             return false;
987*8975f5c5SAndroid Build Coastguard Worker         }
988*8975f5c5SAndroid Build Coastguard Worker         EGLAttrib value = attribMap.get(EGL_POWER_PREFERENCE_ANGLE, 0);
989*8975f5c5SAndroid Build Coastguard Worker         if (value != EGL_LOW_POWER_ANGLE && value != EGL_HIGH_POWER_ANGLE)
990*8975f5c5SAndroid Build Coastguard Worker         {
991*8975f5c5SAndroid Build Coastguard Worker             val->setError(EGL_BAD_ATTRIBUTE,
992*8975f5c5SAndroid Build Coastguard Worker                           "EGL_POWER_PREFERENCE_ANGLE must be "
993*8975f5c5SAndroid Build Coastguard Worker                           "either EGL_LOW_POWER_ANGLE or EGL_HIGH_POWER_ANGLE.");
994*8975f5c5SAndroid Build Coastguard Worker             return false;
995*8975f5c5SAndroid Build Coastguard Worker         }
996*8975f5c5SAndroid Build Coastguard Worker     }
997*8975f5c5SAndroid Build Coastguard Worker 
998*8975f5c5SAndroid Build Coastguard Worker     if (attribMap.contains(EGL_FEATURE_OVERRIDES_ENABLED_ANGLE))
999*8975f5c5SAndroid Build Coastguard Worker     {
1000*8975f5c5SAndroid Build Coastguard Worker         if (!clientExtensions.featureControlANGLE)
1001*8975f5c5SAndroid Build Coastguard Worker         {
1002*8975f5c5SAndroid Build Coastguard Worker             val->setError(EGL_BAD_ATTRIBUTE, "EGL_ANGLE_feature_control is not supported");
1003*8975f5c5SAndroid Build Coastguard Worker             return false;
1004*8975f5c5SAndroid Build Coastguard Worker         }
1005*8975f5c5SAndroid Build Coastguard Worker         else if (attribMap.get(EGL_FEATURE_OVERRIDES_ENABLED_ANGLE, 0) == 0)
1006*8975f5c5SAndroid Build Coastguard Worker         {
1007*8975f5c5SAndroid Build Coastguard Worker             val->setError(EGL_BAD_ATTRIBUTE,
1008*8975f5c5SAndroid Build Coastguard Worker                           "EGL_FEATURE_OVERRIDES_ENABLED_ANGLE must be a valid pointer");
1009*8975f5c5SAndroid Build Coastguard Worker             return false;
1010*8975f5c5SAndroid Build Coastguard Worker         }
1011*8975f5c5SAndroid Build Coastguard Worker     }
1012*8975f5c5SAndroid Build Coastguard Worker     if (attribMap.contains(EGL_FEATURE_OVERRIDES_DISABLED_ANGLE))
1013*8975f5c5SAndroid Build Coastguard Worker     {
1014*8975f5c5SAndroid Build Coastguard Worker         if (!clientExtensions.featureControlANGLE)
1015*8975f5c5SAndroid Build Coastguard Worker         {
1016*8975f5c5SAndroid Build Coastguard Worker             val->setError(EGL_BAD_ATTRIBUTE, "EGL_ANGLE_feature_control is not supported");
1017*8975f5c5SAndroid Build Coastguard Worker             return false;
1018*8975f5c5SAndroid Build Coastguard Worker         }
1019*8975f5c5SAndroid Build Coastguard Worker         else if (attribMap.get(EGL_FEATURE_OVERRIDES_DISABLED_ANGLE, 0) == 0)
1020*8975f5c5SAndroid Build Coastguard Worker         {
1021*8975f5c5SAndroid Build Coastguard Worker             val->setError(EGL_BAD_ATTRIBUTE,
1022*8975f5c5SAndroid Build Coastguard Worker                           "EGL_FEATURE_OVERRIDES_DISABLED_ANGLE must be a valid pointer");
1023*8975f5c5SAndroid Build Coastguard Worker             return false;
1024*8975f5c5SAndroid Build Coastguard Worker         }
1025*8975f5c5SAndroid Build Coastguard Worker     }
1026*8975f5c5SAndroid Build Coastguard Worker 
1027*8975f5c5SAndroid Build Coastguard Worker     return true;
1028*8975f5c5SAndroid Build Coastguard Worker }
1029*8975f5c5SAndroid Build Coastguard Worker 
ValidateStream(const ValidationContext * val,const Display * display,const Stream * stream)1030*8975f5c5SAndroid Build Coastguard Worker bool ValidateStream(const ValidationContext *val, const Display *display, const Stream *stream)
1031*8975f5c5SAndroid Build Coastguard Worker {
1032*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
1033*8975f5c5SAndroid Build Coastguard Worker 
1034*8975f5c5SAndroid Build Coastguard Worker     const DisplayExtensions &displayExtensions = display->getExtensions();
1035*8975f5c5SAndroid Build Coastguard Worker     if (!displayExtensions.stream)
1036*8975f5c5SAndroid Build Coastguard Worker     {
1037*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_ACCESS, "Stream extension not active");
1038*8975f5c5SAndroid Build Coastguard Worker         return false;
1039*8975f5c5SAndroid Build Coastguard Worker     }
1040*8975f5c5SAndroid Build Coastguard Worker 
1041*8975f5c5SAndroid Build Coastguard Worker     if (stream == EGL_NO_STREAM_KHR || !display->isValidStream(stream))
1042*8975f5c5SAndroid Build Coastguard Worker     {
1043*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_STREAM_KHR, "Invalid stream");
1044*8975f5c5SAndroid Build Coastguard Worker         return false;
1045*8975f5c5SAndroid Build Coastguard Worker     }
1046*8975f5c5SAndroid Build Coastguard Worker 
1047*8975f5c5SAndroid Build Coastguard Worker     return true;
1048*8975f5c5SAndroid Build Coastguard Worker }
1049*8975f5c5SAndroid Build Coastguard Worker 
ValidateLabeledObject(const ValidationContext * val,const Display * display,ObjectType objectType,EGLObjectKHR object,const LabeledObject ** outLabeledObject)1050*8975f5c5SAndroid Build Coastguard Worker bool ValidateLabeledObject(const ValidationContext *val,
1051*8975f5c5SAndroid Build Coastguard Worker                            const Display *display,
1052*8975f5c5SAndroid Build Coastguard Worker                            ObjectType objectType,
1053*8975f5c5SAndroid Build Coastguard Worker                            EGLObjectKHR object,
1054*8975f5c5SAndroid Build Coastguard Worker                            const LabeledObject **outLabeledObject)
1055*8975f5c5SAndroid Build Coastguard Worker {
1056*8975f5c5SAndroid Build Coastguard Worker     switch (objectType)
1057*8975f5c5SAndroid Build Coastguard Worker     {
1058*8975f5c5SAndroid Build Coastguard Worker         case ObjectType::Context:
1059*8975f5c5SAndroid Build Coastguard Worker         {
1060*8975f5c5SAndroid Build Coastguard Worker             EGLContext context      = static_cast<EGLContext>(object);
1061*8975f5c5SAndroid Build Coastguard Worker             gl::ContextID contextID = PackParam<gl::ContextID>(context);
1062*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_TRY(ValidateContext(val, display, contextID));
1063*8975f5c5SAndroid Build Coastguard Worker             *outLabeledObject = display->getContext(contextID);
1064*8975f5c5SAndroid Build Coastguard Worker             break;
1065*8975f5c5SAndroid Build Coastguard Worker         }
1066*8975f5c5SAndroid Build Coastguard Worker 
1067*8975f5c5SAndroid Build Coastguard Worker         case ObjectType::Display:
1068*8975f5c5SAndroid Build Coastguard Worker         {
1069*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
1070*8975f5c5SAndroid Build Coastguard Worker             if (display != object)
1071*8975f5c5SAndroid Build Coastguard Worker             {
1072*8975f5c5SAndroid Build Coastguard Worker                 if (val)
1073*8975f5c5SAndroid Build Coastguard Worker                 {
1074*8975f5c5SAndroid Build Coastguard Worker                     val->setError(EGL_BAD_PARAMETER,
1075*8975f5c5SAndroid Build Coastguard Worker                                   "when object type is EGL_OBJECT_DISPLAY_KHR, the "
1076*8975f5c5SAndroid Build Coastguard Worker                                   "object must be the same as the display.");
1077*8975f5c5SAndroid Build Coastguard Worker                 }
1078*8975f5c5SAndroid Build Coastguard Worker                 return false;
1079*8975f5c5SAndroid Build Coastguard Worker             }
1080*8975f5c5SAndroid Build Coastguard Worker 
1081*8975f5c5SAndroid Build Coastguard Worker             *outLabeledObject = static_cast<Display *>(object);
1082*8975f5c5SAndroid Build Coastguard Worker             break;
1083*8975f5c5SAndroid Build Coastguard Worker         }
1084*8975f5c5SAndroid Build Coastguard Worker 
1085*8975f5c5SAndroid Build Coastguard Worker         case ObjectType::Image:
1086*8975f5c5SAndroid Build Coastguard Worker         {
1087*8975f5c5SAndroid Build Coastguard Worker             EGLImage image  = static_cast<EGLImage>(object);
1088*8975f5c5SAndroid Build Coastguard Worker             ImageID imageID = PackParam<ImageID>(image);
1089*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_TRY(ValidateImage(val, display, imageID));
1090*8975f5c5SAndroid Build Coastguard Worker             *outLabeledObject = display->getImage(imageID);
1091*8975f5c5SAndroid Build Coastguard Worker             break;
1092*8975f5c5SAndroid Build Coastguard Worker         }
1093*8975f5c5SAndroid Build Coastguard Worker 
1094*8975f5c5SAndroid Build Coastguard Worker         case ObjectType::Stream:
1095*8975f5c5SAndroid Build Coastguard Worker         {
1096*8975f5c5SAndroid Build Coastguard Worker             Stream *stream = static_cast<Stream *>(object);
1097*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_TRY(ValidateStream(val, display, stream));
1098*8975f5c5SAndroid Build Coastguard Worker             *outLabeledObject = stream;
1099*8975f5c5SAndroid Build Coastguard Worker             break;
1100*8975f5c5SAndroid Build Coastguard Worker         }
1101*8975f5c5SAndroid Build Coastguard Worker 
1102*8975f5c5SAndroid Build Coastguard Worker         case ObjectType::Surface:
1103*8975f5c5SAndroid Build Coastguard Worker         {
1104*8975f5c5SAndroid Build Coastguard Worker             EGLSurface surface  = static_cast<EGLSurface>(object);
1105*8975f5c5SAndroid Build Coastguard Worker             SurfaceID surfaceID = PackParam<SurfaceID>(surface);
1106*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_TRY(ValidateSurface(val, display, surfaceID));
1107*8975f5c5SAndroid Build Coastguard Worker             *outLabeledObject = display->getSurface(surfaceID);
1108*8975f5c5SAndroid Build Coastguard Worker             break;
1109*8975f5c5SAndroid Build Coastguard Worker         }
1110*8975f5c5SAndroid Build Coastguard Worker 
1111*8975f5c5SAndroid Build Coastguard Worker         case ObjectType::Sync:
1112*8975f5c5SAndroid Build Coastguard Worker         {
1113*8975f5c5SAndroid Build Coastguard Worker             Sync *sync    = static_cast<Sync *>(object);
1114*8975f5c5SAndroid Build Coastguard Worker             SyncID syncID = PackParam<SyncID>(sync);
1115*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_TRY(ValidateSync(val, display, syncID));
1116*8975f5c5SAndroid Build Coastguard Worker             *outLabeledObject = sync;
1117*8975f5c5SAndroid Build Coastguard Worker             break;
1118*8975f5c5SAndroid Build Coastguard Worker         }
1119*8975f5c5SAndroid Build Coastguard Worker 
1120*8975f5c5SAndroid Build Coastguard Worker         case ObjectType::Thread:
1121*8975f5c5SAndroid Build Coastguard Worker         {
1122*8975f5c5SAndroid Build Coastguard Worker             ASSERT(val);
1123*8975f5c5SAndroid Build Coastguard Worker             *outLabeledObject = val->eglThread;
1124*8975f5c5SAndroid Build Coastguard Worker             break;
1125*8975f5c5SAndroid Build Coastguard Worker         }
1126*8975f5c5SAndroid Build Coastguard Worker 
1127*8975f5c5SAndroid Build Coastguard Worker         default:
1128*8975f5c5SAndroid Build Coastguard Worker             if (val)
1129*8975f5c5SAndroid Build Coastguard Worker             {
1130*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_PARAMETER, "unknown object type.");
1131*8975f5c5SAndroid Build Coastguard Worker             }
1132*8975f5c5SAndroid Build Coastguard Worker             return false;
1133*8975f5c5SAndroid Build Coastguard Worker     }
1134*8975f5c5SAndroid Build Coastguard Worker 
1135*8975f5c5SAndroid Build Coastguard Worker     return true;
1136*8975f5c5SAndroid Build Coastguard Worker }
1137*8975f5c5SAndroid Build Coastguard Worker 
ValidateLabeledObject(const ValidationContext * val,Display * display,ObjectType objectType,EGLObjectKHR object,LabeledObject ** outLabeledObject)1138*8975f5c5SAndroid Build Coastguard Worker bool ValidateLabeledObject(const ValidationContext *val,
1139*8975f5c5SAndroid Build Coastguard Worker                            Display *display,
1140*8975f5c5SAndroid Build Coastguard Worker                            ObjectType objectType,
1141*8975f5c5SAndroid Build Coastguard Worker                            EGLObjectKHR object,
1142*8975f5c5SAndroid Build Coastguard Worker                            LabeledObject **outLabeledObject)
1143*8975f5c5SAndroid Build Coastguard Worker {
1144*8975f5c5SAndroid Build Coastguard Worker     return ValidateLabeledObject(val, const_cast<const Display *>(display), objectType, object,
1145*8975f5c5SAndroid Build Coastguard Worker                                  const_cast<const LabeledObject **>(outLabeledObject));
1146*8975f5c5SAndroid Build Coastguard Worker }
1147*8975f5c5SAndroid Build Coastguard Worker 
1148*8975f5c5SAndroid Build Coastguard Worker // This is a common sub-check of Display status that's shared by multiple functions
ValidateDisplayPointer(const ValidationContext * val,const Display * display)1149*8975f5c5SAndroid Build Coastguard Worker bool ValidateDisplayPointer(const ValidationContext *val, const Display *display)
1150*8975f5c5SAndroid Build Coastguard Worker {
1151*8975f5c5SAndroid Build Coastguard Worker     if (display == EGL_NO_DISPLAY)
1152*8975f5c5SAndroid Build Coastguard Worker     {
1153*8975f5c5SAndroid Build Coastguard Worker         if (val)
1154*8975f5c5SAndroid Build Coastguard Worker         {
1155*8975f5c5SAndroid Build Coastguard Worker             val->setError(EGL_BAD_DISPLAY, "display is EGL_NO_DISPLAY.");
1156*8975f5c5SAndroid Build Coastguard Worker         }
1157*8975f5c5SAndroid Build Coastguard Worker         return false;
1158*8975f5c5SAndroid Build Coastguard Worker     }
1159*8975f5c5SAndroid Build Coastguard Worker 
1160*8975f5c5SAndroid Build Coastguard Worker     if (!Display::isValidDisplay(display))
1161*8975f5c5SAndroid Build Coastguard Worker     {
1162*8975f5c5SAndroid Build Coastguard Worker         if (val)
1163*8975f5c5SAndroid Build Coastguard Worker         {
1164*8975f5c5SAndroid Build Coastguard Worker             val->setError(EGL_BAD_DISPLAY, "display is not a valid display: 0x%p", display);
1165*8975f5c5SAndroid Build Coastguard Worker         }
1166*8975f5c5SAndroid Build Coastguard Worker         return false;
1167*8975f5c5SAndroid Build Coastguard Worker     }
1168*8975f5c5SAndroid Build Coastguard Worker 
1169*8975f5c5SAndroid Build Coastguard Worker     return true;
1170*8975f5c5SAndroid Build Coastguard Worker }
1171*8975f5c5SAndroid Build Coastguard Worker 
ValidCompositorTimingName(CompositorTiming name)1172*8975f5c5SAndroid Build Coastguard Worker bool ValidCompositorTimingName(CompositorTiming name)
1173*8975f5c5SAndroid Build Coastguard Worker {
1174*8975f5c5SAndroid Build Coastguard Worker     switch (name)
1175*8975f5c5SAndroid Build Coastguard Worker     {
1176*8975f5c5SAndroid Build Coastguard Worker         case CompositorTiming::CompositeDeadline:
1177*8975f5c5SAndroid Build Coastguard Worker         case CompositorTiming::CompositInterval:
1178*8975f5c5SAndroid Build Coastguard Worker         case CompositorTiming::CompositToPresentLatency:
1179*8975f5c5SAndroid Build Coastguard Worker             return true;
1180*8975f5c5SAndroid Build Coastguard Worker 
1181*8975f5c5SAndroid Build Coastguard Worker         default:
1182*8975f5c5SAndroid Build Coastguard Worker             return false;
1183*8975f5c5SAndroid Build Coastguard Worker     }
1184*8975f5c5SAndroid Build Coastguard Worker }
1185*8975f5c5SAndroid Build Coastguard Worker 
ValidTimestampType(Timestamp timestamp)1186*8975f5c5SAndroid Build Coastguard Worker bool ValidTimestampType(Timestamp timestamp)
1187*8975f5c5SAndroid Build Coastguard Worker {
1188*8975f5c5SAndroid Build Coastguard Worker     switch (timestamp)
1189*8975f5c5SAndroid Build Coastguard Worker     {
1190*8975f5c5SAndroid Build Coastguard Worker         case Timestamp::RequestedPresentTime:
1191*8975f5c5SAndroid Build Coastguard Worker         case Timestamp::RenderingCompleteTime:
1192*8975f5c5SAndroid Build Coastguard Worker         case Timestamp::CompositionLatchTime:
1193*8975f5c5SAndroid Build Coastguard Worker         case Timestamp::FirstCompositionStartTime:
1194*8975f5c5SAndroid Build Coastguard Worker         case Timestamp::LastCompositionStartTime:
1195*8975f5c5SAndroid Build Coastguard Worker         case Timestamp::FirstCompositionGPUFinishedTime:
1196*8975f5c5SAndroid Build Coastguard Worker         case Timestamp::DisplayPresentTime:
1197*8975f5c5SAndroid Build Coastguard Worker         case Timestamp::DequeueReadyTime:
1198*8975f5c5SAndroid Build Coastguard Worker         case Timestamp::ReadsDoneTime:
1199*8975f5c5SAndroid Build Coastguard Worker             return true;
1200*8975f5c5SAndroid Build Coastguard Worker 
1201*8975f5c5SAndroid Build Coastguard Worker         default:
1202*8975f5c5SAndroid Build Coastguard Worker             return false;
1203*8975f5c5SAndroid Build Coastguard Worker     }
1204*8975f5c5SAndroid Build Coastguard Worker }
1205*8975f5c5SAndroid Build Coastguard Worker 
ValidateCompatibleSurface(const ValidationContext * val,const Display * display,const gl::Context * context,const Surface * surface)1206*8975f5c5SAndroid Build Coastguard Worker bool ValidateCompatibleSurface(const ValidationContext *val,
1207*8975f5c5SAndroid Build Coastguard Worker                                const Display *display,
1208*8975f5c5SAndroid Build Coastguard Worker                                const gl::Context *context,
1209*8975f5c5SAndroid Build Coastguard Worker                                const Surface *surface)
1210*8975f5c5SAndroid Build Coastguard Worker {
1211*8975f5c5SAndroid Build Coastguard Worker     const Config *contextConfig = context->getConfig();
1212*8975f5c5SAndroid Build Coastguard Worker     const Config *surfaceConfig = surface->getConfig();
1213*8975f5c5SAndroid Build Coastguard Worker 
1214*8975f5c5SAndroid Build Coastguard Worker     // Surface compatible with client API - only OPENGL_ES supported
1215*8975f5c5SAndroid Build Coastguard Worker     switch (context->getClientMajorVersion())
1216*8975f5c5SAndroid Build Coastguard Worker     {
1217*8975f5c5SAndroid Build Coastguard Worker         case 1:
1218*8975f5c5SAndroid Build Coastguard Worker             if (!(surfaceConfig->renderableType & EGL_OPENGL_ES_BIT))
1219*8975f5c5SAndroid Build Coastguard Worker             {
1220*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_MATCH, "Surface not compatible with OpenGL ES 1.x.");
1221*8975f5c5SAndroid Build Coastguard Worker                 return false;
1222*8975f5c5SAndroid Build Coastguard Worker             }
1223*8975f5c5SAndroid Build Coastguard Worker             break;
1224*8975f5c5SAndroid Build Coastguard Worker         case 2:
1225*8975f5c5SAndroid Build Coastguard Worker             if (!(surfaceConfig->renderableType & EGL_OPENGL_ES2_BIT))
1226*8975f5c5SAndroid Build Coastguard Worker             {
1227*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_MATCH, "Surface not compatible with OpenGL ES 2.x.");
1228*8975f5c5SAndroid Build Coastguard Worker                 return false;
1229*8975f5c5SAndroid Build Coastguard Worker             }
1230*8975f5c5SAndroid Build Coastguard Worker             break;
1231*8975f5c5SAndroid Build Coastguard Worker         case 3:
1232*8975f5c5SAndroid Build Coastguard Worker             if (!(surfaceConfig->renderableType & (EGL_OPENGL_ES2_BIT | EGL_OPENGL_ES3_BIT)))
1233*8975f5c5SAndroid Build Coastguard Worker             {
1234*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_MATCH, "Surface not compatible with OpenGL ES 3.x.");
1235*8975f5c5SAndroid Build Coastguard Worker                 return false;
1236*8975f5c5SAndroid Build Coastguard Worker             }
1237*8975f5c5SAndroid Build Coastguard Worker             break;
1238*8975f5c5SAndroid Build Coastguard Worker         default:
1239*8975f5c5SAndroid Build Coastguard Worker             val->setError(EGL_BAD_MATCH, "Surface not compatible with Context API.");
1240*8975f5c5SAndroid Build Coastguard Worker             return false;
1241*8975f5c5SAndroid Build Coastguard Worker     }
1242*8975f5c5SAndroid Build Coastguard Worker 
1243*8975f5c5SAndroid Build Coastguard Worker     // EGL KHR no config context
1244*8975f5c5SAndroid Build Coastguard Worker     if (context->getConfig() == EGL_NO_CONFIG_KHR)
1245*8975f5c5SAndroid Build Coastguard Worker     {
1246*8975f5c5SAndroid Build Coastguard Worker         const DisplayExtensions &displayExtensions = display->getExtensions();
1247*8975f5c5SAndroid Build Coastguard Worker         if (displayExtensions.noConfigContext)
1248*8975f5c5SAndroid Build Coastguard Worker         {
1249*8975f5c5SAndroid Build Coastguard Worker             return true;
1250*8975f5c5SAndroid Build Coastguard Worker         }
1251*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_MATCH, "Context with no config is not supported.");
1252*8975f5c5SAndroid Build Coastguard Worker         return false;
1253*8975f5c5SAndroid Build Coastguard Worker     }
1254*8975f5c5SAndroid Build Coastguard Worker 
1255*8975f5c5SAndroid Build Coastguard Worker     // Config compatibility is defined in section 2.2 of the EGL 1.5 spec
1256*8975f5c5SAndroid Build Coastguard Worker 
1257*8975f5c5SAndroid Build Coastguard Worker     bool colorBufferCompat = surfaceConfig->colorBufferType == contextConfig->colorBufferType;
1258*8975f5c5SAndroid Build Coastguard Worker     if (!colorBufferCompat)
1259*8975f5c5SAndroid Build Coastguard Worker     {
1260*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_MATCH, "Color buffer types are not compatible.");
1261*8975f5c5SAndroid Build Coastguard Worker         return false;
1262*8975f5c5SAndroid Build Coastguard Worker     }
1263*8975f5c5SAndroid Build Coastguard Worker 
1264*8975f5c5SAndroid Build Coastguard Worker     bool colorCompat = surfaceConfig->redSize == contextConfig->redSize &&
1265*8975f5c5SAndroid Build Coastguard Worker                        surfaceConfig->greenSize == contextConfig->greenSize &&
1266*8975f5c5SAndroid Build Coastguard Worker                        surfaceConfig->blueSize == contextConfig->blueSize &&
1267*8975f5c5SAndroid Build Coastguard Worker                        surfaceConfig->alphaSize == contextConfig->alphaSize &&
1268*8975f5c5SAndroid Build Coastguard Worker                        surfaceConfig->luminanceSize == contextConfig->luminanceSize;
1269*8975f5c5SAndroid Build Coastguard Worker     if (!colorCompat)
1270*8975f5c5SAndroid Build Coastguard Worker     {
1271*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_MATCH, "Color buffer sizes are not compatible.");
1272*8975f5c5SAndroid Build Coastguard Worker         return false;
1273*8975f5c5SAndroid Build Coastguard Worker     }
1274*8975f5c5SAndroid Build Coastguard Worker 
1275*8975f5c5SAndroid Build Coastguard Worker     bool componentTypeCompat =
1276*8975f5c5SAndroid Build Coastguard Worker         surfaceConfig->colorComponentType == contextConfig->colorComponentType;
1277*8975f5c5SAndroid Build Coastguard Worker     if (!componentTypeCompat)
1278*8975f5c5SAndroid Build Coastguard Worker     {
1279*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_MATCH, "Color buffer component types are not compatible.");
1280*8975f5c5SAndroid Build Coastguard Worker         return false;
1281*8975f5c5SAndroid Build Coastguard Worker     }
1282*8975f5c5SAndroid Build Coastguard Worker 
1283*8975f5c5SAndroid Build Coastguard Worker     bool dsCompat = surfaceConfig->depthSize == contextConfig->depthSize &&
1284*8975f5c5SAndroid Build Coastguard Worker                     surfaceConfig->stencilSize == contextConfig->stencilSize;
1285*8975f5c5SAndroid Build Coastguard Worker     if (!dsCompat)
1286*8975f5c5SAndroid Build Coastguard Worker     {
1287*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_MATCH, "Depth-stencil buffer types are not compatible.");
1288*8975f5c5SAndroid Build Coastguard Worker         return false;
1289*8975f5c5SAndroid Build Coastguard Worker     }
1290*8975f5c5SAndroid Build Coastguard Worker 
1291*8975f5c5SAndroid Build Coastguard Worker     bool surfaceTypeCompat = (surfaceConfig->surfaceType & contextConfig->surfaceType) != 0;
1292*8975f5c5SAndroid Build Coastguard Worker     if (!surfaceTypeCompat)
1293*8975f5c5SAndroid Build Coastguard Worker     {
1294*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_MATCH, "Surface type is not compatible.");
1295*8975f5c5SAndroid Build Coastguard Worker         return false;
1296*8975f5c5SAndroid Build Coastguard Worker     }
1297*8975f5c5SAndroid Build Coastguard Worker 
1298*8975f5c5SAndroid Build Coastguard Worker     return true;
1299*8975f5c5SAndroid Build Coastguard Worker }
1300*8975f5c5SAndroid Build Coastguard Worker 
ValidateSurfaceBadAccess(const ValidationContext * val,const gl::Context * previousContext,const Surface * surface)1301*8975f5c5SAndroid Build Coastguard Worker bool ValidateSurfaceBadAccess(const ValidationContext *val,
1302*8975f5c5SAndroid Build Coastguard Worker                               const gl::Context *previousContext,
1303*8975f5c5SAndroid Build Coastguard Worker                               const Surface *surface)
1304*8975f5c5SAndroid Build Coastguard Worker {
1305*8975f5c5SAndroid Build Coastguard Worker     if (surface->isReferenced() &&
1306*8975f5c5SAndroid Build Coastguard Worker         (previousContext == nullptr || (surface != previousContext->getCurrentDrawSurface() &&
1307*8975f5c5SAndroid Build Coastguard Worker                                         surface != previousContext->getCurrentReadSurface())))
1308*8975f5c5SAndroid Build Coastguard Worker     {
1309*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_ACCESS, "Surface can only be current on one thread");
1310*8975f5c5SAndroid Build Coastguard Worker         return false;
1311*8975f5c5SAndroid Build Coastguard Worker     }
1312*8975f5c5SAndroid Build Coastguard Worker     return true;
1313*8975f5c5SAndroid Build Coastguard Worker }
1314*8975f5c5SAndroid Build Coastguard Worker 
ValidateCreateSyncBase(const ValidationContext * val,const Display * display,EGLenum type,const AttributeMap & attribs,bool isExt)1315*8975f5c5SAndroid Build Coastguard Worker bool ValidateCreateSyncBase(const ValidationContext *val,
1316*8975f5c5SAndroid Build Coastguard Worker                             const Display *display,
1317*8975f5c5SAndroid Build Coastguard Worker                             EGLenum type,
1318*8975f5c5SAndroid Build Coastguard Worker                             const AttributeMap &attribs,
1319*8975f5c5SAndroid Build Coastguard Worker                             bool isExt)
1320*8975f5c5SAndroid Build Coastguard Worker {
1321*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
1322*8975f5c5SAndroid Build Coastguard Worker 
1323*8975f5c5SAndroid Build Coastguard Worker     attribs.initializeWithoutValidation();
1324*8975f5c5SAndroid Build Coastguard Worker 
1325*8975f5c5SAndroid Build Coastguard Worker     gl::Context *currentContext  = val->eglThread->getContext();
1326*8975f5c5SAndroid Build Coastguard Worker     egl::Display *currentDisplay = currentContext ? currentContext->getDisplay() : nullptr;
1327*8975f5c5SAndroid Build Coastguard Worker 
1328*8975f5c5SAndroid Build Coastguard Worker     switch (type)
1329*8975f5c5SAndroid Build Coastguard Worker     {
1330*8975f5c5SAndroid Build Coastguard Worker         case EGL_SYNC_FENCE_KHR:
1331*8975f5c5SAndroid Build Coastguard Worker         case EGL_SYNC_GLOBAL_FENCE_ANGLE:
1332*8975f5c5SAndroid Build Coastguard Worker             if (!attribs.isEmpty())
1333*8975f5c5SAndroid Build Coastguard Worker             {
1334*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE, "Invalid attribute");
1335*8975f5c5SAndroid Build Coastguard Worker                 return false;
1336*8975f5c5SAndroid Build Coastguard Worker             }
1337*8975f5c5SAndroid Build Coastguard Worker 
1338*8975f5c5SAndroid Build Coastguard Worker             if (!display->getExtensions().fenceSync)
1339*8975f5c5SAndroid Build Coastguard Worker             {
1340*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_MATCH, "EGL_KHR_fence_sync extension is not available");
1341*8975f5c5SAndroid Build Coastguard Worker                 return false;
1342*8975f5c5SAndroid Build Coastguard Worker             }
1343*8975f5c5SAndroid Build Coastguard Worker 
1344*8975f5c5SAndroid Build Coastguard Worker             if (type == EGL_SYNC_GLOBAL_FENCE_ANGLE)
1345*8975f5c5SAndroid Build Coastguard Worker             {
1346*8975f5c5SAndroid Build Coastguard Worker                 if (!display->getExtensions().globalFenceSyncANGLE)
1347*8975f5c5SAndroid Build Coastguard Worker                 {
1348*8975f5c5SAndroid Build Coastguard Worker                     val->setError(EGL_BAD_MATCH,
1349*8975f5c5SAndroid Build Coastguard Worker                                   "EGL_ANGLE_global_fence_sync extension is not available");
1350*8975f5c5SAndroid Build Coastguard Worker                     return false;
1351*8975f5c5SAndroid Build Coastguard Worker                 }
1352*8975f5c5SAndroid Build Coastguard Worker             }
1353*8975f5c5SAndroid Build Coastguard Worker 
1354*8975f5c5SAndroid Build Coastguard Worker             if (display != currentDisplay)
1355*8975f5c5SAndroid Build Coastguard Worker             {
1356*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_MATCH,
1357*8975f5c5SAndroid Build Coastguard Worker                               "CreateSync can only be called on the current display");
1358*8975f5c5SAndroid Build Coastguard Worker                 return false;
1359*8975f5c5SAndroid Build Coastguard Worker             }
1360*8975f5c5SAndroid Build Coastguard Worker 
1361*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_TRY(ValidateContext(val, currentDisplay, currentContext->id()));
1362*8975f5c5SAndroid Build Coastguard Worker 
1363*8975f5c5SAndroid Build Coastguard Worker             if (!currentContext->getExtensions().EGLSyncOES)
1364*8975f5c5SAndroid Build Coastguard Worker             {
1365*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_MATCH,
1366*8975f5c5SAndroid Build Coastguard Worker                               "EGL_SYNC_FENCE_KHR cannot be used without "
1367*8975f5c5SAndroid Build Coastguard Worker                               "GL_OES_EGL_sync support.");
1368*8975f5c5SAndroid Build Coastguard Worker                 return false;
1369*8975f5c5SAndroid Build Coastguard Worker             }
1370*8975f5c5SAndroid Build Coastguard Worker             break;
1371*8975f5c5SAndroid Build Coastguard Worker 
1372*8975f5c5SAndroid Build Coastguard Worker         case EGL_SYNC_NATIVE_FENCE_ANDROID:
1373*8975f5c5SAndroid Build Coastguard Worker             if (!display->getExtensions().fenceSync)
1374*8975f5c5SAndroid Build Coastguard Worker             {
1375*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_MATCH, "EGL_KHR_fence_sync extension is not available");
1376*8975f5c5SAndroid Build Coastguard Worker                 return false;
1377*8975f5c5SAndroid Build Coastguard Worker             }
1378*8975f5c5SAndroid Build Coastguard Worker 
1379*8975f5c5SAndroid Build Coastguard Worker             if (!display->getExtensions().nativeFenceSyncANDROID)
1380*8975f5c5SAndroid Build Coastguard Worker             {
1381*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_DISPLAY,
1382*8975f5c5SAndroid Build Coastguard Worker                               "EGL_ANDROID_native_fence_sync extension is not available.");
1383*8975f5c5SAndroid Build Coastguard Worker                 return false;
1384*8975f5c5SAndroid Build Coastguard Worker             }
1385*8975f5c5SAndroid Build Coastguard Worker 
1386*8975f5c5SAndroid Build Coastguard Worker             if (display != currentDisplay)
1387*8975f5c5SAndroid Build Coastguard Worker             {
1388*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_MATCH,
1389*8975f5c5SAndroid Build Coastguard Worker                               "CreateSync can only be called on the current display");
1390*8975f5c5SAndroid Build Coastguard Worker                 return false;
1391*8975f5c5SAndroid Build Coastguard Worker             }
1392*8975f5c5SAndroid Build Coastguard Worker 
1393*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_TRY(ValidateContext(val, currentDisplay, currentContext->id()));
1394*8975f5c5SAndroid Build Coastguard Worker 
1395*8975f5c5SAndroid Build Coastguard Worker             if (!currentContext->getExtensions().EGLSyncOES)
1396*8975f5c5SAndroid Build Coastguard Worker             {
1397*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_MATCH,
1398*8975f5c5SAndroid Build Coastguard Worker                               "EGL_SYNC_NATIVE_FENCE_ANDROID cannot be used without "
1399*8975f5c5SAndroid Build Coastguard Worker                               "GL_OES_EGL_sync support.");
1400*8975f5c5SAndroid Build Coastguard Worker                 return false;
1401*8975f5c5SAndroid Build Coastguard Worker             }
1402*8975f5c5SAndroid Build Coastguard Worker 
1403*8975f5c5SAndroid Build Coastguard Worker             for (const auto &attributeIter : attribs)
1404*8975f5c5SAndroid Build Coastguard Worker             {
1405*8975f5c5SAndroid Build Coastguard Worker                 EGLAttrib attribute = attributeIter.first;
1406*8975f5c5SAndroid Build Coastguard Worker 
1407*8975f5c5SAndroid Build Coastguard Worker                 switch (attribute)
1408*8975f5c5SAndroid Build Coastguard Worker                 {
1409*8975f5c5SAndroid Build Coastguard Worker                     case EGL_SYNC_NATIVE_FENCE_FD_ANDROID:
1410*8975f5c5SAndroid Build Coastguard Worker                         break;
1411*8975f5c5SAndroid Build Coastguard Worker 
1412*8975f5c5SAndroid Build Coastguard Worker                     default:
1413*8975f5c5SAndroid Build Coastguard Worker                         val->setError(EGL_BAD_ATTRIBUTE, "Invalid attribute");
1414*8975f5c5SAndroid Build Coastguard Worker                         return false;
1415*8975f5c5SAndroid Build Coastguard Worker                 }
1416*8975f5c5SAndroid Build Coastguard Worker             }
1417*8975f5c5SAndroid Build Coastguard Worker             break;
1418*8975f5c5SAndroid Build Coastguard Worker 
1419*8975f5c5SAndroid Build Coastguard Worker         case EGL_SYNC_REUSABLE_KHR:
1420*8975f5c5SAndroid Build Coastguard Worker             if (!attribs.isEmpty())
1421*8975f5c5SAndroid Build Coastguard Worker             {
1422*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE, "Invalid attribute");
1423*8975f5c5SAndroid Build Coastguard Worker                 return false;
1424*8975f5c5SAndroid Build Coastguard Worker             }
1425*8975f5c5SAndroid Build Coastguard Worker 
1426*8975f5c5SAndroid Build Coastguard Worker             if (!display->getExtensions().reusableSyncKHR)
1427*8975f5c5SAndroid Build Coastguard Worker             {
1428*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_MATCH, "EGL_KHR_reusable_sync extension is not available.");
1429*8975f5c5SAndroid Build Coastguard Worker                 return false;
1430*8975f5c5SAndroid Build Coastguard Worker             }
1431*8975f5c5SAndroid Build Coastguard Worker             break;
1432*8975f5c5SAndroid Build Coastguard Worker 
1433*8975f5c5SAndroid Build Coastguard Worker         case EGL_SYNC_METAL_SHARED_EVENT_ANGLE:
1434*8975f5c5SAndroid Build Coastguard Worker             if (!display->getExtensions().fenceSync)
1435*8975f5c5SAndroid Build Coastguard Worker             {
1436*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_MATCH, "EGL_KHR_fence_sync extension is not available");
1437*8975f5c5SAndroid Build Coastguard Worker                 return false;
1438*8975f5c5SAndroid Build Coastguard Worker             }
1439*8975f5c5SAndroid Build Coastguard Worker 
1440*8975f5c5SAndroid Build Coastguard Worker             if (!display->getExtensions().mtlSyncSharedEventANGLE)
1441*8975f5c5SAndroid Build Coastguard Worker             {
1442*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_DISPLAY,
1443*8975f5c5SAndroid Build Coastguard Worker                               "EGL_ANGLE_metal_shared_event_sync is not available");
1444*8975f5c5SAndroid Build Coastguard Worker                 return false;
1445*8975f5c5SAndroid Build Coastguard Worker             }
1446*8975f5c5SAndroid Build Coastguard Worker 
1447*8975f5c5SAndroid Build Coastguard Worker             if (display != currentDisplay)
1448*8975f5c5SAndroid Build Coastguard Worker             {
1449*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_MATCH,
1450*8975f5c5SAndroid Build Coastguard Worker                               "CreateSync can only be called on the current display");
1451*8975f5c5SAndroid Build Coastguard Worker                 return false;
1452*8975f5c5SAndroid Build Coastguard Worker             }
1453*8975f5c5SAndroid Build Coastguard Worker 
1454*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_TRY(ValidateContext(val, currentDisplay, currentContext->id()));
1455*8975f5c5SAndroid Build Coastguard Worker 
1456*8975f5c5SAndroid Build Coastguard Worker             // This should be implied by exposing EGL_KHR_fence_sync
1457*8975f5c5SAndroid Build Coastguard Worker             ASSERT(currentContext->getExtensions().EGLSyncOES);
1458*8975f5c5SAndroid Build Coastguard Worker 
1459*8975f5c5SAndroid Build Coastguard Worker             for (const auto &attributeIter : attribs)
1460*8975f5c5SAndroid Build Coastguard Worker             {
1461*8975f5c5SAndroid Build Coastguard Worker                 EGLAttrib attribute = attributeIter.first;
1462*8975f5c5SAndroid Build Coastguard Worker                 EGLAttrib value     = attributeIter.second;
1463*8975f5c5SAndroid Build Coastguard Worker 
1464*8975f5c5SAndroid Build Coastguard Worker                 switch (attribute)
1465*8975f5c5SAndroid Build Coastguard Worker                 {
1466*8975f5c5SAndroid Build Coastguard Worker                     case EGL_SYNC_CONDITION:
1467*8975f5c5SAndroid Build Coastguard Worker                         if (type != EGL_SYNC_METAL_SHARED_EVENT_ANGLE ||
1468*8975f5c5SAndroid Build Coastguard Worker                             (value != EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR &&
1469*8975f5c5SAndroid Build Coastguard Worker                              value != EGL_SYNC_METAL_SHARED_EVENT_SIGNALED_ANGLE))
1470*8975f5c5SAndroid Build Coastguard Worker                         {
1471*8975f5c5SAndroid Build Coastguard Worker                             val->setError(EGL_BAD_ATTRIBUTE, "Invalid attribute");
1472*8975f5c5SAndroid Build Coastguard Worker                         }
1473*8975f5c5SAndroid Build Coastguard Worker                         break;
1474*8975f5c5SAndroid Build Coastguard Worker 
1475*8975f5c5SAndroid Build Coastguard Worker                     case EGL_SYNC_METAL_SHARED_EVENT_OBJECT_ANGLE:
1476*8975f5c5SAndroid Build Coastguard Worker                         if (!value)
1477*8975f5c5SAndroid Build Coastguard Worker                         {
1478*8975f5c5SAndroid Build Coastguard Worker                             val->setError(EGL_BAD_ATTRIBUTE,
1479*8975f5c5SAndroid Build Coastguard Worker                                           "EGL_SYNC_METAL_SHARED_EVENT_ANGLE can't be NULL");
1480*8975f5c5SAndroid Build Coastguard Worker                             return false;
1481*8975f5c5SAndroid Build Coastguard Worker                         }
1482*8975f5c5SAndroid Build Coastguard Worker                         break;
1483*8975f5c5SAndroid Build Coastguard Worker 
1484*8975f5c5SAndroid Build Coastguard Worker                     case EGL_SYNC_METAL_SHARED_EVENT_SIGNAL_VALUE_LO_ANGLE:
1485*8975f5c5SAndroid Build Coastguard Worker                     case EGL_SYNC_METAL_SHARED_EVENT_SIGNAL_VALUE_HI_ANGLE:
1486*8975f5c5SAndroid Build Coastguard Worker                         break;
1487*8975f5c5SAndroid Build Coastguard Worker 
1488*8975f5c5SAndroid Build Coastguard Worker                     default:
1489*8975f5c5SAndroid Build Coastguard Worker                         val->setError(EGL_BAD_ATTRIBUTE, "Invalid attribute");
1490*8975f5c5SAndroid Build Coastguard Worker                         return false;
1491*8975f5c5SAndroid Build Coastguard Worker                 }
1492*8975f5c5SAndroid Build Coastguard Worker             }
1493*8975f5c5SAndroid Build Coastguard Worker             break;
1494*8975f5c5SAndroid Build Coastguard Worker 
1495*8975f5c5SAndroid Build Coastguard Worker         default:
1496*8975f5c5SAndroid Build Coastguard Worker             if (isExt)
1497*8975f5c5SAndroid Build Coastguard Worker             {
1498*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE, "Invalid type parameter");
1499*8975f5c5SAndroid Build Coastguard Worker                 return false;
1500*8975f5c5SAndroid Build Coastguard Worker             }
1501*8975f5c5SAndroid Build Coastguard Worker             else
1502*8975f5c5SAndroid Build Coastguard Worker             {
1503*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_PARAMETER, "Invalid type parameter");
1504*8975f5c5SAndroid Build Coastguard Worker                 return false;
1505*8975f5c5SAndroid Build Coastguard Worker             }
1506*8975f5c5SAndroid Build Coastguard Worker     }
1507*8975f5c5SAndroid Build Coastguard Worker 
1508*8975f5c5SAndroid Build Coastguard Worker     return true;
1509*8975f5c5SAndroid Build Coastguard Worker }
1510*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetSyncAttribBase(const ValidationContext * val,const Display * display,SyncID sync,EGLint attribute)1511*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetSyncAttribBase(const ValidationContext *val,
1512*8975f5c5SAndroid Build Coastguard Worker                                const Display *display,
1513*8975f5c5SAndroid Build Coastguard Worker                                SyncID sync,
1514*8975f5c5SAndroid Build Coastguard Worker                                EGLint attribute)
1515*8975f5c5SAndroid Build Coastguard Worker {
1516*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateSync(val, display, sync));
1517*8975f5c5SAndroid Build Coastguard Worker 
1518*8975f5c5SAndroid Build Coastguard Worker     const Sync *syncObj = display->getSync(sync);
1519*8975f5c5SAndroid Build Coastguard Worker 
1520*8975f5c5SAndroid Build Coastguard Worker     switch (attribute)
1521*8975f5c5SAndroid Build Coastguard Worker     {
1522*8975f5c5SAndroid Build Coastguard Worker         case EGL_SYNC_CONDITION_KHR:
1523*8975f5c5SAndroid Build Coastguard Worker             switch (syncObj->getType())
1524*8975f5c5SAndroid Build Coastguard Worker             {
1525*8975f5c5SAndroid Build Coastguard Worker                 case EGL_SYNC_FENCE_KHR:
1526*8975f5c5SAndroid Build Coastguard Worker                 case EGL_SYNC_NATIVE_FENCE_ANDROID:
1527*8975f5c5SAndroid Build Coastguard Worker                 case EGL_SYNC_GLOBAL_FENCE_ANGLE:
1528*8975f5c5SAndroid Build Coastguard Worker                 case EGL_SYNC_METAL_SHARED_EVENT_ANGLE:
1529*8975f5c5SAndroid Build Coastguard Worker                     break;
1530*8975f5c5SAndroid Build Coastguard Worker 
1531*8975f5c5SAndroid Build Coastguard Worker                 default:
1532*8975f5c5SAndroid Build Coastguard Worker                     val->setError(EGL_BAD_ATTRIBUTE,
1533*8975f5c5SAndroid Build Coastguard Worker                                   "EGL_SYNC_CONDITION_KHR is not valid for this sync type.");
1534*8975f5c5SAndroid Build Coastguard Worker                     return false;
1535*8975f5c5SAndroid Build Coastguard Worker             }
1536*8975f5c5SAndroid Build Coastguard Worker             break;
1537*8975f5c5SAndroid Build Coastguard Worker 
1538*8975f5c5SAndroid Build Coastguard Worker         // The following attributes are accepted by all types
1539*8975f5c5SAndroid Build Coastguard Worker         case EGL_SYNC_TYPE_KHR:
1540*8975f5c5SAndroid Build Coastguard Worker         case EGL_SYNC_STATUS_KHR:
1541*8975f5c5SAndroid Build Coastguard Worker             break;
1542*8975f5c5SAndroid Build Coastguard Worker 
1543*8975f5c5SAndroid Build Coastguard Worker         default:
1544*8975f5c5SAndroid Build Coastguard Worker             val->setError(EGL_BAD_ATTRIBUTE, "Invalid attribute");
1545*8975f5c5SAndroid Build Coastguard Worker             return false;
1546*8975f5c5SAndroid Build Coastguard Worker     }
1547*8975f5c5SAndroid Build Coastguard Worker 
1548*8975f5c5SAndroid Build Coastguard Worker     return true;
1549*8975f5c5SAndroid Build Coastguard Worker }
1550*8975f5c5SAndroid Build Coastguard Worker 
ValidateQueryDisplayAttribBase(const ValidationContext * val,const Display * display,const EGLint attribute)1551*8975f5c5SAndroid Build Coastguard Worker bool ValidateQueryDisplayAttribBase(const ValidationContext *val,
1552*8975f5c5SAndroid Build Coastguard Worker                                     const Display *display,
1553*8975f5c5SAndroid Build Coastguard Worker                                     const EGLint attribute)
1554*8975f5c5SAndroid Build Coastguard Worker {
1555*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
1556*8975f5c5SAndroid Build Coastguard Worker 
1557*8975f5c5SAndroid Build Coastguard Worker     switch (attribute)
1558*8975f5c5SAndroid Build Coastguard Worker     {
1559*8975f5c5SAndroid Build Coastguard Worker         case EGL_DEVICE_EXT:
1560*8975f5c5SAndroid Build Coastguard Worker             if (!Display::GetClientExtensions().deviceQueryEXT)
1561*8975f5c5SAndroid Build Coastguard Worker             {
1562*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_DISPLAY, "EGL_EXT_device_query extension is not available.");
1563*8975f5c5SAndroid Build Coastguard Worker                 return false;
1564*8975f5c5SAndroid Build Coastguard Worker             }
1565*8975f5c5SAndroid Build Coastguard Worker             break;
1566*8975f5c5SAndroid Build Coastguard Worker 
1567*8975f5c5SAndroid Build Coastguard Worker         case EGL_FEATURE_COUNT_ANGLE:
1568*8975f5c5SAndroid Build Coastguard Worker             if (!Display::GetClientExtensions().featureControlANGLE)
1569*8975f5c5SAndroid Build Coastguard Worker             {
1570*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_DISPLAY,
1571*8975f5c5SAndroid Build Coastguard Worker                               "EGL_ANGLE_feature_control extension is not available.");
1572*8975f5c5SAndroid Build Coastguard Worker                 return false;
1573*8975f5c5SAndroid Build Coastguard Worker             }
1574*8975f5c5SAndroid Build Coastguard Worker             break;
1575*8975f5c5SAndroid Build Coastguard Worker 
1576*8975f5c5SAndroid Build Coastguard Worker         default:
1577*8975f5c5SAndroid Build Coastguard Worker             val->setError(EGL_BAD_ATTRIBUTE, "attribute is not valid.");
1578*8975f5c5SAndroid Build Coastguard Worker             return false;
1579*8975f5c5SAndroid Build Coastguard Worker     }
1580*8975f5c5SAndroid Build Coastguard Worker 
1581*8975f5c5SAndroid Build Coastguard Worker     return true;
1582*8975f5c5SAndroid Build Coastguard Worker }
1583*8975f5c5SAndroid Build Coastguard Worker 
ValidateCreateContextAttribute(const ValidationContext * val,const Display * display,EGLAttrib attribute)1584*8975f5c5SAndroid Build Coastguard Worker bool ValidateCreateContextAttribute(const ValidationContext *val,
1585*8975f5c5SAndroid Build Coastguard Worker                                     const Display *display,
1586*8975f5c5SAndroid Build Coastguard Worker                                     EGLAttrib attribute)
1587*8975f5c5SAndroid Build Coastguard Worker {
1588*8975f5c5SAndroid Build Coastguard Worker     switch (attribute)
1589*8975f5c5SAndroid Build Coastguard Worker     {
1590*8975f5c5SAndroid Build Coastguard Worker         case EGL_CONTEXT_CLIENT_VERSION:
1591*8975f5c5SAndroid Build Coastguard Worker         case EGL_CONTEXT_MINOR_VERSION:
1592*8975f5c5SAndroid Build Coastguard Worker         case EGL_CONTEXT_FLAGS_KHR:
1593*8975f5c5SAndroid Build Coastguard Worker         case EGL_CONTEXT_OPENGL_DEBUG:
1594*8975f5c5SAndroid Build Coastguard Worker         case EGL_CONTEXT_OPENGL_ROBUST_ACCESS:
1595*8975f5c5SAndroid Build Coastguard Worker         case EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR:
1596*8975f5c5SAndroid Build Coastguard Worker             break;
1597*8975f5c5SAndroid Build Coastguard Worker 
1598*8975f5c5SAndroid Build Coastguard Worker         case EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT:
1599*8975f5c5SAndroid Build Coastguard Worker             if (!display->getExtensions().createContextRobustness)
1600*8975f5c5SAndroid Build Coastguard Worker             {
1601*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE);
1602*8975f5c5SAndroid Build Coastguard Worker                 return false;
1603*8975f5c5SAndroid Build Coastguard Worker             }
1604*8975f5c5SAndroid Build Coastguard Worker             break;
1605*8975f5c5SAndroid Build Coastguard Worker 
1606*8975f5c5SAndroid Build Coastguard Worker         case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT:
1607*8975f5c5SAndroid Build Coastguard Worker             if (!display->getExtensions().createContextRobustness)
1608*8975f5c5SAndroid Build Coastguard Worker             {
1609*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE);
1610*8975f5c5SAndroid Build Coastguard Worker                 return false;
1611*8975f5c5SAndroid Build Coastguard Worker             }
1612*8975f5c5SAndroid Build Coastguard Worker             break;
1613*8975f5c5SAndroid Build Coastguard Worker 
1614*8975f5c5SAndroid Build Coastguard Worker         case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY:
1615*8975f5c5SAndroid Build Coastguard Worker         {
1616*8975f5c5SAndroid Build Coastguard Worker             // We either need to have -
1617*8975f5c5SAndroid Build Coastguard Worker             // 1. EGL 1.5 which added support for this as part of core spec
1618*8975f5c5SAndroid Build Coastguard Worker             // 2. EGL_KHR_create_context extension which requires EGL 1.4
1619*8975f5c5SAndroid Build Coastguard Worker             constexpr EGLint kRequiredMajorVersion = 1;
1620*8975f5c5SAndroid Build Coastguard Worker             constexpr EGLint kRequiredMinorVersion = 5;
1621*8975f5c5SAndroid Build Coastguard Worker             if ((kEglMajorVersion < kRequiredMajorVersion ||
1622*8975f5c5SAndroid Build Coastguard Worker                  kEglMinorVersion < kRequiredMinorVersion) &&
1623*8975f5c5SAndroid Build Coastguard Worker                 !display->getExtensions().createContext)
1624*8975f5c5SAndroid Build Coastguard Worker             {
1625*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE);
1626*8975f5c5SAndroid Build Coastguard Worker                 return false;
1627*8975f5c5SAndroid Build Coastguard Worker             }
1628*8975f5c5SAndroid Build Coastguard Worker             break;
1629*8975f5c5SAndroid Build Coastguard Worker         }
1630*8975f5c5SAndroid Build Coastguard Worker 
1631*8975f5c5SAndroid Build Coastguard Worker         case EGL_CONTEXT_OPENGL_NO_ERROR_KHR:
1632*8975f5c5SAndroid Build Coastguard Worker             if (!display->getExtensions().createContextNoError)
1633*8975f5c5SAndroid Build Coastguard Worker             {
1634*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE, "Invalid Context attribute.");
1635*8975f5c5SAndroid Build Coastguard Worker                 return false;
1636*8975f5c5SAndroid Build Coastguard Worker             }
1637*8975f5c5SAndroid Build Coastguard Worker             break;
1638*8975f5c5SAndroid Build Coastguard Worker 
1639*8975f5c5SAndroid Build Coastguard Worker         case EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE:
1640*8975f5c5SAndroid Build Coastguard Worker             if (!display->getExtensions().createContextWebGLCompatibility)
1641*8975f5c5SAndroid Build Coastguard Worker             {
1642*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE,
1643*8975f5c5SAndroid Build Coastguard Worker                               "Attribute "
1644*8975f5c5SAndroid Build Coastguard Worker                               "EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE requires "
1645*8975f5c5SAndroid Build Coastguard Worker                               "EGL_ANGLE_create_context_webgl_compatibility.");
1646*8975f5c5SAndroid Build Coastguard Worker                 return false;
1647*8975f5c5SAndroid Build Coastguard Worker             }
1648*8975f5c5SAndroid Build Coastguard Worker             break;
1649*8975f5c5SAndroid Build Coastguard Worker 
1650*8975f5c5SAndroid Build Coastguard Worker         case EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM:
1651*8975f5c5SAndroid Build Coastguard Worker             if (!display->getExtensions().createContextBindGeneratesResource)
1652*8975f5c5SAndroid Build Coastguard Worker             {
1653*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE,
1654*8975f5c5SAndroid Build Coastguard Worker                               "Attribute EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM requires "
1655*8975f5c5SAndroid Build Coastguard Worker                               "EGL_CHROMIUM_create_context_bind_generates_resource.");
1656*8975f5c5SAndroid Build Coastguard Worker                 return false;
1657*8975f5c5SAndroid Build Coastguard Worker             }
1658*8975f5c5SAndroid Build Coastguard Worker             break;
1659*8975f5c5SAndroid Build Coastguard Worker 
1660*8975f5c5SAndroid Build Coastguard Worker         case EGL_DISPLAY_TEXTURE_SHARE_GROUP_ANGLE:
1661*8975f5c5SAndroid Build Coastguard Worker             if (!display->getExtensions().displayTextureShareGroup)
1662*8975f5c5SAndroid Build Coastguard Worker             {
1663*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE,
1664*8975f5c5SAndroid Build Coastguard Worker                               "Attribute "
1665*8975f5c5SAndroid Build Coastguard Worker                               "EGL_DISPLAY_TEXTURE_SHARE_GROUP_ANGLE requires "
1666*8975f5c5SAndroid Build Coastguard Worker                               "EGL_ANGLE_display_texture_share_group.");
1667*8975f5c5SAndroid Build Coastguard Worker                 return false;
1668*8975f5c5SAndroid Build Coastguard Worker             }
1669*8975f5c5SAndroid Build Coastguard Worker             break;
1670*8975f5c5SAndroid Build Coastguard Worker 
1671*8975f5c5SAndroid Build Coastguard Worker         case EGL_DISPLAY_SEMAPHORE_SHARE_GROUP_ANGLE:
1672*8975f5c5SAndroid Build Coastguard Worker             if (!display->getExtensions().displayTextureShareGroup)
1673*8975f5c5SAndroid Build Coastguard Worker             {
1674*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE,
1675*8975f5c5SAndroid Build Coastguard Worker                               "Attribute "
1676*8975f5c5SAndroid Build Coastguard Worker                               "EGL_DISPLAY_SEMAPHORE_SHARE_GROUP_ANGLE requires "
1677*8975f5c5SAndroid Build Coastguard Worker                               "EGL_ANGLE_display_semaphore_share_group.");
1678*8975f5c5SAndroid Build Coastguard Worker                 return false;
1679*8975f5c5SAndroid Build Coastguard Worker             }
1680*8975f5c5SAndroid Build Coastguard Worker             break;
1681*8975f5c5SAndroid Build Coastguard Worker 
1682*8975f5c5SAndroid Build Coastguard Worker         case EGL_CONTEXT_CLIENT_ARRAYS_ENABLED_ANGLE:
1683*8975f5c5SAndroid Build Coastguard Worker             if (!display->getExtensions().createContextClientArrays)
1684*8975f5c5SAndroid Build Coastguard Worker             {
1685*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE,
1686*8975f5c5SAndroid Build Coastguard Worker                               "Attribute EGL_CONTEXT_CLIENT_ARRAYS_ENABLED_ANGLE requires "
1687*8975f5c5SAndroid Build Coastguard Worker                               "EGL_ANGLE_create_context_client_arrays.");
1688*8975f5c5SAndroid Build Coastguard Worker                 return false;
1689*8975f5c5SAndroid Build Coastguard Worker             }
1690*8975f5c5SAndroid Build Coastguard Worker             break;
1691*8975f5c5SAndroid Build Coastguard Worker 
1692*8975f5c5SAndroid Build Coastguard Worker         case EGL_CONTEXT_PROGRAM_BINARY_CACHE_ENABLED_ANGLE:
1693*8975f5c5SAndroid Build Coastguard Worker             if (!display->getExtensions().programCacheControlANGLE)
1694*8975f5c5SAndroid Build Coastguard Worker             {
1695*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE,
1696*8975f5c5SAndroid Build Coastguard Worker                               "Attribute EGL_CONTEXT_PROGRAM_BINARY_CACHE_ENABLED_ANGLE "
1697*8975f5c5SAndroid Build Coastguard Worker                               "requires EGL_ANGLE_program_cache_control.");
1698*8975f5c5SAndroid Build Coastguard Worker                 return false;
1699*8975f5c5SAndroid Build Coastguard Worker             }
1700*8975f5c5SAndroid Build Coastguard Worker             break;
1701*8975f5c5SAndroid Build Coastguard Worker 
1702*8975f5c5SAndroid Build Coastguard Worker         case EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
1703*8975f5c5SAndroid Build Coastguard Worker             if (!display->getExtensions().robustResourceInitializationANGLE)
1704*8975f5c5SAndroid Build Coastguard Worker             {
1705*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE,
1706*8975f5c5SAndroid Build Coastguard Worker                               "Attribute EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE "
1707*8975f5c5SAndroid Build Coastguard Worker                               "requires EGL_ANGLE_robust_resource_initialization.");
1708*8975f5c5SAndroid Build Coastguard Worker                 return false;
1709*8975f5c5SAndroid Build Coastguard Worker             }
1710*8975f5c5SAndroid Build Coastguard Worker             break;
1711*8975f5c5SAndroid Build Coastguard Worker 
1712*8975f5c5SAndroid Build Coastguard Worker         case EGL_EXTENSIONS_ENABLED_ANGLE:
1713*8975f5c5SAndroid Build Coastguard Worker             if (!display->getExtensions().createContextExtensionsEnabled)
1714*8975f5c5SAndroid Build Coastguard Worker             {
1715*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE,
1716*8975f5c5SAndroid Build Coastguard Worker                               "Attribute EGL_EXTENSIONS_ENABLED_ANGLE "
1717*8975f5c5SAndroid Build Coastguard Worker                               "requires EGL_ANGLE_create_context_extensions_enabled.");
1718*8975f5c5SAndroid Build Coastguard Worker                 return false;
1719*8975f5c5SAndroid Build Coastguard Worker             }
1720*8975f5c5SAndroid Build Coastguard Worker             break;
1721*8975f5c5SAndroid Build Coastguard Worker 
1722*8975f5c5SAndroid Build Coastguard Worker         case EGL_POWER_PREFERENCE_ANGLE:
1723*8975f5c5SAndroid Build Coastguard Worker             if (!display->getExtensions().powerPreference)
1724*8975f5c5SAndroid Build Coastguard Worker             {
1725*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE,
1726*8975f5c5SAndroid Build Coastguard Worker                               "Attribute EGL_POWER_PREFERENCE_ANGLE "
1727*8975f5c5SAndroid Build Coastguard Worker                               "requires EGL_ANGLE_power_preference.");
1728*8975f5c5SAndroid Build Coastguard Worker                 return false;
1729*8975f5c5SAndroid Build Coastguard Worker             }
1730*8975f5c5SAndroid Build Coastguard Worker             break;
1731*8975f5c5SAndroid Build Coastguard Worker 
1732*8975f5c5SAndroid Build Coastguard Worker         case EGL_CONTEXT_OPENGL_BACKWARDS_COMPATIBLE_ANGLE:
1733*8975f5c5SAndroid Build Coastguard Worker             if (!display->getExtensions().createContextBackwardsCompatible)
1734*8975f5c5SAndroid Build Coastguard Worker             {
1735*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE,
1736*8975f5c5SAndroid Build Coastguard Worker                               "Attribute EGL_CONTEXT_OPENGL_BACKWARDS_COMPATIBLE_ANGLE "
1737*8975f5c5SAndroid Build Coastguard Worker                               "requires EGL_ANGLE_create_context_backwards_compatible.");
1738*8975f5c5SAndroid Build Coastguard Worker                 return false;
1739*8975f5c5SAndroid Build Coastguard Worker             }
1740*8975f5c5SAndroid Build Coastguard Worker             break;
1741*8975f5c5SAndroid Build Coastguard Worker 
1742*8975f5c5SAndroid Build Coastguard Worker         case EGL_CONTEXT_PRIORITY_LEVEL_IMG:
1743*8975f5c5SAndroid Build Coastguard Worker             if (!display->getExtensions().contextPriority)
1744*8975f5c5SAndroid Build Coastguard Worker             {
1745*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE,
1746*8975f5c5SAndroid Build Coastguard Worker                               "Attribute EGL_CONTEXT_PRIORITY_LEVEL_IMG requires "
1747*8975f5c5SAndroid Build Coastguard Worker                               "extension EGL_IMG_context_priority.");
1748*8975f5c5SAndroid Build Coastguard Worker                 return false;
1749*8975f5c5SAndroid Build Coastguard Worker             }
1750*8975f5c5SAndroid Build Coastguard Worker             break;
1751*8975f5c5SAndroid Build Coastguard Worker 
1752*8975f5c5SAndroid Build Coastguard Worker         case EGL_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV:
1753*8975f5c5SAndroid Build Coastguard Worker             if (!display->getExtensions().robustnessVideoMemoryPurgeNV)
1754*8975f5c5SAndroid Build Coastguard Worker             {
1755*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE,
1756*8975f5c5SAndroid Build Coastguard Worker                               "Attribute EGL_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV requires "
1757*8975f5c5SAndroid Build Coastguard Worker                               "extension EGL_NV_robustness_video_memory_purge.");
1758*8975f5c5SAndroid Build Coastguard Worker                 return false;
1759*8975f5c5SAndroid Build Coastguard Worker             }
1760*8975f5c5SAndroid Build Coastguard Worker             break;
1761*8975f5c5SAndroid Build Coastguard Worker 
1762*8975f5c5SAndroid Build Coastguard Worker         case EGL_EXTERNAL_CONTEXT_ANGLE:
1763*8975f5c5SAndroid Build Coastguard Worker             if (!display->getExtensions().externalContextAndSurface)
1764*8975f5c5SAndroid Build Coastguard Worker             {
1765*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE,
1766*8975f5c5SAndroid Build Coastguard Worker                               "Attribute "
1767*8975f5c5SAndroid Build Coastguard Worker                               "EGL_EXTERNAL_CONTEXT_ANGLE requires "
1768*8975f5c5SAndroid Build Coastguard Worker                               "EGL_ANGLE_external_context_and_surface.");
1769*8975f5c5SAndroid Build Coastguard Worker                 return false;
1770*8975f5c5SAndroid Build Coastguard Worker             }
1771*8975f5c5SAndroid Build Coastguard Worker             break;
1772*8975f5c5SAndroid Build Coastguard Worker 
1773*8975f5c5SAndroid Build Coastguard Worker         case EGL_PROTECTED_CONTENT_EXT:
1774*8975f5c5SAndroid Build Coastguard Worker             if (!display->getExtensions().protectedContentEXT)
1775*8975f5c5SAndroid Build Coastguard Worker             {
1776*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE,
1777*8975f5c5SAndroid Build Coastguard Worker                               "Attribute EGL_PROTECTED_CONTEXT_EXT requires "
1778*8975f5c5SAndroid Build Coastguard Worker                               "extension EGL_EXT_protected_content.");
1779*8975f5c5SAndroid Build Coastguard Worker                 return false;
1780*8975f5c5SAndroid Build Coastguard Worker             }
1781*8975f5c5SAndroid Build Coastguard Worker             break;
1782*8975f5c5SAndroid Build Coastguard Worker 
1783*8975f5c5SAndroid Build Coastguard Worker         case EGL_CONTEXT_VIRTUALIZATION_GROUP_ANGLE:
1784*8975f5c5SAndroid Build Coastguard Worker             if (!display->getExtensions().contextVirtualizationANGLE)
1785*8975f5c5SAndroid Build Coastguard Worker             {
1786*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE,
1787*8975f5c5SAndroid Build Coastguard Worker                               "Attribute EGL_CONTEXT_VIRTUALIZATION_GROUP_ANGLE requires "
1788*8975f5c5SAndroid Build Coastguard Worker                               "extension EGL_ANGLE_context_virtualization.");
1789*8975f5c5SAndroid Build Coastguard Worker                 return false;
1790*8975f5c5SAndroid Build Coastguard Worker             }
1791*8975f5c5SAndroid Build Coastguard Worker             break;
1792*8975f5c5SAndroid Build Coastguard Worker 
1793*8975f5c5SAndroid Build Coastguard Worker         case EGL_CONTEXT_METAL_OWNERSHIP_IDENTITY_ANGLE:
1794*8975f5c5SAndroid Build Coastguard Worker             if (!display->getExtensions().metalCreateContextOwnershipIdentityANGLE)
1795*8975f5c5SAndroid Build Coastguard Worker             {
1796*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE,
1797*8975f5c5SAndroid Build Coastguard Worker                               "Attribute EGL_CONTEXT_METAL_OWNERSHIP_IDENTITY_ANGLE requires "
1798*8975f5c5SAndroid Build Coastguard Worker                               "EGL_ANGLE_metal_create_context_ownership_identity.");
1799*8975f5c5SAndroid Build Coastguard Worker             }
1800*8975f5c5SAndroid Build Coastguard Worker             break;
1801*8975f5c5SAndroid Build Coastguard Worker 
1802*8975f5c5SAndroid Build Coastguard Worker         default:
1803*8975f5c5SAndroid Build Coastguard Worker             val->setError(EGL_BAD_ATTRIBUTE, "Unknown attribute: 0x%04" PRIxPTR "X", attribute);
1804*8975f5c5SAndroid Build Coastguard Worker             return false;
1805*8975f5c5SAndroid Build Coastguard Worker     }
1806*8975f5c5SAndroid Build Coastguard Worker 
1807*8975f5c5SAndroid Build Coastguard Worker     return true;
1808*8975f5c5SAndroid Build Coastguard Worker }
1809*8975f5c5SAndroid Build Coastguard Worker 
ValidateCreateContextAttributeValue(const ValidationContext * val,const Display * display,const gl::Context * shareContext,EGLAttrib attribute,EGLAttrib value)1810*8975f5c5SAndroid Build Coastguard Worker bool ValidateCreateContextAttributeValue(const ValidationContext *val,
1811*8975f5c5SAndroid Build Coastguard Worker                                          const Display *display,
1812*8975f5c5SAndroid Build Coastguard Worker                                          const gl::Context *shareContext,
1813*8975f5c5SAndroid Build Coastguard Worker                                          EGLAttrib attribute,
1814*8975f5c5SAndroid Build Coastguard Worker                                          EGLAttrib value)
1815*8975f5c5SAndroid Build Coastguard Worker {
1816*8975f5c5SAndroid Build Coastguard Worker     switch (attribute)
1817*8975f5c5SAndroid Build Coastguard Worker     {
1818*8975f5c5SAndroid Build Coastguard Worker         case EGL_CONTEXT_CLIENT_VERSION:
1819*8975f5c5SAndroid Build Coastguard Worker         case EGL_CONTEXT_MINOR_VERSION:
1820*8975f5c5SAndroid Build Coastguard Worker         case EGL_CONTEXT_OPENGL_DEBUG:
1821*8975f5c5SAndroid Build Coastguard Worker         case EGL_CONTEXT_VIRTUALIZATION_GROUP_ANGLE:
1822*8975f5c5SAndroid Build Coastguard Worker         case EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR:
1823*8975f5c5SAndroid Build Coastguard Worker             break;
1824*8975f5c5SAndroid Build Coastguard Worker 
1825*8975f5c5SAndroid Build Coastguard Worker         case EGL_CONTEXT_FLAGS_KHR:
1826*8975f5c5SAndroid Build Coastguard Worker         {
1827*8975f5c5SAndroid Build Coastguard Worker             // Note: EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR does not apply to ES
1828*8975f5c5SAndroid Build Coastguard Worker             constexpr EGLint kValidContextFlags =
1829*8975f5c5SAndroid Build Coastguard Worker                 (EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR | EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR);
1830*8975f5c5SAndroid Build Coastguard Worker             if ((value & ~kValidContextFlags) != 0)
1831*8975f5c5SAndroid Build Coastguard Worker             {
1832*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE);
1833*8975f5c5SAndroid Build Coastguard Worker                 return false;
1834*8975f5c5SAndroid Build Coastguard Worker             }
1835*8975f5c5SAndroid Build Coastguard Worker             break;
1836*8975f5c5SAndroid Build Coastguard Worker         }
1837*8975f5c5SAndroid Build Coastguard Worker 
1838*8975f5c5SAndroid Build Coastguard Worker         case EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT:
1839*8975f5c5SAndroid Build Coastguard Worker         case EGL_CONTEXT_OPENGL_ROBUST_ACCESS:
1840*8975f5c5SAndroid Build Coastguard Worker             if (value != EGL_TRUE && value != EGL_FALSE)
1841*8975f5c5SAndroid Build Coastguard Worker             {
1842*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE);
1843*8975f5c5SAndroid Build Coastguard Worker                 return false;
1844*8975f5c5SAndroid Build Coastguard Worker             }
1845*8975f5c5SAndroid Build Coastguard Worker             break;
1846*8975f5c5SAndroid Build Coastguard Worker 
1847*8975f5c5SAndroid Build Coastguard Worker         case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT:
1848*8975f5c5SAndroid Build Coastguard Worker         case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY:
1849*8975f5c5SAndroid Build Coastguard Worker             if (value != EGL_LOSE_CONTEXT_ON_RESET_EXT && value != EGL_NO_RESET_NOTIFICATION_EXT)
1850*8975f5c5SAndroid Build Coastguard Worker             {
1851*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE);
1852*8975f5c5SAndroid Build Coastguard Worker                 return false;
1853*8975f5c5SAndroid Build Coastguard Worker             }
1854*8975f5c5SAndroid Build Coastguard Worker 
1855*8975f5c5SAndroid Build Coastguard Worker             if (shareContext && shareContext->isResetNotificationEnabled() !=
1856*8975f5c5SAndroid Build Coastguard Worker                                     (value == EGL_LOSE_CONTEXT_ON_RESET_EXT))
1857*8975f5c5SAndroid Build Coastguard Worker             {
1858*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_MATCH);
1859*8975f5c5SAndroid Build Coastguard Worker                 return false;
1860*8975f5c5SAndroid Build Coastguard Worker             }
1861*8975f5c5SAndroid Build Coastguard Worker             break;
1862*8975f5c5SAndroid Build Coastguard Worker 
1863*8975f5c5SAndroid Build Coastguard Worker         case EGL_CONTEXT_OPENGL_NO_ERROR_KHR:
1864*8975f5c5SAndroid Build Coastguard Worker             if (value != EGL_TRUE && value != EGL_FALSE)
1865*8975f5c5SAndroid Build Coastguard Worker             {
1866*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE, "Attribute must be EGL_TRUE or EGL_FALSE.");
1867*8975f5c5SAndroid Build Coastguard Worker                 return false;
1868*8975f5c5SAndroid Build Coastguard Worker             }
1869*8975f5c5SAndroid Build Coastguard Worker             break;
1870*8975f5c5SAndroid Build Coastguard Worker 
1871*8975f5c5SAndroid Build Coastguard Worker         case EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE:
1872*8975f5c5SAndroid Build Coastguard Worker             if (value != EGL_TRUE && value != EGL_FALSE)
1873*8975f5c5SAndroid Build Coastguard Worker             {
1874*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE,
1875*8975f5c5SAndroid Build Coastguard Worker                               "EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE must be "
1876*8975f5c5SAndroid Build Coastguard Worker                               "EGL_TRUE or EGL_FALSE.");
1877*8975f5c5SAndroid Build Coastguard Worker                 return false;
1878*8975f5c5SAndroid Build Coastguard Worker             }
1879*8975f5c5SAndroid Build Coastguard Worker             break;
1880*8975f5c5SAndroid Build Coastguard Worker 
1881*8975f5c5SAndroid Build Coastguard Worker         case EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM:
1882*8975f5c5SAndroid Build Coastguard Worker             if (value != EGL_TRUE && value != EGL_FALSE)
1883*8975f5c5SAndroid Build Coastguard Worker             {
1884*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE,
1885*8975f5c5SAndroid Build Coastguard Worker                               "EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM "
1886*8975f5c5SAndroid Build Coastguard Worker                               "must be EGL_TRUE or EGL_FALSE.");
1887*8975f5c5SAndroid Build Coastguard Worker                 return false;
1888*8975f5c5SAndroid Build Coastguard Worker             }
1889*8975f5c5SAndroid Build Coastguard Worker             break;
1890*8975f5c5SAndroid Build Coastguard Worker 
1891*8975f5c5SAndroid Build Coastguard Worker         case EGL_DISPLAY_TEXTURE_SHARE_GROUP_ANGLE:
1892*8975f5c5SAndroid Build Coastguard Worker             if (value != EGL_TRUE && value != EGL_FALSE)
1893*8975f5c5SAndroid Build Coastguard Worker             {
1894*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE,
1895*8975f5c5SAndroid Build Coastguard Worker                               "EGL_DISPLAY_TEXTURE_SHARE_GROUP_ANGLE must be "
1896*8975f5c5SAndroid Build Coastguard Worker                               "EGL_TRUE or EGL_FALSE.");
1897*8975f5c5SAndroid Build Coastguard Worker                 return false;
1898*8975f5c5SAndroid Build Coastguard Worker             }
1899*8975f5c5SAndroid Build Coastguard Worker             if (shareContext &&
1900*8975f5c5SAndroid Build Coastguard Worker                 shareContext->usingDisplayTextureShareGroup() != (value == EGL_TRUE))
1901*8975f5c5SAndroid Build Coastguard Worker             {
1902*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE,
1903*8975f5c5SAndroid Build Coastguard Worker                               "All contexts within a share group must be "
1904*8975f5c5SAndroid Build Coastguard Worker                               "created with the same value of "
1905*8975f5c5SAndroid Build Coastguard Worker                               "EGL_DISPLAY_TEXTURE_SHARE_GROUP_ANGLE.");
1906*8975f5c5SAndroid Build Coastguard Worker                 return false;
1907*8975f5c5SAndroid Build Coastguard Worker             }
1908*8975f5c5SAndroid Build Coastguard Worker             break;
1909*8975f5c5SAndroid Build Coastguard Worker 
1910*8975f5c5SAndroid Build Coastguard Worker         case EGL_DISPLAY_SEMAPHORE_SHARE_GROUP_ANGLE:
1911*8975f5c5SAndroid Build Coastguard Worker             if (value != EGL_TRUE && value != EGL_FALSE)
1912*8975f5c5SAndroid Build Coastguard Worker             {
1913*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE,
1914*8975f5c5SAndroid Build Coastguard Worker                               "EGL_DISPLAY_SEMAPHORE_SHARE_GROUP_ANGLE must be "
1915*8975f5c5SAndroid Build Coastguard Worker                               "EGL_TRUE or EGL_FALSE.");
1916*8975f5c5SAndroid Build Coastguard Worker                 return false;
1917*8975f5c5SAndroid Build Coastguard Worker             }
1918*8975f5c5SAndroid Build Coastguard Worker             if (shareContext &&
1919*8975f5c5SAndroid Build Coastguard Worker                 shareContext->usingDisplaySemaphoreShareGroup() != (value == EGL_TRUE))
1920*8975f5c5SAndroid Build Coastguard Worker             {
1921*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE,
1922*8975f5c5SAndroid Build Coastguard Worker                               "All contexts within a share group must be "
1923*8975f5c5SAndroid Build Coastguard Worker                               "created with the same value of "
1924*8975f5c5SAndroid Build Coastguard Worker                               "EGL_DISPLAY_SEMAPHORE_SHARE_GROUP_ANGLE.");
1925*8975f5c5SAndroid Build Coastguard Worker                 return false;
1926*8975f5c5SAndroid Build Coastguard Worker             }
1927*8975f5c5SAndroid Build Coastguard Worker             break;
1928*8975f5c5SAndroid Build Coastguard Worker 
1929*8975f5c5SAndroid Build Coastguard Worker         case EGL_CONTEXT_CLIENT_ARRAYS_ENABLED_ANGLE:
1930*8975f5c5SAndroid Build Coastguard Worker             if (value != EGL_TRUE && value != EGL_FALSE)
1931*8975f5c5SAndroid Build Coastguard Worker             {
1932*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE,
1933*8975f5c5SAndroid Build Coastguard Worker                               "EGL_CONTEXT_CLIENT_ARRAYS_ENABLED_ANGLE must "
1934*8975f5c5SAndroid Build Coastguard Worker                               "be EGL_TRUE or EGL_FALSE.");
1935*8975f5c5SAndroid Build Coastguard Worker                 return false;
1936*8975f5c5SAndroid Build Coastguard Worker             }
1937*8975f5c5SAndroid Build Coastguard Worker             break;
1938*8975f5c5SAndroid Build Coastguard Worker 
1939*8975f5c5SAndroid Build Coastguard Worker         case EGL_CONTEXT_PROGRAM_BINARY_CACHE_ENABLED_ANGLE:
1940*8975f5c5SAndroid Build Coastguard Worker             if (value != EGL_TRUE && value != EGL_FALSE)
1941*8975f5c5SAndroid Build Coastguard Worker             {
1942*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE,
1943*8975f5c5SAndroid Build Coastguard Worker                               "EGL_CONTEXT_PROGRAM_BINARY_CACHE_ENABLED_ANGLE must "
1944*8975f5c5SAndroid Build Coastguard Worker                               "be EGL_TRUE or EGL_FALSE.");
1945*8975f5c5SAndroid Build Coastguard Worker                 return false;
1946*8975f5c5SAndroid Build Coastguard Worker             }
1947*8975f5c5SAndroid Build Coastguard Worker             break;
1948*8975f5c5SAndroid Build Coastguard Worker 
1949*8975f5c5SAndroid Build Coastguard Worker         case EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
1950*8975f5c5SAndroid Build Coastguard Worker             if (value != EGL_TRUE && value != EGL_FALSE)
1951*8975f5c5SAndroid Build Coastguard Worker             {
1952*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE,
1953*8975f5c5SAndroid Build Coastguard Worker                               "EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE must be "
1954*8975f5c5SAndroid Build Coastguard Worker                               "either EGL_TRUE or EGL_FALSE.");
1955*8975f5c5SAndroid Build Coastguard Worker                 return false;
1956*8975f5c5SAndroid Build Coastguard Worker             }
1957*8975f5c5SAndroid Build Coastguard Worker             break;
1958*8975f5c5SAndroid Build Coastguard Worker 
1959*8975f5c5SAndroid Build Coastguard Worker         case EGL_EXTENSIONS_ENABLED_ANGLE:
1960*8975f5c5SAndroid Build Coastguard Worker             if (value != EGL_TRUE && value != EGL_FALSE)
1961*8975f5c5SAndroid Build Coastguard Worker             {
1962*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE,
1963*8975f5c5SAndroid Build Coastguard Worker                               "EGL_EXTENSIONS_ENABLED_ANGLE must be "
1964*8975f5c5SAndroid Build Coastguard Worker                               "either EGL_TRUE or EGL_FALSE.");
1965*8975f5c5SAndroid Build Coastguard Worker                 return false;
1966*8975f5c5SAndroid Build Coastguard Worker             }
1967*8975f5c5SAndroid Build Coastguard Worker             break;
1968*8975f5c5SAndroid Build Coastguard Worker 
1969*8975f5c5SAndroid Build Coastguard Worker         case EGL_POWER_PREFERENCE_ANGLE:
1970*8975f5c5SAndroid Build Coastguard Worker             if (value != EGL_LOW_POWER_ANGLE && value != EGL_HIGH_POWER_ANGLE)
1971*8975f5c5SAndroid Build Coastguard Worker             {
1972*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE,
1973*8975f5c5SAndroid Build Coastguard Worker                               "EGL_POWER_PREFERENCE_ANGLE must be "
1974*8975f5c5SAndroid Build Coastguard Worker                               "either EGL_LOW_POWER_ANGLE or EGL_HIGH_POWER_ANGLE.");
1975*8975f5c5SAndroid Build Coastguard Worker                 return false;
1976*8975f5c5SAndroid Build Coastguard Worker             }
1977*8975f5c5SAndroid Build Coastguard Worker             break;
1978*8975f5c5SAndroid Build Coastguard Worker 
1979*8975f5c5SAndroid Build Coastguard Worker         case EGL_CONTEXT_OPENGL_BACKWARDS_COMPATIBLE_ANGLE:
1980*8975f5c5SAndroid Build Coastguard Worker             if (value != EGL_TRUE && value != EGL_FALSE)
1981*8975f5c5SAndroid Build Coastguard Worker             {
1982*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE,
1983*8975f5c5SAndroid Build Coastguard Worker                               "EGL_CONTEXT_OPENGL_BACKWARDS_COMPATIBLE_ANGLE must be "
1984*8975f5c5SAndroid Build Coastguard Worker                               "either EGL_TRUE or EGL_FALSE.");
1985*8975f5c5SAndroid Build Coastguard Worker                 return false;
1986*8975f5c5SAndroid Build Coastguard Worker             }
1987*8975f5c5SAndroid Build Coastguard Worker             break;
1988*8975f5c5SAndroid Build Coastguard Worker 
1989*8975f5c5SAndroid Build Coastguard Worker         case EGL_CONTEXT_PRIORITY_LEVEL_IMG:
1990*8975f5c5SAndroid Build Coastguard Worker             switch (value)
1991*8975f5c5SAndroid Build Coastguard Worker             {
1992*8975f5c5SAndroid Build Coastguard Worker                 case EGL_CONTEXT_PRIORITY_LOW_IMG:
1993*8975f5c5SAndroid Build Coastguard Worker                 case EGL_CONTEXT_PRIORITY_MEDIUM_IMG:
1994*8975f5c5SAndroid Build Coastguard Worker                 case EGL_CONTEXT_PRIORITY_HIGH_IMG:
1995*8975f5c5SAndroid Build Coastguard Worker                     break;
1996*8975f5c5SAndroid Build Coastguard Worker                 default:
1997*8975f5c5SAndroid Build Coastguard Worker                     val->setError(EGL_BAD_ATTRIBUTE,
1998*8975f5c5SAndroid Build Coastguard Worker                                   "Attribute EGL_CONTEXT_PRIORITY_LEVEL_IMG "
1999*8975f5c5SAndroid Build Coastguard Worker                                   "must be one of: EGL_CONTEXT_PRIORITY_LOW_IMG, "
2000*8975f5c5SAndroid Build Coastguard Worker                                   "EGL_CONTEXT_PRIORITY_MEDIUM_IMG, or "
2001*8975f5c5SAndroid Build Coastguard Worker                                   "EGL_CONTEXT_PRIORITY_HIGH_IMG.");
2002*8975f5c5SAndroid Build Coastguard Worker                     return false;
2003*8975f5c5SAndroid Build Coastguard Worker             }
2004*8975f5c5SAndroid Build Coastguard Worker             break;
2005*8975f5c5SAndroid Build Coastguard Worker 
2006*8975f5c5SAndroid Build Coastguard Worker         case EGL_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV:
2007*8975f5c5SAndroid Build Coastguard Worker             if (value != EGL_TRUE && value != EGL_FALSE)
2008*8975f5c5SAndroid Build Coastguard Worker             {
2009*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE,
2010*8975f5c5SAndroid Build Coastguard Worker                               "EGL_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV must "
2011*8975f5c5SAndroid Build Coastguard Worker                               "be either EGL_TRUE or EGL_FALSE.");
2012*8975f5c5SAndroid Build Coastguard Worker                 return false;
2013*8975f5c5SAndroid Build Coastguard Worker             }
2014*8975f5c5SAndroid Build Coastguard Worker             break;
2015*8975f5c5SAndroid Build Coastguard Worker 
2016*8975f5c5SAndroid Build Coastguard Worker         case EGL_EXTERNAL_CONTEXT_ANGLE:
2017*8975f5c5SAndroid Build Coastguard Worker             if (value != EGL_TRUE && value != EGL_FALSE)
2018*8975f5c5SAndroid Build Coastguard Worker             {
2019*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE,
2020*8975f5c5SAndroid Build Coastguard Worker                               "EGL_EXTERNAL_CONTEXT_ANGLE must "
2021*8975f5c5SAndroid Build Coastguard Worker                               "be either EGL_TRUE or EGL_FALSE.");
2022*8975f5c5SAndroid Build Coastguard Worker                 return false;
2023*8975f5c5SAndroid Build Coastguard Worker             }
2024*8975f5c5SAndroid Build Coastguard Worker             if (shareContext && (value == EGL_TRUE))
2025*8975f5c5SAndroid Build Coastguard Worker             {
2026*8975f5c5SAndroid Build Coastguard Worker                 val->setError(
2027*8975f5c5SAndroid Build Coastguard Worker                     EGL_BAD_ATTRIBUTE,
2028*8975f5c5SAndroid Build Coastguard Worker                     "EGL_EXTERNAL_CONTEXT_ANGLE doesn't allow creating with sharedContext.");
2029*8975f5c5SAndroid Build Coastguard Worker                 return false;
2030*8975f5c5SAndroid Build Coastguard Worker             }
2031*8975f5c5SAndroid Build Coastguard Worker             break;
2032*8975f5c5SAndroid Build Coastguard Worker 
2033*8975f5c5SAndroid Build Coastguard Worker         case EGL_PROTECTED_CONTENT_EXT:
2034*8975f5c5SAndroid Build Coastguard Worker             if (value != EGL_TRUE && value != EGL_FALSE)
2035*8975f5c5SAndroid Build Coastguard Worker             {
2036*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE,
2037*8975f5c5SAndroid Build Coastguard Worker                               "EGL_PROTECTED_CONTENT_EXT must "
2038*8975f5c5SAndroid Build Coastguard Worker                               "be either EGL_TRUE or EGL_FALSE.");
2039*8975f5c5SAndroid Build Coastguard Worker                 return false;
2040*8975f5c5SAndroid Build Coastguard Worker             }
2041*8975f5c5SAndroid Build Coastguard Worker             break;
2042*8975f5c5SAndroid Build Coastguard Worker 
2043*8975f5c5SAndroid Build Coastguard Worker         case EGL_CONTEXT_METAL_OWNERSHIP_IDENTITY_ANGLE:
2044*8975f5c5SAndroid Build Coastguard Worker             if (value == 0)
2045*8975f5c5SAndroid Build Coastguard Worker             {
2046*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE,
2047*8975f5c5SAndroid Build Coastguard Worker                               "EGL_CONTEXT_METAL_OWNERSHIP_IDENTITY_ANGLE must"
2048*8975f5c5SAndroid Build Coastguard Worker                               "be non-zero.");
2049*8975f5c5SAndroid Build Coastguard Worker                 return false;
2050*8975f5c5SAndroid Build Coastguard Worker             }
2051*8975f5c5SAndroid Build Coastguard Worker             break;
2052*8975f5c5SAndroid Build Coastguard Worker 
2053*8975f5c5SAndroid Build Coastguard Worker         default:
2054*8975f5c5SAndroid Build Coastguard Worker             UNREACHABLE();
2055*8975f5c5SAndroid Build Coastguard Worker             return false;
2056*8975f5c5SAndroid Build Coastguard Worker     }
2057*8975f5c5SAndroid Build Coastguard Worker 
2058*8975f5c5SAndroid Build Coastguard Worker     return true;
2059*8975f5c5SAndroid Build Coastguard Worker }
2060*8975f5c5SAndroid Build Coastguard Worker 
ValidateCreatePbufferSurfaceAttribute(const ValidationContext * val,const Display * display,EGLAttrib attribute)2061*8975f5c5SAndroid Build Coastguard Worker bool ValidateCreatePbufferSurfaceAttribute(const ValidationContext *val,
2062*8975f5c5SAndroid Build Coastguard Worker                                            const Display *display,
2063*8975f5c5SAndroid Build Coastguard Worker                                            EGLAttrib attribute)
2064*8975f5c5SAndroid Build Coastguard Worker {
2065*8975f5c5SAndroid Build Coastguard Worker     const DisplayExtensions &displayExtensions = display->getExtensions();
2066*8975f5c5SAndroid Build Coastguard Worker 
2067*8975f5c5SAndroid Build Coastguard Worker     switch (attribute)
2068*8975f5c5SAndroid Build Coastguard Worker     {
2069*8975f5c5SAndroid Build Coastguard Worker         case EGL_WIDTH:
2070*8975f5c5SAndroid Build Coastguard Worker         case EGL_HEIGHT:
2071*8975f5c5SAndroid Build Coastguard Worker         case EGL_LARGEST_PBUFFER:
2072*8975f5c5SAndroid Build Coastguard Worker         case EGL_TEXTURE_FORMAT:
2073*8975f5c5SAndroid Build Coastguard Worker         case EGL_TEXTURE_TARGET:
2074*8975f5c5SAndroid Build Coastguard Worker         case EGL_MIPMAP_TEXTURE:
2075*8975f5c5SAndroid Build Coastguard Worker         case EGL_VG_COLORSPACE:
2076*8975f5c5SAndroid Build Coastguard Worker         case EGL_GL_COLORSPACE:
2077*8975f5c5SAndroid Build Coastguard Worker         case EGL_VG_ALPHA_FORMAT:
2078*8975f5c5SAndroid Build Coastguard Worker             break;
2079*8975f5c5SAndroid Build Coastguard Worker 
2080*8975f5c5SAndroid Build Coastguard Worker         case EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
2081*8975f5c5SAndroid Build Coastguard Worker             if (!displayExtensions.robustResourceInitializationANGLE)
2082*8975f5c5SAndroid Build Coastguard Worker             {
2083*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE,
2084*8975f5c5SAndroid Build Coastguard Worker                               "Attribute EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE "
2085*8975f5c5SAndroid Build Coastguard Worker                               "requires EGL_ANGLE_robust_resource_initialization.");
2086*8975f5c5SAndroid Build Coastguard Worker                 return false;
2087*8975f5c5SAndroid Build Coastguard Worker             }
2088*8975f5c5SAndroid Build Coastguard Worker             break;
2089*8975f5c5SAndroid Build Coastguard Worker 
2090*8975f5c5SAndroid Build Coastguard Worker         case EGL_PROTECTED_CONTENT_EXT:
2091*8975f5c5SAndroid Build Coastguard Worker             if (!displayExtensions.protectedContentEXT)
2092*8975f5c5SAndroid Build Coastguard Worker             {
2093*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE,
2094*8975f5c5SAndroid Build Coastguard Worker                               "Attribute EGL_PROTECTED_CONTEXT_EXT requires "
2095*8975f5c5SAndroid Build Coastguard Worker                               "extension EGL_EXT_protected_content.");
2096*8975f5c5SAndroid Build Coastguard Worker                 return false;
2097*8975f5c5SAndroid Build Coastguard Worker             }
2098*8975f5c5SAndroid Build Coastguard Worker             break;
2099*8975f5c5SAndroid Build Coastguard Worker 
2100*8975f5c5SAndroid Build Coastguard Worker         default:
2101*8975f5c5SAndroid Build Coastguard Worker             val->setError(EGL_BAD_ATTRIBUTE);
2102*8975f5c5SAndroid Build Coastguard Worker             return false;
2103*8975f5c5SAndroid Build Coastguard Worker     }
2104*8975f5c5SAndroid Build Coastguard Worker 
2105*8975f5c5SAndroid Build Coastguard Worker     return true;
2106*8975f5c5SAndroid Build Coastguard Worker }
2107*8975f5c5SAndroid Build Coastguard Worker 
ValidateCreatePbufferSurfaceAttributeValue(const ValidationContext * val,const Display * display,EGLAttrib attribute,EGLAttrib value)2108*8975f5c5SAndroid Build Coastguard Worker bool ValidateCreatePbufferSurfaceAttributeValue(const ValidationContext *val,
2109*8975f5c5SAndroid Build Coastguard Worker                                                 const Display *display,
2110*8975f5c5SAndroid Build Coastguard Worker                                                 EGLAttrib attribute,
2111*8975f5c5SAndroid Build Coastguard Worker                                                 EGLAttrib value)
2112*8975f5c5SAndroid Build Coastguard Worker {
2113*8975f5c5SAndroid Build Coastguard Worker     const DisplayExtensions &displayExtensions = display->getExtensions();
2114*8975f5c5SAndroid Build Coastguard Worker 
2115*8975f5c5SAndroid Build Coastguard Worker     switch (attribute)
2116*8975f5c5SAndroid Build Coastguard Worker     {
2117*8975f5c5SAndroid Build Coastguard Worker         case EGL_WIDTH:
2118*8975f5c5SAndroid Build Coastguard Worker         case EGL_HEIGHT:
2119*8975f5c5SAndroid Build Coastguard Worker             if (value < 0)
2120*8975f5c5SAndroid Build Coastguard Worker             {
2121*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_PARAMETER);
2122*8975f5c5SAndroid Build Coastguard Worker                 return false;
2123*8975f5c5SAndroid Build Coastguard Worker             }
2124*8975f5c5SAndroid Build Coastguard Worker             break;
2125*8975f5c5SAndroid Build Coastguard Worker 
2126*8975f5c5SAndroid Build Coastguard Worker         case EGL_LARGEST_PBUFFER:
2127*8975f5c5SAndroid Build Coastguard Worker             break;
2128*8975f5c5SAndroid Build Coastguard Worker 
2129*8975f5c5SAndroid Build Coastguard Worker         case EGL_TEXTURE_FORMAT:
2130*8975f5c5SAndroid Build Coastguard Worker             switch (value)
2131*8975f5c5SAndroid Build Coastguard Worker             {
2132*8975f5c5SAndroid Build Coastguard Worker                 case EGL_NO_TEXTURE:
2133*8975f5c5SAndroid Build Coastguard Worker                 case EGL_TEXTURE_RGB:
2134*8975f5c5SAndroid Build Coastguard Worker                 case EGL_TEXTURE_RGBA:
2135*8975f5c5SAndroid Build Coastguard Worker                     break;
2136*8975f5c5SAndroid Build Coastguard Worker                 default:
2137*8975f5c5SAndroid Build Coastguard Worker                     val->setError(EGL_BAD_ATTRIBUTE);
2138*8975f5c5SAndroid Build Coastguard Worker                     return false;
2139*8975f5c5SAndroid Build Coastguard Worker             }
2140*8975f5c5SAndroid Build Coastguard Worker             break;
2141*8975f5c5SAndroid Build Coastguard Worker 
2142*8975f5c5SAndroid Build Coastguard Worker         case EGL_TEXTURE_TARGET:
2143*8975f5c5SAndroid Build Coastguard Worker             switch (value)
2144*8975f5c5SAndroid Build Coastguard Worker             {
2145*8975f5c5SAndroid Build Coastguard Worker                 case EGL_NO_TEXTURE:
2146*8975f5c5SAndroid Build Coastguard Worker                 case EGL_TEXTURE_2D:
2147*8975f5c5SAndroid Build Coastguard Worker                     break;
2148*8975f5c5SAndroid Build Coastguard Worker                 default:
2149*8975f5c5SAndroid Build Coastguard Worker                     val->setError(EGL_BAD_ATTRIBUTE);
2150*8975f5c5SAndroid Build Coastguard Worker                     return false;
2151*8975f5c5SAndroid Build Coastguard Worker             }
2152*8975f5c5SAndroid Build Coastguard Worker             break;
2153*8975f5c5SAndroid Build Coastguard Worker 
2154*8975f5c5SAndroid Build Coastguard Worker         case EGL_MIPMAP_TEXTURE:
2155*8975f5c5SAndroid Build Coastguard Worker             break;
2156*8975f5c5SAndroid Build Coastguard Worker 
2157*8975f5c5SAndroid Build Coastguard Worker         case EGL_VG_COLORSPACE:
2158*8975f5c5SAndroid Build Coastguard Worker             break;
2159*8975f5c5SAndroid Build Coastguard Worker 
2160*8975f5c5SAndroid Build Coastguard Worker         case EGL_GL_COLORSPACE:
2161*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_TRY(ValidateColorspaceAttribute(val, displayExtensions, value));
2162*8975f5c5SAndroid Build Coastguard Worker             break;
2163*8975f5c5SAndroid Build Coastguard Worker 
2164*8975f5c5SAndroid Build Coastguard Worker         case EGL_VG_ALPHA_FORMAT:
2165*8975f5c5SAndroid Build Coastguard Worker             break;
2166*8975f5c5SAndroid Build Coastguard Worker 
2167*8975f5c5SAndroid Build Coastguard Worker         case EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
2168*8975f5c5SAndroid Build Coastguard Worker             ASSERT(displayExtensions.robustResourceInitializationANGLE);
2169*8975f5c5SAndroid Build Coastguard Worker             if (value != EGL_TRUE && value != EGL_FALSE)
2170*8975f5c5SAndroid Build Coastguard Worker             {
2171*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE,
2172*8975f5c5SAndroid Build Coastguard Worker                               "EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE must be "
2173*8975f5c5SAndroid Build Coastguard Worker                               "either EGL_TRUE or EGL_FALSE.");
2174*8975f5c5SAndroid Build Coastguard Worker                 return false;
2175*8975f5c5SAndroid Build Coastguard Worker             }
2176*8975f5c5SAndroid Build Coastguard Worker             break;
2177*8975f5c5SAndroid Build Coastguard Worker 
2178*8975f5c5SAndroid Build Coastguard Worker         case EGL_PROTECTED_CONTENT_EXT:
2179*8975f5c5SAndroid Build Coastguard Worker             ASSERT(displayExtensions.protectedContentEXT);
2180*8975f5c5SAndroid Build Coastguard Worker             if (value != EGL_TRUE && value != EGL_FALSE)
2181*8975f5c5SAndroid Build Coastguard Worker             {
2182*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE,
2183*8975f5c5SAndroid Build Coastguard Worker                               "EGL_PROTECTED_CONTENT_EXT must "
2184*8975f5c5SAndroid Build Coastguard Worker                               "be either EGL_TRUE or EGL_FALSE.");
2185*8975f5c5SAndroid Build Coastguard Worker                 return false;
2186*8975f5c5SAndroid Build Coastguard Worker             }
2187*8975f5c5SAndroid Build Coastguard Worker             break;
2188*8975f5c5SAndroid Build Coastguard Worker 
2189*8975f5c5SAndroid Build Coastguard Worker         default:
2190*8975f5c5SAndroid Build Coastguard Worker             UNREACHABLE();
2191*8975f5c5SAndroid Build Coastguard Worker             return false;
2192*8975f5c5SAndroid Build Coastguard Worker     }
2193*8975f5c5SAndroid Build Coastguard Worker 
2194*8975f5c5SAndroid Build Coastguard Worker     return true;
2195*8975f5c5SAndroid Build Coastguard Worker }
2196*8975f5c5SAndroid Build Coastguard Worker }  // anonymous namespace
2197*8975f5c5SAndroid Build Coastguard Worker 
setError(EGLint error) const2198*8975f5c5SAndroid Build Coastguard Worker void ValidationContext::setError(EGLint error) const
2199*8975f5c5SAndroid Build Coastguard Worker {
2200*8975f5c5SAndroid Build Coastguard Worker     eglThread->setError(error, entryPoint, labeledObject, nullptr);
2201*8975f5c5SAndroid Build Coastguard Worker }
2202*8975f5c5SAndroid Build Coastguard Worker 
setError(EGLint error,const char * message...) const2203*8975f5c5SAndroid Build Coastguard Worker void ValidationContext::setError(EGLint error, const char *message...) const
2204*8975f5c5SAndroid Build Coastguard Worker {
2205*8975f5c5SAndroid Build Coastguard Worker     ASSERT(message);
2206*8975f5c5SAndroid Build Coastguard Worker 
2207*8975f5c5SAndroid Build Coastguard Worker     constexpr uint32_t kBufferSize = 1000;
2208*8975f5c5SAndroid Build Coastguard Worker     char buffer[kBufferSize];
2209*8975f5c5SAndroid Build Coastguard Worker 
2210*8975f5c5SAndroid Build Coastguard Worker     va_list args;
2211*8975f5c5SAndroid Build Coastguard Worker     va_start(args, message);
2212*8975f5c5SAndroid Build Coastguard Worker     vsnprintf(buffer, kBufferSize, message, args);
2213*8975f5c5SAndroid Build Coastguard Worker 
2214*8975f5c5SAndroid Build Coastguard Worker     eglThread->setError(error, entryPoint, labeledObject, buffer);
2215*8975f5c5SAndroid Build Coastguard Worker }
2216*8975f5c5SAndroid Build Coastguard Worker 
ValidateDisplay(const ValidationContext * val,const Display * display)2217*8975f5c5SAndroid Build Coastguard Worker bool ValidateDisplay(const ValidationContext *val, const Display *display)
2218*8975f5c5SAndroid Build Coastguard Worker {
2219*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateDisplayPointer(val, display));
2220*8975f5c5SAndroid Build Coastguard Worker 
2221*8975f5c5SAndroid Build Coastguard Worker     if (!display->isInitialized())
2222*8975f5c5SAndroid Build Coastguard Worker     {
2223*8975f5c5SAndroid Build Coastguard Worker         if (val)
2224*8975f5c5SAndroid Build Coastguard Worker         {
2225*8975f5c5SAndroid Build Coastguard Worker             val->setError(EGL_NOT_INITIALIZED, "display is not initialized.");
2226*8975f5c5SAndroid Build Coastguard Worker         }
2227*8975f5c5SAndroid Build Coastguard Worker         return false;
2228*8975f5c5SAndroid Build Coastguard Worker     }
2229*8975f5c5SAndroid Build Coastguard Worker 
2230*8975f5c5SAndroid Build Coastguard Worker     if (display->isDeviceLost())
2231*8975f5c5SAndroid Build Coastguard Worker     {
2232*8975f5c5SAndroid Build Coastguard Worker         if (val)
2233*8975f5c5SAndroid Build Coastguard Worker         {
2234*8975f5c5SAndroid Build Coastguard Worker             val->setError(EGL_CONTEXT_LOST, "display had a context loss");
2235*8975f5c5SAndroid Build Coastguard Worker         }
2236*8975f5c5SAndroid Build Coastguard Worker         return false;
2237*8975f5c5SAndroid Build Coastguard Worker     }
2238*8975f5c5SAndroid Build Coastguard Worker 
2239*8975f5c5SAndroid Build Coastguard Worker     return true;
2240*8975f5c5SAndroid Build Coastguard Worker }
2241*8975f5c5SAndroid Build Coastguard Worker 
ValidateSurface(const ValidationContext * val,const Display * display,SurfaceID surfaceID)2242*8975f5c5SAndroid Build Coastguard Worker bool ValidateSurface(const ValidationContext *val, const Display *display, SurfaceID surfaceID)
2243*8975f5c5SAndroid Build Coastguard Worker {
2244*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
2245*8975f5c5SAndroid Build Coastguard Worker 
2246*8975f5c5SAndroid Build Coastguard Worker     if (!display->isValidSurface(surfaceID))
2247*8975f5c5SAndroid Build Coastguard Worker     {
2248*8975f5c5SAndroid Build Coastguard Worker         if (val)
2249*8975f5c5SAndroid Build Coastguard Worker         {
2250*8975f5c5SAndroid Build Coastguard Worker             val->setError(EGL_BAD_SURFACE);
2251*8975f5c5SAndroid Build Coastguard Worker         }
2252*8975f5c5SAndroid Build Coastguard Worker         return false;
2253*8975f5c5SAndroid Build Coastguard Worker     }
2254*8975f5c5SAndroid Build Coastguard Worker 
2255*8975f5c5SAndroid Build Coastguard Worker     return true;
2256*8975f5c5SAndroid Build Coastguard Worker }
2257*8975f5c5SAndroid Build Coastguard Worker 
ValidateConfig(const ValidationContext * val,const Display * display,const Config * config)2258*8975f5c5SAndroid Build Coastguard Worker bool ValidateConfig(const ValidationContext *val, const Display *display, const Config *config)
2259*8975f5c5SAndroid Build Coastguard Worker {
2260*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
2261*8975f5c5SAndroid Build Coastguard Worker 
2262*8975f5c5SAndroid Build Coastguard Worker     if (!display->isValidConfig(config))
2263*8975f5c5SAndroid Build Coastguard Worker     {
2264*8975f5c5SAndroid Build Coastguard Worker         if (val)
2265*8975f5c5SAndroid Build Coastguard Worker         {
2266*8975f5c5SAndroid Build Coastguard Worker             val->setError(EGL_BAD_CONFIG);
2267*8975f5c5SAndroid Build Coastguard Worker         }
2268*8975f5c5SAndroid Build Coastguard Worker         return false;
2269*8975f5c5SAndroid Build Coastguard Worker     }
2270*8975f5c5SAndroid Build Coastguard Worker 
2271*8975f5c5SAndroid Build Coastguard Worker     return true;
2272*8975f5c5SAndroid Build Coastguard Worker }
2273*8975f5c5SAndroid Build Coastguard Worker 
ValidateThreadContext(const ValidationContext * val,const Display * display,EGLenum noContextError)2274*8975f5c5SAndroid Build Coastguard Worker bool ValidateThreadContext(const ValidationContext *val,
2275*8975f5c5SAndroid Build Coastguard Worker                            const Display *display,
2276*8975f5c5SAndroid Build Coastguard Worker                            EGLenum noContextError)
2277*8975f5c5SAndroid Build Coastguard Worker {
2278*8975f5c5SAndroid Build Coastguard Worker     ASSERT(val);
2279*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
2280*8975f5c5SAndroid Build Coastguard Worker 
2281*8975f5c5SAndroid Build Coastguard Worker     if (!val->eglThread->getContext())
2282*8975f5c5SAndroid Build Coastguard Worker     {
2283*8975f5c5SAndroid Build Coastguard Worker         val->setError(noContextError, "No context is current.");
2284*8975f5c5SAndroid Build Coastguard Worker         return false;
2285*8975f5c5SAndroid Build Coastguard Worker     }
2286*8975f5c5SAndroid Build Coastguard Worker 
2287*8975f5c5SAndroid Build Coastguard Worker     return true;
2288*8975f5c5SAndroid Build Coastguard Worker }
2289*8975f5c5SAndroid Build Coastguard Worker 
ValidateContext(const ValidationContext * val,const Display * display,gl::ContextID contextID)2290*8975f5c5SAndroid Build Coastguard Worker bool ValidateContext(const ValidationContext *val, const Display *display, gl::ContextID contextID)
2291*8975f5c5SAndroid Build Coastguard Worker {
2292*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
2293*8975f5c5SAndroid Build Coastguard Worker 
2294*8975f5c5SAndroid Build Coastguard Worker     if (!display->isValidContext(contextID))
2295*8975f5c5SAndroid Build Coastguard Worker     {
2296*8975f5c5SAndroid Build Coastguard Worker         if (val)
2297*8975f5c5SAndroid Build Coastguard Worker         {
2298*8975f5c5SAndroid Build Coastguard Worker             val->setError(EGL_BAD_CONTEXT);
2299*8975f5c5SAndroid Build Coastguard Worker         }
2300*8975f5c5SAndroid Build Coastguard Worker         return false;
2301*8975f5c5SAndroid Build Coastguard Worker     }
2302*8975f5c5SAndroid Build Coastguard Worker 
2303*8975f5c5SAndroid Build Coastguard Worker     return true;
2304*8975f5c5SAndroid Build Coastguard Worker }
2305*8975f5c5SAndroid Build Coastguard Worker 
ValidateImage(const ValidationContext * val,const Display * display,ImageID imageID)2306*8975f5c5SAndroid Build Coastguard Worker bool ValidateImage(const ValidationContext *val, const Display *display, ImageID imageID)
2307*8975f5c5SAndroid Build Coastguard Worker {
2308*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
2309*8975f5c5SAndroid Build Coastguard Worker 
2310*8975f5c5SAndroid Build Coastguard Worker     if (!display->isValidImage(imageID))
2311*8975f5c5SAndroid Build Coastguard Worker     {
2312*8975f5c5SAndroid Build Coastguard Worker         if (val)
2313*8975f5c5SAndroid Build Coastguard Worker         {
2314*8975f5c5SAndroid Build Coastguard Worker             val->setError(EGL_BAD_PARAMETER, "image is not valid.");
2315*8975f5c5SAndroid Build Coastguard Worker         }
2316*8975f5c5SAndroid Build Coastguard Worker         return false;
2317*8975f5c5SAndroid Build Coastguard Worker     }
2318*8975f5c5SAndroid Build Coastguard Worker 
2319*8975f5c5SAndroid Build Coastguard Worker     return true;
2320*8975f5c5SAndroid Build Coastguard Worker }
2321*8975f5c5SAndroid Build Coastguard Worker 
ValidateDevice(const ValidationContext * val,const Device * device)2322*8975f5c5SAndroid Build Coastguard Worker bool ValidateDevice(const ValidationContext *val, const Device *device)
2323*8975f5c5SAndroid Build Coastguard Worker {
2324*8975f5c5SAndroid Build Coastguard Worker     if (device == EGL_NO_DEVICE_EXT)
2325*8975f5c5SAndroid Build Coastguard Worker     {
2326*8975f5c5SAndroid Build Coastguard Worker         if (val)
2327*8975f5c5SAndroid Build Coastguard Worker         {
2328*8975f5c5SAndroid Build Coastguard Worker             val->setError(EGL_BAD_ACCESS, "device is EGL_NO_DEVICE.");
2329*8975f5c5SAndroid Build Coastguard Worker         }
2330*8975f5c5SAndroid Build Coastguard Worker         return false;
2331*8975f5c5SAndroid Build Coastguard Worker     }
2332*8975f5c5SAndroid Build Coastguard Worker 
2333*8975f5c5SAndroid Build Coastguard Worker     if (!Device::IsValidDevice(device))
2334*8975f5c5SAndroid Build Coastguard Worker     {
2335*8975f5c5SAndroid Build Coastguard Worker         if (val)
2336*8975f5c5SAndroid Build Coastguard Worker         {
2337*8975f5c5SAndroid Build Coastguard Worker             val->setError(EGL_BAD_ACCESS, "device is not valid.");
2338*8975f5c5SAndroid Build Coastguard Worker         }
2339*8975f5c5SAndroid Build Coastguard Worker         return false;
2340*8975f5c5SAndroid Build Coastguard Worker     }
2341*8975f5c5SAndroid Build Coastguard Worker 
2342*8975f5c5SAndroid Build Coastguard Worker     return true;
2343*8975f5c5SAndroid Build Coastguard Worker }
2344*8975f5c5SAndroid Build Coastguard Worker 
ValidateSync(const ValidationContext * val,const Display * display,SyncID sync)2345*8975f5c5SAndroid Build Coastguard Worker bool ValidateSync(const ValidationContext *val, const Display *display, SyncID sync)
2346*8975f5c5SAndroid Build Coastguard Worker {
2347*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
2348*8975f5c5SAndroid Build Coastguard Worker 
2349*8975f5c5SAndroid Build Coastguard Worker     if (!display->isValidSync(sync))
2350*8975f5c5SAndroid Build Coastguard Worker     {
2351*8975f5c5SAndroid Build Coastguard Worker         if (val)
2352*8975f5c5SAndroid Build Coastguard Worker         {
2353*8975f5c5SAndroid Build Coastguard Worker             val->setError(EGL_BAD_PARAMETER, "sync object is not valid.");
2354*8975f5c5SAndroid Build Coastguard Worker         }
2355*8975f5c5SAndroid Build Coastguard Worker         return false;
2356*8975f5c5SAndroid Build Coastguard Worker     }
2357*8975f5c5SAndroid Build Coastguard Worker 
2358*8975f5c5SAndroid Build Coastguard Worker     return true;
2359*8975f5c5SAndroid Build Coastguard Worker }
2360*8975f5c5SAndroid Build Coastguard Worker 
GetThreadIfValid(const Thread * thread)2361*8975f5c5SAndroid Build Coastguard Worker const Thread *GetThreadIfValid(const Thread *thread)
2362*8975f5c5SAndroid Build Coastguard Worker {
2363*8975f5c5SAndroid Build Coastguard Worker     // Threads should always be valid
2364*8975f5c5SAndroid Build Coastguard Worker     return thread;
2365*8975f5c5SAndroid Build Coastguard Worker }
2366*8975f5c5SAndroid Build Coastguard Worker 
GetDisplayIfValid(const Display * display)2367*8975f5c5SAndroid Build Coastguard Worker const Display *GetDisplayIfValid(const Display *display)
2368*8975f5c5SAndroid Build Coastguard Worker {
2369*8975f5c5SAndroid Build Coastguard Worker     return ValidateDisplay(nullptr, display) ? display : nullptr;
2370*8975f5c5SAndroid Build Coastguard Worker }
2371*8975f5c5SAndroid Build Coastguard Worker 
GetSurfaceIfValid(const Display * display,SurfaceID surfaceID)2372*8975f5c5SAndroid Build Coastguard Worker const Surface *GetSurfaceIfValid(const Display *display, SurfaceID surfaceID)
2373*8975f5c5SAndroid Build Coastguard Worker {
2374*8975f5c5SAndroid Build Coastguard Worker     // display->getSurface() - validates surfaceID
2375*8975f5c5SAndroid Build Coastguard Worker     return ValidateDisplay(nullptr, display) ? display->getSurface(surfaceID) : nullptr;
2376*8975f5c5SAndroid Build Coastguard Worker }
2377*8975f5c5SAndroid Build Coastguard Worker 
GetImageIfValid(const Display * display,ImageID imageID)2378*8975f5c5SAndroid Build Coastguard Worker const Image *GetImageIfValid(const Display *display, ImageID imageID)
2379*8975f5c5SAndroid Build Coastguard Worker {
2380*8975f5c5SAndroid Build Coastguard Worker     // display->getImage() - validates imageID
2381*8975f5c5SAndroid Build Coastguard Worker     return ValidateDisplay(nullptr, display) ? display->getImage(imageID) : nullptr;
2382*8975f5c5SAndroid Build Coastguard Worker }
2383*8975f5c5SAndroid Build Coastguard Worker 
GetStreamIfValid(const Display * display,const Stream * stream)2384*8975f5c5SAndroid Build Coastguard Worker const Stream *GetStreamIfValid(const Display *display, const Stream *stream)
2385*8975f5c5SAndroid Build Coastguard Worker {
2386*8975f5c5SAndroid Build Coastguard Worker     return ValidateStream(nullptr, display, stream) ? stream : nullptr;
2387*8975f5c5SAndroid Build Coastguard Worker }
2388*8975f5c5SAndroid Build Coastguard Worker 
GetContextIfValid(const Display * display,gl::ContextID contextID)2389*8975f5c5SAndroid Build Coastguard Worker const gl::Context *GetContextIfValid(const Display *display, gl::ContextID contextID)
2390*8975f5c5SAndroid Build Coastguard Worker {
2391*8975f5c5SAndroid Build Coastguard Worker     // display->getContext() - validates contextID
2392*8975f5c5SAndroid Build Coastguard Worker     return ValidateDisplay(nullptr, display) ? display->getContext(contextID) : nullptr;
2393*8975f5c5SAndroid Build Coastguard Worker }
2394*8975f5c5SAndroid Build Coastguard Worker 
GetContextIfValid(Display * display,gl::ContextID contextID)2395*8975f5c5SAndroid Build Coastguard Worker gl::Context *GetContextIfValid(Display *display, gl::ContextID contextID)
2396*8975f5c5SAndroid Build Coastguard Worker {
2397*8975f5c5SAndroid Build Coastguard Worker     return ValidateDisplay(nullptr, display) ? display->getContext(contextID) : nullptr;
2398*8975f5c5SAndroid Build Coastguard Worker }
2399*8975f5c5SAndroid Build Coastguard Worker 
GetDeviceIfValid(const Device * device)2400*8975f5c5SAndroid Build Coastguard Worker const Device *GetDeviceIfValid(const Device *device)
2401*8975f5c5SAndroid Build Coastguard Worker {
2402*8975f5c5SAndroid Build Coastguard Worker     return ValidateDevice(nullptr, device) ? device : nullptr;
2403*8975f5c5SAndroid Build Coastguard Worker }
2404*8975f5c5SAndroid Build Coastguard Worker 
GetSyncIfValid(const Display * display,SyncID syncID)2405*8975f5c5SAndroid Build Coastguard Worker const Sync *GetSyncIfValid(const Display *display, SyncID syncID)
2406*8975f5c5SAndroid Build Coastguard Worker {
2407*8975f5c5SAndroid Build Coastguard Worker     // display->getSync() - validates syncID
2408*8975f5c5SAndroid Build Coastguard Worker     return ValidateDisplay(nullptr, display) ? display->getSync(syncID) : nullptr;
2409*8975f5c5SAndroid Build Coastguard Worker }
2410*8975f5c5SAndroid Build Coastguard Worker 
GetLabeledObjectIfValid(Thread * thread,const Display * display,ObjectType objectType,EGLObjectKHR object)2411*8975f5c5SAndroid Build Coastguard Worker const LabeledObject *GetLabeledObjectIfValid(Thread *thread,
2412*8975f5c5SAndroid Build Coastguard Worker                                              const Display *display,
2413*8975f5c5SAndroid Build Coastguard Worker                                              ObjectType objectType,
2414*8975f5c5SAndroid Build Coastguard Worker                                              EGLObjectKHR object)
2415*8975f5c5SAndroid Build Coastguard Worker {
2416*8975f5c5SAndroid Build Coastguard Worker     if (objectType == ObjectType::Thread)
2417*8975f5c5SAndroid Build Coastguard Worker     {
2418*8975f5c5SAndroid Build Coastguard Worker         return thread;
2419*8975f5c5SAndroid Build Coastguard Worker     }
2420*8975f5c5SAndroid Build Coastguard Worker 
2421*8975f5c5SAndroid Build Coastguard Worker     const LabeledObject *labeledObject = nullptr;
2422*8975f5c5SAndroid Build Coastguard Worker     if (ValidateLabeledObject(nullptr, display, objectType, object, &labeledObject))
2423*8975f5c5SAndroid Build Coastguard Worker     {
2424*8975f5c5SAndroid Build Coastguard Worker         return labeledObject;
2425*8975f5c5SAndroid Build Coastguard Worker     }
2426*8975f5c5SAndroid Build Coastguard Worker 
2427*8975f5c5SAndroid Build Coastguard Worker     return nullptr;
2428*8975f5c5SAndroid Build Coastguard Worker }
2429*8975f5c5SAndroid Build Coastguard Worker 
GetLabeledObjectIfValid(Thread * thread,Display * display,ObjectType objectType,EGLObjectKHR object)2430*8975f5c5SAndroid Build Coastguard Worker LabeledObject *GetLabeledObjectIfValid(Thread *thread,
2431*8975f5c5SAndroid Build Coastguard Worker                                        Display *display,
2432*8975f5c5SAndroid Build Coastguard Worker                                        ObjectType objectType,
2433*8975f5c5SAndroid Build Coastguard Worker                                        EGLObjectKHR object)
2434*8975f5c5SAndroid Build Coastguard Worker {
2435*8975f5c5SAndroid Build Coastguard Worker     if (objectType == ObjectType::Thread)
2436*8975f5c5SAndroid Build Coastguard Worker     {
2437*8975f5c5SAndroid Build Coastguard Worker         return thread;
2438*8975f5c5SAndroid Build Coastguard Worker     }
2439*8975f5c5SAndroid Build Coastguard Worker 
2440*8975f5c5SAndroid Build Coastguard Worker     LabeledObject *labeledObject = nullptr;
2441*8975f5c5SAndroid Build Coastguard Worker     if (ValidateLabeledObject(nullptr, display, objectType, object, &labeledObject))
2442*8975f5c5SAndroid Build Coastguard Worker     {
2443*8975f5c5SAndroid Build Coastguard Worker         return labeledObject;
2444*8975f5c5SAndroid Build Coastguard Worker     }
2445*8975f5c5SAndroid Build Coastguard Worker 
2446*8975f5c5SAndroid Build Coastguard Worker     return nullptr;
2447*8975f5c5SAndroid Build Coastguard Worker }
2448*8975f5c5SAndroid Build Coastguard Worker 
ValidateInitialize(const ValidationContext * val,const Display * display,const EGLint * major,const EGLint * minor)2449*8975f5c5SAndroid Build Coastguard Worker bool ValidateInitialize(const ValidationContext *val,
2450*8975f5c5SAndroid Build Coastguard Worker                         const Display *display,
2451*8975f5c5SAndroid Build Coastguard Worker                         const EGLint *major,
2452*8975f5c5SAndroid Build Coastguard Worker                         const EGLint *minor)
2453*8975f5c5SAndroid Build Coastguard Worker {
2454*8975f5c5SAndroid Build Coastguard Worker     return ValidateDisplayPointer(val, display);
2455*8975f5c5SAndroid Build Coastguard Worker }
2456*8975f5c5SAndroid Build Coastguard Worker 
ValidateTerminate(const ValidationContext * val,const Display * display)2457*8975f5c5SAndroid Build Coastguard Worker bool ValidateTerminate(const ValidationContext *val, const Display *display)
2458*8975f5c5SAndroid Build Coastguard Worker {
2459*8975f5c5SAndroid Build Coastguard Worker     return ValidateDisplayPointer(val, display);
2460*8975f5c5SAndroid Build Coastguard Worker }
2461*8975f5c5SAndroid Build Coastguard Worker 
ValidateCreateContext(const ValidationContext * val,const Display * display,const Config * configuration,gl::ContextID shareContextID,const AttributeMap & attributes)2462*8975f5c5SAndroid Build Coastguard Worker bool ValidateCreateContext(const ValidationContext *val,
2463*8975f5c5SAndroid Build Coastguard Worker                            const Display *display,
2464*8975f5c5SAndroid Build Coastguard Worker                            const Config *configuration,
2465*8975f5c5SAndroid Build Coastguard Worker                            gl::ContextID shareContextID,
2466*8975f5c5SAndroid Build Coastguard Worker                            const AttributeMap &attributes)
2467*8975f5c5SAndroid Build Coastguard Worker {
2468*8975f5c5SAndroid Build Coastguard Worker     if (configuration)
2469*8975f5c5SAndroid Build Coastguard Worker     {
2470*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_TRY(ValidateConfig(val, display, configuration));
2471*8975f5c5SAndroid Build Coastguard Worker     }
2472*8975f5c5SAndroid Build Coastguard Worker     else
2473*8975f5c5SAndroid Build Coastguard Worker     {
2474*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
2475*8975f5c5SAndroid Build Coastguard Worker         const DisplayExtensions &displayExtensions = display->getExtensions();
2476*8975f5c5SAndroid Build Coastguard Worker         if (!displayExtensions.noConfigContext)
2477*8975f5c5SAndroid Build Coastguard Worker         {
2478*8975f5c5SAndroid Build Coastguard Worker             val->setError(EGL_BAD_CONFIG);
2479*8975f5c5SAndroid Build Coastguard Worker             return false;
2480*8975f5c5SAndroid Build Coastguard Worker         }
2481*8975f5c5SAndroid Build Coastguard Worker     }
2482*8975f5c5SAndroid Build Coastguard Worker 
2483*8975f5c5SAndroid Build Coastguard Worker     if (shareContextID.value != 0)
2484*8975f5c5SAndroid Build Coastguard Worker     {
2485*8975f5c5SAndroid Build Coastguard Worker         // Shared context is invalid or is owned by another display
2486*8975f5c5SAndroid Build Coastguard Worker         if (!display->isValidContext(shareContextID))
2487*8975f5c5SAndroid Build Coastguard Worker         {
2488*8975f5c5SAndroid Build Coastguard Worker             val->setError(EGL_BAD_MATCH);
2489*8975f5c5SAndroid Build Coastguard Worker             return false;
2490*8975f5c5SAndroid Build Coastguard Worker         }
2491*8975f5c5SAndroid Build Coastguard Worker     }
2492*8975f5c5SAndroid Build Coastguard Worker 
2493*8975f5c5SAndroid Build Coastguard Worker     const gl::Context *shareContext = display->getContext(shareContextID);
2494*8975f5c5SAndroid Build Coastguard Worker 
2495*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(attributes.validate(val, display, ValidateCreateContextAttribute));
2496*8975f5c5SAndroid Build Coastguard Worker 
2497*8975f5c5SAndroid Build Coastguard Worker     for (const auto &attributePair : attributes)
2498*8975f5c5SAndroid Build Coastguard Worker     {
2499*8975f5c5SAndroid Build Coastguard Worker         EGLAttrib attribute = attributePair.first;
2500*8975f5c5SAndroid Build Coastguard Worker         EGLAttrib value     = attributePair.second;
2501*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_TRY(
2502*8975f5c5SAndroid Build Coastguard Worker             ValidateCreateContextAttributeValue(val, display, shareContext, attribute, value));
2503*8975f5c5SAndroid Build Coastguard Worker     }
2504*8975f5c5SAndroid Build Coastguard Worker 
2505*8975f5c5SAndroid Build Coastguard Worker     // Get the requested client version (default is 1) and check it is 2 or 3.
2506*8975f5c5SAndroid Build Coastguard Worker     EGLAttrib clientMajorVersion = attributes.get(EGL_CONTEXT_CLIENT_VERSION, 1);
2507*8975f5c5SAndroid Build Coastguard Worker     EGLAttrib clientMinorVersion = attributes.get(EGL_CONTEXT_MINOR_VERSION, 0);
2508*8975f5c5SAndroid Build Coastguard Worker     EGLenum api                  = val->eglThread->getAPI();
2509*8975f5c5SAndroid Build Coastguard Worker 
2510*8975f5c5SAndroid Build Coastguard Worker     switch (api)
2511*8975f5c5SAndroid Build Coastguard Worker     {
2512*8975f5c5SAndroid Build Coastguard Worker         case EGL_OPENGL_ES_API:
2513*8975f5c5SAndroid Build Coastguard Worker             switch (clientMajorVersion)
2514*8975f5c5SAndroid Build Coastguard Worker             {
2515*8975f5c5SAndroid Build Coastguard Worker                 case 1:
2516*8975f5c5SAndroid Build Coastguard Worker                     if (clientMinorVersion != 0 && clientMinorVersion != 1)
2517*8975f5c5SAndroid Build Coastguard Worker                     {
2518*8975f5c5SAndroid Build Coastguard Worker                         val->setError(EGL_BAD_ATTRIBUTE);
2519*8975f5c5SAndroid Build Coastguard Worker                         return false;
2520*8975f5c5SAndroid Build Coastguard Worker                     }
2521*8975f5c5SAndroid Build Coastguard Worker                     if (configuration == EGL_NO_CONFIG_KHR)
2522*8975f5c5SAndroid Build Coastguard Worker                     {
2523*8975f5c5SAndroid Build Coastguard Worker                         val->setError(EGL_BAD_MATCH);
2524*8975f5c5SAndroid Build Coastguard Worker                         return false;
2525*8975f5c5SAndroid Build Coastguard Worker                     }
2526*8975f5c5SAndroid Build Coastguard Worker                     if ((configuration != EGL_NO_CONFIG_KHR) &&
2527*8975f5c5SAndroid Build Coastguard Worker                         !(configuration->renderableType & EGL_OPENGL_ES_BIT))
2528*8975f5c5SAndroid Build Coastguard Worker                     {
2529*8975f5c5SAndroid Build Coastguard Worker                         val->setError(EGL_BAD_MATCH);
2530*8975f5c5SAndroid Build Coastguard Worker                         return false;
2531*8975f5c5SAndroid Build Coastguard Worker                     }
2532*8975f5c5SAndroid Build Coastguard Worker                     break;
2533*8975f5c5SAndroid Build Coastguard Worker 
2534*8975f5c5SAndroid Build Coastguard Worker                 case 2:
2535*8975f5c5SAndroid Build Coastguard Worker                     if (clientMinorVersion != 0)
2536*8975f5c5SAndroid Build Coastguard Worker                     {
2537*8975f5c5SAndroid Build Coastguard Worker                         val->setError(EGL_BAD_ATTRIBUTE);
2538*8975f5c5SAndroid Build Coastguard Worker                         return false;
2539*8975f5c5SAndroid Build Coastguard Worker                     }
2540*8975f5c5SAndroid Build Coastguard Worker                     if ((configuration != EGL_NO_CONFIG_KHR) &&
2541*8975f5c5SAndroid Build Coastguard Worker                         !(configuration->renderableType & EGL_OPENGL_ES2_BIT))
2542*8975f5c5SAndroid Build Coastguard Worker                     {
2543*8975f5c5SAndroid Build Coastguard Worker                         val->setError(EGL_BAD_MATCH);
2544*8975f5c5SAndroid Build Coastguard Worker                         return false;
2545*8975f5c5SAndroid Build Coastguard Worker                     }
2546*8975f5c5SAndroid Build Coastguard Worker                     break;
2547*8975f5c5SAndroid Build Coastguard Worker                 case 3:
2548*8975f5c5SAndroid Build Coastguard Worker                     if (clientMinorVersion < 0 || clientMinorVersion > 2)
2549*8975f5c5SAndroid Build Coastguard Worker                     {
2550*8975f5c5SAndroid Build Coastguard Worker                         val->setError(EGL_BAD_ATTRIBUTE);
2551*8975f5c5SAndroid Build Coastguard Worker                         return false;
2552*8975f5c5SAndroid Build Coastguard Worker                     }
2553*8975f5c5SAndroid Build Coastguard Worker                     if ((configuration != EGL_NO_CONFIG_KHR) &&
2554*8975f5c5SAndroid Build Coastguard Worker                         !(configuration->renderableType & EGL_OPENGL_ES3_BIT))
2555*8975f5c5SAndroid Build Coastguard Worker                     {
2556*8975f5c5SAndroid Build Coastguard Worker                         val->setError(EGL_BAD_MATCH);
2557*8975f5c5SAndroid Build Coastguard Worker                         return false;
2558*8975f5c5SAndroid Build Coastguard Worker                     }
2559*8975f5c5SAndroid Build Coastguard Worker                     if (display->getMaxSupportedESVersion() <
2560*8975f5c5SAndroid Build Coastguard Worker                         gl::Version(static_cast<GLuint>(clientMajorVersion),
2561*8975f5c5SAndroid Build Coastguard Worker                                     static_cast<GLuint>(clientMinorVersion)))
2562*8975f5c5SAndroid Build Coastguard Worker                     {
2563*8975f5c5SAndroid Build Coastguard Worker                         gl::Version max = display->getMaxSupportedESVersion();
2564*8975f5c5SAndroid Build Coastguard Worker                         val->setError(EGL_BAD_ATTRIBUTE,
2565*8975f5c5SAndroid Build Coastguard Worker                                       "Requested GLES version (%" PRIxPTR ".%" PRIxPTR
2566*8975f5c5SAndroid Build Coastguard Worker                                       ") is greater than "
2567*8975f5c5SAndroid Build Coastguard Worker                                       "max supported (%d, %d).",
2568*8975f5c5SAndroid Build Coastguard Worker                                       clientMajorVersion, clientMinorVersion, max.major, max.minor);
2569*8975f5c5SAndroid Build Coastguard Worker                         return false;
2570*8975f5c5SAndroid Build Coastguard Worker                     }
2571*8975f5c5SAndroid Build Coastguard Worker                     if ((attributes.get(EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE, EGL_FALSE) ==
2572*8975f5c5SAndroid Build Coastguard Worker                          EGL_TRUE) &&
2573*8975f5c5SAndroid Build Coastguard Worker                         (clientMinorVersion > 1))
2574*8975f5c5SAndroid Build Coastguard Worker                     {
2575*8975f5c5SAndroid Build Coastguard Worker                         val->setError(EGL_BAD_ATTRIBUTE,
2576*8975f5c5SAndroid Build Coastguard Worker                                       "Requested GLES version (%" PRIxPTR ".%" PRIxPTR
2577*8975f5c5SAndroid Build Coastguard Worker                                       ") is greater than "
2578*8975f5c5SAndroid Build Coastguard Worker                                       "max supported 3.1 for WebGL.",
2579*8975f5c5SAndroid Build Coastguard Worker                                       clientMajorVersion, clientMinorVersion);
2580*8975f5c5SAndroid Build Coastguard Worker                         return false;
2581*8975f5c5SAndroid Build Coastguard Worker                     }
2582*8975f5c5SAndroid Build Coastguard Worker                     break;
2583*8975f5c5SAndroid Build Coastguard Worker                 default:
2584*8975f5c5SAndroid Build Coastguard Worker                     val->setError(EGL_BAD_ATTRIBUTE);
2585*8975f5c5SAndroid Build Coastguard Worker                     return false;
2586*8975f5c5SAndroid Build Coastguard Worker             }
2587*8975f5c5SAndroid Build Coastguard Worker             break;
2588*8975f5c5SAndroid Build Coastguard Worker 
2589*8975f5c5SAndroid Build Coastguard Worker         case EGL_OPENGL_API:
2590*8975f5c5SAndroid Build Coastguard Worker             // Desktop GL is not supported by ANGLE.
2591*8975f5c5SAndroid Build Coastguard Worker             val->setError(EGL_BAD_CONFIG);
2592*8975f5c5SAndroid Build Coastguard Worker             return false;
2593*8975f5c5SAndroid Build Coastguard Worker 
2594*8975f5c5SAndroid Build Coastguard Worker         default:
2595*8975f5c5SAndroid Build Coastguard Worker             val->setError(EGL_BAD_MATCH, "Unsupported API.");
2596*8975f5c5SAndroid Build Coastguard Worker             return false;
2597*8975f5c5SAndroid Build Coastguard Worker     }
2598*8975f5c5SAndroid Build Coastguard Worker 
2599*8975f5c5SAndroid Build Coastguard Worker     return true;
2600*8975f5c5SAndroid Build Coastguard Worker }
2601*8975f5c5SAndroid Build Coastguard Worker 
ValidateCreateWindowSurface(const ValidationContext * val,const Display * display,const Config * config,EGLNativeWindowType window,const AttributeMap & attributes)2602*8975f5c5SAndroid Build Coastguard Worker bool ValidateCreateWindowSurface(const ValidationContext *val,
2603*8975f5c5SAndroid Build Coastguard Worker                                  const Display *display,
2604*8975f5c5SAndroid Build Coastguard Worker                                  const Config *config,
2605*8975f5c5SAndroid Build Coastguard Worker                                  EGLNativeWindowType window,
2606*8975f5c5SAndroid Build Coastguard Worker                                  const AttributeMap &attributes)
2607*8975f5c5SAndroid Build Coastguard Worker {
2608*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateConfig(val, display, config));
2609*8975f5c5SAndroid Build Coastguard Worker 
2610*8975f5c5SAndroid Build Coastguard Worker     if (!display->isValidNativeWindow(window))
2611*8975f5c5SAndroid Build Coastguard Worker     {
2612*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_NATIVE_WINDOW);
2613*8975f5c5SAndroid Build Coastguard Worker         return false;
2614*8975f5c5SAndroid Build Coastguard Worker     }
2615*8975f5c5SAndroid Build Coastguard Worker 
2616*8975f5c5SAndroid Build Coastguard Worker     const DisplayExtensions &displayExtensions = display->getExtensions();
2617*8975f5c5SAndroid Build Coastguard Worker 
2618*8975f5c5SAndroid Build Coastguard Worker     attributes.initializeWithoutValidation();
2619*8975f5c5SAndroid Build Coastguard Worker 
2620*8975f5c5SAndroid Build Coastguard Worker     for (const auto &attributeIter : attributes)
2621*8975f5c5SAndroid Build Coastguard Worker     {
2622*8975f5c5SAndroid Build Coastguard Worker         EGLAttrib attribute = attributeIter.first;
2623*8975f5c5SAndroid Build Coastguard Worker         EGLAttrib value     = attributeIter.second;
2624*8975f5c5SAndroid Build Coastguard Worker 
2625*8975f5c5SAndroid Build Coastguard Worker         switch (attribute)
2626*8975f5c5SAndroid Build Coastguard Worker         {
2627*8975f5c5SAndroid Build Coastguard Worker             case EGL_RENDER_BUFFER:
2628*8975f5c5SAndroid Build Coastguard Worker                 switch (value)
2629*8975f5c5SAndroid Build Coastguard Worker                 {
2630*8975f5c5SAndroid Build Coastguard Worker                     case EGL_BACK_BUFFER:
2631*8975f5c5SAndroid Build Coastguard Worker                         break;
2632*8975f5c5SAndroid Build Coastguard Worker                     case EGL_SINGLE_BUFFER:
2633*8975f5c5SAndroid Build Coastguard Worker                         break;
2634*8975f5c5SAndroid Build Coastguard Worker                     default:
2635*8975f5c5SAndroid Build Coastguard Worker                         val->setError(EGL_BAD_ATTRIBUTE);
2636*8975f5c5SAndroid Build Coastguard Worker                         return false;
2637*8975f5c5SAndroid Build Coastguard Worker                 }
2638*8975f5c5SAndroid Build Coastguard Worker                 break;
2639*8975f5c5SAndroid Build Coastguard Worker 
2640*8975f5c5SAndroid Build Coastguard Worker             case EGL_POST_SUB_BUFFER_SUPPORTED_NV:
2641*8975f5c5SAndroid Build Coastguard Worker                 if (!displayExtensions.postSubBuffer)
2642*8975f5c5SAndroid Build Coastguard Worker                 {
2643*8975f5c5SAndroid Build Coastguard Worker                     val->setError(EGL_BAD_ATTRIBUTE);
2644*8975f5c5SAndroid Build Coastguard Worker                     return false;
2645*8975f5c5SAndroid Build Coastguard Worker                 }
2646*8975f5c5SAndroid Build Coastguard Worker                 break;
2647*8975f5c5SAndroid Build Coastguard Worker 
2648*8975f5c5SAndroid Build Coastguard Worker             case EGL_WIDTH:
2649*8975f5c5SAndroid Build Coastguard Worker             case EGL_HEIGHT:
2650*8975f5c5SAndroid Build Coastguard Worker                 if (!displayExtensions.windowFixedSize)
2651*8975f5c5SAndroid Build Coastguard Worker                 {
2652*8975f5c5SAndroid Build Coastguard Worker                     val->setError(EGL_BAD_ATTRIBUTE);
2653*8975f5c5SAndroid Build Coastguard Worker                     return false;
2654*8975f5c5SAndroid Build Coastguard Worker                 }
2655*8975f5c5SAndroid Build Coastguard Worker                 if (value < 0)
2656*8975f5c5SAndroid Build Coastguard Worker                 {
2657*8975f5c5SAndroid Build Coastguard Worker                     val->setError(EGL_BAD_PARAMETER);
2658*8975f5c5SAndroid Build Coastguard Worker                     return false;
2659*8975f5c5SAndroid Build Coastguard Worker                 }
2660*8975f5c5SAndroid Build Coastguard Worker                 break;
2661*8975f5c5SAndroid Build Coastguard Worker 
2662*8975f5c5SAndroid Build Coastguard Worker             case EGL_FIXED_SIZE_ANGLE:
2663*8975f5c5SAndroid Build Coastguard Worker                 if (!displayExtensions.windowFixedSize)
2664*8975f5c5SAndroid Build Coastguard Worker                 {
2665*8975f5c5SAndroid Build Coastguard Worker                     val->setError(EGL_BAD_ATTRIBUTE);
2666*8975f5c5SAndroid Build Coastguard Worker                     return false;
2667*8975f5c5SAndroid Build Coastguard Worker                 }
2668*8975f5c5SAndroid Build Coastguard Worker                 break;
2669*8975f5c5SAndroid Build Coastguard Worker 
2670*8975f5c5SAndroid Build Coastguard Worker             case EGL_SURFACE_ORIENTATION_ANGLE:
2671*8975f5c5SAndroid Build Coastguard Worker                 if (!displayExtensions.surfaceOrientation)
2672*8975f5c5SAndroid Build Coastguard Worker                 {
2673*8975f5c5SAndroid Build Coastguard Worker                     val->setError(EGL_BAD_ATTRIBUTE,
2674*8975f5c5SAndroid Build Coastguard Worker                                   "EGL_ANGLE_surface_orientation is not enabled.");
2675*8975f5c5SAndroid Build Coastguard Worker                     return false;
2676*8975f5c5SAndroid Build Coastguard Worker                 }
2677*8975f5c5SAndroid Build Coastguard Worker                 break;
2678*8975f5c5SAndroid Build Coastguard Worker 
2679*8975f5c5SAndroid Build Coastguard Worker             case EGL_VG_COLORSPACE:
2680*8975f5c5SAndroid Build Coastguard Worker                 if (value != EGL_VG_COLORSPACE_sRGB)
2681*8975f5c5SAndroid Build Coastguard Worker                 {
2682*8975f5c5SAndroid Build Coastguard Worker                     val->setError(EGL_BAD_MATCH);
2683*8975f5c5SAndroid Build Coastguard Worker                     return false;
2684*8975f5c5SAndroid Build Coastguard Worker                 }
2685*8975f5c5SAndroid Build Coastguard Worker                 break;
2686*8975f5c5SAndroid Build Coastguard Worker 
2687*8975f5c5SAndroid Build Coastguard Worker             case EGL_GL_COLORSPACE:
2688*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_TRY(ValidateColorspaceAttribute(val, displayExtensions, value));
2689*8975f5c5SAndroid Build Coastguard Worker                 break;
2690*8975f5c5SAndroid Build Coastguard Worker 
2691*8975f5c5SAndroid Build Coastguard Worker             case EGL_VG_ALPHA_FORMAT:
2692*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_MATCH);
2693*8975f5c5SAndroid Build Coastguard Worker                 return false;
2694*8975f5c5SAndroid Build Coastguard Worker 
2695*8975f5c5SAndroid Build Coastguard Worker             case EGL_DIRECT_COMPOSITION_ANGLE:
2696*8975f5c5SAndroid Build Coastguard Worker                 if (!displayExtensions.directComposition)
2697*8975f5c5SAndroid Build Coastguard Worker                 {
2698*8975f5c5SAndroid Build Coastguard Worker                     val->setError(EGL_BAD_ATTRIBUTE);
2699*8975f5c5SAndroid Build Coastguard Worker                     return false;
2700*8975f5c5SAndroid Build Coastguard Worker                 }
2701*8975f5c5SAndroid Build Coastguard Worker                 break;
2702*8975f5c5SAndroid Build Coastguard Worker 
2703*8975f5c5SAndroid Build Coastguard Worker             case EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
2704*8975f5c5SAndroid Build Coastguard Worker                 if (!display->getExtensions().robustResourceInitializationANGLE)
2705*8975f5c5SAndroid Build Coastguard Worker                 {
2706*8975f5c5SAndroid Build Coastguard Worker                     val->setError(EGL_BAD_ATTRIBUTE,
2707*8975f5c5SAndroid Build Coastguard Worker                                   "Attribute EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE "
2708*8975f5c5SAndroid Build Coastguard Worker                                   "requires EGL_ANGLE_robust_resource_initialization.");
2709*8975f5c5SAndroid Build Coastguard Worker                     return false;
2710*8975f5c5SAndroid Build Coastguard Worker                 }
2711*8975f5c5SAndroid Build Coastguard Worker                 if (value != EGL_TRUE && value != EGL_FALSE)
2712*8975f5c5SAndroid Build Coastguard Worker                 {
2713*8975f5c5SAndroid Build Coastguard Worker                     val->setError(EGL_BAD_ATTRIBUTE,
2714*8975f5c5SAndroid Build Coastguard Worker                                   "EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE must be "
2715*8975f5c5SAndroid Build Coastguard Worker                                   "either EGL_TRUE or EGL_FALSE.");
2716*8975f5c5SAndroid Build Coastguard Worker                     return false;
2717*8975f5c5SAndroid Build Coastguard Worker                 }
2718*8975f5c5SAndroid Build Coastguard Worker                 break;
2719*8975f5c5SAndroid Build Coastguard Worker 
2720*8975f5c5SAndroid Build Coastguard Worker             case EGL_GGP_STREAM_DESCRIPTOR_ANGLE:
2721*8975f5c5SAndroid Build Coastguard Worker                 if (!display->getExtensions().ggpStreamDescriptor)
2722*8975f5c5SAndroid Build Coastguard Worker                 {
2723*8975f5c5SAndroid Build Coastguard Worker                     val->setError(EGL_BAD_ATTRIBUTE,
2724*8975f5c5SAndroid Build Coastguard Worker                                   "EGL_GGP_STREAM_DESCRIPTOR_ANGLE requires "
2725*8975f5c5SAndroid Build Coastguard Worker                                   "EGL_ANGLE_ggp_stream_descriptor.");
2726*8975f5c5SAndroid Build Coastguard Worker                     return false;
2727*8975f5c5SAndroid Build Coastguard Worker                 }
2728*8975f5c5SAndroid Build Coastguard Worker                 break;
2729*8975f5c5SAndroid Build Coastguard Worker 
2730*8975f5c5SAndroid Build Coastguard Worker             case EGL_PROTECTED_CONTENT_EXT:
2731*8975f5c5SAndroid Build Coastguard Worker                 if (!displayExtensions.protectedContentEXT)
2732*8975f5c5SAndroid Build Coastguard Worker                 {
2733*8975f5c5SAndroid Build Coastguard Worker                     val->setError(EGL_BAD_ATTRIBUTE,
2734*8975f5c5SAndroid Build Coastguard Worker                                   "Attribute EGL_PROTECTED_CONTEXT_EXT requires "
2735*8975f5c5SAndroid Build Coastguard Worker                                   "extension EGL_EXT_protected_content.");
2736*8975f5c5SAndroid Build Coastguard Worker                     return false;
2737*8975f5c5SAndroid Build Coastguard Worker                 }
2738*8975f5c5SAndroid Build Coastguard Worker                 if (value != EGL_TRUE && value != EGL_FALSE)
2739*8975f5c5SAndroid Build Coastguard Worker                 {
2740*8975f5c5SAndroid Build Coastguard Worker                     val->setError(EGL_BAD_ATTRIBUTE,
2741*8975f5c5SAndroid Build Coastguard Worker                                   "EGL_PROTECTED_CONTENT_EXT must "
2742*8975f5c5SAndroid Build Coastguard Worker                                   "be either EGL_TRUE or EGL_FALSE.");
2743*8975f5c5SAndroid Build Coastguard Worker                     return false;
2744*8975f5c5SAndroid Build Coastguard Worker                 }
2745*8975f5c5SAndroid Build Coastguard Worker                 break;
2746*8975f5c5SAndroid Build Coastguard Worker 
2747*8975f5c5SAndroid Build Coastguard Worker             case EGL_SWAP_INTERVAL_ANGLE:
2748*8975f5c5SAndroid Build Coastguard Worker                 if (!displayExtensions.createSurfaceSwapIntervalANGLE)
2749*8975f5c5SAndroid Build Coastguard Worker                 {
2750*8975f5c5SAndroid Build Coastguard Worker                     val->setError(EGL_BAD_ATTRIBUTE,
2751*8975f5c5SAndroid Build Coastguard Worker                                   "Attribute EGL_SWAP_INTERVAL_ANGLE requires "
2752*8975f5c5SAndroid Build Coastguard Worker                                   "extension EGL_ANGLE_create_surface_swap_interval.");
2753*8975f5c5SAndroid Build Coastguard Worker                     return false;
2754*8975f5c5SAndroid Build Coastguard Worker                 }
2755*8975f5c5SAndroid Build Coastguard Worker                 if (value < config->minSwapInterval || value > config->maxSwapInterval)
2756*8975f5c5SAndroid Build Coastguard Worker                 {
2757*8975f5c5SAndroid Build Coastguard Worker                     val->setError(EGL_BAD_ATTRIBUTE,
2758*8975f5c5SAndroid Build Coastguard Worker                                   "EGL_SWAP_INTERVAL_ANGLE must "
2759*8975f5c5SAndroid Build Coastguard Worker                                   "be within the EGLConfig min and max swap intervals.");
2760*8975f5c5SAndroid Build Coastguard Worker                     return false;
2761*8975f5c5SAndroid Build Coastguard Worker                 }
2762*8975f5c5SAndroid Build Coastguard Worker                 break;
2763*8975f5c5SAndroid Build Coastguard Worker 
2764*8975f5c5SAndroid Build Coastguard Worker             default:
2765*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE);
2766*8975f5c5SAndroid Build Coastguard Worker                 return false;
2767*8975f5c5SAndroid Build Coastguard Worker         }
2768*8975f5c5SAndroid Build Coastguard Worker     }
2769*8975f5c5SAndroid Build Coastguard Worker 
2770*8975f5c5SAndroid Build Coastguard Worker     if (Display::hasExistingWindowSurface(window))
2771*8975f5c5SAndroid Build Coastguard Worker     {
2772*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_ALLOC);
2773*8975f5c5SAndroid Build Coastguard Worker         return false;
2774*8975f5c5SAndroid Build Coastguard Worker     }
2775*8975f5c5SAndroid Build Coastguard Worker 
2776*8975f5c5SAndroid Build Coastguard Worker     return true;
2777*8975f5c5SAndroid Build Coastguard Worker }
2778*8975f5c5SAndroid Build Coastguard Worker 
ValidateCreatePbufferSurface(const ValidationContext * val,const Display * display,const Config * config,const AttributeMap & attributes)2779*8975f5c5SAndroid Build Coastguard Worker bool ValidateCreatePbufferSurface(const ValidationContext *val,
2780*8975f5c5SAndroid Build Coastguard Worker                                   const Display *display,
2781*8975f5c5SAndroid Build Coastguard Worker                                   const Config *config,
2782*8975f5c5SAndroid Build Coastguard Worker                                   const AttributeMap &attributes)
2783*8975f5c5SAndroid Build Coastguard Worker {
2784*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateConfig(val, display, config));
2785*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(attributes.validate(val, display, ValidateCreatePbufferSurfaceAttribute));
2786*8975f5c5SAndroid Build Coastguard Worker 
2787*8975f5c5SAndroid Build Coastguard Worker     for (const auto &attributeIter : attributes)
2788*8975f5c5SAndroid Build Coastguard Worker     {
2789*8975f5c5SAndroid Build Coastguard Worker         EGLAttrib attribute = attributeIter.first;
2790*8975f5c5SAndroid Build Coastguard Worker         EGLAttrib value     = attributeIter.second;
2791*8975f5c5SAndroid Build Coastguard Worker 
2792*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_TRY(
2793*8975f5c5SAndroid Build Coastguard Worker             ValidateCreatePbufferSurfaceAttributeValue(val, display, attribute, value));
2794*8975f5c5SAndroid Build Coastguard Worker     }
2795*8975f5c5SAndroid Build Coastguard Worker 
2796*8975f5c5SAndroid Build Coastguard Worker     if ((config->surfaceType & EGL_PBUFFER_BIT) == 0)
2797*8975f5c5SAndroid Build Coastguard Worker     {
2798*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_MATCH);
2799*8975f5c5SAndroid Build Coastguard Worker         return false;
2800*8975f5c5SAndroid Build Coastguard Worker     }
2801*8975f5c5SAndroid Build Coastguard Worker 
2802*8975f5c5SAndroid Build Coastguard Worker     const Caps &caps = display->getCaps();
2803*8975f5c5SAndroid Build Coastguard Worker 
2804*8975f5c5SAndroid Build Coastguard Worker     EGLAttrib textureFormat = attributes.get(EGL_TEXTURE_FORMAT, EGL_NO_TEXTURE);
2805*8975f5c5SAndroid Build Coastguard Worker     EGLAttrib textureTarget = attributes.get(EGL_TEXTURE_TARGET, EGL_NO_TEXTURE);
2806*8975f5c5SAndroid Build Coastguard Worker 
2807*8975f5c5SAndroid Build Coastguard Worker     if ((textureFormat != EGL_NO_TEXTURE && textureTarget == EGL_NO_TEXTURE) ||
2808*8975f5c5SAndroid Build Coastguard Worker         (textureFormat == EGL_NO_TEXTURE && textureTarget != EGL_NO_TEXTURE))
2809*8975f5c5SAndroid Build Coastguard Worker     {
2810*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_MATCH);
2811*8975f5c5SAndroid Build Coastguard Worker         return false;
2812*8975f5c5SAndroid Build Coastguard Worker     }
2813*8975f5c5SAndroid Build Coastguard Worker 
2814*8975f5c5SAndroid Build Coastguard Worker     if ((textureFormat == EGL_TEXTURE_RGB && config->bindToTextureRGB != EGL_TRUE) ||
2815*8975f5c5SAndroid Build Coastguard Worker         (textureFormat == EGL_TEXTURE_RGBA && config->bindToTextureRGBA != EGL_TRUE))
2816*8975f5c5SAndroid Build Coastguard Worker     {
2817*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_ATTRIBUTE);
2818*8975f5c5SAndroid Build Coastguard Worker         return false;
2819*8975f5c5SAndroid Build Coastguard Worker     }
2820*8975f5c5SAndroid Build Coastguard Worker 
2821*8975f5c5SAndroid Build Coastguard Worker     EGLint width  = static_cast<EGLint>(attributes.get(EGL_WIDTH, 0));
2822*8975f5c5SAndroid Build Coastguard Worker     EGLint height = static_cast<EGLint>(attributes.get(EGL_HEIGHT, 0));
2823*8975f5c5SAndroid Build Coastguard Worker     if (textureFormat != EGL_NO_TEXTURE && !caps.textureNPOT &&
2824*8975f5c5SAndroid Build Coastguard Worker         (!gl::isPow2(width) || !gl::isPow2(height)))
2825*8975f5c5SAndroid Build Coastguard Worker     {
2826*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_MATCH);
2827*8975f5c5SAndroid Build Coastguard Worker         return false;
2828*8975f5c5SAndroid Build Coastguard Worker     }
2829*8975f5c5SAndroid Build Coastguard Worker 
2830*8975f5c5SAndroid Build Coastguard Worker     return true;
2831*8975f5c5SAndroid Build Coastguard Worker }
2832*8975f5c5SAndroid Build Coastguard Worker 
ValidateCreatePbufferFromClientBuffer(const ValidationContext * val,const Display * display,EGLenum buftype,EGLClientBuffer buffer,const Config * config,const AttributeMap & attributes)2833*8975f5c5SAndroid Build Coastguard Worker bool ValidateCreatePbufferFromClientBuffer(const ValidationContext *val,
2834*8975f5c5SAndroid Build Coastguard Worker                                            const Display *display,
2835*8975f5c5SAndroid Build Coastguard Worker                                            EGLenum buftype,
2836*8975f5c5SAndroid Build Coastguard Worker                                            EGLClientBuffer buffer,
2837*8975f5c5SAndroid Build Coastguard Worker                                            const Config *config,
2838*8975f5c5SAndroid Build Coastguard Worker                                            const AttributeMap &attributes)
2839*8975f5c5SAndroid Build Coastguard Worker {
2840*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateConfig(val, display, config));
2841*8975f5c5SAndroid Build Coastguard Worker 
2842*8975f5c5SAndroid Build Coastguard Worker     const DisplayExtensions &displayExtensions = display->getExtensions();
2843*8975f5c5SAndroid Build Coastguard Worker 
2844*8975f5c5SAndroid Build Coastguard Worker     attributes.initializeWithoutValidation();
2845*8975f5c5SAndroid Build Coastguard Worker 
2846*8975f5c5SAndroid Build Coastguard Worker     switch (buftype)
2847*8975f5c5SAndroid Build Coastguard Worker     {
2848*8975f5c5SAndroid Build Coastguard Worker         case EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE:
2849*8975f5c5SAndroid Build Coastguard Worker             if (!displayExtensions.d3dShareHandleClientBuffer)
2850*8975f5c5SAndroid Build Coastguard Worker             {
2851*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_PARAMETER);
2852*8975f5c5SAndroid Build Coastguard Worker                 return false;
2853*8975f5c5SAndroid Build Coastguard Worker             }
2854*8975f5c5SAndroid Build Coastguard Worker             if (buffer == nullptr)
2855*8975f5c5SAndroid Build Coastguard Worker             {
2856*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_PARAMETER);
2857*8975f5c5SAndroid Build Coastguard Worker                 return false;
2858*8975f5c5SAndroid Build Coastguard Worker             }
2859*8975f5c5SAndroid Build Coastguard Worker             break;
2860*8975f5c5SAndroid Build Coastguard Worker 
2861*8975f5c5SAndroid Build Coastguard Worker         case EGL_D3D_TEXTURE_ANGLE:
2862*8975f5c5SAndroid Build Coastguard Worker             if (!displayExtensions.d3dTextureClientBuffer)
2863*8975f5c5SAndroid Build Coastguard Worker             {
2864*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_PARAMETER);
2865*8975f5c5SAndroid Build Coastguard Worker                 return false;
2866*8975f5c5SAndroid Build Coastguard Worker             }
2867*8975f5c5SAndroid Build Coastguard Worker             if (buffer == nullptr)
2868*8975f5c5SAndroid Build Coastguard Worker             {
2869*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_PARAMETER);
2870*8975f5c5SAndroid Build Coastguard Worker                 return false;
2871*8975f5c5SAndroid Build Coastguard Worker             }
2872*8975f5c5SAndroid Build Coastguard Worker             break;
2873*8975f5c5SAndroid Build Coastguard Worker 
2874*8975f5c5SAndroid Build Coastguard Worker         case EGL_IOSURFACE_ANGLE:
2875*8975f5c5SAndroid Build Coastguard Worker             if (!displayExtensions.iosurfaceClientBuffer)
2876*8975f5c5SAndroid Build Coastguard Worker             {
2877*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_PARAMETER,
2878*8975f5c5SAndroid Build Coastguard Worker                               "<buftype> EGL_IOSURFACE_ANGLE requires the "
2879*8975f5c5SAndroid Build Coastguard Worker                               "EGL_ANGLE_iosurface_client_buffer extension.");
2880*8975f5c5SAndroid Build Coastguard Worker                 return false;
2881*8975f5c5SAndroid Build Coastguard Worker             }
2882*8975f5c5SAndroid Build Coastguard Worker             if (buffer == nullptr)
2883*8975f5c5SAndroid Build Coastguard Worker             {
2884*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_PARAMETER, "<buffer> must be non null");
2885*8975f5c5SAndroid Build Coastguard Worker                 return false;
2886*8975f5c5SAndroid Build Coastguard Worker             }
2887*8975f5c5SAndroid Build Coastguard Worker             break;
2888*8975f5c5SAndroid Build Coastguard Worker         case EGL_EXTERNAL_SURFACE_ANGLE:
2889*8975f5c5SAndroid Build Coastguard Worker             if (!display->getExtensions().externalContextAndSurface)
2890*8975f5c5SAndroid Build Coastguard Worker             {
2891*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE,
2892*8975f5c5SAndroid Build Coastguard Worker                               "Attribute "
2893*8975f5c5SAndroid Build Coastguard Worker                               "EGL_EXTERNAL_SURFACE_ANGLE requires "
2894*8975f5c5SAndroid Build Coastguard Worker                               "EGL_ANGLE_external_context_and_surface.");
2895*8975f5c5SAndroid Build Coastguard Worker                 return false;
2896*8975f5c5SAndroid Build Coastguard Worker             }
2897*8975f5c5SAndroid Build Coastguard Worker             if (buffer != nullptr)
2898*8975f5c5SAndroid Build Coastguard Worker             {
2899*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_PARAMETER, "<buffer> must be null");
2900*8975f5c5SAndroid Build Coastguard Worker                 return false;
2901*8975f5c5SAndroid Build Coastguard Worker             }
2902*8975f5c5SAndroid Build Coastguard Worker             break;
2903*8975f5c5SAndroid Build Coastguard Worker 
2904*8975f5c5SAndroid Build Coastguard Worker         default:
2905*8975f5c5SAndroid Build Coastguard Worker             val->setError(EGL_BAD_PARAMETER);
2906*8975f5c5SAndroid Build Coastguard Worker             return false;
2907*8975f5c5SAndroid Build Coastguard Worker     }
2908*8975f5c5SAndroid Build Coastguard Worker 
2909*8975f5c5SAndroid Build Coastguard Worker     for (AttributeMap::const_iterator attributeIter = attributes.begin();
2910*8975f5c5SAndroid Build Coastguard Worker          attributeIter != attributes.end(); attributeIter++)
2911*8975f5c5SAndroid Build Coastguard Worker     {
2912*8975f5c5SAndroid Build Coastguard Worker         EGLAttrib attribute = attributeIter->first;
2913*8975f5c5SAndroid Build Coastguard Worker         EGLAttrib value     = attributeIter->second;
2914*8975f5c5SAndroid Build Coastguard Worker 
2915*8975f5c5SAndroid Build Coastguard Worker         switch (attribute)
2916*8975f5c5SAndroid Build Coastguard Worker         {
2917*8975f5c5SAndroid Build Coastguard Worker             case EGL_WIDTH:
2918*8975f5c5SAndroid Build Coastguard Worker             case EGL_HEIGHT:
2919*8975f5c5SAndroid Build Coastguard Worker                 if (buftype != EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE &&
2920*8975f5c5SAndroid Build Coastguard Worker                     buftype != EGL_D3D_TEXTURE_ANGLE && buftype != EGL_IOSURFACE_ANGLE &&
2921*8975f5c5SAndroid Build Coastguard Worker                     buftype != EGL_EXTERNAL_SURFACE_ANGLE)
2922*8975f5c5SAndroid Build Coastguard Worker                 {
2923*8975f5c5SAndroid Build Coastguard Worker                     val->setError(EGL_BAD_PARAMETER,
2924*8975f5c5SAndroid Build Coastguard Worker                                   "Width and Height are not supported for this <buftype>");
2925*8975f5c5SAndroid Build Coastguard Worker                     return false;
2926*8975f5c5SAndroid Build Coastguard Worker                 }
2927*8975f5c5SAndroid Build Coastguard Worker                 if (value < 0)
2928*8975f5c5SAndroid Build Coastguard Worker                 {
2929*8975f5c5SAndroid Build Coastguard Worker                     val->setError(EGL_BAD_PARAMETER, "Width and Height must be positive");
2930*8975f5c5SAndroid Build Coastguard Worker                     return false;
2931*8975f5c5SAndroid Build Coastguard Worker                 }
2932*8975f5c5SAndroid Build Coastguard Worker                 break;
2933*8975f5c5SAndroid Build Coastguard Worker 
2934*8975f5c5SAndroid Build Coastguard Worker             case EGL_TEXTURE_FORMAT:
2935*8975f5c5SAndroid Build Coastguard Worker                 switch (value)
2936*8975f5c5SAndroid Build Coastguard Worker                 {
2937*8975f5c5SAndroid Build Coastguard Worker                     case EGL_NO_TEXTURE:
2938*8975f5c5SAndroid Build Coastguard Worker                     case EGL_TEXTURE_RGB:
2939*8975f5c5SAndroid Build Coastguard Worker                     case EGL_TEXTURE_RGBA:
2940*8975f5c5SAndroid Build Coastguard Worker                         break;
2941*8975f5c5SAndroid Build Coastguard Worker                     default:
2942*8975f5c5SAndroid Build Coastguard Worker                         val->setError(EGL_BAD_ATTRIBUTE, "Invalid value for EGL_TEXTURE_FORMAT");
2943*8975f5c5SAndroid Build Coastguard Worker                         return false;
2944*8975f5c5SAndroid Build Coastguard Worker                 }
2945*8975f5c5SAndroid Build Coastguard Worker                 break;
2946*8975f5c5SAndroid Build Coastguard Worker 
2947*8975f5c5SAndroid Build Coastguard Worker             case EGL_TEXTURE_TARGET:
2948*8975f5c5SAndroid Build Coastguard Worker                 switch (value)
2949*8975f5c5SAndroid Build Coastguard Worker                 {
2950*8975f5c5SAndroid Build Coastguard Worker                     case EGL_NO_TEXTURE:
2951*8975f5c5SAndroid Build Coastguard Worker                     case EGL_TEXTURE_2D:
2952*8975f5c5SAndroid Build Coastguard Worker                         break;
2953*8975f5c5SAndroid Build Coastguard Worker                     case EGL_TEXTURE_RECTANGLE_ANGLE:
2954*8975f5c5SAndroid Build Coastguard Worker                         if (buftype != EGL_IOSURFACE_ANGLE)
2955*8975f5c5SAndroid Build Coastguard Worker                         {
2956*8975f5c5SAndroid Build Coastguard Worker                             val->setError(EGL_BAD_PARAMETER,
2957*8975f5c5SAndroid Build Coastguard Worker                                           "<buftype> doesn't support rectangle texture targets");
2958*8975f5c5SAndroid Build Coastguard Worker                             return false;
2959*8975f5c5SAndroid Build Coastguard Worker                         }
2960*8975f5c5SAndroid Build Coastguard Worker                         break;
2961*8975f5c5SAndroid Build Coastguard Worker 
2962*8975f5c5SAndroid Build Coastguard Worker                     default:
2963*8975f5c5SAndroid Build Coastguard Worker                         val->setError(EGL_BAD_ATTRIBUTE, "Invalid value for EGL_TEXTURE_TARGET");
2964*8975f5c5SAndroid Build Coastguard Worker                         return false;
2965*8975f5c5SAndroid Build Coastguard Worker                 }
2966*8975f5c5SAndroid Build Coastguard Worker                 break;
2967*8975f5c5SAndroid Build Coastguard Worker 
2968*8975f5c5SAndroid Build Coastguard Worker             case EGL_MIPMAP_TEXTURE:
2969*8975f5c5SAndroid Build Coastguard Worker                 break;
2970*8975f5c5SAndroid Build Coastguard Worker 
2971*8975f5c5SAndroid Build Coastguard Worker             case EGL_IOSURFACE_PLANE_ANGLE:
2972*8975f5c5SAndroid Build Coastguard Worker                 if (buftype != EGL_IOSURFACE_ANGLE)
2973*8975f5c5SAndroid Build Coastguard Worker                 {
2974*8975f5c5SAndroid Build Coastguard Worker                     val->setError(EGL_BAD_ATTRIBUTE, "<buftype> doesn't support iosurface plane");
2975*8975f5c5SAndroid Build Coastguard Worker                     return false;
2976*8975f5c5SAndroid Build Coastguard Worker                 }
2977*8975f5c5SAndroid Build Coastguard Worker                 break;
2978*8975f5c5SAndroid Build Coastguard Worker 
2979*8975f5c5SAndroid Build Coastguard Worker             case EGL_TEXTURE_TYPE_ANGLE:
2980*8975f5c5SAndroid Build Coastguard Worker                 if (buftype != EGL_IOSURFACE_ANGLE)
2981*8975f5c5SAndroid Build Coastguard Worker                 {
2982*8975f5c5SAndroid Build Coastguard Worker                     val->setError(EGL_BAD_ATTRIBUTE, "<buftype> doesn't support texture type");
2983*8975f5c5SAndroid Build Coastguard Worker                     return false;
2984*8975f5c5SAndroid Build Coastguard Worker                 }
2985*8975f5c5SAndroid Build Coastguard Worker                 break;
2986*8975f5c5SAndroid Build Coastguard Worker 
2987*8975f5c5SAndroid Build Coastguard Worker             case EGL_TEXTURE_INTERNAL_FORMAT_ANGLE:
2988*8975f5c5SAndroid Build Coastguard Worker                 if (buftype != EGL_IOSURFACE_ANGLE && buftype != EGL_D3D_TEXTURE_ANGLE)
2989*8975f5c5SAndroid Build Coastguard Worker                 {
2990*8975f5c5SAndroid Build Coastguard Worker                     val->setError(EGL_BAD_ATTRIBUTE,
2991*8975f5c5SAndroid Build Coastguard Worker                                   "<buftype> doesn't support texture internal format");
2992*8975f5c5SAndroid Build Coastguard Worker                     return false;
2993*8975f5c5SAndroid Build Coastguard Worker                 }
2994*8975f5c5SAndroid Build Coastguard Worker                 break;
2995*8975f5c5SAndroid Build Coastguard Worker 
2996*8975f5c5SAndroid Build Coastguard Worker             case EGL_GL_COLORSPACE:
2997*8975f5c5SAndroid Build Coastguard Worker                 if (buftype != EGL_D3D_TEXTURE_ANGLE)
2998*8975f5c5SAndroid Build Coastguard Worker                 {
2999*8975f5c5SAndroid Build Coastguard Worker                     val->setError(EGL_BAD_ATTRIBUTE,
3000*8975f5c5SAndroid Build Coastguard Worker                                   "<buftype> doesn't support setting GL colorspace");
3001*8975f5c5SAndroid Build Coastguard Worker                     return false;
3002*8975f5c5SAndroid Build Coastguard Worker                 }
3003*8975f5c5SAndroid Build Coastguard Worker                 break;
3004*8975f5c5SAndroid Build Coastguard Worker 
3005*8975f5c5SAndroid Build Coastguard Worker             case EGL_IOSURFACE_USAGE_HINT_ANGLE:
3006*8975f5c5SAndroid Build Coastguard Worker                 if (value & ~(EGL_IOSURFACE_READ_HINT_ANGLE | EGL_IOSURFACE_WRITE_HINT_ANGLE))
3007*8975f5c5SAndroid Build Coastguard Worker                 {
3008*8975f5c5SAndroid Build Coastguard Worker                     val->setError(EGL_BAD_ATTRIBUTE,
3009*8975f5c5SAndroid Build Coastguard Worker                                   "IOSurface usage hint must only contain READ or WRITE");
3010*8975f5c5SAndroid Build Coastguard Worker                     return false;
3011*8975f5c5SAndroid Build Coastguard Worker                 }
3012*8975f5c5SAndroid Build Coastguard Worker                 break;
3013*8975f5c5SAndroid Build Coastguard Worker 
3014*8975f5c5SAndroid Build Coastguard Worker             case EGL_TEXTURE_OFFSET_X_ANGLE:
3015*8975f5c5SAndroid Build Coastguard Worker             case EGL_TEXTURE_OFFSET_Y_ANGLE:
3016*8975f5c5SAndroid Build Coastguard Worker                 if (buftype != EGL_D3D_TEXTURE_ANGLE)
3017*8975f5c5SAndroid Build Coastguard Worker                 {
3018*8975f5c5SAndroid Build Coastguard Worker                     val->setError(EGL_BAD_ATTRIBUTE,
3019*8975f5c5SAndroid Build Coastguard Worker                                   "<buftype> doesn't support setting texture offset");
3020*8975f5c5SAndroid Build Coastguard Worker                     return false;
3021*8975f5c5SAndroid Build Coastguard Worker                 }
3022*8975f5c5SAndroid Build Coastguard Worker                 break;
3023*8975f5c5SAndroid Build Coastguard Worker 
3024*8975f5c5SAndroid Build Coastguard Worker             case EGL_PROTECTED_CONTENT_EXT:
3025*8975f5c5SAndroid Build Coastguard Worker                 if (!displayExtensions.protectedContentEXT)
3026*8975f5c5SAndroid Build Coastguard Worker                 {
3027*8975f5c5SAndroid Build Coastguard Worker                     val->setError(EGL_BAD_ATTRIBUTE,
3028*8975f5c5SAndroid Build Coastguard Worker                                   "Attribute EGL_PROTECTED_CONTEXT_EXT requires "
3029*8975f5c5SAndroid Build Coastguard Worker                                   "extension EGL_EXT_protected_content.");
3030*8975f5c5SAndroid Build Coastguard Worker                     return false;
3031*8975f5c5SAndroid Build Coastguard Worker                 }
3032*8975f5c5SAndroid Build Coastguard Worker                 if (value != EGL_TRUE && value != EGL_FALSE)
3033*8975f5c5SAndroid Build Coastguard Worker                 {
3034*8975f5c5SAndroid Build Coastguard Worker                     val->setError(EGL_BAD_ATTRIBUTE,
3035*8975f5c5SAndroid Build Coastguard Worker                                   "EGL_PROTECTED_CONTENT_EXT must "
3036*8975f5c5SAndroid Build Coastguard Worker                                   "be either EGL_TRUE or EGL_FALSE.");
3037*8975f5c5SAndroid Build Coastguard Worker                     return false;
3038*8975f5c5SAndroid Build Coastguard Worker                 }
3039*8975f5c5SAndroid Build Coastguard Worker                 break;
3040*8975f5c5SAndroid Build Coastguard Worker 
3041*8975f5c5SAndroid Build Coastguard Worker             default:
3042*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE);
3043*8975f5c5SAndroid Build Coastguard Worker                 return false;
3044*8975f5c5SAndroid Build Coastguard Worker         }
3045*8975f5c5SAndroid Build Coastguard Worker     }
3046*8975f5c5SAndroid Build Coastguard Worker 
3047*8975f5c5SAndroid Build Coastguard Worker     EGLAttrib colorspace = attributes.get(EGL_GL_COLORSPACE, EGL_GL_COLORSPACE_LINEAR);
3048*8975f5c5SAndroid Build Coastguard Worker     if (colorspace != EGL_GL_COLORSPACE_LINEAR && colorspace != EGL_GL_COLORSPACE_SRGB)
3049*8975f5c5SAndroid Build Coastguard Worker     {
3050*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_ATTRIBUTE, "invalid GL colorspace");
3051*8975f5c5SAndroid Build Coastguard Worker         return false;
3052*8975f5c5SAndroid Build Coastguard Worker     }
3053*8975f5c5SAndroid Build Coastguard Worker 
3054*8975f5c5SAndroid Build Coastguard Worker     if (!(config->surfaceType & EGL_PBUFFER_BIT))
3055*8975f5c5SAndroid Build Coastguard Worker     {
3056*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_MATCH);
3057*8975f5c5SAndroid Build Coastguard Worker         return false;
3058*8975f5c5SAndroid Build Coastguard Worker     }
3059*8975f5c5SAndroid Build Coastguard Worker 
3060*8975f5c5SAndroid Build Coastguard Worker     EGLAttrib textureFormat = attributes.get(EGL_TEXTURE_FORMAT, EGL_NO_TEXTURE);
3061*8975f5c5SAndroid Build Coastguard Worker     EGLAttrib textureTarget = attributes.get(EGL_TEXTURE_TARGET, EGL_NO_TEXTURE);
3062*8975f5c5SAndroid Build Coastguard Worker     if ((textureFormat != EGL_NO_TEXTURE && textureTarget == EGL_NO_TEXTURE) ||
3063*8975f5c5SAndroid Build Coastguard Worker         (textureFormat == EGL_NO_TEXTURE && textureTarget != EGL_NO_TEXTURE))
3064*8975f5c5SAndroid Build Coastguard Worker     {
3065*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_MATCH);
3066*8975f5c5SAndroid Build Coastguard Worker         return false;
3067*8975f5c5SAndroid Build Coastguard Worker     }
3068*8975f5c5SAndroid Build Coastguard Worker     if ((textureFormat == EGL_TEXTURE_RGB && config->bindToTextureRGB != EGL_TRUE) ||
3069*8975f5c5SAndroid Build Coastguard Worker         (textureFormat == EGL_TEXTURE_RGBA && config->bindToTextureRGBA != EGL_TRUE))
3070*8975f5c5SAndroid Build Coastguard Worker     {
3071*8975f5c5SAndroid Build Coastguard Worker         // TODO([email protected]): For IOSurface pbuffers we require that EGL_TEXTURE_RGBA is
3072*8975f5c5SAndroid Build Coastguard Worker         // set so that eglBindTexImage works. Normally this is only allowed if the config exposes
3073*8975f5c5SAndroid Build Coastguard Worker         // the bindToTextureRGB/RGBA flag. This issue is that enabling this flags means that
3074*8975f5c5SAndroid Build Coastguard Worker         // eglBindTexImage should also work for regular pbuffers which isn't implemented on macOS.
3075*8975f5c5SAndroid Build Coastguard Worker         // Instead of adding the flag we special case the check here to be ignored for IOSurfaces.
3076*8975f5c5SAndroid Build Coastguard Worker         // The TODO is to find a proper solution for this, maybe by implementing eglBindTexImage on
3077*8975f5c5SAndroid Build Coastguard Worker         // OSX?
3078*8975f5c5SAndroid Build Coastguard Worker         if (buftype != EGL_IOSURFACE_ANGLE)
3079*8975f5c5SAndroid Build Coastguard Worker         {
3080*8975f5c5SAndroid Build Coastguard Worker             val->setError(EGL_BAD_ATTRIBUTE);
3081*8975f5c5SAndroid Build Coastguard Worker             return false;
3082*8975f5c5SAndroid Build Coastguard Worker         }
3083*8975f5c5SAndroid Build Coastguard Worker     }
3084*8975f5c5SAndroid Build Coastguard Worker 
3085*8975f5c5SAndroid Build Coastguard Worker     if (buftype == EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE)
3086*8975f5c5SAndroid Build Coastguard Worker     {
3087*8975f5c5SAndroid Build Coastguard Worker         EGLint width  = static_cast<EGLint>(attributes.get(EGL_WIDTH, 0));
3088*8975f5c5SAndroid Build Coastguard Worker         EGLint height = static_cast<EGLint>(attributes.get(EGL_HEIGHT, 0));
3089*8975f5c5SAndroid Build Coastguard Worker 
3090*8975f5c5SAndroid Build Coastguard Worker         if (width == 0 || height == 0)
3091*8975f5c5SAndroid Build Coastguard Worker         {
3092*8975f5c5SAndroid Build Coastguard Worker             val->setError(EGL_BAD_ATTRIBUTE);
3093*8975f5c5SAndroid Build Coastguard Worker             return false;
3094*8975f5c5SAndroid Build Coastguard Worker         }
3095*8975f5c5SAndroid Build Coastguard Worker 
3096*8975f5c5SAndroid Build Coastguard Worker         const Caps &caps = display->getCaps();
3097*8975f5c5SAndroid Build Coastguard Worker         if (textureFormat != EGL_NO_TEXTURE && !caps.textureNPOT &&
3098*8975f5c5SAndroid Build Coastguard Worker             (!gl::isPow2(width) || !gl::isPow2(height)))
3099*8975f5c5SAndroid Build Coastguard Worker         {
3100*8975f5c5SAndroid Build Coastguard Worker             val->setError(EGL_BAD_MATCH);
3101*8975f5c5SAndroid Build Coastguard Worker             return false;
3102*8975f5c5SAndroid Build Coastguard Worker         }
3103*8975f5c5SAndroid Build Coastguard Worker     }
3104*8975f5c5SAndroid Build Coastguard Worker 
3105*8975f5c5SAndroid Build Coastguard Worker     if (buftype == EGL_IOSURFACE_ANGLE)
3106*8975f5c5SAndroid Build Coastguard Worker     {
3107*8975f5c5SAndroid Build Coastguard Worker         if (static_cast<EGLenum>(textureTarget) != config->bindToTextureTarget)
3108*8975f5c5SAndroid Build Coastguard Worker         {
3109*8975f5c5SAndroid Build Coastguard Worker             val->setError(EGL_BAD_ATTRIBUTE,
3110*8975f5c5SAndroid Build Coastguard Worker                           "EGL_IOSURFACE requires the texture target to match the config");
3111*8975f5c5SAndroid Build Coastguard Worker             return false;
3112*8975f5c5SAndroid Build Coastguard Worker         }
3113*8975f5c5SAndroid Build Coastguard Worker         if (textureFormat != EGL_TEXTURE_RGBA)
3114*8975f5c5SAndroid Build Coastguard Worker         {
3115*8975f5c5SAndroid Build Coastguard Worker             val->setError(EGL_BAD_ATTRIBUTE, "EGL_IOSURFACE requires the EGL_TEXTURE_RGBA format");
3116*8975f5c5SAndroid Build Coastguard Worker             return false;
3117*8975f5c5SAndroid Build Coastguard Worker         }
3118*8975f5c5SAndroid Build Coastguard Worker 
3119*8975f5c5SAndroid Build Coastguard Worker         if (!attributes.contains(EGL_WIDTH) || !attributes.contains(EGL_HEIGHT) ||
3120*8975f5c5SAndroid Build Coastguard Worker             !attributes.contains(EGL_TEXTURE_FORMAT) ||
3121*8975f5c5SAndroid Build Coastguard Worker             !attributes.contains(EGL_TEXTURE_TYPE_ANGLE) ||
3122*8975f5c5SAndroid Build Coastguard Worker             !attributes.contains(EGL_TEXTURE_INTERNAL_FORMAT_ANGLE) ||
3123*8975f5c5SAndroid Build Coastguard Worker             !attributes.contains(EGL_IOSURFACE_PLANE_ANGLE))
3124*8975f5c5SAndroid Build Coastguard Worker         {
3125*8975f5c5SAndroid Build Coastguard Worker             val->setError(EGL_BAD_PARAMETER, "Missing required attribute for EGL_IOSURFACE");
3126*8975f5c5SAndroid Build Coastguard Worker             return false;
3127*8975f5c5SAndroid Build Coastguard Worker         }
3128*8975f5c5SAndroid Build Coastguard Worker     }
3129*8975f5c5SAndroid Build Coastguard Worker 
3130*8975f5c5SAndroid Build Coastguard Worker     ANGLE_EGL_TRY_RETURN(val->eglThread,
3131*8975f5c5SAndroid Build Coastguard Worker                          display->validateClientBuffer(config, buftype, buffer, attributes),
3132*8975f5c5SAndroid Build Coastguard Worker                          val->entryPoint, val->labeledObject, false);
3133*8975f5c5SAndroid Build Coastguard Worker 
3134*8975f5c5SAndroid Build Coastguard Worker     return true;
3135*8975f5c5SAndroid Build Coastguard Worker }
3136*8975f5c5SAndroid Build Coastguard Worker 
ValidateCreatePixmapSurface(const ValidationContext * val,const Display * display,const Config * config,EGLNativePixmapType pixmap,const AttributeMap & attributes)3137*8975f5c5SAndroid Build Coastguard Worker bool ValidateCreatePixmapSurface(const ValidationContext *val,
3138*8975f5c5SAndroid Build Coastguard Worker                                  const Display *display,
3139*8975f5c5SAndroid Build Coastguard Worker                                  const Config *config,
3140*8975f5c5SAndroid Build Coastguard Worker                                  EGLNativePixmapType pixmap,
3141*8975f5c5SAndroid Build Coastguard Worker                                  const AttributeMap &attributes)
3142*8975f5c5SAndroid Build Coastguard Worker {
3143*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateConfig(val, display, config));
3144*8975f5c5SAndroid Build Coastguard Worker 
3145*8975f5c5SAndroid Build Coastguard Worker     const DisplayExtensions &displayExtensions = display->getExtensions();
3146*8975f5c5SAndroid Build Coastguard Worker 
3147*8975f5c5SAndroid Build Coastguard Worker     attributes.initializeWithoutValidation();
3148*8975f5c5SAndroid Build Coastguard Worker 
3149*8975f5c5SAndroid Build Coastguard Worker     for (const auto &attributePair : attributes)
3150*8975f5c5SAndroid Build Coastguard Worker     {
3151*8975f5c5SAndroid Build Coastguard Worker         EGLAttrib attribute = attributePair.first;
3152*8975f5c5SAndroid Build Coastguard Worker         EGLAttrib value     = attributePair.second;
3153*8975f5c5SAndroid Build Coastguard Worker 
3154*8975f5c5SAndroid Build Coastguard Worker         switch (attribute)
3155*8975f5c5SAndroid Build Coastguard Worker         {
3156*8975f5c5SAndroid Build Coastguard Worker             case EGL_GL_COLORSPACE:
3157*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_TRY(ValidateColorspaceAttribute(val, displayExtensions, value));
3158*8975f5c5SAndroid Build Coastguard Worker                 break;
3159*8975f5c5SAndroid Build Coastguard Worker 
3160*8975f5c5SAndroid Build Coastguard Worker             case EGL_VG_COLORSPACE:
3161*8975f5c5SAndroid Build Coastguard Worker                 break;
3162*8975f5c5SAndroid Build Coastguard Worker             case EGL_VG_ALPHA_FORMAT:
3163*8975f5c5SAndroid Build Coastguard Worker                 break;
3164*8975f5c5SAndroid Build Coastguard Worker 
3165*8975f5c5SAndroid Build Coastguard Worker             case EGL_TEXTURE_FORMAT:
3166*8975f5c5SAndroid Build Coastguard Worker                 if (!displayExtensions.textureFromPixmapNOK)
3167*8975f5c5SAndroid Build Coastguard Worker                 {
3168*8975f5c5SAndroid Build Coastguard Worker                     val->setError(EGL_BAD_ATTRIBUTE, "EGL_NOK_texture_from_pixmap is not enabled.");
3169*8975f5c5SAndroid Build Coastguard Worker                     return false;
3170*8975f5c5SAndroid Build Coastguard Worker                 }
3171*8975f5c5SAndroid Build Coastguard Worker                 switch (value)
3172*8975f5c5SAndroid Build Coastguard Worker                 {
3173*8975f5c5SAndroid Build Coastguard Worker                     case EGL_NO_TEXTURE:
3174*8975f5c5SAndroid Build Coastguard Worker                     case EGL_TEXTURE_RGB:
3175*8975f5c5SAndroid Build Coastguard Worker                     case EGL_TEXTURE_RGBA:
3176*8975f5c5SAndroid Build Coastguard Worker                         break;
3177*8975f5c5SAndroid Build Coastguard Worker                     default:
3178*8975f5c5SAndroid Build Coastguard Worker                         val->setError(EGL_BAD_ATTRIBUTE);
3179*8975f5c5SAndroid Build Coastguard Worker                         return false;
3180*8975f5c5SAndroid Build Coastguard Worker                 }
3181*8975f5c5SAndroid Build Coastguard Worker                 break;
3182*8975f5c5SAndroid Build Coastguard Worker 
3183*8975f5c5SAndroid Build Coastguard Worker             case EGL_TEXTURE_TARGET:
3184*8975f5c5SAndroid Build Coastguard Worker                 if (!displayExtensions.textureFromPixmapNOK)
3185*8975f5c5SAndroid Build Coastguard Worker                 {
3186*8975f5c5SAndroid Build Coastguard Worker                     val->setError(EGL_BAD_ATTRIBUTE, "EGL_NOK_texture_from_pixmap is not enabled.");
3187*8975f5c5SAndroid Build Coastguard Worker                     return false;
3188*8975f5c5SAndroid Build Coastguard Worker                 }
3189*8975f5c5SAndroid Build Coastguard Worker                 switch (value)
3190*8975f5c5SAndroid Build Coastguard Worker                 {
3191*8975f5c5SAndroid Build Coastguard Worker                     case EGL_NO_TEXTURE:
3192*8975f5c5SAndroid Build Coastguard Worker                     case EGL_TEXTURE_2D:
3193*8975f5c5SAndroid Build Coastguard Worker                         break;
3194*8975f5c5SAndroid Build Coastguard Worker                     default:
3195*8975f5c5SAndroid Build Coastguard Worker                         val->setError(EGL_BAD_ATTRIBUTE);
3196*8975f5c5SAndroid Build Coastguard Worker                         return false;
3197*8975f5c5SAndroid Build Coastguard Worker                 }
3198*8975f5c5SAndroid Build Coastguard Worker                 break;
3199*8975f5c5SAndroid Build Coastguard Worker 
3200*8975f5c5SAndroid Build Coastguard Worker             case EGL_MIPMAP_TEXTURE:
3201*8975f5c5SAndroid Build Coastguard Worker                 if (!displayExtensions.textureFromPixmapNOK)
3202*8975f5c5SAndroid Build Coastguard Worker                 {
3203*8975f5c5SAndroid Build Coastguard Worker                     val->setError(EGL_BAD_ATTRIBUTE, "EGL_NOK_texture_from_pixmap is not enabled.");
3204*8975f5c5SAndroid Build Coastguard Worker                     return false;
3205*8975f5c5SAndroid Build Coastguard Worker                 }
3206*8975f5c5SAndroid Build Coastguard Worker                 break;
3207*8975f5c5SAndroid Build Coastguard Worker 
3208*8975f5c5SAndroid Build Coastguard Worker             case EGL_PROTECTED_CONTENT_EXT:
3209*8975f5c5SAndroid Build Coastguard Worker                 if (!displayExtensions.protectedContentEXT)
3210*8975f5c5SAndroid Build Coastguard Worker                 {
3211*8975f5c5SAndroid Build Coastguard Worker                     val->setError(EGL_BAD_ATTRIBUTE,
3212*8975f5c5SAndroid Build Coastguard Worker                                   "Attribute EGL_PROTECTED_CONTEXT_EXT requires "
3213*8975f5c5SAndroid Build Coastguard Worker                                   "extension EGL_EXT_protected_content.");
3214*8975f5c5SAndroid Build Coastguard Worker                     return false;
3215*8975f5c5SAndroid Build Coastguard Worker                 }
3216*8975f5c5SAndroid Build Coastguard Worker                 if (value != EGL_TRUE && value != EGL_FALSE)
3217*8975f5c5SAndroid Build Coastguard Worker                 {
3218*8975f5c5SAndroid Build Coastguard Worker                     val->setError(EGL_BAD_ATTRIBUTE,
3219*8975f5c5SAndroid Build Coastguard Worker                                   "EGL_PROTECTED_CONTENT_EXT must "
3220*8975f5c5SAndroid Build Coastguard Worker                                   "be either EGL_TRUE or EGL_FALSE.");
3221*8975f5c5SAndroid Build Coastguard Worker                     return false;
3222*8975f5c5SAndroid Build Coastguard Worker                 }
3223*8975f5c5SAndroid Build Coastguard Worker                 break;
3224*8975f5c5SAndroid Build Coastguard Worker 
3225*8975f5c5SAndroid Build Coastguard Worker             default:
3226*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE, "Unknown attribute: 0x%04" PRIxPTR, attribute);
3227*8975f5c5SAndroid Build Coastguard Worker                 return false;
3228*8975f5c5SAndroid Build Coastguard Worker         }
3229*8975f5c5SAndroid Build Coastguard Worker     }
3230*8975f5c5SAndroid Build Coastguard Worker 
3231*8975f5c5SAndroid Build Coastguard Worker     if (!(config->surfaceType & EGL_PIXMAP_BIT))
3232*8975f5c5SAndroid Build Coastguard Worker     {
3233*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_MATCH, "Congfig does not suport pixmaps.");
3234*8975f5c5SAndroid Build Coastguard Worker         return false;
3235*8975f5c5SAndroid Build Coastguard Worker     }
3236*8975f5c5SAndroid Build Coastguard Worker 
3237*8975f5c5SAndroid Build Coastguard Worker     ANGLE_EGL_TRY_RETURN(val->eglThread, display->valdiatePixmap(config, pixmap, attributes),
3238*8975f5c5SAndroid Build Coastguard Worker                          val->entryPoint, val->labeledObject, false);
3239*8975f5c5SAndroid Build Coastguard Worker 
3240*8975f5c5SAndroid Build Coastguard Worker     return true;
3241*8975f5c5SAndroid Build Coastguard Worker }
3242*8975f5c5SAndroid Build Coastguard Worker 
ValidateMakeCurrent(const ValidationContext * val,const Display * display,SurfaceID drawSurfaceID,SurfaceID readSurfaceID,gl::ContextID contextID)3243*8975f5c5SAndroid Build Coastguard Worker bool ValidateMakeCurrent(const ValidationContext *val,
3244*8975f5c5SAndroid Build Coastguard Worker                          const Display *display,
3245*8975f5c5SAndroid Build Coastguard Worker                          SurfaceID drawSurfaceID,
3246*8975f5c5SAndroid Build Coastguard Worker                          SurfaceID readSurfaceID,
3247*8975f5c5SAndroid Build Coastguard Worker                          gl::ContextID contextID)
3248*8975f5c5SAndroid Build Coastguard Worker {
3249*8975f5c5SAndroid Build Coastguard Worker     bool noDraw    = drawSurfaceID.value == 0;
3250*8975f5c5SAndroid Build Coastguard Worker     bool noRead    = readSurfaceID.value == 0;
3251*8975f5c5SAndroid Build Coastguard Worker     bool noContext = contextID.value == 0;
3252*8975f5c5SAndroid Build Coastguard Worker 
3253*8975f5c5SAndroid Build Coastguard Worker     if (noContext && (!noDraw || !noRead))
3254*8975f5c5SAndroid Build Coastguard Worker     {
3255*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_MATCH, "If ctx is EGL_NO_CONTEXT, surfaces must be EGL_NO_SURFACE");
3256*8975f5c5SAndroid Build Coastguard Worker         return false;
3257*8975f5c5SAndroid Build Coastguard Worker     }
3258*8975f5c5SAndroid Build Coastguard Worker 
3259*8975f5c5SAndroid Build Coastguard Worker     // If ctx is EGL_NO_CONTEXT and either draw or read are not EGL_NO_SURFACE, an EGL_BAD_MATCH
3260*8975f5c5SAndroid Build Coastguard Worker     // error is generated. EGL_KHR_surfaceless_context allows both surfaces to be EGL_NO_SURFACE.
3261*8975f5c5SAndroid Build Coastguard Worker     if (!noContext && (noDraw || noRead))
3262*8975f5c5SAndroid Build Coastguard Worker     {
3263*8975f5c5SAndroid Build Coastguard Worker         if (display->getExtensions().surfacelessContext)
3264*8975f5c5SAndroid Build Coastguard Worker         {
3265*8975f5c5SAndroid Build Coastguard Worker             if (noDraw != noRead)
3266*8975f5c5SAndroid Build Coastguard Worker             {
3267*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_MATCH,
3268*8975f5c5SAndroid Build Coastguard Worker                               "If ctx is not EGL_NOT_CONTEXT, draw or read must "
3269*8975f5c5SAndroid Build Coastguard Worker                               "both be EGL_NO_SURFACE, or both not");
3270*8975f5c5SAndroid Build Coastguard Worker                 return false;
3271*8975f5c5SAndroid Build Coastguard Worker             }
3272*8975f5c5SAndroid Build Coastguard Worker         }
3273*8975f5c5SAndroid Build Coastguard Worker         else
3274*8975f5c5SAndroid Build Coastguard Worker         {
3275*8975f5c5SAndroid Build Coastguard Worker             val->setError(EGL_BAD_MATCH,
3276*8975f5c5SAndroid Build Coastguard Worker                           "If ctx is not EGL_NO_CONTEXT, surfaces must not be EGL_NO_SURFACE");
3277*8975f5c5SAndroid Build Coastguard Worker             return false;
3278*8975f5c5SAndroid Build Coastguard Worker         }
3279*8975f5c5SAndroid Build Coastguard Worker     }
3280*8975f5c5SAndroid Build Coastguard Worker 
3281*8975f5c5SAndroid Build Coastguard Worker     // If either of draw or read is a valid surface and the other is EGL_NO_SURFACE, an
3282*8975f5c5SAndroid Build Coastguard Worker     // EGL_BAD_MATCH error is generated.
3283*8975f5c5SAndroid Build Coastguard Worker     if (noRead != noDraw)
3284*8975f5c5SAndroid Build Coastguard Worker     {
3285*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_MATCH,
3286*8975f5c5SAndroid Build Coastguard Worker                       "read and draw must both be valid surfaces, or both be EGL_NO_SURFACE");
3287*8975f5c5SAndroid Build Coastguard Worker         return false;
3288*8975f5c5SAndroid Build Coastguard Worker     }
3289*8975f5c5SAndroid Build Coastguard Worker 
3290*8975f5c5SAndroid Build Coastguard Worker     if (display == EGL_NO_DISPLAY || !Display::isValidDisplay(display))
3291*8975f5c5SAndroid Build Coastguard Worker     {
3292*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_DISPLAY, "'dpy' not a valid EGLDisplay handle");
3293*8975f5c5SAndroid Build Coastguard Worker         return false;
3294*8975f5c5SAndroid Build Coastguard Worker     }
3295*8975f5c5SAndroid Build Coastguard Worker 
3296*8975f5c5SAndroid Build Coastguard Worker     // EGL 1.5 spec: dpy can be uninitialized if all other parameters are null
3297*8975f5c5SAndroid Build Coastguard Worker     if (!display->isInitialized() && (!noContext || !noDraw || !noRead))
3298*8975f5c5SAndroid Build Coastguard Worker     {
3299*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_NOT_INITIALIZED, "'dpy' not initialized");
3300*8975f5c5SAndroid Build Coastguard Worker         return false;
3301*8975f5c5SAndroid Build Coastguard Worker     }
3302*8975f5c5SAndroid Build Coastguard Worker 
3303*8975f5c5SAndroid Build Coastguard Worker     if (!noContext)
3304*8975f5c5SAndroid Build Coastguard Worker     {
3305*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_TRY(ValidateContext(val, display, contextID));
3306*8975f5c5SAndroid Build Coastguard Worker     }
3307*8975f5c5SAndroid Build Coastguard Worker 
3308*8975f5c5SAndroid Build Coastguard Worker     // Allow "un-make" the lost context:
3309*8975f5c5SAndroid Build Coastguard Worker     // If the context is lost, but EGLContext passed to eglMakeCurrent is EGL_NO_CONTEXT, we should
3310*8975f5c5SAndroid Build Coastguard Worker     // not return EGL_CONTEXT_LOST error code.
3311*8975f5c5SAndroid Build Coastguard Worker     if (display->isInitialized() && display->isDeviceLost() && !noContext)
3312*8975f5c5SAndroid Build Coastguard Worker     {
3313*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_CONTEXT_LOST);
3314*8975f5c5SAndroid Build Coastguard Worker         return false;
3315*8975f5c5SAndroid Build Coastguard Worker     }
3316*8975f5c5SAndroid Build Coastguard Worker 
3317*8975f5c5SAndroid Build Coastguard Worker     const Surface *drawSurface = GetSurfaceIfValid(display, drawSurfaceID);
3318*8975f5c5SAndroid Build Coastguard Worker     const Surface *readSurface = GetSurfaceIfValid(display, readSurfaceID);
3319*8975f5c5SAndroid Build Coastguard Worker     const gl::Context *context = GetContextIfValid(display, contextID);
3320*8975f5c5SAndroid Build Coastguard Worker 
3321*8975f5c5SAndroid Build Coastguard Worker     const gl::Context *previousContext = val->eglThread->getContext();
3322*8975f5c5SAndroid Build Coastguard Worker     if (!noContext && context->isReferenced() && context != previousContext)
3323*8975f5c5SAndroid Build Coastguard Worker     {
3324*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_ACCESS, "Context can only be current on one thread");
3325*8975f5c5SAndroid Build Coastguard Worker         return false;
3326*8975f5c5SAndroid Build Coastguard Worker     }
3327*8975f5c5SAndroid Build Coastguard Worker 
3328*8975f5c5SAndroid Build Coastguard Worker     if (!noRead)
3329*8975f5c5SAndroid Build Coastguard Worker     {
3330*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_TRY(ValidateSurface(val, display, readSurfaceID));
3331*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_TRY(ValidateCompatibleSurface(val, display, context, readSurface));
3332*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_TRY(ValidateSurfaceBadAccess(val, previousContext, readSurface));
3333*8975f5c5SAndroid Build Coastguard Worker     }
3334*8975f5c5SAndroid Build Coastguard Worker 
3335*8975f5c5SAndroid Build Coastguard Worker     if (drawSurface != readSurface && !noDraw)
3336*8975f5c5SAndroid Build Coastguard Worker     {
3337*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_TRY(ValidateSurface(val, display, drawSurfaceID));
3338*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_TRY(ValidateCompatibleSurface(val, display, context, drawSurface));
3339*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_TRY(ValidateSurfaceBadAccess(val, previousContext, drawSurface));
3340*8975f5c5SAndroid Build Coastguard Worker     }
3341*8975f5c5SAndroid Build Coastguard Worker     return true;
3342*8975f5c5SAndroid Build Coastguard Worker }
3343*8975f5c5SAndroid Build Coastguard Worker 
ValidateCreateImage(const ValidationContext * val,const Display * display,gl::ContextID contextID,EGLenum target,EGLClientBuffer buffer,const AttributeMap & attributes)3344*8975f5c5SAndroid Build Coastguard Worker bool ValidateCreateImage(const ValidationContext *val,
3345*8975f5c5SAndroid Build Coastguard Worker                          const Display *display,
3346*8975f5c5SAndroid Build Coastguard Worker                          gl::ContextID contextID,
3347*8975f5c5SAndroid Build Coastguard Worker                          EGLenum target,
3348*8975f5c5SAndroid Build Coastguard Worker                          EGLClientBuffer buffer,
3349*8975f5c5SAndroid Build Coastguard Worker                          const AttributeMap &attributes)
3350*8975f5c5SAndroid Build Coastguard Worker {
3351*8975f5c5SAndroid Build Coastguard Worker     const gl::Context *context = GetContextIfValid(display, contextID);
3352*8975f5c5SAndroid Build Coastguard Worker 
3353*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
3354*8975f5c5SAndroid Build Coastguard Worker 
3355*8975f5c5SAndroid Build Coastguard Worker     attributes.initializeWithoutValidation();
3356*8975f5c5SAndroid Build Coastguard Worker 
3357*8975f5c5SAndroid Build Coastguard Worker     const DisplayExtensions &displayExtensions = display->getExtensions();
3358*8975f5c5SAndroid Build Coastguard Worker 
3359*8975f5c5SAndroid Build Coastguard Worker     // TODO(geofflang): Complete validation from EGL_KHR_image_base:
3360*8975f5c5SAndroid Build Coastguard Worker     // If the resource specified by <dpy>, <ctx>, <target>, <buffer> and <attrib_list> is itself an
3361*8975f5c5SAndroid Build Coastguard Worker     // EGLImage sibling, the error EGL_BAD_ACCESS is generated.
3362*8975f5c5SAndroid Build Coastguard Worker 
3363*8975f5c5SAndroid Build Coastguard Worker     for (AttributeMap::const_iterator attributeIter = attributes.begin();
3364*8975f5c5SAndroid Build Coastguard Worker          attributeIter != attributes.end(); attributeIter++)
3365*8975f5c5SAndroid Build Coastguard Worker     {
3366*8975f5c5SAndroid Build Coastguard Worker         EGLAttrib attribute = attributeIter->first;
3367*8975f5c5SAndroid Build Coastguard Worker         EGLAttrib value     = attributeIter->second;
3368*8975f5c5SAndroid Build Coastguard Worker 
3369*8975f5c5SAndroid Build Coastguard Worker         switch (attribute)
3370*8975f5c5SAndroid Build Coastguard Worker         {
3371*8975f5c5SAndroid Build Coastguard Worker             case EGL_IMAGE_PRESERVED:
3372*8975f5c5SAndroid Build Coastguard Worker                 switch (value)
3373*8975f5c5SAndroid Build Coastguard Worker                 {
3374*8975f5c5SAndroid Build Coastguard Worker                     case EGL_TRUE:
3375*8975f5c5SAndroid Build Coastguard Worker                     case EGL_FALSE:
3376*8975f5c5SAndroid Build Coastguard Worker                         break;
3377*8975f5c5SAndroid Build Coastguard Worker 
3378*8975f5c5SAndroid Build Coastguard Worker                     default:
3379*8975f5c5SAndroid Build Coastguard Worker                         val->setError(EGL_BAD_PARAMETER,
3380*8975f5c5SAndroid Build Coastguard Worker                                       "EGL_IMAGE_PRESERVED must be EGL_TRUE or EGL_FALSE.");
3381*8975f5c5SAndroid Build Coastguard Worker                         return false;
3382*8975f5c5SAndroid Build Coastguard Worker                 }
3383*8975f5c5SAndroid Build Coastguard Worker                 break;
3384*8975f5c5SAndroid Build Coastguard Worker 
3385*8975f5c5SAndroid Build Coastguard Worker             case EGL_GL_TEXTURE_LEVEL:
3386*8975f5c5SAndroid Build Coastguard Worker                 if (!displayExtensions.glTexture2DImage &&
3387*8975f5c5SAndroid Build Coastguard Worker                     !displayExtensions.glTextureCubemapImage && !displayExtensions.glTexture3DImage)
3388*8975f5c5SAndroid Build Coastguard Worker                 {
3389*8975f5c5SAndroid Build Coastguard Worker                     val->setError(EGL_BAD_PARAMETER,
3390*8975f5c5SAndroid Build Coastguard Worker                                   "EGL_GL_TEXTURE_LEVEL cannot be used "
3391*8975f5c5SAndroid Build Coastguard Worker                                   "without KHR_gl_texture_*_image support.");
3392*8975f5c5SAndroid Build Coastguard Worker                     return false;
3393*8975f5c5SAndroid Build Coastguard Worker                 }
3394*8975f5c5SAndroid Build Coastguard Worker 
3395*8975f5c5SAndroid Build Coastguard Worker                 if (value < 0)
3396*8975f5c5SAndroid Build Coastguard Worker                 {
3397*8975f5c5SAndroid Build Coastguard Worker                     val->setError(EGL_BAD_PARAMETER, "EGL_GL_TEXTURE_LEVEL cannot be negative.");
3398*8975f5c5SAndroid Build Coastguard Worker                     return false;
3399*8975f5c5SAndroid Build Coastguard Worker                 }
3400*8975f5c5SAndroid Build Coastguard Worker                 break;
3401*8975f5c5SAndroid Build Coastguard Worker 
3402*8975f5c5SAndroid Build Coastguard Worker             case EGL_GL_TEXTURE_ZOFFSET:
3403*8975f5c5SAndroid Build Coastguard Worker                 if (!displayExtensions.glTexture3DImage)
3404*8975f5c5SAndroid Build Coastguard Worker                 {
3405*8975f5c5SAndroid Build Coastguard Worker                     val->setError(EGL_BAD_PARAMETER,
3406*8975f5c5SAndroid Build Coastguard Worker                                   "EGL_GL_TEXTURE_ZOFFSET cannot be used "
3407*8975f5c5SAndroid Build Coastguard Worker                                   "without KHR_gl_texture_3D_image support.");
3408*8975f5c5SAndroid Build Coastguard Worker                     return false;
3409*8975f5c5SAndroid Build Coastguard Worker                 }
3410*8975f5c5SAndroid Build Coastguard Worker                 break;
3411*8975f5c5SAndroid Build Coastguard Worker 
3412*8975f5c5SAndroid Build Coastguard Worker             case EGL_GL_COLORSPACE:
3413*8975f5c5SAndroid Build Coastguard Worker                 if (!displayExtensions.glColorspace)
3414*8975f5c5SAndroid Build Coastguard Worker                 {
3415*8975f5c5SAndroid Build Coastguard Worker                     val->setError(EGL_BAD_PARAMETER,
3416*8975f5c5SAndroid Build Coastguard Worker                                   "EGL_GL_COLORSPACE cannot be used "
3417*8975f5c5SAndroid Build Coastguard Worker                                   "without EGL_KHR_gl_colorspace support.");
3418*8975f5c5SAndroid Build Coastguard Worker                     return false;
3419*8975f5c5SAndroid Build Coastguard Worker                 }
3420*8975f5c5SAndroid Build Coastguard Worker                 switch (value)
3421*8975f5c5SAndroid Build Coastguard Worker                 {
3422*8975f5c5SAndroid Build Coastguard Worker                     case EGL_GL_COLORSPACE_DEFAULT_EXT:
3423*8975f5c5SAndroid Build Coastguard Worker                         break;
3424*8975f5c5SAndroid Build Coastguard Worker                     default:
3425*8975f5c5SAndroid Build Coastguard Worker                         ANGLE_VALIDATION_TRY(
3426*8975f5c5SAndroid Build Coastguard Worker                             ValidateColorspaceAttribute(val, displayExtensions, value));
3427*8975f5c5SAndroid Build Coastguard Worker                         break;
3428*8975f5c5SAndroid Build Coastguard Worker                 }
3429*8975f5c5SAndroid Build Coastguard Worker                 break;
3430*8975f5c5SAndroid Build Coastguard Worker 
3431*8975f5c5SAndroid Build Coastguard Worker             case EGL_TEXTURE_INTERNAL_FORMAT_ANGLE:
3432*8975f5c5SAndroid Build Coastguard Worker                 if (!displayExtensions.imageD3D11Texture && !displayExtensions.vulkanImageANGLE &&
3433*8975f5c5SAndroid Build Coastguard Worker                     !displayExtensions.mtlTextureClientBuffer)
3434*8975f5c5SAndroid Build Coastguard Worker                 {
3435*8975f5c5SAndroid Build Coastguard Worker                     val->setError(EGL_BAD_PARAMETER,
3436*8975f5c5SAndroid Build Coastguard Worker                                   "EGL_TEXTURE_INTERNAL_FORMAT_ANGLE cannot be used without "
3437*8975f5c5SAndroid Build Coastguard Worker                                   "EGL_ANGLE_image_d3d11_texture, EGL_ANGLE_vulkan_image, or "
3438*8975f5c5SAndroid Build Coastguard Worker                                   "EGL_ANGLE_metal_texture_client_buffer support.");
3439*8975f5c5SAndroid Build Coastguard Worker                     return false;
3440*8975f5c5SAndroid Build Coastguard Worker                 }
3441*8975f5c5SAndroid Build Coastguard Worker                 break;
3442*8975f5c5SAndroid Build Coastguard Worker 
3443*8975f5c5SAndroid Build Coastguard Worker             case EGL_D3D11_TEXTURE_PLANE_ANGLE:
3444*8975f5c5SAndroid Build Coastguard Worker                 if (!displayExtensions.imageD3D11Texture)
3445*8975f5c5SAndroid Build Coastguard Worker                 {
3446*8975f5c5SAndroid Build Coastguard Worker                     val->setError(EGL_BAD_ATTRIBUTE,
3447*8975f5c5SAndroid Build Coastguard Worker                                   "EGL_D3D11_TEXTURE_PLANE_ANGLE cannot be used without "
3448*8975f5c5SAndroid Build Coastguard Worker                                   "EGL_ANGLE_image_d3d11_texture support.");
3449*8975f5c5SAndroid Build Coastguard Worker                     return false;
3450*8975f5c5SAndroid Build Coastguard Worker                 }
3451*8975f5c5SAndroid Build Coastguard Worker                 break;
3452*8975f5c5SAndroid Build Coastguard Worker 
3453*8975f5c5SAndroid Build Coastguard Worker             case EGL_D3D11_TEXTURE_ARRAY_SLICE_ANGLE:
3454*8975f5c5SAndroid Build Coastguard Worker                 if (!displayExtensions.imageD3D11Texture)
3455*8975f5c5SAndroid Build Coastguard Worker                 {
3456*8975f5c5SAndroid Build Coastguard Worker                     val->setError(EGL_BAD_ATTRIBUTE,
3457*8975f5c5SAndroid Build Coastguard Worker                                   "EGL_D3D11_TEXTURE_ARRAY_SLICE_ANGLE cannot be used without "
3458*8975f5c5SAndroid Build Coastguard Worker                                   "EGL_ANGLE_image_d3d11_texture support.");
3459*8975f5c5SAndroid Build Coastguard Worker                     return false;
3460*8975f5c5SAndroid Build Coastguard Worker                 }
3461*8975f5c5SAndroid Build Coastguard Worker                 break;
3462*8975f5c5SAndroid Build Coastguard Worker             case EGL_METAL_TEXTURE_ARRAY_SLICE_ANGLE:
3463*8975f5c5SAndroid Build Coastguard Worker                 if (!displayExtensions.mtlTextureClientBuffer)
3464*8975f5c5SAndroid Build Coastguard Worker                 {
3465*8975f5c5SAndroid Build Coastguard Worker                     val->setError(EGL_BAD_ATTRIBUTE,
3466*8975f5c5SAndroid Build Coastguard Worker                                   "EGL_METAL_TEXTURE_ARRAY_SLICE_ANGLE cannot be used without "
3467*8975f5c5SAndroid Build Coastguard Worker                                   "EGL_ANGLE_metal_texture_client_buffer support.");
3468*8975f5c5SAndroid Build Coastguard Worker                     return false;
3469*8975f5c5SAndroid Build Coastguard Worker                 }
3470*8975f5c5SAndroid Build Coastguard Worker                 break;
3471*8975f5c5SAndroid Build Coastguard Worker 
3472*8975f5c5SAndroid Build Coastguard Worker             case EGL_WIDTH:
3473*8975f5c5SAndroid Build Coastguard Worker             case EGL_HEIGHT:
3474*8975f5c5SAndroid Build Coastguard Worker                 if (target != EGL_LINUX_DMA_BUF_EXT)
3475*8975f5c5SAndroid Build Coastguard Worker                 {
3476*8975f5c5SAndroid Build Coastguard Worker                     val->setError(
3477*8975f5c5SAndroid Build Coastguard Worker                         EGL_BAD_PARAMETER,
3478*8975f5c5SAndroid Build Coastguard Worker                         "Parameter cannot be used if target is not EGL_LINUX_DMA_BUF_EXT");
3479*8975f5c5SAndroid Build Coastguard Worker                     return false;
3480*8975f5c5SAndroid Build Coastguard Worker                 }
3481*8975f5c5SAndroid Build Coastguard Worker                 break;
3482*8975f5c5SAndroid Build Coastguard Worker 
3483*8975f5c5SAndroid Build Coastguard Worker             case EGL_LINUX_DRM_FOURCC_EXT:
3484*8975f5c5SAndroid Build Coastguard Worker             case EGL_DMA_BUF_PLANE0_FD_EXT:
3485*8975f5c5SAndroid Build Coastguard Worker             case EGL_DMA_BUF_PLANE0_OFFSET_EXT:
3486*8975f5c5SAndroid Build Coastguard Worker             case EGL_DMA_BUF_PLANE0_PITCH_EXT:
3487*8975f5c5SAndroid Build Coastguard Worker             case EGL_DMA_BUF_PLANE1_FD_EXT:
3488*8975f5c5SAndroid Build Coastguard Worker             case EGL_DMA_BUF_PLANE1_OFFSET_EXT:
3489*8975f5c5SAndroid Build Coastguard Worker             case EGL_DMA_BUF_PLANE1_PITCH_EXT:
3490*8975f5c5SAndroid Build Coastguard Worker             case EGL_DMA_BUF_PLANE2_FD_EXT:
3491*8975f5c5SAndroid Build Coastguard Worker             case EGL_DMA_BUF_PLANE2_OFFSET_EXT:
3492*8975f5c5SAndroid Build Coastguard Worker             case EGL_DMA_BUF_PLANE2_PITCH_EXT:
3493*8975f5c5SAndroid Build Coastguard Worker                 if (!displayExtensions.imageDmaBufImportEXT)
3494*8975f5c5SAndroid Build Coastguard Worker                 {
3495*8975f5c5SAndroid Build Coastguard Worker                     val->setError(EGL_BAD_PARAMETER,
3496*8975f5c5SAndroid Build Coastguard Worker                                   "Parameter cannot be used without "
3497*8975f5c5SAndroid Build Coastguard Worker                                   "EGL_EXT_image_dma_buf_import support.");
3498*8975f5c5SAndroid Build Coastguard Worker                     return false;
3499*8975f5c5SAndroid Build Coastguard Worker                 }
3500*8975f5c5SAndroid Build Coastguard Worker                 break;
3501*8975f5c5SAndroid Build Coastguard Worker 
3502*8975f5c5SAndroid Build Coastguard Worker             case EGL_YUV_COLOR_SPACE_HINT_EXT:
3503*8975f5c5SAndroid Build Coastguard Worker                 if (!displayExtensions.imageDmaBufImportEXT)
3504*8975f5c5SAndroid Build Coastguard Worker                 {
3505*8975f5c5SAndroid Build Coastguard Worker                     val->setError(EGL_BAD_PARAMETER,
3506*8975f5c5SAndroid Build Coastguard Worker                                   "Parameter cannot be used without "
3507*8975f5c5SAndroid Build Coastguard Worker                                   "EGL_EXT_image_dma_buf_import support.");
3508*8975f5c5SAndroid Build Coastguard Worker                     return false;
3509*8975f5c5SAndroid Build Coastguard Worker                 }
3510*8975f5c5SAndroid Build Coastguard Worker 
3511*8975f5c5SAndroid Build Coastguard Worker                 switch (value)
3512*8975f5c5SAndroid Build Coastguard Worker                 {
3513*8975f5c5SAndroid Build Coastguard Worker                     case EGL_ITU_REC601_EXT:
3514*8975f5c5SAndroid Build Coastguard Worker                     case EGL_ITU_REC709_EXT:
3515*8975f5c5SAndroid Build Coastguard Worker                     case EGL_ITU_REC2020_EXT:
3516*8975f5c5SAndroid Build Coastguard Worker                         break;
3517*8975f5c5SAndroid Build Coastguard Worker 
3518*8975f5c5SAndroid Build Coastguard Worker                     default:
3519*8975f5c5SAndroid Build Coastguard Worker                         val->setError(EGL_BAD_PARAMETER,
3520*8975f5c5SAndroid Build Coastguard Worker                                       "Invalid value for EGL_YUV_COLOR_SPACE_HINT_EXT.");
3521*8975f5c5SAndroid Build Coastguard Worker                         return false;
3522*8975f5c5SAndroid Build Coastguard Worker                 }
3523*8975f5c5SAndroid Build Coastguard Worker                 break;
3524*8975f5c5SAndroid Build Coastguard Worker 
3525*8975f5c5SAndroid Build Coastguard Worker             case EGL_SAMPLE_RANGE_HINT_EXT:
3526*8975f5c5SAndroid Build Coastguard Worker                 if (!displayExtensions.imageDmaBufImportEXT)
3527*8975f5c5SAndroid Build Coastguard Worker                 {
3528*8975f5c5SAndroid Build Coastguard Worker                     val->setError(EGL_BAD_PARAMETER,
3529*8975f5c5SAndroid Build Coastguard Worker                                   "Parameter cannot be used without "
3530*8975f5c5SAndroid Build Coastguard Worker                                   "EGL_EXT_image_dma_buf_import support.");
3531*8975f5c5SAndroid Build Coastguard Worker                     return false;
3532*8975f5c5SAndroid Build Coastguard Worker                 }
3533*8975f5c5SAndroid Build Coastguard Worker 
3534*8975f5c5SAndroid Build Coastguard Worker                 switch (value)
3535*8975f5c5SAndroid Build Coastguard Worker                 {
3536*8975f5c5SAndroid Build Coastguard Worker                     case EGL_YUV_FULL_RANGE_EXT:
3537*8975f5c5SAndroid Build Coastguard Worker                     case EGL_YUV_NARROW_RANGE_EXT:
3538*8975f5c5SAndroid Build Coastguard Worker                         break;
3539*8975f5c5SAndroid Build Coastguard Worker 
3540*8975f5c5SAndroid Build Coastguard Worker                     default:
3541*8975f5c5SAndroid Build Coastguard Worker                         val->setError(EGL_BAD_PARAMETER,
3542*8975f5c5SAndroid Build Coastguard Worker                                       "Invalid value for EGL_SAMPLE_RANGE_HINT_EXT.");
3543*8975f5c5SAndroid Build Coastguard Worker                         return false;
3544*8975f5c5SAndroid Build Coastguard Worker                 }
3545*8975f5c5SAndroid Build Coastguard Worker                 break;
3546*8975f5c5SAndroid Build Coastguard Worker 
3547*8975f5c5SAndroid Build Coastguard Worker             case EGL_YUV_CHROMA_HORIZONTAL_SITING_HINT_EXT:
3548*8975f5c5SAndroid Build Coastguard Worker             case EGL_YUV_CHROMA_VERTICAL_SITING_HINT_EXT:
3549*8975f5c5SAndroid Build Coastguard Worker                 if (!displayExtensions.imageDmaBufImportEXT)
3550*8975f5c5SAndroid Build Coastguard Worker                 {
3551*8975f5c5SAndroid Build Coastguard Worker                     val->setError(EGL_BAD_PARAMETER,
3552*8975f5c5SAndroid Build Coastguard Worker                                   "Parameter cannot be used without "
3553*8975f5c5SAndroid Build Coastguard Worker                                   "EGL_EXT_image_dma_buf_import support.");
3554*8975f5c5SAndroid Build Coastguard Worker                     return false;
3555*8975f5c5SAndroid Build Coastguard Worker                 }
3556*8975f5c5SAndroid Build Coastguard Worker 
3557*8975f5c5SAndroid Build Coastguard Worker                 switch (value)
3558*8975f5c5SAndroid Build Coastguard Worker                 {
3559*8975f5c5SAndroid Build Coastguard Worker                     case EGL_YUV_CHROMA_SITING_0_EXT:
3560*8975f5c5SAndroid Build Coastguard Worker                     case EGL_YUV_CHROMA_SITING_0_5_EXT:
3561*8975f5c5SAndroid Build Coastguard Worker                         break;
3562*8975f5c5SAndroid Build Coastguard Worker 
3563*8975f5c5SAndroid Build Coastguard Worker                     default:
3564*8975f5c5SAndroid Build Coastguard Worker                         val->setError(
3565*8975f5c5SAndroid Build Coastguard Worker                             EGL_BAD_PARAMETER,
3566*8975f5c5SAndroid Build Coastguard Worker                             "Invalid value for EGL_YUV_CHROMA_HORIZONTAL_SITING_HINT_EXT or "
3567*8975f5c5SAndroid Build Coastguard Worker                             "EGL_YUV_CHROMA_VERTICAL_SITING_HINT_EXT.");
3568*8975f5c5SAndroid Build Coastguard Worker                         return false;
3569*8975f5c5SAndroid Build Coastguard Worker                 }
3570*8975f5c5SAndroid Build Coastguard Worker                 break;
3571*8975f5c5SAndroid Build Coastguard Worker 
3572*8975f5c5SAndroid Build Coastguard Worker             case EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT:
3573*8975f5c5SAndroid Build Coastguard Worker             case EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT:
3574*8975f5c5SAndroid Build Coastguard Worker             case EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT:
3575*8975f5c5SAndroid Build Coastguard Worker             case EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT:
3576*8975f5c5SAndroid Build Coastguard Worker             case EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT:
3577*8975f5c5SAndroid Build Coastguard Worker             case EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT:
3578*8975f5c5SAndroid Build Coastguard Worker             case EGL_DMA_BUF_PLANE3_FD_EXT:
3579*8975f5c5SAndroid Build Coastguard Worker             case EGL_DMA_BUF_PLANE3_OFFSET_EXT:
3580*8975f5c5SAndroid Build Coastguard Worker             case EGL_DMA_BUF_PLANE3_PITCH_EXT:
3581*8975f5c5SAndroid Build Coastguard Worker             case EGL_DMA_BUF_PLANE3_MODIFIER_LO_EXT:
3582*8975f5c5SAndroid Build Coastguard Worker             case EGL_DMA_BUF_PLANE3_MODIFIER_HI_EXT:
3583*8975f5c5SAndroid Build Coastguard Worker                 if (!displayExtensions.imageDmaBufImportModifiersEXT)
3584*8975f5c5SAndroid Build Coastguard Worker                 {
3585*8975f5c5SAndroid Build Coastguard Worker                     val->setError(EGL_BAD_PARAMETER,
3586*8975f5c5SAndroid Build Coastguard Worker                                   "Parameter cannot be used without "
3587*8975f5c5SAndroid Build Coastguard Worker                                   "EGL_EXT_image_dma_buf_import_modifiers support.");
3588*8975f5c5SAndroid Build Coastguard Worker                     return false;
3589*8975f5c5SAndroid Build Coastguard Worker                 }
3590*8975f5c5SAndroid Build Coastguard Worker                 break;
3591*8975f5c5SAndroid Build Coastguard Worker 
3592*8975f5c5SAndroid Build Coastguard Worker             case EGL_PROTECTED_CONTENT_EXT:
3593*8975f5c5SAndroid Build Coastguard Worker                 if (!displayExtensions.protectedContentEXT)
3594*8975f5c5SAndroid Build Coastguard Worker                 {
3595*8975f5c5SAndroid Build Coastguard Worker                     val->setError(EGL_BAD_ATTRIBUTE,
3596*8975f5c5SAndroid Build Coastguard Worker                                   "Attribute EGL_PROTECTED_CONTEXT_EXT requires "
3597*8975f5c5SAndroid Build Coastguard Worker                                   "extension EGL_EXT_protected_content.");
3598*8975f5c5SAndroid Build Coastguard Worker                     return false;
3599*8975f5c5SAndroid Build Coastguard Worker                 }
3600*8975f5c5SAndroid Build Coastguard Worker                 if (value != EGL_TRUE && value != EGL_FALSE)
3601*8975f5c5SAndroid Build Coastguard Worker                 {
3602*8975f5c5SAndroid Build Coastguard Worker                     val->setError(EGL_BAD_ATTRIBUTE,
3603*8975f5c5SAndroid Build Coastguard Worker                                   "EGL_PROTECTED_CONTENT_EXT must "
3604*8975f5c5SAndroid Build Coastguard Worker                                   "be either EGL_TRUE or EGL_FALSE.");
3605*8975f5c5SAndroid Build Coastguard Worker                     return false;
3606*8975f5c5SAndroid Build Coastguard Worker                 }
3607*8975f5c5SAndroid Build Coastguard Worker                 break;
3608*8975f5c5SAndroid Build Coastguard Worker 
3609*8975f5c5SAndroid Build Coastguard Worker             case EGL_VULKAN_IMAGE_CREATE_INFO_HI_ANGLE:
3610*8975f5c5SAndroid Build Coastguard Worker             case EGL_VULKAN_IMAGE_CREATE_INFO_LO_ANGLE:
3611*8975f5c5SAndroid Build Coastguard Worker                 if (!displayExtensions.vulkanImageANGLE)
3612*8975f5c5SAndroid Build Coastguard Worker                 {
3613*8975f5c5SAndroid Build Coastguard Worker                     val->setError(EGL_BAD_ATTRIBUTE,
3614*8975f5c5SAndroid Build Coastguard Worker                                   "Attribute EGL_VULKAN_IMAGE_CREATE_INFO_{HI,LO}_ANGLE require "
3615*8975f5c5SAndroid Build Coastguard Worker                                   "extension EGL_ANGLE_vulkan_image.");
3616*8975f5c5SAndroid Build Coastguard Worker                     return false;
3617*8975f5c5SAndroid Build Coastguard Worker                 }
3618*8975f5c5SAndroid Build Coastguard Worker                 break;
3619*8975f5c5SAndroid Build Coastguard Worker 
3620*8975f5c5SAndroid Build Coastguard Worker             default:
3621*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_PARAMETER, "invalid attribute: 0x%04" PRIxPTR "X", attribute);
3622*8975f5c5SAndroid Build Coastguard Worker                 return false;
3623*8975f5c5SAndroid Build Coastguard Worker         }
3624*8975f5c5SAndroid Build Coastguard Worker     }
3625*8975f5c5SAndroid Build Coastguard Worker 
3626*8975f5c5SAndroid Build Coastguard Worker     switch (target)
3627*8975f5c5SAndroid Build Coastguard Worker     {
3628*8975f5c5SAndroid Build Coastguard Worker         case EGL_GL_TEXTURE_2D:
3629*8975f5c5SAndroid Build Coastguard Worker         {
3630*8975f5c5SAndroid Build Coastguard Worker             if (!displayExtensions.glTexture2DImage)
3631*8975f5c5SAndroid Build Coastguard Worker             {
3632*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_PARAMETER, "KHR_gl_texture_2D_image not supported.");
3633*8975f5c5SAndroid Build Coastguard Worker                 return false;
3634*8975f5c5SAndroid Build Coastguard Worker             }
3635*8975f5c5SAndroid Build Coastguard Worker 
3636*8975f5c5SAndroid Build Coastguard Worker             if (buffer == 0)
3637*8975f5c5SAndroid Build Coastguard Worker             {
3638*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_PARAMETER,
3639*8975f5c5SAndroid Build Coastguard Worker                               "buffer cannot reference a 2D texture with the name 0.");
3640*8975f5c5SAndroid Build Coastguard Worker                 return false;
3641*8975f5c5SAndroid Build Coastguard Worker             }
3642*8975f5c5SAndroid Build Coastguard Worker 
3643*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_TRY(ValidateContext(val, display, contextID));
3644*8975f5c5SAndroid Build Coastguard Worker             const gl::Texture *texture =
3645*8975f5c5SAndroid Build Coastguard Worker                 context->getTexture({egl_gl::EGLClientBufferToGLObjectHandle(buffer)});
3646*8975f5c5SAndroid Build Coastguard Worker             if (texture == nullptr || texture->getType() != gl::TextureType::_2D)
3647*8975f5c5SAndroid Build Coastguard Worker             {
3648*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_PARAMETER, "target is not a 2D texture.");
3649*8975f5c5SAndroid Build Coastguard Worker                 return false;
3650*8975f5c5SAndroid Build Coastguard Worker             }
3651*8975f5c5SAndroid Build Coastguard Worker 
3652*8975f5c5SAndroid Build Coastguard Worker             if (texture->getBoundSurface() != nullptr)
3653*8975f5c5SAndroid Build Coastguard Worker             {
3654*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ACCESS, "texture has a surface bound to it.");
3655*8975f5c5SAndroid Build Coastguard Worker                 return false;
3656*8975f5c5SAndroid Build Coastguard Worker             }
3657*8975f5c5SAndroid Build Coastguard Worker 
3658*8975f5c5SAndroid Build Coastguard Worker             EGLAttrib level = attributes.get(EGL_GL_TEXTURE_LEVEL, 0);
3659*8975f5c5SAndroid Build Coastguard Worker             if (texture->getWidth(gl::TextureTarget::_2D, static_cast<size_t>(level)) == 0 ||
3660*8975f5c5SAndroid Build Coastguard Worker                 texture->getHeight(gl::TextureTarget::_2D, static_cast<size_t>(level)) == 0)
3661*8975f5c5SAndroid Build Coastguard Worker             {
3662*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_PARAMETER,
3663*8975f5c5SAndroid Build Coastguard Worker                               "target 2D texture does not have a valid size at specified level.");
3664*8975f5c5SAndroid Build Coastguard Worker                 return false;
3665*8975f5c5SAndroid Build Coastguard Worker             }
3666*8975f5c5SAndroid Build Coastguard Worker 
3667*8975f5c5SAndroid Build Coastguard Worker             bool protectedContentAttrib =
3668*8975f5c5SAndroid Build Coastguard Worker                 (attributes.getAsInt(EGL_PROTECTED_CONTENT_EXT, EGL_FALSE) != EGL_FALSE);
3669*8975f5c5SAndroid Build Coastguard Worker             if (protectedContentAttrib != texture->hasProtectedContent())
3670*8975f5c5SAndroid Build Coastguard Worker             {
3671*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_PARAMETER,
3672*8975f5c5SAndroid Build Coastguard Worker                               "EGL_PROTECTED_CONTENT_EXT attribute does not match protected state "
3673*8975f5c5SAndroid Build Coastguard Worker                               "of target.");
3674*8975f5c5SAndroid Build Coastguard Worker                 return false;
3675*8975f5c5SAndroid Build Coastguard Worker             }
3676*8975f5c5SAndroid Build Coastguard Worker 
3677*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_TRY(ValidateCreateImageMipLevelCommon(val, context, texture, level));
3678*8975f5c5SAndroid Build Coastguard Worker         }
3679*8975f5c5SAndroid Build Coastguard Worker         break;
3680*8975f5c5SAndroid Build Coastguard Worker 
3681*8975f5c5SAndroid Build Coastguard Worker         case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X:
3682*8975f5c5SAndroid Build Coastguard Worker         case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
3683*8975f5c5SAndroid Build Coastguard Worker         case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
3684*8975f5c5SAndroid Build Coastguard Worker         case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
3685*8975f5c5SAndroid Build Coastguard Worker         case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
3686*8975f5c5SAndroid Build Coastguard Worker         case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
3687*8975f5c5SAndroid Build Coastguard Worker         {
3688*8975f5c5SAndroid Build Coastguard Worker             if (!displayExtensions.glTextureCubemapImage)
3689*8975f5c5SAndroid Build Coastguard Worker             {
3690*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_PARAMETER, "KHR_gl_texture_cubemap_image not supported.");
3691*8975f5c5SAndroid Build Coastguard Worker                 return false;
3692*8975f5c5SAndroid Build Coastguard Worker             }
3693*8975f5c5SAndroid Build Coastguard Worker 
3694*8975f5c5SAndroid Build Coastguard Worker             if (buffer == 0)
3695*8975f5c5SAndroid Build Coastguard Worker             {
3696*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_PARAMETER,
3697*8975f5c5SAndroid Build Coastguard Worker                               "buffer cannot reference a cubemap texture with the name 0.");
3698*8975f5c5SAndroid Build Coastguard Worker                 return false;
3699*8975f5c5SAndroid Build Coastguard Worker             }
3700*8975f5c5SAndroid Build Coastguard Worker 
3701*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_TRY(ValidateContext(val, display, contextID));
3702*8975f5c5SAndroid Build Coastguard Worker             const gl::Texture *texture =
3703*8975f5c5SAndroid Build Coastguard Worker                 context->getTexture({egl_gl::EGLClientBufferToGLObjectHandle(buffer)});
3704*8975f5c5SAndroid Build Coastguard Worker             if (texture == nullptr || texture->getType() != gl::TextureType::CubeMap)
3705*8975f5c5SAndroid Build Coastguard Worker             {
3706*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_PARAMETER, "target is not a cubemap texture.");
3707*8975f5c5SAndroid Build Coastguard Worker                 return false;
3708*8975f5c5SAndroid Build Coastguard Worker             }
3709*8975f5c5SAndroid Build Coastguard Worker 
3710*8975f5c5SAndroid Build Coastguard Worker             if (texture->getBoundSurface() != nullptr)
3711*8975f5c5SAndroid Build Coastguard Worker             {
3712*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ACCESS, "texture has a surface bound to it.");
3713*8975f5c5SAndroid Build Coastguard Worker                 return false;
3714*8975f5c5SAndroid Build Coastguard Worker             }
3715*8975f5c5SAndroid Build Coastguard Worker 
3716*8975f5c5SAndroid Build Coastguard Worker             EGLAttrib level               = attributes.get(EGL_GL_TEXTURE_LEVEL, 0);
3717*8975f5c5SAndroid Build Coastguard Worker             gl::TextureTarget cubeMapFace = egl_gl::EGLCubeMapTargetToCubeMapTarget(target);
3718*8975f5c5SAndroid Build Coastguard Worker             if (texture->getWidth(cubeMapFace, static_cast<size_t>(level)) == 0 ||
3719*8975f5c5SAndroid Build Coastguard Worker                 texture->getHeight(cubeMapFace, static_cast<size_t>(level)) == 0)
3720*8975f5c5SAndroid Build Coastguard Worker             {
3721*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_PARAMETER,
3722*8975f5c5SAndroid Build Coastguard Worker                               "target cubemap texture does not have a valid "
3723*8975f5c5SAndroid Build Coastguard Worker                               "size at specified level and face.");
3724*8975f5c5SAndroid Build Coastguard Worker                 return false;
3725*8975f5c5SAndroid Build Coastguard Worker             }
3726*8975f5c5SAndroid Build Coastguard Worker 
3727*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_TRY(ValidateCreateImageMipLevelCommon(val, context, texture, level));
3728*8975f5c5SAndroid Build Coastguard Worker 
3729*8975f5c5SAndroid Build Coastguard Worker             if (level == 0 && !texture->isMipmapComplete() &&
3730*8975f5c5SAndroid Build Coastguard Worker                 CubeTextureHasUnspecifiedLevel0Face(texture))
3731*8975f5c5SAndroid Build Coastguard Worker             {
3732*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_PARAMETER,
3733*8975f5c5SAndroid Build Coastguard Worker                               "if level is zero and the texture is incomplete, "
3734*8975f5c5SAndroid Build Coastguard Worker                               "it must have all of its faces specified at level "
3735*8975f5c5SAndroid Build Coastguard Worker                               "zero.");
3736*8975f5c5SAndroid Build Coastguard Worker                 return false;
3737*8975f5c5SAndroid Build Coastguard Worker             }
3738*8975f5c5SAndroid Build Coastguard Worker 
3739*8975f5c5SAndroid Build Coastguard Worker             bool protectedContentAttrib =
3740*8975f5c5SAndroid Build Coastguard Worker                 (attributes.getAsInt(EGL_PROTECTED_CONTENT_EXT, EGL_FALSE) != EGL_FALSE);
3741*8975f5c5SAndroid Build Coastguard Worker             if (protectedContentAttrib != texture->hasProtectedContent())
3742*8975f5c5SAndroid Build Coastguard Worker             {
3743*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_PARAMETER,
3744*8975f5c5SAndroid Build Coastguard Worker                               "EGL_PROTECTED_CONTENT_EXT attribute does not match protected state "
3745*8975f5c5SAndroid Build Coastguard Worker                               "of target.");
3746*8975f5c5SAndroid Build Coastguard Worker                 return false;
3747*8975f5c5SAndroid Build Coastguard Worker             }
3748*8975f5c5SAndroid Build Coastguard Worker         }
3749*8975f5c5SAndroid Build Coastguard Worker         break;
3750*8975f5c5SAndroid Build Coastguard Worker 
3751*8975f5c5SAndroid Build Coastguard Worker         case EGL_GL_TEXTURE_3D:
3752*8975f5c5SAndroid Build Coastguard Worker         {
3753*8975f5c5SAndroid Build Coastguard Worker             if (!displayExtensions.glTexture3DImage)
3754*8975f5c5SAndroid Build Coastguard Worker             {
3755*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_PARAMETER, "KHR_gl_texture_3D_image not supported.");
3756*8975f5c5SAndroid Build Coastguard Worker                 return false;
3757*8975f5c5SAndroid Build Coastguard Worker             }
3758*8975f5c5SAndroid Build Coastguard Worker 
3759*8975f5c5SAndroid Build Coastguard Worker             if (buffer == 0)
3760*8975f5c5SAndroid Build Coastguard Worker             {
3761*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_PARAMETER,
3762*8975f5c5SAndroid Build Coastguard Worker                               "buffer cannot reference a 3D texture with the name 0.");
3763*8975f5c5SAndroid Build Coastguard Worker                 return false;
3764*8975f5c5SAndroid Build Coastguard Worker             }
3765*8975f5c5SAndroid Build Coastguard Worker 
3766*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_TRY(ValidateContext(val, display, contextID));
3767*8975f5c5SAndroid Build Coastguard Worker             const gl::Texture *texture =
3768*8975f5c5SAndroid Build Coastguard Worker                 context->getTexture({egl_gl::EGLClientBufferToGLObjectHandle(buffer)});
3769*8975f5c5SAndroid Build Coastguard Worker             if (texture == nullptr || texture->getType() != gl::TextureType::_3D)
3770*8975f5c5SAndroid Build Coastguard Worker             {
3771*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_PARAMETER, "target is not a 3D texture.");
3772*8975f5c5SAndroid Build Coastguard Worker                 return false;
3773*8975f5c5SAndroid Build Coastguard Worker             }
3774*8975f5c5SAndroid Build Coastguard Worker 
3775*8975f5c5SAndroid Build Coastguard Worker             if (texture->getBoundSurface() != nullptr)
3776*8975f5c5SAndroid Build Coastguard Worker             {
3777*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ACCESS, "texture has a surface bound to it.");
3778*8975f5c5SAndroid Build Coastguard Worker                 return false;
3779*8975f5c5SAndroid Build Coastguard Worker             }
3780*8975f5c5SAndroid Build Coastguard Worker 
3781*8975f5c5SAndroid Build Coastguard Worker             EGLAttrib level   = attributes.get(EGL_GL_TEXTURE_LEVEL, 0);
3782*8975f5c5SAndroid Build Coastguard Worker             EGLAttrib zOffset = attributes.get(EGL_GL_TEXTURE_ZOFFSET, 0);
3783*8975f5c5SAndroid Build Coastguard Worker             if (texture->getWidth(gl::TextureTarget::_3D, static_cast<size_t>(level)) == 0 ||
3784*8975f5c5SAndroid Build Coastguard Worker                 texture->getHeight(gl::TextureTarget::_3D, static_cast<size_t>(level)) == 0 ||
3785*8975f5c5SAndroid Build Coastguard Worker                 texture->getDepth(gl::TextureTarget::_3D, static_cast<size_t>(level)) == 0)
3786*8975f5c5SAndroid Build Coastguard Worker             {
3787*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_PARAMETER,
3788*8975f5c5SAndroid Build Coastguard Worker                               "target 3D texture does not have a valid size at specified level.");
3789*8975f5c5SAndroid Build Coastguard Worker                 return false;
3790*8975f5c5SAndroid Build Coastguard Worker             }
3791*8975f5c5SAndroid Build Coastguard Worker 
3792*8975f5c5SAndroid Build Coastguard Worker             if (static_cast<size_t>(zOffset) >=
3793*8975f5c5SAndroid Build Coastguard Worker                 texture->getDepth(gl::TextureTarget::_3D, static_cast<size_t>(level)))
3794*8975f5c5SAndroid Build Coastguard Worker             {
3795*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_PARAMETER,
3796*8975f5c5SAndroid Build Coastguard Worker                               "target 3D texture does not have enough layers "
3797*8975f5c5SAndroid Build Coastguard Worker                               "for the specified Z offset at the specified "
3798*8975f5c5SAndroid Build Coastguard Worker                               "level.");
3799*8975f5c5SAndroid Build Coastguard Worker                 return false;
3800*8975f5c5SAndroid Build Coastguard Worker             }
3801*8975f5c5SAndroid Build Coastguard Worker 
3802*8975f5c5SAndroid Build Coastguard Worker             bool protectedContentAttrib =
3803*8975f5c5SAndroid Build Coastguard Worker                 (attributes.getAsInt(EGL_PROTECTED_CONTENT_EXT, EGL_FALSE) != EGL_FALSE);
3804*8975f5c5SAndroid Build Coastguard Worker             if (protectedContentAttrib != texture->hasProtectedContent())
3805*8975f5c5SAndroid Build Coastguard Worker             {
3806*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_PARAMETER,
3807*8975f5c5SAndroid Build Coastguard Worker                               "EGL_PROTECTED_CONTENT_EXT attribute does not match protected state "
3808*8975f5c5SAndroid Build Coastguard Worker                               "of target.");
3809*8975f5c5SAndroid Build Coastguard Worker                 return false;
3810*8975f5c5SAndroid Build Coastguard Worker             }
3811*8975f5c5SAndroid Build Coastguard Worker 
3812*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_TRY(ValidateCreateImageMipLevelCommon(val, context, texture, level));
3813*8975f5c5SAndroid Build Coastguard Worker         }
3814*8975f5c5SAndroid Build Coastguard Worker         break;
3815*8975f5c5SAndroid Build Coastguard Worker 
3816*8975f5c5SAndroid Build Coastguard Worker         case EGL_GL_RENDERBUFFER:
3817*8975f5c5SAndroid Build Coastguard Worker         {
3818*8975f5c5SAndroid Build Coastguard Worker             if (!displayExtensions.glRenderbufferImage)
3819*8975f5c5SAndroid Build Coastguard Worker             {
3820*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_PARAMETER, "KHR_gl_renderbuffer_image not supported.");
3821*8975f5c5SAndroid Build Coastguard Worker                 return false;
3822*8975f5c5SAndroid Build Coastguard Worker             }
3823*8975f5c5SAndroid Build Coastguard Worker 
3824*8975f5c5SAndroid Build Coastguard Worker             if (attributes.contains(EGL_GL_TEXTURE_LEVEL))
3825*8975f5c5SAndroid Build Coastguard Worker             {
3826*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_PARAMETER,
3827*8975f5c5SAndroid Build Coastguard Worker                               "EGL_GL_TEXTURE_LEVEL cannot be used in "
3828*8975f5c5SAndroid Build Coastguard Worker                               "conjunction with a renderbuffer target.");
3829*8975f5c5SAndroid Build Coastguard Worker                 return false;
3830*8975f5c5SAndroid Build Coastguard Worker             }
3831*8975f5c5SAndroid Build Coastguard Worker 
3832*8975f5c5SAndroid Build Coastguard Worker             if (buffer == 0)
3833*8975f5c5SAndroid Build Coastguard Worker             {
3834*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_PARAMETER,
3835*8975f5c5SAndroid Build Coastguard Worker                               "buffer cannot reference a renderbuffer with the name 0.");
3836*8975f5c5SAndroid Build Coastguard Worker                 return false;
3837*8975f5c5SAndroid Build Coastguard Worker             }
3838*8975f5c5SAndroid Build Coastguard Worker 
3839*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_TRY(ValidateContext(val, display, contextID));
3840*8975f5c5SAndroid Build Coastguard Worker             const gl::Renderbuffer *renderbuffer =
3841*8975f5c5SAndroid Build Coastguard Worker                 context->getRenderbuffer({egl_gl::EGLClientBufferToGLObjectHandle(buffer)});
3842*8975f5c5SAndroid Build Coastguard Worker             if (renderbuffer == nullptr)
3843*8975f5c5SAndroid Build Coastguard Worker             {
3844*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_PARAMETER, "target is not a renderbuffer.");
3845*8975f5c5SAndroid Build Coastguard Worker                 return false;
3846*8975f5c5SAndroid Build Coastguard Worker             }
3847*8975f5c5SAndroid Build Coastguard Worker 
3848*8975f5c5SAndroid Build Coastguard Worker             if (renderbuffer->getSamples() > 0)
3849*8975f5c5SAndroid Build Coastguard Worker             {
3850*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_PARAMETER, "target renderbuffer cannot be multisampled.");
3851*8975f5c5SAndroid Build Coastguard Worker                 return false;
3852*8975f5c5SAndroid Build Coastguard Worker             }
3853*8975f5c5SAndroid Build Coastguard Worker 
3854*8975f5c5SAndroid Build Coastguard Worker             bool protectedContentAttrib =
3855*8975f5c5SAndroid Build Coastguard Worker                 (attributes.getAsInt(EGL_PROTECTED_CONTENT_EXT, EGL_FALSE) != EGL_FALSE);
3856*8975f5c5SAndroid Build Coastguard Worker             if (protectedContentAttrib != renderbuffer->hasProtectedContent())
3857*8975f5c5SAndroid Build Coastguard Worker             {
3858*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ACCESS,
3859*8975f5c5SAndroid Build Coastguard Worker                               "EGL_PROTECTED_CONTENT_EXT attribute does not match protected state "
3860*8975f5c5SAndroid Build Coastguard Worker                               "of target.");
3861*8975f5c5SAndroid Build Coastguard Worker                 return false;
3862*8975f5c5SAndroid Build Coastguard Worker             }
3863*8975f5c5SAndroid Build Coastguard Worker         }
3864*8975f5c5SAndroid Build Coastguard Worker         break;
3865*8975f5c5SAndroid Build Coastguard Worker 
3866*8975f5c5SAndroid Build Coastguard Worker         case EGL_NATIVE_BUFFER_ANDROID:
3867*8975f5c5SAndroid Build Coastguard Worker         {
3868*8975f5c5SAndroid Build Coastguard Worker             if (!displayExtensions.imageNativeBuffer)
3869*8975f5c5SAndroid Build Coastguard Worker             {
3870*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_PARAMETER, "EGL_ANDROID_image_native_buffer not supported.");
3871*8975f5c5SAndroid Build Coastguard Worker                 return false;
3872*8975f5c5SAndroid Build Coastguard Worker             }
3873*8975f5c5SAndroid Build Coastguard Worker 
3874*8975f5c5SAndroid Build Coastguard Worker             if (context != nullptr)
3875*8975f5c5SAndroid Build Coastguard Worker             {
3876*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_CONTEXT, "ctx must be EGL_NO_CONTEXT.");
3877*8975f5c5SAndroid Build Coastguard Worker                 return false;
3878*8975f5c5SAndroid Build Coastguard Worker             }
3879*8975f5c5SAndroid Build Coastguard Worker 
3880*8975f5c5SAndroid Build Coastguard Worker             ANGLE_EGL_TRY_RETURN(
3881*8975f5c5SAndroid Build Coastguard Worker                 val->eglThread,
3882*8975f5c5SAndroid Build Coastguard Worker                 display->validateImageClientBuffer(context, target, buffer, attributes),
3883*8975f5c5SAndroid Build Coastguard Worker                 val->entryPoint, val->labeledObject, false);
3884*8975f5c5SAndroid Build Coastguard Worker         }
3885*8975f5c5SAndroid Build Coastguard Worker         break;
3886*8975f5c5SAndroid Build Coastguard Worker 
3887*8975f5c5SAndroid Build Coastguard Worker         case EGL_D3D11_TEXTURE_ANGLE:
3888*8975f5c5SAndroid Build Coastguard Worker             if (!displayExtensions.imageD3D11Texture)
3889*8975f5c5SAndroid Build Coastguard Worker             {
3890*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_PARAMETER, "EGL_ANGLE_image_d3d11_texture not supported.");
3891*8975f5c5SAndroid Build Coastguard Worker                 return false;
3892*8975f5c5SAndroid Build Coastguard Worker             }
3893*8975f5c5SAndroid Build Coastguard Worker 
3894*8975f5c5SAndroid Build Coastguard Worker             if (context != nullptr)
3895*8975f5c5SAndroid Build Coastguard Worker             {
3896*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_CONTEXT, "ctx must be EGL_NO_CONTEXT.");
3897*8975f5c5SAndroid Build Coastguard Worker                 return false;
3898*8975f5c5SAndroid Build Coastguard Worker             }
3899*8975f5c5SAndroid Build Coastguard Worker 
3900*8975f5c5SAndroid Build Coastguard Worker             ANGLE_EGL_TRY_RETURN(
3901*8975f5c5SAndroid Build Coastguard Worker                 val->eglThread,
3902*8975f5c5SAndroid Build Coastguard Worker                 display->validateImageClientBuffer(context, target, buffer, attributes),
3903*8975f5c5SAndroid Build Coastguard Worker                 val->entryPoint, val->labeledObject, false);
3904*8975f5c5SAndroid Build Coastguard Worker             break;
3905*8975f5c5SAndroid Build Coastguard Worker 
3906*8975f5c5SAndroid Build Coastguard Worker         case EGL_LINUX_DMA_BUF_EXT:
3907*8975f5c5SAndroid Build Coastguard Worker             if (!displayExtensions.imageDmaBufImportEXT)
3908*8975f5c5SAndroid Build Coastguard Worker             {
3909*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_PARAMETER, "EGL_EXT_image_dma_buf_import not supported.");
3910*8975f5c5SAndroid Build Coastguard Worker                 return false;
3911*8975f5c5SAndroid Build Coastguard Worker             }
3912*8975f5c5SAndroid Build Coastguard Worker 
3913*8975f5c5SAndroid Build Coastguard Worker             if (context != nullptr)
3914*8975f5c5SAndroid Build Coastguard Worker             {
3915*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_CONTEXT, "ctx must be EGL_NO_CONTEXT.");
3916*8975f5c5SAndroid Build Coastguard Worker                 return false;
3917*8975f5c5SAndroid Build Coastguard Worker             }
3918*8975f5c5SAndroid Build Coastguard Worker 
3919*8975f5c5SAndroid Build Coastguard Worker             if (buffer != nullptr)
3920*8975f5c5SAndroid Build Coastguard Worker             {
3921*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_PARAMETER, "buffer must be NULL.");
3922*8975f5c5SAndroid Build Coastguard Worker                 return false;
3923*8975f5c5SAndroid Build Coastguard Worker             }
3924*8975f5c5SAndroid Build Coastguard Worker 
3925*8975f5c5SAndroid Build Coastguard Worker             {
3926*8975f5c5SAndroid Build Coastguard Worker                 EGLenum kRequiredParameters[] = {EGL_WIDTH,
3927*8975f5c5SAndroid Build Coastguard Worker                                                  EGL_HEIGHT,
3928*8975f5c5SAndroid Build Coastguard Worker                                                  EGL_LINUX_DRM_FOURCC_EXT,
3929*8975f5c5SAndroid Build Coastguard Worker                                                  EGL_DMA_BUF_PLANE0_FD_EXT,
3930*8975f5c5SAndroid Build Coastguard Worker                                                  EGL_DMA_BUF_PLANE0_OFFSET_EXT,
3931*8975f5c5SAndroid Build Coastguard Worker                                                  EGL_DMA_BUF_PLANE0_PITCH_EXT};
3932*8975f5c5SAndroid Build Coastguard Worker                 for (EGLenum requiredParameter : kRequiredParameters)
3933*8975f5c5SAndroid Build Coastguard Worker                 {
3934*8975f5c5SAndroid Build Coastguard Worker                     if (!attributes.contains(requiredParameter))
3935*8975f5c5SAndroid Build Coastguard Worker                     {
3936*8975f5c5SAndroid Build Coastguard Worker                         val->setError(EGL_BAD_PARAMETER,
3937*8975f5c5SAndroid Build Coastguard Worker                                       "Missing required parameter 0x%X for image target "
3938*8975f5c5SAndroid Build Coastguard Worker                                       "EGL_LINUX_DMA_BUF_EXT.",
3939*8975f5c5SAndroid Build Coastguard Worker                                       requiredParameter);
3940*8975f5c5SAndroid Build Coastguard Worker                         return false;
3941*8975f5c5SAndroid Build Coastguard Worker                     }
3942*8975f5c5SAndroid Build Coastguard Worker                 }
3943*8975f5c5SAndroid Build Coastguard Worker 
3944*8975f5c5SAndroid Build Coastguard Worker                 bool containPlane0ModifierLo =
3945*8975f5c5SAndroid Build Coastguard Worker                     attributes.contains(EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT);
3946*8975f5c5SAndroid Build Coastguard Worker                 bool containPlane0ModifierHi =
3947*8975f5c5SAndroid Build Coastguard Worker                     attributes.contains(EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT);
3948*8975f5c5SAndroid Build Coastguard Worker                 bool containPlane1ModifierLo =
3949*8975f5c5SAndroid Build Coastguard Worker                     attributes.contains(EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT);
3950*8975f5c5SAndroid Build Coastguard Worker                 bool containPlane1ModifierHi =
3951*8975f5c5SAndroid Build Coastguard Worker                     attributes.contains(EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT);
3952*8975f5c5SAndroid Build Coastguard Worker                 bool containPlane2ModifierLo =
3953*8975f5c5SAndroid Build Coastguard Worker                     attributes.contains(EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT);
3954*8975f5c5SAndroid Build Coastguard Worker                 bool containPlane2ModifierHi =
3955*8975f5c5SAndroid Build Coastguard Worker                     attributes.contains(EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT);
3956*8975f5c5SAndroid Build Coastguard Worker                 bool containPlane3ModifierLo =
3957*8975f5c5SAndroid Build Coastguard Worker                     attributes.contains(EGL_DMA_BUF_PLANE3_MODIFIER_LO_EXT);
3958*8975f5c5SAndroid Build Coastguard Worker                 bool containPlane3ModifierHi =
3959*8975f5c5SAndroid Build Coastguard Worker                     attributes.contains(EGL_DMA_BUF_PLANE3_MODIFIER_HI_EXT);
3960*8975f5c5SAndroid Build Coastguard Worker                 if ((containPlane0ModifierLo ^ containPlane0ModifierHi) ||
3961*8975f5c5SAndroid Build Coastguard Worker                     (containPlane1ModifierLo ^ containPlane1ModifierHi) ||
3962*8975f5c5SAndroid Build Coastguard Worker                     (containPlane2ModifierLo ^ containPlane2ModifierHi) ||
3963*8975f5c5SAndroid Build Coastguard Worker                     (containPlane3ModifierLo ^ containPlane3ModifierHi))
3964*8975f5c5SAndroid Build Coastguard Worker                 {
3965*8975f5c5SAndroid Build Coastguard Worker                     val->setError(
3966*8975f5c5SAndroid Build Coastguard Worker                         EGL_BAD_PARAMETER,
3967*8975f5c5SAndroid Build Coastguard Worker                         "the list of attributes contains EGL_DMA_BUF_PLANE*_MODIFIER_LO_EXT "
3968*8975f5c5SAndroid Build Coastguard Worker                         "but not EGL_DMA_BUF_PLANE*_MODIFIER_HI_EXT or vice versa.");
3969*8975f5c5SAndroid Build Coastguard Worker                     return false;
3970*8975f5c5SAndroid Build Coastguard Worker                 }
3971*8975f5c5SAndroid Build Coastguard Worker             }
3972*8975f5c5SAndroid Build Coastguard Worker             break;
3973*8975f5c5SAndroid Build Coastguard Worker 
3974*8975f5c5SAndroid Build Coastguard Worker         case EGL_METAL_TEXTURE_ANGLE:
3975*8975f5c5SAndroid Build Coastguard Worker             if (!displayExtensions.mtlTextureClientBuffer)
3976*8975f5c5SAndroid Build Coastguard Worker             {
3977*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_PARAMETER,
3978*8975f5c5SAndroid Build Coastguard Worker                               "EGL_ANGLE_metal_texture_client_buffer not supported.");
3979*8975f5c5SAndroid Build Coastguard Worker                 return false;
3980*8975f5c5SAndroid Build Coastguard Worker             }
3981*8975f5c5SAndroid Build Coastguard Worker 
3982*8975f5c5SAndroid Build Coastguard Worker             if (context != nullptr)
3983*8975f5c5SAndroid Build Coastguard Worker             {
3984*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_CONTEXT, "ctx must be EGL_NO_CONTEXT.");
3985*8975f5c5SAndroid Build Coastguard Worker                 return false;
3986*8975f5c5SAndroid Build Coastguard Worker             }
3987*8975f5c5SAndroid Build Coastguard Worker 
3988*8975f5c5SAndroid Build Coastguard Worker             ANGLE_EGL_TRY_RETURN(
3989*8975f5c5SAndroid Build Coastguard Worker                 val->eglThread,
3990*8975f5c5SAndroid Build Coastguard Worker                 display->validateImageClientBuffer(context, target, buffer, attributes),
3991*8975f5c5SAndroid Build Coastguard Worker                 val->entryPoint, val->labeledObject, false);
3992*8975f5c5SAndroid Build Coastguard Worker             break;
3993*8975f5c5SAndroid Build Coastguard Worker         case EGL_VULKAN_IMAGE_ANGLE:
3994*8975f5c5SAndroid Build Coastguard Worker             if (!displayExtensions.vulkanImageANGLE)
3995*8975f5c5SAndroid Build Coastguard Worker             {
3996*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_PARAMETER, "EGL_ANGLE_vulkan_image not supported.");
3997*8975f5c5SAndroid Build Coastguard Worker                 return false;
3998*8975f5c5SAndroid Build Coastguard Worker             }
3999*8975f5c5SAndroid Build Coastguard Worker 
4000*8975f5c5SAndroid Build Coastguard Worker             if (context != nullptr)
4001*8975f5c5SAndroid Build Coastguard Worker             {
4002*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_CONTEXT, "ctx must be EGL_NO_CONTEXT.");
4003*8975f5c5SAndroid Build Coastguard Worker                 return false;
4004*8975f5c5SAndroid Build Coastguard Worker             }
4005*8975f5c5SAndroid Build Coastguard Worker 
4006*8975f5c5SAndroid Build Coastguard Worker             {
4007*8975f5c5SAndroid Build Coastguard Worker                 const EGLenum kRequiredParameters[] = {
4008*8975f5c5SAndroid Build Coastguard Worker                     EGL_VULKAN_IMAGE_CREATE_INFO_HI_ANGLE,
4009*8975f5c5SAndroid Build Coastguard Worker                     EGL_VULKAN_IMAGE_CREATE_INFO_LO_ANGLE,
4010*8975f5c5SAndroid Build Coastguard Worker                 };
4011*8975f5c5SAndroid Build Coastguard Worker                 for (EGLenum requiredParameter : kRequiredParameters)
4012*8975f5c5SAndroid Build Coastguard Worker                 {
4013*8975f5c5SAndroid Build Coastguard Worker                     if (!attributes.contains(requiredParameter))
4014*8975f5c5SAndroid Build Coastguard Worker                     {
4015*8975f5c5SAndroid Build Coastguard Worker                         val->setError(EGL_BAD_PARAMETER,
4016*8975f5c5SAndroid Build Coastguard Worker                                       "Missing required parameter 0x%X for image target "
4017*8975f5c5SAndroid Build Coastguard Worker                                       "EGL_VULKAN_IMAGE_ANGLE.",
4018*8975f5c5SAndroid Build Coastguard Worker                                       requiredParameter);
4019*8975f5c5SAndroid Build Coastguard Worker                         return false;
4020*8975f5c5SAndroid Build Coastguard Worker                     }
4021*8975f5c5SAndroid Build Coastguard Worker                 }
4022*8975f5c5SAndroid Build Coastguard Worker             }
4023*8975f5c5SAndroid Build Coastguard Worker 
4024*8975f5c5SAndroid Build Coastguard Worker             ANGLE_EGL_TRY_RETURN(
4025*8975f5c5SAndroid Build Coastguard Worker                 val->eglThread,
4026*8975f5c5SAndroid Build Coastguard Worker                 display->validateImageClientBuffer(context, target, buffer, attributes),
4027*8975f5c5SAndroid Build Coastguard Worker                 val->entryPoint, val->labeledObject, false);
4028*8975f5c5SAndroid Build Coastguard Worker             break;
4029*8975f5c5SAndroid Build Coastguard Worker         default:
4030*8975f5c5SAndroid Build Coastguard Worker             val->setError(EGL_BAD_PARAMETER, "invalid target: 0x%X", target);
4031*8975f5c5SAndroid Build Coastguard Worker             return false;
4032*8975f5c5SAndroid Build Coastguard Worker     }
4033*8975f5c5SAndroid Build Coastguard Worker 
4034*8975f5c5SAndroid Build Coastguard Worker     if (attributes.contains(EGL_GL_TEXTURE_ZOFFSET) && target != EGL_GL_TEXTURE_3D)
4035*8975f5c5SAndroid Build Coastguard Worker     {
4036*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_PARAMETER,
4037*8975f5c5SAndroid Build Coastguard Worker                       "EGL_GL_TEXTURE_ZOFFSET must be used with a 3D texture target.");
4038*8975f5c5SAndroid Build Coastguard Worker         return false;
4039*8975f5c5SAndroid Build Coastguard Worker     }
4040*8975f5c5SAndroid Build Coastguard Worker 
4041*8975f5c5SAndroid Build Coastguard Worker     return true;
4042*8975f5c5SAndroid Build Coastguard Worker }
4043*8975f5c5SAndroid Build Coastguard Worker 
ValidateDestroyImage(const ValidationContext * val,const Display * display,ImageID imageID)4044*8975f5c5SAndroid Build Coastguard Worker bool ValidateDestroyImage(const ValidationContext *val, const Display *display, ImageID imageID)
4045*8975f5c5SAndroid Build Coastguard Worker {
4046*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateImage(val, display, imageID));
4047*8975f5c5SAndroid Build Coastguard Worker     return true;
4048*8975f5c5SAndroid Build Coastguard Worker }
4049*8975f5c5SAndroid Build Coastguard Worker 
ValidateCreateImageKHR(const ValidationContext * val,const Display * display,gl::ContextID contextID,EGLenum target,EGLClientBuffer buffer,const AttributeMap & attributes)4050*8975f5c5SAndroid Build Coastguard Worker bool ValidateCreateImageKHR(const ValidationContext *val,
4051*8975f5c5SAndroid Build Coastguard Worker                             const Display *display,
4052*8975f5c5SAndroid Build Coastguard Worker                             gl::ContextID contextID,
4053*8975f5c5SAndroid Build Coastguard Worker                             EGLenum target,
4054*8975f5c5SAndroid Build Coastguard Worker                             EGLClientBuffer buffer,
4055*8975f5c5SAndroid Build Coastguard Worker                             const AttributeMap &attributes)
4056*8975f5c5SAndroid Build Coastguard Worker {
4057*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
4058*8975f5c5SAndroid Build Coastguard Worker 
4059*8975f5c5SAndroid Build Coastguard Worker     if (!display->getExtensions().imageBase && !display->getExtensions().image)
4060*8975f5c5SAndroid Build Coastguard Worker     {
4061*8975f5c5SAndroid Build Coastguard Worker         // It is out of spec what happens when calling an extension function when the extension is
4062*8975f5c5SAndroid Build Coastguard Worker         // not available.
4063*8975f5c5SAndroid Build Coastguard Worker         // EGL_BAD_DISPLAY seems like a reasonable error.
4064*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_DISPLAY, "EGL_KHR_image not supported.");
4065*8975f5c5SAndroid Build Coastguard Worker         return false;
4066*8975f5c5SAndroid Build Coastguard Worker     }
4067*8975f5c5SAndroid Build Coastguard Worker 
4068*8975f5c5SAndroid Build Coastguard Worker     return ValidateCreateImage(val, display, contextID, target, buffer, attributes);
4069*8975f5c5SAndroid Build Coastguard Worker }
4070*8975f5c5SAndroid Build Coastguard Worker 
ValidateDestroyImageKHR(const ValidationContext * val,const Display * display,ImageID imageID)4071*8975f5c5SAndroid Build Coastguard Worker bool ValidateDestroyImageKHR(const ValidationContext *val, const Display *display, ImageID imageID)
4072*8975f5c5SAndroid Build Coastguard Worker {
4073*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateImage(val, display, imageID));
4074*8975f5c5SAndroid Build Coastguard Worker 
4075*8975f5c5SAndroid Build Coastguard Worker     if (!display->getExtensions().imageBase && !display->getExtensions().image)
4076*8975f5c5SAndroid Build Coastguard Worker     {
4077*8975f5c5SAndroid Build Coastguard Worker         // It is out of spec what happens when calling an extension function when the extension is
4078*8975f5c5SAndroid Build Coastguard Worker         // not available.
4079*8975f5c5SAndroid Build Coastguard Worker         // EGL_BAD_DISPLAY seems like a reasonable error.
4080*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_DISPLAY);
4081*8975f5c5SAndroid Build Coastguard Worker         return false;
4082*8975f5c5SAndroid Build Coastguard Worker     }
4083*8975f5c5SAndroid Build Coastguard Worker 
4084*8975f5c5SAndroid Build Coastguard Worker     return true;
4085*8975f5c5SAndroid Build Coastguard Worker }
4086*8975f5c5SAndroid Build Coastguard Worker 
ValidateCreateDeviceANGLE(const ValidationContext * val,EGLint device_type,const void * native_device,const EGLAttrib * attrib_list)4087*8975f5c5SAndroid Build Coastguard Worker bool ValidateCreateDeviceANGLE(const ValidationContext *val,
4088*8975f5c5SAndroid Build Coastguard Worker                                EGLint device_type,
4089*8975f5c5SAndroid Build Coastguard Worker                                const void *native_device,
4090*8975f5c5SAndroid Build Coastguard Worker                                const EGLAttrib *attrib_list)
4091*8975f5c5SAndroid Build Coastguard Worker {
4092*8975f5c5SAndroid Build Coastguard Worker     const ClientExtensions &clientExtensions = Display::GetClientExtensions();
4093*8975f5c5SAndroid Build Coastguard Worker     if (!clientExtensions.deviceCreation)
4094*8975f5c5SAndroid Build Coastguard Worker     {
4095*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_ACCESS, "Device creation extension not active");
4096*8975f5c5SAndroid Build Coastguard Worker         return false;
4097*8975f5c5SAndroid Build Coastguard Worker     }
4098*8975f5c5SAndroid Build Coastguard Worker 
4099*8975f5c5SAndroid Build Coastguard Worker     if (attrib_list != nullptr && attrib_list[0] != EGL_NONE)
4100*8975f5c5SAndroid Build Coastguard Worker     {
4101*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_ATTRIBUTE, "Invalid attrib_list parameter");
4102*8975f5c5SAndroid Build Coastguard Worker         return false;
4103*8975f5c5SAndroid Build Coastguard Worker     }
4104*8975f5c5SAndroid Build Coastguard Worker 
4105*8975f5c5SAndroid Build Coastguard Worker     switch (device_type)
4106*8975f5c5SAndroid Build Coastguard Worker     {
4107*8975f5c5SAndroid Build Coastguard Worker         case EGL_D3D11_DEVICE_ANGLE:
4108*8975f5c5SAndroid Build Coastguard Worker             if (!clientExtensions.deviceCreationD3D11)
4109*8975f5c5SAndroid Build Coastguard Worker             {
4110*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE, "D3D11 device creation extension not active");
4111*8975f5c5SAndroid Build Coastguard Worker                 return false;
4112*8975f5c5SAndroid Build Coastguard Worker             }
4113*8975f5c5SAndroid Build Coastguard Worker             break;
4114*8975f5c5SAndroid Build Coastguard Worker         default:
4115*8975f5c5SAndroid Build Coastguard Worker             val->setError(EGL_BAD_ATTRIBUTE, "Invalid device_type parameter");
4116*8975f5c5SAndroid Build Coastguard Worker             return false;
4117*8975f5c5SAndroid Build Coastguard Worker     }
4118*8975f5c5SAndroid Build Coastguard Worker 
4119*8975f5c5SAndroid Build Coastguard Worker     return true;
4120*8975f5c5SAndroid Build Coastguard Worker }
4121*8975f5c5SAndroid Build Coastguard Worker 
ValidateReleaseDeviceANGLE(const ValidationContext * val,const Device * device)4122*8975f5c5SAndroid Build Coastguard Worker bool ValidateReleaseDeviceANGLE(const ValidationContext *val, const Device *device)
4123*8975f5c5SAndroid Build Coastguard Worker {
4124*8975f5c5SAndroid Build Coastguard Worker     const ClientExtensions &clientExtensions = Display::GetClientExtensions();
4125*8975f5c5SAndroid Build Coastguard Worker     if (!clientExtensions.deviceCreation)
4126*8975f5c5SAndroid Build Coastguard Worker     {
4127*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_ACCESS, "Device creation extension not active");
4128*8975f5c5SAndroid Build Coastguard Worker         return false;
4129*8975f5c5SAndroid Build Coastguard Worker     }
4130*8975f5c5SAndroid Build Coastguard Worker 
4131*8975f5c5SAndroid Build Coastguard Worker     if (device == EGL_NO_DEVICE_EXT || !Device::IsValidDevice(device))
4132*8975f5c5SAndroid Build Coastguard Worker     {
4133*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_DEVICE_EXT, "Invalid device parameter");
4134*8975f5c5SAndroid Build Coastguard Worker         return false;
4135*8975f5c5SAndroid Build Coastguard Worker     }
4136*8975f5c5SAndroid Build Coastguard Worker 
4137*8975f5c5SAndroid Build Coastguard Worker     Display *owningDisplay = device->getOwningDisplay();
4138*8975f5c5SAndroid Build Coastguard Worker     if (owningDisplay != nullptr)
4139*8975f5c5SAndroid Build Coastguard Worker     {
4140*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_DEVICE_EXT, "Device must have been created using eglCreateDevice");
4141*8975f5c5SAndroid Build Coastguard Worker         return false;
4142*8975f5c5SAndroid Build Coastguard Worker     }
4143*8975f5c5SAndroid Build Coastguard Worker 
4144*8975f5c5SAndroid Build Coastguard Worker     return true;
4145*8975f5c5SAndroid Build Coastguard Worker }
4146*8975f5c5SAndroid Build Coastguard Worker 
ValidateCreateSync(const ValidationContext * val,const Display * display,EGLenum type,const AttributeMap & attribs)4147*8975f5c5SAndroid Build Coastguard Worker bool ValidateCreateSync(const ValidationContext *val,
4148*8975f5c5SAndroid Build Coastguard Worker                         const Display *display,
4149*8975f5c5SAndroid Build Coastguard Worker                         EGLenum type,
4150*8975f5c5SAndroid Build Coastguard Worker                         const AttributeMap &attribs)
4151*8975f5c5SAndroid Build Coastguard Worker {
4152*8975f5c5SAndroid Build Coastguard Worker     return ValidateCreateSyncBase(val, display, type, attribs, false);
4153*8975f5c5SAndroid Build Coastguard Worker }
4154*8975f5c5SAndroid Build Coastguard Worker 
ValidateCreateSyncKHR(const ValidationContext * val,const Display * display,EGLenum type,const AttributeMap & attribs)4155*8975f5c5SAndroid Build Coastguard Worker bool ValidateCreateSyncKHR(const ValidationContext *val,
4156*8975f5c5SAndroid Build Coastguard Worker                            const Display *display,
4157*8975f5c5SAndroid Build Coastguard Worker                            EGLenum type,
4158*8975f5c5SAndroid Build Coastguard Worker                            const AttributeMap &attribs)
4159*8975f5c5SAndroid Build Coastguard Worker {
4160*8975f5c5SAndroid Build Coastguard Worker     return ValidateCreateSyncBase(val, display, type, attribs, true);
4161*8975f5c5SAndroid Build Coastguard Worker }
4162*8975f5c5SAndroid Build Coastguard Worker 
ValidateDestroySync(const ValidationContext * val,const Display * display,SyncID sync)4163*8975f5c5SAndroid Build Coastguard Worker bool ValidateDestroySync(const ValidationContext *val, const Display *display, SyncID sync)
4164*8975f5c5SAndroid Build Coastguard Worker {
4165*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateSync(val, display, sync));
4166*8975f5c5SAndroid Build Coastguard Worker     return true;
4167*8975f5c5SAndroid Build Coastguard Worker }
4168*8975f5c5SAndroid Build Coastguard Worker 
ValidateDestroySyncKHR(const ValidationContext * val,const Display * dpyPacked,SyncID syncPacked)4169*8975f5c5SAndroid Build Coastguard Worker bool ValidateDestroySyncKHR(const ValidationContext *val,
4170*8975f5c5SAndroid Build Coastguard Worker                             const Display *dpyPacked,
4171*8975f5c5SAndroid Build Coastguard Worker                             SyncID syncPacked)
4172*8975f5c5SAndroid Build Coastguard Worker {
4173*8975f5c5SAndroid Build Coastguard Worker     return ValidateDestroySync(val, dpyPacked, syncPacked);
4174*8975f5c5SAndroid Build Coastguard Worker }
4175*8975f5c5SAndroid Build Coastguard Worker 
ValidateClientWaitSync(const ValidationContext * val,const Display * display,SyncID sync,EGLint flags,EGLTime timeout)4176*8975f5c5SAndroid Build Coastguard Worker bool ValidateClientWaitSync(const ValidationContext *val,
4177*8975f5c5SAndroid Build Coastguard Worker                             const Display *display,
4178*8975f5c5SAndroid Build Coastguard Worker                             SyncID sync,
4179*8975f5c5SAndroid Build Coastguard Worker                             EGLint flags,
4180*8975f5c5SAndroid Build Coastguard Worker                             EGLTime timeout)
4181*8975f5c5SAndroid Build Coastguard Worker {
4182*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateSync(val, display, sync));
4183*8975f5c5SAndroid Build Coastguard Worker     return true;
4184*8975f5c5SAndroid Build Coastguard Worker }
4185*8975f5c5SAndroid Build Coastguard Worker 
ValidateClientWaitSyncKHR(const ValidationContext * val,const Display * dpyPacked,SyncID syncPacked,EGLint flags,EGLTimeKHR timeout)4186*8975f5c5SAndroid Build Coastguard Worker bool ValidateClientWaitSyncKHR(const ValidationContext *val,
4187*8975f5c5SAndroid Build Coastguard Worker                                const Display *dpyPacked,
4188*8975f5c5SAndroid Build Coastguard Worker                                SyncID syncPacked,
4189*8975f5c5SAndroid Build Coastguard Worker                                EGLint flags,
4190*8975f5c5SAndroid Build Coastguard Worker                                EGLTimeKHR timeout)
4191*8975f5c5SAndroid Build Coastguard Worker {
4192*8975f5c5SAndroid Build Coastguard Worker     return ValidateClientWaitSync(val, dpyPacked, syncPacked, flags, timeout);
4193*8975f5c5SAndroid Build Coastguard Worker }
4194*8975f5c5SAndroid Build Coastguard Worker 
ValidateWaitSync(const ValidationContext * val,const Display * display,SyncID sync,EGLint flags)4195*8975f5c5SAndroid Build Coastguard Worker bool ValidateWaitSync(const ValidationContext *val,
4196*8975f5c5SAndroid Build Coastguard Worker                       const Display *display,
4197*8975f5c5SAndroid Build Coastguard Worker                       SyncID sync,
4198*8975f5c5SAndroid Build Coastguard Worker                       EGLint flags)
4199*8975f5c5SAndroid Build Coastguard Worker {
4200*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
4201*8975f5c5SAndroid Build Coastguard Worker 
4202*8975f5c5SAndroid Build Coastguard Worker     const DisplayExtensions &extensions = display->getExtensions();
4203*8975f5c5SAndroid Build Coastguard Worker     if (!extensions.waitSync)
4204*8975f5c5SAndroid Build Coastguard Worker     {
4205*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_ACCESS, "EGL_KHR_wait_sync extension is not available");
4206*8975f5c5SAndroid Build Coastguard Worker         return false;
4207*8975f5c5SAndroid Build Coastguard Worker     }
4208*8975f5c5SAndroid Build Coastguard Worker 
4209*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateSync(val, display, sync));
4210*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateThreadContext(val, display, EGL_BAD_MATCH));
4211*8975f5c5SAndroid Build Coastguard Worker 
4212*8975f5c5SAndroid Build Coastguard Worker     gl::Context *context = val->eglThread->getContext();
4213*8975f5c5SAndroid Build Coastguard Worker     if (!context->getExtensions().EGLSyncOES)
4214*8975f5c5SAndroid Build Coastguard Worker     {
4215*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_MATCH,
4216*8975f5c5SAndroid Build Coastguard Worker                       "Server-side waits cannot be performed without "
4217*8975f5c5SAndroid Build Coastguard Worker                       "GL_OES_EGL_sync support.");
4218*8975f5c5SAndroid Build Coastguard Worker         return false;
4219*8975f5c5SAndroid Build Coastguard Worker     }
4220*8975f5c5SAndroid Build Coastguard Worker 
4221*8975f5c5SAndroid Build Coastguard Worker     if (flags != 0)
4222*8975f5c5SAndroid Build Coastguard Worker     {
4223*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_PARAMETER, "flags must be zero");
4224*8975f5c5SAndroid Build Coastguard Worker         return false;
4225*8975f5c5SAndroid Build Coastguard Worker     }
4226*8975f5c5SAndroid Build Coastguard Worker 
4227*8975f5c5SAndroid Build Coastguard Worker     return true;
4228*8975f5c5SAndroid Build Coastguard Worker }
4229*8975f5c5SAndroid Build Coastguard Worker 
ValidateWaitSyncKHR(const ValidationContext * val,const Display * dpyPacked,SyncID syncPacked,EGLint flags)4230*8975f5c5SAndroid Build Coastguard Worker bool ValidateWaitSyncKHR(const ValidationContext *val,
4231*8975f5c5SAndroid Build Coastguard Worker                          const Display *dpyPacked,
4232*8975f5c5SAndroid Build Coastguard Worker                          SyncID syncPacked,
4233*8975f5c5SAndroid Build Coastguard Worker                          EGLint flags)
4234*8975f5c5SAndroid Build Coastguard Worker {
4235*8975f5c5SAndroid Build Coastguard Worker     return ValidateWaitSync(val, dpyPacked, syncPacked, flags);
4236*8975f5c5SAndroid Build Coastguard Worker }
4237*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetSyncAttrib(const ValidationContext * val,const Display * display,SyncID sync,EGLint attribute,const EGLAttrib * value)4238*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetSyncAttrib(const ValidationContext *val,
4239*8975f5c5SAndroid Build Coastguard Worker                            const Display *display,
4240*8975f5c5SAndroid Build Coastguard Worker                            SyncID sync,
4241*8975f5c5SAndroid Build Coastguard Worker                            EGLint attribute,
4242*8975f5c5SAndroid Build Coastguard Worker                            const EGLAttrib *value)
4243*8975f5c5SAndroid Build Coastguard Worker {
4244*8975f5c5SAndroid Build Coastguard Worker     if (value == nullptr)
4245*8975f5c5SAndroid Build Coastguard Worker     {
4246*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_PARAMETER, "Invalid value parameter");
4247*8975f5c5SAndroid Build Coastguard Worker         return false;
4248*8975f5c5SAndroid Build Coastguard Worker     }
4249*8975f5c5SAndroid Build Coastguard Worker     return ValidateGetSyncAttribBase(val, display, sync, attribute);
4250*8975f5c5SAndroid Build Coastguard Worker }
4251*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetSyncAttribKHR(const ValidationContext * val,const Display * display,SyncID sync,EGLint attribute,const EGLint * value)4252*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetSyncAttribKHR(const ValidationContext *val,
4253*8975f5c5SAndroid Build Coastguard Worker                               const Display *display,
4254*8975f5c5SAndroid Build Coastguard Worker                               SyncID sync,
4255*8975f5c5SAndroid Build Coastguard Worker                               EGLint attribute,
4256*8975f5c5SAndroid Build Coastguard Worker                               const EGLint *value)
4257*8975f5c5SAndroid Build Coastguard Worker {
4258*8975f5c5SAndroid Build Coastguard Worker     if (value == nullptr)
4259*8975f5c5SAndroid Build Coastguard Worker     {
4260*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_PARAMETER, "Invalid value parameter");
4261*8975f5c5SAndroid Build Coastguard Worker         return false;
4262*8975f5c5SAndroid Build Coastguard Worker     }
4263*8975f5c5SAndroid Build Coastguard Worker     return ValidateGetSyncAttribBase(val, display, sync, attribute);
4264*8975f5c5SAndroid Build Coastguard Worker }
4265*8975f5c5SAndroid Build Coastguard Worker 
ValidateCreateStreamKHR(const ValidationContext * val,const Display * display,const AttributeMap & attributes)4266*8975f5c5SAndroid Build Coastguard Worker bool ValidateCreateStreamKHR(const ValidationContext *val,
4267*8975f5c5SAndroid Build Coastguard Worker                              const Display *display,
4268*8975f5c5SAndroid Build Coastguard Worker                              const AttributeMap &attributes)
4269*8975f5c5SAndroid Build Coastguard Worker {
4270*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
4271*8975f5c5SAndroid Build Coastguard Worker 
4272*8975f5c5SAndroid Build Coastguard Worker     const DisplayExtensions &displayExtensions = display->getExtensions();
4273*8975f5c5SAndroid Build Coastguard Worker     if (!displayExtensions.stream)
4274*8975f5c5SAndroid Build Coastguard Worker     {
4275*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_ALLOC, "Stream extension not active");
4276*8975f5c5SAndroid Build Coastguard Worker         return false;
4277*8975f5c5SAndroid Build Coastguard Worker     }
4278*8975f5c5SAndroid Build Coastguard Worker 
4279*8975f5c5SAndroid Build Coastguard Worker     attributes.initializeWithoutValidation();
4280*8975f5c5SAndroid Build Coastguard Worker 
4281*8975f5c5SAndroid Build Coastguard Worker     for (const auto &attributeIter : attributes)
4282*8975f5c5SAndroid Build Coastguard Worker     {
4283*8975f5c5SAndroid Build Coastguard Worker         EGLAttrib attribute = attributeIter.first;
4284*8975f5c5SAndroid Build Coastguard Worker         EGLAttrib value     = attributeIter.second;
4285*8975f5c5SAndroid Build Coastguard Worker 
4286*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_TRY(ValidateStreamAttribute(val, attribute, value, displayExtensions));
4287*8975f5c5SAndroid Build Coastguard Worker     }
4288*8975f5c5SAndroid Build Coastguard Worker 
4289*8975f5c5SAndroid Build Coastguard Worker     return true;
4290*8975f5c5SAndroid Build Coastguard Worker }
4291*8975f5c5SAndroid Build Coastguard Worker 
ValidateDestroyStreamKHR(const ValidationContext * val,const Display * display,const Stream * stream)4292*8975f5c5SAndroid Build Coastguard Worker bool ValidateDestroyStreamKHR(const ValidationContext *val,
4293*8975f5c5SAndroid Build Coastguard Worker                               const Display *display,
4294*8975f5c5SAndroid Build Coastguard Worker                               const Stream *stream)
4295*8975f5c5SAndroid Build Coastguard Worker {
4296*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateStream(val, display, stream));
4297*8975f5c5SAndroid Build Coastguard Worker     return true;
4298*8975f5c5SAndroid Build Coastguard Worker }
4299*8975f5c5SAndroid Build Coastguard Worker 
ValidateStreamAttribKHR(const ValidationContext * val,const Display * display,const Stream * stream,EGLenum attribute,EGLint value)4300*8975f5c5SAndroid Build Coastguard Worker bool ValidateStreamAttribKHR(const ValidationContext *val,
4301*8975f5c5SAndroid Build Coastguard Worker                              const Display *display,
4302*8975f5c5SAndroid Build Coastguard Worker                              const Stream *stream,
4303*8975f5c5SAndroid Build Coastguard Worker                              EGLenum attribute,
4304*8975f5c5SAndroid Build Coastguard Worker                              EGLint value)
4305*8975f5c5SAndroid Build Coastguard Worker {
4306*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateStream(val, display, stream));
4307*8975f5c5SAndroid Build Coastguard Worker 
4308*8975f5c5SAndroid Build Coastguard Worker     if (stream->getState() == EGL_STREAM_STATE_DISCONNECTED_KHR)
4309*8975f5c5SAndroid Build Coastguard Worker     {
4310*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_STATE_KHR, "Bad stream state");
4311*8975f5c5SAndroid Build Coastguard Worker         return false;
4312*8975f5c5SAndroid Build Coastguard Worker     }
4313*8975f5c5SAndroid Build Coastguard Worker 
4314*8975f5c5SAndroid Build Coastguard Worker     return ValidateStreamAttribute(val, attribute, value, display->getExtensions());
4315*8975f5c5SAndroid Build Coastguard Worker }
4316*8975f5c5SAndroid Build Coastguard Worker 
ValidateQueryStreamKHR(const ValidationContext * val,const Display * display,const Stream * stream,EGLenum attribute,const EGLint * value)4317*8975f5c5SAndroid Build Coastguard Worker bool ValidateQueryStreamKHR(const ValidationContext *val,
4318*8975f5c5SAndroid Build Coastguard Worker                             const Display *display,
4319*8975f5c5SAndroid Build Coastguard Worker                             const Stream *stream,
4320*8975f5c5SAndroid Build Coastguard Worker                             EGLenum attribute,
4321*8975f5c5SAndroid Build Coastguard Worker                             const EGLint *value)
4322*8975f5c5SAndroid Build Coastguard Worker {
4323*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateStream(val, display, stream));
4324*8975f5c5SAndroid Build Coastguard Worker 
4325*8975f5c5SAndroid Build Coastguard Worker     switch (attribute)
4326*8975f5c5SAndroid Build Coastguard Worker     {
4327*8975f5c5SAndroid Build Coastguard Worker         case EGL_STREAM_STATE_KHR:
4328*8975f5c5SAndroid Build Coastguard Worker         case EGL_CONSUMER_LATENCY_USEC_KHR:
4329*8975f5c5SAndroid Build Coastguard Worker             break;
4330*8975f5c5SAndroid Build Coastguard Worker         case EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR:
4331*8975f5c5SAndroid Build Coastguard Worker             if (!display->getExtensions().streamConsumerGLTexture)
4332*8975f5c5SAndroid Build Coastguard Worker             {
4333*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE, "Consumer GLTexture extension not active");
4334*8975f5c5SAndroid Build Coastguard Worker                 return false;
4335*8975f5c5SAndroid Build Coastguard Worker             }
4336*8975f5c5SAndroid Build Coastguard Worker             break;
4337*8975f5c5SAndroid Build Coastguard Worker         default:
4338*8975f5c5SAndroid Build Coastguard Worker             val->setError(EGL_BAD_ATTRIBUTE, "Invalid attribute");
4339*8975f5c5SAndroid Build Coastguard Worker             return false;
4340*8975f5c5SAndroid Build Coastguard Worker     }
4341*8975f5c5SAndroid Build Coastguard Worker 
4342*8975f5c5SAndroid Build Coastguard Worker     return true;
4343*8975f5c5SAndroid Build Coastguard Worker }
4344*8975f5c5SAndroid Build Coastguard Worker 
ValidateQueryStreamu64KHR(const ValidationContext * val,const Display * display,const Stream * stream,EGLenum attribute,const EGLuint64KHR * value)4345*8975f5c5SAndroid Build Coastguard Worker bool ValidateQueryStreamu64KHR(const ValidationContext *val,
4346*8975f5c5SAndroid Build Coastguard Worker                                const Display *display,
4347*8975f5c5SAndroid Build Coastguard Worker                                const Stream *stream,
4348*8975f5c5SAndroid Build Coastguard Worker                                EGLenum attribute,
4349*8975f5c5SAndroid Build Coastguard Worker                                const EGLuint64KHR *value)
4350*8975f5c5SAndroid Build Coastguard Worker {
4351*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateStream(val, display, stream));
4352*8975f5c5SAndroid Build Coastguard Worker 
4353*8975f5c5SAndroid Build Coastguard Worker     switch (attribute)
4354*8975f5c5SAndroid Build Coastguard Worker     {
4355*8975f5c5SAndroid Build Coastguard Worker         case EGL_CONSUMER_FRAME_KHR:
4356*8975f5c5SAndroid Build Coastguard Worker         case EGL_PRODUCER_FRAME_KHR:
4357*8975f5c5SAndroid Build Coastguard Worker             break;
4358*8975f5c5SAndroid Build Coastguard Worker         default:
4359*8975f5c5SAndroid Build Coastguard Worker             val->setError(EGL_BAD_ATTRIBUTE, "Invalid attribute");
4360*8975f5c5SAndroid Build Coastguard Worker             return false;
4361*8975f5c5SAndroid Build Coastguard Worker     }
4362*8975f5c5SAndroid Build Coastguard Worker 
4363*8975f5c5SAndroid Build Coastguard Worker     return true;
4364*8975f5c5SAndroid Build Coastguard Worker }
4365*8975f5c5SAndroid Build Coastguard Worker 
ValidateStreamConsumerGLTextureExternalKHR(const ValidationContext * val,const Display * display,const Stream * stream)4366*8975f5c5SAndroid Build Coastguard Worker bool ValidateStreamConsumerGLTextureExternalKHR(const ValidationContext *val,
4367*8975f5c5SAndroid Build Coastguard Worker                                                 const Display *display,
4368*8975f5c5SAndroid Build Coastguard Worker                                                 const Stream *stream)
4369*8975f5c5SAndroid Build Coastguard Worker {
4370*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateThreadContext(val, display, EGL_BAD_CONTEXT));
4371*8975f5c5SAndroid Build Coastguard Worker 
4372*8975f5c5SAndroid Build Coastguard Worker     const DisplayExtensions &displayExtensions = display->getExtensions();
4373*8975f5c5SAndroid Build Coastguard Worker     if (!displayExtensions.streamConsumerGLTexture)
4374*8975f5c5SAndroid Build Coastguard Worker     {
4375*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_ACCESS, "Stream consumer extension not active");
4376*8975f5c5SAndroid Build Coastguard Worker         return false;
4377*8975f5c5SAndroid Build Coastguard Worker     }
4378*8975f5c5SAndroid Build Coastguard Worker 
4379*8975f5c5SAndroid Build Coastguard Worker     gl::Context *context = val->eglThread->getContext();
4380*8975f5c5SAndroid Build Coastguard Worker     if (!context->getExtensions().EGLStreamConsumerExternalNV)
4381*8975f5c5SAndroid Build Coastguard Worker     {
4382*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_ACCESS, "EGL stream consumer external GL extension not enabled");
4383*8975f5c5SAndroid Build Coastguard Worker         return false;
4384*8975f5c5SAndroid Build Coastguard Worker     }
4385*8975f5c5SAndroid Build Coastguard Worker 
4386*8975f5c5SAndroid Build Coastguard Worker     if (stream == EGL_NO_STREAM_KHR || !display->isValidStream(stream))
4387*8975f5c5SAndroid Build Coastguard Worker     {
4388*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_STREAM_KHR, "Invalid stream");
4389*8975f5c5SAndroid Build Coastguard Worker         return false;
4390*8975f5c5SAndroid Build Coastguard Worker     }
4391*8975f5c5SAndroid Build Coastguard Worker 
4392*8975f5c5SAndroid Build Coastguard Worker     if (stream->getState() != EGL_STREAM_STATE_CREATED_KHR)
4393*8975f5c5SAndroid Build Coastguard Worker     {
4394*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_STATE_KHR, "Invalid stream state");
4395*8975f5c5SAndroid Build Coastguard Worker         return false;
4396*8975f5c5SAndroid Build Coastguard Worker     }
4397*8975f5c5SAndroid Build Coastguard Worker 
4398*8975f5c5SAndroid Build Coastguard Worker     // Lookup the texture and ensure it is correct
4399*8975f5c5SAndroid Build Coastguard Worker     gl::Texture *texture = context->getState().getTargetTexture(gl::TextureType::External);
4400*8975f5c5SAndroid Build Coastguard Worker     if (texture == nullptr || texture->id().value == 0)
4401*8975f5c5SAndroid Build Coastguard Worker     {
4402*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_ACCESS, "No external texture bound");
4403*8975f5c5SAndroid Build Coastguard Worker         return false;
4404*8975f5c5SAndroid Build Coastguard Worker     }
4405*8975f5c5SAndroid Build Coastguard Worker 
4406*8975f5c5SAndroid Build Coastguard Worker     return true;
4407*8975f5c5SAndroid Build Coastguard Worker }
4408*8975f5c5SAndroid Build Coastguard Worker 
ValidateStreamConsumerAcquireKHR(const ValidationContext * val,const Display * display,const Stream * stream)4409*8975f5c5SAndroid Build Coastguard Worker bool ValidateStreamConsumerAcquireKHR(const ValidationContext *val,
4410*8975f5c5SAndroid Build Coastguard Worker                                       const Display *display,
4411*8975f5c5SAndroid Build Coastguard Worker                                       const Stream *stream)
4412*8975f5c5SAndroid Build Coastguard Worker {
4413*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
4414*8975f5c5SAndroid Build Coastguard Worker 
4415*8975f5c5SAndroid Build Coastguard Worker     const DisplayExtensions &displayExtensions = display->getExtensions();
4416*8975f5c5SAndroid Build Coastguard Worker     if (!displayExtensions.streamConsumerGLTexture)
4417*8975f5c5SAndroid Build Coastguard Worker     {
4418*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_ACCESS, "Stream consumer extension not active");
4419*8975f5c5SAndroid Build Coastguard Worker         return false;
4420*8975f5c5SAndroid Build Coastguard Worker     }
4421*8975f5c5SAndroid Build Coastguard Worker 
4422*8975f5c5SAndroid Build Coastguard Worker     if (stream == EGL_NO_STREAM_KHR || !display->isValidStream(stream))
4423*8975f5c5SAndroid Build Coastguard Worker     {
4424*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_STREAM_KHR, "Invalid stream");
4425*8975f5c5SAndroid Build Coastguard Worker         return false;
4426*8975f5c5SAndroid Build Coastguard Worker     }
4427*8975f5c5SAndroid Build Coastguard Worker 
4428*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateThreadContext(val, display, EGL_BAD_CONTEXT));
4429*8975f5c5SAndroid Build Coastguard Worker 
4430*8975f5c5SAndroid Build Coastguard Worker     gl::Context *context = val->eglThread->getContext();
4431*8975f5c5SAndroid Build Coastguard Worker     if (!stream->isConsumerBoundToContext(context))
4432*8975f5c5SAndroid Build Coastguard Worker     {
4433*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_ACCESS, "Current GL context not associated with stream consumer");
4434*8975f5c5SAndroid Build Coastguard Worker         return false;
4435*8975f5c5SAndroid Build Coastguard Worker     }
4436*8975f5c5SAndroid Build Coastguard Worker 
4437*8975f5c5SAndroid Build Coastguard Worker     if (stream->getConsumerType() != Stream::ConsumerType::GLTextureRGB &&
4438*8975f5c5SAndroid Build Coastguard Worker         stream->getConsumerType() != Stream::ConsumerType::GLTextureYUV)
4439*8975f5c5SAndroid Build Coastguard Worker     {
4440*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_ACCESS, "Invalid stream consumer type");
4441*8975f5c5SAndroid Build Coastguard Worker         return false;
4442*8975f5c5SAndroid Build Coastguard Worker     }
4443*8975f5c5SAndroid Build Coastguard Worker 
4444*8975f5c5SAndroid Build Coastguard Worker     // Note: technically EGL_STREAM_STATE_EMPTY_KHR is a valid state when the timeout is non-zero.
4445*8975f5c5SAndroid Build Coastguard Worker     // However, the timeout is effectively ignored since it has no useful functionality with the
4446*8975f5c5SAndroid Build Coastguard Worker     // current producers that are implemented, so we don't allow that state
4447*8975f5c5SAndroid Build Coastguard Worker     if (stream->getState() != EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR &&
4448*8975f5c5SAndroid Build Coastguard Worker         stream->getState() != EGL_STREAM_STATE_OLD_FRAME_AVAILABLE_KHR)
4449*8975f5c5SAndroid Build Coastguard Worker     {
4450*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_STATE_KHR, "Invalid stream state");
4451*8975f5c5SAndroid Build Coastguard Worker         return false;
4452*8975f5c5SAndroid Build Coastguard Worker     }
4453*8975f5c5SAndroid Build Coastguard Worker 
4454*8975f5c5SAndroid Build Coastguard Worker     return true;
4455*8975f5c5SAndroid Build Coastguard Worker }
4456*8975f5c5SAndroid Build Coastguard Worker 
ValidateStreamConsumerReleaseKHR(const ValidationContext * val,const Display * display,const Stream * stream)4457*8975f5c5SAndroid Build Coastguard Worker bool ValidateStreamConsumerReleaseKHR(const ValidationContext *val,
4458*8975f5c5SAndroid Build Coastguard Worker                                       const Display *display,
4459*8975f5c5SAndroid Build Coastguard Worker                                       const Stream *stream)
4460*8975f5c5SAndroid Build Coastguard Worker {
4461*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
4462*8975f5c5SAndroid Build Coastguard Worker 
4463*8975f5c5SAndroid Build Coastguard Worker     const DisplayExtensions &displayExtensions = display->getExtensions();
4464*8975f5c5SAndroid Build Coastguard Worker     if (!displayExtensions.streamConsumerGLTexture)
4465*8975f5c5SAndroid Build Coastguard Worker     {
4466*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_ACCESS, "Stream consumer extension not active");
4467*8975f5c5SAndroid Build Coastguard Worker         return false;
4468*8975f5c5SAndroid Build Coastguard Worker     }
4469*8975f5c5SAndroid Build Coastguard Worker 
4470*8975f5c5SAndroid Build Coastguard Worker     if (stream == EGL_NO_STREAM_KHR || !display->isValidStream(stream))
4471*8975f5c5SAndroid Build Coastguard Worker     {
4472*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_STREAM_KHR, "Invalid stream");
4473*8975f5c5SAndroid Build Coastguard Worker         return false;
4474*8975f5c5SAndroid Build Coastguard Worker     }
4475*8975f5c5SAndroid Build Coastguard Worker 
4476*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateThreadContext(val, display, EGL_BAD_CONTEXT));
4477*8975f5c5SAndroid Build Coastguard Worker 
4478*8975f5c5SAndroid Build Coastguard Worker     gl::Context *context = val->eglThread->getContext();
4479*8975f5c5SAndroid Build Coastguard Worker     if (!stream->isConsumerBoundToContext(context))
4480*8975f5c5SAndroid Build Coastguard Worker     {
4481*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_ACCESS, "Current GL context not associated with stream consumer");
4482*8975f5c5SAndroid Build Coastguard Worker         return false;
4483*8975f5c5SAndroid Build Coastguard Worker     }
4484*8975f5c5SAndroid Build Coastguard Worker 
4485*8975f5c5SAndroid Build Coastguard Worker     if (stream->getConsumerType() != Stream::ConsumerType::GLTextureRGB &&
4486*8975f5c5SAndroid Build Coastguard Worker         stream->getConsumerType() != Stream::ConsumerType::GLTextureYUV)
4487*8975f5c5SAndroid Build Coastguard Worker     {
4488*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_ACCESS, "Invalid stream consumer type");
4489*8975f5c5SAndroid Build Coastguard Worker         return false;
4490*8975f5c5SAndroid Build Coastguard Worker     }
4491*8975f5c5SAndroid Build Coastguard Worker 
4492*8975f5c5SAndroid Build Coastguard Worker     if (stream->getState() != EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR &&
4493*8975f5c5SAndroid Build Coastguard Worker         stream->getState() != EGL_STREAM_STATE_OLD_FRAME_AVAILABLE_KHR)
4494*8975f5c5SAndroid Build Coastguard Worker     {
4495*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_STATE_KHR, "Invalid stream state");
4496*8975f5c5SAndroid Build Coastguard Worker         return false;
4497*8975f5c5SAndroid Build Coastguard Worker     }
4498*8975f5c5SAndroid Build Coastguard Worker 
4499*8975f5c5SAndroid Build Coastguard Worker     return true;
4500*8975f5c5SAndroid Build Coastguard Worker }
4501*8975f5c5SAndroid Build Coastguard Worker 
ValidateStreamConsumerGLTextureExternalAttribsNV(const ValidationContext * val,const Display * display,const Stream * stream,const AttributeMap & attribs)4502*8975f5c5SAndroid Build Coastguard Worker bool ValidateStreamConsumerGLTextureExternalAttribsNV(const ValidationContext *val,
4503*8975f5c5SAndroid Build Coastguard Worker                                                       const Display *display,
4504*8975f5c5SAndroid Build Coastguard Worker                                                       const Stream *stream,
4505*8975f5c5SAndroid Build Coastguard Worker                                                       const AttributeMap &attribs)
4506*8975f5c5SAndroid Build Coastguard Worker {
4507*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
4508*8975f5c5SAndroid Build Coastguard Worker 
4509*8975f5c5SAndroid Build Coastguard Worker     const DisplayExtensions &displayExtensions = display->getExtensions();
4510*8975f5c5SAndroid Build Coastguard Worker     if (!displayExtensions.streamConsumerGLTexture)
4511*8975f5c5SAndroid Build Coastguard Worker     {
4512*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_ACCESS, "Stream consumer extension not active");
4513*8975f5c5SAndroid Build Coastguard Worker         return false;
4514*8975f5c5SAndroid Build Coastguard Worker     }
4515*8975f5c5SAndroid Build Coastguard Worker 
4516*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateThreadContext(val, display, EGL_BAD_CONTEXT));
4517*8975f5c5SAndroid Build Coastguard Worker 
4518*8975f5c5SAndroid Build Coastguard Worker     // Although technically not a requirement in spec, the context needs to be checked for support
4519*8975f5c5SAndroid Build Coastguard Worker     // for external textures or future logic will cause assertions. This extension is also
4520*8975f5c5SAndroid Build Coastguard Worker     // effectively useless without external textures.
4521*8975f5c5SAndroid Build Coastguard Worker     gl::Context *context = val->eglThread->getContext();
4522*8975f5c5SAndroid Build Coastguard Worker     if (!context->getExtensions().EGLStreamConsumerExternalNV)
4523*8975f5c5SAndroid Build Coastguard Worker     {
4524*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_ACCESS, "EGL stream consumer external GL extension not enabled");
4525*8975f5c5SAndroid Build Coastguard Worker         return false;
4526*8975f5c5SAndroid Build Coastguard Worker     }
4527*8975f5c5SAndroid Build Coastguard Worker 
4528*8975f5c5SAndroid Build Coastguard Worker     if (stream == EGL_NO_STREAM_KHR || !display->isValidStream(stream))
4529*8975f5c5SAndroid Build Coastguard Worker     {
4530*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_STREAM_KHR, "Invalid stream");
4531*8975f5c5SAndroid Build Coastguard Worker         return false;
4532*8975f5c5SAndroid Build Coastguard Worker     }
4533*8975f5c5SAndroid Build Coastguard Worker 
4534*8975f5c5SAndroid Build Coastguard Worker     if (stream->getState() != EGL_STREAM_STATE_CREATED_KHR)
4535*8975f5c5SAndroid Build Coastguard Worker     {
4536*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_STATE_KHR, "Invalid stream state");
4537*8975f5c5SAndroid Build Coastguard Worker         return false;
4538*8975f5c5SAndroid Build Coastguard Worker     }
4539*8975f5c5SAndroid Build Coastguard Worker 
4540*8975f5c5SAndroid Build Coastguard Worker     const gl::Caps &glCaps = context->getCaps();
4541*8975f5c5SAndroid Build Coastguard Worker 
4542*8975f5c5SAndroid Build Coastguard Worker     EGLAttrib colorBufferType = EGL_RGB_BUFFER;
4543*8975f5c5SAndroid Build Coastguard Worker     EGLAttrib planeCount      = -1;
4544*8975f5c5SAndroid Build Coastguard Worker     EGLAttrib plane[3];
4545*8975f5c5SAndroid Build Coastguard Worker     for (int i = 0; i < 3; i++)
4546*8975f5c5SAndroid Build Coastguard Worker     {
4547*8975f5c5SAndroid Build Coastguard Worker         plane[i] = -1;
4548*8975f5c5SAndroid Build Coastguard Worker     }
4549*8975f5c5SAndroid Build Coastguard Worker 
4550*8975f5c5SAndroid Build Coastguard Worker     attribs.initializeWithoutValidation();
4551*8975f5c5SAndroid Build Coastguard Worker 
4552*8975f5c5SAndroid Build Coastguard Worker     for (const auto &attributeIter : attribs)
4553*8975f5c5SAndroid Build Coastguard Worker     {
4554*8975f5c5SAndroid Build Coastguard Worker         EGLAttrib attribute = attributeIter.first;
4555*8975f5c5SAndroid Build Coastguard Worker         EGLAttrib value     = attributeIter.second;
4556*8975f5c5SAndroid Build Coastguard Worker 
4557*8975f5c5SAndroid Build Coastguard Worker         switch (attribute)
4558*8975f5c5SAndroid Build Coastguard Worker         {
4559*8975f5c5SAndroid Build Coastguard Worker             case EGL_COLOR_BUFFER_TYPE:
4560*8975f5c5SAndroid Build Coastguard Worker                 if (value != EGL_RGB_BUFFER && value != EGL_YUV_BUFFER_EXT)
4561*8975f5c5SAndroid Build Coastguard Worker                 {
4562*8975f5c5SAndroid Build Coastguard Worker                     val->setError(EGL_BAD_PARAMETER, "Invalid color buffer type");
4563*8975f5c5SAndroid Build Coastguard Worker                     return false;
4564*8975f5c5SAndroid Build Coastguard Worker                 }
4565*8975f5c5SAndroid Build Coastguard Worker                 colorBufferType = value;
4566*8975f5c5SAndroid Build Coastguard Worker                 break;
4567*8975f5c5SAndroid Build Coastguard Worker             case EGL_YUV_NUMBER_OF_PLANES_EXT:
4568*8975f5c5SAndroid Build Coastguard Worker                 // planeCount = -1 is a tag for the default plane count so the value must be checked
4569*8975f5c5SAndroid Build Coastguard Worker                 // to be positive here to ensure future logic doesn't break on invalid negative
4570*8975f5c5SAndroid Build Coastguard Worker                 // inputs
4571*8975f5c5SAndroid Build Coastguard Worker                 if (value < 0)
4572*8975f5c5SAndroid Build Coastguard Worker                 {
4573*8975f5c5SAndroid Build Coastguard Worker                     val->setError(EGL_BAD_MATCH, "Invalid plane count");
4574*8975f5c5SAndroid Build Coastguard Worker                     return false;
4575*8975f5c5SAndroid Build Coastguard Worker                 }
4576*8975f5c5SAndroid Build Coastguard Worker                 planeCount = value;
4577*8975f5c5SAndroid Build Coastguard Worker                 break;
4578*8975f5c5SAndroid Build Coastguard Worker             default:
4579*8975f5c5SAndroid Build Coastguard Worker                 if (attribute >= EGL_YUV_PLANE0_TEXTURE_UNIT_NV &&
4580*8975f5c5SAndroid Build Coastguard Worker                     attribute <= EGL_YUV_PLANE2_TEXTURE_UNIT_NV)
4581*8975f5c5SAndroid Build Coastguard Worker                 {
4582*8975f5c5SAndroid Build Coastguard Worker                     if ((value < 0 ||
4583*8975f5c5SAndroid Build Coastguard Worker                          value >= static_cast<EGLAttrib>(glCaps.maxCombinedTextureImageUnits)) &&
4584*8975f5c5SAndroid Build Coastguard Worker                         value != EGL_NONE)
4585*8975f5c5SAndroid Build Coastguard Worker                     {
4586*8975f5c5SAndroid Build Coastguard Worker                         val->setError(EGL_BAD_ACCESS, "Invalid texture unit");
4587*8975f5c5SAndroid Build Coastguard Worker                         return false;
4588*8975f5c5SAndroid Build Coastguard Worker                     }
4589*8975f5c5SAndroid Build Coastguard Worker                     plane[attribute - EGL_YUV_PLANE0_TEXTURE_UNIT_NV] = value;
4590*8975f5c5SAndroid Build Coastguard Worker                 }
4591*8975f5c5SAndroid Build Coastguard Worker                 else
4592*8975f5c5SAndroid Build Coastguard Worker                 {
4593*8975f5c5SAndroid Build Coastguard Worker                     val->setError(EGL_BAD_ATTRIBUTE, "Invalid attribute");
4594*8975f5c5SAndroid Build Coastguard Worker                     return false;
4595*8975f5c5SAndroid Build Coastguard Worker                 }
4596*8975f5c5SAndroid Build Coastguard Worker         }
4597*8975f5c5SAndroid Build Coastguard Worker     }
4598*8975f5c5SAndroid Build Coastguard Worker 
4599*8975f5c5SAndroid Build Coastguard Worker     if (colorBufferType == EGL_RGB_BUFFER)
4600*8975f5c5SAndroid Build Coastguard Worker     {
4601*8975f5c5SAndroid Build Coastguard Worker         if (planeCount > 0)
4602*8975f5c5SAndroid Build Coastguard Worker         {
4603*8975f5c5SAndroid Build Coastguard Worker             val->setError(EGL_BAD_MATCH, "Plane count must be 0 for RGB buffer");
4604*8975f5c5SAndroid Build Coastguard Worker             return false;
4605*8975f5c5SAndroid Build Coastguard Worker         }
4606*8975f5c5SAndroid Build Coastguard Worker         for (int i = 0; i < 3; i++)
4607*8975f5c5SAndroid Build Coastguard Worker         {
4608*8975f5c5SAndroid Build Coastguard Worker             if (plane[i] != -1)
4609*8975f5c5SAndroid Build Coastguard Worker             {
4610*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_MATCH, "Planes cannot be specified");
4611*8975f5c5SAndroid Build Coastguard Worker                 return false;
4612*8975f5c5SAndroid Build Coastguard Worker             }
4613*8975f5c5SAndroid Build Coastguard Worker         }
4614*8975f5c5SAndroid Build Coastguard Worker 
4615*8975f5c5SAndroid Build Coastguard Worker         // Lookup the texture and ensure it is correct
4616*8975f5c5SAndroid Build Coastguard Worker         gl::Texture *texture = context->getState().getTargetTexture(gl::TextureType::External);
4617*8975f5c5SAndroid Build Coastguard Worker         if (texture == nullptr || texture->id().value == 0)
4618*8975f5c5SAndroid Build Coastguard Worker         {
4619*8975f5c5SAndroid Build Coastguard Worker             val->setError(EGL_BAD_ACCESS, "No external texture bound");
4620*8975f5c5SAndroid Build Coastguard Worker             return false;
4621*8975f5c5SAndroid Build Coastguard Worker         }
4622*8975f5c5SAndroid Build Coastguard Worker     }
4623*8975f5c5SAndroid Build Coastguard Worker     else
4624*8975f5c5SAndroid Build Coastguard Worker     {
4625*8975f5c5SAndroid Build Coastguard Worker         if (planeCount == -1)
4626*8975f5c5SAndroid Build Coastguard Worker         {
4627*8975f5c5SAndroid Build Coastguard Worker             planeCount = 2;
4628*8975f5c5SAndroid Build Coastguard Worker         }
4629*8975f5c5SAndroid Build Coastguard Worker         if (planeCount < 1 || planeCount > 3)
4630*8975f5c5SAndroid Build Coastguard Worker         {
4631*8975f5c5SAndroid Build Coastguard Worker             val->setError(EGL_BAD_MATCH, "Invalid YUV plane count");
4632*8975f5c5SAndroid Build Coastguard Worker             return false;
4633*8975f5c5SAndroid Build Coastguard Worker         }
4634*8975f5c5SAndroid Build Coastguard Worker         for (EGLAttrib i = planeCount; i < 3; i++)
4635*8975f5c5SAndroid Build Coastguard Worker         {
4636*8975f5c5SAndroid Build Coastguard Worker             if (plane[i] != -1)
4637*8975f5c5SAndroid Build Coastguard Worker             {
4638*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_MATCH, "Invalid plane specified");
4639*8975f5c5SAndroid Build Coastguard Worker                 return false;
4640*8975f5c5SAndroid Build Coastguard Worker             }
4641*8975f5c5SAndroid Build Coastguard Worker         }
4642*8975f5c5SAndroid Build Coastguard Worker 
4643*8975f5c5SAndroid Build Coastguard Worker         // Set to ensure no texture is referenced more than once
4644*8975f5c5SAndroid Build Coastguard Worker         std::set<gl::Texture *> textureSet;
4645*8975f5c5SAndroid Build Coastguard Worker         for (EGLAttrib i = 0; i < planeCount; i++)
4646*8975f5c5SAndroid Build Coastguard Worker         {
4647*8975f5c5SAndroid Build Coastguard Worker             if (plane[i] == -1)
4648*8975f5c5SAndroid Build Coastguard Worker             {
4649*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_MATCH, "Not all planes specified");
4650*8975f5c5SAndroid Build Coastguard Worker                 return false;
4651*8975f5c5SAndroid Build Coastguard Worker             }
4652*8975f5c5SAndroid Build Coastguard Worker             if (plane[i] != EGL_NONE)
4653*8975f5c5SAndroid Build Coastguard Worker             {
4654*8975f5c5SAndroid Build Coastguard Worker                 gl::Texture *texture = context->getState().getSamplerTexture(
4655*8975f5c5SAndroid Build Coastguard Worker                     static_cast<unsigned int>(plane[i]), gl::TextureType::External);
4656*8975f5c5SAndroid Build Coastguard Worker                 if (texture == nullptr || texture->id().value == 0)
4657*8975f5c5SAndroid Build Coastguard Worker                 {
4658*8975f5c5SAndroid Build Coastguard Worker                     val->setError(
4659*8975f5c5SAndroid Build Coastguard Worker                         EGL_BAD_ACCESS,
4660*8975f5c5SAndroid Build Coastguard Worker                         "No external texture bound at one or more specified texture units");
4661*8975f5c5SAndroid Build Coastguard Worker                     return false;
4662*8975f5c5SAndroid Build Coastguard Worker                 }
4663*8975f5c5SAndroid Build Coastguard Worker                 if (textureSet.find(texture) != textureSet.end())
4664*8975f5c5SAndroid Build Coastguard Worker                 {
4665*8975f5c5SAndroid Build Coastguard Worker                     val->setError(EGL_BAD_ACCESS, "Multiple planes bound to same texture object");
4666*8975f5c5SAndroid Build Coastguard Worker                     return false;
4667*8975f5c5SAndroid Build Coastguard Worker                 }
4668*8975f5c5SAndroid Build Coastguard Worker                 textureSet.insert(texture);
4669*8975f5c5SAndroid Build Coastguard Worker             }
4670*8975f5c5SAndroid Build Coastguard Worker         }
4671*8975f5c5SAndroid Build Coastguard Worker     }
4672*8975f5c5SAndroid Build Coastguard Worker 
4673*8975f5c5SAndroid Build Coastguard Worker     return true;
4674*8975f5c5SAndroid Build Coastguard Worker }
4675*8975f5c5SAndroid Build Coastguard Worker 
ValidateCreateStreamProducerD3DTextureANGLE(const ValidationContext * val,const Display * display,const Stream * stream,const AttributeMap & attribs)4676*8975f5c5SAndroid Build Coastguard Worker bool ValidateCreateStreamProducerD3DTextureANGLE(const ValidationContext *val,
4677*8975f5c5SAndroid Build Coastguard Worker                                                  const Display *display,
4678*8975f5c5SAndroid Build Coastguard Worker                                                  const Stream *stream,
4679*8975f5c5SAndroid Build Coastguard Worker                                                  const AttributeMap &attribs)
4680*8975f5c5SAndroid Build Coastguard Worker {
4681*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
4682*8975f5c5SAndroid Build Coastguard Worker 
4683*8975f5c5SAndroid Build Coastguard Worker     const DisplayExtensions &displayExtensions = display->getExtensions();
4684*8975f5c5SAndroid Build Coastguard Worker     if (!displayExtensions.streamProducerD3DTexture)
4685*8975f5c5SAndroid Build Coastguard Worker     {
4686*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_ACCESS, "Stream producer extension not active");
4687*8975f5c5SAndroid Build Coastguard Worker         return false;
4688*8975f5c5SAndroid Build Coastguard Worker     }
4689*8975f5c5SAndroid Build Coastguard Worker 
4690*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateStream(val, display, stream));
4691*8975f5c5SAndroid Build Coastguard Worker 
4692*8975f5c5SAndroid Build Coastguard Worker     attribs.initializeWithoutValidation();
4693*8975f5c5SAndroid Build Coastguard Worker 
4694*8975f5c5SAndroid Build Coastguard Worker     if (!attribs.isEmpty())
4695*8975f5c5SAndroid Build Coastguard Worker     {
4696*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_ATTRIBUTE, "Invalid attribute");
4697*8975f5c5SAndroid Build Coastguard Worker         return false;
4698*8975f5c5SAndroid Build Coastguard Worker     }
4699*8975f5c5SAndroid Build Coastguard Worker 
4700*8975f5c5SAndroid Build Coastguard Worker     if (stream->getState() != EGL_STREAM_STATE_CONNECTING_KHR)
4701*8975f5c5SAndroid Build Coastguard Worker     {
4702*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_STATE_KHR, "Stream not in connecting state");
4703*8975f5c5SAndroid Build Coastguard Worker         return false;
4704*8975f5c5SAndroid Build Coastguard Worker     }
4705*8975f5c5SAndroid Build Coastguard Worker 
4706*8975f5c5SAndroid Build Coastguard Worker     switch (stream->getConsumerType())
4707*8975f5c5SAndroid Build Coastguard Worker     {
4708*8975f5c5SAndroid Build Coastguard Worker         case Stream::ConsumerType::GLTextureYUV:
4709*8975f5c5SAndroid Build Coastguard Worker             if (stream->getPlaneCount() != 2)
4710*8975f5c5SAndroid Build Coastguard Worker             {
4711*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_MATCH, "Incompatible stream consumer type");
4712*8975f5c5SAndroid Build Coastguard Worker                 return false;
4713*8975f5c5SAndroid Build Coastguard Worker             }
4714*8975f5c5SAndroid Build Coastguard Worker             break;
4715*8975f5c5SAndroid Build Coastguard Worker 
4716*8975f5c5SAndroid Build Coastguard Worker         case Stream::ConsumerType::GLTextureRGB:
4717*8975f5c5SAndroid Build Coastguard Worker             if (stream->getPlaneCount() != 1)
4718*8975f5c5SAndroid Build Coastguard Worker             {
4719*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_MATCH, "Incompatible stream consumer type");
4720*8975f5c5SAndroid Build Coastguard Worker                 return false;
4721*8975f5c5SAndroid Build Coastguard Worker             }
4722*8975f5c5SAndroid Build Coastguard Worker             break;
4723*8975f5c5SAndroid Build Coastguard Worker 
4724*8975f5c5SAndroid Build Coastguard Worker         default:
4725*8975f5c5SAndroid Build Coastguard Worker             val->setError(EGL_BAD_MATCH, "Incompatible stream consumer type");
4726*8975f5c5SAndroid Build Coastguard Worker             return false;
4727*8975f5c5SAndroid Build Coastguard Worker     }
4728*8975f5c5SAndroid Build Coastguard Worker 
4729*8975f5c5SAndroid Build Coastguard Worker     return true;
4730*8975f5c5SAndroid Build Coastguard Worker }
4731*8975f5c5SAndroid Build Coastguard Worker 
ValidateStreamPostD3DTextureANGLE(const ValidationContext * val,const Display * display,const Stream * stream,const void * texture,const AttributeMap & attribs)4732*8975f5c5SAndroid Build Coastguard Worker bool ValidateStreamPostD3DTextureANGLE(const ValidationContext *val,
4733*8975f5c5SAndroid Build Coastguard Worker                                        const Display *display,
4734*8975f5c5SAndroid Build Coastguard Worker                                        const Stream *stream,
4735*8975f5c5SAndroid Build Coastguard Worker                                        const void *texture,
4736*8975f5c5SAndroid Build Coastguard Worker                                        const AttributeMap &attribs)
4737*8975f5c5SAndroid Build Coastguard Worker {
4738*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
4739*8975f5c5SAndroid Build Coastguard Worker 
4740*8975f5c5SAndroid Build Coastguard Worker     const DisplayExtensions &displayExtensions = display->getExtensions();
4741*8975f5c5SAndroid Build Coastguard Worker     if (!displayExtensions.streamProducerD3DTexture)
4742*8975f5c5SAndroid Build Coastguard Worker     {
4743*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_ACCESS, "Stream producer extension not active");
4744*8975f5c5SAndroid Build Coastguard Worker         return false;
4745*8975f5c5SAndroid Build Coastguard Worker     }
4746*8975f5c5SAndroid Build Coastguard Worker 
4747*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateStream(val, display, stream));
4748*8975f5c5SAndroid Build Coastguard Worker 
4749*8975f5c5SAndroid Build Coastguard Worker     attribs.initializeWithoutValidation();
4750*8975f5c5SAndroid Build Coastguard Worker 
4751*8975f5c5SAndroid Build Coastguard Worker     for (auto &attributeIter : attribs)
4752*8975f5c5SAndroid Build Coastguard Worker     {
4753*8975f5c5SAndroid Build Coastguard Worker         EGLAttrib attribute = attributeIter.first;
4754*8975f5c5SAndroid Build Coastguard Worker         EGLAttrib value     = attributeIter.second;
4755*8975f5c5SAndroid Build Coastguard Worker 
4756*8975f5c5SAndroid Build Coastguard Worker         switch (attribute)
4757*8975f5c5SAndroid Build Coastguard Worker         {
4758*8975f5c5SAndroid Build Coastguard Worker             case EGL_D3D_TEXTURE_SUBRESOURCE_ID_ANGLE:
4759*8975f5c5SAndroid Build Coastguard Worker                 if (value < 0)
4760*8975f5c5SAndroid Build Coastguard Worker                 {
4761*8975f5c5SAndroid Build Coastguard Worker                     val->setError(EGL_BAD_PARAMETER, "Invalid subresource index");
4762*8975f5c5SAndroid Build Coastguard Worker                     return false;
4763*8975f5c5SAndroid Build Coastguard Worker                 }
4764*8975f5c5SAndroid Build Coastguard Worker                 break;
4765*8975f5c5SAndroid Build Coastguard Worker             case EGL_NATIVE_BUFFER_PLANE_OFFSET_IMG:
4766*8975f5c5SAndroid Build Coastguard Worker                 if (value < 0)
4767*8975f5c5SAndroid Build Coastguard Worker                 {
4768*8975f5c5SAndroid Build Coastguard Worker                     val->setError(EGL_BAD_PARAMETER, "Invalid plane offset");
4769*8975f5c5SAndroid Build Coastguard Worker                     return false;
4770*8975f5c5SAndroid Build Coastguard Worker                 }
4771*8975f5c5SAndroid Build Coastguard Worker                 break;
4772*8975f5c5SAndroid Build Coastguard Worker             default:
4773*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE, "Invalid attribute");
4774*8975f5c5SAndroid Build Coastguard Worker                 return false;
4775*8975f5c5SAndroid Build Coastguard Worker         }
4776*8975f5c5SAndroid Build Coastguard Worker     }
4777*8975f5c5SAndroid Build Coastguard Worker 
4778*8975f5c5SAndroid Build Coastguard Worker     if (stream->getState() != EGL_STREAM_STATE_EMPTY_KHR &&
4779*8975f5c5SAndroid Build Coastguard Worker         stream->getState() != EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR &&
4780*8975f5c5SAndroid Build Coastguard Worker         stream->getState() != EGL_STREAM_STATE_OLD_FRAME_AVAILABLE_KHR)
4781*8975f5c5SAndroid Build Coastguard Worker     {
4782*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_STATE_KHR, "Stream not fully configured");
4783*8975f5c5SAndroid Build Coastguard Worker         return false;
4784*8975f5c5SAndroid Build Coastguard Worker     }
4785*8975f5c5SAndroid Build Coastguard Worker 
4786*8975f5c5SAndroid Build Coastguard Worker     if (stream->getProducerType() != Stream::ProducerType::D3D11Texture)
4787*8975f5c5SAndroid Build Coastguard Worker     {
4788*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_MATCH, "Incompatible stream producer");
4789*8975f5c5SAndroid Build Coastguard Worker         return false;
4790*8975f5c5SAndroid Build Coastguard Worker     }
4791*8975f5c5SAndroid Build Coastguard Worker 
4792*8975f5c5SAndroid Build Coastguard Worker     if (texture == nullptr)
4793*8975f5c5SAndroid Build Coastguard Worker     {
4794*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_PARAMETER, "Texture is null");
4795*8975f5c5SAndroid Build Coastguard Worker         return false;
4796*8975f5c5SAndroid Build Coastguard Worker     }
4797*8975f5c5SAndroid Build Coastguard Worker 
4798*8975f5c5SAndroid Build Coastguard Worker     ANGLE_EGL_TRY_RETURN(val->eglThread, stream->validateD3D11Texture(texture, attribs),
4799*8975f5c5SAndroid Build Coastguard Worker                          val->entryPoint, val->labeledObject, false);
4800*8975f5c5SAndroid Build Coastguard Worker 
4801*8975f5c5SAndroid Build Coastguard Worker     return true;
4802*8975f5c5SAndroid Build Coastguard Worker }
4803*8975f5c5SAndroid Build Coastguard Worker 
ValidateSyncControlCHROMIUM(const ValidationContext * val,const Display * display,SurfaceID surfaceID)4804*8975f5c5SAndroid Build Coastguard Worker bool ValidateSyncControlCHROMIUM(const ValidationContext *val,
4805*8975f5c5SAndroid Build Coastguard Worker                                  const Display *display,
4806*8975f5c5SAndroid Build Coastguard Worker                                  SurfaceID surfaceID)
4807*8975f5c5SAndroid Build Coastguard Worker {
4808*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateSurface(val, display, surfaceID));
4809*8975f5c5SAndroid Build Coastguard Worker 
4810*8975f5c5SAndroid Build Coastguard Worker     const DisplayExtensions &displayExtensions = display->getExtensions();
4811*8975f5c5SAndroid Build Coastguard Worker     if (!displayExtensions.syncControlCHROMIUM)
4812*8975f5c5SAndroid Build Coastguard Worker     {
4813*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_ACCESS, "syncControlCHROMIUM extension not active");
4814*8975f5c5SAndroid Build Coastguard Worker         return false;
4815*8975f5c5SAndroid Build Coastguard Worker     }
4816*8975f5c5SAndroid Build Coastguard Worker 
4817*8975f5c5SAndroid Build Coastguard Worker     return true;
4818*8975f5c5SAndroid Build Coastguard Worker }
4819*8975f5c5SAndroid Build Coastguard Worker 
ValidateSyncControlRateANGLE(const ValidationContext * val,const Display * display,SurfaceID surfaceID)4820*8975f5c5SAndroid Build Coastguard Worker bool ValidateSyncControlRateANGLE(const ValidationContext *val,
4821*8975f5c5SAndroid Build Coastguard Worker                                   const Display *display,
4822*8975f5c5SAndroid Build Coastguard Worker                                   SurfaceID surfaceID)
4823*8975f5c5SAndroid Build Coastguard Worker {
4824*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateSurface(val, display, surfaceID));
4825*8975f5c5SAndroid Build Coastguard Worker 
4826*8975f5c5SAndroid Build Coastguard Worker     const DisplayExtensions &displayExtensions = display->getExtensions();
4827*8975f5c5SAndroid Build Coastguard Worker     if (!displayExtensions.syncControlRateANGLE)
4828*8975f5c5SAndroid Build Coastguard Worker     {
4829*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_ACCESS, "syncControlRateANGLE extension not active");
4830*8975f5c5SAndroid Build Coastguard Worker         return false;
4831*8975f5c5SAndroid Build Coastguard Worker     }
4832*8975f5c5SAndroid Build Coastguard Worker 
4833*8975f5c5SAndroid Build Coastguard Worker     return true;
4834*8975f5c5SAndroid Build Coastguard Worker }
4835*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetMscRateANGLE(const ValidationContext * val,const Display * display,SurfaceID surfaceID,const EGLint * numerator,const EGLint * denominator)4836*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetMscRateANGLE(const ValidationContext *val,
4837*8975f5c5SAndroid Build Coastguard Worker                              const Display *display,
4838*8975f5c5SAndroid Build Coastguard Worker                              SurfaceID surfaceID,
4839*8975f5c5SAndroid Build Coastguard Worker                              const EGLint *numerator,
4840*8975f5c5SAndroid Build Coastguard Worker                              const EGLint *denominator)
4841*8975f5c5SAndroid Build Coastguard Worker {
4842*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateSyncControlRateANGLE(val, display, surfaceID));
4843*8975f5c5SAndroid Build Coastguard Worker 
4844*8975f5c5SAndroid Build Coastguard Worker     if (numerator == nullptr)
4845*8975f5c5SAndroid Build Coastguard Worker     {
4846*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_PARAMETER, "numerator is null");
4847*8975f5c5SAndroid Build Coastguard Worker         return false;
4848*8975f5c5SAndroid Build Coastguard Worker     }
4849*8975f5c5SAndroid Build Coastguard Worker     if (denominator == nullptr)
4850*8975f5c5SAndroid Build Coastguard Worker     {
4851*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_PARAMETER, "denominator is null");
4852*8975f5c5SAndroid Build Coastguard Worker         return false;
4853*8975f5c5SAndroid Build Coastguard Worker     }
4854*8975f5c5SAndroid Build Coastguard Worker 
4855*8975f5c5SAndroid Build Coastguard Worker     return true;
4856*8975f5c5SAndroid Build Coastguard Worker }
4857*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetSyncValuesCHROMIUM(const ValidationContext * val,const Display * display,SurfaceID surfaceID,const EGLuint64KHR * ust,const EGLuint64KHR * msc,const EGLuint64KHR * sbc)4858*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetSyncValuesCHROMIUM(const ValidationContext *val,
4859*8975f5c5SAndroid Build Coastguard Worker                                    const Display *display,
4860*8975f5c5SAndroid Build Coastguard Worker                                    SurfaceID surfaceID,
4861*8975f5c5SAndroid Build Coastguard Worker                                    const EGLuint64KHR *ust,
4862*8975f5c5SAndroid Build Coastguard Worker                                    const EGLuint64KHR *msc,
4863*8975f5c5SAndroid Build Coastguard Worker                                    const EGLuint64KHR *sbc)
4864*8975f5c5SAndroid Build Coastguard Worker {
4865*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateSyncControlCHROMIUM(val, display, surfaceID));
4866*8975f5c5SAndroid Build Coastguard Worker 
4867*8975f5c5SAndroid Build Coastguard Worker     if (ust == nullptr)
4868*8975f5c5SAndroid Build Coastguard Worker     {
4869*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_PARAMETER, "ust is null");
4870*8975f5c5SAndroid Build Coastguard Worker         return false;
4871*8975f5c5SAndroid Build Coastguard Worker     }
4872*8975f5c5SAndroid Build Coastguard Worker     if (msc == nullptr)
4873*8975f5c5SAndroid Build Coastguard Worker     {
4874*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_PARAMETER, "msc is null");
4875*8975f5c5SAndroid Build Coastguard Worker         return false;
4876*8975f5c5SAndroid Build Coastguard Worker     }
4877*8975f5c5SAndroid Build Coastguard Worker     if (sbc == nullptr)
4878*8975f5c5SAndroid Build Coastguard Worker     {
4879*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_PARAMETER, "sbc is null");
4880*8975f5c5SAndroid Build Coastguard Worker         return false;
4881*8975f5c5SAndroid Build Coastguard Worker     }
4882*8975f5c5SAndroid Build Coastguard Worker 
4883*8975f5c5SAndroid Build Coastguard Worker     return true;
4884*8975f5c5SAndroid Build Coastguard Worker }
4885*8975f5c5SAndroid Build Coastguard Worker 
ValidateDestroySurface(const ValidationContext * val,const Display * display,SurfaceID surfaceID)4886*8975f5c5SAndroid Build Coastguard Worker bool ValidateDestroySurface(const ValidationContext *val,
4887*8975f5c5SAndroid Build Coastguard Worker                             const Display *display,
4888*8975f5c5SAndroid Build Coastguard Worker                             SurfaceID surfaceID)
4889*8975f5c5SAndroid Build Coastguard Worker {
4890*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateSurface(val, display, surfaceID));
4891*8975f5c5SAndroid Build Coastguard Worker     return true;
4892*8975f5c5SAndroid Build Coastguard Worker }
4893*8975f5c5SAndroid Build Coastguard Worker 
ValidateDestroyContext(const ValidationContext * val,const Display * display,gl::ContextID contextID)4894*8975f5c5SAndroid Build Coastguard Worker bool ValidateDestroyContext(const ValidationContext *val,
4895*8975f5c5SAndroid Build Coastguard Worker                             const Display *display,
4896*8975f5c5SAndroid Build Coastguard Worker                             gl::ContextID contextID)
4897*8975f5c5SAndroid Build Coastguard Worker {
4898*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateContext(val, display, contextID));
4899*8975f5c5SAndroid Build Coastguard Worker     return true;
4900*8975f5c5SAndroid Build Coastguard Worker }
4901*8975f5c5SAndroid Build Coastguard Worker 
ValidateSwapBuffers(const ValidationContext * val,const Display * display,SurfaceID surfaceID)4902*8975f5c5SAndroid Build Coastguard Worker bool ValidateSwapBuffers(const ValidationContext *val, const Display *display, SurfaceID surfaceID)
4903*8975f5c5SAndroid Build Coastguard Worker {
4904*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateSurface(val, display, surfaceID));
4905*8975f5c5SAndroid Build Coastguard Worker 
4906*8975f5c5SAndroid Build Coastguard Worker     if (display->isDeviceLost())
4907*8975f5c5SAndroid Build Coastguard Worker     {
4908*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_CONTEXT_LOST);
4909*8975f5c5SAndroid Build Coastguard Worker         return false;
4910*8975f5c5SAndroid Build Coastguard Worker     }
4911*8975f5c5SAndroid Build Coastguard Worker 
4912*8975f5c5SAndroid Build Coastguard Worker     const Surface *eglSurface = display->getSurface(surfaceID);
4913*8975f5c5SAndroid Build Coastguard Worker     if (eglSurface->isLocked())
4914*8975f5c5SAndroid Build Coastguard Worker     {
4915*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_ACCESS);
4916*8975f5c5SAndroid Build Coastguard Worker         return false;
4917*8975f5c5SAndroid Build Coastguard Worker     }
4918*8975f5c5SAndroid Build Coastguard Worker 
4919*8975f5c5SAndroid Build Coastguard Worker     if (eglSurface == EGL_NO_SURFACE || !val->eglThread->getContext() ||
4920*8975f5c5SAndroid Build Coastguard Worker         val->eglThread->getCurrentDrawSurface() != eglSurface)
4921*8975f5c5SAndroid Build Coastguard Worker     {
4922*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_SURFACE);
4923*8975f5c5SAndroid Build Coastguard Worker         return false;
4924*8975f5c5SAndroid Build Coastguard Worker     }
4925*8975f5c5SAndroid Build Coastguard Worker 
4926*8975f5c5SAndroid Build Coastguard Worker     return true;
4927*8975f5c5SAndroid Build Coastguard Worker }
4928*8975f5c5SAndroid Build Coastguard Worker 
ValidateSwapBuffersWithDamageKHR(const ValidationContext * val,const Display * display,SurfaceID surfaceID,const EGLint * rects,EGLint n_rects)4929*8975f5c5SAndroid Build Coastguard Worker bool ValidateSwapBuffersWithDamageKHR(const ValidationContext *val,
4930*8975f5c5SAndroid Build Coastguard Worker                                       const Display *display,
4931*8975f5c5SAndroid Build Coastguard Worker                                       SurfaceID surfaceID,
4932*8975f5c5SAndroid Build Coastguard Worker                                       const EGLint *rects,
4933*8975f5c5SAndroid Build Coastguard Worker                                       EGLint n_rects)
4934*8975f5c5SAndroid Build Coastguard Worker {
4935*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateSurface(val, display, surfaceID));
4936*8975f5c5SAndroid Build Coastguard Worker 
4937*8975f5c5SAndroid Build Coastguard Worker     if (!display->getExtensions().swapBuffersWithDamage)
4938*8975f5c5SAndroid Build Coastguard Worker     {
4939*8975f5c5SAndroid Build Coastguard Worker         // It is out of spec what happens when calling an extension function when the extension is
4940*8975f5c5SAndroid Build Coastguard Worker         // not available. EGL_BAD_DISPLAY seems like a reasonable error.
4941*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_DISPLAY, "EGL_KHR_swap_buffers_with_damage is not available.");
4942*8975f5c5SAndroid Build Coastguard Worker         return false;
4943*8975f5c5SAndroid Build Coastguard Worker     }
4944*8975f5c5SAndroid Build Coastguard Worker 
4945*8975f5c5SAndroid Build Coastguard Worker     const Surface *surface = display->getSurface(surfaceID);
4946*8975f5c5SAndroid Build Coastguard Worker     if (surface == nullptr)
4947*8975f5c5SAndroid Build Coastguard Worker     {
4948*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_SURFACE, "Swap surface cannot be EGL_NO_SURFACE.");
4949*8975f5c5SAndroid Build Coastguard Worker         return false;
4950*8975f5c5SAndroid Build Coastguard Worker     }
4951*8975f5c5SAndroid Build Coastguard Worker 
4952*8975f5c5SAndroid Build Coastguard Worker     if (n_rects < 0)
4953*8975f5c5SAndroid Build Coastguard Worker     {
4954*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_PARAMETER, "n_rects cannot be negative.");
4955*8975f5c5SAndroid Build Coastguard Worker         return false;
4956*8975f5c5SAndroid Build Coastguard Worker     }
4957*8975f5c5SAndroid Build Coastguard Worker 
4958*8975f5c5SAndroid Build Coastguard Worker     if (n_rects > 0 && rects == nullptr)
4959*8975f5c5SAndroid Build Coastguard Worker     {
4960*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_PARAMETER, "n_rects cannot be greater than zero when rects is NULL.");
4961*8975f5c5SAndroid Build Coastguard Worker         return false;
4962*8975f5c5SAndroid Build Coastguard Worker     }
4963*8975f5c5SAndroid Build Coastguard Worker 
4964*8975f5c5SAndroid Build Coastguard Worker     if (surface->isLocked())
4965*8975f5c5SAndroid Build Coastguard Worker     {
4966*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_ACCESS);
4967*8975f5c5SAndroid Build Coastguard Worker         return false;
4968*8975f5c5SAndroid Build Coastguard Worker     }
4969*8975f5c5SAndroid Build Coastguard Worker 
4970*8975f5c5SAndroid Build Coastguard Worker     // TODO(jmadill): Validate Surface is bound to the thread.
4971*8975f5c5SAndroid Build Coastguard Worker 
4972*8975f5c5SAndroid Build Coastguard Worker     return true;
4973*8975f5c5SAndroid Build Coastguard Worker }
4974*8975f5c5SAndroid Build Coastguard Worker 
ValidateWaitNative(const ValidationContext * val,const EGLint engine)4975*8975f5c5SAndroid Build Coastguard Worker bool ValidateWaitNative(const ValidationContext *val, const EGLint engine)
4976*8975f5c5SAndroid Build Coastguard Worker {
4977*8975f5c5SAndroid Build Coastguard Worker     if (val->eglThread->getDisplay() == nullptr)
4978*8975f5c5SAndroid Build Coastguard Worker     {
4979*8975f5c5SAndroid Build Coastguard Worker         // EGL spec says this about eglWaitNative -
4980*8975f5c5SAndroid Build Coastguard Worker         //    eglWaitNative is ignored if there is no current EGL rendering context.
4981*8975f5c5SAndroid Build Coastguard Worker         return true;
4982*8975f5c5SAndroid Build Coastguard Worker     }
4983*8975f5c5SAndroid Build Coastguard Worker 
4984*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateDisplay(val, val->eglThread->getDisplay()));
4985*8975f5c5SAndroid Build Coastguard Worker 
4986*8975f5c5SAndroid Build Coastguard Worker     if (engine != EGL_CORE_NATIVE_ENGINE)
4987*8975f5c5SAndroid Build Coastguard Worker     {
4988*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_PARAMETER, "the 'engine' parameter has an unrecognized value");
4989*8975f5c5SAndroid Build Coastguard Worker         return false;
4990*8975f5c5SAndroid Build Coastguard Worker     }
4991*8975f5c5SAndroid Build Coastguard Worker 
4992*8975f5c5SAndroid Build Coastguard Worker     return true;
4993*8975f5c5SAndroid Build Coastguard Worker }
4994*8975f5c5SAndroid Build Coastguard Worker 
ValidateCopyBuffers(const ValidationContext * val,const Display * display,SurfaceID surfaceID,EGLNativePixmapType target)4995*8975f5c5SAndroid Build Coastguard Worker bool ValidateCopyBuffers(const ValidationContext *val,
4996*8975f5c5SAndroid Build Coastguard Worker                          const Display *display,
4997*8975f5c5SAndroid Build Coastguard Worker                          SurfaceID surfaceID,
4998*8975f5c5SAndroid Build Coastguard Worker                          EGLNativePixmapType target)
4999*8975f5c5SAndroid Build Coastguard Worker {
5000*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateSurface(val, display, surfaceID));
5001*8975f5c5SAndroid Build Coastguard Worker 
5002*8975f5c5SAndroid Build Coastguard Worker     if (display->isDeviceLost())
5003*8975f5c5SAndroid Build Coastguard Worker     {
5004*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_CONTEXT_LOST);
5005*8975f5c5SAndroid Build Coastguard Worker         return false;
5006*8975f5c5SAndroid Build Coastguard Worker     }
5007*8975f5c5SAndroid Build Coastguard Worker 
5008*8975f5c5SAndroid Build Coastguard Worker     return true;
5009*8975f5c5SAndroid Build Coastguard Worker }
5010*8975f5c5SAndroid Build Coastguard Worker 
ValidateBindTexImage(const ValidationContext * val,const Display * display,SurfaceID surfaceID,const EGLint buffer)5011*8975f5c5SAndroid Build Coastguard Worker bool ValidateBindTexImage(const ValidationContext *val,
5012*8975f5c5SAndroid Build Coastguard Worker                           const Display *display,
5013*8975f5c5SAndroid Build Coastguard Worker                           SurfaceID surfaceID,
5014*8975f5c5SAndroid Build Coastguard Worker                           const EGLint buffer)
5015*8975f5c5SAndroid Build Coastguard Worker {
5016*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateSurface(val, display, surfaceID));
5017*8975f5c5SAndroid Build Coastguard Worker 
5018*8975f5c5SAndroid Build Coastguard Worker     if (buffer != EGL_BACK_BUFFER)
5019*8975f5c5SAndroid Build Coastguard Worker     {
5020*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_PARAMETER);
5021*8975f5c5SAndroid Build Coastguard Worker         return false;
5022*8975f5c5SAndroid Build Coastguard Worker     }
5023*8975f5c5SAndroid Build Coastguard Worker 
5024*8975f5c5SAndroid Build Coastguard Worker     const Surface *surface = display->getSurface(surfaceID);
5025*8975f5c5SAndroid Build Coastguard Worker     if (surface->getType() == EGL_WINDOW_BIT)
5026*8975f5c5SAndroid Build Coastguard Worker     {
5027*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_SURFACE);
5028*8975f5c5SAndroid Build Coastguard Worker         return false;
5029*8975f5c5SAndroid Build Coastguard Worker     }
5030*8975f5c5SAndroid Build Coastguard Worker 
5031*8975f5c5SAndroid Build Coastguard Worker     if (surface->getBoundTexture())
5032*8975f5c5SAndroid Build Coastguard Worker     {
5033*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_ACCESS);
5034*8975f5c5SAndroid Build Coastguard Worker         return false;
5035*8975f5c5SAndroid Build Coastguard Worker     }
5036*8975f5c5SAndroid Build Coastguard Worker 
5037*8975f5c5SAndroid Build Coastguard Worker     if (surface->getTextureFormat() == TextureFormat::NoTexture)
5038*8975f5c5SAndroid Build Coastguard Worker     {
5039*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_MATCH);
5040*8975f5c5SAndroid Build Coastguard Worker         return false;
5041*8975f5c5SAndroid Build Coastguard Worker     }
5042*8975f5c5SAndroid Build Coastguard Worker 
5043*8975f5c5SAndroid Build Coastguard Worker     if (surface->isLocked())
5044*8975f5c5SAndroid Build Coastguard Worker     {
5045*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_ACCESS);
5046*8975f5c5SAndroid Build Coastguard Worker         return false;
5047*8975f5c5SAndroid Build Coastguard Worker     }
5048*8975f5c5SAndroid Build Coastguard Worker 
5049*8975f5c5SAndroid Build Coastguard Worker     gl::Context *context = val->eglThread->getContext();
5050*8975f5c5SAndroid Build Coastguard Worker     if (context && !context->isContextLost())
5051*8975f5c5SAndroid Build Coastguard Worker     {
5052*8975f5c5SAndroid Build Coastguard Worker         gl::TextureType type = egl_gl::EGLTextureTargetToTextureType(surface->getTextureTarget());
5053*8975f5c5SAndroid Build Coastguard Worker         gl::Texture *textureObject = context->getTextureByType(type);
5054*8975f5c5SAndroid Build Coastguard Worker         ASSERT(textureObject != nullptr);
5055*8975f5c5SAndroid Build Coastguard Worker 
5056*8975f5c5SAndroid Build Coastguard Worker         if (textureObject->getImmutableFormat())
5057*8975f5c5SAndroid Build Coastguard Worker         {
5058*8975f5c5SAndroid Build Coastguard Worker             val->setError(EGL_BAD_MATCH);
5059*8975f5c5SAndroid Build Coastguard Worker             return false;
5060*8975f5c5SAndroid Build Coastguard Worker         }
5061*8975f5c5SAndroid Build Coastguard Worker     }
5062*8975f5c5SAndroid Build Coastguard Worker 
5063*8975f5c5SAndroid Build Coastguard Worker     return true;
5064*8975f5c5SAndroid Build Coastguard Worker }
5065*8975f5c5SAndroid Build Coastguard Worker 
ValidateReleaseTexImage(const ValidationContext * val,const Display * display,SurfaceID surfaceID,const EGLint buffer)5066*8975f5c5SAndroid Build Coastguard Worker bool ValidateReleaseTexImage(const ValidationContext *val,
5067*8975f5c5SAndroid Build Coastguard Worker                              const Display *display,
5068*8975f5c5SAndroid Build Coastguard Worker                              SurfaceID surfaceID,
5069*8975f5c5SAndroid Build Coastguard Worker                              const EGLint buffer)
5070*8975f5c5SAndroid Build Coastguard Worker {
5071*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateSurface(val, display, surfaceID));
5072*8975f5c5SAndroid Build Coastguard Worker 
5073*8975f5c5SAndroid Build Coastguard Worker     if (buffer != EGL_BACK_BUFFER)
5074*8975f5c5SAndroid Build Coastguard Worker     {
5075*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_PARAMETER);
5076*8975f5c5SAndroid Build Coastguard Worker         return false;
5077*8975f5c5SAndroid Build Coastguard Worker     }
5078*8975f5c5SAndroid Build Coastguard Worker 
5079*8975f5c5SAndroid Build Coastguard Worker     const Surface *surface = display->getSurface(surfaceID);
5080*8975f5c5SAndroid Build Coastguard Worker     if (surface->getType() == EGL_WINDOW_BIT)
5081*8975f5c5SAndroid Build Coastguard Worker     {
5082*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_SURFACE);
5083*8975f5c5SAndroid Build Coastguard Worker         return false;
5084*8975f5c5SAndroid Build Coastguard Worker     }
5085*8975f5c5SAndroid Build Coastguard Worker 
5086*8975f5c5SAndroid Build Coastguard Worker     if (surface->getTextureFormat() == TextureFormat::NoTexture)
5087*8975f5c5SAndroid Build Coastguard Worker     {
5088*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_MATCH);
5089*8975f5c5SAndroid Build Coastguard Worker         return false;
5090*8975f5c5SAndroid Build Coastguard Worker     }
5091*8975f5c5SAndroid Build Coastguard Worker 
5092*8975f5c5SAndroid Build Coastguard Worker     return true;
5093*8975f5c5SAndroid Build Coastguard Worker }
5094*8975f5c5SAndroid Build Coastguard Worker 
ValidateSwapInterval(const ValidationContext * val,const Display * display,EGLint interval)5095*8975f5c5SAndroid Build Coastguard Worker bool ValidateSwapInterval(const ValidationContext *val, const Display *display, EGLint interval)
5096*8975f5c5SAndroid Build Coastguard Worker {
5097*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateThreadContext(val, display, EGL_BAD_CONTEXT));
5098*8975f5c5SAndroid Build Coastguard Worker 
5099*8975f5c5SAndroid Build Coastguard Worker     Surface *drawSurface = val->eglThread->getCurrentDrawSurface();
5100*8975f5c5SAndroid Build Coastguard Worker     if (drawSurface == nullptr)
5101*8975f5c5SAndroid Build Coastguard Worker     {
5102*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_SURFACE);
5103*8975f5c5SAndroid Build Coastguard Worker         return false;
5104*8975f5c5SAndroid Build Coastguard Worker     }
5105*8975f5c5SAndroid Build Coastguard Worker 
5106*8975f5c5SAndroid Build Coastguard Worker     return true;
5107*8975f5c5SAndroid Build Coastguard Worker }
5108*8975f5c5SAndroid Build Coastguard Worker 
ValidateBindAPI(const ValidationContext * val,const EGLenum api)5109*8975f5c5SAndroid Build Coastguard Worker bool ValidateBindAPI(const ValidationContext *val, const EGLenum api)
5110*8975f5c5SAndroid Build Coastguard Worker {
5111*8975f5c5SAndroid Build Coastguard Worker     switch (api)
5112*8975f5c5SAndroid Build Coastguard Worker     {
5113*8975f5c5SAndroid Build Coastguard Worker         case EGL_OPENGL_ES_API:
5114*8975f5c5SAndroid Build Coastguard Worker             break;
5115*8975f5c5SAndroid Build Coastguard Worker         case EGL_OPENVG_API:
5116*8975f5c5SAndroid Build Coastguard Worker             val->setError(EGL_BAD_PARAMETER);
5117*8975f5c5SAndroid Build Coastguard Worker             return false;  // Not supported by this implementation
5118*8975f5c5SAndroid Build Coastguard Worker         default:
5119*8975f5c5SAndroid Build Coastguard Worker             val->setError(EGL_BAD_PARAMETER);
5120*8975f5c5SAndroid Build Coastguard Worker             return false;
5121*8975f5c5SAndroid Build Coastguard Worker     }
5122*8975f5c5SAndroid Build Coastguard Worker 
5123*8975f5c5SAndroid Build Coastguard Worker     return true;
5124*8975f5c5SAndroid Build Coastguard Worker }
5125*8975f5c5SAndroid Build Coastguard Worker 
ValidatePresentationTimeANDROID(const ValidationContext * val,const Display * display,SurfaceID surfaceID,EGLnsecsANDROID time)5126*8975f5c5SAndroid Build Coastguard Worker bool ValidatePresentationTimeANDROID(const ValidationContext *val,
5127*8975f5c5SAndroid Build Coastguard Worker                                      const Display *display,
5128*8975f5c5SAndroid Build Coastguard Worker                                      SurfaceID surfaceID,
5129*8975f5c5SAndroid Build Coastguard Worker                                      EGLnsecsANDROID time)
5130*8975f5c5SAndroid Build Coastguard Worker {
5131*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
5132*8975f5c5SAndroid Build Coastguard Worker 
5133*8975f5c5SAndroid Build Coastguard Worker     if (!display->getExtensions().presentationTime)
5134*8975f5c5SAndroid Build Coastguard Worker     {
5135*8975f5c5SAndroid Build Coastguard Worker         // It is out of spec what happens when calling an extension function when the extension is
5136*8975f5c5SAndroid Build Coastguard Worker         // not available. EGL_BAD_DISPLAY seems like a reasonable error.
5137*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_DISPLAY, "EGL_ANDROID_presentation_time is not available.");
5138*8975f5c5SAndroid Build Coastguard Worker         return false;
5139*8975f5c5SAndroid Build Coastguard Worker     }
5140*8975f5c5SAndroid Build Coastguard Worker 
5141*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateSurface(val, display, surfaceID));
5142*8975f5c5SAndroid Build Coastguard Worker 
5143*8975f5c5SAndroid Build Coastguard Worker     return true;
5144*8975f5c5SAndroid Build Coastguard Worker }
5145*8975f5c5SAndroid Build Coastguard Worker 
ValidateSetBlobCacheFuncsANDROID(const ValidationContext * val,const Display * display,EGLSetBlobFuncANDROID set,EGLGetBlobFuncANDROID get)5146*8975f5c5SAndroid Build Coastguard Worker bool ValidateSetBlobCacheFuncsANDROID(const ValidationContext *val,
5147*8975f5c5SAndroid Build Coastguard Worker                                       const Display *display,
5148*8975f5c5SAndroid Build Coastguard Worker                                       EGLSetBlobFuncANDROID set,
5149*8975f5c5SAndroid Build Coastguard Worker                                       EGLGetBlobFuncANDROID get)
5150*8975f5c5SAndroid Build Coastguard Worker {
5151*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
5152*8975f5c5SAndroid Build Coastguard Worker 
5153*8975f5c5SAndroid Build Coastguard Worker     if (display->areBlobCacheFuncsSet())
5154*8975f5c5SAndroid Build Coastguard Worker     {
5155*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_PARAMETER,
5156*8975f5c5SAndroid Build Coastguard Worker                       "Blob cache functions can only be set once in the lifetime of a Display");
5157*8975f5c5SAndroid Build Coastguard Worker         return false;
5158*8975f5c5SAndroid Build Coastguard Worker     }
5159*8975f5c5SAndroid Build Coastguard Worker 
5160*8975f5c5SAndroid Build Coastguard Worker     if (set == nullptr || get == nullptr)
5161*8975f5c5SAndroid Build Coastguard Worker     {
5162*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_PARAMETER, "Blob cache callbacks cannot be null.");
5163*8975f5c5SAndroid Build Coastguard Worker         return false;
5164*8975f5c5SAndroid Build Coastguard Worker     }
5165*8975f5c5SAndroid Build Coastguard Worker 
5166*8975f5c5SAndroid Build Coastguard Worker     return true;
5167*8975f5c5SAndroid Build Coastguard Worker }
5168*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetConfigAttrib(const ValidationContext * val,const Display * display,const Config * config,EGLint attribute,const EGLint * value)5169*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetConfigAttrib(const ValidationContext *val,
5170*8975f5c5SAndroid Build Coastguard Worker                              const Display *display,
5171*8975f5c5SAndroid Build Coastguard Worker                              const Config *config,
5172*8975f5c5SAndroid Build Coastguard Worker                              EGLint attribute,
5173*8975f5c5SAndroid Build Coastguard Worker                              const EGLint *value)
5174*8975f5c5SAndroid Build Coastguard Worker {
5175*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateConfig(val, display, config));
5176*8975f5c5SAndroid Build Coastguard Worker     ANGLE_TRY(ValidateConfigAttribute(val, display, static_cast<EGLAttrib>(attribute)));
5177*8975f5c5SAndroid Build Coastguard Worker     return true;
5178*8975f5c5SAndroid Build Coastguard Worker }
5179*8975f5c5SAndroid Build Coastguard Worker 
ValidateChooseConfig(const ValidationContext * val,const Display * display,const AttributeMap & attribs,const EGLConfig * configs,EGLint configSize,const EGLint * numConfig)5180*8975f5c5SAndroid Build Coastguard Worker bool ValidateChooseConfig(const ValidationContext *val,
5181*8975f5c5SAndroid Build Coastguard Worker                           const Display *display,
5182*8975f5c5SAndroid Build Coastguard Worker                           const AttributeMap &attribs,
5183*8975f5c5SAndroid Build Coastguard Worker                           const EGLConfig *configs,
5184*8975f5c5SAndroid Build Coastguard Worker                           EGLint configSize,
5185*8975f5c5SAndroid Build Coastguard Worker                           const EGLint *numConfig)
5186*8975f5c5SAndroid Build Coastguard Worker {
5187*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
5188*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateConfigAttributes(val, display, attribs));
5189*8975f5c5SAndroid Build Coastguard Worker 
5190*8975f5c5SAndroid Build Coastguard Worker     if (numConfig == nullptr)
5191*8975f5c5SAndroid Build Coastguard Worker     {
5192*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_PARAMETER, "num_config cannot be null.");
5193*8975f5c5SAndroid Build Coastguard Worker         return false;
5194*8975f5c5SAndroid Build Coastguard Worker     }
5195*8975f5c5SAndroid Build Coastguard Worker 
5196*8975f5c5SAndroid Build Coastguard Worker     return true;
5197*8975f5c5SAndroid Build Coastguard Worker }
5198*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetConfigs(const ValidationContext * val,const Display * display,const EGLConfig * configs,EGLint configSize,const EGLint * numConfig)5199*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetConfigs(const ValidationContext *val,
5200*8975f5c5SAndroid Build Coastguard Worker                         const Display *display,
5201*8975f5c5SAndroid Build Coastguard Worker                         const EGLConfig *configs,
5202*8975f5c5SAndroid Build Coastguard Worker                         EGLint configSize,
5203*8975f5c5SAndroid Build Coastguard Worker                         const EGLint *numConfig)
5204*8975f5c5SAndroid Build Coastguard Worker {
5205*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
5206*8975f5c5SAndroid Build Coastguard Worker 
5207*8975f5c5SAndroid Build Coastguard Worker     if (numConfig == nullptr)
5208*8975f5c5SAndroid Build Coastguard Worker     {
5209*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_PARAMETER, "num_config cannot be null.");
5210*8975f5c5SAndroid Build Coastguard Worker         return false;
5211*8975f5c5SAndroid Build Coastguard Worker     }
5212*8975f5c5SAndroid Build Coastguard Worker 
5213*8975f5c5SAndroid Build Coastguard Worker     return true;
5214*8975f5c5SAndroid Build Coastguard Worker }
5215*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetPlatformDisplay(const ValidationContext * val,EGLenum platform,const void * native_display,const AttributeMap & attribMap)5216*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetPlatformDisplay(const ValidationContext *val,
5217*8975f5c5SAndroid Build Coastguard Worker                                 EGLenum platform,
5218*8975f5c5SAndroid Build Coastguard Worker                                 const void *native_display,
5219*8975f5c5SAndroid Build Coastguard Worker                                 const AttributeMap &attribMap)
5220*8975f5c5SAndroid Build Coastguard Worker {
5221*8975f5c5SAndroid Build Coastguard Worker     return ValidateGetPlatformDisplayCommon(val, platform, native_display, attribMap);
5222*8975f5c5SAndroid Build Coastguard Worker }
5223*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetPlatformDisplayEXT(const ValidationContext * val,EGLenum platform,const void * native_display,const AttributeMap & attribMap)5224*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetPlatformDisplayEXT(const ValidationContext *val,
5225*8975f5c5SAndroid Build Coastguard Worker                                    EGLenum platform,
5226*8975f5c5SAndroid Build Coastguard Worker                                    const void *native_display,
5227*8975f5c5SAndroid Build Coastguard Worker                                    const AttributeMap &attribMap)
5228*8975f5c5SAndroid Build Coastguard Worker {
5229*8975f5c5SAndroid Build Coastguard Worker     return ValidateGetPlatformDisplayCommon(val, platform, native_display, attribMap);
5230*8975f5c5SAndroid Build Coastguard Worker }
5231*8975f5c5SAndroid Build Coastguard Worker 
ValidateCreatePlatformWindowSurfaceEXT(const ValidationContext * val,const Display * display,const Config * configuration,const void * nativeWindow,const AttributeMap & attributes)5232*8975f5c5SAndroid Build Coastguard Worker bool ValidateCreatePlatformWindowSurfaceEXT(const ValidationContext *val,
5233*8975f5c5SAndroid Build Coastguard Worker                                             const Display *display,
5234*8975f5c5SAndroid Build Coastguard Worker                                             const Config *configuration,
5235*8975f5c5SAndroid Build Coastguard Worker                                             const void *nativeWindow,
5236*8975f5c5SAndroid Build Coastguard Worker                                             const AttributeMap &attributes)
5237*8975f5c5SAndroid Build Coastguard Worker {
5238*8975f5c5SAndroid Build Coastguard Worker     if (!Display::GetClientExtensions().platformBase)
5239*8975f5c5SAndroid Build Coastguard Worker     {
5240*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_ACCESS, "EGL_EXT_platform_base not supported");
5241*8975f5c5SAndroid Build Coastguard Worker         return false;
5242*8975f5c5SAndroid Build Coastguard Worker     }
5243*8975f5c5SAndroid Build Coastguard Worker 
5244*8975f5c5SAndroid Build Coastguard Worker     const void *actualNativeWindow =
5245*8975f5c5SAndroid Build Coastguard Worker         display->getImplementation()->getWindowSystem() == angle::NativeWindowSystem::X11
5246*8975f5c5SAndroid Build Coastguard Worker             ? *reinterpret_cast<const void *const *>(nativeWindow)
5247*8975f5c5SAndroid Build Coastguard Worker             : nativeWindow;
5248*8975f5c5SAndroid Build Coastguard Worker 
5249*8975f5c5SAndroid Build Coastguard Worker     return ValidateCreatePlatformWindowSurface(val, display, configuration, actualNativeWindow,
5250*8975f5c5SAndroid Build Coastguard Worker                                                attributes);
5251*8975f5c5SAndroid Build Coastguard Worker }
5252*8975f5c5SAndroid Build Coastguard Worker 
ValidateCreatePlatformPixmapSurfaceEXT(const ValidationContext * val,const Display * display,const Config * configuration,const void * nativePixmap,const AttributeMap & attributes)5253*8975f5c5SAndroid Build Coastguard Worker bool ValidateCreatePlatformPixmapSurfaceEXT(const ValidationContext *val,
5254*8975f5c5SAndroid Build Coastguard Worker                                             const Display *display,
5255*8975f5c5SAndroid Build Coastguard Worker                                             const Config *configuration,
5256*8975f5c5SAndroid Build Coastguard Worker                                             const void *nativePixmap,
5257*8975f5c5SAndroid Build Coastguard Worker                                             const AttributeMap &attributes)
5258*8975f5c5SAndroid Build Coastguard Worker {
5259*8975f5c5SAndroid Build Coastguard Worker     if (!Display::GetClientExtensions().platformBase)
5260*8975f5c5SAndroid Build Coastguard Worker     {
5261*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_ACCESS, "EGL_EXT_platform_base not supported");
5262*8975f5c5SAndroid Build Coastguard Worker         return false;
5263*8975f5c5SAndroid Build Coastguard Worker     }
5264*8975f5c5SAndroid Build Coastguard Worker 
5265*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateConfig(val, display, configuration));
5266*8975f5c5SAndroid Build Coastguard Worker 
5267*8975f5c5SAndroid Build Coastguard Worker     val->setError(EGL_BAD_DISPLAY, "ValidateCreatePlatformPixmapSurfaceEXT unimplemented.");
5268*8975f5c5SAndroid Build Coastguard Worker     return false;
5269*8975f5c5SAndroid Build Coastguard Worker }
5270*8975f5c5SAndroid Build Coastguard Worker 
ValidateProgramCacheGetAttribANGLE(const ValidationContext * val,const Display * display,EGLenum attrib)5271*8975f5c5SAndroid Build Coastguard Worker bool ValidateProgramCacheGetAttribANGLE(const ValidationContext *val,
5272*8975f5c5SAndroid Build Coastguard Worker                                         const Display *display,
5273*8975f5c5SAndroid Build Coastguard Worker                                         EGLenum attrib)
5274*8975f5c5SAndroid Build Coastguard Worker {
5275*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
5276*8975f5c5SAndroid Build Coastguard Worker 
5277*8975f5c5SAndroid Build Coastguard Worker     if (!display->getExtensions().programCacheControlANGLE)
5278*8975f5c5SAndroid Build Coastguard Worker     {
5279*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_ACCESS, "Extension not supported");
5280*8975f5c5SAndroid Build Coastguard Worker         return false;
5281*8975f5c5SAndroid Build Coastguard Worker     }
5282*8975f5c5SAndroid Build Coastguard Worker 
5283*8975f5c5SAndroid Build Coastguard Worker     switch (attrib)
5284*8975f5c5SAndroid Build Coastguard Worker     {
5285*8975f5c5SAndroid Build Coastguard Worker         case EGL_PROGRAM_CACHE_KEY_LENGTH_ANGLE:
5286*8975f5c5SAndroid Build Coastguard Worker         case EGL_PROGRAM_CACHE_SIZE_ANGLE:
5287*8975f5c5SAndroid Build Coastguard Worker             break;
5288*8975f5c5SAndroid Build Coastguard Worker 
5289*8975f5c5SAndroid Build Coastguard Worker         default:
5290*8975f5c5SAndroid Build Coastguard Worker             val->setError(EGL_BAD_PARAMETER, "Invalid program cache attribute.");
5291*8975f5c5SAndroid Build Coastguard Worker             return false;
5292*8975f5c5SAndroid Build Coastguard Worker     }
5293*8975f5c5SAndroid Build Coastguard Worker 
5294*8975f5c5SAndroid Build Coastguard Worker     return true;
5295*8975f5c5SAndroid Build Coastguard Worker }
5296*8975f5c5SAndroid Build Coastguard Worker 
ValidateProgramCacheQueryANGLE(const ValidationContext * val,const Display * display,EGLint index,const void * key,const EGLint * keysize,const void * binary,const EGLint * binarysize)5297*8975f5c5SAndroid Build Coastguard Worker bool ValidateProgramCacheQueryANGLE(const ValidationContext *val,
5298*8975f5c5SAndroid Build Coastguard Worker                                     const Display *display,
5299*8975f5c5SAndroid Build Coastguard Worker                                     EGLint index,
5300*8975f5c5SAndroid Build Coastguard Worker                                     const void *key,
5301*8975f5c5SAndroid Build Coastguard Worker                                     const EGLint *keysize,
5302*8975f5c5SAndroid Build Coastguard Worker                                     const void *binary,
5303*8975f5c5SAndroid Build Coastguard Worker                                     const EGLint *binarysize)
5304*8975f5c5SAndroid Build Coastguard Worker {
5305*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
5306*8975f5c5SAndroid Build Coastguard Worker 
5307*8975f5c5SAndroid Build Coastguard Worker     if (!display->getExtensions().programCacheControlANGLE)
5308*8975f5c5SAndroid Build Coastguard Worker     {
5309*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_ACCESS, "Extension not supported");
5310*8975f5c5SAndroid Build Coastguard Worker         return false;
5311*8975f5c5SAndroid Build Coastguard Worker     }
5312*8975f5c5SAndroid Build Coastguard Worker 
5313*8975f5c5SAndroid Build Coastguard Worker     if (index < 0 || index >= display->programCacheGetAttrib(EGL_PROGRAM_CACHE_SIZE_ANGLE))
5314*8975f5c5SAndroid Build Coastguard Worker     {
5315*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_PARAMETER, "Program index out of range.");
5316*8975f5c5SAndroid Build Coastguard Worker         return false;
5317*8975f5c5SAndroid Build Coastguard Worker     }
5318*8975f5c5SAndroid Build Coastguard Worker 
5319*8975f5c5SAndroid Build Coastguard Worker     if (keysize == nullptr || binarysize == nullptr)
5320*8975f5c5SAndroid Build Coastguard Worker     {
5321*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_PARAMETER, "keysize and binarysize must always be valid pointers.");
5322*8975f5c5SAndroid Build Coastguard Worker         return false;
5323*8975f5c5SAndroid Build Coastguard Worker     }
5324*8975f5c5SAndroid Build Coastguard Worker 
5325*8975f5c5SAndroid Build Coastguard Worker     if (binary && *keysize != static_cast<EGLint>(egl::BlobCache::kKeyLength))
5326*8975f5c5SAndroid Build Coastguard Worker     {
5327*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_PARAMETER, "Invalid program key size.");
5328*8975f5c5SAndroid Build Coastguard Worker         return false;
5329*8975f5c5SAndroid Build Coastguard Worker     }
5330*8975f5c5SAndroid Build Coastguard Worker 
5331*8975f5c5SAndroid Build Coastguard Worker     if ((key == nullptr) != (binary == nullptr))
5332*8975f5c5SAndroid Build Coastguard Worker     {
5333*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_PARAMETER, "key and binary must both be null or both non-null.");
5334*8975f5c5SAndroid Build Coastguard Worker         return false;
5335*8975f5c5SAndroid Build Coastguard Worker     }
5336*8975f5c5SAndroid Build Coastguard Worker 
5337*8975f5c5SAndroid Build Coastguard Worker     return true;
5338*8975f5c5SAndroid Build Coastguard Worker }
5339*8975f5c5SAndroid Build Coastguard Worker 
ValidateProgramCachePopulateANGLE(const ValidationContext * val,const Display * display,const void * key,EGLint keysize,const void * binary,EGLint binarysize)5340*8975f5c5SAndroid Build Coastguard Worker bool ValidateProgramCachePopulateANGLE(const ValidationContext *val,
5341*8975f5c5SAndroid Build Coastguard Worker                                        const Display *display,
5342*8975f5c5SAndroid Build Coastguard Worker                                        const void *key,
5343*8975f5c5SAndroid Build Coastguard Worker                                        EGLint keysize,
5344*8975f5c5SAndroid Build Coastguard Worker                                        const void *binary,
5345*8975f5c5SAndroid Build Coastguard Worker                                        EGLint binarysize)
5346*8975f5c5SAndroid Build Coastguard Worker {
5347*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
5348*8975f5c5SAndroid Build Coastguard Worker 
5349*8975f5c5SAndroid Build Coastguard Worker     if (!display->getExtensions().programCacheControlANGLE)
5350*8975f5c5SAndroid Build Coastguard Worker     {
5351*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_ACCESS, "Extension not supported");
5352*8975f5c5SAndroid Build Coastguard Worker         return false;
5353*8975f5c5SAndroid Build Coastguard Worker     }
5354*8975f5c5SAndroid Build Coastguard Worker 
5355*8975f5c5SAndroid Build Coastguard Worker     if (keysize != static_cast<EGLint>(egl::BlobCache::kKeyLength))
5356*8975f5c5SAndroid Build Coastguard Worker     {
5357*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_PARAMETER, "Invalid program key size.");
5358*8975f5c5SAndroid Build Coastguard Worker         return false;
5359*8975f5c5SAndroid Build Coastguard Worker     }
5360*8975f5c5SAndroid Build Coastguard Worker 
5361*8975f5c5SAndroid Build Coastguard Worker     if (key == nullptr || binary == nullptr)
5362*8975f5c5SAndroid Build Coastguard Worker     {
5363*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_PARAMETER, "null pointer in arguments.");
5364*8975f5c5SAndroid Build Coastguard Worker         return false;
5365*8975f5c5SAndroid Build Coastguard Worker     }
5366*8975f5c5SAndroid Build Coastguard Worker 
5367*8975f5c5SAndroid Build Coastguard Worker     // Upper bound for binarysize is arbitrary.
5368*8975f5c5SAndroid Build Coastguard Worker     if (binarysize <= 0 || binarysize > egl::kProgramCacheSizeAbsoluteMax)
5369*8975f5c5SAndroid Build Coastguard Worker     {
5370*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_PARAMETER, "binarysize out of valid range.");
5371*8975f5c5SAndroid Build Coastguard Worker         return false;
5372*8975f5c5SAndroid Build Coastguard Worker     }
5373*8975f5c5SAndroid Build Coastguard Worker 
5374*8975f5c5SAndroid Build Coastguard Worker     return true;
5375*8975f5c5SAndroid Build Coastguard Worker }
5376*8975f5c5SAndroid Build Coastguard Worker 
ValidateProgramCacheResizeANGLE(const ValidationContext * val,const Display * display,EGLint limit,EGLint mode)5377*8975f5c5SAndroid Build Coastguard Worker bool ValidateProgramCacheResizeANGLE(const ValidationContext *val,
5378*8975f5c5SAndroid Build Coastguard Worker                                      const Display *display,
5379*8975f5c5SAndroid Build Coastguard Worker                                      EGLint limit,
5380*8975f5c5SAndroid Build Coastguard Worker                                      EGLint mode)
5381*8975f5c5SAndroid Build Coastguard Worker {
5382*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
5383*8975f5c5SAndroid Build Coastguard Worker 
5384*8975f5c5SAndroid Build Coastguard Worker     if (!display->getExtensions().programCacheControlANGLE)
5385*8975f5c5SAndroid Build Coastguard Worker     {
5386*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_ACCESS, "Extension not supported");
5387*8975f5c5SAndroid Build Coastguard Worker         return false;
5388*8975f5c5SAndroid Build Coastguard Worker     }
5389*8975f5c5SAndroid Build Coastguard Worker 
5390*8975f5c5SAndroid Build Coastguard Worker     if (limit < 0)
5391*8975f5c5SAndroid Build Coastguard Worker     {
5392*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_PARAMETER, "limit must be non-negative.");
5393*8975f5c5SAndroid Build Coastguard Worker         return false;
5394*8975f5c5SAndroid Build Coastguard Worker     }
5395*8975f5c5SAndroid Build Coastguard Worker 
5396*8975f5c5SAndroid Build Coastguard Worker     switch (mode)
5397*8975f5c5SAndroid Build Coastguard Worker     {
5398*8975f5c5SAndroid Build Coastguard Worker         case EGL_PROGRAM_CACHE_RESIZE_ANGLE:
5399*8975f5c5SAndroid Build Coastguard Worker         case EGL_PROGRAM_CACHE_TRIM_ANGLE:
5400*8975f5c5SAndroid Build Coastguard Worker             break;
5401*8975f5c5SAndroid Build Coastguard Worker 
5402*8975f5c5SAndroid Build Coastguard Worker         default:
5403*8975f5c5SAndroid Build Coastguard Worker             val->setError(EGL_BAD_PARAMETER, "Invalid cache resize mode.");
5404*8975f5c5SAndroid Build Coastguard Worker             return false;
5405*8975f5c5SAndroid Build Coastguard Worker     }
5406*8975f5c5SAndroid Build Coastguard Worker 
5407*8975f5c5SAndroid Build Coastguard Worker     return true;
5408*8975f5c5SAndroid Build Coastguard Worker }
5409*8975f5c5SAndroid Build Coastguard Worker 
ValidateSurfaceAttrib(const ValidationContext * val,const Display * display,SurfaceID surfaceID,EGLint attribute,EGLint value)5410*8975f5c5SAndroid Build Coastguard Worker bool ValidateSurfaceAttrib(const ValidationContext *val,
5411*8975f5c5SAndroid Build Coastguard Worker                            const Display *display,
5412*8975f5c5SAndroid Build Coastguard Worker                            SurfaceID surfaceID,
5413*8975f5c5SAndroid Build Coastguard Worker                            EGLint attribute,
5414*8975f5c5SAndroid Build Coastguard Worker                            EGLint value)
5415*8975f5c5SAndroid Build Coastguard Worker {
5416*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
5417*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateSurface(val, display, surfaceID));
5418*8975f5c5SAndroid Build Coastguard Worker 
5419*8975f5c5SAndroid Build Coastguard Worker     const Surface *surface = display->getSurface(surfaceID);
5420*8975f5c5SAndroid Build Coastguard Worker     if (surface == EGL_NO_SURFACE)
5421*8975f5c5SAndroid Build Coastguard Worker     {
5422*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_SURFACE, "Surface cannot be EGL_NO_SURFACE.");
5423*8975f5c5SAndroid Build Coastguard Worker         return false;
5424*8975f5c5SAndroid Build Coastguard Worker     }
5425*8975f5c5SAndroid Build Coastguard Worker 
5426*8975f5c5SAndroid Build Coastguard Worker     switch (attribute)
5427*8975f5c5SAndroid Build Coastguard Worker     {
5428*8975f5c5SAndroid Build Coastguard Worker         case EGL_MIPMAP_LEVEL:
5429*8975f5c5SAndroid Build Coastguard Worker             break;
5430*8975f5c5SAndroid Build Coastguard Worker 
5431*8975f5c5SAndroid Build Coastguard Worker         case EGL_MULTISAMPLE_RESOLVE:
5432*8975f5c5SAndroid Build Coastguard Worker             switch (value)
5433*8975f5c5SAndroid Build Coastguard Worker             {
5434*8975f5c5SAndroid Build Coastguard Worker                 case EGL_MULTISAMPLE_RESOLVE_DEFAULT:
5435*8975f5c5SAndroid Build Coastguard Worker                     break;
5436*8975f5c5SAndroid Build Coastguard Worker 
5437*8975f5c5SAndroid Build Coastguard Worker                 case EGL_MULTISAMPLE_RESOLVE_BOX:
5438*8975f5c5SAndroid Build Coastguard Worker                     if ((surface->getConfig()->surfaceType & EGL_MULTISAMPLE_RESOLVE_BOX_BIT) == 0)
5439*8975f5c5SAndroid Build Coastguard Worker                     {
5440*8975f5c5SAndroid Build Coastguard Worker                         val->setError(EGL_BAD_MATCH,
5441*8975f5c5SAndroid Build Coastguard Worker                                       "Surface does not support EGL_MULTISAMPLE_RESOLVE_BOX.");
5442*8975f5c5SAndroid Build Coastguard Worker                         return false;
5443*8975f5c5SAndroid Build Coastguard Worker                     }
5444*8975f5c5SAndroid Build Coastguard Worker                     break;
5445*8975f5c5SAndroid Build Coastguard Worker 
5446*8975f5c5SAndroid Build Coastguard Worker                 default:
5447*8975f5c5SAndroid Build Coastguard Worker                     val->setError(EGL_BAD_ATTRIBUTE, "Invalid multisample resolve type.");
5448*8975f5c5SAndroid Build Coastguard Worker                     return false;
5449*8975f5c5SAndroid Build Coastguard Worker             }
5450*8975f5c5SAndroid Build Coastguard Worker             break;
5451*8975f5c5SAndroid Build Coastguard Worker 
5452*8975f5c5SAndroid Build Coastguard Worker         case EGL_SWAP_BEHAVIOR:
5453*8975f5c5SAndroid Build Coastguard Worker             switch (value)
5454*8975f5c5SAndroid Build Coastguard Worker             {
5455*8975f5c5SAndroid Build Coastguard Worker                 case EGL_BUFFER_PRESERVED:
5456*8975f5c5SAndroid Build Coastguard Worker                     if ((surface->getConfig()->surfaceType & EGL_SWAP_BEHAVIOR_PRESERVED_BIT) == 0)
5457*8975f5c5SAndroid Build Coastguard Worker                     {
5458*8975f5c5SAndroid Build Coastguard Worker                         val->setError(EGL_BAD_MATCH,
5459*8975f5c5SAndroid Build Coastguard Worker                                       "Surface does not support EGL_SWAP_BEHAVIOR_PRESERVED.");
5460*8975f5c5SAndroid Build Coastguard Worker                         return false;
5461*8975f5c5SAndroid Build Coastguard Worker                     }
5462*8975f5c5SAndroid Build Coastguard Worker                     break;
5463*8975f5c5SAndroid Build Coastguard Worker 
5464*8975f5c5SAndroid Build Coastguard Worker                 case EGL_BUFFER_DESTROYED:
5465*8975f5c5SAndroid Build Coastguard Worker                     break;
5466*8975f5c5SAndroid Build Coastguard Worker 
5467*8975f5c5SAndroid Build Coastguard Worker                 default:
5468*8975f5c5SAndroid Build Coastguard Worker                     val->setError(EGL_BAD_ATTRIBUTE, "Invalid swap behaviour.");
5469*8975f5c5SAndroid Build Coastguard Worker                     return false;
5470*8975f5c5SAndroid Build Coastguard Worker             }
5471*8975f5c5SAndroid Build Coastguard Worker             break;
5472*8975f5c5SAndroid Build Coastguard Worker 
5473*8975f5c5SAndroid Build Coastguard Worker         case EGL_WIDTH:
5474*8975f5c5SAndroid Build Coastguard Worker         case EGL_HEIGHT:
5475*8975f5c5SAndroid Build Coastguard Worker             if (!display->getExtensions().windowFixedSize)
5476*8975f5c5SAndroid Build Coastguard Worker             {
5477*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE,
5478*8975f5c5SAndroid Build Coastguard Worker                               "EGL_WIDTH or EGL_HEIGHT cannot be set without "
5479*8975f5c5SAndroid Build Coastguard Worker                               "EGL_ANGLE_window_fixed_size support.");
5480*8975f5c5SAndroid Build Coastguard Worker                 return false;
5481*8975f5c5SAndroid Build Coastguard Worker             }
5482*8975f5c5SAndroid Build Coastguard Worker             if (!surface->isFixedSize())
5483*8975f5c5SAndroid Build Coastguard Worker             {
5484*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_MATCH,
5485*8975f5c5SAndroid Build Coastguard Worker                               "EGL_WIDTH or EGL_HEIGHT cannot be set without "
5486*8975f5c5SAndroid Build Coastguard Worker                               "EGL_FIXED_SIZE_ANGLE being enabled on the surface.");
5487*8975f5c5SAndroid Build Coastguard Worker                 return false;
5488*8975f5c5SAndroid Build Coastguard Worker             }
5489*8975f5c5SAndroid Build Coastguard Worker             break;
5490*8975f5c5SAndroid Build Coastguard Worker 
5491*8975f5c5SAndroid Build Coastguard Worker         case EGL_TIMESTAMPS_ANDROID:
5492*8975f5c5SAndroid Build Coastguard Worker             if (!display->getExtensions().getFrameTimestamps &&
5493*8975f5c5SAndroid Build Coastguard Worker                 !display->getExtensions().timestampSurfaceAttributeANGLE)
5494*8975f5c5SAndroid Build Coastguard Worker             {
5495*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE,
5496*8975f5c5SAndroid Build Coastguard Worker                               "EGL_TIMESTAMPS_ANDROID cannot be used without "
5497*8975f5c5SAndroid Build Coastguard Worker                               "EGL_ANDROID_get_frame_timestamps support.");
5498*8975f5c5SAndroid Build Coastguard Worker                 return false;
5499*8975f5c5SAndroid Build Coastguard Worker             }
5500*8975f5c5SAndroid Build Coastguard Worker             switch (value)
5501*8975f5c5SAndroid Build Coastguard Worker             {
5502*8975f5c5SAndroid Build Coastguard Worker                 case EGL_TRUE:
5503*8975f5c5SAndroid Build Coastguard Worker                 case EGL_FALSE:
5504*8975f5c5SAndroid Build Coastguard Worker                     break;
5505*8975f5c5SAndroid Build Coastguard Worker 
5506*8975f5c5SAndroid Build Coastguard Worker                 default:
5507*8975f5c5SAndroid Build Coastguard Worker                     val->setError(EGL_BAD_ATTRIBUTE, "Invalid value.");
5508*8975f5c5SAndroid Build Coastguard Worker                     return false;
5509*8975f5c5SAndroid Build Coastguard Worker             }
5510*8975f5c5SAndroid Build Coastguard Worker             break;
5511*8975f5c5SAndroid Build Coastguard Worker 
5512*8975f5c5SAndroid Build Coastguard Worker         case EGL_FRONT_BUFFER_AUTO_REFRESH_ANDROID:
5513*8975f5c5SAndroid Build Coastguard Worker             if (!display->getExtensions().frontBufferAutoRefreshANDROID)
5514*8975f5c5SAndroid Build Coastguard Worker             {
5515*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE,
5516*8975f5c5SAndroid Build Coastguard Worker                               "EGL_FRONT_BUFFER_AUTO_REFRESH_ANDROID cannot be used without "
5517*8975f5c5SAndroid Build Coastguard Worker                               "EGL_ANDROID_front_buffer_auto_refresh support.");
5518*8975f5c5SAndroid Build Coastguard Worker                 return false;
5519*8975f5c5SAndroid Build Coastguard Worker             }
5520*8975f5c5SAndroid Build Coastguard Worker             switch (value)
5521*8975f5c5SAndroid Build Coastguard Worker             {
5522*8975f5c5SAndroid Build Coastguard Worker                 case EGL_TRUE:
5523*8975f5c5SAndroid Build Coastguard Worker                 case EGL_FALSE:
5524*8975f5c5SAndroid Build Coastguard Worker                     break;
5525*8975f5c5SAndroid Build Coastguard Worker 
5526*8975f5c5SAndroid Build Coastguard Worker                 default:
5527*8975f5c5SAndroid Build Coastguard Worker                     val->setError(EGL_BAD_ATTRIBUTE, "Invalid value.");
5528*8975f5c5SAndroid Build Coastguard Worker                     return false;
5529*8975f5c5SAndroid Build Coastguard Worker             }
5530*8975f5c5SAndroid Build Coastguard Worker             break;
5531*8975f5c5SAndroid Build Coastguard Worker 
5532*8975f5c5SAndroid Build Coastguard Worker         case EGL_RENDER_BUFFER:
5533*8975f5c5SAndroid Build Coastguard Worker             if (value != EGL_BACK_BUFFER && value != EGL_SINGLE_BUFFER)
5534*8975f5c5SAndroid Build Coastguard Worker             {
5535*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE,
5536*8975f5c5SAndroid Build Coastguard Worker                               "EGL_RENDER_BUFFER must be EGL_BACK_BUFFER or EGL_SINGLE_BUFFER.");
5537*8975f5c5SAndroid Build Coastguard Worker                 return false;
5538*8975f5c5SAndroid Build Coastguard Worker             }
5539*8975f5c5SAndroid Build Coastguard Worker 
5540*8975f5c5SAndroid Build Coastguard Worker             if (value == EGL_SINGLE_BUFFER)
5541*8975f5c5SAndroid Build Coastguard Worker             {
5542*8975f5c5SAndroid Build Coastguard Worker                 if (!display->getExtensions().mutableRenderBufferKHR)
5543*8975f5c5SAndroid Build Coastguard Worker                 {
5544*8975f5c5SAndroid Build Coastguard Worker                     val->setError(
5545*8975f5c5SAndroid Build Coastguard Worker                         EGL_BAD_ATTRIBUTE,
5546*8975f5c5SAndroid Build Coastguard Worker                         "Attribute EGL_RENDER_BUFFER requires EGL_KHR_mutable_render_buffer.");
5547*8975f5c5SAndroid Build Coastguard Worker                     return false;
5548*8975f5c5SAndroid Build Coastguard Worker                 }
5549*8975f5c5SAndroid Build Coastguard Worker 
5550*8975f5c5SAndroid Build Coastguard Worker                 if ((surface->getConfig()->surfaceType & EGL_MUTABLE_RENDER_BUFFER_BIT_KHR) == 0)
5551*8975f5c5SAndroid Build Coastguard Worker                 {
5552*8975f5c5SAndroid Build Coastguard Worker                     val->setError(EGL_BAD_MATCH,
5553*8975f5c5SAndroid Build Coastguard Worker                                   "EGL_RENDER_BUFFER requires the surface type bit "
5554*8975f5c5SAndroid Build Coastguard Worker                                   "EGL_MUTABLE_RENDER_BUFFER_BIT_KHR.");
5555*8975f5c5SAndroid Build Coastguard Worker                     return false;
5556*8975f5c5SAndroid Build Coastguard Worker                 }
5557*8975f5c5SAndroid Build Coastguard Worker             }
5558*8975f5c5SAndroid Build Coastguard Worker             break;
5559*8975f5c5SAndroid Build Coastguard Worker 
5560*8975f5c5SAndroid Build Coastguard Worker         default:
5561*8975f5c5SAndroid Build Coastguard Worker             val->setError(EGL_BAD_ATTRIBUTE, "Invalid surface attribute: 0x%04X", attribute);
5562*8975f5c5SAndroid Build Coastguard Worker             return false;
5563*8975f5c5SAndroid Build Coastguard Worker     }
5564*8975f5c5SAndroid Build Coastguard Worker 
5565*8975f5c5SAndroid Build Coastguard Worker     return true;
5566*8975f5c5SAndroid Build Coastguard Worker }
5567*8975f5c5SAndroid Build Coastguard Worker 
ValidateQuerySurface(const ValidationContext * val,const Display * display,SurfaceID surfaceID,EGLint attribute,const EGLint * value)5568*8975f5c5SAndroid Build Coastguard Worker bool ValidateQuerySurface(const ValidationContext *val,
5569*8975f5c5SAndroid Build Coastguard Worker                           const Display *display,
5570*8975f5c5SAndroid Build Coastguard Worker                           SurfaceID surfaceID,
5571*8975f5c5SAndroid Build Coastguard Worker                           EGLint attribute,
5572*8975f5c5SAndroid Build Coastguard Worker                           const EGLint *value)
5573*8975f5c5SAndroid Build Coastguard Worker {
5574*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
5575*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateSurface(val, display, surfaceID));
5576*8975f5c5SAndroid Build Coastguard Worker 
5577*8975f5c5SAndroid Build Coastguard Worker     const Surface *surface = display->getSurface(surfaceID);
5578*8975f5c5SAndroid Build Coastguard Worker     if (surface == EGL_NO_SURFACE)
5579*8975f5c5SAndroid Build Coastguard Worker     {
5580*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_SURFACE, "Surface cannot be EGL_NO_SURFACE.");
5581*8975f5c5SAndroid Build Coastguard Worker         return false;
5582*8975f5c5SAndroid Build Coastguard Worker     }
5583*8975f5c5SAndroid Build Coastguard Worker 
5584*8975f5c5SAndroid Build Coastguard Worker     switch (attribute)
5585*8975f5c5SAndroid Build Coastguard Worker     {
5586*8975f5c5SAndroid Build Coastguard Worker         case EGL_GL_COLORSPACE:
5587*8975f5c5SAndroid Build Coastguard Worker         case EGL_VG_ALPHA_FORMAT:
5588*8975f5c5SAndroid Build Coastguard Worker         case EGL_VG_COLORSPACE:
5589*8975f5c5SAndroid Build Coastguard Worker         case EGL_CONFIG_ID:
5590*8975f5c5SAndroid Build Coastguard Worker         case EGL_HEIGHT:
5591*8975f5c5SAndroid Build Coastguard Worker         case EGL_HORIZONTAL_RESOLUTION:
5592*8975f5c5SAndroid Build Coastguard Worker         case EGL_LARGEST_PBUFFER:
5593*8975f5c5SAndroid Build Coastguard Worker         case EGL_MIPMAP_TEXTURE:
5594*8975f5c5SAndroid Build Coastguard Worker         case EGL_MIPMAP_LEVEL:
5595*8975f5c5SAndroid Build Coastguard Worker         case EGL_MULTISAMPLE_RESOLVE:
5596*8975f5c5SAndroid Build Coastguard Worker         case EGL_PIXEL_ASPECT_RATIO:
5597*8975f5c5SAndroid Build Coastguard Worker         case EGL_RENDER_BUFFER:
5598*8975f5c5SAndroid Build Coastguard Worker         case EGL_SWAP_BEHAVIOR:
5599*8975f5c5SAndroid Build Coastguard Worker         case EGL_TEXTURE_FORMAT:
5600*8975f5c5SAndroid Build Coastguard Worker         case EGL_TEXTURE_TARGET:
5601*8975f5c5SAndroid Build Coastguard Worker         case EGL_VERTICAL_RESOLUTION:
5602*8975f5c5SAndroid Build Coastguard Worker         case EGL_WIDTH:
5603*8975f5c5SAndroid Build Coastguard Worker             break;
5604*8975f5c5SAndroid Build Coastguard Worker 
5605*8975f5c5SAndroid Build Coastguard Worker         case EGL_POST_SUB_BUFFER_SUPPORTED_NV:
5606*8975f5c5SAndroid Build Coastguard Worker             if (!display->getExtensions().postSubBuffer)
5607*8975f5c5SAndroid Build Coastguard Worker             {
5608*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE,
5609*8975f5c5SAndroid Build Coastguard Worker                               "EGL_POST_SUB_BUFFER_SUPPORTED_NV cannot be used "
5610*8975f5c5SAndroid Build Coastguard Worker                               "without EGL_ANGLE_surface_orientation support.");
5611*8975f5c5SAndroid Build Coastguard Worker                 return false;
5612*8975f5c5SAndroid Build Coastguard Worker             }
5613*8975f5c5SAndroid Build Coastguard Worker             break;
5614*8975f5c5SAndroid Build Coastguard Worker 
5615*8975f5c5SAndroid Build Coastguard Worker         case EGL_FIXED_SIZE_ANGLE:
5616*8975f5c5SAndroid Build Coastguard Worker             if (!display->getExtensions().windowFixedSize)
5617*8975f5c5SAndroid Build Coastguard Worker             {
5618*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE,
5619*8975f5c5SAndroid Build Coastguard Worker                               "EGL_FIXED_SIZE_ANGLE cannot be used without "
5620*8975f5c5SAndroid Build Coastguard Worker                               "EGL_ANGLE_window_fixed_size support.");
5621*8975f5c5SAndroid Build Coastguard Worker                 return false;
5622*8975f5c5SAndroid Build Coastguard Worker             }
5623*8975f5c5SAndroid Build Coastguard Worker             break;
5624*8975f5c5SAndroid Build Coastguard Worker 
5625*8975f5c5SAndroid Build Coastguard Worker         case EGL_SURFACE_ORIENTATION_ANGLE:
5626*8975f5c5SAndroid Build Coastguard Worker             if (!display->getExtensions().surfaceOrientation)
5627*8975f5c5SAndroid Build Coastguard Worker             {
5628*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE,
5629*8975f5c5SAndroid Build Coastguard Worker                               "EGL_SURFACE_ORIENTATION_ANGLE cannot be "
5630*8975f5c5SAndroid Build Coastguard Worker                               "queried without "
5631*8975f5c5SAndroid Build Coastguard Worker                               "EGL_ANGLE_surface_orientation support.");
5632*8975f5c5SAndroid Build Coastguard Worker                 return false;
5633*8975f5c5SAndroid Build Coastguard Worker             }
5634*8975f5c5SAndroid Build Coastguard Worker             break;
5635*8975f5c5SAndroid Build Coastguard Worker 
5636*8975f5c5SAndroid Build Coastguard Worker         case EGL_DIRECT_COMPOSITION_ANGLE:
5637*8975f5c5SAndroid Build Coastguard Worker             if (!display->getExtensions().directComposition)
5638*8975f5c5SAndroid Build Coastguard Worker             {
5639*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE,
5640*8975f5c5SAndroid Build Coastguard Worker                               "EGL_DIRECT_COMPOSITION_ANGLE cannot be "
5641*8975f5c5SAndroid Build Coastguard Worker                               "used without "
5642*8975f5c5SAndroid Build Coastguard Worker                               "EGL_ANGLE_direct_composition support.");
5643*8975f5c5SAndroid Build Coastguard Worker                 return false;
5644*8975f5c5SAndroid Build Coastguard Worker             }
5645*8975f5c5SAndroid Build Coastguard Worker             break;
5646*8975f5c5SAndroid Build Coastguard Worker 
5647*8975f5c5SAndroid Build Coastguard Worker         case EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
5648*8975f5c5SAndroid Build Coastguard Worker             if (!display->getExtensions().robustResourceInitializationANGLE)
5649*8975f5c5SAndroid Build Coastguard Worker             {
5650*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE,
5651*8975f5c5SAndroid Build Coastguard Worker                               "EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE cannot be "
5652*8975f5c5SAndroid Build Coastguard Worker                               "used without EGL_ANGLE_robust_resource_initialization "
5653*8975f5c5SAndroid Build Coastguard Worker                               "support.");
5654*8975f5c5SAndroid Build Coastguard Worker                 return false;
5655*8975f5c5SAndroid Build Coastguard Worker             }
5656*8975f5c5SAndroid Build Coastguard Worker             break;
5657*8975f5c5SAndroid Build Coastguard Worker 
5658*8975f5c5SAndroid Build Coastguard Worker         case EGL_TIMESTAMPS_ANDROID:
5659*8975f5c5SAndroid Build Coastguard Worker             if (!display->getExtensions().getFrameTimestamps &&
5660*8975f5c5SAndroid Build Coastguard Worker                 !display->getExtensions().timestampSurfaceAttributeANGLE)
5661*8975f5c5SAndroid Build Coastguard Worker             {
5662*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE,
5663*8975f5c5SAndroid Build Coastguard Worker                               "EGL_TIMESTAMPS_ANDROID cannot be used without "
5664*8975f5c5SAndroid Build Coastguard Worker                               "EGL_ANDROID_get_frame_timestamps support.");
5665*8975f5c5SAndroid Build Coastguard Worker                 return false;
5666*8975f5c5SAndroid Build Coastguard Worker             }
5667*8975f5c5SAndroid Build Coastguard Worker             break;
5668*8975f5c5SAndroid Build Coastguard Worker 
5669*8975f5c5SAndroid Build Coastguard Worker         case EGL_BUFFER_AGE_EXT:
5670*8975f5c5SAndroid Build Coastguard Worker         {
5671*8975f5c5SAndroid Build Coastguard Worker             if (!display->getExtensions().bufferAgeEXT)
5672*8975f5c5SAndroid Build Coastguard Worker             {
5673*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE,
5674*8975f5c5SAndroid Build Coastguard Worker                               "EGL_BUFFER_AGE_EXT cannot be used without "
5675*8975f5c5SAndroid Build Coastguard Worker                               "EGL_EXT_buffer_age support.");
5676*8975f5c5SAndroid Build Coastguard Worker                 return false;
5677*8975f5c5SAndroid Build Coastguard Worker             }
5678*8975f5c5SAndroid Build Coastguard Worker             gl::Context *context = val->eglThread->getContext();
5679*8975f5c5SAndroid Build Coastguard Worker             if ((context == nullptr) || (context->getCurrentDrawSurface() != surface))
5680*8975f5c5SAndroid Build Coastguard Worker             {
5681*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_SURFACE,
5682*8975f5c5SAndroid Build Coastguard Worker                               "The surface must be current to the current context "
5683*8975f5c5SAndroid Build Coastguard Worker                               "in order to query buffer age per extension "
5684*8975f5c5SAndroid Build Coastguard Worker                               "EGL_EXT_buffer_age.");
5685*8975f5c5SAndroid Build Coastguard Worker                 return false;
5686*8975f5c5SAndroid Build Coastguard Worker             }
5687*8975f5c5SAndroid Build Coastguard Worker         }
5688*8975f5c5SAndroid Build Coastguard Worker         break;
5689*8975f5c5SAndroid Build Coastguard Worker 
5690*8975f5c5SAndroid Build Coastguard Worker         case EGL_BITMAP_PITCH_KHR:
5691*8975f5c5SAndroid Build Coastguard Worker         case EGL_BITMAP_ORIGIN_KHR:
5692*8975f5c5SAndroid Build Coastguard Worker         case EGL_BITMAP_PIXEL_RED_OFFSET_KHR:
5693*8975f5c5SAndroid Build Coastguard Worker         case EGL_BITMAP_PIXEL_GREEN_OFFSET_KHR:
5694*8975f5c5SAndroid Build Coastguard Worker         case EGL_BITMAP_PIXEL_BLUE_OFFSET_KHR:
5695*8975f5c5SAndroid Build Coastguard Worker         case EGL_BITMAP_PIXEL_ALPHA_OFFSET_KHR:
5696*8975f5c5SAndroid Build Coastguard Worker         case EGL_BITMAP_PIXEL_LUMINANCE_OFFSET_KHR:
5697*8975f5c5SAndroid Build Coastguard Worker         case EGL_BITMAP_PIXEL_SIZE_KHR:
5698*8975f5c5SAndroid Build Coastguard Worker             if (!display->getExtensions().lockSurface3KHR)
5699*8975f5c5SAndroid Build Coastguard Worker             {
5700*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE, "EGL_KHR_lock_surface3 is not supported.");
5701*8975f5c5SAndroid Build Coastguard Worker                 return false;
5702*8975f5c5SAndroid Build Coastguard Worker             }
5703*8975f5c5SAndroid Build Coastguard Worker             break;
5704*8975f5c5SAndroid Build Coastguard Worker 
5705*8975f5c5SAndroid Build Coastguard Worker         case EGL_PROTECTED_CONTENT_EXT:
5706*8975f5c5SAndroid Build Coastguard Worker             if (!display->getExtensions().protectedContentEXT)
5707*8975f5c5SAndroid Build Coastguard Worker             {
5708*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE, "EGL_EXT_protected_content not supported");
5709*8975f5c5SAndroid Build Coastguard Worker                 return false;
5710*8975f5c5SAndroid Build Coastguard Worker             }
5711*8975f5c5SAndroid Build Coastguard Worker             break;
5712*8975f5c5SAndroid Build Coastguard Worker 
5713*8975f5c5SAndroid Build Coastguard Worker         default:
5714*8975f5c5SAndroid Build Coastguard Worker             val->setError(EGL_BAD_ATTRIBUTE, "Invalid query surface attribute: 0x%04X", attribute);
5715*8975f5c5SAndroid Build Coastguard Worker             return false;
5716*8975f5c5SAndroid Build Coastguard Worker     }
5717*8975f5c5SAndroid Build Coastguard Worker 
5718*8975f5c5SAndroid Build Coastguard Worker     return true;
5719*8975f5c5SAndroid Build Coastguard Worker }
5720*8975f5c5SAndroid Build Coastguard Worker 
ValidateQueryContext(const ValidationContext * val,const Display * display,gl::ContextID contextID,EGLint attribute,const EGLint * value)5721*8975f5c5SAndroid Build Coastguard Worker bool ValidateQueryContext(const ValidationContext *val,
5722*8975f5c5SAndroid Build Coastguard Worker                           const Display *display,
5723*8975f5c5SAndroid Build Coastguard Worker                           gl::ContextID contextID,
5724*8975f5c5SAndroid Build Coastguard Worker                           EGLint attribute,
5725*8975f5c5SAndroid Build Coastguard Worker                           const EGLint *value)
5726*8975f5c5SAndroid Build Coastguard Worker {
5727*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateContext(val, display, contextID));
5728*8975f5c5SAndroid Build Coastguard Worker 
5729*8975f5c5SAndroid Build Coastguard Worker     switch (attribute)
5730*8975f5c5SAndroid Build Coastguard Worker     {
5731*8975f5c5SAndroid Build Coastguard Worker         case EGL_CONFIG_ID:
5732*8975f5c5SAndroid Build Coastguard Worker         case EGL_CONTEXT_CLIENT_TYPE:
5733*8975f5c5SAndroid Build Coastguard Worker         case EGL_CONTEXT_MAJOR_VERSION:
5734*8975f5c5SAndroid Build Coastguard Worker         case EGL_CONTEXT_MINOR_VERSION:
5735*8975f5c5SAndroid Build Coastguard Worker         case EGL_RENDER_BUFFER:
5736*8975f5c5SAndroid Build Coastguard Worker             break;
5737*8975f5c5SAndroid Build Coastguard Worker 
5738*8975f5c5SAndroid Build Coastguard Worker         case EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
5739*8975f5c5SAndroid Build Coastguard Worker             if (!display->getExtensions().robustResourceInitializationANGLE)
5740*8975f5c5SAndroid Build Coastguard Worker             {
5741*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE,
5742*8975f5c5SAndroid Build Coastguard Worker                               "EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE cannot be "
5743*8975f5c5SAndroid Build Coastguard Worker                               "used without EGL_ANGLE_robust_resource_initialization "
5744*8975f5c5SAndroid Build Coastguard Worker                               "support.");
5745*8975f5c5SAndroid Build Coastguard Worker                 return false;
5746*8975f5c5SAndroid Build Coastguard Worker             }
5747*8975f5c5SAndroid Build Coastguard Worker             break;
5748*8975f5c5SAndroid Build Coastguard Worker 
5749*8975f5c5SAndroid Build Coastguard Worker         case EGL_CONTEXT_PRIORITY_LEVEL_IMG:
5750*8975f5c5SAndroid Build Coastguard Worker             if (!display->getExtensions().contextPriority)
5751*8975f5c5SAndroid Build Coastguard Worker             {
5752*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE,
5753*8975f5c5SAndroid Build Coastguard Worker                               "Attribute EGL_CONTEXT_PRIORITY_LEVEL_IMG requires "
5754*8975f5c5SAndroid Build Coastguard Worker                               "extension EGL_IMG_context_priority.");
5755*8975f5c5SAndroid Build Coastguard Worker                 return false;
5756*8975f5c5SAndroid Build Coastguard Worker             }
5757*8975f5c5SAndroid Build Coastguard Worker             break;
5758*8975f5c5SAndroid Build Coastguard Worker 
5759*8975f5c5SAndroid Build Coastguard Worker         case EGL_PROTECTED_CONTENT_EXT:
5760*8975f5c5SAndroid Build Coastguard Worker             if (!display->getExtensions().protectedContentEXT)
5761*8975f5c5SAndroid Build Coastguard Worker             {
5762*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE, "EGL_EXT_protected_content not supported");
5763*8975f5c5SAndroid Build Coastguard Worker                 return false;
5764*8975f5c5SAndroid Build Coastguard Worker             }
5765*8975f5c5SAndroid Build Coastguard Worker             break;
5766*8975f5c5SAndroid Build Coastguard Worker 
5767*8975f5c5SAndroid Build Coastguard Worker         default:
5768*8975f5c5SAndroid Build Coastguard Worker             val->setError(EGL_BAD_ATTRIBUTE, "Invalid context attribute: 0x%04X", attribute);
5769*8975f5c5SAndroid Build Coastguard Worker             return false;
5770*8975f5c5SAndroid Build Coastguard Worker     }
5771*8975f5c5SAndroid Build Coastguard Worker 
5772*8975f5c5SAndroid Build Coastguard Worker     return true;
5773*8975f5c5SAndroid Build Coastguard Worker }
5774*8975f5c5SAndroid Build Coastguard Worker 
ValidateDebugMessageControlKHR(const ValidationContext * val,EGLDEBUGPROCKHR callback,const AttributeMap & attribs)5775*8975f5c5SAndroid Build Coastguard Worker bool ValidateDebugMessageControlKHR(const ValidationContext *val,
5776*8975f5c5SAndroid Build Coastguard Worker                                     EGLDEBUGPROCKHR callback,
5777*8975f5c5SAndroid Build Coastguard Worker                                     const AttributeMap &attribs)
5778*8975f5c5SAndroid Build Coastguard Worker {
5779*8975f5c5SAndroid Build Coastguard Worker     const ClientExtensions &clientExtensions = Display::GetClientExtensions();
5780*8975f5c5SAndroid Build Coastguard Worker     if (!clientExtensions.debug)
5781*8975f5c5SAndroid Build Coastguard Worker     {
5782*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_ACCESS, "EGL_KHR_debug extension is not available.");
5783*8975f5c5SAndroid Build Coastguard Worker         return false;
5784*8975f5c5SAndroid Build Coastguard Worker     }
5785*8975f5c5SAndroid Build Coastguard Worker 
5786*8975f5c5SAndroid Build Coastguard Worker     attribs.initializeWithoutValidation();
5787*8975f5c5SAndroid Build Coastguard Worker 
5788*8975f5c5SAndroid Build Coastguard Worker     for (const auto &attrib : attribs)
5789*8975f5c5SAndroid Build Coastguard Worker     {
5790*8975f5c5SAndroid Build Coastguard Worker         switch (attrib.first)
5791*8975f5c5SAndroid Build Coastguard Worker         {
5792*8975f5c5SAndroid Build Coastguard Worker             case EGL_DEBUG_MSG_CRITICAL_KHR:
5793*8975f5c5SAndroid Build Coastguard Worker             case EGL_DEBUG_MSG_ERROR_KHR:
5794*8975f5c5SAndroid Build Coastguard Worker             case EGL_DEBUG_MSG_WARN_KHR:
5795*8975f5c5SAndroid Build Coastguard Worker             case EGL_DEBUG_MSG_INFO_KHR:
5796*8975f5c5SAndroid Build Coastguard Worker                 if (attrib.second != EGL_TRUE && attrib.second != EGL_FALSE)
5797*8975f5c5SAndroid Build Coastguard Worker                 {
5798*8975f5c5SAndroid Build Coastguard Worker                     val->setError(EGL_BAD_ATTRIBUTE,
5799*8975f5c5SAndroid Build Coastguard Worker                                   "message controls must be EGL_TRUE or EGL_FALSE.");
5800*8975f5c5SAndroid Build Coastguard Worker                     return false;
5801*8975f5c5SAndroid Build Coastguard Worker                 }
5802*8975f5c5SAndroid Build Coastguard Worker                 break;
5803*8975f5c5SAndroid Build Coastguard Worker         }
5804*8975f5c5SAndroid Build Coastguard Worker     }
5805*8975f5c5SAndroid Build Coastguard Worker 
5806*8975f5c5SAndroid Build Coastguard Worker     return true;
5807*8975f5c5SAndroid Build Coastguard Worker }
5808*8975f5c5SAndroid Build Coastguard Worker 
ValidateQueryDebugKHR(const ValidationContext * val,EGLint attribute,const EGLAttrib * value)5809*8975f5c5SAndroid Build Coastguard Worker bool ValidateQueryDebugKHR(const ValidationContext *val, EGLint attribute, const EGLAttrib *value)
5810*8975f5c5SAndroid Build Coastguard Worker {
5811*8975f5c5SAndroid Build Coastguard Worker     const ClientExtensions &clientExtensions = Display::GetClientExtensions();
5812*8975f5c5SAndroid Build Coastguard Worker     if (!clientExtensions.debug)
5813*8975f5c5SAndroid Build Coastguard Worker     {
5814*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_ACCESS, "EGL_KHR_debug extension is not available.");
5815*8975f5c5SAndroid Build Coastguard Worker         return false;
5816*8975f5c5SAndroid Build Coastguard Worker     }
5817*8975f5c5SAndroid Build Coastguard Worker 
5818*8975f5c5SAndroid Build Coastguard Worker     switch (attribute)
5819*8975f5c5SAndroid Build Coastguard Worker     {
5820*8975f5c5SAndroid Build Coastguard Worker         case EGL_DEBUG_MSG_CRITICAL_KHR:
5821*8975f5c5SAndroid Build Coastguard Worker         case EGL_DEBUG_MSG_ERROR_KHR:
5822*8975f5c5SAndroid Build Coastguard Worker         case EGL_DEBUG_MSG_WARN_KHR:
5823*8975f5c5SAndroid Build Coastguard Worker         case EGL_DEBUG_MSG_INFO_KHR:
5824*8975f5c5SAndroid Build Coastguard Worker         case EGL_DEBUG_CALLBACK_KHR:
5825*8975f5c5SAndroid Build Coastguard Worker             break;
5826*8975f5c5SAndroid Build Coastguard Worker 
5827*8975f5c5SAndroid Build Coastguard Worker         default:
5828*8975f5c5SAndroid Build Coastguard Worker             val->setError(EGL_BAD_ATTRIBUTE, "Unknown attribute: 0x%04X", attribute);
5829*8975f5c5SAndroid Build Coastguard Worker             return false;
5830*8975f5c5SAndroid Build Coastguard Worker     }
5831*8975f5c5SAndroid Build Coastguard Worker 
5832*8975f5c5SAndroid Build Coastguard Worker     return true;
5833*8975f5c5SAndroid Build Coastguard Worker }
5834*8975f5c5SAndroid Build Coastguard Worker 
ValidateLabelObjectKHR(const ValidationContext * val,const Display * display,ObjectType objectType,EGLObjectKHR object,EGLLabelKHR label)5835*8975f5c5SAndroid Build Coastguard Worker bool ValidateLabelObjectKHR(const ValidationContext *val,
5836*8975f5c5SAndroid Build Coastguard Worker                             const Display *display,
5837*8975f5c5SAndroid Build Coastguard Worker                             ObjectType objectType,
5838*8975f5c5SAndroid Build Coastguard Worker                             EGLObjectKHR object,
5839*8975f5c5SAndroid Build Coastguard Worker                             EGLLabelKHR label)
5840*8975f5c5SAndroid Build Coastguard Worker {
5841*8975f5c5SAndroid Build Coastguard Worker     const ClientExtensions &clientExtensions = Display::GetClientExtensions();
5842*8975f5c5SAndroid Build Coastguard Worker     if (!clientExtensions.debug)
5843*8975f5c5SAndroid Build Coastguard Worker     {
5844*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_ACCESS, "EGL_KHR_debug extension is not available.");
5845*8975f5c5SAndroid Build Coastguard Worker         return false;
5846*8975f5c5SAndroid Build Coastguard Worker     }
5847*8975f5c5SAndroid Build Coastguard Worker 
5848*8975f5c5SAndroid Build Coastguard Worker     const LabeledObject *labeledObject = nullptr;
5849*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateLabeledObject(val, display, objectType, object, &labeledObject));
5850*8975f5c5SAndroid Build Coastguard Worker 
5851*8975f5c5SAndroid Build Coastguard Worker     return true;
5852*8975f5c5SAndroid Build Coastguard Worker }
5853*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetCompositorTimingSupportedANDROID(const ValidationContext * val,const Display * display,SurfaceID surfaceID,CompositorTiming name)5854*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetCompositorTimingSupportedANDROID(const ValidationContext *val,
5855*8975f5c5SAndroid Build Coastguard Worker                                                  const Display *display,
5856*8975f5c5SAndroid Build Coastguard Worker                                                  SurfaceID surfaceID,
5857*8975f5c5SAndroid Build Coastguard Worker                                                  CompositorTiming name)
5858*8975f5c5SAndroid Build Coastguard Worker {
5859*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
5860*8975f5c5SAndroid Build Coastguard Worker 
5861*8975f5c5SAndroid Build Coastguard Worker     if (!display->getExtensions().getFrameTimestamps)
5862*8975f5c5SAndroid Build Coastguard Worker     {
5863*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_DISPLAY,
5864*8975f5c5SAndroid Build Coastguard Worker                       "EGL_ANDROID_get_frame_timestamps extension is not available.");
5865*8975f5c5SAndroid Build Coastguard Worker         return false;
5866*8975f5c5SAndroid Build Coastguard Worker     }
5867*8975f5c5SAndroid Build Coastguard Worker 
5868*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateSurface(val, display, surfaceID));
5869*8975f5c5SAndroid Build Coastguard Worker 
5870*8975f5c5SAndroid Build Coastguard Worker     if (!ValidCompositorTimingName(name))
5871*8975f5c5SAndroid Build Coastguard Worker     {
5872*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_PARAMETER, "invalid timing name.");
5873*8975f5c5SAndroid Build Coastguard Worker         return false;
5874*8975f5c5SAndroid Build Coastguard Worker     }
5875*8975f5c5SAndroid Build Coastguard Worker 
5876*8975f5c5SAndroid Build Coastguard Worker     return true;
5877*8975f5c5SAndroid Build Coastguard Worker }
5878*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetCompositorTimingANDROID(const ValidationContext * val,const Display * display,SurfaceID surfaceID,EGLint numTimestamps,const EGLint * names,const EGLnsecsANDROID * values)5879*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetCompositorTimingANDROID(const ValidationContext *val,
5880*8975f5c5SAndroid Build Coastguard Worker                                         const Display *display,
5881*8975f5c5SAndroid Build Coastguard Worker                                         SurfaceID surfaceID,
5882*8975f5c5SAndroid Build Coastguard Worker                                         EGLint numTimestamps,
5883*8975f5c5SAndroid Build Coastguard Worker                                         const EGLint *names,
5884*8975f5c5SAndroid Build Coastguard Worker                                         const EGLnsecsANDROID *values)
5885*8975f5c5SAndroid Build Coastguard Worker {
5886*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
5887*8975f5c5SAndroid Build Coastguard Worker 
5888*8975f5c5SAndroid Build Coastguard Worker     if (!display->getExtensions().getFrameTimestamps)
5889*8975f5c5SAndroid Build Coastguard Worker     {
5890*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_DISPLAY,
5891*8975f5c5SAndroid Build Coastguard Worker                       "EGL_ANDROID_get_frame_timestamps extension is not available.");
5892*8975f5c5SAndroid Build Coastguard Worker         return false;
5893*8975f5c5SAndroid Build Coastguard Worker     }
5894*8975f5c5SAndroid Build Coastguard Worker 
5895*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateSurface(val, display, surfaceID));
5896*8975f5c5SAndroid Build Coastguard Worker 
5897*8975f5c5SAndroid Build Coastguard Worker     if (names == nullptr && numTimestamps > 0)
5898*8975f5c5SAndroid Build Coastguard Worker     {
5899*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_PARAMETER, "names is NULL.");
5900*8975f5c5SAndroid Build Coastguard Worker         return false;
5901*8975f5c5SAndroid Build Coastguard Worker     }
5902*8975f5c5SAndroid Build Coastguard Worker 
5903*8975f5c5SAndroid Build Coastguard Worker     if (values == nullptr && numTimestamps > 0)
5904*8975f5c5SAndroid Build Coastguard Worker     {
5905*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_PARAMETER, "values is NULL.");
5906*8975f5c5SAndroid Build Coastguard Worker         return false;
5907*8975f5c5SAndroid Build Coastguard Worker     }
5908*8975f5c5SAndroid Build Coastguard Worker 
5909*8975f5c5SAndroid Build Coastguard Worker     if (numTimestamps < 0)
5910*8975f5c5SAndroid Build Coastguard Worker     {
5911*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_PARAMETER, "numTimestamps must be at least 0.");
5912*8975f5c5SAndroid Build Coastguard Worker         return false;
5913*8975f5c5SAndroid Build Coastguard Worker     }
5914*8975f5c5SAndroid Build Coastguard Worker 
5915*8975f5c5SAndroid Build Coastguard Worker     for (EGLint i = 0; i < numTimestamps; i++)
5916*8975f5c5SAndroid Build Coastguard Worker     {
5917*8975f5c5SAndroid Build Coastguard Worker         CompositorTiming name = FromEGLenum<CompositorTiming>(names[i]);
5918*8975f5c5SAndroid Build Coastguard Worker 
5919*8975f5c5SAndroid Build Coastguard Worker         if (!ValidCompositorTimingName(name))
5920*8975f5c5SAndroid Build Coastguard Worker         {
5921*8975f5c5SAndroid Build Coastguard Worker             val->setError(EGL_BAD_PARAMETER, "invalid compositor timing.");
5922*8975f5c5SAndroid Build Coastguard Worker             return false;
5923*8975f5c5SAndroid Build Coastguard Worker         }
5924*8975f5c5SAndroid Build Coastguard Worker 
5925*8975f5c5SAndroid Build Coastguard Worker         const Surface *surface = display->getSurface(surfaceID);
5926*8975f5c5SAndroid Build Coastguard Worker         if (!surface->getSupportedCompositorTimings().test(name))
5927*8975f5c5SAndroid Build Coastguard Worker         {
5928*8975f5c5SAndroid Build Coastguard Worker             val->setError(EGL_BAD_PARAMETER, "compositor timing not supported by surface.");
5929*8975f5c5SAndroid Build Coastguard Worker             return false;
5930*8975f5c5SAndroid Build Coastguard Worker         }
5931*8975f5c5SAndroid Build Coastguard Worker     }
5932*8975f5c5SAndroid Build Coastguard Worker 
5933*8975f5c5SAndroid Build Coastguard Worker     return true;
5934*8975f5c5SAndroid Build Coastguard Worker }
5935*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetNextFrameIdANDROID(const ValidationContext * val,const Display * display,SurfaceID surfaceID,const EGLuint64KHR * frameId)5936*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetNextFrameIdANDROID(const ValidationContext *val,
5937*8975f5c5SAndroid Build Coastguard Worker                                    const Display *display,
5938*8975f5c5SAndroid Build Coastguard Worker                                    SurfaceID surfaceID,
5939*8975f5c5SAndroid Build Coastguard Worker                                    const EGLuint64KHR *frameId)
5940*8975f5c5SAndroid Build Coastguard Worker {
5941*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
5942*8975f5c5SAndroid Build Coastguard Worker 
5943*8975f5c5SAndroid Build Coastguard Worker     if (!display->getExtensions().getFrameTimestamps)
5944*8975f5c5SAndroid Build Coastguard Worker     {
5945*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_DISPLAY,
5946*8975f5c5SAndroid Build Coastguard Worker                       "EGL_ANDROID_get_frame_timestamps extension is not available.");
5947*8975f5c5SAndroid Build Coastguard Worker         return false;
5948*8975f5c5SAndroid Build Coastguard Worker     }
5949*8975f5c5SAndroid Build Coastguard Worker 
5950*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateSurface(val, display, surfaceID));
5951*8975f5c5SAndroid Build Coastguard Worker 
5952*8975f5c5SAndroid Build Coastguard Worker     if (frameId == nullptr)
5953*8975f5c5SAndroid Build Coastguard Worker     {
5954*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_PARAMETER, "frameId is NULL.");
5955*8975f5c5SAndroid Build Coastguard Worker         return false;
5956*8975f5c5SAndroid Build Coastguard Worker     }
5957*8975f5c5SAndroid Build Coastguard Worker 
5958*8975f5c5SAndroid Build Coastguard Worker     return true;
5959*8975f5c5SAndroid Build Coastguard Worker }
5960*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetFrameTimestampSupportedANDROID(const ValidationContext * val,const Display * display,SurfaceID surfaceID,Timestamp timestamp)5961*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetFrameTimestampSupportedANDROID(const ValidationContext *val,
5962*8975f5c5SAndroid Build Coastguard Worker                                                const Display *display,
5963*8975f5c5SAndroid Build Coastguard Worker                                                SurfaceID surfaceID,
5964*8975f5c5SAndroid Build Coastguard Worker                                                Timestamp timestamp)
5965*8975f5c5SAndroid Build Coastguard Worker {
5966*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
5967*8975f5c5SAndroid Build Coastguard Worker 
5968*8975f5c5SAndroid Build Coastguard Worker     if (!display->getExtensions().getFrameTimestamps)
5969*8975f5c5SAndroid Build Coastguard Worker     {
5970*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_DISPLAY,
5971*8975f5c5SAndroid Build Coastguard Worker                       "EGL_ANDROID_get_frame_timestamps extension is not available.");
5972*8975f5c5SAndroid Build Coastguard Worker         return false;
5973*8975f5c5SAndroid Build Coastguard Worker     }
5974*8975f5c5SAndroid Build Coastguard Worker 
5975*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateSurface(val, display, surfaceID));
5976*8975f5c5SAndroid Build Coastguard Worker 
5977*8975f5c5SAndroid Build Coastguard Worker     if (!ValidTimestampType(timestamp))
5978*8975f5c5SAndroid Build Coastguard Worker     {
5979*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_PARAMETER, "invalid timestamp type.");
5980*8975f5c5SAndroid Build Coastguard Worker         return false;
5981*8975f5c5SAndroid Build Coastguard Worker     }
5982*8975f5c5SAndroid Build Coastguard Worker 
5983*8975f5c5SAndroid Build Coastguard Worker     return true;
5984*8975f5c5SAndroid Build Coastguard Worker }
5985*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetFrameTimestampsANDROID(const ValidationContext * val,const Display * display,SurfaceID surfaceID,EGLuint64KHR frameId,EGLint numTimestamps,const EGLint * timestamps,const EGLnsecsANDROID * values)5986*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetFrameTimestampsANDROID(const ValidationContext *val,
5987*8975f5c5SAndroid Build Coastguard Worker                                        const Display *display,
5988*8975f5c5SAndroid Build Coastguard Worker                                        SurfaceID surfaceID,
5989*8975f5c5SAndroid Build Coastguard Worker                                        EGLuint64KHR frameId,
5990*8975f5c5SAndroid Build Coastguard Worker                                        EGLint numTimestamps,
5991*8975f5c5SAndroid Build Coastguard Worker                                        const EGLint *timestamps,
5992*8975f5c5SAndroid Build Coastguard Worker                                        const EGLnsecsANDROID *values)
5993*8975f5c5SAndroid Build Coastguard Worker {
5994*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
5995*8975f5c5SAndroid Build Coastguard Worker 
5996*8975f5c5SAndroid Build Coastguard Worker     if (!display->getExtensions().getFrameTimestamps)
5997*8975f5c5SAndroid Build Coastguard Worker     {
5998*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_DISPLAY,
5999*8975f5c5SAndroid Build Coastguard Worker                       "EGL_ANDROID_get_frame_timestamps extension is not available.");
6000*8975f5c5SAndroid Build Coastguard Worker         return false;
6001*8975f5c5SAndroid Build Coastguard Worker     }
6002*8975f5c5SAndroid Build Coastguard Worker 
6003*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateSurface(val, display, surfaceID));
6004*8975f5c5SAndroid Build Coastguard Worker 
6005*8975f5c5SAndroid Build Coastguard Worker     const Surface *surface = display->getSurface(surfaceID);
6006*8975f5c5SAndroid Build Coastguard Worker     if (!surface->isTimestampsEnabled())
6007*8975f5c5SAndroid Build Coastguard Worker     {
6008*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_SURFACE, "timestamp collection is not enabled for this surface.");
6009*8975f5c5SAndroid Build Coastguard Worker         return false;
6010*8975f5c5SAndroid Build Coastguard Worker     }
6011*8975f5c5SAndroid Build Coastguard Worker 
6012*8975f5c5SAndroid Build Coastguard Worker     if (timestamps == nullptr && numTimestamps > 0)
6013*8975f5c5SAndroid Build Coastguard Worker     {
6014*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_PARAMETER, "timestamps is NULL.");
6015*8975f5c5SAndroid Build Coastguard Worker         return false;
6016*8975f5c5SAndroid Build Coastguard Worker     }
6017*8975f5c5SAndroid Build Coastguard Worker 
6018*8975f5c5SAndroid Build Coastguard Worker     if (values == nullptr && numTimestamps > 0)
6019*8975f5c5SAndroid Build Coastguard Worker     {
6020*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_PARAMETER, "values is NULL.");
6021*8975f5c5SAndroid Build Coastguard Worker         return false;
6022*8975f5c5SAndroid Build Coastguard Worker     }
6023*8975f5c5SAndroid Build Coastguard Worker 
6024*8975f5c5SAndroid Build Coastguard Worker     if (numTimestamps < 0)
6025*8975f5c5SAndroid Build Coastguard Worker     {
6026*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_PARAMETER, "numTimestamps must be at least 0.");
6027*8975f5c5SAndroid Build Coastguard Worker         return false;
6028*8975f5c5SAndroid Build Coastguard Worker     }
6029*8975f5c5SAndroid Build Coastguard Worker 
6030*8975f5c5SAndroid Build Coastguard Worker     for (EGLint i = 0; i < numTimestamps; i++)
6031*8975f5c5SAndroid Build Coastguard Worker     {
6032*8975f5c5SAndroid Build Coastguard Worker         Timestamp timestamp = FromEGLenum<Timestamp>(timestamps[i]);
6033*8975f5c5SAndroid Build Coastguard Worker 
6034*8975f5c5SAndroid Build Coastguard Worker         if (!ValidTimestampType(timestamp))
6035*8975f5c5SAndroid Build Coastguard Worker         {
6036*8975f5c5SAndroid Build Coastguard Worker             val->setError(EGL_BAD_PARAMETER, "invalid timestamp type.");
6037*8975f5c5SAndroid Build Coastguard Worker             return false;
6038*8975f5c5SAndroid Build Coastguard Worker         }
6039*8975f5c5SAndroid Build Coastguard Worker 
6040*8975f5c5SAndroid Build Coastguard Worker         if (!surface->getSupportedTimestamps().test(timestamp))
6041*8975f5c5SAndroid Build Coastguard Worker         {
6042*8975f5c5SAndroid Build Coastguard Worker             val->setError(EGL_BAD_PARAMETER, "timestamp not supported by surface.");
6043*8975f5c5SAndroid Build Coastguard Worker             return false;
6044*8975f5c5SAndroid Build Coastguard Worker         }
6045*8975f5c5SAndroid Build Coastguard Worker     }
6046*8975f5c5SAndroid Build Coastguard Worker 
6047*8975f5c5SAndroid Build Coastguard Worker     return true;
6048*8975f5c5SAndroid Build Coastguard Worker }
6049*8975f5c5SAndroid Build Coastguard Worker 
ValidateQueryStringiANGLE(const ValidationContext * val,const Display * display,EGLint name,EGLint index)6050*8975f5c5SAndroid Build Coastguard Worker bool ValidateQueryStringiANGLE(const ValidationContext *val,
6051*8975f5c5SAndroid Build Coastguard Worker                                const Display *display,
6052*8975f5c5SAndroid Build Coastguard Worker                                EGLint name,
6053*8975f5c5SAndroid Build Coastguard Worker                                EGLint index)
6054*8975f5c5SAndroid Build Coastguard Worker {
6055*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
6056*8975f5c5SAndroid Build Coastguard Worker 
6057*8975f5c5SAndroid Build Coastguard Worker     if (!Display::GetClientExtensions().featureControlANGLE)
6058*8975f5c5SAndroid Build Coastguard Worker     {
6059*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_DISPLAY, "EGL_ANGLE_feature_control extension is not available.");
6060*8975f5c5SAndroid Build Coastguard Worker         return false;
6061*8975f5c5SAndroid Build Coastguard Worker     }
6062*8975f5c5SAndroid Build Coastguard Worker 
6063*8975f5c5SAndroid Build Coastguard Worker     if (index < 0)
6064*8975f5c5SAndroid Build Coastguard Worker     {
6065*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_PARAMETER, "index is negative.");
6066*8975f5c5SAndroid Build Coastguard Worker         return false;
6067*8975f5c5SAndroid Build Coastguard Worker     }
6068*8975f5c5SAndroid Build Coastguard Worker 
6069*8975f5c5SAndroid Build Coastguard Worker     switch (name)
6070*8975f5c5SAndroid Build Coastguard Worker     {
6071*8975f5c5SAndroid Build Coastguard Worker         case EGL_FEATURE_NAME_ANGLE:
6072*8975f5c5SAndroid Build Coastguard Worker         case EGL_FEATURE_CATEGORY_ANGLE:
6073*8975f5c5SAndroid Build Coastguard Worker         case EGL_FEATURE_STATUS_ANGLE:
6074*8975f5c5SAndroid Build Coastguard Worker             break;
6075*8975f5c5SAndroid Build Coastguard Worker         default:
6076*8975f5c5SAndroid Build Coastguard Worker             val->setError(EGL_BAD_PARAMETER, "name is not valid.");
6077*8975f5c5SAndroid Build Coastguard Worker             return false;
6078*8975f5c5SAndroid Build Coastguard Worker     }
6079*8975f5c5SAndroid Build Coastguard Worker 
6080*8975f5c5SAndroid Build Coastguard Worker     if (static_cast<size_t>(index) >= display->getFeatures().size())
6081*8975f5c5SAndroid Build Coastguard Worker     {
6082*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_PARAMETER, "index is too big.");
6083*8975f5c5SAndroid Build Coastguard Worker         return false;
6084*8975f5c5SAndroid Build Coastguard Worker     }
6085*8975f5c5SAndroid Build Coastguard Worker 
6086*8975f5c5SAndroid Build Coastguard Worker     return true;
6087*8975f5c5SAndroid Build Coastguard Worker }
6088*8975f5c5SAndroid Build Coastguard Worker 
ValidateQueryDisplayAttribEXT(const ValidationContext * val,const Display * display,const EGLint attribute,const EGLAttrib * value)6089*8975f5c5SAndroid Build Coastguard Worker bool ValidateQueryDisplayAttribEXT(const ValidationContext *val,
6090*8975f5c5SAndroid Build Coastguard Worker                                    const Display *display,
6091*8975f5c5SAndroid Build Coastguard Worker                                    const EGLint attribute,
6092*8975f5c5SAndroid Build Coastguard Worker                                    const EGLAttrib *value)
6093*8975f5c5SAndroid Build Coastguard Worker {
6094*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateQueryDisplayAttribBase(val, display, attribute));
6095*8975f5c5SAndroid Build Coastguard Worker     return true;
6096*8975f5c5SAndroid Build Coastguard Worker }
6097*8975f5c5SAndroid Build Coastguard Worker 
ValidateQueryDisplayAttribANGLE(const ValidationContext * val,const Display * display,const EGLint attribute,const EGLAttrib * value)6098*8975f5c5SAndroid Build Coastguard Worker bool ValidateQueryDisplayAttribANGLE(const ValidationContext *val,
6099*8975f5c5SAndroid Build Coastguard Worker                                      const Display *display,
6100*8975f5c5SAndroid Build Coastguard Worker                                      const EGLint attribute,
6101*8975f5c5SAndroid Build Coastguard Worker                                      const EGLAttrib *value)
6102*8975f5c5SAndroid Build Coastguard Worker {
6103*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateQueryDisplayAttribBase(val, display, attribute));
6104*8975f5c5SAndroid Build Coastguard Worker     return true;
6105*8975f5c5SAndroid Build Coastguard Worker }
6106*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetNativeClientBufferANDROID(const ValidationContext * val,const AHardwareBuffer * buffer)6107*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetNativeClientBufferANDROID(const ValidationContext *val,
6108*8975f5c5SAndroid Build Coastguard Worker                                           const AHardwareBuffer *buffer)
6109*8975f5c5SAndroid Build Coastguard Worker {
6110*8975f5c5SAndroid Build Coastguard Worker     // No extension check is done because no display is passed to eglGetNativeClientBufferANDROID
6111*8975f5c5SAndroid Build Coastguard Worker     // despite it being a display extension.  No display is needed for the implementation though.
6112*8975f5c5SAndroid Build Coastguard Worker     if (buffer == nullptr)
6113*8975f5c5SAndroid Build Coastguard Worker     {
6114*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_PARAMETER, "NULL buffer.");
6115*8975f5c5SAndroid Build Coastguard Worker         return false;
6116*8975f5c5SAndroid Build Coastguard Worker     }
6117*8975f5c5SAndroid Build Coastguard Worker 
6118*8975f5c5SAndroid Build Coastguard Worker     return true;
6119*8975f5c5SAndroid Build Coastguard Worker }
6120*8975f5c5SAndroid Build Coastguard Worker 
ValidateCreateNativeClientBufferANDROID(const ValidationContext * val,const egl::AttributeMap & attribMap)6121*8975f5c5SAndroid Build Coastguard Worker bool ValidateCreateNativeClientBufferANDROID(const ValidationContext *val,
6122*8975f5c5SAndroid Build Coastguard Worker                                              const egl::AttributeMap &attribMap)
6123*8975f5c5SAndroid Build Coastguard Worker {
6124*8975f5c5SAndroid Build Coastguard Worker     attribMap.initializeWithoutValidation();
6125*8975f5c5SAndroid Build Coastguard Worker 
6126*8975f5c5SAndroid Build Coastguard Worker     if (attribMap.isEmpty() || attribMap.begin()->second == EGL_NONE)
6127*8975f5c5SAndroid Build Coastguard Worker     {
6128*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_PARAMETER, "invalid attribute list.");
6129*8975f5c5SAndroid Build Coastguard Worker         return false;
6130*8975f5c5SAndroid Build Coastguard Worker     }
6131*8975f5c5SAndroid Build Coastguard Worker 
6132*8975f5c5SAndroid Build Coastguard Worker     int width     = attribMap.getAsInt(EGL_WIDTH, 0);
6133*8975f5c5SAndroid Build Coastguard Worker     int height    = attribMap.getAsInt(EGL_HEIGHT, 0);
6134*8975f5c5SAndroid Build Coastguard Worker     int redSize   = attribMap.getAsInt(EGL_RED_SIZE, 0);
6135*8975f5c5SAndroid Build Coastguard Worker     int greenSize = attribMap.getAsInt(EGL_GREEN_SIZE, 0);
6136*8975f5c5SAndroid Build Coastguard Worker     int blueSize  = attribMap.getAsInt(EGL_BLUE_SIZE, 0);
6137*8975f5c5SAndroid Build Coastguard Worker     int alphaSize = attribMap.getAsInt(EGL_ALPHA_SIZE, 0);
6138*8975f5c5SAndroid Build Coastguard Worker     int usage     = attribMap.getAsInt(EGL_NATIVE_BUFFER_USAGE_ANDROID, 0);
6139*8975f5c5SAndroid Build Coastguard Worker 
6140*8975f5c5SAndroid Build Coastguard Worker     for (AttributeMap::const_iterator attributeIter = attribMap.begin();
6141*8975f5c5SAndroid Build Coastguard Worker          attributeIter != attribMap.end(); attributeIter++)
6142*8975f5c5SAndroid Build Coastguard Worker     {
6143*8975f5c5SAndroid Build Coastguard Worker         EGLAttrib attribute = attributeIter->first;
6144*8975f5c5SAndroid Build Coastguard Worker         switch (attribute)
6145*8975f5c5SAndroid Build Coastguard Worker         {
6146*8975f5c5SAndroid Build Coastguard Worker             case EGL_WIDTH:
6147*8975f5c5SAndroid Build Coastguard Worker             case EGL_HEIGHT:
6148*8975f5c5SAndroid Build Coastguard Worker                 // Validation done after the switch statement
6149*8975f5c5SAndroid Build Coastguard Worker                 break;
6150*8975f5c5SAndroid Build Coastguard Worker             case EGL_RED_SIZE:
6151*8975f5c5SAndroid Build Coastguard Worker             case EGL_GREEN_SIZE:
6152*8975f5c5SAndroid Build Coastguard Worker             case EGL_BLUE_SIZE:
6153*8975f5c5SAndroid Build Coastguard Worker             case EGL_ALPHA_SIZE:
6154*8975f5c5SAndroid Build Coastguard Worker                 if (redSize < 0 || greenSize < 0 || blueSize < 0 || alphaSize < 0)
6155*8975f5c5SAndroid Build Coastguard Worker                 {
6156*8975f5c5SAndroid Build Coastguard Worker                     val->setError(EGL_BAD_PARAMETER, "incorrect channel size requested");
6157*8975f5c5SAndroid Build Coastguard Worker                     return false;
6158*8975f5c5SAndroid Build Coastguard Worker                 }
6159*8975f5c5SAndroid Build Coastguard Worker                 break;
6160*8975f5c5SAndroid Build Coastguard Worker             case EGL_NATIVE_BUFFER_USAGE_ANDROID:
6161*8975f5c5SAndroid Build Coastguard Worker                 // The buffer must be used for either a texture or a renderbuffer.
6162*8975f5c5SAndroid Build Coastguard Worker                 if ((usage & ~(EGL_NATIVE_BUFFER_USAGE_PROTECTED_BIT_ANDROID |
6163*8975f5c5SAndroid Build Coastguard Worker                                EGL_NATIVE_BUFFER_USAGE_RENDERBUFFER_BIT_ANDROID |
6164*8975f5c5SAndroid Build Coastguard Worker                                EGL_NATIVE_BUFFER_USAGE_TEXTURE_BIT_ANDROID)) != 0)
6165*8975f5c5SAndroid Build Coastguard Worker                 {
6166*8975f5c5SAndroid Build Coastguard Worker                     val->setError(EGL_BAD_PARAMETER, "invalid usage flag");
6167*8975f5c5SAndroid Build Coastguard Worker                     return false;
6168*8975f5c5SAndroid Build Coastguard Worker                 }
6169*8975f5c5SAndroid Build Coastguard Worker                 break;
6170*8975f5c5SAndroid Build Coastguard Worker             case EGL_NONE:
6171*8975f5c5SAndroid Build Coastguard Worker                 break;
6172*8975f5c5SAndroid Build Coastguard Worker             default:
6173*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE, "invalid attribute");
6174*8975f5c5SAndroid Build Coastguard Worker                 return false;
6175*8975f5c5SAndroid Build Coastguard Worker         }
6176*8975f5c5SAndroid Build Coastguard Worker     }
6177*8975f5c5SAndroid Build Coastguard Worker 
6178*8975f5c5SAndroid Build Coastguard Worker     // Validate EGL_WIDTH and EGL_HEIGHT values passed in. Done here to account
6179*8975f5c5SAndroid Build Coastguard Worker     // for the case where EGL_WIDTH and EGL_HEIGHT were not part of the attribute list.
6180*8975f5c5SAndroid Build Coastguard Worker     if (width <= 0 || height <= 0)
6181*8975f5c5SAndroid Build Coastguard Worker     {
6182*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_PARAMETER, "incorrect buffer dimensions requested");
6183*8975f5c5SAndroid Build Coastguard Worker         return false;
6184*8975f5c5SAndroid Build Coastguard Worker     }
6185*8975f5c5SAndroid Build Coastguard Worker 
6186*8975f5c5SAndroid Build Coastguard Worker     if (gl::GetAndroidHardwareBufferFormatFromChannelSizes(attribMap) == 0)
6187*8975f5c5SAndroid Build Coastguard Worker     {
6188*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_PARAMETER, "unsupported format");
6189*8975f5c5SAndroid Build Coastguard Worker         return false;
6190*8975f5c5SAndroid Build Coastguard Worker     }
6191*8975f5c5SAndroid Build Coastguard Worker     return true;
6192*8975f5c5SAndroid Build Coastguard Worker }
6193*8975f5c5SAndroid Build Coastguard Worker 
ValidateCopyMetalSharedEventANGLE(const ValidationContext * val,const Display * display,SyncID sync)6194*8975f5c5SAndroid Build Coastguard Worker bool ValidateCopyMetalSharedEventANGLE(const ValidationContext *val,
6195*8975f5c5SAndroid Build Coastguard Worker                                        const Display *display,
6196*8975f5c5SAndroid Build Coastguard Worker                                        SyncID sync)
6197*8975f5c5SAndroid Build Coastguard Worker {
6198*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
6199*8975f5c5SAndroid Build Coastguard Worker 
6200*8975f5c5SAndroid Build Coastguard Worker     if (!display->getExtensions().mtlSyncSharedEventANGLE)
6201*8975f5c5SAndroid Build Coastguard Worker     {
6202*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_DISPLAY, "EGL_ANGLE_metal_shared_event_sync is not available.");
6203*8975f5c5SAndroid Build Coastguard Worker         return false;
6204*8975f5c5SAndroid Build Coastguard Worker     }
6205*8975f5c5SAndroid Build Coastguard Worker 
6206*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateSync(val, display, sync));
6207*8975f5c5SAndroid Build Coastguard Worker 
6208*8975f5c5SAndroid Build Coastguard Worker     return true;
6209*8975f5c5SAndroid Build Coastguard Worker }
6210*8975f5c5SAndroid Build Coastguard Worker 
ValidateDupNativeFenceFDANDROID(const ValidationContext * val,const Display * display,SyncID sync)6211*8975f5c5SAndroid Build Coastguard Worker bool ValidateDupNativeFenceFDANDROID(const ValidationContext *val,
6212*8975f5c5SAndroid Build Coastguard Worker                                      const Display *display,
6213*8975f5c5SAndroid Build Coastguard Worker                                      SyncID sync)
6214*8975f5c5SAndroid Build Coastguard Worker {
6215*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
6216*8975f5c5SAndroid Build Coastguard Worker 
6217*8975f5c5SAndroid Build Coastguard Worker     if (!display->getExtensions().nativeFenceSyncANDROID)
6218*8975f5c5SAndroid Build Coastguard Worker     {
6219*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_DISPLAY, "EGL_ANDROID_native_fence_sync extension is not available.");
6220*8975f5c5SAndroid Build Coastguard Worker         return false;
6221*8975f5c5SAndroid Build Coastguard Worker     }
6222*8975f5c5SAndroid Build Coastguard Worker 
6223*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateSync(val, display, sync));
6224*8975f5c5SAndroid Build Coastguard Worker 
6225*8975f5c5SAndroid Build Coastguard Worker     return true;
6226*8975f5c5SAndroid Build Coastguard Worker }
6227*8975f5c5SAndroid Build Coastguard Worker 
ValidateSwapBuffersWithFrameTokenANGLE(const ValidationContext * val,const Display * display,SurfaceID surfaceID,EGLFrameTokenANGLE frametoken)6228*8975f5c5SAndroid Build Coastguard Worker bool ValidateSwapBuffersWithFrameTokenANGLE(const ValidationContext *val,
6229*8975f5c5SAndroid Build Coastguard Worker                                             const Display *display,
6230*8975f5c5SAndroid Build Coastguard Worker                                             SurfaceID surfaceID,
6231*8975f5c5SAndroid Build Coastguard Worker                                             EGLFrameTokenANGLE frametoken)
6232*8975f5c5SAndroid Build Coastguard Worker {
6233*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
6234*8975f5c5SAndroid Build Coastguard Worker 
6235*8975f5c5SAndroid Build Coastguard Worker     if (!display->getExtensions().swapWithFrameToken)
6236*8975f5c5SAndroid Build Coastguard Worker     {
6237*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_DISPLAY, "EGL_ANGLE_swap_buffers_with_frame_token is not available.");
6238*8975f5c5SAndroid Build Coastguard Worker         return false;
6239*8975f5c5SAndroid Build Coastguard Worker     }
6240*8975f5c5SAndroid Build Coastguard Worker 
6241*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateSurface(val, display, surfaceID));
6242*8975f5c5SAndroid Build Coastguard Worker 
6243*8975f5c5SAndroid Build Coastguard Worker     return true;
6244*8975f5c5SAndroid Build Coastguard Worker }
6245*8975f5c5SAndroid Build Coastguard Worker 
ValidatePrepareSwapBuffersANGLE(const ValidationContext * val,const Display * display,SurfaceID surfaceID)6246*8975f5c5SAndroid Build Coastguard Worker bool ValidatePrepareSwapBuffersANGLE(const ValidationContext *val,
6247*8975f5c5SAndroid Build Coastguard Worker                                      const Display *display,
6248*8975f5c5SAndroid Build Coastguard Worker                                      SurfaceID surfaceID)
6249*8975f5c5SAndroid Build Coastguard Worker {
6250*8975f5c5SAndroid Build Coastguard Worker     return ValidateSwapBuffers(val, display, surfaceID);
6251*8975f5c5SAndroid Build Coastguard Worker }
6252*8975f5c5SAndroid Build Coastguard Worker 
ValidateSignalSyncKHR(const ValidationContext * val,const Display * display,SyncID sync,EGLenum mode)6253*8975f5c5SAndroid Build Coastguard Worker bool ValidateSignalSyncKHR(const ValidationContext *val,
6254*8975f5c5SAndroid Build Coastguard Worker                            const Display *display,
6255*8975f5c5SAndroid Build Coastguard Worker                            SyncID sync,
6256*8975f5c5SAndroid Build Coastguard Worker                            EGLenum mode)
6257*8975f5c5SAndroid Build Coastguard Worker {
6258*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
6259*8975f5c5SAndroid Build Coastguard Worker 
6260*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateSync(val, display, sync));
6261*8975f5c5SAndroid Build Coastguard Worker 
6262*8975f5c5SAndroid Build Coastguard Worker     const Sync *syncObj = display->getSync(sync);
6263*8975f5c5SAndroid Build Coastguard Worker 
6264*8975f5c5SAndroid Build Coastguard Worker     if (syncObj->getType() == EGL_SYNC_REUSABLE_KHR)
6265*8975f5c5SAndroid Build Coastguard Worker     {
6266*8975f5c5SAndroid Build Coastguard Worker         if (!display->getExtensions().reusableSyncKHR)
6267*8975f5c5SAndroid Build Coastguard Worker         {
6268*8975f5c5SAndroid Build Coastguard Worker             val->setError(EGL_BAD_MATCH, "EGL_KHR_reusable_sync extension is not available.");
6269*8975f5c5SAndroid Build Coastguard Worker             return false;
6270*8975f5c5SAndroid Build Coastguard Worker         }
6271*8975f5c5SAndroid Build Coastguard Worker 
6272*8975f5c5SAndroid Build Coastguard Worker         if ((mode != EGL_SIGNALED_KHR) && (mode != EGL_UNSIGNALED_KHR))
6273*8975f5c5SAndroid Build Coastguard Worker         {
6274*8975f5c5SAndroid Build Coastguard Worker             val->setError(EGL_BAD_PARAMETER, "eglSignalSyncKHR invalid mode.");
6275*8975f5c5SAndroid Build Coastguard Worker             return false;
6276*8975f5c5SAndroid Build Coastguard Worker         }
6277*8975f5c5SAndroid Build Coastguard Worker 
6278*8975f5c5SAndroid Build Coastguard Worker         return true;
6279*8975f5c5SAndroid Build Coastguard Worker     }
6280*8975f5c5SAndroid Build Coastguard Worker 
6281*8975f5c5SAndroid Build Coastguard Worker     val->setError(EGL_BAD_MATCH);
6282*8975f5c5SAndroid Build Coastguard Worker     return false;
6283*8975f5c5SAndroid Build Coastguard Worker }
6284*8975f5c5SAndroid Build Coastguard Worker 
ValidateQuerySurfacePointerANGLE(const ValidationContext * val,const Display * display,SurfaceID surfaceID,EGLint attribute,void * const * value)6285*8975f5c5SAndroid Build Coastguard Worker bool ValidateQuerySurfacePointerANGLE(const ValidationContext *val,
6286*8975f5c5SAndroid Build Coastguard Worker                                       const Display *display,
6287*8975f5c5SAndroid Build Coastguard Worker                                       SurfaceID surfaceID,
6288*8975f5c5SAndroid Build Coastguard Worker                                       EGLint attribute,
6289*8975f5c5SAndroid Build Coastguard Worker                                       void *const *value)
6290*8975f5c5SAndroid Build Coastguard Worker {
6291*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
6292*8975f5c5SAndroid Build Coastguard Worker 
6293*8975f5c5SAndroid Build Coastguard Worker     if (!display->getExtensions().querySurfacePointer)
6294*8975f5c5SAndroid Build Coastguard Worker     {
6295*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_ACCESS);
6296*8975f5c5SAndroid Build Coastguard Worker         return false;
6297*8975f5c5SAndroid Build Coastguard Worker     }
6298*8975f5c5SAndroid Build Coastguard Worker 
6299*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateSurface(val, display, surfaceID));
6300*8975f5c5SAndroid Build Coastguard Worker 
6301*8975f5c5SAndroid Build Coastguard Worker     // validate the attribute parameter
6302*8975f5c5SAndroid Build Coastguard Worker     switch (attribute)
6303*8975f5c5SAndroid Build Coastguard Worker     {
6304*8975f5c5SAndroid Build Coastguard Worker         case EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE:
6305*8975f5c5SAndroid Build Coastguard Worker             if (!display->getExtensions().surfaceD3DTexture2DShareHandle)
6306*8975f5c5SAndroid Build Coastguard Worker             {
6307*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE);
6308*8975f5c5SAndroid Build Coastguard Worker                 return false;
6309*8975f5c5SAndroid Build Coastguard Worker             }
6310*8975f5c5SAndroid Build Coastguard Worker             break;
6311*8975f5c5SAndroid Build Coastguard Worker         case EGL_DXGI_KEYED_MUTEX_ANGLE:
6312*8975f5c5SAndroid Build Coastguard Worker             if (!display->getExtensions().keyedMutex)
6313*8975f5c5SAndroid Build Coastguard Worker             {
6314*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE);
6315*8975f5c5SAndroid Build Coastguard Worker                 return false;
6316*8975f5c5SAndroid Build Coastguard Worker             }
6317*8975f5c5SAndroid Build Coastguard Worker             break;
6318*8975f5c5SAndroid Build Coastguard Worker         default:
6319*8975f5c5SAndroid Build Coastguard Worker             val->setError(EGL_BAD_ATTRIBUTE);
6320*8975f5c5SAndroid Build Coastguard Worker             return false;
6321*8975f5c5SAndroid Build Coastguard Worker     }
6322*8975f5c5SAndroid Build Coastguard Worker 
6323*8975f5c5SAndroid Build Coastguard Worker     return true;
6324*8975f5c5SAndroid Build Coastguard Worker }
6325*8975f5c5SAndroid Build Coastguard Worker 
ValidatePostSubBufferNV(const ValidationContext * val,const Display * display,SurfaceID surfaceID,EGLint x,EGLint y,EGLint width,EGLint height)6326*8975f5c5SAndroid Build Coastguard Worker bool ValidatePostSubBufferNV(const ValidationContext *val,
6327*8975f5c5SAndroid Build Coastguard Worker                              const Display *display,
6328*8975f5c5SAndroid Build Coastguard Worker                              SurfaceID surfaceID,
6329*8975f5c5SAndroid Build Coastguard Worker                              EGLint x,
6330*8975f5c5SAndroid Build Coastguard Worker                              EGLint y,
6331*8975f5c5SAndroid Build Coastguard Worker                              EGLint width,
6332*8975f5c5SAndroid Build Coastguard Worker                              EGLint height)
6333*8975f5c5SAndroid Build Coastguard Worker {
6334*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
6335*8975f5c5SAndroid Build Coastguard Worker 
6336*8975f5c5SAndroid Build Coastguard Worker     if (!display->getExtensions().postSubBuffer)
6337*8975f5c5SAndroid Build Coastguard Worker     {
6338*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_ACCESS);
6339*8975f5c5SAndroid Build Coastguard Worker         return false;
6340*8975f5c5SAndroid Build Coastguard Worker     }
6341*8975f5c5SAndroid Build Coastguard Worker 
6342*8975f5c5SAndroid Build Coastguard Worker     if (x < 0 || y < 0 || width < 0 || height < 0)
6343*8975f5c5SAndroid Build Coastguard Worker     {
6344*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_PARAMETER);
6345*8975f5c5SAndroid Build Coastguard Worker         return false;
6346*8975f5c5SAndroid Build Coastguard Worker     }
6347*8975f5c5SAndroid Build Coastguard Worker 
6348*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateSurface(val, display, surfaceID));
6349*8975f5c5SAndroid Build Coastguard Worker 
6350*8975f5c5SAndroid Build Coastguard Worker     if (display->isDeviceLost())
6351*8975f5c5SAndroid Build Coastguard Worker     {
6352*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_CONTEXT_LOST);
6353*8975f5c5SAndroid Build Coastguard Worker         return false;
6354*8975f5c5SAndroid Build Coastguard Worker     }
6355*8975f5c5SAndroid Build Coastguard Worker 
6356*8975f5c5SAndroid Build Coastguard Worker     return true;
6357*8975f5c5SAndroid Build Coastguard Worker }
6358*8975f5c5SAndroid Build Coastguard Worker 
ValidateQueryDeviceAttribEXT(const ValidationContext * val,const Device * device,EGLint attribute,const EGLAttrib * value)6359*8975f5c5SAndroid Build Coastguard Worker bool ValidateQueryDeviceAttribEXT(const ValidationContext *val,
6360*8975f5c5SAndroid Build Coastguard Worker                                   const Device *device,
6361*8975f5c5SAndroid Build Coastguard Worker                                   EGLint attribute,
6362*8975f5c5SAndroid Build Coastguard Worker                                   const EGLAttrib *value)
6363*8975f5c5SAndroid Build Coastguard Worker {
6364*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateDevice(val, device));
6365*8975f5c5SAndroid Build Coastguard Worker 
6366*8975f5c5SAndroid Build Coastguard Worker     if (!Display::GetClientExtensions().deviceQueryEXT)
6367*8975f5c5SAndroid Build Coastguard Worker     {
6368*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_ACCESS, "EGL_EXT_device_query not supported.");
6369*8975f5c5SAndroid Build Coastguard Worker         return false;
6370*8975f5c5SAndroid Build Coastguard Worker     }
6371*8975f5c5SAndroid Build Coastguard Worker 
6372*8975f5c5SAndroid Build Coastguard Worker     // validate the attribute parameter
6373*8975f5c5SAndroid Build Coastguard Worker     switch (attribute)
6374*8975f5c5SAndroid Build Coastguard Worker     {
6375*8975f5c5SAndroid Build Coastguard Worker         case EGL_D3D11_DEVICE_ANGLE:
6376*8975f5c5SAndroid Build Coastguard Worker             if (!device->getExtensions().deviceD3D11)
6377*8975f5c5SAndroid Build Coastguard Worker             {
6378*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE);
6379*8975f5c5SAndroid Build Coastguard Worker                 return false;
6380*8975f5c5SAndroid Build Coastguard Worker             }
6381*8975f5c5SAndroid Build Coastguard Worker             break;
6382*8975f5c5SAndroid Build Coastguard Worker         case EGL_D3D9_DEVICE_ANGLE:
6383*8975f5c5SAndroid Build Coastguard Worker             if (!device->getExtensions().deviceD3D9)
6384*8975f5c5SAndroid Build Coastguard Worker             {
6385*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE);
6386*8975f5c5SAndroid Build Coastguard Worker                 return false;
6387*8975f5c5SAndroid Build Coastguard Worker             }
6388*8975f5c5SAndroid Build Coastguard Worker             break;
6389*8975f5c5SAndroid Build Coastguard Worker         case EGL_METAL_DEVICE_ANGLE:
6390*8975f5c5SAndroid Build Coastguard Worker             if (!device->getExtensions().deviceMetal)
6391*8975f5c5SAndroid Build Coastguard Worker             {
6392*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE);
6393*8975f5c5SAndroid Build Coastguard Worker                 return false;
6394*8975f5c5SAndroid Build Coastguard Worker             }
6395*8975f5c5SAndroid Build Coastguard Worker             break;
6396*8975f5c5SAndroid Build Coastguard Worker         case EGL_VULKAN_VERSION_ANGLE:
6397*8975f5c5SAndroid Build Coastguard Worker         case EGL_VULKAN_INSTANCE_ANGLE:
6398*8975f5c5SAndroid Build Coastguard Worker         case EGL_VULKAN_INSTANCE_EXTENSIONS_ANGLE:
6399*8975f5c5SAndroid Build Coastguard Worker         case EGL_VULKAN_PHYSICAL_DEVICE_ANGLE:
6400*8975f5c5SAndroid Build Coastguard Worker         case EGL_VULKAN_DEVICE_ANGLE:
6401*8975f5c5SAndroid Build Coastguard Worker         case EGL_VULKAN_DEVICE_EXTENSIONS_ANGLE:
6402*8975f5c5SAndroid Build Coastguard Worker         case EGL_VULKAN_FEATURES_ANGLE:
6403*8975f5c5SAndroid Build Coastguard Worker         case EGL_VULKAN_QUEUE_ANGLE:
6404*8975f5c5SAndroid Build Coastguard Worker         case EGL_VULKAN_QUEUE_FAMILIY_INDEX_ANGLE:
6405*8975f5c5SAndroid Build Coastguard Worker         case EGL_VULKAN_GET_INSTANCE_PROC_ADDR:
6406*8975f5c5SAndroid Build Coastguard Worker             if (!device->getExtensions().deviceVulkan)
6407*8975f5c5SAndroid Build Coastguard Worker             {
6408*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE);
6409*8975f5c5SAndroid Build Coastguard Worker                 return false;
6410*8975f5c5SAndroid Build Coastguard Worker             }
6411*8975f5c5SAndroid Build Coastguard Worker             break;
6412*8975f5c5SAndroid Build Coastguard Worker         case EGL_CGL_CONTEXT_ANGLE:
6413*8975f5c5SAndroid Build Coastguard Worker         case EGL_CGL_PIXEL_FORMAT_ANGLE:
6414*8975f5c5SAndroid Build Coastguard Worker             if (!device->getExtensions().deviceCGL)
6415*8975f5c5SAndroid Build Coastguard Worker             {
6416*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE);
6417*8975f5c5SAndroid Build Coastguard Worker                 return false;
6418*8975f5c5SAndroid Build Coastguard Worker             }
6419*8975f5c5SAndroid Build Coastguard Worker             break;
6420*8975f5c5SAndroid Build Coastguard Worker         default:
6421*8975f5c5SAndroid Build Coastguard Worker             val->setError(EGL_BAD_ATTRIBUTE);
6422*8975f5c5SAndroid Build Coastguard Worker             return false;
6423*8975f5c5SAndroid Build Coastguard Worker     }
6424*8975f5c5SAndroid Build Coastguard Worker     return true;
6425*8975f5c5SAndroid Build Coastguard Worker }
6426*8975f5c5SAndroid Build Coastguard Worker 
ValidateQueryDeviceStringEXT(const ValidationContext * val,const Device * device,EGLint name)6427*8975f5c5SAndroid Build Coastguard Worker bool ValidateQueryDeviceStringEXT(const ValidationContext *val, const Device *device, EGLint name)
6428*8975f5c5SAndroid Build Coastguard Worker {
6429*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateDevice(val, device));
6430*8975f5c5SAndroid Build Coastguard Worker     return true;
6431*8975f5c5SAndroid Build Coastguard Worker }
6432*8975f5c5SAndroid Build Coastguard Worker 
ValidateReleaseHighPowerGPUANGLE(const ValidationContext * val,const Display * display,gl::ContextID contextID)6433*8975f5c5SAndroid Build Coastguard Worker bool ValidateReleaseHighPowerGPUANGLE(const ValidationContext *val,
6434*8975f5c5SAndroid Build Coastguard Worker                                       const Display *display,
6435*8975f5c5SAndroid Build Coastguard Worker                                       gl::ContextID contextID)
6436*8975f5c5SAndroid Build Coastguard Worker {
6437*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateContext(val, display, contextID));
6438*8975f5c5SAndroid Build Coastguard Worker     return true;
6439*8975f5c5SAndroid Build Coastguard Worker }
6440*8975f5c5SAndroid Build Coastguard Worker 
ValidateReacquireHighPowerGPUANGLE(const ValidationContext * val,const Display * display,gl::ContextID contextID)6441*8975f5c5SAndroid Build Coastguard Worker bool ValidateReacquireHighPowerGPUANGLE(const ValidationContext *val,
6442*8975f5c5SAndroid Build Coastguard Worker                                         const Display *display,
6443*8975f5c5SAndroid Build Coastguard Worker                                         gl::ContextID contextID)
6444*8975f5c5SAndroid Build Coastguard Worker {
6445*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateContext(val, display, contextID));
6446*8975f5c5SAndroid Build Coastguard Worker     return true;
6447*8975f5c5SAndroid Build Coastguard Worker }
6448*8975f5c5SAndroid Build Coastguard Worker 
ValidateHandleGPUSwitchANGLE(const ValidationContext * val,const Display * display)6449*8975f5c5SAndroid Build Coastguard Worker bool ValidateHandleGPUSwitchANGLE(const ValidationContext *val, const Display *display)
6450*8975f5c5SAndroid Build Coastguard Worker {
6451*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
6452*8975f5c5SAndroid Build Coastguard Worker     return true;
6453*8975f5c5SAndroid Build Coastguard Worker }
6454*8975f5c5SAndroid Build Coastguard Worker 
ValidateForceGPUSwitchANGLE(const ValidationContext * val,const Display * display,EGLint gpuIDHigh,EGLint gpuIDLow)6455*8975f5c5SAndroid Build Coastguard Worker bool ValidateForceGPUSwitchANGLE(const ValidationContext *val,
6456*8975f5c5SAndroid Build Coastguard Worker                                  const Display *display,
6457*8975f5c5SAndroid Build Coastguard Worker                                  EGLint gpuIDHigh,
6458*8975f5c5SAndroid Build Coastguard Worker                                  EGLint gpuIDLow)
6459*8975f5c5SAndroid Build Coastguard Worker {
6460*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
6461*8975f5c5SAndroid Build Coastguard Worker     return true;
6462*8975f5c5SAndroid Build Coastguard Worker }
6463*8975f5c5SAndroid Build Coastguard Worker 
ValidateWaitUntilWorkScheduledANGLE(const ValidationContext * val,const Display * display)6464*8975f5c5SAndroid Build Coastguard Worker bool ValidateWaitUntilWorkScheduledANGLE(const ValidationContext *val, const Display *display)
6465*8975f5c5SAndroid Build Coastguard Worker {
6466*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
6467*8975f5c5SAndroid Build Coastguard Worker     return true;
6468*8975f5c5SAndroid Build Coastguard Worker }
6469*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetCurrentDisplay(const ValidationContext * val)6470*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetCurrentDisplay(const ValidationContext *val)
6471*8975f5c5SAndroid Build Coastguard Worker {
6472*8975f5c5SAndroid Build Coastguard Worker     return true;
6473*8975f5c5SAndroid Build Coastguard Worker }
6474*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetCurrentSurface(const ValidationContext * val,EGLint readdraw)6475*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetCurrentSurface(const ValidationContext *val, EGLint readdraw)
6476*8975f5c5SAndroid Build Coastguard Worker {
6477*8975f5c5SAndroid Build Coastguard Worker     switch (readdraw)
6478*8975f5c5SAndroid Build Coastguard Worker     {
6479*8975f5c5SAndroid Build Coastguard Worker         case EGL_READ:
6480*8975f5c5SAndroid Build Coastguard Worker         case EGL_DRAW:
6481*8975f5c5SAndroid Build Coastguard Worker             return true;
6482*8975f5c5SAndroid Build Coastguard Worker 
6483*8975f5c5SAndroid Build Coastguard Worker         default:
6484*8975f5c5SAndroid Build Coastguard Worker             val->setError(EGL_BAD_PARAMETER, "Invalid surface type");
6485*8975f5c5SAndroid Build Coastguard Worker             return false;
6486*8975f5c5SAndroid Build Coastguard Worker     }
6487*8975f5c5SAndroid Build Coastguard Worker }
6488*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetDisplay(const ValidationContext * val,EGLNativeDisplayType display_id)6489*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetDisplay(const ValidationContext *val, EGLNativeDisplayType display_id)
6490*8975f5c5SAndroid Build Coastguard Worker {
6491*8975f5c5SAndroid Build Coastguard Worker     return true;
6492*8975f5c5SAndroid Build Coastguard Worker }
6493*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetError(const ValidationContext * val)6494*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetError(const ValidationContext *val)
6495*8975f5c5SAndroid Build Coastguard Worker {
6496*8975f5c5SAndroid Build Coastguard Worker     return true;
6497*8975f5c5SAndroid Build Coastguard Worker }
6498*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetProcAddress(const ValidationContext * val,const char * procname)6499*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetProcAddress(const ValidationContext *val, const char *procname)
6500*8975f5c5SAndroid Build Coastguard Worker {
6501*8975f5c5SAndroid Build Coastguard Worker     return true;
6502*8975f5c5SAndroid Build Coastguard Worker }
6503*8975f5c5SAndroid Build Coastguard Worker 
ValidateQueryString(const ValidationContext * val,const Display * dpyPacked,EGLint name)6504*8975f5c5SAndroid Build Coastguard Worker bool ValidateQueryString(const ValidationContext *val, const Display *dpyPacked, EGLint name)
6505*8975f5c5SAndroid Build Coastguard Worker {
6506*8975f5c5SAndroid Build Coastguard Worker     // The only situation where EGL_NO_DISPLAY is allowed is when querying
6507*8975f5c5SAndroid Build Coastguard Worker     // EGL_EXTENSIONS or EGL_VERSION.
6508*8975f5c5SAndroid Build Coastguard Worker     const bool canQueryWithoutDisplay = (name == EGL_VERSION || name == EGL_EXTENSIONS);
6509*8975f5c5SAndroid Build Coastguard Worker 
6510*8975f5c5SAndroid Build Coastguard Worker     if (dpyPacked != nullptr || !canQueryWithoutDisplay)
6511*8975f5c5SAndroid Build Coastguard Worker     {
6512*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_TRY(ValidateDisplay(val, dpyPacked));
6513*8975f5c5SAndroid Build Coastguard Worker     }
6514*8975f5c5SAndroid Build Coastguard Worker 
6515*8975f5c5SAndroid Build Coastguard Worker     switch (name)
6516*8975f5c5SAndroid Build Coastguard Worker     {
6517*8975f5c5SAndroid Build Coastguard Worker         case EGL_CLIENT_APIS:
6518*8975f5c5SAndroid Build Coastguard Worker         case EGL_EXTENSIONS:
6519*8975f5c5SAndroid Build Coastguard Worker         case EGL_VENDOR:
6520*8975f5c5SAndroid Build Coastguard Worker         case EGL_VERSION:
6521*8975f5c5SAndroid Build Coastguard Worker             break;
6522*8975f5c5SAndroid Build Coastguard Worker         default:
6523*8975f5c5SAndroid Build Coastguard Worker             val->setError(EGL_BAD_PARAMETER);
6524*8975f5c5SAndroid Build Coastguard Worker             return false;
6525*8975f5c5SAndroid Build Coastguard Worker     }
6526*8975f5c5SAndroid Build Coastguard Worker     return true;
6527*8975f5c5SAndroid Build Coastguard Worker }
6528*8975f5c5SAndroid Build Coastguard Worker 
ValidateWaitGL(const ValidationContext * val)6529*8975f5c5SAndroid Build Coastguard Worker bool ValidateWaitGL(const ValidationContext *val)
6530*8975f5c5SAndroid Build Coastguard Worker {
6531*8975f5c5SAndroid Build Coastguard Worker     if (val->eglThread->getDisplay() == nullptr)
6532*8975f5c5SAndroid Build Coastguard Worker     {
6533*8975f5c5SAndroid Build Coastguard Worker         // EGL spec says this about eglWaitGL -
6534*8975f5c5SAndroid Build Coastguard Worker         //    eglWaitGL is ignored if there is no current EGL rendering context for OpenGL ES.
6535*8975f5c5SAndroid Build Coastguard Worker         return true;
6536*8975f5c5SAndroid Build Coastguard Worker     }
6537*8975f5c5SAndroid Build Coastguard Worker 
6538*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateDisplay(val, val->eglThread->getDisplay()));
6539*8975f5c5SAndroid Build Coastguard Worker     return true;
6540*8975f5c5SAndroid Build Coastguard Worker }
6541*8975f5c5SAndroid Build Coastguard Worker 
ValidateQueryAPI(const ValidationContext * val)6542*8975f5c5SAndroid Build Coastguard Worker bool ValidateQueryAPI(const ValidationContext *val)
6543*8975f5c5SAndroid Build Coastguard Worker {
6544*8975f5c5SAndroid Build Coastguard Worker     return true;
6545*8975f5c5SAndroid Build Coastguard Worker }
6546*8975f5c5SAndroid Build Coastguard Worker 
ValidateReleaseThread(const ValidationContext * val)6547*8975f5c5SAndroid Build Coastguard Worker bool ValidateReleaseThread(const ValidationContext *val)
6548*8975f5c5SAndroid Build Coastguard Worker {
6549*8975f5c5SAndroid Build Coastguard Worker     return true;
6550*8975f5c5SAndroid Build Coastguard Worker }
6551*8975f5c5SAndroid Build Coastguard Worker 
ValidateWaitClient(const ValidationContext * val)6552*8975f5c5SAndroid Build Coastguard Worker bool ValidateWaitClient(const ValidationContext *val)
6553*8975f5c5SAndroid Build Coastguard Worker {
6554*8975f5c5SAndroid Build Coastguard Worker     if (val->eglThread->getDisplay() == nullptr)
6555*8975f5c5SAndroid Build Coastguard Worker     {
6556*8975f5c5SAndroid Build Coastguard Worker         // EGL spec says this about eglWaitClient -
6557*8975f5c5SAndroid Build Coastguard Worker         //    If there is no current context for the current rendering API,
6558*8975f5c5SAndroid Build Coastguard Worker         //    the function has no effect but still returns EGL_TRUE.
6559*8975f5c5SAndroid Build Coastguard Worker         return true;
6560*8975f5c5SAndroid Build Coastguard Worker     }
6561*8975f5c5SAndroid Build Coastguard Worker 
6562*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateDisplay(val, val->eglThread->getDisplay()));
6563*8975f5c5SAndroid Build Coastguard Worker     return true;
6564*8975f5c5SAndroid Build Coastguard Worker }
6565*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetCurrentContext(const ValidationContext * val)6566*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetCurrentContext(const ValidationContext *val)
6567*8975f5c5SAndroid Build Coastguard Worker {
6568*8975f5c5SAndroid Build Coastguard Worker     return true;
6569*8975f5c5SAndroid Build Coastguard Worker }
6570*8975f5c5SAndroid Build Coastguard Worker 
ValidateCreatePlatformPixmapSurface(const ValidationContext * val,const Display * dpyPacked,const Config * configPacked,const void * native_pixmap,const AttributeMap & attrib_listPacked)6571*8975f5c5SAndroid Build Coastguard Worker bool ValidateCreatePlatformPixmapSurface(const ValidationContext *val,
6572*8975f5c5SAndroid Build Coastguard Worker                                          const Display *dpyPacked,
6573*8975f5c5SAndroid Build Coastguard Worker                                          const Config *configPacked,
6574*8975f5c5SAndroid Build Coastguard Worker                                          const void *native_pixmap,
6575*8975f5c5SAndroid Build Coastguard Worker                                          const AttributeMap &attrib_listPacked)
6576*8975f5c5SAndroid Build Coastguard Worker {
6577*8975f5c5SAndroid Build Coastguard Worker     EGLNativePixmapType nativePixmap =
6578*8975f5c5SAndroid Build Coastguard Worker         reinterpret_cast<EGLNativePixmapType>(const_cast<void *>(native_pixmap));
6579*8975f5c5SAndroid Build Coastguard Worker     return ValidateCreatePixmapSurface(val, dpyPacked, configPacked, nativePixmap,
6580*8975f5c5SAndroid Build Coastguard Worker                                        attrib_listPacked);
6581*8975f5c5SAndroid Build Coastguard Worker }
6582*8975f5c5SAndroid Build Coastguard Worker 
ValidateCreatePlatformWindowSurface(const ValidationContext * val,const Display * dpyPacked,const Config * configPacked,const void * native_window,const AttributeMap & attrib_listPacked)6583*8975f5c5SAndroid Build Coastguard Worker bool ValidateCreatePlatformWindowSurface(const ValidationContext *val,
6584*8975f5c5SAndroid Build Coastguard Worker                                          const Display *dpyPacked,
6585*8975f5c5SAndroid Build Coastguard Worker                                          const Config *configPacked,
6586*8975f5c5SAndroid Build Coastguard Worker                                          const void *native_window,
6587*8975f5c5SAndroid Build Coastguard Worker                                          const AttributeMap &attrib_listPacked)
6588*8975f5c5SAndroid Build Coastguard Worker {
6589*8975f5c5SAndroid Build Coastguard Worker     EGLNativeWindowType nativeWindow =
6590*8975f5c5SAndroid Build Coastguard Worker         reinterpret_cast<EGLNativeWindowType>(const_cast<void *>(native_window));
6591*8975f5c5SAndroid Build Coastguard Worker     return ValidateCreateWindowSurface(val, dpyPacked, configPacked, nativeWindow,
6592*8975f5c5SAndroid Build Coastguard Worker                                        attrib_listPacked);
6593*8975f5c5SAndroid Build Coastguard Worker }
6594*8975f5c5SAndroid Build Coastguard Worker 
ValidateLockSurfaceKHR(const ValidationContext * val,const egl::Display * dpy,SurfaceID surfaceID,const AttributeMap & attributes)6595*8975f5c5SAndroid Build Coastguard Worker bool ValidateLockSurfaceKHR(const ValidationContext *val,
6596*8975f5c5SAndroid Build Coastguard Worker                             const egl::Display *dpy,
6597*8975f5c5SAndroid Build Coastguard Worker                             SurfaceID surfaceID,
6598*8975f5c5SAndroid Build Coastguard Worker                             const AttributeMap &attributes)
6599*8975f5c5SAndroid Build Coastguard Worker {
6600*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateDisplay(val, dpy));
6601*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateSurface(val, dpy, surfaceID));
6602*8975f5c5SAndroid Build Coastguard Worker 
6603*8975f5c5SAndroid Build Coastguard Worker     if (!dpy->getExtensions().lockSurface3KHR)
6604*8975f5c5SAndroid Build Coastguard Worker     {
6605*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_ACCESS);
6606*8975f5c5SAndroid Build Coastguard Worker         return false;
6607*8975f5c5SAndroid Build Coastguard Worker     }
6608*8975f5c5SAndroid Build Coastguard Worker 
6609*8975f5c5SAndroid Build Coastguard Worker     const Surface *surface = dpy->getSurface(surfaceID);
6610*8975f5c5SAndroid Build Coastguard Worker     if (surface->isLocked())
6611*8975f5c5SAndroid Build Coastguard Worker     {
6612*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_ACCESS);
6613*8975f5c5SAndroid Build Coastguard Worker         return false;
6614*8975f5c5SAndroid Build Coastguard Worker     }
6615*8975f5c5SAndroid Build Coastguard Worker 
6616*8975f5c5SAndroid Build Coastguard Worker     if ((surface->getConfig()->surfaceType & EGL_LOCK_SURFACE_BIT_KHR) == false)
6617*8975f5c5SAndroid Build Coastguard Worker     {
6618*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_ACCESS, "Config does not support EGL_LOCK_SURFACE_BIT");
6619*8975f5c5SAndroid Build Coastguard Worker         return false;
6620*8975f5c5SAndroid Build Coastguard Worker     }
6621*8975f5c5SAndroid Build Coastguard Worker 
6622*8975f5c5SAndroid Build Coastguard Worker     if (surface->isCurrentOnAnyContext())
6623*8975f5c5SAndroid Build Coastguard Worker     {
6624*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_ACCESS,
6625*8975f5c5SAndroid Build Coastguard Worker                       "Surface cannot be current to a context for eglLockSurface()");
6626*8975f5c5SAndroid Build Coastguard Worker         return false;
6627*8975f5c5SAndroid Build Coastguard Worker     }
6628*8975f5c5SAndroid Build Coastguard Worker 
6629*8975f5c5SAndroid Build Coastguard Worker     if (surface->hasProtectedContent())
6630*8975f5c5SAndroid Build Coastguard Worker     {
6631*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_ACCESS, "Surface cannot be protected content for eglLockSurface()");
6632*8975f5c5SAndroid Build Coastguard Worker         return false;
6633*8975f5c5SAndroid Build Coastguard Worker     }
6634*8975f5c5SAndroid Build Coastguard Worker 
6635*8975f5c5SAndroid Build Coastguard Worker     attributes.initializeWithoutValidation();
6636*8975f5c5SAndroid Build Coastguard Worker 
6637*8975f5c5SAndroid Build Coastguard Worker     for (const auto &attributeIter : attributes)
6638*8975f5c5SAndroid Build Coastguard Worker     {
6639*8975f5c5SAndroid Build Coastguard Worker         EGLAttrib attribute = attributeIter.first;
6640*8975f5c5SAndroid Build Coastguard Worker         EGLAttrib value     = attributeIter.second;
6641*8975f5c5SAndroid Build Coastguard Worker 
6642*8975f5c5SAndroid Build Coastguard Worker         switch (attribute)
6643*8975f5c5SAndroid Build Coastguard Worker         {
6644*8975f5c5SAndroid Build Coastguard Worker             case EGL_MAP_PRESERVE_PIXELS_KHR:
6645*8975f5c5SAndroid Build Coastguard Worker                 if (!((value == EGL_FALSE) || (value == EGL_TRUE)))
6646*8975f5c5SAndroid Build Coastguard Worker                 {
6647*8975f5c5SAndroid Build Coastguard Worker                     val->setError(EGL_BAD_ATTRIBUTE, "Invalid EGL_MAP_PRESERVE_PIXELS_KHR value");
6648*8975f5c5SAndroid Build Coastguard Worker                     return false;
6649*8975f5c5SAndroid Build Coastguard Worker                 }
6650*8975f5c5SAndroid Build Coastguard Worker                 break;
6651*8975f5c5SAndroid Build Coastguard Worker             case EGL_LOCK_USAGE_HINT_KHR:
6652*8975f5c5SAndroid Build Coastguard Worker                 if ((value & (EGL_READ_SURFACE_BIT_KHR | EGL_WRITE_SURFACE_BIT_KHR)) != value)
6653*8975f5c5SAndroid Build Coastguard Worker                 {
6654*8975f5c5SAndroid Build Coastguard Worker                     val->setError(EGL_BAD_ATTRIBUTE, "Invalid EGL_LOCK_USAGE_HINT_KHR value");
6655*8975f5c5SAndroid Build Coastguard Worker                     return false;
6656*8975f5c5SAndroid Build Coastguard Worker                 }
6657*8975f5c5SAndroid Build Coastguard Worker                 break;
6658*8975f5c5SAndroid Build Coastguard Worker             default:
6659*8975f5c5SAndroid Build Coastguard Worker                 val->setError(EGL_BAD_ATTRIBUTE, "Invalid lock surface attribute");
6660*8975f5c5SAndroid Build Coastguard Worker                 return false;
6661*8975f5c5SAndroid Build Coastguard Worker         }
6662*8975f5c5SAndroid Build Coastguard Worker     }
6663*8975f5c5SAndroid Build Coastguard Worker 
6664*8975f5c5SAndroid Build Coastguard Worker     return true;
6665*8975f5c5SAndroid Build Coastguard Worker }
6666*8975f5c5SAndroid Build Coastguard Worker 
ValidateQuerySurface64KHR(const ValidationContext * val,const egl::Display * dpy,SurfaceID surfaceID,EGLint attribute,const EGLAttribKHR * value)6667*8975f5c5SAndroid Build Coastguard Worker bool ValidateQuerySurface64KHR(const ValidationContext *val,
6668*8975f5c5SAndroid Build Coastguard Worker                                const egl::Display *dpy,
6669*8975f5c5SAndroid Build Coastguard Worker                                SurfaceID surfaceID,
6670*8975f5c5SAndroid Build Coastguard Worker                                EGLint attribute,
6671*8975f5c5SAndroid Build Coastguard Worker                                const EGLAttribKHR *value)
6672*8975f5c5SAndroid Build Coastguard Worker {
6673*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateDisplay(val, dpy));
6674*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateSurface(val, dpy, surfaceID));
6675*8975f5c5SAndroid Build Coastguard Worker 
6676*8975f5c5SAndroid Build Coastguard Worker     if (!dpy->getExtensions().lockSurface3KHR)
6677*8975f5c5SAndroid Build Coastguard Worker     {
6678*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_ACCESS);
6679*8975f5c5SAndroid Build Coastguard Worker         return false;
6680*8975f5c5SAndroid Build Coastguard Worker     }
6681*8975f5c5SAndroid Build Coastguard Worker 
6682*8975f5c5SAndroid Build Coastguard Worker     switch (attribute)
6683*8975f5c5SAndroid Build Coastguard Worker     {
6684*8975f5c5SAndroid Build Coastguard Worker         case EGL_BITMAP_PITCH_KHR:
6685*8975f5c5SAndroid Build Coastguard Worker         case EGL_BITMAP_ORIGIN_KHR:
6686*8975f5c5SAndroid Build Coastguard Worker         case EGL_BITMAP_PIXEL_RED_OFFSET_KHR:
6687*8975f5c5SAndroid Build Coastguard Worker         case EGL_BITMAP_PIXEL_GREEN_OFFSET_KHR:
6688*8975f5c5SAndroid Build Coastguard Worker         case EGL_BITMAP_PIXEL_BLUE_OFFSET_KHR:
6689*8975f5c5SAndroid Build Coastguard Worker         case EGL_BITMAP_PIXEL_ALPHA_OFFSET_KHR:
6690*8975f5c5SAndroid Build Coastguard Worker         case EGL_BITMAP_PIXEL_LUMINANCE_OFFSET_KHR:
6691*8975f5c5SAndroid Build Coastguard Worker         case EGL_BITMAP_PIXEL_SIZE_KHR:
6692*8975f5c5SAndroid Build Coastguard Worker         case EGL_BITMAP_POINTER_KHR:
6693*8975f5c5SAndroid Build Coastguard Worker             break;
6694*8975f5c5SAndroid Build Coastguard Worker         default:
6695*8975f5c5SAndroid Build Coastguard Worker         {
6696*8975f5c5SAndroid Build Coastguard Worker             EGLint querySurfaceValue;
6697*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_TRY(
6698*8975f5c5SAndroid Build Coastguard Worker                 ValidateQuerySurface(val, dpy, surfaceID, attribute, &querySurfaceValue));
6699*8975f5c5SAndroid Build Coastguard Worker         }
6700*8975f5c5SAndroid Build Coastguard Worker         break;
6701*8975f5c5SAndroid Build Coastguard Worker     }
6702*8975f5c5SAndroid Build Coastguard Worker 
6703*8975f5c5SAndroid Build Coastguard Worker     if (value == nullptr)
6704*8975f5c5SAndroid Build Coastguard Worker     {
6705*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_PARAMETER, "value is NULL.");
6706*8975f5c5SAndroid Build Coastguard Worker         return false;
6707*8975f5c5SAndroid Build Coastguard Worker     }
6708*8975f5c5SAndroid Build Coastguard Worker 
6709*8975f5c5SAndroid Build Coastguard Worker     // EGL_KHR_lock_surface3
6710*8975f5c5SAndroid Build Coastguard Worker     //  If <attribute> is either EGL_BITMAP_POINTER_KHR or EGL_BITMAP_PITCH_KHR, and either
6711*8975f5c5SAndroid Build Coastguard Worker     //  <surface> is not locked using eglLockSurfaceKHR ... then an EGL_BAD_ACCESS error is
6712*8975f5c5SAndroid Build Coastguard Worker     //  generated.
6713*8975f5c5SAndroid Build Coastguard Worker     const bool surfaceShouldBeLocked =
6714*8975f5c5SAndroid Build Coastguard Worker         (attribute == EGL_BITMAP_POINTER_KHR) || (attribute == EGL_BITMAP_PITCH_KHR);
6715*8975f5c5SAndroid Build Coastguard Worker     const Surface *surface = dpy->getSurface(surfaceID);
6716*8975f5c5SAndroid Build Coastguard Worker     if (surfaceShouldBeLocked && !surface->isLocked())
6717*8975f5c5SAndroid Build Coastguard Worker     {
6718*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_ACCESS, "Surface is not locked");
6719*8975f5c5SAndroid Build Coastguard Worker         return false;
6720*8975f5c5SAndroid Build Coastguard Worker     }
6721*8975f5c5SAndroid Build Coastguard Worker 
6722*8975f5c5SAndroid Build Coastguard Worker     return true;
6723*8975f5c5SAndroid Build Coastguard Worker }
6724*8975f5c5SAndroid Build Coastguard Worker 
ValidateUnlockSurfaceKHR(const ValidationContext * val,const egl::Display * dpy,SurfaceID surfaceID)6725*8975f5c5SAndroid Build Coastguard Worker bool ValidateUnlockSurfaceKHR(const ValidationContext *val,
6726*8975f5c5SAndroid Build Coastguard Worker                               const egl::Display *dpy,
6727*8975f5c5SAndroid Build Coastguard Worker                               SurfaceID surfaceID)
6728*8975f5c5SAndroid Build Coastguard Worker {
6729*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateDisplay(val, dpy));
6730*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateSurface(val, dpy, surfaceID));
6731*8975f5c5SAndroid Build Coastguard Worker 
6732*8975f5c5SAndroid Build Coastguard Worker     if (!dpy->getExtensions().lockSurface3KHR)
6733*8975f5c5SAndroid Build Coastguard Worker     {
6734*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_ACCESS);
6735*8975f5c5SAndroid Build Coastguard Worker         return false;
6736*8975f5c5SAndroid Build Coastguard Worker     }
6737*8975f5c5SAndroid Build Coastguard Worker 
6738*8975f5c5SAndroid Build Coastguard Worker     const Surface *surface = dpy->getSurface(surfaceID);
6739*8975f5c5SAndroid Build Coastguard Worker     if (!surface->isLocked())
6740*8975f5c5SAndroid Build Coastguard Worker     {
6741*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_PARAMETER, "Surface is not locked.");
6742*8975f5c5SAndroid Build Coastguard Worker         return false;
6743*8975f5c5SAndroid Build Coastguard Worker     }
6744*8975f5c5SAndroid Build Coastguard Worker 
6745*8975f5c5SAndroid Build Coastguard Worker     return true;
6746*8975f5c5SAndroid Build Coastguard Worker }
6747*8975f5c5SAndroid Build Coastguard Worker 
ValidateExportVkImageANGLE(const ValidationContext * val,const Display * dpy,ImageID imageID,const void * vkImage,const void * vkImageCreateInfo)6748*8975f5c5SAndroid Build Coastguard Worker bool ValidateExportVkImageANGLE(const ValidationContext *val,
6749*8975f5c5SAndroid Build Coastguard Worker                                 const Display *dpy,
6750*8975f5c5SAndroid Build Coastguard Worker                                 ImageID imageID,
6751*8975f5c5SAndroid Build Coastguard Worker                                 const void *vkImage,
6752*8975f5c5SAndroid Build Coastguard Worker                                 const void *vkImageCreateInfo)
6753*8975f5c5SAndroid Build Coastguard Worker {
6754*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateImage(val, dpy, imageID));
6755*8975f5c5SAndroid Build Coastguard Worker 
6756*8975f5c5SAndroid Build Coastguard Worker     if (!dpy->getExtensions().vulkanImageANGLE)
6757*8975f5c5SAndroid Build Coastguard Worker     {
6758*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_ACCESS);
6759*8975f5c5SAndroid Build Coastguard Worker         return false;
6760*8975f5c5SAndroid Build Coastguard Worker     }
6761*8975f5c5SAndroid Build Coastguard Worker 
6762*8975f5c5SAndroid Build Coastguard Worker     if (!vkImage)
6763*8975f5c5SAndroid Build Coastguard Worker     {
6764*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_PARAMETER, "Output VkImage pointer is null.");
6765*8975f5c5SAndroid Build Coastguard Worker         return false;
6766*8975f5c5SAndroid Build Coastguard Worker     }
6767*8975f5c5SAndroid Build Coastguard Worker 
6768*8975f5c5SAndroid Build Coastguard Worker     if (!vkImageCreateInfo)
6769*8975f5c5SAndroid Build Coastguard Worker     {
6770*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_PARAMETER, "Output VkImageCreateInfo pointer is null.");
6771*8975f5c5SAndroid Build Coastguard Worker         return false;
6772*8975f5c5SAndroid Build Coastguard Worker     }
6773*8975f5c5SAndroid Build Coastguard Worker 
6774*8975f5c5SAndroid Build Coastguard Worker     return true;
6775*8975f5c5SAndroid Build Coastguard Worker }
6776*8975f5c5SAndroid Build Coastguard Worker 
ValidateSetDamageRegionKHR(const ValidationContext * val,const Display * display,SurfaceID surfaceID,const EGLint * rects,EGLint n_rects)6777*8975f5c5SAndroid Build Coastguard Worker bool ValidateSetDamageRegionKHR(const ValidationContext *val,
6778*8975f5c5SAndroid Build Coastguard Worker                                 const Display *display,
6779*8975f5c5SAndroid Build Coastguard Worker                                 SurfaceID surfaceID,
6780*8975f5c5SAndroid Build Coastguard Worker                                 const EGLint *rects,
6781*8975f5c5SAndroid Build Coastguard Worker                                 EGLint n_rects)
6782*8975f5c5SAndroid Build Coastguard Worker {
6783*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
6784*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateSurface(val, display, surfaceID));
6785*8975f5c5SAndroid Build Coastguard Worker 
6786*8975f5c5SAndroid Build Coastguard Worker     const Surface *surface = display->getSurface(surfaceID);
6787*8975f5c5SAndroid Build Coastguard Worker     if (!(surface->getType() & EGL_WINDOW_BIT))
6788*8975f5c5SAndroid Build Coastguard Worker     {
6789*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_MATCH, "surface is not a postable surface");
6790*8975f5c5SAndroid Build Coastguard Worker         return false;
6791*8975f5c5SAndroid Build Coastguard Worker     }
6792*8975f5c5SAndroid Build Coastguard Worker 
6793*8975f5c5SAndroid Build Coastguard Worker     if (surface != val->eglThread->getCurrentDrawSurface())
6794*8975f5c5SAndroid Build Coastguard Worker     {
6795*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_MATCH,
6796*8975f5c5SAndroid Build Coastguard Worker                       "surface is not the current draw surface for the calling thread");
6797*8975f5c5SAndroid Build Coastguard Worker         return false;
6798*8975f5c5SAndroid Build Coastguard Worker     }
6799*8975f5c5SAndroid Build Coastguard Worker 
6800*8975f5c5SAndroid Build Coastguard Worker     if (surface->getSwapBehavior() != EGL_BUFFER_DESTROYED)
6801*8975f5c5SAndroid Build Coastguard Worker     {
6802*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_MATCH, "surface's swap behavior is not EGL_BUFFER_DESTROYED");
6803*8975f5c5SAndroid Build Coastguard Worker         return false;
6804*8975f5c5SAndroid Build Coastguard Worker     }
6805*8975f5c5SAndroid Build Coastguard Worker 
6806*8975f5c5SAndroid Build Coastguard Worker     if (surface->isDamageRegionSet())
6807*8975f5c5SAndroid Build Coastguard Worker     {
6808*8975f5c5SAndroid Build Coastguard Worker         val->setError(
6809*8975f5c5SAndroid Build Coastguard Worker             EGL_BAD_ACCESS,
6810*8975f5c5SAndroid Build Coastguard Worker             "damage region has already been set on surface since the most recent frame boundary");
6811*8975f5c5SAndroid Build Coastguard Worker         return false;
6812*8975f5c5SAndroid Build Coastguard Worker     }
6813*8975f5c5SAndroid Build Coastguard Worker 
6814*8975f5c5SAndroid Build Coastguard Worker     if (!surface->bufferAgeQueriedSinceLastSwap())
6815*8975f5c5SAndroid Build Coastguard Worker     {
6816*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_ACCESS,
6817*8975f5c5SAndroid Build Coastguard Worker                       "EGL_BUFFER_AGE_KHR attribute of surface has not been queried since the most "
6818*8975f5c5SAndroid Build Coastguard Worker                       "recent frame boundary");
6819*8975f5c5SAndroid Build Coastguard Worker         return false;
6820*8975f5c5SAndroid Build Coastguard Worker     }
6821*8975f5c5SAndroid Build Coastguard Worker 
6822*8975f5c5SAndroid Build Coastguard Worker     return true;
6823*8975f5c5SAndroid Build Coastguard Worker }
6824*8975f5c5SAndroid Build Coastguard Worker 
ValidateQueryDmaBufFormatsEXT(ValidationContext const * val,Display const * dpy,EGLint max_formats,const EGLint * formats,const EGLint * num_formats)6825*8975f5c5SAndroid Build Coastguard Worker bool ValidateQueryDmaBufFormatsEXT(ValidationContext const *val,
6826*8975f5c5SAndroid Build Coastguard Worker                                    Display const *dpy,
6827*8975f5c5SAndroid Build Coastguard Worker                                    EGLint max_formats,
6828*8975f5c5SAndroid Build Coastguard Worker                                    const EGLint *formats,
6829*8975f5c5SAndroid Build Coastguard Worker                                    const EGLint *num_formats)
6830*8975f5c5SAndroid Build Coastguard Worker {
6831*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateDisplay(val, dpy));
6832*8975f5c5SAndroid Build Coastguard Worker 
6833*8975f5c5SAndroid Build Coastguard Worker     if (!dpy->getExtensions().imageDmaBufImportModifiersEXT)
6834*8975f5c5SAndroid Build Coastguard Worker     {
6835*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_ACCESS, "EGL_EXT_dma_buf_import_modfier not supported");
6836*8975f5c5SAndroid Build Coastguard Worker         return false;
6837*8975f5c5SAndroid Build Coastguard Worker     }
6838*8975f5c5SAndroid Build Coastguard Worker 
6839*8975f5c5SAndroid Build Coastguard Worker     if (max_formats < 0)
6840*8975f5c5SAndroid Build Coastguard Worker     {
6841*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_PARAMETER, "max_formats should not be negative");
6842*8975f5c5SAndroid Build Coastguard Worker         return false;
6843*8975f5c5SAndroid Build Coastguard Worker     }
6844*8975f5c5SAndroid Build Coastguard Worker 
6845*8975f5c5SAndroid Build Coastguard Worker     if (max_formats > 0 && formats == nullptr)
6846*8975f5c5SAndroid Build Coastguard Worker     {
6847*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_PARAMETER, "if max_formats is positive, formats should not be NULL");
6848*8975f5c5SAndroid Build Coastguard Worker         return false;
6849*8975f5c5SAndroid Build Coastguard Worker     }
6850*8975f5c5SAndroid Build Coastguard Worker 
6851*8975f5c5SAndroid Build Coastguard Worker     return true;
6852*8975f5c5SAndroid Build Coastguard Worker }
6853*8975f5c5SAndroid Build Coastguard Worker 
ValidateQueryDmaBufModifiersEXT(ValidationContext const * val,Display const * dpy,EGLint format,EGLint max_modifiers,const EGLuint64KHR * modifiers,const EGLBoolean * external_only,const EGLint * num_modifiers)6854*8975f5c5SAndroid Build Coastguard Worker bool ValidateQueryDmaBufModifiersEXT(ValidationContext const *val,
6855*8975f5c5SAndroid Build Coastguard Worker                                      Display const *dpy,
6856*8975f5c5SAndroid Build Coastguard Worker                                      EGLint format,
6857*8975f5c5SAndroid Build Coastguard Worker                                      EGLint max_modifiers,
6858*8975f5c5SAndroid Build Coastguard Worker                                      const EGLuint64KHR *modifiers,
6859*8975f5c5SAndroid Build Coastguard Worker                                      const EGLBoolean *external_only,
6860*8975f5c5SAndroid Build Coastguard Worker                                      const EGLint *num_modifiers)
6861*8975f5c5SAndroid Build Coastguard Worker {
6862*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateDisplay(val, dpy));
6863*8975f5c5SAndroid Build Coastguard Worker 
6864*8975f5c5SAndroid Build Coastguard Worker     if (!dpy->getExtensions().imageDmaBufImportModifiersEXT)
6865*8975f5c5SAndroid Build Coastguard Worker     {
6866*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_ACCESS, "EGL_EXT_dma_buf_import_modfier not supported");
6867*8975f5c5SAndroid Build Coastguard Worker         return false;
6868*8975f5c5SAndroid Build Coastguard Worker     }
6869*8975f5c5SAndroid Build Coastguard Worker 
6870*8975f5c5SAndroid Build Coastguard Worker     if (max_modifiers < 0)
6871*8975f5c5SAndroid Build Coastguard Worker     {
6872*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_PARAMETER, "max_modifiers should not be negative");
6873*8975f5c5SAndroid Build Coastguard Worker         return false;
6874*8975f5c5SAndroid Build Coastguard Worker     }
6875*8975f5c5SAndroid Build Coastguard Worker 
6876*8975f5c5SAndroid Build Coastguard Worker     if (max_modifiers > 0 && modifiers == nullptr)
6877*8975f5c5SAndroid Build Coastguard Worker     {
6878*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_PARAMETER,
6879*8975f5c5SAndroid Build Coastguard Worker                       "if max_modifiers is positive, modifiers should not be NULL");
6880*8975f5c5SAndroid Build Coastguard Worker         return false;
6881*8975f5c5SAndroid Build Coastguard Worker     }
6882*8975f5c5SAndroid Build Coastguard Worker 
6883*8975f5c5SAndroid Build Coastguard Worker     if (!dpy->supportsDmaBufFormat(format))
6884*8975f5c5SAndroid Build Coastguard Worker     {
6885*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_PARAMETER,
6886*8975f5c5SAndroid Build Coastguard Worker                       "format should be one of the formats advertised by QueryDmaBufFormatsEXT");
6887*8975f5c5SAndroid Build Coastguard Worker         return false;
6888*8975f5c5SAndroid Build Coastguard Worker     }
6889*8975f5c5SAndroid Build Coastguard Worker     return true;
6890*8975f5c5SAndroid Build Coastguard Worker }
6891*8975f5c5SAndroid Build Coastguard Worker 
ValidateAcquireExternalContextANGLE(const ValidationContext * val,const egl::Display * display,SurfaceID drawAndReadPacked)6892*8975f5c5SAndroid Build Coastguard Worker bool ValidateAcquireExternalContextANGLE(const ValidationContext *val,
6893*8975f5c5SAndroid Build Coastguard Worker                                          const egl::Display *display,
6894*8975f5c5SAndroid Build Coastguard Worker                                          SurfaceID drawAndReadPacked)
6895*8975f5c5SAndroid Build Coastguard Worker {
6896*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
6897*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateSurface(val, display, drawAndReadPacked));
6898*8975f5c5SAndroid Build Coastguard Worker 
6899*8975f5c5SAndroid Build Coastguard Worker     const DisplayExtensions &displayExtensions = display->getExtensions();
6900*8975f5c5SAndroid Build Coastguard Worker     if (!displayExtensions.externalContextAndSurface)
6901*8975f5c5SAndroid Build Coastguard Worker     {
6902*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_ACCESS, "EGL_ANGLE_external_context_and_surface is not available");
6903*8975f5c5SAndroid Build Coastguard Worker         return false;
6904*8975f5c5SAndroid Build Coastguard Worker     }
6905*8975f5c5SAndroid Build Coastguard Worker 
6906*8975f5c5SAndroid Build Coastguard Worker     gl::Context *currentContext = val->eglThread->getContext();
6907*8975f5c5SAndroid Build Coastguard Worker     if (currentContext == nullptr || !currentContext->isExternal())
6908*8975f5c5SAndroid Build Coastguard Worker     {
6909*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_CONTEXT, "Current context is not an external context");
6910*8975f5c5SAndroid Build Coastguard Worker         return false;
6911*8975f5c5SAndroid Build Coastguard Worker     }
6912*8975f5c5SAndroid Build Coastguard Worker 
6913*8975f5c5SAndroid Build Coastguard Worker     return true;
6914*8975f5c5SAndroid Build Coastguard Worker }
6915*8975f5c5SAndroid Build Coastguard Worker 
ValidateReleaseExternalContextANGLE(const ValidationContext * val,const egl::Display * display)6916*8975f5c5SAndroid Build Coastguard Worker bool ValidateReleaseExternalContextANGLE(const ValidationContext *val, const egl::Display *display)
6917*8975f5c5SAndroid Build Coastguard Worker {
6918*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
6919*8975f5c5SAndroid Build Coastguard Worker 
6920*8975f5c5SAndroid Build Coastguard Worker     const DisplayExtensions &displayExtensions = display->getExtensions();
6921*8975f5c5SAndroid Build Coastguard Worker     if (!displayExtensions.externalContextAndSurface)
6922*8975f5c5SAndroid Build Coastguard Worker     {
6923*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_ACCESS, "EGL_ANGLE_external_context_and_surface is not available");
6924*8975f5c5SAndroid Build Coastguard Worker         return false;
6925*8975f5c5SAndroid Build Coastguard Worker     }
6926*8975f5c5SAndroid Build Coastguard Worker 
6927*8975f5c5SAndroid Build Coastguard Worker     gl::Context *currentContext = val->eglThread->getContext();
6928*8975f5c5SAndroid Build Coastguard Worker     if (currentContext == nullptr || !currentContext->isExternal())
6929*8975f5c5SAndroid Build Coastguard Worker     {
6930*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_CONTEXT, "Current context is not an external context");
6931*8975f5c5SAndroid Build Coastguard Worker         return false;
6932*8975f5c5SAndroid Build Coastguard Worker     }
6933*8975f5c5SAndroid Build Coastguard Worker 
6934*8975f5c5SAndroid Build Coastguard Worker     return true;
6935*8975f5c5SAndroid Build Coastguard Worker }
6936*8975f5c5SAndroid Build Coastguard Worker 
ValidateSetValidationEnabledANGLE(const ValidationContext * val,EGLBoolean validationState)6937*8975f5c5SAndroid Build Coastguard Worker bool ValidateSetValidationEnabledANGLE(const ValidationContext *val, EGLBoolean validationState)
6938*8975f5c5SAndroid Build Coastguard Worker {
6939*8975f5c5SAndroid Build Coastguard Worker     const ClientExtensions &clientExtensions = Display::GetClientExtensions();
6940*8975f5c5SAndroid Build Coastguard Worker     if (!clientExtensions.noErrorANGLE)
6941*8975f5c5SAndroid Build Coastguard Worker     {
6942*8975f5c5SAndroid Build Coastguard Worker         val->setError(EGL_BAD_ACCESS, "EGL_ANGLE_no_error is not available.");
6943*8975f5c5SAndroid Build Coastguard Worker         return false;
6944*8975f5c5SAndroid Build Coastguard Worker     }
6945*8975f5c5SAndroid Build Coastguard Worker 
6946*8975f5c5SAndroid Build Coastguard Worker     return true;
6947*8975f5c5SAndroid Build Coastguard Worker }
6948*8975f5c5SAndroid Build Coastguard Worker 
6949*8975f5c5SAndroid Build Coastguard Worker }  // namespace egl
6950