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

// Shader.cpp: Implements the Shader class and its  derived classes
// VertexShader and FragmentShader. Implements GL shader objects and related
// functionality. [OpenGL ES 2.0.24] section 2.10 page 24 and section 3.8 page 84.

#include "Shader.h"

#include "main.h"
#include "utilities.h"

#include <string>
#include <algorithm>

namespace es2
{
bool Shader::compilerInitialized = false;

Shader::Shader(ResourceManager *manager, GLuint handle) : mHandle(handle), mResourceManager(manager)
{
	mSource = nullptr;

	clear();

	mRefCount = 0;
	mDeleteStatus = false;
}

Shader::~Shader()
{
	delete[] mSource;
}

GLuint Shader::getName() const
{
	return mHandle;
}

void Shader::setSource(GLsizei count, const char *const *string, const GLint *length)
{
	delete[] mSource;
	int totalLength = 0;

	for(int i = 0; i < count; i++)
	{
		if(length && length[i] >= 0)
		{
			totalLength += length[i];
		}
		else
		{
			totalLength += (int)strlen(string[i]);
		}
	}

	mSource = new char[totalLength + 1];
	char *code = mSource;

	for(int i = 0; i < count; i++)
	{
		int stringLength;

		if(length && length[i] >= 0)
		{
			stringLength = length[i];
		}
		else
		{
			stringLength = (int)strlen(string[i]);
		}

		strncpy(code, string[i], stringLength);
		code += stringLength;
	}

	mSource[totalLength] = '\0';
}

size_t Shader::getInfoLogLength() const
{
	if(infoLog.empty())
	{
		return 0;
	}
	else
	{
	   return infoLog.size() + 1;
	}
}

void Shader::getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLogOut)
{
	int index = 0;

	if(bufSize > 0)
	{
		if(!infoLog.empty())
		{
			index = std::min(bufSize - 1, (GLsizei)infoLog.size());
			memcpy(infoLogOut, infoLog.c_str(), index);
		}

		infoLogOut[index] = '\0';
	}

	if(length)
	{
		*length = index;
	}
}

size_t Shader::getSourceLength() const
{
	if(!mSource)
	{
		return 0;
	}
	else
	{
	   return strlen(mSource) + 1;
	}
}

void Shader::getSource(GLsizei bufSize, GLsizei *length, char *source)
{
	int index = 0;

	if(bufSize > 0)
	{
		if(mSource)
		{
			index = std::min(bufSize - 1, (int)strlen(mSource));
			memcpy(source, mSource, index);
		}

		source[index] = '\0';
	}

	if(length)
	{
		*length = index;
	}
}

TranslatorASM *Shader::createCompiler(GLenum shaderType)
{
	if(!compilerInitialized)
	{
		InitCompilerGlobals();
		compilerInitialized = true;
	}

	TranslatorASM *assembler = new TranslatorASM(this, shaderType);

	ShBuiltInResources resources;
	resources.MaxVertexAttribs = MAX_VERTEX_ATTRIBS;
	resources.MaxVertexUniformVectors = MAX_VERTEX_UNIFORM_VECTORS;
	resources.MaxVaryingVectors = MAX_VARYING_VECTORS;
	resources.MaxVertexTextureImageUnits = MAX_VERTEX_TEXTURE_IMAGE_UNITS;
	resources.MaxCombinedTextureImageUnits = MAX_COMBINED_TEXTURE_IMAGE_UNITS;
	resources.MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS;
	resources.MaxFragmentUniformVectors = MAX_FRAGMENT_UNIFORM_VECTORS;
	resources.MaxDrawBuffers = MAX_DRAW_BUFFERS;
	resources.MaxVertexOutputVectors = MAX_VERTEX_OUTPUT_VECTORS;
	resources.MaxFragmentInputVectors = MAX_FRAGMENT_INPUT_VECTORS;
	resources.MinProgramTexelOffset = MIN_PROGRAM_TEXEL_OFFSET;
	resources.MaxProgramTexelOffset = MAX_PROGRAM_TEXEL_OFFSET;
	resources.OES_standard_derivatives = 1;
	resources.OES_fragment_precision_high = 1;
	resources.OES_EGL_image_external = 1;
	resources.EXT_draw_buffers = 1;
	resources.ARB_texture_rectangle = 1;
	resources.MaxCallStackDepth = 64;
	assembler->Init(resources);

	return assembler;
}

void Shader::clear()
{
	infoLog.clear();

	varyings.clear();
	activeUniforms.clear();
	activeAttributes.clear();
}

void Shader::compile()
{
	clear();

	createShader();
	TranslatorASM *compiler = createCompiler(getType());

	// Ensure we don't pass a nullptr source to the compiler
	const char *source = "\0";
	if(mSource)
	{
		source = mSource;
	}

	bool success = compiler->compile(&source, 1, SH_OBJECT_CODE);

	if(false)
	{
		static int serial = 1;

		if(false)
		{
			char buffer[256];
			sprintf(buffer, "shader-input-%d-%d.txt", getName(), serial);
			FILE *file = fopen(buffer, "wt");
			fprintf(file, "%s", mSource);
			fclose(file);
		}

		getShader()->print("shader-output-%d-%d.txt", getName(), serial);

		serial++;
	}

	shaderVersion = compiler->getShaderVersion();
	int clientVersion = es2::getContext()->getClientVersion();

	if(shaderVersion >= 300 && clientVersion < 3)
	{
		infoLog = "GLSL ES 3.00 is not supported by OpenGL ES 2.0 contexts";
		success = false;
	}

	infoLog += compiler->getInfoSink().info.c_str();

	if(!success)
	{
		deleteShader();

		TRACE("\n%s", infoLog.c_str());
	}

	delete compiler;
}

