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