1 //
2 // Copyright (c) 2002-2013 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 <vector>
13 #include <map>
14 
15 #include "angle_gl.h"
16 #include "common/Optional.h"
17 #include "common/debug.h"
18 #include "libANGLE/Caps.h"
19 #include "libANGLE/Constants.h"
20 #include "libANGLE/Debug.h"
21 #include "libANGLE/Error.h"
22 #include "libANGLE/FramebufferAttachment.h"
23 #include "libANGLE/Image.h"
24 #include "libANGLE/Stream.h"
25 #include "libANGLE/angletypes.h"
26 #include "libANGLE/formatutils.h"
27 
28 namespace egl
29 {
30 class Surface;
31 class Stream;
32 }
33 
34 namespace rx
35 {
36 class GLImplFactory;
37 class TextureImpl;
38 class TextureGL;
39 }
40 
41 namespace gl
42 {
43 class ContextState;
44 class Framebuffer;
45 class Sampler;
46 class Texture;
47 
48 bool IsMipmapFiltered(const SamplerState &samplerState);
49 
50 struct ImageDesc final
51 {
52     ImageDesc();
53     ImageDesc(const Extents &size, const Format &format, const InitState initState);
54     ImageDesc(const Extents &size,
55               const Format &format,
56               const GLsizei samples,
57               const bool fixedSampleLocations,
58               const InitState initState);
59 
60     ImageDesc(const ImageDesc &other) = default;
61     ImageDesc &operator=(const ImageDesc &other) = default;
62 
63     Extents size;
64     Format format;
65     GLsizei samples;
66     bool fixedSampleLocations;
67 
68     // Needed for robust resource initialization.
69     InitState initState;
70 };
71 
72 struct SwizzleState final
73 {
74     SwizzleState();
75     SwizzleState(GLenum red, GLenum green, GLenum blue, GLenum alpha);
76     SwizzleState(const SwizzleState &other) = default;
77     SwizzleState &operator=(const SwizzleState &other) = default;
78 
79     bool swizzleRequired() const;
80 
81     bool operator==(const SwizzleState &other) const;
82     bool operator!=(const SwizzleState &other) const;
83 
84     GLenum swizzleRed;
85     GLenum swizzleGreen;
86     GLenum swizzleBlue;
87     GLenum swizzleAlpha;
88 };
89 
90 // State from Table 6.9 (state per texture object) in the OpenGL ES 3.0.2 spec.
91 struct TextureState final : private angle::NonCopyable
92 {
93     TextureState(GLenum target);
94     ~TextureState();
95 
96     bool swizzleRequired() const;
97     GLuint getEffectiveBaseLevel() const;
98     GLuint getEffectiveMaxLevel() const;
99 
100     // Returns the value called "q" in the GLES 3.0.4 spec section 3.8.10.
101     GLuint getMipmapMaxLevel() const;
102 
103     // Returns true if base level changed.
104     bool setBaseLevel(GLuint baseLevel);
105     bool setMaxLevel(GLuint maxLevel);
106 
107     bool isCubeComplete() const;
108 
109     const ImageDesc &getImageDesc(GLenum target, size_t level) const;
110     const ImageDesc &getImageDesc(const ImageIndex &imageIndex) const;
111 
getTargetfinal112     GLenum getTarget() const { return mTarget; }
getSwizzleStatefinal113     const SwizzleState &getSwizzleState() const { return mSwizzleState; }
getSamplerStatefinal114     const SamplerState &getSamplerState() const { return mSamplerState; }
getUsagefinal115     GLenum getUsage() const { return mUsage; }
116 
117   private:
118     // Texture needs access to the ImageDesc functions.
119     friend class Texture;
120     // TODO(jmadill): Remove TextureGL from friends.
121     friend class rx::TextureGL;
122     friend bool operator==(const TextureState &a, const TextureState &b);
123 
124     bool computeSamplerCompleteness(const SamplerState &samplerState,
125                                     const ContextState &data) const;
126     bool computeMipmapCompleteness() const;
127     bool computeLevelCompleteness(GLenum target, size_t level) const;
128 
129     GLenum getBaseImageTarget() const;
130 
131     void setImageDesc(GLenum target, size_t level, const ImageDesc &desc);
132     void setImageDescChain(GLuint baselevel,
133                            GLuint maxLevel,
134                            Extents baseSize,
135                            const Format &format,
136                            InitState initState);
137     void setImageDescChainMultisample(Extents baseSize,
138                                       const Format &format,
139                                       GLsizei samples,
140                                       bool fixedSampleLocations,
141                                       InitState initState);
142 
143     void clearImageDesc(GLenum target, size_t level);
144     void clearImageDescs();
145 
146     const GLenum mTarget;
147 
148     SwizzleState mSwizzleState;
149 
150     SamplerState mSamplerState;
151 
152     GLuint mBaseLevel;
153     GLuint mMaxLevel;
154 
155     GLenum mDepthStencilTextureMode;
156 
157     bool mImmutableFormat;
158     GLuint mImmutableLevels;
159 
160     // From GL_ANGLE_texture_usage
161     GLenum mUsage;
162 
163     std::vector<ImageDesc> mImageDescs;
164     InitState mInitState;
165 };
166 
167 bool operator==(const TextureState &a, const TextureState &b);
168 bool operator!=(const TextureState &a, const TextureState &b);
169 
170 class Texture final : public egl::ImageSibling,
171                       public LabeledObject
172 {
173   public:
174     Texture(rx::GLImplFactory *factory, GLuint id, GLenum target);
175     ~Texture() override;
176 
177     Error onDestroy(const Context *context) override;
178 
179     void setLabel(const std::string &label) override;
180     const std::string &getLabel() const override;
181 
182     GLenum getTarget() const;
183 
184     void setSwizzleRed(GLenum swizzleRed);
185     GLenum getSwizzleRed() const;
186 
187     void setSwizzleGreen(GLenum swizzleGreen);
188     GLenum getSwizzleGreen() const;
189 
190     void setSwizzleBlue(GLenum swizzleBlue);
191     GLenum getSwizzleBlue() const;
192 
193     void setSwizzleAlpha(GLenum swizzleAlpha);
194     GLenum getSwizzleAlpha() const;
195 
196     void setMinFilter(GLenum minFilter);
197     GLenum getMinFilter() const;
198 
199     void setMagFilter(GLenum magFilter);
200     GLenum getMagFilter() const;
201 
202     void setWrapS(GLenum wrapS);
203     GLenum getWrapS() const;
204 
205     void setWrapT(GLenum wrapT);
206     GLenum getWrapT() const;
207 
208     void setWrapR(GLenum wrapR);
209     GLenum getWrapR() const;
210 
211     void setMaxAnisotropy(float maxAnisotropy);
212     float getMaxAnisotropy() const;
213 
214     void setMinLod(GLfloat minLod);
215     GLfloat getMinLod() const;
216 
217     void setMaxLod(GLfloat maxLod);
218     GLfloat getMaxLod() const;
219 
220     void setCompareMode(GLenum compareMode);
221     GLenum getCompareMode() const;
222 
223     void setCompareFunc(GLenum compareFunc);
224     GLenum getCompareFunc() const;
225 
226     void setSRGBDecode(GLenum sRGBDecode);
227     GLenum getSRGBDecode() const;
228 
229     const SamplerState &getSamplerState() const;
230 
231     gl::Error setBaseLevel(const Context *context, GLuint baseLevel);
232     GLuint getBaseLevel() const;
233 
234     void setMaxLevel(GLuint maxLevel);
235     GLuint getMaxLevel() const;
236 
237     void setDepthStencilTextureMode(GLenum mode);
238     GLenum getDepthStencilTextureMode() const;
239 
240     bool getImmutableFormat() const;
241 
242     GLuint getImmutableLevels() const;
243 
244     void setUsage(GLenum usage);
245     GLenum getUsage() const;
246 
247     const TextureState &getTextureState() const;
248 
249     size_t getWidth(GLenum target, size_t level) const;
250     size_t getHeight(GLenum target, size_t level) const;
251     size_t getDepth(GLenum target, size_t level) const;
252     GLsizei getSamples(GLenum target, size_t level) const;
253     bool getFixedSampleLocations(GLenum target, size_t level) const;
254     const Format &getFormat(GLenum target, size_t level) const;
255 
256     // Returns the value called "q" in the GLES 3.0.4 spec section 3.8.10.
257     GLuint getMipmapMaxLevel() const;
258 
259     bool isMipmapComplete() const;
260 
261     Error setImage(const Context *context,
262                    const PixelUnpackState &unpackState,
263                    GLenum target,
264                    size_t level,
265                    GLenum internalFormat,
266                    const Extents &size,
267                    GLenum format,
268                    GLenum type,
269                    const uint8_t *pixels);
270     Error setSubImage(const Context *context,
271                       const PixelUnpackState &unpackState,
272                       GLenum target,
273                       size_t level,
274                       const Box &area,
275                       GLenum format,
276                       GLenum type,
277                       const uint8_t *pixels);
278 
279     Error setCompressedImage(const Context *context,
280                              const PixelUnpackState &unpackState,
281                              GLenum target,
282                              size_t level,
283                              GLenum internalFormat,
284                              const Extents &size,
285                              size_t imageSize,
286                              const uint8_t *pixels);
287     Error setCompressedSubImage(const Context *context,
288                                 const PixelUnpackState &unpackState,
289                                 GLenum target,
290                                 size_t level,
291                                 const Box &area,
292                                 GLenum format,
293                                 size_t imageSize,
294                                 const uint8_t *pixels);
295 
296     Error copyImage(const Context *context,
297                     GLenum target,
298                     size_t level,
299                     const Rectangle &sourceArea,
300                     GLenum internalFormat,
301                     Framebuffer *source);
302     Error copySubImage(const Context *context,
303                        GLenum target,
304                        size_t level,
305                        const Offset &destOffset,
306                        const Rectangle &sourceArea,
307                        Framebuffer *source);
308 
309     Error copyTexture(const Context *context,
310                       GLenum target,
311                       size_t level,
312                       GLenum internalFormat,
313                       GLenum type,
314                       size_t sourceLevel,
315                       bool unpackFlipY,
316                       bool unpackPremultiplyAlpha,
317                       bool unpackUnmultiplyAlpha,
318                       Texture *source);
319     Error copySubTexture(const Context *context,
320                          GLenum target,
321                          size_t level,
322                          const Offset &destOffset,
323                          size_t sourceLevel,
324                          const Rectangle &sourceArea,
325                          bool unpackFlipY,
326                          bool unpackPremultiplyAlpha,
327                          bool unpackUnmultiplyAlpha,
328                          Texture *source);
329     Error copyCompressedTexture(const Context *context, const Texture *source);
330 
331     Error setStorage(const Context *context,
332                      GLenum target,
333                      GLsizei levels,
334                      GLenum internalFormat,
335                      const Extents &size);
336 
337     Error setStorageMultisample(const Context *context,
338                                 GLenum target,
339                                 GLsizei samples,
340                                 GLint internalformat,
341                                 const Extents &size,
342                                 bool fixedSampleLocations);
343 
344     Error setEGLImageTarget(const Context *context, GLenum target, egl::Image *imageTarget);
345 
346     Error generateMipmap(const Context *context);
347 
348     egl::Surface *getBoundSurface() const;
349     egl::Stream *getBoundStream() const;
350 
351     void signalDirty(InitState initState) const;
352 
353     bool isSamplerComplete(const Context *context, const Sampler *optionalSampler);
354 
getImplementation()355     rx::TextureImpl *getImplementation() const { return mTexture; }
356 
357     // FramebufferAttachmentObject implementation
358     Extents getAttachmentSize(const ImageIndex &imageIndex) const override;
359     const Format &getAttachmentFormat(GLenum binding, const ImageIndex &imageIndex) const override;
360     GLsizei getAttachmentSamples(const ImageIndex &imageIndex) const override;
361 
362     void onAttach(const Context *context) override;
363     void onDetach(const Context *context) override;
364     GLuint getId() const override;
365 
366     // Needed for robust resource init.
367     Error ensureInitialized(const Context *context);
368     InitState initState(const ImageIndex &imageIndex) const override;
369     InitState initState() const;
370     void setInitState(const ImageIndex &imageIndex, InitState initState) override;
371 
372     enum DirtyBitType
373     {
374         // Sampler state
375         DIRTY_BIT_MIN_FILTER,
376         DIRTY_BIT_MAG_FILTER,
377         DIRTY_BIT_WRAP_S,
378         DIRTY_BIT_WRAP_T,
379         DIRTY_BIT_WRAP_R,
380         DIRTY_BIT_MAX_ANISOTROPY,
381         DIRTY_BIT_MIN_LOD,
382         DIRTY_BIT_MAX_LOD,
383         DIRTY_BIT_COMPARE_MODE,
384         DIRTY_BIT_COMPARE_FUNC,
385         DIRTY_BIT_SRGB_DECODE,
386 
387         // Texture state
388         DIRTY_BIT_SWIZZLE_RED,
389         DIRTY_BIT_SWIZZLE_GREEN,
390         DIRTY_BIT_SWIZZLE_BLUE,
391         DIRTY_BIT_SWIZZLE_ALPHA,
392         DIRTY_BIT_BASE_LEVEL,
393         DIRTY_BIT_MAX_LEVEL,
394 
395         // Misc
396         DIRTY_BIT_LABEL,
397         DIRTY_BIT_USAGE,
398 
399         DIRTY_BIT_COUNT,
400     };
401     using DirtyBits = angle::BitSet<DIRTY_BIT_COUNT>;
402 
403     void syncState();
hasAnyDirtyBit()404     bool hasAnyDirtyBit() const { return mDirtyBits.any(); }
405 
406   private:
407     rx::FramebufferAttachmentObjectImpl *getAttachmentImpl() const override;
408 
409     // ANGLE-only method, used internally
410     friend class egl::Surface;
411     Error bindTexImageFromSurface(const Context *context, egl::Surface *surface);
412     Error releaseTexImageFromSurface(const Context *context);
413 
414     // ANGLE-only methods, used internally
415     friend class egl::Stream;
416     void bindStream(egl::Stream *stream);
417     void releaseStream();
418     Error acquireImageFromStream(const Context *context,
419                                  const egl::Stream::GLTextureDescription &desc);
420     Error releaseImageFromStream(const Context *context);
421 
422     void invalidateCompletenessCache() const;
423     Error releaseTexImageInternal(const Context *context);
424 
425     Error ensureSubImageInitialized(const Context *context,
426                                     GLenum target,
427                                     size_t level,
428                                     const gl::Box &area);
429 
430     TextureState mState;
431     DirtyBits mDirtyBits;
432     rx::TextureImpl *mTexture;
433 
434     std::string mLabel;
435 
436     egl::Surface *mBoundSurface;
437     egl::Stream *mBoundStream;
438 
439     struct SamplerCompletenessCache
440     {
441         SamplerCompletenessCache();
442 
443         // Context used to generate this cache entry
444         ContextID context;
445 
446         // All values that affect sampler completeness that are not stored within
447         // the texture itself
448         SamplerState samplerState;
449 
450         // Result of the sampler completeness with the above parameters
451         bool samplerComplete;
452     };
453 
454     mutable SamplerCompletenessCache mCompletenessCache;
455 };
456 
457 inline bool operator==(const TextureState &a, const TextureState &b)
458 {
459     return a.mSwizzleState == b.mSwizzleState && a.mSamplerState == b.mSamplerState &&
460            a.mBaseLevel == b.mBaseLevel && a.mMaxLevel == b.mMaxLevel &&
461            a.mImmutableFormat == b.mImmutableFormat && a.mImmutableLevels == b.mImmutableLevels &&
462            a.mUsage == b.mUsage;
463 }
464 
465 inline bool operator!=(const TextureState &a, const TextureState &b)
466 {
467     return !(a == b);
468 }
469 }  // namespace gl
470 
471 #endif  // LIBANGLE_TEXTURE_H_
472