aosp11/12/13 壁纸高斯模糊,毛玻璃SurfaceFlinger层面原理-第二节千里马framework实战

news2024/9/21 5:33:15

hi,粉丝朋友们!
上一个blog已经详细讲解了系统中自带相关接口实现窗口的高斯模糊相关效果,具体点击这里
https://blog.csdn.net/learnframework/article/details/130767893

1、补充app层面实现方式

更多framework干货知识手把手教学

Log.i("qq群",“422901085);

这里额外也补充一下另一种实现方式其实也可以实现:

                if (getWindow().getRootSurfaceControl() != null &&
                        getWindow().getRootSurfaceControl() instanceof ViewRootImpl) {
                    SurfaceControl surfaceControl = ((ViewRootImpl)getWindow().getRootSurfaceControl()).getSurfaceControl();
                    SurfaceControl.Transaction transaction = new SurfaceControl.Transaction();
                    transaction.setBackgroundBlurRadius(surfaceControl,100);
                    transaction.apply();
                    android.util.Log.i("lsm"," setBackgroundBlurRadius");
                }

在这里插入图片描述

其实也就说明关键就是要对这个图层的surfacecontrol进行设置对应的BackgroundBlurRadius即可以,上一节分析的Dim图层也设置了对应的BackgroundBlurRadius
下面开始进入app层面调用了setBackgroundBlurRadius后,SurfaceFlinger是怎么处理的

2、SurfaceFlinger部分源码原理分析

先看看app的setBackgroundBlurRadius接口

      /**
         * Sets the background blur radius of the {@link SurfaceControl}.
         *
         * @param sc SurfaceControl.
         * @param radius Blur radius in pixels.
         * @return itself.
         * @hide
         */
        public Transaction setBackgroundBlurRadius(SurfaceControl sc, int radius) {
            checkPreconditions(sc);
            nativeSetBackgroundBlurRadius(mNativeObject, sc.mNativeObject, radius);
            return this;
        }

可以看到调用是nativeSetBackgroundBlurRadius方法,是个native的方法:

static void nativeSetBackgroundBlurRadius(JNIEnv* env, jclass clazz, jlong transactionObj,
         jlong nativeObject, jint blurRadius) {
    auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);

    SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
    transaction->setBackgroundBlurRadius(ctrl, blurRadius);
}

这里调用的是SurfaceComposerClient::Transaction的setBackgroundBlurRadius

SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setBackgroundBlurRadius(
        const sp<SurfaceControl>& sc, int backgroundBlurRadius) {
    layer_state_t* s = getLayerState(sc);
    if (!s) {
        mStatus = BAD_INDEX;
        return *this;
    }
    s->what |= layer_state_t::eBackgroundBlurRadiusChanged;
    s->backgroundBlurRadius = backgroundBlurRadius;
    return *this;
}

这里其实也比较简单就是针对的layer_state_t结构体的backgroundBlurRadius进行了设置

这里一般会跨进程最后调用到surfaceflinger服务端的Layer.cpp

bool Layer::setBackgroundBlurRadius(int backgroundBlurRadius) {
    if (mDrawingState.backgroundBlurRadius == backgroundBlurRadius) return false;
    // If we start or stop drawing blur then the layer's visibility state may change so increment
    // the magic sequence number.
    if (mDrawingState.backgroundBlurRadius == 0 || backgroundBlurRadius == 0) {
        mDrawingState.sequence++;
    }
    mDrawingState.backgroundBlurRadius = backgroundBlurRadius;
    mDrawingState.modified = true;
    setTransactionFlags(eTransactionNeeded);
    return true;
}

主要就是把这个backgroundBlurRadius赋值给mDrawingState.backgroundBlurRadius

下面就看看SurfaceFlinger里面是怎么使用这个的backgroundBlurRadius属性的
最后发现其实是在./libs/renderengine/gl/GLESRenderEngine.cpp中进行渲染时候进行的使用
其实这里也非常好理解,因为高斯模糊,这属于图像处理,当然不能让cpu来干,应该让GPU干,所以自然很容易想到opengl渲染部分进行的高斯模糊处理

