Surface 和 SurfaceHolder

2024-04-20 21:08
文章标签 surface surfaceholder

本文主要是介绍Surface 和 SurfaceHolder,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Surface 类自 1.0 版本开始就是公共 API 的一部分了。它的描述简单地说,“处理由屏幕合成器管理的原始缓冲区”。该陈述在最初编写时是准确的,但在现代系统上却与事实相去甚远。

Surface 表示一个常常(但不总是!)由 SurfaceFlinger 消费的 buffer queue 的生产者端。当你渲染到 Surface 上时,结果最终将进入被传递给消费者的缓冲区中。Surface 不简单地是一块你可以随意涂鸦的原始内存块。

显示 Surface 的 BufferQueue 通常配置为三重缓冲;但缓冲区是根据需要分配的。因此如果生产者产生缓冲区的速度足够慢 - 可能它是在 60fps 的显示器上执行 30fps 的动画 - 队列中可能只有分配的两块内存。这可能有助于最小化内存消耗。你可以在 dumpsys SurfaceFlinger 的输出中看到与每个 layer 关联的缓冲区的摘要。

Canvas 渲染

曾经一段时间,所有的渲染都是通过软件完成的,今天你依然可以这样做。底层的实现是由 Skia 图形库提供的。如果你想绘制一个矩形,你执行一个库调用,然后它将适当地设置缓冲区中的字节。为了确保不会有两个客户端同时更新一块缓冲区,或在显示时被写入,你不得不锁定缓冲区然后访问它。lockCanvas() 锁定缓冲区并返回一个 Canvas 用于绘制,然后 unlockCanvasAndPost() 解锁缓冲区并把它发送给合成器。

随着时间的推移,带有通用 3D 引擎的设备出现了,Android 围绕 OpenGL ES 重新定位。然而,对于应用及应用框架代码,保持老的 API 正常工作非常重要,所以努力进行
Canvas API 的硬件加速化。正如你在 硬件加速 页的图中所看到的那样,这是一段颠簸的旅程。特别要注意的是尽管为 View 的 onDraw() 方法提供的 Canvas 可能是硬件加速化了的,当一个应用通过 lockCanvas() 直接锁定 Surface 时获得的 Canvas 则从不是。

当你锁定 Surface 获得 Canvas 的访问权限时,“CPU 渲染器” 连接到 BufferQueue 的生产者端且直到 Surface 被销毁才断开。大多数其它的生产者(比如 GLES)可以被断开并重连到 Surface,但基于 Canvas 的 “CPU 渲染器” 不能。这意味着如果你曾经为了一个 Canvas 锁定了它,你就不能用 GLES 在一个 surface 上绘制,或者从视频解码器向它发送帧。

生产者第一次从 BufferQueue 请求数据缓冲区时,它被分配并被初始化为 0。为了避免进程间无意的数据共享,初始化是必须的。当你复用缓冲区时,然而,之前的内容将依然存在。如果你重复地调用 lockCanvas()unlockCanvasAndPost() 而不绘制任何东西,你将在先前渲染的帧之间循环。

Surface 锁定/解锁代码持有一个到先前渲染的缓冲区的引用。当锁定 Surface 时你指定了一个 dirty 区域,它将从先前的缓冲区中拷贝非 dirty 的像素。缓冲区有可能由 SurfaceFlinger 或 HWC 处理;但是由于我们只需要从中读取,所以无需等待独占访问。

应用主要的直接向 Surface 绘制的非 Canvas 方式是通过 OpenGL ES。 EGLSurface 和 OpenGL ES 的部分将描述这些。

SurfaceHolder

一些使用 Surfaces 的东西需要一个SurfaceHolder,特别是SurfaceView。最初的想法是 Surface 表示原始的合成器管理的缓冲区,而 SurfaceHolder 由应用管理并追踪更高层的信息,比如尺寸和格式。Java 语言定义镜像了底层本地的实现。以这种方式分裂它可能不再有用,但它一直是公共API的一部分。

一般来说,任何与 View 有关的东西将被包含进 SurfaceHolder。一些其它的 APIs,比如
MediaCodec,将在 Surface 上运行。你可以简单地从 SurfaceHolder 获得 Surface,因此当你拥有 Surface 时,请将其挂在后者上。

获取和设置 Surface 参数的 APIs,比如大小和格式,是通过 SurfaceHolder 实现的。

原文

