summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/amdgpu_kms.c83
1 files changed, 70 insertions, 13 deletions
diff --git a/src/amdgpu_kms.c b/src/amdgpu_kms.c
index 0342ef8..5e3d322 100644
--- a/src/amdgpu_kms.c
+++ b/src/amdgpu_kms.c
@@ -363,6 +363,9 @@ redisplay_dirty(PixmapDirtyUpdatePtr dirty, RegionPtr region)
{
ScrnInfoPtr scrn = xf86ScreenToScrn(dirty->src->drawable.pScreen);
+ if (RegionNil(region))
+ goto out;
+
if (dirty->slave_dst->master_pixmap)
DamageRegionAppend(&dirty->slave_dst->drawable, region);
@@ -376,6 +379,7 @@ redisplay_dirty(PixmapDirtyUpdatePtr dirty, RegionPtr region)
if (dirty->slave_dst->master_pixmap)
DamageRegionProcessPending(&dirty->slave_dst->drawable);
+out:
DamageEmpty(dirty->damage);
}
@@ -388,6 +392,39 @@ amdgpu_prime_scanout_update_abort(xf86CrtcPtr crtc, void *event_data)
}
void
+amdgpu_sync_shared_pixmap(PixmapDirtyUpdatePtr dirty)
+{
+ ScreenPtr master_screen = dirty->src->master_pixmap->drawable.pScreen;
+ PixmapDirtyUpdatePtr ent;
+ RegionPtr region;
+
+ xorg_list_for_each_entry(ent, &master_screen->pixmap_dirty_list, ent) {
+ if (ent->slave_dst != dirty->src)
+ continue;
+
+ region = dirty_region(ent);
+ redisplay_dirty(ent, region);
+ RegionDestroy(region);
+ }
+}
+
+static Bool
+master_has_sync_shared_pixmap(ScrnInfoPtr scrn, PixmapDirtyUpdatePtr dirty)
+{
+ ScrnInfoPtr master_scrn = xf86ScreenToScrn(dirty->src->master_pixmap->drawable.pScreen);
+
+ return master_scrn->driverName == scrn->driverName;
+}
+
+static Bool
+slave_has_sync_shared_pixmap(ScrnInfoPtr scrn, PixmapDirtyUpdatePtr dirty)
+{
+ ScrnInfoPtr slave_scrn = xf86ScreenToScrn(dirty->slave_dst->drawable.pScreen);
+
+ return slave_scrn->driverName == scrn->driverName;
+}
+
+void
amdgpu_prime_scanout_update_handler(xf86CrtcPtr crtc, uint32_t frame, uint64_t usec,
void *event_data)
{
@@ -400,8 +437,12 @@ amdgpu_prime_scanout_update_handler(xf86CrtcPtr crtc, uint32_t frame, uint64_t u
xorg_list_for_each_entry(dirty, &screen->pixmap_dirty_list, ent) {
if (dirty->src == scanoutpix &&
dirty->slave_dst == drmmode_crtc->scanout[0].pixmap) {
- RegionPtr region = dirty_region(dirty);
+ RegionPtr region;
+
+ if (master_has_sync_shared_pixmap(scrn, dirty))
+ amdgpu_sync_shared_pixmap(dirty);
+ region = dirty_region(dirty);
redisplay_dirty(dirty, region);
RegionDestroy(region);
break;
@@ -465,26 +506,42 @@ amdgpu_prime_scanout_update(PixmapDirtyUpdatePtr dirty)
drmmode_crtc->scanout_update_pending = TRUE;
}
-static void amdgpu_dirty_update(ScreenPtr screen)
+static void
+amdgpu_dirty_update(ScrnInfoPtr scrn)
{
+ ScreenPtr screen = scrn->pScreen;
PixmapDirtyUpdatePtr ent;
-
- if (xorg_list_is_empty(&screen->pixmap_dirty_list))
- return;
+ RegionPtr region;
xorg_list_for_each_entry(ent, &screen->pixmap_dirty_list, ent) {
- RegionPtr region = dirty_region(ent);
+ if (screen->isGPU) {
+ PixmapDirtyUpdatePtr region_ent = ent;
+
+ if (master_has_sync_shared_pixmap(scrn, ent)) {
+ ScreenPtr master_screen = ent->src->master_pixmap->drawable.pScreen;
- if (RegionNotEmpty(region)) {
- if (screen->isGPU)
+ xorg_list_for_each_entry(region_ent, &master_screen->pixmap_dirty_list, ent) {
+ if (region_ent->slave_dst == ent->src)
+ break;
+ }
+ }
+
+ region = dirty_region(region_ent);
+
+ if (RegionNotEmpty(region))
amdgpu_prime_scanout_update(ent);
else
- redisplay_dirty(ent, region);
+ DamageEmpty(region_ent->damage);
+
+ RegionDestroy(region);
} else {
- DamageEmpty(ent->damage);
- }
+ if (slave_has_sync_shared_pixmap(scrn, ent))
+ continue;
- RegionDestroy(region);
+ region = dirty_region(ent);
+ redisplay_dirty(ent, region);
+ RegionDestroy(region);
+ }
}
}
#endif
@@ -766,7 +823,7 @@ static void AMDGPUBlockHandler_KMS(BLOCKHANDLER_ARGS_DECL)
amdgpu_glamor_flush(pScrn);
#ifdef AMDGPU_PIXMAP_SHARING
- amdgpu_dirty_update(pScreen);
+ amdgpu_dirty_update(pScrn);
#endif
}