98
98
if (!pExaPixmap->driverPriv)
99
99
exaCreateDriverPixmap_mixed(pPixmap);
101
if (pExaPixmap->pDamage && exaPixmapIsOffscreen(pPixmap)) {
101
if (pExaPixmap->pDamage && exaPixmapHasGpuCopy(pPixmap)) {
102
ExaScreenPriv(pPixmap->drawable.pScreen);
104
/* This pitch is needed for proper acceleration. For some reason
105
* there are pixmaps without pDamage and a bad fb_pitch value.
106
* So setting devKind when only exaPixmapHasGpuCopy() is true
107
* causes corruption. Pixmaps without pDamage are not migrated
108
* and should have a valid devKind at all times, so that's why this
109
* isn't causing problems. Pixmaps have their gpu pitch set the
110
* first time in the MPH call from exaCreateDriverPixmap_mixed().
102
112
pPixmap->devKind = pExaPixmap->fb_pitch;
103
113
exaCopyDirtyToFb(pixmaps + i);
115
if (pExaScr->deferred_mixed_pixmap == pPixmap &&
116
!pixmaps[i].as_dst && !pixmaps[i].pReg)
117
pExaScr->deferred_mixed_pixmap = NULL;
106
pExaPixmap->offscreen = exaPixmapIsOffscreen(pPixmap);
120
pExaPixmap->use_gpu_copy = exaPixmapHasGpuCopy(pPixmap);
120
134
exaDoMigration(pixmaps, 1, TRUE);
138
exaDamageReport_mixed(DamagePtr pDamage, RegionPtr pRegion, void *closure)
140
PixmapPtr pPixmap = closure;
141
ExaPixmapPriv(pPixmap);
143
/* Move back results of software rendering on system memory copy of mixed driver
144
* pixmap (see exaPrepareAccessReg_mixed).
146
* Defer moving the destination back into the driver pixmap, to try and save
147
* overhead on multiple subsequent software fallbacks.
149
if (!pExaPixmap->use_gpu_copy && exaPixmapHasGpuCopy(pPixmap)) {
150
ExaScreenPriv(pPixmap->drawable.pScreen);
152
if (pExaScr->deferred_mixed_pixmap &&
153
pExaScr->deferred_mixed_pixmap != pPixmap)
154
exaMoveInPixmap_mixed(pExaScr->deferred_mixed_pixmap);
155
pExaScr->deferred_mixed_pixmap = pPixmap;
123
159
/* With mixed pixmaps, if we fail to get direct access to the driver pixmap, we
124
160
* use the DownloadFromScreen hook to retrieve contents to a copy in system
125
161
* memory, perform software rendering on that and move back the results with the
126
* UploadToScreen hook (see exaFinishAccess_mixed).
162
* UploadToScreen hook (see exaDamageReport_mixed).
129
165
exaPrepareAccessReg_mixed(PixmapPtr pPixmap, int index, RegionPtr pReg)
131
if (!ExaDoPrepareAccess(pPixmap, index)) {
132
ExaPixmapPriv(pPixmap);
133
Bool is_offscreen = exaPixmapIsOffscreen(pPixmap);
167
ExaPixmapPriv(pPixmap);
168
Bool has_gpu_copy = exaPixmapHasGpuCopy(pPixmap);
171
success = ExaDoPrepareAccess(pPixmap, index);
173
if (success && has_gpu_copy && pExaPixmap->pDamage) {
174
/* You cannot do accelerated operations while a buffer is mapped. */
175
exaFinishAccess(&pPixmap->drawable, index);
176
/* Update the gpu view of both deferred destination pixmaps and of
177
* source pixmaps that were migrated with a bounding region.
179
exaMoveInPixmap_mixed(pPixmap);
180
success = ExaDoPrepareAccess(pPixmap, index);
183
/* We have a gpu pixmap that can be accessed, we don't need the cpu
184
* copy anymore. Drivers that prefer DFS, should fail prepare
187
DamageUnregister(&pPixmap->drawable, pExaPixmap->pDamage);
188
DamageDestroy(pExaPixmap->pDamage);
189
pExaPixmap->pDamage = NULL;
191
free(pExaPixmap->sys_ptr);
192
pExaPixmap->sys_ptr = NULL;
134
199
ExaMigrationRec pixmaps[1];
136
201
/* Do we need to allocate our system buffer? */
152
217
pixmaps[0].pPix = pPixmap;
153
218
pixmaps[0].pReg = pReg;
155
if (!pExaPixmap->pDamage && (is_offscreen || !exaPixmapIsPinned(pPixmap))) {
220
if (!pExaPixmap->pDamage &&
221
(has_gpu_copy || !exaPixmapIsPinned(pPixmap))) {
156
222
Bool as_dst = pixmaps[0].as_dst;
158
224
/* Set up damage tracking */
159
pExaPixmap->pDamage = DamageCreate(NULL, NULL, DamageReportNone,
160
TRUE, pPixmap->drawable.pScreen,
225
pExaPixmap->pDamage = DamageCreate(exaDamageReport_mixed, NULL,
226
DamageReportNonEmpty, TRUE,
227
pPixmap->drawable.pScreen,
163
230
DamageRegister(&pPixmap->drawable, pExaPixmap->pDamage);
177
244
pixmaps[0].as_src = TRUE;
178
245
pixmaps[0].pReg = NULL;
180
pPixmap->devKind = pExaPixmap->fb_pitch;
181
247
exaCopyDirtyToSys(pixmaps);
185
251
exaPixmapDirty(pPixmap, 0, 0, pPixmap->drawable.width,
186
252
pPixmap->drawable.height);
187
} else if (is_offscreen) {
188
pPixmap->devKind = pExaPixmap->fb_pitch;
253
} else if (has_gpu_copy)
189
254
exaCopyDirtyToSys(pixmaps);
192
256
pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr;
193
257
pPixmap->devKind = pExaPixmap->sys_pitch;
194
pExaPixmap->offscreen = FALSE;
198
/* Move back results of software rendering on system memory copy of mixed driver
199
* pixmap (see exaPrepareAccessReg_mixed).
201
void exaFinishAccess_mixed(PixmapPtr pPixmap, int index)
203
ExaPixmapPriv(pPixmap);
205
if (pExaPixmap->pDamage && exaPixmapIsOffscreen(pPixmap) &&
206
!pExaPixmap->offscreen) {
207
DamageRegionProcessPending(&pPixmap->drawable);
208
exaMoveInPixmap_mixed(pPixmap);
258
pExaPixmap->use_gpu_copy = FALSE;