int gralloc_backend_register(private_handle_t* hnd)
{
	int retval = -EINVAL;

	switch (hnd->flags & (private_handle_t::PRIV_FLAGS_USES_UMP |
	                      private_handle_t::PRIV_FLAGS_USES_ION))
	{
	case private_handle_t::PRIV_FLAGS_USES_UMP:
		if (!s_ump_is_open)
		{
			ump_result res = ump_open(); // MJOLL-4012: UMP implementation needs a ump_close() for each ump_open
			if (res != UMP_OK)
			{
				AERR("Failed to open UMP library with res=%d", res);
			}
			s_ump_is_open = 1;
		}

		if (s_ump_is_open)
		{
			hnd->ump_mem_handle = ump_handle_create_from_secure_id(hnd->ump_id);
			if (UMP_INVALID_MEMORY_HANDLE != (ump_handle)hnd->ump_mem_handle)
			{
				hnd->base = ump_mapped_pointer_get(hnd->ump_mem_handle);
				if (0 != hnd->base)
				{
					hnd->lockState = private_handle_t::LOCK_STATE_MAPPED;
					hnd->writeOwner = 0;
					hnd->lockState = 0;

					return 0;
				}
				else
				{
					AERR("Failed to map UMP handle %p", hnd->ump_mem_handle );
				}

				ump_reference_release((ump_handle)hnd->ump_mem_handle);
			}
			else
			{
				AERR("Failed to create UMP handle %p", hnd->ump_mem_handle );
			}
		}
		break;
	case private_handle_t::PRIV_FLAGS_USES_ION:
		AERR("Gralloc does not support DMA_BUF. Unable to map memory for handle %p", hnd );
		break;
	}

	return retval;
}
Exemplo n.º 2
0
static int gralloc_register_buffer(gralloc_module_t const* module, buffer_handle_t handle)
{
    int err = 0;
    int retval = -EINVAL;
    void *vaddr;
    if (private_handle_t::validate(handle) < 0) {
        ALOGE("Registering invalid buffer, returning error");
        return -EINVAL;
    }

    /* if this handle was created in this process, then we keep it as is. */
    private_handle_t* hnd = (private_handle_t*)handle;

#ifdef USE_PARTIAL_FLUSH
    if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_UMP) {
        private_handle_rect *psRect;
        private_handle_rect *psFRect;
        psRect = (private_handle_rect *)calloc(1, sizeof(private_handle_rect));
        psRect->handle = (int)hnd->ump_id;
        psRect->stride = (int)hnd->stride;
        psFRect = find_last_rect((int)hnd->ump_id);
        psFRect->next = psRect;
    }
