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

AndroidR护眼模式流程分析(上) 护眼模式概述 研究表明,屏幕的蓝光会对睡眠质量造成不良影响。Android 7.1.1 推出一种称为“护眼模式”的功能,可减少设备屏幕发出的蓝光量,以便达到更接近用户当前时间和地点的自然光效果。Android 8.0 推出一项附加功能,可让用户更好地控制护眼模式效果的强度。 Android 10 推出了 COLOR_DISPLAY_SERVICE 系统服务,具备系统 API 接口,使系统、“设置”和系统界面能够更好地控制所有颜色转换(包括护眼模式)。 护眼模式需要实现 Hardware Composer H 阅读详情

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

1、补充app层面实现方式

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

                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的画面
在这里插入图片描述

Android R 原生模糊效果原理 Android原生模糊效果原理 上图是Android S上面的原生模糊效果图,在AndroidS提供了如下setBackgroundBlurRadius 函数给到app是添加模糊效果。 public void setBackgroundBlurRadius (int blurRadius) Blurs the screen behind the window within the bounds of the window. The density of the blur is set by the 阅读详情

相关推荐

用STM32的SPI接口读取MT6835磁编码器,手把手教你避开数据读取的坑

本文详细介绍了如何使用STM32的SPI接口读取MT6835磁编码器,并提供了21个实战细节与避坑指南。从硬件连接、SPI配置到数据解析和实时调试,全面解析了读取位置信息过程中的常见问题及解决方案,帮助工程师在工业控制、伺服电机等场景中高效应用AMR技术。

weixin_30729609的博客 1441

深入Android Framework开发(入门篇)

广大的Android应用开发者是不是对Android系统充满着好奇,是不是很想学习Android系统开发,可惜自己学习难度又太大,本课程将手把手教你学Android Framework开发,带你走进Android系统开发的殿堂,全课程以实战为主,让你自己动手可以定制自己喜欢的Android系统,让你的Android职业道路越走越顺。 学完本课程能让你学会如下知识点: -学习Framework背景及它的巨大作用-Android源码环境搭建及让自己系统第一次跑起来-学习Frameowork开发的一些必要基础知识-学习怎么进行Android源码定位分析,实例:Activity启动流程源码分析-实战开发Frameowork项目--去除第三方应用入口广告页

G2O (General Graph Optimization)入门及简单使用

g2o全称是General Graph Optimization,也就是图优化,我们在做SLAM后端或者更加常见的任何优化问题(曲线拟合)都可以使用G2O进行处理。

晓晨的博客 1万+

android 车载widget小部件部分详细源码实战开发-千里马车载车机framework开发实战课程

通俗解释:一个能够定期刷新并且加到其他应用上的微型视图。

learnframework的博客 1423

基于STM32的简易电压、频率、占空比测量仪

任务详解:我们需要实现三个功能: 第一个是测频率的功能,输入信号为频率为1kHz~10kHz的三种波形(方波、三角波、正弦波),这也是我们最常见的三种波形。幅度是不需要测量的,所以先不关心幅度。 第二个是电压报警功能,当输入信号的幅度超过15V时,我们需要报警(这里我用了一个红色LED当报警器,有条件的还可以加个蜂鸣器)并且把此时的信号幅度显示在OLED屏幕上。 第三个是通信方式的要求,需要有串口通信功能。 第四个是计算占空比的任务,这个任务的输入是幅度为1V~10V、频率为20Hz ~1kHz的方波,需要

weixin_43469377的博客 7251

VulnHub--mrrobot

Vulnhub靶场--Mr robot 靶机

记录笔记 1097

Android源码环境搭建(aosp Ubuntu 16.04 20.04)

Android源码环境搭建(aosp Ubuntu 16.04) 作者:千里马 课程要求: 电脑配置:双核,内存最少 16G,硬盘 200G 以上,独立安装 Ubuntu16.4 系统 学员要求:最少 1 年以上应用开发经验,推荐在 3 年左右 Android 应用开发经验, 熟悉 Java 语言,可以看懂 C/C++ 1、安装 ubuntu16.04(因为这个版本可以直接安装 openjdk-8,如果其他版本自行找方法) 2、openjdk 8 的安装 sudo apt-get install openj

learnframework的博客 2万+

ADT MCP Server 把 ABAP 开发带进 Agent 模式

