1 //
2 // Copyright 2017 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 // params:
7 //   Parameter wrapper structs for OpenGL ES. These helpers cache re-used values
8 //   in entry point routines.
9 
10 #ifndef LIBANGLE_PARAMS_H_
11 #define LIBANGLE_PARAMS_H_
12 
13 #include "angle_gl.h"
14 #include "common/Optional.h"
15 #include "common/angleutils.h"
16 #include "common/mathutil.h"
17 #include "libANGLE/entry_points_enum_autogen.h"
18 
19 namespace gl
20 {
21 class Context;
22 
23 template <EntryPoint EP>
24 struct EntryPointParam;
25 
26 template <EntryPoint EP>
27 using EntryPointParamType = typename EntryPointParam<EP>::Type;
28 
29 class ParamTypeInfo
30 {
31   public:
ParamTypeInfo(const char * selfClass,const ParamTypeInfo * parentType)32     constexpr ParamTypeInfo(const char *selfClass, const ParamTypeInfo *parentType)
33         : mSelfClass(selfClass), mParentTypeInfo(parentType)
34     {
35     }
36 
hasDynamicType(const ParamTypeInfo & typeInfo)37     constexpr bool hasDynamicType(const ParamTypeInfo &typeInfo) const
38     {
39         return mSelfClass == typeInfo.mSelfClass ||
40                (mParentTypeInfo && mParentTypeInfo->hasDynamicType(typeInfo));
41     }
42 
isValid()43     constexpr bool isValid() const { return mSelfClass != nullptr; }
44 
45   private:
46     const char *mSelfClass;
47     const ParamTypeInfo *mParentTypeInfo;
48 };
49 
50 #define ANGLE_PARAM_TYPE_INFO(NAME, BASENAME) \
51     static constexpr ParamTypeInfo TypeInfo = {#NAME, &BASENAME::TypeInfo}
52 
53 class ParamsBase : angle::NonCopyable
54 {
55   public:
ParamsBase(Context * context,...)56     ParamsBase(Context *context, ...){};
57 
58     template <EntryPoint EP, typename... ArgsT>
59     static void Factory(EntryPointParamType<EP> *objBuffer, ArgsT... args);
60 
61     static constexpr ParamTypeInfo TypeInfo = {nullptr, nullptr};
62 };
63 
64 // static
65 template <EntryPoint EP, typename... ArgsT>
Factory(EntryPointParamType<EP> * objBuffer,ArgsT...args)66 ANGLE_INLINE void ParamsBase::Factory(EntryPointParamType<EP> *objBuffer, ArgsT... args)
67 {
68     new (objBuffer) EntryPointParamType<EP>(args...);
69 }
70 
71 class HasIndexRange : public ParamsBase
72 {
73   public:
74     // Dummy placeholder that can't generate an index range.
75     HasIndexRange();
76     HasIndexRange(Context *context, GLsizei count, GLenum type, const void *indices);
77 
78     template <EntryPoint EP, typename... ArgsT>
79     static void Factory(HasIndexRange *objBuffer, ArgsT... args);
80 
81     const Optional<IndexRange> &getIndexRange() const;
82 
83     ANGLE_PARAM_TYPE_INFO(HasIndexRange, ParamsBase);
84 
85   private:
86     Context *mContext;
87     GLsizei mCount;
88     GLenum mType;
89     const GLvoid *mIndices;
90     mutable Optional<IndexRange> mIndexRange;
91 };
92 
93 // Entry point funcs essentially re-map different entry point parameter arrays into
94 // the format the parameter type class expects. For example, for HasIndexRange, for the
95 // various indexed draw calls, they drop parameters that aren't useful and re-arrange
96 // the rest.
97 #define ANGLE_ENTRY_POINT_FUNC(NAME, CLASS, ...)    \
98     \
99 template<> struct EntryPointParam<EntryPoint::NAME> \
100     {                                               \
101         using Type = CLASS;                         \
102     };                                              \
103     \
104 template<> inline void CLASS::Factory<EntryPoint::NAME>(__VA_ARGS__)
105 
ANGLE_ENTRY_POINT_FUNC(DrawElements,HasIndexRange,HasIndexRange * objBuffer,Context * context,GLenum,GLsizei count,GLenum type,const void * indices)106 ANGLE_ENTRY_POINT_FUNC(DrawElements,
107                        HasIndexRange,
108                        HasIndexRange *objBuffer,
109                        Context *context,
110                        GLenum /*mode*/,
111                        GLsizei count,
112                        GLenum type,
113                        const void *indices)
114 {
115     return ParamsBase::Factory<EntryPoint::DrawElements>(objBuffer, context, count, type, indices);
116 }
117 
ANGLE_ENTRY_POINT_FUNC(DrawElementsInstanced,HasIndexRange,HasIndexRange * objBuffer,Context * context,GLenum,GLsizei count,GLenum type,const void * indices,GLsizei)118 ANGLE_ENTRY_POINT_FUNC(DrawElementsInstanced,
119                        HasIndexRange,
120                        HasIndexRange *objBuffer,
121                        Context *context,
122                        GLenum /*mode*/,
123                        GLsizei count,
124                        GLenum type,
125                        const void *indices,
126                        GLsizei /*instanceCount*/)
127 {
128     return ParamsBase::Factory<EntryPoint::DrawElementsInstanced>(objBuffer, context, count, type,
129                                                                   indices);
130 }
131 
ANGLE_ENTRY_POINT_FUNC(DrawElementsInstancedANGLE,HasIndexRange,HasIndexRange * objBuffer,Context * context,GLenum,GLsizei count,GLenum type,const void * indices,GLsizei)132 ANGLE_ENTRY_POINT_FUNC(DrawElementsInstancedANGLE,
133                        HasIndexRange,
134                        HasIndexRange *objBuffer,
135                        Context *context,
136                        GLenum /*mode*/,
137                        GLsizei count,
138                        GLenum type,
139                        const void *indices,
140                        GLsizei /*instanceCount*/)
141 {
142     return ParamsBase::Factory<EntryPoint::DrawElementsInstancedANGLE>(objBuffer, context, count,
143                                                                        type, indices);
144 }
145 
ANGLE_ENTRY_POINT_FUNC(DrawRangeElements,HasIndexRange,HasIndexRange * objBuffer,Context * context,GLenum,GLuint,GLuint,GLsizei count,GLenum type,const void * indices)146 ANGLE_ENTRY_POINT_FUNC(DrawRangeElements,
147                        HasIndexRange,
148                        HasIndexRange *objBuffer,
149                        Context *context,
150                        GLenum /*mode*/,
151                        GLuint /*start*/,
152                        GLuint /*end*/,
153                        GLsizei count,
154                        GLenum type,
155                        const void *indices)
156 {
157     return ParamsBase::Factory<EntryPoint::DrawRangeElements>(objBuffer, context, count, type,
158                                                               indices);
159 }
160 
161 #undef ANGLE_ENTRY_POINT_FUNC
162 
163 template <EntryPoint EP>
164 struct EntryPointParam
165 {
166     using Type = ParamsBase;
167 };
168 
169 // A template struct for determining the default value to return for each entry point.
170 template <EntryPoint EP, typename ReturnType>
171 struct DefaultReturnValue;
172 
173 // Default return values for each basic return type.
174 template <EntryPoint EP>
175 struct DefaultReturnValue<EP, GLint>
176 {
177     static constexpr GLint kValue = -1;
178 };
179 
180 // This doubles as the GLenum return value.
181 template <EntryPoint EP>
182 struct DefaultReturnValue<EP, GLuint>
183 {
184     static constexpr GLuint kValue = 0;
185 };
186 
187 template <EntryPoint EP>
188 struct DefaultReturnValue<EP, GLboolean>
189 {
190     static constexpr GLboolean kValue = GL_FALSE;
191 };
192 
193 // Catch-all rules for pointer types.
194 template <EntryPoint EP, typename PointerType>
195 struct DefaultReturnValue<EP, const PointerType *>
196 {
197     static constexpr const PointerType *kValue = nullptr;
198 };
199 
200 template <EntryPoint EP, typename PointerType>
201 struct DefaultReturnValue<EP, PointerType *>
202 {
203     static constexpr PointerType *kValue = nullptr;
204 };
205 
206 // Overloaded to return invalid index
207 template <>
208 struct DefaultReturnValue<EntryPoint::GetUniformBlockIndex, GLuint>
209 {
210     static constexpr GLuint kValue = GL_INVALID_INDEX;
211 };
212 
213 // Specialized enum error value.
214 template <>
215 struct DefaultReturnValue<EntryPoint::ClientWaitSync, GLenum>
216 {
217     static constexpr GLenum kValue = GL_WAIT_FAILED;
218 };
219 
220 template <EntryPoint EP, typename ReturnType>
221 constexpr ANGLE_INLINE ReturnType GetDefaultReturnValue()
222 {
223     return DefaultReturnValue<EP, ReturnType>::kValue;
224 }
225 
226 }  // namespace gl
227 
228 #endif  // LIBANGLE_PARAMS_H_
229