// // 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 #include #include #include "common/angleutils.h" #include "libANGLE/angletypes.h" namespace angle { struct Format; } // namespace angle namespace gl { struct FormatType; struct InternalFormat; } // namespace gl namespace egl { class AttributeMap; } // namespace egl namespace rx { 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::max(); constexpr static uintptr_t kEmpty = 0; uintptr_t mValue; }; class SerialFactory; 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!=(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; } private: friend class SerialFactory; constexpr explicit Serial(uint64_t value) : mValue(value) {} uint64_t mValue; static constexpr uint64_t kInvalid = 0; }; class SerialFactory final : angle::NonCopyable { public: SerialFactory() : mSerial(1) {} Serial generate() { ASSERT(mSerial != std::numeric_limits::max()); return Serial(mSerial++); } private: uint64_t mSerial; }; 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 (*ColorReadFunction)(const uint8_t *source, uint8_t *dest); typedef void (*ColorWriteFunction)(const uint8_t *source, uint8_t *dest); typedef void (*ColorCopyFunction)(const uint8_t *source, uint8_t *dest); class FastCopyFunctionMap { public: struct Entry { GLenum format; GLenum type; ColorCopyFunction func; }; constexpr FastCopyFunctionMap() : FastCopyFunctionMap(nullptr, 0) {} constexpr FastCopyFunctionMap(const Entry *data, size_t size) : mSize(size), mData(data) {} bool has(const gl::FormatType &formatType) const; ColorCopyFunction get(const gl::FormatType &formatType) const; private: size_t mSize; const Entry *mData; }; struct PackPixelsParams { PackPixelsParams(); PackPixelsParams(const gl::Rectangle &area, GLenum format, GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, gl::Buffer *packBufferIn, ptrdiff_t offset); gl::Rectangle area; GLenum format; GLenum type; GLuint outputPitch; gl::Buffer *packBuffer; gl::PixelPackState pack; ptrdiff_t offset; }; void PackPixels(const PackPixelsParams ¶ms, const angle::Format &sourceFormat, int inputPitch, const uint8_t *source, uint8_t *destination); ColorWriteFunction GetColorWriteFunction(const gl::FormatType &formatType); ColorCopyFunction GetFastCopyFunction(const FastCopyFunctionMap &fastCopyFunctions, const gl::FormatType &formatType); 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); void CopyImageCHROMIUM(const uint8_t *sourceData, size_t sourceRowPitch, size_t sourcePixelBytes, ColorReadFunction readFunction, uint8_t *destData, size_t destRowPitch, size_t destPixelBytes, ColorWriteFunction colorWriteFunction, GLenum destUnsizedFormat, GLenum destComponentType, size_t width, size_t height, 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 gl::Error initializeMultisampleTextureToBlack(const gl::Context *context, gl::Texture *glTexture) = 0; }; class IncompleteTextureSet final : angle::NonCopyable { public: IncompleteTextureSet(); ~IncompleteTextureSet(); void onDestroy(const gl::Context *context); gl::Error getIncompleteTexture(const gl::Context *context, GLenum type, MultisampleTextureInitializer *multisampleInitializer, gl::Texture **textureOut); private: gl::TextureMap mIncompleteTextures; }; } // namespace rx #endif // LIBANGLE_RENDERER_RENDERER_UTILS_H_