Board.KolibriOS.org

Official KolibriOS board
It is currently Sat May 25, 2019 12:12 am

All times are UTC+03:00




Post new topic  Reply to topic  [ 20 posts ]  Go to page 1 2 Next
Author Message
PostPosted: Wed Oct 06, 2010 5:40 pm 
Offline

Joined: Thu Jan 26, 2006 8:47 pm
Posts: 284
Хочу попробовать реализовать следующую вещь:
Процесс-демон который будет полностью отвечать за окна (и скорей всего за виджеты). Т.е. все приложения обращаются к нему, допустим через IPC, с запросами на создание/удаление окон, и какие события хотят получать в ответ.

Плюсы:
Внешний вид приложений будет унифицирован (+темы), с возможностью рисовать на своем окне как сейчас.
Процесс не надо думать как обрабатывать виджеты (фокус, перемещение клавишами и пр.).
Возможность вынести оконную оболочку на другой хост и общаться по сети.
Возможность управлять чужими окнами на уровне виджетов.
Создавать окна разом файлом ресурсов например в формате *.rc, *.res или *.xml (*.rc уже в принципе давно делал, не выкладывал только)

Минусы:
Скорость IPC скажется на скорость оконного менеджера
При текущей реализации возможно убивание процесса (можно конечно сделать сторожевой процесс, который будет заново загружать).
Если падает - то все разом (но есть идеи как быстро все восстановить)


Собственно сразу возникли не понятные проблемы:
Создаю окно 1 типа (прозрачное без ничего). Выделяю память размером ВЫСОТА*ШИРИНА*3 и пытаюсь отрисовать при помощи функции 7 либо 65. Но от чего-то вылетает. Перебором выяснил что мелкие области вроде 10*10 рисует норм, а 100*100 уже валится.

И попутно вопрос - на какой адрес идет маппинг LFB буффера, чтоб не работать через gs или функции 7/65?


Top
   
PostPosted: Wed Oct 06, 2010 7:33 pm 
Veliant wrote:
Скорость IPC скажется на скорость оконного менеджера

При текущей реализации это будет полный тормоз. А вообще такое имеет смысл реализовать полностью вынеся GUI из ядра, иначе это будут полумеры.
Veliant wrote:
Создаю окно 1 типа (прозрачное без ничего). Выделяю память размером ВЫСОТА*ШИРИНА*3 и пытаюсь отрисовать при помощи функции 7 либо 65. Но от чего-то вылетает. Перебором выяснил что мелкие области вроде 10*10 рисует норм, а 100*100 уже валится.

Без кода сказать что-либо сложно - в "угадайку" играть бессмысленно.


Top
   
PostPosted: Wed Oct 06, 2010 7:38 pm 
Offline

Joined: Thu Jan 26, 2006 8:47 pm
Posts: 284
Выкинул не имеющий отношения к проблеме код
Spoiler: Show
Code:
include "macros.inc"

MEOS_APP_START

CODE
   mov   eax, 60
   mov   eax, 1
   mov   ecx, IPC_buffer
   mov   edx, IPC_buffer_size
   mcall
   
   mcall   40, 1100011b   ; Устанавливаем события

   mcall   14            ; Узнаем размеры экрана
   mov   ebx, eax
   and   eax, 0xFFFF
   mov   [screen_h], eax
   shr   ebx, 16
   mov   [screen_w], ebx
   
   mcall   66, 1, 1      ; Режим скан-кодов
   
   mcall   68, 11         ; Инициализация кучи
   
   mov   edx, [screen_w]
   imul   edx, [screen_h]
   
   mov   esi, edx
   shl   edx, 1
   mcall   68, 12         ; Выделить памяти W*H*2
   mov   [window_map], eax
   
   imul   esi, 3
   mov   edx, esi
   mcall   68, 12         ; Выделить памяти W*H*3 (rgb)
   mov   [screen], eax

   call   draw_window

