Esempio n. 1
0
static int gralloc_unregister_buffer(gralloc_module_t const* module, buffer_handle_t handle)
{
    if (private_handle_t::validate(handle) < 0) {
        ALOGE("unregistering invalid buffer, returning error");
        return -EINVAL;
    }

    private_handle_t* hnd = (private_handle_t*)handle;

#ifdef USE_PARTIAL_FLUSH
    if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_UMP)
        if (!release_rect((int)hnd->ump_id))
            ALOGE("secureID: 0x%x, release error", (int)hnd->ump_id);
#endif
    ALOGE_IF(hnd->lockState & private_handle_t::LOCK_STATE_READ_MASK,
            "[unregister] handle %p still locked (state=%08x)", hnd, hnd->lockState);

    /* never unmap buffers that were created in this process */
    if (hnd->pid != getpid()) {
        pthread_mutex_lock(&s_map_lock);
        if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_UMP) {
            ump_mapped_pointer_release((ump_handle)hnd->ump_mem_handle);
            hnd->base = 0;
            ump_reference_release((ump_handle)hnd->ump_mem_handle);
            hnd->ump_mem_handle = (int)UMP_INVALID_MEMORY_HANDLE;
            hnd->lockState  = 0;
            hnd->writeOwner = 0;
        } else if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_IOCTL) {
            if(hnd->base != 0)
                gralloc_unmap(module, handle);

            pthread_mutex_unlock(&s_map_lock);
            if (0 < gMemfd) {
                close(gMemfd);
                gMemfd = 0;
            }
            return 0;
        } else if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION) {
            ump_mapped_pointer_release((ump_handle)hnd->ump_mem_handle);
            ump_reference_release((ump_handle)hnd->ump_mem_handle);
            if (hnd->base)
                gralloc_unmap(module, handle);

            hnd->base = 0;
            hnd->ump_mem_handle = (int)UMP_INVALID_MEMORY_HANDLE;
            hnd->lockState  = 0;
            hnd->writeOwner = 0;
        } else {
            ALOGE("unregistering non-UMP buffer not supported");
        }

        pthread_mutex_unlock(&s_map_lock);
    }

    return 0;
}
static int alloc_device_free(alloc_device_t* dev, buffer_handle_t handle)
{
	if (private_handle_t::validate(handle) < 0)
	{
		return -EINVAL;
	}

	private_handle_t const* hnd = reinterpret_cast<private_handle_t const*>(handle);
	if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)
	{
		// free this buffer
		private_module_t* m = reinterpret_cast<private_module_t*>(dev->common.module);
		const size_t bufferSize = m->finfo.line_length * m->info.yres;
		int index = (hnd->base - m->framebuffer->base) / bufferSize;
		m->bufferMask &= ~(1<<index); 
		close(hnd->fd);

#if GRALLOC_ARM_UMP_MODULE
		if ( (int)UMP_INVALID_MEMORY_HANDLE != hnd->ump_mem_handle )
		{
			ump_reference_release((ump_handle)hnd->ump_mem_handle);
		}
#endif
	}
	else if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_UMP)
	{
#if GRALLOC_ARM_UMP_MODULE
		ump_mapped_pointer_release((ump_handle)hnd->ump_mem_handle);
		ump_reference_release((ump_handle)hnd->ump_mem_handle);
#else
		AERR( "Can't free ump memory for handle:0x%x. Not supported.", (unsigned int)hnd );
#endif
	} 
	else if ( hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION )
	{
#if GRALLOC_ARM_DMA_BUF_MODULE
		private_module_t* m = reinterpret_cast<private_module_t*>(dev->common.module);
		if ( 0 != munmap( (void*)hnd->base, hnd->size ) ) AERR( "Failed to munmap handle 0x%x", (unsigned int)hnd );
		close( hnd->share_fd );
		if ( 0 != ion_free( m->ion_client, hnd->ion_hnd ) ) AERR( "Failed to ion_free( ion_client: %d ion_hnd: %p )", m->ion_client, hnd->ion_hnd );
		memset( (void*)hnd, 0, sizeof( *hnd ) );
#else 
		AERR( "Can't free dma_buf memory for handle:0x%x. Not supported.", (unsigned int)hnd );
#endif
		
	}

	delete hnd;

	return 0;
}
static int alloc_device_free(alloc_device_t* dev, buffer_handle_t handle)
{
	if (private_handle_t::validate(handle) < 0)
	{
		return -EINVAL;
	}

	private_handle_t const* hnd = reinterpret_cast<private_handle_t const*>(handle);
	if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)
	{
		// free this buffer
		private_module_t* m = reinterpret_cast<private_module_t*>(dev->common.module);
		const size_t bufferSize = m->finfo.line_length * m->info.yres;
		int index = (hnd->base - m->framebuffer->base) / bufferSize;
		m->bufferMask &= ~(1<<index); 
		close(hnd->fd);
	}
	else if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_UMP)
	{
		ump_mapped_pointer_release((ump_handle)hnd->ump_mem_handle);
		ump_reference_release((ump_handle)hnd->ump_mem_handle);
	}

	delete hnd;

	return 0;
}
Esempio n. 4
0
static Bool
DestroyPixmap(PixmapPtr pPixmap)
{
    ScreenPtr pScreen = pPixmap->drawable.pScreen;
    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
    Rk30MaliPtr rk_3d = FBDEVPTR(pScrn)->Rk30Mali;
    Bool result;
    UMPBufferInfoPtr umpbuf;
    HASH_FIND_PTR(rk_3d->HashPixmapToUMP, &pPixmap, umpbuf);

    if (umpbuf) {
        DebugMsg("DestroyPixmap %p for migrated UMP pixmap (UMP buffer=%p)\n", pPixmap, umpbuf);

        pPixmap->devKind = umpbuf->BackupDevKind;
        pPixmap->devPrivate.ptr = umpbuf->BackupDevPrivatePtr;

        ump_mapped_pointer_release(umpbuf->handle);
        ump_reference_release(umpbuf->handle);

        HASH_DEL(rk_3d->HashPixmapToUMP, umpbuf);
        DebugMsg("umpbuf->refcount=%d\n", umpbuf->refcount);
        if (--umpbuf->refcount <= 0) {
            DebugMsg("free(umpbuf)\n");
            free(umpbuf);
        }
    }

    pScreen->DestroyPixmap = rk_3d->DestroyPixmap;
    result = (*pScreen->DestroyPixmap) (pPixmap);
    rk_3d->DestroyPixmap = pScreen->DestroyPixmap;
    pScreen->DestroyPixmap = DestroyPixmap;


    return result;
}
Esempio n. 5
0
static void MaliDRI2DestroyBuffer(DrawablePtr pDraw, DRI2Buffer2Ptr buffer)
{
    MaliDRI2BufferPrivatePtr privates;
    ScreenPtr pScreen = pDraw->pScreen;
    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
    Rk30MaliPtr rk_3d = FBDEVPTR(pScrn)->Rk30Mali;

    DebugMsg("DRI2DestroyBuffer %s=%p, buf=%p:%p, att=%d\n",
             pDraw->type == DRAWABLE_WINDOW ? "win" : "pix",
             pDraw, buffer, buffer->driverPrivate, buffer->attachment);

    if (buffer != NULL) {
    if(buffer->driverPrivate != NULL){
        privates = (MaliDRI2BufferPrivatePtr)buffer->driverPrivate;
        if (!privates->pPixmap) {
            /* If pPixmap != 0, then these are freed in DestroyPixmap */
            if (privates->handle != UMP_INVALID_MEMORY_HANDLE) {
                ump_mapped_pointer_release(privates->handle);
                ump_reference_release(privates->handle);
            }
        }
        if (--privates->refcount <= 0) {
            DebugMsg("free(privates)\n");
            free(privates);
        }
    }
	if(buffer != rk_3d->buf_back)
        free(buffer);
    }

}
static int gralloc_alloc_buffer(alloc_device_t* dev, size_t size, int usage, buffer_handle_t* pHandle)
{
	ump_handle ump_mem_handle;
	void *cpu_ptr;
	ump_secure_id ump_id;
	ump_alloc_constraints constraints;

	size = round_up_to_page_size(size);

	if( (usage&GRALLOC_USAGE_SW_READ_MASK) == GRALLOC_USAGE_SW_READ_OFTEN )
	{
		constraints =  UMP_REF_DRV_CONSTRAINT_USE_CACHE;
	}
	else
	{
		constraints = UMP_REF_DRV_CONSTRAINT_NONE;
	}

	ump_mem_handle = ump_ref_drv_allocate(size, constraints);
	if (UMP_INVALID_MEMORY_HANDLE != ump_mem_handle)
	{
		cpu_ptr = ump_mapped_pointer_get(ump_mem_handle);
		if (NULL != cpu_ptr)
		{
			ump_id = ump_secure_id_get(ump_mem_handle);
			if (UMP_INVALID_SECURE_ID != ump_id)
			{
				private_handle_t* hnd = new private_handle_t(private_handle_t::PRIV_FLAGS_USES_UMP, size, (int)cpu_ptr,
				                                             private_handle_t::LOCK_STATE_MAPPED, ump_id, ump_mem_handle);
				if (NULL != hnd)
				{
					*pHandle = hnd;
					return 0;
				}
				else
				{
					LOGE("gralloc_alloc_buffer() failed to allocate handle");
				}
			}
			else
			{
				LOGE("gralloc_alloc_buffer() failed to retrieve valid secure id");
			}
			
			ump_mapped_pointer_release(ump_mem_handle);
		}
		else
		{
			LOGE("gralloc_alloc_buffer() failed to map UMP memory");
		}

		ump_reference_release(ump_mem_handle);
	}
	else
	{
		LOGE("gralloc_alloc_buffer() failed to allcoate UMP memory");
	}

	return -1;
}
Esempio n. 7
0
void
platform_free_eglimage (EGLDisplay display, EGLContext context, GLuint tex_id,
    EGLImageKHR * image, gpointer * image_platform_data)
{
  fbdev_pixmap *pixmap = *image_platform_data;

  eglDestroyImageKHR (display, *image);
  ump_reference_release ((ump_handle) pixmap->data);
  ump_close ();
  g_slice_free (fbdev_pixmap, *image_platform_data);
}
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;
}
Esempio n. 9
0
static void maliDestroyPixmap(ScreenPtr pScreen, void *driverPriv)
{
	PrivPixmap *privPixmap = (PrivPixmap *)driverPriv;

	IGNORE(pScreen);

	if (NULL != privPixmap->mem_info)
	{
		/* frame buffer pixmap should not be called here */
		assert(!privPixmap->isFrameBuffer);
		ump_reference_release(privPixmap->mem_info->handle);
		free(privPixmap->mem_info);
		free(privPixmap);
	}
}
Esempio n. 10
0
static void MaliDRI2DestroyBuffer(DrawablePtr pDraw, DRI2Buffer2Ptr buffer)
{
    MaliDRI2BufferPrivatePtr privates;
    ScreenPtr pScreen = pDraw->pScreen;

//    ErrorF("Destroying attachment %d for drawable %p\n", buffer->attachment, pDraw);

    if (buffer != NULL) {
        privates = (MaliDRI2BufferPrivatePtr)buffer->driverPrivate;
        ump_mapped_pointer_release(privates->handle);
        ump_reference_release(privates->handle);
        free(privates);
        free(buffer);
    }
}
void gralloc_backend_unregister(private_handle_t* hnd)
{
	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:
		ump_mapped_pointer_release((ump_handle)hnd->ump_mem_handle);
		hnd->base = 0;
		ump_reference_release((ump_handle)hnd->ump_mem_handle);
		hnd->ump_mem_handle = UMP_INVALID_MEMORY_HANDLE;
		break;
	case private_handle_t::PRIV_FLAGS_USES_ION:
		AERR( "Can't unregister DMA_BUF buffer for hnd %p. Not supported", hnd );
		break;
	}
}
static void maliDestroyPixmap(ScreenPtr pScreen, void *driverPriv)
{
	PrivPixmap *privPixmap = (PrivPixmap *)driverPriv;

	IGNORE(pScreen);

	if (NULL != privPixmap->mem_info)
	{
		/* Need to destroy the other buffer if it's present. At the moment this never gets called for a
		 * framebuffer pixmap so asserting here for now because it will break if it is called with a framebuffer
		 * pixmap */
		assert(privPixmap->other_buffer == NULL);
		ump_reference_release(privPixmap->mem_info->handle);
		free(privPixmap->mem_info);
		free(privPixmap);
	}
}
static int gralloc_unregister_buffer(gralloc_module_t const* module, buffer_handle_t handle)
{
	if (private_handle_t::validate(handle) < 0)
	{
		LOGE("unregistering invalid buffer, returning error");
		return -EINVAL;
	}

	private_handle_t* hnd = (private_handle_t*)handle;
    
	LOGE_IF(hnd->lockState & private_handle_t::LOCK_STATE_READ_MASK, "[unregister] handle %p still locked (state=%08x)", hnd, hnd->lockState);

	// never unmap buffers that were created in this process
	if (hnd->pid != getpid())
	{
		pthread_mutex_lock(&s_map_lock);

		if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_UMP)
		{
			ump_mapped_pointer_release((ump_handle)hnd->ump_mem_handle);
			hnd->base = 0;
			ump_reference_release((ump_handle)hnd->ump_mem_handle);
			hnd->ump_mem_handle = (int)UMP_INVALID_MEMORY_HANDLE;
		}
		else
		{
			LOGE("unregistering non-UMP buffer not supported");
		}

		hnd->base = 0;
		hnd->lockState  = 0;
		hnd->writeOwner = 0;

		pthread_mutex_unlock(&s_map_lock);
	}

	return 0;
}
Esempio n. 14
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;
}
Esempio n. 15
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;
}
static int gralloc_unregister_buffer(gralloc_module_t const *module, buffer_handle_t handle)
{
	MALI_IGNORE(module);

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

	private_handle_t *hnd = (private_handle_t *)handle;

	AERR_IF(hnd->lockState & private_handle_t::LOCK_STATE_READ_MASK, "[unregister] handle %p still locked (state=%08x)", hnd, hnd->lockState);

	if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)
	{
		AERR("Can't unregister buffer 0x%p as it is a framebuffer", handle);
	}
	else if (hnd->pid == getpid()) // never unmap buffers that were not registered in this process
	{
		pthread_mutex_lock(&s_map_lock);

		if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_UMP)
		{
#if GRALLOC_ARM_UMP_MODULE
			ump_mapped_pointer_release((ump_handle)hnd->ump_mem_handle);
			ump_reference_release((ump_handle)hnd->ump_mem_handle);
			hnd->ump_mem_handle = (int)UMP_INVALID_MEMORY_HANDLE;
#else
			AERR("Can't unregister UMP buffer for handle 0x%p. Not supported", handle);
#endif
		}
		else if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION)
		{
#if GRALLOC_ARM_DMA_BUF_MODULE
			void *base = (void *)hnd->base;
			size_t size = hnd->size;

			if (munmap(base, size) < 0)
			{
				AERR("Could not munmap base:0x%p size:%lu '%s'", base, (unsigned long)size, strerror(errno));
			}

#else
			AERR("Can't unregister DMA_BUF buffer for hnd %p. Not supported", hnd);
#endif

		}
		else
		{
			AERR("Unregistering unknown buffer is not supported. Flags = %d", hnd->flags);
		}

		hnd->base = 0;
		hnd->lockState  = 0;
		hnd->writeOwner = 0;

		pthread_mutex_unlock(&s_map_lock);
	}
	else
	{
		AERR("Trying to unregister buffer 0x%p from process %d that was not created in current process: %d", hnd, hnd->pid, getpid());
	}

	return 0;
}
//static int gralloc_alloc_buffer(alloc_device_t* dev, size_t size, int usage, buffer_handle_t* pHandle, bool reserve)
static int gralloc_alloc_buffer(alloc_device_t* dev, size_t size, int usage, buffer_handle_t* pHandle, int reserve)
{
#if GRALLOC_ARM_DMA_BUF_MODULE
	{
		private_module_t *m = reinterpret_cast<private_module_t *>(dev->common.module);
		ion_user_handle_t ion_hnd;
		unsigned char *cpu_ptr;
		int shared_fd;
		int ret;
		unsigned int heap_mask;
		int Ion_type;
		bool Ishwc = false;
        int Ion_flag = 0;   
        if(usage == (GRALLOC_USAGE_HW_COMPOSER|GRALLOC_USAGE_HW_RENDER))
            Ishwc = true;

		//ret = ion_alloc(m->ion_client, size, 0, ION_HEAP_SYSTEM_MASK, 0, &ion_hnd);
        #ifdef USE_X86	
        
        if(usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK))
            Ion_flag = (ION_FLAG_CACHED|ION_FLAG_CACHED_NEEDS_SYNC);

        if(is_out_log())
            ALOGD("usage=%x,protect=%x,ion_flag=%x,mmu=%d",usage,GRALLOC_USAGE_PROTECTED,Ion_flag,g_MMU_stat);
        if (usage & GRALLOC_USAGE_PROTECTED)  //secrue memery
        {
            unsigned long phys;
            ret = ion_secure_alloc(m->ion_client, size,&phys);
            //ALOGD("secure_alloc ret=%d,phys=%x",ret,(int)phys);
            if(ret != 0)
            {
                AERR("Failed to ion_alloc from ion_client:%d, size: %d", m->ion_client, size);
                return -1;
            }    
	        private_handle_t *hnd = new private_handle_t(private_handle_t::PRIV_FLAGS_USES_ION, usage, size, 0, 0);

    		if (NULL != hnd)
    		{
    			hnd->share_fd = 0;
    			hnd->ion_hnd = 0;
    			hnd->type = 0;
    			hnd->phy_addr = (int)phys;
    			*pHandle = hnd;
                if(is_out_log())
                    ALOGD("secure_alloc_ok phy=%x",usage,hnd->phy_addr);
    			
    			return 0;
    		}
    		else
    		{
    			AERR("Gralloc out of mem for ion_client:%d", m->ion_client);
    		}

    		close(shared_fd);

    		return -1;
        }
        #endif
		//ret = ion_alloc(m->ion_client, size, 0, ION_HEAP_SYSTEM_MASK, 0, &ion_hnd);
        #ifdef USE_X86		
		if(g_MMU_stat
		    && ((usage&GRALLOC_USAGE_HW_CAMERA_WRITE)==0)
		    && !(usage & GRALLOC_USAGE_PRIVATE_2)
		    && !Ishwc)
        #else
		if(g_MMU_stat)
		#endif
		{
		    heap_mask = ION_HEAP(ION_VMALLOC_HEAP_ID);
            #ifdef USE_X86		
		    if (usage & GRALLOC_USAGE_PRIVATE_2)
		    {
		        heap_mask |=  ION_HEAP(ION_SECURE_HEAP_ID);
		    }
            #endif
		    ret = ion_alloc(m->ion_client, size, 0, heap_mask, Ion_flag, &ion_hnd);
		    Ion_type = 1;
		} else {
		    heap_mask = ION_HEAP(ION_CMA_HEAP_ID);
            #ifdef USE_X86		
		    if (usage & GRALLOC_USAGE_PRIVATE_2)
		    {
		        heap_mask |=  ION_HEAP(ION_SECURE_HEAP_ID);
		    }
            #endif

		    if (usage == (GRALLOC_USAGE_HW_CAMERA_WRITE|GRALLOC_USAGE_SW_READ_OFTEN)) {
                     ret = ion_alloc(m->ion_client, size, 0,heap_mask, 
                        (ION_FLAG_CACHED|ION_FLAG_CACHED_NEEDS_SYNC), &ion_hnd);   
		    } else {
                     ret = ion_alloc(m->ion_client, size, 0,heap_mask, Ion_flag, &ion_hnd);
		    }
            #ifdef USE_X86		
		    if(g_MMU_stat && Ishwc)
		    {
		        Ion_type = 1;
 
		    }    
		    else    
		    #endif
		        Ion_type = 0;
		}

		if (ret != 0)
		{
            if( (heap_mask & ION_HEAP(ION_CMA_HEAP_ID))
#ifdef USE_X86
            && !Ishwc
#endif
            )
            {
#ifdef BOARD_WITH_IOMMU
                heap_mask = ION_HEAP(ION_VMALLOC_HEAP_ID);
#else
                heap_mask = ION_HEAP(ION_CARVEOUT_HEAP_ID);
#endif
                ret = ion_alloc(m->ion_client, size, 0, heap_mask, 0, &ion_hnd );
                {
                    if( ret != 0)
                    {
                        AERR("Force to VMALLOC fail ion_client:%d", m->ion_client);
                        return -1;
                    }
                    else
                    {
                        ALOGD("Force to VMALLOC sucess !");
                        Ion_type = 1;
                    }
                }
            }
            else
            {
                AERR("Failed to ion_alloc from ion_client:%d, size: %d", m->ion_client, size);
                return -1;
            }
		}

		ret = ion_share(m->ion_client, ion_hnd, &shared_fd);

		if (ret != 0)
		{
			AERR("ion_share( %d ) failed", m->ion_client);

			if (0 != ion_free(m->ion_client, ion_hnd))
			{
				AERR("ion_free( %d ) failed", m->ion_client);
			}

			return -1;
		}
		cpu_ptr = (unsigned char *)mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, shared_fd, 0);
		#ifdef USE_X86
		//memset(cpu_ptr, 0, size);
		#endif
		if (MAP_FAILED == cpu_ptr)
		{
			AERR("ion_map( %d ) failed", m->ion_client);

			if (0 != ion_free(m->ion_client, ion_hnd))
			{
				AERR("ion_free( %d ) failed", m->ion_client);
			}

			close(shared_fd);
			return -1;
		}

		private_handle_t *hnd = new private_handle_t(private_handle_t::PRIV_FLAGS_USES_ION, usage, size, (int)cpu_ptr, private_handle_t::LOCK_STATE_MAPPED);

		if (NULL != hnd)
		{
		    unsigned long cma_phys = 0;
			hnd->share_fd = shared_fd;
			hnd->ion_hnd = ion_hnd;
			hnd->type = Ion_type;
			if(!Ion_type)
			{
			    int pret;
			    pret = ion_get_phys(m->ion_client, ion_hnd, &cma_phys);
			    //ALOGD("ion_get_phy ret=%d,cma_phys=%x",pret,cma_phys);
			}    
			    
			hnd->phy_addr = (int)cma_phys;
			*pHandle = hnd;
            if(is_out_log())
                ALOGD("alloc_info fd[%d],type=%d,phy=%x",hnd->share_fd,hnd->type,hnd->phy_addr);
			
			return 0;
		}
		else
		{
			AERR("Gralloc out of mem for ion_client:%d", m->ion_client);
		}

		close(shared_fd);
		ret = munmap(cpu_ptr, size);

		if (0 != ret)
		{
			AERR("munmap failed for base:%p size: %d", cpu_ptr, size);
		}

		ret = ion_free(m->ion_client, ion_hnd);

		if (0 != ret)
		{
			AERR("ion_free( %d ) failed", m->ion_client);
		}

		return -1;
	}
