// 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.

#include "Image.hpp"

#include "../libEGL/Texture.hpp"
#include "../common/debug.h"
#include "Common/Math.hpp"
#include "Common/Thread.hpp"

#include <GLES3/gl3.h>

#include <string.h>
#include <algorithm>

#if defined(__APPLE__)
#include <CoreFoundation/CoreFoundation.h>
#include <IOSurface/IOSurface.h>
#endif

namespace gl
{
	bool IsUnsizedInternalFormat(GLint internalformat)
	{
		switch(internalformat)
		{
		case GL_ALPHA:
		case GL_LUMINANCE:
		case GL_LUMINANCE_ALPHA:
		case GL_RED:
		case GL_RG:
		case GL_RGB:
		case GL_RGBA:
		case GL_RED_INTEGER:
		case GL_RG_INTEGER:
		case GL_RGB_INTEGER:
		case GL_RGBA_INTEGER:
		case GL_BGRA_EXT:
		case GL_DEPTH_COMPONENT:
		case GL_DEPTH_STENCIL:
		// GL_EXT_sRGB
	//	case GL_SRGB_EXT:
	//	case GL_SRGB_ALPHA_EXT:
			return true;
		default:
			return false;
		}
	}

	GLenum GetBaseInternalFormat(GLint internalformat)
	{
		switch(internalformat)
		{
		// [OpenGL ES 3.0 Table 3.13]
		case GL_R8:       return GL_RED;
		case GL_R8_SNORM: return GL_RED;
		case GL_RG8:       return GL_RG;
		case GL_RG8_SNORM: return GL_RG;
		case GL_RGB8:       return GL_RGB;
		case GL_RGB8_SNORM: return GL_RGB;
		case GL_RGB565:     return GL_RGB;
		case GL_RGBA4:        return GL_RGBA;
		case GL_RGB5_A1:      return GL_RGBA;
		case GL_RGBA8:        return GL_RGBA;
		case GL_RGBA8_SNORM:  return GL_RGBA;
		case GL_RGB10_A2:     return GL_RGBA;
		case GL_RGB10_A2UI:   return GL_RGBA;
		case GL_SRGB8:        return GL_RGB;
		case GL_SRGB8_ALPHA8: return GL_RGBA;
		case GL_R16F:    return GL_RED;
		case GL_RG16F:   return GL_RG;
		case GL_RGB16F:  return GL_RGB;
		case GL_RGBA16F: return GL_RGBA;
		case GL_R32F:    return GL_RED;
		case GL_RG32F:   return GL_RG;
		case GL_RGB32F:  return GL_RGB;
		case GL_RGBA32F: return GL_RGBA;
		case GL_R11F_G11F_B10F: return GL_RGB;
		case GL_RGB9_E5:        return GL_RGB;
		case GL_R8I:      return GL_RED;
		case GL_R8UI:     return GL_RED;
		case GL_R16I:     return GL_RED;
		case GL_R16UI:    return GL_RED;
		case GL_R32I:     return GL_RED;
		case GL_R32UI:    return GL_RED;
		case GL_RG8I:     return GL_RG;
		case GL_RG8UI:    return GL_RG;
		case GL_RG16I:    return GL_RG;
		case GL_RG16UI:   return GL_RG;
		case GL_RG32I:    return GL_RG;
		case GL_RG32UI:   return GL_RG;
		case GL_RGB8I:    return GL_RGB;
		case GL_RGB8UI:   return GL_RGB;
		case GL_RGB16I:   return GL_RGB;
		case GL_RGB16UI:  return GL_RGB;
		case GL_RGB32I:   return GL_RGB;
		case GL_RGB32UI:  return GL_RGB;
		case GL_RGBA8I:   return GL_RGBA;
		case GL_RGBA8UI:  return GL_RGBA;
		case GL_RGBA16I:  return GL_RGBA;
		case GL_RGBA16UI: return GL_RGBA;
		case GL_RGBA32I:  return GL_RGBA;
		case GL_RGBA32UI: return GL_RGBA;

		// GL_EXT_texture_storage
		case GL_ALPHA8_EXT:             return GL_ALPHA;
		case GL_LUMINANCE8_EXT:         return GL_LUMINANCE;
		case GL_LUMINANCE8_ALPHA8_EXT:  return GL_LUMINANCE_ALPHA;
		case GL_ALPHA32F_EXT:           return GL_ALPHA;
		case GL_LUMINANCE32F_EXT:       return GL_LUMINANCE;
		case GL_LUMINANCE_ALPHA32F_EXT: return GL_LUMINANCE_ALPHA;
		case GL_ALPHA16F_EXT:           return GL_ALPHA;
		case GL_LUMINANCE16F_EXT:       return GL_LUMINANCE;
		case GL_LUMINANCE_ALPHA16F_EXT: return GL_LUMINANCE_ALPHA;

		case GL_BGRA8_EXT: return GL_BGRA_EXT;   // GL_APPLE_texture_format_BGRA8888

		case GL_DEPTH_COMPONENT24:     return GL_DEPTH_COMPONENT;
		case GL_DEPTH_COMPONENT32_OES: return GL_DEPTH_COMPONENT;
		case GL_DEPTH_COMPONENT32F:    return GL_DEPTH_COMPONENT;
		case GL_DEPTH_COMPONENT16:     return GL_DEPTH_COMPONENT;
		case GL_DEPTH32F_STENCIL8:     return GL_DEPTH_STENCIL;
		case GL_DEPTH24_STENCIL8:      return GL_DEPTH_STENCIL;
		case GL_STENCIL_INDEX8:        return GL_STENCIL_INDEX_OES;
		default:
			UNREACHABLE(internalformat);
			break;
		}

		return GL_NONE;
	}

