Home | History | Annotate | Download | only in libGLESv2
      1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved.
      2 //
      3 // Licensed under the Apache License, Version 2.0 (the "License");
      4 // you may not use this file except in compliance with the License.
      5 // You may obtain a copy of the License at
      6 //
      7 //    http://www.apache.org/licenses/LICENSE-2.0
      8 //
      9 // Unless required by applicable law or agreed to in writing, software
     10 // distributed under the License is distributed on an "AS IS" BASIS,
     11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 // See the License for the specific language governing permissions and
     13 // limitations under the License.
     14 
     15 // Texture.h: Defines the abstract Texture class and its concrete derived
     16 // classes Texture2D and TextureCubeMap. Implements GL texture objects and
     17 // related functionality. [OpenGL ES 2.0.24] section 3.7 page 63.
     18 
     19 #ifndef LIBGLESV2_TEXTURE_H_
     20 #define LIBGLESV2_TEXTURE_H_
     21 
     22 #include "Renderbuffer.h"
     23 #include "common/Object.hpp"
     24 #include "utilities.h"
     25 #include "libEGL/Texture.hpp"
     26 #include "common/debug.h"
     27 
     28 #include <GLES2/gl2.h>
     29 
     30 #include <vector>
     31 
     32 namespace gl { class Surface; }
     33 
     34 namespace es2
     35 {
     36 class Sampler;
     37 
     38 enum
     39 {
     40 	IMPLEMENTATION_MAX_TEXTURE_LEVELS = sw::MIPMAP_LEVELS,
     41 	IMPLEMENTATION_MAX_TEXTURE_SIZE = 1 << (IMPLEMENTATION_MAX_TEXTURE_LEVELS - 1),
     42 	IMPLEMENTATION_MAX_3D_TEXTURE_SIZE = IMPLEMENTATION_MAX_TEXTURE_SIZE,
     43 	IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE = IMPLEMENTATION_MAX_TEXTURE_SIZE,
     44 	IMPLEMENTATION_MAX_ARRAY_TEXTURE_LAYERS = IMPLEMENTATION_MAX_TEXTURE_SIZE,
     45 	IMPLEMENTATION_MAX_RENDERBUFFER_SIZE = sw::OUTLINE_RESOLUTION,
     46 };
     47 
     48 class ImageLevels
     49 {
     50 public:
     51 	inline const egl::Image* operator[](size_t index) const
     52 	{
     53 		return (index < IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? image[index] : nullptr;
     54 	}
     55 
     56 	inline egl::Image*& operator[](size_t index)
     57 	{
     58 		if(index < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
     59 		{
     60 			return image[index];
     61 		}
     62 
     63 		return getNullImage();
     64 	}
     65 
     66 	inline void release()
     67 	{
     68 		for(int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
     69 		{
     70 			if(image[i])
     71 			{
     72 				image[i]->release();
     73 				image[i] = nullptr;
     74 			}
     75 		}
     76 	}
     77 
     78 	inline void unbind(const egl::Texture* texture)
     79 	{
     80 		for(int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
     81 		{
     82 			if(image[i])
     83 			{
     84 				image[i]->unbind(texture);
     85 				image[i] = nullptr;
     86 			}
     87 		}
     88 	}
     89 
     90 private:
     91 	egl::Image *image[IMPLEMENTATION_MAX_TEXTURE_LEVELS] = {};
     92     static egl::Image*& getNullImage();
     93 };
     94 
     95 class Texture : public egl::Texture
     96 {
     97 public:
     98 	explicit Texture(GLuint name);
     99 
    100 	sw::Resource *getResource() const override;
    101 
    102 	virtual void addProxyRef(const Renderbuffer *proxy) = 0;
    103 	virtual void releaseProxy(const Renderbuffer *proxy) = 0;
    104 
    105 	virtual GLenum getTarget() const = 0;
    106 
    107 	bool setMinFilter(GLenum filter);
    108 	bool setMagFilter(GLenum filter);
    109 	bool setWrapS(GLenum wrap);
    110 	bool setWrapT(GLenum wrap);
    111 	bool setWrapR(GLenum wrap);
    112 	bool setMaxAnisotropy(GLfloat textureMaxAnisotropy);
    113 	bool setBaseLevel(GLint baseLevel);
    114 	bool setCompareFunc(GLenum compareFunc);
    115 	bool setCompareMode(GLenum compareMode);
    116 	void makeImmutable(GLsizei levels);
    117 	bool setMaxLevel(GLint maxLevel);
    118 	bool setMaxLOD(GLfloat maxLOD);
    119 	bool setMinLOD(GLfloat minLOD);
    120 	bool setSwizzleR(GLenum swizzleR);
    121 	bool setSwizzleG(GLenum swizzleG);
    122 	bool setSwizzleB(GLenum swizzleB);
    123 	bool setSwizzleA(GLenum swizzleA);
    124 
    125 	GLenum getMinFilter() const { return mMinFilter; }
    126 	GLenum getMagFilter() const { return mMagFilter; }
    127 	GLenum getWrapS() const { return mWrapS; }
    128 	GLenum getWrapT() const { return mWrapT; }
    129 	GLenum getWrapR() const { return mWrapR; }
    130 	GLfloat getMaxAnisotropy() const { return mMaxAnisotropy; }
    131 	GLint getBaseLevel() const { return mBaseLevel; }
    132 	GLenum getCompareFunc() const { return mCompareFunc; }
    133 	GLenum getCompareMode() const { return mCompareMode; }
    134 	GLboolean getImmutableFormat() const { return mImmutableFormat; }
    135 	GLsizei getImmutableLevels() const { return mImmutableLevels; }
    136 	GLint getMaxLevel() const { return mMaxLevel; }
    137 	GLfloat getMaxLOD() const { return mMaxLOD; }
    138 	GLfloat getMinLOD() const { return mMinLOD; }
    139 	GLenum getSwizzleR() const { return mSwizzleR; }
    140 	GLenum getSwizzleG() const { return mSwizzleG; }
    141 	GLenum getSwizzleB() const { return mSwizzleB; }
    142 	GLenum getSwizzleA() const { return mSwizzleA; }
    143 
    144 	virtual GLsizei getWidth(GLenum target, GLint level) const = 0;
    145 	virtual GLsizei getHeight(GLenum target, GLint level) const = 0;
    146 	virtual GLsizei getDepth(GLenum target, GLint level) const;
    147 	virtual GLint getFormat(GLenum target, GLint level) const = 0;
    148 	virtual int getTopLevel() const = 0;
    149 	virtual bool requiresSync() const = 0;
    150 
    151 	virtual bool isSamplerComplete(Sampler *sampler) const = 0;
    152 	virtual bool isCompressed(GLenum target, GLint level) const = 0;
    153 	virtual bool isDepth(GLenum target, GLint level) const = 0;
    154 
    155 	virtual Renderbuffer *getRenderbuffer(GLenum target, GLint level) = 0;
    156 	virtual egl::Image *getRenderTarget(GLenum target, unsigned int level) = 0;
    157 	egl::Image *createSharedImage(GLenum target, unsigned int level);
    158 	virtual bool isShared(GLenum target, unsigned int level) const = 0;
    159 
    160 	virtual void generateMipmaps() = 0;
    161 	virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Renderbuffer *source) = 0;
    162 
    163 protected:
    164 	~Texture() override;
    165 
    166 	void setImage(GLenum format, GLenum type, const gl::PixelStorageModes &unpackParameters, const void *pixels, egl::Image *image);
    167 	void subImage(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelStorageModes &unpackParameters, const void *pixels, egl::Image *image);
    168 	void setCompressedImage(GLsizei imageSize, const void *pixels, egl::Image *image);
    169 	void subImageCompressed(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels, egl::Image *image);
    170 
    171 	bool copy(egl::Image *source, const sw::SliceRect &sourceRect, GLint xoffset, GLint yoffset, GLint zoffset, egl::Image *dest);
    172 
    173 	bool isMipmapFiltered(Sampler *sampler) const;
    174 
    175 	GLenum mMinFilter;
    176 	GLenum mMagFilter;
    177 	GLenum mWrapS;
    178 	GLenum mWrapT;
    179 	GLenum mWrapR;
    180 	GLfloat mMaxAnisotropy;
    181 	GLint mBaseLevel;
    182 	GLenum mCompareFunc;
    183 	GLenum mCompareMode;
    184 	GLboolean mImmutableFormat;
    185 	GLsizei mImmutableLevels;
    186 	GLint mMaxLevel;
    187 	GLfloat mMaxLOD;
    188 	GLfloat mMinLOD;
    189 	GLenum mSwizzleR;
    190 	GLenum mSwizzleG;
    191 	GLenum mSwizzleB;
    192 	GLenum mSwizzleA;
    193 
    194 	sw::Resource *resource;
    195 };
    196 
    197 class Texture2D : public Texture
    198 {
    199 public:
    200 	explicit Texture2D(GLuint name);
    201 
    202 	void addProxyRef(const Renderbuffer *proxy) override;
    203 	void releaseProxy(const Renderbuffer *proxy) override;
    204 	void sweep() override;
    205 
    206 	GLenum getTarget() const override;
    207 
    208 	GLsizei getWidth(GLenum target, GLint level) const override;
    209 	GLsizei getHeight(GLenum target, GLint level) const override;
    210 	GLint getFormat(GLenum target, GLint level) const override;
    211 	int getTopLevel() const override;
    212 	bool requiresSync() const override;
    213 
    214 	void setImage(GLint level, GLsizei width, GLsizei height, GLint internalformat, GLenum format, GLenum type, const gl::PixelStorageModes &unpackParameters, const void *pixels);
    215 	void setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels);
    216 	void subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const gl::PixelStorageModes &unpackParameters, const void *pixels);
    217 	void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels);
    218 	void copyImage(GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, Renderbuffer *source);
    219 	void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Renderbuffer *source) override;
    220 
    221 	void setSharedImage(egl::Image *image);
    222 
    223 	bool isSamplerComplete(Sampler *sampler) const override;
    224 	bool isCompressed(GLenum target, GLint level) const override;
    225 	bool isDepth(GLenum target, GLint level) const override;
    226 	void bindTexImage(gl::Surface *surface);
    227 	void releaseTexImage() override;
    228 
    229 	void generateMipmaps() override;
    230 
    231 	Renderbuffer *getRenderbuffer(GLenum target, GLint level) override;
    232 	egl::Image *getRenderTarget(GLenum target, unsigned int level) override;
    233 	bool isShared(GLenum target, unsigned int level) const override;
    234 
    235 	egl::Image *getImage(unsigned int level);
    236 
    237 protected:
    238 	~Texture2D() override;
    239 
    240 	bool isMipmapComplete() const;
    241 
    242 	ImageLevels image;
    243 
    244 	gl::Surface *mSurface;
    245 
    246 	// A specific internal reference count is kept for colorbuffer proxy references,
    247 	// because, as the renderbuffer acting as proxy will maintain a binding pointer
    248 	// back to this texture, there would be a circular reference if we used a binding
    249 	// pointer here. This reference count will cause the pointer to be set to null if
    250 	// the count drops to zero, but will not cause deletion of the Renderbuffer.
    251 	Renderbuffer *mColorbufferProxy;
    252 	unsigned int mProxyRefs;
    253 };
    254 
    255 class Texture2DRect : public Texture2D
    256 {
    257 public:
    258 	explicit Texture2DRect(GLuint name);
    259 
    260 	GLenum getTarget() const override;
    261 
    262 	Renderbuffer *getRenderbuffer(GLenum target, GLint level) override;
    263 };
    264 
    265 class TextureCubeMap : public Texture
    266 {
    267 public:
    268 	explicit TextureCubeMap(GLuint name);
    269 
    270 	void addProxyRef(const Renderbuffer *proxy) override;
    271 	void releaseProxy(const Renderbuffer *proxy) override;
    272 	void sweep() override;
    273 
    274 	GLenum getTarget() const override;
    275 
    276 	GLsizei getWidth(GLenum target, GLint level) const override;
    277 	GLsizei getHeight(GLenum target, GLint level) const override;
    278 	GLint getFormat(GLenum target, GLint level) const override;
    279 	int getTopLevel() const override;
    280 	bool requiresSync() const override;
    281 
    282 	void setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLint internalformat, GLenum format, GLenum type, const gl::PixelStorageModes &unpackParameters, const void *pixels);
    283 	void setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels);
    284 
    285 	void subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const gl::PixelStorageModes &unpackParameters, const void *pixels);
    286 	void subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels);
    287 	void copyImage(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, Renderbuffer *source);
    288 	void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Renderbuffer *source) override;
    289 
    290 	bool isSamplerComplete(Sampler *sampler) const override;
    291 	bool isCompressed(GLenum target, GLint level) const override;
    292 	bool isDepth(GLenum target, GLint level) const override;
    293 	void releaseTexImage() override;
    294 
    295 	void generateMipmaps() override;
    296 	void updateBorders(int level);
    297 
    298 	Renderbuffer *getRenderbuffer(GLenum target, GLint level) override;
    299 	egl::Image *getRenderTarget(GLenum target, unsigned int level) override;
    300 	bool isShared(GLenum target, unsigned int level) const override;
    301 
    302 	egl::Image *getImage(int face, unsigned int level);
    303 
    304 	bool isCubeComplete() const;
    305 
    306 protected:
    307 	~TextureCubeMap() override;
    308 
    309 private:
    310 	bool isMipmapCubeComplete() const;
    311 
    312 	// face is one of the GL_TEXTURE_CUBE_MAP_* enumerants. Returns nullptr on failure.
    313 	egl::Image *getImage(GLenum face, unsigned int level);
    314 
    315 	ImageLevels image[6];
    316 
    317 	// A specific internal reference count is kept for colorbuffer proxy references,
    318 	// because, as the renderbuffer acting as proxy will maintain a binding pointer
    319 	// back to this texture, there would be a circular reference if we used a binding
    320 	// pointer here. This reference count will cause the pointer to be set to null if
    321 	// the count drops to zero, but will not cause deletion of the Renderbuffer.
    322 	Renderbuffer *mFaceProxies[6];
    323 	unsigned int mFaceProxyRefs[6];
    324 };
    325 
    326 class Texture3D : public Texture
    327 {
    328 public:
    329 	explicit Texture3D(GLuint name);
    330 
    331 	void addProxyRef(const Renderbuffer *proxy) override;
    332 	void releaseProxy(const Renderbuffer *proxy) override;
    333 	void sweep() override;
    334 
    335 	GLenum getTarget() const override;
    336 
    337 	GLsizei getWidth(GLenum target, GLint level) const override;
    338 	GLsizei getHeight(GLenum target, GLint level) const override;
    339 	GLsizei getDepth(GLenum target, GLint level) const override;
    340 	GLint getFormat(GLenum target, GLint level) const override;
    341 	int getTopLevel() const override;
    342 	bool requiresSync() const override;
    343 
    344 	void setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLint internalformat, GLenum format, GLenum type, const gl::PixelStorageModes &unpackParameters, const void *pixels);
    345 	void setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels);
    346 	void subImage(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelStorageModes &unpackParameters, const void *pixels);
    347 	void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels);
    348 	void copyImage(GLint level, GLenum internalformat, GLint x, GLint y, GLint z, GLsizei width, GLsizei height, GLsizei depth, Renderbuffer *source);
    349 	void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Renderbuffer *source) override;
    350 
    351 	void setSharedImage(egl::Image *image);
    352 
    353 	bool isSamplerComplete(Sampler *sampler) const override;
    354 	bool isCompressed(GLenum target, GLint level) const override;
    355 	bool isDepth(GLenum target, GLint level) const override;
    356 	void releaseTexImage() override;
    357 
    358 	void generateMipmaps() override;
    359 
    360 	Renderbuffer *getRenderbuffer(GLenum target, GLint level) override;
    361 	egl::Image *getRenderTarget(GLenum target, unsigned int level) override;
    362 	bool isShared(GLenum target, unsigned int level) const override;
    363 
    364 	egl::Image *getImage(unsigned int level);
    365 
    366 protected:
    367 	~Texture3D() override;
    368 
    369 	bool isMipmapComplete() const;
    370 
    371 	ImageLevels image;
    372 
    373 	gl::Surface *mSurface;
    374 
    375 	// A specific internal reference count is kept for colorbuffer proxy references,
    376 	// because, as the renderbuffer acting as proxy will maintain a binding pointer
    377 	// back to this texture, there would be a circular reference if we used a binding
    378 	// pointer here. This reference count will cause the pointer to be set to null if
    379 	// the count drops to zero, but will not cause deletion of the Renderbuffer.
    380 	Renderbuffer *mColorbufferProxy;
    381 	unsigned int mProxyRefs;
    382 };
    383 
    384 class Texture2DArray : public Texture3D
    385 {
    386 public:
    387 	explicit Texture2DArray(GLuint name);
    388 
    389 	GLenum getTarget() const override;
    390 	void generateMipmaps() override;
    391 
    392 protected:
    393 	~Texture2DArray() override;
    394 };
    395 
    396 class TextureExternal : public Texture2D
    397 {
    398 public:
    399 	explicit TextureExternal(GLuint name);
    400 
    401 	GLenum getTarget() const override;
    402 
    403 protected:
    404 	~TextureExternal() override;
    405 };
    406 }
    407 
    408 #endif   // LIBGLESV2_TEXTURE_H_
    409