pixelpump.cc revision 11897
111012Sandreas.sandberg@arm.com/*
211897Ssudhanshu.jha@arm.com * Copyright (c) 2015, 2017 ARM Limited
311012Sandreas.sandberg@arm.com * All rights reserved
411012Sandreas.sandberg@arm.com *
511012Sandreas.sandberg@arm.com * The license below extends only to copyright in the software and shall
611012Sandreas.sandberg@arm.com * not be construed as granting a license to any other intellectual
711012Sandreas.sandberg@arm.com * property including but not limited to intellectual property relating
811012Sandreas.sandberg@arm.com * to a hardware implementation of the functionality of the software
911012Sandreas.sandberg@arm.com * licensed hereunder.  You may use the software subject to the license
1011012Sandreas.sandberg@arm.com * terms below provided that you ensure that this notice is replicated
1111012Sandreas.sandberg@arm.com * unmodified and in its entirety in all distributions of the software,
1211012Sandreas.sandberg@arm.com * modified or unmodified, in source code or in binary form.
1311012Sandreas.sandberg@arm.com *
1411012Sandreas.sandberg@arm.com * Redistribution and use in source and binary forms, with or without
1511012Sandreas.sandberg@arm.com * modification, are permitted provided that the following conditions are
1611012Sandreas.sandberg@arm.com * met: redistributions of source code must retain the above copyright
1711012Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer;
1811012Sandreas.sandberg@arm.com * redistributions in binary form must reproduce the above copyright
1911012Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer in the
2011012Sandreas.sandberg@arm.com * documentation and/or other materials provided with the distribution;
2111012Sandreas.sandberg@arm.com * neither the name of the copyright holders nor the names of its
2211012Sandreas.sandberg@arm.com * contributors may be used to endorse or promote products derived from
2311012Sandreas.sandberg@arm.com * this software without specific prior written permission.
2411012Sandreas.sandberg@arm.com *
2511012Sandreas.sandberg@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2611012Sandreas.sandberg@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2711012Sandreas.sandberg@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2811012Sandreas.sandberg@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2911012Sandreas.sandberg@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3011012Sandreas.sandberg@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3111012Sandreas.sandberg@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3211012Sandreas.sandberg@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3311012Sandreas.sandberg@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3411012Sandreas.sandberg@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3511012Sandreas.sandberg@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3611012Sandreas.sandberg@arm.com *
3711012Sandreas.sandberg@arm.com * Authors: Andreas Sandberg
3811012Sandreas.sandberg@arm.com */
3911012Sandreas.sandberg@arm.com
4011012Sandreas.sandberg@arm.com#include "dev/pixelpump.hh"
4111012Sandreas.sandberg@arm.com
4211012Sandreas.sandberg@arm.comconst DisplayTimings DisplayTimings::vga(
4311012Sandreas.sandberg@arm.com    640, 480,
4411012Sandreas.sandberg@arm.com    48, 96, 16,
4511012Sandreas.sandberg@arm.com    33, 2, 10);
4611012Sandreas.sandberg@arm.com
4711012Sandreas.sandberg@arm.com
4811012Sandreas.sandberg@arm.comDisplayTimings::DisplayTimings(unsigned _width, unsigned _height,
4911012Sandreas.sandberg@arm.com                               unsigned hbp, unsigned h_sync, unsigned hfp,
5011012Sandreas.sandberg@arm.com                               unsigned vbp, unsigned v_sync, unsigned vfp)
5111012Sandreas.sandberg@arm.com    : width(_width), height(_height),
5211012Sandreas.sandberg@arm.com      hBackPorch(hbp), hFrontPorch(hfp), hSync(h_sync),
5311012Sandreas.sandberg@arm.com      vBackPorch(vbp), vFrontPorch(vfp), vSync(v_sync)
5411012Sandreas.sandberg@arm.com{
5511012Sandreas.sandberg@arm.com}
5611012Sandreas.sandberg@arm.com
5711012Sandreas.sandberg@arm.comvoid
5811012Sandreas.sandberg@arm.comDisplayTimings::serialize(CheckpointOut &cp) const
5911012Sandreas.sandberg@arm.com{
6011012Sandreas.sandberg@arm.com    SERIALIZE_SCALAR(width);
6111012Sandreas.sandberg@arm.com    SERIALIZE_SCALAR(height);
6211012Sandreas.sandberg@arm.com
6311012Sandreas.sandberg@arm.com    SERIALIZE_SCALAR(hBackPorch);
6411012Sandreas.sandberg@arm.com    SERIALIZE_SCALAR(hFrontPorch);
6511012Sandreas.sandberg@arm.com    SERIALIZE_SCALAR(hSync);
6611012Sandreas.sandberg@arm.com
6711012Sandreas.sandberg@arm.com    SERIALIZE_SCALAR(vBackPorch);
6811012Sandreas.sandberg@arm.com    SERIALIZE_SCALAR(vFrontPorch);
6911012Sandreas.sandberg@arm.com    SERIALIZE_SCALAR(vSync);
7011012Sandreas.sandberg@arm.com}
7111012Sandreas.sandberg@arm.com
7211012Sandreas.sandberg@arm.comvoid
7311012Sandreas.sandberg@arm.comDisplayTimings::unserialize(CheckpointIn &cp)
7411012Sandreas.sandberg@arm.com{
7511012Sandreas.sandberg@arm.com    UNSERIALIZE_SCALAR(width);
7611012Sandreas.sandberg@arm.com    UNSERIALIZE_SCALAR(height);
7711012Sandreas.sandberg@arm.com
7811012Sandreas.sandberg@arm.com    UNSERIALIZE_SCALAR(hBackPorch);
7911012Sandreas.sandberg@arm.com    UNSERIALIZE_SCALAR(hFrontPorch);
8011012Sandreas.sandberg@arm.com    UNSERIALIZE_SCALAR(hSync);
8111012Sandreas.sandberg@arm.com
8211012Sandreas.sandberg@arm.com    UNSERIALIZE_SCALAR(vBackPorch);
8311012Sandreas.sandberg@arm.com    UNSERIALIZE_SCALAR(vFrontPorch);
8411012Sandreas.sandberg@arm.com    UNSERIALIZE_SCALAR(vSync);
8511012Sandreas.sandberg@arm.com}
8611012Sandreas.sandberg@arm.com
8711012Sandreas.sandberg@arm.com
8811012Sandreas.sandberg@arm.comBasePixelPump::BasePixelPump(EventManager &em, ClockDomain &pxl_clk,
8911012Sandreas.sandberg@arm.com                             unsigned pixel_chunk)
9011012Sandreas.sandberg@arm.com    : EventManager(em), Clocked(pxl_clk), Serializable(),
9111012Sandreas.sandberg@arm.com      pixelChunk(pixel_chunk),
9211012Sandreas.sandberg@arm.com      pixelEvents(),
9311012Sandreas.sandberg@arm.com      evVSyncBegin("evVSyncBegin", this, &BasePixelPump::onVSyncBegin),
9411012Sandreas.sandberg@arm.com      evVSyncEnd("evVSyncEnd", this, &BasePixelPump::onVSyncEnd),
9511012Sandreas.sandberg@arm.com      evHSyncBegin("evHSyncBegin", this, &BasePixelPump::onHSyncBegin),
9611012Sandreas.sandberg@arm.com      evHSyncEnd("evHSyncEnd", this, &BasePixelPump::onHSyncEnd),
9711012Sandreas.sandberg@arm.com      evBeginLine("evBeginLine", this, &BasePixelPump::beginLine),
9811012Sandreas.sandberg@arm.com      evRenderPixels("evRenderPixels", this, &BasePixelPump::renderPixels),
9911012Sandreas.sandberg@arm.com      _timings(DisplayTimings::vga),
10011012Sandreas.sandberg@arm.com      line(0), _posX(0), _underrun(false)
10111012Sandreas.sandberg@arm.com{
10211012Sandreas.sandberg@arm.com}
10311012Sandreas.sandberg@arm.com
10411012Sandreas.sandberg@arm.comBasePixelPump::~BasePixelPump()
10511012Sandreas.sandberg@arm.com{
10611012Sandreas.sandberg@arm.com}
10711012Sandreas.sandberg@arm.com
10811012Sandreas.sandberg@arm.comvoid
10911012Sandreas.sandberg@arm.comBasePixelPump::serialize(CheckpointOut &cp) const
11011012Sandreas.sandberg@arm.com{
11111012Sandreas.sandberg@arm.com    SERIALIZE_SCALAR(line);
11211012Sandreas.sandberg@arm.com    SERIALIZE_SCALAR(_posX);
11311012Sandreas.sandberg@arm.com    SERIALIZE_SCALAR(_underrun);
11411012Sandreas.sandberg@arm.com
11511012Sandreas.sandberg@arm.com    SERIALIZE_OBJ(_timings);
11611012Sandreas.sandberg@arm.com    SERIALIZE_OBJ(fb);
11711012Sandreas.sandberg@arm.com
11811012Sandreas.sandberg@arm.com    for (PixelEvent *event : pixelEvents)
11911012Sandreas.sandberg@arm.com        event->serializeSection(cp, event->name());
12011012Sandreas.sandberg@arm.com}
12111012Sandreas.sandberg@arm.com
12211012Sandreas.sandberg@arm.comvoid
12311012Sandreas.sandberg@arm.comBasePixelPump::unserialize(CheckpointIn &cp)
12411012Sandreas.sandberg@arm.com{
12511012Sandreas.sandberg@arm.com    UNSERIALIZE_SCALAR(line);
12611012Sandreas.sandberg@arm.com    UNSERIALIZE_SCALAR(_posX);
12711012Sandreas.sandberg@arm.com    UNSERIALIZE_SCALAR(_underrun);
12811012Sandreas.sandberg@arm.com
12911012Sandreas.sandberg@arm.com    UNSERIALIZE_OBJ(_timings);
13011012Sandreas.sandberg@arm.com    UNSERIALIZE_OBJ(fb);
13111012Sandreas.sandberg@arm.com
13211012Sandreas.sandberg@arm.com    // We don't need to reschedule the event here since the event was
13311012Sandreas.sandberg@arm.com    // suspended by PixelEvent::drain() and will be rescheduled by
13411012Sandreas.sandberg@arm.com    // PixelEvent::drainResume().
13511012Sandreas.sandberg@arm.com    for (PixelEvent *event : pixelEvents)
13611012Sandreas.sandberg@arm.com        event->unserializeSection(cp, event->name());
13711012Sandreas.sandberg@arm.com}
13811012Sandreas.sandberg@arm.com
13911897Ssudhanshu.jha@arm.comvoid
14011897Ssudhanshu.jha@arm.comBasePixelPump::updateTimings(const DisplayTimings &timings)
14111897Ssudhanshu.jha@arm.com{
14211897Ssudhanshu.jha@arm.com    panic_if(active(), "Trying to update timings in active PixelPump\n");
14311012Sandreas.sandberg@arm.com
14411012Sandreas.sandberg@arm.com    _timings = timings;
14511012Sandreas.sandberg@arm.com
14611012Sandreas.sandberg@arm.com    // Resize the frame buffer if needed
14711012Sandreas.sandberg@arm.com    if (_timings.width != fb.width() || _timings.height != fb.height())
14811012Sandreas.sandberg@arm.com        fb.resize(timings.width, timings.height);
14911012Sandreas.sandberg@arm.com
15011012Sandreas.sandberg@arm.com    // Set the current line past the last line in the frame. This
15111012Sandreas.sandberg@arm.com    // triggers the new frame logic in beginLine().
15211012Sandreas.sandberg@arm.com    line = _timings.linesPerFrame();
15311897Ssudhanshu.jha@arm.com}
15411897Ssudhanshu.jha@arm.com
15511897Ssudhanshu.jha@arm.comvoid
15611897Ssudhanshu.jha@arm.comBasePixelPump::start()
15711897Ssudhanshu.jha@arm.com{
15811012Sandreas.sandberg@arm.com    schedule(evBeginLine, clockEdge());
15911012Sandreas.sandberg@arm.com}
16011012Sandreas.sandberg@arm.com
16111897Ssudhanshu.jha@arm.com
16211012Sandreas.sandberg@arm.comvoid
16311012Sandreas.sandberg@arm.comBasePixelPump::stop()
16411012Sandreas.sandberg@arm.com{
16511012Sandreas.sandberg@arm.com    if (evVSyncEnd.scheduled())
16611012Sandreas.sandberg@arm.com        deschedule(evVSyncEnd);
16711012Sandreas.sandberg@arm.com
16811012Sandreas.sandberg@arm.com    if (evHSyncBegin.scheduled())
16911012Sandreas.sandberg@arm.com        deschedule(evHSyncBegin);
17011012Sandreas.sandberg@arm.com
17111012Sandreas.sandberg@arm.com    if (evHSyncEnd.scheduled())
17211012Sandreas.sandberg@arm.com        deschedule(evHSyncEnd);
17311012Sandreas.sandberg@arm.com
17411012Sandreas.sandberg@arm.com    if (evBeginLine.scheduled())
17511012Sandreas.sandberg@arm.com        deschedule(evBeginLine);
17611012Sandreas.sandberg@arm.com
17711012Sandreas.sandberg@arm.com    if (evRenderPixels.scheduled())
17811012Sandreas.sandberg@arm.com        deschedule(evRenderPixels);
17911012Sandreas.sandberg@arm.com}
18011012Sandreas.sandberg@arm.com
18111012Sandreas.sandberg@arm.comvoid
18211012Sandreas.sandberg@arm.comBasePixelPump::beginLine()
18311012Sandreas.sandberg@arm.com{
18411012Sandreas.sandberg@arm.com    _posX = 0;
18511012Sandreas.sandberg@arm.com    line++;
18611012Sandreas.sandberg@arm.com    if (line >= _timings.linesPerFrame()) {
18711012Sandreas.sandberg@arm.com        _underrun = false;
18811012Sandreas.sandberg@arm.com        line = 0;
18911012Sandreas.sandberg@arm.com    }
19011012Sandreas.sandberg@arm.com
19111012Sandreas.sandberg@arm.com    if (line == _timings.lineVSyncStart()) {
19211012Sandreas.sandberg@arm.com        onVSyncBegin();
19311012Sandreas.sandberg@arm.com    } else if (line == _timings.lineVBackPorchStart()) {
19411012Sandreas.sandberg@arm.com        onVSyncEnd();
19511012Sandreas.sandberg@arm.com    }
19611012Sandreas.sandberg@arm.com
19711012Sandreas.sandberg@arm.com    const Cycles h_sync_begin(0);
19811012Sandreas.sandberg@arm.com    schedule(evHSyncBegin, clockEdge(h_sync_begin));
19911012Sandreas.sandberg@arm.com
20011012Sandreas.sandberg@arm.com    const Cycles h_sync_end(h_sync_begin + _timings.hSync);
20111012Sandreas.sandberg@arm.com    schedule(evHSyncEnd, clockEdge(h_sync_end));
20211012Sandreas.sandberg@arm.com
20311012Sandreas.sandberg@arm.com    // Visible area
20411012Sandreas.sandberg@arm.com    if (line >= _timings.lineFirstVisible() &&
20511012Sandreas.sandberg@arm.com        line < _timings.lineFrontPorchStart()) {
20611012Sandreas.sandberg@arm.com
20711012Sandreas.sandberg@arm.com        const Cycles h_first_visible(h_sync_end + _timings.hBackPorch);
20811012Sandreas.sandberg@arm.com        schedule(evRenderPixels, clockEdge(h_first_visible));
20911012Sandreas.sandberg@arm.com    }
21011012Sandreas.sandberg@arm.com
21111012Sandreas.sandberg@arm.com    schedule(evBeginLine, clockEdge(_timings.cyclesPerLine()));
21211012Sandreas.sandberg@arm.com}
21311012Sandreas.sandberg@arm.com
21411012Sandreas.sandberg@arm.comvoid
21511012Sandreas.sandberg@arm.comBasePixelPump::renderPixels()
21611012Sandreas.sandberg@arm.com{
21711012Sandreas.sandberg@arm.com    // Try to handle multiple pixels at a time; doing so reduces the
21811012Sandreas.sandberg@arm.com    // accuracy of the underrun detection but lowers simulation
21911012Sandreas.sandberg@arm.com    // overhead
22011012Sandreas.sandberg@arm.com    const unsigned x_end(std::min(_posX + pixelChunk, _timings.width));
22111012Sandreas.sandberg@arm.com    const unsigned pxl_count(x_end - _posX);
22211012Sandreas.sandberg@arm.com    const unsigned pos_y(posY());
22311012Sandreas.sandberg@arm.com
22411012Sandreas.sandberg@arm.com    Pixel pixel(0, 0, 0);
22511012Sandreas.sandberg@arm.com    const Pixel underrun_pixel(0, 0, 0);
22611012Sandreas.sandberg@arm.com    for (; _posX < x_end && !_underrun; ++_posX) {
22711012Sandreas.sandberg@arm.com        if (!nextPixel(pixel)) {
22811012Sandreas.sandberg@arm.com            warn("Input buffer underrun in BasePixelPump (%u, %u)\n",
22911012Sandreas.sandberg@arm.com                 _posX, pos_y);
23011012Sandreas.sandberg@arm.com            _underrun = true;
23111012Sandreas.sandberg@arm.com            onUnderrun(_posX, pos_y);
23211012Sandreas.sandberg@arm.com            pixel = underrun_pixel;
23311012Sandreas.sandberg@arm.com        }
23411012Sandreas.sandberg@arm.com        fb.pixel(_posX, pos_y) = pixel;
23511012Sandreas.sandberg@arm.com    }
23611012Sandreas.sandberg@arm.com
23711012Sandreas.sandberg@arm.com    // Fill remaining pixels with a dummy pixel value if we ran out of
23811012Sandreas.sandberg@arm.com    // data
23911012Sandreas.sandberg@arm.com    for (; _posX < x_end; ++_posX)
24011012Sandreas.sandberg@arm.com        fb.pixel(_posX, pos_y) = underrun_pixel;
24111012Sandreas.sandberg@arm.com
24211012Sandreas.sandberg@arm.com    // Schedule a new event to handle the next block of pixels
24311012Sandreas.sandberg@arm.com    if (_posX < _timings.width) {
24411012Sandreas.sandberg@arm.com        schedule(evRenderPixels, clockEdge(Cycles(pxl_count)));
24511012Sandreas.sandberg@arm.com    } else {
24611012Sandreas.sandberg@arm.com        if (pos_y == _timings.height - 1)
24711012Sandreas.sandberg@arm.com            onFrameDone();
24811012Sandreas.sandberg@arm.com    }
24911012Sandreas.sandberg@arm.com}
25011012Sandreas.sandberg@arm.com
25111897Ssudhanshu.jha@arm.comvoid
25211897Ssudhanshu.jha@arm.comBasePixelPump::renderFrame()
25311897Ssudhanshu.jha@arm.com{
25411897Ssudhanshu.jha@arm.com    _underrun = false;
25511897Ssudhanshu.jha@arm.com    line = 0;
25611897Ssudhanshu.jha@arm.com
25711897Ssudhanshu.jha@arm.com    // Signal vsync end and render the frame
25811897Ssudhanshu.jha@arm.com    line = _timings.lineVBackPorchStart();
25911897Ssudhanshu.jha@arm.com    onVSyncEnd();
26011897Ssudhanshu.jha@arm.com
26111897Ssudhanshu.jha@arm.com    // We only care about the visible screen area when rendering the
26211897Ssudhanshu.jha@arm.com    // frame
26311897Ssudhanshu.jha@arm.com    for (line = _timings.lineFirstVisible();
26411897Ssudhanshu.jha@arm.com        line < _timings.lineFrontPorchStart();
26511897Ssudhanshu.jha@arm.com        ++line) {
26611897Ssudhanshu.jha@arm.com
26711897Ssudhanshu.jha@arm.com        _posX = 0;
26811897Ssudhanshu.jha@arm.com
26911897Ssudhanshu.jha@arm.com        onHSyncBegin();
27011897Ssudhanshu.jha@arm.com        onHSyncEnd();
27111897Ssudhanshu.jha@arm.com
27211897Ssudhanshu.jha@arm.com        renderLine();
27311897Ssudhanshu.jha@arm.com    }
27411897Ssudhanshu.jha@arm.com
27511897Ssudhanshu.jha@arm.com    line = _timings.lineFrontPorchStart() - 1;
27611897Ssudhanshu.jha@arm.com    onFrameDone();
27711897Ssudhanshu.jha@arm.com
27811897Ssudhanshu.jha@arm.com    // Signal vsync until the next frame begins
27911897Ssudhanshu.jha@arm.com    line = _timings.lineVSyncStart();
28011897Ssudhanshu.jha@arm.com    onVSyncBegin();
28111897Ssudhanshu.jha@arm.com}
28211897Ssudhanshu.jha@arm.com
28311897Ssudhanshu.jha@arm.comvoid
28411897Ssudhanshu.jha@arm.comBasePixelPump::renderLine()
28511897Ssudhanshu.jha@arm.com{
28611897Ssudhanshu.jha@arm.com    const unsigned pos_y(posY());
28711897Ssudhanshu.jha@arm.com
28811897Ssudhanshu.jha@arm.com    Pixel pixel(0, 0, 0);
28911897Ssudhanshu.jha@arm.com    for (_posX = 0; _posX < _timings.width; ++_posX) {
29011897Ssudhanshu.jha@arm.com        if (!nextPixel(pixel)) {
29111897Ssudhanshu.jha@arm.com            panic("Unexpected underrun in BasePixelPump (%u, %u)\n",
29211897Ssudhanshu.jha@arm.com                 _posX, pos_y);
29311897Ssudhanshu.jha@arm.com        }
29411897Ssudhanshu.jha@arm.com        fb.pixel(_posX, pos_y) = pixel;
29511897Ssudhanshu.jha@arm.com    }
29611897Ssudhanshu.jha@arm.com}
29711897Ssudhanshu.jha@arm.com
29811897Ssudhanshu.jha@arm.com
29911012Sandreas.sandberg@arm.comBasePixelPump::PixelEvent::PixelEvent(
30011012Sandreas.sandberg@arm.com    const char *name, BasePixelPump *_parent, CallbackType _func)
30111012Sandreas.sandberg@arm.com    : Event(), Drainable(),
30211012Sandreas.sandberg@arm.com      _name(name), parent(*_parent), func(_func),
30311012Sandreas.sandberg@arm.com      suspended(false),
30411012Sandreas.sandberg@arm.com      relativeTick(0)
30511012Sandreas.sandberg@arm.com{
30611012Sandreas.sandberg@arm.com    parent.pixelEvents.push_back(this);
30711012Sandreas.sandberg@arm.com}
30811012Sandreas.sandberg@arm.com
30911012Sandreas.sandberg@arm.comDrainState
31011012Sandreas.sandberg@arm.comBasePixelPump::PixelEvent::drain()
31111012Sandreas.sandberg@arm.com{
31211012Sandreas.sandberg@arm.com    if (scheduled())
31311012Sandreas.sandberg@arm.com        suspend();
31411012Sandreas.sandberg@arm.com    return DrainState::Drained;
31511012Sandreas.sandberg@arm.com}
31611012Sandreas.sandberg@arm.com
31711012Sandreas.sandberg@arm.comvoid
31811012Sandreas.sandberg@arm.comBasePixelPump::PixelEvent::drainResume()
31911012Sandreas.sandberg@arm.com{
32011012Sandreas.sandberg@arm.com    if (suspended)
32111012Sandreas.sandberg@arm.com        resume();
32211012Sandreas.sandberg@arm.com}
32311012Sandreas.sandberg@arm.com
32411012Sandreas.sandberg@arm.comvoid
32511012Sandreas.sandberg@arm.comBasePixelPump::PixelEvent::serialize(CheckpointOut &cp) const
32611012Sandreas.sandberg@arm.com{
32711012Sandreas.sandberg@arm.com    assert(!scheduled());
32811012Sandreas.sandberg@arm.com    Event::serialize(cp);
32911012Sandreas.sandberg@arm.com    SERIALIZE_SCALAR(suspended);
33011012Sandreas.sandberg@arm.com    SERIALIZE_SCALAR(relativeTick);
33111012Sandreas.sandberg@arm.com}
33211012Sandreas.sandberg@arm.com
33311012Sandreas.sandberg@arm.comvoid
33411012Sandreas.sandberg@arm.comBasePixelPump::PixelEvent::unserialize(CheckpointIn &cp)
33511012Sandreas.sandberg@arm.com{
33611012Sandreas.sandberg@arm.com    Event::unserialize(cp);
33711012Sandreas.sandberg@arm.com    UNSERIALIZE_SCALAR(suspended);
33811012Sandreas.sandberg@arm.com    UNSERIALIZE_SCALAR(relativeTick);
33911012Sandreas.sandberg@arm.com    assert(!scheduled());
34011012Sandreas.sandberg@arm.com}
34111012Sandreas.sandberg@arm.com
34211012Sandreas.sandberg@arm.comvoid
34311012Sandreas.sandberg@arm.comBasePixelPump::PixelEvent::suspend()
34411012Sandreas.sandberg@arm.com{
34511012Sandreas.sandberg@arm.com    assert(scheduled());
34611012Sandreas.sandberg@arm.com    assert(!suspended);
34711012Sandreas.sandberg@arm.com
34811012Sandreas.sandberg@arm.com    suspended = true;
34911012Sandreas.sandberg@arm.com    relativeTick = when() - curTick();
35011012Sandreas.sandberg@arm.com    parent.deschedule(this);
35111012Sandreas.sandberg@arm.com}
35211012Sandreas.sandberg@arm.com
35311012Sandreas.sandberg@arm.comvoid
35411012Sandreas.sandberg@arm.comBasePixelPump::PixelEvent::resume()
35511012Sandreas.sandberg@arm.com{
35611012Sandreas.sandberg@arm.com    assert(!scheduled());
35711012Sandreas.sandberg@arm.com    assert(suspended);
35811012Sandreas.sandberg@arm.com    parent.schedule(this, relativeTick + curTick());
35911012Sandreas.sandberg@arm.com    suspended = false;
36011012Sandreas.sandberg@arm.com    relativeTick = 0;
36111012Sandreas.sandberg@arm.com}
362