#endif
    if (hnd->pid == getpid())
        return 0;

    if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION)
        err = gralloc_map(module, handle, &vaddr);

    pthread_mutex_lock(&s_map_lock);

    if (!s_ump_is_open) {
        ump_result res = ump_open(); /* TODO: Fix a ump_close() somewhere??? */
        if (res != UMP_OK) {
            pthread_mutex_unlock(&s_map_lock);
            ALOGE("Failed to open UMP library");
            return retval;
        }
        s_ump_is_open = 1;
    }

    if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_UMP) {
        hnd->ump_mem_handle = (int)ump_handle_create_from_secure_id(hnd->ump_id);
        if (UMP_INVALID_MEMORY_HANDLE != (ump_handle)hnd->ump_mem_handle) {
            hnd->base = (int)ump_mapped_pointer_get((ump_handle)hnd->ump_mem_handle);
            if (0 != hnd->base) {
                hnd->lockState = private_handle_t::LOCK_STATE_MAPPED;
                hnd->writeOwner = 0;
                hnd->lockState = 0;

                pthread_mutex_unlock(&s_map_lock);
                return 0;
            } else {
                ALOGE("Failed to map UMP handle");
            }

            ump_reference_release((ump_handle)hnd->ump_mem_handle);
        } else {
            ALOGE("Failed to create UMP handle");
        }
    } else if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_PMEM) {
        pthread_mutex_unlock(&s_map_lock);
        return 0;
    } else if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_IOCTL) {
        void* vaddr = NULL;

        if (gMemfd == 0) {
            gMemfd = open(PFX_NODE_MEM, O_RDWR);
            if (gMemfd < 0) {
                ALOGE("%s:: %s exynos-mem open error\n", __func__, PFX_NODE_MEM);
                return false;
            }
        }

        gralloc_map(module, handle, &vaddr);
        pthread_mutex_unlock(&s_map_lock);
        return 0;
    } else if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION) {
        hnd->ump_mem_handle = (int)ump_handle_create_from_secure_id(hnd->ump_id);
        if (UMP_INVALID_MEMORY_HANDLE != (ump_handle)hnd->ump_mem_handle) {
            vaddr = (void*)ump_mapped_pointer_get((ump_handle)hnd->ump_mem_handle);
            if (0 != vaddr) {
                hnd->lockState = private_handle_t::LOCK_STATE_MAPPED;
                hnd->writeOwner = 0;
                hnd->lockState = 0;

                pthread_mutex_unlock(&s_map_lock);
                return 0;
            } else {
                ALOGE("Failed to map UMP handle");
            }
            ump_reference_release((ump_handle)hnd->ump_mem_handle);
        } else {
            ALOGE("Failed to create UMP handle");
        }
    } else {
        ALOGE("registering non-UMP buffer not supported");
    }

    pthread_mutex_unlock(&s_map_lock);
    return retval;
}
static int gralloc_register_buffer(gralloc_module_t const *module, buffer_handle_t handle)
{
	MALI_IGNORE(module);

	if (private_handle_t::validate(handle) < 0)
	{
		AERR("Registering invalid buffer 0x%p, returning error", handle);
		return -EINVAL;
	}

	// if this handle was created in this process, then we keep it as is.
	private_handle_t *hnd = (private_handle_t *)handle;

	int retval = -EINVAL;

	pthread_mutex_lock(&s_map_lock);

#if GRALLOC_ARM_UMP_MODULE

	if (!s_ump_is_open)
	{
		ump_result res = ump_open(); // MJOLL-4012: UMP implementation needs a ump_close() for each ump_open

		if (res != UMP_OK)
		{
			pthread_mutex_unlock(&s_map_lock);
			AERR("Failed to open UMP library with res=%d", res);
			return retval;
		}

		s_ump_is_open = 1;
	}

#endif

	hnd->pid = getpid();

	if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)
	{
		AERR("Can't register buffer 0x%p as it is a framebuffer", handle);
	}
	else if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_UMP)
	{
#if GRALLOC_ARM_UMP_MODULE
		hnd->ump_mem_handle = (int)ump_handle_create_from_secure_id(hnd->ump_id);

		if (UMP_INVALID_MEMORY_HANDLE != (ump_handle)hnd->ump_mem_handle)
		{
			hnd->base = ump_mapped_pointer_get((ump_handle)hnd->ump_mem_handle);

			if (0 != hnd->base)
			{
				hnd->lockState = private_handle_t::LOCK_STATE_MAPPED;
				hnd->writeOwner = 0;
				hnd->lockState = 0;

				pthread_mutex_unlock(&s_map_lock);
				return 0;
			}
			else
			{
				AERR("Failed to map UMP handle 0x%x", hnd->ump_mem_handle);
			}

			ump_reference_release((ump_handle)hnd->ump_mem_handle);
		}
		else
		{
			AERR("Failed to create UMP handle 0x%x", hnd->ump_mem_handle);
		}

#else
		AERR("Gralloc does not support UMP. Unable to register UMP memory for handle 0x%p", hnd);
#endif
	}
	else if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION)
	{
#if GRALLOC_ARM_DMA_BUF_MODULE
		int ret;
		unsigned char *mappedAddress;
		size_t size = hnd->size;
		hw_module_t *pmodule = NULL;
		private_module_t *m = NULL;

		if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, (const hw_module_t **)&pmodule) == 0)
		{
			m = reinterpret_cast<private_module_t *>(pmodule);
		}
		else
		{
			AERR("Could not get gralloc module for handle: 0x%p", hnd);
			retval = -errno;
			goto cleanup;
		}

		/* the test condition is set to m->ion_client <= 0 here, because:
		 * 1) module structure are initialized to 0 if no initial value is applied
		 * 2) a second user process should get a ion fd greater than 0.
		 */
		if (m->ion_client <= 0)
		{
			/* a second user process must obtain a client handle first via ion_open before it can obtain the shared ion buffer*/
			m->ion_client = ion_open();

			if (m->ion_client < 0)
			{
				AERR("Could not open ion device for handle: 0x%p", hnd);
				retval = -errno;
				goto cleanup;
			}
		}

		mappedAddress = (unsigned char *)mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, hnd->share_fd, 0);

		if (MAP_FAILED == mappedAddress)
		{
			AERR("mmap( share_fd:%d ) failed with %s",  hnd->share_fd, strerror(errno));
			retval = -errno;
			goto cleanup;
		}

		hnd->base = mappedAddress + hnd->offset;
		pthread_mutex_unlock(&s_map_lock);
		return 0;
