/*
 * Copyright (C) 2018 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 "VirtioGpuStream.h"

#include <cros_gralloc_handle.h>
#include <drm/virtgpu_drm.h>
#include <xf86drm.h>

#include <sys/types.h>
#include <sys/mman.h>

#include <errno.h>
#include <unistd.h>

#ifndef PAGE_SIZE
#define PAGE_SIZE 0x1000
#endif

// In a virtual machine, there should only be one GPU
#define RENDERNODE_MINOR 128

// Maximum size of readback / response buffer in bytes
#define MAX_CMDRESPBUF_SIZE (10*PAGE_SIZE)

// Attributes use to allocate our response buffer
// Similar to virgl's fence objects
#define PIPE_BUFFER             0
#define VIRGL_FORMAT_R8_UNORM   64
#define VIRGL_BIND_CUSTOM       (1 << 17)

// Conservative; see virgl_winsys.h
#define VIRGL_MAX_CMDBUF_DWORDS (16*1024)
#define VIRGL_MAX_CMDBUF_SIZE   (4*VIRGL_MAX_CMDBUF_DWORDS)

struct VirtioGpuCmd {
    uint32_t op;
    uint32_t cmdSize;
    unsigned char buf[0];
} __attribute__((packed));

uint32_t CrosGralloc::getHostHandle(native_handle_t const* handle_)
{
    uint32_t id = 0;

    if (m_fd >= 0) {
        cros_gralloc_handle const* handle =
          reinterpret_cast<cros_gralloc_handle const*>(handle_);
        drmPrimeFDToHandle(m_fd, handle->fds[0], &id);
    }

    return id;
}

int CrosGralloc::getFormat(native_handle_t const* handle)
{
    return ((cros_gralloc_handle *)handle)->droid_format;
}

bool VirtioGpuProcessPipe::processPipeInit(renderControl_encoder_context_t *rcEnc)
{
  union {
      uint64_t proto;
      struct {
          int pid;
          int tid;
      } id;
  } puid = {
      .id.pid = getpid(),
      .id.tid = gettid(),
  };
  rcEnc->rcSetPuid(rcEnc, puid.proto);
  return true;
}

VirtioGpuStream::VirtioGpuStream(size_t bufSize) :
    IOStream(0U),
    m_fd(-1),
    m_bufSize(bufSize),
    m_buf(nullptr),
    m_cmdResp_rh(0U),
    m_cmdResp_bo(0U),
    m_cmdResp(nullptr),
    m_cmdRespPos(0U),
    m_cmdPos(0U),
    m_flushPos(0U),
    m_allocSize(0U),
    m_allocFlushSize(0U)
{
}

VirtioGpuStream::~VirtioGpuStream()
{
    if (m_cmdResp) {
        munmap(m_cmdResp, MAX_CMDRESPBUF_SIZE);
    }

    if (m_cmdResp_bo > 0U) {
        drm_gem_close gem_close = {
            .handle = m_cmdResp_bo,
        };
        drmIoctl(m_fd, DRM_IOCTL_GEM_CLOSE, &gem_close);
    }

    if (m_fd >= 0) {
        close(m_fd);
    }

    free(m_buf);
}

int VirtioGpuStream::connect()
{
    if (m_fd < 0) {
        m_fd = drmOpenRender(RENDERNODE_MINOR);
        if (m_fd < 0) {
            ERR("%s: failed with fd %d (%s)", __func__, m_fd, strerror(errno));
            return -1;
        }
    }

    if (!m_cmdResp_bo) {
        drm_virtgpu_resource_create create = {
            .target     = PIPE_BUFFER,
            .format     = VIRGL_FORMAT_R8_UNORM,
            .bind       = VIRGL_BIND_CUSTOM,
            .width      = MAX_CMDRESPBUF_SIZE,
            .height     = 1U,
            .depth      = 1U,
            .array_size = 0U,
            .size       = MAX_CMDRESPBUF_SIZE,
            .stride     = MAX_CMDRESPBUF_SIZE,
        };
        int ret = drmIoctl(m_fd, DRM_IOCTL_VIRTGPU_RESOURCE_CREATE, &create);
        if (ret) {
            ERR("%s: failed with %d allocating command response buffer (%s)",
                __func__, ret, strerror(errno));
            return -1;
        }
        m_cmdResp_bo = create.bo_handle;
        if (!m_cmdResp_bo) {
            ERR("%s: no handle when allocating command response buffer",
                __func__);
            return -1;
        }
        m_cmdResp_rh = create.res_handle;
        if (create.size != MAX_CMDRESPBUF_SIZE) {
	    ERR("%s: command response buffer wrongly sized, create.size=%zu "
		"!= %zu", __func__,
		static_cast<size_t>(create.size),
		static_cast<size_t>(MAX_CMDRESPBUF_SIZE));
	    abort();
	}
    }

    if (!m_cmdResp) {
        drm_virtgpu_map map = {
            .handle = m_cmdResp_bo,
        };
        int ret = drmIoctl(m_fd, DRM_IOCTL_VIRTGPU_MAP, &map);
        if (ret) {
            ERR("%s: failed with %d mapping command response buffer (%s)",
                __func__, ret, strerror(errno));
            return -1;
        }
        m_cmdResp = static_cast<VirtioGpuCmd *>(mmap64(nullptr,
                                                       MAX_CMDRESPBUF_SIZE,
                                                       PROT_READ, MAP_SHARED,
                                                       m_fd, map.offset));
        if (m_cmdResp == MAP_FAILED) {
            ERR("%s: failed with %d mmap'ing command response buffer (%s)",
                __func__, ret, strerror(errno));
            return -1;
        }
    }

    m_gralloc.setFd(m_fd);
    return 0;
}

int VirtioGpuStream::flush()
{
    int ret = commitBuffer(m_allocSize - m_allocFlushSize);
    if (ret)
        return ret;
    m_allocFlushSize = m_allocSize;
    return 0;
}

void *VirtioGpuStream::allocBuffer(size_t minSize)
{
    if (m_buf) {
        // Try to model the alloc() calls being made by the user. They should be
        // obeying the protocol and using alloc() for anything they don't write
        // with writeFully(), so we can know if this alloc() is for part of a
        // command, or not. If it is not for part of a command, we are starting
        // a new command, and should increment m_cmdPos.
        VirtioGpuCmd *cmd = reinterpret_cast<VirtioGpuCmd *>(&m_buf[m_cmdPos]);
        if (m_allocSize + minSize > cmd->cmdSize) {
            m_allocFlushSize = 0U;
            m_allocSize = 0U;
            // This might also be a convenient point to flush commands
            if (m_cmdPos + cmd->cmdSize + minSize > m_bufSize) {
                if (commitAll() < 0) {
                    ERR("%s: command flush failed", __func__);
                    m_flushPos = 0U;
                    m_bufSize = 0U;
                    m_cmdPos = 0U;
                    free(m_buf);
                    m_buf = nullptr;
                    return nullptr;
                }
            } else {
                m_cmdPos += cmd->cmdSize;
                m_flushPos = m_cmdPos;
            }
        }
    }

    // Update m_allocSize here, before minSize is tampered with below
    m_allocSize += minSize;

    // Make sure anything we already have written to the buffer is retained
    minSize += m_flushPos;

    size_t allocSize = (m_bufSize < minSize ? minSize : m_bufSize);
    if (!m_buf) {
        m_buf = static_cast<unsigned char *>(malloc(allocSize));
    } else if (m_bufSize < allocSize) {
        unsigned char *p = static_cast<unsigned char *>(realloc(m_buf, allocSize));
        if (!p) {
            free(m_buf);
        }
        m_buf = p;
    }
    if (!m_buf) {
        ERR("%s: alloc (%zu) failed\n", __func__, allocSize);
        m_allocFlushSize = 0U;
        m_allocSize = 0U;
        m_flushPos = 0U;
        m_bufSize = 0U;
        m_cmdPos = 0U;
    } else {
        m_bufSize = allocSize;
    }
    if (m_flushPos == 0 && m_cmdPos == 0) {
      // During initialization, HostConnection will send an empty command
      // packet to check the connection is good, but it doesn't obey the usual
      // line protocol. This is a 4 byte write to [0], which is our 'op' field,
      // and we don't have an op=0 so it's OK. We fake up a valid length, and
      // overload this workaround by putting the res_handle for the readback
      // buffer in the command payload, patched in just before we submit.
      VirtioGpuCmd *cmd = reinterpret_cast<VirtioGpuCmd *>(&m_buf[m_cmdPos]);
      cmd->op = 0U;
      cmd->cmdSize = sizeof(*cmd) + sizeof(__u32);
    }
    return m_buf + m_cmdPos;
}

// For us, writeFully() means to write a command without any header, directly
// into the buffer stream. We can use the packet frame written directly to the
// stream to verify this write is within bounds, then update the counter.

int VirtioGpuStream::writeFully(const void *buf, size_t len)
{
    if (!valid())
        return -1;

    if (!buf) {
        if (len > 0) {
            // If len is non-zero, buf must not be NULL. Otherwise the pipe would
            // be in a corrupted state, which is lethal for the emulator.
            ERR("%s: failed, buf=NULL, len %zu, lethal error, exiting",
                __func__, len);
            abort();
        }
        return 0;
    }

    VirtioGpuCmd *cmd = reinterpret_cast<VirtioGpuCmd *>(&m_buf[m_cmdPos]);

    if (m_flushPos < sizeof(*cmd)) {
        ERR("%s: writeFully len %zu would overwrite command header, "
            "cmd_pos=%zu, flush_pos=%zu, lethal error, exiting", __func__,
            len, m_cmdPos, m_flushPos);
        abort();
    }

    if (m_flushPos + len > cmd->cmdSize) {
        ERR("%s: writeFully len %zu would overflow the command bounds, "
            "cmd_pos=%zu, flush_pos=%zu, cmdsize=%zu, lethal error, exiting",
            __func__, len, m_cmdPos, m_flushPos, cmd->cmdSize);
        abort();
    }

    if (len > VIRGL_MAX_CMDBUF_SIZE) {
        ERR("%s: Large command (%zu bytes) exceeds virgl limits",
            __func__, len);
        /* Fall through */
    }

    memcpy(&m_buf[m_flushPos], buf, len);
    commitBuffer(len);
    m_allocSize += len;
    return 0;
}

