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