2012-12-15 41 views
1

我的測試案例是繪製兩個三角形,然後等待六毫秒。當這樣做時,它的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背景或一些具有本地線程支持的其他語言。在單線程的語言,如ActionScript和JavaScript,繁忙的環路,如一個在你的OnRender函數是一個很大的禁忌:

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

幀週期爲60赫茲爲16毫秒。通過在循環中浪費6ms,您已經讓自己保留了10ms來完成渲染並在下一次onRender調用之前完成。更糟糕的是,AS3的定時器分辨率很差。查看Tiny Uro(Flash工程師)關於計時器底線的this blog post,不要使用getTimer()或stage.frameRate進行任何類型的同步。

這是所有加起來的是,在您的渲染週期之間,閃光燈永不停止。它只是坐在那裏旋轉。 AS3處理單線程的方式是使用空閒時間來處理異步事件(如mousemove事件)。通過在你的onRender函數中放置一個繁忙的循環,你可以有效地保證現在有停機時間來處理mousemove事件 - 這樣當鼠標移動事件發生時會導致不穩定的幀速率。