2 * Copyright (c) 2015, 2017 ARM Limited
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.
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.
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.
38 #ifndef __DEV_PIXELPUMP_HH__
39 #define __DEV_PIXELPUMP_HH__
43 #include "base/framebuffer.hh"
44 #include "sim/clocked_object.hh"
46 struct BasePixelPumpParams;
48 struct DisplayTimings : public Serializable
51 * Create a display timing configuration struct
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.
62 DisplayTimings(unsigned width, unsigned height,
63 unsigned hbp, unsigned h_sync, unsigned hfp,
64 unsigned vbp, unsigned v_sync, unsigned vfp);
66 void serialize(CheckpointOut &cp) const override;
67 void unserialize(CheckpointIn &cp) override;
69 /** How many pixel clocks are required for one line? */
73 return Cycles(hSync + hBackPorch + width + hBackPorch);
76 /** How many pixel clocks are required for one frame? */
78 cyclesPerFrame() const
80 return Cycles(cyclesPerLine() * linesPerFrame());
83 /** Calculate the first line of the vsync signal */
85 lineVSyncStart() const
90 /** Calculate the first line of the vertical back porch */
92 lineVBackPorchStart() const
94 return lineVSyncStart() + vSync;
97 /** Calculate the first line of the visible region */
99 lineFirstVisible() const
101 return lineVBackPorchStart() + vBackPorch;
104 /** Calculate the first line of the back porch */
106 lineFrontPorchStart() const
108 return lineFirstVisible() + height;
111 /** Calculate the total number of lines in a frame */
113 linesPerFrame() const
115 return lineFrontPorchStart() + vFrontPorch;
118 /** Display width in pixels */
120 /** Display height in pixels */
123 /** Horizontal back porch in pixels */
125 /** Horizontal front porch in pixels */
126 unsigned hFrontPorch;
127 /** Horizontal sync signal length in pixels */
130 /** Vertical back porch in lines */
132 /** Vertical front porch in lines */
133 unsigned vFrontPorch;
134 /** Vertical sync signal in lines */
137 static const DisplayTimings vga;
141 * Timing generator for a pixel-based display.
143 * Pixels are ordered relative to the top left corner of the
144 * display. Scan lines appear in the following order:
146 * <li>Vertical Sync (starting at line 0)
147 * <li>Vertical back porch
149 * <li>Vertical front porch
152 * Pixel order within a scan line:
154 * <li>Horizontal Sync
155 * <li>Horizontal Back Porch
157 * <li>Horizontal Front Porch
161 : public EventManager, public Clocked,
165 BasePixelPump(EventManager &em, ClockDomain &pxl_clk,
166 unsigned pixel_chunk);
167 virtual ~BasePixelPump();
169 void serialize(CheckpointOut &cp) const override;
170 void unserialize(CheckpointIn &cp) override;
172 public: // Public API
173 /** Update frame size using display timing */
174 void updateTimings(const DisplayTimings &timings);
176 /** Render an entire frame in non-caching mode */
179 /** Starting pushing pixels in timing mode */
182 /** Immediately stop pushing pixels */
185 /** Get a constant reference of the current display timings */
186 const DisplayTimings &timings() const { return _timings; }
188 /** Is the pixel pump active and refreshing the display? */
189 bool active() const { return evBeginLine.active(); }
191 /** Did a buffer underrun occur within this refresh interval? */
192 bool underrun() const { return _underrun; }
194 /** Is the current line within the visible range? */
198 return line >= _timings.lineFirstVisible() &&
199 line < _timings.lineFrontPorchStart();
202 /** Current pixel position within the visible area */
203 unsigned posX() const { return _posX; }
205 /** Current pixel position within the visible area */
209 return visibleLine() ? line - _timings.lineFirstVisible() : 0;
212 /** Output frame buffer */
215 protected: // Callbacks
217 * Get the next pixel from the scan line buffer.
219 * @param p Output pixel value, undefined on underrun
220 * @return true on success, false on buffer underrun
222 virtual bool nextPixel(Pixel &p) = 0;
225 * Get the next line of pixels directly from memory. This is for use from
226 * the renderFrame which is called in non-caching mode.
228 * The default implementation falls back to calling nextPixel over and
229 * over, but a more efficient implementation could retrieve the entire line
230 * of pixels all at once using fewer access to memory which bypass any
231 * intermediate structures like an incoming FIFO.
233 * @param ps A vector iterator to store retrieved pixels into.
234 * @param line_length The number of pixels being requested.
235 * @return The number of pixels actually retrieved.
238 nextLine(std::vector<Pixel>::iterator ps, size_t line_length)
241 while (count < line_length && nextPixel(*ps++))
246 /** First pixel clock of the first VSync line. */
247 virtual void onVSyncBegin() {};
250 * Callback on the first pixel of the line after the end VSync
251 * region (typically the first pixel of the vertical back porch).
253 virtual void onVSyncEnd() {};
256 * Start of the HSync region.
258 * @note This is called even for scan lines outside of the visible
261 virtual void onHSyncBegin() {};
264 * Start of the first pixel after the HSync region.
266 * @note This is called even for scan lines outside of the visible
269 virtual void onHSyncEnd() {};
272 * Buffer underrun occurred on a frame.
274 * This method is called once if there is buffer underrun while
275 * refreshing the display. The underrun state is reset on the next
278 * @param x Coordinate within the visible region.
279 * @param y Coordinate within the visible region.
281 virtual void onUnderrun(unsigned x, unsigned y) {};
283 /** Finished displaying the visible region of a frame */
284 virtual void onFrameDone() {};
287 /** Maximum number of pixels to handle per render callback */
288 const unsigned pixelChunk;
292 * Callback helper class with suspend support.
294 * Unlike a normal EventWrapper, this class suspends an event on
295 * drain() and restarts it at drainResume(). The suspend operation
296 * stores the tick relative to curTick() and then deschedules the
297 * event. The resume operation schedules the event at curTick()
298 * plus the relative tick stored when the event was suspended.
300 class PixelEvent : public Event, public Drainable
302 typedef void (BasePixelPump::* CallbackType)();
305 PixelEvent(const char *name, BasePixelPump *parent, CallbackType func);
307 DrainState drain() override;
308 void drainResume() override;
310 void serialize(CheckpointOut &cp) const override;
311 void unserialize(CheckpointIn &cp) override;
313 const std::string name() const override { return _name; }
321 bool active() const { return scheduled() || suspended; }
327 const std::string _name;
328 BasePixelPump &parent;
329 const CallbackType func;
338 /** Fast and event-free line rendering function */
341 /** Convenience vector when doing operations on all events */
342 std::vector<PixelEvent *> pixelEvents;
344 PixelEvent evVSyncBegin;
345 PixelEvent evVSyncEnd;
346 PixelEvent evHSyncBegin;
347 PixelEvent evHSyncEnd;
348 PixelEvent evBeginLine;
349 PixelEvent evRenderPixels;
351 DisplayTimings _timings;
354 * Current line (including back porch, front porch, and vsync)
358 /** X-coordinate within the visible region of a frame */
361 /** Did a buffer underrun occur within this refresh interval? */
365 #endif // __DEV_PIXELPUMP_HH__