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

#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__
