/** * exaCreatePixmap() creates a new pixmap. * * If width and height are 0, this won't be a full-fledged pixmap and it will * get ModifyPixmapHeader() called on it later. So, we mark it as pinned, because * ModifyPixmapHeader() would break migration. These types of pixmaps are used * for scratch pixmaps, or to represent the visible screen. */ static PixmapPtr exaCreatePixmap(ScreenPtr pScreen, int w, int h, int depth) { PixmapPtr pPixmap; ExaPixmapPrivPtr pExaPixmap; int bpp; ExaScreenPriv(pScreen); if (w > 32767 || h > 32767) return NullPixmap; pPixmap = fbCreatePixmap (pScreen, w, h, depth); if (!pPixmap) return NULL; pExaPixmap = ExaGetPixmapPriv(pPixmap); bpp = pPixmap->drawable.bitsPerPixel; /* Glyphs have w/h equal to zero, and may not be migrated. See exaGlyphs. */ if (!w || !h) pExaPixmap->score = EXA_PIXMAP_SCORE_PINNED; else pExaPixmap->score = EXA_PIXMAP_SCORE_INIT; pExaPixmap->area = NULL; pExaPixmap->sys_ptr = pPixmap->devPrivate.ptr; pExaPixmap->sys_pitch = pPixmap->devKind; pExaPixmap->fb_ptr = NULL; if (pExaScr->info->flags & EXA_OFFSCREEN_ALIGN_POT && w != 1) pExaPixmap->fb_pitch = (1 << (exaLog2(w - 1) + 1)) * bpp / 8; else pExaPixmap->fb_pitch = w * bpp / 8; pExaPixmap->fb_pitch = EXA_ALIGN(pExaPixmap->fb_pitch, pExaScr->info->pixmapPitchAlign); pExaPixmap->fb_size = pExaPixmap->fb_pitch * h; if (pExaPixmap->fb_pitch > 131071) { fbDestroyPixmap(pPixmap); return NULL; } /* Set up damage tracking */ pExaPixmap->pDamage = DamageCreate (NULL, NULL, DamageReportNone, TRUE, pScreen, pPixmap); if (pExaPixmap->pDamage == NULL) { fbDestroyPixmap (pPixmap); return NULL; } DamageRegister (&pPixmap->drawable, pExaPixmap->pDamage); DamageSetReportAfterOp (pExaPixmap->pDamage, TRUE); /* None of the pixmap bits are valid initially */ REGION_NULL(pScreen, &pExaPixmap->validReg); return pPixmap; }
static Bool radeon_glamor_destroy_pixmap(PixmapPtr pixmap) { if (pixmap->refcnt == 1) { glamor_egl_destroy_textured_pixmap(pixmap); radeon_set_pixmap_bo(pixmap, NULL); } fbDestroyPixmap(pixmap); return TRUE; }
int call_fbDestroyPixmap(int *pDatabuf) { str_fbDestroyPixmap *function; function = (str_fbDestroyPixmap *)pDatabuf; fbDestroyPixmap(function->Pixmap); return 0; }
Bool glamor_destroy_pixmap(PixmapPtr pixmap) { glamor_screen_private *glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen); if (glamor_priv->dri3_enabled) glamor_egl_destroy_textured_pixmap(pixmap); else glamor_destroy_textured_pixmap(pixmap); return fbDestroyPixmap(pixmap); }
static PixmapPtr intel_dri3_pixmap_from_fd(ScreenPtr screen, int fd, CARD16 width, CARD16 height, CARD16 stride, CARD8 depth, CARD8 bpp) { ScrnInfoPtr scrn = xf86ScreenToScrn(screen); intel_screen_private *intel = intel_get_screen_private(scrn); struct intel_uxa_pixmap *priv; PixmapPtr pixmap; dri_bo *bo; if (depth < 8) return NULL; switch (bpp) { case 8: case 16: case 32: break; default: return NULL; } pixmap = fbCreatePixmap(screen, 0, 0, depth, 0); if (!pixmap) return NULL; if (!screen->ModifyPixmapHeader(pixmap, width, height, 0, 0, stride, NULL)) goto free_pixmap; bo = drm_intel_bo_gem_create_from_prime(intel->bufmgr, fd, (uint32_t)height * stride); if (bo == NULL) goto free_pixmap; intel_uxa_set_pixmap_bo(pixmap, bo); dri_bo_unreference(bo); priv = intel_uxa_get_pixmap_private(pixmap); if (priv == NULL) goto free_pixmap; priv->pinned |= PIN_DRI3; return pixmap; free_pixmap: fbDestroyPixmap(pixmap); return NULL; }
static Bool radeon_glamor_destroy_pixmap(PixmapPtr pixmap) { if (pixmap->refcnt == 1) { if (pixmap->devPrivate.ptr) { struct radeon_bo *bo = radeon_get_pixmap_bo(pixmap); if (bo) radeon_bo_unmap(bo); } glamor_egl_destroy_textured_pixmap(pixmap); radeon_set_pixmap_bo(pixmap, NULL); } fbDestroyPixmap(pixmap); return TRUE; }
static Bool gma_uxa_destroy_pixmap(PixmapPtr pixmap) { gma500Ptr gma = gma_from_pixmap(pixmap); struct gma_bo *bo; /* Only remove bo if we're the last user */ if (pixmap->refcnt == 1) { bo = gma_get_surface(pixmap); if (bo) { gma_set_surface(pixmap, NULL); gma_bo_destroy(gma->fd, bo); } } fbDestroyPixmap(pixmap); return TRUE; }
static Bool kaaDestroyPixmap (PixmapPtr pPixmap) { if (pPixmap->refcnt == 1) { KaaPixmapPriv (pPixmap); if (pKaaPixmap->area) { DBG_PIXMAP(("-- 0x%08x (0x%x) (%dx%d)\n", pPixmap->drawable.id, KaaGetPixmapPriv(pPixmap)->area->offset, pPixmap->drawable.width, pPixmap->drawable.height)); /* Free the offscreen area */ KdOffscreenFree (pPixmap->drawable.pScreen, pKaaPixmap->area); pPixmap->devPrivate = pKaaPixmap->devPrivate; pPixmap->devKind = pKaaPixmap->devKind; } } return fbDestroyPixmap (pPixmap); }
static Bool exaDestroyPixmap (PixmapPtr pPixmap) { if (pPixmap->refcnt == 1) { ExaPixmapPriv (pPixmap); if (pExaPixmap->area) { DBG_PIXMAP(("-- 0x%p (0x%x) (%dx%d)\n", (void*)pPixmap->drawable.id, ExaGetPixmapPriv(pPixmap)->area->offset, pPixmap->drawable.width, pPixmap->drawable.height)); /* Free the offscreen area */ exaOffscreenFree (pPixmap->drawable.pScreen, pExaPixmap->area); pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr; pPixmap->devKind = pExaPixmap->sys_pitch; } REGION_UNINIT(pPixmap->drawable.pScreen, &pExaPixmap->validReg); } return fbDestroyPixmap (pPixmap); }
PixmapPtr glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth, unsigned int usage) { PixmapPtr pixmap; glamor_pixmap_type_t type = GLAMOR_TEXTURE_ONLY; glamor_pixmap_private *pixmap_priv; glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); glamor_pixmap_fbo *fbo = NULL; int pitch; GLenum format; if (w > 32767 || h > 32767) return NullPixmap; if ((usage == GLAMOR_CREATE_PIXMAP_CPU || (usage == CREATE_PIXMAP_USAGE_GLYPH_PICTURE && w <= 64 && h <= 64) || (w == 0 && h == 0) || !glamor_check_pixmap_fbo_depth(depth)) || (!GLAMOR_TEXTURED_LARGE_PIXMAP && !glamor_check_fbo_size(glamor_priv, w, h))) return fbCreatePixmap(screen, w, h, depth, usage); else pixmap = fbCreatePixmap(screen, 0, 0, depth, usage); pixmap_priv = calloc(1, sizeof(*pixmap_priv)); if (!pixmap_priv) { fbDestroyPixmap(pixmap); return fbCreatePixmap(screen, w, h, depth, usage); } glamor_set_pixmap_private(pixmap, pixmap_priv); if (usage == GLAMOR_CREATE_PIXMAP_MAP) type = GLAMOR_MEMORY_MAP; pixmap_priv->base.pixmap = pixmap; pixmap_priv->base.glamor_priv = glamor_priv; format = gl_iformat_for_pixmap(pixmap); pitch = (((w * pixmap->drawable.bitsPerPixel + 7) / 8) + 3) & ~3; screen->ModifyPixmapHeader(pixmap, w, h, 0, 0, pitch, NULL); if (usage == GLAMOR_CREATE_PIXMAP_NO_TEXTURE) { pixmap_priv->type = GLAMOR_TEXTURE_ONLY; pixmap_priv->base.box.x1 = 0; pixmap_priv->base.box.y1 = 0; pixmap_priv->base.box.x2 = w; pixmap_priv->base.box.y2 = h; return pixmap; } else if (type == GLAMOR_MEMORY_MAP || usage == GLAMOR_CREATE_NO_LARGE || glamor_check_fbo_size(glamor_priv, w, h)) { pixmap_priv->type = type; pixmap_priv->base.box.x1 = 0; pixmap_priv->base.box.y1 = 0; pixmap_priv->base.box.x2 = w; pixmap_priv->base.box.y2 = h; fbo = glamor_create_fbo(glamor_priv, w, h, format, usage); } else { int tile_size = glamor_priv->max_fbo_size; DEBUGF("Create LARGE pixmap %p width %d height %d, tile size %d\n", pixmap, w, h, tile_size); pixmap_priv->type = GLAMOR_TEXTURE_LARGE; fbo = glamor_create_fbo_array(glamor_priv, w, h, format, usage, tile_size, tile_size, pixmap_priv); } if (fbo == NULL) { fbDestroyPixmap(pixmap); free(pixmap_priv); return fbCreatePixmap(screen, w, h, depth, usage); } glamor_pixmap_attach_fbo(pixmap, fbo); return pixmap; }
Bool glamor_destroy_pixmap(PixmapPtr pixmap) { glamor_destroy_textured_pixmap(pixmap); return fbDestroyPixmap(pixmap); }
static PixmapPtr radeon_glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth, unsigned usage) { ScrnInfoPtr scrn = xf86ScreenToScrn(screen); RADEONInfoPtr info = RADEONPTR(scrn); struct radeon_pixmap *priv; PixmapPtr pixmap, new_pixmap = NULL; if (!RADEON_CREATE_PIXMAP_SHARED(usage)) { if (info->shadow_primary) { if (usage != CREATE_PIXMAP_USAGE_BACKING_PIXMAP) return fbCreatePixmap(screen, w, h, depth, usage); } else { pixmap = glamor_create_pixmap(screen, w, h, depth, usage); if (pixmap) return pixmap; } } if (w > 32767 || h > 32767) return NullPixmap; if (depth == 1) return fbCreatePixmap(screen, w, h, depth, usage); if (usage == CREATE_PIXMAP_USAGE_GLYPH_PICTURE && w <= 32 && h <= 32) return fbCreatePixmap(screen, w, h, depth, usage); pixmap = fbCreatePixmap(screen, 0, 0, depth, usage); if (pixmap == NullPixmap) return pixmap; if (w && h) { int stride; priv = calloc(1, sizeof (struct radeon_pixmap)); if (priv == NULL) goto fallback_pixmap; priv->bo = radeon_alloc_pixmap_bo(scrn, w, h, depth, usage, pixmap->drawable.bitsPerPixel, &stride, &priv->surface, &priv->tiling_flags); if (!priv->bo) goto fallback_priv; radeon_set_pixmap_private(pixmap, priv); screen->ModifyPixmapHeader(pixmap, w, h, 0, 0, stride, NULL); if (!radeon_glamor_create_textured_pixmap(pixmap, priv)) goto fallback_glamor; pixmap->devPrivate.ptr = NULL; } return pixmap; fallback_glamor: if (RADEON_CREATE_PIXMAP_SHARED(usage)) { /* XXX need further work to handle the DRI2 failure case. * Glamor don't know how to handle a BO only pixmap. Put * a warning indicator here. */ xf86DrvMsg(scrn->scrnIndex, X_WARNING, "Failed to create textured DRI2/PRIME pixmap."); return pixmap; } /* Create textured pixmap failed means glamor failed to * create a texture from current BO for some reasons. We turn * to create a new glamor pixmap and clean up current one. * One thing need to be noted, this new pixmap doesn't * has a priv and bo attached to it. It's glamor's responsbility * to take care of it. Glamor will mark this new pixmap as a * texture only pixmap and will never fallback to DDX layer * afterwards. */ new_pixmap = glamor_create_pixmap(screen, w, h, depth, usage); radeon_bo_unref(priv->bo); fallback_priv: free(priv); fallback_pixmap: fbDestroyPixmap(pixmap); if (new_pixmap) return new_pixmap; else return fbCreatePixmap(screen, w, h, depth, usage); }
/** * Implements CopyPlane and CopyArea from the GPU to the GPU by using * the source as a texture and painting that into the destination. * * This requires that source and dest are different textures, or that * (if the copy area doesn't overlap), GL_NV_texture_barrier is used * to ensure that the caches are flushed at the right times. */ static Bool glamor_copy_cpu_fbo(DrawablePtr src, DrawablePtr dst, GCPtr gc, BoxPtr box, int nbox, int dx, int dy, Bool reverse, Bool upsidedown, Pixel bitplane, void *closure) { ScreenPtr screen = dst->pScreen; glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst); FbBits *src_bits; FbStride src_stride; int src_bpp; int src_xoff, src_yoff; int dst_xoff, dst_yoff; if (gc && gc->alu != GXcopy) goto bail; if (gc && !glamor_pm_is_solid(gc->depth, gc->planemask)) goto bail; glamor_make_current(glamor_priv); glamor_prepare_access(src, GLAMOR_ACCESS_RO); glamor_get_drawable_deltas(dst, dst_pixmap, &dst_xoff, &dst_yoff); if (bitplane) { PixmapPtr src_pix = fbCreatePixmap(screen, dst_pixmap->drawable.width, dst_pixmap->drawable.height, dst->depth, 0); if (!src_pix) { glamor_finish_access(src); goto bail; } src_pix->drawable.x = -dst->x; src_pix->drawable.y = -dst->y; fbGetDrawable(&src_pix->drawable, src_bits, src_stride, src_bpp, src_xoff, src_yoff); if (src->bitsPerPixel > 1) fbCopyNto1(src, &src_pix->drawable, gc, box, nbox, dx, dy, reverse, upsidedown, bitplane, closure); else fbCopy1toN(src, &src_pix->drawable, gc, box, nbox, dx, dy, reverse, upsidedown, bitplane, closure); glamor_upload_boxes(dst_pixmap, box, nbox, src_xoff, src_yoff, dst_xoff, dst_yoff, (uint8_t *) src_bits, src_stride * sizeof(FbBits)); fbDestroyPixmap(src_pix); } else { fbGetDrawable(src, src_bits, src_stride, src_bpp, src_xoff, src_yoff); glamor_upload_boxes(dst_pixmap, box, nbox, src_xoff + dx, src_yoff + dy, dst_xoff, dst_yoff, (uint8_t *) src_bits, src_stride * sizeof (FbBits)); } glamor_finish_access(src); return TRUE; bail: return FALSE; }