static void glamor_pixmap_fbo_cache_put(glamor_screen_private *glamor_priv, glamor_pixmap_fbo *fbo) { struct xorg_list *cache; int n_format; #ifdef NO_FBO_CACHE glamor_purge_fbo(fbo); return; #else n_format = cache_format(fbo->format); if (fbo->fb == 0 || fbo->external || n_format == -1 || glamor_priv->fbo_cache_watermark >= FBO_CACHE_THRESHOLD) { glamor_priv->tick += GLAMOR_CACHE_EXPIRE_MAX; glamor_fbo_expire(glamor_priv); glamor_purge_fbo(glamor_priv, fbo); return; } cache = &glamor_priv->fbo_cache[n_format] [cache_wbucket(fbo->width)] [cache_hbucket(fbo->height)]; DEBUGF ("Put cache entry %p to cache %p w %d h %d format %x fbo %d tex %d \n", fbo, cache, fbo->width, fbo->height, fbo->format, fbo->fb, fbo->tex); glamor_priv->fbo_cache_watermark += fbo->width * fbo->height; xorg_list_add(&fbo->list, cache); fbo->expire = glamor_priv->tick + GLAMOR_CACHE_EXPIRE_MAX; #endif }
void glamor_fbo_expire(glamor_screen_private *glamor_priv) { struct xorg_list *cache; glamor_pixmap_fbo *fbo_entry, *tmp; int i, j, k; for (i = 0; i < CACHE_FORMAT_COUNT; i++) for (j = 0; j < CACHE_BUCKET_WCOUNT; j++) for (k = 0; k < CACHE_BUCKET_HCOUNT; k++) { cache = &glamor_priv->fbo_cache[i][j][k]; xorg_list_for_each_entry_safe_reverse(fbo_entry, tmp, cache, list) { if (GLAMOR_TICK_AFTER(fbo_entry->expire, glamor_priv->tick)) { break; } glamor_priv->fbo_cache_watermark -= fbo_entry->width * fbo_entry->height; xorg_list_del(&fbo_entry->list); DEBUGF("cache %p fbo %p expired %d current %d \n", cache, fbo_entry, fbo_entry->expire, glamor_priv->tick); glamor_purge_fbo(glamor_priv, fbo_entry); } } }
glamor_pixmap_fbo * glamor_create_fbo_from_tex(glamor_screen_private *glamor_priv, int w, int h, GLenum format, GLint tex, int flag) { glamor_pixmap_fbo *fbo; fbo = calloc(1, sizeof(*fbo)); if (fbo == NULL) return NULL; xorg_list_init(&fbo->list); fbo->tex = tex; fbo->width = w; fbo->height = h; fbo->external = FALSE; fbo->format = format; if (flag == CREATE_PIXMAP_USAGE_SHARED) fbo->external = TRUE; if (flag != GLAMOR_CREATE_FBO_NO_FBO) { if (glamor_pixmap_ensure_fb(glamor_priv, fbo) != 0) { glamor_purge_fbo(glamor_priv, fbo); fbo = NULL; } } return fbo; }
void glamor_fini_pixmap_fbo(ScreenPtr screen) { struct xorg_list *cache; glamor_screen_private *glamor_priv; glamor_pixmap_fbo *fbo_entry, *tmp; int i, j, k; glamor_priv = glamor_get_screen_private(screen); for (i = 0; i < CACHE_FORMAT_COUNT; i++) for (j = 0; j < CACHE_BUCKET_WCOUNT; j++) for (k = 0; k < CACHE_BUCKET_HCOUNT; k++) { cache = &glamor_priv->fbo_cache[i][j][k]; xorg_list_for_each_entry_safe_reverse(fbo_entry, tmp, cache, list) { xorg_list_del(&fbo_entry->list); glamor_purge_fbo(glamor_priv, fbo_entry); } }
_X_EXPORT void glamor_set_pixmap_private(PixmapPtr pixmap, glamor_pixmap_private *priv) { glamor_pixmap_private *old_priv; glamor_pixmap_fbo *fbo; old_priv = dixGetPrivate(&pixmap->devPrivates, &glamor_pixmap_private_key); if (priv) { assert(old_priv == NULL); } else { if (old_priv == NULL) return; fbo = glamor_pixmap_detach_fbo(old_priv); glamor_purge_fbo(fbo); free(old_priv); } dixSetPrivate(&pixmap->devPrivates, &glamor_pixmap_private_key, priv); }