// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Texture.cpp: Implements the Texture class and its derived classes
// Texture2D, TextureCubeMap, Texture3D and Texture2DArray. Implements GL texture objects
// and related functionality. [OpenGL ES 2.0.24] section 3.7 page 63.

#include "Texture.h"

#include "main.h"
#include "mathutil.h"
#include "Framebuffer.h"
#include "Device.hpp"
#include "Sampler.h"
#include "Shader.h"
#include "libEGL/Display.h"
#include "common/Surface.hpp"
#include "common/debug.h"

#include <algorithm>

namespace es2
{

egl::Image*& ImageLevels::getNullImage()
{
    static egl::Image* nullImage;
    nullImage = nullptr;
    return nullImage;
}

Texture::Texture(GLuint name) : egl::Texture(name)
{
	mMinFilter = GL_NEAREST_MIPMAP_LINEAR;
	mMagFilter = GL_LINEAR;
	mWrapS = GL_REPEAT;
	mWrapT = GL_REPEAT;
	mWrapR = GL_REPEAT;
	mMaxAnisotropy = 1.0f;
	mBaseLevel = 0;
	mCompareFunc = GL_LEQUAL;
	mCompareMode = GL_NONE;
	mImmutableFormat = GL_FALSE;
	mImmutableLevels = 0;
	mMaxLevel = 1000;
	mMaxLOD = 1000;
	mMinLOD = -1000;
	mSwizzleR = GL_RED;
	mSwizzleG = GL_GREEN;
	mSwizzleB = GL_BLUE;
	mSwizzleA = GL_ALPHA;

	resource = new sw::Resource(0);
}

Texture::~Texture()
{
	resource->destruct();
}

sw::Resource *Texture::getResource() const
{
	return resource;
}

// Returns true on successful filter state update (valid enum parameter)
bool Texture::setMinFilter(GLenum filter)
{
	switch(filter)
	{
	case GL_NEAREST_MIPMAP_NEAREST:
	case GL_LINEAR_MIPMAP_NEAREST:
	case GL_NEAREST_MIPMAP_LINEAR:
	case GL_LINEAR_MIPMAP_LINEAR:
		if((getTarget() == GL_TEXTURE_EXTERNAL_OES) || (getTarget() == GL_TEXTURE_RECTANGLE_ARB))
		{
			return false;
		}
		// Fall through
	case GL_NEAREST:
	case GL_LINEAR:
		mMinFilter = filter;
		return true;
	default:
		return false;
	}
}

// Returns true on successful filter state update (valid enum parameter)
bool Texture::setMagFilter(GLenum filter)
{
	switch(filter)
	{
	case GL_NEAREST:
	case GL_LINEAR:
		mMagFilter = filter;
		return true;
	default:
		return false;
	}
}

// Returns true on successful wrap state update (valid enum parameter)
bool Texture::setWrapS(GLenum wrap)
{
	switch(wrap)
	{
	case GL_REPEAT:
	case GL_MIRRORED_REPEAT:
		if((getTarget() == GL_TEXTURE_EXTERNAL_OES) || (getTarget() == GL_TEXTURE_RECTANGLE_ARB))
		{
			return false;
		}
		// Fall through
	case GL_CLAMP_TO_EDGE:
		mWrapS = wrap;
		return true;
	default:
		return false;
	}
}

// Returns true on successful wrap state update (valid enum parameter)
bool Texture::setWrapT(GLenum wrap)
{
	switch(wrap)
	{
	case GL_REPEAT:
	case GL_MIRRORED_REPEAT:
		if((getTarget() == GL_TEXTURE_EXTERNAL_OES) || (getTarget() == GL_TEXTURE_RECTANGLE_ARB))
		{
			return false;
		}
		// Fall through
	case GL_CLAMP_TO_EDGE:
		mWrapT = wrap;
		return true;
	default:
		return false;
	}
}

// Returns true on successful wrap state update (valid enum parameter)
bool Texture::setWrapR(GLenum wrap)
{
	switch(wrap)
	{
	case GL_REPEAT:
	case GL_MIRRORED_REPEAT:
		if((getTarget() == GL_TEXTURE_EXTERNAL_OES) || (getTarget() == GL_TEXTURE_RECTANGLE_ARB))
		{
			return false;
		}
		// Fall through
	case GL_CLAMP_TO_EDGE:
		mWrapR = wrap;
		return true;
	default:
		return false;
	}
}

// Returns true on successful max anisotropy update (valid anisotropy value)
bool Texture::setMaxAnisotropy(float textureMaxAnisotropy)
{
	textureMaxAnisotropy = std::min(textureMaxAnisotropy, MAX_TEXTURE_MAX_ANISOTROPY);

	if(textureMaxAnisotropy < 1.0f)
	{
		return false;
	}

	if(mMaxAnisotropy != textureMaxAnisotropy)
	{
		mMaxAnisotropy = textureMaxAnisotropy;
	}

	return true;
}

bool Texture::setBaseLevel(GLint baseLevel)
{
	if(baseLevel < 0)
	{
		return false;
	}

	mBaseLevel = baseLevel;
	return true;
}

bool Texture::setCompareFunc(GLenum compareFunc)
{
	switch(compareFunc)
	{
	case GL_LEQUAL:
	case GL_GEQUAL:
	case GL_LESS:
	case GL_GREATER:
	case GL_EQUAL:
	case GL_NOTEQUAL:
	case GL_ALWAYS:
	case GL_NEVER:
		mCompareFunc = compareFunc;
		return true;
	default:
		return false;
	}
}

bool Texture::setCompareMode(GLenum compareMode)
{
	switch(compareMode)
	{
	case GL_COMPARE_REF_TO_TEXTURE:
	case GL_NONE:
		mCompareMode = compareMode;
		return true;
	default:
		return false;
	}
}

void Texture::makeImmutable(GLsizei levels)
{
	mImmutableFormat = GL_TRUE;
	mImmutableLevels = levels;
}

bool Texture::setMaxLevel(GLint maxLevel)
{
	mMaxLevel = maxLevel;
	return true;
}

bool Texture::setMaxLOD(GLfloat maxLOD)
{
	mMaxLOD = maxLOD;
	return true;
}

bool Texture::setMinLOD(GLfloat minLOD)
{
	mMinLOD = minLOD;
	return true;
}

bool Texture::setSwizzleR(GLenum swizzleR)
{
	switch(swizzleR)
	{
	case GL_RED:
	case GL_GREEN:
	case GL_BLUE:
	case GL_ALPHA:
	case GL_ZERO:
	case GL_ONE:
		mSwizzleR = swizzleR;
		return true;
	default:
		return false;
	}
}

bool Texture::setSwizzleG(GLenum swizzleG)
{
	switch(swizzleG)
	{
	case GL_RED:
	case GL_GREEN:
	case GL_BLUE:
	case GL_ALPHA:
	case GL_ZERO:
	case GL_ONE:
		mSwizzleG = swizzleG;
		return true;
	default:
		return false;
	}
}

bool Texture::setSwizzleB(GLenum swizzleB)
{
	switch(swizzleB)
	{
	case GL_RED:
	case GL_GREEN:
	case GL_BLUE:
	case GL_ALPHA:
	case GL_ZERO:
	case GL_ONE:
		mSwizzleB = swizzleB;
		return true;
	default:
		return false;
	}
}

bool Texture::setSwizzleA(GLenum swizzleA)
{
	switch(swizzleA)
	{
	case GL_RED:
	case GL_GREEN:
	case GL_BLUE:
	case GL_ALPHA:
	case GL_ZERO:
	case GL_ONE:
		mSwizzleA = swizzleA;
		return true;
	default:
		return false;
	}
}

GLsizei Texture::getDepth(GLenum target, GLint level) const
{
	return 1;
}

egl::Image *Texture::createSharedImage(GLenum target, unsigned int level)
{
	egl::Image *image = getRenderTarget(target, level);   // Increments reference count

	if(image)
	{
		image->markShared();
	}

	return image;
}

void Texture::setImage(GLenum format, GLenum type, const gl::PixelStorageModes &unpackParameters, const void *pixels, egl::Image *image)
{
	if(pixels && image)
	{
		GLsizei depth = (getTarget() == GL_TEXTURE_3D_OES || getTarget() == GL_TEXTURE_2D_ARRAY) ? image->getDepth() : 1;
		image->loadImageData(0, 0, 0, image->getWidth(), image->getHeight(), depth, format, type, unpackParameters, pixels);
	}
}

void Texture::setCompressedImage(GLsizei imageSize, const void *pixels, egl::Image *image)
{
	if(pixels && image && (imageSize > 0)) // imageSize's correlation to width and height is already validated with gl::ComputeCompressedSize() at the API level
	{
		GLsizei depth = (getTarget() == GL_TEXTURE_3D_OES || getTarget() == GL_TEXTURE_2D_ARRAY) ? image->getDepth() : 1;
		image->loadCompressedData(0, 0, 0, image->getWidth(), image->getHeight(), depth, imageSize, pixels);
	}
}

void Texture::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)
{
	if(!image)
	{
		return error(GL_INVALID_OPERATION);
	}

	if(pixels && width > 0 && height > 0 && depth > 0)
	{
		image->loadImageData(xoffset, yoffset, zoffset, width, height, depth, format, type, unpackParameters, pixels);
	}
}

