UNDERSTANDING ANDROID GRAPHICS INTERNALS – GRAPHICS BASICS (I)

本文深入探讨了Android图形子系统的架构与实现原理,包括SurfaceFlinger的作用、原生窗口(ANativeWindow)的定义与使用,以及图形缓冲区的管理和传递机制。特别介绍了JellyBean版本中引入的垂直同步(vsync)和三缓冲机制如何改善帧率和平滑度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

In this post, it is presumed that you know about frame buffer driver, display control, display overlay, frame buffer, frame rate, common color space schemes, graphics pipeline ,EGL, Direct Rendering Infrastructure; If you do not, Wikipedia is an excellent source to learn these concepts.

The graphics subsystem underwent significant changes from ICS to Jelly Bean release which introduces vsync and triple buffering to improve on frame rate and animation smoothness along with major code refactoring.

  • Surfaces and centralized surface composition

Android graphics runs on top of the Linux graphics DRM driver and EGL, understandable that it did not port from X11 which services remote network login. SurfaceFlinger provides the compositor service and a UI application does not draw to the frame buffer directly, thus must obtain a surface of depth to draw graphics from SurfaceFlinger.

From UI application point of view, a surface is a rectangular canvas window on the screen with 2D geometrical metrics and a particular color scheme. The depth of the surface is specified upon acquisition.

The SurfaceFlinger determines when and whether a surface shows on the screen, partially or entirely; regions of a surface which is lower than other surfaces will not be displayed or will be blended with colors of higher surfaces; regions of a surface out of the scope of the display screen will not be drawn at all. SurfaceFlinger drivers the composition of surface areas and the rendering to the display screen.

  • What is a window on android? (ANativeWindow)

Each OS platform defines its distinct window structure and window types in EGL are derived from OS native window types. On android, the abstract window prototype is defined in system/core/include/system/window.h, namely ANativeWindow or its synonym EGLNativeWindowType in EGL as defined in frameworks/native/opengl/include/EGL/eglplatform.h, essentially two interchangeable terms in two domains.

Innately, a window is associated a certain count of graphic buffers which are used to contain drawing artifacts.

The struct ANativeWindow encompasses static attributes such as 2D resolutions and dynamic ones such as scaling modes, transforms, buffer swap interval range, a collection of callback function pointers.

The (*query)() callback is used to retrieve attributes from the native window.

The (*setSwapInterval) callback is to set swap interval.

(*queueBuffer), (*dequeueBuffer), (*cancellBuffer) are buffer operation routines; in JellyBean, the file descriptor fenceFd is the newly added argument linked to the fence in EGL extension API and is used for buffer idle signaling. When the window needs a fresh buffer to draw on, this callback is invoked to acquire one; when the current buffer is ready for rending, (*queueBuffer) is invoked to post the buffer for rendering. (*cancellBuffer) is invoked to cancel a buffer already dequeued but not used.

Another special (*perform) callback is invoked to perform customized operations. Valid operations include NATIVE_WINDOW_SET_USAGE, NATIVE_WINDOW_SET_CROP, NATIVE_WINDOW_SET_BUFFER_COUNT, NATIVE_WINDOW_SET_BUFFERS_TRANSFORM, NATIVE_WINDOW_SET_BUFFERS_FORMAT, NATIVE_WINDOW_SET_SCALING_MODE, NATIVE_WINDOW_LOCK,NATIVE_WINDOW_UNLOCK_AND_POST, NATIVE_WINDOW_API_CONNECT, NATIVE_WINDOW_API_DISCONNECT, NATIVE_WINDOW_SET_BUFFERS_USER_DIMENSIONS, NATIVE_WINDOW_SET_POST_TRANSFORM_CROP.

More operation codes may be added in the future.

Both ANativeWindow and ANativeWindowBuffer has a field common of type  struct android_native_base_t for reference counting checking.

  • The native graphic buffer handle

In Android, a surface is allocated in the SurfaceFlinger and is passed over binder interface to the client ui app. The buffer affiliated with the surface is also allocated in SurfaceFlinger and passes to client over binder interface. As a note here, if not using ion driver, a surface graphic buffer is consistently allocated in ashmem driver and linked with a process-unique file descriptor. The memory address for the buffer can be restored by re-mapping the file descriptor. The details of preserving the file descriptor and restoring the memory address varies from one platform hardware vendor to another. Android only defines a generic native graphic handle as follows insystem/core/include/cutils/native_handle.h; vendor-specific private handle extends this structure in the gralloc.c.

