//
// Copyright 2002 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.
//

// Texture.h: Defines the gl::Texture class [OpenGL ES 2.0.24] section 3.7 page 63.

#ifndef LIBANGLE_TEXTURE_H_
#define LIBANGLE_TEXTURE_H_

#include <map>
#include <vector>

#include "angle_gl.h"
#include "common/Optional.h"
#include "common/debug.h"
#include "common/utilities.h"
#include "libANGLE/Caps.h"
#include "libANGLE/Constants.h"
#include "libANGLE/Debug.h"
#include "libANGLE/Error.h"
#include "libANGLE/FramebufferAttachment.h"
#include "libANGLE/Image.h"
#include "libANGLE/Observer.h"
#include "libANGLE/RefCountObject.h"
#include "libANGLE/Stream.h"
#include "libANGLE/angletypes.h"
#include "libANGLE/formatutils.h"

namespace egl
{
class Surface;
class Stream;
}  // namespace egl

namespace rx
{
class GLImplFactory;
class TextureImpl;
class TextureGL;
}  // namespace rx

namespace gl
{
class Framebuffer;
class MemoryObject;
class Sampler;
class State;
class Texture;

constexpr GLuint kInitialMaxLevel = 1000;

bool IsMipmapFiltered(GLenum minFilterMode);

// Convert a given filter mode to nearest filtering.
GLenum ConvertToNearestFilterMode(GLenum filterMode);

// Convert a given filter mode to nearest mip filtering.
GLenum ConvertToNearestMipFilterMode(GLenum filterMode);

struct ImageDesc final
{
    ImageDesc();
    ImageDesc(const Extents &size, const Format &format, const InitState initState);
    ImageDesc(const Extents &size,
              const Format &format,
              const GLsizei samples,
              const bool fixedSampleLocations,
              const InitState initState);

    ImageDesc(const ImageDesc &other)            = default;
    ImageDesc &operator=(const ImageDesc &other) = default;

    GLint getMemorySize() const;

    Extents size;
    Format format;
    GLsizei samples;
    bool fixedSampleLocations;

    // Needed for robust resource initialization.
    InitState initState;
};

struct SwizzleState final
{
    SwizzleState();
    SwizzleState(GLenum red, GLenum green, GLenum blue, GLenum alpha);
    SwizzleState(const SwizzleState &other)            = default;
    SwizzleState &operator=(const SwizzleState &other) = default;

    bool swizzleRequired() const;

    bool operator==(const SwizzleState &other) const;
    bool operator!=(const SwizzleState &other) const;

    GLenum swizzleRed;
    GLenum swizzleGreen;
    GLenum swizzleBlue;
    GLenum swizzleAlpha;
};

// State from Table 6.9 (state per texture object) in the OpenGL ES 3.0.2 spec.
class TextureState final : private angle::NonCopyable
{
  public:
    TextureState(TextureType type);
    ~TextureState();

    bool swizzleRequired() const;
    GLuint getEffectiveBaseLevel() const;
    GLuint getEffectiveMaxLevel() const;

    // Returns the value called "q" in the GLES 3.0.4 spec section 3.8.10.
    GLuint getMipmapMaxLevel() const;

    // Returns true if base level changed.
    bool setBaseLevel(GLuint baseLevel);
    GLuint getBaseLevel() const { return mBaseLevel; }
    bool setMaxLevel(GLuint maxLevel);
    GLuint getMaxLevel() const { return mMaxLevel; }

    bool isCubeComplete() const;

    ANGLE_INLINE bool compatibleWithSamplerFormatForWebGL(SamplerFormat format,
                                                          const SamplerState &samplerState) const
    {
        if (!mCachedSamplerFormatValid ||
            mCachedSamplerCompareMode != samplerState.getCompareMode())
        {
            mCachedSamplerFormat      = computeRequiredSamplerFormat(samplerState);
            mCachedSamplerCompareMode = samplerState.getCompareMode();
            mCachedSamplerFormatValid = true;
        }
        // Incomplete textures are compatible with any sampler format.
        return mCachedSamplerFormat == SamplerFormat::InvalidEnum || format == mCachedSamplerFormat;
    }

