Home | History | Annotate | Download | only in libGLESv2
      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