static Bool ExaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, int depth, int bitsPerPixel, int devKind, pointer pPixData) { ScreenPtr pScreen = pPixmap->drawable.pScreen; ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap); modesettingPtr ms = modesettingPTR(pScrn); struct exa_context *exa = ms->exa; if (!priv || pPixData) return FALSE; if (0) { debug_printf("%s pixmap %p sz %dx%dx%d devKind %d\n", __FUNCTION__, pPixmap, width, height, bitsPerPixel, devKind); if (priv->tex) debug_printf(" ==> old texture %dx%d\n", priv->tex->width0, priv->tex->height0); } if (depth <= 0) depth = pPixmap->drawable.depth; if (bitsPerPixel <= 0) bitsPerPixel = pPixmap->drawable.bitsPerPixel; if (width <= 0) width = pPixmap->drawable.width; if (height <= 0) height = pPixmap->drawable.height; if (width <= 0 || height <= 0 || depth <= 0) return FALSE; miModifyPixmapHeader(pPixmap, width, height, depth, bitsPerPixel, devKind, NULL); priv->width = width; priv->height = height; /* Deal with screen resize */ if ((exa->accel || priv->flags) && (!priv->tex || !size_match(width, priv->tex->width0) || !size_match(height, priv->tex->height0) || priv->tex_flags != priv->flags)) { struct pipe_resource *texture = NULL; struct pipe_resource template; memset(&template, 0, sizeof(template));
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 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; }