Небезопасный C# и указатели для 2D-рендеринга: хорошо или плохо?

StackOverflow https://stackoverflow.com/questions/55963

  •  09-06-2019
  •  | 
  •  

Вопрос

Я пишу элемент управления C#, который оборачивает DirectX 9 и предоставляет упрощенный интерфейс для рисования на уровне 2D пикселей..NET требует, чтобы я обернул этот код в блок небезопасного кода и скомпилировал его с параметром разрешения небезопасного кода.

Я блокирую всю поверхность, которая затем возвращает указатель на заблокированную область памяти.Затем я могу записать данные пикселей напрямую, используя «простую» арифметику указателей.Я протестировал это на производительность и обнаружил существенное улучшение скорости по сравнению с другими известными мне «безопасными» методами.

Это самый быстрый способ манипулировать отдельными пикселями в приложении C# .NET?Есть ли лучший и безопасный способ?Если бы существовал столь же быстрый подход, не требующий манипулирования указателями, я бы предпочел использовать его.

(Я знаю, что сейчас 2008 год, и нам всем следует использовать DirectX 3D, OpenGL, и т. д., однако этот элемент управления предназначен исключительно для 2D-рендеринга пикселей и просто не требует 3D-рендеринга.)

Это было полезно?

Решение

Использование небезопасных указателей — это самый быстрый способ прямых манипуляций с памятью в C# (определенно быстрее, чем использование функций-оболочек Marshal).

Просто из любопытства, какие операции 2D-рисования вы пытаетесь выполнить?

Я спрашиваю, потому что блокировка поверхности DirectX для выполнения манипуляций на уровне пикселей сведет на нет большинство преимуществ аппаратного ускорения, которые вы надеялись получить от использования DirectX.Кроме того, устройство DirectX не сможет инициализироваться при использовании служб терминалов (удаленный рабочий стол), поэтому в этом сценарии элемент управления будет непригоден для использования (это может не иметь для вас значения).

DirectX будет большим преимуществом при рисовании больших треугольников и преобразовании изображений (текстура, наложенная на квадрат), но он не будет так хорош при манипуляциях с одним пикселем.

Оставаясь на территории .NET, одной из альтернатив является сохранение объекта Bitmap в качестве поверхности, используя LockBits и прямой доступ к пикселям через небезопасный указатель в возвращаемом объекте BitmapData.

Другие советы

Да, это, наверное, самый быстрый способ.

Несколько лет назад мне пришлось сравнивать два изображения размером 1024x1024 на уровне пикселей;методы get-pixel заняли 2 минуты, а небезопасное сканирование — 0,01 секунды.

Я также использовал unsafe, чтобы ускорить процессы такого рода.Улучшения производительности, мягко говоря, впечатляющие.Дело в том, что unsafe отключает множество вещей, которые могут вам не понадобиться, если вы знаете, что делаете.

Также проверьте Директдроу.Это компонент 2D-графики DirectX.Это действительно быстро.

Недавно мне было поручено создать простой элемент управления гистограммой для одного из наших приложений тонкого клиента (C#).Изображения, которые я анализировал, были размером примерно 1200x1200, и мне пришлось пойти тем же путем.Я мог бы без проблем заставить эту штуку нарисовать себя один раз, но размер элемента управления нужно было изменить.Я пытался избежать этого, но мне пришлось добраться до самих воспоминаний.

Я не говорю, что невозможно использовать стандартные классы .NET, но в конце концов мне так и не удалось заставить это работать.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top