void Texture::subImageCompressed(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels, egl::Image *image)
{
	if(!image)
	{
		return error(GL_INVALID_OPERATION);
	}

	if(pixels && (imageSize > 0)) // imageSize's correlation to width and height is already validated with gl::ComputeCompressedSize() at the API level
	{
		image->loadCompressedData(xoffset, yoffset, zoffset, width, height, depth, imageSize, pixels);
	}
}

bool Texture::copy(egl::Image *source, const sw::SliceRect &sourceRect, GLint xoffset, GLint yoffset, GLint zoffset, egl::Image *dest)
{
	Device *device = getDevice();

	sw::SliceRect destRect(xoffset, yoffset, xoffset + (sourceRect.x1 - sourceRect.x0), yoffset + (sourceRect.y1 - sourceRect.y0), zoffset);
	sw::SliceRectF sourceRectF(static_cast<float>(sourceRect.x0),
	                           static_cast<float>(sourceRect.y0),
	                           static_cast<float>(sourceRect.x1),
	                           static_cast<float>(sourceRect.y1),
	                           sourceRect.slice);
	bool success = device->stretchRect(source, &sourceRectF, dest, &destRect, Device::ALL_BUFFERS);

	if(!success)
	{
		return error(GL_OUT_OF_MEMORY, false);
	}

	return true;
}

bool Texture::isMipmapFiltered(Sampler *sampler) const
{
	GLenum minFilter = sampler ? sampler->getMinFilter() : mMinFilter;

	switch(minFilter)
	{
	case GL_NEAREST:
	case GL_LINEAR:
		return false;
	case GL_NEAREST_MIPMAP_NEAREST:
	case GL_LINEAR_MIPMAP_NEAREST:
	case GL_NEAREST_MIPMAP_LINEAR:
	case GL_LINEAR_MIPMAP_LINEAR:
		return true;
	default: UNREACHABLE(minFilter);
	}

	return false;
}

Texture2D::Texture2D(GLuint name) : Texture(name)
{
	mSurface = nullptr;

	mColorbufferProxy = nullptr;
	mProxyRefs = 0;
}

Texture2D::~Texture2D()
{
	image.unbind(this);

	if(mSurface)
	{
		mSurface->setBoundTexture(nullptr);
		mSurface = nullptr;
	}

	mColorbufferProxy = nullptr;
}

// We need to maintain a count of references to renderbuffers acting as
// proxies for this texture, so that we do not attempt to use a pointer
// to a renderbuffer proxy which has been deleted.
void Texture2D::addProxyRef(const Renderbuffer *proxy)
{
	mProxyRefs++;
}

void Texture2D::releaseProxy(const Renderbuffer *proxy)
{
	if(mProxyRefs > 0)
	{
		mProxyRefs--;
	}

	if(mProxyRefs == 0)
	{
		mColorbufferProxy = nullptr;
	}
}

