on
화면 회전 관련내용
평소에 폰을 사용할때 디스플레이의 방향전환, 회전이 발생할때
뭔가 반응이 느리고 멈추는일이 잦은거같아서 찾아보았습니다
(센서감지callback or 앱 – 프레임워크 메소드호출)
`
public void setRequestedOrientation(@ActivityInfo.ScreenOrientation int requestedOrientation) {
5759 if (mParent == null) {
5760 try {
5761 ActivityManager.getService().setRequestedOrientation(
5762 mToken, requestedOrientation);
5763 } catch (RemoteException e) {
5764 // Empty
5765 }
5766 } else {
5767 mParent.setRequestedOrientation(requestedOrientation);
5768 }
5769 } ` 액티비티 매니저의 setrequested orientation 호출
그후에 activityrecord 의 setRequestedOrientation 호출
`
2193 void setRequestedOrientation(int requestedOrientation) {
2194 final int displayId = getDisplayId();
2195 final Configuration displayConfig =
2196 mStackSupervisor.getDisplayOverrideConfiguration(displayId);
2197
2198 final Configuration config = mWindowContainerController.setOrientation(requestedOrientation,
2199 displayId, displayConfig, mayFreezeScreenLocked(app));
2200 if (config != null) {
2201 frozenBeforeDestroy = true;
2202 if (!service.updateDisplayOverrideConfigurationLocked(config, this,
2203 false /* deferResume */, displayId)) {
2204 mStackSupervisor.resumeFocusedStackTopActivityLocked();
2205 }
2206 }
2207 service.mTaskChangeNotificationController.notifyActivityRequestedOrientationChanged(
2208 task.taskId, requestedOrientation);
2209 }
`
여기서 display (출력 device) 의 config를 변경한후에
config를 적용하도록 하는듯 보입니다.
`
275 public Configuration setOrientation(int requestedOrientation, int displayId,
276 Configuration displayConfig, boolean freezeScreenIfNeeded) {
277 synchronized(mWindowMap) {
278 if (mContainer == null) {
279 Slog.w(TAG_WM,
280 “Attempted to set orientation of non-existing app token: “ + mToken);
281 return null;
282 }
283
284 mContainer.setOrientation(requestedOrientation);
285
286 final IBinder binder = freezeScreenIfNeeded ? mToken.asBinder() : null;
287 return mService.updateOrientationFromAppTokens(displayConfig, binder, displayId);
288
289 }
290 }
`
윈도우 매니저 서비스 디렉토리에있는
AppWindowContainerController.java 에서..
`
2574 boolean updateOrientationFromAppTokensLocked(boolean inTransaction, int displayId) {
2575 long ident = Binder.clearCallingIdentity();
2576 try {
2577 final DisplayContent dc = mRoot.getDisplayContent(displayId);
2578 final int req = dc.getOrientation();
2579 if (req != dc.getLastOrientation()) {
2580 dc.setLastOrientation(req);
2581 //send a message to Policy indicating orientation change to take
2582 //action like disabling/enabling sensors etc.,
2583 // TODO(multi-display): Implement policy for secondary displays.
2584 if (dc.isDefaultDisplay) {
2585 mPolicy.setCurrentOrientationLw(req);
2586 }
2587 if (dc.updateRotationUnchecked(inTransaction)) {
2588 // changed
2589 return true;
2590 }
2591 }
2592
2593 return false;
2594 } finally {
2595 Binder.restoreCallingIdentity(ident);
2596 }
2597
`
윈도우매니저 서비스에서…
뒤에도 같은 클래스내의 함수인데 lock이 걸린함수를 부르는걸로보아
완전히 회전이 완료되기전까지 앱을 freeze 하는듯 보입니다.
이런 멈춤을 최소화하려면 회전된 비트맵을 빨리 그려야할거같습니다.
혹은중간 과정을 줄여야 할거같습니다.
ㅡㅡ아이디어?
만약 기존 비트맵처럼 그린다면..
1.코드의 비트맵을 그릴떄,
2.회전상태, 반전상태에 따라서 if 문을 사용함
3.그리고 getpixel,setpixel 의 메소드를 사용해서 오버헤드가 걸림
회전4가지 상태에 그 반전으로 8가지이고
역행렬,좌우반전,상하반전 이렇게 3가지를 flag로 두면
if문 없이도 8가지 상태를 표현할수 있을거같았음.
if문의 오버헤드를 줄이고,
90도의 rotation과
vertical, horizontal flip ,
transpose
관련된 함수를 하나로 합칠수있을것으로보임.
+getpixel, setpixel 함수호출의 오버헤드를 없앨수있음
이 호출은 확실히 성능에 안좋다.
단점:
빨라질지의문 =(if문의 오버헤드 가 true false boolean혹은 bit 연산의 오버헤드보다 큰게맞는가?)
코드를 알아보기 힘들어짐.
만약에 식을 이렇게
2개의 플래그를 두고 8개의 상태를표현하면
,, 각각 flag의 이름은 ft,fw,fh
기본 = f f f
좌우 = f t f
상하 = f f t
대칭 = f t t
TP = t f f
좌우 = t t f
상하 = t f t
대칭 = t t t
즉 높이H , 너비W 인 비트맵이미지에서
for (i<H-1 …h++)
for(i<W-1 …w++) // 메모리접근은 0부터 세므로 각각 -1
h*row + w
의 반복으로 모든 픽셀을 순회한다면
!ft & ( (W+1) * (fh(H-2 * h)+h) + fw(W-2 * w)+w )
or
ft & ( (H+1) * (fh(W-2 * w)+w) + fw(H-2 * h)+h )
ft에 따라서 w h 변환 여부 결정 (flag 설정시 w,h를 미리 교환해야할거같다)
fw에 따라서 좌우반전
fh에 따라서 상하반전 여부가 결정
적용해보려면 실제로 비트맵을 그리는 코드를 찾아야할거같습니다