drawBitmap在SurfaceView游戏线程上的低性能(android)

时间:2017-03-22 11:50:04

标签: android performance canvas bitmap surfaceview

我正在SurfaceView画布上绘制一组图像。获取surfaceHolder后,doDraw由游戏循环线程调用。当画布上绘制的图像数量很大时,问题是每秒帧数(FPS)非常低。这是因为drawBitmap很慢。

测试设置

cluster arraylist有400个小图片(cluster.Picture)。时差是运行drawBitmap循环的测量参数。为了比较,我将drawBitmap替换为drawRect,并注释掉drawBitmap,使循环空体。 用于测试的设备 https://www.optus.com.au/shop/prepaidmobile/lg/leon

测试结果(毫秒)

  1. drawBitmap 400 loop - Average:25.5,MIN:14,MAX:37
  2. drawRect 400循环 - 平均值:8.6,MIN:5,MAX:21
  3. 没有400循环 - 平均:1.3,MIN:0,MAX:10
  4. 上述时间仅测量逻辑部分。总游戏循环将接近40毫秒。这意味着FPS非常低。即使是100循环,绘制位图也需要18毫秒。

    我尝试设置getHolder()。setFormat(PixelFormat.RGBA_8888),setFixedSize(screenSize.x,screenSize.y)和zorder以及将位图配置设置为RGBA_8888。另外我尝试使用游戏线程的setPriority设置高优先级。

    我不确定我还能做些什么。如何提高游戏循环和FPS的性能。

        public List<PCluster> clusters = new ArrayList<PCluster>();
    
        public void doDraw(Canvas canvas) {
    
        try {
            if (canvas == null) {
                return;
            }
            super.draw(canvas);
    
            canvas.drawColor(backColor);
            if (waitTillLoad) {
                return;
            }
    
        } catch (Exception ex) {
        }
        final int savedState = canvas.save();
        try {
    
            minX = (int) (((viewWidth / mScaleFactor) - Gen.screenSizeWidth) / 2) * Utils.VIEW_SIZE;
            minY = (int) (((viewHeight / mScaleFactor) - Gen.screenSizeHeight) / 2) * Utils.VIEW_SIZE;
    
            if (mPosX > maxX) {
                mPosX = maxX;
            }
            if (mPosX < minX) {
                mPosX = minX;
            }
            if (mPosY > maxY) {
                mPosY = maxY;
            }
            if (mPosY < minY) {
                mPosY = minY;
            }
    
    
            canvas.scale(mScaleFactor, mScaleFactor);
            canvas.translate(mPosX, mPosY);
    
            long startTime = System.currentTimeMillis();
            if (!showBackground) {
    
                for (PCluster cluster : clusters) {
                    if (cluster.isVisible) {
                        canvas.drawBitmap(cluster.Picture, cluster.BoardLocation.left,
                                cluster.BoardLocation.top, null);
                    }
                }
                Log.d("myApp", "   " + (System.currentTimeMillis() - startTime));
            }
    
        } catch (Exception ex) {
        } finally {
            canvas.restoreToCount(savedState);
        }
    }
    

1 个答案:

答案 0 :(得分:1)

我能够使用PorterDuff SRC_OVER绘制对象来提高性能。这可能是因为当透明图像彼此叠加时,计算量较少。还要确保为绘画添加抖动和消除锯齿。

canvasPaint = new Paint();
canvasPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER )); 

canvas.drawBitmap(cluster.Picture, cluster.BoardLocation.left,
                            cluster.BoardLocation.top, canvasPaint );