/** * Inserts the given magic number into the hash table of used magic number * lists. */ static int drm_add_magic(struct drm_device *dev, struct drm_file *priv, drm_magic_t magic) { int hash; drm_magic_entry_t *entry; DRM_DEBUG("%d\n", magic); DRM_SPINLOCK_ASSERT(&dev->dev_lock); hash = drm_hash_magic(magic); entry = malloc(sizeof(*entry), DRM_MEM_MAGIC, M_ZERO | M_NOWAIT); if (!entry) return ENOMEM; entry->magic = magic; entry->priv = priv; entry->next = NULL; if (dev->magiclist[hash].tail) { dev->magiclist[hash].tail->next = entry; dev->magiclist[hash].tail = entry; } else { dev->magiclist[hash].head = entry; dev->magiclist[hash].tail = entry; } return 0; }
/** * Removes the given magic number from the hash table of used magic number * lists. */ static int drm_remove_magic(struct drm_device *dev, drm_magic_t magic) { drm_magic_entry_t *prev = NULL; drm_magic_entry_t *pt; int hash; DRM_SPINLOCK_ASSERT(&dev->dev_lock); DRM_DEBUG("%d\n", magic); hash = drm_hash_magic(magic); for (pt = dev->magiclist[hash].head; pt; prev = pt, pt = pt->next) { if (pt->magic == magic) { if (dev->magiclist[hash].head == pt) { dev->magiclist[hash].head = pt->next; } if (dev->magiclist[hash].tail == pt) { dev->magiclist[hash].tail = prev; } if (prev) { prev->next = pt->next; } free(pt, DRM_MEM_MAGIC); return 0; } } return EINVAL; }
/** * Returns the file private associated with the given magic number. */ static struct drm_file *drm_find_file(struct drm_device *dev, drm_magic_t magic) { drm_magic_entry_t *pt; int hash = drm_hash_magic(magic); DRM_SPINLOCK_ASSERT(&dev->dev_lock); for (pt = dev->magiclist[hash].head; pt; pt = pt->next) { if (pt->magic == magic) { return pt->priv; } } return NULL; }
drm_file_t *drm_find_file_by_proc(drm_device_t *dev, DRM_STRUCTPROC *p) { #if __FreeBSD_version >= 500021 uid_t uid = p->td_ucred->cr_svuid; pid_t pid = p->td_proc->p_pid; #else uid_t uid = p->p_cred->p_svuid; pid_t pid = p->p_pid; #endif drm_file_t *priv; DRM_SPINLOCK_ASSERT(&dev->dev_lock); TAILQ_FOREACH(priv, &dev->files, link) if (priv->pid == pid && priv->uid == uid) return priv; return NULL; }
/** * Emit a synchronous flip. * * This function must be called with the drawable spinlock held. */ static void i915_dispatch_vsync_flip(struct drm_device *dev, struct drm_drawable_info *drw, int plane) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; drm_i915_sarea_t *sarea_priv = dev_priv->sarea_priv; u16 x1, y1, x2, y2; int pf_planes = 1 << plane; DRM_SPINLOCK_ASSERT(&dev->drw_lock); /* If the window is visible on the other plane, we have to flip on that * plane as well. */ if (plane == 1) { x1 = sarea_priv->planeA_x; y1 = sarea_priv->planeA_y; x2 = x1 + sarea_priv->planeA_w; y2 = y1 + sarea_priv->planeA_h; } else { x1 = sarea_priv->planeB_x; y1 = sarea_priv->planeB_y; x2 = x1 + sarea_priv->planeB_w; y2 = y1 + sarea_priv->planeB_h; } if (x2 > 0 && y2 > 0) { int i, num_rects = drw->num_rects; struct drm_clip_rect *rect = drw->rects; for (i = 0; i < num_rects; i++) if (!(rect[i].x1 >= x2 || rect[i].y1 >= y2 || rect[i].x2 <= x1 || rect[i].y2 <= y1)) { pf_planes = 0x3; break; } } i915_dispatch_flip(dev, pf_planes, 1); }