tor-browser

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

renderer_utils.h (20412B)


      1 //
      2 // Copyright 2016 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 // renderer_utils:
      7 //   Helper methods pertaining to most or all back-ends.
      8 //
      9 
     10 #ifndef LIBANGLE_RENDERER_RENDERER_UTILS_H_
     11 #define LIBANGLE_RENDERER_RENDERER_UTILS_H_
     12 
     13 #include <cstdint>
     14 
     15 #include <limits>
     16 #include <map>
     17 
     18 #include "GLSLANG/ShaderLang.h"
     19 #include "common/angleutils.h"
     20 #include "common/utilities.h"
     21 #include "libANGLE/angletypes.h"
     22 
     23 namespace angle
     24 {
     25 struct FeatureSetBase;
     26 struct Format;
     27 enum class FormatID;
     28 }  // namespace angle
     29 
     30 namespace gl
     31 {
     32 struct FormatType;
     33 struct InternalFormat;
     34 class State;
     35 }  // namespace gl
     36 
     37 namespace egl
     38 {
     39 class AttributeMap;
     40 struct DisplayState;
     41 }  // namespace egl
     42 
     43 namespace rx
     44 {
     45 class ContextImpl;
     46 
     47 // The possible rotations of the surface/draw framebuffer, particularly for the Vulkan back-end on
     48 // Android.
     49 enum class SurfaceRotation
     50 {
     51    Identity,
     52    Rotated90Degrees,
     53    Rotated180Degrees,
     54    Rotated270Degrees,
     55    FlippedIdentity,
     56    FlippedRotated90Degrees,
     57    FlippedRotated180Degrees,
     58    FlippedRotated270Degrees,
     59 
     60    InvalidEnum,
     61    EnumCount = InvalidEnum,
     62 };
     63 
     64 bool IsRotatedAspectRatio(SurfaceRotation rotation);
     65 
     66 using SpecConstUsageBits = angle::PackedEnumBitSet<sh::vk::SpecConstUsage, uint32_t>;
     67 
     68 void RotateRectangle(const SurfaceRotation rotation,
     69                     const bool flipY,
     70                     const int framebufferWidth,
     71                     const int framebufferHeight,
     72                     const gl::Rectangle &incoming,
     73                     gl::Rectangle *outgoing);
     74 
     75 using MipGenerationFunction = void (*)(size_t sourceWidth,
     76                                       size_t sourceHeight,
     77                                       size_t sourceDepth,
     78                                       const uint8_t *sourceData,
     79                                       size_t sourceRowPitch,
     80                                       size_t sourceDepthPitch,
     81                                       uint8_t *destData,
     82                                       size_t destRowPitch,
     83                                       size_t destDepthPitch);
     84 
     85 typedef void (*PixelReadFunction)(const uint8_t *source, uint8_t *dest);
     86 typedef void (*PixelWriteFunction)(const uint8_t *source, uint8_t *dest);
     87 typedef void (*FastCopyFunction)(const uint8_t *source,
     88                                 int srcXAxisPitch,
     89                                 int srcYAxisPitch,
     90                                 uint8_t *dest,
     91                                 int destXAxisPitch,
     92                                 int destYAxisPitch,
     93                                 int width,
     94                                 int height);
     95 
     96 class FastCopyFunctionMap
     97 {
     98  public:
     99    struct Entry
    100    {
    101        angle::FormatID formatID;
    102        FastCopyFunction func;
    103    };
    104 
    105    constexpr FastCopyFunctionMap() : FastCopyFunctionMap(nullptr, 0) {}
    106 
    107    constexpr FastCopyFunctionMap(const Entry *data, size_t size) : mSize(size), mData(data) {}
    108 
    109    bool has(angle::FormatID formatID) const;
    110    FastCopyFunction get(angle::FormatID formatID) const;
    111 
    112  private:
    113    size_t mSize;
    114    const Entry *mData;
    115 };
    116 
    117 struct PackPixelsParams
    118 {
    119    PackPixelsParams();
    120    PackPixelsParams(const gl::Rectangle &area,
    121                     const angle::Format &destFormat,
    122                     GLuint outputPitch,
    123                     bool reverseRowOrderIn,
    124                     gl::Buffer *packBufferIn,
    125                     ptrdiff_t offset);
    126 
    127    gl::Rectangle area;
    128    const angle::Format *destFormat;
    129    GLuint outputPitch;
    130    gl::Buffer *packBuffer;
    131    bool reverseRowOrder;
    132    ptrdiff_t offset;
    133    SurfaceRotation rotation;
    134 };
    135 
    136 void PackPixels(const PackPixelsParams &params,
    137                const angle::Format &sourceFormat,
    138                int inputPitch,
    139                const uint8_t *source,
    140                uint8_t *destination);
    141 
    142 using InitializeTextureDataFunction = void (*)(size_t width,
    143                                               size_t height,
    144                                               size_t depth,
    145                                               uint8_t *output,
    146                                               size_t outputRowPitch,
    147                                               size_t outputDepthPitch);
    148 
    149 using LoadImageFunction = void (*)(size_t width,
    150                                   size_t height,
    151                                   size_t depth,
    152                                   const uint8_t *input,
    153                                   size_t inputRowPitch,
    154                                   size_t inputDepthPitch,
    155                                   uint8_t *output,
    156                                   size_t outputRowPitch,
    157                                   size_t outputDepthPitch);
    158 
    159 struct LoadImageFunctionInfo
    160 {
    161    LoadImageFunctionInfo() : loadFunction(nullptr), requiresConversion(false) {}
    162    LoadImageFunctionInfo(LoadImageFunction loadFunction, bool requiresConversion)
    163        : loadFunction(loadFunction), requiresConversion(requiresConversion)
    164    {}
    165 
    166    LoadImageFunction loadFunction;
    167    bool requiresConversion;
    168 };
    169 
    170 using LoadFunctionMap = LoadImageFunctionInfo (*)(GLenum);
    171 
    172 bool ShouldUseDebugLayers(const egl::AttributeMap &attribs);
    173 
    174 void CopyImageCHROMIUM(const uint8_t *sourceData,
    175                       size_t sourceRowPitch,
    176                       size_t sourcePixelBytes,
    177                       size_t sourceDepthPitch,
    178                       PixelReadFunction pixelReadFunction,
    179                       uint8_t *destData,
    180                       size_t destRowPitch,
    181                       size_t destPixelBytes,
    182                       size_t destDepthPitch,
    183                       PixelWriteFunction pixelWriteFunction,
    184                       GLenum destUnsizedFormat,
    185                       GLenum destComponentType,
    186                       size_t width,
    187                       size_t height,
    188                       size_t depth,
    189                       bool unpackFlipY,
    190                       bool unpackPremultiplyAlpha,
    191                       bool unpackUnmultiplyAlpha);
    192 
    193 // Incomplete textures are 1x1 textures filled with black, used when samplers are incomplete.
    194 // This helper class encapsulates handling incomplete textures. Because the GL back-end
    195 // can take advantage of the driver's incomplete textures, and because clearing multisample
    196 // textures is so difficult, we can keep an instance of this class in the back-end instead
    197 // of moving the logic to the Context front-end.
    198 
    199 // This interface allows us to call-back to init a multisample texture.
    200 class MultisampleTextureInitializer
    201 {
    202  public:
    203    virtual ~MultisampleTextureInitializer() {}
    204    virtual angle::Result initializeMultisampleTextureToBlack(const gl::Context *context,
    205                                                              gl::Texture *glTexture) = 0;
    206 };
    207 
    208 class IncompleteTextureSet final : angle::NonCopyable
    209 {
    210  public:
    211    IncompleteTextureSet();
    212    ~IncompleteTextureSet();
    213 
    214    void onDestroy(const gl::Context *context);
    215 
    216    angle::Result getIncompleteTexture(const gl::Context *context,
    217                                       gl::TextureType type,
    218                                       gl::SamplerFormat format,
    219                                       MultisampleTextureInitializer *multisampleInitializer,
    220                                       gl::Texture **textureOut);
    221 
    222  private:
    223    using TextureMapWithSamplerFormat = angle::PackedEnumMap<gl::SamplerFormat, gl::TextureMap>;
    224 
    225    TextureMapWithSamplerFormat mIncompleteTextures;
    226    gl::Buffer *mIncompleteTextureBufferAttachment;
    227 };
    228 
    229 // Helpers to set a matrix uniform value based on GLSL or HLSL semantics.
    230 // The return value indicate if the data was updated or not.
    231 template <int cols, int rows>
    232 struct SetFloatUniformMatrixGLSL
    233 {
    234    static void Run(unsigned int arrayElementOffset,
    235                    unsigned int elementCount,
    236                    GLsizei countIn,
    237                    GLboolean transpose,
    238                    const GLfloat *value,
    239                    uint8_t *targetData);
    240 };
    241 
    242 template <int cols, int rows>
    243 struct SetFloatUniformMatrixHLSL
    244 {
    245    static void Run(unsigned int arrayElementOffset,
    246                    unsigned int elementCount,
    247                    GLsizei countIn,
    248                    GLboolean transpose,
    249                    const GLfloat *value,
    250                    uint8_t *targetData);
    251 };
    252 
    253 // Helper method to de-tranpose a matrix uniform for an API query.
    254 void GetMatrixUniform(GLenum type, GLfloat *dataOut, const GLfloat *source, bool transpose);
    255 
    256 template <typename NonFloatT>
    257 void GetMatrixUniform(GLenum type, NonFloatT *dataOut, const NonFloatT *source, bool transpose);
    258 
    259 const angle::Format &GetFormatFromFormatType(GLenum format, GLenum type);
    260 
    261 angle::Result ComputeStartVertex(ContextImpl *contextImpl,
    262                                 const gl::IndexRange &indexRange,
    263                                 GLint baseVertex,
    264                                 GLint *firstVertexOut);
    265 
    266 angle::Result GetVertexRangeInfo(const gl::Context *context,
    267                                 GLint firstVertex,
    268                                 GLsizei vertexOrIndexCount,
    269                                 gl::DrawElementsType indexTypeOrInvalid,
    270                                 const void *indices,
    271                                 GLint baseVertex,
    272                                 GLint *startVertexOut,
    273                                 size_t *vertexCountOut);
    274 
    275 gl::Rectangle ClipRectToScissor(const gl::State &glState, const gl::Rectangle &rect, bool invertY);
    276 
    277 // Helper method to intialize a FeatureSet with overrides from the DisplayState
    278 void ApplyFeatureOverrides(angle::FeatureSetBase *features, const egl::DisplayState &state);
    279 
    280 template <typename In>
    281 uint32_t LineLoopRestartIndexCountHelper(GLsizei indexCount, const uint8_t *srcPtr)
    282 {
    283    constexpr In restartIndex = gl::GetPrimitiveRestartIndexFromType<In>();
    284    const In *inIndices       = reinterpret_cast<const In *>(srcPtr);
    285    uint32_t numIndices       = 0;
    286    // See CopyLineLoopIndicesWithRestart() below for more info on how
    287    // numIndices is calculated.
    288    GLsizei loopStartIndex = 0;
    289    for (GLsizei curIndex = 0; curIndex < indexCount; curIndex++)
    290    {
    291        In vertex = inIndices[curIndex];
    292        if (vertex != restartIndex)
    293        {
    294            numIndices++;
    295        }
    296        else
    297        {
    298            if (curIndex > loopStartIndex)
    299            {
    300                numIndices += 2;
    301            }
    302            loopStartIndex = curIndex + 1;
    303        }
    304    }
    305    if (indexCount > loopStartIndex)
    306    {
    307        numIndices++;
    308    }
    309    return numIndices;
    310 }
    311 
    312 inline uint32_t GetLineLoopWithRestartIndexCount(gl::DrawElementsType glIndexType,
    313                                                 GLsizei indexCount,
    314                                                 const uint8_t *srcPtr)
    315 {
    316    switch (glIndexType)
    317    {
    318        case gl::DrawElementsType::UnsignedByte:
    319            return LineLoopRestartIndexCountHelper<uint8_t>(indexCount, srcPtr);
    320        case gl::DrawElementsType::UnsignedShort:
    321            return LineLoopRestartIndexCountHelper<uint16_t>(indexCount, srcPtr);
    322        case gl::DrawElementsType::UnsignedInt:
    323            return LineLoopRestartIndexCountHelper<uint32_t>(indexCount, srcPtr);
    324        default:
    325            UNREACHABLE();
    326            return 0;
    327    }
    328 }
    329 
    330 // Writes the line-strip vertices for a line loop to outPtr,
    331 // where outLimit is calculated as in GetPrimitiveRestartIndexCount.
    332 template <typename In, typename Out>
    333 void CopyLineLoopIndicesWithRestart(GLsizei indexCount, const uint8_t *srcPtr, uint8_t *outPtr)
    334 {
    335    constexpr In restartIndex     = gl::GetPrimitiveRestartIndexFromType<In>();
    336    constexpr Out outRestartIndex = gl::GetPrimitiveRestartIndexFromType<Out>();
    337    const In *inIndices           = reinterpret_cast<const In *>(srcPtr);
    338    Out *outIndices               = reinterpret_cast<Out *>(outPtr);
    339    GLsizei loopStartIndex        = 0;
    340    for (GLsizei curIndex = 0; curIndex < indexCount; curIndex++)
    341    {
    342        In vertex = inIndices[curIndex];
    343        if (vertex != restartIndex)
    344        {
    345            *(outIndices++) = static_cast<Out>(vertex);
    346        }
    347        else
    348        {
    349            if (curIndex > loopStartIndex)
    350            {
    351                // Emit an extra vertex only if the loop is not empty.
    352                *(outIndices++) = inIndices[loopStartIndex];
    353                // Then restart the strip.
    354                *(outIndices++) = outRestartIndex;
    355            }
    356            loopStartIndex = curIndex + 1;
    357        }
    358    }
    359    if (indexCount > loopStartIndex)
    360    {
    361        // Close the last loop if not empty.
    362        *(outIndices++) = inIndices[loopStartIndex];
    363    }
    364 }
    365 
    366 void GetSamplePosition(GLsizei sampleCount, size_t index, GLfloat *xy);
    367 
    368 angle::Result MultiDrawArraysGeneral(ContextImpl *contextImpl,
    369                                     const gl::Context *context,
    370                                     gl::PrimitiveMode mode,
    371                                     const GLint *firsts,
    372                                     const GLsizei *counts,
    373                                     GLsizei drawcount);
    374 angle::Result MultiDrawArraysIndirectGeneral(ContextImpl *contextImpl,
    375                                             const gl::Context *context,
    376                                             gl::PrimitiveMode mode,
    377                                             const void *indirect,
    378                                             GLsizei drawcount,
    379                                             GLsizei stride);
    380 angle::Result MultiDrawArraysInstancedGeneral(ContextImpl *contextImpl,
    381                                              const gl::Context *context,
    382                                              gl::PrimitiveMode mode,
    383                                              const GLint *firsts,
    384                                              const GLsizei *counts,
    385                                              const GLsizei *instanceCounts,
    386                                              GLsizei drawcount);
    387 angle::Result MultiDrawElementsGeneral(ContextImpl *contextImpl,
    388                                       const gl::Context *context,
    389                                       gl::PrimitiveMode mode,
    390                                       const GLsizei *counts,
    391                                       gl::DrawElementsType type,
    392                                       const GLvoid *const *indices,
    393                                       GLsizei drawcount);
    394 angle::Result MultiDrawElementsIndirectGeneral(ContextImpl *contextImpl,
    395                                               const gl::Context *context,
    396                                               gl::PrimitiveMode mode,
    397                                               gl::DrawElementsType type,
    398                                               const void *indirect,
    399                                               GLsizei drawcount,
    400                                               GLsizei stride);
    401 angle::Result MultiDrawElementsInstancedGeneral(ContextImpl *contextImpl,
    402                                                const gl::Context *context,
    403                                                gl::PrimitiveMode mode,
    404                                                const GLsizei *counts,
    405                                                gl::DrawElementsType type,
    406                                                const GLvoid *const *indices,
    407                                                const GLsizei *instanceCounts,
    408                                                GLsizei drawcount);
    409 angle::Result MultiDrawArraysInstancedBaseInstanceGeneral(ContextImpl *contextImpl,
    410                                                          const gl::Context *context,
    411                                                          gl::PrimitiveMode mode,
    412                                                          const GLint *firsts,
    413                                                          const GLsizei *counts,
    414                                                          const GLsizei *instanceCounts,
    415                                                          const GLuint *baseInstances,
    416                                                          GLsizei drawcount);
    417 angle::Result MultiDrawElementsInstancedBaseVertexBaseInstanceGeneral(ContextImpl *contextImpl,
    418                                                                      const gl::Context *context,
    419                                                                      gl::PrimitiveMode mode,
    420                                                                      const GLsizei *counts,
    421                                                                      gl::DrawElementsType type,
    422                                                                      const GLvoid *const *indices,
    423                                                                      const GLsizei *instanceCounts,
    424                                                                      const GLint *baseVertices,
    425                                                                      const GLuint *baseInstances,
    426                                                                      GLsizei drawcount);
    427 
    428 // RAII object making sure reset uniforms is called no matter whether there's an error in draw calls
    429 class ResetBaseVertexBaseInstance : angle::NonCopyable
    430 {
    431  public:
    432    ResetBaseVertexBaseInstance(gl::Program *programObject,
    433                                bool resetBaseVertex,
    434                                bool resetBaseInstance);
    435 
    436    ~ResetBaseVertexBaseInstance();
    437 
    438  private:
    439    gl::Program *mProgramObject;
    440    bool mResetBaseVertex;
    441    bool mResetBaseInstance;
    442 };
    443 
    444 angle::FormatID ConvertToSRGB(angle::FormatID formatID);
    445 angle::FormatID ConvertToLinear(angle::FormatID formatID);
    446 bool IsOverridableLinearFormat(angle::FormatID formatID);
    447 
    448 enum class PipelineType
    449 {
    450    Graphics = 0,
    451    Compute  = 1,
    452 
    453    InvalidEnum = 2,
    454    EnumCount   = 2,
    455 };
    456 }  // namespace rx
    457 
    458 // MultiDraw macro patterns
    459 // These macros are to avoid too much code duplication as we don't want to have if detect for
    460 // hasDrawID/BaseVertex/BaseInstance inside for loop in a multiDrawANGLE call Part of these are put
    461 // in the header as we want to share with specialized context impl on some platforms for multidraw
    462 #define ANGLE_SET_DRAW_ID_UNIFORM_0(drawID) \
    463    {}
    464 #define ANGLE_SET_DRAW_ID_UNIFORM_1(drawID) programObject->setDrawIDUniform(drawID)
    465 #define ANGLE_SET_DRAW_ID_UNIFORM(cond) ANGLE_SET_DRAW_ID_UNIFORM_##cond
    466 
    467 #define ANGLE_SET_BASE_VERTEX_UNIFORM_0(baseVertex) \
    468    {}
    469 #define ANGLE_SET_BASE_VERTEX_UNIFORM_1(baseVertex) programObject->setBaseVertexUniform(baseVertex);
    470 #define ANGLE_SET_BASE_VERTEX_UNIFORM(cond) ANGLE_SET_BASE_VERTEX_UNIFORM_##cond
    471 
    472 #define ANGLE_SET_BASE_INSTANCE_UNIFORM_0(baseInstance) \
    473    {}
    474 #define ANGLE_SET_BASE_INSTANCE_UNIFORM_1(baseInstance) \
    475    programObject->setBaseInstanceUniform(baseInstance)
    476 #define ANGLE_SET_BASE_INSTANCE_UNIFORM(cond) ANGLE_SET_BASE_INSTANCE_UNIFORM_##cond
    477 
    478 #define ANGLE_NOOP_DRAW_ context->noopDraw(mode, counts[drawID])
    479 #define ANGLE_NOOP_DRAW_INSTANCED \
    480    context->noopDrawInstanced(mode, counts[drawID], instanceCounts[drawID])
    481 #define ANGLE_NOOP_DRAW(_instanced) ANGLE_NOOP_DRAW##_instanced
    482 
    483 #define ANGLE_MARK_TRANSFORM_FEEDBACK_USAGE_ \
    484    gl::MarkTransformFeedbackBufferUsage(context, counts[drawID], 1)
    485 #define ANGLE_MARK_TRANSFORM_FEEDBACK_USAGE_INSTANCED \
    486    gl::MarkTransformFeedbackBufferUsage(context, counts[drawID], instanceCounts[drawID])
    487 #define ANGLE_MARK_TRANSFORM_FEEDBACK_USAGE(instanced) \
    488    ANGLE_MARK_TRANSFORM_FEEDBACK_USAGE##instanced
    489 
    490 // Helper macro that casts to a bitfield type then verifies no bits were dropped.
    491 #define SetBitField(lhs, rhs)                                                         \
    492    do                                                                                \
    493    {                                                                                 \
    494        auto ANGLE_LOCAL_VAR = rhs;                                                   \
    495        lhs = static_cast<typename std::decay<decltype(lhs)>::type>(ANGLE_LOCAL_VAR); \
    496        ASSERT(static_cast<decltype(ANGLE_LOCAL_VAR)>(lhs) == ANGLE_LOCAL_VAR);       \
    497    } while (0)
    498 
    499 #endif  // LIBANGLE_RENDERER_RENDERER_UTILS_H_