22c04190c6
This patch moves away from using M5_ATTR_OVERRIDE and the m5::hashmap (and similar) abstractions, as these are no longer needed with gcc 4.7 and clang 3.1 as minimum compiler versions.
313 lines
9.9 KiB
C++
313 lines
9.9 KiB
C++
/*
|
|
* Copyright (c) 2015 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
|
|
/** Starting pushing pixels using the supplied display timings. */
|
|
void start(const DisplayTimings &timings);
|
|
|
|
/** 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();
|
|
|
|
/** 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__
|