Home | History | Annotate | Download | only in libGL
      1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved.
      2 //
      3 // Licensed under the Apache License, Version 2.0 (the "License");
      4 // you may not use this file except in compliance with the License.
      5 // You may obtain a copy of the License at
      6 //
      7 //    http://www.apache.org/licenses/LICENSE-2.0
      8 //
      9 // Unless required by applicable law or agreed to in writing, software
     10 // distributed under the License is distributed on an "AS IS" BASIS,
     11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 // See the License for the specific language governing permissions and
     13 // limitations under the License.
     14 
     15 // Fence.cpp: Implements the Fence class, which supports the GL_NV_fence extension.
     16 
     17 #include "Fence.h"
     18 
     19 #include "main.h"
     20 #include "Common/Thread.hpp"
     21 
     22 namespace gl
     23 {
     24 
     25 Fence::Fence()
     26 {
     27 	mQuery = false;
     28 	mCondition = GL_NONE;
     29 	mStatus = GL_FALSE;
     30 }
     31 
     32 Fence::~Fence()
     33 {
     34 	mQuery = false;
     35 }
     36 
     37 GLboolean Fence::isFence()
     38 {
     39 	// GL_NV_fence spec:
     40 	// A name returned by GenFencesNV, but not yet set via SetFenceNV, is not the name of an existing fence.
     41 	return mQuery;
     42 }
     43 
     44 void Fence::setFence(GLenum condition)
     45 {
     46 	if(condition != GL_ALL_COMPLETED_NV)
     47 	{
     48 		return error(GL_INVALID_VALUE);
     49 	}
     50 
     51 	mQuery = true;
     52 	mCondition = condition;
     53 	mStatus = GL_FALSE;
     54 }
     55 
     56 GLboolean Fence::testFence()
     57 {
     58 	if(!mQuery)
     59 	{
     60 		return error(GL_INVALID_OPERATION, GL_TRUE);
     61 	}
     62 
     63 	// The current assumtion is that no matter where the fence is placed, it is
     64 	// done by the time it is tested, which is similar to Context::flush(), since
     65 	// we don't queue anything without processing it as fast as possible.
     66 	mStatus = GL_TRUE;
     67 
     68 	return mStatus;
     69 }
     70 
     71 void Fence::finishFence()
     72 {
     73 	if(!mQuery)
     74 	{
     75 		return error(GL_INVALID_OPERATION);
     76 	}
     77 
     78 	while(!testFence())
     79 	{
     80 		sw::Thread::yield();
     81 	}
     82 }
     83 
     84 void Fence::getFenceiv(GLenum pname, GLint *params)
     85 {
     86 	if(!mQuery)
     87 	{
     88 		return error(GL_INVALID_OPERATION);
     89 	}
     90 
     91 	switch(pname)
     92 	{
     93 	case GL_FENCE_STATUS_NV:
     94 		{
     95 			// GL_NV_fence spec:
     96 			// Once the status of a fence has been finished (via FinishFenceNV) or tested and the returned status is TRUE (via either TestFenceNV
     97 			// or GetFenceivNV querying the FENCE_STATUS_NV), the status remains TRUE until the next SetFenceNV of the fence.
     98 			if(mStatus)
     99 			{
    100 				params[0] = GL_TRUE;
    101 				return;
    102 			}
    103 
    104 			mStatus = testFence();
    105 
    106 			params[0] = mStatus;
    107 			break;
    108 		}
    109 	case GL_FENCE_CONDITION_NV:
    110 		params[0] = mCondition;
    111 		break;
    112 	default:
    113 		return error(GL_INVALID_ENUM);
    114 		break;
    115 	}
    116 }
    117 
    118 }
    119