~ubuntu-branches/ubuntu/utopic/xserver-xorg-video-intel/utopic

« back to all changes in this revision

Viewing changes to src/sna/sna_display.c

  • Committer: Package Import Robot
  • Author(s): Timo Aaltonen
  • Date: 2012-09-12 07:43:59 UTC
  • mfrom: (1.4.22)
  • Revision ID: package-import@ubuntu.com-20120912074359-i3h8ol6hoghbemoq
Tags: 2:2.20.7-0ubuntu1
Merge from unreleased debian git.

Show diffs side-by-side

added added

removed removed

Lines of Context:
60
60
struct sna_crtc {
61
61
        struct drm_mode_modeinfo kmode;
62
62
        int dpms_mode;
 
63
        PixmapPtr scanout_pixmap;
63
64
        struct kgem_bo *bo;
64
65
        uint32_t cursor;
65
66
        bool shadow;
131
132
        ScrnInfoPtr scrn = sna->scrn;
132
133
        struct drm_mode_fb_cmd arg;
133
134
 
 
135
        assert(bo->refcnt);
134
136
        assert(bo->proxy == NULL);
135
137
        if (bo->delta) {
136
138
                DBG(("%s: reusing fb=%d for handle=%d\n",
152
154
        arg.depth = scrn->depth;
153
155
        arg.handle = bo->handle;
154
156
 
 
157
        assert(sna->scrn->vtSema); /* must be master */
155
158
        if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_ADDFB, &arg)) {
156
159
                xf86DrvMsg(scrn->scrnIndex, X_ERROR,
157
160
                           "%s: failed to add fb: %dx%d depth=%d, bpp=%d, pitch=%d: %d\n",
315
318
        return str;
316
319
}
317
320
 
318
 
static void
319
 
sna_output_backlight_init(xf86OutputPtr output)
 
321
static char *
 
322
has_device_backlight(xf86OutputPtr output, int *best_type)
 
323
{
 
324
        struct sna_output *sna_output = output->driver_private;
 
325
        struct sna *sna = to_sna(output->scrn);
 
326
        struct pci_device *pci = sna->PciInfo;
 
327
        char path[1024];
 
328
        char *best_iface = NULL;
 
329
        DIR *dir;
 
330
        struct dirent *de;
 
331
 
 
332
        snprintf(path, sizeof(path),
 
333
                 "/sys/bus/pci/devices/%04x:%02x:%02x.%d/backlight",
 
334
                 pci->domain, pci->bus, pci->dev, pci->func);
 
335
 
 
336
        DBG(("%s: scanning %s\n", __FUNCTION__, path));
 
337
        dir = opendir(path);
 
338
        if (dir == NULL)
 
339
                return NULL;
 
340
 
 
341
        while ((de = readdir(dir))) {
 
342
                char buf[100];
 
343
                int fd, v;
 
344
 
 
345
                if (*de->d_name == '.')
 
346
                        continue;
 
347
 
 
348
                DBG(("%s: %s\n", __FUNCTION__, de->d_name));
 
349
                snprintf(path, sizeof(path), "%s/%s/type",
 
350
                         BACKLIGHT_CLASS, de->d_name);
 
351
 
 
352
                v = -1;
 
353
                fd = open(path, O_RDONLY);
 
354
                if (fd >= 0) {
 
355
                        v = read(fd, buf, sizeof(buf)-1);
 
356
                        close(fd);
 
357
                }
 
358
                if (v > 0) {
 
359
                        while (v > 0 && isspace(buf[v-1]))
 
360
                                v--;
 
361
                        buf[v] = '\0';
 
362
 
 
363
                        if (strcmp(buf, "raw") == 0)
 
364
                                v = RAW;
 
365
                        else if (strcmp(buf, "platform") == 0)
 
366
                                v = PLATFORM;
 
367
                        else if (strcmp(buf, "firmware") == 0)
 
368
                                v = FIRMWARE;
 
369
                        else
 
370
                                v = INT_MAX;
 
371
                } else
 
372
                        v = INT_MAX;
 
373
 
 
374
                if (v < *best_type) {
 
375
                        char *copy;
 
376
                        int max;
 
377
 
 
378
                        sna_output->backlight_iface = de->d_name;
 
379
                        max = sna_output_backlight_get_max(output);
 
380
                        sna_output->backlight_iface = NULL;
 
381
                        if (max <= 0)
 
382
                                continue;
 
383
 
 
384
                        copy = strdup(de->d_name);
 
385
                        if (copy) {
 
386
                                free(best_iface);
 
387
                                best_iface = copy;
 
388
                                *best_type = v;
 
389
                        }
 
390
                }
 
391
        }
 
392
        closedir(dir);
 
393
 
 
394
        return best_iface;
 
395
}
 
396
 
 
397
static char *
 
398
has_backlight(xf86OutputPtr output, int *best_type)
320
399
{
321
400
        static const char *known_interfaces[] = {
322
401
                "gmux_backlight",
332
411
                "acpi_video0",
333
412
                "intel_backlight",
334
413
        };
335
 
        MessageType from = X_PROBED;
336
414
        struct sna_output *sna_output = output->driver_private;
337
 
        char *best_iface;
338
 
        int best_type;
 
415
        char *best_iface = NULL;
339
416
        DIR *dir;
340
417
        struct dirent *de;
341
418
 
342
 
        best_type = INT_MAX;
343
 
        best_iface = has_user_backlight_override(output);
344
 
        if (best_iface)
345
 
                goto skip;
346
 
 
347
419
        dir = opendir(BACKLIGHT_CLASS);
348
420
        if (dir == NULL)
349
 
                return;
 
421
                return NULL;
350
422
 
351
423
        while ((de = readdir(dir))) {
352
424
                char path[1024];
391
463
                        v += i;
392
464
                }
393
465
 
394
 
                if (v < best_type) {
 
466
                if (v < *best_type) {
395
467
                        char *copy;
396
468
                        int max;
397
469
 
407
479
                        if (copy) {
408
480
                                free(best_iface);
409
481
                                best_iface = copy;
410
 
                                best_type = v;
 
482
                                *best_type = v;
411
483
                        }
412
484
                }
413
485
        }
414
486
        closedir(dir);
415
487
 
416
 
        if (!best_iface)
417
 
                return;
418
 
 
419
 
skip:
 
488
        return best_iface;
 
489
}
 
490
 
 
491
static void
 
492
sna_output_backlight_init(xf86OutputPtr output)
 
493
{
 
494
        struct sna_output *sna_output = output->driver_private;
 
495
        MessageType from = X_PROBED;
 
496
        char *best_iface;
 
497
        int best_type;
 
498
 
 
499
        best_type = INT_MAX;
 
500
        best_iface = has_user_backlight_override(output);
 
501
        if (best_iface)
 
502
                goto done;
 
503
 
 
504
        best_iface = has_device_backlight(output, &best_type);
 
505
        if (best_iface)
 
506
                goto done;
 
507
 
 
508
        best_iface = has_backlight(output, &best_type);
 
509
        if (best_iface)
 
510
                goto done;
 
511
 
 
512
        return;
 
513
 
 
514
done:
420
515
        sna_output->backlight_iface = best_iface;
421
516
        sna_output->backlight_max = sna_output_backlight_get_max(output);
422
517
        sna_output->backlight_active_level = sna_output_backlight_get(output);
432
527
                   sna_output->backlight_iface, best_iface);
433
528
}
434
529
 
435
 
 
436
530
static void
437
531
mode_from_kmode(ScrnInfoPtr scrn,
438
532
                drmModeModeInfoPtr kmode,
566
660
        arg.crtc_id = sna_crtc->id;
567
661
        arg.fb_id = fb_id(sna_crtc->bo);
568
662
        if (sna_crtc->transform) {
569
 
                assert(sna_crtc->shadow);
570
663
                arg.x = 0;
571
664
                arg.y = 0;
572
665
        } else {
711
804
                        continue;
712
805
                }
713
806
 
 
807
                DBG(("%s: CRTC:%d (pipe %d) vrefresh=%d\n",
 
808
                     __FUNCTION__,i, to_sna_crtc(crtc)->pipe,
 
809
                     xf86ModeVRefresh(&crtc->mode)));
714
810
                max_vrefresh = max(max_vrefresh, xf86ModeVRefresh(&crtc->mode));
715
811
        }
716
812
 
939
1035
        struct kgem_bo *bo;
940
1036
 
941
1037
        sna_crtc->transform = false;
942
 
        if (use_shadow(sna, crtc)) {
 
1038
        if (sna_crtc->scanout_pixmap) {
 
1039
                DBG(("%s: attaching to scanout pixmap\n", __FUNCTION__));
 
1040
 
 
1041
                bo = sna_pixmap_pin(sna_crtc->scanout_pixmap, PIN_SCANOUT);
 
1042
                if (bo == NULL)
 
1043
                        return NULL;
 
1044
 
 
1045
                if (!get_fb(sna, bo,
 
1046
                            sna_crtc->scanout_pixmap->drawable.width,
 
1047
                            sna_crtc->scanout_pixmap->drawable.height))
 
1048
                        return NULL;
 
1049
 
 
1050
                sna_crtc->transform = true;
 
1051
                return kgem_bo_reference(bo);
 
1052
        } else if (use_shadow(sna, crtc)) {
943
1053
                if (!sna_crtc_enable_shadow(sna, sna_crtc))
944
1054
                        return NULL;
945
1055
 
991
1101
        } else {
992
1102
                DBG(("%s: attaching to framebuffer\n", __FUNCTION__));
993
1103
                sna_crtc_disable_shadow(sna, sna_crtc);
994
 
                bo = sna_pixmap_pin(sna->front);
 
1104
                bo = sna_pixmap_pin(sna->front, PIN_SCANOUT);
995
1105
                if (bo == NULL)
996
1106
                        return NULL;
997
1107
 
1299
1409
        crtc->driver_private = NULL;
1300
1410
}
1301
1411
 
 
1412
#if HAS_PIXMAP_SHARING
 
1413
static Bool
 
1414
sna_set_scanout_pixmap(xf86CrtcPtr crtc, PixmapPtr pixmap)
 
1415
{
 
1416
        DBG(("%s: CRTC:%d, pipe=%d setting scanout pixmap=%ld\n",
 
1417
             __FUNCTION__,to_sna_crtc(crtc)->id, to_sna_crtc(crtc)->pipe,
 
1418
             pixmap ? pixmap->drawable.serialNumber : 0));
 
1419
        to_sna_crtc(crtc)->scanout_pixmap = pixmap;
 
1420
        return TRUE;
 
1421
}
 
1422
#endif
 
1423
 
1302
1424
static const xf86CrtcFuncsRec sna_crtc_funcs = {
1303
1425
        .dpms = sna_crtc_dpms,
1304
1426
        .set_mode_major = sna_crtc_set_mode_major,
1309
1431
        .load_cursor_argb = sna_crtc_load_cursor_argb,
1310
1432
        .gamma_set = sna_crtc_gamma_set,
1311
1433
        .destroy = sna_crtc_destroy,
 
1434
#if HAS_PIXMAP_SHARING
 
1435
        .set_scanout_pixmap = sna_set_scanout_pixmap,
 
1436
#endif
1312
1437
};
1313
1438
 
1314
1439
static uint32_t
2144
2269
    return WT_DONTWALKCHILDREN;
2145
2270
}
2146
2271
 
2147
 
static void
2148
 
sna_redirect_screen_pixmap(ScrnInfoPtr scrn, PixmapPtr old, PixmapPtr new)
2149
 
{
2150
 
        ScreenPtr screen = scrn->pScreen;
2151
 
        struct sna_visit_set_pixmap_window visit;
2152
 
 
2153
 
        visit.old = old;
2154
 
        visit.new = new;
2155
 
        TraverseTree(screen->root, sna_visit_set_window_pixmap, &visit);
2156
 
 
2157
 
        screen->SetScreenPixmap(new);
2158
 
}
2159
 
 
2160
2272
static void copy_front(struct sna *sna, PixmapPtr old, PixmapPtr new)
2161
2273
{
2162
2274
        struct sna_pixmap *old_priv, *new_priv;
2229
2341
{
2230
2342
        xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
2231
2343
        struct sna *sna = to_sna(scrn);
 
2344
        ScreenPtr screen = scrn->pScreen;
2232
2345
        PixmapPtr old_front, new_front;
2233
2346
        int i;
2234
2347
 
2235
 
        DBG(("%s (%d, %d) -> (%d, %d)\n",
2236
 
             __FUNCTION__,
 
2348
        DBG(("%s (%d, %d) -> (%d, %d)\n", __FUNCTION__,
2237
2349
             scrn->virtualX, scrn->virtualY,
2238
2350
             width, height));
2239
2351
 
2240
2352
        if (scrn->virtualX == width && scrn->virtualY == height)
2241
2353
                return TRUE;
2242
2354
 
2243
 
        assert(scrn->pScreen->GetScreenPixmap(scrn->pScreen) == sna->front);
2244
 
        assert(scrn->pScreen->GetWindowPixmap(scrn->pScreen->root) == sna->front);
 
2355
        assert(sna->front);
 
2356
        assert(screen->GetScreenPixmap(screen) == sna->front);
 
2357
 
2245
2358
        DBG(("%s: creating new framebuffer %dx%d\n",
2246
2359
             __FUNCTION__, width, height));
2247
2360
 
2248
2361
        old_front = sna->front;
2249
 
        new_front = scrn->pScreen->CreatePixmap(scrn->pScreen,
2250
 
                                                 width, height,
2251
 
                                                 scrn->depth,
2252
 
                                                 SNA_CREATE_FB);
 
2362
        new_front = screen->CreatePixmap(screen,
 
2363
                                         width, height, scrn->depth,
 
2364
                                         SNA_CREATE_FB);
2253
2365
        if (!new_front)
2254
2366
                return FALSE;
2255
2367
 
2278
2390
                        sna_crtc_disable(crtc);
2279
2391
        }
2280
2392
 
2281
 
        sna_redirect_screen_pixmap(scrn, old_front, sna->front);
2282
 
        assert(scrn->pScreen->GetScreenPixmap(scrn->pScreen) == sna->front);
2283
 
        assert(scrn->pScreen->GetWindowPixmap(scrn->pScreen->root) == sna->front);
2284
 
 
2285
 
        scrn->pScreen->DestroyPixmap(old_front);
 
2393
        if (screen->root) {
 
2394
                struct sna_visit_set_pixmap_window visit;
 
2395
 
 
2396
                visit.old = old_front;
 
2397
                visit.new = sna->front;
 
2398
                TraverseTree(screen->root, sna_visit_set_window_pixmap, &visit);
 
2399
                assert(screen->GetWindowPixmap(screen->root) == sna->front);
 
2400
        }
 
2401
        screen->SetScreenPixmap(sna->front);
 
2402
        assert(screen->GetScreenPixmap(screen) == sna->front);
 
2403
 
 
2404
        screen->DestroyPixmap(old_front);
2286
2405
 
2287
2406
        return TRUE;
2288
2407
}
2338
2457
                        continue;
2339
2458
                }
2340
2459
 
2341
 
                kgem_bo_destroy(&sna->kgem, crtc->bo);
2342
 
                crtc->bo = kgem_bo_reference(bo);
 
2460
                if (crtc->bo != bo) {
 
2461
                        kgem_bo_destroy(&sna->kgem, crtc->bo);
 
2462
                        crtc->bo = kgem_bo_reference(bo);
 
2463
                }
2343
2464
 
2344
2465
                count++;
2345
2466
        }
2412
2533
        for (i = 0; i < mode->kmode->count_connectors; i++)
2413
2534
                sna_output_init(scrn, mode, i);
2414
2535
 
 
2536
#if HAS_PIXMAP_SHARING
 
2537
        xf86ProviderSetup(scrn, NULL, "Intel");
 
2538
#endif
2415
2539
        xf86InitialConfiguration(scrn, TRUE);
2416
2540
 
2417
2541
        return true;