//
// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//

// Fence11.cpp: Defines the rx::FenceNV11 and rx::Sync11 classes which implement
// rx::FenceNVImpl and rx::SyncImpl.

#include "libANGLE/renderer/d3d/d3d11/Fence11.h"

#include "common/utilities.h"
#include "libANGLE/Context.h"
#include "libANGLE/renderer/d3d/d3d11/Context11.h"
#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"

namespace rx
{

//
// Template helpers for set and test operations.
//

template <class FenceClass>
angle::Result FenceSetHelper(const gl::Context *context, FenceClass *fence)
{
    if (!fence->mQuery)
    {
        D3D11_QUERY_DESC queryDesc;
        queryDesc.Query     = D3D11_QUERY_EVENT;
        queryDesc.MiscFlags = 0;

        Context11 *context11 = GetImplAs<Context11>(context);
        HRESULT result = fence->mRenderer->getDevice()->CreateQuery(&queryDesc, &fence->mQuery);
        ANGLE_TRY_HR(context11, result, "Failed to create event query");
    }

    fence->mRenderer->getDeviceContext()->End(fence->mQuery);
    return angle::Result::Continue;
}

template <class FenceClass>
angle::Result FenceTestHelper(const gl::Context *context,
                              FenceClass *fence,
                              bool flushCommandBuffer,
                              GLboolean *outFinished)
{
    ASSERT(fence->mQuery);

    UINT getDataFlags = (flushCommandBuffer ? 0 : D3D11_ASYNC_GETDATA_DONOTFLUSH);

    Context11 *context11 = GetImplAs<Context11>(context);
    HRESULT result =
        fence->mRenderer->getDeviceContext()->GetData(fence->mQuery, nullptr, 0, getDataFlags);
    ANGLE_TRY_HR(context11, result, "Failed to get query data");

    ASSERT(result == S_OK || result == S_FALSE);
    *outFinished = ((result == S_OK) ? GL_TRUE : GL_FALSE);
    return angle::Result::Continue;
}

//
// FenceNV11
//

FenceNV11::FenceNV11(Renderer11 *renderer) : FenceNVImpl(), mRenderer(renderer), mQuery(nullptr) {}

FenceNV11::~FenceNV11()
{
    SafeRelease(mQuery);
}

angle::Result FenceNV11::set(const gl::Context *context, GLenum condition)
{
    return FenceSetHelper(context, this);
}

angle::Result FenceNV11::test(const gl::Context *context, GLboolean *outFinished)
{
    return FenceTestHelper(context, this, true, outFinished);
}

angle::Result FenceNV11::finish(const gl::Context *context)
{
    GLboolean finished = GL_FALSE;

    int loopCount = 0;
    while (finished != GL_TRUE)
    {
        loopCount++;
        ANGLE_TRY(FenceTestHelper(context, this, true, &finished));

        bool checkDeviceLost = (loopCount % kPollingD3DDeviceLostCheckFrequency) == 0;
        if (checkDeviceLost && mRenderer->testDeviceLost())
        {
            ANGLE_TRY_HR(GetImplAs<Context11>(context), DXGI_ERROR_DRIVER_INTERNAL_ERROR,
                         "Device was lost while querying result of an event query.");
        }

        ScheduleYield();
    }

    return angle::Result::Continue;
}

//
// Sync11
//

// 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.

Sync11::Sync11(Renderer11 *renderer) : SyncImpl(), mRenderer(renderer), mQuery(nullptr)
{
    LARGE_INTEGER counterFreqency = {};
    BOOL success                  = QueryPerformanceFrequency(&counterFreqency);
    ASSERT(success);

    mCounterFrequency = counterFreqency.QuadPart;
}

Sync11::~Sync11()
{
    SafeRelease(mQuery);
}

angle::Result Sync11::set(const gl::Context *context, GLenum condition, GLbitfield flags)
{
    ASSERT(condition == GL_SYNC_GPU_COMMANDS_COMPLETE && flags == 0);
    return FenceSetHelper(context, this);
}

angle::Result Sync11::clientWait(const gl::Context *context,
                                 GLbitfield flags,
                                 GLuint64 timeout,
                                 GLenum *outResult)
{
    ASSERT(outResult);

    bool flushCommandBuffer = ((flags & GL_SYNC_FLUSH_COMMANDS_BIT) != 0);

    *outResult = GL_WAIT_FAILED;

    GLboolean result = GL_FALSE;
    ANGLE_TRY(FenceTestHelper(context, this, flushCommandBuffer, &result));

    if (result == GL_TRUE)
    {
        *outResult = GL_ALREADY_SIGNALED;
        return angle::Result::Continue;
    }

    if (timeout == 0)
    {
        *outResult = GL_TIMEOUT_EXPIRED;
        return angle::Result::Continue;
    }

    LARGE_INTEGER currentCounter = {};
    BOOL success                 = QueryPerformanceCounter(&currentCounter);
    ASSERT(success);

    LONGLONG timeoutInSeconds = static_cast<LONGLONG>(timeout / 1000000000ull);
    LONGLONG endCounter       = currentCounter.QuadPart + mCounterFrequency * timeoutInSeconds;

    // Extremely unlikely, but if mCounterFrequency is large enough, endCounter can wrap
    if (endCounter < currentCounter.QuadPart)
    {
        endCounter = MAXLONGLONG;
    }

    int loopCount = 0;
    while (currentCounter.QuadPart < endCounter && !result)
    {
        loopCount++;
        ScheduleYield();
        success = QueryPerformanceCounter(&currentCounter);
        ASSERT(success);

        *outResult = GL_WAIT_FAILED;

        ANGLE_TRY(FenceTestHelper(context, this, flushCommandBuffer, &result));

        bool checkDeviceLost = (loopCount % kPollingD3DDeviceLostCheckFrequency) == 0;
        if (checkDeviceLost && mRenderer->testDeviceLost())
        {
            *outResult = GL_WAIT_FAILED;
            ANGLE_TRY_HR(GetImplAs<Context11>(context), DXGI_ERROR_DRIVER_INTERNAL_ERROR,
                         "Device was lost while querying result of an event query.");
        }
    }

    if (currentCounter.QuadPart >= endCounter)
    {
        *outResult = GL_TIMEOUT_EXPIRED;
    }
    else
    {
        *outResult = GL_CONDITION_SATISFIED;
    }

    return angle::Result::Continue;
}

angle::Result Sync11::serverWait(const gl::Context *context, GLbitfield flags, GLuint64 timeout)
{
    // 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.
    return angle::Result::Continue;
}

angle::Result Sync11::getStatus(const gl::Context *context, GLint *outResult)
{
    GLboolean result = GL_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.
    *outResult = GL_SIGNALED;
    ANGLE_TRY(FenceTestHelper(context, this, false, &result));

    *outResult = (result ? GL_SIGNALED : GL_UNSIGNALED);
    return angle::Result::Continue;
}

}  // namespace rx