#endif

#if GRALLOC_ARM_UMP_MODULE
	{
		ump_handle ump_mem_handle;
		void *cpu_ptr;
		ump_secure_id ump_id;
		int constraints;

		size = round_up_to_page_size(size);

		if ((usage & GRALLOC_USAGE_SW_READ_MASK) == GRALLOC_USAGE_SW_READ_OFTEN)
		{
			constraints =  UMP_REF_DRV_CONSTRAINT_USE_CACHE;
		}
		else
		{
			constraints = UMP_REF_DRV_CONSTRAINT_NONE;
		}
	    if ( reserve & 0x01)
		{
		
		    constraints |= UMP_REF_DRV_CONSTRAINT_PRE_RESERVE;
		}
		
		if( reserve & 0x02)
		{
            constraints |= UMP_REF_DRV_UK_CONSTRAINT_MEM_SWITCH;

		}
#ifdef GRALLOC_SIMULATE_FAILURES
		/* if the failure condition matches, fail this iteration */
		if (__ump_alloc_should_fail())
		{
			ump_mem_handle = UMP_INVALID_MEMORY_HANDLE;
		}
		else
#endif
		{
			ump_mem_handle = ump_ref_drv_allocate(size, (ump_alloc_constraints)constraints);

			if (UMP_INVALID_MEMORY_HANDLE != ump_mem_handle)
			{
				cpu_ptr = ump_mapped_pointer_get(ump_mem_handle);

				if (NULL != cpu_ptr)
				{
					ump_id = ump_secure_id_get(ump_mem_handle);

					if (UMP_INVALID_SECURE_ID != ump_id)
					{
						private_handle_t *hnd = new private_handle_t(private_handle_t::PRIV_FLAGS_USES_UMP, usage, size, (int)cpu_ptr,
						private_handle_t::LOCK_STATE_MAPPED, ump_id, ump_mem_handle);

						if (NULL != hnd)
						{
						#ifdef  USE_LCDC_COMPOSER
            		 		if( reserve & 0x02)
					  		{
	                    		hnd->phy_addr = 0;   
					  		}
					  		else
					  		{
                    		    hnd->phy_addr = ump_phy_addr_get(ump_mem_handle);        
                    		}   
                    	#endif
							*pHandle = hnd;
							return 0;
						}
						else
						{
							AERR("gralloc_alloc_buffer() failed to allocate handle. ump_handle = %p, ump_id = %d", ump_mem_handle, ump_id);
						}
					}
					else
					{
						AERR("gralloc_alloc_buffer() failed to retrieve valid secure id. ump_handle = %p", ump_mem_handle);
					}

					ump_mapped_pointer_release(ump_mem_handle);
				}
				else
				{
					AERR("gralloc_alloc_buffer() failed to map UMP memory. ump_handle = %p", ump_mem_handle);
				}

				ump_reference_release(ump_mem_handle);
			}
			else
			{
				AERR("gralloc_alloc_buffer() failed to allocate UMP memory. size:%d constraints: %d", size, constraints);
			}
		}
		return -1;
	}
