About

<#TEMPLATE_INCLUDE_NINEPAGE_ABOUTME#>
  • Jan

    11

    回顾 Starling2 —— skipUnchangedFrames 属性局限性

    • 0 Comments
    • Flash Platform
    • 发布:古树悬叶
    • 引用:0
    • 浏览:

    以下测试环境为 Starling 2.1 与 Feathers UI 3.1.1

    package
    {
        import flash.display.Sprite;
        import flash.display.StageAlign;
        import flash.display.StageScaleMode;

        import starling.core.Starling;

        public class Starling2Test extends Sprite
        {
            private var _starling:Starling;

            public function Starling2Test()
            {
                super();

                stage.align = StageAlign.TOP_LEFT;
                stage.scaleMode = StageScaleMode.NO_SCALE;

                _starling = new Starling(Starling2, stage);
                _starling.start();

                _starling.skipUnchangedFrames = true;//默认为 false,设为 true

                _starling.showStatsAt();//新版的概要分析器在上面的属性为true时如果跳过了场景的重绘时背景会变绿色
            }
        }
    }

    接下来看看概要分析器的背景会不会变绿色。

    1、先来个空场景,没有任何重绘,这个很正常。 

    package
    {
        import starling.display.Sprite;

        public class Starling2 extends Sprite
        {
            public function Starling2()
            {
                super();//空场景,概要分析器变绿色了
            }
        }
    }

    2、往原生舞台添加一个空白容器对象:

    package
    {
        import flash.display.Sprite;

        import starling.core.Starling;
        import starling.display.Sprite;

        public class Starling2 extends starling.display.Sprite
        {
            private var sp:flash.display.Sprite = new flash.display.Sprite();

            public function Starling2()
            {
                super();

                //往原生舞台添加一个空的 Sprite 对象,依旧可以跳过帧重绘,背景变绿
                Starling.current.nativeOverlay.addChild(sp);
            }        
        }    
    }

    这时候你可能会觉只要原生舞台没有对象绘制,skipUnchangedFrames 依旧会起作用,可以跳过静态的帧画面重绘,实际上是错的……看下面:

    package
    {
        import flash.display.Shape;

        import starling.core.Starling;
        import starling.display.Sprite;

        public class Starling2 extends starling.display.Sprite
        {
            private var shape:Shape = new Shape();

            public function Starling2()
            {
                super();

                //往原生舞台添加一个空 Shape 对象,无法跳过帧重绘,概要分析背景一直是黑色的
                Starling.current.nativeOverlay.addChild(shape);
            }        
        }    
    }

    3、回到刚才的 Sprite 对象,给它加点需要原生舞台绘制的东西试试:

    package
    {
        import flash.display.Bitmap;
        import flash.display.BitmapData;
        import flash.display.Sprite;

        import starling.core.Starling;
        import starling.display.Sprite;

        public class Starling2 extends starling.display.Sprite
        {
            private var sp:flash.display.Sprite = new flash.display.Sprite();

            private var bit:Bitmap = new Bitmap(new BitmapData(50, 50, false, 0xff0000));

            public function Starling2()
            {
                super();

                Starling.current.nativeOverlay.addChild(sp);

                sp.graphics.beginFill(0xff);
                sp.graphics.drawRect(0,0,100,100);
                sp.graphics.endFill();

                sp.y = 200;

                //如果没有将 Bitmap 对象加到显示列表中,它依旧是可以变绿的
                //如果将以下 bit 对象加到显示列表中,skipUnchangedFrames 就失效了,不能跳过任何帧,背景依旧是黑色的
                //sp.addChild(bit);
            }        
        }    
    }

    实际测试结果,不仅是 Bitmap 会让 skipUnchangedFrames 失效,原生的 TextField 对象也会让 skipUnchangedFrames 失效。只要不往原生舞台添加任何对象就可以了吧?但有时候你可能是被迫的,甚至是你完全不知情的情况下往原生舞台添加了显示对象。举两个常见例子:

    a、如果需要一个动态文本框用于输入用户帐号和密码、对话框等,那么你就不得不往原生舞台添加传统的 TextField 对象;

    b、当使用 feathers 组件的 TextInput 组件时,你没有往原生舞台添加任何对象,但实际上 feathers 组件会自动往原生舞台添加动态文本框的过程,你完全可能就是在不知情的情况下被添加了。

    当 TextInput 获取了焦点有了输入光标时,实际上有一个输入文本框被 feathers 自动添加到了原生舞台。

    4、上面这些其实还不够精彩,重头戏来了。颤抖吧,骚年!

    package
    {
        import starling.display.Quad;
        import starling.display.Sprite;
        import starling.events.Event;

        public class Starling2 extends Sprite
        {        
            private var q:Quad = new Quad(10,10,0xffff);

            public function Starling2()
            {
                super();

                this.addChild(q);
                this.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
            }

            private function enterFrameHandler(e:Event):void
            {
                q.y = 200;
                q.y = 100;
                q.y = 200;            
            }
        }
    }

    你会发现运行上面的代码后,概要分析器的背景颜色并没有变成绿色,尽管帮助手册上 skipUnchangedFrames 的说明写了:

    When enabled, Starling will skip rendering the stage if it hasn't changed since the last frame.

    大概意思是:只要舞台上的对象前一帧和后一帧如果都没有发生任何变化,Starling 会跳过重绘。

    所以这个属性实际上并不会像 feathers 框架那样有一个 flag 标记通过 invalidate() 方法验证前一帧与后一帧是否真正的变化过(和 Flex 框架里的组件类似),如果是 feathers :

    package
    {
        import feathers.controls.Label;

        import starling.display.Sprite;
        import starling.events.Event;

        public class Starling2 extends Sprite
        {
            private var label:Label = new Label();

            public function Starling2()
            {
                super();            

                this.addChild(label);

                label.y = 200;
                label.text = "aaaaaaaaaaa";

                this.addEventListener(Event.ENTER_FRAME, enterFrameHandler);            
            }

            private function enterFrameHandler(e:Event):void
            {
                /*
                //这一段代码需要注释掉,否则概要分析器的背景也不会变绿
                //因为 feathers 组件并没有对 x 与 y 进行 flag 标记
                label.y = 200;
                label.y = 100;
                label.y = 200;
                */


                //概要分析器背景是绿色的。
                //但它真的利用了 skipUnchangedFrames 属性的功能了吗?
                label.width = 200;
                label.width = 100;
                label.width = 200;

                label.text = "aaaaaaaaaaa";
                label.text = "bbbbbbbbbbb";
                label.text = "aaaaaaaaaaa";            
            }        
        }    
    }

    feathers 阻止重绘是通过 flag 标记与 invalidate() 方法验证实现的,和 skipUnchangedFrames 属性有半毛钱关系?我整个人都不好了。

    • Tags:
    • 2017 / 1 / 11
    相关文章:
      Post Comment.

      发表评论