diff options
Diffstat (limited to 'kms++/src/omap')
-rw-r--r-- | kms++/src/omap/omapframebuffer.cpp | 81 |
1 files changed, 67 insertions, 14 deletions
diff --git a/kms++/src/omap/omapframebuffer.cpp b/kms++/src/omap/omapframebuffer.cpp index e1e2234..b27ca22 100644 --- a/kms++/src/omap/omapframebuffer.cpp +++ b/kms++/src/omap/omapframebuffer.cpp @@ -17,20 +17,24 @@ extern "C" { #include <omap_drmif.h> } +#define __round_mask(x, y) ((__typeof__(x))((y)-1)) +#define round_up(x, y) ((((x)-1) | __round_mask(x, y))+1) +#define PAGE_SIZE 4096 + using namespace std; namespace kms { -OmapFramebuffer::OmapFramebuffer(OmapCard& card, uint32_t width, uint32_t height, const string& fourcc) - : OmapFramebuffer(card, width, height, FourCCToPixelFormat(fourcc)) +OmapFramebuffer::OmapFramebuffer(OmapCard& card, uint32_t width, uint32_t height, const string& fourcc, Flags flags) + : OmapFramebuffer(card, width, height, FourCCToPixelFormat(fourcc), flags) { } -OmapFramebuffer::OmapFramebuffer(OmapCard& card, uint32_t width, uint32_t height, PixelFormat format) - : MappedFramebuffer(card, width, height), m_omap_card(card), m_format(format) +OmapFramebuffer::OmapFramebuffer(OmapCard& card, uint32_t width, uint32_t height, PixelFormat format, Flags flags) + :MappedFramebuffer(card, width, height), m_omap_card(card), m_format(format) { - Create(); + Create(flags); } OmapFramebuffer::~OmapFramebuffer() @@ -38,7 +42,7 @@ OmapFramebuffer::~OmapFramebuffer() Destroy(); } -void OmapFramebuffer::Create() +void OmapFramebuffer::Create(Flags buffer_flags) { const PixelFormatInfo& format_info = get_pixel_format_info(m_format); @@ -50,13 +54,61 @@ void OmapFramebuffer::Create() uint32_t flags = OMAP_BO_SCANOUT | OMAP_BO_WC; - uint32_t size = width() * height() * pi.bitspp / 8; - - struct omap_bo* bo = omap_bo_new(m_omap_card.dev(), size, flags); - if (!bo) - throw invalid_argument(string("omap_bo_new failed: ") + strerror(errno)); - - uint32_t stride = width() * pi.bitspp / 8; +#if defined(OMAP_BO_MEM_CONTIG) + if (buffer_flags & Flags::MemContig) + flags |= OMAP_BO_MEM_CONTIG; + if (buffer_flags & Flags::MemTiler) + flags |= OMAP_BO_MEM_TILER; + if (buffer_flags & Flags::MemPin) + flags |= OMAP_BO_MEM_PIN; +#endif + + struct omap_bo* bo; + + uint32_t stride; + + if (!(buffer_flags & Flags::Tiled)) { + stride = width() * pi.bitspp / 8; + + uint32_t size = stride * height() / pi.ysub; + + bo = omap_bo_new(m_omap_card.dev(), size, flags); + if (!bo) + throw invalid_argument(string("omap_bo_new failed: ") + strerror(errno)); + } else { + unsigned bitspertiler; + + switch (m_format) { + case PixelFormat::NV12: + bitspertiler = i == 0 ? 8 : 16; break; + case PixelFormat::YUYV: + case PixelFormat::UYVY: + bitspertiler = 32; break; + case PixelFormat::ARGB8888: + case PixelFormat::XRGB8888: + bitspertiler = 32; break; + case PixelFormat::RGB565: + bitspertiler = 16; break; + default: + throw invalid_argument("unimplemented format"); + } + + switch (bitspertiler) { + case 8: flags |= OMAP_BO_TILED_8; break; + case 16: flags |= OMAP_BO_TILED_16; break; + case 32: flags |= OMAP_BO_TILED_32; break; + default: + throw invalid_argument("bad bitspertiler"); + } + + uint32_t width_tiler = width() * pi.bitspp / bitspertiler; + + bo = omap_bo_new_tiled(m_omap_card.dev(), width_tiler, height(), flags); + if (!bo) + throw invalid_argument(string("omap_bo_new_tiled failed: ") + strerror(errno)); + + stride = round_up(width() * pi.bitspp / 8, PAGE_SIZE); + } plane.omap_bo = bo; plane.handle = omap_bo_handle(bo); @@ -67,7 +119,7 @@ void OmapFramebuffer::Create() plane.prime_fd = -1; } - /* create framebuffer object for the dumb-buffer */ + /* create framebuffer object */ uint32_t bo_handles[4] = { m_planes[0].handle, m_planes[1].handle }; uint32_t pitches[4] = { m_planes[0].stride, m_planes[1].stride }; uint32_t offsets[4] = { m_planes[0].offset, m_planes[1].offset }; @@ -82,6 +134,7 @@ void OmapFramebuffer::Create() void OmapFramebuffer::Destroy() { + /* delete framebuffer */ drmModeRmFB(card().fd(), id()); for (uint i = 0; i < m_num_planes; ++i) { |