3. 1.그래픽 버퍼 공유 메모리 생성
서피스 플링거 서비스와 서비스 클라이언트간의 data 공유를 위해 그래픽 버퍼 공유 메모리 생성
Client SurfaceFlinger
생성 버퍼등록 Android
kernel
그래픽 버퍼 공유
메모리
Ex)CameraService에서 preview data를 surfaceflinger와 공유하기 위한 그래픽 버퍼 공유 메모리 생성
CameraService.cpp
status_t CameraService::Client::startPreviewMode()
{
result = mHardware->startPreview();
}
3
4. 1.그래픽 버퍼 공유 메모리 생성
QualcommCameraHardware.cpp
status_t QualcommCameraHardware::startPreview()
{
return startPreviewInternal();
}
status_t QualcommCameraHardware::startPreviewInternal()
{
mPreviewInitialized = initPreview();
}
bool QualcommCameraHardware::initPreview()
{
mPreviewHeap = new PmemPool(pmem_region, MemoryHeapBase::READ_ONLY |
MemoryHeapBase::NO_CACHING,
MSM_PMEM_PREVIEW,
mPreviewFrameSize,
kPreviewBufferCountActual,
mPreviewFrameSize,
CbCrOffset, 0, "preview");
QualcommCameraHardware::PmemPool::PmemPool(..)
{
sp<MemoryHeapBase> masterHeap =new MemoryHeapBase(pmem_pool, mAlignedSize,flags);
MemoryHeapBase class를 이용하여, "/dev/pmem_adsp“ 영역(pmem_pool)에 mAlignedSize 만큼의 공유 메모리 생성
(kernel virtual address)
4
5. 1.그래픽 버퍼 공유 메모리 생성
sp<MemoryHeapPmem> pmemHeap = new MemoryHeapPmem(masterHeap, flags);
생성된 공유 메모리의 영역을 physical 메모리의 연속된 영역으로 잡음
mHeap = pmemHeap;
register_buf(mBufferSize,
mFrameSize, mCbCrOffset, myOffset,
mHeap->getHeapID(),
mAlignedBufferSize * cnt,
(uint8_t *)mHeap->base() + mAlignedBufferSize * cnt,
pmem_type,
active);
생성된 공유 메모리를 camera drive에 등록.
completeInitialization(); 생성된 MemoryHeapBase 영역을 4개의 mBuffers로 나눔
CameraService Android
Virtual address
생성 Mapping된 address return
Kernel
mBuffers[0] Virtual address
mBuffers[3]
Physical memory 0x4000 write
Camera driver
0x1000
5
6. 2. 그래픽 버퍼 공유 메모리 등록 요청
생성된 그래픽 버퍼 공유 메모리를 SurfaceFlinger에게 등록 요청 한다.
status_t CameraService::Client::registerPreviewBuffers() {
ISurface::BufferHeap buffers(w, h, w, h,
mPixelFormat,
mOrientation,
0,
mHardware->getPreviewHeap());생성된 그래픽 버퍼 공유 메모리의 프락시
생성된 그래픽 버퍼 공유 메모리의 넓이,높이,format, 서비스 프락시를 가진 buffers class를 생성한다.
status_t result = mSurface->registerBuffers(buffers);
mSurface는 layerbuffer의 서피스 핸들인 SurfaceLayerBuffer를 가리킨다.
}
Layerbuffer.cpp
status_t LayerBuffer::SurfaceLayerBuffer::registerBuffers(const ISurface::BufferHeap& buffers)
{
sp<LayerBuffer> owner(getOwner());
if (owner != 0)
return owner->registerBuffers(buffers);
return NO_INIT;
}
status_t LayerBuffer::registerBuffers(const ISurface::BufferHeap& buffers)
{
sp<BufferSource> source = new BufferSource(*this, buffers);
mSource = source;
}
6
7. 2. 그래픽 버퍼 공유 메모리 등록 요청
LayerBuffer::BufferSource::BufferSource(LayerBuffer& layer,const ISurface::BufferHeap& buffers)
{
mBufferSize = info.getScanlineSize(buffers.hor_stride)*buffers.ver_stride;
mBufferHeap = buffers;
buffers에는 공유 메모리에 접근할 수 있는 프락시가 저장 되어 있다,
즉, Buffersource의 mBufferHeap 변수가 공유 메모리를 가리키게 된다.
}
void LayerBuffer::onDraw(const Region& clip) const
{
sp<Source> source(getSource());
Layerbuffer if (LIKELY(source != 0)) {
source->onDraw(clip);
onDraw() } else {
clearWithOpenGL(clip);
Source }
}
onDraw()
void LayerBuffer::Source::onDraw(const Region& clip) const {
}
void LayerBuffer::BufferSource::onDraw(const Region& clip)
const
{
BufferSource OverlaySource
mLayer.drawWithOpenGL(tempClip, mTexture);
onDraw() onDraw() }
void LayerBuffer::OverlaySource::onDraw(const Region& clip)
const
{
mLayer.clearWithOpenGL(clip, 0, 0, 0, 0);
layer를 검은색으로 덮음
}
7
8. 2. 그래픽 버퍼 공유 메모리 등록 요청
SurfaceFlinger
CameraService
Layerbuffer
BufferHeap 등록
mSource BufferSource
mBufferHeap
Android
Virtual address
Kernel
Virtual address mBuffers[0]
mBuffers[3]
Physical memory 0x4000 write
Camera driver
0x1000
8
9. 2. 그래픽 버퍼 공유 메모리 등록 요청-Overlay 경우
Camera process
SurfaceFlinger
mSurface->createOverlay
1.CameraService 에서 setOverlay()호출 Layerbuffer
mSource
3. Overlay 변수 저장
4. Preview thread에서 OverlaySource
mOverlay->setFd(mPreviewHeap->mHeap- Overlay
>getHeapID());
5. mOverlay->queueBuffer
((void *)offset_addr);
2.Overlay device open
Overlay device
queueBuffer
mBuffers[0]
mBuffers[3] 4번 이후
Overlay는
그래픽 버퍼 공유 메모리를 가리킴
9