    const ImageDesc &getImageDesc(TextureTarget target, size_t level) const;
    const ImageDesc &getImageDesc(const ImageIndex &imageIndex) const;

    TextureType getType() const { return mType; }
    const SwizzleState &getSwizzleState() const { return mSwizzleState; }
    const SamplerState &getSamplerState() const { return mSamplerState; }
    GLenum getUsage() const { return mUsage; }
    bool hasProtectedContent() const { return mHasProtectedContent; }
    bool renderabilityValidation() const { return mRenderabilityValidation; }
    GLenum getDepthStencilTextureMode() const { return mDepthStencilTextureMode; }

    bool isExternalMemoryTexture() const { return mIsExternalMemoryTexture; }
    bool hasBeenBoundAsImage() const { return mHasBeenBoundAsImage; }
    bool hasBeenBoundAsAttachment() const { return mHasBeenBoundAsAttachment; }
    bool hasBeenBoundToMSRTTFramebuffer() const { return mHasBeenBoundToMSRTTFramebuffer; }
    bool hasBeenBoundAsSourceOfEglImage() const { return mHasBeenBoundAsSourceOfEglImage; }

    gl::SrgbOverride getSRGBOverride() const { return mSrgbOverride; }

    // Returns the desc of the base level. Only valid for cube-complete/mip-complete textures.
    const ImageDesc &getBaseLevelDesc() const;
    const ImageDesc &getLevelZeroDesc() const;

    // This helper is used by backends that require special setup to read stencil data
    bool isStencilMode() const
    {
        const GLenum format =
            getImageDesc(getBaseImageTarget(), getEffectiveBaseLevel()).format.info->format;
        return (format == GL_DEPTH_STENCIL) ? (mDepthStencilTextureMode == GL_STENCIL_INDEX)
                                            : (format == GL_STENCIL_INDEX);
    }

    // GLES1 emulation: For GL_OES_draw_texture
    void setCrop(const Rectangle &rect);
    const Rectangle &getCrop() const;

    // GLES1 emulation: Auto-mipmap generation is a texparameter
    void setGenerateMipmapHint(GLenum hint);
    GLenum getGenerateMipmapHint() const;

    bool setASTCDecodePrecision(GLenum astcDecodePrecision);
    GLenum getASTCDecodePrecision() const;

    // Return the enabled mipmap level count.
    GLuint getEnabledLevelCount() const;

    bool getImmutableFormat() const { return mImmutableFormat; }
    GLuint getImmutableLevels() const { return mImmutableLevels; }

    const std::vector<ImageDesc> &getImageDescs() const { return mImageDescs; }

    InitState getInitState() const { return mInitState; }

    const OffsetBindingPointer<Buffer> &getBuffer() const { return mBuffer; }

    const std::string &getLabel() const { return mLabel; }

    gl::TilingMode getTilingMode() const { return mTilingMode; }

    bool isInternalIncompleteTexture() const { return mIsInternalIncompleteTexture; }

    const FoveationState &getFoveationState() const { return mFoveationState; }

    GLenum getSurfaceCompressionFixedRate() const { return mCompressionFixedRate; }

    const egl::ImageSourceAttributes &getEGLImageSourceAttributes() const
    {
        return mEGLImageSourceAttributes;
    }

    SourceImageIndex toSourceIndex(const OwnImageIndex &index) const
    {
        return mEGLImageSourceAttributes.toSourceIndex(index);
    }
    SourceLevel toSourceLevel(OwnLevel level) const
    {
        return mEGLImageSourceAttributes.toSourceLevel(level);
    }
    SourceLayer toSourceLayer(OwnLayer layer) const
    {
        return mEGLImageSourceAttributes.toSourceLayer(layer);
    }
    SourceLayer toSourceDepth(const Offset &offset) const
    {
        return mEGLImageSourceAttributes.toSourceDepth(offset);
    }

