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

#pragma once

#include <atomic>
#include <memory>

#include <EGL/egl.h>
#include <EGL/eglext.h>

#include "aemu/base/Compiler.h"
#include "aemu/base/files/Stream.h"
#include "aemu/base/synchronization/Lock.h"

namespace gfxstream {
namespace gl {

// The EmulatedEglFenceSync class wraps actual EGLSyncKHR objects
// and issues calls to eglCreateSyncKHR, eglClientWaitSyncKHR,
// and eglDestroySyncKHR.
//
// The purpose of this class:
// - We need to track EGL sync objects created by the guest and
//   realized in the host OpenGL driver. They are passed between
//   guest and host all the time.
// - In particular, we also need to destroy EGL sync objects at
//   the proper time. There are at least 3 issues (referenced below
//   in spec comments):
//   1 According to spec, we would need to allow concurrent
//     eglClientWaitSyncKHR and eglDestroySyncKHR to all finish
//     properly.
//   2 If the EGL sync object is of EGL_SYNC_NATIVE_FENCE_ANDROID
//     nature, we cannot mirror the guest's call to eglDestroySyncKHR
//     by calling the same function on the host, because Goldfish
//     sync device can only know when native fence FD's are signaled
//     when a host-side EGL sync object is signaled. Thus, we would
//     need to delete such sync objects after both the guest and
//     the Goldfish sync device are done with them.
//   3 We sometimes create sync objects that are only seen by
//     the Goldfish OpenGL driver in the guest, such as for
//     implementing eglSwapBuffers() in a way that avoids
//     out of order frames. It is cumbersome to eglDestroySyncKHR
//     those on the guest, as that would require starting up another guest
//     thread and OpenGL context (complete with host connection)
//     to destroy it.
class EmulatedEglFenceSync {
  public:
    // The constructor wraps eglCreateSyncKHR on the host OpenGL driver.
    // |hasNativeFence| specifies whether this sync object
    // is of EGL_SYNC_NATIVE_FENCE_ANDROID nature (2), and
    // |destroyWhenSignaled| specifies whether or not to destroy
    // the sync object when the native fence FD becomes signaled (3).
    static std::unique_ptr<EmulatedEglFenceSync> create(
        EGLSyncKHR sync,
        bool hasNativeFence,
        bool destroyWhenSignaled);

    ~EmulatedEglFenceSync();

    // wait() wraps eglClientWaitSyncKHR. During such a wait, we need
    // to increment the reference count while the wait is active,
    // in case there is a concurrent call to eglDestroySyncKHR (1).
    EGLint wait(uint64_t timeout);

    // waitAsync wraps eglWaitSyncKHR.
    void waitAsync();

    // isSignaled wraps eglGetSyncAttribKHR.
    bool isSignaled();

    bool shouldDestroyWhenSignaled() const {
        return mDestroyWhenSignaled;
    }

    // When a native fence gets signaled, this function is called to update the
    // timeline counter in the EmulatedEglFenceSync internal timeline and delete old
    // fences.
    static void incrementTimelineAndDeleteOldFences();

    // incRef() / decRef() increment/decrement refence counts in order
    // to deal with sync object destruction. This is a simple reference
    // counting implementation that is almost literally the kref() in
    // the Linux kernel.
    //
    // We do not use shared_ptr or anything like that here because
    // we need to explicitly manipulate the reference count in order to
    // satisfy (1,2,3) above.
    void incRef() { assert(mCount > 0); ++mCount; }
    bool decRef() {
        assert(mCount > 0);
        if (mCount == 1 || --mCount == 0) {
            // destroy() here would delay calls to eglDestroySyncKHR
            // in the host driver until all waits have completed,
            // which is a bit different from simply allowing concurrent calls.
            // But, from the guest's perspective, the contract of allowing
            // everything to finish is still fulfilled, and there is
            // no reason to think (theoretically or practically) that
            // is undesirable to destroy the underlying EGL sync object
            // a tiny bit later. We could have put in extra logic to allow
            // concurrent destruction, but this would have made the code
            // undesirably less simple.
            destroy();
            // This delete-then-return seems OK.
            delete this;
            return true;
        }
        return false;
    }

    void setIsCompositionFence(bool isComposition) {
        mIsCompositionFence = isComposition;
    }

    bool isCompositionFence() const {
        return mIsCompositionFence;
    }

    // Tracks current active set of fences. Useful for snapshotting.
    void addToRegistry();
    void removeFromRegistry();

    static EmulatedEglFenceSync* getFromHandle(uint64_t handle);

    // Functions for snapshotting all fence state at once
    static void onSave(android::base::Stream* stream);
    static void onLoad(android::base::Stream* stream);

  private:
    EmulatedEglFenceSync(EGLDisplay display,
                         EGLSyncKHR sync,
                         bool hasNativeFence,
                         bool destroyWhenSignaled);

    bool mDestroyWhenSignaled;
    std::atomic<int> mCount {1};

    // EGL state needed for calling OpenGL sync operations.
    EGLDisplay mDisplay;
    EGLSyncKHR mSync;

    // Whether this fence was against composition, in which case
    // we should make this wait till next vsync.
    bool mIsCompositionFence = false;

    // destroy() wraps eglDestroySyncKHR. This is private, because we need
    // careful control of when eglDestroySyncKHR is actually called.
    void destroy();

    DISALLOW_COPY_AND_ASSIGN(EmulatedEglFenceSync);
};

}  // namespace gl
}  // namespace gfxstream
