Contenu connexe Similaire à Surface flingerservice(서피스플링거서비스초기화) (20) Surface flingerservice(서피스플링거서비스초기화)2. 1.Surfaceflinger 전체 구조
SurfaceFlinger
Client NaitveWindow
App SurfacecomposerClient
layer1 OpenGL ES
Graphic buffer API NativeBuffer
Front buffer
*EGL
layer2
NativeBuffer
layer3 back buffer
Android mmap으로
mapping mapping
kernel
FrameBuffer
Graphic buffer
공유 메모리
Front buffer Lcd Pannel
……
back buffer
*EGL:Embedded Graphic Library
2
3. 2.SurfaceFlinger 클래스의 인스턴스 생성
Systemserver.java
public class SystemServer {
public static void main(String[] args) {
System.loadLibrary("android_servers");
init1(args);
}
native public static void init1(String[] args);
}
Com_android_server_systemserser.cpp
static JNINativeMethod gMethods[] = {
/* name, signature, funcPtr */
{ "init1", "([Ljava/lang/String;)V", (void*) android_server_SystemServer_init1 },
};
static void android_server_SystemServer_init1(JNIEnv* env, jobject clazz)
{
system_init();
}
System_init.cpp
extern "C" status_t system_init()
{
SurfaceFlinger::instantiate();
SensorService::instantiate();
jclass clazz = env->FindClass("com/android/server/SystemServer");
jmethodID methodId = env->GetStaticMethodID(clazz, "init2", "()V");
env->CallStaticVoidMethod(clazz, methodId);
}
3
4. 2.SurfaceFlinger 클래스의 인스턴스 생성
Pthread_create
2 3
Thread
Run() _threadLoop()
Refbase
4 1회호출 5 반복호출
1
SurfaceFlinger
onFirstRef() ReadyToRun() ThreadLoop()
RefBase.cpp
void RefBase::incStrong(const void* id) const{
const_cast<RefBase*>(this)->onFirstRef();
}
SurfaceFlinger..cpp
void SurfaceFlinger::onFirstRef()
{
run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY);
1 // Wait for the main thread to be done with its initialization
mReadyToRunBarrier.wait(); ReadyToRun 함수에서 mReadyToRunBarrier.open()가 불릴때 까지 기다린다.
}
4
5. 2.SurfaceFlinger 클래스의 인스턴스 생성
Threads.cpp
status_t Thread::run(const char* name, int32_t priority, size_t stack){
res = androidCreateRawThreadEtc
(_threadLoop,this, name, priority, stack, &mThread);
}
2
int androidCreateRawThreadEtc(){
int result = pthread_create(&thread, &attr,
(android_pthread_entry)entryFunction, userData);
} 3
int Thread::_threadLoop(void* user)
{
do {
bool result;
if (first) {
first = false;
self->mStatus = self->readyToRun(); 4
}
else{
result = self->threadLoop(); 5
}
}
}
5
6. 2.SurfaceFlinger 클래스의 인스턴스 생성-readyToRun()
SurfacefFlinger.cpp
status_t SurfaceFlinger::readyToRun()
(
1.메인 디스 플레이 초기화
// initialize the main display
GraphicPlane& plane(graphicPlane(dpy));
DisplayHardware* const hw = new DisplayHardware(this, dpy);
plane.setDisplayHardware(hw);
2. 디스 플레이 공유 메모리 생성
// create the shared control-block
mServerHeap = new MemoryHeapBase(4096, MemoryHeapBase::READ_ONLY, "SurfaceFlinger read-only heap");
mServerCblk = static_cast<surface_flinger_cblk_t*>(mServerHeap->getBase());
new(mServerCblk) surface_flinger_cblk_t;
3. initialize the shared control block
mServerCblk->connected |= 1<<dpy;
display_cblk_t* dcblk = mServerCblk->displays + dpy;
memset(dcblk, 0, sizeof(display_cblk_t));
4.open GL ES 초기화
// Initialize OpenGL|ES
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
glPixelStorei(GL_PACK_ALIGNMENT, 4);
glEnableClientState(GL_VERTEX_ARRAY);
5.onfirstref()에서 기다리고 있는 thread에 signal 보냄.
mReadyToRunBarrier.open();
6.부트 애니메이션 시작
// start boot animation
property_set("ctl.start", "bootanim"); /system/bin/bootanimation 프로세스 실행.
}
6
7. 3.메인 디스플레이 초기화
1.GraphicPlane& plane(graphicPlane(dpy));
디스플레이의 정보를 가지는 graphicplane calss를 생성하고 , 0번째 요소를 메인 디스플레이로 설정한다.
GraphicPlane& plane(graphicPlane(dpy)); //dpy=0;
GraphicPlane& SurfaceFlinger::graphicPlane(int dpy)
{
return const_cast<GraphicPlane&>(const_cast<SurfaceFlinger const *>(this)->graphicPlane(dpy));
}
const GraphicPlane& SurfaceFlinger::graphicPlane(int dpy) const
{
const GraphicPlane& plane(mGraphicPlanes[dpy]);
return plane;
}
2. DisplayHardware* const hw = new DisplayHardware(this, dpy);
DisplayHardware를 생성하고, EGL 네이티브 윈도우를 생성하고 초기화 한다.
DisplayHardware::DisplayHardware(..): DisplayHardwareBase(flinger, dpy),mFlinger(flinger), mFlags(0), mHwc(0)
{
init(dpy);
}
void DisplayHardware::init(uint32_t dpy)
{
mNativeWindow = new FramebufferNativeWindow(); Native window 생성
//EGL 초기화 수행
}
7
8. 3.메인 디스플레이 초기화
FramebufferNativeWindow::FramebufferNativeWindow()
{
if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module) == 0)
{ gralloc.msm8960.so 를 load해서
err = framebuffer_open(module, &fbDev);
framebuffer device를 open하고 framebuffer에 접근할 수 있는 변수를 fbDev에 저장한다.
static inline int framebuffer_open(const struct hw_module_t* module,
struct framebuffer_device_t** device) {
return module->methods->open(module,
GRALLOC_HARDWARE_FB0, (struct hw_device_t**)device);
} "fb0"
err = gralloc_open(module, &grDev);
그래픽 버퍼 할당 device를 open하고 ,device에 접근 할 수 있는 변수를 grDev에 저장한다.
tatic inline int gralloc_open(const struct hw_module_t* module,
struct alloc_device_t** device) {
return module->methods->open(module,
GRALLOC_HARDWARE_GPU0, (struct hw_device_t**)device);
} “gpu0”
for (i = 0; i < mNumBuffers; i++)
{
buffers[i] = new NativeBuffer( fbDev->width, fbDev->height, fbDev->format, GRALLOC_USAGE_HW_FB);
}
framebuffer를 가리키는 Nativebuffer 구조체를 생성한다.
Nativebuffer의 그래픽 버퍼가
프레임 버퍼에 매핑되어 있다는 의미
8
9. 3.메인 디스플레이 초기화
for (i = 0; i < mNumBuffers; i++) 프레임 버퍼에 메모리를 할당한다는 의미
{
err = grDev->alloc(grDev,
fbDev->width, fbDev->height, fbDev->format,
GRALLOC_USAGE_HW_FB, &buffers[i]->handle, &buffers[i]->stride);
}
Nativebuffer 와 mapping된 framebuffer에 메모리를 할당한다.
ANativeWindow::setSwapInterval = setSwapInterval; int FramebufferNativeWindow::lockBuffer(..){
ANativeWindow::dequeueBuffer = dequeueBuffer; framebuffer_device_t* fb = self->fbDev;
ANativeWindow::lockBuffer = lockBuffer; fb-> lockBuffer(fb, index);
ANativeWindow::queueBuffer = queueBuffer; }
…
NativeWindow method와 framebuffer method를 mapping한다.
}
3. plane.setDisplayHardware(hw);
생성한 displayHardware의 정보들을 GraphicPlane class에 설정해 준다.(withd,height,orientation)
void GraphicPlane::setDisplayHardware(DisplayHardware *hw)
{
mHw = hw;
const float w = hw->getWidth();
const float h = hw->getHeight();
GraphicPlane::orientationToTransfrom(displayOrientation, w, h,&mDisplayTransform);
}
9
10. 4.디스플레이 공유 메모리 생성 및 초기화
1. mServerHeap = new MemoryHeapBase(4096, MemoryHeapBase::READ_ONLY, "SurfaceFlinger read-only heap");
디스플레이의 정보를 공유할 디스플레이 공유 메모리 생성
2. mServerCblk = static_cast<surface_flinger_cblk_t*>(mServerHeap->getBase());
생성된 공유 메모리의 시작점을 얻어 옴.
3. new(mServerCblk) surface_flinger_cblk_t;
시작점에 surface_flinger_cblk_t를 생성하고, mServerCblk 멤버 변수가 가리킴.
4. mServerCblk->connected |= 1<<dpy;
connected 변수에 연결된 display의 식별번호를 저장(1개인 경우 0x00000001, 두개인 경우 0x00000011)
5. display_cblk_t* dcblk = mServerCblk->displays + dpy;
memset(dcblk, 0, sizeof(display_cblk_t));
dcblk->w = plane.getWidth();
dcblk->h = plane.getHeight();
dcblk->format = f;
dcblk->orientation = ISurfaceComposer::eOrientationDefault;
display_cblk_t 를 생성하고 displayhardware 구조체 value로 초기화 함.
디스플레이 공유 메모리
surface_flinger_cblk_t surfaceflinger
connected mServerCblk
Dislay_cblk_t dcblk
w,h:프레임 버퍼 너비,높이
Density,fps
Format,orientation
Xdpi,ydpi
10
11. 참고. Android HAL 구조 분석(Framebuffer_open 분석)
1.Android HAL의 일반적인 구조
xxx_module_t Xxx_device_t
hw_module_t hw_device_t
Module
id Xxx_HARDWARE_MODULE_I
D close
methods 생성 Xxx_close
Xxx_module_methods
open Xxx_device_open
Struct xxx_module_t HAL_MODULE_INFO_SYM={ Static int xxx_device_open(…){
common:{
tag:HARDWARE_MODULE_TAG, xxx_device_t *dev;
version_major:1, dev=(xxx_device_t *)malloc(sizeof(xxx_device_t));
version_minor:0,
id:xxx_HARDWARE_MODULD_ID, dev->common.module=<hw_module_t>(module);
name:”xxx module” Dev->close=xxx_close
author:”xxx”
methods :&xxx_module_medthods *device=&dev->device.common;
}
} }
Static struct hw_module_methods_t xxx_module_methods={
open:xxx_device_open
};
11
12. 참고. Android HAL 구조 분석(Framebuffer_open 분석)
2.framebuffer_open 분석
if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module) == 0)
{
err = framebuffer_open(module, &fbDev); struct private_module_t HAL_MODULE_INFO_SYM = {
} base: {
common: {
tag: HARDWARE_MODULE_TAG,
version_major: 1,
static inline int framebuffer_open(const struct hw_module_t*
version_minor: 0,
module,
id: GRALLOC_HARDWARE_MODULE_ID,
struct framebuffer_device_t** device) {
name: "Graphics Memory Allocator Module",
return module->methods->open(module,
author: "The Android Open Source Project",
GRALLOC_HARDWARE_FB0, (struct
methods: &gralloc_module_methods,
hw_device_t**)device);
dso: 0,
}
reserved: {0},
},
static struct hw_module_methods_t gralloc_module_methods = {
open: gralloc_device_open
};
int gralloc_device_open(const hw_module_t* module, const char* name,hw_device_t** device)
{
status = fb_device_open(module, name, device);
}
int fb_device_open(hw_module_t const* module, const char* name,hw_device_t** device){
fb_context_t *dev = (fb_context_t*)malloc(sizeof(*dev));
dev->device.common.module = const_cast<hw_module_t*>(module); dev->device.setSwapInterval = fb_setSwapInterval;
dev->device.common.close = fb_close; dev->device.post = fb_post;
12
13. 참고. Android HAL 구조 분석(Framebuffer_open 분석)
private_module_t fb_context_t
hw_module_t hw_device_t
Module
id GRALLOC_HARDWARE_MODULE_
ID close
methods 생성 fb_close
setSwapInterval fb_setSwapInterval
post fb_post
gralloc_module_methods
open gralloc_device_open dev->device.width;
dev->device.height;
dev->device.format
13