今天讨论 ADT MCP Server,不能只把它看成 Visual Studio Code 里多出来的一个开关。它真正有意思的地方,在于它把 ABAP 后端开发里那些原本需要手工点击、手工创建、手工激活、手工查服务元数据的动作,包装成一组可以被 GitHub Copilot 这类 coding agent 调用的工具。SAP 在 RAP130 练习里把它描述为运行在 ADT for Visual Studio Code 扩展内部的本地 HTTP Server,它实现的是 Model Context Pro

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 184

跟千里马学框架 遇到的坑

加一个临时的环境变量 : export ANDROID_PRODUCT_OUT=你自己的源码路径/out/target/product/generic_x86_64。在编译 aosp 的 所有的东西都是和他一样的, 但是出现了这个问题。首先你的 ubuntu 要开启虚拟机。明明所有的都是一样的但是出现了这个问题 , 啥情况。这里我们选择:6 –-- > aosp_x86_64。然后在进行 : emulator。

qq_26500807的博客 618

stable diffusioncontrolNet 预处理器/模型的下载及安装使用教程

首先说明,controlNet 的模型 不同于stable diffusion 模型,这一点一定要区分清楚。下面提供多个ControlNet 预处理器+ 专用模型的百度网盘下载链接,都是由群友整理贡献,但各自包含的版本不同,大家可自行选择。推荐下载紫色链接内的模型,fp16版文件更小,稍微新一些的controlnet插件还添加了对control-lora的支持(注意,要求controlnet插件的版本比12月16号新(1.1.423以上)才能正常识别),推荐下载;

代码简单说 Vue、JAVA、PHP、Node.js 熟练运用,接口、架构、性能全搞定。 3385

使用ChatGPT工具阅读文献的实战教程

本文介绍核心内容为使用ChatGPT工具阅读文献,希望对学习和使用ChatGPT的同学们有所帮助。为了兼顾质量和速度,本专栏的更新频率为一周一到两更。 文章目录 1. 前言 2. 实战教程 2.1 下载工具并登录 2.2 提取文献中的关键信息

herosunly的博客 15万+

aosp13/14/15/16如何实现窗口局部区域高斯模糊毛玻璃效果及Winscope原生重大bug发现

以前高斯模糊原理也分析过,知道是在SurfaceFlinger触摸绘制时候进行的高斯模糊,那么再来分析一下高斯模糊相关实现时候是否有相关区域设置参数,从而反推出相关接口。简单说学员就是想实现对状态栏等区域局部进行高斯模糊,以前方案是针对窗口layer所有进行模糊,那么是否可以实现窗口的局部高斯模糊呢?但是上面分享模糊都是针对整个窗口进行的,就是桌面窗口设置一下后面窗口进行模糊的标志位,然后针对桌面窗口后面的壁纸窗口进行整体模糊。那么接下来要去探索aosp原生系统是否有接口支持局部高斯模糊呢?

learnframework的博客 871

基于Simulink进行步进电机的重复控制仿真建模

重复控制概述目的:通过引入一个周期延迟环节来补偿系统的周期性误差,从而提高系统对周期性参考信号或扰动的跟踪性能。方法内部模型原理:在控制器中嵌入一个与周期性信号相关的模型(例如周期延迟环节),以实现对周期性误差的零稳态误差控制。滤波器设计:为了避免高频噪声放大,通常会在重复控制器中加入低通滤波器。优势对周期性信号具有良好的跟踪性能。不需要精确的数学模型即可实现高性能控制。挑战:需要合理设计重复控制器的参数以避免系统不稳定。

amy_mhd的博客 268

从零开始学习Android Framework

这里写自定义目录标题欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入 欢迎使用Markdown编辑器 你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Mar

逸寒 2341

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

android studio调试debug 系统framework、systemserver方法-千里马带你学framework

