blob: 2e12b293176bdcda184872e85d3e86d5607d0a1f [file] [log] [blame]
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00001//
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
13namespace gl
14{
15
16Fence::Fence()
17{
18 mQuery = NULL;
19 mCondition = GL_NONE;
20 mStatus = GL_FALSE;
21}
22
23Fence::~Fence()
24{
25 if (mQuery != NULL)
26 {
apatrick@chromium.orgf289ee82012-01-11 20:03:29 +000027 getDisplay()->freeEventQuery(mQuery);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +000028 }
29}
30
31GLboolean Fence::isFence()
32{
33 // GL_NV_fence spec:
34 // A name returned by GenFencesNV, but not yet set via SetFenceNV, is not the name of an existing fence.
35 return mQuery != NULL;
36}
37
38void Fence::setFence(GLenum condition)
39{
apatrick@chromium.orgf289ee82012-01-11 20:03:29 +000040 if (!mQuery)
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +000041 {
apatrick@chromium.orgf289ee82012-01-11 20:03:29 +000042 mQuery = getDisplay()->allocateEventQuery();
43 if (!mQuery)
44 {
45 return error(GL_OUT_OF_MEMORY);
46 }
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +000047 }
48
49 HRESULT result = mQuery->Issue(D3DISSUE_END);
50 ASSERT(SUCCEEDED(result));
51
52 mCondition = condition;
53 mStatus = GL_FALSE;
54}
55
56GLboolean Fence::testFence()
57{
58 if (mQuery == NULL)
59 {
60 return error(GL_INVALID_OPERATION, GL_TRUE);
61 }
62
63 HRESULT result = mQuery->GetData(NULL, 0, D3DGETDATA_FLUSH);
64
daniel@transgaming.com6f5c5fc2011-11-09 17:46:39 +000065 if (checkDeviceLost(result))
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +000066 {
67 return error(GL_OUT_OF_MEMORY, GL_TRUE);
68 }
69
70 ASSERT(result == S_OK || result == S_FALSE);
71 mStatus = result == S_OK;
72 return mStatus;
73}
74
75void Fence::finishFence()
76{
77 if (mQuery == NULL)
78 {
79 return error(GL_INVALID_OPERATION);
80 }
81
82 while (!testFence())
83 {
84 Sleep(0);
85 }
86}
87
88void Fence::getFenceiv(GLenum pname, GLint *params)
89{
90 if (mQuery == NULL)
91 {
92 return error(GL_INVALID_OPERATION);
93 }
94
95 switch (pname)
96 {
97 case GL_FENCE_STATUS_NV:
98 {
99 // GL_NV_fence spec:
100 // Once the status of a fence has been finished (via FinishFenceNV) or tested and the returned status is TRUE (via either TestFenceNV
101 // or GetFenceivNV querying the FENCE_STATUS_NV), the status remains TRUE until the next SetFenceNV of the fence.
102 if (mStatus)
103 {
104 params[0] = GL_TRUE;
105 return;
106 }
107
108 HRESULT result = mQuery->GetData(NULL, 0, 0);
109
daniel@transgaming.com6f5c5fc2011-11-09 17:46:39 +0000110 if (checkDeviceLost(result))
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +0000111 {
112 params[0] = GL_TRUE;
113 return error(GL_OUT_OF_MEMORY);
114 }
115
116 ASSERT(result == S_OK || result == S_FALSE);
117 mStatus = result == S_OK;
118 params[0] = mStatus;
119
120 break;
121 }
122 case GL_FENCE_CONDITION_NV:
123 params[0] = mCondition;
124 break;
125 default:
126 return error(GL_INVALID_ENUM);
127 break;
128 }
129}
130
131}