diff options
Diffstat (limited to 'kms++/src/dumbframebuffer.cpp')
-rw-r--r-- | kms++/src/dumbframebuffer.cpp | 78 |
1 files changed, 45 insertions, 33 deletions
diff --git a/kms++/src/dumbframebuffer.cpp b/kms++/src/dumbframebuffer.cpp index 4419687..fc50586 100644 --- a/kms++/src/dumbframebuffer.cpp +++ b/kms++/src/dumbframebuffer.cpp @@ -19,24 +19,13 @@ using namespace std; namespace kms { - -DumbFramebuffer::DumbFramebuffer(Card &card, uint32_t width, uint32_t height, const string& fourcc) - :DumbFramebuffer(card, width, height, FourCCToPixelFormat(fourcc)) +DumbFramebuffer::DumbFramebuffer(Card& card, uint32_t width, uint32_t height, const string& fourcc) + : DumbFramebuffer(card, width, height, FourCCToPixelFormat(fourcc)) { } DumbFramebuffer::DumbFramebuffer(Card& card, uint32_t width, uint32_t height, PixelFormat format) - :Framebuffer(card, width, height), m_format(format) -{ - Create(); -} - -DumbFramebuffer::~DumbFramebuffer() -{ - Destroy(); -} - -void DumbFramebuffer::Create() + : Framebuffer(card, width, height), m_format(format) { int r; @@ -46,14 +35,22 @@ void DumbFramebuffer::Create() for (int i = 0; i < format_info.num_planes; ++i) { const PixelFormatPlaneInfo& pi = format_info.planes[i]; - FramebufferPlane& plane = m_planes[i]; + FramebufferPlane& plane = m_planes.at(i); /* create dumb buffer */ struct drm_mode_create_dumb creq = drm_mode_create_dumb(); - creq.width = width(); - creq.height = height() / pi.ysub; + creq.width = width; + creq.height = height / pi.ysub; + /* + * For fully planar YUV buffers, the chroma planes don't combine + * U and V components, their width must thus be divided by the + * horizontal subsampling factor. + */ + if (format_info.type == PixelColorType::YUV && + format_info.num_planes == 3) + creq.width /= pi.xsub; creq.bpp = pi.bitspp; - r = drmIoctl(card().fd(), DRM_IOCTL_MODE_CREATE_DUMB, &creq); + r = drmIoctl(card.fd(), DRM_IOCTL_MODE_CREATE_DUMB, &creq); if (r) throw invalid_argument(string("DRM_IOCTL_MODE_CREATE_DUMB failed: ") + strerror(errno)); @@ -66,11 +63,26 @@ void DumbFramebuffer::Create() } /* create framebuffer object for the dumb-buffer */ - 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 }; + uint32_t bo_handles[4] = { + m_planes[0].handle, + m_planes[1].handle, + m_planes[2].handle, + m_planes[3].handle, + }; + uint32_t pitches[4] = { + m_planes[0].stride, + m_planes[1].stride, + m_planes[2].stride, + m_planes[3].stride, + }; + uint32_t offsets[4] = { + m_planes[0].offset, + m_planes[1].offset, + m_planes[2].offset, + m_planes[3].offset, + }; uint32_t id; - r = drmModeAddFB2(card().fd(), width(), height(), (uint32_t)format(), + r = drmModeAddFB2(card.fd(), width, height, (uint32_t)format, bo_handles, pitches, offsets, &id, 0); if (r) throw invalid_argument(string("drmModeAddFB2 failed: ") + strerror(errno)); @@ -78,13 +90,13 @@ void DumbFramebuffer::Create() set_id(id); } -void DumbFramebuffer::Destroy() +DumbFramebuffer::~DumbFramebuffer() { /* delete framebuffer */ drmModeRmFB(card().fd(), id()); for (uint i = 0; i < m_num_planes; ++i) { - FramebufferPlane& plane = m_planes[i]; + FramebufferPlane& plane = m_planes.at(i); /* unmap buffer */ if (plane.map) @@ -101,7 +113,7 @@ void DumbFramebuffer::Destroy() uint8_t* DumbFramebuffer::map(unsigned plane) { - FramebufferPlane& p = m_planes[plane]; + FramebufferPlane& p = m_planes.at(plane); if (p.map) return p.map; @@ -114,8 +126,8 @@ uint8_t* DumbFramebuffer::map(unsigned plane) throw invalid_argument(string("DRM_IOCTL_MODE_MAP_DUMB failed: ") + strerror(errno)); /* perform actual memory mapping */ - p.map = (uint8_t *)mmap(0, p.size, PROT_READ | PROT_WRITE, MAP_SHARED, - card().fd(), mreq.offset); + p.map = (uint8_t*)mmap(0, p.size, PROT_READ | PROT_WRITE, MAP_SHARED, + card().fd(), mreq.offset); if (p.map == MAP_FAILED) throw invalid_argument(string("mmap failed: ") + strerror(errno)); @@ -124,15 +136,15 @@ uint8_t* DumbFramebuffer::map(unsigned plane) int DumbFramebuffer::prime_fd(unsigned int plane) { - if (m_planes[plane].prime_fd >= 0) - return m_planes[plane].prime_fd; + if (m_planes.at(plane).prime_fd >= 0) + return m_planes.at(plane).prime_fd; - int r = drmPrimeHandleToFD(card().fd(), m_planes[plane].handle, - DRM_CLOEXEC | O_RDWR, &m_planes[plane].prime_fd); + int r = drmPrimeHandleToFD(card().fd(), m_planes.at(plane).handle, + DRM_CLOEXEC | O_RDWR, &m_planes.at(plane).prime_fd); if (r) throw std::runtime_error("drmPrimeHandleToFD failed"); - return m_planes[plane].prime_fd; + return m_planes.at(plane).prime_fd; } -} +} // namespace kms |