/*
 * 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.
 *
 * Authors: Andreas Sandberg
 */

#include "dev/pixelpump.hh"

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());

    Pixel pixel(0, 0, 0);
    for (_posX = 0; _posX < _timings.width; ++_posX) {
        if (!nextPixel(pixel)) {
            panic("Unexpected underrun in BasePixelPump (%u, %u)\n",
                 _posX, pos_y);
        }
        fb.pixel(_posX, pos_y) = pixel;
    }
}


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;
}
