Перейти к содержанию
    

Алгоритм расчёта цвета прозрачности

Дано: C674x DSP.  Цветовое пространство - 16 бит на пиксел (RGB 5:6:5).

Надо: реализовать быстрый алгоритм отрисовки с цветом прозрачности. Цвет прозрачности один - либо прозрачно, либо нет.

 

Пока так (неоптимально):

for(y=0;y<100;y++)
  for(x=0;x<100;x++)
    if(src_color!=colorkey)dst_color=src_color;

 

Советник производительности (perfomance adviser) пишет, что очень мешает условие внутри цикла и рекомендует заменить его на более быстрый алгоритм.

 

Копаю intrinsic для C674x, что-то не могу сообразить из них что-то эффективное. Конкретно, вот это условие:

if(src_color!=colorkey)dst_color=src_color;

 

Надо заменить  на быстрое выражение, логика которого:

( SRC_COLOR == COLOR_KEY ? ) DST_COLOR : DST_COLOR=SRC_COLOR ;

 

Причём, значение цветового ключа можно выбрать любым, какое будет удобно. Будет только одно значение цветового  ключа. Подозреваю, лучшие значения 0 или FFFF.

 

И всё-же как ускориться ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

а как  в плисе нельзя? 

cond = (src_color == color_key) 

(dst_color & !cond) | (src_color & cond)

где cond нужно расширить до разрядности операндов. 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Задать цвет прозрачности 0, и сравнивать с нулём. Проще не придумывается. 

if (src) dst = src;

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Приятно был удивлён, что сравнение с нулём привело к генерации более эффективного кода.

 

Задача сводится к отрисовке небольшого квадратного блока 8x8 пикселей с цветом прозрачности.  Ниже вариант без прозрачности - в нём за 1 раз рисуются 4 пиксела(8 байтная пересылка).  Теперь как цвет прозрачности применить одновременно к 4-м пикселам, чтобы было быстро ?

 

//VRAMOffset - указатель на видеобуфер, может быть невыровненный доступ
//SROMOffset - указатель на исходные данные (выровнен на 8 байт)

void Draw_Tile8x8(u16 SX,u32 SY,s16 DX,s16 DY)
{
 u64 * __restrict SROMOffset=(u64*)&SROMBuffer[(SY*SPRITE_PITCH)+(SX<<1)];
 u64 * __restrict VRAMOffset=(u64*)&VRAMBuffer[((DY*SCREEN_WIDTH)+DX)<<1];
 for(u32 y=0;y<8;y++)
 {
  _mem8(VRAMOffset++)=_amem8(SROMOffset++);
  _mem8(VRAMOffset++)=_amem8(SROMOffset++);

  SROMOffset+=((SPRITE_PITCH>>1)-8)>>2;
  VRAMOffset+=(SCREEN_WIDTH-8)>>2;
 }
}

 

Изменено пользователем repstosw

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...