void Texture2D::sweep()
{
	int imageCount = 0;

	for(int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
	{
		if(image[i] && image[i]->isChildOf(this))
		{
			if(!image[i]->hasSingleReference())
			{
				return;
			}

			imageCount++;
		}
	}

	if(imageCount == referenceCount)
	{
		destroy();
	}
}

GLenum Texture2D::getTarget() const
{
	return GL_TEXTURE_2D;
}

GLsizei Texture2D::getWidth(GLenum target, GLint level) const
{
	ASSERT(target == getTarget());
	return image[level] ? image[level]->getWidth() : 0;
}

GLsizei Texture2D::getHeight(GLenum target, GLint level) const
{
	ASSERT(target == getTarget());
	return image[level] ? image[level]->getHeight() : 0;
}

GLint Texture2D::getFormat(GLenum target, GLint level) const
{
	ASSERT(target == getTarget());
	return image[level] ? image[level]->getFormat() : GL_NONE;
}

int Texture2D::getTopLevel() const
{
	int level = mBaseLevel;

	while(level < IMPLEMENTATION_MAX_TEXTURE_LEVELS && image[level])
	{
		level++;
	}

	return level - 1;
}

bool Texture2D::hasNonBaseLevels() const
{
	for(int level = 1; level < IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
	{
		if (image[level])
		{
			return true;
		}
	}

	return false;
}

bool Texture2D::requiresSync() const
{
	for(int level = 0; level < IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
	{
		if(image[level] && image[level]->requiresSync())
		{
			return true;
		}
	}

	return false;
}

void Texture2D::setImage(GLint level, GLsizei width, GLsizei height, GLint internalformat, GLenum format, GLenum type, const gl::PixelStorageModes &unpackParameters, const void *pixels)
{
	if(image[level])
	{
		image[level]->release();
	}

	image[level] = egl::Image::create(this, width, height, internalformat);

	if(!image[level])
	{
		return error(GL_OUT_OF_MEMORY);
	}

	Texture::setImage(format, type, unpackParameters, pixels, image[level]);
}

void Texture2D::bindTexImage(gl::Surface *surface)
{
	image.release();

	image[0] = surface->getRenderTarget();

	assert(!mSurface); // eglBindTexImage called before eglReleaseTexImage

	mSurface = surface;
	mSurface->setBoundTexture(this);
}

void Texture2D::releaseTexImage()
{
	image.release();

	if(mSurface)
	{
		mSurface->setBoundTexture(nullptr);
		mSurface = nullptr;
	}
}

void Texture2D::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels)
{
	if(image[level])
	{
		image[level]->release();
	}

	image[level] = egl::Image::create(this, width, height, format);

	if(!image[level])
	{
		return error(GL_OUT_OF_MEMORY);
	}

	Texture::setCompressedImage(imageSize, pixels, image[level]);
}

void Texture2D::subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const gl::PixelStorageModes &unpackParameters, const void *pixels)
{
	Texture::subImage(xoffset, yoffset, 0, width, height, 1, format, type, unpackParameters, pixels, image[level]);
}

void Texture2D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels)
{
	Texture::subImageCompressed(xoffset, yoffset, 0, width, height, 1, format, imageSize, pixels, image[level]);
}

void Texture2D::copyImage(GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, Renderbuffer *source)
{
	if(image[level])
	{
		image[level]->release();
	}

	image[level] = egl::Image::create(this, width, height, internalformat);

	if(!image[level])
	{
		return error(GL_OUT_OF_MEMORY);
	}

	if(width != 0 && height != 0)
	{
		egl::Image *renderTarget = source->getRenderTarget();

		if(!renderTarget)
		{
			ERR("Failed to retrieve the render target.");
			return error(GL_OUT_OF_MEMORY);
		}

		sw::SliceRect sourceRect(x, y, x + width, y + height, 0);
		sourceRect.clip(0, 0, renderTarget->getWidth(), renderTarget->getHeight());

		copy(renderTarget, sourceRect, 0, 0, 0, image[level]);

		renderTarget->release();
	}
}

void Texture2D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Renderbuffer *source)
{
	if(!image[level])
	{
		return error(GL_INVALID_OPERATION);
	}

	if(xoffset + width > image[level]->getWidth() || yoffset + height > image[level]->getHeight() || zoffset != 0)
	{
		return error(GL_INVALID_VALUE);
	}

	if(width > 0 && height > 0)
	{
		egl::Image *renderTarget = source->getRenderTarget();

		if(!renderTarget)
		{
			ERR("Failed to retrieve the render target.");
			return error(GL_OUT_OF_MEMORY);
		}

		sw::SliceRect sourceRect(x, y, x + width, y + height, 0);
		sourceRect.clip(0, 0, renderTarget->getWidth(), renderTarget->getHeight());

		copy(renderTarget, sourceRect, xoffset, yoffset, zoffset, image[level]);

		renderTarget->release();
	}
}

void Texture2D::setSharedImage(egl::Image *sharedImage)
{
	if(sharedImage == image[0])
	{
		return;
	}

	sharedImage->addRef();

	if(image[0])
	{
		image[0]->release();
	}

	image[0] = sharedImage;
}

bool Texture2D::isBaseLevelDefined() const
{
	if(!image[mBaseLevel])
	{
		return false;
	}

	GLsizei width = image[mBaseLevel]->getWidth();
	GLsizei height = image[mBaseLevel]->getHeight();

	if(width <= 0 || height <= 0)
	{
		return false;
	}

	return true;
}

// Tests for 2D texture sampling completeness. [OpenGL ES 3.0.5] section 3.8.13 page 160.
bool Texture2D::isSamplerComplete(Sampler *sampler) const
{
	if(mImmutableFormat == GL_TRUE)
	{
		return true;
	}

	if(!isBaseLevelDefined())
	{
		return false;
	}

	if(isMipmapFiltered(sampler))
	{
		if(!isMipmapComplete())
		{
			return false;
		}
	}

	return true;
}

// Tests for 2D texture (mipmap) completeness. [OpenGL ES 3.0.5] section 3.8.13 page 160.
bool Texture2D::isMipmapComplete() const
{
	if(mBaseLevel > mMaxLevel)
	{
		return false;
	}

	GLsizei width = image[mBaseLevel]->getWidth();
	GLsizei height = image[mBaseLevel]->getHeight();
	int maxsize = std::max(width, height);
	int p = log2(maxsize) + mBaseLevel;
	int q = std::min(p, mMaxLevel);

	for(int level = mBaseLevel + 1; level <= q; level++)
	{
		if(!image[level])
		{
			return false;
		}

		if(image[level]->getFormat() != image[mBaseLevel]->getFormat())
		{
			return false;
		}

		int i = level - mBaseLevel;

		if(image[level]->getWidth() != std::max(1, width >> i))
		{
			return false;
		}

		if(image[level]->getHeight() != std::max(1, height >> i))
		{
			return false;
		}
	}

	return true;
}

bool Texture2D::isCompressed(GLenum target, GLint level) const
{
	return IsCompressed(getFormat(target, level));
}

bool Texture2D::isDepth(GLenum target, GLint level) const
{
	return IsDepthTexture(getFormat(target, level));
}

void Texture2D::generateMipmaps()
{
	if(!image[mBaseLevel])
	{
		return;   // Image unspecified. Not an error.
	}

	if(image[mBaseLevel]->getWidth() == 0 || image[mBaseLevel]->getHeight() == 0)
	{
		return;   // Zero dimension. Not an error.
	}

	int maxsize = std::max(image[mBaseLevel]->getWidth(), image[mBaseLevel]->getHeight());
	int p = log2(maxsize) + mBaseLevel;
	int q = std::min(p, mMaxLevel);

	for(int i = mBaseLevel + 1; i <= q; i++)
	{
		if(image[i])
		{
			image[i]->release();
		}

		image[i] = egl::Image::create(this, std::max(image[mBaseLevel]->getWidth() >> i, 1), std::max(image[mBaseLevel]->getHeight() >> i, 1), image[mBaseLevel]->getFormat());

		if(!image[i])
		{
			return error(GL_OUT_OF_MEMORY);
		}

		getDevice()->stretchRect(image[i - 1], 0, image[i], 0, Device::ALL_BUFFERS | Device::USE_FILTER);
	}
}

