精华内容
下载资源
问答
  • <p>Octree 在pcl中是双缓冲机制实现的, 什么使双缓冲机制?</p>
  • 双缓冲、多缓冲技术在计算机科学中其实是一个广义的概念,不过其本质上的意思都是差不多的。今天我们就来讲一讲双缓冲技术在android绘图中的应用。 何谓缓冲? 在理解双缓冲的原理之前,我们先要明白,什么叫缓冲?...

    转载请说明出处:http://www.jianshu.com/p/efc0bebfd22e

    双缓冲、多缓冲技术在计算机科学中其实是一个广义的概念,不过其本质上的意思都是差不多的。今天我们就来讲一讲双缓冲技术在android绘图中的应用。

    何谓缓冲?

    在理解双缓冲的原理之前,我们先要明白,什么叫缓冲?
    我们可以举一个比较通俗的粟子,比如:

    工头给你一个任务,让你把50块大板砖从A处搬到距离你1000米之外的B处去。你心想,50块板砖? 小case,我一次就能扛完。于是你撸起袖子,一步一步,真的一趟就搞定了。这个时候工头一声奸笑对你说,小伙子不错,那边还有2000块砖,你也搬过去吧。。。
    看到这堆积如山的砖头,你眼前一黑,这孙子真是想累死我啊,钱给这么少还干这么多活!
    可是没办法呀,谁叫自己当初书读得少,长大了只能靠搬砖为生呢。正当你准备徒手一趟一趟地开始干时,丰满漂亮的工头,的老婆来了,她走过来,带着迷一般的微笑。那种笑容,甜蜜优雅,仿佛春风拂过泸沽湖,秋雨浸润九寨沟,让你虎躯一震。她对你说,你开工地上的卡车把这些砖搬过去吧,2000块砖太多了,一趟一趟搬太累。
    你瞬间来了精神,把砖搬到卡车上,油门一踩不带走一片云彩,一下就把2000块砖搬过去了。。。
    …………
    “快起来,什么时候了还在睡,快去搬砖!”
    该死的工头又来催!

    缓冲的概念就讲到这里。

    Android绘图中的双缓冲

    我们知道,我们在绘图时有两样东西是少不了的,一个是Canvas(画布),一个是Paint(画笔)。Canvas提供画各种图形的方法,如画圆(drawCircle),画矩形(drawRect)等等,Paint用来设置画笔的样式,比如笔的粗细,颜色等。每个Canvas内部持有一个Bitmap对象的引用,画图的过程其实就是往这个Bitmap当中写入ARGB信息。
    比如我们现在自定义一个View,在上面画一个矩形和一个圆:

    @Override
        protected void onDraw(Canvas canvas) {
            canvas.drawRect(rect,mPaint);
            canvas.drawCircle(cx,cy,100,mPaint);
        }
    

    那么现在有一个问题,画矩形和画圆是两个独立的动作,会不会在drawRect执行完之后屏幕上马上就会显示出来一个矩形呢?
    为了验证我们的猜想,我们在两个绘图动作中加一个sleep:

    @Override
        protected void onDraw(Canvas canvas) {
            canvas.drawRect(rect,mPaint);
            try {
                TimeUnit.MILLISECONDS.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            canvas.drawCircle(cx,cy,100,mPaint);
        }
    

    我们会看到,并不是先显示矩形再显示圆,而是两个几乎同时一起显示出来的。这就说明必须要等onDraw方法执行完成之后,才会把数据交给GPU去处理展示。这就是android绘图当中的第一道缓冲,即显示缓冲区。

    而所谓的双缓冲,在android绘图中其实就是再创建一个Canvas和对应的Bitmap,然后在onDraw方法里默认的Canvas通过drawBitmap画刚才new的那个bitmap从而实现双缓冲。用代码简单的表述是这样的:

    private void init(){
        Bitmap bufferBm = Bitmap.create(getWidth,getHeight,Bitmap.Config.ARGB_8888);
        Canvas bufferCanvas = new Canvas(bufferBm);
    }
    
    private void drawSomething(){
        bufferCanvas.drawRect();
        bufferCanvas.drawCircle();
        ...
        invalidate();
    }
    
    @Override
    protected void onDraw(Canvas canvas) {
        canvas.drawBitmap(bufferBm,0,0,null);
    }
    

    示意图:

    438

    双缓冲绘图的优缺点及适用场景

    我们通过一个例子来说明。
    实现这样一个功能,一个自定义View,每次点击的时候在点击处画一个圆。我们先不使用双缓冲来实现:

    不用双缓冲的代码:

    public class MyView extends View{
    
        private Paint mPaint;
        private List<Point> mPoints;
    
        public MyView(Context context) {
            super(context);
        }
    
        public MyView(Context context, AttributeSet attrs) {
            super(context, attrs);
            mPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);
            mPaint.setStyle(Paint.Style.FILL);
            mPaint.setColor(Color.GREEN);
            setBackgroundColor(Color.WHITE);
            mPoints = new ArrayList<>();
        }
    
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            int action = event.getAction();
            switch (action){
                case MotionEvent.ACTION_DOWN:
                    mPoints.add(new Point((int)event.getX(),(int)event.getY()));
                    break;
                case MotionEvent.ACTION_UP:
                    invalidate();
                    break;
            }
            return true;
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            for (Point p : mPoints) {
                canvas.drawCircle(p.x,p.y,50,mPaint);
            }
        }
    

    在实验之前,我们先打开开发者选项里的”GPU呈现模式分析“,设置为“在屏幕上显示为条形图”(不同的手机可能有略微的差异,我这里用的是google Nexus5)。

    可以看到,当画的圆数目比较少时,GPU的负荷较低,但是出现一个逐步上升的趋势:

    380
    不使用双缓冲-少数据-GPU占用图

    内存使用情况是这样的:


    700
    不使用双缓冲-少数据-内存占用图

    当画的圆数目增加到比较大时,GPU负荷有点惨不妨睹了:


    377
    不使用双缓冲-大数据-GPU占用图

    这时的内存使用情况:


    700
    不使用双缓冲-大数据-内存占用图

    我们现在改用双缓冲来绘图,代码如下:

    public class MyView extends View{
    
        private Paint mPaint;
        private Canvas mBufferCanvas;
        private Bitmap mBufferBitmap;
    
        public MyView(Context context) {
            super(context);
        }
    
        public MyView(Context context, AttributeSet attrs) {
            super(context, attrs);
            mPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);
            mPaint.setStyle(Paint.Style.FILL);
            mPaint.setColor(Color.GREEN);
            setBackgroundColor(Color.WHITE);
        }
    
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            int action = event.getAction();
            switch (action){
                case MotionEvent.ACTION_DOWN:
                    if (mBufferBitmap == null) {
                        mBufferBitmap = Bitmap.createBitmap(getWidth(),getHeight(), Bitmap.Config.ARGB_8888);
                        mBufferCanvas = new Canvas(mBufferBitmap);
                    }
                    mBufferCanvas.drawCircle((int)event.getX(),(int)event.getY(),50,mPaint);
                    break;
                case MotionEvent.ACTION_UP:
                    invalidate();
                    break;
            }
            return true;
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            if (mBufferBitmap == null) {
                return;
            }
            canvas.drawBitmap(mBufferBitmap,0,0,null);
        }
    }
    

    使用双缓冲,在数量较小时的GPU使用情况是这样的:


    378
    使用双缓冲-少数据-GPU占用图

    这时候的内存使用情况:


    700
    使用双缓冲-少数据-内存占用图

    使用双缓冲,在数量非常大的时候,GPU使用情况是这样的:

    382
    使用双缓冲-大数据-GPU占用图

    内存使用情况:


    700
    使用双缓冲-大数据-内存占用图

    从上面的实验数据我们可以得出结论:

    • 在绘制数据量较小时,不使用双缓冲,GPU的负荷更低,即绘制性能更高;
    • 在绘制数据量较大时,使用双缓冲绘图,绘制性能明显高于不使用双缓冲的情况;
    • 使用双缓冲会增加内存消耗。

    其实上面的结论也很好理解,就像上面举的搬砖的例子,如果砖少的话,用车来拉明显是划不来的,砖的数量很多的时候,用车来拉就可以节省很多时间,但是用车就要消耗额外的资源,这就需要根据不同的情况做出正确的选择。

    android的双缓冲绘图技术就讲到这里,有不对的地方或大家有什么问题欢迎留言。


    android实现画板功能源码

    320

    转载请说明出处:http://www.jianshu.com/p/efc0bebfd22e

        </div>
    
    展开全文
  • 双缓冲、多缓冲技术在计算机科学中其实是一个广义的概念,不过其本质上的意思都是差不多的。今天我们就来讲一讲双缓冲技术在android绘图中的应用。 何谓缓冲? 在理解双缓冲的原理之前,我们先要明白,什么叫缓冲? ...

    双缓冲、多缓冲技术在计算机科学中其实是一个广义的概念,不过其本质上的意思都是差不多的。今天我们就来讲一讲双缓冲技术在android绘图中的应用。

    何谓缓冲?

    在理解双缓冲的原理之前,我们先要明白,什么叫缓冲?
    我们可以举一个比较通俗的粟子,比如:

    工头给你一个任务,让你把50块大板砖从A处搬到距离你1000米之外的B处去。你心想,50块板砖? 小case,我一次就能扛完。于是你撸起袖子,一步一步,真的一趟就搞定了。这个时候工头一声奸笑对你说,小伙子不错,那边还有2000块砖,你也搬过去吧。。。
    看到这堆积如山的砖头,你眼前一黑,这孙子真是想累死我啊,钱给这么少还干这么多活!
    可是没办法呀,谁叫自己当初书读得少,长大了只能靠搬砖为生呢。正当你准备徒手一趟一趟地开始干时,丰满漂亮的工头,的老婆来了,她走过来,带着迷一般的微笑。那种笑容,甜蜜优雅,仿佛春风拂过泸沽湖,秋雨浸润九寨沟,让你虎躯一震。她对你说,你开工地上的卡车把这些砖搬过去吧,2000块砖太多了,一趟一趟搬太累。
    你瞬间来了精神,把砖搬到卡车上,油门一踩不带走一片云彩,一下就把2000块砖搬过去了。。。
    ............
    “快起来,什么时候了还在睡,快去搬砖!”
    该死的工头又来催!

    缓冲的概念就讲到这里。

    Android绘图中的双缓冲

    我们知道,我们在绘图时有两样东西是少不了的,一个是Canvas(画布),一个是Paint(画笔)。Canvas提供画各种图形的方法,如画圆(drawCircle),画矩形(drawRect)等等,Paint用来设置画笔的样式,比如笔的粗细,颜色等。每个Canvas内部持有一个Bitmap对象的引用,画图的过程其实就是往这个Bitmap当中写入ARGB信息。
    比如我们现在自定义一个View,在上面画一个矩形和一个圆:

    @Override
        protected void onDraw(Canvas canvas) {
            canvas.drawRect(rect,mPaint);
            canvas.drawCircle(cx,cy,100,mPaint);
        }
    
    

    那么现在有一个问题,画矩形和画圆是两个独立的动作,会不会在drawRect执行完之后屏幕上马上就会显示出来一个矩形呢?
    为了验证我们的猜想,我们在两个绘图动作中加一个sleep:

    @Override
        protected void onDraw(Canvas canvas) {
            canvas.drawRect(rect,mPaint);
            try {
                TimeUnit.MILLISECONDS.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            canvas.drawCircle(cx,cy,100,mPaint);
        }
    
    

    我们会看到,并不是先显示矩形再显示圆,而是两个几乎同时一起显示出来的。这就说明必须要等onDraw方法执行完成之后,才会把数据交给GPU去处理展示。这就是android绘图当中的第一道缓冲,即显示缓冲区。

    而所谓的双缓冲,在android绘图中其实就是再创建一个Canvas和对应的Bitmap,然后在onDraw方法里默认的Canvas通过drawBitmap画刚才new的那个bitmap从而实现双缓冲。用代码简单的表述是这样的:

    private void init(){
        Bitmap bufferBm = Bitmap.create(getWidth,getHeight,Bitmap.Config.ARGB_8888);
        Canvas bufferCanvas = new Canvas(bufferBm);
    }
    
    private void drawSomething(){
        bufferCanvas.drawRect();
        bufferCanvas.drawCircle();
        ...
        invalidate();
    }
    
    @Override
    protected void onDraw(Canvas canvas) {
        canvas.drawBitmap(bufferBm,0,0,null);
    }
    
    

    示意图:

    双缓冲绘图的优缺点及适用场景

    我们通过一个例子来说明。
    实现这样一个功能,一个自定义View,每次点击的时候在点击处画一个圆。我们先不使用双缓冲来实现:

    不用双缓冲的代码:

    public class MyView extends View{
    
        private Paint mPaint;
        private List<Point> mPoints;
    
        public MyView(Context context) {
            super(context);
        }
    
        public MyView(Context context, AttributeSet attrs) {
            super(context, attrs);
            mPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);
            mPaint.setStyle(Paint.Style.FILL);
            mPaint.setColor(Color.GREEN);
            setBackgroundColor(Color.WHITE);
            mPoints = new ArrayList<>();
        }
    
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            int action = event.getAction();
            switch (action){
                case MotionEvent.ACTION_DOWN:
                    mPoints.add(new Point((int)event.getX(),(int)event.getY()));
                    break;
                case MotionEvent.ACTION_UP:
                    invalidate();
                    break;
            }
            return true;
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            for (Point p : mPoints) {
                canvas.drawCircle(p.x,p.y,50,mPaint);
            }
        }
    
    

    在实验之前,我们先打开开发者选项里的”GPU呈现模式分析“,设置为“在屏幕上显示为条形图”(不同的手机可能有略微的差异,我这里用的是google Nexus5)。

    可以看到,当画的圆数目比较少时,GPU的负荷较低,但是出现一个逐步上升的趋势:

    内存使用情况是这样的:

    当画的圆数目增加到比较大时,GPU负荷有点惨不妨睹了:

    这时的内存使用情况:

    我们现在改用双缓冲来绘图,代码如下:

    public class MyView extends View{
    
        private Paint mPaint;
        private Canvas mBufferCanvas;
        private Bitmap mBufferBitmap;
    
        public MyView(Context context) {
            super(context);
        }
    
        public MyView(Context context, AttributeSet attrs) {
            super(context, attrs);
            mPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);
            mPaint.setStyle(Paint.Style.FILL);
            mPaint.setColor(Color.GREEN);
            setBackgroundColor(Color.WHITE);
        }
    
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            int action = event.getAction();
            switch (action){
                case MotionEvent.ACTION_DOWN:
                    if (mBufferBitmap == null) {
                        mBufferBitmap = Bitmap.createBitmap(getWidth(),getHeight(), Bitmap.Config.ARGB_8888);
                        mBufferCanvas = new Canvas(mBufferBitmap);
                    }
                    mBufferCanvas.drawCircle((int)event.getX(),(int)event.getY(),50,mPaint);
                    break;
                case MotionEvent.ACTION_UP:
                    invalidate();
                    break;
            }
            return true;
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            if (mBufferBitmap == null) {
                return;
            }
            canvas.drawBitmap(mBufferBitmap,0,0,null);
        }
    }
    
    

    使用双缓冲,在数量较小时的GPU使用情况是这样的:

    image

    这时候的内存使用情况:

    使用双缓冲,在数量非常大的时候,GPU使用情况是这样的:

    内存使用情况:

    从上面的实验数据我们可以得出结论:

    • 在绘制数据量较小时,不使用双缓冲,GPU的负荷更低,即绘制性能更高;
    • 在绘制数据量较大时,使用双缓冲绘图,绘制性能明显高于不使用双缓冲的情况;
    • 使用双缓冲会增加内存消耗。

    其实上面的结论也很好理解,就像上面举的搬砖的例子,如果砖少的话,用车来拉明显是划不来的,砖的数量很多的时候,用车来拉就可以节省很多时间,但是用车就要消耗额外的资源,这就需要根据不同的情况做出正确的选择。

    android的双缓冲绘图技术就讲到这里,有不对的地方或大家有什么问题欢迎留言。


    android实现画板功能源码

    作者:wensefu
    链接:https://www.jianshu.com/p/efc0bebfd22e

    展开全文
  • 现在遇到个问题,Android系统有的时候只使用了一个fb,有的时候使用了两个fb, 一芯双屏又是个什么意思?很多东西需要学习啊.

    现在遇到个问题,Android系统有的时候只使用了一个fb,有的时候使用了两个fb,

    一芯双屏又是个什么意思?很多东西需要学习啊.

    展开全文
  • 函数glfwSwapBuffers有什么用?

    千次阅读 2019-01-06 08:50:58
    SwapBuffers翻译过来是交换缓冲区的意思,既然buffer加了s,也就意味着不止一个buffer,所以这里涉及到了一个双缓冲的概念. 关于双缓冲英文解释如下: Double Buffer: When an application draws in a single buffer...

    小白日常笔记,如有错误欢迎批评指正~

    glfwSwapBuffers(GLFWwindow *window)

    SwapBuffers翻译过来是交换缓冲区的意思,既然buffer加了s,也就意味着不止一个buffer,所以这里涉及到了一个双缓冲的概念.

    关于双缓冲英文解释如下:
    Double Buffer:
    When an application draws in a single buffer image might display flickering issues. This is because the resulting output is not drawn in an instant ,but drawn pixel by pixel and usually from left to right ,top to bottom.Because this image is not drawn in an instant to the user while still being rendered to,the result may contain artifacts.To circumvent these issues,window application apply a double buffer for rendering.The front buffercontains the final output image that is shown at the screen,while all the rendering commands draw the back buffer.As soon as all the rendering commands are finished we swap the back buffer to the front buffer,so the image is instantly displayed to the user,removing all the aforementioned artifact.

    总结中文解释如下:
    因为电脑绘图是一个个像素逐一画的,需要时间,如果单一缓冲,我们可能会看到具体绘画过程,会造成屏幕闪烁等问题,而我们用户不需要具体看到你绘制的过程,所以为了解决这个问题,这里用了双缓冲技术,用两个内存区域来保存数据,分为前缓冲区和后缓冲区,前缓冲区用于展示屏幕上的内容,而后缓冲区就用来绘制,然后每一帧开始的时候,将两个缓冲区交换,这样后缓冲区又可以画新的内容。

    展开全文
  • 而库函数调用则面向的是应用开发的,相当于应用程序的api,采用这样的方式有很多种原因,第一:双缓冲技术的实现。第二,可移植性。第三,底层调用本身的一些性能方面的缺陷。第四:让api也可...
  • 内核帧缓冲区做的–显示刷新机制首先,4.1以前,是双缓冲机制+VSync,之后便是三缓冲机制,那么什么双缓冲机制,什么是三缓冲机制,网上一堆说明的,这里不说什么生涩难懂的技术语言,只用自然语言,废话不说,先...
  • Project1.rar

    2020-07-15 21:34:53
    在源码的showRTInfo(string whichScreen) //real time info //这个whichScreen指的是缓冲区的意思,因为我用的是双缓冲。 4:AI蛇:AI的难度设计的刚刚好,不那么笨,也不那么聪明。。。。(我不会做那种毫发无损吃...
  • 把之前自己写的那个俄罗斯方块游戏引擎移植到Android平台上,做成一个俄罗斯方块游戏Demo,不过也已经达到可玩的程度了,其中主要的技术有:传感器的使用、振动器的使用、定时器的使用、双缓冲绘图、触摸消息捕获...
  • Android俄罗斯方块游戏源码

    千次阅读 2013-08-21 16:53:37
    把之前自己写的那个俄罗斯方块游戏引擎移植到Android平台上,做成一个俄罗斯方块游戏Demo,不过也已经达到可玩的程度了,其中主要的技术有:传感器的使用、振动器的使用、定时器的使用、双缓冲绘图、触摸消息捕获...
  • Netty剖析之NIO-Channel

    2020-01-31 21:07:03
    什么是Channel? Channel即通道的意思,NIO的通道类似于流,但有如下区别: 通道可以同时进行读写操作,而流同一时刻只能读或者写 通道可以实现异步读写数据,而流只可同步操作 通道可以从缓冲区读数据,也可以写...
  • 点击上方↗“蓝字”→点击右上角“...”→选“设为星标★”标星|防走丢本文目录:内存条是什么内存条的...内存是内存储器的意思,是电脑运行的缓冲区,内存越大,运行越快。通常所说电脑内存(RAM)的大小,即是指内...
  • 要想学习和掌握它的诸多新特性,只能从Oracle手册入手,而数万页的11g手册不免让人心存畏惧,从中挑出对新特性的描述更需要一“火眼金睛”。  好消息!在本书第1版出版时隔4年后,Thomas Kyte及时了解了大家的这...
  • 疯狂的程序员

    热门讨论 2012-07-18 18:05:32
    从校医院出来,绝影就拄了拐杖。他说:“妈不行我还是痛,带我去城里的医院吧。”去了城里的医院,绝影就开始住院了,因为伤口已经严重感染。 2DOS 两周后绝影出院了。出院的时候还是拄着拐杖。 这两周里,发生了...
  • Windows API是这种命名方式的绝好例子,当人们看到ShowWindow,GetWindowText,DeleteFile和GetCommandLine之类的API函数名称时,恐怕不用查手册,就能知道它们是做什么用的。比起int 21h/09h和int 13h/02h之类的...
  •  GC是垃圾收集的意思(Gabage Collection),内存处理是编程人员容易出现问题的地方,忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃,Java提供的GC功能可以自动监测对象是否超过作用域从而达到自动回收...
  • java 面试题 总结

    2009-09-16 08:45:34
     GC是垃圾收集的意思(Gabage Collection),内存处理是编程人员容易出现问题的地方,忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃,Java提供的GC功能可以自动监测对象是否超过作用域从而达到自动回收...
  • Phoenix-award workstation BIOS V6.00PC,An Energy star Ally copyright(c) 1984-2003,Phoenix Technologies,LTD 这句英语的意思是:Phoenix-award这两家COMS芯片开发公司合并后共同开发第6号BIOS版本,采用美国...
  • arcgis工具

    2012-10-22 22:37:31
    当查询ArcInfo coverages, shape文件, INFO表以及dBASE表时,SQL表达式中的字段名必须用引号扩起。如:“AREA”,如果查询的是个人地理数据库数据,则需要将字段名包含在方括号内,如:[AREA],如果查询的是ArcSDE...
  • NIO:同时支持阻塞与非阻塞模式,但这里我们以其同步非阻塞I/O模式来说明,并且是面向缓冲区的 AIO:异步非阻塞I/O模型 详情移步:https://github.com/higminteam/practice/blob/master/src/main/java/com/practice/io...
  • 会计理论考试题

    2012-03-07 21:04:40
    12.常见的形码汉字输入技术有全拼码和拼码。( N ) 13.微机的键盘是一种分离式的智能键盘,通过电缆与主机连接。( Y ) 14.计算机的常用输出设备有打印机和键盘。( N) 15.汉字语音识别输入技术属于汉字智能输入...

空空如也

空空如也

1 2
收藏数 24
精华内容 9
关键字:

双缓冲什么意思