• 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 bool IsMipmapFiltered(const SamplerState &samplerState);
52 
53 struct ImageDesc final
54 {
55     ImageDesc();
56     ImageDesc(const Extents &size, const Format &format, const InitState initState);
57     ImageDesc(const Extents &size,
58               const Format &format,
59               const GLsizei samples,
60               const bool fixedSampleLocations,
61               const InitState initState);
62 
63     ImageDesc(const ImageDesc &other) = default;
64     ImageDesc &operator=(const ImageDesc &other) = default;
65 
66     GLint getMemorySize() const;
67 
68     Extents size;
69     Format format;
70     GLsizei samples;
71     bool fixedSampleLocations;
72 
73     // Needed for robust resource initialization.
74     InitState initState;
75 };
76 
77 struct SwizzleState final
78 {
79     SwizzleState();
80     SwizzleState(GLenum red, GLenum green, GLenum blue, GLenum alpha);
81     SwizzleState(const SwizzleState &other) = default;
82     SwizzleState &operator=(const SwizzleState &other) = default;
83 
84     bool swizzleRequired() const;
85 
86     bool operator==(const SwizzleState &other) const;
87     bool operator!=(const SwizzleState &other) const;
88 
89     GLenum swizzleRed;
90     GLenum swizzleGreen;
91     GLenum swizzleBlue;
92     GLenum swizzleAlpha;
93 };
94 
95 // State from Table 6.9 (state per texture object) in the OpenGL ES 3.0.2 spec.
96 class TextureState final : private angle::NonCopyable
97 {
98   public:
99     TextureState(TextureType type);
100     ~TextureState();
101 
102     bool swizzleRequired() const;
103     GLuint getEffectiveBaseLevel() const;
104     GLuint getEffectiveMaxLevel() const;
105 
106     // Returns the value called "q" in the GLES 3.0.4 spec section 3.8.10.
107     GLuint getMipmapMaxLevel() const;
108 
109     // Returns true if base level changed.
110     bool setBaseLevel(GLuint baseLevel);
111     bool setMaxLevel(GLuint maxLevel);
112 
113     bool isCubeComplete() const;
114 
compatibleWithSamplerFormat(SamplerFormat format,const SamplerState & samplerState)115     ANGLE_INLINE bool compatibleWithSamplerFormat(SamplerFormat format,
116                                                   const SamplerState &samplerState) const
117     {
118         if (!mCachedSamplerFormatValid ||
119             mCachedSamplerCompareMode != samplerState.getCompareMode())
120         {
121             mCachedSamplerFormat      = computeRequiredSamplerFormat(samplerState);
122             mCachedSamplerCompareMode = samplerState.getCompareMode();
123             mCachedSamplerFormatValid = true;
124         }
125         // Incomplete textures are compatible with any sampler format.
126         return mCachedSamplerFormat == SamplerFormat::InvalidEnum || format == mCachedSamplerFormat;
127     }
128 
129     const ImageDesc &getImageDesc(TextureTarget target, size_t level) const;
130     const ImageDesc &getImageDesc(const ImageIndex &imageIndex) const;
131 
getType()132     TextureType getType() const { return mType; }
getSwizzleState()133     const SwizzleState &getSwizzleState() const { return mSwizzleState; }
getSamplerState()134     const SamplerState &getSamplerState() const { return mSamplerState; }
getUsage()135     GLenum getUsage() const { return mUsage; }
getDepthStencilTextureMode()136     GLenum getDepthStencilTextureMode() const { return mDepthStencilTextureMode; }
isStencilMode()137     bool isStencilMode() const { return mDepthStencilTextureMode == GL_STENCIL_INDEX; }
138 
139     // Returns the desc of the base level. Only valid for cube-complete/mip-complete textures.
140     const ImageDesc &getBaseLevelDesc() const;
141 
142     // GLES1 emulation: For GL_OES_draw_texture
143     void setCrop(const gl::Rectangle &rect);
144     const gl::Rectangle &getCrop() const;
145 
146     // GLES1 emulation: Auto-mipmap generation is a texparameter
147     void setGenerateMipmapHint(GLenum hint);
148     GLenum getGenerateMipmapHint() const;
149 
150   private:
151     // Texture needs access to the ImageDesc functions.
152     friend class Texture;
153     // TODO(jmadill): Remove TextureGL from friends.
154     friend class rx::TextureGL;
155     friend bool operator==(const TextureState &a, const TextureState &b);
156 
157     bool computeSamplerCompleteness(const SamplerState &samplerState, const State &data) const;
158     bool computeMipmapCompleteness() const;
159     bool computeLevelCompleteness(TextureTarget target, size_t level) const;
160     SamplerFormat computeRequiredSamplerFormat(const SamplerState &samplerState) const;
161 
162     TextureTarget getBaseImageTarget() const;
163 
164     void setImageDesc(TextureTarget target, size_t level, const ImageDesc &desc);
165     void setImageDescChain(GLuint baselevel,
166                            GLuint maxLevel,
167                            Extents baseSize,
168                            const Format &format,
169                            InitState initState);
170     void setImageDescChainMultisample(Extents baseSize,
171                                       const Format &format,
172                                       GLsizei samples,
173                                       bool fixedSampleLocations,
174                                       InitState initState);
175 
176     void clearImageDesc(TextureTarget target, size_t level);
177     void clearImageDescs();
178 
179     const TextureType mType;
180 
181     SwizzleState mSwizzleState;
182 
183     SamplerState mSamplerState;
184 
185     GLuint mBaseLevel;
186     GLuint mMaxLevel;
187 
188     GLenum mDepthStencilTextureMode;
189 
190     bool mImmutableFormat;
191     GLuint mImmutableLevels;
192 
193     // From GL_ANGLE_texture_usage
194     GLenum mUsage;
195 
196     std::vector<ImageDesc> mImageDescs;
197 
198     // GLES1 emulation: Texture crop rectangle
199     // For GL_OES_draw_texture
200     gl::Rectangle mCropRect;
201 
202     // GLES1 emulation: Generate-mipmap hint per texture
203     GLenum mGenerateMipmapHint;
204 
205     InitState mInitState;
206 
207     mutable SamplerFormat mCachedSamplerFormat;
208     mutable GLenum mCachedSamplerCompareMode;
209     mutable bool mCachedSamplerFormatValid;
210 };
211 
212 bool operator==(const TextureState &a, const TextureState &b);
213 bool operator!=(const TextureState &a, const TextureState &b);
214 
215 class Texture final : public RefCountObject, public egl::ImageSibling, public LabeledObject
216 {
217   public:
218     Texture(rx::GLImplFactory *factory, TextureID id, TextureType type);
219     ~Texture() override;
220 
221     void onDestroy(const Context *context) override;
222 
223     void setLabel(const Context *context, const std::string &label) override;
224     const std::string &getLabel() const override;
225 
getType()226     TextureType getType() const { return mState.mType; }
227 
228     void setSwizzleRed(const Context *context, GLenum swizzleRed);
229     GLenum getSwizzleRed() const;
230 
231     void setSwizzleGreen(const Context *context, GLenum swizzleGreen);
232     GLenum getSwizzleGreen() const;
233 
234     void setSwizzleBlue(const Context *context, GLenum swizzleBlue);
235     GLenum getSwizzleBlue() const;
236 
237     void setSwizzleAlpha(const Context *context, GLenum swizzleAlpha);
238     GLenum getSwizzleAlpha() const;
239 
240     void setMinFilter(const Context *context, GLenum minFilter);
241     GLenum getMinFilter() const;
242 
243     void setMagFilter(const Context *context, GLenum magFilter);
244     GLenum getMagFilter() const;
245 
246     void setWrapS(const Context *context, GLenum wrapS);
247     GLenum getWrapS() const;
248 
249     void setWrapT(const Context *context, GLenum wrapT);
250     GLenum getWrapT() const;
251 
252     void setWrapR(const Context *context, GLenum wrapR);
253     GLenum getWrapR() const;
254 
255     void setMaxAnisotropy(const Context *context, float maxAnisotropy);
256     float getMaxAnisotropy() const;
257 
258     void setMinLod(const Context *context, GLfloat minLod);
259     GLfloat getMinLod() const;
260 
261     void setMaxLod(const Context *context, GLfloat maxLod);
262     GLfloat getMaxLod() const;
263 
264     void setCompareMode(const Context *context, GLenum compareMode);
265     GLenum getCompareMode() const;
266 
267     void setCompareFunc(const Context *context, GLenum compareFunc);
268     GLenum getCompareFunc() const;
269 
270     void setSRGBDecode(const Context *context, GLenum sRGBDecode);
271     GLenum getSRGBDecode() const;
272 
273     const SamplerState &getSamplerState() const;
274 
275     angle::Result setBaseLevel(const Context *context, GLuint baseLevel);
276     GLuint getBaseLevel() const;
277 
278     void setMaxLevel(const Context *context, GLuint maxLevel);
279     GLuint getMaxLevel() const;
280 
281     void setDepthStencilTextureMode(const Context *context, GLenum mode);
282     GLenum getDepthStencilTextureMode() const;
283 
284     bool getImmutableFormat() const;
285 
286     GLuint getImmutableLevels() const;
287 
288     void setUsage(const Context *context, GLenum usage);
289     GLenum getUsage() const;
290 
291     void setBorderColor(const Context *context, const ColorGeneric &color);
292     const ColorGeneric &getBorderColor() const;
293 
294     const TextureState &getTextureState() const;
295 
296     size_t getWidth(TextureTarget target, size_t level) const;
297     size_t getHeight(TextureTarget target, size_t level) const;
298     size_t getDepth(TextureTarget target, size_t level) const;
299     GLsizei getSamples(TextureTarget target, size_t level) const;
300     bool getFixedSampleLocations(TextureTarget target, size_t level) const;
301     const Format &getFormat(TextureTarget target, size_t level) const;
302 
303     // Returns the value called "q" in the GLES 3.0.4 spec section 3.8.10.
304     GLuint getMipmapMaxLevel() const;
305 
306     bool isMipmapComplete() const;
307 
308     angle::Result setImage(Context *context,
309                            const PixelUnpackState &unpackState,
310                            TextureTarget target,
311                            GLint level,
312                            GLenum internalFormat,
313                            const Extents &size,
314                            GLenum format,
315                            GLenum type,
316                            const uint8_t *pixels);
317     angle::Result setSubImage(Context *context,
318                               const PixelUnpackState &unpackState,
319                               Buffer *unpackBuffer,
320                               TextureTarget target,
321                               GLint level,
322                               const Box &area,
323                               GLenum format,
324                               GLenum type,
325                               const uint8_t *pixels);
326 
327     angle::Result setCompressedImage(Context *context,
328                                      const PixelUnpackState &unpackState,
329                                      TextureTarget target,
330                                      GLint level,
331                                      GLenum internalFormat,
332                                      const Extents &size,
333                                      size_t imageSize,
334                                      const uint8_t *pixels);
335     angle::Result setCompressedSubImage(const Context *context,
336                                         const PixelUnpackState &unpackState,
337                                         TextureTarget target,
338                                         GLint level,
339                                         const Box &area,
340                                         GLenum format,
341                                         size_t imageSize,
342                                         const uint8_t *pixels);
343 
344     angle::Result copyImage(Context *context,
345                             TextureTarget target,
346                             GLint level,
347                             const Rectangle &sourceArea,
348                             GLenum internalFormat,
349                             Framebuffer *source);
350     angle::Result copySubImage(Context *context,
351                                const ImageIndex &index,
352                                const Offset &destOffset,
353                                const Rectangle &sourceArea,
354                                Framebuffer *source);
355 
356     angle::Result copyTexture(Context *context,
357                               TextureTarget target,
358                               GLint level,
359                               GLenum internalFormat,
360                               GLenum type,
361                               GLint sourceLevel,
362                               bool unpackFlipY,
363                               bool unpackPremultiplyAlpha,
364                               bool unpackUnmultiplyAlpha,
365                               Texture *source);
366     angle::Result copySubTexture(const Context *context,
367                                  TextureTarget target,
368                                  GLint level,
369                                  const Offset &destOffset,
370                                  GLint sourceLevel,
371                                  const Box &sourceBox,
372                                  bool unpackFlipY,
373                                  bool unpackPremultiplyAlpha,
374                                  bool unpackUnmultiplyAlpha,
375                                  Texture *source);
376     angle::Result copyCompressedTexture(Context *context, const Texture *source);
377 
378     angle::Result setStorage(Context *context,
379                              TextureType type,
380                              GLsizei levels,
381                              GLenum internalFormat,
382                              const Extents &size);
383 
384     angle::Result setStorageMultisample(Context *context,
385                                         TextureType type,
386                                         GLsizei samples,
387                                         GLint internalformat,
388                                         const Extents &size,
389                                         bool fixedSampleLocations);
390 
391     angle::Result setStorageExternalMemory(Context *context,
392                                            TextureType type,
393                                            GLsizei levels,
394                                            GLenum internalFormat,
395                                            const Extents &size,
396                                            MemoryObject *memoryObject,
397                                            GLuint64 offset);
398 
399     angle::Result setImageExternal(Context *context,
400                                    TextureTarget target,
401                                    GLint level,
402                                    GLenum internalFormat,
403                                    const Extents &size,
404                                    GLenum format,
405                                    GLenum type);
406 
407     angle::Result setEGLImageTarget(Context *context, TextureType type, egl::Image *imageTarget);
408 
409     angle::Result generateMipmap(Context *context);
410 
411     egl::Surface *getBoundSurface() const;
412     egl::Stream *getBoundStream() const;
413 
414     GLint getMemorySize() const;
415     GLint getLevelMemorySize(TextureTarget target, GLint level) const;
416 
417     void signalDirtyStorage(InitState initState);
418 
419     bool isSamplerComplete(const Context *context, const Sampler *optionalSampler);
420 
getImplementation()421     rx::TextureImpl *getImplementation() const { return mTexture; }
422 
423     // FramebufferAttachmentObject implementation
424     Extents getAttachmentSize(const ImageIndex &imageIndex) const override;
425     Format getAttachmentFormat(GLenum binding, const ImageIndex &imageIndex) const override;
426     GLsizei getAttachmentSamples(const ImageIndex &imageIndex) const override;
427     bool isRenderable(const Context *context,
428                       GLenum binding,
429                       const ImageIndex &imageIndex) const override;
430 
431     bool getAttachmentFixedSampleLocations(const ImageIndex &imageIndex) const;
432 
433     // GLES1 emulation
434     void setCrop(const gl::Rectangle &rect);
435     const gl::Rectangle &getCrop() const;
436     void setGenerateMipmapHint(GLenum generate);
437     GLenum getGenerateMipmapHint() const;
438 
439     void onAttach(const Context *context) override;
440     void onDetach(const Context *context) override;
441     GLuint getId() const override;
442     GLuint getNativeID() const;
443 
444     // Needed for robust resource init.
445     angle::Result ensureInitialized(const Context *context);
446     InitState initState(const ImageIndex &imageIndex) const override;
initState()447     InitState initState() const { return mState.mInitState; }
448     void setInitState(const ImageIndex &imageIndex, InitState initState) override;
449 
450     enum DirtyBitType
451     {
452         // Sampler state
453         DIRTY_BIT_MIN_FILTER,
454         DIRTY_BIT_MAG_FILTER,
455         DIRTY_BIT_WRAP_S,
456         DIRTY_BIT_WRAP_T,
457         DIRTY_BIT_WRAP_R,
458         DIRTY_BIT_MAX_ANISOTROPY,
459         DIRTY_BIT_MIN_LOD,
460         DIRTY_BIT_MAX_LOD,
461         DIRTY_BIT_COMPARE_MODE,
462         DIRTY_BIT_COMPARE_FUNC,
463         DIRTY_BIT_SRGB_DECODE,
464         DIRTY_BIT_BORDER_COLOR,
465 
466         // Texture state
467         DIRTY_BIT_SWIZZLE_RED,
468         DIRTY_BIT_SWIZZLE_GREEN,
469         DIRTY_BIT_SWIZZLE_BLUE,
470         DIRTY_BIT_SWIZZLE_ALPHA,
471         DIRTY_BIT_BASE_LEVEL,
472         DIRTY_BIT_MAX_LEVEL,
473         DIRTY_BIT_DEPTH_STENCIL_TEXTURE_MODE,
474 
475         // Misc
476         DIRTY_BIT_LABEL,
477         DIRTY_BIT_USAGE,
478         DIRTY_BIT_IMPLEMENTATION,
479 
480         DIRTY_BIT_COUNT,
481     };
482     using DirtyBits = angle::BitSet<DIRTY_BIT_COUNT>;
483 
484     angle::Result syncState(const Context *context);
hasAnyDirtyBit()485     bool hasAnyDirtyBit() const { return mDirtyBits.any(); }
486 
487     // ObserverInterface implementation.
488     void onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message) override;
489 
490   private:
491     rx::FramebufferAttachmentObjectImpl *getAttachmentImpl() const override;
492 
493     // ANGLE-only method, used internally
494     friend class egl::Surface;
495     angle::Result bindTexImageFromSurface(Context *context, egl::Surface *surface);
496     angle::Result releaseTexImageFromSurface(const Context *context);
497 
498     // ANGLE-only methods, used internally
499     friend class egl::Stream;
500     void bindStream(egl::Stream *stream);
501     void releaseStream();
502     angle::Result acquireImageFromStream(const Context *context,
503                                          const egl::Stream::GLTextureDescription &desc);
504     angle::Result releaseImageFromStream(const Context *context);
505 
506     void invalidateCompletenessCache() const;
507     angle::Result releaseTexImageInternal(Context *context);
508 
509     angle::Result ensureSubImageInitialized(const Context *context,
510                                             TextureTarget target,
511                                             size_t level,
512                                             const gl::Box &area);
513 
514     angle::Result handleMipmapGenerationHint(Context *context, int level);
515 
516     void signalDirtyState(size_t dirtyBit);
517 
518     TextureState mState;
519     DirtyBits mDirtyBits;
520     rx::TextureImpl *mTexture;
521     angle::ObserverBinding mImplObserver;
522 
523     std::string mLabel;
524 
525     egl::Surface *mBoundSurface;
526     egl::Stream *mBoundStream;
527 
528     struct SamplerCompletenessCache
529     {
530         SamplerCompletenessCache();
531 
532         // Context used to generate this cache entry
533         ContextID context;
534 
535         // All values that affect sampler completeness that are not stored within
536         // the texture itself
537         SamplerState samplerState;
538 
539         // Result of the sampler completeness with the above parameters
540         bool samplerComplete;
541     };
542 
543     mutable SamplerCompletenessCache mCompletenessCache;
544 };
545 
546 inline bool operator==(const TextureState &a, const TextureState &b)
547 {
548     return a.mSwizzleState == b.mSwizzleState && a.mSamplerState == b.mSamplerState &&
549            a.mBaseLevel == b.mBaseLevel && a.mMaxLevel == b.mMaxLevel &&
550            a.mImmutableFormat == b.mImmutableFormat && a.mImmutableLevels == b.mImmutableLevels &&
551            a.mUsage == b.mUsage;
552 }
553 
554 inline bool operator!=(const TextureState &a, const TextureState &b)
555 {
556     return !(a == b);
557 }
558 }  // namespace gl
559 
560 #endif  // LIBANGLE_TEXTURE_H_
561