Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / third_party / angle / src / libGLESv2 / Fence.cpp
index ee9a07a..966a327 100644 (file)
 // found in the LICENSE file.
 //
 
-// Fence.cpp: Implements the gl::Fence class, which supports the GL_NV_fence extension.
-
-// Important note on accurate timers in Windows:
-//
-// QueryPerformanceCounter has a few major issues, including being 10x as expensive to call
-// as timeGetTime on laptops and "jumping" during certain hardware events.
-//
-// See the comments at the top of the Chromium source file "chromium/src/base/time/time_win.cc"
-//   https://code.google.com/p/chromium/codesearch#chromium/src/base/time/time_win.cc
-//
-// We still opt to use QPC. In the present and moving forward, most newer systems will not suffer
-// from buggy implementations.
+// Fence.cpp: Implements the gl::FenceNV and gl::FenceSync classes, which support the GL_NV_fence
+// extension and GLES3 sync objects.
 
 #include "libGLESv2/Fence.h"
 #include "libGLESv2/renderer/FenceImpl.h"
 #include "libGLESv2/renderer/Renderer.h"
 #include "libGLESv2/main.h"
+#include "common/utilities.h"
 
 #include "angle_gl.h"
 
 namespace gl
 {
 
-FenceNV::FenceNV(rx::Renderer *renderer)
+FenceNV::FenceNV(rx::FenceNVImpl *impl)
+    : mFence(impl),
+      mIsSet(false),
+      mStatus(GL_FALSE),
+      mCondition(GL_NONE)
 {
-    mFence = renderer->createFence();
 }
 
 FenceNV::~FenceNV()
 {
-    delete mFence;
+    SafeDelete(mFence);
 }
 
 GLboolean FenceNV::isFence() const
 {
     // GL_NV_fence spec:
     // A name returned by GenFencesNV, but not yet set via SetFenceNV, is not the name of an existing fence.
-    return (mFence->isSet() ? GL_TRUE : GL_FALSE);
+    return (mIsSet ? GL_TRUE : GL_FALSE);
 }
 
-void FenceNV::setFence(GLenum condition)
+Error FenceNV::setFence(GLenum condition)
 {
-    mFence->set();
+    Error error = mFence->set();
+    if (error.isError())
+    {
+        return error;
+    }
 
     mCondition = condition;
     mStatus = GL_FALSE;
-}
-
-GLboolean FenceNV::testFence()
-{
-    // Flush the command buffer by default
-    bool result = mFence->test(true);
+    mIsSet = true;
 
-    mStatus = (result ? GL_TRUE : GL_FALSE);
-    return mStatus;
+    return Error(GL_NO_ERROR);
 }
 
-void FenceNV::finishFence()
+Error FenceNV::testFence(GLboolean *outResult)
 {
-    ASSERT(mFence->isSet());
-
-    while (!mFence->test(true))
+    // Flush the command buffer by default
+    Error error = mFence->test(true, &mStatus);
+    if (error.isError())
     {
-        Sleep(0);
+        return error;
     }
-}
-
-GLint FenceNV::getFencei(GLenum pname)
-{
-    ASSERT(mFence->isSet());
 
-    switch (pname)
-    {
-      case GL_FENCE_STATUS_NV:
-        {
-            // GL_NV_fence spec:
-            // Once the status of a fence has been finished (via FinishFenceNV) or tested and the returned status is TRUE (via either TestFenceNV
-            // or GetFenceivNV querying the FENCE_STATUS_NV), the status remains TRUE until the next SetFenceNV of the fence.
-            if (mStatus == GL_TRUE)
-            {
-                return GL_TRUE;
-            }
-
-            mStatus = (mFence->test(false) ? GL_TRUE : GL_FALSE);
-            return mStatus;
-        }
-
-      case GL_FENCE_CONDITION_NV:
-        return mCondition;
-
-      default: UNREACHABLE(); return 0;
-    }
+    *outResult = mStatus;
+    return Error(GL_NO_ERROR);
 }
 
-FenceSync::FenceSync(rx::Renderer *renderer, GLuint id)
-    : RefCountObject(id)
+Error FenceNV::finishFence()
 {
-    mFence = renderer->createFence();
-
-    LARGE_INTEGER counterFreqency = { 0 };
-    BOOL success = QueryPerformanceFrequency(&counterFreqency);
-    UNUSED_ASSERTION_VARIABLE(success);
-    ASSERT(success);
+    ASSERT(mIsSet);
 
-    mCounterFrequency = counterFreqency.QuadPart;
+    return mFence->finishFence(&mStatus);
 }
 
-FenceSync::~FenceSync()
+FenceSync::FenceSync(rx::FenceSyncImpl *impl, GLuint id)
+    : RefCountObject(id),
+      mFence(impl),
+      mCondition(GL_NONE)
 {
-    delete mFence;
 }
 
-void FenceSync::set(GLenum condition)
+FenceSync::~FenceSync()
 {
-    mCondition = condition;
-    mFence->set();
+    SafeDelete(mFence);
 }
 
-GLenum FenceSync::clientWait(GLbitfield flags, GLuint64 timeout)
+Error FenceSync::set(GLenum condition)
 {
-    ASSERT(mFence->isSet());
-
-    bool flushCommandBuffer = ((flags & GL_SYNC_FLUSH_COMMANDS_BIT) != 0);
-
-    if (mFence->test(flushCommandBuffer))
+    Error error = mFence->set();
+    if (error.isError())
     {
-        return GL_ALREADY_SIGNALED;
+        return error;
     }
 
-    if (mFence->hasError())
-    {
-        return GL_WAIT_FAILED;
-    }
-
-    if (timeout == 0)
-    {
-        return GL_TIMEOUT_EXPIRED;
-    }
-
-    LARGE_INTEGER currentCounter = { 0 };
-    BOOL success = QueryPerformanceCounter(&currentCounter);
-    UNUSED_ASSERTION_VARIABLE(success);
-    ASSERT(success);
-
-    LONGLONG timeoutInSeconds = static_cast<LONGLONG>(timeout) * static_cast<LONGLONG>(1000000ll);
-    LONGLONG endCounter = currentCounter.QuadPart + mCounterFrequency * timeoutInSeconds;
-
-    while (currentCounter.QuadPart < endCounter && !mFence->test(flushCommandBuffer))
-    {
-        Sleep(0);
-        BOOL success = QueryPerformanceCounter(&currentCounter);
-        UNUSED_ASSERTION_VARIABLE(success);
-        ASSERT(success);
-    }
-
-    if (mFence->hasError())
-    {
-        return GL_WAIT_FAILED;
-    }
-
-    if (currentCounter.QuadPart >= endCounter)
-    {
-        return GL_TIMEOUT_EXPIRED;
-    }
-
-    return GL_CONDITION_SATISFIED;
+    mCondition = condition;
+    return Error(GL_NO_ERROR);
 }
 
-void FenceSync::serverWait()
+Error FenceSync::clientWait(GLbitfield flags, GLuint64 timeout, GLenum *outResult)
 {
-    // Because our API is currently designed to be called from a single thread, we don't need to do
-    // extra work for a server-side fence. GPU commands issued after the fence is created will always
-    // be processed after the fence is signaled.
+    ASSERT(mCondition != GL_NONE);
+    return mFence->clientWait(flags, timeout, outResult);
 }
 
-GLenum FenceSync::getStatus() const
+Error FenceSync::serverWait(GLbitfield flags, GLuint64 timeout)
 {
-    if (mFence->test(false))
-    {
-        // The spec does not specify any way to report errors during the status test (e.g. device lost)
-        // so we report the fence is unblocked in case of error or signaled.
-        return GL_SIGNALED;
-    }
+    return mFence->serverWait(flags, timeout);
+}
 
-    return GL_UNSIGNALED;
+Error FenceSync::getStatus(GLint *outResult) const
+{
+    return mFence->getStatus(outResult);
 }
 
 }