omapfb: add TILER support
authorTomi Valkeinen <tomi.valkeinen@ti.com>
Thu, 18 May 2017 10:21:07 +0000 (13:21 +0300)
committerTomi Valkeinen <tomi.valkeinen@ti.com>
Wed, 24 May 2017 10:23:07 +0000 (13:23 +0300)
Add TILER rotation support for omapframebuffer.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
kms++/inc/kms++/omap/omapframebuffer.h
kms++/src/omap/omapframebuffer.cpp
py/pykms/pykmsomap.cpp

index 16d6cf87dd6759934c148f0757a5af5d3a577cdf..dcaaa4fd9a97039680cc42354607e0712ef74440 100644 (file)
@@ -12,8 +12,8 @@ class OmapCard;
 class OmapFramebuffer : public MappedFramebuffer
 {
 public:
-       OmapFramebuffer(OmapCard& card, uint32_t width, uint32_t height, const std::string& fourcc);
-       OmapFramebuffer(OmapCard& card, uint32_t width, uint32_t height, PixelFormat format);
+       OmapFramebuffer(OmapCard& card, uint32_t width, uint32_t height, const std::string& fourcc, bool tiled = false);
+       OmapFramebuffer(OmapCard& card, uint32_t width, uint32_t height, PixelFormat format, bool tiled = false);
        virtual ~OmapFramebuffer();
 
        uint32_t width() const { return Framebuffer::width(); }
@@ -42,7 +42,7 @@ private:
                uint8_t* map;
        };
 
-       void Create();
+       void Create(bool tiled);
        void Destroy();
 
        unsigned m_num_planes;
index e1e2234a49985e3baec60da0863b3245519c1d66..9997933d85eff05aea5a78d7a1564e54d9adc4d0 100644 (file)
@@ -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, bool tiled)
+       : OmapFramebuffer(card, width, height, FourCCToPixelFormat(fourcc), tiled)
 {
 }
 
-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, bool tiled)
+       :MappedFramebuffer(card, width, height), m_omap_card(card), m_format(format)
 {
-       Create();
+       Create(tiled);
 }
 
 OmapFramebuffer::~OmapFramebuffer()
@@ -38,7 +42,7 @@ OmapFramebuffer::~OmapFramebuffer()
        Destroy();
 }
 
-void OmapFramebuffer::Create()
+void OmapFramebuffer::Create(bool tiled)
 {
        const PixelFormatInfo& format_info = get_pixel_format_info(m_format);
 
@@ -50,13 +54,52 @@ 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;
+               struct omap_bo* bo;
+
+               uint32_t stride;
+
+               if (!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 +110,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 +125,7 @@ void OmapFramebuffer::Create()
 
 void OmapFramebuffer::Destroy()
 {
+       /* delete framebuffer */
        drmModeRmFB(card().fd(), id());
 
        for (uint i = 0; i < m_num_planes; ++i) {
index 7480c782b1fd8bc47accda09114b94b52f74dd2c..bad20fb0f3852c39ea25d3aeb7e82a7a70704fd3 100644 (file)
@@ -15,10 +15,12 @@ void init_pykmsomap(py::module &m)
                        ;
 
        py::class_<OmapFramebuffer>(m, "OmapFramebuffer", py::base<MappedFramebuffer>())
-                       .def(py::init<OmapCard&, uint32_t, uint32_t, const string&>(),
-                            py::keep_alive<1, 2>())    // Keep Card alive until this is destructed
-                       .def(py::init<OmapCard&, uint32_t, uint32_t, PixelFormat>(),
-                            py::keep_alive<1, 2>())    // Keep OmapCard alive until this is destructed
+                       .def(py::init<OmapCard&, uint32_t, uint32_t, const string&, bool>(),
+                            py::keep_alive<1, 2>(),    // Keep Card alive until this is destructed
+                            py::arg("card"), py::arg("width"), py::arg("height"), py::arg("fourcc"), py::arg("tiled") = false)
+                       .def(py::init<OmapCard&, uint32_t, uint32_t, PixelFormat, bool>(),
+                            py::keep_alive<1, 2>(),    // Keep OmapCard alive until this is destructed
+                            py::arg("card"), py::arg("width"), py::arg("height"), py::arg("pixfmt"), py::arg("tiled") = false)
                        .def_property_readonly("format", &OmapFramebuffer::format)
                        .def_property_readonly("num_planes", &OmapFramebuffer::num_planes)
                        .def("fd", &OmapFramebuffer::prime_fd)