Home | History | Annotate | Download | only in libGLESv2
      1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved.
      2 //
      3 // Licensed under the Apache License, Version 2.0 (the "License");
      4 // you may not use this file except in compliance with the License.
      5 // You may obtain a copy of the License at
      6 //
      7 //    http://www.apache.org/licenses/LICENSE-2.0
      8 //
      9 // Unless required by applicable law or agreed to in writing, software
     10 // distributed under the License is distributed on an "AS IS" BASIS,
     11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 // See the License for the specific language governing permissions and
     13 // limitations under the License.
     14 
     15 // Query.cpp: Implements the es2::Query class
     16 
     17 #include "Query.h"
     18 
     19 #include "main.h"
     20 #include "Common/Thread.hpp"
     21 
     22 namespace es2
     23 {
     24 
     25 Query::Query(GLuint name, GLenum type) : NamedObject(name)
     26 {
     27 	mQuery = nullptr;
     28 	mStatus = GL_FALSE;
     29 	mResult = GL_FALSE;
     30 	mType = type;
     31 }
     32 
     33 Query::~Query()
     34 {
     35 	delete mQuery;
     36 }
     37 
     38 void Query::begin()
     39 {
     40 	if(!mQuery)
     41 	{
     42 		sw::Query::Type type;
     43 		switch(mType)
     44 		{
     45 		case GL_ANY_SAMPLES_PASSED_EXT:
     46 		case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
     47 			type = sw::Query::FRAGMENTS_PASSED;
     48 			break;
     49 		case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
     50 			type = sw::Query::TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN;
     51 			break;
     52 		default:
     53 			UNREACHABLE(mType);
     54 			return;
     55 		}
     56 
     57 		mQuery = new sw::Query(type);
     58 
     59 		if(!mQuery)
     60 		{
     61 			return error(GL_OUT_OF_MEMORY);
     62 		}
     63 	}
     64 
     65 	Device *device = getDevice();
     66 
     67 	mQuery->begin();
     68 	device->addQuery(mQuery);
     69 	switch(mType)
     70 	{
     71 	case GL_ANY_SAMPLES_PASSED_EXT:
     72 	case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
     73 		device->setOcclusionEnabled(true);
     74 		break;
     75 	case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
     76 		device->setTransformFeedbackQueryEnabled(true);
     77 		break;
     78 	default:
     79 		ASSERT(false);
     80 	}
     81 }
     82 
     83 void Query::end()
     84 {
     85 	if(!mQuery)
     86 	{
     87 		return error(GL_INVALID_OPERATION);
     88 	}
     89 
     90 	Device *device = getDevice();
     91 
     92 	mQuery->end();
     93 	device->removeQuery(mQuery);
     94 	switch(mType)
     95 	{
     96 	case GL_ANY_SAMPLES_PASSED_EXT:
     97 	case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
     98 		device->setOcclusionEnabled(false);
     99 		break;
    100 	case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
    101 		device->setTransformFeedbackQueryEnabled(false);
    102 		break;
    103 	default:
    104 		ASSERT(false);
    105 	}
    106 
    107 	mStatus = GL_FALSE;
    108 	mResult = GL_FALSE;
    109 }
    110 
    111 GLuint Query::getResult()
    112 {
    113 	if(mQuery)
    114 	{
    115 		while(!testQuery())
    116 		{
    117 			sw::Thread::yield();
    118 		}
    119 	}
    120 
    121 	return (GLuint)mResult;
    122 }
    123 
    124 GLboolean Query::isResultAvailable()
    125 {
    126 	if(mQuery)
    127 	{
    128 		testQuery();
    129 	}
    130 
    131 	return mStatus;
    132 }
    133 
    134 GLenum Query::getType() const
    135 {
    136 	return mType;
    137 }
    138 
    139 GLboolean Query::testQuery()
    140 {
    141 	if(mQuery != nullptr && mStatus != GL_TRUE)
    142 	{
    143 		if(!mQuery->building && mQuery->reference == 0)
    144 		{
    145 			unsigned int resultSum = mQuery->data;
    146 			mStatus = GL_TRUE;
    147 
    148 			switch(mType)
    149 			{
    150 			case GL_ANY_SAMPLES_PASSED_EXT:
    151 			case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
    152 				mResult = (resultSum > 0) ? GL_TRUE : GL_FALSE;
    153 				break;
    154 			case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
    155 				mResult = resultSum;
    156 				break;
    157 			default:
    158 				ASSERT(false);
    159 			}
    160 		}
    161 
    162 		return mStatus;
    163 	}
    164 
    165 	return GL_TRUE;   // Prevent blocking when query is nullptr
    166 }
    167 }
    168