1 //
2 // Copyright (c) 2002-2010 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 // Fence.cpp: Implements the gl::Fence class, which supports the GL_NV_fence extension.
8
9 #include "libGLESv2/Fence.h"
10
11 #include "libGLESv2/main.h"
12
13 namespace gl
14 {
15
Fence()16 Fence::Fence()
17 {
18 mQuery = NULL;
19 mCondition = GL_NONE;
20 mStatus = GL_FALSE;
21 }
22
~Fence()23 Fence::~Fence()
24 {
25 if (mQuery != NULL)
26 {
27 mQuery->Release();
28 mQuery = NULL;
29 }
30 }
31
isFence()32 GLboolean Fence::isFence()
33 {
34 // GL_NV_fence spec:
35 // A name returned by GenFencesNV, but not yet set via SetFenceNV, is not the name of an existing fence.
36 return mQuery != NULL;
37 }
38
setFence(GLenum condition)39 void Fence::setFence(GLenum condition)
40 {
41 if (mQuery != NULL)
42 {
43 mQuery->Release();
44 mQuery = NULL;
45 }
46
47 if (FAILED(getDevice()->CreateQuery(D3DQUERYTYPE_EVENT, &mQuery)))
48 {
49 return error(GL_OUT_OF_MEMORY);
50 }
51
52 HRESULT result = mQuery->Issue(D3DISSUE_END);
53 ASSERT(SUCCEEDED(result));
54
55 mCondition = condition;
56 mStatus = GL_FALSE;
57 }
58
testFence()59 GLboolean Fence::testFence()
60 {
61 if (mQuery == NULL)
62 {
63 return error(GL_INVALID_OPERATION, GL_TRUE);
64 }
65
66 HRESULT result = mQuery->GetData(NULL, 0, D3DGETDATA_FLUSH);
67
68 if (result == D3DERR_DEVICELOST)
69 {
70 return error(GL_OUT_OF_MEMORY, GL_TRUE);
71 }
72
73 ASSERT(result == S_OK || result == S_FALSE);
74 mStatus = result == S_OK;
75 return mStatus;
76 }
77
finishFence()78 void Fence::finishFence()
79 {
80 if (mQuery == NULL)
81 {
82 return error(GL_INVALID_OPERATION);
83 }
84
85 while (!testFence())
86 {
87 Sleep(0);
88 }
89 }
90
getFenceiv(GLenum pname,GLint * params)91 void Fence::getFenceiv(GLenum pname, GLint *params)
92 {
93 if (mQuery == NULL)
94 {
95 return error(GL_INVALID_OPERATION);
96 }
97
98 switch (pname)
99 {
100 case GL_FENCE_STATUS_NV:
101 {
102 // GL_NV_fence spec:
103 // Once the status of a fence has been finished (via FinishFenceNV) or tested and the returned status is TRUE (via either TestFenceNV
104 // or GetFenceivNV querying the FENCE_STATUS_NV), the status remains TRUE until the next SetFenceNV of the fence.
105 if (mStatus)
106 {
107 params[0] = GL_TRUE;
108 return;
109 }
110
111 HRESULT result = mQuery->GetData(NULL, 0, 0);
112
113 if (result == D3DERR_DEVICELOST)
114 {
115 params[0] = GL_TRUE;
116 return error(GL_OUT_OF_MEMORY);
117 }
118
119 ASSERT(result == S_OK || result == S_FALSE);
120 mStatus = result == S_OK;
121 params[0] = mStatus;
122
123 break;
124 }
125 case GL_FENCE_CONDITION_NV:
126 params[0] = mCondition;
127 break;
128 default:
129 return error(GL_INVALID_ENUM);
130 break;
131 }
132 }
133
134 }
135