  private:
    // Texture needs access to the ImageDesc functions.
    friend class Texture;
    friend bool operator==(const TextureState &a, const TextureState &b);

    bool computeSamplerCompleteness(const SamplerState &samplerState, const State &state) const;
    bool computeSamplerCompletenessForCopyImage(const SamplerState &samplerState,
                                                const State &state) const;

    bool computeMipmapCompleteness() const;
    bool computeLevelCompleteness(TextureTarget target, size_t level) const;
    SamplerFormat computeRequiredSamplerFormat(const SamplerState &samplerState) const;

    TextureTarget getBaseImageTarget() const;

    void setImageDesc(TextureTarget target, size_t level, const ImageDesc &desc);
    void setImageDescChain(GLuint baselevel,
                           GLuint maxLevel,
                           Extents baseSize,
                           const Format &format,
                           InitState initState);
    void setImageDescChainMultisample(Extents baseSize,
                                      const Format &format,
                                      GLsizei samples,
                                      bool fixedSampleLocations,
                                      InitState initState);

    void clearImageDesc(TextureTarget target, size_t level);
    void clearImageDescs();

    const TextureType mType;

    SwizzleState mSwizzleState;

    SamplerState mSamplerState;

    SrgbOverride mSrgbOverride;

    GLuint mBaseLevel;
    GLuint mMaxLevel;

    GLenum mDepthStencilTextureMode;

    // Distinguish internally created textures.  The Vulkan backend avoids initializing them from an
    // unlocked tail call because they are lazily created on draw, and we don't want to add the
    // overhead of tail-call checks to draw calls.
    bool mIsInternalIncompleteTexture;

    // Whether this is an external memory texture created via EXT_external_objects or
    // ANGLE_external_objects_flags.
    bool mIsExternalMemoryTexture;

    bool mHasBeenBoundAsImage;
    bool mHasBeenBoundAsAttachment;
    bool mHasBeenBoundToMSRTTFramebuffer;
    bool mHasBeenBoundAsSourceOfEglImage;

    bool mImmutableFormat;
    GLuint mImmutableLevels;

    // From GL_ANGLE_texture_usage
    GLenum mUsage;

    // GL_EXT_protected_textures
    bool mHasProtectedContent;

    bool mRenderabilityValidation;

    // GL_EXT_memory_object
    gl::TilingMode mTilingMode;

    std::vector<ImageDesc> mImageDescs;

    // GLES1 emulation: Texture crop rectangle
    // For GL_OES_draw_texture
    Rectangle mCropRect;

    // GLES1 emulation: Generate-mipmap hint per texture
    GLenum mGenerateMipmapHint;

    // GL_OES_texture_buffer / GLES3.2
    OffsetBindingPointer<Buffer> mBuffer;

    InitState mInitState;

    mutable SamplerFormat mCachedSamplerFormat;
    mutable GLenum mCachedSamplerCompareMode;
    mutable bool mCachedSamplerFormatValid;
    std::string mLabel;

    // GL_QCOM_texture_foveated
    FoveationState mFoveationState;

    // GL_EXT_texture_storage_compression
    GLenum mCompressionFixedRate;

    // GL_EXT_texture_compression_astc_decode_mode
    // GL_EXT_texture_compression_astc_decode_mode_rgb9e5
    GLenum mAstcDecodePrecision;

    // |mEGLImageSourceAttributes.type| is only valid if this texture is an "EGLImage target" and
    // the associated EGL Image was originally sourced from an OpenGL texture.  Such EGL Images can
    // be a slice of the underlying resource.  The level and layer offset are used to track the
    // location of the slice.
    egl::ImageSourceAttributes mEGLImageSourceAttributes;
};

bool operator==(const TextureState &a, const TextureState &b);
bool operator!=(const TextureState &a, const TextureState &b);

class TextureBufferContentsObservers final : angle::NonCopyable
{
  public:
    TextureBufferContentsObservers(Texture *texture);
    void enableForBuffer(Buffer *buffer);
    void disableForBuffer(Buffer *buffer);
    bool isEnabledForBuffer(Buffer *buffer);

