pixelpump.hh revision 11012
13536Sgblack@eecs.umich.edu/* 23536Sgblack@eecs.umich.edu * Copyright (c) 2015 ARM Limited 33536Sgblack@eecs.umich.edu * All rights reserved 43536Sgblack@eecs.umich.edu * 53536Sgblack@eecs.umich.edu * The license below extends only to copyright in the software and shall 63536Sgblack@eecs.umich.edu * not be construed as granting a license to any other intellectual 73536Sgblack@eecs.umich.edu * property including but not limited to intellectual property relating 83536Sgblack@eecs.umich.edu * to a hardware implementation of the functionality of the software 93536Sgblack@eecs.umich.edu * licensed hereunder. You may use the software subject to the license 103536Sgblack@eecs.umich.edu * terms below provided that you ensure that this notice is replicated 113536Sgblack@eecs.umich.edu * unmodified and in its entirety in all distributions of the software, 123536Sgblack@eecs.umich.edu * modified or unmodified, in source code or in binary form. 133536Sgblack@eecs.umich.edu * 143536Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without 153536Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are 163536Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright 173536Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer; 183536Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright 193536Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the 203536Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution; 213536Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its 223536Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from 233536Sgblack@eecs.umich.edu * this software without specific prior written permission. 243536Sgblack@eecs.umich.edu * 253536Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 263536Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 273536Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 283536Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 293536Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 303536Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 313536Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 323536Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 335543Ssaidi@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 343536Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 353536Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 363536Sgblack@eecs.umich.edu * 373536Sgblack@eecs.umich.edu * Authors: Andreas Sandberg 383536Sgblack@eecs.umich.edu */ 393536Sgblack@eecs.umich.edu 403536Sgblack@eecs.umich.edu#ifndef __DEV_PIXELPUMP_HH__ 415543Ssaidi@eecs.umich.edu#define __DEV_PIXELPUMP_HH__ 425543Ssaidi@eecs.umich.edu 433536Sgblack@eecs.umich.edu#include "base/framebuffer.hh" 443536Sgblack@eecs.umich.edu#include "sim/clocked_object.hh" 453536Sgblack@eecs.umich.edu 463536Sgblack@eecs.umich.edustruct BasePixelPumpParams; 473536Sgblack@eecs.umich.edu 483536Sgblack@eecs.umich.edustruct DisplayTimings : public Serializable 493536Sgblack@eecs.umich.edu{ 503536Sgblack@eecs.umich.edu /** 513536Sgblack@eecs.umich.edu * Create a display timing configuration struct 523536Sgblack@eecs.umich.edu * 533536Sgblack@eecs.umich.edu * @param width Width of the visible area of the screen. 545543Ssaidi@eecs.umich.edu * @param height Height of the visible area of the screen. 555543Ssaidi@eecs.umich.edu * @param hfp Horizontal front porch in pixel clocks. 563536Sgblack@eecs.umich.edu * @param h_sync Horizontal sync in pixel clocks. 573536Sgblack@eecs.umich.edu * @param hbp Horizontal back porch in pixel clocks. 583536Sgblack@eecs.umich.edu * @param vfp Vertical front porch in scan lines. 593536Sgblack@eecs.umich.edu * @param v_sync Vertical sync in scan lines. 603536Sgblack@eecs.umich.edu * @param vbp Vertical back porch in scan lines. 613536Sgblack@eecs.umich.edu */ 623536Sgblack@eecs.umich.edu DisplayTimings(unsigned width, unsigned height, 633536Sgblack@eecs.umich.edu unsigned hbp, unsigned h_sync, unsigned hfp, 643536Sgblack@eecs.umich.edu unsigned vbp, unsigned v_sync, unsigned vfp); 653536Sgblack@eecs.umich.edu 663536Sgblack@eecs.umich.edu void serialize(CheckpointOut &cp) const M5_ATTR_OVERRIDE; 673536Sgblack@eecs.umich.edu void unserialize(CheckpointIn &cp) M5_ATTR_OVERRIDE; 683536Sgblack@eecs.umich.edu 693536Sgblack@eecs.umich.edu /** How many pixel clocks are required for one line? */ 703536Sgblack@eecs.umich.edu Cycles cyclesPerLine() const { 713536Sgblack@eecs.umich.edu return Cycles(hSync + hBackPorch + width + hBackPorch); 725543Ssaidi@eecs.umich.edu } 733536Sgblack@eecs.umich.edu 743536Sgblack@eecs.umich.edu /** How many pixel clocks are required for one frame? */ 753536Sgblack@eecs.umich.edu Cycles cyclesPerFrame() const { 763536Sgblack@eecs.umich.edu return Cycles(cyclesPerLine() * linesPerFrame()); 773536Sgblack@eecs.umich.edu } 783536Sgblack@eecs.umich.edu 793536Sgblack@eecs.umich.edu /** Calculate the first line of the vsync signal */ 803536Sgblack@eecs.umich.edu unsigned lineVSyncStart() const { 813536Sgblack@eecs.umich.edu return 0; 823536Sgblack@eecs.umich.edu } 833536Sgblack@eecs.umich.edu 843536Sgblack@eecs.umich.edu /** Calculate the first line of the vertical back porch */ 853536Sgblack@eecs.umich.edu unsigned lineVBackPorchStart() const { 863536Sgblack@eecs.umich.edu return lineVSyncStart() + vSync; 873536Sgblack@eecs.umich.edu } 883536Sgblack@eecs.umich.edu 893536Sgblack@eecs.umich.edu /** Calculate the first line of the visible region */ 903536Sgblack@eecs.umich.edu unsigned lineFirstVisible() const { 913536Sgblack@eecs.umich.edu return lineVBackPorchStart() + vBackPorch; 925543Ssaidi@eecs.umich.edu } 935543Ssaidi@eecs.umich.edu 943536Sgblack@eecs.umich.edu /** Calculate the first line of the back porch */ 953536Sgblack@eecs.umich.edu unsigned lineFrontPorchStart() const { 963536Sgblack@eecs.umich.edu return lineFirstVisible() + height; 973536Sgblack@eecs.umich.edu } 983536Sgblack@eecs.umich.edu 993536Sgblack@eecs.umich.edu /** Calculate the total number of lines in a frame */ 1003536Sgblack@eecs.umich.edu unsigned linesPerFrame() const { 1013536Sgblack@eecs.umich.edu return lineFrontPorchStart() + vFrontPorch; 1023536Sgblack@eecs.umich.edu } 1033536Sgblack@eecs.umich.edu 1043536Sgblack@eecs.umich.edu /** Display width in pixels */ 1053536Sgblack@eecs.umich.edu unsigned width; 1063536Sgblack@eecs.umich.edu /** Display height in pixels */ 1073536Sgblack@eecs.umich.edu unsigned height; 1083536Sgblack@eecs.umich.edu 1093536Sgblack@eecs.umich.edu /** Horizontal back porch in pixels */ 1103536Sgblack@eecs.umich.edu unsigned hBackPorch; 1113536Sgblack@eecs.umich.edu /** Horizontal front porch in pixels */ 1123536Sgblack@eecs.umich.edu unsigned hFrontPorch; 1133536Sgblack@eecs.umich.edu /** Horizontal sync signal length in pixels */ 1143536Sgblack@eecs.umich.edu unsigned hSync; 1153536Sgblack@eecs.umich.edu 1163536Sgblack@eecs.umich.edu /** Vertical back porch in lines */ 1173536Sgblack@eecs.umich.edu unsigned vBackPorch; 1183536Sgblack@eecs.umich.edu /** Vertical front porch in lines */ 1193536Sgblack@eecs.umich.edu unsigned vFrontPorch; 1203536Sgblack@eecs.umich.edu /** Vertical sync signal in lines */ 1213536Sgblack@eecs.umich.edu unsigned vSync; 1223536Sgblack@eecs.umich.edu 1233536Sgblack@eecs.umich.edu static const DisplayTimings vga; 1243536Sgblack@eecs.umich.edu}; 1253536Sgblack@eecs.umich.edu 1263536Sgblack@eecs.umich.edu/** 1273536Sgblack@eecs.umich.edu * Timing generator for a pixel-based display. 1283536Sgblack@eecs.umich.edu * 1293536Sgblack@eecs.umich.edu * Pixels are ordered relative to the top left corner of the 1303536Sgblack@eecs.umich.edu * display. Scan lines appear in the following order: 1313536Sgblack@eecs.umich.edu * <ol> 1323536Sgblack@eecs.umich.edu * <li>Vertical Sync (starting at line 0) 1335107Sgblack@eecs.umich.edu * <li>Vertical back porch 1343536Sgblack@eecs.umich.edu * <li>Visible lines 1353536Sgblack@eecs.umich.edu * <li>Vertical front porch 1367678Sgblack@eecs.umich.edu * </ol> 1375107Sgblack@eecs.umich.edu * 1383536Sgblack@eecs.umich.edu * Pixel order within a scan line: 1393536Sgblack@eecs.umich.edu * <ol> 1403536Sgblack@eecs.umich.edu * <li>Horizontal Sync 1415567Snate@binkert.org * <li>Horizontal Back Porch 1423536Sgblack@eecs.umich.edu * <li>Visible pixels 1433550Sgblack@eecs.umich.edu * <li>Horizontal Front Porch 1444060Ssaidi@eecs.umich.edu * </ol> 1453536Sgblack@eecs.umich.edu */ 1463536Sgblack@eecs.umich.educlass BasePixelPump 1473536Sgblack@eecs.umich.edu : public EventManager, public Clocked, 1483536Sgblack@eecs.umich.edu public Serializable 1493536Sgblack@eecs.umich.edu{ 1505543Ssaidi@eecs.umich.edu public: 1513536Sgblack@eecs.umich.edu BasePixelPump(EventManager &em, ClockDomain &pxl_clk, unsigned pixel_chunk); 1523536Sgblack@eecs.umich.edu virtual ~BasePixelPump(); 1533536Sgblack@eecs.umich.edu 1543536Sgblack@eecs.umich.edu void serialize(CheckpointOut &cp) const M5_ATTR_OVERRIDE; 1553571Sgblack@eecs.umich.edu void unserialize(CheckpointIn &cp) M5_ATTR_OVERRIDE; 1565107Sgblack@eecs.umich.edu 1573571Sgblack@eecs.umich.edu public: // Public API 1585107Sgblack@eecs.umich.edu /** Starting pushing pixels using the supplied display timings. */ 1594070Ssaidi@eecs.umich.edu void start(const DisplayTimings &timings); 1604070Ssaidi@eecs.umich.edu 1614070Ssaidi@eecs.umich.edu /** Immediately stop pushing pixels */ 1625107Sgblack@eecs.umich.edu void stop(); 1635107Sgblack@eecs.umich.edu 1645107Sgblack@eecs.umich.edu /** Get a constant reference of the current display timings */ 1655107Sgblack@eecs.umich.edu const DisplayTimings &timings() const { return _timings; } 1665107Sgblack@eecs.umich.edu 1675107Sgblack@eecs.umich.edu /** Is the pixel pump active and refreshing the display? */ 1685107Sgblack@eecs.umich.edu bool active() const { return evBeginLine.active(); } 1695107Sgblack@eecs.umich.edu 1703536Sgblack@eecs.umich.edu /** Did a buffer underrun occur within this refresh interval? */ 1713536Sgblack@eecs.umich.edu bool underrun() const { return _underrun; } 1723536Sgblack@eecs.umich.edu 1733536Sgblack@eecs.umich.edu /** Is the current line within the visible range? */ 1743536Sgblack@eecs.umich.edu bool visibleLine() const { 1755543Ssaidi@eecs.umich.edu return line >= _timings.lineFirstVisible() && 1765543Ssaidi@eecs.umich.edu line < _timings.lineFrontPorchStart(); 1773536Sgblack@eecs.umich.edu } 1783536Sgblack@eecs.umich.edu 1793536Sgblack@eecs.umich.edu /** Current pixel position within the visible area */ 1803536Sgblack@eecs.umich.edu unsigned posX() const { return _posX; } 1813536Sgblack@eecs.umich.edu 1827720Sgblack@eecs.umich.edu /** Current pixel position within the visible area */ 1837720Sgblack@eecs.umich.edu unsigned posY() const { 1844172Ssaidi@eecs.umich.edu return visibleLine() ? line - _timings.lineFirstVisible() : 0; 1854070Ssaidi@eecs.umich.edu } 1864070Ssaidi@eecs.umich.edu 1874070Ssaidi@eecs.umich.edu /** Output frame buffer */ 1887720Sgblack@eecs.umich.edu FrameBuffer fb; 1897720Sgblack@eecs.umich.edu 1904070Ssaidi@eecs.umich.edu protected: // Callbacks 1914070Ssaidi@eecs.umich.edu /** 1924060Ssaidi@eecs.umich.edu * Get the next pixel from the scan line buffer. 1934070Ssaidi@eecs.umich.edu * 1944172Ssaidi@eecs.umich.edu * @param p Output pixel value, undefined on underrun 1954172Ssaidi@eecs.umich.edu * @return true on success, false on buffer underrun 1964070Ssaidi@eecs.umich.edu */ 1974070Ssaidi@eecs.umich.edu virtual bool nextPixel(Pixel &p) = 0; 1987720Sgblack@eecs.umich.edu 1997720Sgblack@eecs.umich.edu /** First pixel clock of the first VSync line. */ 2004070Ssaidi@eecs.umich.edu virtual void onVSyncBegin() {}; 2014070Ssaidi@eecs.umich.edu 2024060Ssaidi@eecs.umich.edu /** 2034172Ssaidi@eecs.umich.edu * Callback on the first pixel of the line after the end VSync 2044172Ssaidi@eecs.umich.edu * region (typically the first pixel of the vertical back porch). 2054070Ssaidi@eecs.umich.edu */ 2064070Ssaidi@eecs.umich.edu virtual void onVSyncEnd() {}; 2074172Ssaidi@eecs.umich.edu 2084172Ssaidi@eecs.umich.edu /** 2094172Ssaidi@eecs.umich.edu * Start of the HSync region. 2104070Ssaidi@eecs.umich.edu * 2114070Ssaidi@eecs.umich.edu * @note This is called even for scan lines outside of the visible 2124060Ssaidi@eecs.umich.edu * region. 2134060Ssaidi@eecs.umich.edu */ 2144060Ssaidi@eecs.umich.edu virtual void onHSyncBegin() {}; 2153571Sgblack@eecs.umich.edu 2163571Sgblack@eecs.umich.edu /** 2173571Sgblack@eecs.umich.edu * Start of the first pixel after the HSync region. 2183536Sgblack@eecs.umich.edu * 2193536Sgblack@eecs.umich.edu * @note This is called even for scan lines outside of the visible 2203536Sgblack@eecs.umich.edu * region. 2213536Sgblack@eecs.umich.edu */ 2223536Sgblack@eecs.umich.edu virtual void onHSyncEnd() {}; 2235543Ssaidi@eecs.umich.edu 2245543Ssaidi@eecs.umich.edu /** 2253536Sgblack@eecs.umich.edu * Buffer underrun occurred on a frame. 2263536Sgblack@eecs.umich.edu * 2273536Sgblack@eecs.umich.edu * This method is called once if there is buffer underrun while 2283536Sgblack@eecs.umich.edu * refreshing the display. The underrun state is reset on the next 2297720Sgblack@eecs.umich.edu * refresh. 2307720Sgblack@eecs.umich.edu * 2317720Sgblack@eecs.umich.edu * @param x Coordinate within the visible region. 2327720Sgblack@eecs.umich.edu * @param y Coordinate within the visible region. 2337720Sgblack@eecs.umich.edu */ 2347720Sgblack@eecs.umich.edu virtual void onUnderrun(unsigned x, unsigned y) {}; 2357720Sgblack@eecs.umich.edu 2363571Sgblack@eecs.umich.edu /** Finished displaying the visible region of a frame */ 2373550Sgblack@eecs.umich.edu virtual void onFrameDone() {}; 2383571Sgblack@eecs.umich.edu 2393536Sgblack@eecs.umich.edu private: // Params 2403536Sgblack@eecs.umich.edu /** Maximum number of pixels to handle per render callback */ 2413536Sgblack@eecs.umich.edu const unsigned pixelChunk; 2423536Sgblack@eecs.umich.edu 2433536Sgblack@eecs.umich.edu private: 2444060Ssaidi@eecs.umich.edu /** 2454060Ssaidi@eecs.umich.edu * Callback helper class with suspend support. 2463536Sgblack@eecs.umich.edu * 2473536Sgblack@eecs.umich.edu * Unlike a normal EventWrapper, this class suspends an event on 2483536Sgblack@eecs.umich.edu * drain() and restarts it at drainResume(). The suspend operation 2493536Sgblack@eecs.umich.edu * stores the tick relative to curTick() and then deschedules the 2503536Sgblack@eecs.umich.edu * event. The resume operation schedules the event at curTick() 2517720Sgblack@eecs.umich.edu * plus the relative tick stored when the event was suspended. 2524060Ssaidi@eecs.umich.edu */ 2533536Sgblack@eecs.umich.edu class PixelEvent : public Event, public Drainable 254 { 255 typedef void (BasePixelPump::* CallbackType)(); 256 257 public: 258 PixelEvent(const char *name, BasePixelPump *parent, CallbackType func); 259 260 DrainState drain() M5_ATTR_OVERRIDE; 261 void drainResume() M5_ATTR_OVERRIDE; 262 263 void serialize(CheckpointOut &cp) const M5_ATTR_OVERRIDE; 264 void unserialize(CheckpointIn &cp) M5_ATTR_OVERRIDE; 265 266 const std::string name() const M5_ATTR_OVERRIDE { return _name; } 267 void process() M5_ATTR_OVERRIDE { 268 (parent.*func)(); 269 } 270 271 bool active() const { return scheduled() || suspended; } 272 273 private: 274 void suspend(); 275 void resume(); 276 277 const std::string _name; 278 BasePixelPump &parent; 279 const CallbackType func; 280 281 bool suspended; 282 Tick relativeTick; 283 }; 284 285 void beginLine(); 286 void renderPixels(); 287 288 /** Convenience vector when doing operations on all events */ 289 std::vector<PixelEvent *> pixelEvents; 290 291 PixelEvent evVSyncBegin; 292 PixelEvent evVSyncEnd; 293 PixelEvent evHSyncBegin; 294 PixelEvent evHSyncEnd; 295 PixelEvent evBeginLine; 296 PixelEvent evRenderPixels; 297 298 DisplayTimings _timings; 299 300 /** 301 * Current line (including back porch, front porch, and vsync) 302 * within a frame. 303 */ 304 unsigned line; 305 /** X-coordinate within the visible region of a frame */ 306 unsigned _posX; 307 308 /** Did a buffer underrun occur within this refresh interval? */ 309 bool _underrun; 310}; 311 312#endif // __DEV_PIXELPUMP_HH__ 313