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