egl::Image *Texture2D::getImage(unsigned int level)
{
	return image[level];
}

Renderbuffer *Texture2D::getRenderbuffer(GLenum target, GLint level)
{
	if(target != getTarget())
	{
		return error(GL_INVALID_OPERATION, (Renderbuffer*)nullptr);
	}

	if(!mColorbufferProxy)
	{
		mColorbufferProxy = new Renderbuffer(name, new RenderbufferTexture2D(this, level));
	}
	else
	{
		mColorbufferProxy->setLevel(level);
	}

	return mColorbufferProxy;
}

egl::Image *Texture2D::getRenderTarget(GLenum target, unsigned int level)
{
	ASSERT(target == getTarget());
	ASSERT(level < IMPLEMENTATION_MAX_TEXTURE_LEVELS);

	if(image[level])
	{
		image[level]->addRef();
	}

	return image[level];
}

bool Texture2D::isShared(GLenum target, unsigned int level) const
{
	ASSERT(target == getTarget());
	ASSERT(level < IMPLEMENTATION_MAX_TEXTURE_LEVELS);

	if(mSurface)   // Bound to an EGLSurface
	{
		return true;
	}

	if(!image[level])
	{
		return false;
	}

	return image[level]->isShared();
}

Texture2DRect::Texture2DRect(GLuint name) : Texture2D(name)
{
	mMinFilter = GL_LINEAR;
	mMagFilter = GL_LINEAR;
	mWrapS = GL_CLAMP_TO_EDGE;
	mWrapT = GL_CLAMP_TO_EDGE;
	mWrapR = GL_CLAMP_TO_EDGE;
}

GLenum Texture2DRect::getTarget() const
{
	return GL_TEXTURE_RECTANGLE_ARB;
}

Renderbuffer *Texture2DRect::getRenderbuffer(GLenum target, GLint level)
{
	if((target != getTarget()) || (level != 0))
	{
		return error(GL_INVALID_OPERATION, (Renderbuffer*)nullptr);
	}

	if(!mColorbufferProxy)
	{
		mColorbufferProxy = new Renderbuffer(name, new RenderbufferTexture2DRect(this));
	}

	return mColorbufferProxy;
}

TextureCubeMap::TextureCubeMap(GLuint name) : Texture(name)
{
	for(int f = 0; f < 6; f++)
	{
		mFaceProxies[f] = nullptr;
		mFaceProxyRefs[f] = 0;
	}
}

TextureCubeMap::~TextureCubeMap()
{
	for(int i = 0; i < 6; i++)
	{
		image[i].unbind(this);
		mFaceProxies[i] = nullptr;
	}
}

// We need to maintain a count of references to renderbuffers acting as
// proxies for this texture, so that the texture is not deleted while
// proxy references still exist. If the reference count drops to zero,
// we set our proxy pointer null, so that a new attempt at referencing
// will cause recreation.
void TextureCubeMap::addProxyRef(const Renderbuffer *proxy)
{
	for(int f = 0; f < 6; f++)
	{
		if(mFaceProxies[f] == proxy)
		{
			mFaceProxyRefs[f]++;
		}
	}
}

void TextureCubeMap::releaseProxy(const Renderbuffer *proxy)
{
	for(int f = 0; f < 6; f++)
	{
		if(mFaceProxies[f] == proxy)
		{
			if(mFaceProxyRefs[f] > 0)
			{
				mFaceProxyRefs[f]--;
			}

			if(mFaceProxyRefs[f] == 0)
			{
				mFaceProxies[f] = nullptr;
			}
		}
	}
}

void TextureCubeMap::sweep()
{
	int imageCount = 0;

	for(int f = 0; f < 6; f++)
	{
		for(int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
		{
			if(image[f][i] && image[f][i]->isChildOf(this))
			{
				if(!image[f][i]->hasSingleReference())
				{
					return;
				}

				imageCount++;
			}
		}
	}

	if(imageCount == referenceCount)
	{
		destroy();
	}
}

GLenum TextureCubeMap::getTarget() const
{
	return GL_TEXTURE_CUBE_MAP;
}

GLsizei TextureCubeMap::getWidth(GLenum target, GLint level) const
{
	int face = CubeFaceIndex(target);
	return image[face][level] ? image[face][level]->getWidth() : 0;
}

GLsizei TextureCubeMap::getHeight(GLenum target, GLint level) const
{
	int face = CubeFaceIndex(target);
	return image[face][level] ? image[face][level]->getHeight() : 0;
}

GLint TextureCubeMap::getFormat(GLenum target, GLint level) const
{
	int face = CubeFaceIndex(target);
	return image[face][level] ? image[face][level]->getFormat() : 0;
}

int TextureCubeMap::getTopLevel() const
{
	int level = mBaseLevel;

	while(level < IMPLEMENTATION_MAX_TEXTURE_LEVELS && image[0][level])
	{
		level++;
	}

	return level - 1;
}

bool TextureCubeMap::hasNonBaseLevels() const
{
	for(int level = 1; level < IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
	{
		for(int face = 0; face < 6; face++)
		{
			if (image[face][level])
			{
				return true;
			}
		}
	}

	return false;
}

bool TextureCubeMap::requiresSync() const
{
	for(int level = 0; level < IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
	{
		for(int face = 0; face < 6; face++)
		{
			if(image[face][level] && image[face][level]->requiresSync())
			{
				return true;
			}
		}
	}

	return false;
}

void TextureCubeMap::setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels)
{
	int face = CubeFaceIndex(target);

	if(image[face][level])
	{
		image[face][level]->release();
	}

	image[face][level] = egl::Image::create(this, width, height, 1, 1, format);

	if(!image[face][level])
	{
		return error(GL_OUT_OF_MEMORY);
	}

	Texture::setCompressedImage(imageSize, pixels, image[face][level]);
}

void TextureCubeMap::subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const gl::PixelStorageModes &unpackParameters, const void *pixels)
{
	Texture::subImage(xoffset, yoffset, 0, width, height, 1, format, type, unpackParameters, pixels, image[CubeFaceIndex(target)][level]);
}

void TextureCubeMap::subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels)
{
	Texture::subImageCompressed(xoffset, yoffset, 0, width, height, 1, format, imageSize, pixels, image[CubeFaceIndex(target)][level]);
}

bool TextureCubeMap::isBaseLevelDefined() const
{
	for(int face = 0; face < 6; face++)
	{
		if(!image[face][mBaseLevel])
		{
			return false;
		}
	}

	int size = image[0][mBaseLevel]->getWidth();

	if(size <= 0)
	{
		return false;
	}

	return true;
}

