blob: aad8cd36ce502e67055b2c549d42f179a54e62db [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
daniel@transgaming.comef21ab22012-10-31 17:52:47 +000016Fence::Fence(renderer::Renderer *renderer)
apatrick@chromium.org563c0a52012-03-23 21:18:42 +000017{
daniel@transgaming.comef21ab22012-10-31 17:52:47 +000018 mRenderer = renderer;
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 {
daniel@transgaming.comef21ab22012-10-31 17:52:47 +000028 mRenderer->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
daniel@transgaming.comef21ab22012-10-31 17:52:47 +000039// D3D9_REPLACE
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +000040void Fence::setFence(GLenum condition)
41{
apatrick@chromium.orgf289ee82012-01-11 20:03:29 +000042 if (!mQuery)
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +000043 {
daniel@transgaming.comef21ab22012-10-31 17:52:47 +000044 mQuery = mRenderer->allocateEventQuery();
apatrick@chromium.orgf289ee82012-01-11 20:03:29 +000045 if (!mQuery)
46 {
47 return error(GL_OUT_OF_MEMORY);
48 }
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +000049 }
50
51 HRESULT result = mQuery->Issue(D3DISSUE_END);
52 ASSERT(SUCCEEDED(result));
53
54 mCondition = condition;
55 mStatus = GL_FALSE;
56}
57
daniel@transgaming.comef21ab22012-10-31 17:52:47 +000058// D3D9_REPLACE
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +000059GLboolean 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
daniel@transgaming.com6f5c5fc2011-11-09 17:46:39 +000068 if (checkDeviceLost(result))
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +000069 {
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
78void 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
91void 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
daniel@transgaming.comef21ab22012-10-31 17:52:47 +0000111 HRESULT result = mQuery->GetData(NULL, 0, 0); // D3D9_REPLACE
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +0000112
daniel@transgaming.com6f5c5fc2011-11-09 17:46:39 +0000113 if (checkDeviceLost(result))
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +0000114 {
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}