Аппаратное ускорение Java - PullRequest
19 голосов
/ 07 января 2011

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

1) В Eclipse версии 3.6.0 с последним обновлением Java для Mac OS X (я думаю, 1.6u10), аппаратное ускорение включенодефолт?Я где-то читал, что

someCanvas.getGraphicsConfiguration().getBufferCapabilities().isPageFlipping()

должен указывать, включено ли аппаратное ускорение, и моя программа сообщает значение true, когда оно запускается на моем основном экземпляре Canvas для рисования в.Если мое аппаратное ускорение не включено сейчас или по умолчанию, что мне нужно сделать, чтобы включить его?

2) Я видел несколько статей здесь и там о разнице между BufferedImage и VolatileImage, главным образомговоря, что VolatileImage является аппаратно ускоренным изображением и хранится в VRAM для быстрого копирования из операций.Тем не менее, я также обнаружил несколько случаев, когда BufferedImage также называется аппаратно ускоренным.Аппаратное ускорение BufferedImage также ускоряется в моей среде?Каким будет преимущество использования VolatileImage, если оба типа аппаратно ускорены?Мое основное предположение о преимуществе наличия VolatileImage в случае, когда оба имеют ускорение, состоит в том, что VolatileImage может обнаружить, когда его VRAM был сброшен.Но если бы BufferedImage теперь также поддерживает ускорение, не будет ли в нем встроено такое же обнаружение, просто скрытое от пользователя, на случай, если память будет выгружена?

3) Есть ли какое-то преимущество дляиспользование

someGraphicsConfiguration.getCompatibleImage/getCompatibleVolatileImage()

вместо

ImageIO.read()

В учебном пособии я читал некоторые общие понятия о правильной настройке окна рендеринга ( tutorial ).использует метод getCompatibleImage, который, я считаю, возвращает BufferedImage, чтобы получить их «аппаратно ускоренные» изображения для быстрого рисования, что связано с вопросом 2 о том, ускоряется ли аппаратно.

4) Это меньше аппаратного ускорения,но это то, что мне было любопытно: мне нужно заказать, какая графика рисуется?Я знаю, что при использовании OpenGL через C / C ++ лучше всего убедиться, что одна и та же графика рисуется во всех местах, где она должна быть нарисована одновременно, чтобы уменьшить количество раз, когда текущая текстура должна переключаться.Из того, что я прочитал, кажется, что Java позаботится об этом для меня и убедится, что все нарисовано наиболее оптимальным образом, но, опять же, ничего подобного не было ясно сказано.

5)Какие классы AWT / Swing поддерживают аппаратное ускорение, и какие следует использовать?В настоящее время я использую класс, который расширяет JFrame для создания окна, и добавляю к нему Canvas, из которого я создаю BufferStrategy.Это хорошая практика, или есть какой-то другой способ, которым я должен реализовать это?

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

Ответы [ 2 ]

16 голосов
/ 12 декабря 2012

1) До сих пор аппаратное ускорение никогда не включалось по умолчанию, и, насколько мне известно, оно еще не изменилось.Чтобы активировать ускорение рендеринга, передайте этот аргумент (-Dsun.java2d.opengl = true) в средство запуска Java при запуске программы или установите его перед использованием любых библиотек рендеринга.System.setProperty("sun.java2d.opengl", "true"); Это необязательный параметр.

2) Да BufferedImage инкапсулирует некоторые детали управления энергозависимой памятью, поскольку при ускорении BufferdImage его копия сохраняется в V-Ramкак VolatileImage.

Потенциал для BufferedImage - это до тех пор, пока вы не возитесь с содержащимися в нем пикселями, просто копируете их как вызов graphics.drawImage(), тогда BufferedImage будетускориться после определенного не указанного количества копий, и он будет управлять VolatileImage для вас.

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

3) Преимущество использования createCompatibleImage()/createCompatibleVolatileImage() состоит в том, что ImageIO.read() не выполняет никакого преобразования в значение по умолчанию.поддерживается модель данных изображения.Поэтому, если вы импортируете PNG, он будет представлен в формате, созданном программой чтения PNG.Это означает, что каждый раз, когда он визуализируется с помощью GraphicsDevice, он сначала должен быть преобразован в совместимую модель данных изображения.

BufferedImage image = ImageIO.read ( url );
BufferedImage convertedImage = null;
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment ();
GraphicsDevice gd = ge.getDefaultScreenDevice ();
GraphicsConfiguration gc = gd.getDefaultConfiguration ();
convertedImage = gc.createCompatibleImage (image.getWidth (), 
                                           image.getHeight (), 
                                           image.getTransparency () );
Graphics2D g2d = convertedImage.createGraphics ();
g2d.drawImage ( image, 0, 0, image.getWidth (), image.getHeight (), null );
g2d.dispose()

Приведенный выше процесс преобразует изображение, считанное с изображения io api, вBufferedImage, которое имеет модель данных изображения, совместимую с устройством экрана по умолчанию, поэтому преобразование не требуется при его рендеринге.Время, когда это наиболее выгодно, это когда вы будете рендерить изображение очень часто.

4) Вам не нужно прилагать усилия для пакетной визуализации вашего изображения, потому что по большей части Java попытается сделать этодля тебя.Нет никаких причин, по которым вы не можете попытаться сделать это, но в целом лучше профилировать свои приложения и подтвердить наличие узкого места в коде рендеринга изображений, прежде чем пытаться выполнить оптимизацию производительности, подобную этой.Основным недостатком является то, что он может быть реализован немного по-разному в каждой JVM, и тогда усовершенствования могут оказаться бесполезными.

5) Насколько я знаю, проект, который вы обрисовали в общих чертах, является одной из лучших стратегий, когдаделает Double Buffering вручную и активно рендерит приложение.http://docs.oracle.com/javase/7/docs/api/java/awt/image/BufferStrategy.html По этой ссылке вы найдете описание BufferStrategy.В описании показан фрагмент кода, рекомендуемый способ активного рендеринга с объектом BufferStrategy.Я использую эту конкретную технику для моего активного кода рендеринга.Единственное основное отличие заключается в том, что в моем коде.Как и вы, я создал BufferStrategy на экземпляре Canvas, который я надел на JFrame.

2 голосов
/ 07 января 2011

Судя по некоторой более старой документации , на виртуальных машинах Sun вы можете узнать, включено аппаратное ускорение или нет, проверив свойство sun.java2d.opengl.

К сожалению, я не знаю, относится ли это к Apple JVM.

Вы можете проверить аппаратное ускорение отдельного образа, используя Image s getCapabilities(GraphicsConfiguration).isAccelerated()

Сказав все это, вся документация, которую я видел (включая эту ), подразумевает, что BufferedImage это не аппаратное ускорение. По этой же причине Swing также был изменен на использование VolatileImage s для двойной буферизации.

...