diff options
Diffstat (limited to 'gfx/angle/checkout/src/libANGLE/renderer/renderer_utils.h')
-rw-r--r-- | gfx/angle/checkout/src/libANGLE/renderer/renderer_utils.h | 406 |
1 files changed, 406 insertions, 0 deletions
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/renderer_utils.h b/gfx/angle/checkout/src/libANGLE/renderer/renderer_utils.h new file mode 100644 index 0000000000..667f3d5a02 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/renderer/renderer_utils.h @@ -0,0 +1,406 @@ +// +// 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 ¶ms, + 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 bool 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 bool 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> +size_t LineLoopRestartIndexCountHelper(GLsizei indexCount, const uint8_t *srcPtr) +{ + constexpr In restartIndex = gl::GetPrimitiveRestartIndexFromType<In>(); + const In *inIndices = reinterpret_cast<const In *>(srcPtr); + size_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 size_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_ |