// Copyright 2016 The Android Open Source Project
//
// This software is licensed under the terms of the GNU General Public
// License version 2, as published by the Free Software Foundation, and
// may be copied, distributed, and modified under those terms.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
#include "android/opengl/OpenglEsPipe.h"

#include "android/base/async/Looper.h"
#include "android/opengles.h"
#include "android/opengles-pipe.h"
#include "android/opengl/GLProcessPipe.h"

#include <atomic>

#include <assert.h>
#include <stdlib.h>
#include <string.h>

// Set to 1 or 2 for debug traces
//#define DEBUG 1

#if DEBUG >= 1
#define D(...) printf(__VA_ARGS__), printf("\n"), fflush(stdout)
#else
#define D(...) ((void)0)
#endif

#if DEBUG >= 2
#define DD(...) printf(__VA_ARGS__), printf("\n"), fflush(stdout)
#else
#define DD(...) ((void)0)
#endif

using emugl::ChannelBuffer;
using emugl::RenderChannel;
using emugl::RenderChannelPtr;
using ChannelState = emugl::RenderChannel::State;

namespace android {
namespace opengl {

namespace {

class EmuglPipe : public AndroidPipe {
public:
    //////////////////////////////////////////////////////////////////////////
    // The pipe service class for this implementation.
    class Service : public AndroidPipe::Service {
    public:
        Service() : AndroidPipe::Service("opengles") {}

        // Create a new EmuglPipe instance.
        virtual AndroidPipe* create(void* mHwPipe, const char* args) override {
            auto renderer = android_getOpenglesRenderer();
            if (!renderer) {
                // This should never happen, unless there is a bug in the
                // emulator's initialization, or the system image.
                D("Trying to open the OpenGLES pipe without GPU emulation!");
                return nullptr;
            }

            EmuglPipe* pipe = new EmuglPipe(mHwPipe, this, renderer);
            if (!pipe->mIsWorking) {
                delete pipe;
                pipe = nullptr;
            }
            return pipe;
        }

        // Really cannot save/load these pipes' state.
        virtual bool canLoad() const override { return false; }
    };

    /////////////////////////////////////////////////////////////////////////
    // Constructor, check that |mIsWorking| is true after this call to verify
    // that everything went well.
    EmuglPipe(void* hwPipe,
              Service* service,
              const emugl::RendererPtr& renderer)
        : AndroidPipe(hwPipe, service) {
        mChannel = renderer->createRenderChannel();
        if (!mChannel) {
            D("Failed to create an OpenGLES pipe channel!");
            return;
        }

        mIsWorking = true;
        mChannel->setEventCallback([this](ChannelState state,
                                          RenderChannel::EventSource source) {
            this->onChannelIoEvent(state);
        });
    }

    //////////////////////////////////////////////////////////////////////////
    // Overriden AndroidPipe methods

    virtual void onGuestClose() override {
        D("%s", __func__);
        mIsWorking = false;
        mChannel->stop();
        // stop callback will call close() which deletes the pipe
    }

    virtual unsigned onGuestPoll() const override {
        DD("%s", __func__);

        unsigned ret = 0;
        ChannelState state = mChannel->currentState();
        if (canReadAny(state)) {
            ret |= PIPE_POLL_IN;
        }
        if (canWrite(state)) {
            ret |= PIPE_POLL_OUT;
        }
        return ret;
    }

    virtual int onGuestRecv(AndroidPipeBuffer* buffers, int numBuffers)
            override {
        DD("%s", __func__);

        // Consume the pipe's dataForReading, then put the next received data piece
        // there. Repeat until the buffers are full or we're out of data
        // in the channel.
        int len = 0;
        size_t buffOffset = 0;

        auto buff = buffers;
        const auto buffEnd = buff + numBuffers;
        while (buff != buffEnd) {
            if (mDataForReadingLeft == 0) {
                // No data left, read a new chunk from the channel.
                //
                // Spin a little bit here: many GL calls are much faster than
                // the whole host-to-guest-to-host transition.
                int spinCount = 20;
                while (!mChannel->read(&mDataForReading,
                                    RenderChannel::CallType::Nonblocking)) {
                    if (mChannel->isStopped()) {
                        return PIPE_ERROR_IO;
                    } else if (len == 0) {
                        if (canRead(mChannel->currentState()) || --spinCount > 0) {
                            continue;
                        }
                        return PIPE_ERROR_AGAIN;
                    } else {
                        return len;
                    }
                }

                mDataForReadingLeft = mDataForReading.size();
            }

            const size_t curSize =
                    std::min(buff->size - buffOffset, mDataForReadingLeft.load());
            memcpy(buff->data + buffOffset,
                mDataForReading.data() +
                        (mDataForReading.size() - mDataForReadingLeft),
                curSize);

            len += curSize;
            mDataForReadingLeft -= curSize;
            buffOffset += curSize;
            if (buffOffset == buff->size) {
                ++buff;
                buffOffset = 0;
            }
        }

        return len;
    }

