LINUX.ORG.RU

Фреймбуфер возвращает неправильное разрешение экрана

 ,


0

2

Запускаю раз:

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <sys/mman.h>
#include <sys/ioctl.h>

int main()
{
    usleep(2 * 1000 * 1000);

    int fbfd = 0;
    struct fb_var_screeninfo vinfo;
    struct fb_fix_screeninfo finfo;
    long int screensize = 0;
    char *fbp = 0;
    int x = 0, y = 0;
    long int location = 0;

    // Open the file for reading and writing
    fbfd = open("/dev/fb0", O_RDWR);
    if (fbfd == -1) {
        perror("Error: cannot open framebuffer device");
        exit(1);
    }
    printf("The framebuffer device was opened successfully.\n");

    // Get fixed screen information
    if (ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo) == -1) {
        perror("Error reading fixed information");
        exit(2);
    }

    // Get variable screen information
    if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo) == -1) {
        perror("Error reading variable information");
        exit(3);
    }

    printf("%dx%d, %dbpp\nVirt: %dx%d\n", vinfo.xres, vinfo.yres, vinfo.bits_per_pixel, vinfo.xres_virtual, vinfo.yres_virtual);

    // Figure out the size of the screen in bytes
    screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;

    // Map the device to memory
    fbp = (char *)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED,
                       fbfd, 0);
    if ((int)fbp == -1) {
        perror("Error: failed to map framebuffer device to memory");
        exit(4);
    }
    printf("The framebuffer device was mapped to memory successfully.\n");

    // Figure out where in memory to put the pixel
    while (1)
    for (y = 0; y < 300; y++)
    for (x = 0; x < 300; x++)
    {
        location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) +
                   (y+vinfo.yoffset) * finfo.line_length;
        if (vinfo.bits_per_pixel == 32)
        {
            *(fbp + location + vinfo   .red.offset    / 8) = 0xFF;
            *(fbp + location + vinfo .green.offset  / 8) = 0x00;
            *(fbp + location + vinfo  .blue.offset   / 8) = 0xFF;
            *(fbp + location + vinfo.transp.offset / 8) = 0x0;
        }
    }

    munmap(fbp, screensize);
    close(fbfd);
    return 0;
}
При экране в 1920х1080 получаю в ответ в консоли:
The framebuffer device was opened successfully.
640x480, 32bpp
Virt: 640x480
The framebuffer device was mapped to memory successfully.
Вот и хрен бы с ним, вот только вместо розового квадрата получаю рубленный на три части: https://s11.postimg.org/43d4h79xf/Screenshot_01_11_2016_18_36_56.png То есть на самом деле там не 640х480 а 1920х1080. Пробовал зааллоцировать по нужному разрешению - mmap шлет лесом.

Ответ на: комментарий от someoneelsenotme

Результаты записи в /dev/fb должны быть видны только в виртульных консолях (/dev/tty1 и т.д.). Рисование под X-ами идёт через их API.

Если рисуется, значит бага в драйвере или где ещё, искать в таком случае решения проблем с разрешением смысла нет.

mky ★★★★★
()
Ответ на: комментарий от someoneelsenotme

Рисуется жи

Ну ты порнорежиссёр, под иксами фреймбуффер юзать. Как вообще заработало...

I-Love-Microsoft ★★★★★
()

Здаётся мне, что искы сидят на каком-нибудь /dev/dri/card0, а то, что /dev/fb0 рапортует какое-то разрешение... Ну, осталась там в каких-то регистрах видеокарты информация о разрешении, в котором она была до переключения драйвером из SVGA-compatible режима в нативный. Что-то рисуется? Ну, значит буффер для SVGA-режима перекрывается с буффером для текущего режима.

anonymous
()
Ответ на: комментарий от andreyu

Проверял влияет ли что я выставил на запускаемый терминал --maximize - там была проблема что в самом начале размер терминала по-умолчанию, а потом он разворачивается (спустя 50-100 мс)