	GLint GetSizedInternalFormat(GLint internalformat, GLenum type)
	{
		if(!IsUnsizedInternalFormat(internalformat))
		{
			return internalformat;
		}

		switch(internalformat)
		{
		case GL_RGBA:
			switch(type)
			{
			case GL_UNSIGNED_BYTE: return GL_RGBA8;
			case GL_BYTE:          return GL_RGBA8_SNORM;
			case GL_UNSIGNED_SHORT_4_4_4_4:      return GL_RGBA4;
			case GL_UNSIGNED_SHORT_5_5_5_1:      return GL_RGB5_A1;
			case GL_UNSIGNED_INT_2_10_10_10_REV: return GL_RGB10_A2;
			case GL_FLOAT:          return GL_RGBA32F;
			case GL_HALF_FLOAT:     return GL_RGBA16F;
			case GL_HALF_FLOAT_OES: return GL_RGBA16F;
			default: UNREACHABLE(type); return GL_NONE;
			}
		case GL_RGBA_INTEGER:
			switch(type)
			{
			case GL_UNSIGNED_BYTE:  return GL_RGBA8UI;
			case GL_BYTE:           return GL_RGBA8I;
			case GL_UNSIGNED_SHORT: return GL_RGBA16UI;
			case GL_SHORT:          return GL_RGBA16I;
			case GL_UNSIGNED_INT:   return GL_RGBA32UI;
			case GL_INT:            return GL_RGBA32I;
			case GL_UNSIGNED_INT_2_10_10_10_REV: return GL_RGB10_A2UI;
			default: UNREACHABLE(type); return GL_NONE;
			}
		case GL_RGB:
			switch(type)
			{
			case GL_UNSIGNED_BYTE:  return GL_RGB8;
			case GL_BYTE:           return GL_RGB8_SNORM;
			case GL_UNSIGNED_SHORT_5_6_5:         return GL_RGB565;
			case GL_UNSIGNED_INT_10F_11F_11F_REV: return GL_R11F_G11F_B10F;
			case GL_UNSIGNED_INT_5_9_9_9_REV:     return GL_RGB9_E5;
			case GL_FLOAT:          return GL_RGB32F;
			case GL_HALF_FLOAT:     return GL_RGB16F;
			case GL_HALF_FLOAT_OES: return GL_RGB16F;
			default: UNREACHABLE(type); return GL_NONE;
			}
		case GL_RGB_INTEGER:
			switch(type)
			{
			case GL_UNSIGNED_BYTE:  return GL_RGB8UI;
			case GL_BYTE:           return GL_RGB8I;
			case GL_UNSIGNED_SHORT: return GL_RGB16UI;
			case GL_SHORT:          return GL_RGB16I;
			case GL_UNSIGNED_INT:   return GL_RGB32UI;
			case GL_INT:            return GL_RGB32I;
			default: UNREACHABLE(type); return GL_NONE;
			}
		case GL_RG:
			switch(type)
			{
			case GL_UNSIGNED_BYTE:  return GL_RG8;
			case GL_BYTE:           return GL_RG8_SNORM;
			case GL_FLOAT:          return GL_RG32F;
			case GL_HALF_FLOAT:     return GL_RG16F;
			case GL_HALF_FLOAT_OES: return GL_RG16F;
			default: UNREACHABLE(type); return GL_NONE;
			}
		case GL_RG_INTEGER:
			switch(type)
			{
			case GL_UNSIGNED_BYTE:  return GL_RG8UI;
			case GL_BYTE:           return GL_RG8I;
			case GL_UNSIGNED_SHORT: return GL_RG16UI;
			case GL_SHORT:          return GL_RG16I;
			case GL_UNSIGNED_INT:   return GL_RG32UI;
			case GL_INT:            return GL_RG32I;
			default: UNREACHABLE(type); return GL_NONE;
			}
		case GL_RED:
			switch(type)
			{
			case GL_UNSIGNED_BYTE:  return GL_R8;
			case GL_BYTE:           return GL_R8_SNORM;
			case GL_FLOAT:          return GL_R32F;
			case GL_HALF_FLOAT:     return GL_R16F;
			case GL_HALF_FLOAT_OES: return GL_R16F;
			default: UNREACHABLE(type); return GL_NONE;
			}
		case GL_RED_INTEGER:
			switch(type)
			{
			case GL_UNSIGNED_BYTE:  return GL_R8UI;
			case GL_BYTE:           return GL_R8I;
			case GL_UNSIGNED_SHORT: return GL_R16UI;
			case GL_SHORT:          return GL_R16I;
			case GL_UNSIGNED_INT:   return GL_R32UI;
			case GL_INT:            return GL_R32I;
			default: UNREACHABLE(type); return GL_NONE;
			}
		case GL_LUMINANCE_ALPHA:
			switch(type)
			{
			case GL_UNSIGNED_BYTE:  return GL_LUMINANCE8_ALPHA8_EXT;
			case GL_FLOAT:          return GL_LUMINANCE_ALPHA32F_EXT;
			case GL_HALF_FLOAT:     return GL_LUMINANCE_ALPHA16F_EXT;
			case GL_HALF_FLOAT_OES: return GL_LUMINANCE_ALPHA16F_EXT;
			default: UNREACHABLE(type); return GL_NONE;
			}
		case GL_LUMINANCE:
			switch(type)
			{
			case GL_UNSIGNED_BYTE:  return GL_LUMINANCE8_EXT;
			case GL_FLOAT:          return GL_LUMINANCE32F_EXT;
			case GL_HALF_FLOAT:     return GL_LUMINANCE16F_EXT;
			case GL_HALF_FLOAT_OES: return GL_LUMINANCE16F_EXT;
			default: UNREACHABLE(type); return GL_NONE;
			}
		case GL_ALPHA:
			switch(type)
			{
			case GL_UNSIGNED_BYTE:  return GL_ALPHA8_EXT;
			case GL_FLOAT:          return GL_ALPHA32F_EXT;
			case GL_HALF_FLOAT:     return GL_ALPHA16F_EXT;
			case GL_HALF_FLOAT_OES: return GL_ALPHA16F_EXT;
			default: UNREACHABLE(type); return GL_NONE;
			}
		case GL_BGRA_EXT:
			switch(type)
			{
			case GL_UNSIGNED_BYTE:                  return GL_BGRA8_EXT;
			case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT: // Only valid for glReadPixels calls.
			case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT: // Only valid for glReadPixels calls.
			default: UNREACHABLE(type); return GL_NONE;
			}
		case GL_DEPTH_COMPONENT:
			switch(type)
			{
			case GL_UNSIGNED_SHORT: return GL_DEPTH_COMPONENT16;
			case GL_UNSIGNED_INT:   return GL_DEPTH_COMPONENT32_OES;
			case GL_FLOAT:          return GL_DEPTH_COMPONENT32F;
			default: UNREACHABLE(type); return GL_NONE;
			}
		case GL_DEPTH_STENCIL:
			switch(type)
			{
			case GL_UNSIGNED_INT_24_8:              return GL_DEPTH24_STENCIL8;
			case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: return GL_DEPTH32F_STENCIL8;
			default: UNREACHABLE(type); return GL_NONE;
			}

		// GL_OES_texture_stencil8
	//	case GL_STENCIL_INDEX_OES / GL_UNSIGNED_BYTE: return GL_STENCIL_INDEX8;

		// GL_EXT_sRGB
	//	case GL_SRGB_EXT / GL_UNSIGNED_BYTE: return GL_SRGB8;
	//	case GL_SRGB_ALPHA_EXT / GL_UNSIGNED_BYTE: return GL_SRGB8_ALPHA8;

		default:
			UNREACHABLE(internalformat);
		}

		return GL_NONE;
	}

	sw::Format SelectInternalFormat(GLint format)
	{
		switch(format)
		{
		case GL_RGBA4:   return sw::FORMAT_A8B8G8R8;
		case GL_RGB5_A1: return sw::FORMAT_A8B8G8R8;
		case GL_RGBA8:   return sw::FORMAT_A8B8G8R8;
		case GL_RGB565:  return sw::FORMAT_R5G6B5;
		case GL_RGB8:    return sw::FORMAT_X8B8G8R8;

		case GL_DEPTH_COMPONENT32F:    return sw::FORMAT_D32F_LOCKABLE;
		case GL_DEPTH_COMPONENT16:     return sw::FORMAT_D32F_LOCKABLE;
		case GL_DEPTH_COMPONENT24:     return sw::FORMAT_D32F_LOCKABLE;
		case GL_DEPTH_COMPONENT32_OES: return sw::FORMAT_D32F_LOCKABLE;
		case GL_DEPTH24_STENCIL8:      return sw::FORMAT_D32FS8_TEXTURE;
		case GL_DEPTH32F_STENCIL8:     return sw::FORMAT_D32FS8_TEXTURE;
		case GL_STENCIL_INDEX8:        return sw::FORMAT_S8;

		case GL_R8:             return sw::FORMAT_R8;
		case GL_RG8:            return sw::FORMAT_G8R8;
		case GL_R8I:            return sw::FORMAT_R8I;
		case GL_RG8I:           return sw::FORMAT_G8R8I;
		case GL_RGB8I:          return sw::FORMAT_X8B8G8R8I;
		case GL_RGBA8I:         return sw::FORMAT_A8B8G8R8I;
		case GL_R8UI:           return sw::FORMAT_R8UI;
		case GL_RG8UI:          return sw::FORMAT_G8R8UI;
		case GL_RGB8UI:         return sw::FORMAT_X8B8G8R8UI;
		case GL_RGBA8UI:        return sw::FORMAT_A8B8G8R8UI;
		case GL_R16I:           return sw::FORMAT_R16I;
		case GL_RG16I:          return sw::FORMAT_G16R16I;
		case GL_RGB16I:         return sw::FORMAT_X16B16G16R16I;
		case GL_RGBA16I:        return sw::FORMAT_A16B16G16R16I;
		case GL_R16UI:          return sw::FORMAT_R16UI;
		case GL_RG16UI:         return sw::FORMAT_G16R16UI;
		case GL_RGB16UI:        return sw::FORMAT_X16B16G16R16UI;
		case GL_RGBA16UI:       return sw::FORMAT_A16B16G16R16UI;
		case GL_R32I:           return sw::FORMAT_R32I;
		case GL_RG32I:          return sw::FORMAT_G32R32I;
		case GL_RGB32I:         return sw::FORMAT_X32B32G32R32I;
		case GL_RGBA32I:        return sw::FORMAT_A32B32G32R32I;
		case GL_R32UI:          return sw::FORMAT_R32UI;
		case GL_RG32UI:         return sw::FORMAT_G32R32UI;
		case GL_RGB32UI:        return sw::FORMAT_X32B32G32R32UI;
		case GL_RGBA32UI:       return sw::FORMAT_A32B32G32R32UI;
		case GL_R16F:           return sw::FORMAT_R16F;
		case GL_RG16F:          return sw::FORMAT_G16R16F;
		case GL_R11F_G11F_B10F: return sw::FORMAT_X16B16G16R16F_UNSIGNED;
		case GL_RGB16F:         return sw::FORMAT_X16B16G16R16F;
		case GL_RGBA16F:        return sw::FORMAT_A16B16G16R16F;
		case GL_R32F:           return sw::FORMAT_R32F;
		case GL_RG32F:          return sw::FORMAT_G32R32F;
		case GL_RGB32F:         return sw::FORMAT_X32B32G32R32F;
		case GL_RGBA32F:        return sw::FORMAT_A32B32G32R32F;
		case GL_RGB10_A2:       return sw::FORMAT_A2B10G10R10;
		case GL_RGB10_A2UI:     return sw::FORMAT_A2B10G10R10UI;
		case GL_SRGB8:          return sw::FORMAT_SRGB8_X8;
		case GL_SRGB8_ALPHA8:   return sw::FORMAT_SRGB8_A8;

		case GL_ETC1_RGB8_OES:              return sw::FORMAT_ETC1;
		case GL_COMPRESSED_R11_EAC:         return sw::FORMAT_R11_EAC;
		case GL_COMPRESSED_SIGNED_R11_EAC:  return sw::FORMAT_SIGNED_R11_EAC;
		case GL_COMPRESSED_RG11_EAC:        return sw::FORMAT_RG11_EAC;
		case GL_COMPRESSED_SIGNED_RG11_EAC: return sw::FORMAT_SIGNED_RG11_EAC;
		case GL_COMPRESSED_RGB8_ETC2:       return sw::FORMAT_RGB8_ETC2;
		case GL_COMPRESSED_SRGB8_ETC2:      return sw::FORMAT_SRGB8_ETC2;
		case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:  return sw::FORMAT_RGB8_PUNCHTHROUGH_ALPHA1_ETC2;
		case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: return sw::FORMAT_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2;
		case GL_COMPRESSED_RGBA8_ETC2_EAC:        return sw::FORMAT_RGBA8_ETC2_EAC;
		case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: return sw::FORMAT_SRGB8_ALPHA8_ETC2_EAC;
		case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:    return sw::FORMAT_DXT1;
		case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:   return sw::FORMAT_DXT1;
		case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: return sw::FORMAT_DXT3;
		case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: return sw::FORMAT_DXT5;

		case GL_ALPHA32F_EXT:           return sw::FORMAT_A32F;
		case GL_LUMINANCE32F_EXT:       return sw::FORMAT_L32F;
		case GL_LUMINANCE_ALPHA32F_EXT: return sw::FORMAT_A32L32F;
		case GL_RGB9_E5:                return sw::FORMAT_X16B16G16R16F_UNSIGNED;
		case GL_ALPHA16F_EXT:           return sw::FORMAT_A16F;
		case GL_LUMINANCE16F_EXT:       return sw::FORMAT_L16F;
		case GL_LUMINANCE_ALPHA16F_EXT: return sw::FORMAT_A16L16F;
		case GL_R8_SNORM:    return sw::FORMAT_R8_SNORM;
		case GL_RG8_SNORM:   return sw::FORMAT_G8R8_SNORM;
		case GL_RGB8_SNORM:  return sw::FORMAT_X8B8G8R8_SNORM;
		case GL_RGBA8_SNORM: return sw::FORMAT_A8B8G8R8_SNORM;
		case GL_LUMINANCE8_EXT:        return sw::FORMAT_L8;
		case GL_LUMINANCE8_ALPHA8_EXT: return sw::FORMAT_A8L8;
		case GL_BGRA8_EXT:  return sw::FORMAT_A8R8G8B8;
		case GL_ALPHA8_EXT: return sw::FORMAT_A8;

		case SW_YV12_BT601: return sw::FORMAT_YV12_BT601;
		case SW_YV12_BT709: return sw::FORMAT_YV12_BT709;
		case SW_YV12_JFIF:  return sw::FORMAT_YV12_JFIF;

		default:
			UNREACHABLE(format);   // Not a sized internal format.
			return sw::FORMAT_NULL;
		}
	}

