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

#ifndef __DEV_PIXELPUMP_HH__
#define __DEV_PIXELPUMP_HH__

#include "base/framebuffer.hh"
#include "sim/clocked_object.hh"

struct BasePixelPumpParams;

struct DisplayTimings : public Serializable
{
    /**
     * Create a display timing configuration struct
     *
     * @param width Width of the visible area of the screen.
     * @param height Height of the visible area of the screen.
     * @param hfp Horizontal front porch in pixel clocks.
     * @param h_sync Horizontal sync in pixel clocks.
     * @param hbp Horizontal back porch in pixel clocks.
     * @param vfp Vertical front porch in scan lines.
     * @param v_sync Vertical sync in scan lines.
     * @param vbp Vertical back porch in scan lines.
     */
    DisplayTimings(unsigned width, unsigned height,
                   unsigned hbp, unsigned h_sync, unsigned hfp,
                   unsigned vbp, unsigned v_sync, unsigned vfp);

    void serialize(CheckpointOut &cp) const override;
    void unserialize(CheckpointIn &cp) override;

    /** How many pixel clocks are required for one line? */
    Cycles cyclesPerLine() const {
        return Cycles(hSync + hBackPorch +  width + hBackPorch);
    }

    /** How many pixel clocks are required for one frame? */
    Cycles cyclesPerFrame() const {
        return Cycles(cyclesPerLine() * linesPerFrame());
    }

    /** Calculate the first line of the vsync signal */
    unsigned lineVSyncStart() const {
        return 0;
    }

    /** Calculate the first line of the vertical back porch */
    unsigned lineVBackPorchStart() const {
        return lineVSyncStart() + vSync;
    }

    /** Calculate the first line of the visible region */
    unsigned lineFirstVisible() const {
        return lineVBackPorchStart() + vBackPorch;
    }

    /** Calculate the first line of the back porch */
    unsigned lineFrontPorchStart() const {
        return lineFirstVisible() + height;
    }

    /** Calculate the total number of lines in a frame */
    unsigned linesPerFrame() const {
        return lineFrontPorchStart() + vFrontPorch;
    }

    /** Display width in pixels */
    unsigned width;
    /** Display height in pixels */
    unsigned height;

    /** Horizontal back porch in pixels */
    unsigned hBackPorch;
    /** Horizontal front porch in pixels */
    unsigned hFrontPorch;
    /** Horizontal sync signal length in pixels */
    unsigned hSync;

    /** Vertical back porch in lines */
    unsigned vBackPorch;
    /** Vertical front porch in lines */
    unsigned vFrontPorch;
    /** Vertical sync signal in lines */
    unsigned vSync;

    static const DisplayTimings vga;
};

/**
 * Timing generator for a pixel-based display.
 *
 * Pixels are ordered relative to the top left corner of the
 * display. Scan lines appear in the following order:
 * <ol>
 *   <li>Vertical Sync (starting at line 0)
 *   <li>Vertical back porch
 *   <li>Visible lines
 *   <li>Vertical front porch
 * </ol>
 *
 * Pixel order within a scan line:
 * <ol>
 *   <li>Horizontal Sync
 *   <li>Horizontal Back Porch
 *   <li>Visible pixels
 *   <li>Horizontal Front Porch
 * </ol>
 */
