AHI: различия между версиями
Andy51 (обсуждение | вклад) | Andy51 (обсуждение | вклад) (Добавил.. много..) | ||
Строка 15: | Строка 15: | ||
С учётом сказанного, для наиболее эффективного использования средств, предоставляемых драйвером, их следует использовать в приложении, основанном на [[Task|таске]]. | С учётом сказанного, для наиболее эффективного использования средств, предоставляемых драйвером, их следует использовать в приложении, основанном на [[Task|таске]]. | ||
− | + | == Основные концепции == | |
API драйвера напоминает интерфейсом обычные графические библиотеки, как например GDI. Рассмотрим основные понятия и приёмы работы с AHI в применении к эльфописанию. | API драйвера напоминает интерфейсом обычные графические библиотеки, как например GDI. Рассмотрим основные понятия и приёмы работы с AHI в применении к эльфописанию. | ||
Строка 22: | Строка 22: | ||
Для обеспечения такой возможности используется специальный объект, с которым разработчику [[ELF|эльфа]] под драйвер придётся сталкиваться постоянно - это ''контекст устройства''. | Для обеспечения такой возможности используется специальный объект, с которым разработчику [[ELF|эльфа]] под драйвер придётся сталкиваться постоянно - это ''контекст устройства''. | ||
− | + | === Контекст устройства === | |
'''Контекст устройства''' ({{lang-en|Device Context}}) — структура данных, обеспечивающая эксклюзивный доступ к устройству вывода для приложения, использующего эту структуру и предотвращающая влияние других приложений на процесс работы с устройством. В ней хранятся все данные о текущем состоянии устройства, устанавливаемом приложением - владельцем контекста. | '''Контекст устройства''' ({{lang-en|Device Context}}) — структура данных, обеспечивающая эксклюзивный доступ к устройству вывода для приложения, использующего эту структуру и предотвращающая влияние других приложений на процесс работы с устройством. В ней хранятся все данные о текущем состоянии устройства, устанавливаемом приложением - владельцем контекста. | ||
Строка 33: | Строка 33: | ||
Если бы небыло системы контекстов, и данные сразу попадали в устройство, то после установки '''Приложением B''' цвета в <font color="blue">синий</font>, '''Приложение A''' тоже бы получало <font color="blue">синие</font> линии вместо желаемых <font color="red">красных</font>. | Если бы небыло системы контекстов, и данные сразу попадали в устройство, то после установки '''Приложением B''' цвета в <font color="blue">синий</font>, '''Приложение A''' тоже бы получало <font color="blue">синие</font> линии вместо желаемых <font color="red">красных</font>. | ||
+ | |||
В коде контекст описывается как тип <tt>'''AHIDEVCONTEXT_T'''</tt> и является первым параметром почти у всех функций AHI. | В коде контекст описывается как тип <tt>'''AHIDEVCONTEXT_T'''</tt> и является первым параметром почти у всех функций AHI. | ||
Строка 66: | Строка 67: | ||
</li> | </li> | ||
</ol> | </ol> | ||
+ | |||
+ | === Поверхности === | ||
+ | Прежде чем переходить к рассмотрению непосредственно программирования под AHI, необходимо ознакомиться с ещё одним важнейшим понятием - "поверхностями". | ||
+ | |||
+ | Поверхность ({{lang-en|Surface}}, "Сурфейс") — логически выделенный участок [[Видеопамять|видеопамяти]] чипа ATI. | ||
+ | |||
+ | Как многим из вас известно, у видеочипов часто есть собственная видеопамять, причём эта видеопамять не обязательно доступна [[MCU|процессору]] напрмяую. В телефонах [[Motorola]] с чипами ATI именно такой случай. | ||
+ | |||
+ | Размер внутренней видеопамяти (располагается прямо на чипе) на [[W2250]] и [[W2260]] одинаков и составляет ''192Kb'', однако к [[W2260]] подключен внешний модуль для расширения внутренней видеопамяти. Последняя работает медленнее внутренней, что отчасти компенсируется её значительно большим объёмом. | ||
+ | |||
+ | [[MCU]] может обращаться к видеопамяти двумя способами - через [[DMAC]] (только запись), либо через [[QSPI]] (чтение и запись). | ||
+ | |||
+ | Все растровые операции AHI производятся с участием поверхностей. Есть четыре наиболее важные поверхности, используемые в работе драйвера. Однако, последняя фраза не означает, что поверхностей именно четыре, скорее следует понимать это как статусы, присваиваемые определённым поверхностям, и при этом одна и та же поверхность(участок памяти) может принимать одновременно несколько таких статусов: | ||
+ | *'''Отображаемая поверхность ("Display Surface", "Экранная поверхность", она же "Экранный буфер") | ||
+ | *:Это та поверхность, из которой в данный момент чип берёт информацию для непосредственного вывода на экран. | ||
+ | *:Устанавливается с помощью функции [[AhiDispSurfSet]], а получить можно с помощью [[AhiDispSurfGet]] | ||
+ | *'''Поверхность назначения ("Destination Surface", "Поверхность-приёмник") | ||
+ | *:Эта поверхность является целевой для функций рисования, тоесть в неё будет попадать результат операции. | ||
+ | *:Устанавливается функцией [[AhiDrawSurfDstSet]] | ||
+ | *'''Поверхность-источник ("Source Surface") | ||
+ | *:Эта поверхность является источником данных для функций рисования, например картинка спрайта, который мы хотим нарисовать. | ||
+ | *:Устанавливается функцией [[AhiDrawSurfSrcSet]] | ||
+ | *'''Поверхность кисти ("Brush Surface") | ||
+ | *:С этой поверхностью приложения никогда не работают напрямую, но о её существовании лучше знать, чтобы проще было понимать принцип работы некоторых функций рисования - она является важным вспомогательным инструментом. Всегда монохромная (однобитная). | ||
+ | *:Устанавливается и инициализируется самим драйвером. | ||
+ | |||
+ | |||
+ | === Инициализация === | ||
+ | Итак, у нас теперь есть контекст, полученный одним из двух способов, указанных выше. Что дальше? | ||
+ | |||
+ | Вне зависимости от того, собственный у нас контекст или нет, нужно провести его инициализацию. Различие лишь в том, что в случае собственного контекста её достаточно провести один раз, а в случае использования системного - почти каждый раз перед вызовом какой-либо функции рисования AHI. | ||
+ | |||
+ | Перед тем, как вызвать какую-либо функцию рисования, мы должны установить необходимые для её работы параметры: | ||
+ | <ol> | ||
+ | <li>'''Установить поверхность-приёмник<br> | ||
+ | Часто для этого используется отображаемая поверхность, если не планируется вывод с использованием [[Двойная буферизация|двойной буферизации]]. | ||
+ | <pre> | ||
+ | // Наш контекст, полученный ранее | ||
+ | AHIDEVCONTEXT_T dCtx; | ||
+ | |||
+ | // Наша отображаемая поверхность | ||
+ | AHISURFACE_T sDisp; | ||
+ | |||
+ | // Получим отображаемую поверхность. Достаточно сделать это один раз, ведь врядли она поменяется. | ||
+ | AhiDispSurfGet( dCtx, &sDisp ); | ||
+ | |||
+ | // Устанавливаем поверхность-приёмник | ||
+ | AhiDrawSurfDstSet( dCtx, sDisp, 0 ); | ||
+ | </pre> | ||
+ | </li> | ||
+ | |||
+ | <li>'''Установить поверхность-источник<br> | ||
+ | Обычно для этой роли используют либо пользовательскую поверхность с нужной к выводу картинкой, либо системную внеэкранную поверхность (см. [[Двойная буферизация]]). | ||
+ | <pre> | ||
+ | // Сохраним сюда системную внеэкранную поверхность | ||
+ | AHISURFACE_T sDraw; | ||
+ | |||
+ | // Получим системную внеэкранную поверхность | ||
+ | sDraw = DAL_GetDrawingSurface( DISPLAY_MAIN ); | ||
+ | |||
+ | // Устанавливаем поверхность-источник | ||
+ | AhiDrawSurfSrcSet( dCtx, sDraw, 0 ); | ||
+ | </pre> | ||
+ | </li> | ||
+ | |||
+ | <li>'''Установить [[Clipping|области вырезания]] для приёмника и источника<br> | ||
+ | Пока что выключим их, и для этого передадим в функции [[AhiDrawClipDstSet]] и [[AhiDrawClipSrcSet]] - <tt>NULL</tt>: | ||
+ | <pre> | ||
+ | // Выключаем области вырезания для приёмника и источника | ||
+ | AhiDrawClipDstSet( dCtx, NULL ); | ||
+ | AhiDrawClipSrcSet( dCtx, NULL ); | ||
+ | </pre> | ||
+ | </li> | ||
+ | |||
+ | <li>'''Установить [[Raster Operations|растровую операцию]]<br> | ||
+ | Для вывода растровых изображений, установим <tt>SRCCOPY</tt> | ||
+ | <pre> | ||
+ | // Устанавливаем растровую операцию на прямое копирование из источника | ||
+ | AhiDrawRopSet( dCtx, AHIROP3(AHIROP_SRCCOPY) ); | ||
+ | </pre> | ||
+ | </li> | ||
+ | </ol> | ||
+ | |||
+ | |||
---- | ---- | ||
Пока что это всё, ждите продолжения :) | Пока что это всё, ждите продолжения :) | ||
− | --[[Участник:Andy51|Andy51]] | + | --[[Участник:Andy51|Andy51]] 23:42, 20 августа 2009 (MSD) |
[[Категория:Эльфостроение]] | [[Категория:Эльфостроение]] |
Версия 19:42, 20 августа 2009
AHI англ. ATI Handheld Interface — драйвер для чипов ATI. Присутствует в каждой прошивке для телефонов, где есть чип ATI, а это - все телефоны на базе LTE и LTE2.
Содержание
Чипы ATI
Два основных чипа, используемых в телефонах Motorola:
API драйвера для различных чипов одинаков, однако внутреннее устройство значительно различается (По словам владельцев. Лично мне неизвестно, насколько. A51)
Применение
Вывод графики через драйвер, в обход стандартных средств прошивки (см. Canvas), предоставляет больше возможностей по сравнению с последними, и, при правильном применении, работает значительно быстрее.
Если Вам нужно, чтобы вывод собственной графики был на максимально возможной скорости, как, например, для разработки динамичных игр - тогда стоит задуматься о применении средств драйвера. В остальных случаях использование Canvas будет значительно проще.
С учётом сказанного, для наиболее эффективного использования средств, предоставляемых драйвером, их следует использовать в приложении, основанном на таске.
Основные концепции
API драйвера напоминает интерфейсом обычные графические библиотеки, как например GDI. Рассмотрим основные понятия и приёмы работы с AHI в применении к эльфописанию.
AHI разрабатывался отдельно от программных продуктов, где он используется, поэтому был спроектирован максимально универсальным. Одно из следствий такой универсальности является возможность драйвера распараллеливать работу с железом между различными "клиентами", а именно - между приложениями операционной системы и самой ОС.
Для обеспечения такой возможности используется специальный объект, с которым разработчику эльфа под драйвер придётся сталкиваться постоянно - это контекст устройства.
Контекст устройства
Контекст устройства (англ. Device Context) — структура данных, обеспечивающая эксклюзивный доступ к устройству вывода для приложения, использующего эту структуру и предотвращающая влияние других приложений на процесс работы с устройством. В ней хранятся все данные о текущем состоянии устройства, устанавливаемом приложением - владельцем контекста.
Чтобы лучше разъяснить как это работает, рассмотрим ситуацию на упрощенном примере:
- Приложения A и B работают параллельно, и хотят получить доступ к Устройству, для чего каждый из них создаёт с помощью AHI новый контекст для собственного пользования.
- Приложение A пытается изменить состояние Устройства, скажем, меняет основной цвет "кисти" на красный. А на самом деле, информация о цвете кисти попадает не сразу в Устройство, а сохраняется в контексте приложения A.
- Приложение B тоже меняет (в своём контексте) цвет кисти, но на синий.
- Теперь, Приложение B пытается вывести линию синим цветом. Для этого драйвер отсылает контекст приложения B (вместе с информацией о цвете) Устройству и подаёт команду на рисование линии текущим (синим) цветом.
- После этого, если Приложение A тоже решит нарисовать линию, ему не придётся "задумываться" о том, что Приложение B что-то там проделало с Устройством, а просто вызовет функцию рисования линии, и драйвер нарисует её красным цветом, выполнив те же процедуры с контекстом.
Если бы небыло системы контекстов, и данные сразу попадали в устройство, то после установки Приложением B цвета в синий, Приложение A тоже бы получало синие линии вместо желаемых красных.
В коде контекст описывается как тип AHIDEVCONTEXT_T и является первым параметром почти у всех функций AHI.
В ОС P2K напрямую функции драйвера не используются (кроме Java-машины), а Функции графики предоставляются через промежуточную надстройку над AHI - DAL, поэтому все приложения ОС (а точнее, система UIS), так же как и сама ОС, используют единственный системный контекст.
Для эльфов есть выбор, как получить контекст:
- Можно получить системный контекст, который использует ОС, с помощью функции DAL_GetDeviceContext:
// Это будет наш контекст. Удобнее всего объявить его глобальным AHIDEVCONTEXT_T dCtx; // Получаем системный контекст dCtx = DAL_GetDeviceContext(0);
Недостаток этого способа - необходимо помнить, что приложение не является единственным клиентом драйвера, и делать необходимые установки перед каждой операцией вывода.
- Либо можно создать новый контекст только для нужд приложения, с помощью функций ldrGetAhiDevice и AhiDevOpen:
// Это будет наш контекст. Удобнее всего объявить его глобальным AHIDEVCONTEXT_T dCtx; // Информация об устройстве AHIDEVICE_T device; // В EP2 уже есть вспомогательная функция для получения информации об устройстве device = ldrGetAhiDevice(); // Создаём контекст sts = AhiDevOpen( &dCtx, device, "Matrix", 0 );
Недостаток этого способа - если функции драйвера используются несколькими клиентами одновременно, они работают медленнее из-за необходимости постоянно переключаться между контекстами.
Поверхности
Прежде чем переходить к рассмотрению непосредственно программирования под AHI, необходимо ознакомиться с ещё одним важнейшим понятием - "поверхностями".
Поверхность (англ. Surface, "Сурфейс") — логически выделенный участок видеопамяти чипа ATI.
Как многим из вас известно, у видеочипов часто есть собственная видеопамять, причём эта видеопамять не обязательно доступна процессору напрмяую. В телефонах Motorola с чипами ATI именно такой случай.
Размер внутренней видеопамяти (располагается прямо на чипе) на W2250 и W2260 одинаков и составляет 192Kb, однако к W2260 подключен внешний модуль для расширения внутренней видеопамяти. Последняя работает медленнее внутренней, что отчасти компенсируется её значительно большим объёмом.
MCU может обращаться к видеопамяти двумя способами - через DMAC (только запись), либо через QSPI (чтение и запись).
Все растровые операции AHI производятся с участием поверхностей. Есть четыре наиболее важные поверхности, используемые в работе драйвера. Однако, последняя фраза не означает, что поверхностей именно четыре, скорее следует понимать это как статусы, присваиваемые определённым поверхностям, и при этом одна и та же поверхность(участок памяти) может принимать одновременно несколько таких статусов:
- Отображаемая поверхность ("Display Surface", "Экранная поверхность", она же "Экранный буфер")
- Это та поверхность, из которой в данный момент чип берёт информацию для непосредственного вывода на экран.
- Устанавливается с помощью функции AhiDispSurfSet, а получить можно с помощью AhiDispSurfGet
- Поверхность назначения ("Destination Surface", "Поверхность-приёмник")
- Эта поверхность является целевой для функций рисования, тоесть в неё будет попадать результат операции.
- Устанавливается функцией AhiDrawSurfDstSet
- Поверхность-источник ("Source Surface")
- Эта поверхность является источником данных для функций рисования, например картинка спрайта, который мы хотим нарисовать.
- Устанавливается функцией AhiDrawSurfSrcSet
- Поверхность кисти ("Brush Surface")
- С этой поверхностью приложения никогда не работают напрямую, но о её существовании лучше знать, чтобы проще было понимать принцип работы некоторых функций рисования - она является важным вспомогательным инструментом. Всегда монохромная (однобитная).
- Устанавливается и инициализируется самим драйвером.
Инициализация
Итак, у нас теперь есть контекст, полученный одним из двух способов, указанных выше. Что дальше?
Вне зависимости от того, собственный у нас контекст или нет, нужно провести его инициализацию. Различие лишь в том, что в случае собственного контекста её достаточно провести один раз, а в случае использования системного - почти каждый раз перед вызовом какой-либо функции рисования AHI.
Перед тем, как вызвать какую-либо функцию рисования, мы должны установить необходимые для её работы параметры:
- Установить поверхность-приёмник
Часто для этого используется отображаемая поверхность, если не планируется вывод с использованием двойной буферизации.// Наш контекст, полученный ранее AHIDEVCONTEXT_T dCtx; // Наша отображаемая поверхность AHISURFACE_T sDisp; // Получим отображаемую поверхность. Достаточно сделать это один раз, ведь врядли она поменяется. AhiDispSurfGet( dCtx, &sDisp ); // Устанавливаем поверхность-приёмник AhiDrawSurfDstSet( dCtx, sDisp, 0 );
- Установить поверхность-источник
Обычно для этой роли используют либо пользовательскую поверхность с нужной к выводу картинкой, либо системную внеэкранную поверхность (см. Двойная буферизация).// Сохраним сюда системную внеэкранную поверхность AHISURFACE_T sDraw; // Получим системную внеэкранную поверхность sDraw = DAL_GetDrawingSurface( DISPLAY_MAIN ); // Устанавливаем поверхность-источник AhiDrawSurfSrcSet( dCtx, sDraw, 0 );
- Установить области вырезания для приёмника и источника
Пока что выключим их, и для этого передадим в функции AhiDrawClipDstSet и AhiDrawClipSrcSet - NULL:// Выключаем области вырезания для приёмника и источника AhiDrawClipDstSet( dCtx, NULL ); AhiDrawClipSrcSet( dCtx, NULL );
- Установить растровую операцию
Для вывода растровых изображений, установим SRCCOPY// Устанавливаем растровую операцию на прямое копирование из источника AhiDrawRopSet( dCtx, AHIROP3(AHIROP_SRCCOPY) );
Пока что это всё, ждите продолжения :) --Andy51 23:42, 20 августа 2009 (MSD)