summaryrefslogtreecommitdiff
path: root/kms++
diff options
context:
space:
mode:
Diffstat (limited to 'kms++')
-rw-r--r--kms++/inc/kms++/omap/omapframebuffer.h15
-rw-r--r--kms++/src/omap/omapframebuffer.cpp81
2 files changed, 79 insertions, 17 deletions
diff --git a/kms++/inc/kms++/omap/omapframebuffer.h b/kms++/inc/kms++/omap/omapframebuffer.h
index 16d6cf8..d1152b5 100644
--- a/kms++/inc/kms++/omap/omapframebuffer.h
+++ b/kms++/inc/kms++/omap/omapframebuffer.h
@@ -12,8 +12,17 @@ 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);
+ enum Flags
+ {
+ None = 0,
+ Tiled = 1 << 0,
+ MemContig = 1 << 1,
+ MemTiler = 1 << 2,
+ MemPin = 1 << 3,
+ };
+
+ OmapFramebuffer(OmapCard& card, uint32_t width, uint32_t height, const std::string& fourcc, Flags flags = Flags::None);
+ OmapFramebuffer(OmapCard& card, uint32_t width, uint32_t height, PixelFormat format, Flags flags = Flags::None);
virtual ~OmapFramebuffer();
uint32_t width() const { return Framebuffer::width(); }
@@ -42,7 +51,7 @@ private:
uint8_t* map;
};
- void Create();
+ void Create(Flags buffer_flags);
void Destroy();
unsigned m_num_planes;
diff --git a/kms++/src/omap/omapframebuffer.cpp b/kms++/src/omap/omapframebuffer.cpp
index e1e2234..b27ca22 100644
--- a/kms++/src/omap/omapframebuffer.cpp
+++ b/kms++/src/omap/omapframebuffer.cpp
@@ -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, Flags flags)
+ : OmapFramebuffer(card, width, height, FourCCToPixelFormat(fourcc), flags)
{
}
-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, Flags flags)
+ :MappedFramebuffer(card, width, height), m_omap_card(card), m_format(format)
{
- Create();
+ Create(flags);
}
OmapFramebuffer::~OmapFramebuffer()
@@ -38,7 +42,7 @@ OmapFramebuffer::~OmapFramebuffer()
Destroy();
}
-void OmapFramebuffer::Create()
+void OmapFramebuffer::Create(Flags buffer_flags)
{
const PixelFormatInfo& format_info = get_pixel_format_info(m_format);
@@ -50,13 +54,61 @@ 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;
+#if defined(OMAP_BO_MEM_CONTIG)
+ if (buffer_flags & Flags::MemContig)
+ flags |= OMAP_BO_MEM_CONTIG;
+ if (buffer_flags & Flags::MemTiler)
+ flags |= OMAP_BO_MEM_TILER;
+ if (buffer_flags & Flags::MemPin)
+ flags |= OMAP_BO_MEM_PIN;
+#endif
+
+ struct omap_bo* bo;
+
+ uint32_t stride;
+
+ if (!(buffer_flags & Flags::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 +119,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 +134,7 @@ void OmapFramebuffer::Create()
void OmapFramebuffer::Destroy()
{
+ /* delete framebuffer */
drmModeRmFB(card().fd(), id());
for (uint i = 0; i < m_num_planes; ++i) {