	// Returns the size, in bytes, of a single client-side pixel.
    // OpenGL ES 3.0.5 table 3.2.
	GLsizei ComputePixelSize(GLenum format, GLenum type)
	{
		switch(format)
		{
		case GL_RED:
		case GL_RED_INTEGER:
		case GL_ALPHA:
		case GL_LUMINANCE:
			switch(type)
			{
			case GL_BYTE:           return 1;
			case GL_UNSIGNED_BYTE:  return 1;
			case GL_FLOAT:          return 4;
			case GL_HALF_FLOAT:     return 2;
			case GL_HALF_FLOAT_OES: return 2;
			case GL_SHORT:          return 2;
			case GL_UNSIGNED_SHORT: return 2;
			case GL_INT:            return 4;
			case GL_UNSIGNED_INT:   return 4;
			default: UNREACHABLE(type);
			}
			break;
		case GL_RG:
		case GL_RG_INTEGER:
		case GL_LUMINANCE_ALPHA:
			switch(type)
			{
			case GL_BYTE:           return 2;
			case GL_UNSIGNED_BYTE:  return 2;
			case GL_FLOAT:          return 8;
			case GL_HALF_FLOAT:     return 4;
			case GL_HALF_FLOAT_OES: return 4;
			case GL_SHORT:          return 4;
			case GL_UNSIGNED_SHORT: return 4;
			case GL_INT:            return 8;
			case GL_UNSIGNED_INT:   return 8;
			default: UNREACHABLE(type);
			}
			break;
		case GL_RGB:
		case GL_RGB_INTEGER:
			switch(type)
			{
			case GL_BYTE:                         return 3;
			case GL_UNSIGNED_BYTE:                return 3;
			case GL_UNSIGNED_SHORT_5_6_5:         return 2;
			case GL_UNSIGNED_INT_10F_11F_11F_REV: return 4;
			case GL_UNSIGNED_INT_5_9_9_9_REV:     return 4;
			case GL_FLOAT:                        return 12;
			case GL_HALF_FLOAT:                   return 6;
			case GL_HALF_FLOAT_OES:               return 6;
			case GL_SHORT:                        return 6;
			case GL_UNSIGNED_SHORT:               return 6;
			case GL_INT:                          return 12;
			case GL_UNSIGNED_INT:                 return 12;
			default: UNREACHABLE(type);
			}
			break;
		case GL_RGBA:
		case GL_RGBA_INTEGER:
		case GL_BGRA_EXT:
			switch(type)
			{
			case GL_BYTE:                           return 4;
			case GL_UNSIGNED_BYTE:                  return 4;
			case GL_UNSIGNED_SHORT_4_4_4_4:         return 2;
			case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT: return 2;
			case GL_UNSIGNED_SHORT_5_5_5_1:         return 2;
			case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT: return 2;
			case GL_UNSIGNED_INT_2_10_10_10_REV:    return 4;
			case GL_FLOAT:                          return 16;
			case GL_HALF_FLOAT:                     return 8;
			case GL_HALF_FLOAT_OES:                 return 8;
			case GL_SHORT:                          return 8;
			case GL_UNSIGNED_SHORT:                 return 8;
			case GL_INT:                            return 16;
			case GL_UNSIGNED_INT:                   return 16;
			default: UNREACHABLE(type);
			}
			break;
		case GL_DEPTH_COMPONENT:
			switch(type)
			{
			case GL_FLOAT:          return 4;
			case GL_UNSIGNED_SHORT: return 2;
			case GL_UNSIGNED_INT:   return 4;
			default: UNREACHABLE(type);
			}
			break;
		case GL_DEPTH_STENCIL:
			switch(type)
			{
			case GL_UNSIGNED_INT_24_8:              return 4;
			case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: return 8;
			default: UNREACHABLE(type);
			}
			break;
		default:
			UNREACHABLE(format);
		}

		return 0;
	}

	GLsizei ComputePitch(GLsizei width, GLenum format, GLenum type, GLint alignment)
	{
		ASSERT(alignment > 0 && sw::isPow2(alignment));

		GLsizei rawPitch = ComputePixelSize(format, type) * width;
		return (rawPitch + alignment - 1) & ~(alignment - 1);
	}

	size_t ComputePackingOffset(GLenum format, GLenum type, GLsizei width, GLsizei height, const gl::PixelStorageModes &storageModes)
	{
		GLsizei pitchB = ComputePitch(width, format, type, storageModes.alignment);
		return (storageModes.skipImages * height + storageModes.skipRows) * pitchB + storageModes.skipPixels * ComputePixelSize(format, type);
	}

	inline GLsizei ComputeCompressedPitch(GLsizei width, GLenum format)
	{
		return ComputeCompressedSize(width, 1, format);
	}

	inline int GetNumCompressedBlocks(int w, int h, int blockSizeX, int blockSizeY)
	{
		return ((w + blockSizeX - 1) / blockSizeX) * ((h + blockSizeY - 1) / blockSizeY);
	}

	GLsizei ComputeCompressedSize(GLsizei width, GLsizei height, GLenum format)
	{
		switch(format)
		{
		case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
		case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
		case GL_ETC1_RGB8_OES:
		case GL_COMPRESSED_R11_EAC:
		case GL_COMPRESSED_SIGNED_R11_EAC:
		case GL_COMPRESSED_RGB8_ETC2:
		case GL_COMPRESSED_SRGB8_ETC2:
		case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
		case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
			return 8 * GetNumCompressedBlocks(width, height, 4, 4);
		case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
		case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
		case GL_COMPRESSED_RG11_EAC:
		case GL_COMPRESSED_SIGNED_RG11_EAC:
		case GL_COMPRESSED_RGBA8_ETC2_EAC:
		case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
			return 16 * GetNumCompressedBlocks(width, height, 4, 4);
		default:
			UNREACHABLE(format);
			return 0;
		}
	}
}

namespace egl
{
	// We assume the image data can be indexed with a signed 32-bit offset,
	// so we must keep the size reasonable. 1 GiB ought to be enough for anybody.
	// 4 extra bytes account for the padding added in Surface::size().
	// They are not addressed separately, so can't cause overflow.
	// TODO(b/145229887): Eliminate or don't hard-code the padding bytes.
	enum : uint64_t { IMPLEMENTATION_MAX_IMAGE_SIZE_BYTES = 0x40000000u + 4 };

	enum TransferType
	{
		Bytes,
		RGB8toRGBX8,
		RGB16toRGBX16,
		RGB32toRGBX32,
		RGB32FtoRGBX32F,
		RGB16FtoRGBX16F,
		RGBA4toRGBA8,
		RGBA5_A1toRGBA8,
		R11G11B10FtoRGBX16F,
		RGB9_E5FtoRGBX16F,
		D16toD32F,
		D24X8toD32F,
		D32toD32F,
		D32FtoD32F_CLAMPED,
		D32FX32toD32F,
		X24S8toS8,
		X56S8toS8,
		RGBA1010102toRGBA8,
		RGB8toRGB565,
		R32FtoR16F,
		RG32FtoRG16F,
		RGB32FtoRGB16F,
		RGB32FtoRGB16F_UNSIGNED,
		RGBA32FtoRGBA16F
	};

