Передача байтового массива в PixelShaderEffect - PullRequest
0 голосов
/ 22 мая 2018

Я быстро анимирую изображения из файла на основе нестандартного пиксельного формата в приложении C # / UWP / Win2D.Между изображениями есть корреляция (подумайте, анимация флипбука), но нет ничего программного.

Я написал прототип и включил соответствующий код ниже.Цвета "Белый" и "Черный" будут в конечном итоге преобразованы в таблицу поиска цветов (например, 5 = Белый)

....
//Create render target in function elsewhere
CanvasRenderTarget crt = new CanvasRenderTarget(Sender, FrameWidth, FrameHeight, defaultDpi);
GenerateNextFrame(crt);
....

private void GenerateNextFrame(CanvasRenderTarget frame)
{
    var frameSize = FrameHeight * FrameWidth * sizeof(ushort);
    var frameBytes = new byte[frameSize];
    var frameShorts = new ushort[FrameWidth * FrameHeight];
    var colors = new Color[FrameWidth * FrameHeight];
    var white = Colors.White;
    var black = Colors.Black;
    var comp = (ushort.MaxValue / 2);

    //read bytes from file
    FrameFileStream.AsStreamForRead().Read(frameBytes, 0, frameSize);
    //convert bytes to shorts
    System.Buffer.BlockCopy(frameBytes, 0, frameShorts, 0, frameSize);

    //convert shorts to colors
    for (var i = 0; i < colors.Length; i++)
    {
        colors[i] = (frameShorts[i] < comp) ? white : black;
    }
    //set colors on frame
    frame.SetPixelColors(colors);
}

Производительность составляет ~ 60 кадров в секунду при FrameWidth / FrameHeight 512, нопадает до ~ 30FPS в 1024. Все, что больше, работает еще хуже.

Профилирование этого с большими данными показывает, что узким местом являются циклический массив цветов и вызовы SetPixelColors.

Я пробовал несколько методов, чтобы ускорить это (PLINQ, Parallel.ForEach, предварительно поставив в очередьданных), но не удалось получить его быстрее, чем форма, представленная выше.

Я считаю, что правильный способ справиться с этим - создать новый поддерживаемый тип DirectXPixelFormat для CanvasRenderTarget, чтобы я мог просто использовать SetPixelBytes.Это кажется невозможным.

Следующим правильным вариантом является написание PixelShaderEffect, которое принимает frameBytes, создает пиксели в оттенках серого, а затем использует его в качестве источника другого эффекта для установки цвета.

Я не былсмог найти любые примеры создания IGraphicsEffectSource.

Буду очень признателен за любой совет, документацию или, что лучше всего, за работающее «вот как вы передаете байтовый массив в PixelShaderEffect».

...