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 16 Fence::Fence() 17 { 18 mQuery = NULL; 19 mCondition = GL_NONE; 20 mStatus = GL_FALSE; 21 } 22 23 Fence::~Fence() 24 { 25 if (mQuery != NULL) 26 { 27 mQuery->Release(); 28 mQuery = NULL; 29 } 30 } 31 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 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 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 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 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