Mais conteúdo relacionado
Semelhante a Surface flingerservice(서피스플링거서비스초기화 ics) (20)
Surface flingerservice(서피스플링거서비스초기화 ics)
- 2. 1.Surfaceflinger 전체 구조
SurfaceFlinger
ANativeWindow
*EGL
Graphic Hwcomposer FramebufferNativeWindow
Client
buffer EGLSurface
layer1 OpenGL ES NativeBuffer
API Front buffer
layer2
NativeBuffer
layer3 back buffer
Android
mapping
kernel
Overlay Module FrameBuffer
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 type의 변수를 만들고(plane), 그 변수는 mGraphicPlanes[[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 Main surface 생성, hwcomposer 생성 한다.
DisplayHardware::DisplayHardware(..): DisplayHardwareBase(flinger, dpy),mFlinger(flinger), mFlags(0), mHwc(0)
{
init(dpy);
}
void DisplayHardware::init(uint32_t dpy)
{
1. framebuffer에 buffer(front,back)를 할당하고, 그와 mapping되는 nativebuffer type의 buffer 생성 함.
mNativeWindow = new FramebufferNativeWindow();
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에 저장한다.
Hardware/libhardware/include/hardware/fb.h
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에 저장한다.
Hardware/libhardware/include/hardware/gralloc.h
static 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에 메모리를 할당한다.
(buffer의 handle이 할당된 메모리를 가리키게 된다(&buffers[i]->handle))
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; }
…
ANativeWindow method와 framebuffer method를 mapping한다.
(ANativeWindow Type의 surface에서 lockbuffer를 호출하면, FramebufferNativeWindow 의 lockbuffer가 호출된다.)
}
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. 3.메인 디스플레이 초기화
2.EGL Surface type의 main surface를 생성 한다.
surface = eglCreateWindowSurface(display, config, mNativeWindow.get(), NULL);
3.HW Compser를 초기화 한다.
mHwc = new HWComposer(mFlinger); hwc_module_t HAL_MODULE_INFO_SYM = {
if (mHwc->initCheck() == NO_ERROR) { common: {
mHwc->setFrameBuffer(mDisplay, mSurface); tag: HARDWARE_MODULE_TAG,
EGL Surfae를 hwcomposer의 buffer로 설정 함. version_major: 1,
} version_minor: 0,
} id: HWC_HARDWARE_MODULE_ID,
name: "Sample hwcomposer module",
HWComposer::HWComposer(const sp<SurfaceFlinger>& flinger) author: "The Android Open Source Project",
: mFlinger(flinger), methods: &hwc_module_methods,
mModule(0), mHwc(0), mList(0), mCapacity(0), }
mNumOVLayers(0), mNumFBLayers(0), };
mDpy(EGL_NO_DISPLAY), mSur(EGL_NO_SURFACE)
{
int err = hw_get_module(HWC_HARDWARE_MODULE_ID, &mModule);
if (err == 0) {
err = hwc_open(mModule, &mHwc);
if (err == 0) { static inline int hwc_open(const struct hw_module_t* module,
if (mHwc->registerProcs) { hwc_composer_device_t** device)
mCBContext.hwc = this; {
mCBContext.procs.invalidate = &hook_invalidate; return module->methods->open(module,
mHwc->registerProcs(mHwc, &mCBContext.procs); HWC_HARDWARE_COMPOSER,
} (struct hw_device_t**)device);
} }
}
} static struct hw_module_methods_t hwc_module_methods = {
open: hwc_device_open
};
10
- 11. 3.메인 디스플레이 초기화
static int hwc_device_open(const struct hw_module_t* module, const char* name,struct hw_device_t** device)
{
dev->mOverlayLibObject = new overlay::Overlay(); overlay 생성
dev->previousOverlayHandle = NULL;
dev->hwcOverlayStatus = HWC_OVERLAY_CLOSED;
dev->device.common.tag = HARDWARE_DEVICE_TAG;
dev->device.common.version = 0;
dev->device.common.module = const_cast<hw_module_t*>(module);
dev->device.common.close = hwc_device_close;
dev->device.prepare = hwc_prepare;
dev->device.set = hwc_set;
dev->device.registerProcs = hwc_registerProcs;
dev->device.enableHDMIOutput = hwc_enableHDMIOutput;
*device = &dev->device.common;
}
hwc_module_t hwc_device_t
hw_module_t hw_device_t
module
id HWC_HARDWARE_MODULE_
close hwc_device_close
ID
methods hwc_module_methods 생성 prepare hwc_prepare
set hwc_set
registerProcs hwc_registerProcs
hwc_module_methods mOverlayLibObject new overlay
open hwc_device_open
11
- 12. 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
12