bool Shader::isCompiled()
{
	return getShader() != 0;
}

void Shader::addRef()
{
	mRefCount++;
}

void Shader::release()
{
	mRefCount--;

	if(mRefCount == 0 && mDeleteStatus)
	{
		mResourceManager->deleteShader(mHandle);
	}
}

unsigned int Shader::getRefCount() const
{
	return mRefCount;
}

bool Shader::isFlaggedForDeletion() const
{
	return mDeleteStatus;
}

void Shader::flagForDeletion()
{
	mDeleteStatus = true;
}

void Shader::releaseCompiler()
{
	FreeCompilerGlobals();
	compilerInitialized = false;
}

// true if varying x has a higher priority in packing than y
bool Shader::compareVarying(const glsl::Varying &x, const glsl::Varying &y)
{
	if(x.type == y.type)
	{
		return x.size() > y.size();
	}

	switch(x.type)
	{
	case GL_FLOAT_MAT4: return true;
	case GL_FLOAT_MAT2:
		switch(y.type)
		{
		case GL_FLOAT_MAT4: return false;
		case GL_FLOAT_MAT2: return true;
		case GL_FLOAT_VEC4: return true;
		case GL_FLOAT_MAT3: return true;
		case GL_FLOAT_VEC3: return true;
		case GL_FLOAT_VEC2: return true;
		case GL_FLOAT:      return true;
		default: UNREACHABLE(y.type);
		}
		break;
	case GL_FLOAT_VEC4:
		switch(y.type)
		{
		case GL_FLOAT_MAT4: return false;
		case GL_FLOAT_MAT2: return false;
		case GL_FLOAT_VEC4: return true;
		case GL_FLOAT_MAT3: return true;
		case GL_FLOAT_VEC3: return true;
		case GL_FLOAT_VEC2: return true;
		case GL_FLOAT:      return true;
		default: UNREACHABLE(y.type);
		}
		break;
	case GL_FLOAT_MAT3:
		switch(y.type)
		{
		case GL_FLOAT_MAT4: return false;
		case GL_FLOAT_MAT2: return false;
		case GL_FLOAT_VEC4: return false;
		case GL_FLOAT_MAT3: return true;
		case GL_FLOAT_VEC3: return true;
		case GL_FLOAT_VEC2: return true;
		case GL_FLOAT:      return true;
		default: UNREACHABLE(y.type);
		}
		break;
	case GL_FLOAT_VEC3:
		switch(y.type)
		{
		case GL_FLOAT_MAT4: return false;
		case GL_FLOAT_MAT2: return false;
		case GL_FLOAT_VEC4: return false;
		case GL_FLOAT_MAT3: return false;
		case GL_FLOAT_VEC3: return true;
		case GL_FLOAT_VEC2: return true;
		case GL_FLOAT:      return true;
		default: UNREACHABLE(y.type);
		}
		break;
	case GL_FLOAT_VEC2:
		switch(y.type)
		{
		case GL_FLOAT_MAT4: return false;
		case GL_FLOAT_MAT2: return false;
		case GL_FLOAT_VEC4: return false;
		case GL_FLOAT_MAT3: return false;
		case GL_FLOAT_VEC3: return false;
		case GL_FLOAT_VEC2: return true;
		case GL_FLOAT:      return true;
		default: UNREACHABLE(y.type);
		}
		break;
	case GL_FLOAT: return false;
	default: UNREACHABLE(x.type);
	}

	return false;
}

VertexShader::VertexShader(ResourceManager *manager, GLuint handle) : Shader(manager, handle)
{
	vertexShader = 0;
}

VertexShader::~VertexShader()
{
	delete vertexShader;
}

GLenum VertexShader::getType() const
{
	return GL_VERTEX_SHADER;
}

int VertexShader::getSemanticIndex(const std::string &attributeName) const
{
	if(!attributeName.empty())
	{
		for(const auto &attribute : activeAttributes)
		{
			if(attribute.name == attributeName)
			{
				return attribute.registerIndex;
			}
		}
	}

	return -1;
}

sw::Shader *VertexShader::getShader() const
{
	return vertexShader;
}

sw::VertexShader *VertexShader::getVertexShader() const
{
	return vertexShader;
}

void VertexShader::createShader()
{
	delete vertexShader;
	vertexShader = new sw::VertexShader();
}

void VertexShader::deleteShader()
{
	delete vertexShader;
	vertexShader = nullptr;
}

FragmentShader::FragmentShader(ResourceManager *manager, GLuint handle) : Shader(manager, handle)
{
	pixelShader = 0;
}

FragmentShader::~FragmentShader()
{
	delete pixelShader;
}

GLenum FragmentShader::getType() const
{
	return GL_FRAGMENT_SHADER;
}

sw::Shader *FragmentShader::getShader() const
{
	return pixelShader;
}

sw::PixelShader *FragmentShader::getPixelShader() const
{
	return pixelShader;
}

void FragmentShader::createShader()
{
	delete pixelShader;
	pixelShader = new sw::PixelShader();
}

void FragmentShader::deleteShader()
{
	delete pixelShader;
	pixelShader = nullptr;
}

}