void GLESRenderEngine::drawLayersInternal(
        const std::shared_ptr<std::promise<RenderEngineResult>>&& resultPromise,
        const DisplaySettings& display, const std::vector<LayerSettings>& layers,
        const std::shared_ptr<ExternalTexture>& buffer, const bool useFramebufferCache,
        base::unique_fd&& bufferFence) {
    ATRACE_CALL();
    //省略
    std::deque<const LayerSettings> blurLayers;
    if (CC_LIKELY(mBlurFilter != nullptr)) {
        for (const auto& layer : layers) {
            if (layer.backgroundBlurRadius > 0) { //遍历出这个backgroundBlurRadius的layer
                blurLayers.push_back(layer);
            }
        }
    }
    const auto blurLayersSize = blurLayers.size();
//省略

    for (const auto& layer : layers) { //遍历所有图层layer进行相关的渲染,注意这里是从底到顶的顺序
        if (blurLayers.size() > 0 && blurLayers.front() == layer) {//如果遍历到了设置了blurebehind的layer
            blurLayers.pop_front();

            auto status = mBlurFilter->prepare(); //准备相关的模糊参数
          
            if (blurLayers.size() == 0) {//假设已经没有了那么就开始设置好相关的buffer
                //这里很关键,会把已经绘制的FrameBuffer进行获取,后面把这个数据进行对应的blur
                // Done blurring, time to bind the native FBO and render our blur onto it.
                fbo = std::make_unique<BindNativeBufferAsFramebuffer>(*this,
                                                                      buffer.get()
                                                                              ->getBuffer()
                                                                              ->getNativeBuffer(),
                                                                      useFramebufferCache);
                status = fbo->getStatus();
                setViewportAndProjection(display.physicalDisplay, display.clip);
            } else {
             //省略这种情况
            }
           
					//进行真的模糊
            status = mBlurFilter->render(blurLayersSize > 1);
        }
				//省略
        if (layer.source.buffer.buffer != nullptr) {//这里正常的layer渲染
          //省略
        }
//省略
    return;
}

代码相对较多,这里只需要理解以下几个关键点:

1、遍历layers时候是底部layer先开始,这个需要注意
为啥这样呢?想想这里是相当于surfaceflinger要把各个图层渲染到一个新的屏幕画布,当然是底部的layer先画

2、识别到有blurbehind的layer时候,要把之前的已经渲染好了的layer的整体画面进行blur模糊,然后再继续绘制的前的layer的画面
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/547942.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Restful API

Restful API 一、RESTful API是什么意思二、对比三、小知识四、用 apifox 进行测试1. GET2. POST3. PUT4. DELETE 一、RESTful API是什么意思 REST 与技术无关&#xff0c;代表的是一种软件架构风格&#xff0c;REST是Representational State Transfer的简称&#xff0c;中文翻…

操作系统实验三 内存分配及回收研究

前言 本次实验跟前两次相比简单许多&#xff0c;主要是体会底层的一些运行机制。其实&#xff0c;要说简单&#xff0c;也不是真的很简单&#xff0c;毕竟还是存在一些更底层的东西需要我们去探讨。接下来就让我们通过实验来感受一下。 1.实验目的 掌握Linux操作系统的内存分…

地表水灌区取水计量设施包含哪些设备?

方案背景 根据《关于强化取水口取水监测计量的意见》、《十四五”节水型社会建设规划》以及《2022年水资源管理工作要点》等政策要求&#xff0c;为强化水资源管理&#xff0c;做好水资源税改革&#xff0c;构建节水型社会&#xff0c;要全面加强取水计量监测设施建设&#xff…

【计算机系统基础3】数据的存储与运算

3.程序调试与实践&#xff1a;数据存储与运算 3.1真值与机器数 真值&#xff1a; 数据在现实世界中的表示 机器数&#xff1a; 数据在计算机内部的二进制编码表示 温度&#xff1a;零下3.5度 习惯写法&#xff1a;-3.5 (数据的真值/数据的实际值) 3.1.1整数的编码 带符号整数&…

15:13进去面试,5分钟就完事了,问的实在是太......

干了两年外包&#xff0c;本来想出来正儿八经找个互联网公司上班&#xff0c;没想到算法死在另一家厂子。 自从加入这家外包公司&#xff0c;每天都在加班&#xff0c;钱倒是给的不少&#xff0c;所以也就忍了。没想到11月一纸通知&#xff0c;所有人不许加班&#xff0c;薪资…

2023年值得关注的低代码平台推荐

低代码平台在数字化转型的浪潮中受到越来越多企业的青睐&#xff0c;因为它们提供了一种更容易、更快的方式来开发网络和移动应用程序。低代码平台只需要最少的编码知识&#xff0c;使公司能够在很短的时间内开发出定制的应用程序&#xff0c;而这只是使用传统的搭建手段所需时…

参数传递之传名,传地址,得结果,传值

编译原理速成&#xff0c;参数传递之传名&#xff0c;传地址&#xff0c;得结果&#xff0c;传值(四)_哔哩哔哩_bilibili 学习自上面的文章。 题目1&#xff1a; &#xff08;1&#xff09;传名。 (2)传地址。&#xff08;注意观察&#xff0c;AB变成了临时变量T1&#xff0c;…

jvm之G1 GC

写在前面 jdk9以及之后的版本已经将默认的垃圾收集器parallel更换为G1.本文就一起来看下。 1&#xff1a;G1介绍 parallel GC的设计目标是高吞吐量&#xff0c;CMS GC的设计目标是低延迟&#xff0c;而G1的设计目标不是这二者中的任何一个&#xff0c;其设计目标是让GC的STW…

我的世界Fabric mod开发-快速漏斗

前往我的主页以阅读完整内容&#xff0c;并获取源码 DearXuan的主页 MOD介绍 使用漏斗链进行分类或传递物品时,常常会发现漏斗速度太慢,难以收集全部掉落物.或者漏斗太多,影响性能.而现有的漏斗加速mod则是引入新的快速漏斗,存在各种兼容问题.开服时发现paper服务器可以修改原…

华为OD机试真题 Java 实现【区间连接器】【2023Q1 200分】

一、题目描述 有一组区间 [a0, b0], [a1, b1], … (a, b 表示起点, 终点)&#xff0c;区间有可能重叠、相邻&#xff0c;重叠或相邻则可以合并为更大的区间&#xff1b; 给定一组连接器[x1, x2, x3, …]&#xff08;x 表示连接器的最大可连接长度&#xff0c;即 x>gap&…

支付宝沙箱支付(java电脑版)

目录 下载支付demo配置环境AlipayConfig 下载支付demo 网址&#xff1a;https://open.alipay.com/ 下载并打开项目发现无法运行&#xff1a; 手动转化项目&#xff1a; 等待下载整理一下maven pom 通过tomat部署运行测试。 导入阿里支付的pom依赖 <dependency> &l…

都2023了,你竟然还不知道网络安全该怎么学

前言 网络安全是指网络系统的硬件、软件及其系统中的数据受到保护&#xff0c;不因偶然或恶意原因而遭受破坏、更改、泄露&#xff0c;系统连续可靠正常地运行&#xff0c;网络服务不中断。网络安全因何而重要&#xff1f; 截至2023年4月,我国网民规模为_11.51亿_&#xff0c…

模板初阶(泛型编程)

模板初阶 &#x1f506;泛型编程&#x1f506;函数模板函数模板概念函数模板格式函数模板的原理函数模板的实例化模板参数的匹配原则 &#x1f506;类模板类模板的定义格式类模板的实例化类模板与模板类的区别 &#x1f506;结语 &#x1f506;泛型编程 泛型编程&#xff1a;编…

【总结】Numpy2

Numpy 1. 数组和数的运算 array1 np.arange(1,10) array1 # array([1, 2, 3, 4, 5, 6, 7, 8, 9]) array1 10 # array([11, 12, 13, 14, 15, 16, 17, 18, 19]) array1 - 10 # array([-9, -8, -7, -6, -5, -4, -3, -2, -1]) array1 * 10 # array([10, 20, 30, 40, 50, 60, 70…

Flutter:如何在Android中实现串口通信调试

本文介绍如何通过flutter_libserialport插件在Flutter中实现串口通信调试。 1、引入依赖 在flutter工程的pubspec.yaml文件中引入flutter_libserialport依赖&#xff1a; dependencies:flutter_libserialport: ^0.3.0 2、导入import依赖包 在dart代码中import导入flutter_li…

快手国际化 后端开发面经二面

目录 1.Redis用的什么数据类型2.Hash底层结构3.JVM垃圾判别阶段算法4.MySQL索引模型5.为什么用B树6.联合索引在B树如何构造的7.覆盖索引知道吗 1.Redis用的什么数据类型 1.String(字符类型) 2.Hash(散列类型) 3.List(列表类型) 4.Set(集合类型) 5.SortedSet(有序集合类型&…

设计模式 单例模式(创建型)

一、前言 学习设计模式我们关注的是什么&#xff0c;如何实现么&#xff1f;是也不是。我认为比了解如何实现设计模式更重要的是这些设计模式的应用场景&#xff0c;什么场景下我们该用这种设计模式&#xff1b;以及这些设计模式所包含的思想&#xff0c;最终帮助我们把代码写…

继承 + 多态 + final + 权限修饰符

目录 继承 多态 final 权限修饰符 继承 继承定义&#xff1a; 可以让类跟类之间产生子父的关系继承的好处 可以把多个子类中重复的代码抽取到父类中&#xff0c;子类可以直接使用&#xff0c;减少代码几余&#xff0c;提高代码的复用性子类继承内容 非私有private构造方法…

#机器学习--深度学习中的正则化

#机器学习--深度学习中的正则化 引言1、参数范数惩罚2、 L 2 L^{2} L2 正则化3、 L 1 L^{1} L1 正则化4、显式约束和重投影5、参数绑定和参数共享6、Bagging7、Dropout 引言 本系列博客旨在为机器学习(深度学习)提供数学理论基础。因此内容更为精简&#xff0c;适合二次学习的…

uniapp实现条码扫描 可开闪光灯,原生H5调用,不需要任何sdk。

主要思路 使用QuaggaJs这个库。调用摄像头使用的 navigator.mediaDevices.getUserMedia 这个H5的api。通过 video 和 canvas 把摄像头获取到的数据展现到页面上&#xff0c;同时调用监听Quagga解析。 获取设备摄像头权限,用于后续开启摄像头。创建video元素显示摄像头画面,和ca…