framebuffer.cc revision 10839
110839Sandreas.sandberg@arm.com/*
210839Sandreas.sandberg@arm.com * Copyright (c) 2015 ARM Limited
310839Sandreas.sandberg@arm.com * All rights reserved
410839Sandreas.sandberg@arm.com *
510839Sandreas.sandberg@arm.com * The license below extends only to copyright in the software and shall
610839Sandreas.sandberg@arm.com * not be construed as granting a license to any other intellectual
710839Sandreas.sandberg@arm.com * property including but not limited to intellectual property relating
810839Sandreas.sandberg@arm.com * to a hardware implementation of the functionality of the software
910839Sandreas.sandberg@arm.com * licensed hereunder.  You may use the software subject to the license
1010839Sandreas.sandberg@arm.com * terms below provided that you ensure that this notice is replicated
1110839Sandreas.sandberg@arm.com * unmodified and in its entirety in all distributions of the software,
1210839Sandreas.sandberg@arm.com * modified or unmodified, in source code or in binary form.
1310839Sandreas.sandberg@arm.com *
1410839Sandreas.sandberg@arm.com * Redistribution and use in source and binary forms, with or without
1510839Sandreas.sandberg@arm.com * modification, are permitted provided that the following conditions are
1610839Sandreas.sandberg@arm.com * met: redistributions of source code must retain the above copyright
1710839Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer;
1810839Sandreas.sandberg@arm.com * redistributions in binary form must reproduce the above copyright
1910839Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer in the
2010839Sandreas.sandberg@arm.com * documentation and/or other materials provided with the distribution;
2110839Sandreas.sandberg@arm.com * neither the name of the copyright holders nor the names of its
2210839Sandreas.sandberg@arm.com * contributors may be used to endorse or promote products derived from
2310839Sandreas.sandberg@arm.com * this software without specific prior written permission.
2410839Sandreas.sandberg@arm.com *
2510839Sandreas.sandberg@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2610839Sandreas.sandberg@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2710839Sandreas.sandberg@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2810839Sandreas.sandberg@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2910839Sandreas.sandberg@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3010839Sandreas.sandberg@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3110839Sandreas.sandberg@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3210839Sandreas.sandberg@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3310839Sandreas.sandberg@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3410839Sandreas.sandberg@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3510839Sandreas.sandberg@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3610839Sandreas.sandberg@arm.com *
3710839Sandreas.sandberg@arm.com * Authors: Andreas Sandberg
3810839Sandreas.sandberg@arm.com */
3910839Sandreas.sandberg@arm.com
4010839Sandreas.sandberg@arm.com#include "base/framebuffer.hh"
4110839Sandreas.sandberg@arm.com
4210839Sandreas.sandberg@arm.com#include <zlib.h>
4310839Sandreas.sandberg@arm.com
4410839Sandreas.sandberg@arm.com#include <cassert>
4510839Sandreas.sandberg@arm.com
4610839Sandreas.sandberg@arm.com#include "base/bitfield.hh"
4710839Sandreas.sandberg@arm.com
4810839Sandreas.sandberg@arm.comconst PixelConverter PixelConverter::rgba8888_le(4, 0, 8, 16, 8, 8, 8);
4910839Sandreas.sandberg@arm.comconst PixelConverter PixelConverter::rgba8888_be(4, 0, 8, 16, 8, 8, 8,
5010839Sandreas.sandberg@arm.com                                                 BigEndianByteOrder);
5110839Sandreas.sandberg@arm.comconst PixelConverter PixelConverter::rgb565_le(2,  0, 5, 11, 5, 6, 5);
5210839Sandreas.sandberg@arm.comconst PixelConverter PixelConverter::rgb565_be(2,  0, 5, 11, 5, 6, 5,
5310839Sandreas.sandberg@arm.com                                               BigEndianByteOrder);
5410839Sandreas.sandberg@arm.com
5510839Sandreas.sandberg@arm.comconst FrameBuffer FrameBuffer::dummy(320, 240);
5610839Sandreas.sandberg@arm.com
5710839Sandreas.sandberg@arm.comPixelConverter::PixelConverter(unsigned _length,
5810839Sandreas.sandberg@arm.com                               unsigned ro, unsigned go, unsigned bo,
5910839Sandreas.sandberg@arm.com                               unsigned rw, unsigned gw, unsigned bw,
6010839Sandreas.sandberg@arm.com                               ByteOrder _byte_order)
6110839Sandreas.sandberg@arm.com    : length(_length),
6210839Sandreas.sandberg@arm.com      depth(rw + gw + bw),
6310839Sandreas.sandberg@arm.com      byte_order(_byte_order),
6410839Sandreas.sandberg@arm.com      ch_r(ro, rw),
6510839Sandreas.sandberg@arm.com      ch_g(go, gw),
6610839Sandreas.sandberg@arm.com      ch_b(bo, bw)
6710839Sandreas.sandberg@arm.com{
6810839Sandreas.sandberg@arm.com    assert(length > 1);
6910839Sandreas.sandberg@arm.com}
7010839Sandreas.sandberg@arm.com
7110839Sandreas.sandberg@arm.comPixelConverter::Channel::Channel(unsigned _offset, unsigned width)
7210839Sandreas.sandberg@arm.com    : offset(_offset),
7310839Sandreas.sandberg@arm.com      mask(::mask(width)),
7410839Sandreas.sandberg@arm.com      factor(255.0 / mask)
7510839Sandreas.sandberg@arm.com{
7610839Sandreas.sandberg@arm.com}
7710839Sandreas.sandberg@arm.com
7810839Sandreas.sandberg@arm.comuint32_t
7910839Sandreas.sandberg@arm.comPixelConverter::readWord(const uint8_t *p) const
8010839Sandreas.sandberg@arm.com{
8110839Sandreas.sandberg@arm.com    uint32_t word(0);
8210839Sandreas.sandberg@arm.com
8310839Sandreas.sandberg@arm.com    if (byte_order == LittleEndianByteOrder) {
8410839Sandreas.sandberg@arm.com        for (int i = 0; i < length; ++i)
8510839Sandreas.sandberg@arm.com            word |= p[i] << (8 * i);
8610839Sandreas.sandberg@arm.com    } else {
8710839Sandreas.sandberg@arm.com        for (int i = 0; i < length; ++i)
8810839Sandreas.sandberg@arm.com            word |= p[i] << (8 * (length - i - 1));
8910839Sandreas.sandberg@arm.com    }
9010839Sandreas.sandberg@arm.com
9110839Sandreas.sandberg@arm.com    return word;
9210839Sandreas.sandberg@arm.com}
9310839Sandreas.sandberg@arm.com
9410839Sandreas.sandberg@arm.comvoid
9510839Sandreas.sandberg@arm.comPixelConverter::writeWord(uint8_t *p, uint32_t word) const
9610839Sandreas.sandberg@arm.com{
9710839Sandreas.sandberg@arm.com    if (byte_order == LittleEndianByteOrder) {
9810839Sandreas.sandberg@arm.com        for (int i = 0; i < length; ++i)
9910839Sandreas.sandberg@arm.com            p[i] = (word >> (8 * i)) & 0xFF;
10010839Sandreas.sandberg@arm.com    } else {
10110839Sandreas.sandberg@arm.com        for (int i = 0; i < length; ++i)
10210839Sandreas.sandberg@arm.com            p[i] = (word >> (8 * (length - i - 1))) & 0xFF;
10310839Sandreas.sandberg@arm.com    }
10410839Sandreas.sandberg@arm.com}
10510839Sandreas.sandberg@arm.com
10610839Sandreas.sandberg@arm.com
10710839Sandreas.sandberg@arm.com
10810839Sandreas.sandberg@arm.com
10910839Sandreas.sandberg@arm.comFrameBuffer::FrameBuffer(unsigned width, unsigned height)
11010839Sandreas.sandberg@arm.com    : pixels(width * height),
11110839Sandreas.sandberg@arm.com      _width(width), _height(height)
11210839Sandreas.sandberg@arm.com{
11310839Sandreas.sandberg@arm.com    clear();
11410839Sandreas.sandberg@arm.com}
11510839Sandreas.sandberg@arm.com
11610839Sandreas.sandberg@arm.comFrameBuffer::FrameBuffer()
11710839Sandreas.sandberg@arm.com    : _width(0), _height(0)
11810839Sandreas.sandberg@arm.com{
11910839Sandreas.sandberg@arm.com}
12010839Sandreas.sandberg@arm.com
12110839Sandreas.sandberg@arm.comFrameBuffer::~FrameBuffer()
12210839Sandreas.sandberg@arm.com{
12310839Sandreas.sandberg@arm.com}
12410839Sandreas.sandberg@arm.com
12510839Sandreas.sandberg@arm.comvoid
12610839Sandreas.sandberg@arm.comFrameBuffer::resize(unsigned width, unsigned height)
12710839Sandreas.sandberg@arm.com{
12810839Sandreas.sandberg@arm.com    _width = width;
12910839Sandreas.sandberg@arm.com    _height = height;
13010839Sandreas.sandberg@arm.com
13110839Sandreas.sandberg@arm.com    pixels.resize(width * height);
13210839Sandreas.sandberg@arm.com}
13310839Sandreas.sandberg@arm.com
13410839Sandreas.sandberg@arm.comvoid
13510839Sandreas.sandberg@arm.comFrameBuffer::fill(const Pixel &pixel)
13610839Sandreas.sandberg@arm.com{
13710839Sandreas.sandberg@arm.com    for (auto &p : pixels)
13810839Sandreas.sandberg@arm.com        p = pixel;
13910839Sandreas.sandberg@arm.com}
14010839Sandreas.sandberg@arm.com
14110839Sandreas.sandberg@arm.comvoid
14210839Sandreas.sandberg@arm.comFrameBuffer::clear()
14310839Sandreas.sandberg@arm.com{
14410839Sandreas.sandberg@arm.com    static const Pixel black(0, 0, 0);
14510839Sandreas.sandberg@arm.com
14610839Sandreas.sandberg@arm.com    fill(black);
14710839Sandreas.sandberg@arm.com}
14810839Sandreas.sandberg@arm.com
14910839Sandreas.sandberg@arm.comvoid
15010839Sandreas.sandberg@arm.comFrameBuffer::copyIn(const uint8_t *fb, const PixelConverter &conv)
15110839Sandreas.sandberg@arm.com{
15210839Sandreas.sandberg@arm.com    for (auto &p : pixels) {
15310839Sandreas.sandberg@arm.com        p = conv.toPixel(fb);
15410839Sandreas.sandberg@arm.com        fb += conv.length;
15510839Sandreas.sandberg@arm.com    }
15610839Sandreas.sandberg@arm.com}
15710839Sandreas.sandberg@arm.com
15810839Sandreas.sandberg@arm.comvoid
15910839Sandreas.sandberg@arm.comFrameBuffer::copyOut(uint8_t *fb, const PixelConverter &conv) const
16010839Sandreas.sandberg@arm.com{
16110839Sandreas.sandberg@arm.com    for (auto &p : pixels) {
16210839Sandreas.sandberg@arm.com        conv.fromPixel(fb, p);
16310839Sandreas.sandberg@arm.com        fb += conv.length;
16410839Sandreas.sandberg@arm.com    }
16510839Sandreas.sandberg@arm.com}
16610839Sandreas.sandberg@arm.com
16710839Sandreas.sandberg@arm.comuint64_t
16810839Sandreas.sandberg@arm.comFrameBuffer::getHash() const
16910839Sandreas.sandberg@arm.com{
17010839Sandreas.sandberg@arm.com    return adler32(0UL,
17110839Sandreas.sandberg@arm.com                   reinterpret_cast<const Bytef *>(pixels.data()),
17210839Sandreas.sandberg@arm.com                   area() * sizeof(Pixel));
17310839Sandreas.sandberg@arm.com}
174