omapfb: add constructor with fourcc
[android/external-libkmsxx.git] / kms++ / src / omap / omapframebuffer.cpp
2 #include <cstring>
3 #include <stdexcept>
4 #include <sys/mman.h>
5 #include <xf86drm.h>
6 #include <xf86drmMode.h>
7 #include <fcntl.h>
8 #include <unistd.h>
9 #include <drm_fourcc.h>
10 #include <drm.h>
11 #include <drm_mode.h>
13 #include <kms++/kms++.h>
14 #include <kms++/omap/omapkms++.h>
16 extern "C" {
17 #include <omap_drmif.h>
18 }
20 using namespace std;
22 namespace kms
23 {
25 OmapFramebuffer::OmapFramebuffer(OmapCard& card, uint32_t width, uint32_t height, const string& fourcc)
26         : OmapFramebuffer(card, width, height, FourCCToPixelFormat(fourcc))
27 {
28 }
30 OmapFramebuffer::OmapFramebuffer(OmapCard& card, uint32_t width, uint32_t height, PixelFormat format)
31         : MappedFramebuffer(card, width, height), m_omap_card(card), m_format(format)
32 {
33         Create();
34 }
36 OmapFramebuffer::~OmapFramebuffer()
37 {
38         Destroy();
39 }
41 void OmapFramebuffer::Create()
42 {
43         const PixelFormatInfo& format_info = get_pixel_format_info(m_format);
45         m_num_planes = format_info.num_planes;
47         for (int i = 0; i < format_info.num_planes; ++i) {
48                 const PixelFormatPlaneInfo& pi = format_info.planes[i];
49                 FramebufferPlane& plane = m_planes[i];
51                 uint32_t flags = OMAP_BO_SCANOUT | OMAP_BO_WC;
53                 uint32_t size = width() * height() * pi.bitspp / 8;
55                 struct omap_bo* bo =  omap_bo_new(m_omap_card.dev(), size, flags);
56                 if (!bo)
57                         throw invalid_argument(string("omap_bo_new failed: ") + strerror(errno));
59                 uint32_t stride = width() * pi.bitspp / 8;
61                 plane.omap_bo = bo;
62                 plane.handle = omap_bo_handle(bo);
63                 plane.stride = stride;
64                 plane.size = omap_bo_size(bo);
65                 plane.offset = 0;
66                 plane.map = 0;
67                 plane.prime_fd = -1;
68         }
70         /* create framebuffer object for the dumb-buffer */
71         uint32_t bo_handles[4] = { m_planes[0].handle, m_planes[1].handle };
72         uint32_t pitches[4] = { m_planes[0].stride, m_planes[1].stride };
73         uint32_t offsets[4] = { m_planes[0].offset, m_planes[1].offset };
74         uint32_t id;
75         int r = drmModeAddFB2(card().fd(), width(), height(), (uint32_t)format(),
76                           bo_handles, pitches, offsets, &id, 0);
77         if (r)
78                 throw invalid_argument(string("drmModeAddFB2 failed: ") + strerror(errno));
80         set_id(id);
81 }
83 void OmapFramebuffer::Destroy()
84 {
85         drmModeRmFB(card().fd(), id());
87         for (uint i = 0; i < m_num_planes; ++i) {
88                 FramebufferPlane& plane = m_planes[i];
90                 /* unmap buffer */
91                 if (plane.map)
92                         munmap(plane.map, plane.size);
94                 omap_bo_del(plane.omap_bo);
96                 if (plane.prime_fd >= 0)
97                         ::close(plane.prime_fd);
98         }
99 }
101 uint8_t* OmapFramebuffer::map(unsigned plane)
103         FramebufferPlane& p = m_planes[plane];
105         if (p.map)
106                 return p.map;
108         p.map = (uint8_t*)omap_bo_map(p.omap_bo);
109         if (p.map == MAP_FAILED)
110                 throw invalid_argument(string("mmap failed: ") + strerror(errno));
112         return p.map;
115 int OmapFramebuffer::prime_fd(unsigned int plane)
117         FramebufferPlane& p = m_planes[plane];
119         if (p.prime_fd >= 0)
120                 return p.prime_fd;
122         int fd = omap_bo_dmabuf(p.omap_bo);
123         if (fd < 0)
124                 throw std::runtime_error("omap_bo_dmabuf failed\n");
126         p.prime_fd = fd;
128         return fd;