Подтвердить что ты не робот

Аппаратное ускорение Java

Я проводил некоторое время, изучая возможности аппаратного ускорения 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()

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

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

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

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

4b9b3361

Ответ 1

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() не делает никакого преобразования в поддерживаемую по умолчанию Image Data Model. Поэтому, если вы импортируете 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) Насколько я знаю, дизайн, который вы наметили, является одной из лучших стратегий при выполнении двойной буферизации вручную и активной визуализации приложения. http://docs.oracle.com/javase/7/docs/api/java/awt/image/BufferStrategy.html По этой ссылке вы найдете описание BufferStrategy. В описании он показывает фрагмент кода, который является рекомендуемым способом для активного рендеринга с объектом BufferStrategy. Я использую эту технику для своего активного кода рендеринга. Единственное существенное отличие в том, что в моем коде. как вы, я создал BufferStrategy в экземпляре Canvas, который я положил на JFrame.

Ответ 2

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

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

Вы можете проверить, ускоряется ли аппаратное ускорение с помощью Image getCapabilities(GraphicsConfiguration).isAccelerated()

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