OpenGL学习

https://www.cnblogs.com/shakin/p/4521799.html

帧缓冲区是一块内存,这个块内存可以是共享内存(CPU和GPU能同时访问),或者是显存,GPU可以直接访问

客户端先通过opengl es 绘制到 Graphicbuffer上(以共享内存作为帧缓存区),然后经过 sfufaceFlinger 合成,最终再有open gl es 绘制到显卡上(此时以显卡作为帧缓冲区,即frambuffer)

Surface 可以代表一个抽象窗口即共享内存是一个窗口(可以存放数据),此时Surface (虚拟窗口)利用共享内存实现双缓冲,显示器也代表一种窗口即显卡是一个窗口(frambuffer可以存放数据),
此时显示器(真实窗口)利用显存也可以实现双缓冲

所以opengl es 是一种双缓冲规范,给他提供内存,再根据定义好的接口实现双缓冲机制,就成了open gl 库

在open gl 中 只有0号帧缓冲区才可以上屏,所以你虽然创建了很多帧缓冲区,但是你用完这些帧缓冲区后,最后你得拷贝到0号帧缓冲区才能有机会上屏,因为eglswpebuffer 会把0号帧缓冲区切为前台。

Eglswpe 其实是把 后台”缓冲区“(你刚刚经过draw,然后又把fbo拷贝到0号帧缓冲区,刚刚渲染完的一帧)(可能是0号帧缓冲区吧),切换为前台”缓冲区“。

那么离屏渲染还需要进行eglswpebuffer吗?不需要,理解为渲染到一个后台窗口,只不过这个窗口是单缓存的,在窗口中绘制到Pbuffer内存区域(使用渲染缓冲区依附在FBO上)。

Pbuffer Surface 是单缓冲的 我们不需要调用 eglSwapBuffers 每次渲染操作直接写入 Pbuffer Surface,并可以在渲染完成后直接读取其内容用于其他处理。

数据的搬运都是通过GraphicBuffer搬运的,最终数据被搬运到SurfaceFlinger 中,在SurfaceFlinger中合成后,又才真正的在真实的显示内存上创建FameBuffer(真实设备的帧缓冲)给opengl es ,open gl es 通过写这个缓存才上屏幕的。之前的搬运工具都是通过surface创建的 GraphicBuffer(联合EGLImage)。如果是本地窗口给opengl es,那么渲染之后直接上屏(本地窗口surface 中的 mGraphicProduct 关联 SurfaceFlinger)。如果是通过open gl 中生成的纹理id 进而创建的SurfaceTexure 进而再创建Surface,给与camera,或者 播放器,那么这个时候,这个呗创建的surface 中的 GraphicBuffer 被传递到 纹理,进而open gl 通过这个纹理数据,在进行渲染,渲染完成之后,再把数据 放入到开始绑定到open gl 的本地窗口Surface中的GraphicBuffer上,然后才给到SurfaceFlinger,进而再合成(SurfaceFlinger合成),再渲染(以真正的设备显示内存最为帧缓冲区),结果(swapbuffer交换前后缓冲区)再上屏。如果本地窗口surface 直接给于了camera 或者媒体解析器,那么内部解码之后的数据就会直接放到 Surface中的 GraphicBuffer中之后,这些数据直接就被搬运到SurfaceFlinger中,进行再合成,再渲染,然后再上屏。

SurfaceTexture 的工作原理:SurfaceTexture内部有自己的BufferQueue,它的一端链接这生产者,比如camera,opengl 绘制,多媒体解码数据,然后数据被转化了纹理,这个纹理是作用于消费端opengl 环境的即以视图Textureview中SurfaceTexture为本地窗口的opengles 环境中的纹理Id上。这个opengl 环境会作为生产者使用这个纹理最终渲染到Textureview中SurfaceTexture上的Graphicbuffer上。再然后该Graphicbuffer又会最为外部纹理渲染到以本地Surface作为本地窗口的opengl 环境的纹理Id上。最终渲染结果放在了本地Surface的生产端GraphicBuffer上(这一步就是是窗口开启硬件加速后再使用GPU渲染的,硬渲染不是软渲染),消费者是SurfaceFlinger(SurfaceFlinger中有Layer,Layer种有BufferQueue)。所以如果你要对纹理进行处理,那么处理完之后的数据(opengl 渲染完放在了GrahpicBuffer中) 还要在作为产生端再流转到本地窗口对应的surface上,而本地窗口surface又作为生产端把数据流转到SurfaceFlinger中了。所以如果不想对解码数据进行处理,那么就直接把本地TextureView中的surfacetexture交给解码器,数据会直接流转到以本地surface为本地窗口的open gl 环境的纹理Id上。然后渲染结果还是放在了Surface上的GraphicBuffer,最后流转大了SurfaceFlinger上。少了第一步的openGl 环境的处理。

解码后的数据流转到本地TextureView上的SurfaceTexture上后,可以理解成GraPhicBuffer就是需要显示在TextureView上的一张一张的图片,然后最后TextureView和视图树一起,进入硬件绘制即使用 openGl es 绘制。把以把TextureView最为一个视图树中的一个图层,图片就是他的背景,这个样好理解一点。

最后图的最后 surfaceTexture和surface之间应该画一个open gl 环境,这里少画了,不然,surfaceTexture中的数据怎么流转到surface。

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值