17f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy/* 27f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy * Copyright (C) 2013 The Android Open Source Project 37f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy * 47f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy * Licensed under the Apache License, Version 2.0 (the "License"); 57f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy * you may not use this file except in compliance with the License. 67f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy * You may obtain a copy of the License at 77f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy * 87f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy * http://www.apache.org/licenses/LICENSE-2.0 97f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy * 107f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy * Unless required by applicable law or agreed to in writing, software 117f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy * distributed under the License is distributed on an "AS IS" BASIS, 127f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 137f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy * See the License for the specific language governing permissions and 147f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy * limitations under the License. 157f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy */ 167f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy 177f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy#ifndef ANDROID_HWUI_QUERY_H 187f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy#define ANDROID_HWUI_QUERY_H 197f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy 207f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy#include <GLES3/gl3.h> 217f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy 227f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy#include "Extensions.h" 237f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy 247f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guynamespace android { 257f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guynamespace uirenderer { 267f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy 277f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy/** 287f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy * A Query instance can be used to perform occlusion queries. If the device 297f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy * does not support occlusion queries, the result of a query will always be 307f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy * 0 and the result will always be marked available. 317f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy * 327f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy * To run an occlusion query successfully, you must start end end the query: 337f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy * 347f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy * Query query; 357f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy * query.begin(); 367f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy * // execute OpenGL calls 377f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy * query.end(); 387f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy * GLuint result = query.getResult(); 397f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy */ 407f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guyclass Query { 417f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guypublic: 427f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy /** 437f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy * Possible query targets. 447f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy */ 457f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy enum Target { 467f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy /** 477f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy * Indicates if any sample passed the depth & stencil tests. 487f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy */ 497f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy kTargetSamples = GL_ANY_SAMPLES_PASSED, 507f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy /** 517f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy * Indicates if any sample passed the depth & stencil tests. 527f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy * The implementation may choose to use a less precise version 537f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy * of the test, potentially resulting in false positives. 547f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy */ 557f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy kTargetConservativeSamples = GL_ANY_SAMPLES_PASSED_CONSERVATIVE, 567f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy }; 577f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy 587f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy /** 597f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy * Creates a new query with the specified target. The default 607f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy * target is kTargetSamples (of GL_ANY_SAMPLES_PASSED in OpenGL.) 617f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy */ 627f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy Query(Target target = kTargetSamples): mActive(false), mTarget(target), 637f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy mCanQuery(Extensions::getInstance().hasOcclusionQueries()), 647f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy mQuery(0) { 657f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy } 667f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy 677f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy ~Query() { 687f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy if (mQuery) { 697f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy glDeleteQueries(1, &mQuery); 707f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy } 717f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy } 727f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy 737f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy /** 747f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy * Begins the query. If the query has already begun or if the device 757f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy * does not support occlusion queries, calling this method as no effect. 767f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy * After calling this method successfully, the query is marked active. 777f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy */ 787f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy void begin() { 797f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy if (!mActive && mCanQuery) { 807f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy if (!mQuery) { 817f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy glGenQueries(1, &mQuery); 827f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy } 837f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy 847f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy glBeginQuery(mTarget, mQuery); 857f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy mActive = true; 867f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy } 877f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy } 887f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy 897f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy /** 907f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy * Ends the query. If the query has already begun or if the device 917f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy * does not support occlusion queries, calling this method as no effect. 927f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy * After calling this method successfully, the query is marked inactive. 937f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy */ 947f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy void end() { 957f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy if (mQuery && mActive) { 967f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy glEndQuery(mTarget); 977f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy mActive = false; 987f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy } 997f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy } 1007f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy 1017f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy /** 1027f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy * Returns true if the query is active, false otherwise. 1037f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy */ 1047f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy bool isActive() { 1057f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy return mActive; 1067f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy } 1077f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy 1087f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy /** 1097f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy * Returns true if the result of the query is available, 1107f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy * false otherwise. Calling getResult() before the result 1117f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy * is available may result in the calling thread being blocked. 1127f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy * If the device does not support queries, this method always 1137f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy * returns true. 1147f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy */ 1157f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy bool isResultAvailable() { 1167f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy if (!mQuery) return true; 1177f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy 1187f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy GLuint result; 1197f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy glGetQueryObjectuiv(mQuery, GL_QUERY_RESULT_AVAILABLE, &result); 1207f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy return result == GL_TRUE; 1217f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy } 1227f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy 1237f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy /** 1247f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy * Returns the result of the query. If the device does not 1257f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy * support queries this method will return 0. 1267f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy * 1277f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy * Calling this method implicitely calls end() if the query 1287f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy * is currently active. 1297f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy */ 1307f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy GLuint getResult() { 1317f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy if (!mQuery) return 0; 1327f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy 1337f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy end(); 1347f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy 1357f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy GLuint result; 1367f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy glGetQueryObjectuiv(mQuery, GL_QUERY_RESULT, &result); 1377f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy return result; 1387f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy } 1397f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy 1407f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy 1417f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guyprivate: 1427f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy bool mActive; 1437f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy GLenum mTarget; 1447f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy bool mCanQuery; 1457f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy GLuint mQuery; 1467f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy 1477f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy}; // class Query 1487f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy 1497f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy}; // namespace uirenderer 1507f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy}; // namespace android 1517f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy 1527f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy#endif // ANDROID_HWUI_QUERY_H 153