blob: 11467ec1891e07fb1cf6f37191e2b7d980a6c9b9 [file] [log] [blame]
//
// Copyright 2017 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// params:
// Parameter wrapper structs for OpenGL ES. These helpers cache re-used values
// in entry point routines.
#ifndef LIBANGLE_PARAMS_H_
#define LIBANGLE_PARAMS_H_
#include "angle_gl.h"
#include "common/Optional.h"
#include "common/angleutils.h"
#include "common/mathutil.h"
#include "libANGLE/entry_points_enum_autogen.h"
namespace gl
{
class Context;
template <EntryPoint EP>
struct EntryPointParam;
template <EntryPoint EP>
using EntryPointParamType = typename EntryPointParam<EP>::Type;
class ParamTypeInfo
{
public:
constexpr ParamTypeInfo(const char *selfClass, const ParamTypeInfo *parentType)
: mSelfClass(selfClass), mParentTypeInfo(parentType)
{
}
constexpr bool hasDynamicType(const ParamTypeInfo &typeInfo) const
{
return areEqual(mSelfClass, typeInfo.mSelfClass) ||
(mParentTypeInfo && mParentTypeInfo->hasDynamicType(typeInfo));
}
constexpr bool isValid() const { return mSelfClass != nullptr; }
private:
// This function performs a compile-time comparison of string literals.
// This function cannot be made more beautiful [without C++ 14].
constexpr bool areEqual(const char* lhs, const char* rhs) const
{
return (*lhs == *rhs) && ((*lhs == 0) || (areEqual(lhs + 1, rhs + 1)));
}
const char *mSelfClass;
const ParamTypeInfo *mParentTypeInfo;
};
#define ANGLE_PARAM_TYPE_INFO(NAME, BASENAME) \
static constexpr ParamTypeInfo TypeInfo = {#NAME, &BASENAME::TypeInfo}
class ParamsBase : angle::NonCopyable
{
public:
ParamsBase(Context *context, ...);
template <EntryPoint EP, typename... ArgsT>
static void Factory(EntryPointParamType<EP> *objBuffer, ArgsT... args);
static constexpr ParamTypeInfo TypeInfo = {nullptr, nullptr};
};
// static
template <EntryPoint EP, typename... ArgsT>
void ParamsBase::Factory(EntryPointParamType<EP> *objBuffer, ArgsT... args)
{
new (objBuffer) EntryPointParamType<EP>(args...);
}
class HasIndexRange : public ParamsBase
{
public:
HasIndexRange(Context *context, GLsizei count, GLenum type, const void *indices);
template <EntryPoint EP, typename... ArgsT>
static void Factory(HasIndexRange *objBuffer, ArgsT... args);
const Optional<IndexRange> &getIndexRange() const;
ANGLE_PARAM_TYPE_INFO(HasIndexRange, ParamsBase);
private:
Context *mContext;
GLsizei mCount;
GLenum mType;
const GLvoid *mIndices;
mutable Optional<IndexRange> mIndexRange;
};
// Entry point funcs essentially re-map different entry point parameter arrays into
// the format the parameter type class expects. For example, for HasIndexRange, for the
// various indexed draw calls, they drop parameters that aren't useful and re-arrange
// the rest.
#define ANGLE_ENTRY_POINT_FUNC(NAME, CLASS, ...) \
\
template<> struct EntryPointParam<EntryPoint::NAME> \
{ \
using Type = CLASS; \
}; \
\
template<> inline void CLASS::Factory<EntryPoint::NAME>(__VA_ARGS__)
ANGLE_ENTRY_POINT_FUNC(DrawElements,
HasIndexRange,
HasIndexRange *objBuffer,
Context *context,
GLenum /*mode*/,
GLsizei count,
GLenum type,
const void *indices)
{
return ParamsBase::Factory<EntryPoint::DrawElements>(objBuffer, context, count, type, indices);
}
ANGLE_ENTRY_POINT_FUNC(DrawElementsInstanced,
HasIndexRange,
HasIndexRange *objBuffer,
Context *context,
GLenum /*mode*/,
GLsizei count,
GLenum type,
const void *indices,
GLsizei /*instanceCount*/)
{
return ParamsBase::Factory<EntryPoint::DrawElementsInstanced>(objBuffer, context, count, type,
indices);
}
ANGLE_ENTRY_POINT_FUNC(DrawElementsInstancedANGLE,
HasIndexRange,
HasIndexRange *objBuffer,
Context *context,
GLenum /*mode*/,
GLsizei count,
GLenum type,
const void *indices,
GLsizei /*instanceCount*/)
{
return ParamsBase::Factory<EntryPoint::DrawElementsInstancedANGLE>(objBuffer, context, count,
type, indices);
}
ANGLE_ENTRY_POINT_FUNC(DrawRangeElements,
HasIndexRange,
HasIndexRange *objBuffer,
Context *context,
GLenum /*mode*/,
GLuint /*start*/,
GLuint /*end*/,
GLsizei count,
GLenum type,
const void *indices)
{
return ParamsBase::Factory<EntryPoint::DrawRangeElements>(objBuffer, context, count, type,
indices);
}
#undef ANGLE_ENTRY_POINT_FUNC
template <EntryPoint EP>
struct EntryPointParam
{
using Type = ParamsBase;
};
} // namespace gl
#endif // LIBANGLE_PARAMS_H_