• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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; }
getDepthStencilTextureMode()147     GLenum getDepthStencilTextureMode() const { return mDepthStencilTextureMode; }
isStencilMode()148     bool isStencilMode() const { return mDepthStencilTextureMode == GL_STENCIL_INDEX; }
149 
hasBeenBoundAsImage()150     bool hasBeenBoundAsImage() const { return mHasBeenBoundAsImage; }
hasBeenBoundAsAttachment()151     bool hasBeenBoundAsAttachment() const { return mHasBeenBoundAsAttachment; }
152 
getSRGBOverride()153     gl::SrgbOverride getSRGBOverride() const { return mSrgbOverride; }
154 
155     // Returns the desc of the base level. Only valid for cube-complete/mip-complete textures.
156     const ImageDesc &getBaseLevelDesc() const;
157     const ImageDesc &getLevelZeroDesc() const;
158 
159     // GLES1 emulation: For GL_OES_draw_texture
160     void setCrop(const Rectangle &rect);
161     const Rectangle &getCrop() const;
162 
163     // GLES1 emulation: Auto-mipmap generation is a texparameter
164     void setGenerateMipmapHint(GLenum hint);
165     GLenum getGenerateMipmapHint() const;
166 
167     // Return the enabled mipmap level count.
168     GLuint getEnabledLevelCount() const;
169 
getImmutableFormat()170     bool getImmutableFormat() const { return mImmutableFormat; }
getImmutableLevels()171     GLuint getImmutableLevels() const { return mImmutableLevels; }
172 
getImageDescs()173     const std::vector<ImageDesc> &getImageDescs() const { return mImageDescs; }
174 
getInitState()175     InitState getInitState() const { return mInitState; }
176 
getBuffer()177     const OffsetBindingPointer<Buffer> &getBuffer() const { return mBuffer; }
178 
getLabel()179     const std::string &getLabel() const { return mLabel; }
180 
181   private:
182     // Texture needs access to the ImageDesc functions.
183     friend class Texture;
184     friend bool operator==(const TextureState &a, const TextureState &b);
185 
186     bool computeSamplerCompleteness(const SamplerState &samplerState, const State &state) const;
187     bool computeMipmapCompleteness() const;
188     bool computeLevelCompleteness(TextureTarget target, size_t level) const;
189     SamplerFormat computeRequiredSamplerFormat(const SamplerState &samplerState) const;
190 
191     TextureTarget getBaseImageTarget() const;
192 
193     void setImageDesc(TextureTarget target, size_t level, const ImageDesc &desc);
194     void setImageDescChain(GLuint baselevel,
195                            GLuint maxLevel,
196                            Extents baseSize,
197                            const Format &format,
198                            InitState initState);
199     void setImageDescChainMultisample(Extents baseSize,
200                                       const Format &format,
201                                       GLsizei samples,
202                                       bool fixedSampleLocations,
203                                       InitState initState);
204 
205     void clearImageDesc(TextureTarget target, size_t level);
206     void clearImageDescs();
207 
208     const TextureType mType;
209 
210     SwizzleState mSwizzleState;
211 
212     SamplerState mSamplerState;
213 
214     SrgbOverride mSrgbOverride;
215 
216     GLuint mBaseLevel;
217     GLuint mMaxLevel;
218 
219     GLenum mDepthStencilTextureMode;
220 
221     bool mHasBeenBoundAsImage;
222     bool mHasBeenBoundAsAttachment;
223 
224     bool mImmutableFormat;
225     GLuint mImmutableLevels;
226 
227     // From GL_ANGLE_texture_usage
228     GLenum mUsage;
229 
230     // GL_EXT_protected_textures
231     bool mHasProtectedContent;
232 
233     std::vector<ImageDesc> mImageDescs;
234 
235     // GLES1 emulation: Texture crop rectangle
236     // For GL_OES_draw_texture
237     Rectangle mCropRect;
238 
239     // GLES1 emulation: Generate-mipmap hint per texture
240     GLenum mGenerateMipmapHint;
241 
242     // GL_OES_texture_buffer / GLES3.2
243     OffsetBindingPointer<Buffer> mBuffer;
244 
245     InitState mInitState;
246 
247     mutable SamplerFormat mCachedSamplerFormat;
248     mutable GLenum mCachedSamplerCompareMode;
249     mutable bool mCachedSamplerFormatValid;
250     std::string mLabel;
251 };
252 
253 bool operator==(const TextureState &a, const TextureState &b);
254 bool operator!=(const TextureState &a, const TextureState &b);
255 
256 class Texture final : public RefCountObject<TextureID>,
257                       public egl::ImageSibling,
258                       public LabeledObject
259 {
260   public:
261     Texture(rx::GLImplFactory *factory, TextureID id, TextureType type);
262     ~Texture() override;
263 
264     void onDestroy(const Context *context) override;
265 
266     void setLabel(const Context *context, const std::string &label) override;
267     const std::string &getLabel() const override;
268 
getType()269     TextureType getType() const { return mState.mType; }
270 
271     void setSwizzleRed(const Context *context, GLenum swizzleRed);
272     GLenum getSwizzleRed() const;
273 
274     void setSwizzleGreen(const Context *context, GLenum swizzleGreen);
275     GLenum getSwizzleGreen() const;
276 
277     void setSwizzleBlue(const Context *context, GLenum swizzleBlue);
278     GLenum getSwizzleBlue() const;
279 
280     void setSwizzleAlpha(const Context *context, GLenum swizzleAlpha);
281     GLenum getSwizzleAlpha() const;
282 
283     void setMinFilter(const Context *context, GLenum minFilter);
284     GLenum getMinFilter() const;
285 
286     void setMagFilter(const Context *context, GLenum magFilter);
287     GLenum getMagFilter() const;
288 
289     void setWrapS(const Context *context, GLenum wrapS);
290     GLenum getWrapS() const;
291 
292     void setWrapT(const Context *context, GLenum wrapT);
293     GLenum getWrapT() const;
294 
295     void setWrapR(const Context *context, GLenum wrapR);
296     GLenum getWrapR() const;
297 
298     void setMaxAnisotropy(const Context *context, float maxAnisotropy);
299     float getMaxAnisotropy() const;
300 
301     void setMinLod(const Context *context, GLfloat minLod);
302     GLfloat getMinLod() const;
303 
304     void setMaxLod(const Context *context, GLfloat maxLod);
305     GLfloat getMaxLod() const;
306 
307     void setCompareMode(const Context *context, GLenum compareMode);
308     GLenum getCompareMode() const;
309 
310     void setCompareFunc(const Context *context, GLenum compareFunc);
311     GLenum getCompareFunc() const;
312 
313     void setSRGBDecode(const Context *context, GLenum sRGBDecode);
314     GLenum getSRGBDecode() const;
315 
316     void setSRGBOverride(const Context *context, GLenum sRGBOverride);
317     GLenum getSRGBOverride() const;
318 
319     const SamplerState &getSamplerState() const;
320 
321     angle::Result setBaseLevel(const Context *context, GLuint baseLevel);
322     GLuint getBaseLevel() const;
323 
324     void setMaxLevel(const Context *context, GLuint maxLevel);
325     GLuint getMaxLevel() const;
326 
327     void setDepthStencilTextureMode(const Context *context, GLenum mode);
328     GLenum getDepthStencilTextureMode() const;
329 
330     bool getImmutableFormat() const;
331 
332     GLuint getImmutableLevels() const;
333 
334     void setUsage(const Context *context, GLenum usage);
335     GLenum getUsage() const;
336 
337     void setProtectedContent(Context *context, bool hasProtectedContent);
338     bool hasProtectedContent() const override;
339 
getState()340     const TextureState &getState() const { return mState; }
341 
342     void setBorderColor(const Context *context, const ColorGeneric &color);
343     const ColorGeneric &getBorderColor() const;
344 
345     angle::Result setBuffer(const Context *context, gl::Buffer *buffer, GLenum internalFormat);
346     angle::Result setBufferRange(const Context *context,
347                                  gl::Buffer *buffer,
348                                  GLenum internalFormat,
349                                  GLintptr offset,
350                                  GLsizeiptr size);
351     const OffsetBindingPointer<Buffer> &getBuffer() const;
352 
353     GLint getRequiredTextureImageUnits(const Context *context) const;
354 
355     const TextureState &getTextureState() const;
356 
357     const Extents &getExtents(TextureTarget target, size_t level) const;
358     size_t getWidth(TextureTarget target, size_t level) const;
359     size_t getHeight(TextureTarget target, size_t level) const;
360     size_t getDepth(TextureTarget target, size_t level) const;
361     GLsizei getSamples(TextureTarget target, size_t level) const;
362     bool getFixedSampleLocations(TextureTarget target, size_t level) const;
363     const Format &getFormat(TextureTarget target, size_t level) const;
364 
365     // Returns the value called "q" in the GLES 3.0.4 spec section 3.8.10.
366     GLuint getMipmapMaxLevel() const;
367 
368     bool isMipmapComplete() const;
369 
370     angle::Result setImage(Context *context,
371                            const PixelUnpackState &unpackState,
372                            Buffer *unpackBuffer,
373                            TextureTarget target,
374                            GLint level,
375                            GLenum internalFormat,
376                            const Extents &size,
377                            GLenum format,
378                            GLenum type,
379                            const uint8_t *pixels);
380     angle::Result setSubImage(Context *context,
381                               const PixelUnpackState &unpackState,
382                               Buffer *unpackBuffer,
383                               TextureTarget target,
384                               GLint level,
385                               const Box &area,
386                               GLenum format,
387                               GLenum type,
388                               const uint8_t *pixels);
389 
390     angle::Result setCompressedImage(Context *context,
391                                      const PixelUnpackState &unpackState,
392                                      TextureTarget target,
393                                      GLint level,
394                                      GLenum internalFormat,
395                                      const Extents &size,
396                                      size_t imageSize,
397                                      const uint8_t *pixels);
398     angle::Result setCompressedSubImage(const Context *context,
399                                         const PixelUnpackState &unpackState,
400                                         TextureTarget target,
401                                         GLint level,
402                                         const Box &area,
403                                         GLenum format,
404                                         size_t imageSize,
405                                         const uint8_t *pixels);
406 
407     angle::Result copyImage(Context *context,
408                             TextureTarget target,
409                             GLint level,
410                             const Rectangle &sourceArea,
411                             GLenum internalFormat,
412                             Framebuffer *source);
413     angle::Result copySubImage(Context *context,
414                                const ImageIndex &index,
415                                const Offset &destOffset,
416                                const Rectangle &sourceArea,
417                                Framebuffer *source);
418 
419     angle::Result copyRenderbufferSubData(Context *context,
420                                           const gl::Renderbuffer *srcBuffer,
421                                           GLint srcLevel,
422                                           GLint srcX,
423                                           GLint srcY,
424                                           GLint srcZ,
425                                           GLint dstLevel,
426                                           GLint dstX,
427                                           GLint dstY,
428                                           GLint dstZ,
429                                           GLsizei srcWidth,
430                                           GLsizei srcHeight,
431                                           GLsizei srcDepth);
432 
433     angle::Result copyTextureSubData(Context *context,
434                                      const gl::Texture *srcTexture,
435                                      GLint srcLevel,
436                                      GLint srcX,
437                                      GLint srcY,
438                                      GLint srcZ,
439                                      GLint dstLevel,
440                                      GLint dstX,
441                                      GLint dstY,
442                                      GLint dstZ,
443                                      GLsizei srcWidth,
444                                      GLsizei srcHeight,
445                                      GLsizei srcDepth);
446 
447     angle::Result copyTexture(Context *context,
448                               TextureTarget target,
449                               GLint level,
450                               GLenum internalFormat,
451                               GLenum type,
452                               GLint sourceLevel,
453                               bool unpackFlipY,
454                               bool unpackPremultiplyAlpha,
455                               bool unpackUnmultiplyAlpha,
456                               Texture *source);
457     angle::Result copySubTexture(const Context *context,
458                                  TextureTarget target,
459                                  GLint level,
460                                  const Offset &destOffset,
461                                  GLint sourceLevel,
462                                  const Box &sourceBox,
463                                  bool unpackFlipY,
464                                  bool unpackPremultiplyAlpha,
465                                  bool unpackUnmultiplyAlpha,
466                                  Texture *source);
467     angle::Result copyCompressedTexture(Context *context, const Texture *source);
468 
469     angle::Result setStorage(Context *context,
470                              TextureType type,
471                              GLsizei levels,
472                              GLenum internalFormat,
473                              const Extents &size);
474 
475     angle::Result setStorageMultisample(Context *context,
476                                         TextureType type,
477                                         GLsizei samplesIn,
478                                         GLint internalformat,
479                                         const Extents &size,
480                                         bool fixedSampleLocations);
481 
482     angle::Result setStorageExternalMemory(Context *context,
483                                            TextureType type,
484                                            GLsizei levels,
485                                            GLenum internalFormat,
486                                            const Extents &size,
487                                            MemoryObject *memoryObject,
488                                            GLuint64 offset,
489                                            GLbitfield createFlags,
490                                            GLbitfield usageFlags,
491                                            const void *imageCreateInfoPNext);
492 
493     angle::Result setImageExternal(Context *context,
494                                    TextureTarget target,
495                                    GLint level,
496                                    GLenum internalFormat,
497                                    const Extents &size,
498                                    GLenum format,
499                                    GLenum type);
500 
501     angle::Result setEGLImageTarget(Context *context, TextureType type, egl::Image *imageTarget);
502 
503     angle::Result generateMipmap(Context *context);
504 
505     void onBindAsImageTexture();
506 
507     egl::Surface *getBoundSurface() const;
508     egl::Stream *getBoundStream() const;
509 
510     GLint getMemorySize() const;
511     GLint getLevelMemorySize(TextureTarget target, GLint level) const;
512 
513     void signalDirtyStorage(InitState initState);
514 
515     bool isSamplerComplete(const Context *context, const Sampler *optionalSampler);
516 
517     GLenum getImplementationColorReadFormat(const Context *context) const;
518     GLenum getImplementationColorReadType(const Context *context) const;
519 
520     // We pass the pack buffer and state explicitly so they can be overridden during capture.
521     angle::Result getTexImage(const Context *context,
522                               const PixelPackState &packState,
523                               Buffer *packBuffer,
524                               TextureTarget target,
525                               GLint level,
526                               GLenum format,
527                               GLenum type,
528                               void *pixels);
529 
530     angle::Result getCompressedTexImage(const Context *context,
531                                         const PixelPackState &packState,
532                                         Buffer *packBuffer,
533                                         TextureTarget target,
534                                         GLint level,
535                                         void *pixels);
536 
getImplementation()537     rx::TextureImpl *getImplementation() const { return mTexture; }
538 
539     // FramebufferAttachmentObject implementation
540     Extents getAttachmentSize(const ImageIndex &imageIndex) const override;
541     Format getAttachmentFormat(GLenum binding, const ImageIndex &imageIndex) const override;
542     GLsizei getAttachmentSamples(const ImageIndex &imageIndex) const override;
543     bool isRenderable(const Context *context,
544                       GLenum binding,
545                       const ImageIndex &imageIndex) const override;
546 
547     bool getAttachmentFixedSampleLocations(const ImageIndex &imageIndex) const;
548 
549     // GLES1 emulation
550     void setCrop(const Rectangle &rect);
551     const Rectangle &getCrop() const;
552     void setGenerateMipmapHint(GLenum generate);
553     GLenum getGenerateMipmapHint() const;
554 
555     void onAttach(const Context *context, rx::Serial framebufferSerial) override;
556     void onDetach(const Context *context, rx::Serial framebufferSerial) override;
557 
558     // Used specifically for FramebufferAttachmentObject.
559     GLuint getId() const override;
560 
561     GLuint getNativeID() const;
562 
563     // Needed for robust resource init.
564     angle::Result ensureInitialized(const Context *context);
565     InitState initState(const ImageIndex &imageIndex) const override;
initState()566     InitState initState() const { return mState.mInitState; }
567     void setInitState(const ImageIndex &imageIndex, InitState initState) override;
568     void setInitState(InitState initState);
569 
isBoundToFramebuffer(rx::Serial framebufferSerial)570     bool isBoundToFramebuffer(rx::Serial framebufferSerial) const
571     {
572         for (size_t index = 0; index < mBoundFramebufferSerials.size(); ++index)
573         {
574             if (mBoundFramebufferSerials[index] == framebufferSerial)
575                 return true;
576         }
577 
578         return false;
579     }
580 
isDepthOrStencil()581     bool isDepthOrStencil() const
582     {
583         return mState.getBaseLevelDesc().format.info->isDepthOrStencil();
584     }
585 
586     enum DirtyBitType
587     {
588         // Sampler state
589         DIRTY_BIT_MIN_FILTER,
590         DIRTY_BIT_MAG_FILTER,
591         DIRTY_BIT_WRAP_S,
592         DIRTY_BIT_WRAP_T,
593         DIRTY_BIT_WRAP_R,
594         DIRTY_BIT_MAX_ANISOTROPY,
595         DIRTY_BIT_MIN_LOD,
596         DIRTY_BIT_MAX_LOD,
597         DIRTY_BIT_COMPARE_MODE,
598         DIRTY_BIT_COMPARE_FUNC,
599         DIRTY_BIT_SRGB_DECODE,
600         DIRTY_BIT_SRGB_OVERRIDE,
601         DIRTY_BIT_BORDER_COLOR,
602 
603         // Texture state
604         DIRTY_BIT_SWIZZLE_RED,
605         DIRTY_BIT_SWIZZLE_GREEN,
606         DIRTY_BIT_SWIZZLE_BLUE,
607         DIRTY_BIT_SWIZZLE_ALPHA,
608         DIRTY_BIT_BASE_LEVEL,
609         DIRTY_BIT_MAX_LEVEL,
610         DIRTY_BIT_DEPTH_STENCIL_TEXTURE_MODE,
611 
612         // Image state
613         DIRTY_BIT_BOUND_AS_IMAGE,
614         DIRTY_BIT_BOUND_AS_ATTACHMENT,
615 
616         // Misc
617         DIRTY_BIT_USAGE,
618         DIRTY_BIT_IMPLEMENTATION,
619 
620         DIRTY_BIT_COUNT,
621     };
622     using DirtyBits = angle::BitSet<DIRTY_BIT_COUNT>;
623 
624     angle::Result syncState(const Context *context, Command source);
hasAnyDirtyBit()625     bool hasAnyDirtyBit() const { return mDirtyBits.any(); }
hasAnyDirtyBitExcludingBoundAsAttachmentBit()626     bool hasAnyDirtyBitExcludingBoundAsAttachmentBit() const
627     {
628         static constexpr DirtyBits kBoundAsAttachment = DirtyBits({DIRTY_BIT_BOUND_AS_ATTACHMENT});
629         return mDirtyBits.any() && mDirtyBits != kBoundAsAttachment;
630     }
631 
632     // ObserverInterface implementation.
633     void onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message) override;
634 
635   private:
636     rx::FramebufferAttachmentObjectImpl *getAttachmentImpl() const override;
637 
638     // ANGLE-only method, used internally
639     friend class egl::Surface;
640     angle::Result bindTexImageFromSurface(Context *context, egl::Surface *surface);
641     angle::Result releaseTexImageFromSurface(const Context *context);
642 
643     // ANGLE-only methods, used internally
644     friend class egl::Stream;
645     void bindStream(egl::Stream *stream);
646     void releaseStream();
647     angle::Result acquireImageFromStream(const Context *context,
648                                          const egl::Stream::GLTextureDescription &desc);
649     angle::Result releaseImageFromStream(const Context *context);
650 
651     void invalidateCompletenessCache() const;
652     angle::Result releaseTexImageInternal(Context *context);
653 
654     bool doesSubImageNeedInit(const Context *context,
655                               const ImageIndex &imageIndex,
656                               const Box &area) const;
657     angle::Result ensureSubImageInitialized(const Context *context,
658                                             const ImageIndex &imageIndex,
659                                             const Box &area);
660 
661     angle::Result handleMipmapGenerationHint(Context *context, int level);
662 
663     void signalDirtyState(size_t dirtyBit);
664 
665     TextureState mState;
666     DirtyBits mDirtyBits;
667     rx::TextureImpl *mTexture;
668     angle::ObserverBinding mImplObserver;
669     // For EXT_texture_buffer, observes buffer changes.
670     angle::ObserverBinding mBufferObserver;
671 
672     egl::Surface *mBoundSurface;
673     egl::Stream *mBoundStream;
674 
675     // We track all the serials of the Framebuffers this texture is attached to. Note that this
676     // allows duplicates because different ranges of a Texture can be bound to the same Framebuffer.
677     // For the purposes of depth-stencil loops, a simple "isBound" check works fine. For color
678     // attachment Feedback Loop checks we then need to check further to see when a Texture is bound
679     // to mulitple bindings that the bindings don't overlap.
680     static constexpr uint32_t kFastFramebufferSerialCount = 8;
681     angle::FastVector<rx::Serial, kFastFramebufferSerialCount> mBoundFramebufferSerials;
682 
683     struct SamplerCompletenessCache
684     {
685         SamplerCompletenessCache();
686 
687         // Context used to generate this cache entry
688         ContextID context;
689 
690         // All values that affect sampler completeness that are not stored within
691         // the texture itself
692         SamplerState samplerState;
693 
694         // Result of the sampler completeness with the above parameters
695         bool samplerComplete;
696     };
697 
698     mutable SamplerCompletenessCache mCompletenessCache;
699 };
700 
701 inline bool operator==(const TextureState &a, const TextureState &b)
702 {
703     return a.mSwizzleState == b.mSwizzleState && a.mSamplerState == b.mSamplerState &&
704            a.mBaseLevel == b.mBaseLevel && a.mMaxLevel == b.mMaxLevel &&
705            a.mImmutableFormat == b.mImmutableFormat && a.mImmutableLevels == b.mImmutableLevels &&
706            a.mUsage == b.mUsage;
707 }
708 
709 inline bool operator!=(const TextureState &a, const TextureState &b)
710 {
711     return !(a == b);
712 }
713 }  // namespace gl
714 
715 #endif  // LIBANGLE_TEXTURE_H_
716