#endif
	}
	else
	{
		AERR("registering non-UMP buffer not supported. flags = %d", hnd->flags);
	}

cleanup:
	pthread_mutex_unlock(&s_map_lock);
	return retval;
}
Exemplo n.º 4
0
static int gralloc_alloc_framebuffer_locked(alloc_device_t *dev, size_t size, int usage, buffer_handle_t *pHandle)
{
	private_module_t *m = reinterpret_cast<private_module_t *>(dev->common.module);

	// allocate the framebuffer
	if (m->framebuffer == NULL)
	{
		// initialize the framebuffer, the framebuffer is mapped once and forever.
		int err = init_frame_buffer_locked(m);

		if (err < 0)
		{
			return err;
		}
	}

	const uint32_t bufferMask = m->bufferMask;
	const uint32_t numBuffers = m->numBuffers;
	const size_t bufferSize = m->finfo.line_length * m->info.yres;

	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;
		AERR("fallback to single buffering. Virtual Y-res too small %d", m->info.yres);
		return gralloc_alloc_buffer(dev, bufferSize, newUsage, pHandle);
	}

	if (bufferMask >= ((1LU << numBuffers) - 1))
	{
		// We ran out of buffers.
		return -ENOMEM;
	}

	int vaddr = m->framebuffer->base;

	// find a free slot
	for (uint32_t i = 0 ; i < numBuffers ; i++)
	{
		if ((bufferMask & (1LU << i)) == 0)
		{
			m->bufferMask |= (1LU << i);
			break;
		}

		vaddr += bufferSize;
	}

	// The entire framebuffer memory is already mapped, now create a buffer object for parts of this memory
	private_handle_t *hnd = new private_handle_t(private_handle_t::PRIV_FLAGS_FRAMEBUFFER, usage, size, vaddr,
	        0, dup(m->framebuffer->fd), vaddr - m->framebuffer->base);
#if GRALLOC_ARM_UMP_MODULE
	hnd->ump_id = m->framebuffer->ump_id;

	/* create a backing ump memory handle if the framebuffer is exposed as a secure ID */
	if ((int)UMP_INVALID_SECURE_ID != hnd->ump_id)
	{
		hnd->ump_mem_handle = (int)ump_handle_create_from_secure_id(hnd->ump_id);

		if ((int)UMP_INVALID_MEMORY_HANDLE == hnd->ump_mem_handle)
		{
			AINF("warning: unable to create UMP handle from secure ID %i\n", hnd->ump_id);
		}
	}

#endif

#if GRALLOC_ARM_DMA_BUF_MODULE
	{
#ifdef FBIOGET_DMABUF
		struct fb_dmabuf_export fb_dma_buf;

		if (ioctl(m->framebuffer->fd, FBIOGET_DMABUF, &fb_dma_buf) == 0)
		{
			AINF("framebuffer accessed with dma buf (fd 0x%x)\n", (int)fb_dma_buf.fd);
			hnd->share_fd = fb_dma_buf.fd;
		}

#endif
	}
