转自:http://blog.youkuaiyun.com/jxt1234and2010/article/details/46407383
硬件合成器-HwComposer
使用3D合成,需要大面积的像素混合计算和大量的内存传输(GPU读写GraphicBuffer所需),对GPU和DDR来说是一个巨大的负担。在GPU/DDR重度使用的场景(比如玩游戏),会造成发热、卡顿等。
为了提升性能,减少功耗,可以将合成这个过程交由另一个芯片完成,减轻GPU负担。进一步,直接让这个芯片连LCD,在LCD需要显示某一行时在线合成。
HwComposer便是这一个/多个专用合成芯片的驱动HAL层。
驱动由集成芯片系统的厂商自行设计,但需要遵循一定的标准,这个标准就是Android规定的HwComposer接口。
接口定义
hwcomposer的接口定义位于此文件:
hardware/libhardware/include/hardware/hwcomposer.h
其中部分宏定义在:
hardware/libhardware/include/hardware/hwcomposer_defs.h
Layer
在SurfaceFlinger中,Layer对应于window表示一个Buffer循环体系,对HwComposer而言,Layer仅指代当前Buffer,也即SurfaceFlinger中的Layer的当前帧。
typedef struct hwc_layer_1 {
int32_t compositionType;
uint32_t hints;
uint32_t flags;
union {
hwc_color_t backgroundColor;
struct {
union {
buffer_handle_t handle;
const native_handle_t* sidebandStream;
};
uint32_t transform;
int32_t blending;
union {
hwc_rect_t sourceCropi;
hwc_rect_t sourceCrop;
hwc_frect_t sourceCropf;
};
hwc_rect_t displayFrame;
hwc_region_t visibleRegionScreen;
int acquireFenceFd;
int releaseFenceFd;
uint8_t planeAlpha;
uint8_t _pad[3];
hwc_region_t surfaceDamage;
};
};
#ifdef __LP64__
uint8_t reserved[120 - 112];
#else
uint8_t reserved[96 - 84];
#endif
} hwc_layer_1_t;
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
这里面最难理解和最易出错的是 SourceCrop、DisplayFrame和VisibleRegion,在处理SOC上的显示问题时,这往往是首先考虑的因素:
如图所示,该Layer的显示区域部分被L2完全挡住,source crop 为该Layer参与合成的范围,display frame 为该Layer合成的目标区域,visibleRegion为该Layer被挡住后,剩余的可见区域集。
看完了这个结构体,上一篇
http://blog.youkuaiyun.com/jxt1234and2010/article/details/46057267
所提到的adb shell dumpsys SurfaceFlinger 所得到的表格,各参数表示什么意思自然一下就清楚了。
Display
typedef struct hwc_display_contents_1 {
int retireFenceFd;
union {
struct {
hwc_display_t dpy;
hwc_surface_t sur;
};
struct {
buffer_handle_t outbuf;
int outbufAcquireFenceFd;
};
};
uint32_t flags;
size_t numHwLayers;
hwc_layer_1_t hwLayers[0];
} hwc_display_contents_1_t;
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
关于物理显示屏(physical display)和虚拟显示屏(virtual display)
物理显示屏表示连接实际的显示仪器如LCD,目的是产生显示效果,可以使用在线合成。
虚拟显示屏表示目的是合成一个Buffer,不需要理会这个Buffer后续如何产生显示效果,这时需要把所有图层合成到指定的Buffer上。这种情况下必须离线合成。典型场景是手机连WFD/hdmi,手机合成好的Buffer通过wifi/hdmi传输到电视上显示。
Device
最后是device的函数指针定义
typedef struct hwc_composer_device_1 {
struct hw_device_t common;
int (*prepare)(struct hwc_composer_device_1 *dev,
size_t numDisplays, hwc_display_contents_1_t** displays);
int (*set)(struct hwc_composer_device_1 *dev,
size_t numDisplays, hwc_display_contents_1_t** displays);
int (*eventControl)(struct hwc_composer_device_1* dev, int disp,
int event, int enabled);
union {
int (*blank)(struct hwc_composer_device_1* dev, int disp, int blank);
int (*setPowerMode)(struct hwc_composer_device_1* dev, int disp,
int mode);
};
int (*query)(struct hwc_composer_device_1* dev, int what, int* value);
void (*registerProcs)(struct hwc_composer_device_1* dev,
hwc_procs_t const* procs);
void (*dump)(struct hwc_composer_device_1* dev, char *buff, int buff_len);
int (*getDisplayConfigs)(struct hwc_composer_device_1* dev, int disp,
uint32_t* configs, size_t* numConfigs);
int (*getDisplayAttributes)(struct hwc_composer_device_1* dev, int disp,
uint32_t config, const uint32_t* attributes, int32_t* values);
int (*getActiveConfig)(struct hwc_composer_device_1* dev, int disp);
int (*setActiveConfig)(struct hwc_composer_device_1* dev, int disp,
int index);
int (*setCursorPositionAsync)(struct hwc_composer_device_1 *dev, int disp, int x_pos, int y_pos);
void* reserved_proc[1];
} hwc_composer_device_1_t;