20 #include "pedigree/kernel/machine/Framebuffer.h" 21 #include "pedigree/kernel/Log.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" 27 Framebuffer::Framebuffer() : m_pParent(0), m_FramebufferBase(0), m_bActive(true)
29 m_Palette =
new uint32_t[256];
32 for (
size_t g = 0; g <= 255; g += 0x33)
33 for (
size_t b = 0; b <= 255; b += 0x33)
34 for (
size_t r = 0; r <= 255; r += 0x33)
35 m_Palette[i++] = Graphics::createRgb(r, g, b);
38 "Framebuffer: created " <<
Dec << i <<
Hex 39 <<
" entries in the default palette");
42 Framebuffer::~Framebuffer()
46 size_t Framebuffer::getWidth()
const 51 size_t Framebuffer::getHeight()
const 56 Graphics::PixelFormat Framebuffer::getFormat()
const 61 bool Framebuffer::getActive()
const 66 void Framebuffer::setActive(
bool b)
74 m_Palette =
new uint32_t[nEntries];
75 MemoryCopy(m_Palette, palette, nEntries *
sizeof(uint32_t));
78 "Framebuffer: new palette set with " <<
Dec << nEntries <<
Hex 82 uint32_t *Framebuffer::getPalette()
const 90 return m_pParent->getRawBuffer();
91 return reinterpret_cast<void *
>(m_FramebufferBase);
95 const void *srcData, Graphics::PixelFormat srcFormat,
size_t width,
96 size_t height, uint32_t *pPalette)
99 return m_pParent->createBuffer(
100 srcData, srcFormat, width, height, pPalette);
101 return swCreateBuffer(srcData, srcFormat, width, height, pPalette);
109 swDestroyBuffer(pBuffer);
132 if (m_pParent->getFormat() == m_PixelFormat)
136 &buf, x, y, m_XPos + x, m_YPos + y, w, h,
false);
143 ERROR(
"Child framebuffer has different pixel format to " 150 m_pParent->redraw(m_XPos + x, m_YPos + y, w, h,
true);
153 hwRedraw(x, y, w, h);
158 size_t desty,
size_t width,
size_t height,
bool bLowestCall)
162 pBuffer, srcx, srcy, m_XPos + destx, m_YPos + desty, width, height,
164 if (bLowestCall || !m_pParent)
165 swBlit(pBuffer, srcx, srcy, destx, desty, width, height);
169 void *pBuffer,
size_t srcx,
size_t srcy,
size_t destx,
size_t desty,
170 size_t width,
size_t height, Graphics::PixelFormat format,
bool bLowestCall)
176 pBuffer, srcx, srcy, destx, desty, width, height, format, bLowestCall);
180 size_t x,
size_t y,
size_t width,
size_t height, uint32_t colour,
181 Graphics::PixelFormat format,
bool bLowestCall)
185 m_XPos + x, m_YPos + y, width, height, colour, format,
false);
186 if (bLowestCall || !m_pParent)
187 swRect(x, y, width, height, colour, format);
191 size_t srcx,
size_t srcy,
size_t destx,
size_t desty,
size_t w,
size_t h,
196 m_XPos + srcx, m_YPos + srcy, m_XPos + destx, m_YPos + desty, w, h,
198 if (bLowestCall || !m_pParent)
199 swCopy(srcx, srcy, destx, desty, w, h);
203 size_t x1,
size_t y1,
size_t x2,
size_t y2, uint32_t colour,
204 Graphics::PixelFormat format,
bool bLowestCall)
208 m_XPos + x1, m_YPos + y1, m_XPos + x2, m_YPos + y2, colour, format,
210 if (bLowestCall || !m_pParent)
211 swLine(x1, y1, x2, y2, colour, format);
215 size_t x,
size_t y, uint32_t colour, Graphics::PixelFormat format,
219 m_pParent->setPixel(m_XPos + x, m_YPos + y, colour, format,
false);
220 if (bLowestCall || !m_pParent)
221 swSetPixel(x, y, colour, format);
224 void Framebuffer::setXPos(
size_t x)
229 void Framebuffer::setYPos(
size_t y)
234 void Framebuffer::setWidth(
size_t w)
239 void Framebuffer::setHeight(
size_t h)
244 void Framebuffer::setFormat(Graphics::PixelFormat pf)
249 void Framebuffer::setBytesPerPixel(
size_t b)
251 m_nBytesPerPixel = b;
254 uint32_t Framebuffer::getBytesPerPixel()
const 256 return m_nBytesPerPixel;
259 void Framebuffer::setBytesPerLine(
size_t b)
264 uint32_t Framebuffer::getBytesPerLine()
const 266 return m_nBytesPerLine;
279 void Framebuffer::setFramebuffer(uintptr_t p)
281 m_FramebufferBase = p;
287 ret.
base = m_FramebufferBase;
288 ret.
width = m_nWidth;
290 ret.
format = m_PixelFormat;
299 size_t desty,
size_t width,
size_t height,
bool bLowestCall)
301 swDraw(pBuffer, srcx, srcy, destx, desty, width, height, bLowestCall);
305 const void *srcData, Graphics::PixelFormat srcFormat,
size_t width,
306 size_t height, uint32_t *pPalette)
313 Graphics::PixelFormat destFormat = m_PixelFormat;
315 size_t sourceBytesPerPixel = bytesPerPixel(srcFormat);
316 size_t sourceBytesPerLine = width * sourceBytesPerPixel;
318 size_t destBytesPerPixel = m_nBytesPerPixel;
319 size_t destBytesPerLine = width * destBytesPerPixel;
321 size_t fullBufferSize = height * destBytesPerLine;
335 if (((sourceBytesPerPixel == destBytesPerPixel) &&
336 (sourceBytesPerLine == destBytesPerLine)) &&
337 (srcFormat == destFormat))
344 MemoryCopy(pAddress, srcData, fullBufferSize);
350 for (y = 0; y < height; y++)
352 for (x = 0; x < width; x++)
354 size_t sourceOffset =
355 (y * sourceBytesPerLine) + (x * sourceBytesPerPixel);
357 (y * destBytesPerLine) + (x * destBytesPerPixel);
361 const uint32_t *pSource =
reinterpret_cast<const uint32_t *
>(
362 adjust_pointer(srcData, sourceOffset));
364 uint32_t transform = 0;
365 if (srcFormat == Graphics::Bits8_Idx)
367 uint32_t source = pPalette[(*pSource) & 0xFF];
368 Graphics::convertPixel(
369 source, Graphics::Bits24_Bgr, transform, destFormat);
373 Graphics::convertPixel(
374 *pSource, srcFormat, transform, destFormat);
377 if (destBytesPerPixel == 4)
379 uint32_t *pDest =
reinterpret_cast<uint32_t *
>(
380 adjust_pointer(pAddress, destOffset));
382 if (sourceBytesPerPixel == 3)
383 transform &= 0xFFFFFF;
384 else if (sourceBytesPerPixel == 2)
389 else if (destBytesPerPixel == 3)
392 uint32_t *pDest =
reinterpret_cast<uint32_t *
>(
393 adjust_pointer(pAddress, destOffset));
394 *pDest = (*pDest & 0xFF000000) | (transform & 0xFFFFFF);
396 else if (destBytesPerPixel == 2)
398 uint16_t *pDest =
reinterpret_cast<uint16_t *
>(
399 adjust_pointer(pAddress, destOffset));
400 *pDest = transform & 0xFFFF;
402 else if (destBytesPerPixel == 1)
412 pBuffer->
width = width;
414 pBuffer->
format = m_PixelFormat;
417 pBuffer->
pBacking =
reinterpret_cast<void *
>(pRegion);
438 size_t desty,
size_t width,
size_t height)
447 size_t bytesPerLine = m_nBytesPerLine;
448 size_t destBytesPerPixel = m_nBytesPerPixel;
451 size_t sourceBytesPerLine = pBuffer->
width * destBytesPerPixel;
454 if ((srcx > pBuffer->
width) || (srcy > pBuffer->
height))
456 if ((destx > m_nWidth) || (desty > m_nHeight))
458 if ((srcx + width) > pBuffer->
width)
459 width = (srcx + width) - pBuffer->
width;
460 if ((srcy + height) > pBuffer->
height)
461 height = (srcy + height) - pBuffer->
height;
462 if ((destx + width) > m_nWidth)
463 width = m_nWidth - destx;
464 if ((desty + height) > m_nHeight)
465 height = m_nHeight - desty;
469 void *pSrc =
reinterpret_cast<void *
>(pBuffer->
base);
472 if (
UNLIKELY((srcx == destx) && (srcx == 0) && (width == m_nWidth)))
474 size_t sourceBufferOffset = (srcy * sourceBytesPerLine);
475 size_t frameBufferOffset = (desty * bytesPerLine);
478 reinterpret_cast<void *
>(m_FramebufferBase + frameBufferOffset);
479 void *src = adjust_pointer(pSrc, sourceBufferOffset);
481 MemoryCopy(dest, src, bytesPerLine * height);
486 for (
size_t y1 = desty, y2 = srcy; y1 < (desty + height); y1++, y2++)
488 size_t sourceBufferOffset =
489 (y2 * sourceBytesPerLine) + (srcx * sourceBytesPerPixel);
490 size_t frameBufferOffset =
491 (y1 * bytesPerLine) + (destx * destBytesPerPixel);
494 reinterpret_cast<void *
>(m_FramebufferBase + frameBufferOffset);
495 void *src = adjust_pointer(pSrc, sourceBufferOffset);
497 MemoryCopy(dest, src, width * destBytesPerPixel);
503 size_t x,
size_t y,
size_t width,
size_t height, uint32_t colour,
504 Graphics::PixelFormat format)
512 if ((x > m_nWidth) || (y > m_nHeight))
514 if (width > m_nWidth)
516 if (height > m_nHeight)
518 if ((x + width) > m_nWidth)
519 width = (x + width) - m_nWidth;
520 if ((y + height) > m_nHeight)
521 height = (y + height) - m_nHeight;
523 uint32_t transformColour = 0;
524 if (format == Graphics::Bits8_Idx)
526 uint32_t source = m_Palette[colour & 0xFF];
527 Graphics::convertPixel(
528 source, Graphics::Bits24_Bgr, transformColour, m_PixelFormat);
531 Graphics::convertPixel(colour, format, transformColour, m_PixelFormat);
533 size_t bytesPerPixel = m_nBytesPerPixel;
534 size_t bytesPerLine = m_nBytesPerLine;
537 if (
UNLIKELY((!x) && (width == m_nWidth)))
539 size_t frameBufferOffset = (y * bytesPerLine) + (x * bytesPerPixel);
542 reinterpret_cast<void *
>(m_FramebufferBase + frameBufferOffset);
544 size_t copySize = (bytesPerLine * height);
545 if (bytesPerPixel == 4)
547 if ((copySize % 8) == 0)
549 uint64_t val = (
static_cast<uint64_t
>(transformColour) << 32) |
551 QuadWordSet(dest, val, copySize / 8);
554 DoubleWordSet(dest, transformColour, copySize / 4);
556 else if (bytesPerPixel == 3)
560 for (
size_t i = 0; i < (copySize / 3); i++)
562 uint32_t *p =
reinterpret_cast<uint32_t *
>(
563 m_FramebufferBase + frameBufferOffset + (i * 3));
564 *p = (*p & 0xFF000000) | transformColour;
567 else if (bytesPerPixel == 2)
569 if ((copySize % 8) == 0)
571 uint64_t val = (
static_cast<uint64_t
>(transformColour) << 48) |
572 (
static_cast<uint64_t
>(transformColour) << 32) |
573 (transformColour << 16) | transformColour;
574 QuadWordSet(dest, val, copySize / 8);
576 else if ((copySize % 4) == 0)
578 uint32_t val = (transformColour << 16) | transformColour;
579 DoubleWordSet(dest, val, copySize / 4);
582 WordSet(dest, transformColour, copySize / 2);
585 ByteSet(dest, transformColour, (bytesPerLine * height));
590 for (
size_t desty = y; desty < (y + height); desty++)
592 size_t frameBufferOffset =
593 (desty * bytesPerLine) + (x * bytesPerPixel);
596 reinterpret_cast<void *
>(m_FramebufferBase + frameBufferOffset);
598 size_t copySize = width * bytesPerPixel;
599 if (bytesPerPixel == 4)
601 if ((copySize % 8) == 0)
604 (
static_cast<uint64_t
>(transformColour) << 32) |
606 QuadWordSet(dest, val, copySize / 8);
609 DoubleWordSet(dest, transformColour, copySize / 4);
611 else if (bytesPerPixel == 3)
615 for (
size_t i = 0; i < (copySize / 3); i++)
617 uint32_t *p =
reinterpret_cast<uint32_t *
>(
618 m_FramebufferBase + frameBufferOffset + (i * 3));
619 *p = (*p & 0xFF000000) | transformColour;
622 else if (bytesPerPixel == 2)
624 if ((copySize % 8) == 0)
627 (
static_cast<uint64_t
>(transformColour) << 48) |
628 (
static_cast<uint64_t
>(transformColour) << 32) |
629 (transformColour << 16) | transformColour;
630 QuadWordSet(dest, val, copySize / 8);
632 else if ((copySize % 4) == 0)
634 uint32_t val = (transformColour << 16) | transformColour;
635 DoubleWordSet(dest, val, copySize / 4);
638 WordSet(dest, transformColour, copySize / 2);
641 ByteSet(dest, transformColour, (width * bytesPerPixel));
647 size_t srcx,
size_t srcy,
size_t destx,
size_t desty,
size_t w,
size_t h)
653 if (
UNLIKELY((srcx == destx) && (srcy == desty)))
657 if ((srcx > m_nWidth) || (srcy > m_nHeight))
659 if ((destx > m_nWidth) || (desty > m_nHeight))
661 if ((srcx + w) > m_nWidth)
662 w = (srcx + w) - m_nWidth;
663 if ((srcy + h) > m_nHeight)
664 h = (srcy + h) - m_nHeight;
665 if ((destx + w) > m_nWidth)
666 w = (destx + w) - m_nWidth;
667 if ((desty + h) > m_nHeight)
668 h = (desty + h) - m_nHeight;
670 if ((srcx == destx) && (srcy == desty))
675 size_t bytesPerLine = m_nBytesPerLine;
676 size_t bytesPerPixel = m_nBytesPerPixel;
680 if (
UNLIKELY(((!srcx) && (!destx)) && (w == m_nWidth)))
682 size_t frameBufferOffsetSrc =
683 (srcy * bytesPerLine) + (srcx * bytesPerPixel);
684 size_t frameBufferOffsetDest =
685 (desty * bytesPerLine) + (destx * bytesPerPixel);
688 reinterpret_cast<void *
>(m_FramebufferBase + frameBufferOffsetDest);
690 reinterpret_cast<void *
>(m_FramebufferBase + frameBufferOffsetSrc);
692 MemoryCopy(dest, src, h * bytesPerLine);
697 for (
size_t yoff = 0; yoff < h; yoff++)
699 size_t frameBufferOffsetSrc =
700 ((srcy + yoff) * bytesPerLine) + (srcx * bytesPerPixel);
701 size_t frameBufferOffsetDest =
702 ((desty + yoff) * bytesPerLine) + (destx * bytesPerPixel);
704 void *dest =
reinterpret_cast<void *
>(
705 m_FramebufferBase + frameBufferOffsetDest);
706 void *src =
reinterpret_cast<void *
>(
707 m_FramebufferBase + frameBufferOffsetSrc);
709 MemoryCopy(dest, src, w * bytesPerPixel);
714 void Framebuffer::swLine(
715 size_t x1,
size_t y1,
size_t x2,
size_t y2, uint32_t colour,
716 Graphics::PixelFormat format)
734 if (
UNLIKELY((x1 == x2) && (y1 == y2)))
737 uint32_t transformColour = 0;
738 if (format == Graphics::Bits8_Idx)
740 uint32_t source = m_Palette[colour & 0xFF];
741 Graphics::convertPixel(
742 source, Graphics::Bits24_Bgr, transformColour, m_PixelFormat);
745 Graphics::convertPixel(colour, format, transformColour, m_PixelFormat);
752 for (
size_t y = y1; y < y2; y++)
753 setPixel(x1, y, transformColour, m_PixelFormat);
760 for (
size_t x = x1; x < x2; x++)
761 setPixel(x, y1, transformColour, m_PixelFormat);
769 ssize_t dx =
static_cast<ssize_t
>(x2) - static_cast<ssize_t>(x1);
770 ssize_t dy =
static_cast<ssize_t
>(y2) - static_cast<ssize_t>(y1);
771 ssize_t p = 2 * (dy - dx);
787 setPixel(x, y, transformColour, m_PixelFormat);
800 setPixel(x, y, transformColour, m_PixelFormat);
805 size_t x,
size_t y, uint32_t colour, Graphics::PixelFormat format)
815 size_t bytesPerPixel = m_nBytesPerPixel;
816 size_t bytesPerLine = m_nBytesPerLine;
818 uint32_t transformColour = 0;
819 if (format == Graphics::Bits8_Idx)
821 uint32_t source = m_Palette[colour & 0xFF];
822 Graphics::convertPixel(
823 source, Graphics::Bits24_Bgr, transformColour, m_PixelFormat);
826 Graphics::convertPixel(colour, format, transformColour, m_PixelFormat);
828 size_t frameBufferOffset = (y * bytesPerLine) + (x * bytesPerPixel);
830 if (bytesPerPixel == 4)
833 reinterpret_cast<uint32_t *
>(m_FramebufferBase + frameBufferOffset);
834 *pDest = transformColour;
836 else if (bytesPerPixel == 3)
840 reinterpret_cast<uint32_t *
>(m_FramebufferBase + frameBufferOffset);
841 *pDest = (*pDest & 0xFF000000) | (transformColour & 0xFFFFFF);
843 else if (bytesPerPixel == 2)
846 reinterpret_cast<uint16_t *
>(m_FramebufferBase + frameBufferOffset);
847 *pDest = transformColour & 0xFFFF;
849 else if (bytesPerPixel == 1)
855 void Framebuffer::swDraw(
856 void *pBuffer,
size_t srcx,
size_t srcy,
size_t destx,
size_t desty,
857 size_t width,
size_t height, Graphics::PixelFormat format,
bool bLowestCall)
862 createBuffer(pBuffer, format, srcx + width, srcy + height, m_Palette);
867 blit(p, srcx, srcy, destx, desty, width, height, bLowestCall);
871 void Framebuffer::swDraw(
873 size_t desty,
size_t width,
size_t height,
bool bLowestCall)
875 blit(pBuffer, srcx, srcy, destx, desty, width, height, bLowestCall);
virtual void copy(size_t srcx, size_t srcy, size_t destx, size_t desty, size_t w, size_t h, bool bLowestCall=true)
static PhysicalMemoryManager & instance()
void swCopy(size_t srcx, size_t srcy, size_t destx, size_t desty, size_t w, size_t h)
uintptr_t base
Base of this buffer in memory. For internal use only.
Graphics::Buffer * swCreateBuffer(const void *srcData, Graphics::PixelFormat srcFormat, size_t width, size_t height, uint32_t *pPalette)
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)
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.
void swRect(size_t x, size_t y, size_t width, size_t height, uint32_t colour, Graphics::PixelFormat format)
void swBlit(Graphics::Buffer *pBuffer, size_t srcx, size_t srcy, size_t destx, size_t desty, size_t width, size_t height)
size_t bufferId
Buffer ID, for easy identification within drivers.
virtual void destroyBuffer(Graphics::Buffer *pBuffer)
virtual void * getRawBuffer() const
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)
static const size_t Write
void redraw(size_t x=~0UL, size_t y=~0UL, size_t w=~0UL, size_t h=~0UL, bool bChild=false)
Special memory entity in the kernel's virtual address space.
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)
void swSetPixel(size_t x, size_t y, uint32_t colour, Graphics::PixelFormat format=Graphics::Bits32_Argb)
Abstracts the system's framebuffer offering.
void setPixel(size_t x, size_t y, uint32_t colour, Graphics::PixelFormat format=Graphics::Bits32_Argb, bool bLowestCall=true)
void setPalette(uint32_t *palette, size_t nEntries)
size_t width
Width of the buffer in pixels.
virtual bool allocateRegion(MemoryRegion &Region, size_t cPages, size_t pageConstraints, size_t Flags, physical_uintptr_t start=-1)=0
void * virtualAddress() const
size_t height
Height of the buffer in pixels.
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)
virtual Graphics::Buffer * createBuffer(const void *srcData, Graphics::PixelFormat srcFormat, size_t width, size_t height, uint32_t *pPalette=0)
size_t bytesPerPixel
Number of bytes per pixel (as it may be different to the format).