framebuffer.hh revision 10839:10cac0f0f419
1/* 2 * Copyright (c) 2015 ARM Limited 3 * All rights reserved 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software 9 * licensed hereunder. You may use the software subject to the license 10 * terms below provided that you ensure that this notice is replicated 11 * unmodified and in its entirety in all distributions of the software, 12 * modified or unmodified, in source code or in binary form. 13 * 14 * Redistribution and use in source and binary forms, with or without 15 * modification, are permitted provided that the following conditions are 16 * met: redistributions of source code must retain the above copyright 17 * notice, this list of conditions and the following disclaimer; 18 * redistributions in binary form must reproduce the above copyright 19 * notice, this list of conditions and the following disclaimer in the 20 * documentation and/or other materials provided with the distribution; 21 * neither the name of the copyright holders nor the names of its 22 * contributors may be used to endorse or promote products derived from 23 * this software without specific prior written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36 * 37 * Authors: Andreas Sandberg 38 */ 39 40#ifndef __BASE_FRAMEBUFFER_HH__ 41#define __BASE_FRAMEBUFFER_HH__ 42 43#include <cmath> 44#include <cstdint> 45 46#include <vector> 47 48#include "base/types.hh" 49 50/** 51 * Internal gem5 representation of a Pixel. 52 */ 53struct Pixel 54{ 55 Pixel() 56 : red(0), green(0), blue(0), padding(0) {} 57 58 Pixel(uint8_t _red, uint8_t _green, uint8_t _blue) 59 : red(_red), green(_green), blue(_blue), padding(0) {} 60 61 uint8_t red; 62 uint8_t green; 63 uint8_t blue; 64 uint8_t padding; 65}; 66 67inline bool 68operator==(const Pixel &lhs, const Pixel &rhs) 69{ 70 return lhs.red == rhs.red && 71 lhs.green == rhs.green && 72 lhs.blue == rhs.blue && 73 lhs.padding == rhs.padding; 74} 75 76 77/** 78 * Configurable RGB pixel converter. 79 * 80 * This class converts between external RGB representations and gem5's 81 * internal Pixel representation. The class assumes that pixels are 82 * stored in a word of configurable length (up to 32 bits). Individual 83 * pixels are assumed to be represented by contiguous bit ranges in 84 * the word (i.e., it is possible to shift and mask out a contiguous 85 * bit range for each pixel). 86 */ 87class PixelConverter 88{ 89 public: 90 /** 91 * Color channel conversion and scaling helper class. 92 */ 93 struct Channel { 94 /** 95 * @param offset Offset in bits. 96 * @param width Width in bits. 97 */ 98 Channel(unsigned offset, unsigned width); 99 100 /** 101 * Get the value of a single color channel represented as an 102 * 8-bit number. 103 */ 104 uint8_t toPixel(uint32_t word) const { 105 return round(((word >> offset) & mask) * factor); 106 } 107 108 /** 109 * Convert an 8-bit representation of a color into an external 110 * format. 111 */ 112 uint32_t fromPixel(uint8_t ch) const { 113 return (static_cast<uint8_t>(round(ch / factor)) & mask) << offset; 114 } 115 116 /** Offset in bits */ 117 unsigned offset; 118 /** Bit mask (after shifting) */ 119 unsigned mask; 120 /** 121 * Scaling factor when converting to the full range of an 122 * 8-bit color channel 123 */ 124 float factor; 125 }; 126 127 PixelConverter(unsigned length, 128 unsigned ro, unsigned go, unsigned bo, 129 unsigned rw, unsigned gw, unsigned bw, 130 ByteOrder byte_order = LittleEndianByteOrder); 131 132 /** Get the Pixel representation of a color word. */ 133 Pixel toPixel(uint32_t word) const { 134 return Pixel(ch_r.toPixel(word), 135 ch_g.toPixel(word), 136 ch_b.toPixel(word)); 137 } 138 139 /** Get a Pixel representation by reading a word from memory. */ 140 Pixel toPixel(const uint8_t *rfb) const { 141 return toPixel(readWord(rfb)); 142 } 143 144 /** Convert a Pixel into a color word */ 145 uint32_t fromPixel(const Pixel &pixel) const { 146 return ch_r.fromPixel(pixel.red) | 147 ch_g.fromPixel(pixel.green) | 148 ch_b.fromPixel(pixel.blue); 149 } 150 151 /** 152 * Convert a pixel into a color word and store the resulting word 153 * in memory. 154 */ 155 void fromPixel(uint8_t *rfb, const Pixel &pixel) const { 156 writeWord(rfb, fromPixel(pixel)); 157 } 158 159 /** 160 * Read a word of a given length and endianness from memory. 161 * 162 * The number of bytes read from memory is determined by the 163 * length of a color word. Note that some of the bytes may be 164 * padding. 165 * 166 * @param p Pointer to the first byte in the word. 167 * @return Word in host endianness. 168 */ 169 uint32_t readWord(const uint8_t *p) const; 170 /** 171 * Write a word of a given length and endianness to memory. 172 * 173 * @param p Pointer to the first byte in memory. 174 * @param word Word to store (host endianness). 175 */ 176 void writeWord(uint8_t *p, uint32_t word) const; 177 178 /** Bytes per pixel when stored in memory (including padding) */ 179 unsigned length; 180 /** 181 * Number of bits used to represent one pixel value (excluding 182 * padding). This could be less than length * 8 if the pixel value 183 * is padded. 184 */ 185 unsigned depth; 186 /** Byte order when stored to memory. */ 187 ByteOrder byte_order; 188 189 /** Red channel conversion helper */ 190 Channel ch_r; 191 /** Green channel conversion helper */ 192 Channel ch_g; 193 /** Blue channel conversion helper */ 194 Channel ch_b; 195 196 /** Predefined 32-bit RGB (red in least significant bits, 8 197 * bits/channel, little endian) conversion helper */ 198 static const PixelConverter rgba8888_le; 199 /** Predefined 16-bit RGB565 (red in least significant bits, 200 * little endian) conversion helper */ 201 static const PixelConverter rgb565_le; 202 203 /** Predefined 32-bit RGB (red in least significant bits, 8 204 * bits/channel, big endian) conversion helper */ 205 static const PixelConverter rgba8888_be; 206 /** Predefined 16-bit RGB565 (red in least significant bits, 207 * big endian) conversion helper */ 208 static const PixelConverter rgb565_be; 209}; 210 211/** 212 * Internal gem5 representation of a frame buffer 213 * 214 * Display controllers and other devices producing images are expected 215 * to use this class to represent the final image. 216 * 217 * Pixels are indexed relative to the upper left corner of the 218 * image. That is, the pixel at position (0, 0) is the upper left 219 * corner. The backing store is a linear vector of Pixels ordered left 220 * to right starting in the upper left corner. 221 */ 222class FrameBuffer 223{ 224 public: 225 /** 226 * Create a frame buffer of a given size. 227 * 228 * @param width Width in pixels 229 * @param height Height in pixels 230 */ 231 FrameBuffer(unsigned width, unsigned height); 232 /** Create an empty (0x0) frame buffer */ 233 FrameBuffer(); 234 235 virtual ~FrameBuffer(); 236 237 /** 238 * Resize the frame buffer. 239 * 240 * This method resizes frame buffer including the backing 241 * store. The contents of the backing store are undefined after 242 * this operation. 243 * 244 * @param with Width in pixels. 245 * @param height Height in pixels. 246 */ 247 void resize(unsigned width, unsigned height); 248 249 /** Frame buffer width in pixels */ 250 unsigned width() const { return _width; } 251 /** Frame buffer height in pixels */ 252 unsigned height() const { return _height; } 253 /** Total number of pixels in frame buffer */ 254 unsigned area() const { return _width * _height; } 255 256 /** 257 * Fill the frame buffer with a single pixel value 258 * 259 * @param pixel Pixel value to fill with. 260 */ 261 void fill(const Pixel &pixel); 262 /** 263 * Fill the frame buffer with black pixels 264 */ 265 void clear(); 266 267 /** 268 * Fill the frame buffer with pixel data from an external buffer 269 * of the same width and height as this frame buffer. 270 * 271 * @param fb External frame buffer 272 * @param conv Pixel conversion helper 273 */ 274 void copyIn(const uint8_t *fb, const PixelConverter &conv); 275 /** 276 * Fill the frame buffer with pixel data from an external buffer 277 * of the same width and height as this frame buffer. 278 * 279 * @param fb External frame buffer 280 * @param conv Pixel conversion helper 281 */ 282 void copyIn(const std::vector<uint8_t> &fb, const PixelConverter &conv) { 283 copyIn(fb.data(), conv); 284 } 285 286 /** 287 * Store the contents of this frame buffer in an external buffer 288 * of the same width and height as this frame buffer. 289 * 290 * @param fb External frame buffer 291 * @param conv Pixel conversion helper 292 */ 293 void copyOut(uint8_t *fb, const PixelConverter &conv) const; 294 /** 295 * Store the contents of this frame buffer in an external buffer 296 * of the same width and height as this frame buffer. 297 * 298 * @param fb External frame buffer 299 * @param conv Pixel conversion helper 300 */ 301 void copyOut(std::vector<uint8_t> &fb, const PixelConverter &conv) const { 302 copyOut(fb.data(), conv); 303 } 304 305 /** 306 * Get a pixel from an (x, y) coordinate 307 * 308 * @param x Distance from the left margin. 309 * @param y Distance from the top of the frame. 310 */ 311 const Pixel &pixel(unsigned x, unsigned y) const { 312 assert(x < _width); 313 assert(y < _height); 314 315 return pixels[y * _width + x]; 316 } 317 318 /** 319 * Get a pixel from an (x, y) coordinate 320 * 321 * @param x Distance from the left margin. 322 * @param y Distance from the top of the frame. 323 */ 324 Pixel &pixel(unsigned x, unsigned y) { 325 assert(x < _width); 326 assert(y < _height); 327 328 return pixels[y * _width + x]; 329 } 330 331 /** 332 * Create a hash of the image that can be used for quick 333 * comparisons. 334 */ 335 uint64_t getHash() const; 336 337 /** 338 * Static "dummy" frame buffer. 339 * 340 * This is a dummy frame buffer that can be used as a place holder 341 * for devices that always expect a frame buffer to be present. 342 */ 343 static const FrameBuffer dummy; 344 345 /** Frame buffer backing store */ 346 std::vector<Pixel> pixels; 347 348 protected: 349 /** Width in pixels */ 350 unsigned _width; 351 /** Height in pixels */ 352 unsigned _height; 353}; 354 355#endif // __BASE_FRAMEBUFFER_HH__ 356