2012-09-01 3 views
8

렌더러를 프로파일 링하려고하는데 설명 할 수없는 이상한 프로파일 링 동작이 나타납니다.왜 glClear가 OpenGLES에서 차단 되었습니까?

계속 렌더링하도록 설정된 glSurfaceView를 사용하고 있습니다.

이 내 onDrawFrame()

public void onDrawFrame(GL10 unused) { 
    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT); 
    executeAllDrawCommands(); 
} 

이 경부 하에서 천천히 행동했다 구조화, 그래서 타이머 클래스를 생성하고,이 몇 가지 프로파일 시작 방법입니다. 나는 내가 본 것에 놀랐다.

public void onDrawFrame(GL10 unused) { 
    swapTimer.end(); 

    clearTimer.start(); 
    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT); 
    clearTimer.end(); 

    drawTimer.start(); 
    executeAllDrawCommands(); 
    drawTimer.end(); 

    swapTimer.start(); 
} 

clearTimer 조치 그것이 내 모든 그리기 호출을 실행하는 데 걸리는 시간 glClear, drawTimer 조치를 호출하는 데 걸리는 시간, swapTimer 측정 시간 :

나는 그렇게처럼 내 onDrawFrame 방법에 대한 몇 가지 프로브를 넣어 onDrawFrame이 종료 할 때와 반환 할 때 (eglSwapBuffers를 호출하는 데 걸리는 시간). 나는 매우 부하가 적은 장면을 실행하면

, 나는 내가 설명 할 수없는 정말 이상한 숫자를 가지고 : 나는 내가 믿는대로 장치가 VSYNC를 강제가 다소 약간 큰 것으로 스왑 시간을 예상

swapTimer : 20ms (average) 
clearTimer : 11ms (average) 
drawTimer : 2ms (average) 

~ 30fps에서 사용 가능하게 설정했는데 실제로 '명확한'통화가 11 밀리 초 동안 차단되는 이유를 모르겠습니다. 비동기 명령을 내 보내서 반환한다고 가정 했습니까?

내가 훨씬 더 바쁜 장면을 그릴 때, 숫자가 꽤 ​​변경 : 내 드로우 호출 그것은 수직 동기화 시간을 많이 숨어처럼 보인다 너무 많은 시간을내어이 장면에서

swapTimer : 2ms (average) 
clearTimer : 0ms (average) 
drawTimer : 44ms (average) 

을 , 맑은 전화의 블록은 완전히 사라집니다.

가볍게로드 된 장면에서 glClear가 차단되는 이유에 대한 설명이 있습니까? 경우 누군가 내 '타이머'클래스 소스 코드에

링크 내 측정 기술의 의심 : http://pastebin.com/bhXt368W

+0

clearTimer.start() 메소드를 사용하기 전에 GLES20.glFinish()를 호출하여 시간이 어떻게 변하는 지 확인할 수 있습니까? –

+0

glFinish (와 그 주위에 finishTimer.start()/end()를 넣었습니다. 그리고 glClear에서 항상 벗어납니다. 대신 glFinish는 몇 밀리 초가 걸리며 glClear는 즉시가됩니다. vsync 시간이 glClear 내부에 나타나는 것을보고 놀랐지 만 vsync와 관련된 것 같습니다. – Tim

답변

10

내가 (주위)와 finishTimer.start()/종료()는 glFinish을두고, 그것은 glClear에서 항상 벗어나게됩니다. 대신 glFinish는 몇 밀리 초가 걸리며 glClear는 즉시가됩니다.

설명합니다.

장면이 매우 밝고 그림이 매우 빠르게 렌더링되면 픽셀을 지우고 새 색으로 채우는 데 시간이 걸립니다 (항상 시간이 걸릴 것입니다. 그렇지 않으면 렌더러가 뒤에 있고 현재 드로잉입니다). 새로운 것들). 최신 Android 기기에는 채우기 제한이 있습니다. 예를 들어, Nexus One은 30 Hz에서 채우기 잠금을 사용합니다. 실제 드로잉이 얼마나 빨라지더라도 화면은 그 빈도로 동기화됩니다. 도면이 30Hz 미만으로 끝나면 렌더러가 화면과 동기화됩니다. 따라서 glClear() 호출을 제거해도 알 수있는 지연이 있음을 알 수 있습니다. 렌더러는 화면의 업데이트보다 빠르거나 빠릅니다.

렌더러에 많은 객체가있는 경우 렌더러가 화면 업데이트 이후에 동기화되므로 동기화가 중단됩니다 (바쁜 장면의 프로필 데이터가 제공됨).

당신이 glFinish()를 사용

, 그것은, 유효 노출 률 논리에 따라, glFinish() 이제 화면 동기화를 보장하는 기능입니다 것을 의미 glClear() 기능은 다른 원인이 시간을 제거합니다.

계산 :

F = 1/T

쉬운 장면 :

F = 1/T = 1/((20 + 11 + 2) * 10^- 3) = ~ 30 Hz

동기화 지연 시간이 프로파일 러에 나타납니다. 렌더러가 화면과 동기화되고 있습니다. 즉 glClear() 또는 glFinish() 전화를 삭제하면 지연이 다른 곳에 표시됩니다.

무거운 장면 :

F = 1/T은 = 1/((2 + 0 + 44) * 10^-2)) = ~ 22 Hz로

동기화의 지연 시간은하지 않는다 프로파일 러에 나타납니다. Renderer는 화면의 업데이트 빈도 다음에 있습니다. 그것은이처럼 보인다

모든 올바른 것 같다

수직 동기화 관련이있다.

관련 문제