Хочу попробовать реализовать следующую вещь:
Процесс-демон который будет полностью отвечать за окна (и скорей всего за виджеты). Т.е. все приложения обращаются к нему, допустим через IPC, с запросами на создание/удаление окон, и какие события хотят получать в ответ.
Плюсы:
Внешний вид приложений будет унифицирован (+темы), с возможностью рисовать на своем окне как сейчас.
Процесс не надо думать как обрабатывать виджеты (фокус, перемещение клавишами и пр.).
Возможность вынести оконную оболочку на другой хост и общаться по сети.
Возможность управлять чужими окнами на уровне виджетов.
Создавать окна разом файлом ресурсов например в формате *.rc, *.res или *.xml (*.rc уже в принципе давно делал, не выкладывал только)
Минусы:
Скорость IPC скажется на скорость оконного менеджера
При текущей реализации возможно убивание процесса (можно конечно сделать сторожевой процесс, который будет заново загружать).
Если падает - то все разом (но есть идеи как быстро все восстановить)
Собственно сразу возникли не понятные проблемы:
Создаю окно 1 типа (прозрачное без ничего). Выделяю память размером ВЫСОТА*ШИРИНА*3 и пытаюсь отрисовать при помощи функции 7 либо 65. Но от чего-то вылетает. Перебором выяснил что мелкие области вроде 10*10 рисует норм, а 100*100 уже валится.
И попутно вопрос - на какой адрес идет маппинг LFB буффера, чтоб не работать через gs или функции 7/65?
Альтернативный WM
При текущей реализации это будет полный тормоз. А вообще такое имеет смысл реализовать полностью вынеся GUI из ядра, иначе это будут полумеры.Veliant wrote:Скорость IPC скажется на скорость оконного менеджера
Без кода сказать что-либо сложно - в "угадайку" играть бессмысленно.Veliant wrote:Создаю окно 1 типа (прозрачное без ничего). Выделяю память размером ВЫСОТА*ШИРИНА*3 и пытаюсь отрисовать при помощи функции 7 либо 65. Но от чего-то вылетает. Перебором выяснил что мелкие области вроде 10*10 рисует норм, а 100*100 уже валится.
Выкинул не имеющий отношения к проблеме код
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
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 Кб) так, что фактический
размер выделенного блока больше или равен запрошенному.
Позор мне Спасибо, Марат
Ничего страшного, у всех бывает. Иногда глаз "замылится", иногда просто тупим.
Рискну также что-то добавить
Цитата: "При текущей реализации это будет полный тормоз. А вообще такое имеет смысл реализовать полностью вынеся 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.
Если я не прав - критикуйте.
Текст данного сообщения довольно схематичный, поэтому жду запросов на более детальное изложение там, где это необходимо.
Цитата: "При текущей реализации это будет полный тормоз. А вообще такое имеет смысл реализовать полностью вынеся 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.
Если я не прав - критикуйте.
Текст данного сообщения довольно схематичный, поэтому жду запросов на более детальное изложение там, где это необходимо.
Приложение не должно думать как рисовать - ядро должно предоставлять средства для отрисовки. Сейчас более оптимальным думаю будет работа с фрейм буфером напрямую.- напрямую обращаться к адресному прстранству видео фрейм буфера;
- напрямую обращаться к портам ввода/вывода видео карты;
Разделяемая память возможно ускорила бы обмен данными. А пока что, надо в ядре ускорить каким-то образом обмен сообщениями между процессами.- использовать механизм именной разделяемой памяти (при помощи которого можно передавать изображения);
Ничего не мешает запускать этот процесс первым в автозапуске, на данном этапе.
Проблемы с пересечением API все же будут некоторые (например оконный менеджер не сможет управлять окнами, созданными ядром), либо придется делать костыли - сделать некоторую трансляцию API, на уровне перекомпиляции, и процесс просто будет работать со своим окном, как с canvas'ом.
Относительно интерфейса как раз тоже есть пока 2 мысли:
-библиотекой виджетов пользуется только оконный менеджер.
Spoiler:
Плюсы:-Процесс только создает/настраивает/удаляет виджеты в окне, а оконная система сама внутри себя заботится о перерисовке, работе с виджетами и прочим, лишь изредка дергая процесс теми сообщениями, которые он запросил, в следствии чего снизится обмен сообщениями между процессом и менеджером окон => быстродействие.
-Библиотека с виджетами подгружается только один раз - для процесса оконного менеджера
Spoiler:
Плюсы:-Приложение может использовать свою какую-то стороннюю библиотеку виджетов
Минусы:
-Большое число передач между процессом и оконным менеджером
-Опять же отступление от единого дизайна системы
По большому счету, процесс должен один раз сказать оконному менеджеру разметку своего окна, и потом, если надо, в ходе работы изменяет некоторые элементы, и больше незачем его дергать.
Veliant
Первый вариант как раз самый громоздкий и тормозной. На любое действие придётся дёргать оконный менеджер. Изменить надпись или цвет кнопки, добавить строчку в листбокс, перерисовать список, все через ipc. Те же проблемы и с декораторами. Традиционное окно - рамки окна, заголовок с кнопками и системным меню, меню приложения, панели инструментов, клиентская часть, строка состояния. Если приложение рисует только клиентскую часть то любая операция с меню, тулбоксами и т.п. потребует вызовов оконного менеджера. По этой причине Gnome притормаживает там, где WinXP просто летает. На мой взгляд оптимальной является реализация GUI в специальной DLL с автоматической подгрузкой при запуске приложения. При этом традиционый для Колибри цикл выборки сообщений должен быть в DLL, а в программе обработчики для уже оттранслированных GUI событий.
Первый вариант как раз самый громоздкий и тормозной. На любое действие придётся дёргать оконный менеджер. Изменить надпись или цвет кнопки, добавить строчку в листбокс, перерисовать список, все через ipc. Те же проблемы и с декораторами. Традиционное окно - рамки окна, заголовок с кнопками и системным меню, меню приложения, панели инструментов, клиентская часть, строка состояния. Если приложение рисует только клиентскую часть то любая операция с меню, тулбоксами и т.п. потребует вызовов оконного менеджера. По этой причине Gnome притормаживает там, где WinXP просто летает. На мой взгляд оптимальной является реализация GUI в специальной DLL с автоматической подгрузкой при запуске приложения. При этом традиционый для Колибри цикл выборки сообщений должен быть в DLL, а в программе обработчики для уже оттранслированных GUI событий.
Ой, неужели это кто-то реализует?Serge wrote:цикл выборки сообщений должен быть в DLL, а в программе обработчики для уже оттранслированных GUI событий.
Сложно, но можно. Делал такую демку
- Attachments
-
-
demo.7z (21.2 KiB)
- Скопировать содержимое /lib в /rd/1/lib
Downloaded 441 times
-
В данном случае под приложением я имел в виду Ваш планируемый даемон (т.е. GUI сервер). Ни в коем случае не рядовое приложение.Цитата:Приложение не должно думать как рисовать - ядро должно предоставлять средства для отрисовки.- напрямую обращаться к адресному прстранству видео фрейм буфера;
- напрямую обращаться к портам ввода/вывода видео карты;
Если придерживаться традиционного API - то именно вызовов. Однако можно ведь рисовать и все данные клиентской части размещать в именной разделяемой памяти - тогда достаточно только одного вызова.Если приложение рисует только клиентскую часть то любая операция с меню, тулбоксами и т.п. потребует вызовов оконного менеджера.
Хотя в целом с замечанием я согласен.
А что за демка? На текущем ядре и ночной сборке не запускается.Serge wrote:Сложно, но можно. Делал такую демку
Mario
А что пишет на доску отладки ?
А что пишет на доску отладки ?
В том и дело, что ничего. Пробовал запускать из KFM и KFAR.
В CPU тоже ничего.
Единственно запускал из Qemu с образа жесткого диска, доступной для ОС оперативки 128 Мб.
В CPU тоже ничего.
Единственно запускал из Qemu с образа жесткого диска, доступной для ОС оперативки 128 Мб.
Who is online
Users browsing this forum: No registered users and 3 guests