someoneelsenotme
() автор топика
Ответ на: комментарий от someoneelsenotme

Лол. /dev/fb0 с /dev/pts/... не связан.

anonymous
()
Ответ на: комментарий от anonymous

не, DRM-фреймбуферы по идее должны работать. Их может быть много. Просто лучше этим в новом коде сейчас не пользоваться, а использовать libdrm или библиотеку какую типа SDL.

И да, фреймбуферы связаны с ttyx (хотя это костыль такой). Можно смело брать свободный tty, аллоцировать на нём fb и пользоваться (если умеет видеодрайвер). Тогда можно будет переключаться по Ctrl-Alt-Fx :)

Ещё - если система не embedded и разрешение фреймбуфера не прописано где в конфигах/commandline/DT, параметры фреймбуфера нужно выставлять, иначе работать нифига толком не будет.

А вообще, зачем эти жксперименты?

slapin ★★★★★
()
Ответ на: комментарий от slapin

Хотел потеребонькать во фреймбуфере, фм какой-нибудь написать например. Или смотрелку картинок. Правда не знал что фб только для ttyx, думал может и в обычном эмуляторе сосноли покатит.

someoneelsenotme
() автор топика
Ответ на: комментарий от someoneelsenotme

Если хочешь полноценно - погоняй в виртуалке или qemu. Там можно fbcon и виртуальные терминалы (не pty/pts) выключить и иметь чистый не замутнённый fb и сериал-консоль. Тогда ttyX не будет, можно через коммандлайн или через DT или через platform data настроить fb и ковырять как хочется не боясь что-нибудь порушить. Хотя от fbcon и виртуальных терминалов зла особо никакого нету, надо просто знать об их существовании. Просто работа одновременно fb и X11 (да и wayland тоже) может работать не на всех драйверах корректно.

Но опять же, повторю совет - осиливай libdrm а не fbdev, там возможностей больше а сущности те же и приятнее всё. Только опять же не на том же ядре, где хост. По умолчанию без хаков 2 раза файловый дескриптор тебе никто не отдаст, так что лучше в qemu или виртуалке.

fbdev сейчас актуален только на совсем примитивных устройствах.

slapin ★★★★★
()

чел, слушай тут такое дело: иксы работают в обход framebuffer. там конечно лежат какие-то настройки но они неактуальны. тебе надо иксы глушить перед тем как в fb лезть.

i36_zubov
()
Ответ на: комментарий от slapin

fbdev сейчас актуален только на совсем примитивных устройствах.

Потому и взял, хочу в олдскул удариться.

Если хочешь полноценно - погоняй в виртуалке или qemu. Там можно fbcon и виртуальные терминалы (не pty/pts) выключить и иметь чистый не замутнённый fb и сериал-консоль. Тогда ttyX не будет, можно через коммандлайн или через DT или через platform data настроить fb и ковырять как хочется не боясь что-нибудь порушить. Хотя от fbcon и виртуальных терминалов зла особо никакого нету, надо просто знать об их существовании. Просто работа одновременно fb и X11 (да и wayland тоже) может работать не на всех драйверах корректно.

В ней и сижу. Пробовал бы через ttyx, но эта срань под маком не дает в нее переключиться. rCTRL(host)+F1..6 не работает, VirtualBox.

someoneelsenotme
() автор топика
Ответ на: комментарий от someoneelsenotme

А ну дык заведи отдельную виртуалку для тестов на fb, монтируй рут по nfs (есть же на маке сервер nfs?) и просто будет - пересобрал бинарник в полной виртуалке, потестил во второй просто перезапуском. По идее должно быть удобно. Я маком никогда не пользовался, так что точнее не подскажу, но это даже у людей под виндой работает, так что должно быть всё хорошо. Я так понимаю на маке дефолтная fs case insensitive, значит нужно будет отдельную для nfs сделать и монтировать её на обеих виртуалках. Тогда ничего переключать ничего не надо будет, только между виртуалками.

slapin ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.