SurfaceFlinger旋转流程分析
2013-08-13 16:36
351 查看
chipset: MSM8X25Q
codebase: Android4.1
本文主要对SF(SurfaceFilnger)处理旋转事件的流程做个简单分析。GPU和mdp都可以用来旋转,文中对两者穿插说明。
系统初始化会调用GraphicPlane::setDisplayHardware,此函数主要判断系统是否默认设置了rotation property值,如果有,则先保存下来。另外,SF是以transform其实就是以矩阵来作旋转计算的,计算方法以线性代数中的知识为依据:
[html]
view plaincopyprint?
void GraphicPlane::setDisplayHardware(DisplayHardware *hw)
{
mHw = hw;
// initialize the display orientation transform.
// it's a constant that should come from the display driver.
int displayOrientation =
ISurfaceComposer::eOrientationDefault;
char property[PROPERTY_VALUE_MAX];
/*读取property*/
if (property_get("ro.sf.hwrotation", property, NULL)
> 0) {
//displayOrientation
switch (atoi(property)) {
/*当然,你也可以仿照添加180°的旋转。*/
case 90:
displayOrientation =
ISurfaceComposer::eOrientation90;
break;
case 270:
displayOrientation =
ISurfaceComposer::eOrientation270;
break;
}
}
const float w = hw->getWidth();
const float h =
hw->getHeight();
/*根据宽和高以及orientation生成一个transform*/
GraphicPlane::orientationToTransfrom(displayOrientation, w, h,
&mDisplayTransform);
/*90°或者270°时需要变换宽高。*/
if (displayOrientation & ISurfaceComposer::eOrientationSwapMask) {
mDisplayWidth =
h;
mDisplayHeight = w;
} else {
mDisplayWidth = w;
mDisplayHeight =
h;
}
/*保存当前全局旋转角度,意味着整个系统的显示都要根据整个值
来得出最后是否要旋转。如果为90°或者270°,那就是横屏,如果
是180°,画面就要反转180°。*/
setOrientation(ISurfaceComposer::eOrientationDefault);
}
status_t GraphicPlane::setOrientation(int orientation)
{
// If the rotation can be handled in hardware, this is where
// the magic should happen.
const DisplayHardware& hw(displayHardware());
const float w = mDisplayWidth;
const float h =
mDisplayHeight;
mWidth = int(w);
mHeight = int(h);
Transform orientationTransform;
GraphicPlane::orientationToTransfrom(orientation, w, h,
&orientationTransform);
if (orientation & ISurfaceComposer::eOrientationSwapMask) {
mWidth =
int(h);
mHeight = int(w);
}
mOrientation =
orientation;
/*将orientation和h/w计算和得出一个全局的transform,这里的
相乘计算方法,就是利用矩阵来实现的。*/
mGlobalTransform = mDisplayTransform * orientationTransform;
return NO_ERROR;
}
由于整个系统一直默认旋转只是流程中一个坐标的特殊处理,不管系统上层是否请求旋转,如横屏游戏,sensor坐标变化,默认的旋转是一直会被处理的。
注意别把这两种旋转混淆了,默认旋转是一般情况下用户看到的显示效果,而上层apk
请求的旋转相对默认旋转是瞬间的。
现在以上层发生旋转事件为例看下SF处理旋转的流程。
上层调用SurfaceFlinger::setTransactionState设置当前角度变化了:
[html]
view plaincopyprint?
void SurfaceFlinger::setTransactionState(const Vector<ComposerState>& state,
int orientation, uint32_t flags) {
Mutex::Autolock _l(mStateLock);
uint32_t transactionFlags =
0;
/*当前坐标和要设置的坐标不相等表明要作旋转了!*/
if (mCurrentState.orientation != orientation) {
if (uint32_t(orientation)<=eOrientation270 ||
orientation==42) {
mCurrentState.orientation =
orientation;
transactionFlags |= eTransactionNeeded;
} else if (orientation != eOrientationUnchanged) {
ALOGW("setTransactionState: ignoring unrecognized orientation: %d",
orientation);
}
}
/*设置旋转标志,SF处理的时候会用到。*/
const size_t count =
state.size();
for (size_t i=0 ; i<count ; i++) {
const ComposerState& s(state[i]);
sp<Client> client( static_cast<Client *>(s.client.get())
);
transactionFlags |= setClientStateLocked(client, s.state);
}
if (transactionFlags) {
// this triggers the transaction
setTransactionFlags(transactionFlags);
~~snip
}
SF收到消息后,调用SurfaceFlinger::onMessageReceived进行处理,核心的部分都在这里了。
[html]
view plaincopyprint?
void SurfaceFlinger::onMessageReceived(int32_t what)
{
ATRACE_CALL();
switch (what) {
case MessageQueue::INVALIDATE:
case MessageQueue::REFRESH: {
// case MessageQueue::INVALIDATE: {
// if we're in a global transaction, don't do anything.
const uint32_t mask =
eTransactionNeeded | eTraversalNeeded;
uint32_t transactionFlags =
peekTransactionFlags(mask);
/*处理事务*/
if (CC_UNLIKELY(transactionFlags)) {
handleTransaction(transactionFlags);
}
const uint32_t mask1 =
eDelayedTraversalNeeded;
uint32_t transactionFlags1 =
peekTransactionFlags(mask1);
if (CC_UNLIKELY(transactionFlags1)) {
handleDelayedTransaction(transactionFlags);
}
/*计算可视区域*/
// post surfaces (if needed)
handlePageFlip();
~~snip
case MessageQueue::REFRESH: {
~~snip
/*处理几何坐标*/
if (CC_UNLIKELY(mHwWorkListDirty)) {
// build the h/w work list
handleWorkList();
}
/*render*/
if (CC_LIKELY(hw.canDraw())) {
// repaint the framebuffer (if needed)
handleRepaint();
// inform the h/w that we're done compositing
hw.compositionComplete();
postFramebuffer();
} else {
// pretend we did the post
hw.compositionComplete();
}
} break;
}
}
下面一一对这几个函数分析。
handleTransaction
[html]
view plaincopyprint?
void SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
{
~~snip
const uint32_t mask =
eTransactionNeeded | eTraversalNeeded;
transactionFlags = getTransactionFlags(mask);
handleTransactionLocked(transactionFlags);
~~snip
}
void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
{
const LayerVector& currentLayers(mCurrentState.layersSortedByZ);
const size_t count = currentLayers.size();
/*
* Traversal of the children
* (perform the transaction for each of them if needed)
*/
/*判断是否有事务要处理。*/
const bool layersNeedTransaction =
transactionFlags & eTraversalNeeded;
if (layersNeedTransaction) {
for (size_t i=0 ; i<count ; i++) {
const sp<LayerBase>&
layer = currentLayers[i];
uint32_t trFlags =
layer->getTransactionFlags(eTransactionNeeded);
if (!trFlags) continue;
const uint32_t flags =
layer->doTransaction(0);
if (flags & Layer::eVisibleRegion)
mVisibleRegionsDirty =
true;
}
}
~~snip
if (transactionFlags & eTransactionNeeded) {
/*有旋转角度变化的事务。*/
if (mCurrentState.orientation != mDrawingState.orientation) {
// the orientation has changed, recompute all visible regions
// and invalidate everything.
const int dpy =
0;
const int orientation =
mCurrentState.orientation;
// Currently unused: const uint32_t
flags = mCurrentState.orientationFlags;
GraphicPlane& plane(graphicPlane(dpy));
/*根据当前旋转的坐标,还有默认的旋转坐标,计算和得出最终全局transform。
此函数前面分析过了。*/
plane.setOrientation(orientation);
const Transform& planeTransform(plane.transform());
// update the shared control block
const DisplayHardware& hw(plane.displayHardware());
volatile display_cblk_t* dcblk =
mServerCblk->displays + dpy;
dcblk->orientation =
orientation;
dcblk->w =
plane.getWidth();
dcblk->h =
plane.getHeight();
/*旋转过后当然要重新绘制显示画面了,设置标志。*/
mVisibleRegionsDirty =
true;
mDirtyRegion.set(hw.bounds());
}
~~snip
}
可见handleTransaction主要设置全局的transform。
handlePageFlip
[html]
view plaincopyprint?
void SurfaceFlinger::handlePageFlip()
{
ATRACE_CALL();
const DisplayHardware& hw =
graphicPlane(0).displayHardware();
const Region screenRegion(hw.bounds());
const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
const bool visibleRegions =
lockPageFlip(currentLayers);
if (visibleRegions || mVisibleRegionsDirty) {
Region opaqueRegion;
/*有旋转过,所以要重新计算可视区域*/
computeVisibleRegions(currentLayers, mDirtyRegion, opaqueRegion);
~~snip
}
~~snip
}
void SurfaceFlinger::computeVisibleRegions(
const LayerVector& currentLayers, Region& dirtyRegion, Region& opaqueRegion)
{
ATRACE_CALL();
const GraphicPlane& plane(graphicPlane(0));
const Transform& planeTransform(plane.transform());
const DisplayHardware& hw(plane.displayHardware());
const Region screenRegion(hw.bounds());
Region aboveOpaqueLayers;
Region aboveCoveredLayers;
Region dirty;
bool secureFrameBuffer =
false;
size_t i = currentLayers.size();
while (i--) {
const sp<LayerBase>&
layer = currentLayers[i];
/*将全局的transform传进去,然后调用各个layer作计算。*/
layer->validateVisibility(planeTransform);
~~snip
}
}
void LayerBase::validateVisibility(const Transform& planeTransform)
{
const Layer::State& s(drawingState());
/*全局transform和当前layer的transform相乘计算得到一个transform.*/
const Transform tr(planeTransform * s.transform);
const bool transformed =
tr.transformed();
const DisplayHardware& hw(graphicPlane(0).displayHardware());
const uint32_t hw_h =
hw.getHeight();
const Rect& crop(s.active.crop);
Rect win(s.active.w, s.active.h);
if (!crop.isEmpty()) {
win.intersect(crop, &win);
}
mNumVertices =
4;
/* mVertices 相当重要,系统根据当前的transform还有当前layer的
区域作计算,当然也包含了全局的transform信息在里面,计算出来的
坐标保存到了mVertices 去。要注意,mVertices 只是给GPU用的,如果
用mdp做旋转,SF后面的流程会对其做相应设置。*/
tr.transform(mVertices[0], win.left, win.top);
tr.transform(mVertices[1], win.left, win.bottom);
tr.transform(mVertices[2], win.right, win.bottom);
tr.transform(mVertices[3], win.right, win.top);
for (size_t i=0 ; i<4 ; i++)
mVertices[i][1] = hw_h - mVertices[i][1];
if (CC_UNLIKELY(transformed)) {
// NOTE: here we could also punt if we have too many rectangles
// in the transparent region
/*根据transform对透明区域作处理。*/
if (tr.preserveRects()) {
// transform the transparent region
transparentRegionScreen =
tr.transform(s.transparentRegion);
} else {
// transformation too complex, can't do the transparent region
// optimization.
transparentRegionScreen.clear();
}
} else {
transparentRegionScreen =
s.transparentRegion;
}
/*保存相应的一些信息到新的参数变量中,以便后面用到。*/
// cache a few things...
mOrientation =
tr.getOrientation();
mPlaneOrientation = planeTransform.getOrientation();
mTransform =
tr;
mTransformedBounds = tr.transform(win);
}
可见,从handlePageFlip中,我们主要是得到了GPU要处理的坐标,保存到了mVertices数组中。
handleWorkList
[html]
view plaincopyprint?
void SurfaceFlinger::handleWorkList()
{
mHwWorkListDirty =
false;
HWComposer& hwc(graphicPlane(0).displayHardware().getHwComposer());
if (hwc.initCheck() == NO_ERROR) {
const Vector< sp<LayerBase>
>& currentLayers(mVisibleLayersSortedByZ);
const size_t count =
currentLayers.size();
hwc.createWorkList(count);
hwc_layer_t* const cur(hwc.getLayers());
for (size_t i=0 ; cur && i<count ; i++) {
/*依次调用各个layer的setGeometry 。*/
currentLayers[i]->setGeometry(&cur[i]);
}
}
}
void Layer::setGeometry(hwc_layer_t* hwcl)
{
/*调用基类函数。*/
LayerBaseClient::setGeometry(hwcl);
hwcl->flags &= ~HWC_SKIP_LAYER;
/*不完全透明时需要GPU处理。*/
// we can't do alpha-fade with the hwc HAL
const State& s(drawingState());
if (s.alpha < 0xFF) {
hwcl->flags =
HWC_SKIP_LAYER;
}
/*
* Transformations are applied in this order:
* 1) buffer orientation/flip/mirror
* 2) state transformation (window manager)
* 3) layer orientation (screen orientation)
* mTransform is already the composition of (2) and (3)
* (NOTE: the matrices are multiplied in reverse order)
*/
/*这里就是在根据要求的旋转信息得出最终的transform,
然后赋值给hwcl,hwcl的信息最后会传给mdp处理。*/
const Transform bufferOrientation(mCurrentTransform);
hwcl->sourceTransform =
bufferOrientation.getOrientation();
const Transform tr(mTransform * bufferOrientation);
// this gives us only the "orientation" component of the transform
const uint32_t finalTransform =
tr.getOrientation();
// we can only handle simple transformation
if (finalTransform & Transform::ROT_INVALID) {
hwcl->flags =
HWC_SKIP_LAYER;
} else {
hwcl->transform =
finalTransform;
}
/*得到layer区域相对坐标,绝对坐标在基类中计算得到。*/
Rect crop = computeBufferCrop();
hwcl->sourceCrop.left =
crop.left;
hwcl->sourceCrop.top =
crop.top;
hwcl->sourceCrop.right =
crop.right;
hwcl->sourceCrop.bottom =
crop.bottom;
}
由此看来handleWorkList主要是服务于mdp的,如果用GPU旋转的话可以不需要这些信息。
handleRepaint
[html]
view plaincopyprint?
void SurfaceFlinger::handleRepaint()
{
~~snip
setupHardwareComposer();
/*对各个layer作render*/
composeSurfaces(mDirtyRegion);
// update the swap region and clear the dirty region
mSwapRegion.orSelf(mDirtyRegion);
mDirtyRegion.clear();
}
void SurfaceFlinger::composeSurfaces(const Region& dirty)
{
const DisplayHardware& hw(graphicPlane(0).displayHardware());
HWComposer& hwc(hw.getHwComposer());
hwc_layer_t* const cur(hwc.getLayers());
const size_t fbLayerCount =
hwc.getLayerCount(HWC_FRAMEBUFFER);
if (!cur || fbLayerCount) {
~~snip
const Vector< sp<LayerBase>
>& layers(mVisibleLayersSortedByZ);
const size_t count =
layers.size();
for (size_t i=0 ; i<count ; i++) {
const sp<LayerBase>& layer(layers[i]);
const Region clip(dirty.intersect(layer->visibleRegionScreen));
~~snip
/*如果不是HWC_FRAMEBUFFER 类型的话不处理,也就是让mdp去做处理。*/
#ifdef QCOMHW
if (cur && (cur[i].compositionType != HWC_FRAMEBUFFER))
continue;
#endif
/*依次调用各种layer的draw函数 */
// render the layer
layer->draw(clip);
}
}
~~snip
}
void LayerBase::draw(const Region& clip) const
{
//Dont draw External-only layers
if (isLayerExternalOnly(getLayer())) {
return;
}
onDraw(clip);
}
void Layer::onDraw(const Region& clip) const
{
~~snip
/*画图*/
drawWithOpenGL(clip);
glDisable(GL_TEXTURE_EXTERNAL_OES);
glDisable(GL_TEXTURE_2D);
}
void LayerBase::drawWithOpenGL(const Region& clip) const
{
const DisplayHardware& hw(graphicPlane(0).displayHardware());
const uint32_t fbHeight =
hw.getHeight();
const State& s(drawingState());
~~snip
struct TexCoords {
GLfloat u;
GLfloat v;
};
Rect crop(s.active.w, s.active.h);
if (!s.active.crop.isEmpty()) {
crop = s.active.crop;
}
GLfloat left = GLfloat(crop.left) / GLfloat(s.active.w);
GLfloat top =
GLfloat(crop.top) / GLfloat(s.active.h);
GLfloat right = GLfloat(crop.right) / GLfloat(s.active.w);
GLfloat bottom =
GLfloat(crop.bottom) / GLfloat(s.active.h);
/*得到顶点坐标*/
TexCoords texCoords[4];
texCoords[0].u = left;
texCoords[0].v =
top;
texCoords[1].u = left;
texCoords[1].v =
bottom;
texCoords[2].u = right;
texCoords[2].v =
bottom;
texCoords[3].u = right;
texCoords[3].v =
top;
for (int i = 0; i
< 4; i++) {
texCoords[i].v =
1.0f - texCoords[i].v;
}
/*OpenGL利用下面这些函数将根据纹理坐标和顶点坐标
得到最后layer的显示区域以及内容。*/
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glVertexPointer(2, GL_FLOAT, 0, mVertices);
glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
glDrawArrays(GL_TRIANGLE_FAN, 0, mNumVertices);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisable(GL_BLEND);
}
所以,composeSurfaces是服务于GPU的。
虽然mdp已经旋转完成了,但是似乎还没有看到如何送给mdp啊?看看postFramebuffer.
postFramebuffer
[html]
view plaincopyprint?
void SurfaceFlinger::postFramebuffer()
{
~~snip
const DisplayHardware& hw(graphicPlane(0).displayHardware());
const nsecs_t now = systemTime();
mDebugInSwapBuffers =
now;
hw.flip(mSwapRegion);
~~snip
}
void DisplayHardware::flip(const Region& dirty) const
{
~~snip
if (mHwc->initCheck() == NO_ERROR) {
mHwc->commit();
} else {
eglSwapBuffers(dpy, surface);
}
~~snip
}
status_t HWComposer::commit() const {
/*调用了HAL的set,看起来和硬件有关联了!*/
int err = mHwc->set(mHwc, mDpy, mSur, ((mSwapRectOn)?mListDirty:mList));
if (mSwapRectOn && mListDirty) {
mListDirty->flags &= ~HWC_GEOMETRY_CHANGED;
} else if ( mList) {
mList->flags &= ~HWC_GEOMETRY_CHANGED;
}
return (status_t)err;
}
static int hwc_set(hwc_composer_device_t *dev,
hwc_display_t dpy,
hwc_surface_t sur,
hwc_layer_list_t* list)
{
int ret = 0;
hwc_context_t* ctx = (hwc_context_t*)(dev);
if (LIKELY(list)) {
VideoOverlay::draw(ctx, list);
ExtOnly::draw(ctx, list);
CopyBit::draw(ctx, list, (EGLDisplay)dpy, (EGLSurface)sur);
/*调用到mdp的draw了!!!*/
MDPComp::draw(ctx, list);
EGLBoolean sucess =
eglSwapBuffers((EGLDisplay)dpy, (EGLSurface)sur);
~~snip
}
return ret;
}
总的下来,流程还是比较清晰的,不过里面很多transform很容易把人给弄晕掉,可以加log看值跟踪下。
2013/02/17
codebase: Android4.1
本文主要对SF(SurfaceFilnger)处理旋转事件的流程做个简单分析。GPU和mdp都可以用来旋转,文中对两者穿插说明。
系统初始化会调用GraphicPlane::setDisplayHardware,此函数主要判断系统是否默认设置了rotation property值,如果有,则先保存下来。另外,SF是以transform其实就是以矩阵来作旋转计算的,计算方法以线性代数中的知识为依据:
[html]
view plaincopyprint?
void GraphicPlane::setDisplayHardware(DisplayHardware *hw)
{
mHw = hw;
// initialize the display orientation transform.
// it's a constant that should come from the display driver.
int displayOrientation =
ISurfaceComposer::eOrientationDefault;
char property[PROPERTY_VALUE_MAX];
/*读取property*/
if (property_get("ro.sf.hwrotation", property, NULL)
> 0) {
//displayOrientation
switch (atoi(property)) {
/*当然,你也可以仿照添加180°的旋转。*/
case 90:
displayOrientation =
ISurfaceComposer::eOrientation90;
break;
case 270:
displayOrientation =
ISurfaceComposer::eOrientation270;
break;
}
}
const float w = hw->getWidth();
const float h =
hw->getHeight();
/*根据宽和高以及orientation生成一个transform*/
GraphicPlane::orientationToTransfrom(displayOrientation, w, h,
&mDisplayTransform);
/*90°或者270°时需要变换宽高。*/
if (displayOrientation & ISurfaceComposer::eOrientationSwapMask) {
mDisplayWidth =
h;
mDisplayHeight = w;
} else {
mDisplayWidth = w;
mDisplayHeight =
h;
}
/*保存当前全局旋转角度,意味着整个系统的显示都要根据整个值
来得出最后是否要旋转。如果为90°或者270°,那就是横屏,如果
是180°,画面就要反转180°。*/
setOrientation(ISurfaceComposer::eOrientationDefault);
}
status_t GraphicPlane::setOrientation(int orientation)
{
// If the rotation can be handled in hardware, this is where
// the magic should happen.
const DisplayHardware& hw(displayHardware());
const float w = mDisplayWidth;
const float h =
mDisplayHeight;
mWidth = int(w);
mHeight = int(h);
Transform orientationTransform;
GraphicPlane::orientationToTransfrom(orientation, w, h,
&orientationTransform);
if (orientation & ISurfaceComposer::eOrientationSwapMask) {
mWidth =
int(h);
mHeight = int(w);
}
mOrientation =
orientation;
/*将orientation和h/w计算和得出一个全局的transform,这里的
相乘计算方法,就是利用矩阵来实现的。*/
mGlobalTransform = mDisplayTransform * orientationTransform;
return NO_ERROR;
}
void GraphicPlane::setDisplayHardware(DisplayHardware *hw) { mHw = hw; // initialize the display orientation transform. // it's a constant that should come from the display driver. int displayOrientation = ISurfaceComposer::eOrientationDefault; char property[PROPERTY_VALUE_MAX]; /*读取property*/ if (property_get("ro.sf.hwrotation", property, NULL) > 0) { //displayOrientation switch (atoi(property)) { /*当然,你也可以仿照添加180°的旋转。*/ case 90: displayOrientation = ISurfaceComposer::eOrientation90; break; case 270: displayOrientation = ISurfaceComposer::eOrientation270; break; } } const float w = hw->getWidth(); const float h = hw->getHeight(); /*根据宽和高以及orientation生成一个transform*/ GraphicPlane::orientationToTransfrom(displayOrientation, w, h, &mDisplayTransform); /*90°或者270°时需要变换宽高。*/ if (displayOrientation & ISurfaceComposer::eOrientationSwapMask) { mDisplayWidth = h; mDisplayHeight = w; } else { mDisplayWidth = w; mDisplayHeight = h; } /*保存当前全局旋转角度,意味着整个系统的显示都要根据整个值 来得出最后是否要旋转。如果为90°或者270°,那就是横屏,如果 是180°,画面就要反转180°。*/ setOrientation(ISurfaceComposer::eOrientationDefault); } status_t GraphicPlane::setOrientation(int orientation) { // If the rotation can be handled in hardware, this is where // the magic should happen. const DisplayHardware& hw(displayHardware()); const float w = mDisplayWidth; const float h = mDisplayHeight; mWidth = int(w); mHeight = int(h); Transform orientationTransform; GraphicPlane::orientationToTransfrom(orientation, w, h, &orientationTransform); if (orientation & ISurfaceComposer::eOrientationSwapMask) { mWidth = int(h); mHeight = int(w); } mOrientation = orientation; /*将orientation和h/w计算和得出一个全局的transform,这里的 相乘计算方法,就是利用矩阵来实现的。*/ mGlobalTransform = mDisplayTransform * orientationTransform; return NO_ERROR; }
由于整个系统一直默认旋转只是流程中一个坐标的特殊处理,不管系统上层是否请求旋转,如横屏游戏,sensor坐标变化,默认的旋转是一直会被处理的。
注意别把这两种旋转混淆了,默认旋转是一般情况下用户看到的显示效果,而上层apk
请求的旋转相对默认旋转是瞬间的。
现在以上层发生旋转事件为例看下SF处理旋转的流程。
上层调用SurfaceFlinger::setTransactionState设置当前角度变化了:
[html]
view plaincopyprint?
void SurfaceFlinger::setTransactionState(const Vector<ComposerState>& state,
int orientation, uint32_t flags) {
Mutex::Autolock _l(mStateLock);
uint32_t transactionFlags =
0;
/*当前坐标和要设置的坐标不相等表明要作旋转了!*/
if (mCurrentState.orientation != orientation) {
if (uint32_t(orientation)<=eOrientation270 ||
orientation==42) {
mCurrentState.orientation =
orientation;
transactionFlags |= eTransactionNeeded;
} else if (orientation != eOrientationUnchanged) {
ALOGW("setTransactionState: ignoring unrecognized orientation: %d",
orientation);
}
}
/*设置旋转标志,SF处理的时候会用到。*/
const size_t count =
state.size();
for (size_t i=0 ; i<count ; i++) {
const ComposerState& s(state[i]);
sp<Client> client( static_cast<Client *>(s.client.get())
);
transactionFlags |= setClientStateLocked(client, s.state);
}
if (transactionFlags) {
// this triggers the transaction
setTransactionFlags(transactionFlags);
~~snip
}
void SurfaceFlinger::setTransactionState(const Vector<ComposerState>& state, int orientation, uint32_t flags) { Mutex::Autolock _l(mStateLock); uint32_t transactionFlags = 0; /*当前坐标和要设置的坐标不相等表明要作旋转了!*/ if (mCurrentState.orientation != orientation) { if (uint32_t(orientation)<=eOrientation270 || orientation==42) { mCurrentState.orientation = orientation; transactionFlags |= eTransactionNeeded; } else if (orientation != eOrientationUnchanged) { ALOGW("setTransactionState: ignoring unrecognized orientation: %d", orientation); } } /*设置旋转标志,SF处理的时候会用到。*/ const size_t count = state.size(); for (size_t i=0 ; i<count ; i++) { const ComposerState& s(state[i]); sp<Client> client( static_cast<Client *>(s.client.get()) ); transactionFlags |= setClientStateLocked(client, s.state); } if (transactionFlags) { // this triggers the transaction setTransactionFlags(transactionFlags); ~~snip }
SF收到消息后,调用SurfaceFlinger::onMessageReceived进行处理,核心的部分都在这里了。
[html]
view plaincopyprint?
void SurfaceFlinger::onMessageReceived(int32_t what)
{
ATRACE_CALL();
switch (what) {
case MessageQueue::INVALIDATE:
case MessageQueue::REFRESH: {
// case MessageQueue::INVALIDATE: {
// if we're in a global transaction, don't do anything.
const uint32_t mask =
eTransactionNeeded | eTraversalNeeded;
uint32_t transactionFlags =
peekTransactionFlags(mask);
/*处理事务*/
if (CC_UNLIKELY(transactionFlags)) {
handleTransaction(transactionFlags);
}
const uint32_t mask1 =
eDelayedTraversalNeeded;
uint32_t transactionFlags1 =
peekTransactionFlags(mask1);
if (CC_UNLIKELY(transactionFlags1)) {
handleDelayedTransaction(transactionFlags);
}
/*计算可视区域*/
// post surfaces (if needed)
handlePageFlip();
~~snip
case MessageQueue::REFRESH: {
~~snip
/*处理几何坐标*/
if (CC_UNLIKELY(mHwWorkListDirty)) {
// build the h/w work list
handleWorkList();
}
/*render*/
if (CC_LIKELY(hw.canDraw())) {
// repaint the framebuffer (if needed)
handleRepaint();
// inform the h/w that we're done compositing
hw.compositionComplete();
postFramebuffer();
} else {
// pretend we did the post
hw.compositionComplete();
}
} break;
}
}
void SurfaceFlinger::onMessageReceived(int32_t what) { ATRACE_CALL(); switch (what) { case MessageQueue::INVALIDATE: case MessageQueue::REFRESH: { // case MessageQueue::INVALIDATE: { // if we're in a global transaction, don't do anything. const uint32_t mask = eTransactionNeeded | eTraversalNeeded; uint32_t transactionFlags = peekTransactionFlags(mask); /*处理事务*/ if (CC_UNLIKELY(transactionFlags)) { handleTransaction(transactionFlags); } const uint32_t mask1 = eDelayedTraversalNeeded; uint32_t transactionFlags1 = peekTransactionFlags(mask1); if (CC_UNLIKELY(transactionFlags1)) { handleDelayedTransaction(transactionFlags); } /*计算可视区域*/ // post surfaces (if needed) handlePageFlip(); ~~snip case MessageQueue::REFRESH: { ~~snip /*处理几何坐标*/ if (CC_UNLIKELY(mHwWorkListDirty)) { // build the h/w work list handleWorkList(); } /*render*/ if (CC_LIKELY(hw.canDraw())) { // repaint the framebuffer (if needed) handleRepaint(); // inform the h/w that we're done compositing hw.compositionComplete(); postFramebuffer(); } else { // pretend we did the post hw.compositionComplete(); } } break; } }
下面一一对这几个函数分析。
handleTransaction
[html]
view plaincopyprint?
void SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
{
~~snip
const uint32_t mask =
eTransactionNeeded | eTraversalNeeded;
transactionFlags = getTransactionFlags(mask);
handleTransactionLocked(transactionFlags);
~~snip
}
void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
{
const LayerVector& currentLayers(mCurrentState.layersSortedByZ);
const size_t count = currentLayers.size();
/*
* Traversal of the children
* (perform the transaction for each of them if needed)
*/
/*判断是否有事务要处理。*/
const bool layersNeedTransaction =
transactionFlags & eTraversalNeeded;
if (layersNeedTransaction) {
for (size_t i=0 ; i<count ; i++) {
const sp<LayerBase>&
layer = currentLayers[i];
uint32_t trFlags =
layer->getTransactionFlags(eTransactionNeeded);
if (!trFlags) continue;
const uint32_t flags =
layer->doTransaction(0);
if (flags & Layer::eVisibleRegion)
mVisibleRegionsDirty =
true;
}
}
~~snip
if (transactionFlags & eTransactionNeeded) {
/*有旋转角度变化的事务。*/
if (mCurrentState.orientation != mDrawingState.orientation) {
// the orientation has changed, recompute all visible regions
// and invalidate everything.
const int dpy =
0;
const int orientation =
mCurrentState.orientation;
// Currently unused: const uint32_t
flags = mCurrentState.orientationFlags;
GraphicPlane& plane(graphicPlane(dpy));
/*根据当前旋转的坐标,还有默认的旋转坐标,计算和得出最终全局transform。
此函数前面分析过了。*/
plane.setOrientation(orientation);
const Transform& planeTransform(plane.transform());
// update the shared control block
const DisplayHardware& hw(plane.displayHardware());
volatile display_cblk_t* dcblk =
mServerCblk->displays + dpy;
dcblk->orientation =
orientation;
dcblk->w =
plane.getWidth();
dcblk->h =
plane.getHeight();
/*旋转过后当然要重新绘制显示画面了,设置标志。*/
mVisibleRegionsDirty =
true;
mDirtyRegion.set(hw.bounds());
}
~~snip
}
void SurfaceFlinger::handleTransaction(uint32_t transactionFlags) { ~~snip const uint32_t mask = eTransactionNeeded | eTraversalNeeded; transactionFlags = getTransactionFlags(mask); handleTransactionLocked(transactionFlags); ~~snip } void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) { const LayerVector& currentLayers(mCurrentState.layersSortedByZ); const size_t count = currentLayers.size(); /* * Traversal of the children * (perform the transaction for each of them if needed) */ /*判断是否有事务要处理。*/ const bool layersNeedTransaction = transactionFlags & eTraversalNeeded; if (layersNeedTransaction) { for (size_t i=0 ; i<count ; i++) { const sp<LayerBase>& layer = currentLayers[i]; uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded); if (!trFlags) continue; const uint32_t flags = layer->doTransaction(0); if (flags & Layer::eVisibleRegion) mVisibleRegionsDirty = true; } } ~~snip if (transactionFlags & eTransactionNeeded) { /*有旋转角度变化的事务。*/ if (mCurrentState.orientation != mDrawingState.orientation) { // the orientation has changed, recompute all visible regions // and invalidate everything. const int dpy = 0; const int orientation = mCurrentState.orientation; // Currently unused: const uint32_t flags = mCurrentState.orientationFlags; GraphicPlane& plane(graphicPlane(dpy)); /*根据当前旋转的坐标,还有默认的旋转坐标,计算和得出最终全局transform。 此函数前面分析过了。*/ plane.setOrientation(orientation); const Transform& planeTransform(plane.transform()); // update the shared control block const DisplayHardware& hw(plane.displayHardware()); volatile display_cblk_t* dcblk = mServerCblk->displays + dpy; dcblk->orientation = orientation; dcblk->w = plane.getWidth(); dcblk->h = plane.getHeight(); /*旋转过后当然要重新绘制显示画面了,设置标志。*/ mVisibleRegionsDirty = true; mDirtyRegion.set(hw.bounds()); } ~~snip }
可见handleTransaction主要设置全局的transform。
handlePageFlip
[html]
view plaincopyprint?
void SurfaceFlinger::handlePageFlip()
{
ATRACE_CALL();
const DisplayHardware& hw =
graphicPlane(0).displayHardware();
const Region screenRegion(hw.bounds());
const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
const bool visibleRegions =
lockPageFlip(currentLayers);
if (visibleRegions || mVisibleRegionsDirty) {
Region opaqueRegion;
/*有旋转过,所以要重新计算可视区域*/
computeVisibleRegions(currentLayers, mDirtyRegion, opaqueRegion);
~~snip
}
~~snip
}
void SurfaceFlinger::computeVisibleRegions(
const LayerVector& currentLayers, Region& dirtyRegion, Region& opaqueRegion)
{
ATRACE_CALL();
const GraphicPlane& plane(graphicPlane(0));
const Transform& planeTransform(plane.transform());
const DisplayHardware& hw(plane.displayHardware());
const Region screenRegion(hw.bounds());
Region aboveOpaqueLayers;
Region aboveCoveredLayers;
Region dirty;
bool secureFrameBuffer =
false;
size_t i = currentLayers.size();
while (i--) {
const sp<LayerBase>&
layer = currentLayers[i];
/*将全局的transform传进去,然后调用各个layer作计算。*/
layer->validateVisibility(planeTransform);
~~snip
}
}
void LayerBase::validateVisibility(const Transform& planeTransform)
{
const Layer::State& s(drawingState());
/*全局transform和当前layer的transform相乘计算得到一个transform.*/
const Transform tr(planeTransform * s.transform);
const bool transformed =
tr.transformed();
const DisplayHardware& hw(graphicPlane(0).displayHardware());
const uint32_t hw_h =
hw.getHeight();
const Rect& crop(s.active.crop);
Rect win(s.active.w, s.active.h);
if (!crop.isEmpty()) {
win.intersect(crop, &win);
}
mNumVertices =
4;
/* mVertices 相当重要,系统根据当前的transform还有当前layer的
区域作计算,当然也包含了全局的transform信息在里面,计算出来的
坐标保存到了mVertices 去。要注意,mVertices 只是给GPU用的,如果
用mdp做旋转,SF后面的流程会对其做相应设置。*/
tr.transform(mVertices[0], win.left, win.top);
tr.transform(mVertices[1], win.left, win.bottom);
tr.transform(mVertices[2], win.right, win.bottom);
tr.transform(mVertices[3], win.right, win.top);
for (size_t i=0 ; i<4 ; i++)
mVertices[i][1] = hw_h - mVertices[i][1];
if (CC_UNLIKELY(transformed)) {
// NOTE: here we could also punt if we have too many rectangles
// in the transparent region
/*根据transform对透明区域作处理。*/
if (tr.preserveRects()) {
// transform the transparent region
transparentRegionScreen =
tr.transform(s.transparentRegion);
} else {
// transformation too complex, can't do the transparent region
// optimization.
transparentRegionScreen.clear();
}
} else {
transparentRegionScreen =
s.transparentRegion;
}
/*保存相应的一些信息到新的参数变量中,以便后面用到。*/
// cache a few things...
mOrientation =
tr.getOrientation();
mPlaneOrientation = planeTransform.getOrientation();
mTransform =
tr;
mTransformedBounds = tr.transform(win);
}
void SurfaceFlinger::handlePageFlip() { ATRACE_CALL(); const DisplayHardware& hw = graphicPlane(0).displayHardware(); const Region screenRegion(hw.bounds()); const LayerVector& currentLayers(mDrawingState.layersSortedByZ); const bool visibleRegions = lockPageFlip(currentLayers); if (visibleRegions || mVisibleRegionsDirty) { Region opaqueRegion; /*有旋转过,所以要重新计算可视区域*/ computeVisibleRegions(currentLayers, mDirtyRegion, opaqueRegion); ~~snip } ~~snip } void SurfaceFlinger::computeVisibleRegions( const LayerVector& currentLayers, Region& dirtyRegion, Region& opaqueRegion) { ATRACE_CALL(); const GraphicPlane& plane(graphicPlane(0)); const Transform& planeTransform(plane.transform()); const DisplayHardware& hw(plane.displayHardware()); const Region screenRegion(hw.bounds()); Region aboveOpaqueLayers; Region aboveCoveredLayers; Region dirty; bool secureFrameBuffer = false; size_t i = currentLayers.size(); while (i--) { const sp<LayerBase>& layer = currentLayers[i]; /*将全局的transform传进去,然后调用各个layer作计算。*/ layer->validateVisibility(planeTransform); ~~snip } } void LayerBase::validateVisibility(const Transform& planeTransform) { const Layer::State& s(drawingState()); /*全局transform和当前layer的transform相乘计算得到一个transform.*/ const Transform tr(planeTransform * s.transform); const bool transformed = tr.transformed(); const DisplayHardware& hw(graphicPlane(0).displayHardware()); const uint32_t hw_h = hw.getHeight(); const Rect& crop(s.active.crop); Rect win(s.active.w, s.active.h); if (!crop.isEmpty()) { win.intersect(crop, &win); } mNumVertices = 4; /* mVertices 相当重要,系统根据当前的transform还有当前layer的 区域作计算,当然也包含了全局的transform信息在里面,计算出来的 坐标保存到了mVertices 去。要注意,mVertices 只是给GPU用的,如果 用mdp做旋转,SF后面的流程会对其做相应设置。*/ tr.transform(mVertices[0], win.left, win.top); tr.transform(mVertices[1], win.left, win.bottom); tr.transform(mVertices[2], win.right, win.bottom); tr.transform(mVertices[3], win.right, win.top); for (size_t i=0 ; i<4 ; i++) mVertices[i][1] = hw_h - mVertices[i][1]; if (CC_UNLIKELY(transformed)) { // NOTE: here we could also punt if we have too many rectangles // in the transparent region /*根据transform对透明区域作处理。*/ if (tr.preserveRects()) { // transform the transparent region transparentRegionScreen = tr.transform(s.transparentRegion); } else { // transformation too complex, can't do the transparent region // optimization. transparentRegionScreen.clear(); } } else { transparentRegionScreen = s.transparentRegion; } /*保存相应的一些信息到新的参数变量中,以便后面用到。*/ // cache a few things... mOrientation = tr.getOrientation(); mPlaneOrientation = planeTransform.getOrientation(); mTransform = tr; mTransformedBounds = tr.transform(win); }
可见,从handlePageFlip中,我们主要是得到了GPU要处理的坐标,保存到了mVertices数组中。
handleWorkList
[html]
view plaincopyprint?
void SurfaceFlinger::handleWorkList()
{
mHwWorkListDirty =
false;
HWComposer& hwc(graphicPlane(0).displayHardware().getHwComposer());
if (hwc.initCheck() == NO_ERROR) {
const Vector< sp<LayerBase>
>& currentLayers(mVisibleLayersSortedByZ);
const size_t count =
currentLayers.size();
hwc.createWorkList(count);
hwc_layer_t* const cur(hwc.getLayers());
for (size_t i=0 ; cur && i<count ; i++) {
/*依次调用各个layer的setGeometry 。*/
currentLayers[i]->setGeometry(&cur[i]);
}
}
}
void Layer::setGeometry(hwc_layer_t* hwcl)
{
/*调用基类函数。*/
LayerBaseClient::setGeometry(hwcl);
hwcl->flags &= ~HWC_SKIP_LAYER;
/*不完全透明时需要GPU处理。*/
// we can't do alpha-fade with the hwc HAL
const State& s(drawingState());
if (s.alpha < 0xFF) {
hwcl->flags =
HWC_SKIP_LAYER;
}
/*
* Transformations are applied in this order:
* 1) buffer orientation/flip/mirror
* 2) state transformation (window manager)
* 3) layer orientation (screen orientation)
* mTransform is already the composition of (2) and (3)
* (NOTE: the matrices are multiplied in reverse order)
*/
/*这里就是在根据要求的旋转信息得出最终的transform,
然后赋值给hwcl,hwcl的信息最后会传给mdp处理。*/
const Transform bufferOrientation(mCurrentTransform);
hwcl->sourceTransform =
bufferOrientation.getOrientation();
const Transform tr(mTransform * bufferOrientation);
// this gives us only the "orientation" component of the transform
const uint32_t finalTransform =
tr.getOrientation();
// we can only handle simple transformation
if (finalTransform & Transform::ROT_INVALID) {
hwcl->flags =
HWC_SKIP_LAYER;
} else {
hwcl->transform =
finalTransform;
}
/*得到layer区域相对坐标,绝对坐标在基类中计算得到。*/
Rect crop = computeBufferCrop();
hwcl->sourceCrop.left =
crop.left;
hwcl->sourceCrop.top =
crop.top;
hwcl->sourceCrop.right =
crop.right;
hwcl->sourceCrop.bottom =
crop.bottom;
}
void SurfaceFlinger::handleWorkList() { mHwWorkListDirty = false; HWComposer& hwc(graphicPlane(0).displayHardware().getHwComposer()); if (hwc.initCheck() == NO_ERROR) { const Vector< sp<LayerBase> >& currentLayers(mVisibleLayersSortedByZ); const size_t count = currentLayers.size(); hwc.createWorkList(count); hwc_layer_t* const cur(hwc.getLayers()); for (size_t i=0 ; cur && i<count ; i++) { /*依次调用各个layer的setGeometry 。*/ currentLayers[i]->setGeometry(&cur[i]); } } } void Layer::setGeometry(hwc_layer_t* hwcl) { /*调用基类函数。*/ LayerBaseClient::setGeometry(hwcl); hwcl->flags &= ~HWC_SKIP_LAYER; /*不完全透明时需要GPU处理。*/ // we can't do alpha-fade with the hwc HAL const State& s(drawingState()); if (s.alpha < 0xFF) { hwcl->flags = HWC_SKIP_LAYER; } /* * Transformations are applied in this order: * 1) buffer orientation/flip/mirror * 2) state transformation (window manager) * 3) layer orientation (screen orientation) * mTransform is already the composition of (2) and (3) * (NOTE: the matrices are multiplied in reverse order) */ /*这里就是在根据要求的旋转信息得出最终的transform, 然后赋值给hwcl,hwcl的信息最后会传给mdp处理。*/ const Transform bufferOrientation(mCurrentTransform); hwcl->sourceTransform = bufferOrientation.getOrientation(); const Transform tr(mTransform * bufferOrientation); // this gives us only the "orientation" component of the transform const uint32_t finalTransform = tr.getOrientation(); // we can only handle simple transformation if (finalTransform & Transform::ROT_INVALID) { hwcl->flags = HWC_SKIP_LAYER; } else { hwcl->transform = finalTransform; } /*得到layer区域相对坐标,绝对坐标在基类中计算得到。*/ Rect crop = computeBufferCrop(); hwcl->sourceCrop.left = crop.left; hwcl->sourceCrop.top = crop.top; hwcl->sourceCrop.right = crop.right; hwcl->sourceCrop.bottom = crop.bottom; }
由此看来handleWorkList主要是服务于mdp的,如果用GPU旋转的话可以不需要这些信息。
handleRepaint
[html]
view plaincopyprint?
void SurfaceFlinger::handleRepaint()
{
~~snip
setupHardwareComposer();
/*对各个layer作render*/
composeSurfaces(mDirtyRegion);
// update the swap region and clear the dirty region
mSwapRegion.orSelf(mDirtyRegion);
mDirtyRegion.clear();
}
void SurfaceFlinger::composeSurfaces(const Region& dirty)
{
const DisplayHardware& hw(graphicPlane(0).displayHardware());
HWComposer& hwc(hw.getHwComposer());
hwc_layer_t* const cur(hwc.getLayers());
const size_t fbLayerCount =
hwc.getLayerCount(HWC_FRAMEBUFFER);
if (!cur || fbLayerCount) {
~~snip
const Vector< sp<LayerBase>
>& layers(mVisibleLayersSortedByZ);
const size_t count =
layers.size();
for (size_t i=0 ; i<count ; i++) {
const sp<LayerBase>& layer(layers[i]);
const Region clip(dirty.intersect(layer->visibleRegionScreen));
~~snip
/*如果不是HWC_FRAMEBUFFER 类型的话不处理,也就是让mdp去做处理。*/
#ifdef QCOMHW
if (cur && (cur[i].compositionType != HWC_FRAMEBUFFER))
continue;
#endif
/*依次调用各种layer的draw函数 */
// render the layer
layer->draw(clip);
}
}
~~snip
}
void LayerBase::draw(const Region& clip) const
{
//Dont draw External-only layers
if (isLayerExternalOnly(getLayer())) {
return;
}
onDraw(clip);
}
void Layer::onDraw(const Region& clip) const
{
~~snip
/*画图*/
drawWithOpenGL(clip);
glDisable(GL_TEXTURE_EXTERNAL_OES);
glDisable(GL_TEXTURE_2D);
}
void LayerBase::drawWithOpenGL(const Region& clip) const
{
const DisplayHardware& hw(graphicPlane(0).displayHardware());
const uint32_t fbHeight =
hw.getHeight();
const State& s(drawingState());
~~snip
struct TexCoords {
GLfloat u;
GLfloat v;
};
Rect crop(s.active.w, s.active.h);
if (!s.active.crop.isEmpty()) {
crop = s.active.crop;
}
GLfloat left = GLfloat(crop.left) / GLfloat(s.active.w);
GLfloat top =
GLfloat(crop.top) / GLfloat(s.active.h);
GLfloat right = GLfloat(crop.right) / GLfloat(s.active.w);
GLfloat bottom =
GLfloat(crop.bottom) / GLfloat(s.active.h);
/*得到顶点坐标*/
TexCoords texCoords[4];
texCoords[0].u = left;
texCoords[0].v =
top;
texCoords[1].u = left;
texCoords[1].v =
bottom;
texCoords[2].u = right;
texCoords[2].v =
bottom;
texCoords[3].u = right;
texCoords[3].v =
top;
for (int i = 0; i
< 4; i++) {
texCoords[i].v =
1.0f - texCoords[i].v;
}
/*OpenGL利用下面这些函数将根据纹理坐标和顶点坐标
得到最后layer的显示区域以及内容。*/
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glVertexPointer(2, GL_FLOAT, 0, mVertices);
glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
glDrawArrays(GL_TRIANGLE_FAN, 0, mNumVertices);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisable(GL_BLEND);
}
void SurfaceFlinger::handleRepaint() { ~~snip setupHardwareComposer(); /*对各个layer作render*/ composeSurfaces(mDirtyRegion); // update the swap region and clear the dirty region mSwapRegion.orSelf(mDirtyRegion); mDirtyRegion.clear(); } void SurfaceFlinger::composeSurfaces(const Region& dirty) { const DisplayHardware& hw(graphicPlane(0).displayHardware()); HWComposer& hwc(hw.getHwComposer()); hwc_layer_t* const cur(hwc.getLayers()); const size_t fbLayerCount = hwc.getLayerCount(HWC_FRAMEBUFFER); if (!cur || fbLayerCount) { ~~snip const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ); const size_t count = layers.size(); for (size_t i=0 ; i<count ; i++) { const sp<LayerBase>& layer(layers[i]); const Region clip(dirty.intersect(layer->visibleRegionScreen)); ~~snip /*如果不是HWC_FRAMEBUFFER 类型的话不处理,也就是让mdp去做处理。*/ #ifdef QCOMHW if (cur && (cur[i].compositionType != HWC_FRAMEBUFFER)) continue; #endif /*依次调用各种layer的draw函数 */ // render the layer layer->draw(clip); } } ~~snip } void LayerBase::draw(const Region& clip) const { //Dont draw External-only layers if (isLayerExternalOnly(getLayer())) { return; } onDraw(clip); } void Layer::onDraw(const Region& clip) const { ~~snip /*画图*/ drawWithOpenGL(clip); glDisable(GL_TEXTURE_EXTERNAL_OES); glDisable(GL_TEXTURE_2D); } void LayerBase::drawWithOpenGL(const Region& clip) const { const DisplayHardware& hw(graphicPlane(0).displayHardware()); const uint32_t fbHeight = hw.getHeight(); const State& s(drawingState()); ~~snip struct TexCoords { GLfloat u; GLfloat v; }; Rect crop(s.active.w, s.active.h); if (!s.active.crop.isEmpty()) { crop = s.active.crop; } GLfloat left = GLfloat(crop.left) / GLfloat(s.active.w); GLfloat top = GLfloat(crop.top) / GLfloat(s.active.h); GLfloat right = GLfloat(crop.right) / GLfloat(s.active.w); GLfloat bottom = GLfloat(crop.bottom) / GLfloat(s.active.h); /*得到顶点坐标*/ TexCoords texCoords[4]; texCoords[0].u = left; texCoords[0].v = top; texCoords[1].u = left; texCoords[1].v = bottom; texCoords[2].u = right; texCoords[2].v = bottom; texCoords[3].u = right; texCoords[3].v = top; for (int i = 0; i < 4; i++) { texCoords[i].v = 1.0f - texCoords[i].v; } /*OpenGL利用下面这些函数将根据纹理坐标和顶点坐标 得到最后layer的显示区域以及内容。*/ glEnableClientState(GL_TEXTURE_COORD_ARRAY); glVertexPointer(2, GL_FLOAT, 0, mVertices); glTexCoordPointer(2, GL_FLOAT, 0, texCoords); glDrawArrays(GL_TRIANGLE_FAN, 0, mNumVertices); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisable(GL_BLEND); }
所以,composeSurfaces是服务于GPU的。
虽然mdp已经旋转完成了,但是似乎还没有看到如何送给mdp啊?看看postFramebuffer.
postFramebuffer
[html]
view plaincopyprint?
void SurfaceFlinger::postFramebuffer()
{
~~snip
const DisplayHardware& hw(graphicPlane(0).displayHardware());
const nsecs_t now = systemTime();
mDebugInSwapBuffers =
now;
hw.flip(mSwapRegion);
~~snip
}
void DisplayHardware::flip(const Region& dirty) const
{
~~snip
if (mHwc->initCheck() == NO_ERROR) {
mHwc->commit();
} else {
eglSwapBuffers(dpy, surface);
}
~~snip
}
status_t HWComposer::commit() const {
/*调用了HAL的set,看起来和硬件有关联了!*/
int err = mHwc->set(mHwc, mDpy, mSur, ((mSwapRectOn)?mListDirty:mList));
if (mSwapRectOn && mListDirty) {
mListDirty->flags &= ~HWC_GEOMETRY_CHANGED;
} else if ( mList) {
mList->flags &= ~HWC_GEOMETRY_CHANGED;
}
return (status_t)err;
}
static int hwc_set(hwc_composer_device_t *dev,
hwc_display_t dpy,
hwc_surface_t sur,
hwc_layer_list_t* list)
{
int ret = 0;
hwc_context_t* ctx = (hwc_context_t*)(dev);
if (LIKELY(list)) {
VideoOverlay::draw(ctx, list);
ExtOnly::draw(ctx, list);
CopyBit::draw(ctx, list, (EGLDisplay)dpy, (EGLSurface)sur);
/*调用到mdp的draw了!!!*/
MDPComp::draw(ctx, list);
EGLBoolean sucess =
eglSwapBuffers((EGLDisplay)dpy, (EGLSurface)sur);
~~snip
}
return ret;
}
void SurfaceFlinger::postFramebuffer() { ~~snip const DisplayHardware& hw(graphicPlane(0).displayHardware()); const nsecs_t now = systemTime(); mDebugInSwapBuffers = now; hw.flip(mSwapRegion); ~~snip } void DisplayHardware::flip(const Region& dirty) const { ~~snip if (mHwc->initCheck() == NO_ERROR) { mHwc->commit(); } else { eglSwapBuffers(dpy, surface); } ~~snip } status_t HWComposer::commit() const { /*调用了HAL的set,看起来和硬件有关联了!*/ int err = mHwc->set(mHwc, mDpy, mSur, ((mSwapRectOn)?mListDirty:mList)); if (mSwapRectOn && mListDirty) { mListDirty->flags &= ~HWC_GEOMETRY_CHANGED; } else if ( mList) { mList->flags &= ~HWC_GEOMETRY_CHANGED; } return (status_t)err; } static int hwc_set(hwc_composer_device_t *dev, hwc_display_t dpy, hwc_surface_t sur, hwc_layer_list_t* list) { int ret = 0; hwc_context_t* ctx = (hwc_context_t*)(dev); if (LIKELY(list)) { VideoOverlay::draw(ctx, list); ExtOnly::draw(ctx, list); CopyBit::draw(ctx, list, (EGLDisplay)dpy, (EGLSurface)sur); /*调用到mdp的draw了!!!*/ MDPComp::draw(ctx, list); EGLBoolean sucess = eglSwapBuffers((EGLDisplay)dpy, (EGLSurface)sur); ~~snip } return ret; }
总的下来,流程还是比较清晰的,不过里面很多transform很容易把人给弄晕掉,可以加log看值跟踪下。
2013/02/17
相关文章推荐
- Surfaceflinger process流程分析
- Android SurfaceFlinger VSync流程分析
- Surfaceflinger process流程分析
- Android display架构分析七-Surfaceflinger process流程分析
- Android display架构分析七-Surfaceflinger process流程分析
- Android SurfaceFlinger process 流程分析
- Surfaceflinger process流程分析
- surfaceflinger process 进程分析
- Android SurfaceFlinger 学习之路(三)----Android开机动画流程简述
- Android核心分析之(27)Android GDI 之SurfaceFlinger之动态结构...
- SurfaceFlinger启动过程分析(一)、(二)、(三)、(四)【转】
- Android SurfaceFlinger服务代理对象获取过程源码分析
- Android surfaceflinger 源代码分析
- SurfaceFlinger启动过程分析(一)、(二)、(三)、(四)【转】
- Android SurfaceFlinger服务启动过程源码分析1
- Android 7.1 WindowManagerService 屏幕旋转流程分析 (二)
- Android系统Surface机制的SurfaceFlinger服务的启动过程分析
- Android SurfaceFlinger服务的消息循环过程源码分析
- GUI系统之SurfaceFlinger(7)应用程序的典型绘图流程
- 通过 dumpsys SurfaceFlinger 分析Android 系统图层