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

// Query.cpp: Implements the es2::Query class

#include "Query.h"

#include "main.h"
#include "Common/Thread.hpp"

namespace es2
{

Query::Query(GLuint name, GLenum type) : NamedObject(name)
{
	mQuery = nullptr;
	mStatus = GL_FALSE;
	mResult = GL_FALSE;
	mType = type;
}

Query::~Query()
{
	mQuery->release();
}

void Query::begin()
{
	if(!mQuery)
	{
		sw::Query::Type type;
		switch(mType)
		{
		case GL_ANY_SAMPLES_PASSED_EXT:
		case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
			type = sw::Query::FRAGMENTS_PASSED;
			break;
		case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
			type = sw::Query::TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN;
			break;
		default:
			UNREACHABLE(mType);
			return;
		}

		mQuery = new sw::Query(type);

		if(!mQuery)
		{
			return error(GL_OUT_OF_MEMORY);
		}
	}

	Device *device = getDevice();

	mQuery->begin();
	device->addQuery(mQuery);
	switch(mType)
	{
	case GL_ANY_SAMPLES_PASSED_EXT:
	case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
		device->setOcclusionEnabled(true);
		break;
	case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
		device->setTransformFeedbackQueryEnabled(true);
		break;
	default:
		ASSERT(false);
	}
}

void Query::end()
{
	if(!mQuery)
	{
		return error(GL_INVALID_OPERATION);
	}

	Device *device = getDevice();

	mQuery->end();
	device->removeQuery(mQuery);
	switch(mType)
	{
	case GL_ANY_SAMPLES_PASSED_EXT:
	case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
		device->setOcclusionEnabled(false);
		break;
	case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
		device->setTransformFeedbackQueryEnabled(false);
		break;
	default:
		ASSERT(false);
	}

	mStatus = GL_FALSE;
	mResult = GL_FALSE;
}

GLuint Query::getResult()
{
	if(mQuery)
	{
		while(!testQuery())
		{
			sw::Thread::yield();
		}
	}

	return (GLuint)mResult;
}

GLboolean Query::isResultAvailable()
{
	if(mQuery)
	{
		testQuery();
	}

	return mStatus;
}

GLenum Query::getType() const
{
	return mType;
}

GLboolean Query::testQuery()
{
	if(mQuery != nullptr && mStatus != GL_TRUE)
	{
		if(!mQuery->building && mQuery->isReady())
		{
			unsigned int resultSum = mQuery->data;
			mStatus = GL_TRUE;

			switch(mType)
			{
			case GL_ANY_SAMPLES_PASSED_EXT:
			case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
				mResult = (resultSum > 0) ? GL_TRUE : GL_FALSE;
				break;
			case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
				mResult = resultSum;
				break;
			default:
				ASSERT(false);
			}
		}

		return mStatus;
	}

	return GL_TRUE;   // Prevent blocking when query is nullptr
}
}