#endif

	*pHandle = hnd;

	return 0;
}
Exemplo n.º 5
0
static Bool maliModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, int depth, int bitsPerPixel, int devKind, pointer pPixData)
{
	unsigned int size;
	PrivPixmap *privPixmap = (PrivPixmap *)exaGetPixmapDriverPrivate(pPixmap);
	mali_mem_info *mem_info;
	ScreenPtr pScreen = pPixmap->drawable.pScreen;
	ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
	MaliPtr fPtr = MALIPTR(pScrn);

	if (!pPixmap)
	{
		return FALSE;
	}

	miModifyPixmapHeader(pPixmap, width, height, depth, bitsPerPixel, devKind, pPixData);

	if ((pPixData == fPtr->fbmem) || current_buf)
	{
		/* Wrap one of the fbdev virtual buffers */
		ump_secure_id ump_id = UMP_INVALID_SECURE_ID;

		privPixmap->isFrameBuffer = TRUE;
		privPixmap->frameBufferNumber = current_buf;
		mem_info = privPixmap->mem_info;

		if (mem_info)
		{
			return TRUE;
		}

		/* create new mem_info for the on-screen buffer */
		mem_info = calloc(1, sizeof(*mem_info));

		if (!mem_info)
		{
			ERROR_MSG("failed to allocate for memory metadata");
			return FALSE;
		}

		/* get the secure ID for the framebuffers */
		if (ioctl(fPtr->fb_lcd_fd, GET_UMP_SECURE_ID_BUF(current_buf), &ump_id) < 0
		        || UMP_INVALID_SECURE_ID == ump_id)
		{
			free(mem_info);
			privPixmap->mem_info = NULL;
			ERROR_MSG("UMP failed to retrieve secure id, current_buf: %d", current_buf);
			return FALSE;
		}

		INFO_MSG("GET_UMP_SECURE_ID_BUF(%d) returned 0x%x", current_buf, ump_id);

		mem_info->handle = ump_handle_create_from_secure_id(ump_id);

		if (UMP_INVALID_MEMORY_HANDLE == mem_info->handle)
		{
			ERROR_MSG("UMP failed to create handle from secure id");
			free(mem_info);
			privPixmap->mem_info = NULL;
			return FALSE;
		}

		size = exaGetPixmapPitch(pPixmap) * pPixmap->drawable.height;
		mem_info->usize = size;

		privPixmap->mem_info = mem_info;

		if (bitsPerPixel != 0)
		{
			privPixmap->bits_per_pixel = bitsPerPixel;
		}

		/* When this is called directly from X to create the front buffer, current_buf is zero as expected. When this
		 * function is called recursively to create the back buffers, current_buf is increased to the next buffer */
		privPixmap->mem_info->offset = current_buf * size;

		if (pPixData == fPtr->fbmem)
		{
			/* This is executed only when this function is called directly from X. We need to create the other
			 * back buffers now because we can't "wrap" existing memory in a pixmap during DRI2CreateBuffer
			 * for the back buffer of the framebuffer. In DRI2CreateBuffer instead of allocating a new
			 * pixmap for the back buffer like we do for non-swappable windows, we'll just use the 'current_pixmap'
			 * to grab this pointer from the screen pixmap and return it. */

			PrivPixmap *current_privPixmap = privPixmap;
			int i;
			PrivBuffer *buf_info = calloc(1, sizeof(*buf_info));

			if (NULL == buf_info)
			{
				ERROR_MSG("Failed to allocate buf_info memory");
				free(mem_info);
				privPixmap->mem_info = NULL;
				return FALSE;
			}

			buf_info->current_pixmap = 0;
			buf_info->num_pixmaps = fPtr->dri2_num_buffers;
			buf_info->pPixmaps[0] = pPixmap;
			current_privPixmap->buf_info = buf_info;

			for (i = 1; i < buf_info->num_pixmaps; i++)
			{
				current_buf++;
				buf_info->pPixmaps[i] = (*pScreen->CreatePixmap)(pScreen, width, height, depth, 0);
				assert(buf_info->pPixmaps[i]);
				current_privPixmap = (PrivPixmap *)exaGetPixmapDriverPrivate(buf_info->pPixmaps[i]);
				current_privPixmap->buf_info = buf_info;
			}

			current_buf = 0;
		}

		INFO_MSG("Creating FRAMEBUFFER pixmap %p at offset %lu, privPixmap=%p", pPixmap, privPixmap->mem_info->offset, privPixmap);

		return TRUE;
	}

	if (pPixData)
	{
		/* When this happens we're being told to wrap existing pixmap data for which we don't know the UMP
		 * handle. We can and still need to wrap it but it won't be offscreen - we can't accelerate it in any
		 * way. */

		if (privPixmap->mem_info != NULL)
		{
			return TRUE;
		}

		return FALSE;
	}

	pPixmap->devKind = ((pPixmap->drawable.width * pPixmap->drawable.bitsPerPixel) + 7) / 8;
	pPixmap->devKind = MALI_ALIGN(pPixmap->devKind, 8);

	size = exaGetPixmapPitch(pPixmap) * pPixmap->drawable.height;

	/* allocate pixmap data */
	mem_info = privPixmap->mem_info;

	if (mem_info && mem_info->usize == size)
	{
		return TRUE;
	}

	if (mem_info && mem_info->usize != 0)
	{
		ump_reference_release(mem_info->handle);
		mem_info->handle = NULL;
		memset(privPixmap, 0, sizeof(*privPixmap));

		return TRUE;
	}

	if (!size)
	{
		return TRUE;
	}

	if (NULL == mem_info)
	{
		mem_info = calloc(1, sizeof(*mem_info));

		if (!mem_info)
		{
			ERROR_MSG("failed to allocate memory metadata");
			return FALSE;
		}
	}

	if (fPtr->use_cached_ump)
	{
		mem_info->handle = ump_ref_drv_allocate(size, UMP_REF_DRV_CONSTRAINT_PHYSICALLY_LINEAR | UMP_REF_DRV_CONSTRAINT_USE_CACHE);
	}
	else
	{
		mem_info->handle = ump_ref_drv_allocate(size, UMP_REF_DRV_CONSTRAINT_PHYSICALLY_LINEAR);
	}

	if (UMP_INVALID_MEMORY_HANDLE == mem_info->handle)
	{
		ERROR_MSG("failed to allocate UMP memory (%i bytes)", size);
		return FALSE;
	}

	mem_info->usize = size;
	privPixmap->mem_info = mem_info;
	privPixmap->mem_info->usize = size;
	privPixmap->bits_per_pixel = 16;

	return TRUE;
}
static int gralloc_register_buffer(gralloc_module_t const* module, buffer_handle_t handle)
{
	if (private_handle_t::validate(handle) < 0)
	{
		LOGE("Registering invalid buffer, returning error");
		return -EINVAL;
	}

	// if this handle was created in this process, then we keep it as is.
	private_handle_t* hnd = (private_handle_t*)handle;
	if (hnd->pid == getpid())
	{
		return 0;
	}

	int retval = -EINVAL;

	pthread_mutex_lock(&s_map_lock);

	if (!s_ump_is_open)
	{
		ump_result res = ump_open(); // TODO: Fix a ump_close() somewhere???
		if (res != UMP_OK)
		{
			pthread_mutex_unlock(&s_map_lock);
			LOGE("Failed to open UMP library");
			return retval;
		}
		s_ump_is_open = 1;
	}

	if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_UMP)
	{
		hnd->ump_mem_handle = (int)ump_handle_create_from_secure_id(hnd->ump_id);
		if (UMP_INVALID_MEMORY_HANDLE != (ump_handle)hnd->ump_mem_handle)
		{
			hnd->base = (int)ump_mapped_pointer_get((ump_handle)hnd->ump_mem_handle);
			if (0 != hnd->base)
			{
				hnd->lockState = private_handle_t::LOCK_STATE_MAPPED;
				hnd->writeOwner = 0;
				hnd->lockState = 0;

				pthread_mutex_unlock(&s_map_lock);
				return 0;
			}
			else
			{
				LOGE("Failed to map UMP handle");
			}

			ump_reference_release((ump_handle)hnd->ump_mem_handle);
		}
		else
		{
			LOGE("Failed to create UMP handle");
		}
	}
	else
	{
		LOGE("registering non-UMP buffer not supported");
	}

	pthread_mutex_unlock(&s_map_lock);
	return retval;
}
Exemplo n.º 7
0
static DRI2Buffer2Ptr MaliDRI2CreateBuffer(DrawablePtr  pDraw,
                                           unsigned int attachment,
                                           unsigned int format)
{
    ScreenPtr                pScreen  = pDraw->pScreen;
    ScrnInfoPtr              pScrn    = xf86Screens[pScreen->myNum];
    DRI2Buffer2Ptr           buffer;
    MaliDRI2BufferPrivatePtr privates;
    ump_handle               handle;
    FBDevPtr pMxv = FBDEVPTR(pScrn);
    Rk30MaliPtr rk_3d = pMxv->Rk30Mali;
    OvlHWPtr overlay = pMxv->OvlHW;
    Bool                     can_use_overlay = TRUE;
    PixmapPtr                pWindowPixmap;

    if (pDraw->type == DRAWABLE_WINDOW &&
        (pWindowPixmap = pScreen->GetWindowPixmap((WindowPtr)pDraw)))
    {
        DebugMsg("win=%p (w=%d, h=%d, x=%d, y=%d) has backing pix=%p (w=%d, h=%d, screen_x=%d, screen_y=%d)\n",
                 pDraw, pDraw->width, pDraw->height, pDraw->x, pDraw->y,
                 pWindowPixmap, pWindowPixmap->drawable.width, pWindowPixmap->drawable.height,
                 pWindowPixmap->screen_x, pWindowPixmap->screen_y);
    }

    if(attachment != DRI2BufferBackLeft && rk_3d->buf_back != NULL){
	DebugMsg("DRI2 return NullBuffer\n");
	return rk_3d->buf_back;
    }

    if (!(buffer = calloc(1, sizeof *buffer))) {
        ErrorF("MaliDRI2CreateBuffer: calloc failed\n");
        return NULL;
    }


    /* If it is a pixmap, just migrate this pixmap to UMP buffer */
    if (pDraw->type == DRAWABLE_PIXMAP)
    {
        if (!(privates = MigratePixmapToUMP((PixmapPtr)pDraw))) {
            ErrorF("MaliDRI2CreateBuffer: MigratePixmapToUMP failed\n");
            free(buffer);
            return NULL;
        }
        privates->refcount++;
        buffer->attachment    = attachment;
        buffer->driverPrivate = privates;
        buffer->format        = format;
        buffer->flags         = 0;
        buffer->cpp           = pDraw->bitsPerPixel / 8;
        buffer->pitch         = ((PixmapPtr)pDraw)->devKind;
        buffer->name = ump_secure_id_get(privates->handle);

        DebugMsg("DRI2CreateBuffer pix=%p, buf=%p:%p, att=%d, ump=%d:%d, w=%d, h=%d, cpp=%d, depth=%d\n",
                 pDraw, buffer, privates, attachment, buffer->name, buffer->flags,
                 privates->width, privates->height, buffer->cpp, privates->depth);

        return buffer;
    }

    /* The drawable must be a window for using hardware overlays */
    if (pDraw->type != DRAWABLE_WINDOW){
        ErrorF("Unexpected pDraw->type (%d) in MaliDRI2CreateBuffer\n", pDraw->type);
        return NULL;
    }

    if (!(privates = calloc(1, sizeof *privates))) {
        ErrorF("MaliDRI2CreateBuffer: calloc failed\n");
        free(buffer);
        return NULL;
    }

    /* We could not get framebuffer secure id */
    if (rk_3d->ump_fb_secure_id1 == UMP_INVALID_SECURE_ID)
        can_use_overlay = FALSE;

    /* Overlay is already used by a different window */
    if (rk_3d->pOverlayWin && rk_3d->pOverlayWin != (void *)pDraw)
        can_use_overlay = FALSE;

    /* TODO: try to support other color depths later */
    if (pDraw->bitsPerPixel != 32)
        can_use_overlay = FALSE;

    /* The default common values */
    buffer->attachment    = attachment;
    buffer->driverPrivate = privates;
    buffer->format        = format;
    buffer->flags         = 0;
    buffer->cpp           = pDraw->bitsPerPixel / 8;
    /* Stride must be 8 bytes aligned for Mali400 */
//    buffer->pitch         = ((buffer->cpp * pDraw->width + 7) / 8) * 8;
    buffer->pitch         = ((buffer->cpp * overlay->cur_var.xres_virtual + 7) / 8) * 8;
    privates->size     = pDraw->height * buffer->pitch;
    privates->width    = pDraw->width;
    privates->height   = pDraw->height;
    privates->depth    = pDraw->depth;

/*    if (disp && disp->framebuffer_size - disp->gfx_layer_size < privates->size) {
        DebugMsg("Not enough space in the offscreen framebuffer (wanted %d for DRI2)\n",
                 privates->size);
        can_use_overlay = FALSE;
    }
*/
/*
    if((pDraw->width+pDraw->x) > overlay->cur_var.xres ||
		(pDraw->height+pDraw->y) > overlay->cur_var.yres)
        can_use_overlay = FALSE;
*/
    if(pDraw->width < 2 || pDraw->height < 2){
     can_use_overlay = FALSE;
    }

    if(attachment != DRI2BufferBackLeft){
//     can_use_overlay = FALSE;
	free(privates);
	buffer->driverPrivate = NULL;
	buffer->name = UMP_INVALID_SECURE_ID;
	if(rk_3d->buf_back == NULL)
	    rk_3d->buf_back = buffer;
	goto end;
    }

    if(rk_3d->OvlPg == ERRORL){
	rk_3d->OvlPg = OvlAllocLay(pScrn, ANYL);
	if(rk_3d->OvlPg == ERRORL)
	    can_use_overlay = FALSE;
	else{//init
	    OvlSetupFb(pScrn, 0, 0, rk_3d->OvlPg);
	    OvlEnable(pScrn, rk_3d->OvlPg, 1);
	}
    }

    rk_3d->bOverlayWinEnabled = can_use_overlay;

    if (can_use_overlay)
        rk_3d->pOverlayWin = (WindowPtr)pDraw;
//	buffer->pitch         = ((buffer->cpp * overlay->OvlLay[rk_3d->OvlPg].var.xres_virtual + 7) / 8) * 8;
//	rk_3d->bOverlayWinEnabled = TRUE;


// Stride must be 8 bytes aligned for Mali400
//	privates->size   = pDraw->height * buffer->pitch;
//	buffer->flags = 0;

	privates->handle = UMP_INVALID_MEMORY_HANDLE;
	privates->addr = NULL;
	buffer->name = rk_3d->ump_fb_secure_id1;
	privates->handle = ump_handle_create_from_secure_id(buffer->name);
	privates->addr = ump_mapped_pointer_get(privates->handle);
//        privates->addr = NULL;//(void*)0x94000000;
/*    }
    else
    {
//	rk_3d->bOverlayWinEnabled = FALSE;
//        Allocate UMP memory buffer
#ifdef HAVE_LIBUMP_CACHE_CONTROL
        privates->handle = ump_ref_drv_allocate(privates->size,
                                    UMP_REF_DRV_CONSTRAINT_PHYSICALLY_LINEAR |
                                    UMP_REF_DRV_CONSTRAINT_USE_CACHE);
        ump_cache_operations_control(UMP_CACHE_OP_START);
        ump_switch_hw_usage_secure_id(ump_secure_id_get(privates->handle),
                                      UMP_USED_BY_MALI);
        ump_cache_operations_control(UMP_CACHE_OP_FINISH);
#else
        privates->handle = ump_ref_drv_allocate(privates->size,
                                    UMP_REF_DRV_CONSTRAINT_PHYSICALLY_LINEAR);
#endif
        if (privates->handle == UMP_INVALID_MEMORY_HANDLE) {
            ErrorF("Failed to allocate UMP buffer (size=%d)\n",
                   (int)privates->size);
        }
        privates->addr = ump_mapped_pointer_get(privates->handle);
        buffer->name = ump_secure_id_get(privates->handle);
        buffer->flags = 0;

    }
*/
end:
    DebugMsg("DRI2CreateBuffer win=%p, buf=%p:%p, att=%d, ump=%d:%d, w=%d, h=%d, cpp=%d, depth=%d adr=%p\n",
             pDraw, buffer, privates, attachment, buffer->name, buffer->flags,
             privates->width, privates->height, buffer->cpp, privates->depth,privates->addr);

    return buffer;
}
static Bool maliModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, int depth, int bitsPerPixel, int devKind, pointer pPixData)
{
	unsigned int size;
	PrivPixmap *privPixmap = (PrivPixmap *)exaGetPixmapDriverPrivate(pPixmap);
	mali_mem_info *mem_info;
	ScreenPtr pScreen = pPixmap->drawable.pScreen;
	ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
	MaliPtr fPtr = MALIPTR(pScrn);

	if (!pPixmap)
	{
		return FALSE;
	}

	miModifyPixmapHeader(pPixmap, width, height, depth, bitsPerPixel, devKind, pPixData);

	if ((pPixData == fPtr->fbmem) || offset)
	{
		/* Wrap one of the fbdev virtual buffers */
		ump_secure_id ump_id = UMP_INVALID_SECURE_ID;

		privPixmap->isFrameBuffer = TRUE;

		mem_info = privPixmap->mem_info;

		if (mem_info)
		{
			return TRUE;
		}

		/* create new mem_info for the on-screen buffer */
		mem_info = calloc(1, sizeof(*mem_info));

		if (!mem_info)
		{
			ERROR_MSG("failed to allocate for memory metadata");
			return FALSE;
		}

		/* get the secure ID for the framebuffers */
		if (!offset)
		{
			(void)ioctl(fPtr->fb_lcd_fd, GET_UMP_SECURE_ID_BUF1, &ump_id);
			ERROR_MSG("GET_UMP_SECURE_ID_BUF1 returned 0x%x offset: %i virt address: %p fb_virt: %p\n", ump_id, offset, pPixData, fPtr->fbmem);
		}
		else
		{
			(void)ioctl(fPtr->fb_lcd_fd, GET_UMP_SECURE_ID_BUF2, &ump_id);
			ERROR_MSG("GET_UMP_SECURE_ID_BUF2 returned 0x%x offset: %i virt address: %p fb_virt: %p\n", ump_id, offset, pPixData, fPtr->fbmem);
		}

		if (UMP_INVALID_SECURE_ID == ump_id)
		{
			free(mem_info);
			privPixmap->mem_info = NULL;
			ERROR_MSG("UMP failed to retrieve secure id");
			return FALSE;
		}

		mem_info->handle = ump_handle_create_from_secure_id(ump_id);

		if (UMP_INVALID_MEMORY_HANDLE == mem_info->handle)
		{
			ERROR_MSG("UMP failed to create handle from secure id");
			free(mem_info);
			privPixmap->mem_info = NULL;
			return FALSE;
		}

		size = exaGetPixmapPitch(pPixmap) * pPixmap->drawable.height;
		mem_info->usize = size;

		privPixmap->mem_info = mem_info;

		if (bitsPerPixel != 0)
		{
			privPixmap->bits_per_pixel = bitsPerPixel;
		}

		/* When this is called directly from X to create the front buffer, offset is zero as expected. When this
		 * function is called recursively to create the back buffer, offset is the offset within the fbdev to
		 * the second buffer */
		privPixmap->mem_info->offset = offset;

		/* Only wrap the other half if there is another half! */
		if (pPixData == fPtr->fbmem)
		{
			/* This is executed only when this function is called directly from X. We need to create the
			 * back buffer now because we can't "wrap" existing memory in a pixmap during DRI2CreateBuffer
			 * for the back buffer of the framebuffer. In DRI2CreateBuffer instead of allocating a new
			 * pixmap for the back buffer like we do for non-swappable windows, we'll just grab this pointer
			 * from the screen pixmap and return it. */

			PrivPixmap *other_privPixmap;

			offset = size;
			privPixmap->other_buffer = (*pScreen->CreatePixmap)(pScreen, width, height, depth, 0);

			/* Store a pointer to this pixmap in the one we just created. Both fbdev pixmaps are then
			 * accessible from the screen pixmap, whichever of the fbdev pixmaps happens to be the screen
			 * pixmap at the time */
			other_privPixmap = (PrivPixmap *)exaGetPixmapDriverPrivate(privPixmap->other_buffer);
			other_privPixmap->other_buffer = pPixmap;

			offset = 0;
		}

		INFO_MSG("Creating FRAMEBUFFER pixmap %p at offset %lu, privPixmap=%p\n", pPixmap, privPixmap->mem_info->offset, privPixmap);

		return TRUE;
	}

	if (pPixData)
	{
		/* When this happens we're being told to wrap existing pixmap data for which we don't know the UMP
		 * handle. We can and still need to wrap it but it won't be offscreen - we can't accelerate it in any
		 * way. */

		if (privPixmap->mem_info != NULL)
		{
			return TRUE;
		}

		return FALSE;
	}

	pPixmap->devKind = ((pPixmap->drawable.width * pPixmap->drawable.bitsPerPixel) + 7) / 8;
	pPixmap->devKind = MALI_ALIGN(pPixmap->devKind, 8);

	size = exaGetPixmapPitch(pPixmap) * pPixmap->drawable.height;

	/* allocate pixmap data */
	mem_info = privPixmap->mem_info;

	if (mem_info && mem_info->usize == size)
	{
		return TRUE;
	}

	if (mem_info && mem_info->usize != 0)
	{
		ump_reference_release(mem_info->handle);
		mem_info->handle = NULL;
		memset(privPixmap, 0, sizeof(*privPixmap));

		return TRUE;
	}

	if (!size)
	{
		return TRUE;
	}

	if (NULL == mem_info)
	{
		mem_info = calloc(1, sizeof(*mem_info));

		if (!mem_info)
		{
			ERROR_MSG("failed to allocate memory metadata");
			return FALSE;
		}
	}

	if (fPtr->use_cached_ump)
	{
		mem_info->handle = ump_ref_drv_allocate(size, UMP_REF_DRV_CONSTRAINT_PHYSICALLY_LINEAR | UMP_REF_DRV_CONSTRAINT_USE_CACHE);
	}
	else
	{
		mem_info->handle = ump_ref_drv_allocate(size, UMP_REF_DRV_CONSTRAINT_PHYSICALLY_LINEAR);
	}

	if (UMP_INVALID_MEMORY_HANDLE == mem_info->handle)
	{
		ERROR_MSG("failed to allocate UMP memory (%i bytes)", size);
		return FALSE;
	}

	mem_info->usize = size;
	privPixmap->mem_info = mem_info;
	privPixmap->mem_info->usize = size;
	privPixmap->bits_per_pixel = 16;

	return TRUE;
}