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