Page 1 of 2

Альтернативный WM

Posted: Wed Oct 06, 2010 5:40 pm
by Veliant
Хочу попробовать реализовать следующую вещь:
Процесс-демон который будет полностью отвечать за окна (и скорей всего за виджеты). Т.е. все приложения обращаются к нему, допустим через IPC, с запросами на создание/удаление окон, и какие события хотят получать в ответ.

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

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


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

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

Re: Альтернативный WM

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

Re: Альтернативный WM

Posted: Wed Oct 06, 2010 7:38 pm
by Veliant
Выкинул не имеющий отношения к проблеме код
Spoiler:

Code: Select all

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

Re: Альтернативный WM

Posted: Thu Oct 07, 2010 12:15 pm
by Mario
Veliant
Смотрим код:

Code: Select all

   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: Select all

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

Re: Альтернативный WM

Posted: Thu Oct 07, 2010 4:58 pm
by Veliant
Позор мне :oops: Спасибо, Марат

Re: Альтернативный WM

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

Re: Альтернативный WM

Posted: Thu Oct 07, 2010 8:59 pm
by FireWall
Рискну также что-то добавить :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.

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

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

Re: Альтернативный WM

Posted: Thu Oct 07, 2010 9:52 pm
by Veliant
- напрямую обращаться к адресному прстранству видео фрейм буфера;
- напрямую обращаться к портам ввода/вывода видео карты;
Приложение не должно думать как рисовать - ядро должно предоставлять средства для отрисовки. Сейчас более оптимальным думаю будет работа с фрейм буфером напрямую.
- использовать механизм именной разделяемой памяти (при помощи которого можно передавать изображения);
Разделяемая память возможно ускорила бы обмен данными. А пока что, надо в ядре ускорить каким-то образом обмен сообщениями между процессами.

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

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

Re: Альтернативный WM

Posted: Fri Oct 08, 2010 10:28 am
by Serge
Veliant

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

Re: Альтернативный WM

Posted: Fri Oct 08, 2010 6:28 pm
by Freeman
Serge wrote:цикл выборки сообщений должен быть в DLL, а в программе обработчики для уже оттранслированных GUI событий.
Ой, неужели это кто-то реализует?

Re: Альтернативный WM

Posted: Fri Oct 08, 2010 7:12 pm
by Serge
Сложно, но можно. Делал такую демку

Re: Альтернативный WM

Posted: Fri Oct 08, 2010 7:45 pm
by FireWall
Цитата:
- напрямую обращаться к адресному прстранству видео фрейм буфера;
- напрямую обращаться к портам ввода/вывода видео карты;
Приложение не должно думать как рисовать - ядро должно предоставлять средства для отрисовки.
В данном случае под приложением я имел в виду Ваш планируемый даемон (т.е. GUI сервер). Ни в коем случае не рядовое приложение.

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

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

Re: Альтернативный WM

Posted: Fri Oct 08, 2010 10:42 pm
by Mario
Serge wrote:Сложно, но можно. Делал такую демку
А что за демка? На текущем ядре и ночной сборке не запускается.

Re: Альтернативный WM

Posted: Fri Oct 08, 2010 11:52 pm
by Serge
Mario

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

Re: Альтернативный WM

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