Board.KolibriOS.org

Official KolibriOS board
It is currently Tue Dec 01, 2020 3:22 am

All times are UTC+03:00




Post new topic  Reply to topic  [ 100 posts ]  Go to page Previous 1 2 3 4 5 6 7 Next
Author Message
PostPosted: Sun Oct 04, 2009 6:44 pm 
Offline
User avatar

Joined: Thu May 19, 2005 4:43 pm
Posts: 896
Quote:
ты имееш ввиду libGUI ? В каком файле код ?


Да. Код в файле draw_controls.inc Только код полностью на C. Если написать на ассемблере, то быстрее будет работать. Реализовать функцию рисующую и на экране и в буфере можно по разному. У меня реализовано так:
Code:
void DrawPixel(int x,int y,DWORD color)
{
   char      r,g,b;
   char      *ptr;
   DWORD   *ptr2;

   if (x>screen.size_x-1) {x=screen.size_x-1;}
   if (y>screen.size_y-1) {y=screen.size_y-1;}
   if (x<0) {x=0;}
   if (y<0) {y=0;}

   switch(screen.draw_output)
   {
      case DRAW_OUTPUT_SCREEN:
      {
         x+=screen.x;
         y+=screen.y;
         gui_ksys_put_pixel_window(x,y,color);
         break;
      }
      case DRAW_OUTPUT_BUFFER:
      {
         ptr=screen.buffer;
         switch(screen.bits_per_pixel)
         {
            case 24:
            {
               ptr=ptr+(y*screen.size_x+x)*3;
               b=color & 0xff;
               color=color >>8;
               g=color & 0xff;
               color=color >>8;
               r=color & 0xff;

               ptr[0]=b;
               ptr[1]=g;
               ptr[2]=r;
               break;
            }
            case 32:
            {
               ptr2=(DWORD*)ptr+y*screen.size_x+x;
               *ptr2=color;
               break;
            }
            default: break;
         }
         break;
      }
   }
}


Функций, непосредственно работающих с экраном/буффером 4: DrawPixel(),DrawHorizontalLine(),DrawVerticalLine(),DrawImage(). Все остальные функции рисования используют эти 4. В результате можно рисовать как на экране, так и в буффере.

_________________
KolibriOS-перспективная ос!
Kolibri is best operation system in the world!


Top
   
PostPosted: Mon Oct 05, 2009 6:46 am 
Offline
Mentor
User avatar

Joined: Tue Jan 15, 2008 11:27 am
Posts: 756
andrew_programmer
Я бы в начале функции проверку на выход за границы изменил бы на такую:

Code:
if  ( (x>screen.size_x-1) || (y>screen.size_y-1) || (x<0) || (y<0) )
         return;


Top
   
PostPosted: Mon Oct 05, 2009 2:51 pm 
Offline
User avatar

Joined: Thu May 19, 2005 4:43 pm
Posts: 896
Да, для отдельных пикселей лучше так.
Эта проверка границ у меня взята из вывода геометрических примитивов. Там просто так отсекать вывод по границам нельзя. Видимо забыл поменять код. Когда дело дойдёт до полной оптимизации функций рисования, то я всеми этими вещами займусь.

_________________
KolibriOS-перспективная ос!

Kolibri is best operation system in the world!


Top
   
PostPosted: Mon Oct 05, 2009 11:06 pm 
Offline
User avatar

Joined: Mon Oct 27, 2008 10:10 pm
Posts: 871
что-бы не мигало и быстрее выводило при прорисовке добавил возможность вывода через буфер. Появилось 5 функций для работы с буфером (создание, удаление, очистка, вывод на экран, установка активного буфера). Пока поддерживается только 1 буфер, но в будущем можно будет расширить их число.
Старый вариант работы, с выводом на экран тоже возможен. В архиве 2 программы используют буфер, остальные рисуют напрямую в экран.
Шрифт вроде стал работать быстрее.


Attachments:
vectors_091005.7z [22.14 KiB]
Downloaded 212 times
Top
   
PostPosted: Mon Oct 05, 2009 11:39 pm 
Offline
User avatar

Joined: Mon Oct 27, 2008 10:10 pm
Posts: 871
переделал еще 1 пример под буфер, точно быстрее выводит :D