  private:
    Texture *mTexture;
};

class Texture final : public RefCountObject<TextureID>,
                      public egl::ImageSibling,
                      public LabeledObject
{
  public:
    Texture(rx::GLImplFactory *factory, TextureID id, TextureType type);
    ~Texture() override;

    void onDestroy(const Context *context) override;

    angle::Result setLabel(const Context *context, const std::string &label) override;

    const std::string &getLabel() const override;

    TextureType getType() const { return mState.mType; }

    void setSwizzleRed(const Context *context, GLenum swizzleRed);
    GLenum getSwizzleRed() const;

    void setSwizzleGreen(const Context *context, GLenum swizzleGreen);
    GLenum getSwizzleGreen() const;

    void setSwizzleBlue(const Context *context, GLenum swizzleBlue);
    GLenum getSwizzleBlue() const;

    void setSwizzleAlpha(const Context *context, GLenum swizzleAlpha);
    GLenum getSwizzleAlpha() const;

    void setMinFilter(const Context *context, GLenum minFilter);
    GLenum getMinFilter() const;

    void setMagFilter(const Context *context, GLenum magFilter);
    GLenum getMagFilter() const;

    void setWrapS(const Context *context, GLenum wrapS);
    GLenum getWrapS() const;

    void setWrapT(const Context *context, GLenum wrapT);
    GLenum getWrapT() const;

    void setWrapR(const Context *context, GLenum wrapR);
    GLenum getWrapR() const;

    void setMaxAnisotropy(const Context *context, float maxAnisotropy);
    float getMaxAnisotropy() const;

    void setMinLod(const Context *context, GLfloat minLod);
    GLfloat getMinLod() const;

    void setMaxLod(const Context *context, GLfloat maxLod);
    GLfloat getMaxLod() const;

    void setLodBias(const Context *context, GLfloat lodBias);
    GLfloat getLodBias() const;

    void setCompareMode(const Context *context, GLenum compareMode);
    GLenum getCompareMode() const;

    void setCompareFunc(const Context *context, GLenum compareFunc);
    GLenum getCompareFunc() const;

    void setASTCDecodePrecision(const Context *context, GLenum astcDecodePrecision);
    GLenum getASTCDecodePrecision() const;

    void setSRGBDecode(const Context *context, GLenum sRGBDecode);
    GLenum getSRGBDecode() const;

    void setSRGBOverride(const Context *context, GLenum sRGBOverride);
    GLenum getSRGBOverride() const;

    const SamplerState &getSamplerState() const;

    angle::Result setBaseLevel(const Context *context, GLuint baseLevel);
    GLuint getBaseLevel() const;

    void setMaxLevel(const Context *context, GLuint maxLevel);
    GLuint getMaxLevel() const;

    void setDepthStencilTextureMode(const Context *context, GLenum mode);
    GLenum getDepthStencilTextureMode() const;

    bool getImmutableFormat() const;

    GLuint getImmutableLevels() const;

    void setUsage(const Context *context, GLenum usage);
    GLenum getUsage() const;

    void setProtectedContent(Context *context, bool hasProtectedContent);
    bool hasProtectedContent() const override;
    bool hasFoveatedRendering() const override { return isFoveationEnabled(); }
    const gl::FoveationState *getFoveationState() const override { return &mState.mFoveationState; }

    void setRenderabilityValidation(Context *context, bool renderabilityValidation);

    void setTilingMode(Context *context, GLenum tilingMode);
    GLenum getTilingMode() const;

    const TextureState &getState() const { return mState; }

    void setBorderColor(const Context *context, const ColorGeneric &color);
    const ColorGeneric &getBorderColor() const;

    angle::Result setBuffer(Context *context, gl::Buffer *buffer, GLenum internalFormat);
    angle::Result setBufferRange(Context *context,
                                 gl::Buffer *buffer,
                                 GLenum internalFormat,
                                 GLintptr offset,
                                 GLsizeiptr size);
    const OffsetBindingPointer<Buffer> &getBuffer() const;

    GLint getRequiredTextureImageUnits(const Context *context) const;

    const TextureState &getTextureState() const;

    const Extents &getExtents(TextureTarget target, size_t level) const;
    size_t getWidth(TextureTarget target, size_t level) const;
    size_t getHeight(TextureTarget target, size_t level) const;
    size_t getDepth(TextureTarget target, size_t level) const;
    GLsizei getSamples(TextureTarget target, size_t level) const;
    bool getFixedSampleLocations(TextureTarget target, size_t level) const;
    const Format &getFormat(TextureTarget target, size_t level) const;

    // Returns the value called "q" in the GLES 3.0.4 spec section 3.8.10.
    GLuint getMipmapMaxLevel() const;

    bool isMipmapComplete() const;

    void setFoveatedFeatureBits(const GLuint features);
    GLuint getFoveatedFeatureBits() const;
    bool isFoveationEnabled() const;
    GLuint getSupportedFoveationFeatures() const;

    GLuint getNumFocalPoints() const { return mState.mFoveationState.getMaxNumFocalPoints(); }
    void setMinPixelDensity(const GLfloat density);
    GLfloat getMinPixelDensity() const;
    void setFocalPoint(uint32_t layer,
                       uint32_t focalPointIndex,
                       float focalX,
                       float focalY,
                       float gainX,
                       float gainY,
                       float foveaArea);
    const FocalPoint &getFocalPoint(uint32_t layer, uint32_t focalPoint) const;

    GLint getImageCompressionRate(const Context *context) const;
    GLint getFormatSupportedCompressionRates(const Context *context,
                                             GLenum internalformat,
                                             GLsizei bufSize,
                                             GLint *rates) const;

    angle::Result setImage(Context *context,
                           const PixelUnpackState &unpackState,
                           Buffer *unpackBuffer,
                           TextureTarget target,
                           GLint level,
                           GLenum internalFormat,
                           const Extents &size,
                           GLenum format,
                           GLenum type,
                           const uint8_t *pixels);
    angle::Result setSubImage(Context *context,
                              const PixelUnpackState &unpackState,
                              Buffer *unpackBuffer,
                              TextureTarget target,
                              GLint level,
                              const Box &area,
                              GLenum format,
                              GLenum type,
                              const uint8_t *pixels);

    angle::Result setCompressedImage(Context *context,
                                     const PixelUnpackState &unpackState,
                                     TextureTarget target,
                                     GLint level,
                                     GLenum internalFormat,
                                     const Extents &size,
                                     size_t imageSize,
                                     const uint8_t *pixels);
    angle::Result setCompressedSubImage(const Context *context,
                                        const PixelUnpackState &unpackState,
                                        TextureTarget target,
                                        GLint level,
                                        const Box &area,
                                        GLenum format,
                                        size_t imageSize,
                                        const uint8_t *pixels);

    angle::Result copyImage(Context *context,
                            TextureTarget target,
                            GLint level,
                            const Rectangle &sourceArea,
                            GLenum internalFormat,
                            Framebuffer *source);
    angle::Result copySubImage(Context *context,
                               const ImageIndex &index,
                               const Offset &destOffset,
                               const Rectangle &sourceArea,
                               Framebuffer *source);

    angle::Result copyRenderbufferSubData(Context *context,
                                          const gl::Renderbuffer *srcBuffer,
                                          GLint srcX,
                                          GLint srcY,
                                          GLint dstLevel,
                                          GLint dstX,
                                          GLint dstY,
                                          GLint dstZ,
                                          GLsizei srcWidth,
                                          GLsizei srcHeight);

    angle::Result copyTextureSubData(Context *context,
                                     const gl::Texture *srcTexture,
                                     GLint srcLevel,
                                     GLint srcX,
                                     GLint srcY,
                                     GLint srcZ,
                                     GLint dstLevel,
                                     GLint dstX,
                                     GLint dstY,
                                     GLint dstZ,
                                     GLsizei srcWidth,
                                     GLsizei srcHeight,
                                     GLsizei srcDepth);

    angle::Result copyTexture(Context *context,
                              TextureTarget target,
                              GLint level,
                              GLenum internalFormat,
                              GLenum type,
                              GLint sourceLevel,
                              bool unpackFlipY,
                              bool unpackPremultiplyAlpha,
                              bool unpackUnmultiplyAlpha,
                              Texture *source);
    angle::Result copySubTexture(const Context *context,
                                 TextureTarget target,
                                 GLint level,
                                 const Offset &destOffset,
                                 GLint sourceLevel,
                                 const Box &sourceBox,
                                 bool unpackFlipY,
                                 bool unpackPremultiplyAlpha,
                                 bool unpackUnmultiplyAlpha,
                                 Texture *source);
    angle::Result copyCompressedTexture(Context *context, const Texture *source);

    angle::Result setStorage(Context *context,
                             TextureType type,
                             GLsizei levels,
                             GLenum internalFormat,
                             const Extents &size);

    angle::Result setStorageMultisample(Context *context,
                                        TextureType type,
                                        GLsizei samplesIn,
                                        GLint internalformat,
                                        const Extents &size,
                                        bool fixedSampleLocations);

    angle::Result setStorageExternalMemory(Context *context,
                                           TextureType type,
                                           GLsizei levels,
                                           GLenum internalFormat,
                                           const Extents &size,
                                           MemoryObject *memoryObject,
                                           GLuint64 offset,
                                           GLbitfield createFlags,
                                           GLbitfield usageFlags,
                                           const void *imageCreateInfoPNext);

    angle::Result setImageExternal(Context *context,
                                   TextureTarget target,
                                   GLint level,
                                   GLenum internalFormat,
                                   const Extents &size,
                                   GLenum format,
                                   GLenum type);

    angle::Result setEGLImageTarget(Context *context, TextureType type, egl::Image *imageTarget);

    angle::Result setStorageEGLImageTarget(Context *context,
                                           TextureType type,
                                           egl::Image *image,
                                           const GLint *attrib_list);

    angle::Result setStorageAttribs(Context *context,
                                    TextureType type,
                                    GLsizei levels,
                                    GLenum internalFormat,
                                    const Extents &size,
                                    const GLint *attribList);

    angle::Result generateMipmap(Context *context);

    angle::Result clearImage(Context *context,
                             GLint level,
                             GLenum format,
                             GLenum type,
                             const uint8_t *data);
    angle::Result clearSubImage(Context *context,
                                GLint level,
                                const Box &area,
                                GLenum format,
                                GLenum type,
                                const uint8_t *data);

    void onBindAsImageTexture();
    void onBindAsEglImageSource();

    egl::Surface *getBoundSurface() const;
    egl::Stream *getBoundStream() const;

    GLint getMemorySize() const;
    GLint getLevelMemorySize(TextureTarget target, GLint level) const;

    void signalDirtyStorage(InitState initState);

    bool isSamplerComplete(const Context *context, const Sampler *optionalSampler);
    bool isSamplerCompleteForCopyImage(const Context *context,
                                       const Sampler *optionalSampler) const;
    // Check the rules in Framebuffer Attachment Completeness sections, excluding those related to
    // framebuffer layers.  If a texture is immutable, always returns true, otherwise checks
    // cube-completeness, mip-completeness, etc, if necessary.
    bool isFramebufferAttachmentComplete(GLuint attachmentMipLevel, const char **error) const;

    GLenum getImplementationColorReadFormat(const Context *context) const;
    GLenum getImplementationColorReadType(const Context *context) const;

    // We pass the pack buffer and state explicitly so they can be overridden during capture.
    angle::Result getTexImage(const Context *context,
                              const PixelPackState &packState,
                              Buffer *packBuffer,
                              TextureTarget target,
                              GLint level,
                              GLenum format,
                              GLenum type,
                              void *pixels);

    angle::Result getCompressedTexImage(const Context *context,
                                        const PixelPackState &packState,
                                        Buffer *packBuffer,
                                        TextureTarget target,
                                        GLint level,
                                        void *pixels);

    rx::TextureImpl *getImplementation() const { return mTexture; }

    // FramebufferAttachmentObject implementation
    Extents getAttachmentSize(const ImageIndex &imageIndex) const override;
    Format getAttachmentFormat(GLenum binding, const ImageIndex &imageIndex) const override;
    GLsizei getAttachmentSamples(const ImageIndex &imageIndex) const override;
    bool isRenderable(const Context *context,
                      GLenum binding,
                      const ImageIndex &imageIndex) const override;

    bool getAttachmentFixedSampleLocations(const ImageIndex &imageIndex) const;

    // GLES1 emulation
    void setCrop(const Rectangle &rect);
    const Rectangle &getCrop() const;
    void setGenerateMipmapHint(GLenum generate);
    GLenum getGenerateMipmapHint() const;

    void onAttach(const Context *context, rx::UniqueSerial framebufferSerial) override;
    void onDetach(const Context *context, rx::UniqueSerial framebufferSerial) override;

    // Used specifically for FramebufferAttachmentObject.
    GLuint getId() const override;

    // Needed for robust resource init.
    angle::Result ensureInitialized(const Context *context);
    InitState initState(GLenum binding, const ImageIndex &imageIndex) const override;
    InitState initState() const { return mState.mInitState; }
    void setInitState(GLenum binding, const ImageIndex &imageIndex, InitState initState) override;
    void setInitState(InitState initState);

    bool isBoundToFramebuffer(rx::UniqueSerial framebufferSerial) const
    {
        for (size_t index = 0; index < mBoundFramebufferSerials.size(); ++index)
        {
            if (mBoundFramebufferSerials[index] == framebufferSerial)
                return true;
        }

        return false;
    }

    bool isEGLImageSource(const ImageIndex &index) const;

    bool isDepthOrStencil() const
    {
        return mState.getBaseLevelDesc().format.info->isDepthOrStencil();
    }

    enum DirtyBitType
    {
        // Sampler state
        DIRTY_BIT_MIN_FILTER,
        DIRTY_BIT_MAG_FILTER,
        DIRTY_BIT_WRAP_S,
        DIRTY_BIT_WRAP_T,
        DIRTY_BIT_WRAP_R,
        DIRTY_BIT_MAX_ANISOTROPY,
        DIRTY_BIT_MIN_LOD,
        DIRTY_BIT_MAX_LOD,
        DIRTY_BIT_COMPARE_MODE,
        DIRTY_BIT_COMPARE_FUNC,
        DIRTY_BIT_SRGB_DECODE,
        DIRTY_BIT_SRGB_OVERRIDE,
        DIRTY_BIT_BORDER_COLOR,

        // Texture state
        DIRTY_BIT_SWIZZLE_RED,
        DIRTY_BIT_SWIZZLE_GREEN,
        DIRTY_BIT_SWIZZLE_BLUE,
        DIRTY_BIT_SWIZZLE_ALPHA,
        DIRTY_BIT_BASE_LEVEL,
        DIRTY_BIT_MAX_LEVEL,
        DIRTY_BIT_DEPTH_STENCIL_TEXTURE_MODE,
        DIRTY_BIT_RENDERABILITY_VALIDATION_ANGLE,
        DIRTY_BIT_ASTC_DECODE_PRECISION,
        DIRTY_BIT_LOD_BIAS_QCOM,

        // Image state
        DIRTY_BIT_BOUND_AS_IMAGE,
        DIRTY_BIT_BOUND_AS_ATTACHMENT,

        // Misc
        DIRTY_BIT_USAGE,
        DIRTY_BIT_IMPLEMENTATION,

        DIRTY_BIT_COUNT,
    };
    using DirtyBits = angle::BitSet<DIRTY_BIT_COUNT>;

    angle::Result syncState(const Context *context, Command source);
    bool hasAnyDirtyBit() const { return mDirtyBits.any(); }
    bool hasAnyDirtyBitExcludingBoundAsAttachmentBit() const
    {
        static constexpr DirtyBits kBoundAsAttachment = DirtyBits({DIRTY_BIT_BOUND_AS_ATTACHMENT});
        return mDirtyBits.any() && mDirtyBits != kBoundAsAttachment;
    }

    // ObserverInterface implementation.
    void onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message) override;