	template<TransferType transferType>
	void TransferRow(unsigned char *dest, const unsigned char *source, GLsizei width, GLsizei bytes);

	template<>
	void TransferRow<Bytes>(unsigned char *dest, const unsigned char *source, GLsizei width, GLsizei bytes)
	{
		memcpy(dest, source, width * bytes);
	}

	template<>
	void TransferRow<RGB8toRGBX8>(unsigned char *dest, const unsigned char *source, GLsizei width, GLsizei bytes)
	{
		unsigned char *destB = dest;

		for(int x = 0; x < width; x++)
		{
			destB[4 * x + 0] = source[x * 3 + 0];
			destB[4 * x + 1] = source[x * 3 + 1];
			destB[4 * x + 2] = source[x * 3 + 2];
			destB[4 * x + 3] = 0xFF;
		}
	}

	template<>
	void TransferRow<RGB16toRGBX16>(unsigned char *dest, const unsigned char *source, GLsizei width, GLsizei bytes)
	{
		const unsigned short *sourceS = reinterpret_cast<const unsigned short*>(source);
		unsigned short *destS = reinterpret_cast<unsigned short*>(dest);

		for(int x = 0; x < width; x++)
		{
			destS[4 * x + 0] = sourceS[x * 3 + 0];
			destS[4 * x + 1] = sourceS[x * 3 + 1];
			destS[4 * x + 2] = sourceS[x * 3 + 2];
			destS[4 * x + 3] = 0xFFFF;
		}
	}

	template<>
	void TransferRow<RGB32toRGBX32>(unsigned char *dest, const unsigned char *source, GLsizei width, GLsizei bytes)
	{
		const unsigned int *sourceI = reinterpret_cast<const unsigned int*>(source);
		unsigned int *destI = reinterpret_cast<unsigned int*>(dest);

		for(int x = 0; x < width; x++)
		{
			destI[4 * x + 0] = sourceI[x * 3 + 0];
			destI[4 * x + 1] = sourceI[x * 3 + 1];
			destI[4 * x + 2] = sourceI[x * 3 + 2];
			destI[4 * x + 3] = 0xFFFFFFFF;
		}
	}

	template<>
	void TransferRow<RGB32FtoRGBX32F>(unsigned char *dest, const unsigned char *source, GLsizei width, GLsizei bytes)
	{
		const float *sourceF = reinterpret_cast<const float*>(source);
		float *destF = reinterpret_cast<float*>(dest);

		for(int x = 0; x < width; x++)
		{
			destF[4 * x + 0] = sourceF[x * 3 + 0];
			destF[4 * x + 1] = sourceF[x * 3 + 1];
			destF[4 * x + 2] = sourceF[x * 3 + 2];
			destF[4 * x + 3] = 1.0f;
		}
	}

	template<>
	void TransferRow<RGB16FtoRGBX16F>(unsigned char *dest, const unsigned char *source, GLsizei width, GLsizei bytes)
	{
		const unsigned short *sourceH = reinterpret_cast<const unsigned short*>(source);
		unsigned short *destH = reinterpret_cast<unsigned short*>(dest);

		for(int x = 0; x < width; x++)
		{
			destH[4 * x + 0] = sourceH[x * 3 + 0];
			destH[4 * x + 1] = sourceH[x * 3 + 1];
			destH[4 * x + 2] = sourceH[x * 3 + 2];
			destH[4 * x + 3] = 0x3C00;   // SEEEEEMMMMMMMMMM, S = 0, E = 15, M = 0: 16-bit floating-point representation of 1.0
		}
	}

	template<>
	void TransferRow<RGBA4toRGBA8>(unsigned char *dest, const unsigned char *source, GLsizei width, GLsizei bytes)
	{
		const unsigned short *source4444 = reinterpret_cast<const unsigned short*>(source);
		unsigned char *dest4444 = dest;

		for(int x = 0; x < width; x++)
		{
			unsigned short rgba = source4444[x];
			dest4444[4 * x + 0] = ((rgba & 0xF000) >> 8) | ((rgba & 0xF000) >> 12);
			dest4444[4 * x + 1] = ((rgba & 0x0F00) >> 4) | ((rgba & 0x0F00) >> 8);
			dest4444[4 * x + 2] = ((rgba & 0x00F0) << 0) | ((rgba & 0x00F0) >> 4);
			dest4444[4 * x + 3] = ((rgba & 0x000F) << 4) | ((rgba & 0x000F) >> 0);
		}
	}

	template<>
	void TransferRow<RGBA5_A1toRGBA8>(unsigned char *dest, const unsigned char *source, GLsizei width, GLsizei bytes)
	{
		const unsigned short *source5551 = reinterpret_cast<const unsigned short*>(source);
		unsigned char *dest8888 = dest;

		for(int x = 0; x < width; x++)
		{
			unsigned short rgba = source5551[x];
			dest8888[4 * x + 0] = ((rgba & 0xF800) >> 8) | ((rgba & 0xF800) >> 13);
			dest8888[4 * x + 1] = ((rgba & 0x07C0) >> 3) | ((rgba & 0x07C0) >> 8);
			dest8888[4 * x + 2] = ((rgba & 0x003E) << 2) | ((rgba & 0x003E) >> 3);
			dest8888[4 * x + 3] = (rgba & 0x0001) ? 0xFF : 0;
		}
	}

	template<>
	void TransferRow<RGBA1010102toRGBA8>(unsigned char *dest, const unsigned char *source, GLsizei width, GLsizei bytes)
	{
		const unsigned int *source1010102 = reinterpret_cast<const unsigned int*>(source);
		unsigned char *dest8888 = dest;

		for(int x = 0; x < width; x++)
		{
			unsigned int rgba = source1010102[x];
			dest8888[4 * x + 0] = sw::unorm<8>((rgba & 0x000003FF) * (1.0f / 0x000003FF));
			dest8888[4 * x + 1] = sw::unorm<8>((rgba & 0x000FFC00) * (1.0f / 0x000FFC00));
			dest8888[4 * x + 2] = sw::unorm<8>((rgba & 0x3FF00000) * (1.0f / 0x3FF00000));
			dest8888[4 * x + 3] = sw::unorm<8>((rgba & 0xC0000000) * (1.0f / 0xC0000000));
		}
	}

	template<>
	void TransferRow<RGB8toRGB565>(unsigned char *dest, const unsigned char *source, GLsizei width, GLsizei bytes)
	{
		unsigned short *dest565 = reinterpret_cast<unsigned short*>(dest);

		for(int x = 0; x < width; x++)
		{
			float r = source[3 * x + 0] * (1.0f / 0xFF);
			float g = source[3 * x + 1] * (1.0f / 0xFF);
			float b = source[3 * x + 2] * (1.0f / 0xFF);
			dest565[x] = (sw::unorm<5>(r) << 11) | (sw::unorm<6>(g) << 5) | (sw::unorm<5>(b) << 0);
		}
	}

	template<>
	void TransferRow<R11G11B10FtoRGBX16F>(unsigned char *dest, const unsigned char *source, GLsizei width, GLsizei bytes)
	{
		const sw::R11G11B10F *sourceRGB = reinterpret_cast<const sw::R11G11B10F*>(source);
		sw::half *destF = reinterpret_cast<sw::half*>(dest);

		for(int x = 0; x < width; x++, sourceRGB++, destF += 4)
		{
			sourceRGB->toRGB16F(destF);
			destF[3] = 1.0f;
		}
	}

	template<>
	void TransferRow<RGB9_E5FtoRGBX16F>(unsigned char *dest, const unsigned char *source, GLsizei width, GLsizei bytes)
	{
		const sw::RGB9E5 *sourceRGB = reinterpret_cast<const sw::RGB9E5*>(source);
		sw::half *destF = reinterpret_cast<sw::half*>(dest);

		for(int x = 0; x < width; x++, sourceRGB++, destF += 4)
		{
			sourceRGB->toRGB16F(destF);
			destF[3] = 1.0f;
		}
	}

	template<>
	void TransferRow<R32FtoR16F>(unsigned char *dest, const unsigned char *source, GLsizei width, GLsizei bytes)
	{
		const float *source32F = reinterpret_cast<const float*>(source);
		sw::half *dest16F = reinterpret_cast<sw::half*>(dest);

		for(int x = 0; x < width; x++)
		{
			dest16F[x] = source32F[x];
		}
	}

	template<>
	void TransferRow<RG32FtoRG16F>(unsigned char *dest, const unsigned char *source, GLsizei width, GLsizei bytes)
	{
		const float *source32F = reinterpret_cast<const float*>(source);
		sw::half *dest16F = reinterpret_cast<sw::half*>(dest);

		for(int x = 0; x < width; x++)
		{
			dest16F[2 * x + 0] = source32F[2 * x + 0];
			dest16F[2 * x + 1] = source32F[2 * x + 1];
		}
	}

