diff options
author | Michel Dänzer <michel.daenzer@amd.com> | 2016-09-08 17:56:24 +0900 |
---|---|---|
committer | Michel Dänzer <michel@daenzer.net> | 2016-09-09 19:03:24 +0900 |
commit | d6feed2cd78fe879aba4860a6d9bc2e388b9f135 (patch) | |
tree | fe367e513aee7bf2b5126523bd94371afed7b80a /src/drmmode_display.c | |
parent | 4927b84ec84bc0cb5055686cca6be54390f82803 (diff) |
Synchronize scanout pixmaps for TearFree
Copy the damaged areas which are still valid in the other scanout pixmap
from there, then only copy the remaining damaged area from the screen
pixmap.
This is slightly more efficient (only needs one Damage record instead of
two, and only needs to copy each screen update across PCIe once with
ShadowPrimary and a discrete GPU), and will be significantly more
efficient for PRIME with the following change.
(Ported from radeon commit eda1f3df6aaed683036369fe8820da4dac3c2ae2)
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'src/drmmode_display.c')
-rw-r--r-- | src/drmmode_display.c | 80 |
1 files changed, 39 insertions, 41 deletions
diff --git a/src/drmmode_display.c b/src/drmmode_display.c index a8ee5f0..1e4622d 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -462,10 +462,20 @@ drmmode_crtc_scanout_destroy(drmmode_ptr drmmode, amdgpu_bo_unref(&scanout->bo); scanout->bo = NULL; } +} + +static void +drmmode_crtc_scanout_free(drmmode_crtc_private_ptr drmmode_crtc) +{ + drmmode_crtc_scanout_destroy(drmmode_crtc->drmmode, + &drmmode_crtc->scanout[0]); + drmmode_crtc_scanout_destroy(drmmode_crtc->drmmode, + &drmmode_crtc->scanout[1]); - if (scanout->damage) { - DamageDestroy(scanout->damage); - scanout->damage = NULL; + if (drmmode_crtc->scanout_damage) { + DamageDestroy(drmmode_crtc->scanout_damage); + drmmode_crtc->scanout_damage = NULL; + RegionUninit(&drmmode_crtc->scanout_last_region); } } @@ -475,15 +485,8 @@ drmmode_scanout_free(ScrnInfoPtr scrn) xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); int c; - for (c = 0; c < xf86_config->num_crtc; c++) { - drmmode_crtc_private_ptr drmmode_crtc = - xf86_config->crtc[c]->driver_private; - - drmmode_crtc_scanout_destroy(drmmode_crtc->drmmode, - &drmmode_crtc->scanout[0]); - drmmode_crtc_scanout_destroy(drmmode_crtc->drmmode, - &drmmode_crtc->scanout[1]); - } + for (c = 0; c < xf86_config->num_crtc; c++) + drmmode_crtc_scanout_free(xf86_config->crtc[c]->driver_private); } static void * @@ -726,33 +729,31 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, &drmmode_crtc->scanout[i], mode->HDisplay, mode->VDisplay); - - if (drmmode_crtc->scanout[i].pixmap) { - RegionPtr pRegion; - BoxPtr pBox; - - if (!drmmode_crtc->scanout[i].damage) { - drmmode_crtc->scanout[i].damage = - DamageCreate(amdgpu_screen_damage_report, - NULL, DamageReportRawRegion, - TRUE, pScreen, NULL); - DamageRegister(&pScreen->GetScreenPixmap(pScreen)->drawable, - drmmode_crtc->scanout[i].damage); - } - - pRegion = DamageRegion(drmmode_crtc->scanout[i].damage); - RegionUninit(pRegion); - pRegion->data = NULL; - pBox = RegionExtents(pRegion); - pBox->x1 = 0; - pBox->y1 = 0; - pBox->x2 = max(pBox->x2, pScrn->virtualX); - pBox->y2 = max(pBox->y2, pScrn->virtualY); - } } if (drmmode_crtc->scanout[0].pixmap && (!info->tear_free || drmmode_crtc->scanout[1].pixmap)) { + RegionPtr pRegion; + BoxPtr pBox; + + if (!drmmode_crtc->scanout_damage) { + drmmode_crtc->scanout_damage = + DamageCreate(amdgpu_screen_damage_report, + NULL, DamageReportRawRegion, + TRUE, pScreen, NULL); + DamageRegister(&pScreen->GetScreenPixmap(pScreen)->drawable, + drmmode_crtc->scanout_damage); + } + + pRegion = DamageRegion(drmmode_crtc->scanout_damage); + RegionUninit(pRegion); + pRegion->data = NULL; + pBox = RegionExtents(pRegion); + pBox->x1 = 0; + pBox->y1 = 0; + pBox->x2 = max(pBox->x2, pScrn->virtualX); + pBox->y2 = max(pBox->y2, pScrn->virtualY); + drmmode_crtc->scanout_id = 0; fb_id = drmmode_crtc->scanout[0].fb_id; x = y = 0; @@ -840,10 +841,8 @@ done: } else { crtc->active = TRUE; - if (fb_id != drmmode_crtc->scanout[0].fb_id) { - drmmode_crtc_scanout_destroy(drmmode, &drmmode_crtc->scanout[0]); - drmmode_crtc_scanout_destroy(drmmode, &drmmode_crtc->scanout[1]); - } + if (fb_id != drmmode_crtc->scanout[0].fb_id) + drmmode_crtc_scanout_free(drmmode_crtc); } return ret; @@ -1068,8 +1067,7 @@ static Bool drmmode_set_scanout_pixmap(xf86CrtcPtr crtc, PixmapPtr ppix) if (crtc->randr_crtc->scanout_pixmap) PixmapStopDirtyTracking(crtc->randr_crtc->scanout_pixmap, drmmode_crtc->scanout[0].pixmap); - drmmode_crtc_scanout_destroy(drmmode_crtc->drmmode, - &drmmode_crtc->scanout[0]); + drmmode_crtc_scanout_free(drmmode_crtc); return TRUE; } |