diff options
Diffstat (limited to 'gfx/angle/checkout/src/libANGLE/validationEGL.h')
-rw-r--r-- | gfx/angle/checkout/src/libANGLE/validationEGL.h | 201 |
1 files changed, 201 insertions, 0 deletions
diff --git a/gfx/angle/checkout/src/libANGLE/validationEGL.h b/gfx/angle/checkout/src/libANGLE/validationEGL.h new file mode 100644 index 0000000000..8f04de288f --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/validationEGL.h @@ -0,0 +1,201 @@ +// +// Copyright 2015 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. +// + +// validationEGL.h: Validation functions for generic EGL entry point parameters + +#ifndef LIBANGLE_VALIDATIONEGL_H_ +#define LIBANGLE_VALIDATIONEGL_H_ + +#include "common/PackedEnums.h" +#include "libANGLE/Error.h" +#include "libANGLE/Thread.h" + +#include <EGL/egl.h> +#include <EGL/eglext.h> + +namespace gl +{ +class Context; +} + +namespace egl +{ +constexpr EGLint kEglMajorVersion = 1; +constexpr EGLint kEglMinorVersion = 5; + +class AttributeMap; +struct ClientExtensions; +struct Config; +class Device; +class Display; +class Image; +class Stream; +class Surface; +class Sync; +class Thread; +class LabeledObject; + +struct ValidationContext +{ + ValidationContext(Thread *threadIn, const char *entryPointIn, const LabeledObject *objectIn) + : eglThread(threadIn), entryPoint(entryPointIn), labeledObject(objectIn) + {} + + // We should remove the message-less overload once we have messages for all EGL errors. + void setError(EGLint error) const; + ANGLE_FORMAT_PRINTF(3, 4) + void setError(EGLint error, const char *message...) const; + + Thread *eglThread; + const char *entryPoint; + const LabeledObject *labeledObject; +}; + +// Object validation +bool ValidateDisplay(const ValidationContext *val, const Display *display); +bool ValidateSurface(const ValidationContext *val, const Display *display, const Surface *surface); +bool ValidateConfig(const ValidationContext *val, const Display *display, const Config *config); +bool ValidateContext(const ValidationContext *val, + const Display *display, + const gl::Context *context); +bool ValidateImage(const ValidationContext *val, const Display *display, const Image *image); +bool ValidateDevice(const ValidationContext *val, const Device *device); +bool ValidateSync(const ValidationContext *val, const Display *display, const Sync *sync); + +// Return the requested object only if it is valid (otherwise nullptr) +const Thread *GetThreadIfValid(const Thread *thread); +const Display *GetDisplayIfValid(const Display *display); +const Surface *GetSurfaceIfValid(const Display *display, const Surface *surface); +const Image *GetImageIfValid(const Display *display, const Image *image); +const Stream *GetStreamIfValid(const Display *display, const Stream *stream); +const gl::Context *GetContextIfValid(const Display *display, const gl::Context *context); +const Device *GetDeviceIfValid(const Device *device); +const Sync *GetSyncIfValid(const Display *display, const Sync *sync); +LabeledObject *GetLabeledObjectIfValid(Thread *thread, + const Display *display, + ObjectType objectType, + EGLObjectKHR object); + +// A template struct for determining the default value to return for each entry point. +template <angle::EntryPoint EP, typename ReturnType> +struct DefaultReturnValue +{ + static constexpr ReturnType kValue = static_cast<ReturnType>(0); +}; + +template <angle::EntryPoint EP, typename ReturnType> +ReturnType GetDefaultReturnValue(Thread *thread); + +template <> +ANGLE_INLINE EGLint +GetDefaultReturnValue<angle::EntryPoint::EGLLabelObjectKHR, EGLint>(Thread *thread) +{ + return thread->getError(); +} + +template <angle::EntryPoint EP, typename ReturnType> +ANGLE_INLINE ReturnType GetDefaultReturnValue(Thread *thread) +{ + return DefaultReturnValue<EP, ReturnType>::kValue; +} + +// First case: handling packed enums. +template <typename PackedT, typename FromT> +typename std::enable_if<std::is_enum<PackedT>::value, PackedT>::type PackParam(FromT from) +{ + return FromEGLenum<PackedT>(from); +} + +// This and the next 2 template specializations handle distinguishing between EGLint, EGLAttrib +// and other. This is needed because on some architectures EGLint and EGLAttrib are not the same +// base type. Previously the code conditionally compiled 2 specializations on 64 bit but it turns +// out on WatchOS the assumption about 32/64 bit and if EGLint and ELGAttrib are the same or +// different did not hold. +template <typename PackedT, + typename FromT, + typename std::enable_if<!std::is_enum<PackedT>::value>::type * = nullptr, + typename std::enable_if<std::is_same<FromT, const EGLint *>::value>::type * = nullptr> +typename std::remove_reference<PackedT>::type PackParam(FromT attribs) +{ + return AttributeMap::CreateFromIntArray(attribs); +} + +template <typename PackedT, + typename FromT, + typename std::enable_if<!std::is_enum<PackedT>::value>::type * = nullptr, + typename std::enable_if<!std::is_same<FromT, const EGLint *>::value>::type * = nullptr, + typename std::enable_if<std::is_same<FromT, const EGLAttrib *>::value>::type * = nullptr> +typename std::remove_reference<PackedT>::type PackParam(FromT attribs) +{ + return AttributeMap::CreateFromAttribArray(attribs); +} + +template <typename PackedT, + typename FromT, + typename std::enable_if<!std::is_enum<PackedT>::value>::type * = nullptr, + typename std::enable_if<!std::is_same<FromT, const EGLint *>::value>::type * = nullptr, + typename std::enable_if<!std::is_same<FromT, const EGLAttrib *>::value>::type * = nullptr> +typename std::remove_reference<PackedT>::type PackParam(FromT attribs) +{ + return static_cast<PackedT>(attribs); +} + +} // namespace egl + +#define ANGLE_EGL_VALIDATE(THREAD, EP, OBJ, RETURN_TYPE, ...) \ + do \ + { \ + const char *epname = "egl" #EP; \ + ValidationContext vctx(THREAD, epname, OBJ); \ + auto ANGLE_LOCAL_VAR = (Validate##EP(&vctx, ##__VA_ARGS__)); \ + if (!ANGLE_LOCAL_VAR) \ + { \ + return GetDefaultReturnValue<angle::EntryPoint::EGL##EP, RETURN_TYPE>(THREAD); \ + } \ + } while (0) + +#define ANGLE_EGL_VALIDATE_VOID(THREAD, EP, OBJ, ...) \ + do \ + { \ + const char *epname = "egl" #EP; \ + ValidationContext vctx(THREAD, epname, OBJ); \ + auto ANGLE_LOCAL_VAR = (Validate##EP(&vctx, ##__VA_ARGS__)); \ + if (!ANGLE_LOCAL_VAR) \ + { \ + return; \ + } \ + } while (0) + +#define ANGLE_EGL_TRY(THREAD, EXPR, FUNCNAME, LABELOBJECT) \ + do \ + { \ + auto ANGLE_LOCAL_VAR = (EXPR); \ + if (ANGLE_LOCAL_VAR.isError()) \ + return THREAD->setError(ANGLE_LOCAL_VAR, FUNCNAME, LABELOBJECT); \ + } while (0) + +#define ANGLE_EGL_TRY_RETURN(THREAD, EXPR, FUNCNAME, LABELOBJECT, RETVAL) \ + do \ + { \ + auto ANGLE_LOCAL_VAR = (EXPR); \ + if (ANGLE_LOCAL_VAR.isError()) \ + { \ + THREAD->setError(ANGLE_LOCAL_VAR, FUNCNAME, LABELOBJECT); \ + return RETVAL; \ + } \ + } while (0) + +#define ANGLE_EGLBOOLEAN_TRY(EXPR) \ + do \ + { \ + EGLBoolean ANGLE_LOCAL_VAR = (EXPR); \ + if (ANGLE_LOCAL_VAR != EGL_TRUE) \ + { \ + return ANGLE_LOCAL_VAR; \ + } \ + } while (0) + +#endif // LIBANGLE_VALIDATIONEGL_H_ |