【问题标题】:BitmapData lock and unlock not working on androidBitmapData 锁定和解锁在 android 上不起作用
【发布时间】:2014-02-18 01:01:24
【问题描述】:

以下代码将从另一个位图(akka
该代码在 PC 上运行良好,性能也不错。

当我在更多的安卓设备上测试它时,它不起作用。无论是高端设备还是较慢的设备。我做了一些测试,发现问题出在 BitmapData 的 lock() 和 unlock() 函数上。它根本不会更新设备上的图像,只会更新一次。
我试图删除它们,但它滞后了很多。 PC上的性能下降也很明显。 有谁知道解决方案,我在哪里做错了?

import flash.display.BitmapData;
import flash.display.Bitmap;
import flash.geom.Point;
import flash.events.MouseEvent;
import flash.geom.ColorTransform;
import flash.geom.Rectangle;

var m:BitmapData = new water_pattern;
var b:BitmapData = new droplet;

var bm:Bitmap = new Bitmap(m);

var bla = new blabla();
addChild(bla);
bla.addChild(bm);

function p($x,$y){


var refPoint = new Point($x-b.width/2,$y-b.height/2);
for(var i=0;i<b.width;i++)
for(var j=0;j<b.height;j++)
{
    var a:uint = (b.getPixel32(i,j)>> 24) & 0xFF;
    a=0xFF-a;
    var tp:uint = m.getPixel32(refPoint.x+i,refPoint.y+j);
    var tp_trans:uint = (tp >> 24)&0xFF;
    if(tp_trans>a){

        tp=(tp&0x00FFFFFF)|(a<<24);
        m.setPixel32(refPoint.x+i,refPoint.y+j,tp);
    }
}

//for(var k=0;k<10000000;k++){};
}
var k=1;
var md = function(e)
{
    m.lock();
    p(bm.mouseX,bm.mouseY);
    m.unlock();
};

bla.addEventListener(MouseEvent.MOUSE_DOWN,function(e)
{
    bla.addEventListener(Event.EXIT_FRAME,md);
});
bla.addEventListener(MouseEvent.MOUSE_UP,function(e)
{
    bla.removeEventListener(Event.EXIT_FRAME,md);
});

我已经修改了代码:

public function draw($x, $y)
        {

            var refPoint = new Point($x - brush.width / 2, $y - brush.height / 2);
            var r:Rectangle = new Rectangle(refPoint.x, refPoint.y, brush.width, brush.height);

             var pv:Vector.<uint> = pattern.getVector(r);
             var bv:Vector.<uint> = brush.getVector(brush.rect);


             for (var i = 0; i < bv.length; i++)
                {
                    var a:uint = (bv[i]>>24) &0xFF;
                    a = 0xFF - a;
                    var tp:uint = pv[i];
                    var tp_trans:uint = (tp >> 24) & 0xFF;

                //  trace(a.toString(16) + " vs " + tp_trans.toString(16));
                    if (tp_trans > a)
                    {

                        tp = (tp & 0x00FFFFFF) | (a << 24);
                        //      trace("??>" + tp);
                        pv[i] = tp;
                    }
                }

               pattern.setVector(r, pv);
        }

现在它可以工作了,但在设备上仍然很慢。在我看到 Jeff Ward 的评论之前,我将其更改为 CPU 上的渲染模式。它工作得很快。 最大的问题是在 CPU 模式下,与 GPU 相比,游戏速度非常慢。然而,这个脚本在 CPU 上速度很快,但在 GPU 上却很慢。

所以我再次尝试了第一个代码并感到惊讶。有用。杰夫沃德,谢谢你,你是个天才。 现在的问题仍然是为什么?谁能解释一下?

【问题讨论】:

  • 你是用GPU渲染模式,还是直接?
  • 你试过直接吗?我想知道 GPU 渲染模式是否没有注意到对底层位图数据的这种更新。在unlock() 语句之后尝试bm.alpha = 0.98+0.02*Math.random();,或者重新分配位图数据:bm.bitmapData = m;
  • 是的,它直接工作。虽然这就像一个魅力,但我的游戏的其余部分是滞后的。老实说,我不明白这么简单的东西如何在 GPU 模式下变得迟钝并且不起作用,以及它在直接模式下的表现如何,但其他工作正常的东西却变得迟钝
  • GPU 和直接模式采用完全不同的 GPU 加速方法,因此它们在不同情况下会快/慢。无论如何,这些技巧是否使 GPU 模式有效?或者bm.filters = [];你需要进入GPU模式才能意识到你已经改变了BitmapData的内容,它需要重新上传纹理(这本身可能是一个滞后的操作,取决于位图的大小)。跨度>
  • 在 GPU 模式下,更改位图中的任何像素都需要重新上传完整的位图,因此位图的大小是限制因素。在直接模式下,它只对已更新的屏幕部分进行 blit。所以我猜游戏的某些部分会一次改变很多屏幕(在直接模式下很慢),而且这种效果会改变一个大的位图,但一次只改变一点点(在 GPU 模式下很慢)。跨度>

标签: android actionscript-3 image-processing air bitmapdata


【解决方案1】:

对于您最初的问题,有时 GPU 模式不会对底层位图数据进行更改。在您的unlock() 之后尝试任何一个这些操作以“提示”它应该重新上传位图数据:

bm.filters = [];
bm.bitmapData = m;
bm.alpha = 0.98+Math.random()*0.02;

但正如您所发现的,上传位图数据可能会很慢。阐明 GPU/直接渲染模式:

在 GPU 模式下,更改位图中的任何像素都需要重新上传完整的位图,因此位图的大小是限制因素。在直接模式下,它只对已更新的屏幕部分进行 blit。所以我猜游戏的某些部分会同时改变很多屏幕(在直接模式下很慢),而这种效果会改变一个大的位图,但一次只改变一点点(在 GPU 模式下很慢)。

您必须发挥创造力以最大限度地提高 GPU 的性能:

  1. 在 GPU 模式下,将效果拆分为多个位图,并且对于任何给定的帧只进行尽可能少的更改。 (中等努力)
  2. 使用Starling GPU 加速框架和 Starling 过滤器(GPU 着色器)来实现您的效果(工作量取决于您已经在游戏中投入了多少),请参阅 a coupleexamples

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-08-07
    • 1970-01-01
    • 2016-02-27
    • 2021-11-02
    • 1970-01-01
    • 1970-01-01
    • 2018-02-01
    相关资源
    最近更新 更多