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

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