#endif
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;
}
Esempio n. 20
0
static int gralloc_alloc_buffer(alloc_device_t *dev, size_t size, int usage, buffer_handle_t *pHandle)
{
#if GRALLOC_ARM_DMA_BUF_MODULE
	{
		private_module_t *m = reinterpret_cast<private_module_t *>(dev->common.module);
		ion_user_handle_t ion_hnd;
		unsigned char *cpu_ptr;
		int shared_fd;
		int ret;
		unsigned int ion_flags = 0;

		if( (usage & GRALLOC_USAGE_SW_READ_MASK) == GRALLOC_USAGE_SW_READ_OFTEN )
			ion_flags = ION_FLAG_CACHED | ION_FLAG_CACHED_NEEDS_SYNC;
		if (usage & GRALLOC_USAGE_PRIVATE_1) {
			ret = ion_alloc(m->ion_client, size, 0, ION_HEAP_CARVEOUT_MASK, ion_flags, &ion_hnd);
		} else {
			ret = ion_alloc(m->ion_client, size, 0, ION_HEAP_SYSTEM_MASK, ion_flags, &ion_hnd);
		}

		if (ret != 0)
		{
			AERR("Failed to ion_alloc from ion_client:%d", m->ion_client);
			return -1;
		}

		ret = ion_share(m->ion_client, ion_hnd, &shared_fd);

		if (ret != 0)
		{
			AERR("ion_share( %d ) failed", m->ion_client);

			if (0 != ion_free(m->ion_client, ion_hnd))
			{
				AERR("ion_free( %d ) failed", m->ion_client);
			}

			return -1;
		}

		cpu_ptr = (unsigned char *)mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, shared_fd, 0);

		if (MAP_FAILED == cpu_ptr)
		{
			AERR("ion_map( %d ) failed", m->ion_client);

			if (0 != ion_free(m->ion_client, ion_hnd))
			{
				AERR("ion_free( %d ) failed", m->ion_client);
			}

			close(shared_fd);
			return -1;
		}

		private_handle_t *hnd = new private_handle_t(private_handle_t::PRIV_FLAGS_USES_ION, usage, size, (int)cpu_ptr, private_handle_t::LOCK_STATE_MAPPED);

		if (NULL != hnd)
		{
			hnd->share_fd = shared_fd;
			hnd->ion_hnd = ion_hnd;
			*pHandle = hnd;
			return 0;
		}
		else
		{
			AERR("Gralloc out of mem for ion_client:%d", m->ion_client);
		}

		close(shared_fd);
		ret = munmap(cpu_ptr, size);

		if (0 != ret)
		{
			AERR("munmap failed for base:%p size: %d", cpu_ptr, size);
		}

		ret = ion_free(m->ion_client, ion_hnd);

		if (0 != ret)
		{
			AERR("ion_free( %d ) failed", m->ion_client);
		}

		return -1;
	}
