2012-12-15 2 views
1

내 테스트 케이스는 두 개의 삼각형을 그리고 나서 6 밀리 초를 기다리는 것입니다. 이렇게하면 fps는 60입니다.Flash MouseMove 성능 문제

무대 위를 마우스로 움직이면 fps가 안정적이지 않습니다. 비활성 시간이 증가하고 비활성화 시간을 줄일 수있는 방법이 없습니다. 왜 이런 일이 일어나는가?

다음은 몇 가지 스크린 샷입니다.

화면 스카우트의 캡처 : http://i.stack.imgur.com/xK0xV.png

GPUView FPS 그래프 : http://i.stack.imgur.com/XO0HQ.png

그리고 응용 프로그램의 코드

package 
{ 
import com.adobe.utils.AGALMiniAssembler; 
import com.adobe.utils.PerspectiveMatrix3D; 
import flash.display.Bitmap; 
import flash.display.Sprite; 
import flash.display.StageAlign; 
import flash.display.StageDisplayState; 
import flash.display.StageScaleMode; 
import flash.display3D.Context3D; 
import flash.display3D.Context3DCompareMode; 
import flash.display3D.Context3DProgramType; 
import flash.display3D.Context3DTextureFormat; 
import flash.display3D.Context3DVertexBufferFormat; 
import flash.display3D.IndexBuffer3D; 
import flash.display3D.Program3D; 
import flash.display3D.VertexBuffer3D; 
import flash.display3D.textures.Texture; 
import flash.events.Event; 
import flash.events.MouseEvent; 
import flash.geom.Matrix3D; 
import flash.geom.Rectangle; 
import flash.text.TextField; 
import flash.utils.getTimer; 


[SWF(width="1000",height="600", backgroundColor = 0x000000, frameRate="60")] 
public class SingleThreadRender extends Sprite 
{ 
    [Embed(source = "RockSmooth.jpg")] 
    protected const TextureBitmap:Class; 

    protected var context3D:Context3D; 

    protected var vertexbuffer:VertexBuffer3D; 
    protected var indexBuffer:IndexBuffer3D; 
    protected var program:Program3D; 
    protected var texture:Texture; 
    protected var projectionTransform:PerspectiveMatrix3D; 

    private var dataReady :Boolean = false; 


    private var text  :TextField = null; 

    public function SingleThreadRender() 
    { 
     text = new TextField(); 
     text.text = "gogo"; 
     addChild(text); 
     stage.mouseChildren = false; 

     startRenderThread(); 
    } 


    private function startRenderThread() :void { 
     stage.stage3Ds[0].addEventListener(Event.CONTEXT3D_CREATE, initMolehill); 
     stage.stage3Ds[0].requestContext3D(); 
     stage.scaleMode = StageScaleMode.NO_SCALE; 
     stage.align = StageAlign.TOP_LEFT; 
     stage.stageHeight = 600 
     stage.stageWidth = 800; 
     addEventListener(Event.ENTER_FRAME, onRender); 
     stage.addEventListener(MouseEvent.RIGHT_CLICK,rightClickHandler); 
    } 

    protected function initMolehill(e:Event):void 
    { 
     context3D = stage.stage3Ds[0].context3D;    
     context3D.configureBackBuffer(1000, 600, 1, true); 

     var vertices:Vector.<Number> = Vector.<Number>([ 
      -3,-3, 0,0, 0, // x, y, z, u, v 
      -3, 3, 0, 0, 1, 
      3, -3, 0, 1, 1, 
      3, 3, 0, 1, 0]); 
     vertexbuffer = context3D.createVertexBuffer(4, 5); 
     vertexbuffer.uploadFromVector(vertices, 0, 4); 
     indexBuffer = context3D.createIndexBuffer(6);   
     indexBuffer.uploadFromVector (Vector.<uint>([0, 1, 2, 2, 3, 0]), 0, 6); 

     var bitmap:Bitmap = new TextureBitmap(); 

     texture = context3D.createTexture(bitmap.bitmapData.width, bitmap.bitmapData.height, Context3DTextureFormat.BGRA, false); 
     texture.uploadFromBitmapData(bitmap.bitmapData); 

     var vertexShaderAssembler : AGALMiniAssembler = new AGALMiniAssembler(); 
     vertexShaderAssembler.assemble(Context3DProgramType.VERTEX, 
      "m44 op, va0, vc0\n" + // pos to clipspace 
      "mov v0, va1" // copy uv 
     ); 
     var fragmentShaderAssembler : AGALMiniAssembler= new AGALMiniAssembler(); 
     fragmentShaderAssembler.assemble(Context3DProgramType.FRAGMENT, 
      "tex ft1, v0, fs0 <2d,linear,nomip>\n" + 
      "mov oc, ft1" 
     ); 

     program = context3D.createProgram(); 
     program.upload(vertexShaderAssembler.agalcode, fragmentShaderAssembler.agalcode); 

     projectionTransform = new PerspectiveMatrix3D(); 
     var aspect:Number = 4/3; 
     var zNear:Number = 0.1; 
     var zFar:Number = 1000; 
     var fov:Number = 45*Math.PI/180; 
     projectionTransform.perspectiveFieldOfViewLH(fov, aspect, zNear, zFar); 
    } 

    private function rightClickHandler(event :MouseEvent) :void { 
     stage.removeEventListener(MouseEvent.RIGHT_CLICK,rightClickHandler); 
     stage.fullScreenSourceRect = new Rectangle(0,0,stage.fullScreenWidth,stage.fullScreenHeight); 
     stage.displayState = StageDisplayState.FULL_SCREEN_INTERACTIVE; 
    } 

    private var firstTime :Boolean = true; 
    protected function onRender(e:Event):void 
    { 
     if(stage.frameRate != 60) { 
      stage.frameRate = 60; 
     } 
     if (!context3D) 
      return; 
     var start :int = flash.utils.getTimer(); 
     var now :int = 0; 
     while(true) { 
      now = flash.utils.getTimer(); 
      if((now - start) > 6) { 
       break; 
      } 
     } 

     context3D.clear (1,1, 1, 1); 

     context3D.setDepthTest(true, Context3DCompareMode.LESS_EQUAL); 
     context3D.setVertexBufferAt (0, vertexbuffer, 0, Context3DVertexBufferFormat.FLOAT_3); 
     context3D.setVertexBufferAt(1, vertexbuffer, 3, Context3DVertexBufferFormat.FLOAT_2); 
     context3D.setTextureAt(0, texture);   
     context3D.setProgram(program); 
     var m:Matrix3D = new Matrix3D(); 
     m.appendTranslation(0, 0, 2); 
     m.append(projectionTransform); 

     context3D.setProgramConstantsFromMatrix(Context3DProgramType.VERTEX, 0, m, true); 

     var i:int = 2; 
     while(i--) 
      context3D.drawTriangles(indexBuffer,0,2); 
     context3D.present(); 

     while(true) { 
      now = flash.utils.getTimer(); 
      if((now - start) > 6) { 
       break; 
      } 
     } 

    } 
} 
+1

Mac에서 테스트 중이십니까? – ansiart

+0

Starling을 사용하여 Stage3D에서 평생토록 쉽게 사용할 수있는 이유가 있습니까? – antman

+0

이것은 문제를 시연하는 테스트 케이스입니다. – niluzhou1984

답변

0

난 당신이 C 배경 또는 일부에서 오는 있으리라 믿고있어 네이티브 스레딩을 지원하는 다른 언어.

while(true) { 
    now = flash.utils.getTimer(); 
    if((now - start) > 6) { 
     break; 
    } 
} 

60 Hz에서의 프레임 기간은 16ms입니다 : 같은 액션 스크립트와 자바 스크립트와 같은 단일 스레드 언어, 이러한 당신의 OnRender 기능의 하나로서 바쁜 루프는 더 - 더 큰 없습니다. 루프에서 6ms를 낭비하면 렌더링을 수행하고 다음 onRender 호출 전에 10ms를 남겨 둡니다. 문제를 더욱 악화 시키려면 AS3의 타이머 해상도가 매우 낮습니다. 타이머 - 최종선에 대한 Tinic Uro (Flash 엔지니어)의 this blog post을 확인하십시오. 모든 종류의 동기화에는 getTimer() 또는 stage.frameRate를 사용하지 마십시오.

렌더링주기 사이에 플래시가 멈추지 않습니다. 저기에 앉아있어. AS3이 싱글 스레드 방식을 다루는 방식은 유휴 시간을 사용하여 비동기 이벤트 (예 : mousemove 이벤트)를 처리하는 것입니다. onRender 함수에서 busy 루프를 사용하면 mousemove 이벤트를 처리 할 때 다운 타임이 발생하는 것을 효과적으로 보장 할 수 있습니다. 따라서 mousemove 이벤트가 발생할 때 엉뚱한 프레임 속도가 발생합니다.