Event.RESIZE時にStage3Dの描画を行うとフリーズ

by yuichiroharai
Event.RESIZE時にContext3D.clear()と.present()を呼び出すとFlash Playerがフリーズしてしまいます。
♥0 | Line 49 | Modified 2011-11-21 19:12:17 | MIT License
play

ActionScript3 source code

/**
 * Copyright yuichiroharai ( http://wonderfl.net/user/yuichiroharai )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/11PM
 */

package {
    import com.adobe.utils.AGALMiniAssembler;    
    import flash.display.*;
    import flash.display3D.*;
    import flash.events.Event;

    public class Stage3DFreezeTest extends Sprite {
        public static const AGAL_VERTEX:String = "m44 op, va0, vc0\n" + "mov v0, va1";
        public static const AGAL_FRAGMENT:String = "mov oc, v0";
        private var _stage3D:Stage3D;
        private var _context3D:Context3D;

        public function Stage3DFreezeTest() {
            stage.align = StageAlign.TOP_LEFT;
            stage.scaleMode = StageScaleMode.NO_SCALE;

            _stage3D = stage.stage3Ds[0];
            _stage3D.addEventListener(Event.CONTEXT3D_CREATE, _onContext3dCreate);
            _stage3D.requestContext3D(Context3DRenderMode.AUTO);
        }
        private function _onContext3dCreate(e:Event=null):void {
            _context3D = Stage3D(e.target).context3D;
            //_createAGAL();
            _resize3DBackBuffer();
            addEventListener(Event.ENTER_FRAME, _onEnterFrame);
            stage.addEventListener(Event.RESIZE, _onResize);
            stage.addEventListener(Event.FULLSCREEN, _onResize);
        }

        private function _onEnterFrame(e:Event):void {
            // ENTER_FRAME毎にclearとpresentを何度も呼び出しても問題無い
            _context3D.clear(0, 0, 0);
            _context3D.present();
            _context3D.clear(0, 0, 0);
            _context3D.present();
        }
        private function _onResize(e:Event):void {
            // RESIZE時に割り込んでclearとpresentを呼び出すとフリーズ
            _context3D.clear(0, 0, 0);
            _context3D.present();
            //_resize3DBackBuffer();
        }
        private function _createAGAL():void {
            var program3D:Program3D, vertexAssembler:AGALMiniAssembler, fragmentAssembler:AGALMiniAssembler;

            vertexAssembler = new AGALMiniAssembler();
            vertexAssembler.assemble(Context3DProgramType.VERTEX, Stage3DFreezeTest.AGAL_VERTEX);
            fragmentAssembler = new AGALMiniAssembler();
            fragmentAssembler.assemble(Context3DProgramType.FRAGMENT, Stage3DFreezeTest.AGAL_FRAGMENT);
            program3D = _context3D.createProgram();
            program3D.upload(vertexAssembler.agalcode, fragmentAssembler.agalcode);
            _context3D.setProgram(program3D);
        }
        private function _resize3DBackBuffer():void {
            _context3D.configureBackBuffer(stage.stageWidth, stage.stageHeight, 2, true);
        }
    }
}