tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

Error.h (6899B)


      1 //
      2 // Copyright 2014 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 // Error.h: Defines the egl::Error and gl::Error classes which encapsulate API errors
      7 // and optional error messages.
      8 
      9 #ifndef LIBANGLE_ERROR_H_
     10 #define LIBANGLE_ERROR_H_
     11 
     12 #include <EGL/egl.h>
     13 #include <EGL/eglext.h>
     14 #include "angle_gl.h"
     15 #include "common/angleutils.h"
     16 #include "common/debug.h"
     17 
     18 #include <memory>
     19 #include <ostream>
     20 #include <string>
     21 
     22 namespace angle
     23 {
     24 template <typename ErrorT, typename ErrorBaseT, ErrorBaseT NoErrorVal, typename CodeT, CodeT EnumT>
     25 class ErrorStreamBase : angle::NonCopyable
     26 {
     27  public:
     28    ErrorStreamBase() : mID(EnumT) {}
     29    ErrorStreamBase(GLuint id) : mID(id) {}
     30 
     31    template <typename T>
     32    ErrorStreamBase &operator<<(T value)
     33    {
     34        mErrorStream << value;
     35        return *this;
     36    }
     37 
     38    operator ErrorT() { return ErrorT(EnumT, mID, mErrorStream.str()); }
     39 
     40  private:
     41    GLuint mID;
     42    std::ostringstream mErrorStream;
     43 };
     44 }  // namespace angle
     45 
     46 namespace egl
     47 {
     48 class Error;
     49 }  // namespace egl
     50 
     51 namespace egl
     52 {
     53 
     54 class [[nodiscard]] Error final
     55 {
     56  public:
     57    explicit inline Error(EGLint errorCode);
     58    Error(EGLint errorCode, std::string &&message);
     59    Error(EGLint errorCode, EGLint id, std::string &&message);
     60    inline Error(const Error &other);
     61    inline Error(Error &&other);
     62    inline ~Error() = default;
     63 
     64    inline Error &operator=(const Error &other);
     65    inline Error &operator=(Error &&other);
     66 
     67    inline EGLint getCode() const;
     68    inline EGLint getID() const;
     69    inline bool isError() const;
     70 
     71    const std::string &getMessage() const;
     72 
     73    static inline Error NoError();
     74 
     75  private:
     76    void createMessageString() const;
     77 
     78    friend std::ostream &operator<<(std::ostream &os, const Error &err);
     79 
     80    EGLint mCode;
     81    EGLint mID;
     82    mutable std::unique_ptr<std::string> mMessage;
     83 };
     84 
     85 namespace priv
     86 {
     87 
     88 template <EGLint EnumT>
     89 using ErrorStream = angle::ErrorStreamBase<Error, EGLint, EGL_SUCCESS, EGLint, EnumT>;
     90 
     91 }  // namespace priv
     92 
     93 using EglBadAccess         = priv::ErrorStream<EGL_BAD_ACCESS>;
     94 using EglBadAlloc          = priv::ErrorStream<EGL_BAD_ALLOC>;
     95 using EglBadAttribute      = priv::ErrorStream<EGL_BAD_ATTRIBUTE>;
     96 using EglBadConfig         = priv::ErrorStream<EGL_BAD_CONFIG>;
     97 using EglBadContext        = priv::ErrorStream<EGL_BAD_CONTEXT>;
     98 using EglBadCurrentSurface = priv::ErrorStream<EGL_BAD_CURRENT_SURFACE>;
     99 using EglBadDevice         = priv::ErrorStream<EGL_BAD_DEVICE_EXT>;
    100 using EglBadDisplay        = priv::ErrorStream<EGL_BAD_DISPLAY>;
    101 using EglBadMatch          = priv::ErrorStream<EGL_BAD_MATCH>;
    102 using EglBadNativeWindow   = priv::ErrorStream<EGL_BAD_NATIVE_WINDOW>;
    103 using EglBadNativePixmap   = priv::ErrorStream<EGL_BAD_NATIVE_PIXMAP>;
    104 using EglBadParameter      = priv::ErrorStream<EGL_BAD_PARAMETER>;
    105 using EglBadState          = priv::ErrorStream<EGL_BAD_STATE_KHR>;
    106 using EglBadStream         = priv::ErrorStream<EGL_BAD_STREAM_KHR>;
    107 using EglBadSurface        = priv::ErrorStream<EGL_BAD_SURFACE>;
    108 using EglContextLost       = priv::ErrorStream<EGL_CONTEXT_LOST>;
    109 using EglNotInitialized    = priv::ErrorStream<EGL_NOT_INITIALIZED>;
    110 
    111 inline Error NoError()
    112 {
    113    return Error::NoError();
    114 }
    115 
    116 }  // namespace egl
    117 
    118 #define ANGLE_CONCAT1(x, y) x##y
    119 #define ANGLE_CONCAT2(x, y) ANGLE_CONCAT1(x, y)
    120 #define ANGLE_LOCAL_VAR ANGLE_CONCAT2(_localVar, __LINE__)
    121 
    122 #define ANGLE_TRY_TEMPLATE(EXPR, FUNC)                \
    123    do                                                \
    124    {                                                 \
    125        auto ANGLE_LOCAL_VAR = EXPR;                  \
    126        if (ANGLE_UNLIKELY(IsError(ANGLE_LOCAL_VAR))) \
    127        {                                             \
    128            FUNC(ANGLE_LOCAL_VAR);                    \
    129        }                                             \
    130    } while (0)
    131 
    132 #define ANGLE_RETURN(X) return X;
    133 #define ANGLE_TRY(EXPR) ANGLE_TRY_TEMPLATE(EXPR, ANGLE_RETURN)
    134 
    135 // TODO(jmadill): Remove after EGL error refactor. http://anglebug.com/3041
    136 #define ANGLE_SWALLOW_ERR(EXPR)                                       \
    137    do                                                                \
    138    {                                                                 \
    139        auto ANGLE_LOCAL_VAR = EXPR;                                  \
    140        if (ANGLE_UNLIKELY(IsError(ANGLE_LOCAL_VAR)))                 \
    141        {                                                             \
    142            ERR() << "Unhandled internal error: " << ANGLE_LOCAL_VAR; \
    143        }                                                             \
    144    } while (0)
    145 
    146 #undef ANGLE_LOCAL_VAR
    147 #undef ANGLE_CONCAT2
    148 #undef ANGLE_CONCAT1
    149 
    150 #define ANGLE_CHECK(CONTEXT, EXPR, MESSAGE, ERROR)                                    \
    151    do                                                                                \
    152    {                                                                                 \
    153        if (ANGLE_UNLIKELY(!(EXPR)))                                                  \
    154        {                                                                             \
    155            CONTEXT->handleError(ERROR, MESSAGE, __FILE__, ANGLE_FUNCTION, __LINE__); \
    156            return angle::Result::Stop;                                               \
    157        }                                                                             \
    158    } while (0)
    159 
    160 namespace angle
    161 {
    162 // Result signals if calling code should continue running or early exit. A value of Stop can
    163 // either indicate an Error or a non-Error early exit condition such as a detected no-op.
    164 // Incomplete signals special cases that are neither success nor failure but require
    165 // special attention.
    166 enum class [[nodiscard]] Result{
    167    Continue,
    168    Stop,
    169    Incomplete,
    170 };
    171 
    172 // TODO(jmadill): Remove this when refactor is complete. http://anglebug.com/3041
    173 egl::Error ResultToEGL(Result result);
    174 }  // namespace angle
    175 
    176 // TODO(jmadill): Remove this when refactor is complete. http://anglebug.com/3041
    177 inline bool IsError(angle::Result result)
    178 {
    179    return result == angle::Result::Stop;
    180 }
    181 
    182 // TODO(jmadill): Remove this when refactor is complete. http://anglebug.com/3041
    183 inline bool IsError(const egl::Error &err)
    184 {
    185    return err.isError();
    186 }
    187 
    188 // TODO(jmadill): Remove this when refactor is complete. http://anglebug.com/3041
    189 inline bool IsError(bool value)
    190 {
    191    return !value;
    192 }
    193 
    194 // Utility macro for handling implementation methods inside Validation.
    195 #define ANGLE_HANDLE_VALIDATION_ERR(X) \
    196    do                                 \
    197    {                                  \
    198        (void)(X);                     \
    199        return false;                  \
    200    } while (0)
    201 
    202 #define ANGLE_VALIDATION_TRY(EXPR) ANGLE_TRY_TEMPLATE(EXPR, ANGLE_HANDLE_VALIDATION_ERR)
    203 
    204 #include "Error.inc"
    205 
    206 #endif  // LIBANGLE_ERROR_H_