#endif

#if GRALLOC_ARM_UMP_MODULE
	{
		ump_handle ump_mem_handle;
		void *cpu_ptr;
		ump_secure_id ump_id;
		ump_alloc_constraints constraints;

		size = round_up_to_page_size(size);

		if ((usage & GRALLOC_USAGE_SW_READ_MASK) == GRALLOC_USAGE_SW_READ_OFTEN)
		{
			constraints =  UMP_REF_DRV_CONSTRAINT_USE_CACHE;
		}
		else
		{
			constraints = UMP_REF_DRV_CONSTRAINT_NONE;
		}

#ifdef GRALLOC_SIMULATE_FAILURES
		/* if the failure condition matches, fail this iteration */
		if (__ump_alloc_should_fail())
		{
			ump_mem_handle = UMP_INVALID_MEMORY_HANDLE;
		}
		else
#endif
		{
			ump_mem_handle = ump_ref_drv_allocate(size, constraints);

			if (UMP_INVALID_MEMORY_HANDLE != ump_mem_handle)
			{
				cpu_ptr = ump_mapped_pointer_get(ump_mem_handle);

				if (NULL != cpu_ptr)
				{
					ump_id = ump_secure_id_get(ump_mem_handle);

					if (UMP_INVALID_SECURE_ID != ump_id)
					{
						private_handle_t *hnd = new private_handle_t(private_handle_t::PRIV_FLAGS_USES_UMP, usage, size, (int)cpu_ptr,
						private_handle_t::LOCK_STATE_MAPPED, ump_id, ump_mem_handle);

						if (NULL != hnd)
						{
							*pHandle = hnd;
							return 0;
						}
						else
						{
							AERR("gralloc_alloc_buffer() failed to allocate handle. ump_handle = %p, ump_id = %d", ump_mem_handle, ump_id);
						}
					}
					else
					{
						AERR("gralloc_alloc_buffer() failed to retrieve valid secure id. ump_handle = %p", ump_mem_handle);
					}

					ump_mapped_pointer_release(ump_mem_handle);
				}
				else
				{
					AERR("gralloc_alloc_buffer() failed to map UMP memory. ump_handle = %p", ump_mem_handle);
				}

				ump_reference_release(ump_mem_handle);
			}
			else
			{
				AERR("gralloc_alloc_buffer() failed to allocate UMP memory. size:%d constraints: %d", size, constraints);
			}
		}
		return -1;
	}
