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; }
/* Migrate pixmap to UMP buffer */ static UMPBufferInfoPtr MigratePixmapToUMP(PixmapPtr pPixmap) { ScreenPtr pScreen = pPixmap->drawable.pScreen; ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; Rk30MaliPtr rk_3d = FBDEVPTR(pScrn)->Rk30Mali; UMPBufferInfoPtr umpbuf; size_t pitch = ((pPixmap->devKind + 7) / 8) * 8; size_t size = pitch * pPixmap->drawable.height; HASH_FIND_PTR(rk_3d->HashPixmapToUMP, &pPixmap, umpbuf); if (umpbuf) { DebugMsg("MigratePixmapToUMP %p, already exists = %p\n", pPixmap, umpbuf); return umpbuf; } /* create the UMP buffer */ umpbuf = calloc(1, sizeof(UMPBufferInfoRec)); if (!umpbuf) { ErrorF("MigratePixmapToUMP: calloc failed\n"); return NULL; } umpbuf->refcount = 1; umpbuf->pPixmap = pPixmap; umpbuf->handle = ump_ref_drv_allocate(size, UMP_REF_DRV_CONSTRAINT_PHYSICALLY_LINEAR); if (umpbuf->handle == UMP_INVALID_MEMORY_HANDLE) { ErrorF("MigratePixmapToUMP: ump_ref_drv_allocate failed\n"); free(umpbuf); return NULL; } umpbuf->size = size; umpbuf->addr = ump_mapped_pointer_get(umpbuf->handle); umpbuf->depth = pPixmap->drawable.depth; umpbuf->width = pPixmap->drawable.width; umpbuf->height = pPixmap->drawable.height; /* copy the pixel data to the new location */ if (pitch == pPixmap->devKind) { memcpy(umpbuf->addr, pPixmap->devPrivate.ptr, size); } else { int y; for (y = 0; y < umpbuf->height; y++) { memcpy(umpbuf->addr + y * pitch, pPixmap->devPrivate.ptr + y * pPixmap->devKind, pPixmap->devKind); } } umpbuf->BackupDevKind = pPixmap->devKind; umpbuf->BackupDevPrivatePtr = pPixmap->devPrivate.ptr; pPixmap->devKind = pitch; pPixmap->devPrivate.ptr = umpbuf->addr; HASH_ADD_PTR(rk_3d->HashPixmapToUMP, pPixmap, umpbuf); DebugMsg("MigratePixmapToUMP %p, new buf = %p\n", pPixmap, umpbuf); return umpbuf; }
static DRI2Buffer2Ptr MaliDRI2CreateBuffer(DrawablePtr pDraw, unsigned int attachment, unsigned int format) { ScreenPtr pScreen = pDraw->pScreen; ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; PixmapPtr pPixmap = NULL; DRI2Buffer2Ptr buffer = calloc(1, sizeof *buffer); MaliDRI2BufferPrivatePtr privates = calloc(1, sizeof *privates); ump_handle handle; size_t size; if (pDraw->type == DRAWABLE_WINDOW) { pPixmap = pScreen->GetWindowPixmap((WindowPtr)pDraw); } else { ErrorF("Unexpected pDraw->type (%d) in MaliDRI2CreateBuffer\n", pDraw->type); return NULL; } /* initialize buffer info to default values */ buffer->attachment = attachment; buffer->driverPrivate = privates; buffer->format = format; buffer->flags = 0; buffer->cpp = pPixmap->drawable.bitsPerPixel / 8; buffer->pitch = PixmapBytePad(pDraw->width, pDraw->depth); /* allocate UMP buffer */ size = pDraw->height * buffer->pitch; handle = ump_ref_drv_allocate(size, UMP_REF_DRV_CONSTRAINT_PHYSICALLY_LINEAR | UMP_REF_DRV_CONSTRAINT_USE_CACHE); if (handle == UMP_INVALID_MEMORY_HANDLE) { ErrorF("invalid UMP handle, bufsize=%d\n", (int)size); } privates->size = size; privates->handle = handle; privates->addr = ump_mapped_pointer_get(handle); privates->width = pDraw->width; privates->height = pDraw->height; privates->depth = pDraw->depth; buffer->name = ump_secure_id_get(handle); buffer->flags = 0; /* offset */ // ErrorF("MaliDRI2CreateBuffer attachment=%d %p, format=%d, cpp=%d, depth=%d\n", // attachment, buffer, format, buffer->cpp, privates->depth); return buffer; }
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 }
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; }
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_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 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; }