/*
 * Copyright (c) 2015, 2017 ARM Limited
 * All rights reserved
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "dev/pixelpump.hh"

#include "base/logging.hh"

namespace gem5
{

const DisplayTimings DisplayTimings::vga(
    640, 480,
    48, 96, 16,
    33, 2, 10);


DisplayTimings::DisplayTimings(unsigned _width, unsigned _height,
                               unsigned hbp, unsigned h_sync, unsigned hfp,
                               unsigned vbp, unsigned v_sync, unsigned vfp)
    : width(_width), height(_height),
      hBackPorch(hbp), hFrontPorch(hfp), hSync(h_sync),
      vBackPorch(vbp), vFrontPorch(vfp), vSync(v_sync)
{
}

void
DisplayTimings::serialize(CheckpointOut &cp) const
{
    SERIALIZE_SCALAR(width);
    SERIALIZE_SCALAR(height);

    SERIALIZE_SCALAR(hBackPorch);
    SERIALIZE_SCALAR(hFrontPorch);
    SERIALIZE_SCALAR(hSync);

    SERIALIZE_SCALAR(vBackPorch);
    SERIALIZE_SCALAR(vFrontPorch);
    SERIALIZE_SCALAR(vSync);
}

void
DisplayTimings::unserialize(CheckpointIn &cp)
{
    UNSERIALIZE_SCALAR(width);
    UNSERIALIZE_SCALAR(height);

    UNSERIALIZE_SCALAR(hBackPorch);
    UNSERIALIZE_SCALAR(hFrontPorch);
    UNSERIALIZE_SCALAR(hSync);

    UNSERIALIZE_SCALAR(vBackPorch);
    UNSERIALIZE_SCALAR(vFrontPorch);
    UNSERIALIZE_SCALAR(vSync);
}


BasePixelPump::BasePixelPump(EventManager &em, ClockDomain &pxl_clk,
                             unsigned pixel_chunk)
    : EventManager(em), Clocked(pxl_clk), Serializable(),
      pixelChunk(pixel_chunk),
      pixelEvents(),
      evVSyncBegin("evVSyncBegin", this, &BasePixelPump::onVSyncBegin),
      evVSyncEnd("evVSyncEnd", this, &BasePixelPump::onVSyncEnd),
      evHSyncBegin("evHSyncBegin", this, &BasePixelPump::onHSyncBegin),
      evHSyncEnd("evHSyncEnd", this, &BasePixelPump::onHSyncEnd),
      evBeginLine("evBeginLine", this, &BasePixelPump::beginLine),
      evRenderPixels("evRenderPixels", this, &BasePixelPump::renderPixels),
      _timings(DisplayTimings::vga),
      line(0), _posX(0), _underrun(false)
{
}

BasePixelPump::~BasePixelPump()
{
}

void
BasePixelPump::serialize(CheckpointOut &cp) const
{
    SERIALIZE_SCALAR(line);
    SERIALIZE_SCALAR(_posX);
    SERIALIZE_SCALAR(_underrun);

    SERIALIZE_OBJ(_timings);
    SERIALIZE_OBJ(fb);

    for (PixelEvent *event : pixelEvents)
        event->serializeSection(cp, event->name());
}

void
BasePixelPump::unserialize(CheckpointIn &cp)
{
    UNSERIALIZE_SCALAR(line);
    UNSERIALIZE_SCALAR(_posX);
    UNSERIALIZE_SCALAR(_underrun);

    UNSERIALIZE_OBJ(_timings);
    UNSERIALIZE_OBJ(fb);

    // We don't need to reschedule the event here since the event was
    // suspended by PixelEvent::drain() and will be rescheduled by
    // PixelEvent::drainResume().
    for (PixelEvent *event : pixelEvents)
        event->unserializeSection(cp, event->name());
}

void
BasePixelPump::updateTimings(const DisplayTimings &timings)
{
    panic_if(active(), "Trying to update timings in active PixelPump\n");

    _timings = timings;

    // Resize the frame buffer if needed
    if (_timings.width != fb.width() || _timings.height != fb.height())
        fb.resize(timings.width, timings.height);

    // Set the current line past the last line in the frame. This
    // triggers the new frame logic in beginLine().
    line = _timings.linesPerFrame();
}

void
BasePixelPump::start()
{
    schedule(evBeginLine, clockEdge());
}


void
BasePixelPump::stop()
{
    if (evVSyncEnd.scheduled())
        deschedule(evVSyncEnd);

    if (evHSyncBegin.scheduled())
        deschedule(evHSyncBegin);

    if (evHSyncEnd.scheduled())
        deschedule(evHSyncEnd);

    if (evBeginLine.scheduled())
        deschedule(evBeginLine);

    if (evRenderPixels.scheduled())
        deschedule(evRenderPixels);
}

void
BasePixelPump::beginLine()
{
    _posX = 0;
    line++;
    if (line >= _timings.linesPerFrame()) {
        _underrun = false;
        line = 0;
    }

    if (line == _timings.lineVSyncStart()) {
        onVSyncBegin();
    } else if (line == _timings.lineVBackPorchStart()) {
        onVSyncEnd();
    }

    const Cycles h_sync_begin(0);
    schedule(evHSyncBegin, clockEdge(h_sync_begin));

    const Cycles h_sync_end(h_sync_begin + _timings.hSync);
    schedule(evHSyncEnd, clockEdge(h_sync_end));

    // Visible area
    if (line >= _timings.lineFirstVisible() &&
        line < _timings.lineFrontPorchStart()) {

        const Cycles h_first_visible(h_sync_end + _timings.hBackPorch);
        schedule(evRenderPixels, clockEdge(h_first_visible));
    }

    schedule(evBeginLine, clockEdge(_timings.cyclesPerLine()));
}

void
BasePixelPump::renderPixels()
{
    // Try to handle multiple pixels at a time; doing so reduces the
    // accuracy of the underrun detection but lowers simulation
    // overhead
    const unsigned x_end(std::min(_posX + pixelChunk, _timings.width));
    const unsigned pxl_count(x_end - _posX);
    const unsigned pos_y(posY());

    Pixel pixel(0, 0, 0);
    const Pixel underrun_pixel(0, 0, 0);
    for (; _posX < x_end && !_underrun; ++_posX) {
        if (!nextPixel(pixel)) {
            warn("Input buffer underrun in BasePixelPump (%u, %u)\n",
                 _posX, pos_y);
            _underrun = true;
            onUnderrun(_posX, pos_y);
            pixel = underrun_pixel;
        }
        fb.pixel(_posX, pos_y) = pixel;
    }

    // Fill remaining pixels with a dummy pixel value if we ran out of
    // data
    for (; _posX < x_end; ++_posX)
        fb.pixel(_posX, pos_y) = underrun_pixel;

    // Schedule a new event to handle the next block of pixels
    if (_posX < _timings.width) {
        schedule(evRenderPixels, clockEdge(Cycles(pxl_count)));
    } else {
        if (pos_y == _timings.height - 1)
            onFrameDone();
    }
}

void
BasePixelPump::renderFrame()
{
    _underrun = false;
    line = 0;

    // Signal vsync end and render the frame
    line = _timings.lineVBackPorchStart();
    onVSyncEnd();

    // We only care about the visible screen area when rendering the
    // frame
    for (line = _timings.lineFirstVisible();
        line < _timings.lineFrontPorchStart();
        ++line) {

        _posX = 0;

        onHSyncBegin();
        onHSyncEnd();

        renderLine();
    }

    line = _timings.lineFrontPorchStart() - 1;
    onFrameDone();

    // Signal vsync until the next frame begins
    line = _timings.lineVSyncStart();
    onVSyncBegin();
}

void
BasePixelPump::renderLine()
{
    const unsigned pos_y = posY();
    const size_t _width = fb.width();

    auto pixel_it = fb.pixels.begin() + _width * pos_y;
    panic_if(nextLine(pixel_it, _width) != _width,
            "Unexpected underrun in BasePixelPump (%u, %u)", _width, pos_y);
}


BasePixelPump::PixelEvent::PixelEvent(
    const char *name, BasePixelPump *_parent, CallbackType _func)
    : Event(), Drainable(),
      _name(name), parent(*_parent), func(_func),
      suspended(false),
      relativeTick(0)
{
    parent.pixelEvents.push_back(this);
}

DrainState
BasePixelPump::PixelEvent::drain()
{
    if (scheduled())
        suspend();
    return DrainState::Drained;
}

void
BasePixelPump::PixelEvent::drainResume()
{
    if (suspended)
        resume();
}

void
BasePixelPump::PixelEvent::serialize(CheckpointOut &cp) const
{
    assert(!scheduled());
    Event::serialize(cp);
    SERIALIZE_SCALAR(suspended);
    SERIALIZE_SCALAR(relativeTick);
}

void
BasePixelPump::PixelEvent::unserialize(CheckpointIn &cp)
{
    Event::unserialize(cp);
    UNSERIALIZE_SCALAR(suspended);
    UNSERIALIZE_SCALAR(relativeTick);
    assert(!scheduled());
}

void
BasePixelPump::PixelEvent::suspend()
{
    assert(scheduled());
    assert(!suspended);

    suspended = true;
    relativeTick = when() - curTick();
    parent.deschedule(this);
}

void
BasePixelPump::PixelEvent::resume()
{
    assert(!scheduled());
    assert(suspended);
    parent.schedule(this, relativeTick + curTick());
    suspended = false;
    relativeTick = 0;
}

} // namespace gem5
