gralloc: Enable framebuffer memory mapping.
Enable mapping from framebuffer if debug.gralloc.map_fb_memory
is set to 1. This is useful for bringup.
Change-Id: I3c860148729c5f5c98d84bf17e6633285b4b0af1
diff --git a/libgralloc/framebuffer.cpp b/libgralloc/framebuffer.cpp
index d95b376..3828680 100644
--- a/libgralloc/framebuffer.cpp
+++ b/libgralloc/framebuffer.cpp
@@ -86,11 +86,13 @@
{
private_module_t* m =
reinterpret_cast<private_module_t*>(dev->common.module);
- struct mdp_display_commit prim_commit;
- memset(&prim_commit, 0, sizeof(struct mdp_display_commit));
- prim_commit.wait_for_finish = 1;
- if (ioctl(m->framebuffer->fd, MSMFB_DISPLAY_COMMIT, &prim_commit) == -1) {
- ALOGE("%s: MSMFB_DISPLAY_COMMIT for primary failed, str: %s",
+ private_handle_t *hnd = static_cast<private_handle_t*>
+ (const_cast<native_handle_t*>(buffer));
+ const size_t offset = hnd->base - m->framebuffer->base;
+ m->info.activate = FB_ACTIVATE_VBL;
+ m->info.yoffset = offset / m->finfo.line_length;
+ if (ioctl(m->framebuffer->fd, FBIOPUT_VSCREENINFO, &m->info) == -1) {
+ ALOGE("%s: FBIOPUT_VSCREENINFO for primary failed, str: %s",
__FUNCTION__, strerror(errno));
return -errno;
}
@@ -308,7 +310,7 @@
*/
int err;
- module->numBuffers = 2;
+ module->numBuffers = info.yres_virtual / info.yres;
module->bufferMask = 0;
//adreno needs page aligned offsets. Align the fbsize to pagesize.
size_t fbSize = roundUpToPageSize(finfo.line_length * info.yres)*
@@ -325,6 +327,10 @@
module->framebuffer->base = intptr_t(vaddr);
memset(vaddr, 0, fbSize);
module->currentOffset = 0;
+ //Enable vsync
+ int enable = 1;
+ ioctl(module->framebuffer->fd, MSMFB_OVERLAY_VSYNC_CTRL,
+ &enable);
return 0;
}
diff --git a/libgralloc/gpu.cpp b/libgralloc/gpu.cpp
index 60b57fe..b8ee1f2 100644
--- a/libgralloc/gpu.cpp
+++ b/libgralloc/gpu.cpp
@@ -151,6 +151,76 @@
}
}
+int gpu_context_t::gralloc_alloc_framebuffer_locked(size_t size, int usage,
+ buffer_handle_t* pHandle)
+{
+ private_module_t* m = reinterpret_cast<private_module_t*>(common.module);
+
+ // we don't support framebuffer allocations with graphics heap flags
+ if (usage & GRALLOC_HEAP_MASK) {
+ return -EINVAL;
+ }
+
+ if (m->framebuffer == NULL) {
+ ALOGE("%s: Invalid framebuffer", __FUNCTION__);
+ return -EINVAL;
+ }
+
+ const uint32_t bufferMask = m->bufferMask;
+ const uint32_t numBuffers = m->numBuffers;
+ size_t bufferSize = m->finfo.line_length * m->info.yres;
+
+ //adreno needs FB size to be page aligned
+ bufferSize = roundUpToPageSize(bufferSize);
+
+ if (numBuffers == 1) {
+ // If we have only one buffer, we never use page-flipping. Instead,
+ // we return a regular buffer which will be memcpy'ed to the main
+ // screen when post is called.
+ int newUsage = (usage & ~GRALLOC_USAGE_HW_FB) | GRALLOC_USAGE_HW_2D;
+ return gralloc_alloc_buffer(bufferSize, newUsage, pHandle, BUFFER_TYPE_UI,
+ m->fbFormat, m->info.xres, m->info.yres);
+ }
+
+ if (bufferMask >= ((1LU<<numBuffers)-1)) {
+ // We ran out of buffers.
+ return -ENOMEM;
+ }
+
+ // create a "fake" handle for it
+ intptr_t vaddr = intptr_t(m->framebuffer->base);
+ private_handle_t* hnd = new private_handle_t(
+ dup(m->framebuffer->fd), bufferSize,
+ private_handle_t::PRIV_FLAGS_USES_PMEM |
+ private_handle_t::PRIV_FLAGS_FRAMEBUFFER,
+ BUFFER_TYPE_UI, m->fbFormat, m->info.xres,
+ m->info.yres);
+
+ // find a free slot
+ for (uint32_t i=0 ; i<numBuffers ; i++) {
+ if ((bufferMask & (1LU<<i)) == 0) {
+ m->bufferMask |= (1LU<<i);
+ break;
+ }
+ vaddr += bufferSize;
+ }
+ hnd->base = vaddr;
+ hnd->offset = vaddr - intptr_t(m->framebuffer->base);
+ *pHandle = hnd;
+ return 0;
+}
+
+
+int gpu_context_t::gralloc_alloc_framebuffer(size_t size, int usage,
+ buffer_handle_t* pHandle)
+{
+ private_module_t* m = reinterpret_cast<private_module_t*>(common.module);
+ pthread_mutex_lock(&m->lock);
+ int err = gralloc_alloc_framebuffer_locked(size, usage, pHandle);
+ pthread_mutex_unlock(&m->lock);
+ return err;
+}
+
int gpu_context_t::alloc_impl(int w, int h, int format, int usage,
buffer_handle_t* pHandle, int* pStride,
size_t bufferSize) {
@@ -187,8 +257,22 @@
bufferType = BUFFER_TYPE_VIDEO;
}
- int err = gralloc_alloc_buffer(size, usage, pHandle, bufferType,
- grallocFormat, alignedw, alignedh);
+ bool useFbMem = false;
+ char property[PROPERTY_VALUE_MAX];
+ if((usage & GRALLOC_USAGE_HW_FB) &&
+ (property_get("debug.gralloc.map_fb_memory", property, NULL) > 0) &&
+ (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
+ (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
+ useFbMem = true;
+ }
+
+ int err = 0;
+ if(useFbMem) {
+ err = gralloc_alloc_framebuffer(size, usage, pHandle);
+ } else {
+ err = gralloc_alloc_buffer(size, usage, pHandle, bufferType,
+ grallocFormat, alignedw, alignedh);
+ }
if (err < 0) {
return err;
@@ -200,21 +284,26 @@
int gpu_context_t::free_impl(private_handle_t const* hnd) {
private_module_t* m = reinterpret_cast<private_module_t*>(common.module);
+ if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) {
+ const size_t bufferSize = m->finfo.line_length * m->info.yres;
+ int index = (hnd->base - m->framebuffer->base) / bufferSize;
+ m->bufferMask &= ~(1<<index);
+ } else {
- terminateBuffer(&m->base, const_cast<private_handle_t*>(hnd));
- IMemAlloc* memalloc = mAllocCtrl->getAllocator(hnd->flags);
- int err = memalloc->free_buffer((void*)hnd->base, (size_t) hnd->size,
- hnd->offset, hnd->fd);
- if(err)
- return err;
- // free the metadata space
- unsigned long size = ROUND_UP_PAGESIZE(sizeof(MetaData_t));
- err = memalloc->free_buffer((void*)hnd->base_metadata,
- (size_t) size, hnd->offset_metadata,
- hnd->fd_metadata);
- if (err)
- return err;
-
+ terminateBuffer(&m->base, const_cast<private_handle_t*>(hnd));
+ IMemAlloc* memalloc = mAllocCtrl->getAllocator(hnd->flags);
+ int err = memalloc->free_buffer((void*)hnd->base, (size_t) hnd->size,
+ hnd->offset, hnd->fd);
+ if(err)
+ return err;
+ // free the metadata space
+ unsigned long size = ROUND_UP_PAGESIZE(sizeof(MetaData_t));
+ err = memalloc->free_buffer((void*)hnd->base_metadata,
+ (size_t) size, hnd->offset_metadata,
+ hnd->fd_metadata);
+ if (err)
+ return err;
+ }
delete hnd;
return 0;
}
diff --git a/libgralloc/gpu.h b/libgralloc/gpu.h
index 6826ffe..8712c6c 100644
--- a/libgralloc/gpu.h
+++ b/libgralloc/gpu.h
@@ -51,6 +51,11 @@
int format, int usage,
buffer_handle_t* pHandle,
int* pStride);
+ int gralloc_alloc_framebuffer_locked(size_t size, int usage,
+ buffer_handle_t* pHandle);
+
+ int gralloc_alloc_framebuffer(size_t size, int usage,
+ buffer_handle_t* pHandle);
static int gralloc_free(alloc_device_t* dev, buffer_handle_t handle);