	template<>
	void TransferRow<RGB32FtoRGB16F>(unsigned char *dest, const unsigned char *source, GLsizei width, GLsizei bytes)
	{
		const float *source32F = reinterpret_cast<const float*>(source);
		sw::half *dest16F = reinterpret_cast<sw::half*>(dest);

		for(int x = 0; x < width; x++)
		{
			dest16F[4 * x + 0] = source32F[3 * x + 0];
			dest16F[4 * x + 1] = source32F[3 * x + 1];
			dest16F[4 * x + 2] = source32F[3 * x + 2];
			dest16F[4 * x + 3] = 1.0f;
		}
	}

	template<>
	void TransferRow<RGB32FtoRGB16F_UNSIGNED>(unsigned char *dest, const unsigned char *source, GLsizei width, GLsizei bytes)
	{
		const float *source32F = reinterpret_cast<const float*>(source);
		sw::half *dest16F = reinterpret_cast<sw::half*>(dest);

		for(int x = 0; x < width; x++)
		{
			dest16F[4 * x + 0] = std::max(source32F[3 * x + 0], 0.0f);
			dest16F[4 * x + 1] = std::max(source32F[3 * x + 1], 0.0f);
			dest16F[4 * x + 2] = std::max(source32F[3 * x + 2], 0.0f);
			dest16F[4 * x + 3] = 1.0f;
		}
	}

	template<>
	void TransferRow<RGBA32FtoRGBA16F>(unsigned char *dest, const unsigned char *source, GLsizei width, GLsizei bytes)
	{
		const float *source32F = reinterpret_cast<const float*>(source);
		sw::half *dest16F = reinterpret_cast<sw::half*>(dest);

		for(int x = 0; x < width; x++)
		{
			dest16F[4 * x + 0] = source32F[4 * x + 0];
			dest16F[4 * x + 1] = source32F[4 * x + 1];
			dest16F[4 * x + 2] = source32F[4 * x + 2];
			dest16F[4 * x + 3] = source32F[4 * x + 3];
		}
	}

	template<>
	void TransferRow<D16toD32F>(unsigned char *dest, const unsigned char *source, GLsizei width, GLsizei bytes)
	{
		const unsigned short *sourceD16 = reinterpret_cast<const unsigned short*>(source);
		float *destF = reinterpret_cast<float*>(dest);

		for(int x = 0; x < width; x++)
		{
			destF[x] = (float)sourceD16[x] / 0xFFFF;
		}
	}

	template<>
	void TransferRow<D24X8toD32F>(unsigned char *dest, const unsigned char *source, GLsizei width, GLsizei bytes)
	{
		const unsigned int *sourceD24 = reinterpret_cast<const unsigned int*>(source);
		float *destF = reinterpret_cast<float*>(dest);

		for(int x = 0; x < width; x++)
		{
			destF[x] = (float)(sourceD24[x] & 0xFFFFFF00) / 0xFFFFFF00;
		}
	}

	template<>
	void TransferRow<D32toD32F>(unsigned char *dest, const unsigned char *source, GLsizei width, GLsizei bytes)
	{
		const unsigned int *sourceD32 = reinterpret_cast<const unsigned int*>(source);
		float *destF = reinterpret_cast<float*>(dest);

		for(int x = 0; x < width; x++)
		{
			// NOTE: Second (float) cast is required to avoid compiler warning:
			// error: implicit conversion from 'unsigned int' to 'float' changes value from
			// 4294967295 to 4294967296 [-Werror,-Wimplicit-int-float-conversion]
			destF[x] = (float)sourceD32[x] / (float)0xFFFFFFFF;
		}
	}

	template<>
	void TransferRow<D32FtoD32F_CLAMPED>(unsigned char *dest, const unsigned char *source, GLsizei width, GLsizei bytes)
	{
		const float *sourceF = reinterpret_cast<const float*>(source);
		float *destF = reinterpret_cast<float*>(dest);

		for(int x = 0; x < width; x++)
		{
			destF[x] = sw::clamp(sourceF[x], 0.0f, 1.0f);
		}
	}

	template<>
	void TransferRow<D32FX32toD32F>(unsigned char *dest, const unsigned char *source, GLsizei width, GLsizei bytes)
	{
		struct D32FS8 { float depth32f; unsigned int stencil24_8; };
		const D32FS8 *sourceD32FS8 = reinterpret_cast<const D32FS8*>(source);
		float *destF = reinterpret_cast<float*>(dest);

		for(int x = 0; x < width; x++)
		{
			destF[x] = sw::clamp(sourceD32FS8[x].depth32f, 0.0f, 1.0f);
		}
	}

	template<>
	void TransferRow<X24S8toS8>(unsigned char *dest, const unsigned char *source, GLsizei width, GLsizei bytes)
	{
		const unsigned int *sourceI = reinterpret_cast<const unsigned int*>(source);
		unsigned char *destI = dest;

		for(int x = 0; x < width; x++)
		{
			destI[x] = static_cast<unsigned char>(sourceI[x] & 0x000000FF);   // FIXME: Quad layout
		}
	}

	template<>
	void TransferRow<X56S8toS8>(unsigned char *dest, const unsigned char *source, GLsizei width, GLsizei bytes)
	{
		struct D32FS8 { float depth32f; unsigned int stencil24_8; };
		const D32FS8 *sourceD32FS8 = reinterpret_cast<const D32FS8*>(source);
		unsigned char *destI = dest;

		for(int x = 0; x < width; x++)
		{
			destI[x] = static_cast<unsigned char>(sourceD32FS8[x].stencil24_8 & 0x000000FF);   // FIXME: Quad layout
		}
	}

	struct Rectangle
	{
		GLsizei bytes;
		GLsizei width;
		GLsizei height;
		GLsizei depth;
		int inputPitch;
		int inputHeight;
		int destPitch;
		GLsizei destSlice;
	};

	template<TransferType transferType>
	void Transfer(void *buffer, const void *input, const Rectangle &rect)
	{
		for(int z = 0; z < rect.depth; z++)
		{
			const unsigned char *inputStart = static_cast<const unsigned char*>(input) + (z * rect.inputPitch * rect.inputHeight);
			unsigned char *destStart = static_cast<unsigned char*>(buffer) + (z * rect.destSlice);
			for(int y = 0; y < rect.height; y++)
			{
				const unsigned char *source = inputStart + y * rect.inputPitch;
				unsigned char *dest = destStart + y * rect.destPitch;

				TransferRow<transferType>(dest, source, rect.width, rect.bytes);
			}
		}
	}

	class ImageImplementation : public Image
	{
	public:
		ImageImplementation(Texture *parentTexture, GLsizei width, GLsizei height, GLint internalformat)
			: Image(parentTexture, width, height, internalformat) {}
		ImageImplementation(Texture *parentTexture, GLsizei width, GLsizei height, GLsizei depth, int border, GLint internalformat)
			: Image(parentTexture, width, height, depth, border, internalformat) {}
		ImageImplementation(GLsizei width, GLsizei height, GLint internalformat, int pitchP)
			: Image(width, height, internalformat, pitchP) {}
		ImageImplementation(GLsizei width, GLsizei height, GLint internalformat, int multiSampleDepth, bool lockable)
			: Image(width, height, internalformat, multiSampleDepth, lockable) {}

		~ImageImplementation() override
		{
			sync();   // Wait for any threads that use this image to finish.
		}

		void *lockInternal(int x, int y, int z, sw::Lock lock, sw::Accessor client) override
		{
			return Image::lockInternal(x, y, z, lock, client);
		}

		void unlockInternal() override
		{
			return Image::unlockInternal();
		}

		void release() override
		{
			return Image::release();
		}
	};

	Image *Image::create(Texture *parentTexture, GLsizei width, GLsizei height, GLint internalformat)
	{
		if(size(width, height, 1, 0, 1, internalformat) > IMPLEMENTATION_MAX_IMAGE_SIZE_BYTES)
		{
			return nullptr;
		}

		return new ImageImplementation(parentTexture, width, height, internalformat);
	}

	Image *Image::create(Texture *parentTexture, GLsizei width, GLsizei height, GLsizei depth, int border, GLint internalformat)
	{
		if(size(width, height, depth, border, 1, internalformat) > IMPLEMENTATION_MAX_IMAGE_SIZE_BYTES)
		{
			return nullptr;
		}

		return new ImageImplementation(parentTexture, width, height, depth, border, internalformat);
	}

	Image *Image::create(GLsizei width, GLsizei height, GLint internalformat, int pitchP)
	{
		if(size(pitchP, height, 1, 0, 1, internalformat) > IMPLEMENTATION_MAX_IMAGE_SIZE_BYTES)
		{
			return nullptr;
		}

		return new ImageImplementation(width, height, internalformat, pitchP);
	}

	Image *Image::create(GLsizei width, GLsizei height, GLint internalformat, int multiSampleDepth, bool lockable)
	{
		if(size(width, height, 1, 0, multiSampleDepth, internalformat) > IMPLEMENTATION_MAX_IMAGE_SIZE_BYTES)
		{
			return nullptr;
		}

		return new ImageImplementation(width, height, internalformat, multiSampleDepth, lockable);
	}

