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