gem5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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  * Authors: Andreas Sandberg
38  */
39 
40 #include "dev/pixelpump.hh"
41 
43  640, 480,
44  48, 96, 16,
45  33, 2, 10);
46 
47 
48 DisplayTimings::DisplayTimings(unsigned _width, unsigned _height,
49  unsigned hbp, unsigned h_sync, unsigned hfp,
50  unsigned vbp, unsigned v_sync, unsigned vfp)
51  : width(_width), height(_height),
52  hBackPorch(hbp), hFrontPorch(hfp), hSync(h_sync),
53  vBackPorch(vbp), vFrontPorch(vfp), vSync(v_sync)
54 {
55 }
56 
57 void
59 {
62 
66 
70 }
71 
72 void
74 {
77 
81 
85 }
86 
87 
89  unsigned pixel_chunk)
90  : EventManager(em), Clocked(pxl_clk), Serializable(),
91  pixelChunk(pixel_chunk),
92  pixelEvents(),
93  evVSyncBegin("evVSyncBegin", this, &BasePixelPump::onVSyncBegin),
94  evVSyncEnd("evVSyncEnd", this, &BasePixelPump::onVSyncEnd),
95  evHSyncBegin("evHSyncBegin", this, &BasePixelPump::onHSyncBegin),
96  evHSyncEnd("evHSyncEnd", this, &BasePixelPump::onHSyncEnd),
97  evBeginLine("evBeginLine", this, &BasePixelPump::beginLine),
98  evRenderPixels("evRenderPixels", this, &BasePixelPump::renderPixels),
99  _timings(DisplayTimings::vga),
100  line(0), _posX(0), _underrun(false)
101 {
102 }
103 
105 {
106 }
107 
108 void
110 {
114 
116  SERIALIZE_OBJ(fb);
117 
118  for (PixelEvent *event : pixelEvents)
119  event->serializeSection(cp, event->name());
120 }
121 
122 void
124 {
128 
131 
132  // We don't need to reschedule the event here since the event was
133  // suspended by PixelEvent::drain() and will be rescheduled by
134  // PixelEvent::drainResume().
135  for (PixelEvent *event : pixelEvents)
136  event->unserializeSection(cp, event->name());
137 }
138 
139 void
141 {
142  panic_if(active(), "Trying to update timings in active PixelPump\n");
143 
144  _timings = timings;
145 
146  // Resize the frame buffer if needed
147  if (_timings.width != fb.width() || _timings.height != fb.height())
148  fb.resize(timings.width, timings.height);
149 
150  // Set the current line past the last line in the frame. This
151  // triggers the new frame logic in beginLine().
153 }
154 
155 void
157 {
159 }
160 
161 
162 void
164 {
165  if (evVSyncEnd.scheduled())
167 
168  if (evHSyncBegin.scheduled())
170 
171  if (evHSyncEnd.scheduled())
173 
174  if (evBeginLine.scheduled())
176 
179 }
180 
181 void
183 {
184  _posX = 0;
185  line++;
186  if (line >= _timings.linesPerFrame()) {
187  _underrun = false;
188  line = 0;
189  }
190 
191  if (line == _timings.lineVSyncStart()) {
192  onVSyncBegin();
193  } else if (line == _timings.lineVBackPorchStart()) {
194  onVSyncEnd();
195  }
196 
197  const Cycles h_sync_begin(0);
198  schedule(evHSyncBegin, clockEdge(h_sync_begin));
199 
200  const Cycles h_sync_end(h_sync_begin + _timings.hSync);
201  schedule(evHSyncEnd, clockEdge(h_sync_end));
202 
203  // Visible area
204  if (line >= _timings.lineFirstVisible() &&
206 
207  const Cycles h_first_visible(h_sync_end + _timings.hBackPorch);
208  schedule(evRenderPixels, clockEdge(h_first_visible));
209  }
210 
212 }
213 
214 void
216 {
217  // Try to handle multiple pixels at a time; doing so reduces the
218  // accuracy of the underrun detection but lowers simulation
219  // overhead
220  const unsigned x_end(std::min(_posX + pixelChunk, _timings.width));
221  const unsigned pxl_count(x_end - _posX);
222  const unsigned pos_y(posY());
223 
224  Pixel pixel(0, 0, 0);
225  const Pixel underrun_pixel(0, 0, 0);
226  for (; _posX < x_end && !_underrun; ++_posX) {
227  if (!nextPixel(pixel)) {
228  warn("Input buffer underrun in BasePixelPump (%u, %u)\n",
229  _posX, pos_y);
230  _underrun = true;
231  onUnderrun(_posX, pos_y);
232  pixel = underrun_pixel;
233  }
234  fb.pixel(_posX, pos_y) = pixel;
235  }
236 
237  // Fill remaining pixels with a dummy pixel value if we ran out of
238  // data
239  for (; _posX < x_end; ++_posX)
240  fb.pixel(_posX, pos_y) = underrun_pixel;
241 
242  // Schedule a new event to handle the next block of pixels
243  if (_posX < _timings.width) {
244  schedule(evRenderPixels, clockEdge(Cycles(pxl_count)));
245  } else {
246  if (pos_y == _timings.height - 1)
247  onFrameDone();
248  }
249 }
250 
251 void
253 {
254  _underrun = false;
255  line = 0;
256 
257  // Signal vsync end and render the frame
259  onVSyncEnd();
260 
261  // We only care about the visible screen area when rendering the
262  // frame
263  for (line = _timings.lineFirstVisible();
265  ++line) {
266 
267  _posX = 0;
268 
269  onHSyncBegin();
270  onHSyncEnd();
271 
272  renderLine();
273  }
274 
276  onFrameDone();
277 
278  // Signal vsync until the next frame begins
280  onVSyncBegin();
281 }
282 
283 void
285 {
286  const unsigned pos_y(posY());
287 
288  Pixel pixel(0, 0, 0);
289  for (_posX = 0; _posX < _timings.width; ++_posX) {
290  if (!nextPixel(pixel)) {
291  panic("Unexpected underrun in BasePixelPump (%u, %u)\n",
292  _posX, pos_y);
293  }
294  fb.pixel(_posX, pos_y) = pixel;
295  }
296 }
297 
298 
300  const char *name, BasePixelPump *_parent, CallbackType _func)
301  : Event(), Drainable(),
302  _name(name), parent(*_parent), func(_func),
303  suspended(false),
304  relativeTick(0)
305 {
306  parent.pixelEvents.push_back(this);
307 }
308 
311 {
312  if (scheduled())
313  suspend();
314  return DrainState::Drained;
315 }
316 
317 void
319 {
320  if (suspended)
321  resume();
322 }
323 
324 void
326 {
327  assert(!scheduled());
328  Event::serialize(cp);
329  SERIALIZE_SCALAR(suspended);
330  SERIALIZE_SCALAR(relativeTick);
331 }
332 
333 void
335 {
336  Event::unserialize(cp);
337  UNSERIALIZE_SCALAR(suspended);
338  UNSERIALIZE_SCALAR(relativeTick);
339  assert(!scheduled());
340 }
341 
342 void
344 {
345  assert(scheduled());
346  assert(!suspended);
347 
348  suspended = true;
349  relativeTick = when() - curTick();
350  parent.deschedule(this);
351 }
352 
353 void
355 {
356  assert(!scheduled());
357  assert(suspended);
358  parent.schedule(this, relativeTick + curTick());
359  suspended = false;
360  relativeTick = 0;
361 }
unsigned vSync
Vertical sync signal in lines.
Definition: pixelpump.hh:121
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition: eventq.cc:244
const Pixel & pixel(unsigned x, unsigned y) const
Get a pixel from an (x, y) coordinate.
Definition: framebuffer.hh:336
std::vector< PixelEvent * > pixelEvents
Convenience vector when doing operations on all events.
Definition: pixelpump.hh:299
Timing generator for a pixel-based display.
Definition: pixelpump.hh:146
Cycles is a wrapper class for representing cycle counts, i.e.
Definition: types.hh:83
unsigned lineFrontPorchStart() const
Calculate the first line of the back porch.
Definition: pixelpump.hh:95
virtual void onFrameDone()
Finished displaying the visible region of a frame.
Definition: pixelpump.hh:244
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: eventq.cc:253
void beginLine()
Definition: pixelpump.cc:182
const std::string & name()
Definition: trace.cc:49
bool _underrun
Did a buffer underrun occur within this refresh interval?
Definition: pixelpump.hh:319
DrainState
Object drain/handover states.
Definition: drain.hh:71
virtual void onHSyncBegin()
Start of the HSync region.
Definition: pixelpump.hh:221
#define panic(...)
Definition: misc.hh:153
void resize(unsigned width, unsigned height)
Resize the frame buffer.
Definition: framebuffer.cc:143
DrainState drain() override
Notify an object that it needs to drain its state.
Definition: pixelpump.cc:310
unsigned line
Current line (including back porch, front porch, and vsync) within a frame.
Definition: pixelpump.hh:314
panic_if(!root,"Invalid expression\n")
bool scheduled() const
Determine if the current event is scheduled.
Definition: eventq.hh:381
unsigned posY() const
Current pixel position within the visible area.
Definition: pixelpump.hh:190
Bitfield< 2 > em
Definition: misc.hh:603
void stop()
Immediately stop pushing pixels.
Definition: pixelpump.cc:163
unsigned hBackPorch
Horizontal back porch in pixels.
Definition: pixelpump.hh:110
#define UNSERIALIZE_OBJ(obj)
Definition: serialize.hh:179
void renderLine()
Fast and event-free line rendering function.
Definition: pixelpump.cc:284
unsigned linesPerFrame() const
Calculate the total number of lines in a frame.
Definition: pixelpump.hh:100
unsigned vFrontPorch
Vertical front porch in lines.
Definition: pixelpump.hh:119
Cycles cyclesPerLine() const
How many pixel clocks are required for one line?
Definition: pixelpump.hh:70
void start()
Starting pushing pixels in timing mode.
Definition: pixelpump.cc:156
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: pixelpump.cc:123
void deschedule(Event &event)
Definition: eventq.hh:734
PixelEvent(const char *name, BasePixelPump *parent, CallbackType func)
Definition: pixelpump.cc:299
#define warn(...)
Definition: misc.hh:219
BasePixelPump(EventManager &em, ClockDomain &pxl_clk, unsigned pixel_chunk)
Definition: pixelpump.cc:88
Callback helper class with suspend support.
Definition: pixelpump.hh:260
Interface for objects that might require draining before checkpointing.
Definition: drain.hh:223
DisplayTimings _timings
Definition: pixelpump.hh:308
#define UNSERIALIZE_SCALAR(scalar)
Definition: serialize.hh:145
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...
virtual void onUnderrun(unsigned x, unsigned y)
Buffer underrun occurred on a frame.
Definition: pixelpump.hh:241
Tick curTick()
The current simulated tick.
Definition: core.hh:47
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: pixelpump.cc:334
unsigned height() const
Frame buffer height in pixels.
Definition: framebuffer.hh:277
bool active() const
Is the pixel pump active and refreshing the display?
Definition: pixelpump.hh:175
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition: pixelpump.cc:109
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:213
void renderFrame()
Render an entire frame in KVM execution mode.
Definition: pixelpump.cc:252
virtual void onHSyncEnd()
Start of the first pixel after the HSync region.
Definition: pixelpump.hh:229
void renderPixels()
Definition: pixelpump.cc:215
#define SERIALIZE_OBJ(obj)
Definition: serialize.hh:178
BasePixelPump & parent
Definition: pixelpump.hh:285
PixelEvent evHSyncEnd
Definition: pixelpump.hh:304
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: pixelpump.cc:73
PixelEvent evVSyncEnd
Definition: pixelpump.hh:302
unsigned _posX
X-coordinate within the visible region of a frame.
Definition: pixelpump.hh:316
void updateTimings(const DisplayTimings &timings)
Update frame size using display timing.
Definition: pixelpump.cc:140
FrameBuffer fb
Output frame buffer.
Definition: pixelpump.hh:195
virtual void onVSyncBegin()
First pixel clock of the first VSync line.
Definition: pixelpump.hh:207
Helper class for objects that need to be clocked.
Draining buffers pending serialization/handover.
Bitfield< 10, 5 > event
unsigned height
Display height in pixels.
Definition: pixelpump.hh:107
Basic support for object serialization.
Definition: serialize.hh:220
PixelEvent evRenderPixels
Definition: pixelpump.hh:306
const unsigned pixelChunk
Maximum number of pixels to handle per render callback.
Definition: pixelpump.hh:244
#define SERIALIZE_SCALAR(scalar)
Definition: serialize.hh:143
PixelEvent evBeginLine
Definition: pixelpump.hh:305
unsigned hFrontPorch
Horizontal front porch in pixels.
Definition: pixelpump.hh:112
PixelEvent evHSyncBegin
Definition: pixelpump.hh:303
unsigned lineFirstVisible() const
Calculate the first line of the visible region.
Definition: pixelpump.hh:90
unsigned hSync
Horizontal sync signal length in pixels.
Definition: pixelpump.hh:114
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition: pixelpump.cc:58
The ClockDomain provides clock to group of clocked objects bundled under the same clock domain...
Definition: clock_domain.hh:73
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition: pixelpump.cc:325
std::ostream CheckpointOut
Definition: serialize.hh:67
unsigned width() const
Frame buffer width in pixels.
Definition: framebuffer.hh:275
Definition: eventq.hh:185
Bitfield< 4 > width
Definition: miscregs.hh:1383
void schedule(Event &event, Tick when)
Definition: eventq.hh:728
unsigned vBackPorch
Vertical back porch in lines.
Definition: pixelpump.hh:117
static const DisplayTimings vga
Definition: pixelpump.hh:123
virtual bool nextPixel(Pixel &p)=0
Get the next pixel from the scan line buffer.
Internal gem5 representation of a Pixel.
Definition: framebuffer.hh:58
unsigned lineVBackPorchStart() const
Calculate the first line of the vertical back porch.
Definition: pixelpump.hh:85
unsigned lineVSyncStart() const
Calculate the first line of the vsync signal.
Definition: pixelpump.hh:80
void drainResume() override
Resume execution after a successful drain.
Definition: pixelpump.cc:318
unsigned width
Display width in pixels.
Definition: pixelpump.hh:105
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:48
const DisplayTimings & timings() const
Get a constant reference of the current display timings.
Definition: pixelpump.hh:172
virtual ~BasePixelPump()
Definition: pixelpump.cc:104

Generated on Fri Jun 9 2017 13:03:46 for gem5 by doxygen 1.8.6