首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >硬件加速:RenderThread处理DrawOp树

硬件加速:RenderThread处理DrawOp树

作者头像
小柔
发布于 2022-10-09 04:40:32
发布于 2022-10-09 04:40:32
69400
代码可运行
举报
文章被收录于专栏:小柔博客园小柔博客园
运行总次数:0
代码可运行

theme: condensed-night-purple

初始化硬件加速环境

在ViewRootImpl的setView方法中会判断如果支持硬件加速就初始化硬件加速的环境并将创建的HardwareRenderer保存到ViewRootImpl的mAttachInfo中

软件绘制和硬件绘制

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 final boolean hardwareAccelerated =
                (attrs.flags & WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED) != 0;

    if (hardwareAccelerated) {
           //是否支持开启硬件加速 ,通常都是true
         if (!HardwareRenderer.isAvailable()) {
            return;
          }
           //初始化HardwareRenderer
     mAttachInfo.mHardwareRenderer = HardwareRenderer.create(mContext, translucent);
          if (mAttachInfo.mHardwareRenderer != null) {
          mAttachInfo.mHardwareRenderer.setName(attrs.getTitle().toString());
        mAttachInfo.mHardwareAccelerated =
                    mAttachInfo.mHardwareAccelerationRequested = true;
                }
            }
        }
HardwareRenderer.create主要工作
  • 建立硬件加速环境
  • 创建HardwareRenderer并保存到ViewRootImpl的attachInfo中(后续会通过该属性进行硬件加速的构建环节)
  • 创建RootRenderNode之后的DisplayList要同步到根RenderNode中
  • 为当前widow建立一个ThreadProxy用于向RenderThread提交绘制任务DrawFrameTask(RenderThread中通过Quene来存储这些TASK)
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
static HardwareRenderer create(Context context, boolean translucent) {
    HardwareRenderer renderer = null;
    if (DisplayListCanvas.isAvailable()) {
        renderer = new ThreadedRenderer(context, translucent);
    }
    return renderer;
}
    
ThreadedRenderer(Context context, boolean translucent) {
    final TypedArray a = context.obtainStyledAttributes(null, R.styleable.Lighting, 0, 0);
    ...
    <!--建立rootnode-->
    long rootNodePtr = nCreateRootRenderNode();
    mRootNode = RenderNode.adopt(rootNodePtr);
   <!--建立native ThreadProxy-->
    mNativeProxy = nCreateProxy(translucent, rootNodePtr);
    ...
}

ThreadProxy初始化工作: 启动RenderThread并使用mRenderThread属性引用 向RenderThread提交为当前窗口创建CanvasContext的任务,之后的绘制指令会通过它进行中转

RenderThread

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
RenderThread::RenderThread() : Thread(true), Singleton<RenderThread>()
, mNextWakeup(LLONG_MAX)
, mDisplayEventReceiver(nullptr)
, mVsyncRequested(false)
, mFrameCallbackTaskPending(false)
, mFrameCallbackTask(nullptr)
, mRenderState(nullptr)
, mEglManager(nullptr) {
Properties::load();
mFrameCallbackTask = new DispatchFrameCallbacks(this);
mLooper = new Looper(false);
run("RenderThread");
}

创建EGLManager(管理EGL Surface,OpenGl上下文),RenderState(渲染状态机),mDisplayEventReceiver(后续接受Vsync事件处理),Looper(用于执行渲染的TASK操作)。由于RenderThread是单例,因此上面这些属性也都是单例的

mDisplayEventReceiver

接收SF上抛的Vsync信号,通过监听DisplayEventReceiver的BitTube来回调编舞者的doFrame方法

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
void RenderThread::initializeDisplayEventReceiver() {
    mDisplayEventReceiver = new DisplayEventReceiver();
    status_t status = mDisplayEventReceiver->initCheck();
    //监听FD
    mLooper->addFd(mDisplayEventReceiver->getFd(), 0,
            Looper::EVENT_INPUT, RenderThread::displayEventReceiverCallback, this);
}

CanvasContext

也叫作OPENGL的上下文(持有EGLContetx和EGLSurface);在创建RenderThread的时候会向RenderThread发送第一个Task,就是创建CanvasContext

CanvasContext.setSurface

1.创建EGLContext和EGLSurface

2.将当前EGLSurface(本质是ANativeWindow)绑定到EGLContext(有多个EGLSurface的时候控制渲染哪个Surface)

持有mRenderThread,rootRenderNode,mEglManager这些属性

ANativeWindwos其实是EGLSurface在native层的Surface对象,通过eglManager创建