	size_t Image::size(int width, int height, int depth, int border, int samples, GLint internalformat)
	{
		return sw::Surface::size(width, height, depth, border, samples, gl::SelectInternalFormat(internalformat));
	}

	int ClientBuffer::getWidth() const
	{
		return width;
	}

	int ClientBuffer::getHeight() const
	{
		return height;
	}

	sw::Format ClientBuffer::getFormat() const
	{
		return format;
	}

	size_t ClientBuffer::getPlane() const
	{
		return plane;
	}

	int ClientBuffer::pitchP() const
	{
#if defined(__APPLE__)
		if(buffer)
		{
			IOSurfaceRef ioSurface = reinterpret_cast<IOSurfaceRef>(buffer);
			int pitchB = static_cast<int>(IOSurfaceGetBytesPerRowOfPlane(ioSurface, plane));
			int bytesPerPixel = sw::Surface::bytes(format);
			ASSERT((pitchB % bytesPerPixel) == 0);
			return pitchB / bytesPerPixel;
		}

		return 0;
#else
		return sw::Surface::pitchP(width, 0, format, false);
#endif
	}

	void ClientBuffer::retain()
	{
#if defined(__APPLE__)
		if(buffer)
		{
			CFRetain(reinterpret_cast<IOSurfaceRef>(buffer));
		}
#endif
	}

	void ClientBuffer::release()
	{
#if defined(__APPLE__)
		if(buffer)
		{
			CFRelease(reinterpret_cast<IOSurfaceRef>(buffer));
			buffer = nullptr;
		}
#endif
	}

	void* ClientBuffer::lock(int x, int y, int z)
	{
#if defined(__APPLE__)
		if(buffer)
		{
			IOSurfaceRef ioSurface = reinterpret_cast<IOSurfaceRef>(buffer);
			IOSurfaceLock(ioSurface, 0, nullptr);
			void* pixels = IOSurfaceGetBaseAddressOfPlane(ioSurface, plane);
			int bytes = sw::Surface::bytes(format);
			int pitchB = static_cast<int>(IOSurfaceGetBytesPerRowOfPlane(ioSurface, plane));
			int sliceB = static_cast<int>(IOSurfaceGetHeightOfPlane(ioSurface, plane)) * pitchB;
			return (unsigned char*)pixels + x * bytes + y * pitchB + z * sliceB;
		}

		return nullptr;
#else
		int bytes = sw::Surface::bytes(format);
		int pitchB = sw::Surface::pitchB(width, 0, format, false);
		int sliceB = height * pitchB;
		return (unsigned char*)buffer + x * bytes + y * pitchB + z * sliceB;
#endif
	}

	void ClientBuffer::unlock()
	{
#if defined(__APPLE__)
		if(buffer)
		{
			IOSurfaceRef ioSurface = reinterpret_cast<IOSurfaceRef>(buffer);
			IOSurfaceUnlock(ioSurface, 0, nullptr);
		}
#endif
	}

	bool ClientBuffer::requiresSync() const
	{
#if defined(__APPLE__)
		return true;
#else
		return false;
#endif
	}

	class ClientBufferImage : public egl::Image
	{
	public:
		explicit ClientBufferImage(const ClientBuffer& clientBuffer) :
			egl::Image(clientBuffer.getWidth(),
				clientBuffer.getHeight(),
				getClientBufferInternalFormat(clientBuffer.getFormat()),
				clientBuffer.pitchP()),
			clientBuffer(clientBuffer)
		{
			shared = false;
			this->clientBuffer.retain();
		}

	private:
		ClientBuffer clientBuffer;

		~ClientBufferImage() override
		{
			sync();   // Wait for any threads that use this image to finish.

			clientBuffer.release();
		}

		static GLint getClientBufferInternalFormat(sw::Format format)
		{
			switch(format)
			{
			case sw::FORMAT_R8:            return GL_R8;
			case sw::FORMAT_G8R8:          return GL_RG8;
			case sw::FORMAT_X8R8G8B8:      return GL_RGB8;
			case sw::FORMAT_A8R8G8B8:      return GL_BGRA8_EXT;
			case sw::FORMAT_R16UI:         return GL_R16UI;
			case sw::FORMAT_A16B16G16R16F: return GL_RGBA16F;
			default:                       return GL_NONE;
			}
		}

		void *lockInternal(int x, int y, int z, sw::Lock lock, sw::Accessor client) override
		{
			LOGLOCK("image=%p op=%s.swsurface lock=%d", this, __FUNCTION__, lock);

			// Always do this for reference counting.
			void *data = sw::Surface::lockInternal(x, y, z, lock, client);

			if(x != 0 || y != 0 || z != 0)
			{
				LOGLOCK("badness: %s called with unsupported parms: image=%p x=%d y=%d z=%d", __FUNCTION__, this, x, y, z);
			}

			LOGLOCK("image=%p op=%s.ani lock=%d", this, __FUNCTION__, lock);

			// Lock the ClientBuffer and use its address.
			data = clientBuffer.lock(x, y, z);

			if(lock == sw::LOCK_UNLOCKED)
			{
				// We're never going to get a corresponding unlock, so unlock
				// immediately. This keeps the reference counts sane.
				clientBuffer.unlock();
			}

			return data;
		}

		void unlockInternal() override
		{
			LOGLOCK("image=%p op=%s.ani", this, __FUNCTION__);
			clientBuffer.unlock();

			LOGLOCK("image=%p op=%s.swsurface", this, __FUNCTION__);
			sw::Surface::unlockInternal();
		}

		void *lock(int x, int y, int z, sw::Lock lock) override
		{
			LOGLOCK("image=%p op=%s lock=%d", this, __FUNCTION__, lock);
			(void)sw::Surface::lockExternal(x, y, z, lock, sw::PUBLIC);

			return clientBuffer.lock(x, y, z);
		}

		void unlock() override
		{
			LOGLOCK("image=%p op=%s.ani", this, __FUNCTION__);
			clientBuffer.unlock();

			LOGLOCK("image=%p op=%s.swsurface", this, __FUNCTION__);
			sw::Surface::unlockExternal();
		}

		bool requiresSync() const override
		{
			return clientBuffer.requiresSync();
		}

		void release() override
		{
			Image::release();
		}
	};

	Image *Image::create(const egl::ClientBuffer& clientBuffer)
	{
		return new ClientBufferImage(clientBuffer);
	}

	Image::~Image()
	{
		// sync() must be called in the destructor of the most derived class to ensure their vtable isn't destroyed
		// before all threads are done using this image. Image itself is abstract so it can't be the most derived.
		ASSERT(isUnlocked());

		if(parentTexture)
		{
			parentTexture->release();
		}

		ASSERT(!shared);
	}

	void *Image::lockInternal(int x, int y, int z, sw::Lock lock, sw::Accessor client)
	{
		return Surface::lockInternal(x, y, z, lock, client);
	}

	void Image::unlockInternal()
	{
		Surface::unlockInternal();
	}

	void Image::release()
	{
		int refs = dereference();

		if(refs > 0)
		{
			if(parentTexture)
			{
				parentTexture->sweep();
			}
		}
		else
		{
			delete this;
		}
	}

	void Image::unbind(const egl::Texture *parent)
	{
		if(parentTexture == parent)
		{
			parentTexture = nullptr;
		}

		release();
	}

	bool Image::isChildOf(const egl::Texture *parent) const
	{
		return parentTexture == parent;
	}

