gem5  v21.1.0.2
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
gem5::curTick
Tick curTick()
The universal simulation clock.
Definition: cur_tick.hh:46
gem5::BasePixelPump::stop
void stop()
Immediately stop pushing pixels.
Definition: pixelpump.cc:166
UNSERIALIZE_OBJ
#define UNSERIALIZE_OBJ(obj)
Definition: serialize.hh:655
gem5::BasePixelPump::onVSyncEnd
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
gem5::BasePixelPump::BasePixelPump
BasePixelPump(EventManager &em, ClockDomain &pxl_clk, unsigned pixel_chunk)
Definition: pixelpump.cc:91
warn
#define warn(...)
Definition: logging.hh:245
gem5::DisplayTimings::vSync
unsigned vSync
Vertical sync signal in lines.
Definition: pixelpump.hh:138
gem5::DisplayTimings::cyclesPerLine
Cycles cyclesPerLine() const
How many pixel clocks are required for one line?
Definition: pixelpump.hh:74
gem5::BasePixelPump::_underrun
bool _underrun
Did a buffer underrun occur within this refresh interval?
Definition: pixelpump.hh:365
gem5::BasePixelPump::pixelEvents
std::vector< PixelEvent * > pixelEvents
Convenience vector when doing operations on all events.
Definition: pixelpump.hh:345
gem5::DisplayTimings::lineVSyncStart
unsigned lineVSyncStart() const
Calculate the first line of the vsync signal.
Definition: pixelpump.hh:88
UNSERIALIZE_SCALAR
#define UNSERIALIZE_SCALAR(scalar)
Definition: serialize.hh:575
gem5::BasePixelPump::evHSyncEnd
PixelEvent evHSyncEnd
Definition: pixelpump.hh:350
gem5::CheckpointIn
Definition: serialize.hh:68
gem5::MipsISA::event
Bitfield< 10, 5 > event
Definition: pra_constants.hh:300
gem5::BasePixelPump::unserialize
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: pixelpump.cc:126
gem5::BasePixelPump::renderLine
void renderLine()
Fast and event-free line rendering function.
Definition: pixelpump.cc:287
gem5::BasePixelPump::start
void start()
Starting pushing pixels in timing mode.
Definition: pixelpump.cc:159
gem5::BasePixelPump::renderFrame
void renderFrame()
Render an entire frame in non-caching mode.
Definition: pixelpump.cc:255
gem5::FrameBuffer::width
unsigned width() const
Frame buffer width in pixels.
Definition: framebuffer.hh:99
gem5::BasePixelPump::evBeginLine
PixelEvent evBeginLine
Definition: pixelpump.hh:351
gem5::DisplayTimings::vFrontPorch
unsigned vFrontPorch
Vertical front porch in lines.
Definition: pixelpump.hh:136
gem5::EventManager::schedule
void schedule(Event &event, Tick when)
Definition: eventq.hh:1019
pixelpump.hh
gem5::BasePixelPump::onFrameDone
virtual void onFrameDone()
Finished displaying the visible region of a frame.
Definition: pixelpump.hh:287
gem5::DisplayTimings::vga
static const DisplayTimings vga
Definition: pixelpump.hh:140
gem5::DisplayTimings::height
unsigned height
Display height in pixels.
Definition: pixelpump.hh:124
gem5::DisplayTimings::hBackPorch
unsigned hBackPorch
Horizontal back porch in pixels.
Definition: pixelpump.hh:127
gem5::BasePixelPump::renderPixels
void renderPixels()
Definition: pixelpump.cc:218
gem5::DisplayTimings
Definition: pixelpump.hh:51
gem5::BasePixelPump::PixelEvent::drainResume
void drainResume() override
Resume execution after a successful drain.
Definition: pixelpump.cc:317
gem5::Clocked
Helper class for objects that need to be clocked.
Definition: clocked_object.hh:62
gem5::BasePixelPump::PixelEvent
Callback helper class with suspend support.
Definition: pixelpump.hh:303
gem5::FrameBuffer::height
unsigned height() const
Frame buffer height in pixels.
Definition: framebuffer.hh:101
gem5::Cycles
Cycles is a wrapper class for representing cycle counts, i.e.
Definition: types.hh:78
gem5::BasePixelPump::onVSyncBegin
virtual void onVSyncBegin()
First pixel clock of the first VSync line.
Definition: pixelpump.hh:250
gem5::BasePixelPump::nextLine
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
gem5::DisplayTimings::serialize
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition: pixelpump.cc:61
gem5::X86ISA::em
Bitfield< 2 > em
Definition: misc.hh:608
gem5::BasePixelPump::PixelEvent::suspend
void suspend()
Definition: pixelpump.cc:342
gem5::EventManager
Definition: eventq.hh:987
gem5::Serializable
Basic support for object serialization.
Definition: serialize.hh:169
gem5::BasePixelPump::PixelEvent::resume
void resume()
Definition: pixelpump.cc:353
gem5::DrainState
DrainState
Object drain/handover states.
Definition: drain.hh:74
gem5::DisplayTimings::linesPerFrame
unsigned linesPerFrame() const
Calculate the total number of lines in a frame.
Definition: pixelpump.hh:116
gem5::ClockDomain
The ClockDomain provides clock to group of clocked objects bundled under the same clock domain.
Definition: clock_domain.hh:71
gem5::ArmISA::width
Bitfield< 4 > width
Definition: misc_types.hh:71
SERIALIZE_OBJ
#define SERIALIZE_OBJ(obj)
Definition: serialize.hh:648
gem5::Event
Definition: eventq.hh:251
gem5::DisplayTimings::DisplayTimings
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
gem5::BasePixelPump::pixelChunk
const unsigned pixelChunk
Maximum number of pixels to handle per render callback.
Definition: pixelpump.hh:287
gem5::BasePixelPump::serialize
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition: pixelpump.cc:112
gem5::FrameBuffer::pixel
const Pixel & pixel(unsigned x, unsigned y) const
Get a pixel from an (x, y) coordinate.
Definition: framebuffer.hh:160
gem5::BasePixelPump::PixelEvent::PixelEvent
PixelEvent(const char *name, BasePixelPump *parent, CallbackType func)
Definition: pixelpump.cc:298
gem5::DisplayTimings::hSync
unsigned hSync
Horizontal sync signal length in pixels.
Definition: pixelpump.hh:131
gem5::BasePixelPump::updateTimings
void updateTimings(const DisplayTimings &timings)
Update frame size using display timing.
Definition: pixelpump.cc:143
gem5::BasePixelPump::timings
const DisplayTimings & timings() const
Get a constant reference of the current display timings.
Definition: pixelpump.hh:189
gem5::FrameBuffer::resize
void resize(unsigned width, unsigned height)
Resize the frame buffer.
Definition: framebuffer.cc:83
gem5::DisplayTimings::lineFrontPorchStart
unsigned lineFrontPorchStart() const
Calculate the first line of the back porch.
Definition: pixelpump.hh:109
gem5::BasePixelPump::onHSyncBegin
virtual void onHSyncBegin()
Start of the HSync region.
Definition: pixelpump.hh:264
gem5::DisplayTimings::hFrontPorch
unsigned hFrontPorch
Horizontal front porch in pixels.
Definition: pixelpump.hh:129
gem5::DrainState::Drained
@ Drained
Buffers drained, ready for serialization/handover.
gem5::BasePixelPump::_timings
DisplayTimings _timings
Definition: pixelpump.hh:354
gem5::DisplayTimings::unserialize
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: pixelpump.cc:76
name
const std::string & name()
Definition: trace.cc:49
SERIALIZE_SCALAR
#define SERIALIZE_SCALAR(scalar)
Definition: serialize.hh:568
gem5::BasePixelPump::active
bool active() const
Is the pixel pump active and refreshing the display?
Definition: pixelpump.hh:192
gem5::Clocked::clockEdge
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...
Definition: clocked_object.hh:177
gem5::Pixel
Internal gem5 representation of a Pixel.
Definition: pixel.hh:58
gem5::DisplayTimings::width
unsigned width
Display width in pixels.
Definition: pixelpump.hh:122
gem5::BasePixelPump::nextPixel
virtual bool nextPixel(Pixel &p)=0
Get the next pixel from the scan line buffer.
gem5::EventManager::deschedule
void deschedule(Event &event)
Definition: eventq.hh:1028
gem5::DisplayTimings::vBackPorch
unsigned vBackPorch
Vertical back porch in lines.
Definition: pixelpump.hh:134
gem5::BasePixelPump::onHSyncEnd
virtual void onHSyncEnd()
Start of the first pixel after the HSync region.
Definition: pixelpump.hh:272
gem5::BasePixelPump::line
unsigned line
Current line (including back porch, front porch, and vsync) within a frame.
Definition: pixelpump.hh:360
gem5::BasePixelPump::PixelEvent::drain
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
gem5::BasePixelPump::PixelEvent::unserialize
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: pixelpump.cc:333
panic_if
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
Definition: logging.hh:203
gem5::BasePixelPump::PixelEvent::serialize
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition: pixelpump.cc:324
gem5::BasePixelPump::_posX
unsigned _posX
X-coordinate within the visible region of a frame.
Definition: pixelpump.hh:362
gem5::Event::serialize
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition: eventq.cc:239
gem5::BasePixelPump::evVSyncEnd
PixelEvent evVSyncEnd
Definition: pixelpump.hh:348
gem5::FrameBuffer::pixels
std::vector< Pixel > pixels
Frame buffer backing store.
Definition: framebuffer.hh:195
gem5::Event::unserialize
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: eventq.cc:248
gem5::Drainable
Interface for objects that might require draining before checkpointing.
Definition: drain.hh:234
gem5::BasePixelPump::PixelEvent::parent
BasePixelPump & parent
Definition: pixelpump.hh:331
logging.hh
gem5::BasePixelPump::evRenderPixels
PixelEvent evRenderPixels
Definition: pixelpump.hh:352
gem5::BasePixelPump::posY
unsigned posY() const
Current pixel position within the visible area.
Definition: pixelpump.hh:210
gem5::DisplayTimings::lineVBackPorchStart
unsigned lineVBackPorchStart() const
Calculate the first line of the vertical back porch.
Definition: pixelpump.hh:95
gem5::CheckpointOut
std::ostream CheckpointOut
Definition: serialize.hh:66
gem5::BasePixelPump::onUnderrun
virtual void onUnderrun(unsigned x, unsigned y)
Buffer underrun occurred on a frame.
Definition: pixelpump.hh:284
gem5::BasePixelPump::beginLine
void beginLine()
Definition: pixelpump.cc:185
gem5::BasePixelPump::evHSyncBegin
PixelEvent evHSyncBegin
Definition: pixelpump.hh:349
gem5::BasePixelPump::~BasePixelPump
virtual ~BasePixelPump()
Definition: pixelpump.cc:107
gem5
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
Definition: decoder.cc:40
gem5::BasePixelPump
Timing generator for a pixel-based display.
Definition: pixelpump.hh:163
gem5::Event::scheduled
bool scheduled() const
Determine if the current event is scheduled.
Definition: eventq.hh:465
gem5::DisplayTimings::lineFirstVisible
unsigned lineFirstVisible() const
Calculate the first line of the visible region.
Definition: pixelpump.hh:102
gem5::BasePixelPump::fb
FrameBuffer fb
Output frame buffer.
Definition: pixelpump.hh:216

Generated on Tue Sep 21 2021 12:25:17 for gem5 by doxygen 1.8.17