//
// Copyright (c) 2002-2013 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/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;

bool IsMipmapFiltered(const SamplerState &samplerState);

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);
    bool setMaxLevel(GLuint maxLevel);

    bool isCubeComplete() const;

    ANGLE_INLINE bool compatibleWithSamplerFormat(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; }
    GLenum getDepthStencilTextureMode() const { return mDepthStencilTextureMode; }

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

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

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

  private:
    // Texture needs access to the ImageDesc functions.
    friend class Texture;
    // TODO(jmadill): Remove TextureGL from friends.
    friend class rx::TextureGL;
    friend bool operator==(const TextureState &a, const TextureState &b);

    bool computeSamplerCompleteness(const SamplerState &samplerState, const State &data) 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;

    GLuint mBaseLevel;
    GLuint mMaxLevel;

    GLenum mDepthStencilTextureMode;

    bool mImmutableFormat;
    GLuint mImmutableLevels;

    // From GL_ANGLE_texture_usage
    GLenum mUsage;

    std::vector<ImageDesc> mImageDescs;

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

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

    InitState mInitState;

    mutable SamplerFormat mCachedSamplerFormat;
    mutable GLenum mCachedSamplerCompareMode;
    mutable bool mCachedSamplerFormatValid;
};

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

class Texture final : public RefCountObject,
                      public egl::ImageSibling,
                      public LabeledObject,
                      public angle::ObserverInterface
{
  public:
    Texture(rx::GLImplFactory *factory, GLuint id, TextureType type);
    ~Texture() override;

    void onDestroy(const Context *context) override;

    void 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 setCompareMode(const Context *context, GLenum compareMode);
    GLenum getCompareMode() const;

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

    void setSRGBDecode(const Context *context, GLenum sRGBDecode);
    GLenum getSRGBDecode() 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 setBorderColor(const Context *context, const ColorGeneric &color);
    const ColorGeneric &getBorderColor() const;

    const TextureState &getTextureState() 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;

    angle::Result setImage(Context *context,
                           const PixelUnpackState &unpackState,
                           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 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 samples,
                                        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);

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

    angle::Result generateMipmap(Context *context);

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

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

    void signalDirtyStorage(const Context *context, InitState initState);

    bool isSamplerComplete(const Context *context, const Sampler *optionalSampler);

    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 gl::Rectangle &rect);
    const gl::Rectangle &getCrop() const;
    void setGenerateMipmapHint(GLenum generate);
    GLenum getGenerateMipmapHint() const;

    void onAttach(const Context *context) override;
    void onDetach(const Context *context) override;
    GLuint getId() const override;

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

    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_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,

        // Misc
        DIRTY_BIT_LABEL,
        DIRTY_BIT_USAGE,
        DIRTY_BIT_IMPLEMENTATION,

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

    angle::Result syncState(const Context *context);
    bool hasAnyDirtyBit() const { return mDirtyBits.any(); }

    // ObserverInterface implementation.
    void onSubjectStateChange(const gl::Context *context,
                              angle::SubjectIndex index,
                              angle::SubjectMessage message) override;

  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;
    angle::Result releaseTexImageInternal(Context *context);

    angle::Result ensureSubImageInitialized(const Context *context,
                                            TextureTarget target,
                                            size_t level,
                                            const gl::Box &area);

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

    void signalDirtyState(const Context *context, size_t dirtyBit);

    TextureState mState;
    DirtyBits mDirtyBits;
    rx::TextureImpl *mTexture;
    angle::ObserverBinding mImplObserver;

    std::string mLabel;

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

    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;
};

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_