Window持有ViewRootImpl持有attachInfo持有mHardWare---》创建持有ThreadProxy---》ThreadProxy提交创建CanvasContext的申请,CanvasContext中创建EGLContext,EGLSurface并绑定需要渲染的Surface---》持有RenderThread等待Vsync信号

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
void CanvasContext::setSurface(ANativeWindow* window) {
    mNativeWindow = window;
    //建立EglSurface
    if (window) {
        mEglSurface = mEglManager.createSurface(window);
    }
    if (mEglSurface != EGL_NO_SURFACE) {
        const bool preserveBuffer = (mSwapBehavior != kSwap_discardBuffer);
        mBufferPreserved = mEglManager.setPreserveBuffer(mEglSurface, preserveBuffer);
        mHaveNewSurface = true;
        //绑定上下文
        makeCurrent();
    }}

EGLSurface EglManager::createSurface(EGLNativeWindowType window) {
    //构建EglContext
    initialize();
    //创建EglSurface
    EGLSurface surface = eglCreateWindowSurface(mEglDisplay, mEglConfig, window, nullptr);
         return surface;
}

//最后创建egl_window_surface_v2_t,将window当成ANativeWindow
static EGLSurface createWindowSurface(EGLDisplay dpy, EGLConfig config,
        NativeWindowType window, const EGLint* /*attrib_list*/)
{
   ...
    egl_surface_t* surface;
   //其实返回的就是egl_window_surface_v2_t
    surface = new egl_window_surface_v2_t(dpy, config, depthFormat,
            static_cast<ANativeWindow*>(window));
..	    return surface;
}

摘一张图:

总结流程

初始化流程

参考文章

android硬件加速

GPU渲染简介

GPU和CPU的渲染和渲染管道出图原理

