improve ExtFb
authorTomi Valkeinen <tomi.valkeinen@ti.com>
Fri, 10 Feb 2017 05:03:38 +0000 (07:03 +0200)
committerTomi Valkeinen <tomi.valkeinen@ti.com>
Fri, 10 Feb 2017 08:54:04 +0000 (10:54 +0200)
Inherit MappedFramebuffer and add map()

kms++/inc/kms++/extframebuffer.h
kms++/src/extframebuffer.cpp

index 227a57631e8c36738833de81d3c00eff81e1f39a..89551c3c30d332cf695147594c9a801170079f78 100644 (file)
@@ -1,12 +1,12 @@
 #pragma once
 
-#include "framebuffer.h"
+#include "mappedframebuffer.h"
 #include "pixelformats.h"
 
 namespace kms
 {
 
-class ExtFramebuffer : public Framebuffer
+class ExtFramebuffer : public MappedFramebuffer
 {
 public:
        ExtFramebuffer(Card& card, uint32_t width, uint32_t height, PixelFormat format,
@@ -15,6 +15,32 @@ public:
                       int fds[4], uint32_t pitches[4], uint32_t offsets[4]);
        virtual ~ExtFramebuffer();
 
+       uint32_t width() const { return Framebuffer::width(); }
+       uint32_t height() const { return Framebuffer::height(); }
+
+       PixelFormat format() const { return m_format; }
+       unsigned num_planes() const { return m_num_planes; }
+
+       uint32_t handle(unsigned plane) const { return m_planes[plane].handle; }
+       uint32_t stride(unsigned plane) const { return m_planes[plane].stride; }
+       uint32_t size(unsigned plane) const { return m_planes[plane].size; }
+       uint32_t offset(unsigned plane) const { return m_planes[plane].offset; }
+       uint8_t* map(unsigned plane);
+
 private:
+       struct FramebufferPlane {
+               uint32_t handle;
+               int prime_fd;
+               uint32_t size;
+               uint32_t stride;
+               uint32_t offset;
+               uint8_t *map;
+       };
+
+       unsigned m_num_planes;
+       struct FramebufferPlane m_planes[4];
+
+       PixelFormat m_format;
 };
+
 }
index 1af2f628df8598e64f635165680d051ed380d132..2f23a33ed538e7c793827feff640fe03265b3f5f 100644 (file)
@@ -14,8 +14,26 @@ namespace kms
 
 ExtFramebuffer::ExtFramebuffer(Card& card, uint32_t width, uint32_t height, PixelFormat format,
                               uint32_t handles[], uint32_t pitches[], uint32_t offsets[])
-       : Framebuffer(card, width, height)
+       : MappedFramebuffer(card, width, height)
 {
+       m_format = format;
+
+       const PixelFormatInfo& format_info = get_pixel_format_info(format);
+
+       m_num_planes = format_info.num_planes;
+
+       for (int i = 0; i < format_info.num_planes; ++i) {
+               FramebufferPlane& plane = m_planes[i];
+
+               plane.handle = handles[i];
+               plane.prime_fd = 0;
+
+               plane.stride = pitches[i];
+               plane.offset = offsets[i];
+               plane.size = plane.stride * height;
+               plane.map = 0;
+       }
+
        uint32_t id;
        int r = drmModeAddFB2(card.fd(), width, height, (uint32_t)format, handles, pitches, offsets, &id, 0);
        if (r)
@@ -26,23 +44,35 @@ ExtFramebuffer::ExtFramebuffer(Card& card, uint32_t width, uint32_t height, Pixe
 
 ExtFramebuffer::ExtFramebuffer(Card& card, uint32_t width, uint32_t height, PixelFormat format,
                               int fds[4], uint32_t pitches[4], uint32_t offsets[4])
-       : Framebuffer(card, width, height)
+       : MappedFramebuffer(card, width, height)
 {
        int r;
 
+       m_format = format;
+
        const PixelFormatInfo& format_info = get_pixel_format_info(format);
 
-       uint32_t handles[4] = { 0 };
+       m_num_planes = format_info.num_planes;
 
        for (int i = 0; i < format_info.num_planes; ++i) {
-               r = drmPrimeFDToHandle(card.fd(), fds[i], &handles[i]);
+               FramebufferPlane& plane = m_planes[i];
+
+               plane.prime_fd = fds[i];
+
+               r = drmPrimeFDToHandle(card.fd(), fds[i], &plane.handle);
                if (r)
                        throw invalid_argument(string("drmPrimeFDToHandle: ") + strerror(errno));
+
+               plane.stride = pitches[i];
+               plane.offset = offsets[i];
+               plane.size = plane.stride * height;
+               plane.map = 0;
        }
 
        uint32_t id;
+       uint32_t bo_handles[4] = { m_planes[0].handle, m_planes[1].handle };
        r = drmModeAddFB2(card.fd(), width, height, (uint32_t)format,
-                         handles, pitches, offsets, &id, 0);
+                         bo_handles, pitches, offsets, &id, 0);
        if (r)
                throw invalid_argument(string("drmModeAddFB2 failed: ") + strerror(errno));
 
@@ -54,4 +84,22 @@ ExtFramebuffer::~ExtFramebuffer()
        drmModeRmFB(card().fd(), id());
 }
 
+uint8_t* ExtFramebuffer::map(unsigned plane)
+{
+       FramebufferPlane& p = m_planes[plane];
+
+       if (!p.prime_fd)
+               throw invalid_argument("cannot mmap non-dmabuf fb");
+
+       if (p.map)
+               return p.map;
+
+       p.map = (uint8_t *)mmap(0, p.size, PROT_READ | PROT_WRITE, MAP_SHARED,
+                                         p.prime_fd, 0);
+       if (p.map == MAP_FAILED)
+               throw invalid_argument(string("mmap failed: ") + strerror(errno));
+
+       return p.map;
+}
+
 }