Открыть главное меню

AHI: различия между версиями

 
(Добавил.. много..)
Строка 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]] 18:29, 20 августа 2009 (MSD)
+
--[[Участник:Andy51|Andy51]] 23:42, 20 августа 2009 (MSD)
  
 
[[Категория:Эльфостроение]]
 
[[Категория:Эльфостроение]]

Версия 19:42, 20 августа 2009

AHI англ. ATI Handheld Interface — драйвер для чипов ATI. Присутствует в каждой прошивке для телефонов, где есть чип ATI, а это - все телефоны на базе LTE и LTE2.

Чипы ATI

Два основных чипа, используемых в телефонах Motorola:

  • ATI W2250 - преимущественно в LTE
  • ATI W2260 - преимущественно в LTE2

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), так же как и сама ОС, используют единственный системный контекст.

Для эльфов есть выбор, как получить контекст:

  1. Можно получить системный контекст, который использует ОС, с помощью функции DAL_GetDeviceContext:
    // Это будет наш контекст. Удобнее всего объявить его глобальным
    AHIDEVCONTEXT_T	dCtx;
    // Получаем системный контекст
    dCtx = DAL_GetDeviceContext(0);

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

  2. Либо можно создать новый контекст только для нужд приложения, с помощью функций 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.

Перед тем, как вызвать какую-либо функцию рисования, мы должны установить необходимые для её работы параметры:

  1. Установить поверхность-приёмник
    Часто для этого используется отображаемая поверхность, если не планируется вывод с использованием двойной буферизации.
    // Наш контекст, полученный ранее
    AHIDEVCONTEXT_T	dCtx;
    // Наша отображаемая поверхность
    AHISURFACE_T	sDisp;
    // Получим отображаемую поверхность. Достаточно сделать это один раз, ведь врядли она поменяется.
    AhiDispSurfGet( dCtx, &sDisp );
    // Устанавливаем поверхность-приёмник
    AhiDrawSurfDstSet( dCtx, sDisp, 0 );
  2. Установить поверхность-источник
    Обычно для этой роли используют либо пользовательскую поверхность с нужной к выводу картинкой, либо системную внеэкранную поверхность (см. Двойная буферизация).
    // Сохраним сюда системную внеэкранную поверхность
    AHISURFACE_T	sDraw;
    // Получим системную внеэкранную поверхность
    sDraw = DAL_GetDrawingSurface( DISPLAY_MAIN );
    // Устанавливаем поверхность-источник
    AhiDrawSurfSrcSet( dCtx, sDraw, 0 );
  3. Установить области вырезания для приёмника и источника
    Пока что выключим их, и для этого передадим в функции AhiDrawClipDstSet и AhiDrawClipSrcSet - NULL:
    // Выключаем области вырезания для приёмника и источника
    AhiDrawClipDstSet( dCtx, NULL );
    AhiDrawClipSrcSet( dCtx, NULL );
  4. Установить растровую операцию
    Для вывода растровых изображений, установим SRCCOPY
    // Устанавливаем растровую операцию на прямое копирование из источника
    AhiDrawRopSet( dCtx, AHIROP3(AHIROP_SRCCOPY) );



Пока что это всё, ждите продолжения :) --Andy51 23:42, 20 августа 2009 (MSD)