Skip to content

Commit

Permalink
drm/virtgio: Send flip event based on backend setting
Browse files Browse the repository at this point in the history
Cache out fences in atomic commit and signal them when the backend asks
to. The backend is supposed to send to frontend the number of fences to
signal when the backend presents a frame to users. Only in this way we
can preserve the semantics of present fence.

Tracked-On: OAM-128370
Signed-off-by: hangliu1 <[email protected]>
Signed-off-by: Weifeng Liu <[email protected]>
  • Loading branch information
phreer committed Dec 10, 2024
1 parent e4c7a16 commit 86d17c8
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 9 deletions.
35 changes: 27 additions & 8 deletions drivers/gpu/drm/virtio/virtgpu_display.c
Original file line number Diff line number Diff line change
Expand Up @@ -161,18 +161,37 @@ static void virtio_gpu_crtc_atomic_flush(struct drm_crtc *crtc,
struct virtio_gpu_output *output = drm_crtc_to_virtio_gpu_output(crtc);
struct drm_device *drm = crtc->dev;
struct virtio_gpu_device *vgdev = drm->dev_private;
int i;

if(vgdev->has_vblank) {
if (crtc->state->event) {
spin_lock_irq(&drm->event_lock);
if (drm_crtc_vblank_get(crtc) != 0)
drm_crtc_send_vblank_event(crtc, crtc->state->event);
else
drm_crtc_arm_vblank_event(crtc, crtc->state->event);
spin_unlock_irq(&drm->event_lock);
if (vgdev->has_vblank && crtc->state->event) {
spin_lock_irq(&drm->event_lock);
if (drm_crtc_vblank_get(crtc) != 0) {
// Cannot enable vblank, send it right now.
drm_crtc_send_vblank_event(crtc, crtc->state->event);
crtc->state->event = NULL;
} else {
for (i = 0; i < VBLANK_EVENT_CACHE_SIZE; i++) {
if (vgdev->cache_event[i] == NULL) {
break;
}
}
if (i == VBLANK_EVENT_CACHE_SIZE) {
// Cache is full, empty it cache or the system
// gets huang.
for (i = 0; i < VBLANK_EVENT_CACHE_SIZE; i++) {
if (vgdev->cache_event[i] != NULL) {
drm_crtc_send_vblank_event(crtc, vgdev->cache_event[i]);
vgdev->cache_event[i] = NULL;
}
}
i = 0;
}
vgdev->cache_event[i] = crtc->state->event;
crtc->state->event = NULL;
}
spin_unlock_irq(&drm->event_lock);
}

if(vgdev->has_multi_plane)
virtio_gpu_resource_flush_sync(crtc);

Expand Down
4 changes: 4 additions & 0 deletions drivers/gpu/drm/virtio/virtgpu_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,9 @@ struct virtio_gpu_vbuffer {
#define VIRTIO_GPU_MAX_PLANES 6
/*hardcode igpu scaler number ver>11 */
#define SKL_NUM_SCALERS 2

#define VBLANK_EVENT_CACHE_SIZE 3

struct virtio_gpu_output {
int index;
struct drm_crtc crtc;
Expand Down Expand Up @@ -238,6 +241,7 @@ struct virtio_gpu_device {
struct virtio_device *vdev;

struct virtio_gpu_output outputs[VIRTIO_GPU_MAX_SCANOUTS];
struct drm_pending_vblank_event *cache_event[VBLANK_EVENT_CACHE_SIZE];
uint32_t num_scanouts;
uint32_t num_vblankq;
struct virtio_gpu_queue ctrlq;
Expand Down
18 changes: 17 additions & 1 deletion drivers/gpu/drm/virtio/virtgpu_vq.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ void virtio_gpu_vblank_ack(struct virtqueue *vq)
unsigned long irqflags;
unsigned int len;
unsigned int *ret_value;
int target = 0;
int target = 0, i, curr = 0;

while((target < vgdev->num_vblankq) && (vgdev->vblank[target].vblank.vq != vq)) {
target++;
Expand All @@ -115,6 +115,22 @@ void virtio_gpu_vblank_ack(struct virtqueue *vq)
spin_unlock_irqrestore(&vgdev->vblank[target].vblank.qlock, irqflags);
drm_handle_vblank(dev, target);

spin_lock_irqsave(&dev->event_lock, irqflags);
for (i = 0; i < VBLANK_EVENT_CACHE_SIZE; i++) {
if (vgdev->cache_event[i]) {
if (i < *ret_value) {
drm_crtc_send_vblank_event(&vgdev->outputs[target].crtc,
vgdev->cache_event[i]);
vgdev->cache_event[i] = NULL;
}
}
}

for (i = 0; i < VBLANK_EVENT_CACHE_SIZE; ++i)
if (vgdev->cache_event[i])
vgdev->cache_event[curr++] = vgdev->cache_event[i];

spin_unlock_irqrestore(&dev->event_lock, irqflags);
}

void virtio_gpu_cursor_ack(struct virtqueue *vq)
Expand Down

0 comments on commit 86d17c8

Please sign in to comment.