Attachments:
File comment: еще 1 пример с буфером
bug_buf.7z [6.13 KiB]
Downloaded 212 times
Top
   
PostPosted: Tue Oct 06, 2009 12:02 am 
Offline
User avatar

Joined: Mon Apr 16, 2007 6:38 pm
Posts: 1222
вообще супер! =)

_________________
И мы уже давно не пешки,
Мы пули, мы орлы, и решки!
Война ютит бинарный код,
Умри, или иди вперед!


Top
   
PostPosted: Tue Oct 06, 2009 1:07 am 
Offline
User avatar

Joined: Thu May 19, 2005 4:43 pm
Posts: 896
В коде попиксельного рисования в буфере желательно заменить вот это:
Code:
drawpixel_buf:
  bt bx,15
  jc @f
  bt cx,15
  jc @f
  cmp bx,word[active_buffer_w]
  jge @f
  cmp cx,word[active_buffer_h]
  jge @f
  push edi esi
  mov edi,dword[active_buffer] ;ptr - pointer to buffer
  mov esi,ebx ;esi=coord x
  imul esi,3    ;x*3
  add edi,esi   ;ptr+x*3

  xor esi,esi
  mov si,word[active_buffer_w] ;size x
  imul esi,ecx ;size_x*y   
  imul esi,3   ;size_x*y*3
  add edi,esi   ;ptr+x*3+size_x*y*3
  mov word[edi],dx ;
  ror edx,16      
  mov byte[edi+2],dl
  ror edx,16
  pop esi edi
  @@:
  ret

хотя бы на это
Code:
 drawpixel_buf:
  bt bx,15
  jc @f
  bt cx,15
  jc @f
  cmp bx,word[active_buffer_w]
  jge @f
  cmp cx,word[active_buffer_h]
  jge @f
  push esi
  xor esi,esi
  mov si,word[active_buffer_w] ;size x
  imul esi,ecx   ;size_x*y
  add esi,ebx   ;size_x*y+x
  lea esi,[esi+esi*2] ;(size_x*y+x)*3
  add esi,dword[active_buffer] ;ptr+(size_x*y+x)*3
 
  mov word[esi],dx ;
  ror edx,16      
  mov byte[esi+2],dl
  ror edx,16
  pop esi
  @@:
  ret

Небольшие рекомендации.
В коде попиксельного рисования отдельного вида кривой желательно сделать как можно меньше обращений к системной памяти. То есть желательно отказаться от push/pop для функции попиксельного рисования. Перед вызовом drawpixel_buf необходимые параметры поместить в регистры(указатель на буфер, его ширина и высота). Если последовательно рисуется множество точек одной кривой, то заранее размещённые в регистрах параметры дадут очень существенное ускорение работы. Скорость работы регистровой памяти значительно выше, чем системной.

_________________
KolibriOS-перспективная ос!

Kolibri is best operation system in the world!


Top
   
PostPosted: Tue Oct 06, 2009 10:08 am 
Добавлю пять копеек:
1) Если условно разбить буфер на знакоместа определенного размера (например, 50х50 пикселов) и дополнительно использовав область для хранения признака обновления знакоместа, можно немного ускорить вывод обновляя только те знакоместа, в которые производился вывод. Конечно при вызове перерисовки окна нужно перерисовывать весь буфер, но потом достаточно только перерисовывать изменения. Особенно заметна будет разница в скорости на полноэкранных приложениях, при обновлении небольших участков.
2) Имеет смысл сделать буфер чуть большим отображаемого куска на экране, иначе у жучары части пропадают в некоторых ракурсах.


Top
   
PostPosted: Tue Oct 06, 2009 1:21 pm 
Offline
User avatar

Joined: Mon Oct 27, 2008 10:10 pm
Posts: 871
andrew_programmer согласен что не оптимально, перекомпилировал, работает. Только не пойму как вместо умножения на 3 написано:
Code:
  lea esi,[esi+esi*2] ;(size_x*y+x)*3

почему не так:
Code:
  imul esi,3

или так:
Code:
  lea esi,[esi*3] ;(size_x*y+x)*3


Top
   
PostPosted: Tue Oct 06, 2009 1:57 pm 
IgorA wrote:
почему не так:
Code:
  imul esi,3

