diff options
Diffstat (limited to 'kms++/src/dumbframebuffer.cpp')
-rw-r--r-- | kms++/src/dumbframebuffer.cpp | 42 |
1 files changed, 32 insertions, 10 deletions
diff --git a/kms++/src/dumbframebuffer.cpp b/kms++/src/dumbframebuffer.cpp index 3448fb1..fc50586 100644 --- a/kms++/src/dumbframebuffer.cpp +++ b/kms++/src/dumbframebuffer.cpp @@ -19,14 +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) + : Framebuffer(card, width, height), m_format(format) { int r; @@ -42,6 +41,14 @@ DumbFramebuffer::DumbFramebuffer(Card& card, uint32_t width, uint32_t height, Pi struct drm_mode_create_dumb creq = drm_mode_create_dumb(); 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); if (r) @@ -56,9 +63,24 @@ DumbFramebuffer::DumbFramebuffer(Card& card, uint32_t width, uint32_t height, Pi } /* 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, bo_handles, pitches, offsets, &id, 0); @@ -104,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)); @@ -125,4 +147,4 @@ int DumbFramebuffer::prime_fd(unsigned int plane) return m_planes.at(plane).prime_fd; } -} +} // namespace kms |