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 gl::Query class
16
17#include "Query.h"
18
19#include "main.h"
20#include "Common/Thread.hpp"
21
22namespace gl
23{
24
25Query::Query(GLuint name, GLenum type) : NamedObject(name)
26{
27	mQuery = nullptr;
28	mStatus = GL_FALSE;
29	mResult = GL_FALSE;
30	mType = type;
31}
32
33Query::~Query()
34{
35	delete mQuery;
36}
37
38void Query::begin()
39{
40	if(!mQuery)
41	{
42		sw::Query::Type type;
43		switch(mType)
44		{
45		case GL_ANY_SAMPLES_PASSED:
46		case GL_ANY_SAMPLES_PASSED_CONSERVATIVE:
47			type = sw::Query::FRAGMENTS_PASSED;
48			break;
49		default:
50			ASSERT(false);
51		}
52
53		mQuery = new sw::Query(type);
54
55		if(!mQuery)
56		{
57			return error(GL_OUT_OF_MEMORY);
58		}
59	}
60
61	Device *device = getDevice();
62
63	mQuery->begin();
64	device->addQuery(mQuery);
65	device->setOcclusionEnabled(true);
66}
67
68void Query::end()
69{
70	if(!mQuery)
71	{
72		return error(GL_INVALID_OPERATION);
73	}
74
75	Device *device = getDevice();
76
77	mQuery->end();
78	device->removeQuery(mQuery);
79	device->setOcclusionEnabled(false);
80
81	mStatus = GL_FALSE;
82	mResult = GL_FALSE;
83}
84
85GLuint Query::getResult()
86{
87	if(mQuery)
88	{
89		while(!testQuery())
90		{
91			sw::Thread::yield();
92		}
93	}
94
95	return (GLuint)mResult;
96}
97
98GLboolean Query::isResultAvailable()
99{
100	if(mQuery)
101	{
102		testQuery();
103	}
104
105	return mStatus;
106}
107
108GLenum Query::getType() const
109{
110	return mType;
111}
112
113GLboolean Query::testQuery()
114{
115	if(mQuery && mStatus != GL_TRUE)
116	{
117		if(!mQuery->building && mQuery->reference == 0)
118		{
119			unsigned int numPixels = mQuery->data;
120			mStatus = GL_TRUE;
121
122			switch(mType)
123			{
124			case GL_ANY_SAMPLES_PASSED:
125			case GL_ANY_SAMPLES_PASSED_CONSERVATIVE:
126				mResult = (numPixels > 0) ? GL_TRUE : GL_FALSE;
127				break;
128			default:
129				ASSERT(false);
130			}
131		}
132
133		return mStatus;
134	}
135
136	return GL_TRUE;   // Prevent blocking when query is null
137}
138}
139