Home | History | Annotate | Download | only in libGLESv2
      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 es2
     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 FenceSync::FenceSync(GLuint name, GLenum condition, GLbitfield flags) : NamedObject(name), mCondition(condition), mFlags(flags)
    119 {
    120 }
    121 
    122 FenceSync::~FenceSync()
    123 {
    124 }
    125 
    126 GLenum FenceSync::clientWait(GLbitfield flags, GLuint64 timeout)
    127 {
    128 	// The current assumtion is that no matter where the fence is placed, it is
    129 	// done by the time it is tested, which is similar to Context::flush(), since
    130 	// we don't queue anything without processing it as fast as possible.
    131 	return GL_ALREADY_SIGNALED;
    132 }
    133 
    134 void FenceSync::serverWait(GLbitfield flags, GLuint64 timeout)
    135 {
    136 }
    137 
    138 void FenceSync::getSynciv(GLenum pname, GLsizei *length, GLint *values)
    139 {
    140 	switch(pname)
    141 	{
    142 	case GL_OBJECT_TYPE:
    143 		values[0] = GL_SYNC_FENCE;
    144 		if(length) {
    145 			*length = 1;
    146 		}
    147 		break;
    148 	case GL_SYNC_STATUS:
    149 		// The current assumtion is that no matter where the fence is placed, it is
    150 		// done by the time it is tested, which is similar to Context::flush(), since
    151 		// we don't queue anything without processing it as fast as possible.
    152 		values[0] = GL_SIGNALED;
    153 		if(length) {
    154 			*length = 1;
    155 		}
    156 		break;
    157 	case GL_SYNC_CONDITION:
    158 		values[0] = GL_SYNC_GPU_COMMANDS_COMPLETE;
    159 		if(length) {
    160 			*length = 1;
    161 		}
    162 		break;
    163 	case GL_SYNC_FLAGS:
    164 		if(length) {
    165 			*length = 0;
    166 		}
    167 		break;
    168 	default:
    169 		return error(GL_INVALID_ENUM);
    170 	}
    171 }
    172 
    173 }
    174