    // Texture buffer updates.
    void onBufferContentsChange();

    void markInternalIncompleteTexture() { mState.mIsInternalIncompleteTexture = true; }

    // Texture bound to MSRTT framebuffer.
    void onBindToMSRTTFramebuffer();

  private:
    rx::FramebufferAttachmentObjectImpl *getAttachmentImpl() const override;

    // ANGLE-only method, used internally
    friend class egl::Surface;
    angle::Result bindTexImageFromSurface(Context *context, egl::Surface *surface);
    angle::Result releaseTexImageFromSurface(const Context *context);

    // ANGLE-only methods, used internally
    friend class egl::Stream;
    void bindStream(egl::Stream *stream);
    void releaseStream();
    angle::Result acquireImageFromStream(const Context *context,
                                         const egl::Stream::GLTextureDescription &desc);
    angle::Result releaseImageFromStream(const Context *context);

    void invalidateCompletenessCache() const;

    void releaseTexImageInternalNoRedefinition(Context *context);
    angle::Result releaseTexImageInternal(Context *context);

    bool doesSubImageNeedInit(const Context *context,
                              const ImageIndex &imageIndex,
                              const Box &area) const;
    angle::Result ensureSubImageInitialized(const Context *context,
                                            const ImageIndex &imageIndex,
                                            const Box &area);