typedef struct native_handle
{
int version;        /* sizeof(native_handle_t) */
int numFds;         /* number of file-descriptors at &data[0] */
int numInts;        /* number of ints at &data[numFds] */
int data[0];        /* numFds + numInts ints */
} native_handle_t;

In window.h the actually used buffer is typedefed as

typedef const native_handle_t* buffer_handle_t;

  • The native graphic buffer ANativeWindowBuffer

The ANativeWindowBuffer is structured in the same file as ANativeWindow.

typedef struct ANativeWindowBuffer {

#ifdef __cplusplus     ANativeWindowBuffer() {

        common.magic = ANDROID_NATIVE_BUFFER_MAGIC;         common.version = sizeof(ANativeWindowBuffer);         memset(common.reserved, 0, sizeof(common.reserved));}

// Implement the methods that sp<ANativeWindowBuffer> expects so that it     // can be used to automatically refcount ANativeWindowBuffer's.    

void incStrong(const void* id) const {         common.incRef(const_cast<android_native_base_t*>(&common));     }    

void decStrong(const void* id) const {         common.decRef(const_cast<android_native_base_t*>(&common));     }

#endif

struct android_native_base_t common;

int width;    

int height;    

int stride;    

int format;    

int usage;

void* reserved[2];

buffer_handle_t handle;

void* reserved_proc[8]; }

ANativeWindowBuffer_t;

  • Flattenable

For easy traversing over binder interface, an  graphic object may opts to implement the Flattenable interface whose declaration is quoted below.

/*  * The Flattenable interface allows an object to serialize itself out  * to a byte-buffer and an array of file descriptors.  */

class Flattenable {

public:    

// size in bytes of the flattened object    

virtual size_t getFlattenedSize() const = 0;

// number of file descriptors to flatten    

virtual size_t getFdCount() const = 0;

// flattens the object into buffer.    

// size should be at least of getFlattenedSize()  

// file descriptors are written in the fds[] array but ownership is    

// not transfered (ie: they must be dupped by the caller of    

// flatten() if needed).    

virtual status_t flatten(void* buffer, size_t size,             int fds[], size_t count) const = 0;

// unflattens the object from buffer.    

// size should be equal to the value of getFlattenedSize() when the    

// object was flattened.    

// unflattened file descriptors are found in the fds[] array and    

// don't need to be dupped(). ie: the caller of unflatten doesn't    

// keep ownership. If a fd is not retained by unflatten() it must be    

// explicitly closed.    

virtual status_t unflatten(void const* buffer,   size_t size, int fds[], size_t count) = 0;

protected:     virtual ~Flattenable() = 0;

};

资源下载链接为: https://pan.quark.cn/s/22ca96b7bd39 在当今的软件开发领域,自动化构建与发布是提升开发效率和项目质量的关键环节。Jenkins Pipeline作为一种强大的自动化工具,能够有效助力Java项目的快速构建、测试及部署。本文将详细介绍如何利用Jenkins Pipeline实现Java项目的自动化构建与发布。 Jenkins Pipeline简介 Jenkins Pipeline是运行在Jenkins上的一套工作流框架,它将原本分散在单个或多个节点上独立运行的任务串联起来,实现复杂流程的编排与可视化。它是Jenkins 2.X的核心特性之一,推动了Jenkins从持续集成(CI)向持续交付(CD)及DevOps的转变。 创建Pipeline项目 要使用Jenkins Pipeline自动化构建发布Java项目,首先需要创建Pipeline项目。具体步骤如下: 登录Jenkins,点击“新建项”,选择“Pipeline”。 输入项目名称和描述,点击“确定”。 在Pipeline脚本中定义项目字典、发版脚本和预发布脚本。 编写Pipeline脚本 Pipeline脚本是Jenkins Pipeline的核心,用于定义自动化构建和发布的流程。以下是一个简单的Pipeline脚本示例: 在上述脚本中,定义了四个阶段:Checkout、Build、Push package和Deploy/Rollback。每个阶段都可以根据实际需求进行配置和调整。 通过Jenkins Pipeline自动化构建发布Java项目,可以显著提升开发效率和项目质量。借助Pipeline,我们能够轻松实现自动化构建、测试和部署,从而提高项目的整体质量和可靠性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值