const unsigned char *VirtioGpuStream::readFully(void *buf, size_t len)
{
    if (!valid())
        return nullptr;

    if (!buf) {
        if (len > 0) {
            // If len is non-zero, buf must not be NULL. Otherwise the pipe would
            // be in a corrupted state, which is lethal for the emulator.
            ERR("%s: failed, buf=NULL, len %zu, lethal error, exiting.",
                __func__, len);
            abort();
        }
        return nullptr;
    }

    // Read is too big for current architecture
    if (len > MAX_CMDRESPBUF_SIZE - sizeof(*m_cmdResp)) {
        ERR("%s: failed, read too large, len %zu, lethal error, exiting.",
            __func__, len);
        abort();
    }

    // Commit all outstanding write commands (if any)
    if (commitAll() < 0) {
        ERR("%s: command flush failed", __func__);
        return nullptr;
    }

    if (len > 0U && m_cmdRespPos == 0U) {
        // When we are about to read for the first time, wait for the virtqueue
        // to drain to this command, otherwise the data could be stale
        drm_virtgpu_3d_wait wait = {
            .handle = m_cmdResp_bo,
        };
        int ret = drmIoctl(m_fd, DRM_IOCTL_VIRTGPU_WAIT, &wait);
        if (ret) {
            ERR("%s: failed with %d waiting for response buffer (%s)",
                __func__, ret, strerror(errno));
            // Fall through, hope for the best
        }
    }

    // Most likely a protocol implementation error
    if (m_cmdResp->cmdSize - sizeof(*m_cmdResp) < m_cmdRespPos + len) {
        ERR("%s: failed, op %zu, len %zu, cmdSize %zu, pos %zu, lethal "
            "error, exiting.", __func__, m_cmdResp->op, len,
            m_cmdResp->cmdSize, m_cmdRespPos);
        abort();
    }

    memcpy(buf, &m_cmdResp->buf[m_cmdRespPos], len);

    if (m_cmdRespPos + len == m_cmdResp->cmdSize - sizeof(*m_cmdResp)) {
        m_cmdRespPos = 0U;
    } else {
        m_cmdRespPos += len;
    }

    return reinterpret_cast<const unsigned char *>(buf);
}

