blob: b6fa1de4327fe83636a666a4972022ecdcc0f636 [file] [log] [blame]
daniel@transgaming.com86bdb822012-01-20 18:24:39 +00001//
2// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// Query.cpp: Implements the gl::Query class
8
9#include "libGLESv2/Query.h"
10
11#include "libGLESv2/main.h"
12
13namespace gl
14{
15
16Query::Query(GLuint id, GLenum type) : RefCountObject(id)
17{
18 mQuery = NULL;
19 mStatus = GL_FALSE;
20 mResult = GL_FALSE;
21 mType = type;
22}
23
24Query::~Query()
25{
26 if (mQuery != NULL)
27 {
28 mQuery->Release();
29 mQuery = NULL;
30 }
31}
32
33void Query::begin()
34{
35 if (mQuery == NULL)
36 {
daniel@transgaming.com621ce052012-10-31 17:52:29 +000037 // D3D9_REPLACE
daniel@transgaming.com86bdb822012-01-20 18:24:39 +000038 if (FAILED(getDevice()->CreateQuery(D3DQUERYTYPE_OCCLUSION, &mQuery)))
39 {
40 return error(GL_OUT_OF_MEMORY);
41 }
42 }
43
44 HRESULT result = mQuery->Issue(D3DISSUE_BEGIN);
45 ASSERT(SUCCEEDED(result));
46}
47
48void Query::end()
49{
50 if (mQuery == NULL)
51 {
52 return error(GL_INVALID_OPERATION);
53 }
54
55 HRESULT result = mQuery->Issue(D3DISSUE_END);
56 ASSERT(SUCCEEDED(result));
57
58 mStatus = GL_FALSE;
59 mResult = GL_FALSE;
60}
61
62GLuint Query::getResult()
63{
64 if (mQuery != NULL)
65 {
66 while (!testQuery())
67 {
68 Sleep(0);
69 // explicitly check for device loss
70 // some drivers seem to return S_FALSE even if the device is lost
71 // instead of D3DERR_DEVICELOST like they should
daniel@transgaming.com621ce052012-10-31 17:52:29 +000072 if (gl::getDisplay()->getRenderer()->testDeviceLost()) // D3D9_REPLACE
daniel@transgaming.com86bdb822012-01-20 18:24:39 +000073 {
74 gl::getDisplay()->notifyDeviceLost();
75 return error(GL_OUT_OF_MEMORY, 0);
76 }
77 }
78 }
79
80 return (GLuint)mResult;
81}
82
83GLboolean Query::isResultAvailable()
84{
85 if (mQuery != NULL)
86 {
87 testQuery();
88 }
89
90 return mStatus;
91}
92
93GLenum Query::getType() const
94{
95 return mType;
96}
97
98GLboolean Query::testQuery()
99{
100 if (mQuery != NULL && mStatus != GL_TRUE)
101 {
102 DWORD numPixels = 0;
103
104 HRESULT hres = mQuery->GetData(&numPixels, sizeof(DWORD), D3DGETDATA_FLUSH);
105 if (hres == S_OK)
106 {
107 mStatus = GL_TRUE;
108
109 switch (mType)
110 {
111 case GL_ANY_SAMPLES_PASSED_EXT:
112 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
113 mResult = (numPixels > 0) ? GL_TRUE : GL_FALSE;
114 break;
115 default:
116 ASSERT(false);
117 }
118 }
119 else if (checkDeviceLost(hres))
120 {
121 return error(GL_OUT_OF_MEMORY, GL_TRUE);
122 }
123
124 return mStatus;
125 }
126
127 return GL_TRUE; // prevent blocking when query is null
128}
129}