// Tests for cube map sampling completeness. [OpenGL ES 3.0.5] section 3.8.13 page 161.
bool TextureCubeMap::isSamplerComplete(Sampler *sampler) const
{
	if(mImmutableFormat == GL_TRUE)
	{
		return true;
	}

	if(!isBaseLevelDefined())
	{
		return false;
	}

	if(!isMipmapFiltered(sampler))
	{
		if(!isCubeComplete())
		{
			return false;
		}
	}
	else
	{
		if(!isMipmapCubeComplete())   // Also tests for isCubeComplete()
		{
			return false;
		}
	}

	return true;
}

// Tests for cube texture completeness. [OpenGL ES 3.0.5] section 3.8.13 page 160.
bool TextureCubeMap::isCubeComplete() const
{
	if(!isBaseLevelDefined())
	{
		return false;
	}

	if(image[0][mBaseLevel]->getWidth() <= 0 || image[0][mBaseLevel]->getHeight() != image[0][mBaseLevel]->getWidth())
	{
		return false;
	}

	for(unsigned int face = 1; face < 6; face++)
	{
		if(image[face][mBaseLevel]->getWidth()  != image[0][mBaseLevel]->getWidth() ||
		   image[face][mBaseLevel]->getWidth()  != image[0][mBaseLevel]->getHeight() ||
		   image[face][mBaseLevel]->getFormat() != image[0][mBaseLevel]->getFormat())
		{
			return false;
		}
	}

	return true;
}

bool TextureCubeMap::isMipmapCubeComplete() const
{
	if(mBaseLevel > mMaxLevel)
	{
		return false;
	}

	if(!isCubeComplete())
	{
		return false;
	}

	GLsizei size = image[0][mBaseLevel]->getWidth();
	int p = log2(size) + mBaseLevel;
	int q = std::min(p, mMaxLevel);

	for(int face = 0; face < 6; face++)
	{
		for(int level = mBaseLevel + 1; level <= q; level++)
		{
			if(!image[face][level])
			{
				return false;
			}

			if(image[face][level]->getFormat() != image[0][mBaseLevel]->getFormat())
			{
				return false;
			}

			int i = level - mBaseLevel;

			if(image[face][level]->getWidth() != std::max(1, size >> i))
			{
				return false;
			}
		}
	}

	return true;
}

void TextureCubeMap::updateBorders(int level)
{
	egl::Image *posX = image[CubeFaceIndex(GL_TEXTURE_CUBE_MAP_POSITIVE_X)][level];
	egl::Image *negX = image[CubeFaceIndex(GL_TEXTURE_CUBE_MAP_NEGATIVE_X)][level];
	egl::Image *posY = image[CubeFaceIndex(GL_TEXTURE_CUBE_MAP_POSITIVE_Y)][level];
	egl::Image *negY = image[CubeFaceIndex(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y)][level];
	egl::Image *posZ = image[CubeFaceIndex(GL_TEXTURE_CUBE_MAP_POSITIVE_Z)][level];
	egl::Image *negZ = image[CubeFaceIndex(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z)][level];

	if(!posX || !negX || !posY || !negY || !posZ || !negZ)
	{
		return;
	}

	if(posX->getBorder() == 0)   // Non-seamless cube map.
	{
		return;
	}

	if(!posX->hasDirtyContents() || !posY->hasDirtyContents() || !posZ->hasDirtyContents() || !negX->hasDirtyContents() || !negY->hasDirtyContents() || !negZ->hasDirtyContents())
	{
		return;
	}

	// Copy top / bottom first.
	posX->copyCubeEdge(sw::Surface::BOTTOM, negY, sw::Surface::RIGHT);
	posY->copyCubeEdge(sw::Surface::BOTTOM, posZ, sw::Surface::TOP);
	posZ->copyCubeEdge(sw::Surface::BOTTOM, negY, sw::Surface::TOP);
	negX->copyCubeEdge(sw::Surface::BOTTOM, negY, sw::Surface::LEFT);
	negY->copyCubeEdge(sw::Surface::BOTTOM, negZ, sw::Surface::BOTTOM);
	negZ->copyCubeEdge(sw::Surface::BOTTOM, negY, sw::Surface::BOTTOM);

	posX->copyCubeEdge(sw::Surface::TOP, posY, sw::Surface::RIGHT);
	posY->copyCubeEdge(sw::Surface::TOP, negZ, sw::Surface::TOP);
	posZ->copyCubeEdge(sw::Surface::TOP, posY, sw::Surface::BOTTOM);
	negX->copyCubeEdge(sw::Surface::TOP, posY, sw::Surface::LEFT);
	negY->copyCubeEdge(sw::Surface::TOP, posZ, sw::Surface::BOTTOM);
	negZ->copyCubeEdge(sw::Surface::TOP, posY, sw::Surface::TOP);

	// Copy left / right after top and bottom are done.
	// The corner colors will be computed assuming top / bottom are already set.
	posX->copyCubeEdge(sw::Surface::RIGHT, negZ, sw::Surface::LEFT);
	posY->copyCubeEdge(sw::Surface::RIGHT, posX, sw::Surface::TOP);
	posZ->copyCubeEdge(sw::Surface::RIGHT, posX, sw::Surface::LEFT);
	negX->copyCubeEdge(sw::Surface::RIGHT, posZ, sw::Surface::LEFT);
	negY->copyCubeEdge(sw::Surface::RIGHT, posX, sw::Surface::BOTTOM);
	negZ->copyCubeEdge(sw::Surface::RIGHT, negX, sw::Surface::LEFT);

	posX->copyCubeEdge(sw::Surface::LEFT, posZ, sw::Surface::RIGHT);
	posY->copyCubeEdge(sw::Surface::LEFT, negX, sw::Surface::TOP);
	posZ->copyCubeEdge(sw::Surface::LEFT, negX, sw::Surface::RIGHT);
	negX->copyCubeEdge(sw::Surface::LEFT, negZ, sw::Surface::RIGHT);
	negY->copyCubeEdge(sw::Surface::LEFT, negX, sw::Surface::BOTTOM);
	negZ->copyCubeEdge(sw::Surface::LEFT, posX, sw::Surface::RIGHT);

	posX->markContentsClean();
	posY->markContentsClean();
	posZ->markContentsClean();
	negX->markContentsClean();
	negY->markContentsClean();
	negZ->markContentsClean();
}

bool TextureCubeMap::isCompressed(GLenum target, GLint level) const
{
	return IsCompressed(getFormat(target, level));
}

bool TextureCubeMap::isDepth(GLenum target, GLint level) const
{
	return IsDepthTexture(getFormat(target, level));
}

void TextureCubeMap::releaseTexImage()
{
	UNREACHABLE(0);   // Cube maps cannot have an EGL surface bound as an image
}

void TextureCubeMap::setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLint internalformat, GLenum format, GLenum type, const gl::PixelStorageModes &unpackParameters, const void *pixels)
{
	int face = CubeFaceIndex(target);

	if(image[face][level])
	{
		image[face][level]->release();
	}

	image[face][level] = egl::Image::create(this, width, height, 1, 1, internalformat);

	if(!image[face][level])
	{
		return error(GL_OUT_OF_MEMORY);
	}

	Texture::setImage(format, type, unpackParameters, pixels, image[face][level]);
}

