У меня есть вопрос о производительности о пиксельном гибочном станке. Я хочу увеличиться, многие BitmapData (удвойте их размер в новый BitmapData). Я делал это с as3, но требуемый для использования пиксельного гибочного станка для получения лучшей производительности. На моей машине я вытаскиваю лучшую производительность из пиксельных демонстраций гибочного станка затем as3.
К моему удивлению (или плохое кодирование / понимающий), я вытаскиваю намного худшую производительность из пиксельного гибочного станка - 2 секунды по сравнению с 1/2 секундой! Я ожидал получать, по крайней мере, то же представление в качестве as3. Что я делаю неправильно?
Я получил простой пиксельный код гибочного станка здесь (и он включен ниже для легкой ссылки).
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;
}
}
}
И пиксельный код гибочного станка:
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
}
}
Думаю, проблема в том, что вы сравниваете Pixel Bender с родным кодом плеера, а не с "actionscript". Я сомневаюсь, что Pixel Bender когда-либо выиграет в этом сценарии.
Масштабирование, которое происходит здесь destBmd.draw( srcBmd, mx );
, закодировано непосредственно в плеере; это, вероятно, настолько быстро, насколько вы можете получить (используя эквивалентный алгоритм). С другой стороны, ваше ядро, по крайней мере, должно быть сначала скомпилировано (или JIT-компилировано), чтобы запуститься (возможно, есть ряд других причин, по которым оно работает медленнее; я не знаю многого о специфике, однако).
Посмотрите на это сообщение из блога инженера Flash Player:
Давным-давно, еще во времена Flash Player 8, у нас была идея добавить общий способ делать растровые фильтры. Сложно кодирование растровых фильтров, как мы это делали для Flash Player 8, не только не является гибким, но и требует добавления огромного количества собственного кода в проигрывателя и необходимости оптимизировать его для каждой платформы. Проблема для для нас всегда был вопрос о том, как создавать такие общие фильтры. Различные идеи витали в воздухе, но в в итоге оставался один камень преткновения: у нас у нас не было ни языка, ни компилятора. После слияния Macromedia с Adobe были выпущены Flash Player и Adobe Pixel Bender объединились, и мы наконец-то получили то, что нам было нужно: язык и компилятор.
Итак, по сути, Pixel Bender быстрее, чем манипулирование пикселями непосредственно в Actionscript. Он превзойдет эквивалентный миллион вызовов setPixel и getPixel. Но он не будет быстрее, чем сам плеер (опять же, используя тот же алгоритм).
В некотором смысле то, что вы пытаетесь сделать, похоже на написание, скажем, фильтра свечения в PB. Конечно, это круто, и вы можете многому научиться, если интересуетесь обработкой изображений. Но если ваш фильтр должен работать так же, как родной фильтр, в этом нет особого смысла, кроме образовательных целей: родной фильтр будет быстрее, и он уже доступен, без лишней строчки кода.
Я смутно слышал, что, хотя процесс подключения к файлу пиксельного бендера и т.д. медленнее, сама обработка происходит быстрее. Итак, я предполагаю, что вы увидите, что по мере увеличения размера изображения фильтр сгибания пикселей может в конечном итоге стать более эффективным. Или, может быть, PixelBender лучше всего сохранить для чуть более сложных манипуляций с изображениями.