wait_event:
   mcall   10
   call   dword [handlers + eax*4]
   jmp   wait_event

hl_redraw:
   call   draw_window
ret

hl_key:
   mcall   2
   cmp   eax, 1
   je   .empty_buffer
   .empty_buffer:
ret

hl_mouse:
   mcall   37, 0
   mov   ebx, eax
   shr   ebx, 16
   xchg   ax, bx
   ; AX - x, BX - y
ret

hl_ipc:
ret

draw_window:
   mcall   12, 1
   
   mov   eax, 0
   mov   ebx, [screen_w]      ; 0 << 16 + scrren_w
   mov   ecx, [screen_h]      ; 0 << 16 + scrren_h
   mov   edx, 0x41FFFFFF
   mov   esi, 0x01FFFFFF
   mcall

; ВОТ СОБСТВЕННО ТУТ ВЫВОЖУ
;под отладчиком валится на int 0x40 с ...OE. Suspended   
   ;mov   ecx, [screen_w]
   ;shl   ecx, 16
   ;or   ecx, [screen_h]
   ;mov   ebx, [screen]
   ;mcall   7, , , 0
   
   mcall   12, 2
ret

DATA
handlers:
   dd   0, hl_redraw, hl_key, 0, 0, 0, hl_mouse, hl_ipc
   
screen_w   dd 0
screen_h   dd 0

window_map   dd 0
screen      dd 0

IPC_buffer:
   .lock   dd 0
   .size   dd 0
   db 128 dup (0)
IPC_buffer_size   dd $-IPC_buffer

UDATA

MEOS_APP_END


Top
   
PostPosted: Thu Oct 07, 2010 12:15 pm 
Veliant
Смотрим код:
Code:
   mov   esi, edx
   shl   edx, 1
   mcall   68, 12         ; Выделить памяти W*H*2
   mov   [window_map], eax
   
   imul   esi, 3
   mov   edx, esi
   mcall   68, 12         ; Выделить памяти W*H*3 (rgb)
   mov   [screen], eax

А потом внимательное читаем документацию:
Code:
======================================================================
========== Функция 68, подфункция 12 - выделить блок памяти. =========
======================================================================
Параметры:
  * eax = 68 - номер функции
  * ebx = 12 - номер подфункции
  * ecx = требуемый размер в байтах
Возвращаемое значение:
  * eax = указатель на выделенный блок
Замечания:
  * Предварительно следует инициализировать кучу процесса вызовом
    подфункции 11.
  * Функция выделяет целое число страниц (4 Кб) так, что фактический
    размер выделенного блока больше или равен запрошенному.


Если не помогает, то стучимся головой об стенку. Только аккуратно - стенки бывают хрупкие. :wink:


Top
   
PostPosted: Thu Oct 07, 2010 4:58 pm 
Offline

Joined: Thu Jan 26, 2006 8:47 pm
Posts: 284
Позор мне :oops: Спасибо, Марат


Top
   
PostPosted: Thu Oct 07, 2010 6:02 pm 
Ничего страшного, у всех бывает. Иногда глаз "замылится", иногда просто тупим.


Top
   
PostPosted: Thu Oct 07, 2010 8:59 pm 
Offline

Joined: Wed Sep 15, 2010 7:22 pm
Posts: 101
Рискну также что-то добавить :wink:

Цитата: "При текущей реализации это будет полный тормоз. А вообще такое имеет смысл реализовать полностью вынеся GUI из ядра, иначе это будут полумеры." [Mario]

По поводу необходимости выноса в этом случае GUI из ядра полностью согласен.

По поводу тормозов ... Если это реализовать так, как предлагалось создателем темы - то это да. Но ведь ядро KolibriOS позволяет приложению:
- напрямую обращаться к адресному прстранству видео фрейм буфера;
- напрямую обращаться к портам ввода/вывода видео карты;
- использовать механизм именной разделяемой памяти (при помощи которого можно передавать изображения);
(Или я не прав?)
Всё это позволяет реализовать всю графическую систему в виде ring3 сервера, при этом сами графические функции не должны быть существенно более медленными. (Опять таки, если это не так, то хотелось бы знать почему это не так.)

