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