作者: zangcf 时间: 2016-4-27 18:40
下面的思路,我们还是从surface进行入手考虑:
1,当系统申请生成一个surface的时候,我们顺便生成一个影子surface
2,当系统对surface进行画图的时候,我们同时也对影子surface进行画图。
3,当系统对surface进行提交的时候,我们也对影子surface进行提交。
4,但是需要修改yi影子surface的参数,使得其下一到后半个屏幕作者: zangcf 时间: 2016-4-27 19:19
public int relayoutWindow(Session session, IWindow client, int seq,
WindowManager.LayoutParams attrs, int requestedWidth,
int requestedHeight, int viewVisibility, int flags,
Rect outFrame, Rect outOverscanInsets, Rect outContentInsets,
Rect outVisibleInsets, Rect outStableInsets, Configuration outConfig,
Surface outSurface) {
中会调用::
try {
if (!win.mHasSurface) {
surfaceChanged = true;
}
SurfaceControl surfaceControl = winAnimator.createSurfaceLocked();
if (surfaceControl != null) {
outSurface.copyFrom(surfaceControl);
if (SHOW_TRANSACTIONS) Slog.i(TAG,
" OUT SURFACE " + outSurface + ": copied");
} else {
// For some reason there isn't a surface. Clear the
// caller's object so they see the same state.
outSurface.release();
} 作者: zangcf 时间: 2016-4-27 19:20
SurfaceControl createSurfaceLocked() {
final WindowState w = mWin;
if (mSurfaceControl == null) {
if (WindowManagerService.DEBUG_ANIM || WindowManagerService.DEBUG_ORIENTATION) Slog.i(TAG,
"createSurface " + this + ": mDrawState=DRAW_PENDING");
mDrawState = DRAW_PENDING;
if (w.mAppToken != null) {
if (w.mAppToken.mAppAnimator.animation == null) {
w.mAppToken.allDrawn = false;
w.mAppToken.deferClearAllDrawn = false;
} else {
// Currently animating, persist current state of allDrawn until animation
// is complete.
w.mAppToken.deferClearAllDrawn = true;
}
}
int flags = SurfaceControl.HIDDEN;
final WindowManager.LayoutParams attrs = w.mAttrs;
if ((attrs.flags&WindowManager.LayoutParams.FLAG_SECURE) != 0) {
flags |= SurfaceControl.SECURE;
}
if (mService.isScreenCaptureDisabledLocked(UserHandle.getUserId(mWin.mOwnerUid))) {
flags |= SurfaceControl.SECURE;
}
int width;
int height;
if ((attrs.flags & LayoutParams.FLAG_SCALED) != 0) {
// for a scaled surface, we always want the requested
// size.
width = w.mRequestedWidth;
height = w.mRequestedHeight;
} else {
width = w.mCompatFrame.width();
height = w.mCompatFrame.height();
}
// Something is wrong and SurfaceFlinger will not like this,
// try to revert to sane values
if (width <= 0) {
width = 1;
}
if (height <= 0) {
height = 1;
}
float left = w.mFrame.left + w.mXOffset;
float top = w.mFrame.top + w.mYOffset;
// Adjust for surface insets.
width += attrs.surfaceInsets.left + attrs.surfaceInsets.right;
height += attrs.surfaceInsets.top + attrs.surfaceInsets.bottom;
left -= attrs.surfaceInsets.left;
top -= attrs.surfaceInsets.top;
if (DEBUG_VISIBILITY) {
Slog.v(TAG, "Creating surface in session "
+ mSession.mSurfaceSession + " window " + this
+ " w=" + width + " h=" + height
+ " x=" + left + " y=" + top
+ " format=" + attrs.format + " flags=" + flags);
}
// We may abort, so initialize to defaults.
mSurfaceShown = false;
mSurfaceLayer = 0;
mSurfaceAlpha = 0;
mSurfaceX = 0;
mSurfaceY = 0;
w.mLastSystemDecorRect.set(0, 0, 0, 0);
mLastClipRect.set(0, 0, 0, 0);
// Set up surface control with initial size.
try {
mSurfaceW = width;
mSurfaceH = height;
final boolean isHwAccelerated = (attrs.flags &
WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED) != 0;
final int format = isHwAccelerated ? PixelFormat.TRANSLUCENT : attrs.format;
if (!PixelFormat.formatHasAlpha(attrs.format)
&& attrs.surfaceInsets.left == 0
&& attrs.surfaceInsets.top == 0
&& attrs.surfaceInsets.right == 0
&& attrs.surfaceInsets.bottom == 0) {
flags |= SurfaceControl.OPAQUE;
}
if (WindowManagerService.DEBUG_SURFACE_TRACE) {
mSurfaceControl = new SurfaceTrace(
mSession.mSurfaceSession,
attrs.getTitle().toString(),
width, height, format, flags);
} else {
mSurfaceControl = new SurfaceControl(
mSession.mSurfaceSession,
attrs.getTitle().toString(),
width, height, format, flags);
}