	void Image::loadImageData(GLsizei width, GLsizei height, GLsizei depth, int inputPitch, int inputHeight, GLenum format, GLenum type, const void *input, void *buffer)
	{
		Rectangle rect;
		rect.bytes = gl::ComputePixelSize(format, type);
		rect.width = width;
		rect.height = height;
		rect.depth = depth;
		rect.inputPitch = inputPitch;
		rect.inputHeight = inputHeight;
		rect.destPitch = getPitch();
		rect.destSlice = getSlice();

		// [OpenGL ES 3.0.5] table 3.2 and 3.3.
		switch(format)
		{
		case GL_RGBA:
			switch(type)
			{
			case GL_UNSIGNED_BYTE:
				switch(internalformat)
				{
				case GL_RGBA8:
				case GL_SRGB8_ALPHA8:
					return Transfer<Bytes>(buffer, input, rect);
				case GL_RGB5_A1:
				case GL_RGBA4:
					ASSERT_OR_RETURN(getExternalFormat() == sw::FORMAT_A8B8G8R8);
					return Transfer<Bytes>(buffer, input, rect);
				default:
					UNREACHABLE(internalformat);
				}
			case GL_BYTE:
				ASSERT_OR_RETURN(internalformat == GL_RGBA8_SNORM && getExternalFormat() == sw::FORMAT_A8B8G8R8_SNORM);
				return Transfer<Bytes>(buffer, input, rect);
			case GL_UNSIGNED_SHORT_4_4_4_4:
				ASSERT_OR_RETURN(internalformat == GL_RGBA4 && getExternalFormat() == sw::FORMAT_A8B8G8R8);
				return Transfer<RGBA4toRGBA8>(buffer, input, rect);
			case GL_UNSIGNED_SHORT_5_5_5_1:
				ASSERT_OR_RETURN(internalformat == GL_RGB5_A1 && getExternalFormat() == sw::FORMAT_A8B8G8R8);
				return Transfer<RGBA5_A1toRGBA8>(buffer, input, rect);
			case GL_UNSIGNED_INT_2_10_10_10_REV:
				switch(internalformat)
				{
				case GL_RGB10_A2:
					ASSERT_OR_RETURN(getExternalFormat() == sw::FORMAT_A2B10G10R10);
					return Transfer<Bytes>(buffer, input, rect);
				case GL_RGB5_A1:
					ASSERT_OR_RETURN(getExternalFormat() == sw::FORMAT_A8B8G8R8);
					return Transfer<RGBA1010102toRGBA8>(buffer, input, rect);
				default:
					UNREACHABLE(internalformat);
				}
			case GL_HALF_FLOAT:
			case GL_HALF_FLOAT_OES:
				ASSERT_OR_RETURN(internalformat == GL_RGBA16F && getExternalFormat() == sw::FORMAT_A16B16G16R16F);
				return Transfer<Bytes>(buffer, input, rect);
			case GL_FLOAT:
				switch(internalformat)
				{
				case GL_RGBA32F: return Transfer<Bytes>(buffer, input, rect);
				case GL_RGBA16F: return Transfer<RGBA32FtoRGBA16F>(buffer, input, rect);
				default: UNREACHABLE(internalformat);
				}
			default:
				UNREACHABLE(type);
			}
		case GL_RGBA_INTEGER:
			switch(type)
			{
			case GL_UNSIGNED_BYTE:
				ASSERT_OR_RETURN(internalformat == GL_RGBA8UI && getExternalFormat() == sw::FORMAT_A8B8G8R8UI);
				return Transfer<Bytes>(buffer, input, rect);
			case GL_BYTE:
				ASSERT_OR_RETURN(internalformat == GL_RGBA8I && getExternalFormat() == sw::FORMAT_A8B8G8R8I);
				return Transfer<Bytes>(buffer, input, rect);
			case GL_UNSIGNED_SHORT:
				ASSERT_OR_RETURN(internalformat == GL_RGBA16UI && getExternalFormat() == sw::FORMAT_A16B16G16R16UI);
				return Transfer<Bytes>(buffer, input, rect);
			case GL_SHORT:
				ASSERT_OR_RETURN(internalformat == GL_RGBA16I && getExternalFormat() == sw::FORMAT_A16B16G16R16I);
				return Transfer<Bytes>(buffer, input, rect);
			case GL_UNSIGNED_INT:
				ASSERT_OR_RETURN(internalformat == GL_RGBA32UI && getExternalFormat() == sw::FORMAT_A32B32G32R32UI);
				return Transfer<Bytes>(buffer, input, rect);
			case GL_INT:
				ASSERT_OR_RETURN(internalformat == GL_RGBA32I && getExternalFormat() == sw::FORMAT_A32B32G32R32I);
				return Transfer<Bytes>(buffer, input, rect);
			case GL_UNSIGNED_INT_2_10_10_10_REV:
				ASSERT_OR_RETURN(internalformat == GL_RGB10_A2UI && getExternalFormat() == sw::FORMAT_A2B10G10R10UI);
				return Transfer<Bytes>(buffer, input, rect);
			default:
				UNREACHABLE(type);
			}
		case GL_BGRA_EXT:
			switch(type)
			{
			case GL_UNSIGNED_BYTE:
				ASSERT_OR_RETURN(internalformat == GL_BGRA8_EXT && getExternalFormat() == sw::FORMAT_A8R8G8B8);
				return Transfer<Bytes>(buffer, input, rect);
			case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:   // Only valid for glReadPixels calls.
			case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:   // Only valid for glReadPixels calls.
			default:
				UNREACHABLE(type);
			}
		case GL_RGB:
			switch(type)
			{
			case GL_UNSIGNED_BYTE:
				switch(internalformat)
				{
				case GL_RGB8:   return Transfer<RGB8toRGBX8>(buffer, input, rect);
				case GL_SRGB8:  return Transfer<RGB8toRGBX8>(buffer, input, rect);
				case GL_RGB565: return Transfer<RGB8toRGB565>(buffer, input, rect);
				default: UNREACHABLE(internalformat);
				}
			case GL_BYTE:
				ASSERT_OR_RETURN(internalformat == GL_RGB8_SNORM && getExternalFormat() == sw::FORMAT_X8B8G8R8_SNORM);
				return Transfer<RGB8toRGBX8>(buffer, input, rect);
			case GL_UNSIGNED_SHORT_5_6_5:
				ASSERT_OR_RETURN(internalformat == GL_RGB565 && getExternalFormat() == sw::FORMAT_R5G6B5);
				return Transfer<Bytes>(buffer, input, rect);
			case GL_UNSIGNED_INT_10F_11F_11F_REV:
				ASSERT_OR_RETURN(internalformat == GL_R11F_G11F_B10F && getExternalFormat() == sw::FORMAT_X16B16G16R16F_UNSIGNED);
				return Transfer<R11G11B10FtoRGBX16F>(buffer, input, rect);
			case GL_UNSIGNED_INT_5_9_9_9_REV:
				ASSERT_OR_RETURN(internalformat == GL_RGB9_E5 && getExternalFormat() == sw::FORMAT_X16B16G16R16F_UNSIGNED);
				return Transfer<RGB9_E5FtoRGBX16F>(buffer, input, rect);
			case GL_HALF_FLOAT:
			case GL_HALF_FLOAT_OES:
				switch(internalformat)
				{
				case GL_RGB16F:
					ASSERT_OR_RETURN(getExternalFormat() == sw::FORMAT_X16B16G16R16F);
					return Transfer<RGB16FtoRGBX16F>(buffer, input, rect);
				case GL_R11F_G11F_B10F:
				case GL_RGB9_E5:
					ASSERT_OR_RETURN(getExternalFormat() == sw::FORMAT_X16B16G16R16F_UNSIGNED);
					return Transfer<RGB16FtoRGBX16F>(buffer, input, rect);
				default:
					UNREACHABLE(internalformat);
				}
			case GL_FLOAT:
				switch(internalformat)
				{
				case GL_RGB32F:
					ASSERT_OR_RETURN(getExternalFormat() == sw::FORMAT_X32B32G32R32F);
					return Transfer<RGB32FtoRGBX32F>(buffer, input, rect);
				case GL_RGB16F:
					ASSERT_OR_RETURN(getExternalFormat() == sw::FORMAT_X16B16G16R16F);
					return Transfer<RGB32FtoRGB16F>(buffer, input, rect);
				case GL_R11F_G11F_B10F:
				case GL_RGB9_E5:
					ASSERT_OR_RETURN(getExternalFormat() == sw::FORMAT_X16B16G16R16F_UNSIGNED);
					return Transfer<RGB32FtoRGB16F_UNSIGNED>(buffer, input, rect);
				default:
					UNREACHABLE(internalformat);
				}
			default:
				UNREACHABLE(type);
			}
		case GL_RGB_INTEGER:
			switch(type)
			{
			case GL_UNSIGNED_BYTE:
				ASSERT_OR_RETURN(internalformat == GL_RGB8UI && getExternalFormat() == sw::FORMAT_X8B8G8R8UI);
				return Transfer<RGB8toRGBX8>(buffer, input, rect);
			case GL_BYTE:
				ASSERT_OR_RETURN(internalformat == GL_RGB8I && getExternalFormat() == sw::FORMAT_X8B8G8R8I);
				return Transfer<RGB8toRGBX8>(buffer, input, rect);
			case GL_UNSIGNED_SHORT:
				ASSERT_OR_RETURN(internalformat == GL_RGB16UI && getExternalFormat() == sw::FORMAT_X16B16G16R16UI);
				return Transfer<RGB16toRGBX16>(buffer, input, rect);
			case GL_SHORT:
				ASSERT_OR_RETURN(internalformat == GL_RGB16I && getExternalFormat() == sw::FORMAT_X16B16G16R16I);
				return Transfer<RGB16toRGBX16>(buffer, input, rect);
			case GL_UNSIGNED_INT:
				ASSERT_OR_RETURN(internalformat == GL_RGB32UI && getExternalFormat() == sw::FORMAT_X32B32G32R32UI);
				return Transfer<RGB32toRGBX32>(buffer, input, rect);
			case GL_INT:
				ASSERT_OR_RETURN(internalformat == GL_RGB32I && getExternalFormat() == sw::FORMAT_X32B32G32R32I);
				return Transfer<RGB32toRGBX32>(buffer, input, rect);
			default:
				UNREACHABLE(type);
			}
		case GL_RG:
			switch(type)
			{
			case GL_UNSIGNED_BYTE:
			case GL_BYTE:
			case GL_HALF_FLOAT:
			case GL_HALF_FLOAT_OES:
				return Transfer<Bytes>(buffer, input, rect);
			case GL_FLOAT:
				switch(internalformat)
				{
				case GL_RG32F: return Transfer<Bytes>(buffer, input, rect);
				case GL_RG16F: return Transfer<RG32FtoRG16F>(buffer, input, rect);
				default: UNREACHABLE(internalformat);
				}
			default:
				UNREACHABLE(type);
			}
		case GL_RG_INTEGER:
			switch(type)
			{
			case GL_UNSIGNED_BYTE:
				ASSERT_OR_RETURN(internalformat == GL_RG8UI && getExternalFormat() == sw::FORMAT_G8R8UI);
				return Transfer<Bytes>(buffer, input, rect);
			case GL_BYTE:
				ASSERT_OR_RETURN(internalformat == GL_RG8I && getExternalFormat() == sw::FORMAT_G8R8I);
				return Transfer<Bytes>(buffer, input, rect);
			case GL_UNSIGNED_SHORT:
				ASSERT_OR_RETURN(internalformat == GL_RG16UI && getExternalFormat() == sw::FORMAT_G16R16UI);
				return Transfer<Bytes>(buffer, input, rect);
			case GL_SHORT:
				ASSERT_OR_RETURN(internalformat == GL_RG16I && getExternalFormat() == sw::FORMAT_G16R16I);
				return Transfer<Bytes>(buffer, input, rect);
			case GL_UNSIGNED_INT:
				ASSERT_OR_RETURN(internalformat == GL_RG32UI && getExternalFormat() == sw::FORMAT_G32R32UI);
				return Transfer<Bytes>(buffer, input, rect);
			case GL_INT:
				ASSERT_OR_RETURN(internalformat == GL_RG32I && getExternalFormat() == sw::FORMAT_G32R32I);
				return Transfer<Bytes>(buffer, input, rect);
			default:
				UNREACHABLE(type);
			}
		case GL_RED:
			switch(type)
			{
			case GL_UNSIGNED_BYTE:
			case GL_BYTE:
			case GL_HALF_FLOAT:
			case GL_HALF_FLOAT_OES:
				return Transfer<Bytes>(buffer, input, rect);
			case GL_FLOAT:
				switch(internalformat)
				{
				case GL_R32F: return Transfer<Bytes>(buffer, input, rect);
				case GL_R16F: return Transfer<R32FtoR16F>(buffer, input, rect);
				default: UNREACHABLE(internalformat);
				}
			default:
				UNREACHABLE(type);
			}
		case GL_RED_INTEGER:
			switch(type)
			{
			case GL_UNSIGNED_BYTE:
				ASSERT_OR_RETURN(internalformat == GL_R8UI && getExternalFormat() == sw::FORMAT_R8UI);
				return Transfer<Bytes>(buffer, input, rect);
			case GL_BYTE:
				ASSERT_OR_RETURN(internalformat == GL_R8I && getExternalFormat() == sw::FORMAT_R8I);
				return Transfer<Bytes>(buffer, input, rect);
			case GL_UNSIGNED_SHORT:
				ASSERT_OR_RETURN(internalformat == GL_R16UI && getExternalFormat() == sw::FORMAT_R16UI);
				return Transfer<Bytes>(buffer, input, rect);
			case GL_SHORT:
				ASSERT_OR_RETURN(internalformat == GL_R16I && getExternalFormat() == sw::FORMAT_R16I);
				return Transfer<Bytes>(buffer, input, rect);
			case GL_UNSIGNED_INT:
				ASSERT_OR_RETURN(internalformat == GL_R32UI && getExternalFormat() == sw::FORMAT_R32UI);
				return Transfer<Bytes>(buffer, input, rect);
			case GL_INT:
				ASSERT_OR_RETURN(internalformat == GL_R32I && getExternalFormat() == sw::FORMAT_R32I);
				return Transfer<Bytes>(buffer, input, rect);
			default:
				UNREACHABLE(type);
			}
		case GL_DEPTH_COMPONENT:
			switch(type)
			{
			case GL_UNSIGNED_SHORT: return Transfer<D16toD32F>(buffer, input, rect);
			case GL_UNSIGNED_INT:   return Transfer<D32toD32F>(buffer, input, rect);
			case GL_FLOAT:          return Transfer<D32FtoD32F_CLAMPED>(buffer, input, rect);
			case GL_DEPTH_COMPONENT24:       // Only valid for glRenderbufferStorage calls.
			case GL_DEPTH_COMPONENT32_OES:   // Only valid for glRenderbufferStorage calls.
			default: UNREACHABLE(type);
			}
		case GL_DEPTH_STENCIL:
			switch(type)
			{
			case GL_UNSIGNED_INT_24_8:              return Transfer<D24X8toD32F>(buffer, input, rect);
			case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: return Transfer<D32FX32toD32F>(buffer, input, rect);
			default: UNREACHABLE(type);
			}
		case GL_LUMINANCE_ALPHA:
			switch(type)
			{
			case GL_UNSIGNED_BYTE:
				return Transfer<Bytes>(buffer, input, rect);
			case GL_FLOAT:
				switch(internalformat)
				{
				case GL_LUMINANCE_ALPHA32F_EXT: return Transfer<Bytes>(buffer, input, rect);
				case GL_LUMINANCE_ALPHA16F_EXT: return Transfer<RG32FtoRG16F>(buffer, input, rect);
				default: UNREACHABLE(internalformat);
				}
			case GL_HALF_FLOAT:
			case GL_HALF_FLOAT_OES:
				ASSERT_OR_RETURN(internalformat == GL_LUMINANCE_ALPHA16F_EXT);
				return Transfer<Bytes>(buffer, input, rect);
			default:
				UNREACHABLE(type);
			}
		case GL_LUMINANCE:
		case GL_ALPHA:
			switch(type)
			{
			case GL_UNSIGNED_BYTE:
				return Transfer<Bytes>(buffer, input, rect);
			case GL_FLOAT:
				switch(internalformat)
				{
				case GL_LUMINANCE32F_EXT: return Transfer<Bytes>(buffer, input, rect);
				case GL_LUMINANCE16F_EXT: return Transfer<R32FtoR16F>(buffer, input, rect);
				case GL_ALPHA32F_EXT:     return Transfer<Bytes>(buffer, input, rect);
				case GL_ALPHA16F_EXT:     return Transfer<R32FtoR16F>(buffer, input, rect);
				default: UNREACHABLE(internalformat);
				}
			case GL_HALF_FLOAT:
			case GL_HALF_FLOAT_OES:
				ASSERT_OR_RETURN(internalformat == GL_LUMINANCE16F_EXT || internalformat == GL_ALPHA16F_EXT);
				return Transfer<Bytes>(buffer, input, rect);
			default:
				UNREACHABLE(type);
			}
		default:
			UNREACHABLE(format);
		}
	}