Android硬件加速(二)-RenderThread与OpenGLGPU渲染

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-08-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Android硬件加速(二)-RenderThread与OpenGL GPU渲染
Android4.0之后,系统默认开启硬件加速来渲染视图,之前,理解Android硬件加速的小白文简单的讲述了硬件加速的简单模型,不过主要针对前半阶段,并没怎么说是如何使用OpenGL、GPU处理数据的,OpenGL主要处理的任务有Surface的composition及图形图像的渲染,本篇文章简单说一下后半部分的模型,这部分对于理解View渲染也有不少帮助,也能更好的帮助理解GPU渲染玄学曲线。
看书的小蜗牛
2018/08/16
10.7K0
Android硬件加速(二)-RenderThread与OpenGL GPU渲染
理解Android硬件加速原理的小白文
硬件加速,直观上说就是依赖GPU实现图形绘制加速,软硬件加速的区别主要是图形的绘制究竟是GPU来处理还是CPU,如果是GPU,就认为是硬件加速绘制,反之,软件绘制。在Android中也是如此,不过相对于普通的软件绘制,硬件加速还做了其他方面优化,不仅仅限定在绘制方面,绘制之前,在如何构建绘制区域上,硬件加速也做出了很大优化,因此硬件加速特性可以从下面两部分来分析:
看书的小蜗牛
2018/06/29
2.1K0
理解Android硬件加速原理的小白文
硬件渲染源码分析流程详解
硬件渲染中采用AttachInfo的mThreadRenderer.draw方法传入view,attachinfo和ViewRootImpl开始硬件渲染。
小柔
2022/10/09
1.3K0
软件绘制 & 硬件加速绘制 【DisplayList & RenderNode】
两者都是从SF获取一块内存,绘制都是在APP端,绘制好后都是通知SF去进行合成图层
北洋
2023/09/18
7260
软件绘制 &amp; 硬件加速绘制 【DisplayList &amp; RenderNode】
两者都是从SF获取一块内存,绘制都是在APP端,绘制好后都是通知SF去进行合成图层
小柔
2022/10/09
1.5K0
软件绘制 &amp; 硬件加速绘制 【DisplayList &amp; RenderNode】
【Android 音视频开发打怪升级:OpenGL渲染视频画面篇】四、深入了解OpenGL之EGL
前面的文章就介绍过,OpenGL是基于线程的,直到目前为止,我们并没有深刻的认识到这个问题,但我们知道的是,当我们继承GLSurfaceView.Renderer时,系统会回调以下方法:
开发的猫
2020/04/02
2.7K0
【Android 音视频开发打怪升级:OpenGL渲染视频画面篇】四、深入了解OpenGL之EGL
硬件加速绘制基础知识
OPENGL 是统一不同厂商GPU绘制的接口,通过GPU的计算得到一张图片(内存中的一块Buffer保存着信息)
小柔
2022/10/09
6730
图片的实时渲染和离屏渲染
之前我们比较多的介绍视频的渲染和处理,本文我们想谈一谈图片,和视频比起来,图片确实相对简单点,我们知道视频本质上是一帧帧的“图片”组成的,都了解了视频了,图片还需要去了解吗?图片的渲染和视频有相通之处,也有其独特的特点。
马上就说
2023/03/05
2.1K0
图片的实时渲染和离屏渲染
OpenGL 之 EGL 使用实践
而当我们使用这组接口完成绘制之后,要把结果显示在屏幕上,就要用到 EGL 来完成这个转换工作。
音视频开发进阶
2019/07/25
3.1K0
音视频直播技术--视频渲染之EGL
我们在Andriod系统下做视频渲染时要使用 OpengGL ES, 而使用 OpengGL ES 就不得不提到 EGL。那么EGL是什么呢?它又在渲染时起到什么作用呢?今天我就给大家介绍一下 EGL.
音视频_李超
2020/04/02
2K0
Android配置EGL环境C++版
android搭建opengles 的egl环境之前使用java已经写过,但是一般实际开发opengles的相关代码都在native层,因为native的话效率会比java高很多,步骤都是一致的,只是换一种语言写而已。之前使用java写的opengles egl环境搭建点击下面链接: https://www.jianshu.com/p/ce3496ab9e02
曾大稳
2020/01/20
1.5K0
Android配置EGL环境C++版
hwui介绍与分析
hwui全称**HardwareAcceleratedRenderingEngineforUI,**hwui是一个基于GPU加速的2D图形引擎。HWUI的目标是提供高效、稳定、高质量的2D图形渲染能力,为Android系统的UI体验提供技术支持。
用户1907613
2023/09/17
2.5K0
hwui介绍与分析
从零开始仿写一个抖音App——Android绘制机制以及Surface家族源码全解析
本文首发于微信公众号——世界上有意思的事,搬运转载请注明出处,否则将追究版权责任。微信号:a1018998632,交流qq群:859640274
何时夕
2019/03/04
3.2K0
从零开始仿写一个抖音App——Android绘制机制以及Surface家族源码全解析
Android 图形架构
要理解Android的图形架构,我们需要先理解window的概念。维基百科中给window的定义是:Window是图形用户界面(GUI)系统中显示器上一个单独的视图区域(可以想象你电脑桌面上一个个窗口)。
字节流动
2022/09/26
2.6K0
EGL 作用及其使用
EGL 是 OpenGL ES 渲染 API 和本地窗口系统(native platform window system)之间的一个中间接口层,EGL作为OpenGL ES与显示设备的桥梁,让OpenGL ES绘制的内容能够在呈现当前设备上。它主要由系统制造商实现。
字节流动
2021/06/09
2.6K0
EGL 作用及其使用
【Android 音视频开发打怪升级:FFmpeg音视频编解码篇】
在 Java 层,Android 已经为我们提供了 GLSurfaceView 用于 OpenGL ES 的渲染,我们不必关心 OpenGL ES 中关于 EGL 部分的内容,也无需关注 OpenGL ES 的渲染流程。
开发的猫
2020/06/03
2.3K0
RenderDemo(1):用 OpenGL 画一个三角形丨音视频工程示例
这个公众号会路线图式的遍历分享音视频技术:音视频基础 → 音视频工具 → 音视频工程示例 → 音视频工业实战。关注一下成本不高,错过干货损失不小 ↓↓↓
关键帧
2022/11/29
1.4K0
RenderDemo(1):用 OpenGL 画一个三角形丨音视频工程示例
Android配置EGL环境
Android配置egl环境我们根据GLSurfaceView源码来实现。在GLSurfaceView源码里面,当调用setRenderer的时候会开启一个线程GLThread,GLThread调用start的时候会初始化EglHelper来配置egl环境,然后一个while(true)执行,根据不同的标识判断执行egl的环境配置,Renderer的onSurfaceCreated,onSurfaceChanged,onDrawFrame等函数。
曾大稳
2018/09/11
1.5K0
学习 OpenGL ES 之前,你需要了解下 EGL
EGL 是 OpenGL ES 和本地窗口系统(Native Window System)之间的通信接口,它的主要作用:
字节流动
2021/11/10
4.2K1
OpenGL ES 共享上下文实现多线程渲染
EGL 是 OpenGL ES 和本地窗口系统(Native Window System)之间的通信接口,它的主要作用:
字节流动
2021/06/04
6.9K0
推荐阅读
相关推荐
Android硬件加速(二)-RenderThread与OpenGL GPU渲染
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验