• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2015 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 
7 // validationEGL.h: Validation functions for generic EGL entry point parameters
8 
9 #ifndef LIBANGLE_VALIDATIONEGL_H_
10 #define LIBANGLE_VALIDATIONEGL_H_
11 
12 #include "common/PackedEnums.h"
13 #include "libANGLE/Error.h"
14 #include "libANGLE/Thread.h"
15 
16 #include <EGL/egl.h>
17 #include <EGL/eglext.h>
18 
19 namespace gl
20 {
21 class Context;
22 }
23 
24 namespace egl
25 {
26 
27 class AttributeMap;
28 struct ClientExtensions;
29 struct Config;
30 class Device;
31 class Display;
32 class Image;
33 class Stream;
34 class Surface;
35 class Sync;
36 class Thread;
37 class LabeledObject;
38 
39 struct ValidationContext
40 {
ValidationContextValidationContext41     ValidationContext(Thread *threadIn, const char *entryPointIn, const LabeledObject *objectIn)
42         : eglThread(threadIn), entryPoint(entryPointIn), labeledObject(objectIn)
43     {}
44 
45     // We should remove the message-less overload once we have messages for all EGL errors.
46     void setError(EGLint error) const;
47     ANGLE_FORMAT_PRINTF(3, 4)
48     void setError(EGLint error, const char *message...) const;
49 
50     Thread *eglThread;
51     const char *entryPoint;
52     const LabeledObject *labeledObject;
53 };
54 
55 // Object validation
56 bool ValidateDisplay(const ValidationContext *val, const Display *display);
57 bool ValidateSurface(const ValidationContext *val, const Display *display, const Surface *surface);
58 bool ValidateConfig(const ValidationContext *val, const Display *display, const Config *config);
59 bool ValidateContext(const ValidationContext *val,
60                      const Display *display,
61                      const gl::Context *context);
62 bool ValidateImage(const ValidationContext *val, const Display *display, const Image *image);
63 bool ValidateDevice(const ValidationContext *val, const Device *device);
64 bool ValidateSync(const ValidationContext *val, const Display *display, const Sync *sync);
65 
66 // Return the requested object only if it is valid (otherwise nullptr)
67 const Thread *GetThreadIfValid(const Thread *thread);
68 const Display *GetDisplayIfValid(const Display *display);
69 const Surface *GetSurfaceIfValid(const Display *display, const Surface *surface);
70 const Image *GetImageIfValid(const Display *display, const Image *image);
71 const Stream *GetStreamIfValid(const Display *display, const Stream *stream);
72 const gl::Context *GetContextIfValid(const Display *display, const gl::Context *context);
73 const Device *GetDeviceIfValid(const Device *device);
74 const Sync *GetSyncIfValid(const Display *display, const Sync *sync);
75 LabeledObject *GetLabeledObjectIfValid(Thread *thread,
76                                        const Display *display,
77                                        ObjectType objectType,
78                                        EGLObjectKHR object);
79 
80 // A template struct for determining the default value to return for each entry point.
81 template <angle::EntryPoint EP, typename ReturnType>
82 struct DefaultReturnValue
83 {
84     static constexpr ReturnType kValue = static_cast<ReturnType>(0);
85 };
86 
87 template <angle::EntryPoint EP, typename ReturnType>
88 ReturnType GetDefaultReturnValue(Thread *thread);
89 
90 template <>
91 ANGLE_INLINE EGLint
92 GetDefaultReturnValue<angle::EntryPoint::EGLLabelObjectKHR, EGLint>(Thread *thread)
93 {
94     return thread->getError();
95 }
96 
97 template <angle::EntryPoint EP, typename ReturnType>
GetDefaultReturnValue(Thread * thread)98 ANGLE_INLINE ReturnType GetDefaultReturnValue(Thread *thread)
99 {
100     return DefaultReturnValue<EP, ReturnType>::kValue;
101 }
102 
103 // First case: handling packed enums.
104 template <typename PackedT, typename FromT>
PackParam(FromT from)105 typename std::enable_if<std::is_enum<PackedT>::value, PackedT>::type PackParam(FromT from)
106 {
107     return FromEGLenum<PackedT>(from);
108 }
109 
110 // Second case: handling other types.
111 template <typename PackedT, typename FromT>
112 typename std::enable_if<!std::is_enum<PackedT>::value,
113                         typename std::remove_reference<PackedT>::type>::type
114 PackParam(FromT from);
115 
116 template <>
117 inline const AttributeMap PackParam<const AttributeMap &, const EGLint *>(const EGLint *attribs)
118 {
119     return AttributeMap::CreateFromIntArray(attribs);
120 }
121 
122 // In a 32-bit environment the EGLAttrib and EGLint types are the same. We need to mask out one of
123 // the two specializations to avoid having an override ambiguity.
124 #if defined(ANGLE_IS_64_BIT_CPU)
125 template <>
126 inline const AttributeMap PackParam<const AttributeMap &, const EGLAttrib *>(
127     const EGLAttrib *attribs)
128 {
129     return AttributeMap::CreateFromAttribArray(attribs);
130 }
131 #endif  // defined(ANGLE_IS_64_BIT_CPU)
132 
133 template <typename PackedT, typename FromT>
134 inline typename std::enable_if<!std::is_enum<PackedT>::value,
135                                typename std::remove_reference<PackedT>::type>::type
PackParam(FromT from)136 PackParam(FromT from)
137 {
138     return static_cast<PackedT>(from);
139 }
140 }  // namespace egl
141 
142 #define ANGLE_EGL_VALIDATE(THREAD, EP, OBJ, RETURN_TYPE, ...)                              \
143     do                                                                                     \
144     {                                                                                      \
145         const char *epname = "egl" #EP;                                                    \
146         ValidationContext vctx(THREAD, epname, OBJ);                                       \
147         auto ANGLE_LOCAL_VAR = (Validate##EP(&vctx, ##__VA_ARGS__));                       \
148         if (!ANGLE_LOCAL_VAR)                                                              \
149         {                                                                                  \
150             return GetDefaultReturnValue<angle::EntryPoint::EGL##EP, RETURN_TYPE>(THREAD); \
151         }                                                                                  \
152     } while (0)
153 
154 #define ANGLE_EGL_VALIDATE_VOID(THREAD, EP, OBJ, ...)                \
155     do                                                               \
156     {                                                                \
157         const char *epname = "egl" #EP;                              \
158         ValidationContext vctx(THREAD, epname, OBJ);                 \
159         auto ANGLE_LOCAL_VAR = (Validate##EP(&vctx, ##__VA_ARGS__)); \
160         if (!ANGLE_LOCAL_VAR)                                        \
161         {                                                            \
162             return;                                                  \
163         }                                                            \
164     } while (0)
165 
166 #define ANGLE_EGL_TRY(THREAD, EXPR, FUNCNAME, LABELOBJECT)                   \
167     do                                                                       \
168     {                                                                        \
169         auto ANGLE_LOCAL_VAR = (EXPR);                                       \
170         if (ANGLE_LOCAL_VAR.isError())                                       \
171             return THREAD->setError(ANGLE_LOCAL_VAR, FUNCNAME, LABELOBJECT); \
172     } while (0)
173 
174 #define ANGLE_EGL_TRY_RETURN(THREAD, EXPR, FUNCNAME, LABELOBJECT, RETVAL) \
175     do                                                                    \
176     {                                                                     \
177         auto ANGLE_LOCAL_VAR = (EXPR);                                    \
178         if (ANGLE_LOCAL_VAR.isError())                                    \
179         {                                                                 \
180             THREAD->setError(ANGLE_LOCAL_VAR, FUNCNAME, LABELOBJECT);     \
181             return RETVAL;                                                \
182         }                                                                 \
183     } while (0)
184 
185 #endif  // LIBANGLE_VALIDATIONEGL_H_
186