Передача байтового массива в PixelShaderEffect

Я быстро анимирую изображения из файла на основе нестандартного пиксельного формата в приложении 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, но падает до ~30 кадров в секунду в 1024. Все, что больше, работает еще хуже.

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

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

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

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

Я не смог найти никаких примеров создания IGraphicsEffectSource.

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

0 ответов

Другие вопросы по тегам