Home | History | Annotate | Download | only in libGLESv2
      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