1/* 2 * Copyright (c) 2015 ARM Limited 3 * All rights reserved 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software 9 * licensed hereunder. You may use the software subject to the license 10 * terms below provided that you ensure that this notice is replicated 11 * unmodified and in its entirety in all distributions of the software, 12 * modified or unmodified, in source code or in binary form. 13 * 14 * Redistribution and use in source and binary forms, with or without 15 * modification, are permitted provided that the following conditions are 16 * met: redistributions of source code must retain the above copyright 17 * notice, this list of conditions and the following disclaimer; 18 * redistributions in binary form must reproduce the above copyright 19 * notice, this list of conditions and the following disclaimer in the 20 * documentation and/or other materials provided with the distribution; 21 * neither the name of the copyright holders nor the names of its 22 * contributors may be used to endorse or promote products derived from 23 * this software without specific prior written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36 * 37 * Authors: Andreas Sandberg 38 */ 39 40#ifndef __DEV_PIXELPUMP_HH__ 41#define __DEV_PIXELPUMP_HH__ 42 43#include "base/framebuffer.hh" 44#include "sim/clocked_object.hh" 45 46struct BasePixelPumpParams; 47 48struct DisplayTimings : public Serializable 49{ 50 /** 51 * Create a display timing configuration struct 52 * 53 * @param width Width of the visible area of the screen. 54 * @param height Height of the visible area of the screen. 55 * @param hfp Horizontal front porch in pixel clocks. 56 * @param h_sync Horizontal sync in pixel clocks. 57 * @param hbp Horizontal back porch in pixel clocks. 58 * @param vfp Vertical front porch in scan lines. 59 * @param v_sync Vertical sync in scan lines. 60 * @param vbp Vertical back porch in scan lines. 61 */ 62 DisplayTimings(unsigned width, unsigned height, 63 unsigned hbp, unsigned h_sync, unsigned hfp, 64 unsigned vbp, unsigned v_sync, unsigned vfp); 65
|
66 void serialize(CheckpointOut &cp) const M5_ATTR_OVERRIDE;
67 void unserialize(CheckpointIn &cp) M5_ATTR_OVERRIDE;
|
66 void serialize(CheckpointOut &cp) const override; 67 void unserialize(CheckpointIn &cp) override; |
68 69 /** How many pixel clocks are required for one line? */ 70 Cycles cyclesPerLine() const { 71 return Cycles(hSync + hBackPorch + width + hBackPorch); 72 } 73 74 /** How many pixel clocks are required for one frame? */ 75 Cycles cyclesPerFrame() const { 76 return Cycles(cyclesPerLine() * linesPerFrame()); 77 } 78 79 /** Calculate the first line of the vsync signal */ 80 unsigned lineVSyncStart() const { 81 return 0; 82 } 83 84 /** Calculate the first line of the vertical back porch */ 85 unsigned lineVBackPorchStart() const { 86 return lineVSyncStart() + vSync; 87 } 88 89 /** Calculate the first line of the visible region */ 90 unsigned lineFirstVisible() const { 91 return lineVBackPorchStart() + vBackPorch; 92 } 93 94 /** Calculate the first line of the back porch */ 95 unsigned lineFrontPorchStart() const { 96 return lineFirstVisible() + height; 97 } 98 99 /** Calculate the total number of lines in a frame */ 100 unsigned linesPerFrame() const { 101 return lineFrontPorchStart() + vFrontPorch; 102 } 103 104 /** Display width in pixels */ 105 unsigned width; 106 /** Display height in pixels */ 107 unsigned height; 108 109 /** Horizontal back porch in pixels */ 110 unsigned hBackPorch; 111 /** Horizontal front porch in pixels */ 112 unsigned hFrontPorch; 113 /** Horizontal sync signal length in pixels */ 114 unsigned hSync; 115 116 /** Vertical back porch in lines */ 117 unsigned vBackPorch; 118 /** Vertical front porch in lines */ 119 unsigned vFrontPorch; 120 /** Vertical sync signal in lines */ 121 unsigned vSync; 122 123 static const DisplayTimings vga; 124}; 125 126/** 127 * Timing generator for a pixel-based display. 128 * 129 * Pixels are ordered relative to the top left corner of the 130 * display. Scan lines appear in the following order: 131 * <ol> 132 * <li>Vertical Sync (starting at line 0) 133 * <li>Vertical back porch 134 * <li>Visible lines 135 * <li>Vertical front porch 136 * </ol> 137 * 138 * Pixel order within a scan line: 139 * <ol> 140 * <li>Horizontal Sync 141 * <li>Horizontal Back Porch 142 * <li>Visible pixels 143 * <li>Horizontal Front Porch 144 * </ol> 145 */ 146class BasePixelPump 147 : public EventManager, public Clocked, 148 public Serializable 149{ 150 public: 151 BasePixelPump(EventManager &em, ClockDomain &pxl_clk, unsigned pixel_chunk); 152 virtual ~BasePixelPump(); 153
|
154 void serialize(CheckpointOut &cp) const M5_ATTR_OVERRIDE;
155 void unserialize(CheckpointIn &cp) M5_ATTR_OVERRIDE;
|
154 void serialize(CheckpointOut &cp) const override; 155 void unserialize(CheckpointIn &cp) override; |
156 157 public: // Public API 158 /** Starting pushing pixels using the supplied display timings. */ 159 void start(const DisplayTimings &timings); 160 161 /** Immediately stop pushing pixels */ 162 void stop(); 163 164 /** Get a constant reference of the current display timings */ 165 const DisplayTimings &timings() const { return _timings; } 166 167 /** Is the pixel pump active and refreshing the display? */ 168 bool active() const { return evBeginLine.active(); } 169 170 /** Did a buffer underrun occur within this refresh interval? */ 171 bool underrun() const { return _underrun; } 172 173 /** Is the current line within the visible range? */ 174 bool visibleLine() const { 175 return line >= _timings.lineFirstVisible() && 176 line < _timings.lineFrontPorchStart(); 177 } 178 179 /** Current pixel position within the visible area */ 180 unsigned posX() const { return _posX; } 181 182 /** Current pixel position within the visible area */ 183 unsigned posY() const { 184 return visibleLine() ? line - _timings.lineFirstVisible() : 0; 185 } 186 187 /** Output frame buffer */ 188 FrameBuffer fb; 189 190 protected: // Callbacks 191 /** 192 * Get the next pixel from the scan line buffer. 193 * 194 * @param p Output pixel value, undefined on underrun 195 * @return true on success, false on buffer underrun 196 */ 197 virtual bool nextPixel(Pixel &p) = 0; 198 199 /** First pixel clock of the first VSync line. */ 200 virtual void onVSyncBegin() {}; 201 202 /** 203 * Callback on the first pixel of the line after the end VSync 204 * region (typically the first pixel of the vertical back porch). 205 */ 206 virtual void onVSyncEnd() {}; 207 208 /** 209 * Start of the HSync region. 210 * 211 * @note This is called even for scan lines outside of the visible 212 * region. 213 */ 214 virtual void onHSyncBegin() {}; 215 216 /** 217 * Start of the first pixel after the HSync region. 218 * 219 * @note This is called even for scan lines outside of the visible 220 * region. 221 */ 222 virtual void onHSyncEnd() {}; 223 224 /** 225 * Buffer underrun occurred on a frame. 226 * 227 * This method is called once if there is buffer underrun while 228 * refreshing the display. The underrun state is reset on the next 229 * refresh. 230 * 231 * @param x Coordinate within the visible region. 232 * @param y Coordinate within the visible region. 233 */ 234 virtual void onUnderrun(unsigned x, unsigned y) {}; 235 236 /** Finished displaying the visible region of a frame */ 237 virtual void onFrameDone() {}; 238 239 private: // Params 240 /** Maximum number of pixels to handle per render callback */ 241 const unsigned pixelChunk; 242 243 private: 244 /** 245 * Callback helper class with suspend support. 246 * 247 * Unlike a normal EventWrapper, this class suspends an event on 248 * drain() and restarts it at drainResume(). The suspend operation 249 * stores the tick relative to curTick() and then deschedules the 250 * event. The resume operation schedules the event at curTick() 251 * plus the relative tick stored when the event was suspended. 252 */ 253 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;
|
260 DrainState drain() override; 261 void drainResume() override; |
262
|
263 void serialize(CheckpointOut &cp) const M5_ATTR_OVERRIDE;
264 void unserialize(CheckpointIn &cp) M5_ATTR_OVERRIDE;
|
263 void serialize(CheckpointOut &cp) const override; 264 void unserialize(CheckpointIn &cp) override; |
265
|
266 const std::string name() const M5_ATTR_OVERRIDE { return _name; }
267 void process() M5_ATTR_OVERRIDE {
|
266 const std::string name() const override { return _name; } 267 void process() 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__
|