diff options
Diffstat (limited to 'kms++/src')
| -rw-r--r-- | kms++/src/omap/omapframebuffer.cpp | 72 | 
1 files changed, 58 insertions, 14 deletions
| diff --git a/kms++/src/omap/omapframebuffer.cpp b/kms++/src/omap/omapframebuffer.cpp index e1e2234..9997933 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, 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) { | 
