diff options
-rw-r--r-- | src/dev/arm/hdlcd.cc | 14 | ||||
-rw-r--r-- | src/dev/pixelpump.cc | 61 | ||||
-rw-r--r-- | src/dev/pixelpump.hh | 18 |
3 files changed, 82 insertions, 11 deletions
diff --git a/src/dev/arm/hdlcd.cc b/src/dev/arm/hdlcd.cc index 363aeba94..a92ae4627 100644 --- a/src/dev/arm/hdlcd.cc +++ b/src/dev/arm/hdlcd.cc @@ -1,5 +1,5 @@ /* - * 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 @@ -204,8 +204,11 @@ HDLcd::drainResume() // 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) @@ -476,7 +479,10 @@ HDLcd::cmdEnable() { createDmaEngine(); conv = pixelConverter(); - pixelPump.start(displayTimings()); + + // Update timing parameter before rendering frames + pixelPump.updateTimings(displayTimings()); + pixelPump.start(); } void diff --git a/src/dev/pixelpump.cc b/src/dev/pixelpump.cc index 3ffe96d96..e1cf73af6 100644 --- a/src/dev/pixelpump.cc +++ b/src/dev/pixelpump.cc @@ -1,5 +1,5 @@ /* - * 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 @@ -136,10 +136,11 @@ BasePixelPump::unserialize(CheckpointIn &cp) 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 @@ -149,9 +150,15 @@ BasePixelPump::start(const DisplayTimings &timings) // 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() { @@ -241,6 +248,54 @@ BasePixelPump::renderPixels() } } +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(), diff --git a/src/dev/pixelpump.hh b/src/dev/pixelpump.hh index 159ee79cb..bc21fca75 100644 --- a/src/dev/pixelpump.hh +++ b/src/dev/pixelpump.hh @@ -1,5 +1,5 @@ /* - * 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 @@ -148,15 +148,22 @@ class BasePixelPump 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(); @@ -285,6 +292,9 @@ class BasePixelPump 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; |