pixelpump.hh revision 11012
111012Sandreas.sandberg@arm.com/* 211012Sandreas.sandberg@arm.com * Copyright (c) 2015 ARM Limited 311012Sandreas.sandberg@arm.com * All rights reserved 411012Sandreas.sandberg@arm.com * 511012Sandreas.sandberg@arm.com * The license below extends only to copyright in the software and shall 611012Sandreas.sandberg@arm.com * not be construed as granting a license to any other intellectual 711012Sandreas.sandberg@arm.com * property including but not limited to intellectual property relating 811012Sandreas.sandberg@arm.com * to a hardware implementation of the functionality of the software 911012Sandreas.sandberg@arm.com * licensed hereunder. You may use the software subject to the license 1011012Sandreas.sandberg@arm.com * terms below provided that you ensure that this notice is replicated 1111012Sandreas.sandberg@arm.com * unmodified and in its entirety in all distributions of the software, 1211012Sandreas.sandberg@arm.com * modified or unmodified, in source code or in binary form. 1311012Sandreas.sandberg@arm.com * 1411012Sandreas.sandberg@arm.com * Redistribution and use in source and binary forms, with or without 1511012Sandreas.sandberg@arm.com * modification, are permitted provided that the following conditions are 1611012Sandreas.sandberg@arm.com * met: redistributions of source code must retain the above copyright 1711012Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer; 1811012Sandreas.sandberg@arm.com * redistributions in binary form must reproduce the above copyright 1911012Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer in the 2011012Sandreas.sandberg@arm.com * documentation and/or other materials provided with the distribution; 2111012Sandreas.sandberg@arm.com * neither the name of the copyright holders nor the names of its 2211012Sandreas.sandberg@arm.com * contributors may be used to endorse or promote products derived from 2311012Sandreas.sandberg@arm.com * this software without specific prior written permission. 2411012Sandreas.sandberg@arm.com * 2511012Sandreas.sandberg@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2611012Sandreas.sandberg@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2711012Sandreas.sandberg@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2811012Sandreas.sandberg@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2911012Sandreas.sandberg@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 3011012Sandreas.sandberg@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3111012Sandreas.sandberg@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3211012Sandreas.sandberg@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3311012Sandreas.sandberg@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3411012Sandreas.sandberg@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3511012Sandreas.sandberg@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3611012Sandreas.sandberg@arm.com * 3711012Sandreas.sandberg@arm.com * Authors: Andreas Sandberg 3811012Sandreas.sandberg@arm.com */ 3911012Sandreas.sandberg@arm.com 4011012Sandreas.sandberg@arm.com#ifndef __DEV_PIXELPUMP_HH__ 4111012Sandreas.sandberg@arm.com#define __DEV_PIXELPUMP_HH__ 4211012Sandreas.sandberg@arm.com 4311012Sandreas.sandberg@arm.com#include "base/framebuffer.hh" 4411012Sandreas.sandberg@arm.com#include "sim/clocked_object.hh" 4511012Sandreas.sandberg@arm.com 4611012Sandreas.sandberg@arm.comstruct BasePixelPumpParams; 4711012Sandreas.sandberg@arm.com 4811012Sandreas.sandberg@arm.comstruct DisplayTimings : public Serializable 4911012Sandreas.sandberg@arm.com{ 5011012Sandreas.sandberg@arm.com /** 5111012Sandreas.sandberg@arm.com * Create a display timing configuration struct 5211012Sandreas.sandberg@arm.com * 5311012Sandreas.sandberg@arm.com * @param width Width of the visible area of the screen. 5411012Sandreas.sandberg@arm.com * @param height Height of the visible area of the screen. 5511012Sandreas.sandberg@arm.com * @param hfp Horizontal front porch in pixel clocks. 5611012Sandreas.sandberg@arm.com * @param h_sync Horizontal sync in pixel clocks. 5711012Sandreas.sandberg@arm.com * @param hbp Horizontal back porch in pixel clocks. 5811012Sandreas.sandberg@arm.com * @param vfp Vertical front porch in scan lines. 5911012Sandreas.sandberg@arm.com * @param v_sync Vertical sync in scan lines. 6011012Sandreas.sandberg@arm.com * @param vbp Vertical back porch in scan lines. 6111012Sandreas.sandberg@arm.com */ 6211012Sandreas.sandberg@arm.com DisplayTimings(unsigned width, unsigned height, 6311012Sandreas.sandberg@arm.com unsigned hbp, unsigned h_sync, unsigned hfp, 6411012Sandreas.sandberg@arm.com unsigned vbp, unsigned v_sync, unsigned vfp); 6511012Sandreas.sandberg@arm.com 6611012Sandreas.sandberg@arm.com void serialize(CheckpointOut &cp) const M5_ATTR_OVERRIDE; 6711012Sandreas.sandberg@arm.com void unserialize(CheckpointIn &cp) M5_ATTR_OVERRIDE; 6811012Sandreas.sandberg@arm.com 6911012Sandreas.sandberg@arm.com /** How many pixel clocks are required for one line? */ 7011012Sandreas.sandberg@arm.com Cycles cyclesPerLine() const { 7111012Sandreas.sandberg@arm.com return Cycles(hSync + hBackPorch + width + hBackPorch); 7211012Sandreas.sandberg@arm.com } 7311012Sandreas.sandberg@arm.com 7411012Sandreas.sandberg@arm.com /** How many pixel clocks are required for one frame? */ 7511012Sandreas.sandberg@arm.com Cycles cyclesPerFrame() const { 7611012Sandreas.sandberg@arm.com return Cycles(cyclesPerLine() * linesPerFrame()); 7711012Sandreas.sandberg@arm.com } 7811012Sandreas.sandberg@arm.com 7911012Sandreas.sandberg@arm.com /** Calculate the first line of the vsync signal */ 8011012Sandreas.sandberg@arm.com unsigned lineVSyncStart() const { 8111012Sandreas.sandberg@arm.com return 0; 8211012Sandreas.sandberg@arm.com } 8311012Sandreas.sandberg@arm.com 8411012Sandreas.sandberg@arm.com /** Calculate the first line of the vertical back porch */ 8511012Sandreas.sandberg@arm.com unsigned lineVBackPorchStart() const { 8611012Sandreas.sandberg@arm.com return lineVSyncStart() + vSync; 8711012Sandreas.sandberg@arm.com } 8811012Sandreas.sandberg@arm.com 8911012Sandreas.sandberg@arm.com /** Calculate the first line of the visible region */ 9011012Sandreas.sandberg@arm.com unsigned lineFirstVisible() const { 9111012Sandreas.sandberg@arm.com return lineVBackPorchStart() + vBackPorch; 9211012Sandreas.sandberg@arm.com } 9311012Sandreas.sandberg@arm.com 9411012Sandreas.sandberg@arm.com /** Calculate the first line of the back porch */ 9511012Sandreas.sandberg@arm.com unsigned lineFrontPorchStart() const { 9611012Sandreas.sandberg@arm.com return lineFirstVisible() + height; 9711012Sandreas.sandberg@arm.com } 9811012Sandreas.sandberg@arm.com 9911012Sandreas.sandberg@arm.com /** Calculate the total number of lines in a frame */ 10011012Sandreas.sandberg@arm.com unsigned linesPerFrame() const { 10111012Sandreas.sandberg@arm.com return lineFrontPorchStart() + vFrontPorch; 10211012Sandreas.sandberg@arm.com } 10311012Sandreas.sandberg@arm.com 10411012Sandreas.sandberg@arm.com /** Display width in pixels */ 10511012Sandreas.sandberg@arm.com unsigned width; 10611012Sandreas.sandberg@arm.com /** Display height in pixels */ 10711012Sandreas.sandberg@arm.com unsigned height; 10811012Sandreas.sandberg@arm.com 10911012Sandreas.sandberg@arm.com /** Horizontal back porch in pixels */ 11011012Sandreas.sandberg@arm.com unsigned hBackPorch; 11111012Sandreas.sandberg@arm.com /** Horizontal front porch in pixels */ 11211012Sandreas.sandberg@arm.com unsigned hFrontPorch; 11311012Sandreas.sandberg@arm.com /** Horizontal sync signal length in pixels */ 11411012Sandreas.sandberg@arm.com unsigned hSync; 11511012Sandreas.sandberg@arm.com 11611012Sandreas.sandberg@arm.com /** Vertical back porch in lines */ 11711012Sandreas.sandberg@arm.com unsigned vBackPorch; 11811012Sandreas.sandberg@arm.com /** Vertical front porch in lines */ 11911012Sandreas.sandberg@arm.com unsigned vFrontPorch; 12011012Sandreas.sandberg@arm.com /** Vertical sync signal in lines */ 12111012Sandreas.sandberg@arm.com unsigned vSync; 12211012Sandreas.sandberg@arm.com 12311012Sandreas.sandberg@arm.com static const DisplayTimings vga; 12411012Sandreas.sandberg@arm.com}; 12511012Sandreas.sandberg@arm.com 12611012Sandreas.sandberg@arm.com/** 12711012Sandreas.sandberg@arm.com * Timing generator for a pixel-based display. 12811012Sandreas.sandberg@arm.com * 12911012Sandreas.sandberg@arm.com * Pixels are ordered relative to the top left corner of the 13011012Sandreas.sandberg@arm.com * display. Scan lines appear in the following order: 13111012Sandreas.sandberg@arm.com * <ol> 13211012Sandreas.sandberg@arm.com * <li>Vertical Sync (starting at line 0) 13311012Sandreas.sandberg@arm.com * <li>Vertical back porch 13411012Sandreas.sandberg@arm.com * <li>Visible lines 13511012Sandreas.sandberg@arm.com * <li>Vertical front porch 13611012Sandreas.sandberg@arm.com * </ol> 13711012Sandreas.sandberg@arm.com * 13811012Sandreas.sandberg@arm.com * Pixel order within a scan line: 13911012Sandreas.sandberg@arm.com * <ol> 14011012Sandreas.sandberg@arm.com * <li>Horizontal Sync 14111012Sandreas.sandberg@arm.com * <li>Horizontal Back Porch 14211012Sandreas.sandberg@arm.com * <li>Visible pixels 14311012Sandreas.sandberg@arm.com * <li>Horizontal Front Porch 14411012Sandreas.sandberg@arm.com * </ol> 14511012Sandreas.sandberg@arm.com */ 14611012Sandreas.sandberg@arm.comclass BasePixelPump 14711012Sandreas.sandberg@arm.com : public EventManager, public Clocked, 14811012Sandreas.sandberg@arm.com public Serializable 14911012Sandreas.sandberg@arm.com{ 15011012Sandreas.sandberg@arm.com public: 15111012Sandreas.sandberg@arm.com BasePixelPump(EventManager &em, ClockDomain &pxl_clk, unsigned pixel_chunk); 15211012Sandreas.sandberg@arm.com virtual ~BasePixelPump(); 15311012Sandreas.sandberg@arm.com 15411012Sandreas.sandberg@arm.com void serialize(CheckpointOut &cp) const M5_ATTR_OVERRIDE; 15511012Sandreas.sandberg@arm.com void unserialize(CheckpointIn &cp) M5_ATTR_OVERRIDE; 15611012Sandreas.sandberg@arm.com 15711012Sandreas.sandberg@arm.com public: // Public API 15811012Sandreas.sandberg@arm.com /** Starting pushing pixels using the supplied display timings. */ 15911012Sandreas.sandberg@arm.com void start(const DisplayTimings &timings); 16011012Sandreas.sandberg@arm.com 16111012Sandreas.sandberg@arm.com /** Immediately stop pushing pixels */ 16211012Sandreas.sandberg@arm.com void stop(); 16311012Sandreas.sandberg@arm.com 16411012Sandreas.sandberg@arm.com /** Get a constant reference of the current display timings */ 16511012Sandreas.sandberg@arm.com const DisplayTimings &timings() const { return _timings; } 16611012Sandreas.sandberg@arm.com 16711012Sandreas.sandberg@arm.com /** Is the pixel pump active and refreshing the display? */ 16811012Sandreas.sandberg@arm.com bool active() const { return evBeginLine.active(); } 16911012Sandreas.sandberg@arm.com 17011012Sandreas.sandberg@arm.com /** Did a buffer underrun occur within this refresh interval? */ 17111012Sandreas.sandberg@arm.com bool underrun() const { return _underrun; } 17211012Sandreas.sandberg@arm.com 17311012Sandreas.sandberg@arm.com /** Is the current line within the visible range? */ 17411012Sandreas.sandberg@arm.com bool visibleLine() const { 17511012Sandreas.sandberg@arm.com return line >= _timings.lineFirstVisible() && 17611012Sandreas.sandberg@arm.com line < _timings.lineFrontPorchStart(); 17711012Sandreas.sandberg@arm.com } 17811012Sandreas.sandberg@arm.com 17911012Sandreas.sandberg@arm.com /** Current pixel position within the visible area */ 18011012Sandreas.sandberg@arm.com unsigned posX() const { return _posX; } 18111012Sandreas.sandberg@arm.com 18211012Sandreas.sandberg@arm.com /** Current pixel position within the visible area */ 18311012Sandreas.sandberg@arm.com unsigned posY() const { 18411012Sandreas.sandberg@arm.com return visibleLine() ? line - _timings.lineFirstVisible() : 0; 18511012Sandreas.sandberg@arm.com } 18611012Sandreas.sandberg@arm.com 18711012Sandreas.sandberg@arm.com /** Output frame buffer */ 18811012Sandreas.sandberg@arm.com FrameBuffer fb; 18911012Sandreas.sandberg@arm.com 19011012Sandreas.sandberg@arm.com protected: // Callbacks 19111012Sandreas.sandberg@arm.com /** 19211012Sandreas.sandberg@arm.com * Get the next pixel from the scan line buffer. 19311012Sandreas.sandberg@arm.com * 19411012Sandreas.sandberg@arm.com * @param p Output pixel value, undefined on underrun 19511012Sandreas.sandberg@arm.com * @return true on success, false on buffer underrun 19611012Sandreas.sandberg@arm.com */ 19711012Sandreas.sandberg@arm.com virtual bool nextPixel(Pixel &p) = 0; 19811012Sandreas.sandberg@arm.com 19911012Sandreas.sandberg@arm.com /** First pixel clock of the first VSync line. */ 20011012Sandreas.sandberg@arm.com virtual void onVSyncBegin() {}; 20111012Sandreas.sandberg@arm.com 20211012Sandreas.sandberg@arm.com /** 20311012Sandreas.sandberg@arm.com * Callback on the first pixel of the line after the end VSync 20411012Sandreas.sandberg@arm.com * region (typically the first pixel of the vertical back porch). 20511012Sandreas.sandberg@arm.com */ 20611012Sandreas.sandberg@arm.com virtual void onVSyncEnd() {}; 20711012Sandreas.sandberg@arm.com 20811012Sandreas.sandberg@arm.com /** 20911012Sandreas.sandberg@arm.com * Start of the HSync region. 21011012Sandreas.sandberg@arm.com * 21111012Sandreas.sandberg@arm.com * @note This is called even for scan lines outside of the visible 21211012Sandreas.sandberg@arm.com * region. 21311012Sandreas.sandberg@arm.com */ 21411012Sandreas.sandberg@arm.com virtual void onHSyncBegin() {}; 21511012Sandreas.sandberg@arm.com 21611012Sandreas.sandberg@arm.com /** 21711012Sandreas.sandberg@arm.com * Start of the first pixel after the HSync region. 21811012Sandreas.sandberg@arm.com * 21911012Sandreas.sandberg@arm.com * @note This is called even for scan lines outside of the visible 22011012Sandreas.sandberg@arm.com * region. 22111012Sandreas.sandberg@arm.com */ 22211012Sandreas.sandberg@arm.com virtual void onHSyncEnd() {}; 22311012Sandreas.sandberg@arm.com 22411012Sandreas.sandberg@arm.com /** 22511012Sandreas.sandberg@arm.com * Buffer underrun occurred on a frame. 22611012Sandreas.sandberg@arm.com * 22711012Sandreas.sandberg@arm.com * This method is called once if there is buffer underrun while 22811012Sandreas.sandberg@arm.com * refreshing the display. The underrun state is reset on the next 22911012Sandreas.sandberg@arm.com * refresh. 23011012Sandreas.sandberg@arm.com * 23111012Sandreas.sandberg@arm.com * @param x Coordinate within the visible region. 23211012Sandreas.sandberg@arm.com * @param y Coordinate within the visible region. 23311012Sandreas.sandberg@arm.com */ 23411012Sandreas.sandberg@arm.com virtual void onUnderrun(unsigned x, unsigned y) {}; 23511012Sandreas.sandberg@arm.com 23611012Sandreas.sandberg@arm.com /** Finished displaying the visible region of a frame */ 23711012Sandreas.sandberg@arm.com virtual void onFrameDone() {}; 23811012Sandreas.sandberg@arm.com 23911012Sandreas.sandberg@arm.com private: // Params 24011012Sandreas.sandberg@arm.com /** Maximum number of pixels to handle per render callback */ 24111012Sandreas.sandberg@arm.com const unsigned pixelChunk; 24211012Sandreas.sandberg@arm.com 24311012Sandreas.sandberg@arm.com private: 24411012Sandreas.sandberg@arm.com /** 24511012Sandreas.sandberg@arm.com * Callback helper class with suspend support. 24611012Sandreas.sandberg@arm.com * 24711012Sandreas.sandberg@arm.com * Unlike a normal EventWrapper, this class suspends an event on 24811012Sandreas.sandberg@arm.com * drain() and restarts it at drainResume(). The suspend operation 24911012Sandreas.sandberg@arm.com * stores the tick relative to curTick() and then deschedules the 25011012Sandreas.sandberg@arm.com * event. The resume operation schedules the event at curTick() 25111012Sandreas.sandberg@arm.com * plus the relative tick stored when the event was suspended. 25211012Sandreas.sandberg@arm.com */ 25311012Sandreas.sandberg@arm.com class PixelEvent : public Event, public Drainable 25411012Sandreas.sandberg@arm.com { 25511012Sandreas.sandberg@arm.com typedef void (BasePixelPump::* CallbackType)(); 25611012Sandreas.sandberg@arm.com 25711012Sandreas.sandberg@arm.com public: 25811012Sandreas.sandberg@arm.com PixelEvent(const char *name, BasePixelPump *parent, CallbackType func); 25911012Sandreas.sandberg@arm.com 26011012Sandreas.sandberg@arm.com DrainState drain() M5_ATTR_OVERRIDE; 26111012Sandreas.sandberg@arm.com void drainResume() M5_ATTR_OVERRIDE; 26211012Sandreas.sandberg@arm.com 26311012Sandreas.sandberg@arm.com void serialize(CheckpointOut &cp) const M5_ATTR_OVERRIDE; 26411012Sandreas.sandberg@arm.com void unserialize(CheckpointIn &cp) M5_ATTR_OVERRIDE; 26511012Sandreas.sandberg@arm.com 26611012Sandreas.sandberg@arm.com const std::string name() const M5_ATTR_OVERRIDE { return _name; } 26711012Sandreas.sandberg@arm.com void process() M5_ATTR_OVERRIDE { 26811012Sandreas.sandberg@arm.com (parent.*func)(); 26911012Sandreas.sandberg@arm.com } 27011012Sandreas.sandberg@arm.com 27111012Sandreas.sandberg@arm.com bool active() const { return scheduled() || suspended; } 27211012Sandreas.sandberg@arm.com 27311012Sandreas.sandberg@arm.com private: 27411012Sandreas.sandberg@arm.com void suspend(); 27511012Sandreas.sandberg@arm.com void resume(); 27611012Sandreas.sandberg@arm.com 27711012Sandreas.sandberg@arm.com const std::string _name; 27811012Sandreas.sandberg@arm.com BasePixelPump &parent; 27911012Sandreas.sandberg@arm.com const CallbackType func; 28011012Sandreas.sandberg@arm.com 28111012Sandreas.sandberg@arm.com bool suspended; 28211012Sandreas.sandberg@arm.com Tick relativeTick; 28311012Sandreas.sandberg@arm.com }; 28411012Sandreas.sandberg@arm.com 28511012Sandreas.sandberg@arm.com void beginLine(); 28611012Sandreas.sandberg@arm.com void renderPixels(); 28711012Sandreas.sandberg@arm.com 28811012Sandreas.sandberg@arm.com /** Convenience vector when doing operations on all events */ 28911012Sandreas.sandberg@arm.com std::vector<PixelEvent *> pixelEvents; 29011012Sandreas.sandberg@arm.com 29111012Sandreas.sandberg@arm.com PixelEvent evVSyncBegin; 29211012Sandreas.sandberg@arm.com PixelEvent evVSyncEnd; 29311012Sandreas.sandberg@arm.com PixelEvent evHSyncBegin; 29411012Sandreas.sandberg@arm.com PixelEvent evHSyncEnd; 29511012Sandreas.sandberg@arm.com PixelEvent evBeginLine; 29611012Sandreas.sandberg@arm.com PixelEvent evRenderPixels; 29711012Sandreas.sandberg@arm.com 29811012Sandreas.sandberg@arm.com DisplayTimings _timings; 29911012Sandreas.sandberg@arm.com 30011012Sandreas.sandberg@arm.com /** 30111012Sandreas.sandberg@arm.com * Current line (including back porch, front porch, and vsync) 30211012Sandreas.sandberg@arm.com * within a frame. 30311012Sandreas.sandberg@arm.com */ 30411012Sandreas.sandberg@arm.com unsigned line; 30511012Sandreas.sandberg@arm.com /** X-coordinate within the visible region of a frame */ 30611012Sandreas.sandberg@arm.com unsigned _posX; 30711012Sandreas.sandberg@arm.com 30811012Sandreas.sandberg@arm.com /** Did a buffer underrun occur within this refresh interval? */ 30911012Sandreas.sandberg@arm.com bool _underrun; 31011012Sandreas.sandberg@arm.com}; 31111012Sandreas.sandberg@arm.com 31211012Sandreas.sandberg@arm.com#endif // __DEV_PIXELPUMP_HH__ 313