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

Kernel-side graphics support
  • Veliant wrote:Скорость IPC скажется на скорость оконного менеджера
    При текущей реализации это будет полный тормоз. А вообще такое имеет смысл реализовать полностью вынеся GUI из ядра, иначе это будут полумеры.
    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 Кб) так, что фактический
        размер выделенного блока больше или равен запрошенному.
    Если не помогает, то стучимся головой об стенку. Только аккуратно - стенки бывают хрупкие. :wink:
  • Позор мне :oops: Спасибо, Марат
  • Ничего страшного, у всех бывает. Иногда глаз "замылится", иногда просто тупим.
  • Рискну также что-то добавить :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.

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

    Текст данного сообщения довольно схематичный, поэтому жду запросов на более детальное изложение там, где это необходимо.
  • - напрямую обращаться к адресному прстранству видео фрейм буфера;
    - напрямую обращаться к портам ввода/вывода видео карты;
    Приложение не должно думать как рисовать - ядро должно предоставлять средства для отрисовки. Сейчас более оптимальным думаю будет работа с фрейм буфером напрямую.
    - использовать механизм именной разделяемой памяти (при помощи которого можно передавать изображения);
    Разделяемая память возможно ускорила бы обмен данными. А пока что, надо в ядре ускорить каким-то образом обмен сообщениями между процессами.

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

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

    Первый вариант как раз самый громоздкий и тормозной. На любое действие придётся дёргать оконный менеджер. Изменить надпись или цвет кнопки, добавить строчку в листбокс, перерисовать список, все через ipc. Те же проблемы и с декораторами. Традиционное окно - рамки окна, заголовок с кнопками и системным меню, меню приложения, панели инструментов, клиентская часть, строка состояния. Если приложение рисует только клиентскую часть то любая операция с меню, тулбоксами и т.п. потребует вызовов оконного менеджера. По этой причине Gnome притормаживает там, где WinXP просто летает. На мой взгляд оптимальной является реализация GUI в специальной DLL с автоматической подгрузкой при запуске приложения. При этом традиционый для Колибри цикл выборки сообщений должен быть в DLL, а в программе обработчики для уже оттранслированных GUI событий.
  • Serge wrote:цикл выборки сообщений должен быть в DLL, а в программе обработчики для уже оттранслированных GUI событий.
    Ой, неужели это кто-то реализует?
  • Сложно, но можно. Делал такую демку
    Attachments
    demo.7z (21.2 KiB)
    Скопировать содержимое /lib в /rd/1/lib
    Downloaded 434 times
  • Цитата:
    - напрямую обращаться к адресному прстранству видео фрейм буфера;
    - напрямую обращаться к портам ввода/вывода видео карты;
    Приложение не должно думать как рисовать - ядро должно предоставлять средства для отрисовки.
    В данном случае под приложением я имел в виду Ваш планируемый даемон (т.е. GUI сервер). Ни в коем случае не рядовое приложение.

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

    Хотя в целом с замечанием я согласен.
  • Serge wrote:Сложно, но можно. Делал такую демку
    А что за демка? На текущем ядре и ночной сборке не запускается.
  • Mario

    А что пишет на доску отладки ?
  • В том и дело, что ничего. Пробовал запускать из KFM и KFAR.
    В CPU тоже ничего.
    Единственно запускал из Qemu с образа жесткого диска, доступной для ОС оперативки 128 Мб.
  • Who is online

    Users browsing this forum: No registered users and 2 guests