| // | |
| // 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; | |
| enum class EnsureInitializedLevels | |
| { | |
| BaseOnly, | |
| AllEnabledLevels, | |
| }; | |
| 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; | |
| // Used by validation, returns the number of possible mip levels for this texture type based on | |
| // level 0's definition. | |
| GLuint getMaxPossibleMipmapLevelsFromLevelZero() 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; | |
| GLuint getCompatibleLevelCount(GLuint baseLevel, | |
| GLuint maxLevel, | |
| bool *anyIncompatibleLevelOut) const; | |
| bool getImmutableFormat() const { return mImmutableFormat; } | |
| GLuint getImmutableLevels() const { return mImmutableLevels; } | |
| bool anyLevelsDefinedAtOrAbove(GLuint level, GLuint maxLevel) const; | |
| bool isCompatibleWithLevelZero(GLint level, | |
| GLsizei width, | |
| GLsizei height, | |
| GLsizei depth, | |
| const InternalFormat &format) const; | |
| 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; | |
| } | |
| OwnerImageIndex toOwnerIndex(const ImageIndex &index) const | |
| { | |
| return mEGLImageSourceAttributes.toOwnerIndex(index); | |
| } | |
| OwnerLevel toOwnerLevel(LevelIndex level) const | |
| { | |
| return mEGLImageSourceAttributes.toOwnerLevel(level); | |
| } | |
| OwnerLayer toOwnerLayer(LayerIndex layer) const | |
| { | |
| return mEGLImageSourceAttributes.toOwnerLayer(layer); | |
| } | |
| OwnerLayer toOwnerDepth(const Offset &offset) const | |
| { | |
| return mEGLImageSourceAttributes.toOwnerDepth(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, EnsureInitializedLevels levels); | |
| 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 OwnerImageIndex &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_ |