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