Repository: google/filament
File: filament/backend/src/vulkan/VulkanDriver.cpp (C++)

Code before:
    auto fence = resource_ptr<VulkanFence>::cast(&mResourceManager, fh);
    fence.dec();
}

FenceStatus VulkanDriver::getFenceStatus(Handle<HwFence> const fh) {
    return fenceWait(fh, 0);
}

FenceStatus VulkanDriver::fenceWait(FenceHandle const fh, uint64_t const timeout) {
    auto fence = resource_ptr<VulkanFence>::cast(&mResourceManager, fh);

    // we have to take into account that the STL's wait_for() actually works with
    // time_points relative to steady_clock::now() internally.
    using namespace std::chrono;
    auto const now = steady_clock::now();
    steady_clock::time_point until = steady_clock::time_point::max();
    if (now <= steady_clock::time_point::max() - nanoseconds(timeout)) {
        until = now + nanoseconds(timeout);
    }

    std::shared_ptr const cmdfence = fence->wait(until);
    if (!cmdfence) {
        return FenceStatus::TIMEOUT_EXPIRED;
    }

    // now we are holding a reference to our VulkanCmdFence, so we now it can't
    // disappear while we wait
    return cmdfence->wait(mPlatform->getDevice(), timeout, until);
}

void VulkanDriver::getPlatformSync(Handle<HwSync> sh, CallbackHandler* handler,
        Platform::SyncCallback cb, void* userData) {
    auto sync = resource_ptr<VulkanSync>::cast(&mResourceManager, sh);
    auto cbData = std::make_unique<VulkanSync::CallbackData>();
    cbData->handler = handler;
    cbData->cb = cb;
    cbData->userData = userData;

    // If we haven't already set the handle, toss the conversion callback in the
    // back of the list.
    {
        std::lock_guard guard(sync->lock);
        if (sync->sync == nullptr) {
            sync->conversionCallbacks.push_back(std::move(cbData));
            return;
        }
    }

    // Otherwise, go ahead and schedule the callback now.
    cbData->sync = sync->sync;
    scheduleCallback(cbData->handler, cbData.release(), syncCallbackWrapper);

Review comment (suggestion):
### ### 
```suggestion
    // now we are holding a reference to our VulkanCmdFence, so we know it can't
```

Code after:
    auto fence = resource_ptr<VulkanFence>::cast(&mResourceManager, fh);
    fence.dec();
}

FenceStatus VulkanDriver::getFenceStatus(Handle<HwFence> const fh) {
    return fenceWait(fh, 0);
}

FenceStatus VulkanDriver::fenceWait(FenceHandle const fh, uint64_t const timeout) {
    auto fence = resource_ptr<VulkanFence>::cast(&mResourceManager, fh);

    // we have to take into account that the STL's wait_for() actually works with
    // time_points relative to steady_clock::now() internally.
    using namespace std::chrono;
    auto const now = steady_clock::now();
    steady_clock::time_point until = steady_clock::time_point::max();
    if (now <= steady_clock::time_point::max() - nanoseconds(timeout)) {
        until = now + nanoseconds(timeout);
    }

    std::shared_ptr const cmdfence = fence->wait(until);
    if (!cmdfence) {
        return FenceStatus::TIMEOUT_EXPIRED;
    }

    // now we are holding a reference to our VulkanCmdFence, so we know it can't
    // disappear while we wait
    return cmdfence->wait(mPlatform->getDevice(), timeout, until);
}

void VulkanDriver::getPlatformSync(Handle<HwSync> sh, CallbackHandler* handler,
        Platform::SyncCallback cb, void* userData) {
    auto sync = resource_ptr<VulkanSync>::cast(&mResourceManager, sh);
    auto cbData = std::make_unique<VulkanSync::CallbackData>();
    cbData->handler = handler;
    cbData->cb = cb;
    cbData->userData = userData;

    // If we haven't already set the handle, toss the conversion callback in the
    // back of the list.
    {
        std::lock_guard guard(sync->lock);
        if (sync->sync == nullptr) {
            sync->conversionCallbacks.push_back(std::move(cbData));
            return;
        }
    }

    // Otherwise, go ahead and schedule the callback now.
    cbData->sync = sync->sync;
    scheduleCallback(cbData->handler, cbData.release(), syncCallbackWrapper);