class BasePixelPump
    : public EventManager, public Clocked,
      public Serializable
{
  public:
    BasePixelPump(EventManager &em, ClockDomain &pxl_clk,
                  unsigned pixel_chunk);
    virtual ~BasePixelPump();

    void serialize(CheckpointOut &cp) const override;
    void unserialize(CheckpointIn &cp) override;

  public: // Public API
    /** Update frame size using display timing */
    void updateTimings(const DisplayTimings &timings);

    /** Render an entire frame in KVM execution mode */
    void renderFrame();

    /** Starting pushing pixels in timing mode */
    void start();

    /** Immediately stop pushing pixels */
    void stop();

    /** Get a constant reference of the current display timings */
    const DisplayTimings &timings() const { return _timings; }

    /** Is the pixel pump active and refreshing the display? */
    bool active() const { return evBeginLine.active(); }

    /** Did a buffer underrun occur within this refresh interval? */
    bool underrun() const { return _underrun; }

    /** Is the current line within the visible range? */
    bool visibleLine() const {
        return line >= _timings.lineFirstVisible() &&
            line < _timings.lineFrontPorchStart();
    }

    /** Current pixel position within the visible area */
    unsigned posX() const { return _posX; }

    /** Current pixel position within the visible area */
    unsigned posY() const {
        return visibleLine() ? line - _timings.lineFirstVisible() : 0;
    }

    /** Output frame buffer */
    FrameBuffer fb;

  protected: // Callbacks
    /**
     * Get the next pixel from the scan line buffer.
     *
     * @param p Output pixel value, undefined on underrun
     * @return true on success, false on buffer underrun
     */
    virtual bool nextPixel(Pixel &p) = 0;

    /** First pixel clock of the first VSync line. */
    virtual void onVSyncBegin() {};

    /**
     * Callback on the first pixel of the line after the end VSync
     * region (typically the first pixel of the vertical back porch).
     */
    virtual void onVSyncEnd() {};

    /**
     * Start of the HSync region.
     *
     * @note This is called even for scan lines outside of the visible
     * region.
     */
    virtual void onHSyncBegin() {};

    /**
     * Start of the first pixel after the HSync region.
     *
     * @note This is called even for scan lines outside of the visible
     * region.
     */
    virtual void onHSyncEnd() {};

    /**
     * Buffer underrun occurred on a frame.
     *
     * This method is called once if there is buffer underrun while
     * refreshing the display. The underrun state is reset on the next
     * refresh.
     *
     * @param x Coordinate within the visible region.
     * @param y Coordinate within the visible region.
     */
    virtual void onUnderrun(unsigned x, unsigned y) {};

    /** Finished displaying the visible region of a frame */
    virtual void onFrameDone() {};

  private: // Params
    /** Maximum number of pixels to handle per render callback */
    const unsigned pixelChunk;

  private:
    /**
     * Callback helper class with suspend support.
     *
     * Unlike a normal EventWrapper, this class suspends an event on
     * drain() and restarts it at drainResume(). The suspend operation
     * stores the tick relative to curTick() and then deschedules the
     * event. The resume operation schedules the event at curTick()
     * plus the relative tick stored when the event was suspended.
     */
    class PixelEvent : public Event, public Drainable
    {
        typedef void (BasePixelPump::* CallbackType)();

      public:
        PixelEvent(const char *name, BasePixelPump *parent, CallbackType func);

        DrainState drain() override;
        void drainResume() override;

        void serialize(CheckpointOut &cp) const override;
        void unserialize(CheckpointIn &cp) override;

        const std::string name() const override { return _name; }
        void process() override {
            (parent.*func)();
        }

        bool active() const { return scheduled() || suspended; }

      private:
        void suspend();
        void resume();

        const std::string _name;
        BasePixelPump &parent;
        const CallbackType func;

        bool suspended;
        Tick relativeTick;
    };

    void beginLine();
    void renderPixels();

    /** Fast and event-free line rendering function */
    void renderLine();

    /** Convenience vector when doing operations on all events */
    std::vector<PixelEvent *> pixelEvents;

    PixelEvent evVSyncBegin;
    PixelEvent evVSyncEnd;
    PixelEvent evHSyncBegin;
    PixelEvent evHSyncEnd;
    PixelEvent evBeginLine;
    PixelEvent evRenderPixels;

    DisplayTimings _timings;

    /**
     * Current line (including back porch, front porch, and vsync)
     * within a frame.
     */
    unsigned line;
    /** X-coordinate within the visible region of a frame */
    unsigned _posX;

    /** Did a buffer underrun occur within this refresh interval? */
    bool _underrun;
};

#endif // __DEV_PIXELPUMP_HH__
