gem5  v22.1.0.0
pixelpump.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015, 2017 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 
38 #include "dev/pixelpump.hh"
39 
40 #include "base/logging.hh"
41 
42 namespace gem5
43 {
44 
45 const DisplayTimings DisplayTimings::vga(
46  640, 480,
47  48, 96, 16,
48  33, 2, 10);
49 
50 
51 DisplayTimings::DisplayTimings(unsigned _width, unsigned _height,
52  unsigned hbp, unsigned h_sync, unsigned hfp,
53  unsigned vbp, unsigned v_sync, unsigned vfp)
54  : width(_width), height(_height),
55  hBackPorch(hbp), hFrontPorch(hfp), hSync(h_sync),
56  vBackPorch(vbp), vFrontPorch(vfp), vSync(v_sync)
57 {
58 }
59 
60 void
62 {
65 
69 
73 }
74 
75 void
77 {
80 
84 
88 }
89 
90 
92  unsigned pixel_chunk)
93  : EventManager(em), Clocked(pxl_clk), Serializable(),
94  pixelChunk(pixel_chunk),
95  pixelEvents(),
96  evVSyncBegin("evVSyncBegin", this, &BasePixelPump::onVSyncBegin),
97  evVSyncEnd("evVSyncEnd", this, &BasePixelPump::onVSyncEnd),
98  evHSyncBegin("evHSyncBegin", this, &BasePixelPump::onHSyncBegin),
99  evHSyncEnd("evHSyncEnd", this, &BasePixelPump::onHSyncEnd),
100  evBeginLine("evBeginLine", this, &BasePixelPump::beginLine),
101  evRenderPixels("evRenderPixels", this, &BasePixelPump::renderPixels),
102  _timings(DisplayTimings::vga),
103  line(0), _posX(0), _underrun(false)
104 {
105 }
106 
108 {
109 }
110 
111 void
113 {
117 
119  SERIALIZE_OBJ(fb);
120 
121  for (PixelEvent *event : pixelEvents)
122  event->serializeSection(cp, event->name());
123 }
124 
125 void
127 {
131 
134 
135  // We don't need to reschedule the event here since the event was
136  // suspended by PixelEvent::drain() and will be rescheduled by
137  // PixelEvent::drainResume().
138  for (PixelEvent *event : pixelEvents)
139  event->unserializeSection(cp, event->name());
140 }
141 
142 void
144 {
145  panic_if(active(), "Trying to update timings in active PixelPump\n");
146 
147  _timings = timings;
148 
149  // Resize the frame buffer if needed
150  if (_timings.width != fb.width() || _timings.height != fb.height())
152 
153  // Set the current line past the last line in the frame. This
154  // triggers the new frame logic in beginLine().
156 }
157 
158 void
160 {
162 }
163 
164 
165 void
167 {
168  if (evVSyncEnd.scheduled())
170 
171  if (evHSyncBegin.scheduled())
173 
174  if (evHSyncEnd.scheduled())
176 
177  if (evBeginLine.scheduled())
179 
182 }
183 
184 void
186 {
187  _posX = 0;
188  line++;
189  if (line >= _timings.linesPerFrame()) {
190  _underrun = false;
191  line = 0;
192  }
193 
194  if (line == _timings.lineVSyncStart()) {
195  onVSyncBegin();
196  } else if (line == _timings.lineVBackPorchStart()) {
197  onVSyncEnd();
198  }
199 
200  const Cycles h_sync_begin(0);
201  schedule(evHSyncBegin, clockEdge(h_sync_begin));
202 
203  const Cycles h_sync_end(h_sync_begin + _timings.hSync);
204  schedule(evHSyncEnd, clockEdge(h_sync_end));
205 
206  // Visible area
207  if (line >= _timings.lineFirstVisible() &&
209 
210  const Cycles h_first_visible(h_sync_end + _timings.hBackPorch);
211  schedule(evRenderPixels, clockEdge(h_first_visible));
212  }
213 
215 }
216 
217 void
219 {
220  // Try to handle multiple pixels at a time; doing so reduces the
221  // accuracy of the underrun detection but lowers simulation
222  // overhead
223  const unsigned x_end(std::min(_posX + pixelChunk, _timings.width));
224  const unsigned pxl_count(x_end - _posX);
225  const unsigned pos_y(posY());
226 
227  Pixel pixel(0, 0, 0);
228  const Pixel underrun_pixel(0, 0, 0);
229  for (; _posX < x_end && !_underrun; ++_posX) {
230  if (!nextPixel(pixel)) {
231  warn("Input buffer underrun in BasePixelPump (%u, %u)\n",
232  _posX, pos_y);
233  _underrun = true;
234  onUnderrun(_posX, pos_y);
235  pixel = underrun_pixel;
236  }
237  fb.pixel(_posX, pos_y) = pixel;
238  }
239 
240  // Fill remaining pixels with a dummy pixel value if we ran out of
241  // data
242  for (; _posX < x_end; ++_posX)
243  fb.pixel(_posX, pos_y) = underrun_pixel;
244 
245  // Schedule a new event to handle the next block of pixels
246  if (_posX < _timings.width) {
247  schedule(evRenderPixels, clockEdge(Cycles(pxl_count)));
248  } else {
249  if (pos_y == _timings.height - 1)
250  onFrameDone();
251  }
252 }
253 
254 void
256 {
257  _underrun = false;
258  line = 0;
259 
260  // Signal vsync end and render the frame
262  onVSyncEnd();
263 
264  // We only care about the visible screen area when rendering the
265  // frame
266  for (line = _timings.lineFirstVisible();
268  ++line) {
269 
270  _posX = 0;
271 
272  onHSyncBegin();
273  onHSyncEnd();
274 
275  renderLine();
276  }
277 
279  onFrameDone();
280 
281  // Signal vsync until the next frame begins
283  onVSyncBegin();
284 }
285 
286 void
288 {
289  const unsigned pos_y = posY();
290  const size_t _width = fb.width();
291 
292  auto pixel_it = fb.pixels.begin() + _width * pos_y;
293  panic_if(nextLine(pixel_it, _width) != _width,
294  "Unexpected underrun in BasePixelPump (%u, %u)", _width, pos_y);
295 }
296 
297 
299  const char *name, BasePixelPump *_parent, CallbackType _func)
300  : Event(), Drainable(),
301  _name(name), parent(*_parent), func(_func),
302  suspended(false),
303  relativeTick(0)
304 {
305  parent.pixelEvents.push_back(this);
306 }
307 
310 {
311  if (scheduled())
312  suspend();
313  return DrainState::Drained;
314 }
315 
316 void
318 {
319  if (suspended)
320  resume();
321 }
322 
323 void
325 {
326  assert(!scheduled());
327  Event::serialize(cp);
328  SERIALIZE_SCALAR(suspended);
329  SERIALIZE_SCALAR(relativeTick);
330 }
331 
332 void
334 {
335  Event::unserialize(cp);
336  UNSERIALIZE_SCALAR(suspended);
337  UNSERIALIZE_SCALAR(relativeTick);
338  assert(!scheduled());
339 }
340 
341 void
343 {
344  assert(scheduled());
345  assert(!suspended);
346 
347  suspended = true;
348  relativeTick = when() - curTick();
349  parent.deschedule(this);
350 }
351 
352 void
354 {
355  assert(!scheduled());
356  assert(suspended);
357  parent.schedule(this, relativeTick + curTick());
358  suspended = false;
359  relativeTick = 0;
360 }
361 
362 } // namespace gem5
Callback helper class with suspend support.
Definition: pixelpump.hh:304
PixelEvent(const char *name, BasePixelPump *parent, CallbackType func)
Definition: pixelpump.cc:298
DrainState drain() override
Draining is the process of clearing out the states of SimObjects.These are the SimObjects that are pa...
Definition: pixelpump.cc:309
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: pixelpump.cc:333
void drainResume() override
Resume execution after a successful drain.
Definition: pixelpump.cc:317
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition: pixelpump.cc:324
Timing generator for a pixel-based display.
Definition: pixelpump.hh:166
void stop()
Immediately stop pushing pixels.
Definition: pixelpump.cc:166
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: pixelpump.cc:126
bool active() const
Is the pixel pump active and refreshing the display?
Definition: pixelpump.hh:192
std::vector< PixelEvent * > pixelEvents
Convenience vector when doing operations on all events.
Definition: pixelpump.hh:345
void updateTimings(const DisplayTimings &timings)
Update frame size using display timing.
Definition: pixelpump.cc:143
FrameBuffer fb
Output frame buffer.
Definition: pixelpump.hh:216
virtual void onHSyncEnd()
Start of the first pixel after the HSync region.
Definition: pixelpump.hh:272
virtual void onVSyncBegin()
First pixel clock of the first VSync line.
Definition: pixelpump.hh:250
BasePixelPump(EventManager &em, ClockDomain &pxl_clk, unsigned pixel_chunk)
Definition: pixelpump.cc:91
const unsigned pixelChunk
Maximum number of pixels to handle per render callback.
Definition: pixelpump.hh:287
bool _underrun
Did a buffer underrun occur within this refresh interval?
Definition: pixelpump.hh:365
virtual void onVSyncEnd()
Callback on the first pixel of the line after the end VSync region (typically the first pixel of the ...
Definition: pixelpump.hh:256
PixelEvent evHSyncEnd
Definition: pixelpump.hh:350
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition: pixelpump.cc:112
virtual size_t nextLine(std::vector< Pixel >::iterator ps, size_t line_length)
Get the next line of pixels directly from memory.
Definition: pixelpump.hh:241
virtual ~BasePixelPump()
Definition: pixelpump.cc:107
DisplayTimings _timings
Definition: pixelpump.hh:354
PixelEvent evRenderPixels
Definition: pixelpump.hh:352
void start()
Starting pushing pixels in timing mode.
Definition: pixelpump.cc:159
virtual void onHSyncBegin()
Start of the HSync region.
Definition: pixelpump.hh:264
const DisplayTimings & timings() const
Get a constant reference of the current display timings.
Definition: pixelpump.hh:189
void renderLine()
Fast and event-free line rendering function.
Definition: pixelpump.cc:287
virtual bool nextPixel(Pixel &p)=0
Get the next pixel from the scan line buffer.
void renderFrame()
Render an entire frame in non-caching mode.
Definition: pixelpump.cc:255
unsigned posY() const
Current pixel position within the visible area.
Definition: pixelpump.hh:210
PixelEvent evBeginLine
Definition: pixelpump.hh:351
virtual void onUnderrun(unsigned x, unsigned y)
Buffer underrun occurred on a frame.
Definition: pixelpump.hh:284
unsigned line
Current line (including back porch, front porch, and vsync) within a frame.
Definition: pixelpump.hh:360
PixelEvent evHSyncBegin
Definition: pixelpump.hh:349
unsigned _posX
X-coordinate within the visible region of a frame.
Definition: pixelpump.hh:362
PixelEvent evVSyncEnd
Definition: pixelpump.hh:348
virtual void onFrameDone()
Finished displaying the visible region of a frame.
Definition: pixelpump.hh:287
The ClockDomain provides clock to group of clocked objects bundled under the same clock domain.
Definition: clock_domain.hh:72
Helper class for objects that need to be clocked.
Tick clockEdge(Cycles cycles=Cycles(0)) const
Determine the tick when a cycle begins, by default the current one, but the argument also enables the...
Cycles is a wrapper class for representing cycle counts, i.e.
Definition: types.hh:79
Interface for objects that might require draining before checkpointing.
Definition: drain.hh:235
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: eventq.cc:248
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition: eventq.cc:239
std::vector< Pixel > pixels
Frame buffer backing store.
Definition: framebuffer.hh:195
unsigned height() const
Frame buffer height in pixels.
Definition: framebuffer.hh:101
const Pixel & pixel(unsigned x, unsigned y) const
Get a pixel from an (x, y) coordinate.
Definition: framebuffer.hh:160
void resize(unsigned width, unsigned height)
Resize the frame buffer.
Definition: framebuffer.cc:83
unsigned width() const
Frame buffer width in pixels.
Definition: framebuffer.hh:99
Basic support for object serialization.
Definition: serialize.hh:170
DrainState
Object drain/handover states.
Definition: drain.hh:75
@ Drained
Buffers drained, ready for serialization/handover.
void deschedule(Event &event)
Definition: eventq.hh:1028
bool scheduled() const
Determine if the current event is scheduled.
Definition: eventq.hh:465
void schedule(Event &event, Tick when)
Definition: eventq.hh:1019
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
Definition: logging.hh:204
#define UNSERIALIZE_OBJ(obj)
Definition: serialize.hh:655
#define SERIALIZE_OBJ(obj)
This macro serializes an object into its own section.
Definition: serialize.hh:648
#define warn(...)
Definition: logging.hh:246
Bitfield< 4 > width
Definition: misc_types.hh:72
Bitfield< 10, 5 > event
Bitfield< 2 > em
Definition: misc.hh:607
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
Tick curTick()
The universal simulation clock.
Definition: cur_tick.hh:46
std::ostream CheckpointOut
Definition: serialize.hh:66
#define UNSERIALIZE_SCALAR(scalar)
Definition: serialize.hh:575
#define SERIALIZE_SCALAR(scalar)
Definition: serialize.hh:568
unsigned vSync
Vertical sync signal in lines.
Definition: pixelpump.hh:138
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: pixelpump.cc:76
unsigned linesPerFrame() const
Calculate the total number of lines in a frame.
Definition: pixelpump.hh:116
unsigned height
Display height in pixels.
Definition: pixelpump.hh:124
unsigned width
Display width in pixels.
Definition: pixelpump.hh:122
unsigned lineVBackPorchStart() const
Calculate the first line of the vertical back porch.
Definition: pixelpump.hh:95
unsigned hFrontPorch
Horizontal front porch in pixels.
Definition: pixelpump.hh:129
unsigned lineFrontPorchStart() const
Calculate the first line of the back porch.
Definition: pixelpump.hh:109
unsigned hSync
Horizontal sync signal length in pixels.
Definition: pixelpump.hh:131
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition: pixelpump.cc:61
static const DisplayTimings vga
Definition: pixelpump.hh:140
Cycles cyclesPerLine() const
How many pixel clocks are required for one line?
Definition: pixelpump.hh:74
DisplayTimings(unsigned width, unsigned height, unsigned hbp, unsigned h_sync, unsigned hfp, unsigned vbp, unsigned v_sync, unsigned vfp)
Create a display timing configuration struct.
Definition: pixelpump.cc:51
unsigned vFrontPorch
Vertical front porch in lines.
Definition: pixelpump.hh:136
unsigned hBackPorch
Horizontal back porch in pixels.
Definition: pixelpump.hh:127
unsigned vBackPorch
Vertical back porch in lines.
Definition: pixelpump.hh:134
unsigned lineVSyncStart() const
Calculate the first line of the vsync signal.
Definition: pixelpump.hh:88
unsigned lineFirstVisible() const
Calculate the first line of the visible region.
Definition: pixelpump.hh:102
Internal gem5 representation of a Pixel.
Definition: pixel.hh:59
const std::string & name()
Definition: trace.cc:49

Generated on Wed Dec 21 2022 10:22:34 for gem5 by doxygen 1.9.1