/*
- * Copyright (c) 2010-2013, 2015 ARM Limited
+ * Copyright (c) 2010-2013, 2015, 2017 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
// We restored from an old checkpoint without a pixel pump, start
// an new refresh. This typically happens when restoring from old
// checkpoints.
- if (enabled() && !pixelPump.active())
- pixelPump.start(displayTimings());
+ if (enabled() && !pixelPump.active()) {
+ // Update timing parameter before rendering frames
+ pixelPump.updateTimings(displayTimings());
+ pixelPump.start();
+ }
// We restored from a checkpoint and need to update the VNC server
if (pixelPump.active() && vnc)
{
createDmaEngine();
conv = pixelConverter();
- pixelPump.start(displayTimings());
+
+ // Update timing parameter before rendering frames
+ pixelPump.updateTimings(displayTimings());
+ pixelPump.start();
}
void
/*
- * Copyright (c) 2015 ARM Limited
+ * Copyright (c) 2015, 2017 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
event->unserializeSection(cp, event->name());
}
-
void
-BasePixelPump::start(const DisplayTimings &timings)
+BasePixelPump::updateTimings(const DisplayTimings &timings)
{
+ panic_if(active(), "Trying to update timings in active PixelPump\n");
+
_timings = timings;
// Resize the frame buffer if needed
// Set the current line past the last line in the frame. This
// triggers the new frame logic in beginLine().
line = _timings.linesPerFrame();
+}
+
+void
+BasePixelPump::start()
+{
schedule(evBeginLine, clockEdge());
}
+
void
BasePixelPump::stop()
{
}
}
+void
+BasePixelPump::renderFrame()
+{
+ _underrun = false;
+ line = 0;
+
+ // Signal vsync end and render the frame
+ line = _timings.lineVBackPorchStart();
+ onVSyncEnd();
+
+ // We only care about the visible screen area when rendering the
+ // frame
+ for (line = _timings.lineFirstVisible();
+ line < _timings.lineFrontPorchStart();
+ ++line) {
+
+ _posX = 0;
+
+ onHSyncBegin();
+ onHSyncEnd();
+
+ renderLine();
+ }
+
+ line = _timings.lineFrontPorchStart() - 1;
+ onFrameDone();
+
+ // Signal vsync until the next frame begins
+ line = _timings.lineVSyncStart();
+ onVSyncBegin();
+}
+
+void
+BasePixelPump::renderLine()
+{
+ const unsigned pos_y(posY());
+
+ Pixel pixel(0, 0, 0);
+ for (_posX = 0; _posX < _timings.width; ++_posX) {
+ if (!nextPixel(pixel)) {
+ panic("Unexpected underrun in BasePixelPump (%u, %u)\n",
+ _posX, pos_y);
+ }
+ fb.pixel(_posX, pos_y) = pixel;
+ }
+}
+
+
BasePixelPump::PixelEvent::PixelEvent(
const char *name, BasePixelPump *_parent, CallbackType _func)
: Event(), Drainable(),
/*
- * Copyright (c) 2015 ARM Limited
+ * Copyright (c) 2015, 2017 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
public Serializable
{
public:
- BasePixelPump(EventManager &em, ClockDomain &pxl_clk, unsigned pixel_chunk);
+ BasePixelPump(EventManager &em, ClockDomain &pxl_clk,
+ unsigned pixel_chunk);
virtual ~BasePixelPump();
void serialize(CheckpointOut &cp) const override;
void unserialize(CheckpointIn &cp) override;
public: // Public API
- /** Starting pushing pixels using the supplied display timings. */
- void start(const DisplayTimings &timings);
+ /** Update frame size using display timing */
+ void updateTimings(const DisplayTimings &timings);
+
+ /** Render an entire frame in KVM execution mode */
+ void renderFrame();
+
+ /** Starting pushing pixels in timing mode */
+ void start();
/** Immediately stop pushing pixels */
void stop();
void beginLine();
void renderPixels();
+ /** Fast and event-free line rendering function */
+ void renderLine();
+
/** Convenience vector when doing operations on all events */
std::vector<PixelEvent *> pixelEvents;