int VirtioGpuStream::commitBuffer(size_t size)
{
    if (m_flushPos + size > m_bufSize) {
        ERR("%s: illegal commit size %zu, flushPos %zu, bufSize %zu",
            __func__, size, m_flushPos, m_bufSize);
        return -1;
    }
    m_flushPos += size;
    return 0;
}

int VirtioGpuStream::commitAll()
{
    size_t pos = 0U, numFlushed = 0U;
    while (pos < m_flushPos) {
        VirtioGpuCmd *cmd = reinterpret_cast<VirtioGpuCmd *>(&m_buf[pos]);

        // Should never happen
        if (pos + cmd->cmdSize > m_bufSize) {
            ERR("%s: failed, pos %zu, cmdSize %zu, bufSize %zu, lethal "
                "error, exiting.", __func__, pos, cmd->cmdSize, m_bufSize);
            abort();
        }

        // Saw dummy command; patch it with res handle
        if (cmd->op == 0) {
            *(uint32_t *)cmd->buf = m_cmdResp_rh;
        }

        // Flush a single command
        drm_virtgpu_execbuffer execbuffer = {
            .size           = cmd->cmdSize,
            .command        = reinterpret_cast<__u64>(cmd),
            .bo_handles     = reinterpret_cast<__u64>(&m_cmdResp_bo),
            .num_bo_handles = 1U,
        };
        int ret = drmIoctl(m_fd, DRM_IOCTL_VIRTGPU_EXECBUFFER, &execbuffer);
        if (ret) {
            ERR("%s: failed with %d executing command buffer (%s)",  __func__,
                ret, strerror(errno));
            return -1;
        }

        pos += cmd->cmdSize;
        numFlushed++;
    }

    if (pos > m_flushPos) {
        ERR("%s: aliasing, flushPos %zu, pos %zu, probably ok", __func__,
            m_flushPos, pos);
        /* Fall through */
    }

    m_flushPos = 0U;
    m_cmdPos = 0U;
    return 0;
}