    virtual int onGuestSend(const AndroidPipeBuffer* buffers,
                            int numBuffers) override {
        DD("%s", __func__);

        if (int ret = sendReadyStatus()) {
            return ret;
        }

        // Count the total bytes to send.
        int count = 0;
        for (int n = 0; n < numBuffers; ++n) {
            count += buffers[n].size;
        }

        // Copy everything into a single ChannelBuffer.
        ChannelBuffer outBuffer;
        outBuffer.resize_noinit(count);
        auto ptr = outBuffer.data();
        for (int n = 0; n < numBuffers; ++n) {
            memcpy(ptr, buffers[n].data, buffers[n].size);
            ptr += buffers[n].size;
        }

        // Send it through the channel.
        if (!mChannel->write(std::move(outBuffer))) {
            return PIPE_ERROR_IO;
        }

        return count;
    }

    virtual void onGuestWantWakeOn(int flags) override {
        DD("%s: flags=%d", __func__, flags);

        // We reset these flags when we actually wake the pipe, so only
        // add to them here.
        mCareAboutRead |= (flags & PIPE_WAKE_READ) != 0;
        mCareAboutWrite |= (flags & PIPE_WAKE_WRITE) != 0;

        ChannelState state = mChannel->currentState();
        processIoEvents(state);
    }

private:
    // Returns true iff there is data to read from the emugl channel.
    static bool canRead(ChannelState state) {
        return (state & ChannelState::CanRead) != ChannelState::Empty;
    }

    // Returns true iff the emugl channel can accept data.
    static bool canWrite(ChannelState state) {
        return (state & ChannelState::CanWrite) != ChannelState::Empty;
    }

    // Returns true iff there is data to read from the local cache or from
    // the emugl channel.
    bool canReadAny(ChannelState state) const {
        return mDataForReadingLeft != 0 || canRead(state);
    }

    // Check that the pipe is working and that the render channel can be
    // written to. Return 0 in case of success, and one PIPE_ERROR_XXX
    // value on error.
    int sendReadyStatus() const {
        if (mIsWorking) {
            ChannelState state = mChannel->currentState();
            if (canWrite(state)) {
                return 0;
            }
            return PIPE_ERROR_AGAIN;
        } else if (!mHwPipe) {
            return PIPE_ERROR_IO;
        } else {
            return PIPE_ERROR_INVAL;
        }
    }

    // Check the read/write state of the render channel and signal the pipe
    // if any condition meets mCareAboutRead or mCareAboutWrite.
    void processIoEvents(ChannelState state) {
        int wakeFlags = 0;

        if (mCareAboutRead && canReadAny(state)) {
            wakeFlags |= PIPE_WAKE_READ;
            mCareAboutRead = false;
        }
        if (mCareAboutWrite && canWrite(state)) {
            wakeFlags |= PIPE_WAKE_WRITE;
            mCareAboutWrite = false;
        }

        // Send wake signal to the guest if needed.
        if (wakeFlags != 0) {
            signalWake(wakeFlags);
        }
    }

    // Called when an i/o event occurs on the render channel
    void onChannelIoEvent(ChannelState state) {
        D("%s: %d", __func__, (int)state);

        if ((state & ChannelState::Stopped) != ChannelState::Empty) {
            close();
        } else {
            processIoEvents(state);
        }
    }

    // Close the pipe, this may be called from the host or guest side.
    void close() {
        D("%s", __func__);

        // If the pipe isn't in a working state, delete immediately.
        if (!mIsWorking) {
            mChannel->stop();
            delete this;
            return;
        }

        // Force the closure of the channel - if a guest is blocked
        // waiting for a wake signal, it will receive an error.
        if (mHwPipe) {
            closeFromHost();
            mHwPipe = nullptr;
        }

        mIsWorking = false;
    }

    // A RenderChannel pointer used for communication.
    RenderChannelPtr mChannel;

    // Guest state tracking - if it requested us to wake on read/write
    // availability. If guest doesn't care about some operation type, we should
    // not wake it when that operation becomes available.
    // Note: we need an atomic or operation, and atomic<bool> doesn't have it -
    //  that's why it is atomic<char> here.
    std::atomic<char> mCareAboutRead {false};
    std::atomic<char> mCareAboutWrite {false};

    // Set to |true| if the pipe is in working state, |false| means we're not
    // initialized or the pipe is closed.
    bool mIsWorking = false;

    // These two variables serve as a reading buffer for the guest.
    // Each time we get a read request, first we extract a single chunk from
    // the |mChannel| into here, and then copy its content into the
    // guest-supplied memory.
    // If guest didn't have enough room for the whole buffer, we track the
    // number of remaining bytes in |mDataForReadingLeft| for the next read().
    ChannelBuffer mDataForReading;
    std::atomic<size_t> mDataForReadingLeft { 0 };

    DISALLOW_COPY_ASSIGN_AND_MOVE(EmuglPipe);
};

}  // namespace

void registerPipeService() {
    android::AndroidPipe::Service::add(new EmuglPipe::Service());
    registerGLProcessPipeService();
}

}  // namespace opengl
}  // namespace android

// Declared in android/opengles-pipe.h
void android_init_opengles_pipe() {
    android::opengl::registerPipeService();
}