void TextureCubeMap::copyImage(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, Renderbuffer *source)
{
	int face = CubeFaceIndex(target);

	if(image[face][level])
	{
		image[face][level]->release();
	}

	image[face][level] = egl::Image::create(this, width, height, 1, 1, internalformat);

	if(!image[face][level])
	{
		return error(GL_OUT_OF_MEMORY);
	}

	if(width != 0 && height != 0)
	{
		egl::Image *renderTarget = source->getRenderTarget();

		if(!renderTarget)
		{
			ERR("Failed to retrieve the render target.");
			return error(GL_OUT_OF_MEMORY);
		}

		sw::SliceRect sourceRect(x, y, x + width, y + height, 0);
		sourceRect.clip(0, 0, renderTarget->getWidth(), renderTarget->getHeight());

		copy(renderTarget, sourceRect, 0, 0, 0, image[face][level]);

		renderTarget->release();
	}
}

egl::Image *TextureCubeMap::getImage(int face, unsigned int level)
{
	return image[face][level];
}

egl::Image *TextureCubeMap::getImage(GLenum face, unsigned int level)
{
	return image[CubeFaceIndex(face)][level];
}

void TextureCubeMap::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Renderbuffer *source)
{
	int face = CubeFaceIndex(target);

	if(!image[face][level])
	{
		return error(GL_INVALID_OPERATION);
	}

	GLsizei size = image[face][level]->getWidth();

	if(xoffset + width > size || yoffset + height > size || zoffset != 0)
	{
		return error(GL_INVALID_VALUE);
	}

	if(width > 0 && height > 0)
	{
		egl::Image *renderTarget = source->getRenderTarget();

		if(!renderTarget)
		{
			ERR("Failed to retrieve the render target.");
			return error(GL_OUT_OF_MEMORY);
		}

		sw::SliceRect sourceRect(x, y, x + width, y + height, 0);
		sourceRect.clip(0, 0, renderTarget->getWidth(), renderTarget->getHeight());

		copy(renderTarget, sourceRect, xoffset, yoffset, zoffset, image[face][level]);

		renderTarget->release();
	}
}

void TextureCubeMap::generateMipmaps()
{
	if(!isCubeComplete())
	{
		return error(GL_INVALID_OPERATION);
	}

	int p = log2(image[0][mBaseLevel]->getWidth()) + mBaseLevel;
	int q = std::min(p, mMaxLevel);

	for(int f = 0; f < 6; f++)
	{
		ASSERT(image[f][mBaseLevel]);

		for(int i = mBaseLevel + 1; i <= q; i++)
		{
			if(image[f][i])
			{
				image[f][i]->release();
			}

			image[f][i] = egl::Image::create(this, std::max(image[f][mBaseLevel]->getWidth() >> i, 1), std::max(image[f][mBaseLevel]->getHeight() >> i, 1), 1, 1, image[f][mBaseLevel]->getFormat());

			if(!image[f][i])
			{
				return error(GL_OUT_OF_MEMORY);
			}

			getDevice()->stretchRect(image[f][i - 1], 0, image[f][i], 0, Device::ALL_BUFFERS | Device::USE_FILTER);
		}
	}
}

Renderbuffer *TextureCubeMap::getRenderbuffer(GLenum target, GLint level)
{
	if(!IsCubemapTextureTarget(target))
	{
		return error(GL_INVALID_OPERATION, (Renderbuffer*)nullptr);
	}

	int face = CubeFaceIndex(target);

	if(!mFaceProxies[face])
	{
		mFaceProxies[face] = new Renderbuffer(name, new RenderbufferTextureCubeMap(this, target, level));
	}
	else
	{
		mFaceProxies[face]->setLevel(level);
	}

	return mFaceProxies[face];
}

egl::Image *TextureCubeMap::getRenderTarget(GLenum target, unsigned int level)
{
	ASSERT(IsCubemapTextureTarget(target));
	ASSERT(level < IMPLEMENTATION_MAX_TEXTURE_LEVELS);

	int face = CubeFaceIndex(target);

	if(image[face][level])
	{
		image[face][level]->addRef();
	}

	return image[face][level];
}

bool TextureCubeMap::isShared(GLenum target, unsigned int level) const
{
	ASSERT(IsCubemapTextureTarget(target));
	ASSERT(level < IMPLEMENTATION_MAX_TEXTURE_LEVELS);

	int face = CubeFaceIndex(target);

	if(!image[face][level])
	{
		return false;
	}

	return image[face][level]->isShared();
}

Texture3D::Texture3D(GLuint name) : Texture(name)
{
	mSurface = nullptr;

	mColorbufferProxy = nullptr;
	mProxyRefs = 0;
}

Texture3D::~Texture3D()
{
	image.unbind(this);

	if(mSurface)
	{
		mSurface->setBoundTexture(nullptr);
		mSurface = nullptr;
	}

	mColorbufferProxy = nullptr;
}

// We need to maintain a count of references to renderbuffers acting as
// proxies for this texture, so that we do not attempt to use a pointer
// to a renderbuffer proxy which has been deleted.
void Texture3D::addProxyRef(const Renderbuffer *proxy)
{
	mProxyRefs++;
}

void Texture3D::releaseProxy(const Renderbuffer *proxy)
{
	if(mProxyRefs > 0)
	{
		mProxyRefs--;
	}

	if(mProxyRefs == 0)
	{
		mColorbufferProxy = nullptr;
	}
}

