20#include "pedigree/kernel/Log.h"
21#include "pedigree/kernel/machine/Framebuffer.h"
22#include "pedigree/kernel/processor/MemoryRegion.h"
23#include "pedigree/kernel/processor/PhysicalMemoryManager.h"
24#include "pedigree/kernel/processor/VirtualAddressSpace.h"
25#include "pedigree/kernel/utilities/utility.h"
27Framebuffer::Framebuffer() : m_pParent(0), m_FramebufferBase(0), m_bActive(true) {
28 m_Palette =
new uint32_t[256];
31 for (
size_t g = 0; g <= 255; g += 0x33)
32 for (
size_t b = 0; b <= 255; b += 0x33)
33 for (
size_t r = 0; r <= 255; r += 0x33)
34 m_Palette[i++] = Graphics::createRgb(r, g, b);
36 NOTICE(
"Framebuffer: created " <<
Dec << i <<
Hex <<
" entries in the default palette");
39Framebuffer::~Framebuffer() {}
41size_t Framebuffer::getWidth()
const {
45size_t Framebuffer::getHeight()
const {
49Graphics::PixelFormat Framebuffer::getFormat()
const {
53bool Framebuffer::getActive()
const {
57void Framebuffer::setActive(
bool b) {
64 MemoryCopy(
m_Palette, palette, nEntries *
sizeof(uint32_t));
66 NOTICE(
"Framebuffer: new palette set with " <<
Dec << nEntries <<
Hex <<
" entries");
69uint32_t* Framebuffer::getPalette()
const {
76 return reinterpret_cast<void*
>(m_FramebufferBase);
80 return ~physical_uintptr_t(0);
84 size_t width,
size_t height, uint32_t* pPalette) {
87 return swCreateBuffer(srcData, srcFormat, width, height, pPalette);
94 swDestroyBuffer(pBuffer);
122 "Child framebuffer has different pixel format to "
135 size_t desty,
size_t width,
size_t height,
bool bLowestCall) {
139 swBlit(pBuffer, srcx, srcy, destx, desty, width, height);
143 size_t width,
size_t height, Graphics::PixelFormat format,
148 swDraw(pBuffer, srcx, srcy, destx, desty, width, height, format, bLowestCall);
152 Graphics::PixelFormat format,
bool bLowestCall) {
156 swRect(x, y, width, height, colour, format);
164 swCopy(srcx, srcy, destx, desty, w, h);
168 Graphics::PixelFormat format,
bool bLowestCall) {
172 swLine(x1, y1, x2, y2, colour, format);
183void Framebuffer::setXPos(
size_t x) {
187void Framebuffer::setYPos(
size_t y) {
191void Framebuffer::setWidth(
size_t w) {
195void Framebuffer::setHeight(
size_t h) {
199void Framebuffer::setFormat(Graphics::PixelFormat pf) {
203void Framebuffer::setBytesPerPixel(
size_t b) {
207uint32_t Framebuffer::getBytesPerPixel()
const {
211void Framebuffer::setBytesPerLine(
size_t b) {
215uint32_t Framebuffer::getBytesPerLine()
const {
227void Framebuffer::setFramebuffer(uintptr_t p) {
228 m_FramebufferBase = p;
233 ret.
base = m_FramebufferBase;
244 size_t desty,
size_t width,
size_t height,
bool bLowestCall) {
245 swDraw(pBuffer, srcx, srcy, destx, desty, width, height, bLowestCall);
249 size_t width,
size_t height, uint32_t* pPalette) {
257 size_t sourceBytesPerPixel = bytesPerPixel(srcFormat);
258 size_t sourceBytesPerLine = width * sourceBytesPerPixel;
261 size_t destBytesPerLine = width * destBytesPerPixel;
263 size_t fullBufferSize = height * destBytesPerLine;
277 if (((sourceBytesPerPixel == destBytesPerPixel) && (sourceBytesPerLine == destBytesPerLine)) &&
278 (srcFormat == destFormat)) {
284 MemoryCopy(pAddress, srcData, fullBufferSize);
288 for (y = 0; y < height; y++) {
289 for (x = 0; x < width; x++) {
290 size_t sourceOffset = (y * sourceBytesPerLine) + (x * sourceBytesPerPixel);
291 size_t destOffset = (y * destBytesPerLine) + (x * destBytesPerPixel);
295 const uint32_t* pSource =
296 reinterpret_cast<const uint32_t*
>(adjust_pointer(srcData, sourceOffset));
298 uint32_t transform = 0;
299 if (srcFormat == Graphics::Bits8_Idx) {
300 uint32_t source = pPalette[(*pSource) & 0xFF];
301 Graphics::convertPixel(source, Graphics::Bits24_Bgr, transform, destFormat);
303 Graphics::convertPixel(*pSource, srcFormat, transform, destFormat);
306 if (destBytesPerPixel == 4) {
307 uint32_t* pDest =
reinterpret_cast<uint32_t*
>(adjust_pointer(pAddress, destOffset));
309 if (sourceBytesPerPixel == 3)
310 transform &= 0xFFFFFF;
311 else if (sourceBytesPerPixel == 2)
315 }
else if (destBytesPerPixel == 3) {
317 uint32_t* pDest =
reinterpret_cast<uint32_t*
>(adjust_pointer(pAddress, destOffset));
318 *pDest = (*pDest & 0xFF000000) | (transform & 0xFFFFFF);
319 }
else if (destBytesPerPixel == 2) {
320 uint16_t* pDest =
reinterpret_cast<uint16_t*
>(adjust_pointer(pAddress, destOffset));
321 *pDest = transform & 0xFFFF;
322 }
else if (destBytesPerPixel == 1) {
331 pBuffer->
width = width;
336 pBuffer->
pBacking =
reinterpret_cast<void*
>(pRegion);
352 size_t desty,
size_t width,
size_t height) {
364 size_t sourceBytesPerLine = pBuffer->
width * destBytesPerPixel;
367 if ((srcx > pBuffer->
width) || (srcy > pBuffer->
height))
371 if ((srcx + width) > pBuffer->
width)
372 width = (srcx + width) - pBuffer->
width;
373 if ((srcy + height) > pBuffer->
height)
374 height = (srcy + height) - pBuffer->
height;
382 void* pSrc =
reinterpret_cast<void*
>(pBuffer->
base);
386 if (
UNLIKELY((srcx == 0) && (destx == 0) && (width * destBytesPerPixel == bytesPerLine) &&
387 (sourceBytesPerLine == bytesPerLine))) {
388 size_t sourceBufferOffset = (srcy * sourceBytesPerLine);
389 size_t frameBufferOffset = (desty * bytesPerLine);
391 void* dest =
reinterpret_cast<void*
>(m_FramebufferBase + frameBufferOffset);
392 void* src = adjust_pointer(pSrc, sourceBufferOffset);
394 MemoryCopy(dest, src, bytesPerLine * height);
397 for (
size_t y1 = desty, y2 = srcy; y1 < (desty + height); y1++, y2++) {
398 size_t sourceBufferOffset = (y2 * sourceBytesPerLine) + (srcx * sourceBytesPerPixel);
399 size_t frameBufferOffset = (y1 * bytesPerLine) + (destx * destBytesPerPixel);
401 void* dest =
reinterpret_cast<void*
>(m_FramebufferBase + frameBufferOffset);
402 void* src = adjust_pointer(pSrc, sourceBufferOffset);
404 MemoryCopy(dest, src, width * destBytesPerPixel);
410 Graphics::PixelFormat format) {
428 uint32_t transformColour = 0;
429 if (format == Graphics::Bits8_Idx) {
430 uint32_t source =
m_Palette[colour & 0xFF];
431 Graphics::convertPixel(source, Graphics::Bits24_Bgr, transformColour,
m_PixelFormat);
433 Graphics::convertPixel(colour, format, transformColour,
m_PixelFormat);
440 size_t frameBufferOffset = (y * bytesPerLine) + (x * bytesPerPixel);
442 void* dest =
reinterpret_cast<void*
>(m_FramebufferBase + frameBufferOffset);
444 size_t copySize = (bytesPerLine * height);
445 if (bytesPerPixel == 4)
447 if ((copySize % 8) == 0)
449 uint64_t val = (
static_cast<uint64_t
>(transformColour) << 32) | transformColour;
450 QuadWordSet(dest, val, copySize / 8);
452 DoubleWordSet(dest, transformColour, copySize / 4);
453 }
else if (bytesPerPixel == 3) {
456 for (
size_t i = 0; i < (copySize / 3); i++) {
457 uint32_t* p =
reinterpret_cast<uint32_t*
>(m_FramebufferBase + frameBufferOffset + (i * 3));
458 *p = (*p & 0xFF000000) | transformColour;
460 }
else if (bytesPerPixel == 2) {
461 if ((copySize % 8) == 0)
463 uint64_t val = (
static_cast<uint64_t
>(transformColour) << 48) |
464 (
static_cast<uint64_t
>(transformColour) << 32) | (transformColour << 16) |
466 QuadWordSet(dest, val, copySize / 8);
467 }
else if ((copySize % 4) == 0)
469 uint32_t val = (transformColour << 16) | transformColour;
470 DoubleWordSet(dest, val, copySize / 4);
472 WordSet(dest, transformColour, copySize / 2);
474 ByteSet(dest, transformColour, (bytesPerLine * height));
477 for (
size_t desty = y; desty < (y + height); desty++) {
478 size_t frameBufferOffset = (desty * bytesPerLine) + (x * bytesPerPixel);
480 void* dest =
reinterpret_cast<void*
>(m_FramebufferBase + frameBufferOffset);
482 size_t copySize = width * bytesPerPixel;
483 if (bytesPerPixel == 4)
485 if ((copySize % 8) == 0)
487 uint64_t val = (
static_cast<uint64_t
>(transformColour) << 32) | transformColour;
488 QuadWordSet(dest, val, copySize / 8);
490 DoubleWordSet(dest, transformColour, copySize / 4);
491 }
else if (bytesPerPixel == 3) {
494 for (
size_t i = 0; i < (copySize / 3); i++) {
496 reinterpret_cast<uint32_t*
>(m_FramebufferBase + frameBufferOffset + (i * 3));
497 *p = (*p & 0xFF000000) | transformColour;
499 }
else if (bytesPerPixel == 2) {
500 if ((copySize % 8) == 0)
502 uint64_t val = (
static_cast<uint64_t
>(transformColour) << 48) |
503 (
static_cast<uint64_t
>(transformColour) << 32) | (transformColour << 16) |
505 QuadWordSet(dest, val, copySize / 8);
506 }
else if ((copySize % 4) == 0)
508 uint32_t val = (transformColour << 16) | transformColour;
509 DoubleWordSet(dest, val, copySize / 4);
511 WordSet(dest, transformColour, copySize / 2);
513 ByteSet(dest, transformColour, (width * bytesPerPixel));
523 if (
UNLIKELY((srcx == destx) && (srcy == desty)))
540 if ((srcx == destx) && (srcy == desty))
551 size_t frameBufferOffsetSrc = (srcy * bytesPerLine) + (srcx * bytesPerPixel);
552 size_t frameBufferOffsetDest = (desty * bytesPerLine) + (destx * bytesPerPixel);
554 void* dest =
reinterpret_cast<void*
>(m_FramebufferBase + frameBufferOffsetDest);
555 void* src =
reinterpret_cast<void*
>(m_FramebufferBase + frameBufferOffsetSrc);
557 MemoryCopy(dest, src, h * bytesPerLine);
560 for (
size_t yoff = 0; yoff < h; yoff++) {
561 size_t frameBufferOffsetSrc = ((srcy + yoff) * bytesPerLine) + (srcx * bytesPerPixel);
562 size_t frameBufferOffsetDest = ((desty + yoff) * bytesPerLine) + (destx * bytesPerPixel);
564 void* dest =
reinterpret_cast<void*
>(m_FramebufferBase + frameBufferOffsetDest);
565 void* src =
reinterpret_cast<void*
>(m_FramebufferBase + frameBufferOffsetSrc);
567 MemoryCopy(dest, src, w * bytesPerPixel);
572void Framebuffer::swLine(
size_t x1,
size_t y1,
size_t x2,
size_t y2, uint32_t colour,
573 Graphics::PixelFormat format) {
590 if (
UNLIKELY((x1 == x2) && (y1 == y2)))
593 uint32_t transformColour = 0;
594 if (format == Graphics::Bits8_Idx) {
595 uint32_t source =
m_Palette[colour & 0xFF];
596 Graphics::convertPixel(source, Graphics::Bits24_Bgr, transformColour,
m_PixelFormat);
598 Graphics::convertPixel(colour, format, transformColour,
m_PixelFormat);
605 for (
size_t y = y1; y < y2; y++)
608 }
else if (y1 == y2) {
611 for (
size_t x = x1; x < x2; x++)
620 ssize_t dx =
static_cast<ssize_t
>(x2) -
static_cast<ssize_t
>(x1);
621 ssize_t dy =
static_cast<ssize_t
>(y2) -
static_cast<ssize_t
>(y1);
622 ssize_t p = 2 * (dy - dx);
662 uint32_t transformColour = 0;
663 if (format == Graphics::Bits8_Idx) {
664 uint32_t source =
m_Palette[colour & 0xFF];
665 Graphics::convertPixel(source, Graphics::Bits24_Bgr, transformColour,
m_PixelFormat);
667 Graphics::convertPixel(colour, format, transformColour,
m_PixelFormat);
669 size_t frameBufferOffset = (y * bytesPerLine) + (x * bytesPerPixel);
671 if (bytesPerPixel == 4) {
672 uint32_t* pDest =
reinterpret_cast<uint32_t*
>(m_FramebufferBase + frameBufferOffset);
673 *pDest = transformColour;
674 }
else if (bytesPerPixel == 3) {
676 uint32_t* pDest =
reinterpret_cast<uint32_t*
>(m_FramebufferBase + frameBufferOffset);
677 *pDest = (*pDest & 0xFF000000) | (transformColour & 0xFFFFFF);
678 }
else if (bytesPerPixel == 2) {
679 uint16_t* pDest =
reinterpret_cast<uint16_t*
>(m_FramebufferBase + frameBufferOffset);
680 *pDest = transformColour & 0xFFFF;
681 }
else if (bytesPerPixel == 1) {
686void Framebuffer::swDraw(
void* pBuffer,
size_t srcx,
size_t srcy,
size_t destx,
size_t desty,
687 size_t width,
size_t height, Graphics::PixelFormat format,
695 blit(p, srcx, srcy, destx, desty, width, height, bLowestCall);
699void Framebuffer::swDraw(
Graphics::Buffer* pBuffer,
size_t srcx,
size_t srcy,
size_t destx,
700 size_t desty,
size_t width,
size_t height,
bool bLowestCall) {
701 blit(pBuffer, srcx, srcy, destx, desty, width, height, bLowestCall);
virtual void hwRedraw(size_t x=~0UL, size_t y=~0UL, size_t w=~0UL, size_t h=~0UL)
Inherited by drivers that provide a hardware redraw function.
uint32_t * m_Palette
Current graphics palette - an array of 256 32-bit RGBA entries.
virtual Graphics::Buffer * createBuffer(const void *srcData, Graphics::PixelFormat srcFormat, size_t width, size_t height, uint32_t *pPalette=0)
Graphics::PixelFormat m_PixelFormat
Framebuffer pixel format.
void swSetPixel(size_t x, size_t y, uint32_t colour, Graphics::PixelFormat format=Graphics::Bits32_Argb)
virtual void blit(Graphics::Buffer *pBuffer, size_t srcx, size_t srcy, size_t destx, size_t desty, size_t width, size_t height, bool bLowestCall=true)
size_t m_nBytesPerPixel
Bytes per pixel in this framebuffer.
virtual void copy(size_t srcx, size_t srcy, size_t destx, size_t desty, size_t w, size_t h, bool bLowestCall=true)
bool m_bActive
Whether this framebuffer is active or not.
void swRect(size_t x, size_t y, size_t width, size_t height, uint32_t colour, Graphics::PixelFormat format)
virtual void draw(void *pBuffer, size_t srcx, size_t srcy, size_t destx, size_t desty, size_t width, size_t height, Graphics::PixelFormat format=Graphics::Bits32_Argb, bool bLowestCall=true)
Graphics::Buffer * swCreateBuffer(const void *srcData, Graphics::PixelFormat srcFormat, size_t width, size_t height, uint32_t *pPalette)
virtual physical_uintptr_t getPhysicalPage(size_t offset) const
virtual void destroyBuffer(Graphics::Buffer *pBuffer)
virtual void * getRawBuffer() const
void swCopy(size_t srcx, size_t srcy, size_t destx, size_t desty, size_t w, size_t h)
void setPalette(uint32_t *palette, size_t nEntries)
size_t m_XPos
X position on our parent's framebuffer.
void setPixel(size_t x, size_t y, uint32_t colour, Graphics::PixelFormat format=Graphics::Bits32_Argb, bool bLowestCall=true)
size_t m_nWidth
Width of the framebuffer in pixels.
size_t m_nHeight
Height of the framebuffer in pixels.
size_t m_YPos
Y position on our parent's framebuffer.
void swBlit(Graphics::Buffer *pBuffer, size_t srcx, size_t srcy, size_t destx, size_t desty, size_t width, size_t height)
virtual void rect(size_t x, size_t y, size_t width, size_t height, uint32_t colour, Graphics::PixelFormat format=Graphics::Bits32_Argb, bool bLowestCall=true)
virtual void line(size_t x1, size_t y1, size_t x2, size_t y2, uint32_t colour, Graphics::PixelFormat format=Graphics::Bits32_Argb, bool bLowestCall=true)
void redraw(size_t x=~0UL, size_t y=~0UL, size_t w=~0UL, size_t h=~0UL, bool bChild=false)
size_t m_nBytesPerLine
Bytes per line in this framebuffer.
Framebuffer * m_pParent
Parent of this framebuffer.
Special memory entity in the kernel's virtual address space.
void * virtualAddress() const
static PhysicalMemoryManager & instance()
static constexpr size_t getPageSize() PURE
virtual bool allocateRegion(MemoryRegion &Region, size_t cPages, size_t pageConstraints, size_t Flags, physical_uintptr_t start=-1)=0
static const size_t Write
size_t bytesPerPixel
Number of bytes per pixel (as it may be different to the format).
size_t width
Width of the buffer in pixels.
uintptr_t base
Base of this buffer in memory. For internal use only.
size_t height
Height of the buffer in pixels.
size_t bufferId
Buffer ID, for easy identification within drivers.