/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include "EmulatedEglFenceSync.h"

#include <unordered_set>

#include "OpenGLESDispatch/DispatchTables.h"
#include "OpenGLESDispatch/EGLDispatch.h"
#include "RenderThreadInfoGl.h"
#include "StalePtrRegistry.h"
#include "aemu/base/containers/Lookup.h"
#include "aemu/base/containers/StaticMap.h"
#include "aemu/base/files/StreamSerializing.h"
#include "aemu/base/synchronization/Lock.h"

namespace gfxstream {
namespace gl {
namespace {

using android::base::AutoLock;
using android::base::Lock;
using android::base::StaticMap;

// Timeline class is meant to delete native fences after the
// sync device has incremented the timeline.  We assume a
// maximum number of outstanding timelines in the guest (16) in
// order to derive when a native fence is definitely safe to
// delete. After at least that many timeline increments have
// happened, we sweep away the remaining native fences.
// The function that performs the deleting,
// incrementTimelineAndDeleteOldFences(), happens on the SyncThread.

class Timeline {
  public:
    Timeline() = default;

    static constexpr int kMaxGuestTimelines = 16;
    void addFence(EmulatedEglFenceSync* fence) {
        mFences.set(fence, mTime.load() + kMaxGuestTimelines);
    }

    void incrementTimelineAndDeleteOldFences() {
        ++mTime;
        sweep();
    }

    void sweep() {
        mFences.eraseIf([time = mTime.load()](EmulatedEglFenceSync* fence, int fenceTime) {
            EmulatedEglFenceSync* actual = EmulatedEglFenceSync::getFromHandle((uint64_t)(uintptr_t)fence);
            if (!actual) return true;

            bool shouldErase = fenceTime <= time;
            if (shouldErase) {
                if (!actual->decRef() &&
                    actual->shouldDestroyWhenSignaled()) {
                    actual->decRef();
                }
            }
            return shouldErase;
        });
    }

  private:
    std::atomic<int> mTime {0};
    StaticMap<EmulatedEglFenceSync*, int> mFences;
};

static Timeline* sTimeline() {
    static Timeline* t = new Timeline;
    return t;
}

}  // namespace

// static
void EmulatedEglFenceSync::incrementTimelineAndDeleteOldFences() {
    sTimeline()->incrementTimelineAndDeleteOldFences();
}

// static
std::unique_ptr<EmulatedEglFenceSync> EmulatedEglFenceSync::create(
        EGLDisplay display,
        bool hasNativeFence,
        bool destroyWhenSignaled) {
    auto sync = s_egl.eglCreateSyncKHR(display, EGL_SYNC_FENCE_KHR, nullptr);
    if (sync == EGL_NO_SYNC_KHR) {
        ERR("Failed to create EGL fence sync: %d", s_egl.eglGetError());
        return nullptr;
    }

    // This MUST be present, or we get a deadlock effect.
    s_gles2.glFlush();

    return std::unique_ptr<EmulatedEglFenceSync>(
        new EmulatedEglFenceSync(display,
                                 sync,
                                 hasNativeFence,
                                 destroyWhenSignaled));
}

EmulatedEglFenceSync::EmulatedEglFenceSync(EGLDisplay display,
                                           EGLSyncKHR sync,
                                           bool hasNativeFence,
                                           bool destroyWhenSignaled)
    : mDestroyWhenSignaled(destroyWhenSignaled),
      mDisplay(display),
      mSync(sync) {

    addToRegistry();

    assert(mCount == 1);
    if (hasNativeFence) {
        incRef();
        sTimeline()->addFence(this);
    }

    // Assumes that there is a valid + current OpenGL context
    assert(RenderThreadInfoGl::get());
}

EmulatedEglFenceSync::~EmulatedEglFenceSync() {
    removeFromRegistry();
}

EGLint EmulatedEglFenceSync::wait(uint64_t timeout) {
    incRef();
    EGLint wait_res =
        s_egl.eglClientWaitSyncKHR(mDisplay, mSync,
                                   EGL_SYNC_FLUSH_COMMANDS_BIT_KHR,
                                   timeout);
    decRef();
    return wait_res;
}

void EmulatedEglFenceSync::waitAsync() {
    s_egl.eglWaitSyncKHR(mDisplay, mSync, 0);
}

bool EmulatedEglFenceSync::isSignaled() {
    EGLint val;
    if (EGL_TRUE ==
            s_egl.eglGetSyncAttribKHR(
                mDisplay, mSync, EGL_SYNC_STATUS_KHR, &val))
        return val == EGL_SIGNALED_KHR;

    return true; // if invalid, treat as signaled
}

void EmulatedEglFenceSync::destroy() {
    s_egl.eglDestroySyncKHR(mDisplay, mSync);
}

// Snapshots for EmulatedEglFenceSync//////////////////////////////////////////////////////
// It's possible, though it does not happen often, that a fence
// can be created but not yet waited on by the guest, which
// needs careful handling:
//
// 1. Avoid manipulating garbage memory on snapshot restore;
// rcCreateSyncKHR *creates new fence in valid memory*
// --snapshot--
// rcClientWaitSyncKHR *refers to uninitialized memory*
// rcDestroySyncKHR *refers to uninitialized memory*
// 2. Make rcCreateSyncKHR/rcDestroySyncKHR implementations return
// the "signaled" status if referring to previous snapshot fences. It's
// assumed that the GPU is long done with them.
// 3. Avoid name collisions where a new EmulatedEglFenceSync object is created
// that has the same uint64_t casting as a EmulatedEglFenceSync object from a previous
// snapshot.

// Maintain a StalePtrRegistry<EmulatedEglFenceSync>:
static StalePtrRegistry<EmulatedEglFenceSync>* sFenceRegistry() {
    static StalePtrRegistry<EmulatedEglFenceSync>* s = new StalePtrRegistry<EmulatedEglFenceSync>;
    return s;
}

// static
void EmulatedEglFenceSync::addToRegistry() {
    sFenceRegistry()->addPtr(this);
}

// static
void EmulatedEglFenceSync::removeFromRegistry() {
    sFenceRegistry()->removePtr(this);
}

// static
void EmulatedEglFenceSync::onSave(android::base::Stream* stream) {
    sFenceRegistry()->makeCurrentPtrsStale();
    sFenceRegistry()->onSave(stream);
}

// static
void EmulatedEglFenceSync::onLoad(android::base::Stream* stream) {
    sFenceRegistry()->onLoad(stream);
}

// static
EmulatedEglFenceSync* EmulatedEglFenceSync::getFromHandle(uint64_t handle) {
    return sFenceRegistry()->getPtr(handle);
}

}  // namespace gl
}  // namespace gfxstream