или так:
Code:
  lea esi,[esi*3] ;(size_x*y+x)*3

1. Потому что IMUL теоретически медленней.
2. Потому что Зубков.
Code:
Команда LEA
LEA можно использовать (кроме прямого назначения — вычисления адреса сложно адресуемой переменной) для следующих двух ситуаций:

быстрое умножение
        lea        еах,[еах*2]     ; ЕАХ = ЕАХ * 2 (shl eax,1 лучше)

        lea        еах,[еах+еах*2]  ; ЕАХ = ЕАХ * 3
        lea        еах,[еах*4]      ; ЕАХ = ЕАХ * 4 (shl eax,2 лучше)

        lea        еах,[еах+еах*4]  ; ЕАХ = ЕАХ * 5
        lea        еах,[еах+еах*8]  ; ЕАХ = ЕАХ * 9

трехоперандное сложение
        lea        ecx,[eax+ebx]    ; ЕСХ = ЕАХ * ЕВХ

Единственный недостаток LEA — увеличивается вероятность AGI с предыдущей командой (см. ниже).


Top
   
PostPosted: Tue Oct 06, 2009 2:18 pm 
Offline
User avatar

Joined: Thu May 19, 2005 4:43 pm
Posts: 896
Quote:
почему не так:
imul esi,3

Потому что так на умножение уйдёт минимум 10 тактов. А при помощи командыlea esi,[esi+2*esi] всего 2-3 такта.
Quote:
почему не так:
imul esi,3
или так:
lea esi,[esi*3] ;(size_x*y+x)*3

С учётом того, что команда lea может выполняться одновременно с другой командой в любом конвеере, получается, что по скорости кода lea esi,[esi*3] =imul esi,3

Для процессора умножение на 2 в степени n - это просто сдвиг на n бит влево. Операция сложения, также как и команда lea тоже может выполняться в любом конвеере. В общем вычисление адреса вместе с занесением его в ESI занимает минимум 2-3 такта, против минимум 10 в случае с imul.

_________________
KolibriOS-перспективная ос!

Kolibri is best operation system in the world!


Top
   
PostPosted: Wed Oct 07, 2009 2:41 pm 
Offline
User avatar

Joined: Mon Oct 27, 2008 10:10 pm
Posts: 871
Сделал 3 изменения:
1) исправил функцию рисования точки в буфере, как сказал andrew_programmer
2) доработал алгоритм отсечения кривых, когда они попадают на верхнюю и на левую границу окна
3) можно использовать несколько отдельных буферов (номера принимают функции на входе, максимум 8 буферов, хотя при необходимости можно добавить)

Дописал справку, под новые функции.


Attachments:
vectors_091007.7z [24.08 KiB]
Downloaded 205 times
Top
   
PostPosted: Wed Oct 07, 2009 3:49 pm 
Offline
Mentor
User avatar

Joined: Tue Jan 15, 2008 11:27 am
Posts: 756
в документации опечаточка. нужно исправить "длинна" на "длина"


Top
   
PostPosted: Wed Oct 07, 2009 7:35 pm 
Offline
Kernel Developer
User avatar

Joined: Mon Mar 20, 2006 10:44 am
Posts: 558
IgorA
Делай больше коментариев в коде, и перед каждой функцией желатьельно, полез посмотреть - все равно что в IDA посмотрел, найдется мало желающих помогать в разработке.


Top
   
PostPosted: Wed Oct 07, 2009 7:52 pm 
Offline
User avatar

Joined: Mon Oct 27, 2008 10:10 pm
Posts: 871
Albom
Исправлю
Ghost
Я более подробно пробовал писать в документации. Но могу и в коде больше коментов написать. Если писать комментарии в коде, то в какой кодировке лучше OEM или ANSI?
Ghost wrote:
больше коментариев в коде, и перед каждой функцией желатьельно

Имеешь в виду саму библиотеку или ее использование. Или и то и другое?


Top
   
Display posts from previous:  Sort by  
Post new topic  Reply to topic  [ 100 posts ]  Go to page Previous 1 2 3 4 5 6 7 Next

All times are UTC+03:00


Who is online

Users browsing this forum: No registered users and 0 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Limited