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; }
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; }
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; }
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; }
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); } }
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; }
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) { 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; }
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; }
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; }