Есть правда и принципиальные проблемы (если сохранять существующий программный интерфейс):при текущем API даже прорисовка самого простейшего окна требует нескольких системных вызовов; графическую систему это существенно не замедляет, так как сами графические функции требуют порой сотни тысяч тактов процессора, в то время как пара переключений ring3 -> ring0 -> ring3 только порядка 1000 тактов процессора; если же эти функции выполнять будет другое ring3 приложение, то
- число переключений ring3 -> ring0 -> ring3 удвоится;
- потребуется поменять работу планировщика, чтобы сервер запускался сразу (иначе каждый такой системный вызов потребует ожидания того момента, когда дойдёт очередь до запуска сервера GUI - а это точно тормоза);
- возникают проблемы с доступом к данным вызвавшего GUI-системный вызов процесса (ибо адресное пространство при этом уже меняется существенно); если не менять API, то выходом может быть что-то вроде отображения адесного пространства вызвавшего GUI-системный вызов приложения в адресное пространство сервера GUI хотя бы в режиме read only.

Иными словами, для того, чтобы реализовать всё это без тормозов, потребуется довольно существенные изменения в работе самого ядра KolibriOS.

Другой вариант - это радикально менять GUI API. Но тогда сама работа KolibriOS тоже радикально поменяется:
сейчас есть два варианта:
(1) система даёт сигнал о необходимости прорисовки окна, а приложение шаг за шагом даёт команды прорисовки, которые система просто исполняет;
(2) приложение само заставлет систему шаг за шагом заново перерисовать окно.
тогда эти варианты видоизменяться:
(1) система извещает приложение: "Кой что изменилось в GUI - проверь структуры данных своего окна!" ; приложение же их изменяет, если это надо, и отсылает сообщение: "Теперь со структурами данных всё OK -можно рисовать!"; ну и система после этого даёт сигнал GUI-серверу, что данные для прорисовки готовы (после опроса всех затронутых приложений).
(2) приложение меняет структуры данных своего окна и извещает систему об этом.

P.S.

Если я не прав - критикуйте.

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


Top
   
PostPosted: Thu Oct 07, 2010 9:52 pm 
Offline

Joined: Thu Jan 26, 2006 8:47 pm
Posts: 284
Quote:
- напрямую обращаться к адресному прстранству видео фрейм буфера;
- напрямую обращаться к портам ввода/вывода видео карты;

Приложение не должно думать как рисовать - ядро должно предоставлять средства для отрисовки. Сейчас более оптимальным думаю будет работа с фрейм буфером напрямую.
Quote:
- использовать механизм именной разделяемой памяти (при помощи которого можно передавать изображения);

Разделяемая память возможно ускорила бы обмен данными. А пока что, надо в ядре ускорить каким-то образом обмен сообщениями между процессами.

Ничего не мешает запускать этот процесс первым в автозапуске, на данном этапе.
Проблемы с пересечением API все же будут некоторые (например оконный менеджер не сможет управлять окнами, созданными ядром), либо придется делать костыли - сделать некоторую трансляцию API, на уровне перекомпиляции, и процесс просто будет работать со своим окном, как с canvas'ом.

Относительно интерфейса как раз тоже есть пока 2 мысли:
-библиотекой виджетов пользуется только оконный менеджер.
Spoiler: Show
Плюсы:
-Процесс только создает/настраивает/удаляет виджеты в окне, а оконная система сама внутри себя заботится о перерисовке, работе с виджетами и прочим, лишь изредка дергая процесс теми сообщениями, которые он запросил, в следствии чего снизится обмен сообщениями между процессом и менеджером окон => быстродействие.
-Библиотека с виджетами подгружается только один раз - для процесса оконного менеджера