void Texture3D::sweep()
{
	int imageCount = 0;

	for(int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
	{
		if(image[i] && image[i]->isChildOf(this))
		{
			if(!image[i]->hasSingleReference())
			{
				return;
			}

			imageCount++;
		}
	}

	if(imageCount == referenceCount)
	{
		destroy();
	}
}

GLenum Texture3D::getTarget() const
{
	return GL_TEXTURE_3D_OES;
}

GLsizei Texture3D::getWidth(GLenum target, GLint level) const
{
	ASSERT(target == getTarget());
	return image[level] ? image[level]->getWidth() : 0;
}

GLsizei Texture3D::getHeight(GLenum target, GLint level) const
{
	ASSERT(target == getTarget());
	return image[level] ? image[level]->getHeight() : 0;
}

GLsizei Texture3D::getDepth(GLenum target, GLint level) const
{
	ASSERT(target == getTarget());
	return image[level] ? image[level]->getDepth() : 0;
}

GLint Texture3D::getFormat(GLenum target, GLint level) const
{
	ASSERT(target == getTarget());
	return image[level] ? image[level]->getFormat() : GL_NONE;
}

int Texture3D::getTopLevel() const
{
	int level = mBaseLevel;

	while(level < IMPLEMENTATION_MAX_TEXTURE_LEVELS && image[level])
	{
		level++;
	}

	return level - 1;
}

bool Texture3D::hasNonBaseLevels() const
{
	for(int level = 1; level < IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
	{
		if (image[level])
		{
			return true;
		}
	}

	return false;
}

bool Texture3D::requiresSync() const
{
	for(int level = 0; level < IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
	{
		if(image[level] && image[level]->requiresSync())
		{
			return true;
		}
	}

	return false;
}

void Texture3D::setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLint internalformat, GLenum format, GLenum type, const gl::PixelStorageModes &unpackParameters, const void *pixels)
{
	if(image[level])
	{
		image[level]->release();
	}

	image[level] = egl::Image::create(this, width, height, depth, 0, internalformat);

	if(!image[level])
	{
		return error(GL_OUT_OF_MEMORY);
	}

	Texture::setImage(format, type, unpackParameters, pixels, image[level]);
}

void Texture3D::releaseTexImage()
{
	UNREACHABLE(0);   // 3D textures cannot have an EGL surface bound as an image
}

void Texture3D::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels)
{
	if(image[level])
	{
		image[level]->release();
	}

	image[level] = egl::Image::create(this, width, height, depth, 0, format);

	if(!image[level])
	{
		return error(GL_OUT_OF_MEMORY);
	}

	Texture::setCompressedImage(imageSize, pixels, image[level]);
}

void Texture3D::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)
{
	Texture::subImage(xoffset, yoffset, zoffset, width, height, depth, format, type, unpackParameters, pixels, image[level]);
}

void Texture3D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels)
{
	Texture::subImageCompressed(xoffset, yoffset, zoffset, width, height, depth, format, imageSize, pixels, image[level]);
}

void Texture3D::copyImage(GLint level, GLenum internalformat, GLint x, GLint y, GLint z, GLsizei width, GLsizei height, GLsizei depth, Renderbuffer *source)
{
	if(image[level])
	{
		image[level]->release();
	}

	image[level] = egl::Image::create(this, width, height, depth, 0, internalformat);

	if(!image[level])
	{
		return error(GL_OUT_OF_MEMORY);
	}

	if(width != 0 && height != 0 && depth != 0)
	{
		egl::Image *renderTarget = source->getRenderTarget();

		if(!renderTarget)
		{
			ERR("Failed to retrieve the render target.");
			return error(GL_OUT_OF_MEMORY);
		}

		sw::SliceRect sourceRect(x, y, x + width, y + height, z);
		sourceRect.clip(0, 0, renderTarget->getWidth(), renderTarget->getHeight());

		for(GLint sliceZ = 0; sliceZ < depth; sliceZ++, sourceRect.slice++)
		{
			copy(renderTarget, sourceRect, 0, 0, sliceZ, image[level]);
		}

		renderTarget->release();
	}
}

void Texture3D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Renderbuffer *source)
{
	if(!image[level])
	{
		return error(GL_INVALID_OPERATION);
	}

	if(xoffset + width > image[level]->getWidth() || yoffset + height > image[level]->getHeight() || zoffset >= image[level]->getDepth())
	{
		return error(GL_INVALID_VALUE);
	}

	if(width > 0 && height > 0)
	{
		egl::Image *renderTarget = source->getRenderTarget();

		if(!renderTarget)
		{
			ERR("Failed to retrieve the render target.");
			return error(GL_OUT_OF_MEMORY);
		}

		sw::SliceRect sourceRect = {x, y, x + width, y + height, 0};
		sourceRect.clip(0, 0, renderTarget->getWidth(), renderTarget->getHeight());

		copy(renderTarget, sourceRect, xoffset, yoffset, zoffset, image[level]);

		renderTarget->release();
	}
}

void Texture3D::setSharedImage(egl::Image *sharedImage)
{
	sharedImage->addRef();

	if(image[0])
	{
		image[0]->release();
	}

	image[0] = sharedImage;
}

bool Texture3D::isBaseLevelDefined() const
{
	if(!image[mBaseLevel])
	{
		return false;
	}

	GLsizei width = image[mBaseLevel]->getWidth();
	GLsizei height = image[mBaseLevel]->getHeight();
	GLsizei depth = image[mBaseLevel]->getDepth();

	if(width <= 0 || height <= 0 || depth <= 0)
	{
		return false;
	}

	return true;
}

// Tests for 3D texture sampling completeness. [OpenGL ES 3.0.5] section 3.8.13 page 160.
bool Texture3D::isSamplerComplete(Sampler *sampler) const
{
	if(mImmutableFormat == GL_TRUE)
	{
		return true;
	}

	if(!isBaseLevelDefined())
	{
		return false;
	}

	if(isMipmapFiltered(sampler))
	{
		if(!isMipmapComplete())
		{
			return false;
		}
	}

	return true;
}

// Tests for 3D texture (mipmap) completeness. [OpenGL ES 3.0.5] section 3.8.13 page 160.
bool Texture3D::isMipmapComplete() const
{
	if(mBaseLevel > mMaxLevel)
	{
		return false;
	}

	GLsizei width = image[mBaseLevel]->getWidth();
	GLsizei height = image[mBaseLevel]->getHeight();
	GLsizei depth = image[mBaseLevel]->getDepth();
	bool isTexture2DArray = getTarget() == GL_TEXTURE_2D_ARRAY;

	int maxsize = isTexture2DArray ? std::max(width, height) : std::max(std::max(width, height), depth);
	int p = log2(maxsize) + mBaseLevel;
	int q = std::min(p, mMaxLevel);

	for(int level = mBaseLevel + 1; level <= q; level++)
	{
		if(!image[level])
		{
			return false;
		}

		if(image[level]->getFormat() != image[mBaseLevel]->getFormat())
		{
			return false;
		}

		int i = level - mBaseLevel;

		if(image[level]->getWidth() != std::max(1, width >> i))
		{
			return false;
		}

		if(image[level]->getHeight() != std::max(1, height >> i))
		{
			return false;
		}

		int levelDepth = isTexture2DArray ? depth : std::max(1, depth >> i);
		if(image[level]->getDepth() != levelDepth)
		{
			return false;
		}
	}

	return true;
}

bool Texture3D::isCompressed(GLenum target, GLint level) const
{
	return IsCompressed(getFormat(target, level));
}

bool Texture3D::isDepth(GLenum target, GLint level) const
{
	return IsDepthTexture(getFormat(target, level));
}

