michael@0: // michael@0: // Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved. michael@0: // Use of this source code is governed by a BSD-style license that can be michael@0: // found in the LICENSE file. michael@0: // michael@0: michael@0: // Texture.h: Defines the abstract gl::Texture class and its concrete derived michael@0: // classes Texture2D and TextureCubeMap. Implements GL texture objects and michael@0: // related functionality. [OpenGL ES 2.0.24] section 3.7 page 63. michael@0: michael@0: #ifndef LIBGLESV2_TEXTURE_H_ michael@0: #define LIBGLESV2_TEXTURE_H_ michael@0: michael@0: #include michael@0: michael@0: #define GL_APICALL michael@0: #include michael@0: michael@0: #include "common/debug.h" michael@0: #include "common/RefCountObject.h" michael@0: #include "libGLESv2/angletypes.h" michael@0: michael@0: namespace egl michael@0: { michael@0: class Surface; michael@0: } michael@0: michael@0: namespace rx michael@0: { michael@0: class Renderer; michael@0: class TextureStorageInterface; michael@0: class TextureStorageInterface2D; michael@0: class TextureStorageInterfaceCube; michael@0: class RenderTarget; michael@0: class Image; michael@0: } michael@0: michael@0: namespace gl michael@0: { michael@0: class Framebuffer; michael@0: class Renderbuffer; michael@0: michael@0: enum michael@0: { michael@0: // These are the maximums the implementation can support michael@0: // The actual GL caps are limited by the device caps michael@0: // and should be queried from the Context michael@0: IMPLEMENTATION_MAX_TEXTURE_SIZE = 16384, michael@0: IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE = 16384, michael@0: michael@0: IMPLEMENTATION_MAX_TEXTURE_LEVELS = 15 // 1+log2 of MAX_TEXTURE_SIZE michael@0: }; michael@0: michael@0: class Texture : public RefCountObject michael@0: { michael@0: public: michael@0: Texture(rx::Renderer *renderer, GLuint id); michael@0: michael@0: virtual ~Texture(); michael@0: michael@0: virtual void addProxyRef(const Renderbuffer *proxy) = 0; michael@0: virtual void releaseProxy(const Renderbuffer *proxy) = 0; michael@0: michael@0: virtual GLenum getTarget() const = 0; michael@0: michael@0: bool setMinFilter(GLenum filter); michael@0: bool setMagFilter(GLenum filter); michael@0: bool setWrapS(GLenum wrap); michael@0: bool setWrapT(GLenum wrap); michael@0: bool setMaxAnisotropy(float textureMaxAnisotropy, float contextMaxAnisotropy); michael@0: bool setUsage(GLenum usage); michael@0: michael@0: GLenum getMinFilter() const; michael@0: GLenum getMagFilter() const; michael@0: GLenum getWrapS() const; michael@0: GLenum getWrapT() const; michael@0: float getMaxAnisotropy() const; michael@0: int getLodOffset(); michael@0: void getSamplerState(SamplerState *sampler); michael@0: GLenum getUsage() const; michael@0: bool isMipmapFiltered() const; michael@0: michael@0: virtual bool isSamplerComplete() const = 0; michael@0: michael@0: rx::TextureStorageInterface *getNativeTexture(); michael@0: virtual Renderbuffer *getRenderbuffer(GLenum target) = 0; michael@0: michael@0: virtual void generateMipmaps() = 0; michael@0: virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source) = 0; michael@0: michael@0: bool hasDirtyParameters() const; michael@0: bool hasDirtyImages() const; michael@0: void resetDirty(); michael@0: unsigned int getTextureSerial(); michael@0: unsigned int getRenderTargetSerial(GLenum target); michael@0: michael@0: bool isImmutable() const; michael@0: michael@0: static const GLuint INCOMPLETE_TEXTURE_ID = static_cast(-1); // Every texture takes an id at creation time. The value is arbitrary because it is never registered with the resource manager. michael@0: michael@0: protected: michael@0: void setImage(GLint unpackAlignment, const void *pixels, rx::Image *image); michael@0: bool subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, rx::Image *image); michael@0: void setCompressedImage(GLsizei imageSize, const void *pixels, rx::Image *image); michael@0: bool subImageCompressed(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels, rx::Image *image); michael@0: michael@0: GLint creationLevels(GLsizei width, GLsizei height) const; michael@0: GLint creationLevels(GLsizei size) const; michael@0: michael@0: virtual void createTexture() = 0; michael@0: virtual void updateTexture() = 0; michael@0: virtual void convertToRenderTarget() = 0; michael@0: virtual rx::RenderTarget *getRenderTarget(GLenum target) = 0; michael@0: michael@0: virtual int levelCount() = 0; michael@0: michael@0: rx::Renderer *mRenderer; michael@0: michael@0: SamplerState mSamplerState; michael@0: GLenum mUsage; michael@0: michael@0: bool mDirtyImages; michael@0: michael@0: bool mImmutable; michael@0: michael@0: private: michael@0: DISALLOW_COPY_AND_ASSIGN(Texture); michael@0: michael@0: virtual rx::TextureStorageInterface *getStorage(bool renderTarget) = 0; michael@0: }; michael@0: michael@0: class Texture2D : public Texture michael@0: { michael@0: public: michael@0: Texture2D(rx::Renderer *renderer, GLuint id); michael@0: michael@0: ~Texture2D(); michael@0: michael@0: void addProxyRef(const Renderbuffer *proxy); michael@0: void releaseProxy(const Renderbuffer *proxy); michael@0: michael@0: virtual GLenum getTarget() const; michael@0: michael@0: GLsizei getWidth(GLint level) const; michael@0: GLsizei getHeight(GLint level) const; michael@0: GLenum getInternalFormat(GLint level) const; michael@0: GLenum getActualFormat(GLint level) const; michael@0: bool isCompressed(GLint level) const; michael@0: bool isDepth(GLint level) const; michael@0: michael@0: void setImage(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels); michael@0: void setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels); michael@0: void subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels); michael@0: void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels); michael@0: void copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source); michael@0: virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source); michael@0: void storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); michael@0: michael@0: virtual bool isSamplerComplete() const; michael@0: virtual void bindTexImage(egl::Surface *surface); michael@0: virtual void releaseTexImage(); michael@0: michael@0: virtual void generateMipmaps(); michael@0: michael@0: virtual Renderbuffer *getRenderbuffer(GLenum target); michael@0: michael@0: protected: michael@0: friend class RenderbufferTexture2D; michael@0: virtual rx::RenderTarget *getRenderTarget(GLenum target); michael@0: virtual rx::RenderTarget *getDepthStencil(GLenum target); michael@0: virtual int levelCount(); michael@0: michael@0: private: michael@0: DISALLOW_COPY_AND_ASSIGN(Texture2D); michael@0: michael@0: virtual void createTexture(); michael@0: virtual void updateTexture(); michael@0: virtual void convertToRenderTarget(); michael@0: virtual rx::TextureStorageInterface *getStorage(bool renderTarget); michael@0: michael@0: bool isMipmapComplete() const; michael@0: michael@0: void redefineImage(GLint level, GLint internalformat, GLsizei width, GLsizei height); michael@0: void commitRect(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height); michael@0: michael@0: rx::Image *mImageArray[IMPLEMENTATION_MAX_TEXTURE_LEVELS]; michael@0: michael@0: rx::TextureStorageInterface2D *mTexStorage; michael@0: egl::Surface *mSurface; michael@0: michael@0: // A specific internal reference count is kept for colorbuffer proxy references, michael@0: // because, as the renderbuffer acting as proxy will maintain a binding pointer michael@0: // back to this texture, there would be a circular reference if we used a binding michael@0: // pointer here. This reference count will cause the pointer to be set to NULL if michael@0: // the count drops to zero, but will not cause deletion of the Renderbuffer. michael@0: Renderbuffer *mColorbufferProxy; michael@0: unsigned int mProxyRefs; michael@0: }; michael@0: michael@0: class TextureCubeMap : public Texture michael@0: { michael@0: public: michael@0: TextureCubeMap(rx::Renderer *renderer, GLuint id); michael@0: michael@0: ~TextureCubeMap(); michael@0: michael@0: void addProxyRef(const Renderbuffer *proxy); michael@0: void releaseProxy(const Renderbuffer *proxy); michael@0: michael@0: virtual GLenum getTarget() const; michael@0: michael@0: GLsizei getWidth(GLenum target, GLint level) const; michael@0: GLsizei getHeight(GLenum target, GLint level) const; michael@0: GLenum getInternalFormat(GLenum target, GLint level) const; michael@0: GLenum getActualFormat(GLenum target, GLint level) const; michael@0: bool isCompressed(GLenum target, GLint level) const; michael@0: michael@0: void setImagePosX(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels); michael@0: void setImageNegX(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels); michael@0: void setImagePosY(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels); michael@0: void setImageNegY(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels); michael@0: void setImagePosZ(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels); michael@0: void setImageNegZ(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels); michael@0: michael@0: void setCompressedImage(GLenum face, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels); michael@0: michael@0: void subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels); michael@0: void subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels); michael@0: void copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source); michael@0: virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source); michael@0: void storage(GLsizei levels, GLenum internalformat, GLsizei size); michael@0: michael@0: virtual bool isSamplerComplete() const; michael@0: michael@0: virtual void generateMipmaps(); michael@0: michael@0: virtual Renderbuffer *getRenderbuffer(GLenum target); michael@0: michael@0: static unsigned int faceIndex(GLenum face); michael@0: michael@0: protected: michael@0: friend class RenderbufferTextureCubeMap; michael@0: virtual rx::RenderTarget *getRenderTarget(GLenum target); michael@0: virtual int levelCount(); michael@0: michael@0: private: michael@0: DISALLOW_COPY_AND_ASSIGN(TextureCubeMap); michael@0: michael@0: virtual void createTexture(); michael@0: virtual void updateTexture(); michael@0: virtual void convertToRenderTarget(); michael@0: virtual rx::TextureStorageInterface *getStorage(bool renderTarget); michael@0: michael@0: bool isCubeComplete() const; michael@0: bool isMipmapCubeComplete() const; michael@0: michael@0: void setImage(int faceIndex, GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels); michael@0: void commitRect(int faceIndex, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height); michael@0: void redefineImage(int faceIndex, GLint level, GLint internalformat, GLsizei width, GLsizei height); michael@0: michael@0: rx::Image *mImageArray[6][IMPLEMENTATION_MAX_TEXTURE_LEVELS]; michael@0: michael@0: rx::TextureStorageInterfaceCube *mTexStorage; michael@0: michael@0: // A specific internal reference count is kept for colorbuffer proxy references, michael@0: // because, as the renderbuffer acting as proxy will maintain a binding pointer michael@0: // back to this texture, there would be a circular reference if we used a binding michael@0: // pointer here. This reference count will cause the pointer to be set to NULL if michael@0: // the count drops to zero, but will not cause deletion of the Renderbuffer. michael@0: Renderbuffer *mFaceProxies[6]; michael@0: unsigned int *mFaceProxyRefs[6]; michael@0: }; michael@0: } michael@0: michael@0: #endif // LIBGLESV2_TEXTURE_H_