2010-05-17 1 views
5

У меня вопрос о производительности пикселя. Я хочу увеличить многие BitmapData (удвоить их размер в новые BitmapData). Я делал это с as3, но хотел использовать пиксельный изгиб для повышения производительности. На моей машине я получаю лучшую производительность из пикселя bender demonstrations, затем as3., используя PixelBender, чтобы удвоить размер растрового изображения

К моему удивлению (или плохому кодированию/пониманию), я получаю гораздо хуже. Производительность из пикселя - 2 секунды против 1/2 секунды! Я ожидал получить , по крайней мере, то же самое как as3. Что я делаю не так?

У меня есть простой код пикселя-декодера here (и он приведен ниже для удобства).

package 
{ 

import flash.display.BitmapData; 
import flash.display.Shader; 
import flash.display.ShaderJob; 
import flash.display.Sprite; 
import flash.display.StageAlign; 
import flash.display.StageScaleMode; 
import flash.events.Event; 
import flash.geom.Matrix; 

public class flashFlash extends Sprite 
{ 


[Embed (source="pixelbender/bilinearresample.pbj", mimeType="application/octet-stream") ] 
private static var BilinearScaling:Class; 

public function flashFlash():void 
{ 
    stage.align = StageAlign.TOP_LEFT; 
    stage.scaleMode = StageScaleMode.NO_SCALE; 

    addEventListener(Event.ENTER_FRAME, efCb, false, 0, true); 
} 

private function efCb(evt:Event):void 
{ 
    removeEventListener(Event.ENTER_FRAME, efCb, false); 

    traceTime("init"); 

    var srcBmd:BitmapData = new BitmapData(80, 120, false, 0); 
    var destBmd:BitmapData = new BitmapData(160, 240, false, 0); 

    var mx:Matrix = new Matrix(); 
    mx.scale(2, 2); 
    for (var i:uint = 0; i < 3000; i++) 
    { destBmd.draw(srcBmd, mx); 
    } 

    traceTime("scaled with as3"); 

    // create and configure a Shader object 
    var shader:Shader = new Shader(); 
    shader.byteCode = new BilinearScaling(); 
    shader.data.scale.value = [.5]; 
    shader.data.src.input = srcBmd; 

    for (var j:uint = 0; j < 3000; j++) 
    { 
     var shaderJob:ShaderJob = new ShaderJob(); 
     shaderJob.shader = shader; 
     shaderJob.target = destBmd; 
     shaderJob.start(true); 
    } 

    traceTime("scaled with pixel bender bilinearresample.pbj"); 
} 

private static var _lastTraceTime:Number = new Date().getTime(); 
public static function traceTime(note:String):Number 
{ var nowTime:Number = new Date().getTime(); 
    var diff:Number = (nowTime-_lastTraceTime); 
    trace("[t" + diff + "] " + note); 
    _lastTraceTime = nowTime; 
    return diff; 
} 

} 
} 

И пиксельный код бендер:

<languageVersion : 1.0;> 

kernel BilinearResample 
< namespace : "com.brooksandrus.pixelbender"; 
    vendor : "Brooks Andrus"; 
    version : 1; 
    description : "Resizes an image using bilinear resampling. Constrains aspect ratio - divide Math.max(input.width/output.width, input.height/output.height) and pass in to the scale parameter"; 
> 
{ 
    parameter float scale 
    < 
     minValue: 0.0; 
     maxValue: 1000.0; 
     defaultValue: 1.0; 
    >; 

    input image4 src; 
    output pixel4 dst; 

    void 
    evaluatePixel() 
    { 
     // scale should be Math.max(src.width/output.width, src.height/output.height) 
     dst = sampleLinear(src, outCoord() * scale); // bilinear scaling 
    } 
} 
+0

Проверка работоспособности: в части AS3 вы увеличиваете одно и то же изображение во много раз, вместо того, чтобы масштабировать его один раз и копировать результат. Это надзор, или все они будут разными образами в реальном коде? – fenomas

+0

Хороший вопрос - все они будут разными изображениями в реальном коде. В этом примере я просто пытаюсь выяснить, как оптимизировать масштабирование, поэтому я запускаю его через итерации 3k. – jedierikb

+0

Может быть интересно протестировать несколько изображений, чтобы увидеть, как это влияет на скорость. (или создание 1-300.png с скриптом для фотошопа или что-то в этом роде) – quoo

ответ

8

Я думаю, проблема в том, что вы действительно сравниваете Pixel Bender с кодом родного игрока, а не против «actionscript». Я сомневаюсь, что Pixel Bender когда-нибудь выиграет по этому сценарию.

Масштабирование, которое здесь происходит, destBmd.draw(srcBmd, mx); кодируется непосредственно в плеере; это, вероятно, так же быстро, как вы можете получить (используя эквивалентный алгоритм). С другой стороны, ваше ядро, по крайней мере, должно быть скомпилировано (или JIT-скомпилировано) для запуска (возможно, существует ряд других причин для его замедления, хотя я мало знаю об особенностях).

Заканчивать этот пост от the blog of a Flash Player engineer:

Долгое время назад, в Flash Player дней у нас была идея добавления общий способ сделать растровые фильтры. Жесткий кодирования растровых фильтров, как мы сделали для Flash Player 8 не только не гибок, но несет бремя добавления огромное количество нативного кода в игрока и того, чтобы оптимизировать его для каждого и каждой платформы. Вопрос для нас всегда был так, как вы могли бы создать такие общие фильтры. Различные идеи плавали вокруг, но в конце была одна точка крепления: у нас не было языка и не было компилятора. После Слияние Macromedia с Adobe Flash Player и Adobe Pixel Команда Бендера собралась вместе, и мы, , наконец-то получили то, что нам было нужно: язык и компилятор.

Итак, Pixel Bender, в основном, работает быстрее, чем манипулировать пикселями непосредственно в ActionScript. Он будет превосходить эквивалентные звонки setPixel и getPixel. Но он не будет быстрее самого игрока (опять же, используя тот же алгоритм).

В каком-то смысле вы пытаетесь сделать это, например, написание, например, фильтра свечения в PB.Конечно, это круто, и вы можете многому научиться у него, если вы заинтересованы в обработке изображений. Но если ваш фильтр должен работать так же, как собственный фильтр, в нем нет особого смысла, кроме образовательных целей: собственный фильтр будет быстрее, и он уже доступен, без дополнительной строки кода.

2

Я смутно помню, услышав, что в то время как процесс подключения к Pixel Bender файла и т.д. медленнее, сама обработка происходит быстрее. Поэтому я представляю, что вы увидите, что по мере увеличения размера изображения фильтр пикселей может в конечном итоге стать более эффективным. Или, возможно, PixelBender лучше всего сэкономить на несколько более сложных манипуляциях с изображениями.