灿的OpenGL ES渲染到用户存储空间,如mmap'd的/ dev / FB1?

时间:2019-01-31 20:01:19

标签: c++ linux opengl-es raspberry-pi opengl-es-2.0

我正在尝试确定是否可以使OpenGL ES 2.0将缓冲区内容呈现到用户空间中的mmap内存中,而不是GPU分配的内存中。

不幸的是,glReadPixels()函数的运行速度非常慢,因为它使整个流水线停滞了,因此即使读取10x10像素也会将帧速率从60hz降至5hz。

我正在阅读本文,并且我了解我可以使用帧缓冲区对象来完成此操作 http://processors.wiki.ti.com/index.php/Render_to_Texture_with_OpenGL_ES#Pixmaps

我正在尝试下面的代码,但是我不知道如何获得FBO的地址

我正在使用的硬件是具有WaveShare 3.5英寸SPI TFT LCD和LCD-Show驱动程序的Raspberry Pi3。但这可能与任何硬件有关。

我遇到的问题是无法获取指向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;

0 个答案:

没有答案
相关问题