Может ли OpenGL ES выполнять рендеринг в память пользовательского пространства, например, mmap'd / dev / fb1? - PullRequest
0 голосов
/ 31 января 2019

Я пытаюсь выяснить, можно ли заставить OpenGL ES 2.0 рендерить содержимое буфера в mmap 'память в пространстве пользователя вместо памяти, выделенной графическим процессором.

К сожалению,Функция glReadPixels() невероятно медленная, поскольку она останавливает весь конвейер, поэтому даже чтение 10x10 пикселей снижает частоту кадров с 60 Гц до 5 Гц.

Я читаю эту статью и понимаю, что могу использоватьобъект Frame Buffer для выполнения этого http://processors.wiki.ti.com/index.php/Render_to_Texture_with_OpenGL_ES#Pixmaps

Я пытаюсь использовать приведенный ниже код, но не могу понять, как получить адрес для FBO

Аппаратное обеспечение I 'Я использую Raspberry Pi 3 с драйверами WaveShare 3.5 "SPI TFT LCD и LCD-Show. Но это может относиться к любому оборудованию.

Проблема, с которой я столкнулся, заключается в том, что нет способа получить указатель наFBO, все, что у меня есть, это дескрипторы, используемые OpenCV. Так что даже если бы я хотел memcpy из одного места в другое, у меня нет адреса памяти GPU для работы. Это невозможно сделать, потому что память GPU яне адресуется из пространства пользователя?

Спасибо,

//CREATE FBO OBJECT
GLuint       m_hFBO[2];       // Handles for Frame Buffer Objects
const unsigned int gTextureSize = 1024;
GLuint       m_hTexture[2];   // Texture handles
// Generate handles for two dynamically rendered texture maps
glGenTextures(2, m_hTexture);

for (int Index = 0; Index < 2; Index++)
{
    // Bind and configure each texture
    glBindTexture(GL_TEXTURE_2D, m_hTexture[Index]);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, gTextureSize, gTextureSize, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);

    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}

// Generate handles for two Frame Buffer Objects
glGenFramebuffers(2, m_hFBO);

for (int Index = 0; Index < 2; Index++)
{
    // Attach each texture to the first color buffer of an FBO and clear it
    glBindFramebuffer(GL_FRAMEBUFFER, m_hFBO[Index]);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_hTexture[Index], 0);
    glClear(GL_COLOR_BUFFER_BIT);
}

//MMAP /DEV/FB1
struct fb_fix_screeninfo finfo;
uint32_t pixels;
const char *device = "/dev/fb1";
int fbfd = open(device, O_RDWR);
if (fbfd == -1) {printf("cannot open /dev/fb1 device"); return;}
if (ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo) == -1) {printf("cannot get /dev/fb1 fixed information"); return;}
struct fb_var_screeninfo vinfo;
if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo) == -1) {printf("cannot get /dev/fb1 variable information"); return;}
//---------------------------------------------------------------------
if((vinfo.xres * 2) != finfo.line_length) {printf("assumption failed ... /dev/fb1 lines are padded"); return;}
if ((vinfo.xres % 16) != 0) {printf("/dev/fb1 width must be a multiple of 16"); return;}
if (vinfo.bits_per_pixel != 16){printf("/dev/fb1 is not 16 bits per pixel"); return;}
//---------------------------------------------------------------------
fbp1 = (uint16_t*)mmap(0,finfo.smem_len,PROT_READ | PROT_WRITE,MAP_SHARED,fbfd,0);
if (fbp1 == MAP_FAILED){printf("cannot map /dev/fb1 into memory"); return;}
memset(fbp1, 0, finfo.smem_len);

pixels = vinfo.xres * vinfo.yres;
...