void Texture3D::generateMipmaps()
{
	if(!image[mBaseLevel])
	{
		return;   // Image unspecified. Not an error.
	}

	if(image[mBaseLevel]->getWidth() == 0 || image[mBaseLevel]->getHeight() == 0 || image[mBaseLevel]->getDepth() == 0)
	{
		return;   // Zero dimension. Not an error.
	}

	int maxsize = std::max(std::max(image[mBaseLevel]->getWidth(), image[mBaseLevel]->getHeight()), image[mBaseLevel]->getDepth());
	int p = log2(maxsize) + mBaseLevel;
	int q = std::min(p, mMaxLevel);

	for(int i = mBaseLevel + 1; i <= q; i++)
	{
		if(image[i])
		{
			image[i]->release();
		}

		image[i] = egl::Image::create(this, std::max(image[mBaseLevel]->getWidth() >> i, 1), std::max(image[mBaseLevel]->getHeight() >> i, 1), std::max(image[mBaseLevel]->getDepth() >> i, 1), 0, image[mBaseLevel]->getFormat());

		if(!image[i])
		{
			return error(GL_OUT_OF_MEMORY);
		}

		getDevice()->stretchCube(image[i - 1], image[i]);
	}
}

egl::Image *Texture3D::getImage(unsigned int level)
{
	return image[level];
}

Renderbuffer *Texture3D::getRenderbuffer(GLenum target, GLint level)
{
	if(target != getTarget())
	{
		return error(GL_INVALID_OPERATION, (Renderbuffer*)nullptr);
	}

	if(!mColorbufferProxy)
	{
		mColorbufferProxy = new Renderbuffer(name, new RenderbufferTexture3D(this, level));
	}
	else
	{
		mColorbufferProxy->setLevel(level);
	}

	return mColorbufferProxy;
}

egl::Image *Texture3D::getRenderTarget(GLenum target, unsigned int level)
{
	ASSERT(target == getTarget());
	ASSERT(level < IMPLEMENTATION_MAX_TEXTURE_LEVELS);

	if(image[level])
	{
		image[level]->addRef();
	}

	return image[level];
}

bool Texture3D::isShared(GLenum target, unsigned int level) const
{
	ASSERT(target == getTarget());
	ASSERT(level < IMPLEMENTATION_MAX_TEXTURE_LEVELS);

	if(mSurface)   // Bound to an EGLSurface
	{
		return true;
	}

	if(!image[level])
	{
		return false;
	}

	return image[level]->isShared();
}

Texture2DArray::Texture2DArray(GLuint name) : Texture3D(name)
{
}

Texture2DArray::~Texture2DArray()
{
}

GLenum Texture2DArray::getTarget() const
{
	return GL_TEXTURE_2D_ARRAY;
}

void Texture2DArray::generateMipmaps()
{
	if(!image[mBaseLevel])
	{
		return;   // Image unspecified. Not an error.
	}

	if(image[mBaseLevel]->getWidth() == 0 || image[mBaseLevel]->getHeight() == 0 || image[mBaseLevel]->getDepth() == 0)
	{
		return;   // Zero dimension. Not an error.
	}

	int depth = image[mBaseLevel]->getDepth();
	int maxsize = std::max(image[mBaseLevel]->getWidth(), image[mBaseLevel]->getHeight());
	int p = log2(maxsize) + mBaseLevel;
	int q = std::min(p, mMaxLevel);

	for(int i = mBaseLevel + 1; i <= q; i++)
	{
		if(image[i])
		{
			image[i]->release();
		}

		GLsizei w = std::max(image[mBaseLevel]->getWidth() >> i, 1);
		GLsizei h = std::max(image[mBaseLevel]->getHeight() >> i, 1);
		image[i] = egl::Image::create(this, w, h, depth, 0, image[mBaseLevel]->getFormat());

		if(!image[i])
		{
			return error(GL_OUT_OF_MEMORY);
		}

		GLsizei srcw = image[i - 1]->getWidth();
		GLsizei srch = image[i - 1]->getHeight();
		for(int z = 0; z < depth; ++z)
		{
			sw::SliceRectF srcRect(0.0f, 0.0f, static_cast<float>(srcw), static_cast<float>(srch), z);
			sw::SliceRect dstRect(0, 0, w, h, z);
			getDevice()->stretchRect(image[i - 1], &srcRect, image[i], &dstRect, Device::ALL_BUFFERS | Device::USE_FILTER);
		}
	}
}

TextureExternal::TextureExternal(GLuint name) : Texture2D(name)
{
	mMinFilter = GL_LINEAR;
	mMagFilter = GL_LINEAR;
	mWrapS = GL_CLAMP_TO_EDGE;
	mWrapT = GL_CLAMP_TO_EDGE;
	mWrapR = GL_CLAMP_TO_EDGE;
}

TextureExternal::~TextureExternal()
{
}

GLenum TextureExternal::getTarget() const
{
	return GL_TEXTURE_EXTERNAL_OES;
}

}

NO_SANITIZE_FUNCTION egl::Image *createBackBuffer(int width, int height, sw::Format format, int multiSampleDepth)
{
	if(width > es2::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE || height > es2::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE)
	{
		ERR("Invalid parameters: %dx%d", width, height);
		return nullptr;
	}

	GLenum internalformat = sw2es::ConvertBackBufferFormat(format);

	return egl::Image::create(width, height, internalformat, multiSampleDepth, false);
}

NO_SANITIZE_FUNCTION egl::Image *createBackBufferFromClientBuffer(const egl::ClientBuffer& clientBuffer)
{
	if(clientBuffer.getWidth() > es2::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE ||
	   clientBuffer.getHeight() > es2::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE)
	{
		ERR("Invalid parameters: %dx%d", clientBuffer.getWidth(), clientBuffer.getHeight());
		return nullptr;
	}

	return egl::Image::create(clientBuffer);
}

NO_SANITIZE_FUNCTION egl::Image *createDepthStencil(int width, int height, sw::Format format, int multiSampleDepth)
{
	if(width > es2::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE || height > es2::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE)
	{
		ERR("Invalid parameters: %dx%d", width, height);
		return nullptr;
	}

	bool lockable = true;

	switch(format)
	{
//	case sw::FORMAT_D15S1:
	case sw::FORMAT_D24S8:
	case sw::FORMAT_D24X8:
//	case sw::FORMAT_D24X4S4:
	case sw::FORMAT_D24FS8:
	case sw::FORMAT_D32:
	case sw::FORMAT_D16:
		lockable = false;
		break;
//	case sw::FORMAT_S8_LOCKABLE:
//	case sw::FORMAT_D16_LOCKABLE:
	case sw::FORMAT_D32F_LOCKABLE:
//	case sw::FORMAT_D32_LOCKABLE:
	case sw::FORMAT_DF24S8:
	case sw::FORMAT_DF16S8:
		lockable = true;
		break;
	default:
		UNREACHABLE(format);
	}

	GLenum internalformat = sw2es::ConvertDepthStencilFormat(format);

	egl::Image *surface = egl::Image::create(width, height, internalformat, multiSampleDepth, lockable);

	if(!surface)
	{
		ERR("Out of memory");
		return nullptr;
	}

	return surface;
}
