xref: /aosp_15_r20/external/angle/src/libANGLE/validationEGL.h (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2015 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.h: Validation functions for generic EGL entry point parameters
8*8975f5c5SAndroid Build Coastguard Worker 
9*8975f5c5SAndroid Build Coastguard Worker #ifndef LIBANGLE_VALIDATIONEGL_H_
10*8975f5c5SAndroid Build Coastguard Worker #define LIBANGLE_VALIDATIONEGL_H_
11*8975f5c5SAndroid Build Coastguard Worker 
12*8975f5c5SAndroid Build Coastguard Worker #include "common/PackedEnums.h"
13*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Display.h"
14*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Error.h"
15*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Thread.h"
16*8975f5c5SAndroid Build Coastguard Worker 
17*8975f5c5SAndroid Build Coastguard Worker #include <EGL/egl.h>
18*8975f5c5SAndroid Build Coastguard Worker #include <EGL/eglext.h>
19*8975f5c5SAndroid Build Coastguard Worker 
20*8975f5c5SAndroid Build Coastguard Worker namespace gl
21*8975f5c5SAndroid Build Coastguard Worker {
22*8975f5c5SAndroid Build Coastguard Worker class Context;
23*8975f5c5SAndroid Build Coastguard Worker }
24*8975f5c5SAndroid Build Coastguard Worker 
25*8975f5c5SAndroid Build Coastguard Worker namespace egl
26*8975f5c5SAndroid Build Coastguard Worker {
27*8975f5c5SAndroid Build Coastguard Worker constexpr EGLint kEglMajorVersion = 1;
28*8975f5c5SAndroid Build Coastguard Worker constexpr EGLint kEglMinorVersion = 5;
29*8975f5c5SAndroid Build Coastguard Worker 
30*8975f5c5SAndroid Build Coastguard Worker class AttributeMap;
31*8975f5c5SAndroid Build Coastguard Worker struct ClientExtensions;
32*8975f5c5SAndroid Build Coastguard Worker struct Config;
33*8975f5c5SAndroid Build Coastguard Worker class Device;
34*8975f5c5SAndroid Build Coastguard Worker class Display;
35*8975f5c5SAndroid Build Coastguard Worker class Image;
36*8975f5c5SAndroid Build Coastguard Worker class Stream;
37*8975f5c5SAndroid Build Coastguard Worker class Surface;
38*8975f5c5SAndroid Build Coastguard Worker class Sync;
39*8975f5c5SAndroid Build Coastguard Worker class Thread;
40*8975f5c5SAndroid Build Coastguard Worker class LabeledObject;
41*8975f5c5SAndroid Build Coastguard Worker 
42*8975f5c5SAndroid Build Coastguard Worker struct ValidationContext
43*8975f5c5SAndroid Build Coastguard Worker {
ValidationContextValidationContext44*8975f5c5SAndroid Build Coastguard Worker     ValidationContext(Thread *threadIn, const char *entryPointIn, const LabeledObject *objectIn)
45*8975f5c5SAndroid Build Coastguard Worker         : eglThread(threadIn), entryPoint(entryPointIn), labeledObject(objectIn)
46*8975f5c5SAndroid Build Coastguard Worker     {}
47*8975f5c5SAndroid Build Coastguard Worker 
48*8975f5c5SAndroid Build Coastguard Worker     // We should remove the message-less overload once we have messages for all EGL errors.
49*8975f5c5SAndroid Build Coastguard Worker     void setError(EGLint error) const;
50*8975f5c5SAndroid Build Coastguard Worker     ANGLE_FORMAT_PRINTF(3, 4)
51*8975f5c5SAndroid Build Coastguard Worker     void setError(EGLint error, const char *message...) const;
52*8975f5c5SAndroid Build Coastguard Worker 
53*8975f5c5SAndroid Build Coastguard Worker     Thread *eglThread;
54*8975f5c5SAndroid Build Coastguard Worker     const char *entryPoint;
55*8975f5c5SAndroid Build Coastguard Worker     const LabeledObject *labeledObject;
56*8975f5c5SAndroid Build Coastguard Worker };
57*8975f5c5SAndroid Build Coastguard Worker 
58*8975f5c5SAndroid Build Coastguard Worker // Object validation
59*8975f5c5SAndroid Build Coastguard Worker bool ValidateDisplay(const ValidationContext *val, const Display *display);
60*8975f5c5SAndroid Build Coastguard Worker bool ValidateSurface(const ValidationContext *val, const Display *display, SurfaceID surfaceID);
61*8975f5c5SAndroid Build Coastguard Worker bool ValidateConfig(const ValidationContext *val, const Display *display, const Config *config);
62*8975f5c5SAndroid Build Coastguard Worker bool ValidateContext(const ValidationContext *val, const Display *display, gl::ContextID contextID);
63*8975f5c5SAndroid Build Coastguard Worker bool ValidateImage(const ValidationContext *val, const Display *display, ImageID imageID);
64*8975f5c5SAndroid Build Coastguard Worker bool ValidateDevice(const ValidationContext *val, const Device *device);
65*8975f5c5SAndroid Build Coastguard Worker bool ValidateSync(const ValidationContext *val, const Display *display, SyncID sync);
66*8975f5c5SAndroid Build Coastguard Worker 
67*8975f5c5SAndroid Build Coastguard Worker // Return the requested object only if it is valid (otherwise nullptr)
68*8975f5c5SAndroid Build Coastguard Worker const Thread *GetThreadIfValid(const Thread *thread);
69*8975f5c5SAndroid Build Coastguard Worker const Display *GetDisplayIfValid(const Display *display);
70*8975f5c5SAndroid Build Coastguard Worker const Surface *GetSurfaceIfValid(const Display *display, SurfaceID surfaceID);
71*8975f5c5SAndroid Build Coastguard Worker const Image *GetImageIfValid(const Display *display, ImageID imageID);
72*8975f5c5SAndroid Build Coastguard Worker const Stream *GetStreamIfValid(const Display *display, const Stream *stream);
73*8975f5c5SAndroid Build Coastguard Worker const gl::Context *GetContextIfValid(const Display *display, gl::ContextID contextID);
74*8975f5c5SAndroid Build Coastguard Worker gl::Context *GetContextIfValid(Display *display, gl::ContextID contextID);
75*8975f5c5SAndroid Build Coastguard Worker const Device *GetDeviceIfValid(const Device *device);
76*8975f5c5SAndroid Build Coastguard Worker const Sync *GetSyncIfValid(const Display *display, SyncID sync);
77*8975f5c5SAndroid Build Coastguard Worker const LabeledObject *GetLabeledObjectIfValid(Thread *thread,
78*8975f5c5SAndroid Build Coastguard Worker                                              const Display *display,
79*8975f5c5SAndroid Build Coastguard Worker                                              ObjectType objectType,
80*8975f5c5SAndroid Build Coastguard Worker                                              EGLObjectKHR object);
81*8975f5c5SAndroid Build Coastguard Worker LabeledObject *GetLabeledObjectIfValid(Thread *thread,
82*8975f5c5SAndroid Build Coastguard Worker                                        Display *display,
83*8975f5c5SAndroid Build Coastguard Worker                                        ObjectType objectType,
84*8975f5c5SAndroid Build Coastguard Worker                                        EGLObjectKHR object);
85*8975f5c5SAndroid Build Coastguard Worker 
86*8975f5c5SAndroid Build Coastguard Worker // A template struct for determining the default value to return for each entry point.
87*8975f5c5SAndroid Build Coastguard Worker template <angle::EntryPoint EP, typename ReturnType>
88*8975f5c5SAndroid Build Coastguard Worker struct DefaultReturnValue
89*8975f5c5SAndroid Build Coastguard Worker {
90*8975f5c5SAndroid Build Coastguard Worker     static constexpr ReturnType kValue = static_cast<ReturnType>(0);
91*8975f5c5SAndroid Build Coastguard Worker };
92*8975f5c5SAndroid Build Coastguard Worker 
93*8975f5c5SAndroid Build Coastguard Worker template <angle::EntryPoint EP, typename ReturnType>
94*8975f5c5SAndroid Build Coastguard Worker ReturnType GetDefaultReturnValue(Thread *thread);
95*8975f5c5SAndroid Build Coastguard Worker 
96*8975f5c5SAndroid Build Coastguard Worker template <>
97*8975f5c5SAndroid Build Coastguard Worker ANGLE_INLINE EGLint
98*8975f5c5SAndroid Build Coastguard Worker GetDefaultReturnValue<angle::EntryPoint::EGLLabelObjectKHR, EGLint>(Thread *thread)
99*8975f5c5SAndroid Build Coastguard Worker {
100*8975f5c5SAndroid Build Coastguard Worker     return thread->getError();
101*8975f5c5SAndroid Build Coastguard Worker }
102*8975f5c5SAndroid Build Coastguard Worker 
103*8975f5c5SAndroid Build Coastguard Worker template <angle::EntryPoint EP, typename ReturnType>
GetDefaultReturnValue(Thread * thread)104*8975f5c5SAndroid Build Coastguard Worker ANGLE_INLINE ReturnType GetDefaultReturnValue(Thread *thread)
105*8975f5c5SAndroid Build Coastguard Worker {
106*8975f5c5SAndroid Build Coastguard Worker     return DefaultReturnValue<EP, ReturnType>::kValue;
107*8975f5c5SAndroid Build Coastguard Worker }
108*8975f5c5SAndroid Build Coastguard Worker 
109*8975f5c5SAndroid Build Coastguard Worker // First case: handling packed enums.
110*8975f5c5SAndroid Build Coastguard Worker template <typename PackedT, typename FromT>
PackParam(FromT from)111*8975f5c5SAndroid Build Coastguard Worker typename std::enable_if<std::is_enum<PackedT>::value, PackedT>::type PackParam(FromT from)
112*8975f5c5SAndroid Build Coastguard Worker {
113*8975f5c5SAndroid Build Coastguard Worker     return FromEGLenum<PackedT>(from);
114*8975f5c5SAndroid Build Coastguard Worker }
115*8975f5c5SAndroid Build Coastguard Worker 
116*8975f5c5SAndroid Build Coastguard Worker // Second case: handling resource ids.
117*8975f5c5SAndroid Build Coastguard Worker template <typename PackedT,
118*8975f5c5SAndroid Build Coastguard Worker           typename FromT,
119*8975f5c5SAndroid Build Coastguard Worker           typename std::enable_if<IsResourceIDType<PackedT>::value>::type * = nullptr>
PackParam(FromT from)120*8975f5c5SAndroid Build Coastguard Worker PackedT PackParam(FromT from)
121*8975f5c5SAndroid Build Coastguard Worker {
122*8975f5c5SAndroid Build Coastguard Worker     return {static_cast<GLuint>(reinterpret_cast<uintptr_t>(from))};
123*8975f5c5SAndroid Build Coastguard Worker }
124*8975f5c5SAndroid Build Coastguard Worker 
125*8975f5c5SAndroid Build Coastguard Worker // This and the next 2 template specializations handle distinguishing between EGLint, EGLAttrib
126*8975f5c5SAndroid Build Coastguard Worker // and other. This is needed because on some architectures EGLint and EGLAttrib are not the same
127*8975f5c5SAndroid Build Coastguard Worker // base type. Previously the code conditionally compiled 2 specializations on 64 bit but it turns
128*8975f5c5SAndroid Build Coastguard Worker // out on WatchOS the assumption about 32/64 bit and if EGLint and ELGAttrib are the same or
129*8975f5c5SAndroid Build Coastguard Worker // different did not hold.
130*8975f5c5SAndroid Build Coastguard Worker template <typename PackedT,
131*8975f5c5SAndroid Build Coastguard Worker           typename FromT,
132*8975f5c5SAndroid Build Coastguard Worker           typename std::enable_if<!std::is_enum<PackedT>::value>::type              * = nullptr,
133*8975f5c5SAndroid Build Coastguard Worker           typename std::enable_if<std::is_same<FromT, const EGLint *>::value>::type * = nullptr>
PackParam(FromT attribs)134*8975f5c5SAndroid Build Coastguard Worker typename std::remove_reference<PackedT>::type PackParam(FromT attribs)
135*8975f5c5SAndroid Build Coastguard Worker {
136*8975f5c5SAndroid Build Coastguard Worker     return AttributeMap::CreateFromIntArray(attribs);
137*8975f5c5SAndroid Build Coastguard Worker }
138*8975f5c5SAndroid Build Coastguard Worker 
139*8975f5c5SAndroid Build Coastguard Worker template <typename PackedT,
140*8975f5c5SAndroid Build Coastguard Worker           typename FromT,
141*8975f5c5SAndroid Build Coastguard Worker           typename std::enable_if<!std::is_enum<PackedT>::value>::type                 * = nullptr,
142*8975f5c5SAndroid Build Coastguard Worker           typename std::enable_if<!std::is_same<FromT, const EGLint *>::value>::type   * = nullptr,
143*8975f5c5SAndroid Build Coastguard Worker           typename std::enable_if<std::is_same<FromT, const EGLAttrib *>::value>::type * = nullptr>
PackParam(FromT attribs)144*8975f5c5SAndroid Build Coastguard Worker typename std::remove_reference<PackedT>::type PackParam(FromT attribs)
145*8975f5c5SAndroid Build Coastguard Worker {
146*8975f5c5SAndroid Build Coastguard Worker     return AttributeMap::CreateFromAttribArray(attribs);
147*8975f5c5SAndroid Build Coastguard Worker }
148*8975f5c5SAndroid Build Coastguard Worker 
149*8975f5c5SAndroid Build Coastguard Worker template <typename PackedT,
150*8975f5c5SAndroid Build Coastguard Worker           typename FromT,
151*8975f5c5SAndroid Build Coastguard Worker           typename std::enable_if<!std::is_enum<PackedT>::value>::type                  * = nullptr,
152*8975f5c5SAndroid Build Coastguard Worker           typename std::enable_if<!std::is_same<FromT, const EGLint *>::value>::type    * = nullptr,
153*8975f5c5SAndroid Build Coastguard Worker           typename std::enable_if<!std::is_same<FromT, const EGLAttrib *>::value>::type * = nullptr,
154*8975f5c5SAndroid Build Coastguard Worker           typename std::enable_if<!IsResourceIDType<PackedT>::value>::type              * = nullptr>
PackParam(FromT from)155*8975f5c5SAndroid Build Coastguard Worker typename std::remove_reference<PackedT>::type PackParam(FromT from)
156*8975f5c5SAndroid Build Coastguard Worker {
157*8975f5c5SAndroid Build Coastguard Worker     return static_cast<PackedT>(from);
158*8975f5c5SAndroid Build Coastguard Worker }
159*8975f5c5SAndroid Build Coastguard Worker 
160*8975f5c5SAndroid Build Coastguard Worker }  // namespace egl
161*8975f5c5SAndroid Build Coastguard Worker 
162*8975f5c5SAndroid Build Coastguard Worker #define ANGLE_EGL_VALIDATE(THREAD, EP, OBJ, RETURN_TYPE, ...)                              \
163*8975f5c5SAndroid Build Coastguard Worker     do                                                                                     \
164*8975f5c5SAndroid Build Coastguard Worker     {                                                                                      \
165*8975f5c5SAndroid Build Coastguard Worker         const char *epname = "egl" #EP;                                                    \
166*8975f5c5SAndroid Build Coastguard Worker         ValidationContext vctx(THREAD, epname, OBJ);                                       \
167*8975f5c5SAndroid Build Coastguard Worker         auto ANGLE_LOCAL_VAR = (Validate##EP(&vctx, ##__VA_ARGS__));                       \
168*8975f5c5SAndroid Build Coastguard Worker         if (!ANGLE_LOCAL_VAR)                                                              \
169*8975f5c5SAndroid Build Coastguard Worker         {                                                                                  \
170*8975f5c5SAndroid Build Coastguard Worker             return GetDefaultReturnValue<angle::EntryPoint::EGL##EP, RETURN_TYPE>(THREAD); \
171*8975f5c5SAndroid Build Coastguard Worker         }                                                                                  \
172*8975f5c5SAndroid Build Coastguard Worker     } while (0)
173*8975f5c5SAndroid Build Coastguard Worker 
174*8975f5c5SAndroid Build Coastguard Worker #define ANGLE_EGL_VALIDATE_VOID(THREAD, EP, OBJ, ...)                \
175*8975f5c5SAndroid Build Coastguard Worker     do                                                               \
176*8975f5c5SAndroid Build Coastguard Worker     {                                                                \
177*8975f5c5SAndroid Build Coastguard Worker         const char *epname = "egl" #EP;                              \
178*8975f5c5SAndroid Build Coastguard Worker         ValidationContext vctx(THREAD, epname, OBJ);                 \
179*8975f5c5SAndroid Build Coastguard Worker         auto ANGLE_LOCAL_VAR = (Validate##EP(&vctx, ##__VA_ARGS__)); \
180*8975f5c5SAndroid Build Coastguard Worker         if (!ANGLE_LOCAL_VAR)                                        \
181*8975f5c5SAndroid Build Coastguard Worker         {                                                            \
182*8975f5c5SAndroid Build Coastguard Worker             return;                                                  \
183*8975f5c5SAndroid Build Coastguard Worker         }                                                            \
184*8975f5c5SAndroid Build Coastguard Worker     } while (0)
185*8975f5c5SAndroid Build Coastguard Worker 
186*8975f5c5SAndroid Build Coastguard Worker #define ANGLE_EGL_TRY(THREAD, EXPR, FUNCNAME, LABELOBJECT)                   \
187*8975f5c5SAndroid Build Coastguard Worker     do                                                                       \
188*8975f5c5SAndroid Build Coastguard Worker     {                                                                        \
189*8975f5c5SAndroid Build Coastguard Worker         auto ANGLE_LOCAL_VAR = (EXPR);                                       \
190*8975f5c5SAndroid Build Coastguard Worker         if (ANGLE_LOCAL_VAR.isError())                                       \
191*8975f5c5SAndroid Build Coastguard Worker             return THREAD->setError(ANGLE_LOCAL_VAR, FUNCNAME, LABELOBJECT); \
192*8975f5c5SAndroid Build Coastguard Worker     } while (0)
193*8975f5c5SAndroid Build Coastguard Worker 
194*8975f5c5SAndroid Build Coastguard Worker #define ANGLE_EGL_TRY_RETURN(THREAD, EXPR, FUNCNAME, LABELOBJECT, RETVAL) \
195*8975f5c5SAndroid Build Coastguard Worker     do                                                                    \
196*8975f5c5SAndroid Build Coastguard Worker     {                                                                     \
197*8975f5c5SAndroid Build Coastguard Worker         auto ANGLE_LOCAL_VAR = (EXPR);                                    \
198*8975f5c5SAndroid Build Coastguard Worker         if (ANGLE_LOCAL_VAR.isError())                                    \
199*8975f5c5SAndroid Build Coastguard Worker         {                                                                 \
200*8975f5c5SAndroid Build Coastguard Worker             THREAD->setError(ANGLE_LOCAL_VAR, FUNCNAME, LABELOBJECT);     \
201*8975f5c5SAndroid Build Coastguard Worker             return RETVAL;                                                \
202*8975f5c5SAndroid Build Coastguard Worker         }                                                                 \
203*8975f5c5SAndroid Build Coastguard Worker     } while (0)
204*8975f5c5SAndroid Build Coastguard Worker 
205*8975f5c5SAndroid Build Coastguard Worker #if ANGLE_USE_DISPLAY_PREPARE_FOR_CALL
206*8975f5c5SAndroid Build Coastguard Worker #    define ANGLE_EGL_TRY_PREPARE_FOR_CALL_RETURN ANGLE_EGL_TRY_RETURN
207*8975f5c5SAndroid Build Coastguard Worker #    define ANGLE_EGL_TRY_PREPARE_FOR_CALL ANGLE_EGL_TRY
208*8975f5c5SAndroid Build Coastguard Worker #else
209*8975f5c5SAndroid Build Coastguard Worker #    define ANGLE_EGL_TRY_PREPARE_FOR_CALL_RETURN(...)
210*8975f5c5SAndroid Build Coastguard Worker #    define ANGLE_EGL_TRY_PREPARE_FOR_CALL(...)
211*8975f5c5SAndroid Build Coastguard Worker #endif
212*8975f5c5SAndroid Build Coastguard Worker 
213*8975f5c5SAndroid Build Coastguard Worker #define ANGLE_EGLBOOLEAN_TRY(EXPR)           \
214*8975f5c5SAndroid Build Coastguard Worker     do                                       \
215*8975f5c5SAndroid Build Coastguard Worker     {                                        \
216*8975f5c5SAndroid Build Coastguard Worker         EGLBoolean ANGLE_LOCAL_VAR = (EXPR); \
217*8975f5c5SAndroid Build Coastguard Worker         if (ANGLE_LOCAL_VAR != EGL_TRUE)     \
218*8975f5c5SAndroid Build Coastguard Worker         {                                    \
219*8975f5c5SAndroid Build Coastguard Worker             return ANGLE_LOCAL_VAR;          \
220*8975f5c5SAndroid Build Coastguard Worker         }                                    \
221*8975f5c5SAndroid Build Coastguard Worker     } while (0)
222*8975f5c5SAndroid Build Coastguard Worker 
223*8975f5c5SAndroid Build Coastguard Worker #endif  // LIBANGLE_VALIDATIONEGL_H_
224