Home | History | Annotate | Download | only in renderer
      1 #include "precompiled.h"
      2 //
      3 // Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
      4 // Use of this source code is governed by a BSD-style license that can be
      5 // found in the LICENSE file.
      6 //
      7 
      8 // Fence9.cpp: Defines the rx::Fence9 class.
      9 
     10 #include "libGLESv2/renderer/Fence9.h"
     11 #include "libGLESv2/main.h"
     12 #include "libGLESv2/renderer/renderer9_utils.h"
     13 #include "libGLESv2/renderer/Renderer9.h"
     14 
     15 namespace rx
     16 {
     17 
     18 Fence9::Fence9(rx::Renderer9 *renderer)
     19 {
     20     mRenderer = renderer;
     21     mQuery = NULL;
     22 }
     23 
     24 Fence9::~Fence9()
     25 {
     26     if (mQuery)
     27     {
     28         mRenderer->freeEventQuery(mQuery);
     29         mQuery = NULL;
     30     }
     31 }
     32 
     33 GLboolean Fence9::isFence()
     34 {
     35     // GL_NV_fence spec:
     36     // A name returned by GenFencesNV, but not yet set via SetFenceNV, is not the name of an existing fence.
     37     return mQuery != NULL;
     38 }
     39 
     40 void Fence9::setFence(GLenum condition)
     41 {
     42     if (!mQuery)
     43     {
     44         mQuery = mRenderer->allocateEventQuery();
     45         if (!mQuery)
     46         {
     47             return gl::error(GL_OUT_OF_MEMORY);
     48         }
     49     }
     50 
     51     HRESULT result = mQuery->Issue(D3DISSUE_END);
     52     ASSERT(SUCCEEDED(result));
     53 
     54     setCondition(condition);
     55     setStatus(GL_FALSE);
     56 }
     57 
     58 GLboolean Fence9::testFence()
     59 {
     60     if (mQuery == NULL)
     61     {
     62         return gl::error(GL_INVALID_OPERATION, GL_TRUE);
     63     }
     64 
     65     HRESULT result = mQuery->GetData(NULL, 0, D3DGETDATA_FLUSH);
     66 
     67     if (d3d9::isDeviceLostError(result))
     68     {
     69         mRenderer->notifyDeviceLost();
     70         return gl::error(GL_OUT_OF_MEMORY, GL_TRUE);
     71     }
     72 
     73     ASSERT(result == S_OK || result == S_FALSE);
     74     setStatus(result == S_OK);
     75     return getStatus();
     76 }
     77 
     78 void Fence9::finishFence()
     79 {
     80     if (mQuery == NULL)
     81     {
     82         return gl::error(GL_INVALID_OPERATION);
     83     }
     84 
     85     while (!testFence())
     86     {
     87         Sleep(0);
     88     }
     89 }
     90 
     91 void Fence9::getFenceiv(GLenum pname, GLint *params)
     92 {
     93     if (mQuery == NULL)
     94     {
     95         return gl::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 (getStatus())
    106             {
    107                 params[0] = GL_TRUE;
    108                 return;
    109             }
    110 
    111             HRESULT result = mQuery->GetData(NULL, 0, 0);
    112 
    113             if (d3d9::isDeviceLostError(result))
    114             {
    115                 params[0] = GL_TRUE;
    116                 mRenderer->notifyDeviceLost();
    117                 return gl::error(GL_OUT_OF_MEMORY);
    118             }
    119 
    120             ASSERT(result == S_OK || result == S_FALSE);
    121             setStatus(result == S_OK);
    122             params[0] = getStatus();
    123 
    124             break;
    125         }
    126         case GL_FENCE_CONDITION_NV:
    127             params[0] = getCondition();
    128             break;
    129         default:
    130             return gl::error(GL_INVALID_ENUM);
    131             break;
    132     }
    133 }
    134 
    135 }
    136