这篇关于Surface 和 SurfaceHolder的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/921325

相关文章

android的surface

相信很多Android开发者都知道Canvas类是UI的画布(虽然这种说法并不严谨),因为我们在Canvas上完成各种图形的绘制,那么我们Activity上的各种交互控件又是如何展示并渲染到屏幕上的呢,所以在另一个层面上也有一个“画布”角色——Surface,接下来我们将一起揭开其神秘面纱。 Surface 是Android系统中真正的画布,Activity上的所有UI都是在Surface 上完

GEE:Landsat C01和C02数据集进行LST(Land Surface Temperature)地表温度分析

LST(Land Surface Temperature) LST(Land Surface Temperature)是指地表温度,是地表上空气与地表之间的热交换过程的结果。地表温度是一个重要的地理要素,对气候研究、气象预报、农业生产、环境评估等方面有着重要的影响。下面将详细介绍LST的定义、计算方法以及其在不同领域的应用。 首先,LST的定义是指地表的温度,即地球表面的实际温度。它与空气温度

Surface安装Windows和Ubuntu双系统方法(包括Ubuntu适配触控屏的方法)

这是一个目录0.0 前言让我们从一块砖头开始现在你有了能进入windows系统的surface并且想安装Ubuntu现在Ubuntu也有了再见 前言   之前我的Surface装上Ubuntu了好好的,能用,但是Ubuntu原本的内核是不支持很多Surface的功能的,比如触控屏,说实话触控屏也确实不怎么常用,但是很多时候就是那种“我可以不用,但你不能没有”的心态,说不定什么

Android Surface对应的Buffer怎么传递给HWC

Android Surface对应的Buffer怎么传递给HWC 引言 因为要预研Android Video overlay,需要将SurfaceView对应的GraphicBuffer从drm_hwcomposer中剥离出来,这就需要们了解SurfaceView对应的GraphicBuffer的前世今生,以及它的数据流向以及在各个模块之间的对应关系。这篇博客,我们分析下该Graphi

Android6.0 显示系统(二) SurfaceFlinger创建Surface

接上篇博客分析到SurfaceComposerClient中调用createSurface函数会最后调用到SurfaceFlinger的Client的createSurface函数。 我们来看下这个函数,其handle和gbp都是Binder对象,gbp就是图像缓冲区对象。这个handle对象的作用和前面介绍Activity中的token作用类似,也是利用Binder的唯一性为Surface

Android图形系统之Surface与SurfaceHolder关系(四)

Surface 对象使应用能够渲染要在屏幕上显示的图像。通过 SurfaceHolder 接口,应用可以编辑和控制 Surface。 1.Surface Surface 是一个接口,供生产方与消耗方交换缓冲区。 用于显示 Surface 的 BufferQueue 通常配置为三重缓冲。缓冲区是按需分配的,因此,如果生产方足够缓慢地生成缓冲区(例如在 60 fps 的显示屏上以 30 fp

ijkplayer源码分析之surface与opengl关联初始化(一)

ijkplayer源码分析之opengl与surface关联初始化 ===================================================== ijkplayer源码分析系列文章列表: ijkplayer源码分析之surface与opengl es关联初始化(一) ijkplayer源码分析之audio与opensl es初始化(二) ==========

Android用surface直接显示yuv数据(三)

本文用Java创建UI并联合JNI层操作surface来直接显示yuv数据(yv12),开发环境为Android 4.4,全志A23平台。 package com.example.myyuvviewer;import java.io.File;import java.io.FileInputStream;import android.app.Activity;import an

Android用surface直接显示yuv数据(一)

研究了一段时间Android的surface系统,一直执着地认为所有在surface或者屏幕上显示的画面,必须要转换成RGB才能显示,yuv数据也要通过颜色空间转换成RGB才能显示。可最近在研究stagefright视频显示时发现,根本找不到omx解码后的yuv是怎么转换成RGB的代码,yuv数据在render之后就找不到去向了,可画面确确实实的显示出来了,这从此颠覆了yuv必须要转换成R

Android用C++创建surface显示RGB数据

以下在Android 4.4平台开发测试,用于在屏幕直接显示RGB数据,当然,如果要直接显示YUV,写个函数转换一下也能直接显示。 其中从文件中获取RGB的RGB数据可以从这里下载 http://kc.cc/WeVp #include <cutils/memory.h>#include <unistd.h>#include <utils/Log.h>#include <binder/IP