    angle::Result handleMipmapGenerationHint(Context *context, int level);

    angle::Result setEGLImageTargetImpl(Context *context,
                                        TextureType type,
                                        GLuint levels,
                                        egl::Image *imageTarget);
    angle::Result orphanImages(const gl::Context *context,
                               egl::RefCountObjectReleaser<egl::Image> *outReleaseImage);

    void signalDirtyState(size_t dirtyBit);

    TextureState mState;
    DirtyBits mDirtyBits;
    rx::TextureImpl *mTexture;
    angle::ObserverBinding mImplObserver;
    // For EXT_texture_buffer, observes buffer changes.
    angle::ObserverBinding mBufferObserver;

    egl::Surface *mBoundSurface;
    egl::Stream *mBoundStream;

    // We track all the serials of the Framebuffers this texture is attached to. Note that this
    // allows duplicates because different ranges of a Texture can be bound to the same Framebuffer.
    // For the purposes of depth-stencil loops, a simple "isBound" check works fine. For color
    // attachment Feedback Loop checks we then need to check further to see when a Texture is bound
    // to mulitple bindings that the bindings don't overlap.
    static constexpr uint32_t kFastFramebufferSerialCount = 8;
    angle::FastVector<rx::UniqueSerial, kFastFramebufferSerialCount> mBoundFramebufferSerials;

    struct SamplerCompletenessCache
    {
        SamplerCompletenessCache();

        // Context used to generate this cache entry
        ContextID context;

        // All values that affect sampler completeness that are not stored within
        // the texture itself
        SamplerState samplerState;

        // Result of the sampler completeness with the above parameters
        bool samplerComplete;
    };

    mutable SamplerCompletenessCache mCompletenessCache;
    TextureBufferContentsObservers mBufferContentsObservers;
};

inline bool operator==(const TextureState &a, const TextureState &b)
{
    return a.mSwizzleState == b.mSwizzleState && a.mSamplerState == b.mSamplerState &&
           a.mBaseLevel == b.mBaseLevel && a.mMaxLevel == b.mMaxLevel &&
           a.mImmutableFormat == b.mImmutableFormat && a.mImmutableLevels == b.mImmutableLevels &&
           a.mUsage == b.mUsage;
}

inline bool operator!=(const TextureState &a, const TextureState &b)
{
    return !(a == b);
}
}  // namespace gl

#endif  // LIBANGLE_TEXTURE_H_
