Edit

kc3-lang/angle/src/libANGLE/renderer/renderer_utils.h

Branch :

  • Show log

    Commit

  • Author : James Darpinian
    Date : 2019-08-06 17:17:19
    Hash : 7e48c9eb
    Message : Add explicit integer casts WebKit uses the -Wshorten-64-to-32 flag which warns on these cases. Bug: 3439 Change-Id: I8c1de60da0f173ca2036e2120e79b857f5f2775f Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1740866 Commit-Queue: James Darpinian <jdarpinian@chromium.org> Reviewed-by: Kenneth Russell <kbr@chromium.org>

  • src/libANGLE/renderer/renderer_utils.h
  • //
    // Copyright 2016 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.
    //
    // renderer_utils:
    //   Helper methods pertaining to most or all back-ends.
    //
    
    #ifndef LIBANGLE_RENDERER_RENDERER_UTILS_H_
    #define LIBANGLE_RENDERER_RENDERER_UTILS_H_
    
    #include <cstdint>
    
    #include <atomic>
    #include <limits>
    #include <map>
    
    #include "common/angleutils.h"
    #include "common/utilities.h"
    #include "libANGLE/angletypes.h"
    
    namespace angle
    {
    struct FeatureSetBase;
    struct Format;
    enum class FormatID;
    }  // namespace angle
    
    namespace gl
    {
    struct FormatType;
    struct InternalFormat;
    class State;
    }  // namespace gl
    
    namespace egl
    {
    class AttributeMap;
    struct DisplayState;
    }  // namespace egl
    
    namespace rx
    {
    class ContextImpl;
    
    class ResourceSerial
    {
      public:
        constexpr ResourceSerial() : mValue(kDirty) {}
        explicit constexpr ResourceSerial(uintptr_t value) : mValue(value) {}
        constexpr bool operator==(ResourceSerial other) const { return mValue == other.mValue; }
        constexpr bool operator!=(ResourceSerial other) const { return mValue != other.mValue; }
    
        void dirty() { mValue = kDirty; }
        void clear() { mValue = kEmpty; }
    
        constexpr bool valid() const { return mValue != kEmpty && mValue != kDirty; }
        constexpr bool empty() const { return mValue == kEmpty; }
    
      private:
        constexpr static uintptr_t kDirty = std::numeric_limits<uintptr_t>::max();
        constexpr static uintptr_t kEmpty = 0;
    
        uintptr_t mValue;
    };
    
    class Serial final
    {
      public:
        constexpr Serial() : mValue(kInvalid) {}
        constexpr Serial(const Serial &other) = default;
        Serial &operator=(const Serial &other) = default;
    
        constexpr bool operator==(const Serial &other) const
        {
            return mValue != kInvalid && mValue == other.mValue;
        }
        constexpr bool operator==(uint32_t value) const
        {
            return mValue != kInvalid && mValue == static_cast<uint64_t>(value);
        }
        constexpr bool operator!=(const Serial &other) const
        {
            return mValue == kInvalid || mValue != other.mValue;
        }
        constexpr bool operator>(const Serial &other) const { return mValue > other.mValue; }
        constexpr bool operator>=(const Serial &other) const { return mValue >= other.mValue; }
        constexpr bool operator<(const Serial &other) const { return mValue < other.mValue; }
        constexpr bool operator<=(const Serial &other) const { return mValue <= other.mValue; }
    
        constexpr bool operator<(uint32_t value) const { return mValue < static_cast<uint64_t>(value); }
    
        // Useful for serialization.
        constexpr uint64_t getValue() const { return mValue; }
    
      private:
        template <typename T>
        friend class SerialFactoryBase;
        constexpr explicit Serial(uint64_t value) : mValue(value) {}
        uint64_t mValue;
        static constexpr uint64_t kInvalid = 0;
    };
    
    template <typename SerialBaseType>
    class SerialFactoryBase final : angle::NonCopyable
    {
      public:
        SerialFactoryBase() : mSerial(1) {}
    
        Serial generate()
        {
            ASSERT(mSerial + 1 > mSerial);
            return Serial(mSerial++);
        }
    
      private:
        SerialBaseType mSerial;
    };
    
    using SerialFactory       = SerialFactoryBase<uint64_t>;
    using AtomicSerialFactory = SerialFactoryBase<std::atomic<uint64_t>>;
    
    using MipGenerationFunction = void (*)(size_t sourceWidth,
                                           size_t sourceHeight,
                                           size_t sourceDepth,
                                           const uint8_t *sourceData,
                                           size_t sourceRowPitch,
                                           size_t sourceDepthPitch,
                                           uint8_t *destData,
                                           size_t destRowPitch,
                                           size_t destDepthPitch);
    
    typedef void (*PixelReadFunction)(const uint8_t *source, uint8_t *dest);
    typedef void (*PixelWriteFunction)(const uint8_t *source, uint8_t *dest);
    typedef void (*PixelCopyFunction)(const uint8_t *source, uint8_t *dest);
    
    class FastCopyFunctionMap
    {
      public:
        struct Entry
        {
            angle::FormatID formatID;
            PixelCopyFunction func;
        };
    
        constexpr FastCopyFunctionMap() : FastCopyFunctionMap(nullptr, 0) {}
    
        constexpr FastCopyFunctionMap(const Entry *data, size_t size) : mSize(size), mData(data) {}
    
        bool has(angle::FormatID formatID) const;
        PixelCopyFunction get(angle::FormatID formatID) const;
    
      private:
        size_t mSize;
        const Entry *mData;
    };
    
    struct PackPixelsParams
    {
        PackPixelsParams();
        PackPixelsParams(const gl::Rectangle &area,
                         const angle::Format &destFormat,
                         GLuint outputPitch,
                         bool reverseRowOrderIn,
                         gl::Buffer *packBufferIn,
                         ptrdiff_t offset);
    
        gl::Rectangle area;
        const angle::Format *destFormat;
        GLuint outputPitch;
        gl::Buffer *packBuffer;
        bool reverseRowOrder;
        ptrdiff_t offset;
    };
    
    void PackPixels(const PackPixelsParams &params,
                    const angle::Format &sourceFormat,
                    int inputPitch,
                    const uint8_t *source,
                    uint8_t *destination);
    
    using InitializeTextureDataFunction = void (*)(size_t width,
                                                   size_t height,
                                                   size_t depth,
                                                   uint8_t *output,
                                                   size_t outputRowPitch,
                                                   size_t outputDepthPitch);
    
    using LoadImageFunction = void (*)(size_t width,
                                       size_t height,
                                       size_t depth,
                                       const uint8_t *input,
                                       size_t inputRowPitch,
                                       size_t inputDepthPitch,
                                       uint8_t *output,
                                       size_t outputRowPitch,
                                       size_t outputDepthPitch);
    
    struct LoadImageFunctionInfo
    {
        LoadImageFunctionInfo() : loadFunction(nullptr), requiresConversion(false) {}
        LoadImageFunctionInfo(LoadImageFunction loadFunction, bool requiresConversion)
            : loadFunction(loadFunction), requiresConversion(requiresConversion)
        {}
    
        LoadImageFunction loadFunction;
        bool requiresConversion;
    };
    
    using LoadFunctionMap = LoadImageFunctionInfo (*)(GLenum);
    
    bool ShouldUseDebugLayers(const egl::AttributeMap &attribs);
    bool ShouldUseVirtualizedContexts(const egl::AttributeMap &attribs, bool defaultValue);
    
    void CopyImageCHROMIUM(const uint8_t *sourceData,
                           size_t sourceRowPitch,
                           size_t sourcePixelBytes,
                           size_t sourceDepthPitch,
                           PixelReadFunction pixelReadFunction,
                           uint8_t *destData,
                           size_t destRowPitch,
                           size_t destPixelBytes,
                           size_t destDepthPitch,
                           PixelWriteFunction pixelWriteFunction,
                           GLenum destUnsizedFormat,
                           GLenum destComponentType,
                           size_t width,
                           size_t height,
                           size_t depth,
                           bool unpackFlipY,
                           bool unpackPremultiplyAlpha,
                           bool unpackUnmultiplyAlpha);
    
    // Incomplete textures are 1x1 textures filled with black, used when samplers are incomplete.
    // This helper class encapsulates handling incomplete textures. Because the GL back-end
    // can take advantage of the driver's incomplete textures, and because clearing multisample
    // textures is so difficult, we can keep an instance of this class in the back-end instead
    // of moving the logic to the Context front-end.
    
    // This interface allows us to call-back to init a multisample texture.
    class MultisampleTextureInitializer
    {
      public:
        virtual ~MultisampleTextureInitializer() {}
        virtual angle::Result initializeMultisampleTextureToBlack(const gl::Context *context,
                                                                  gl::Texture *glTexture) = 0;
    };
    
    class IncompleteTextureSet final : angle::NonCopyable
    {
      public:
        IncompleteTextureSet();
        ~IncompleteTextureSet();
    
        void onDestroy(const gl::Context *context);
    
        angle::Result getIncompleteTexture(const gl::Context *context,
                                           gl::TextureType type,
                                           MultisampleTextureInitializer *multisampleInitializer,
                                           gl::Texture **textureOut);
    
      private:
        gl::TextureMap mIncompleteTextures;
    };
    
    // Helpers to set a matrix uniform value based on GLSL or HLSL semantics.
    // The return value indicate if the data was updated or not.
    template <int cols, int rows>
    struct SetFloatUniformMatrixGLSL
    {
        static void Run(unsigned int arrayElementOffset,
                        unsigned int elementCount,
                        GLsizei countIn,
                        GLboolean transpose,
                        const GLfloat *value,
                        uint8_t *targetData);
    };
    
    template <int cols, int rows>
    struct SetFloatUniformMatrixHLSL
    {
        static void Run(unsigned int arrayElementOffset,
                        unsigned int elementCount,
                        GLsizei countIn,
                        GLboolean transpose,
                        const GLfloat *value,
                        uint8_t *targetData);
    };
    
    // Helper method to de-tranpose a matrix uniform for an API query.
    void GetMatrixUniform(GLenum type, GLfloat *dataOut, const GLfloat *source, bool transpose);
    
    template <typename NonFloatT>
    void GetMatrixUniform(GLenum type, NonFloatT *dataOut, const NonFloatT *source, bool transpose);
    
    const angle::Format &GetFormatFromFormatType(GLenum format, GLenum type);
    
    angle::Result ComputeStartVertex(ContextImpl *contextImpl,
                                     const gl::IndexRange &indexRange,
                                     GLint baseVertex,
                                     GLint *firstVertexOut);
    
    angle::Result GetVertexRangeInfo(const gl::Context *context,
                                     GLint firstVertex,
                                     GLsizei vertexOrIndexCount,
                                     gl::DrawElementsType indexTypeOrInvalid,
                                     const void *indices,
                                     GLint baseVertex,
                                     GLint *startVertexOut,
                                     size_t *vertexCountOut);
    
    gl::Rectangle ClipRectToScissor(const gl::State &glState, const gl::Rectangle &rect, bool invertY);
    
    // Helper method to intialize a FeatureSet with overrides from the DisplayState
    void OverrideFeaturesWithDisplayState(angle::FeatureSetBase *features,
                                          const egl::DisplayState &state);
    
    template <typename In>
    uint32_t LineLoopRestartIndexCountHelper(GLsizei indexCount, const uint8_t *srcPtr)
    {
        constexpr In restartIndex = gl::GetPrimitiveRestartIndexFromType<In>();
        const In *inIndices       = reinterpret_cast<const In *>(srcPtr);
        uint32_t numIndices       = 0;
        // See CopyLineLoopIndicesWithRestart() below for more info on how
        // numIndices is calculated.
        GLsizei loopStartIndex = 0;
        for (GLsizei curIndex = 0; curIndex < indexCount; curIndex++)
        {
            In vertex = inIndices[curIndex];
            if (vertex != restartIndex)
            {
                numIndices++;
            }
            else
            {
                if (curIndex > loopStartIndex)
                {
                    numIndices += 2;
                }
                loopStartIndex = curIndex + 1;
            }
        }
        if (indexCount > loopStartIndex)
        {
            numIndices++;
        }
        return numIndices;
    }
    
    inline uint32_t GetLineLoopWithRestartIndexCount(gl::DrawElementsType glIndexType,
                                                     GLsizei indexCount,
                                                     const uint8_t *srcPtr)
    {
        switch (glIndexType)
        {
            case gl::DrawElementsType::UnsignedByte:
                return LineLoopRestartIndexCountHelper<uint8_t>(indexCount, srcPtr);
            case gl::DrawElementsType::UnsignedShort:
                return LineLoopRestartIndexCountHelper<uint16_t>(indexCount, srcPtr);
            case gl::DrawElementsType::UnsignedInt:
                return LineLoopRestartIndexCountHelper<uint32_t>(indexCount, srcPtr);
            default:
                UNREACHABLE();
                return 0;
        }
    }
    
    // Writes the line-strip vertices for a line loop to outPtr,
    // where outLimit is calculated as in GetPrimitiveRestartIndexCount.
    template <typename In, typename Out>
    void CopyLineLoopIndicesWithRestart(GLsizei indexCount, const uint8_t *srcPtr, uint8_t *outPtr)
    {
        constexpr In restartIndex     = gl::GetPrimitiveRestartIndexFromType<In>();
        constexpr Out outRestartIndex = gl::GetPrimitiveRestartIndexFromType<Out>();
        const In *inIndices           = reinterpret_cast<const In *>(srcPtr);
        Out *outIndices               = reinterpret_cast<Out *>(outPtr);
        GLsizei loopStartIndex        = 0;
        for (GLsizei curIndex = 0; curIndex < indexCount; curIndex++)
        {
            In vertex = inIndices[curIndex];
            if (vertex != restartIndex)
            {
                *(outIndices++) = static_cast<Out>(vertex);
            }
            else
            {
                if (curIndex > loopStartIndex)
                {
                    // Emit an extra vertex only if the loop is not empty.
                    *(outIndices++) = inIndices[loopStartIndex];
                    // Then restart the strip.
                    *(outIndices++) = outRestartIndex;
                }
                loopStartIndex = curIndex + 1;
            }
        }
        if (indexCount > loopStartIndex)
        {
            // Close the last loop if not empty.
            *(outIndices++) = inIndices[loopStartIndex];
        }
    }
    }  // namespace rx
    
    #endif  // LIBANGLE_RENDERER_RENDERER_UTILS_H_