#endif

}
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;
}
Esempio n. 22
0
gboolean
platform_alloc_eglimage (EGLDisplay display, EGLContext context, GLint format,
    GLint type, gint width, gint height, GLuint tex_id, EGLImageKHR * image,
    gpointer * image_platform_data)
{
  fbdev_pixmap pixmap;

  pixmap.flags = FBDEV_PIXMAP_SUPPORTS_UMP;
  pixmap.width = width;
  pixmap.height = height;

  switch (format) {
    case GL_LUMINANCE:
      g_return_val_if_fail (type == GL_UNSIGNED_BYTE, FALSE);
      pixmap.red_size = 0;
      pixmap.green_size = 0;
      pixmap.blue_size = 0;
      pixmap.alpha_size = 0;
      pixmap.luminance_size = 8;
      break;
    case GL_LUMINANCE_ALPHA:
      g_return_val_if_fail (type == GL_UNSIGNED_BYTE, FALSE);
      pixmap.red_size = 0;
      pixmap.green_size = 0;
      pixmap.blue_size = 0;
      pixmap.alpha_size = 8;
      pixmap.luminance_size = 8;
      break;
    case GL_RGB:
      if (type == GL_UNSIGNED_BYTE) {
        pixmap.red_size = 8;
        pixmap.green_size = 8;
        pixmap.blue_size = 8;
        pixmap.alpha_size = 0;
        pixmap.luminance_size = 0;
      } else if (type == GL_UNSIGNED_SHORT_5_6_5) {
        pixmap.red_size = 5;
        pixmap.green_size = 6;
        pixmap.blue_size = 5;
        pixmap.alpha_size = 0;
        pixmap.luminance_size = 0;
      } else {
        g_return_val_if_reached (FALSE);
      }
      break;
    case GL_RGBA:
      g_return_val_if_fail (type == GL_UNSIGNED_BYTE, FALSE);
      pixmap.red_size = 8;
      pixmap.green_size = 8;
      pixmap.blue_size = 8;
      pixmap.alpha_size = 8;
      pixmap.luminance_size = 0;
      break;
    default:
      g_assert_not_reached ();
      return FALSE;
  }

  pixmap.buffer_size =
      pixmap.red_size + pixmap.green_size + pixmap.blue_size +
      pixmap.alpha_size + pixmap.luminance_size;
  pixmap.bytes_per_pixel = pixmap.buffer_size / 8;
  pixmap.format = 0;

  if (ump_open () != UMP_OK) {
    GST_ERROR ("Failed to open UMP");
    return FALSE;
  }

  pixmap.data =
      ump_ref_drv_allocate (GST_ROUND_UP_4 (pixmap.width) * pixmap.height *
      pixmap.bytes_per_pixel, UMP_REF_DRV_CONSTRAINT_PHYSICALLY_LINEAR);
  if (pixmap.data == UMP_INVALID_MEMORY_HANDLE) {
    GST_ERROR ("Failed to allocate pixmap data via UMP");
    ump_close ();
    return FALSE;
  }

  *image_platform_data = g_slice_dup (fbdev_pixmap, &pixmap);
  *image =
      eglCreateImageKHR (display, EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR,
      (EGLClientBuffer) * image_platform_data, NULL);
  if (!image) {
    GST_ERROR ("Failed to create EGLImage for pixmap");
    ump_reference_release ((ump_handle) pixmap.data);
    ump_close ();
    g_slice_free (fbdev_pixmap, *image_platform_data);
    return FALSE;
  }

  return TRUE;
}