blob: 14d1239abf2bc1ebcf0d65a2d59504c0b6106deb [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
apatrick@chromium.org563c0a52012-03-23 21:18:42 +000016Fence::Fence(egl::Display* display)
17{
18 mDisplay = display;
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +000019 mQuery = NULL;
20 mCondition = GL_NONE;
21 mStatus = GL_FALSE;
22}
23
24Fence::~Fence()
25{
26 if (mQuery != NULL)
27 {
apatrick@chromium.org563c0a52012-03-23 21:18:42 +000028 mDisplay->freeEventQuery(mQuery);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +000029 }
30}
31
32GLboolean 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
39void Fence::setFence(GLenum condition)
40{
apatrick@chromium.orgf289ee82012-01-11 20:03:29 +000041 if (!mQuery)
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +000042 {
apatrick@chromium.org563c0a52012-03-23 21:18:42 +000043 mQuery = mDisplay->allocateEventQuery();
apatrick@chromium.orgf289ee82012-01-11 20:03:29 +000044 if (!mQuery)
45 {
46 return error(GL_OUT_OF_MEMORY);
47 }
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +000048 }
49
50 HRESULT result = mQuery->Issue(D3DISSUE_END);
51 ASSERT(SUCCEEDED(result));
52
53 mCondition = condition;
54 mStatus = GL_FALSE;
55}
56
57GLboolean Fence::testFence()
58{
59 if (mQuery == NULL)
60 {
61 return error(GL_INVALID_OPERATION, GL_TRUE);
62 }
63
64 HRESULT result = mQuery->GetData(NULL, 0, D3DGETDATA_FLUSH);
65
daniel@transgaming.com6f5c5fc2011-11-09 17:46:39 +000066 if (checkDeviceLost(result))
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +000067 {
68 return error(GL_OUT_OF_MEMORY, GL_TRUE);
69 }
70
71 ASSERT(result == S_OK || result == S_FALSE);
72 mStatus = result == S_OK;
73 return mStatus;
74}
75
76void Fence::finishFence()
77{
78 if (mQuery == NULL)
79 {
80 return error(GL_INVALID_OPERATION);
81 }
82
83 while (!testFence())
84 {
85 Sleep(0);
86 }
87}
88
89void Fence::getFenceiv(GLenum pname, GLint *params)
90{
91 if (mQuery == NULL)
92 {
93 return error(GL_INVALID_OPERATION);
94 }
95
96 switch (pname)
97 {
98 case GL_FENCE_STATUS_NV:
99 {
100 // GL_NV_fence spec:
101 // Once the status of a fence has been finished (via FinishFenceNV) or tested and the returned status is TRUE (via either TestFenceNV
102 // or GetFenceivNV querying the FENCE_STATUS_NV), the status remains TRUE until the next SetFenceNV of the fence.
103 if (mStatus)
104 {
105 params[0] = GL_TRUE;
106 return;
107 }
108
109 HRESULT result = mQuery->GetData(NULL, 0, 0);
110
daniel@transgaming.com6f5c5fc2011-11-09 17:46:39 +0000111 if (checkDeviceLost(result))
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +0000112 {
113 params[0] = GL_TRUE;
114 return error(GL_OUT_OF_MEMORY);
115 }
116
117 ASSERT(result == S_OK || result == S_FALSE);
118 mStatus = result == S_OK;
119 params[0] = mStatus;
120
121 break;
122 }
123 case GL_FENCE_CONDITION_NV:
124 params[0] = mCondition;
125 break;
126 default:
127 return error(GL_INVALID_ENUM);
128 break;
129 }
130}
131
132}