2011-01-07 5 views
17

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

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

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

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

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

ответ

16

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() 

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

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

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

+0

Есть ли какая-то особая причина, по которой большинство/все примеры используют JFrame для хранения холста? Из того, что я понял, Свинг ужасен. Почему бы вам не использовать рамку? У меня есть код, который делает именно это, и, кажется, его сложнее создать, чем JFrame. Также как аппаратное ускорение включено, если оно не по умолчанию? – Freezerburn

+0

@FreezerBurn Я не знаю, почему большинство примеров используют JFrame vs Frame. Я предполагаю, что это делается с помощью JFrame, потому что это то, что наиболее широко известно. Это только предположение, но я бы предположил, что рендеринг вручную на Java с использованием только контейнера верхнего уровня (JFrame, Frame и т. Д.) И холста имеет мало различий между тем, который вы выбираете. Чтобы активировать ускорение рендеринга, передайте этот аргумент (-Dsun.java2d.opengl = true) в Java-пуск при запуске программы или установите его перед использованием любых библиотек рендеринга. (System.setProperty ("sun.java2d.opengl", "true");) Это необязательный параметр. – Zixradoom

+0

JFrame Swing, где рамка/холст AWT. Swing - это новая библиотека компонентов, а AWT - устаревшая библиотека. Swing использует легкие компоненты, где AWT - это собственные компоненты. JFrame предпочла более старые компоненты AWT. – chubbsondubs

2

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

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

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

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

+0

Где я могу найти свойство sun.java2d.opengl? Я видел, как это упоминалось, но я никогда не знал, где его проверить или поместить, чтобы убедиться, что он включен в Mac/Eclipse. Также: http://download.oracle.com/javase/1.5.0/docs/guide/2d/new_features.html говорит, что BufferedImages управляются в 1.5.0 и кэшируются в видеопамяти. – Freezerburn

+0

Давайте посмотрим ... Я думаю, что это 'System.getProperty (" sun.java2d.opengl ")', чтобы получить значение свойства. Что касается 'BufferedImage', он сказал, что он может быть кэширован в видеопамяти, но ничего не говорит о том, что на самом деле манипулирует им. – Powerlord

+0

Печать вывода getProperty дает мне «пустую» консоль. Насколько я понимаю, как ускорение работает на Java, BufferedImage, находящийся в видеопамяти, допускает быстрое копирование, которое должен иметь VolatileImage? Я бы предположил, что это будет так, если он использует видео-видео-копирование. – Freezerburn

Смежные вопросы