~darkxst/ubuntu/raring/xorg-server/lp1073724

« back to all changes in this revision

Viewing changes to exa/exa_migration_mixed.c

  • Committer: Bazaar Package Importer
  • Author(s): Bryce Harrington
  • Date: 2010-06-07 14:50:49 UTC
  • mfrom: (0.9.4 upstream)
  • mto: This revision was merged to the branch mainline in revision 187.
  • Revision ID: james.westby@ubuntu.com-20100607145049-eys326hqtq5mjqxt
Tags: upstream-1.8.1.901
ImportĀ upstreamĀ versionĀ 1.8.1.901

Show diffs side-by-side

added added

removed removed

Lines of Context:
80
80
     */
81
81
    for (i = 0; i < npixmaps; i++) {
82
82
        if (exaPixmapIsPinned (pixmaps[i].pPix) &&
83
 
            !exaPixmapIsOffscreen (pixmaps[i].pPix))
 
83
            !exaPixmapHasGpuCopy (pixmaps[i].pPix))
84
84
        {
85
85
            can_accel = FALSE;
86
86
            break;
98
98
        if (!pExaPixmap->driverPriv)
99
99
            exaCreateDriverPixmap_mixed(pPixmap);
100
100
 
101
 
        if (pExaPixmap->pDamage && exaPixmapIsOffscreen(pPixmap)) {
 
101
        if (pExaPixmap->pDamage && exaPixmapHasGpuCopy(pPixmap)) {
 
102
            ExaScreenPriv(pPixmap->drawable.pScreen);
 
103
 
 
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().
 
111
             */
102
112
            pPixmap->devKind = pExaPixmap->fb_pitch;
103
113
            exaCopyDirtyToFb(pixmaps + i);
 
114
 
 
115
            if (pExaScr->deferred_mixed_pixmap == pPixmap &&
 
116
                !pixmaps[i].as_dst && !pixmaps[i].pReg)
 
117
                pExaScr->deferred_mixed_pixmap = NULL;
104
118
        }
105
119
 
106
 
        pExaPixmap->offscreen = exaPixmapIsOffscreen(pPixmap);
 
120
        pExaPixmap->use_gpu_copy = exaPixmapHasGpuCopy(pPixmap);
107
121
    }
108
122
}
109
123
 
120
134
    exaDoMigration(pixmaps, 1, TRUE);
121
135
}
122
136
 
 
137
void
 
138
exaDamageReport_mixed(DamagePtr pDamage, RegionPtr pRegion, void *closure)
 
139
{
 
140
    PixmapPtr pPixmap = closure;
 
141
    ExaPixmapPriv(pPixmap);
 
142
 
 
143
    /* Move back results of software rendering on system memory copy of mixed driver
 
144
     * pixmap (see exaPrepareAccessReg_mixed).
 
145
     *
 
146
     * Defer moving the destination back into the driver pixmap, to try and save
 
147
     * overhead on multiple subsequent software fallbacks.
 
148
     */
 
149
    if (!pExaPixmap->use_gpu_copy && exaPixmapHasGpuCopy(pPixmap)) {
 
150
        ExaScreenPriv(pPixmap->drawable.pScreen);
 
151
 
 
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;
 
156
    }
 
157
}
 
158
 
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).
127
163
 */
128
164
void
129
165
exaPrepareAccessReg_mixed(PixmapPtr pPixmap, int index, RegionPtr pReg)
130
166
{
131
 
    if (!ExaDoPrepareAccess(pPixmap, index)) {
132
 
        ExaPixmapPriv(pPixmap);
133
 
        Bool is_offscreen = exaPixmapIsOffscreen(pPixmap);
 
167
    ExaPixmapPriv(pPixmap);
 
168
    Bool has_gpu_copy = exaPixmapHasGpuCopy(pPixmap);
 
169
    Bool success;
 
170
 
 
171
    success = ExaDoPrepareAccess(pPixmap, index);
 
172
 
 
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.
 
178
         */
 
179
        exaMoveInPixmap_mixed(pPixmap);
 
180
        success = ExaDoPrepareAccess(pPixmap, index);
 
181
 
 
182
        if (success) {
 
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
 
185
             * access.
 
186
             */
 
187
            DamageUnregister(&pPixmap->drawable, pExaPixmap->pDamage);
 
188
            DamageDestroy(pExaPixmap->pDamage);
 
189
            pExaPixmap->pDamage = NULL;
 
190
 
 
191
            free(pExaPixmap->sys_ptr);
 
192
            pExaPixmap->sys_ptr = NULL;
 
193
 
 
194
            return;
 
195
        }
 
196
    }
 
197
 
 
198
    if (!success) {
134
199
        ExaMigrationRec pixmaps[1];
135
200
 
136
201
        /* Do we need to allocate our system buffer? */
152
217
        pixmaps[0].pPix = pPixmap;
153
218
        pixmaps[0].pReg = pReg;
154
219
 
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;
157
223
 
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,
161
228
                                               pPixmap);
162
229
 
163
230
            DamageRegister(&pPixmap->drawable, pExaPixmap->pDamage);
165
232
            /* This is used by exa to optimize migration. */
166
233
            DamageSetReportAfterOp(pExaPixmap->pDamage, TRUE);
167
234
 
168
 
            if (is_offscreen) {
 
235
            if (has_gpu_copy) {
169
236
                exaPixmapDirty(pPixmap, 0, 0, pPixmap->drawable.width,
170
237
                               pPixmap->drawable.height);
171
238
 
177
244
                    pixmaps[0].as_src = TRUE;
178
245
                    pixmaps[0].pReg = NULL;
179
246
                }
180
 
                pPixmap->devKind = pExaPixmap->fb_pitch;
181
247
                exaCopyDirtyToSys(pixmaps);
182
248
            }
183
249
 
184
250
            if (as_dst)
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);
190
 
        }
191
255
 
192
256
        pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr;
193
257
        pPixmap->devKind = pExaPixmap->sys_pitch;
194
 
        pExaPixmap->offscreen = FALSE;
195
 
    }
196
 
}
197
 
 
198
 
/* Move back results of software rendering on system memory copy of mixed driver
199
 
 * pixmap (see exaPrepareAccessReg_mixed).
200
 
 */
201
 
void exaFinishAccess_mixed(PixmapPtr pPixmap, int index)
202
 
{
203
 
    ExaPixmapPriv(pPixmap);
204
 
 
205
 
    if (pExaPixmap->pDamage && exaPixmapIsOffscreen(pPixmap) &&
206
 
        !pExaPixmap->offscreen) {
207
 
        DamageRegionProcessPending(&pPixmap->drawable);
208
 
        exaMoveInPixmap_mixed(pPixmap);
209
 
    }
210
 
}
 
258
        pExaPixmap->use_gpu_copy = FALSE;
 
259
    }
 
260
}
 
261