hi,粉丝朋友们大家好! 近来很多学员在说想要在android系统里面用android studio进行直接调试,针对这个需求其实我以前是确实有尝试的,包括前期破解鸿蒙系统和android关系时候也是有用到的。 下面我来给大家介绍一下怎么在android studio调试我们的framework代码: 1、首先肯定得搭建好源码的导入android studio,并且可以达到正常跳转的地步,这个部分可以看我之前的blog,或者看我的android framework入门课(可以加我qq:2102309716

liaosongmao1的专栏 1166

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

千里马framework学习跨进程实战课程学员疑问解答:ClassNotFoundException when unmarshalling

hi,粉丝朋友们!

liaosongmao1的专栏 345

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

重大消息:手机车机互联投屏专题发布-千里马带你学框架

android投屏的使用场景以前在新能源车机还没火爆时候,大部分停留在手机小屏幕投屏到大屏幕的情况及整个多端设备的互动,整体需求和技术发展其实也就是比较有限,但是新能源车机火爆后,那么这种手机和车机互联互动的需求出现了爆发性增长,车机上各种创新类的交互都和这个手机车机之间的投屏有关系,因为手机的app生态和更新换代肯定比车机频繁,这样做好了手机车机互动投屏,可以让车机复用手机的强大功能。手机–>车机 --复用丰富的手机生态,和手机互动互联,弥补车机生态不足短板。├── 6-ByteBuffer的详细讲解。

learnframework的博客 1486

手把手教你做投屏AAC的详细介绍-千里马带你学framework

AAC(Advanced Audio Coding)是一种现代的音频编码技术,用于数字音频的传输和存储领域。AAC是MPEG-2和MPEG-4标准中的一部分,可提供更高质量的音频数据。AAC被认为是MP3的继任者。AAC比MP3的压缩率更高,压缩后的文件越小,二是保真性比MP3强。ACC最开始是基于MPEG-2的音频编码技术,MPEG-4标准出现后,AAC重新集成了其特性,加入了SBR技术和PS技术。特点:更好的声音质量和更低的压缩比,减少了由于压缩而引入的失真和噪音。

learnframework的博客 1036

Android下SF合成流程重学习之GPU合成

通过上述的代码我们可以看到在启动之初就搭建好了EGL环境,并将当前线程与context绑定,为后面使用gl命令做好准备,然后创建了ImageManager 线程,这个线程是管理输入Buffer的EGLImage,然后创建了GLFrameBuffer,用来操作输出的buffer。当需要GPU合成时,会通过生产者RenderSurface::dequeueBuffer请求一块图形缓存,然后GPU就合成/绘图,把数据保存到这块图形缓存中,通过RenderSurface::queueBuffer提交这块缓存。

IT先森 7912

千里马带你学framework:android 13 WM_SHELL_STARTING_WINDOW相关记录笔记

这里是为啥阿,因为高版本StartingWindow已经移殖到了Systemui进程,让Systemui来负责窗口创建相关,所以自然就wms端处理不了,要跨进程让systemui处理。这里注意,明显用wm开启时候,和正常wm相关的打印输出也是不一样的,明显显示是No IProtoLogGroup named WM_SHELL_STARTING_WINDOW。这个时候logcat -s WindowManager是没有这个shell相关打印,必须要。才可以打印出相关的Proto日志。

learnframework的博客 2307

截图框架代码原理 android 11

截图SurfaceControl.screenshot框架代码流程 一、应用端接口调用 Bitmap screenshot = SurfaceControl.screenshot(new Rect(),width,height,rotation);通过SurfaceControl.screenshot来获取一个bitmap对象,原理就是创造一个graphicBuffer ,屏幕上面各个lay...

zxtanshui的专栏 841

干货分享:aosp13锁屏壁纸部分原理剖析

这里主要就是到DataSystem目录获取对应的目录/data/system/users/0,加上锁屏壁纸对应的文件名字wallpaper_lock_orig,wallpaper_lock,构造出对应的File文件对象。到此服务端返回了fd后就业务完成,下面就是跨进程传递fd客户端,客户端拿到了fd后进行数据写入,这块回到最开头的WallpaperManager.java的setStream方法既可以。这里在设置的壁纸中就有壁纸设置的入口,选择正确壁纸图片,然后可以选着设置锁屏还是桌面壁纸。

learnframework的博客 847

手把手教你aosp android 12 pixel 解锁oem 编译刷入大全

hi,因为同学们学完了我的课程后,开始想玩一下google的pixel实体机,不想一直玩模拟器了,那么千里马老师今天也在咸鱼上掏了一个pixel 3来给大家展示一下这个google的机子怎么玩,其实我自己本身是有小米的lineage系统在玩,为了满足广大粉丝的好奇心也就自掏腰包买了个pixel玩,下面我们正式开始记录整个pixel 3的刷入自己编译修改的aosp代码: 入门课,实战课,跨进程专题,input专题 ps需要学习深入framework课程和课程优惠 新课程优惠获取请加入qq群:422901085

learnframework的博客 1万+

android11 SurfaceFlinger 服务启动分析

android SurfaceFlinger 服务启动分析

我的博客 1295
上一篇: android13 FLAG_BLUR_BEHIND 壁纸高斯模糊,毛玻璃背景方案设计-千里马framework实战
下一篇: 安卓漏洞揭秘-android投屏scrcpy支持声音部分调研-千里马framework投屏开发
千里马学框架
博客等级 码龄6年 1万+粉丝 650原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

千里马学框架

帮助你了,就请我喝杯咖啡

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值