-библиотекой виджетов пользуется каждое приложение, а оконный менеджер выдает только область
Spoiler: Show
Плюсы:
-Приложение может использовать свою какую-то стороннюю библиотеку виджетов
Минусы:
-Большое число передач между процессом и оконным менеджером
-Опять же отступление от единого дизайна системы


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


Top
   
PostPosted: Fri Oct 08, 2010 10:28 am 
Offline
Kernel Developer

Joined: Wed Mar 08, 2006 6:25 pm
Posts: 3952
Veliant

Первый вариант как раз самый громоздкий и тормозной. На любое действие придётся дёргать оконный менеджер. Изменить надпись или цвет кнопки, добавить строчку в листбокс, перерисовать список, все через ipc. Те же проблемы и с декораторами. Традиционное окно - рамки окна, заголовок с кнопками и системным меню, меню приложения, панели инструментов, клиентская часть, строка состояния. Если приложение рисует только клиентскую часть то любая операция с меню, тулбоксами и т.п. потребует вызовов оконного менеджера. По этой причине Gnome притормаживает там, где WinXP просто летает. На мой взгляд оптимальной является реализация GUI в специальной DLL с автоматической подгрузкой при запуске приложения. При этом традиционый для Колибри цикл выборки сообщений должен быть в DLL, а в программе обработчики для уже оттранслированных GUI событий.


Top
   
PostPosted: Fri Oct 08, 2010 6:28 pm 
Offline
User avatar

Joined: Tue May 08, 2007 12:44 am
Posts: 346
Serge wrote:
цикл выборки сообщений должен быть в DLL, а в программе обработчики для уже оттранслированных GUI событий.

Ой, неужели это кто-то реализует?

_________________
Разработчик языка программирования Кантор


Top
   
PostPosted: Fri Oct 08, 2010 7:12 pm 
Offline
Kernel Developer

Joined: Wed Mar 08, 2006 6:25 pm
Posts: 3952
Сложно, но можно. Делал такую демку


Attachments:
File comment: Скопировать содержимое /lib в /rd/1/lib
demo.7z [21.2 KiB]
Downloaded 174 times
Top
   
PostPosted: Fri Oct 08, 2010 7:45 pm 
Offline

Joined: Wed Sep 15, 2010 7:22 pm
Posts: 101
Quote:
Цитата:
Quote:
- напрямую обращаться к адресному прстранству видео фрейм буфера;
- напрямую обращаться к портам ввода/вывода видео карты;


Приложение не должно думать как рисовать - ядро должно предоставлять средства для отрисовки.


В данном случае под приложением я имел в виду Ваш планируемый даемон (т.е. GUI сервер). Ни в коем случае не рядовое приложение.


Quote:
Если приложение рисует только клиентскую часть то любая операция с меню, тулбоксами и т.п. потребует вызовов оконного менеджера.


Если придерживаться традиционного API - то именно вызовов. Однако можно ведь рисовать и все данные клиентской части размещать в именной разделяемой памяти - тогда достаточно только одного вызова.

Хотя в целом с замечанием я согласен.


Top
   
PostPosted: Fri Oct 08, 2010 10:42 pm 
Serge wrote:
Сложно, но можно. Делал такую демку

А что за демка? На текущем ядре и ночной сборке не запускается.


Top
   
PostPosted: Fri Oct 08, 2010 11:52 pm 
Offline
Kernel Developer

Joined: Wed Mar 08, 2006 6:25 pm
Posts: 3952
Mario

А что пишет на доску отладки ?


Top
   
PostPosted: Sat Oct 09, 2010 12:07 am 
В том и дело, что ничего. Пробовал запускать из KFM и KFAR.
В CPU тоже ничего.
Единственно запускал из Qemu с образа жесткого диска, доступной для ОС оперативки 128 Мб.


Top
   
Display posts from previous:  Sort by  
Post new topic  Reply to topic  [ 20 posts ]  Go to page 1 2 Next

All times are UTC+03:00


Who is online

Users browsing this forum: No registered users and 1 guest


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