• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 abstract gl::Texture class and its concrete derived
8 // classes Texture2D and TextureCubeMap. Implements GL texture objects and
9 // related functionality. [OpenGL ES 2.0.24] section 3.7 page 63.
10 
11 #ifndef LIBGLESV2_TEXTURE_H_
12 #define LIBGLESV2_TEXTURE_H_
13 
14 #include <vector>
15 
16 #include <GLES3/gl3.h>
17 #include <GLES2/gl2.h>
18 
19 #include "common/debug.h"
20 #include "common/RefCountObject.h"
21 #include "libGLESv2/angletypes.h"
22 #include "libGLESv2/RenderbufferProxySet.h"
23 
24 namespace egl
25 {
26 class Surface;
27 }
28 
29 namespace rx
30 {
31 class Renderer;
32 class TextureStorageInterface;
33 class TextureStorageInterface2D;
34 class TextureStorageInterfaceCube;
35 class TextureStorageInterface3D;
36 class TextureStorageInterface2DArray;
37 class RenderTarget;
38 class Image;
39 }
40 
41 namespace gl
42 {
43 class Framebuffer;
44 class FramebufferAttachment;
45 
46 enum
47 {
48     // These are the maximums the implementation can support
49     // The actual GL caps are limited by the device caps
50     // and should be queried from the Context
51     IMPLEMENTATION_MAX_2D_TEXTURE_SIZE = 16384,
52     IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE = 16384,
53     IMPLEMENTATION_MAX_3D_TEXTURE_SIZE = 2048,
54     IMPLEMENTATION_MAX_2D_ARRAY_TEXTURE_LAYERS = 2048,
55 
56     IMPLEMENTATION_MAX_TEXTURE_LEVELS = 15   // 1+log2 of MAX_TEXTURE_SIZE
57 };
58 
59 bool IsMipmapFiltered(const SamplerState &samplerState);
60 
61 class Texture : public RefCountObject
62 {
63   public:
64     Texture(rx::Renderer *renderer, GLuint id, GLenum target);
65 
66     virtual ~Texture();
67 
68     void addProxyRef(const FramebufferAttachment *proxy);
69     void releaseProxy(const FramebufferAttachment *proxy);
70 
71     GLenum getTarget() const;
72 
73     void setMinFilter(GLenum filter);
74     void setMagFilter(GLenum filter);
75     void setWrapS(GLenum wrap);
76     void setWrapT(GLenum wrap);
77     void setWrapR(GLenum wrap);
78     void setMaxAnisotropy(float textureMaxAnisotropy, float contextMaxAnisotropy);
79     void setCompareMode(GLenum mode);
80     void setCompareFunc(GLenum func);
81     void setSwizzleRed(GLenum swizzle);
82     void setSwizzleGreen(GLenum swizzle);
83     void setSwizzleBlue(GLenum swizzle);
84     void setSwizzleAlpha(GLenum swizzle);
85     void setBaseLevel(GLint baseLevel);
86     void setMaxLevel(GLint maxLevel);
87     void setMinLod(GLfloat minLod);
88     void setMaxLod(GLfloat maxLod);
89     void setUsage(GLenum usage);
90 
91     GLenum getMinFilter() const;
92     GLenum getMagFilter() const;
93     GLenum getWrapS() const;
94     GLenum getWrapT() const;
95     GLenum getWrapR() const;
96     float getMaxAnisotropy() const;
97     GLenum getSwizzleRed() const;
98     GLenum getSwizzleGreen() const;
99     GLenum getSwizzleBlue() const;
100     GLenum getSwizzleAlpha() const;
101     GLint getBaseLevel() const;
102     GLint getMaxLevel() const;
103     GLfloat getMinLod() const;
104     GLfloat getMaxLod() const;
105     bool isSwizzled() const;
106     void getSamplerState(SamplerState *sampler);
107     GLenum getUsage() const;
108 
109     GLint getBaseLevelWidth() const;
110     GLint getBaseLevelHeight() const;
111     GLint getBaseLevelDepth() const;
112     GLenum getBaseLevelInternalFormat() const;
113 
114     virtual bool isSamplerComplete(const SamplerState &samplerState) const = 0;
115 
116     rx::TextureStorageInterface *getNativeTexture();
117 
118     virtual void generateMipmaps() = 0;
119     virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source) = 0;
120 
121     bool hasDirtyParameters() const;
122     bool hasDirtyImages() const;
123     void resetDirty();
124     unsigned int getTextureSerial();
125 
126     bool isImmutable() const;
127     int immutableLevelCount();
128 
129     static const GLuint INCOMPLETE_TEXTURE_ID = static_cast<GLuint>(-1);   // Every texture takes an id at creation time. The value is arbitrary because it is never registered with the resource manager.
130 
131   protected:
132     void setImage(const PixelUnpackState &unpack, GLenum type, const void *pixels, rx::Image *image);
133     bool subImage(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
134                   GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels, rx::Image *image);
135     void setCompressedImage(GLsizei imageSize, const void *pixels, rx::Image *image);
136     bool subImageCompressed(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
137                             GLenum format, GLsizei imageSize, const void *pixels, rx::Image *image);
138     bool isFastUnpackable(const PixelUnpackState &unpack, GLenum sizedInternalFormat);
139     bool fastUnpackPixels(const PixelUnpackState &unpack, const void *pixels, const Box &destArea,
140                           GLenum sizedInternalFormat, GLenum type, rx::RenderTarget *destRenderTarget);
141 
142     GLint creationLevels(GLsizei width, GLsizei height, GLsizei depth) const;
143     int mipLevels() const;
144 
145     virtual void initializeStorage(bool renderTarget) = 0;
146     virtual void updateStorage() = 0;
147     virtual bool ensureRenderTarget() = 0;
148 
149     rx::Renderer *mRenderer;
150 
151     SamplerState mSamplerState;
152     GLenum mUsage;
153 
154     bool mDirtyImages;
155 
156     bool mImmutable;
157 
158     GLenum mTarget;
159 
160     // A specific internal reference count is kept for colorbuffer proxy references,
161     // because, as the renderbuffer acting as proxy will maintain a binding pointer
162     // back to this texture, there would be a circular reference if we used a binding
163     // pointer here. This reference count will cause the pointer to be set to NULL if
164     // the count drops to zero, but will not cause deletion of the FramebufferAttachment.
165     RenderbufferProxySet mRenderbufferProxies;
166 
167   private:
168     DISALLOW_COPY_AND_ASSIGN(Texture);
169 
170     virtual rx::TextureStorageInterface *getBaseLevelStorage() = 0;
171     virtual const rx::Image *getBaseLevelImage() const = 0;
172 };
173 
174 class Texture2D : public Texture
175 {
176   public:
177     Texture2D(rx::Renderer *renderer, GLuint id);
178 
179     ~Texture2D();
180 
181     GLsizei getWidth(GLint level) const;
182     GLsizei getHeight(GLint level) const;
183     GLenum getInternalFormat(GLint level) const;
184     GLenum getActualFormat(GLint level) const;
185     bool isCompressed(GLint level) const;
186     bool isDepth(GLint level) const;
187 
188     void setImage(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
189     void setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels);
190     void subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
191     void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels);
192     void copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
193     virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
194     void storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
195 
196     virtual bool isSamplerComplete(const SamplerState &samplerState) const;
197     virtual void bindTexImage(egl::Surface *surface);
198     virtual void releaseTexImage();
199 
200     virtual void generateMipmaps();
201 
202     FramebufferAttachment *getAttachment(GLint level);
203     unsigned int getRenderTargetSerial(GLint level);
204 
205   protected:
206     friend class Texture2DAttachment;
207     rx::RenderTarget *getRenderTarget(GLint level);
208     rx::RenderTarget *getDepthSencil(GLint level);
209 
210   private:
211     DISALLOW_COPY_AND_ASSIGN(Texture2D);
212 
213     virtual void initializeStorage(bool renderTarget);
214     rx::TextureStorageInterface2D *createCompleteStorage(bool renderTarget) const;
215     void setCompleteTexStorage(rx::TextureStorageInterface2D *newCompleteTexStorage);
216 
217     virtual void updateStorage();
218     virtual bool ensureRenderTarget();
219     virtual rx::TextureStorageInterface *getBaseLevelStorage();
220     virtual const rx::Image *getBaseLevelImage() const;
221 
222     bool isMipmapComplete() const;
223     bool isValidLevel(int level) const;
224     bool isLevelComplete(int level) const;
225     void updateStorageLevel(int level);
226 
227     void redefineImage(GLint level, GLenum internalformat, GLsizei width, GLsizei height);
228     void commitRect(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
229 
230     rx::Image *mImageArray[IMPLEMENTATION_MAX_TEXTURE_LEVELS];
231 
232     rx::TextureStorageInterface2D *mTexStorage;
233     egl::Surface *mSurface;
234 };
235 
236 class TextureCubeMap : public Texture
237 {
238   public:
239     TextureCubeMap(rx::Renderer *renderer, GLuint id);
240 
241     ~TextureCubeMap();
242 
243     GLsizei getWidth(GLenum target, GLint level) const;
244     GLsizei getHeight(GLenum target, GLint level) const;
245     GLenum getInternalFormat(GLenum target, GLint level) const;
246     GLenum getActualFormat(GLenum target, GLint level) const;
247     bool isCompressed(GLenum target, GLint level) const;
248     bool isDepth(GLenum target, GLint level) const;
249 
250     void setImagePosX(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
251     void setImageNegX(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
252     void setImagePosY(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
253     void setImageNegY(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
254     void setImagePosZ(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
255     void setImageNegZ(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
256 
257     void setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels);
258 
259     void subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
260     void subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels);
261     void copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
262     virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
263     void storage(GLsizei levels, GLenum internalformat, GLsizei size);
264 
265     virtual bool isSamplerComplete(const SamplerState &samplerState) const;
266     bool isCubeComplete() const;
267 
268     virtual void generateMipmaps();
269 
270     FramebufferAttachment *getAttachment(GLenum target, GLint level);
271     unsigned int getRenderTargetSerial(GLenum target, GLint level);
272 
273     static int targetToIndex(GLenum target);
274 
275   protected:
276     friend class TextureCubeMapAttachment;
277     rx::RenderTarget *getRenderTarget(GLenum target, GLint level);
278     rx::RenderTarget *getDepthStencil(GLenum target, GLint level);
279 
280   private:
281     DISALLOW_COPY_AND_ASSIGN(TextureCubeMap);
282 
283     virtual void initializeStorage(bool renderTarget);
284     rx::TextureStorageInterfaceCube *createCompleteStorage(bool renderTarget) const;
285     void setCompleteTexStorage(rx::TextureStorageInterfaceCube *newCompleteTexStorage);
286 
287     virtual void updateStorage();
288     virtual bool ensureRenderTarget();
289     virtual rx::TextureStorageInterface *getBaseLevelStorage();
290     virtual const rx::Image *getBaseLevelImage() const;
291 
292     bool isMipmapCubeComplete() const;
293     bool isValidFaceLevel(int faceIndex, int level) const;
294     bool isFaceLevelComplete(int faceIndex, int level) const;
295     void updateStorageFaceLevel(int faceIndex, int level);
296 
297     void setImage(int faceIndex, GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
298     void commitRect(int faceIndex, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
299     void redefineImage(int faceIndex, GLint level, GLenum internalformat, GLsizei width, GLsizei height);
300 
301     rx::Image *mImageArray[6][IMPLEMENTATION_MAX_TEXTURE_LEVELS];
302 
303     rx::TextureStorageInterfaceCube *mTexStorage;
304 };
305 
306 class Texture3D : public Texture
307 {
308   public:
309     Texture3D(rx::Renderer *renderer, GLuint id);
310 
311     ~Texture3D();
312 
313     GLsizei getWidth(GLint level) const;
314     GLsizei getHeight(GLint level) const;
315     GLsizei getDepth(GLint level) const;
316     GLenum getInternalFormat(GLint level) const;
317     GLenum getActualFormat(GLint level) const;
318     bool isCompressed(GLint level) const;
319     bool isDepth(GLint level) const;
320 
321     void setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
322     void setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels);
323     void subImage(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
324     void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels);
325     void storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
326 
327     virtual void generateMipmaps();
328     virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
329 
330     virtual bool isSamplerComplete(const SamplerState &samplerState) const;
331     virtual bool isMipmapComplete() const;
332 
333     FramebufferAttachment *getAttachment(GLint level, GLint layer);
334     unsigned int getRenderTargetSerial(GLint level, GLint layer);
335 
336   protected:
337     friend class Texture3DAttachment;
338     rx::RenderTarget *getRenderTarget(GLint level);
339     rx::RenderTarget *getRenderTarget(GLint level, GLint layer);
340     rx::RenderTarget *getDepthStencil(GLint level, GLint layer);
341 
342   private:
343     DISALLOW_COPY_AND_ASSIGN(Texture3D);
344 
345     virtual void initializeStorage(bool renderTarget);
346     rx::TextureStorageInterface3D *createCompleteStorage(bool renderTarget) const;
347     void setCompleteTexStorage(rx::TextureStorageInterface3D *newCompleteTexStorage);
348 
349     virtual void updateStorage();
350     virtual bool ensureRenderTarget();
351 
352     virtual rx::TextureStorageInterface *getBaseLevelStorage();
353     virtual const rx::Image *getBaseLevelImage() const;
354 
355     void redefineImage(GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
356     void commitRect(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth);
357 
358     bool isValidLevel(int level) const;
359     bool isLevelComplete(int level) const;
360     void updateStorageLevel(int level);
361 
362     rx::Image *mImageArray[IMPLEMENTATION_MAX_TEXTURE_LEVELS];
363 
364     rx::TextureStorageInterface3D *mTexStorage;
365 };
366 
367 class Texture2DArray : public Texture
368 {
369   public:
370     Texture2DArray(rx::Renderer *renderer, GLuint id);
371 
372     ~Texture2DArray();
373 
374     GLsizei getWidth(GLint level) const;
375     GLsizei getHeight(GLint level) const;
376     GLsizei getLayers(GLint level) const;
377     GLenum getInternalFormat(GLint level) const;
378     GLenum getActualFormat(GLint level) const;
379     bool isCompressed(GLint level) const;
380     bool isDepth(GLint level) const;
381 
382     void setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
383     void setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels);
384     void subImage(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
385     void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels);
386     void storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
387 
388     virtual void generateMipmaps();
389     virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
390 
391     virtual bool isSamplerComplete(const SamplerState &samplerState) const;
392     virtual bool isMipmapComplete() const;
393 
394     FramebufferAttachment *getAttachment(GLint level, GLint layer);
395     unsigned int getRenderTargetSerial(GLint level, GLint layer);
396 
397   protected:
398     friend class Texture2DArrayAttachment;
399     rx::RenderTarget *getRenderTarget(GLint level, GLint layer);
400     rx::RenderTarget *getDepthStencil(GLint level, GLint layer);
401 
402   private:
403     DISALLOW_COPY_AND_ASSIGN(Texture2DArray);
404 
405     virtual void initializeStorage(bool renderTarget);
406     rx::TextureStorageInterface2DArray *createCompleteStorage(bool renderTarget) const;
407     void setCompleteTexStorage(rx::TextureStorageInterface2DArray *newCompleteTexStorage);
408 
409     virtual void updateStorage();
410     virtual bool ensureRenderTarget();
411 
412     virtual rx::TextureStorageInterface *getBaseLevelStorage();
413     virtual const rx::Image *getBaseLevelImage() const;
414 
415     void deleteImages();
416     void redefineImage(GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
417     void commitRect(GLint level, GLint xoffset, GLint yoffset, GLint layerTarget, GLsizei width, GLsizei height);
418 
419     bool isValidLevel(int level) const;
420     bool isLevelComplete(int level) const;
421     void updateStorageLevel(int level);
422 
423     // Storing images as an array of single depth textures since D3D11 treats each array level of a
424     // Texture2D object as a separate subresource.  Each layer would have to be looped over
425     // to update all the texture layers since they cannot all be updated at once and it makes the most
426     // sense for the Image class to not have to worry about layer subresource as well as mip subresources.
427     GLsizei mLayerCounts[IMPLEMENTATION_MAX_TEXTURE_LEVELS];
428     rx::Image **mImageArray[IMPLEMENTATION_MAX_TEXTURE_LEVELS];
429 
430     rx::TextureStorageInterface2DArray *mTexStorage;
431 };
432 
433 }
434 
435 #endif   // LIBGLESV2_TEXTURE_H_
436