xref: /aosp_15_r20/external/angle/src/libANGLE/Texture.h (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1 //
2 // Copyright 2002 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 
7 // Texture.h: Defines the gl::Texture class [OpenGL ES 2.0.24] section 3.7 page 63.
8 
9 #ifndef LIBANGLE_TEXTURE_H_
10 #define LIBANGLE_TEXTURE_H_
11 
12 #include <map>
13 #include <vector>
14 
15 #include "angle_gl.h"
16 #include "common/Optional.h"
17 #include "common/debug.h"
18 #include "common/utilities.h"
19 #include "libANGLE/Caps.h"
20 #include "libANGLE/Constants.h"
21 #include "libANGLE/Debug.h"
22 #include "libANGLE/Error.h"
23 #include "libANGLE/FramebufferAttachment.h"
24 #include "libANGLE/Image.h"
25 #include "libANGLE/Observer.h"
26 #include "libANGLE/Stream.h"
27 #include "libANGLE/angletypes.h"
28 #include "libANGLE/formatutils.h"
29 
30 namespace egl
31 {
32 class Surface;
33 class Stream;
34 }  // namespace egl
35 
36 namespace rx
37 {
38 class GLImplFactory;
39 class TextureImpl;
40 class TextureGL;
41 }  // namespace rx
42 
43 namespace gl
44 {
45 class Framebuffer;
46 class MemoryObject;
47 class Sampler;
48 class State;
49 class Texture;
50 
51 constexpr GLuint kInitialMaxLevel = 1000;
52 
53 bool IsMipmapFiltered(GLenum minFilterMode);
54 
55 // Convert a given filter mode to nearest filtering.
56 GLenum ConvertToNearestFilterMode(GLenum filterMode);
57 
58 // Convert a given filter mode to nearest mip filtering.
59 GLenum ConvertToNearestMipFilterMode(GLenum filterMode);
60 
61 struct ImageDesc final
62 {
63     ImageDesc();
64     ImageDesc(const Extents &size, const Format &format, const InitState initState);
65     ImageDesc(const Extents &size,
66               const Format &format,
67               const GLsizei samples,
68               const bool fixedSampleLocations,
69               const InitState initState);
70 
71     ImageDesc(const ImageDesc &other)            = default;
72     ImageDesc &operator=(const ImageDesc &other) = default;
73 
74     GLint getMemorySize() const;
75 
76     Extents size;
77     Format format;
78     GLsizei samples;
79     bool fixedSampleLocations;
80 
81     // Needed for robust resource initialization.
82     InitState initState;
83 };
84 
85 struct SwizzleState final
86 {
87     SwizzleState();
88     SwizzleState(GLenum red, GLenum green, GLenum blue, GLenum alpha);
89     SwizzleState(const SwizzleState &other)            = default;
90     SwizzleState &operator=(const SwizzleState &other) = default;
91 
92     bool swizzleRequired() const;
93 
94     bool operator==(const SwizzleState &other) const;
95     bool operator!=(const SwizzleState &other) const;
96 
97     GLenum swizzleRed;
98     GLenum swizzleGreen;
99     GLenum swizzleBlue;
100     GLenum swizzleAlpha;
101 };
102 
103 // State from Table 6.9 (state per texture object) in the OpenGL ES 3.0.2 spec.
104 class TextureState final : private angle::NonCopyable
105 {
106   public:
107     TextureState(TextureType type);
108     ~TextureState();
109 
110     bool swizzleRequired() const;
111     GLuint getEffectiveBaseLevel() const;
112     GLuint getEffectiveMaxLevel() const;
113 
114     // Returns the value called "q" in the GLES 3.0.4 spec section 3.8.10.
115     GLuint getMipmapMaxLevel() const;
116 
117     // Returns true if base level changed.
118     bool setBaseLevel(GLuint baseLevel);
getBaseLevel()119     GLuint getBaseLevel() const { return mBaseLevel; }
120     bool setMaxLevel(GLuint maxLevel);
getMaxLevel()121     GLuint getMaxLevel() const { return mMaxLevel; }
122 
123     bool isCubeComplete() const;
124 
compatibleWithSamplerFormatForWebGL(SamplerFormat format,const SamplerState & samplerState)125     ANGLE_INLINE bool compatibleWithSamplerFormatForWebGL(SamplerFormat format,
126                                                           const SamplerState &samplerState) const
127     {
128         if (!mCachedSamplerFormatValid ||
129             mCachedSamplerCompareMode != samplerState.getCompareMode())
130         {
131             mCachedSamplerFormat      = computeRequiredSamplerFormat(samplerState);
132             mCachedSamplerCompareMode = samplerState.getCompareMode();
133             mCachedSamplerFormatValid = true;
134         }
135         // Incomplete textures are compatible with any sampler format.
136         return mCachedSamplerFormat == SamplerFormat::InvalidEnum || format == mCachedSamplerFormat;
137     }
138 
139     const ImageDesc &getImageDesc(TextureTarget target, size_t level) const;
140     const ImageDesc &getImageDesc(const ImageIndex &imageIndex) const;
141 
getType()142     TextureType getType() const { return mType; }
getSwizzleState()143     const SwizzleState &getSwizzleState() const { return mSwizzleState; }
getSamplerState()144     const SamplerState &getSamplerState() const { return mSamplerState; }
getUsage()145     GLenum getUsage() const { return mUsage; }
hasProtectedContent()146     bool hasProtectedContent() const { return mHasProtectedContent; }
renderabilityValidation()147     bool renderabilityValidation() const { return mRenderabilityValidation; }
getDepthStencilTextureMode()148     GLenum getDepthStencilTextureMode() const { return mDepthStencilTextureMode; }
149 
hasBeenBoundAsImage()150     bool hasBeenBoundAsImage() const { return mHasBeenBoundAsImage; }
hasBeenBoundAsAttachment()151     bool hasBeenBoundAsAttachment() const { return mHasBeenBoundAsAttachment; }
hasBeenBoundToMSRTTFramebuffer()152     bool hasBeenBoundToMSRTTFramebuffer() const { return mHasBeenBoundToMSRTTFramebuffer; }
153 
getSRGBOverride()154     gl::SrgbOverride getSRGBOverride() const { return mSrgbOverride; }
155 
156     // Returns the desc of the base level. Only valid for cube-complete/mip-complete textures.
157     const ImageDesc &getBaseLevelDesc() const;
158     const ImageDesc &getLevelZeroDesc() const;
159 
160     // This helper is used by backends that require special setup to read stencil data
isStencilMode()161     bool isStencilMode() const
162     {
163         const GLenum format =
164             getImageDesc(getBaseImageTarget(), getEffectiveBaseLevel()).format.info->format;
165         return (format == GL_DEPTH_STENCIL) ? (mDepthStencilTextureMode == GL_STENCIL_INDEX)
166                                             : (format == GL_STENCIL_INDEX);
167     }
168 
169     // GLES1 emulation: For GL_OES_draw_texture
170     void setCrop(const Rectangle &rect);
171     const Rectangle &getCrop() const;
172 
173     // GLES1 emulation: Auto-mipmap generation is a texparameter
174     void setGenerateMipmapHint(GLenum hint);
175     GLenum getGenerateMipmapHint() const;
176 
177     // Return the enabled mipmap level count.
178     GLuint getEnabledLevelCount() const;
179 
getImmutableFormat()180     bool getImmutableFormat() const { return mImmutableFormat; }
getImmutableLevels()181     GLuint getImmutableLevels() const { return mImmutableLevels; }
182 
getImageDescs()183     const std::vector<ImageDesc> &getImageDescs() const { return mImageDescs; }
184 
getInitState()185     InitState getInitState() const { return mInitState; }
186 
getBuffer()187     const OffsetBindingPointer<Buffer> &getBuffer() const { return mBuffer; }
188 
getLabel()189     const std::string &getLabel() const { return mLabel; }
190 
getTilingMode()191     gl::TilingMode getTilingMode() const { return mTilingMode; }
192 
isInternalIncompleteTexture()193     bool isInternalIncompleteTexture() const { return mIsInternalIncompleteTexture; }
194 
getFoveationState()195     const FoveationState &getFoveationState() const { return mFoveationState; }
196 
getSurfaceCompressionFixedRate()197     GLenum getSurfaceCompressionFixedRate() const { return mCompressionFixedRate; }
198 
199   private:
200     // Texture needs access to the ImageDesc functions.
201     friend class Texture;
202     friend bool operator==(const TextureState &a, const TextureState &b);
203 
204     bool computeSamplerCompleteness(const SamplerState &samplerState, const State &state) const;
205     bool computeSamplerCompletenessForCopyImage(const SamplerState &samplerState,
206                                                 const State &state) const;
207 
208     bool computeMipmapCompleteness() const;
209     bool computeLevelCompleteness(TextureTarget target, size_t level) const;
210     SamplerFormat computeRequiredSamplerFormat(const SamplerState &samplerState) const;
211 
212     TextureTarget getBaseImageTarget() const;
213 
214     void setImageDesc(TextureTarget target, size_t level, const ImageDesc &desc);
215     void setImageDescChain(GLuint baselevel,
216                            GLuint maxLevel,
217                            Extents baseSize,
218                            const Format &format,
219                            InitState initState);
220     void setImageDescChainMultisample(Extents baseSize,
221                                       const Format &format,
222                                       GLsizei samples,
223                                       bool fixedSampleLocations,
224                                       InitState initState);
225 
226     void clearImageDesc(TextureTarget target, size_t level);
227     void clearImageDescs();
228 
229     const TextureType mType;
230 
231     SwizzleState mSwizzleState;
232 
233     SamplerState mSamplerState;
234 
235     SrgbOverride mSrgbOverride;
236 
237     GLuint mBaseLevel;
238     GLuint mMaxLevel;
239 
240     GLenum mDepthStencilTextureMode;
241 
242     // Distinguish internally created textures.  The Vulkan backend avoids initializing them from an
243     // unlocked tail call because they are lazily created on draw, and we don't want to add the
244     // overhead of tail-call checks to draw calls.
245     bool mIsInternalIncompleteTexture;
246 
247     bool mHasBeenBoundAsImage;
248     bool mHasBeenBoundAsAttachment;
249     bool mHasBeenBoundToMSRTTFramebuffer;
250 
251     bool mImmutableFormat;
252     GLuint mImmutableLevels;
253 
254     // From GL_ANGLE_texture_usage
255     GLenum mUsage;
256 
257     // GL_EXT_protected_textures
258     bool mHasProtectedContent;
259 
260     bool mRenderabilityValidation;
261 
262     // GL_EXT_memory_object
263     gl::TilingMode mTilingMode;
264 
265     std::vector<ImageDesc> mImageDescs;
266 
267     // GLES1 emulation: Texture crop rectangle
268     // For GL_OES_draw_texture
269     Rectangle mCropRect;
270 
271     // GLES1 emulation: Generate-mipmap hint per texture
272     GLenum mGenerateMipmapHint;
273 
274     // GL_OES_texture_buffer / GLES3.2
275     OffsetBindingPointer<Buffer> mBuffer;
276 
277     InitState mInitState;
278 
279     mutable SamplerFormat mCachedSamplerFormat;
280     mutable GLenum mCachedSamplerCompareMode;
281     mutable bool mCachedSamplerFormatValid;
282     std::string mLabel;
283 
284     // GL_QCOM_texture_foveated
285     FoveationState mFoveationState;
286 
287     // GL_EXT_texture_storage_compression
288     GLenum mCompressionFixedRate;
289 };
290 
291 bool operator==(const TextureState &a, const TextureState &b);
292 bool operator!=(const TextureState &a, const TextureState &b);
293 
294 class TextureBufferContentsObservers final : angle::NonCopyable
295 {
296   public:
297     TextureBufferContentsObservers(Texture *texture);
298     void enableForBuffer(Buffer *buffer);
299     void disableForBuffer(Buffer *buffer);
300     bool isEnabledForBuffer(Buffer *buffer);
301 
302   private:
303     Texture *mTexture;
304 };
305 
306 class Texture final : public RefCountObject<TextureID>,
307                       public egl::ImageSibling,
308                       public LabeledObject
309 {
310   public:
311     Texture(rx::GLImplFactory *factory, TextureID id, TextureType type);
312     ~Texture() override;
313 
314     void onDestroy(const Context *context) override;
315 
316     angle::Result setLabel(const Context *context, const std::string &label) override;
317 
318     const std::string &getLabel() const override;
319 
getType()320     TextureType getType() const { return mState.mType; }
321 
322     void setSwizzleRed(const Context *context, GLenum swizzleRed);
323     GLenum getSwizzleRed() const;
324 
325     void setSwizzleGreen(const Context *context, GLenum swizzleGreen);
326     GLenum getSwizzleGreen() const;
327 
328     void setSwizzleBlue(const Context *context, GLenum swizzleBlue);
329     GLenum getSwizzleBlue() const;
330 
331     void setSwizzleAlpha(const Context *context, GLenum swizzleAlpha);
332     GLenum getSwizzleAlpha() const;
333 
334     void setMinFilter(const Context *context, GLenum minFilter);
335     GLenum getMinFilter() const;
336 
337     void setMagFilter(const Context *context, GLenum magFilter);
338     GLenum getMagFilter() const;
339 
340     void setWrapS(const Context *context, GLenum wrapS);
341     GLenum getWrapS() const;
342 
343     void setWrapT(const Context *context, GLenum wrapT);
344     GLenum getWrapT() const;
345 
346     void setWrapR(const Context *context, GLenum wrapR);
347     GLenum getWrapR() const;
348 
349     void setMaxAnisotropy(const Context *context, float maxAnisotropy);
350     float getMaxAnisotropy() const;
351 
352     void setMinLod(const Context *context, GLfloat minLod);
353     GLfloat getMinLod() const;
354 
355     void setMaxLod(const Context *context, GLfloat maxLod);
356     GLfloat getMaxLod() const;
357 
358     void setCompareMode(const Context *context, GLenum compareMode);
359     GLenum getCompareMode() const;
360 
361     void setCompareFunc(const Context *context, GLenum compareFunc);
362     GLenum getCompareFunc() const;
363 
364     void setSRGBDecode(const Context *context, GLenum sRGBDecode);
365     GLenum getSRGBDecode() const;
366 
367     void setSRGBOverride(const Context *context, GLenum sRGBOverride);
368     GLenum getSRGBOverride() const;
369 
370     const SamplerState &getSamplerState() const;
371 
372     angle::Result setBaseLevel(const Context *context, GLuint baseLevel);
373     GLuint getBaseLevel() const;
374 
375     void setMaxLevel(const Context *context, GLuint maxLevel);
376     GLuint getMaxLevel() const;
377 
378     void setDepthStencilTextureMode(const Context *context, GLenum mode);
379     GLenum getDepthStencilTextureMode() const;
380 
381     bool getImmutableFormat() const;
382 
383     GLuint getImmutableLevels() const;
384 
385     void setUsage(const Context *context, GLenum usage);
386     GLenum getUsage() const;
387 
388     void setProtectedContent(Context *context, bool hasProtectedContent);
389     bool hasProtectedContent() const override;
hasFoveatedRendering()390     bool hasFoveatedRendering() const override { return isFoveationEnabled(); }
getFoveationState()391     const gl::FoveationState *getFoveationState() const override { return &mState.mFoveationState; }
392 
393     void setRenderabilityValidation(Context *context, bool renderabilityValidation);
394 
395     void setTilingMode(Context *context, GLenum tilingMode);
396     GLenum getTilingMode() const;
397 
getState()398     const TextureState &getState() const { return mState; }
399 
400     void setBorderColor(const Context *context, const ColorGeneric &color);
401     const ColorGeneric &getBorderColor() const;
402 
403     angle::Result setBuffer(const Context *context, gl::Buffer *buffer, GLenum internalFormat);
404     angle::Result setBufferRange(const Context *context,
405                                  gl::Buffer *buffer,
406                                  GLenum internalFormat,
407                                  GLintptr offset,
408                                  GLsizeiptr size);
409     const OffsetBindingPointer<Buffer> &getBuffer() const;
410 
411     GLint getRequiredTextureImageUnits(const Context *context) const;
412 
413     const TextureState &getTextureState() const;
414 
415     const Extents &getExtents(TextureTarget target, size_t level) const;
416     size_t getWidth(TextureTarget target, size_t level) const;
417     size_t getHeight(TextureTarget target, size_t level) const;
418     size_t getDepth(TextureTarget target, size_t level) const;
419     GLsizei getSamples(TextureTarget target, size_t level) const;
420     bool getFixedSampleLocations(TextureTarget target, size_t level) const;
421     const Format &getFormat(TextureTarget target, size_t level) const;
422 
423     // Returns the value called "q" in the GLES 3.0.4 spec section 3.8.10.
424     GLuint getMipmapMaxLevel() const;
425 
426     bool isMipmapComplete() const;
427 
428     void setFoveatedFeatureBits(const GLuint features);
429     GLuint getFoveatedFeatureBits() const;
430     bool isFoveationEnabled() const;
431     GLuint getSupportedFoveationFeatures() const;
432 
getNumFocalPoints()433     GLuint getNumFocalPoints() const { return mState.mFoveationState.getMaxNumFocalPoints(); }
434     void setMinPixelDensity(const GLfloat density);
435     GLfloat getMinPixelDensity() const;
436     void setFocalPoint(uint32_t layer,
437                        uint32_t focalPointIndex,
438                        float focalX,
439                        float focalY,
440                        float gainX,
441                        float gainY,
442                        float foveaArea);
443     const FocalPoint &getFocalPoint(uint32_t layer, uint32_t focalPoint) const;
444 
445     GLint getImageCompressionRate(const Context *context) const;
446     GLint getFormatSupportedCompressionRates(const Context *context,
447                                              GLenum internalformat,
448                                              GLsizei bufSize,
449                                              GLint *rates) const;
450 
451     angle::Result setImage(Context *context,
452                            const PixelUnpackState &unpackState,
453                            Buffer *unpackBuffer,
454                            TextureTarget target,
455                            GLint level,
456                            GLenum internalFormat,
457                            const Extents &size,
458                            GLenum format,
459                            GLenum type,
460                            const uint8_t *pixels);
461     angle::Result setSubImage(Context *context,
462                               const PixelUnpackState &unpackState,
463                               Buffer *unpackBuffer,
464                               TextureTarget target,
465                               GLint level,
466                               const Box &area,
467                               GLenum format,
468                               GLenum type,
469                               const uint8_t *pixels);
470 
471     angle::Result setCompressedImage(Context *context,
472                                      const PixelUnpackState &unpackState,
473                                      TextureTarget target,
474                                      GLint level,
475                                      GLenum internalFormat,
476                                      const Extents &size,
477                                      size_t imageSize,
478                                      const uint8_t *pixels);
479     angle::Result setCompressedSubImage(const Context *context,
480                                         const PixelUnpackState &unpackState,
481                                         TextureTarget target,
482                                         GLint level,
483                                         const Box &area,
484                                         GLenum format,
485                                         size_t imageSize,
486                                         const uint8_t *pixels);
487 
488     angle::Result copyImage(Context *context,
489                             TextureTarget target,
490                             GLint level,
491                             const Rectangle &sourceArea,
492                             GLenum internalFormat,
493                             Framebuffer *source);
494     angle::Result copySubImage(Context *context,
495                                const ImageIndex &index,
496                                const Offset &destOffset,
497                                const Rectangle &sourceArea,
498                                Framebuffer *source);
499 
500     angle::Result copyRenderbufferSubData(Context *context,
501                                           const gl::Renderbuffer *srcBuffer,
502                                           GLint srcLevel,
503                                           GLint srcX,
504                                           GLint srcY,
505                                           GLint srcZ,
506                                           GLint dstLevel,
507                                           GLint dstX,
508                                           GLint dstY,
509                                           GLint dstZ,
510                                           GLsizei srcWidth,
511                                           GLsizei srcHeight,
512                                           GLsizei srcDepth);
513 
514     angle::Result copyTextureSubData(Context *context,
515                                      const gl::Texture *srcTexture,
516                                      GLint srcLevel,
517                                      GLint srcX,
518                                      GLint srcY,
519                                      GLint srcZ,
520                                      GLint dstLevel,
521                                      GLint dstX,
522                                      GLint dstY,
523                                      GLint dstZ,
524                                      GLsizei srcWidth,
525                                      GLsizei srcHeight,
526                                      GLsizei srcDepth);
527 
528     angle::Result copyTexture(Context *context,
529                               TextureTarget target,
530                               GLint level,
531                               GLenum internalFormat,
532                               GLenum type,
533                               GLint sourceLevel,
534                               bool unpackFlipY,
535                               bool unpackPremultiplyAlpha,
536                               bool unpackUnmultiplyAlpha,
537                               Texture *source);
538     angle::Result copySubTexture(const Context *context,
539                                  TextureTarget target,
540                                  GLint level,
541                                  const Offset &destOffset,
542                                  GLint sourceLevel,
543                                  const Box &sourceBox,
544                                  bool unpackFlipY,
545                                  bool unpackPremultiplyAlpha,
546                                  bool unpackUnmultiplyAlpha,
547                                  Texture *source);
548     angle::Result copyCompressedTexture(Context *context, const Texture *source);
549 
550     angle::Result setStorage(Context *context,
551                              TextureType type,
552                              GLsizei levels,
553                              GLenum internalFormat,
554                              const Extents &size);
555 
556     angle::Result setStorageMultisample(Context *context,
557                                         TextureType type,
558                                         GLsizei samplesIn,
559                                         GLint internalformat,
560                                         const Extents &size,
561                                         bool fixedSampleLocations);
562 
563     angle::Result setStorageExternalMemory(Context *context,
564                                            TextureType type,
565                                            GLsizei levels,
566                                            GLenum internalFormat,
567                                            const Extents &size,
568                                            MemoryObject *memoryObject,
569                                            GLuint64 offset,
570                                            GLbitfield createFlags,
571                                            GLbitfield usageFlags,
572                                            const void *imageCreateInfoPNext);
573 
574     angle::Result setImageExternal(Context *context,
575                                    TextureTarget target,
576                                    GLint level,
577                                    GLenum internalFormat,
578                                    const Extents &size,
579                                    GLenum format,
580                                    GLenum type);
581 
582     angle::Result setEGLImageTarget(Context *context, TextureType type, egl::Image *imageTarget);
583 
584     angle::Result setStorageEGLImageTarget(Context *context,
585                                            TextureType type,
586                                            egl::Image *image,
587                                            const GLint *attrib_list);
588 
589     angle::Result setStorageAttribs(Context *context,
590                                     TextureType type,
591                                     GLsizei levels,
592                                     GLenum internalFormat,
593                                     const Extents &size,
594                                     const GLint *attribList);
595 
596     angle::Result generateMipmap(Context *context);
597 
598     angle::Result clearImage(Context *context,
599                              GLint level,
600                              GLenum format,
601                              GLenum type,
602                              const uint8_t *data);
603     angle::Result clearSubImage(Context *context,
604                                 GLint level,
605                                 const Box &area,
606                                 GLenum format,
607                                 GLenum type,
608                                 const uint8_t *data);
609 
610     void onBindAsImageTexture();
611 
612     egl::Surface *getBoundSurface() const;
613     egl::Stream *getBoundStream() const;
614 
615     GLint getMemorySize() const;
616     GLint getLevelMemorySize(TextureTarget target, GLint level) const;
617 
618     void signalDirtyStorage(InitState initState);
619 
620     bool isSamplerComplete(const Context *context, const Sampler *optionalSampler);
621     bool isSamplerCompleteForCopyImage(const Context *context,
622                                        const Sampler *optionalSampler) const;
623 
624     GLenum getImplementationColorReadFormat(const Context *context) const;
625     GLenum getImplementationColorReadType(const Context *context) const;
626 
627     // We pass the pack buffer and state explicitly so they can be overridden during capture.
628     angle::Result getTexImage(const Context *context,
629                               const PixelPackState &packState,
630                               Buffer *packBuffer,
631                               TextureTarget target,
632                               GLint level,
633                               GLenum format,
634                               GLenum type,
635                               void *pixels);
636 
637     angle::Result getCompressedTexImage(const Context *context,
638                                         const PixelPackState &packState,
639                                         Buffer *packBuffer,
640                                         TextureTarget target,
641                                         GLint level,
642                                         void *pixels);
643 
getImplementation()644     rx::TextureImpl *getImplementation() const { return mTexture; }
645 
646     // FramebufferAttachmentObject implementation
647     Extents getAttachmentSize(const ImageIndex &imageIndex) const override;
648     Format getAttachmentFormat(GLenum binding, const ImageIndex &imageIndex) const override;
649     GLsizei getAttachmentSamples(const ImageIndex &imageIndex) const override;
650     bool isRenderable(const Context *context,
651                       GLenum binding,
652                       const ImageIndex &imageIndex) const override;
653 
654     bool getAttachmentFixedSampleLocations(const ImageIndex &imageIndex) const;
655 
656     // GLES1 emulation
657     void setCrop(const Rectangle &rect);
658     const Rectangle &getCrop() const;
659     void setGenerateMipmapHint(GLenum generate);
660     GLenum getGenerateMipmapHint() const;
661 
662     void onAttach(const Context *context, rx::UniqueSerial framebufferSerial) override;
663     void onDetach(const Context *context, rx::UniqueSerial framebufferSerial) override;
664 
665     // Used specifically for FramebufferAttachmentObject.
666     GLuint getId() const override;
667 
668     GLuint getNativeID() const;
669 
670     // Needed for robust resource init.
671     angle::Result ensureInitialized(const Context *context);
672     InitState initState(GLenum binding, const ImageIndex &imageIndex) const override;
initState()673     InitState initState() const { return mState.mInitState; }
674     void setInitState(GLenum binding, const ImageIndex &imageIndex, InitState initState) override;
675     void setInitState(InitState initState);
676 
isBoundToFramebuffer(rx::UniqueSerial framebufferSerial)677     bool isBoundToFramebuffer(rx::UniqueSerial framebufferSerial) const
678     {
679         for (size_t index = 0; index < mBoundFramebufferSerials.size(); ++index)
680         {
681             if (mBoundFramebufferSerials[index] == framebufferSerial)
682                 return true;
683         }
684 
685         return false;
686     }
687 
isDepthOrStencil()688     bool isDepthOrStencil() const
689     {
690         return mState.getBaseLevelDesc().format.info->isDepthOrStencil();
691     }
692 
693     enum DirtyBitType
694     {
695         // Sampler state
696         DIRTY_BIT_MIN_FILTER,
697         DIRTY_BIT_MAG_FILTER,
698         DIRTY_BIT_WRAP_S,
699         DIRTY_BIT_WRAP_T,
700         DIRTY_BIT_WRAP_R,
701         DIRTY_BIT_MAX_ANISOTROPY,
702         DIRTY_BIT_MIN_LOD,
703         DIRTY_BIT_MAX_LOD,
704         DIRTY_BIT_COMPARE_MODE,
705         DIRTY_BIT_COMPARE_FUNC,
706         DIRTY_BIT_SRGB_DECODE,
707         DIRTY_BIT_SRGB_OVERRIDE,
708         DIRTY_BIT_BORDER_COLOR,
709 
710         // Texture state
711         DIRTY_BIT_SWIZZLE_RED,
712         DIRTY_BIT_SWIZZLE_GREEN,
713         DIRTY_BIT_SWIZZLE_BLUE,
714         DIRTY_BIT_SWIZZLE_ALPHA,
715         DIRTY_BIT_BASE_LEVEL,
716         DIRTY_BIT_MAX_LEVEL,
717         DIRTY_BIT_DEPTH_STENCIL_TEXTURE_MODE,
718         DIRTY_BIT_RENDERABILITY_VALIDATION_ANGLE,
719 
720         // Image state
721         DIRTY_BIT_BOUND_AS_IMAGE,
722         DIRTY_BIT_BOUND_AS_ATTACHMENT,
723 
724         // Bound to MSRTT Framebuffer
725         DIRTY_BIT_BOUND_TO_MSRTT_FRAMEBUFFER,
726 
727         // Misc
728         DIRTY_BIT_USAGE,
729         DIRTY_BIT_IMPLEMENTATION,
730 
731         DIRTY_BIT_COUNT,
732     };
733     using DirtyBits = angle::BitSet<DIRTY_BIT_COUNT>;
734 
735     angle::Result syncState(const Context *context, Command source);
hasAnyDirtyBit()736     bool hasAnyDirtyBit() const { return mDirtyBits.any(); }
hasAnyDirtyBitExcludingBoundAsAttachmentBit()737     bool hasAnyDirtyBitExcludingBoundAsAttachmentBit() const
738     {
739         static constexpr DirtyBits kBoundAsAttachment = DirtyBits({DIRTY_BIT_BOUND_AS_ATTACHMENT});
740         return mDirtyBits.any() && mDirtyBits != kBoundAsAttachment;
741     }
742 
743     // ObserverInterface implementation.
744     void onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message) override;
745 
746     // Texture buffer updates.
747     void onBufferContentsChange();
748 
markInternalIncompleteTexture()749     void markInternalIncompleteTexture() { mState.mIsInternalIncompleteTexture = true; }
750 
751     // Texture bound to MSRTT framebuffer.
752     void onBindToMSRTTFramebuffer();
753 
754   private:
755     rx::FramebufferAttachmentObjectImpl *getAttachmentImpl() const override;
756 
757     // ANGLE-only method, used internally
758     friend class egl::Surface;
759     angle::Result bindTexImageFromSurface(Context *context, egl::Surface *surface);
760     angle::Result releaseTexImageFromSurface(const Context *context);
761 
762     // ANGLE-only methods, used internally
763     friend class egl::Stream;
764     void bindStream(egl::Stream *stream);
765     void releaseStream();
766     angle::Result acquireImageFromStream(const Context *context,
767                                          const egl::Stream::GLTextureDescription &desc);
768     angle::Result releaseImageFromStream(const Context *context);
769 
770     void invalidateCompletenessCache() const;
771     angle::Result releaseTexImageInternal(Context *context);
772 
773     bool doesSubImageNeedInit(const Context *context,
774                               const ImageIndex &imageIndex,
775                               const Box &area) const;
776     angle::Result ensureSubImageInitialized(const Context *context,
777                                             const ImageIndex &imageIndex,
778                                             const Box &area);
779 
780     angle::Result handleMipmapGenerationHint(Context *context, int level);
781 
782     angle::Result setEGLImageTargetImpl(Context *context,
783                                         TextureType type,
784                                         GLuint levels,
785                                         egl::Image *imageTarget);
786 
787     void signalDirtyState(size_t dirtyBit);
788 
789     TextureState mState;
790     DirtyBits mDirtyBits;
791     rx::TextureImpl *mTexture;
792     angle::ObserverBinding mImplObserver;
793     // For EXT_texture_buffer, observes buffer changes.
794     angle::ObserverBinding mBufferObserver;
795 
796     egl::Surface *mBoundSurface;
797     egl::Stream *mBoundStream;
798 
799     // We track all the serials of the Framebuffers this texture is attached to. Note that this
800     // allows duplicates because different ranges of a Texture can be bound to the same Framebuffer.
801     // For the purposes of depth-stencil loops, a simple "isBound" check works fine. For color
802     // attachment Feedback Loop checks we then need to check further to see when a Texture is bound
803     // to mulitple bindings that the bindings don't overlap.
804     static constexpr uint32_t kFastFramebufferSerialCount = 8;
805     angle::FastVector<rx::UniqueSerial, kFastFramebufferSerialCount> mBoundFramebufferSerials;
806 
807     struct SamplerCompletenessCache
808     {
809         SamplerCompletenessCache();
810 
811         // Context used to generate this cache entry
812         ContextID context;
813 
814         // All values that affect sampler completeness that are not stored within
815         // the texture itself
816         SamplerState samplerState;
817 
818         // Result of the sampler completeness with the above parameters
819         bool samplerComplete;
820     };
821 
822     mutable SamplerCompletenessCache mCompletenessCache;
823     TextureBufferContentsObservers mBufferContentsObservers;
824 };
825 
826 inline bool operator==(const TextureState &a, const TextureState &b)
827 {
828     return a.mSwizzleState == b.mSwizzleState && a.mSamplerState == b.mSamplerState &&
829            a.mBaseLevel == b.mBaseLevel && a.mMaxLevel == b.mMaxLevel &&
830            a.mImmutableFormat == b.mImmutableFormat && a.mImmutableLevels == b.mImmutableLevels &&
831            a.mUsage == b.mUsage;
832 }
833 
834 inline bool operator!=(const TextureState &a, const TextureState &b)
835 {
836     return !(a == b);
837 }
838 }  // namespace gl
839 
840 #endif  // LIBANGLE_TEXTURE_H_
841