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 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_alloc_framebuffer_locked(alloc_device_t *dev, size_t size, int usage, buffer_handle_t *pHandle) { private_module_t *m = reinterpret_cast<private_module_t *>(dev->common.module); // allocate the framebuffer if (m->framebuffer == NULL) { // initialize the framebuffer, the framebuffer is mapped once and forever. int err = init_frame_buffer_locked(m); if (err < 0) { return err; } } const uint32_t bufferMask = m->bufferMask; const uint32_t numBuffers = m->numBuffers; const size_t bufferSize = m->finfo.line_length * m->info.yres; if (numBuffers == 1) { // If we have only one buffer, we never use page-flipping. Instead, // we return a regular buffer which will be memcpy'ed to the main // screen when post is called. int newUsage = (usage & ~GRALLOC_USAGE_HW_FB) | GRALLOC_USAGE_HW_2D; AERR("fallback to single buffering. Virtual Y-res too small %d", m->info.yres); return gralloc_alloc_buffer(dev, bufferSize, newUsage, pHandle); } if (bufferMask >= ((1LU << numBuffers) - 1)) { // We ran out of buffers. return -ENOMEM; } int vaddr = m->framebuffer->base; // find a free slot for (uint32_t i = 0 ; i < numBuffers ; i++) { if ((bufferMask & (1LU << i)) == 0) { m->bufferMask |= (1LU << i); break; } vaddr += bufferSize; } // The entire framebuffer memory is already mapped, now create a buffer object for parts of this memory private_handle_t *hnd = new private_handle_t(private_handle_t::PRIV_FLAGS_FRAMEBUFFER, usage, size, vaddr, 0, dup(m->framebuffer->fd), vaddr - m->framebuffer->base); #if GRALLOC_ARM_UMP_MODULE hnd->ump_id = m->framebuffer->ump_id; /* create a backing ump memory handle if the framebuffer is exposed as a secure ID */ if ((int)UMP_INVALID_SECURE_ID != hnd->ump_id) { hnd->ump_mem_handle = (int)ump_handle_create_from_secure_id(hnd->ump_id); if ((int)UMP_INVALID_MEMORY_HANDLE == hnd->ump_mem_handle) { AINF("warning: unable to create UMP handle from secure ID %i\n", hnd->ump_id); } } #endif #if GRALLOC_ARM_DMA_BUF_MODULE { #ifdef FBIOGET_DMABUF struct fb_dmabuf_export fb_dma_buf; if (ioctl(m->framebuffer->fd, FBIOGET_DMABUF, &fb_dma_buf) == 0) { AINF("framebuffer accessed with dma buf (fd 0x%x)\n", (int)fb_dma_buf.fd); hnd->share_fd = fb_dma_buf.fd; } #endif } #endif *pHandle = hnd; return 0; }
static Bool maliModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, int depth, int bitsPerPixel, int devKind, pointer pPixData) { unsigned int size; PrivPixmap *privPixmap = (PrivPixmap *)exaGetPixmapDriverPrivate(pPixmap); mali_mem_info *mem_info; ScreenPtr pScreen = pPixmap->drawable.pScreen; ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; MaliPtr fPtr = MALIPTR(pScrn); if (!pPixmap) { return FALSE; } miModifyPixmapHeader(pPixmap, width, height, depth, bitsPerPixel, devKind, pPixData); if ((pPixData == fPtr->fbmem) || current_buf) { /* Wrap one of the fbdev virtual buffers */ ump_secure_id ump_id = UMP_INVALID_SECURE_ID; privPixmap->isFrameBuffer = TRUE; privPixmap->frameBufferNumber = current_buf; mem_info = privPixmap->mem_info; if (mem_info) { return TRUE; } /* create new mem_info for the on-screen buffer */ mem_info = calloc(1, sizeof(*mem_info)); if (!mem_info) { ERROR_MSG("failed to allocate for memory metadata"); return FALSE; } /* get the secure ID for the framebuffers */ if (ioctl(fPtr->fb_lcd_fd, GET_UMP_SECURE_ID_BUF(current_buf), &ump_id) < 0 || UMP_INVALID_SECURE_ID == ump_id) { free(mem_info); privPixmap->mem_info = NULL; ERROR_MSG("UMP failed to retrieve secure id, current_buf: %d", current_buf); return FALSE; } INFO_MSG("GET_UMP_SECURE_ID_BUF(%d) returned 0x%x", current_buf, ump_id); mem_info->handle = ump_handle_create_from_secure_id(ump_id); if (UMP_INVALID_MEMORY_HANDLE == mem_info->handle) { ERROR_MSG("UMP failed to create handle from secure id"); free(mem_info); privPixmap->mem_info = NULL; return FALSE; } size = exaGetPixmapPitch(pPixmap) * pPixmap->drawable.height; mem_info->usize = size; privPixmap->mem_info = mem_info; if (bitsPerPixel != 0) { privPixmap->bits_per_pixel = bitsPerPixel; } /* When this is called directly from X to create the front buffer, current_buf is zero as expected. When this * function is called recursively to create the back buffers, current_buf is increased to the next buffer */ privPixmap->mem_info->offset = current_buf * size; if (pPixData == fPtr->fbmem) { /* This is executed only when this function is called directly from X. We need to create the other * back buffers now because we can't "wrap" existing memory in a pixmap during DRI2CreateBuffer * for the back buffer of the framebuffer. In DRI2CreateBuffer instead of allocating a new * pixmap for the back buffer like we do for non-swappable windows, we'll just use the 'current_pixmap' * to grab this pointer from the screen pixmap and return it. */ PrivPixmap *current_privPixmap = privPixmap; int i; PrivBuffer *buf_info = calloc(1, sizeof(*buf_info)); if (NULL == buf_info) { ERROR_MSG("Failed to allocate buf_info memory"); free(mem_info); privPixmap->mem_info = NULL; return FALSE; } buf_info->current_pixmap = 0; buf_info->num_pixmaps = fPtr->dri2_num_buffers; buf_info->pPixmaps[0] = pPixmap; current_privPixmap->buf_info = buf_info; for (i = 1; i < buf_info->num_pixmaps; i++) { current_buf++; buf_info->pPixmaps[i] = (*pScreen->CreatePixmap)(pScreen, width, height, depth, 0); assert(buf_info->pPixmaps[i]); current_privPixmap = (PrivPixmap *)exaGetPixmapDriverPrivate(buf_info->pPixmaps[i]); current_privPixmap->buf_info = buf_info; } current_buf = 0; } INFO_MSG("Creating FRAMEBUFFER pixmap %p at offset %lu, privPixmap=%p", pPixmap, privPixmap->mem_info->offset, privPixmap); return TRUE; } if (pPixData) { /* When this happens we're being told to wrap existing pixmap data for which we don't know the UMP * handle. We can and still need to wrap it but it won't be offscreen - we can't accelerate it in any * way. */ if (privPixmap->mem_info != NULL) { return TRUE; } return FALSE; } pPixmap->devKind = ((pPixmap->drawable.width * pPixmap->drawable.bitsPerPixel) + 7) / 8; pPixmap->devKind = MALI_ALIGN(pPixmap->devKind, 8); size = exaGetPixmapPitch(pPixmap) * pPixmap->drawable.height; /* allocate pixmap data */ mem_info = privPixmap->mem_info; if (mem_info && mem_info->usize == size) { return TRUE; } if (mem_info && mem_info->usize != 0) { ump_reference_release(mem_info->handle); mem_info->handle = NULL; memset(privPixmap, 0, sizeof(*privPixmap)); return TRUE; } if (!size) { return TRUE; } if (NULL == mem_info) { mem_info = calloc(1, sizeof(*mem_info)); if (!mem_info) { ERROR_MSG("failed to allocate memory metadata"); return FALSE; } } if (fPtr->use_cached_ump) { mem_info->handle = ump_ref_drv_allocate(size, UMP_REF_DRV_CONSTRAINT_PHYSICALLY_LINEAR | UMP_REF_DRV_CONSTRAINT_USE_CACHE); } else { mem_info->handle = ump_ref_drv_allocate(size, UMP_REF_DRV_CONSTRAINT_PHYSICALLY_LINEAR); } if (UMP_INVALID_MEMORY_HANDLE == mem_info->handle) { ERROR_MSG("failed to allocate UMP memory (%i bytes)", size); return FALSE; } mem_info->usize = size; privPixmap->mem_info = mem_info; privPixmap->mem_info->usize = size; privPixmap->bits_per_pixel = 16; return TRUE; }
static int gralloc_register_buffer(gralloc_module_t const* module, buffer_handle_t handle) { if (private_handle_t::validate(handle) < 0) { LOGE("Registering invalid buffer, returning error"); return -EINVAL; } // if this handle was created in this process, then we keep it as is. private_handle_t* hnd = (private_handle_t*)handle; if (hnd->pid == getpid()) { return 0; } int retval = -EINVAL; pthread_mutex_lock(&s_map_lock); if (!s_ump_is_open) { ump_result res = ump_open(); // TODO: Fix a ump_close() somewhere??? if (res != UMP_OK) { pthread_mutex_unlock(&s_map_lock); LOGE("Failed to open UMP library"); return retval; } s_ump_is_open = 1; } if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_UMP) { hnd->ump_mem_handle = (int)ump_handle_create_from_secure_id(hnd->ump_id); if (UMP_INVALID_MEMORY_HANDLE != (ump_handle)hnd->ump_mem_handle) { hnd->base = (int)ump_mapped_pointer_get((ump_handle)hnd->ump_mem_handle); if (0 != hnd->base) { hnd->lockState = private_handle_t::LOCK_STATE_MAPPED; hnd->writeOwner = 0; hnd->lockState = 0; pthread_mutex_unlock(&s_map_lock); return 0; } else { LOGE("Failed to map UMP handle"); } ump_reference_release((ump_handle)hnd->ump_mem_handle); } else { LOGE("Failed to create UMP handle"); } } else { LOGE("registering non-UMP buffer not supported"); } pthread_mutex_unlock(&s_map_lock); return retval; }
static DRI2Buffer2Ptr MaliDRI2CreateBuffer(DrawablePtr pDraw, unsigned int attachment, unsigned int format) { ScreenPtr pScreen = pDraw->pScreen; ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; DRI2Buffer2Ptr buffer; MaliDRI2BufferPrivatePtr privates; ump_handle handle; FBDevPtr pMxv = FBDEVPTR(pScrn); Rk30MaliPtr rk_3d = pMxv->Rk30Mali; OvlHWPtr overlay = pMxv->OvlHW; Bool can_use_overlay = TRUE; PixmapPtr pWindowPixmap; if (pDraw->type == DRAWABLE_WINDOW && (pWindowPixmap = pScreen->GetWindowPixmap((WindowPtr)pDraw))) { DebugMsg("win=%p (w=%d, h=%d, x=%d, y=%d) has backing pix=%p (w=%d, h=%d, screen_x=%d, screen_y=%d)\n", pDraw, pDraw->width, pDraw->height, pDraw->x, pDraw->y, pWindowPixmap, pWindowPixmap->drawable.width, pWindowPixmap->drawable.height, pWindowPixmap->screen_x, pWindowPixmap->screen_y); } if(attachment != DRI2BufferBackLeft && rk_3d->buf_back != NULL){ DebugMsg("DRI2 return NullBuffer\n"); return rk_3d->buf_back; } if (!(buffer = calloc(1, sizeof *buffer))) { ErrorF("MaliDRI2CreateBuffer: calloc failed\n"); return NULL; } /* If it is a pixmap, just migrate this pixmap to UMP buffer */ if (pDraw->type == DRAWABLE_PIXMAP) { if (!(privates = MigratePixmapToUMP((PixmapPtr)pDraw))) { ErrorF("MaliDRI2CreateBuffer: MigratePixmapToUMP failed\n"); free(buffer); return NULL; } privates->refcount++; buffer->attachment = attachment; buffer->driverPrivate = privates; buffer->format = format; buffer->flags = 0; buffer->cpp = pDraw->bitsPerPixel / 8; buffer->pitch = ((PixmapPtr)pDraw)->devKind; buffer->name = ump_secure_id_get(privates->handle); DebugMsg("DRI2CreateBuffer pix=%p, buf=%p:%p, att=%d, ump=%d:%d, w=%d, h=%d, cpp=%d, depth=%d\n", pDraw, buffer, privates, attachment, buffer->name, buffer->flags, privates->width, privates->height, buffer->cpp, privates->depth); return buffer; } /* The drawable must be a window for using hardware overlays */ if (pDraw->type != DRAWABLE_WINDOW){ ErrorF("Unexpected pDraw->type (%d) in MaliDRI2CreateBuffer\n", pDraw->type); return NULL; } if (!(privates = calloc(1, sizeof *privates))) { ErrorF("MaliDRI2CreateBuffer: calloc failed\n"); free(buffer); return NULL; } /* We could not get framebuffer secure id */ if (rk_3d->ump_fb_secure_id1 == UMP_INVALID_SECURE_ID) can_use_overlay = FALSE; /* Overlay is already used by a different window */ if (rk_3d->pOverlayWin && rk_3d->pOverlayWin != (void *)pDraw) can_use_overlay = FALSE; /* TODO: try to support other color depths later */ if (pDraw->bitsPerPixel != 32) can_use_overlay = FALSE; /* The default common values */ buffer->attachment = attachment; buffer->driverPrivate = privates; buffer->format = format; buffer->flags = 0; buffer->cpp = pDraw->bitsPerPixel / 8; /* Stride must be 8 bytes aligned for Mali400 */ // buffer->pitch = ((buffer->cpp * pDraw->width + 7) / 8) * 8; buffer->pitch = ((buffer->cpp * overlay->cur_var.xres_virtual + 7) / 8) * 8; privates->size = pDraw->height * buffer->pitch; privates->width = pDraw->width; privates->height = pDraw->height; privates->depth = pDraw->depth; /* if (disp && disp->framebuffer_size - disp->gfx_layer_size < privates->size) { DebugMsg("Not enough space in the offscreen framebuffer (wanted %d for DRI2)\n", privates->size); can_use_overlay = FALSE; } */ /* if((pDraw->width+pDraw->x) > overlay->cur_var.xres || (pDraw->height+pDraw->y) > overlay->cur_var.yres) can_use_overlay = FALSE; */ if(pDraw->width < 2 || pDraw->height < 2){ can_use_overlay = FALSE; } if(attachment != DRI2BufferBackLeft){ // can_use_overlay = FALSE; free(privates); buffer->driverPrivate = NULL; buffer->name = UMP_INVALID_SECURE_ID; if(rk_3d->buf_back == NULL) rk_3d->buf_back = buffer; goto end; } if(rk_3d->OvlPg == ERRORL){ rk_3d->OvlPg = OvlAllocLay(pScrn, ANYL); if(rk_3d->OvlPg == ERRORL) can_use_overlay = FALSE; else{//init OvlSetupFb(pScrn, 0, 0, rk_3d->OvlPg); OvlEnable(pScrn, rk_3d->OvlPg, 1); } } rk_3d->bOverlayWinEnabled = can_use_overlay; if (can_use_overlay) rk_3d->pOverlayWin = (WindowPtr)pDraw; // buffer->pitch = ((buffer->cpp * overlay->OvlLay[rk_3d->OvlPg].var.xres_virtual + 7) / 8) * 8; // rk_3d->bOverlayWinEnabled = TRUE; // Stride must be 8 bytes aligned for Mali400 // privates->size = pDraw->height * buffer->pitch; // buffer->flags = 0; privates->handle = UMP_INVALID_MEMORY_HANDLE; privates->addr = NULL; buffer->name = rk_3d->ump_fb_secure_id1; privates->handle = ump_handle_create_from_secure_id(buffer->name); privates->addr = ump_mapped_pointer_get(privates->handle); // privates->addr = NULL;//(void*)0x94000000; /* } else { // rk_3d->bOverlayWinEnabled = FALSE; // Allocate UMP memory buffer #ifdef HAVE_LIBUMP_CACHE_CONTROL privates->handle = ump_ref_drv_allocate(privates->size, UMP_REF_DRV_CONSTRAINT_PHYSICALLY_LINEAR | UMP_REF_DRV_CONSTRAINT_USE_CACHE); ump_cache_operations_control(UMP_CACHE_OP_START); ump_switch_hw_usage_secure_id(ump_secure_id_get(privates->handle), UMP_USED_BY_MALI); ump_cache_operations_control(UMP_CACHE_OP_FINISH); #else privates->handle = ump_ref_drv_allocate(privates->size, UMP_REF_DRV_CONSTRAINT_PHYSICALLY_LINEAR); #endif if (privates->handle == UMP_INVALID_MEMORY_HANDLE) { ErrorF("Failed to allocate UMP buffer (size=%d)\n", (int)privates->size); } privates->addr = ump_mapped_pointer_get(privates->handle); buffer->name = ump_secure_id_get(privates->handle); buffer->flags = 0; } */ end: DebugMsg("DRI2CreateBuffer win=%p, buf=%p:%p, att=%d, ump=%d:%d, w=%d, h=%d, cpp=%d, depth=%d adr=%p\n", pDraw, buffer, privates, attachment, buffer->name, buffer->flags, privates->width, privates->height, buffer->cpp, privates->depth,privates->addr); return buffer; }
static Bool maliModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, int depth, int bitsPerPixel, int devKind, pointer pPixData) { unsigned int size; PrivPixmap *privPixmap = (PrivPixmap *)exaGetPixmapDriverPrivate(pPixmap); mali_mem_info *mem_info; ScreenPtr pScreen = pPixmap->drawable.pScreen; ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; MaliPtr fPtr = MALIPTR(pScrn); if (!pPixmap) { return FALSE; } miModifyPixmapHeader(pPixmap, width, height, depth, bitsPerPixel, devKind, pPixData); if ((pPixData == fPtr->fbmem) || offset) { /* Wrap one of the fbdev virtual buffers */ ump_secure_id ump_id = UMP_INVALID_SECURE_ID; privPixmap->isFrameBuffer = TRUE; mem_info = privPixmap->mem_info; if (mem_info) { return TRUE; } /* create new mem_info for the on-screen buffer */ mem_info = calloc(1, sizeof(*mem_info)); if (!mem_info) { ERROR_MSG("failed to allocate for memory metadata"); return FALSE; } /* get the secure ID for the framebuffers */ if (!offset) { (void)ioctl(fPtr->fb_lcd_fd, GET_UMP_SECURE_ID_BUF1, &ump_id); ERROR_MSG("GET_UMP_SECURE_ID_BUF1 returned 0x%x offset: %i virt address: %p fb_virt: %p\n", ump_id, offset, pPixData, fPtr->fbmem); } else { (void)ioctl(fPtr->fb_lcd_fd, GET_UMP_SECURE_ID_BUF2, &ump_id); ERROR_MSG("GET_UMP_SECURE_ID_BUF2 returned 0x%x offset: %i virt address: %p fb_virt: %p\n", ump_id, offset, pPixData, fPtr->fbmem); } if (UMP_INVALID_SECURE_ID == ump_id) { free(mem_info); privPixmap->mem_info = NULL; ERROR_MSG("UMP failed to retrieve secure id"); return FALSE; } mem_info->handle = ump_handle_create_from_secure_id(ump_id); if (UMP_INVALID_MEMORY_HANDLE == mem_info->handle) { ERROR_MSG("UMP failed to create handle from secure id"); free(mem_info); privPixmap->mem_info = NULL; return FALSE; } size = exaGetPixmapPitch(pPixmap) * pPixmap->drawable.height; mem_info->usize = size; privPixmap->mem_info = mem_info; if (bitsPerPixel != 0) { privPixmap->bits_per_pixel = bitsPerPixel; } /* When this is called directly from X to create the front buffer, offset is zero as expected. When this * function is called recursively to create the back buffer, offset is the offset within the fbdev to * the second buffer */ privPixmap->mem_info->offset = offset; /* Only wrap the other half if there is another half! */ if (pPixData == fPtr->fbmem) { /* This is executed only when this function is called directly from X. We need to create the * back buffer now because we can't "wrap" existing memory in a pixmap during DRI2CreateBuffer * for the back buffer of the framebuffer. In DRI2CreateBuffer instead of allocating a new * pixmap for the back buffer like we do for non-swappable windows, we'll just grab this pointer * from the screen pixmap and return it. */ PrivPixmap *other_privPixmap; offset = size; privPixmap->other_buffer = (*pScreen->CreatePixmap)(pScreen, width, height, depth, 0); /* Store a pointer to this pixmap in the one we just created. Both fbdev pixmaps are then * accessible from the screen pixmap, whichever of the fbdev pixmaps happens to be the screen * pixmap at the time */ other_privPixmap = (PrivPixmap *)exaGetPixmapDriverPrivate(privPixmap->other_buffer); other_privPixmap->other_buffer = pPixmap; offset = 0; } INFO_MSG("Creating FRAMEBUFFER pixmap %p at offset %lu, privPixmap=%p\n", pPixmap, privPixmap->mem_info->offset, privPixmap); return TRUE; } if (pPixData) { /* When this happens we're being told to wrap existing pixmap data for which we don't know the UMP * handle. We can and still need to wrap it but it won't be offscreen - we can't accelerate it in any * way. */ if (privPixmap->mem_info != NULL) { return TRUE; } return FALSE; } pPixmap->devKind = ((pPixmap->drawable.width * pPixmap->drawable.bitsPerPixel) + 7) / 8; pPixmap->devKind = MALI_ALIGN(pPixmap->devKind, 8); size = exaGetPixmapPitch(pPixmap) * pPixmap->drawable.height; /* allocate pixmap data */ mem_info = privPixmap->mem_info; if (mem_info && mem_info->usize == size) { return TRUE; } if (mem_info && mem_info->usize != 0) { ump_reference_release(mem_info->handle); mem_info->handle = NULL; memset(privPixmap, 0, sizeof(*privPixmap)); return TRUE; } if (!size) { return TRUE; } if (NULL == mem_info) { mem_info = calloc(1, sizeof(*mem_info)); if (!mem_info) { ERROR_MSG("failed to allocate memory metadata"); return FALSE; } } if (fPtr->use_cached_ump) { mem_info->handle = ump_ref_drv_allocate(size, UMP_REF_DRV_CONSTRAINT_PHYSICALLY_LINEAR | UMP_REF_DRV_CONSTRAINT_USE_CACHE); } else { mem_info->handle = ump_ref_drv_allocate(size, UMP_REF_DRV_CONSTRAINT_PHYSICALLY_LINEAR); } if (UMP_INVALID_MEMORY_HANDLE == mem_info->handle) { ERROR_MSG("failed to allocate UMP memory (%i bytes)", size); return FALSE; } mem_info->usize = size; privPixmap->mem_info = mem_info; privPixmap->mem_info->usize = size; privPixmap->bits_per_pixel = 16; return TRUE; }