	void Image::loadStencilData(GLsizei width, GLsizei height, GLsizei depth, int inputPitch, int inputHeight, GLenum format, GLenum type, const void *input, void *buffer)
	{
		Rectangle rect;
		rect.bytes = gl::ComputePixelSize(format, type);
		rect.width = width;
		rect.height = height;
		rect.depth = depth;
		rect.inputPitch = inputPitch;
		rect.inputHeight = inputHeight;
		rect.destPitch = getStencilPitchB();
		rect.destSlice = getStencilSliceB();

		switch(type)
		{
		case GL_UNSIGNED_INT_24_8:              return Transfer<X24S8toS8>(buffer, input, rect);
		case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: return Transfer<X56S8toS8>(buffer, input, rect);
		default: UNREACHABLE(format);
		}
	}

	void Image::loadImageData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelStorageModes &unpackParameters, const void *pixels)
	{
		GLsizei inputWidth = (unpackParameters.rowLength == 0) ? width : unpackParameters.rowLength;
		GLsizei inputPitch = gl::ComputePitch(inputWidth, format, type, unpackParameters.alignment);
		GLsizei inputHeight = (unpackParameters.imageHeight == 0) ? height : unpackParameters.imageHeight;
		char *input = ((char*)pixels) + gl::ComputePackingOffset(format, type, inputWidth, inputHeight, unpackParameters);

		void *buffer = lock(xoffset, yoffset, zoffset, sw::LOCK_WRITEONLY);

		if(buffer)
		{
			loadImageData(width, height, depth, inputPitch, inputHeight, format, type, input, buffer);
		}

		unlock();

		if(hasStencil())
		{
			unsigned char *stencil = reinterpret_cast<unsigned char*>(lockStencil(xoffset, yoffset, zoffset, sw::PUBLIC));

			if(stencil)
			{
				loadStencilData(width, height, depth, inputPitch, inputHeight, format, type, input, stencil);
			}

			unlockStencil();
		}
	}

	void Image::loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels)
	{
		int inputPitch = gl::ComputeCompressedPitch(width, internalformat);
		int inputSlice = imageSize / depth;
		int rows = inputSlice / inputPitch;

		void *buffer = lock(xoffset, yoffset, zoffset, sw::LOCK_WRITEONLY);

		if(buffer)
		{
			for(int z = 0; z < depth; z++)
			{
				for(int y = 0; y < rows; y++)
				{
					GLbyte *dest = (GLbyte*)buffer + y * getPitch() + z * getSlice();
					GLbyte *source = (GLbyte*)pixels + y * inputPitch + z * inputSlice;
					memcpy(dest, source, inputPitch);
				}
			}
		}

		unlock();
	}
}
