index fa5562cea1f21df701cb1507982862527c428d1a..4fae49ebc0045bac6cfc08f85d7c9c791ec9194c 100644 (file)
#include <sys/mman.h>
#include <xf86drm.h>
#include <xf86drmMode.h>
+#include <fcntl.h>
+#include <unistd.h>
#include <drm_fourcc.h>
#include <drm.h>
#include <drm_mode.h>
Destroy();
}
-void DumbFramebuffer::print_short() const
-{
- printf("DumbFramebuffer %d\n", id());
-}
-
struct FormatPlaneInfo
{
uint8_t bitspp; /* bits per (macro) pixel */
/* create dumb buffer */
struct drm_mode_create_dumb creq = drm_mode_create_dumb();
- creq.width = width() / pi.xsub;
+ creq.width = width();
creq.height = height() / pi.ysub;
- creq.bpp = pi.bitspp;
+ creq.bpp = pi.bitspp / pi.xsub;
r = drmIoctl(card().fd(), DRM_IOCTL_MODE_CREATE_DUMB, &creq);
if (r)
- throw std::invalid_argument("foo");
+ throw invalid_argument(string("DRM_IOCTL_MODE_CREATE_DUMB failed") + strerror(errno));
plane.handle = creq.handle;
plane.stride = creq.pitch;
plane.size = creq.height * creq.pitch;
plane.offset = 0;
-
- /*
- printf("buf %d: %dx%d, bitspp %d, stride %d, size %d\n",
- i, creq.width, creq.height, pi->bitspp, plane->stride, plane->size);
- */
-
- /* prepare buffer for memory mapping */
- struct drm_mode_map_dumb mreq = drm_mode_map_dumb();
- mreq.handle = plane.handle;
- r = drmIoctl(card().fd(), DRM_IOCTL_MODE_MAP_DUMB, &mreq);
- if (r)
- throw std::invalid_argument("foo");
-
- /* perform actual memory mapping */
- m_planes[i].map = (uint8_t *)mmap(0, plane.size, PROT_READ | PROT_WRITE, MAP_SHARED,
- card().fd(), mreq.offset);
- if (plane.map == MAP_FAILED)
- throw std::invalid_argument("foo");
-
- /* clear the framebuffer to 0 */
- memset(plane.map, 0, plane.size);
+ plane.map = 0;
+ plane.prime_fd = -1;
}
/* create framebuffer object for the dumb-buffer */
r = drmModeAddFB2(card().fd(), width(), height(), (uint32_t)format(),
bo_handles, pitches, offsets, &id, 0);
if (r)
- throw std::invalid_argument("foo");
+ throw invalid_argument(string("drmModeAddFB2 failed: ") + strerror(errno));
set_id(id);
}
FramebufferPlane& plane = m_planes[i];
/* unmap buffer */
- munmap(plane.map, plane.size);
+ if (plane.map)
+ munmap(plane.map, plane.size);
/* delete dumb buffer */
struct drm_mode_destroy_dumb dreq = drm_mode_destroy_dumb();
dreq.handle = plane.handle;
drmIoctl(card().fd(), DRM_IOCTL_MODE_DESTROY_DUMB, &dreq);
-
+ if (plane.prime_fd >= 0)
+ ::close(plane.prime_fd);
}
}
-void DumbFramebuffer::clear()
+uint8_t* DumbFramebuffer::map(unsigned plane)
+{
+ FramebufferPlane& p = m_planes[plane];
+
+ if (p.map)
+ return p.map;
+
+ /* prepare buffer for memory mapping */
+ struct drm_mode_map_dumb mreq = drm_mode_map_dumb();
+ mreq.handle = p.handle;
+ int r = drmIoctl(card().fd(), DRM_IOCTL_MODE_MAP_DUMB, &mreq);
+ if (r)
+ 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);
+ if (p.map == MAP_FAILED)
+ throw invalid_argument(string("mmap failed: ") + strerror(errno));
+
+ return p.map;
+}
+
+int DumbFramebuffer::prime_fd(unsigned int plane)
{
- for (unsigned i = 0; i < m_num_planes; ++i)
- memset(m_planes[i].map, 0, m_planes[i].size);
+ if (m_planes[plane].prime_fd >= 0)
+ return m_planes[plane].prime_fd;
+
+ int r = drmPrimeHandleToFD(card().fd(), m_planes[plane].handle,
+ DRM_CLOEXEC, &m_planes[plane].prime_fd);
+ if (r)
+ throw std::runtime_error("drmPrimeHandleToFD failed\n");
+
+ return m_planes[plane].prime_fd;
}
}